Skip to main content

vk_video/device/
wgpu_api.rs

1use std::sync::Arc;
2
3use crate::{
4    DecoderError, VulkanAdapter, VulkanDevice, VulkanEncoderError, VulkanInstance, WgpuInitError,
5    WgpuTexturesDecoder, WgpuTexturesEncoder,
6    device::{DecoderParameters, EncoderParameters, VulkanDeviceDescriptor},
7    parser::{h264::H264Parser, reference_manager::ReferenceContext},
8    vulkan_decoder::{FrameSorter, ImageModifiers, VulkanDecoder},
9    vulkan_encoder::VulkanEncoder,
10    wrappers::Device,
11};
12
13impl VulkanDevice {
14    pub fn create_wgpu_textures_decoder(
15        self: &Arc<Self>,
16        parameters: DecoderParameters,
17    ) -> Result<WgpuTexturesDecoder, DecoderError> {
18        let parser = H264Parser::default();
19        let reference_ctx = ReferenceContext::new(parameters.missed_frame_handling);
20
21        let vulkan_decoder = VulkanDecoder::new(
22            Arc::new(self.decoding_device()?),
23            parameters.usage_flags,
24            ImageModifiers {
25                additional_queue_index: self.queues.transfer.family_index,
26                create_flags: Default::default(),
27                usage_flags: Default::default(),
28            },
29        )?;
30        let frame_sorter = FrameSorter::<wgpu::Texture>::new();
31
32        Ok(WgpuTexturesDecoder {
33            parser,
34            reference_ctx,
35            vulkan_decoder,
36            frame_sorter,
37        })
38    }
39
40    pub fn create_wgpu_textures_encoder(
41        self: &Arc<Self>,
42        parameters: EncoderParameters,
43    ) -> Result<WgpuTexturesEncoder, VulkanEncoderError> {
44        let parameters = self.validate_and_fill_encoder_parameters(
45            parameters.output_parameters,
46            parameters.input_parameters.width,
47            parameters.input_parameters.height,
48            parameters.input_parameters.target_framerate,
49        )?;
50        let encoder = VulkanEncoder::new(Arc::new(self.encoding_device()?), parameters)?;
51        Ok(WgpuTexturesEncoder {
52            vulkan_encoder: encoder,
53        })
54    }
55
56    pub fn wgpu_device(&self) -> wgpu::Device {
57        self.wgpu_ctx.wgpu_device.clone()
58    }
59
60    pub fn wgpu_queue(&self) -> wgpu::Queue {
61        self.wgpu_ctx.wgpu_queue.clone()
62    }
63
64    pub fn wgpu_adapter(&self) -> wgpu::Adapter {
65        self.wgpu_ctx.wgpu_adapter.clone()
66    }
67}
68
69pub(crate) struct WgpuContext {
70    pub(crate) wgpu_device: wgpu::Device,
71    pub(crate) wgpu_queue: wgpu::Queue,
72    pub(crate) wgpu_adapter: wgpu::Adapter,
73}
74
75impl WgpuContext {
76    pub(crate) fn new(
77        instance: &VulkanInstance,
78        wgpu_adapter: wgpu::hal::ExposedAdapter<wgpu::hal::vulkan::Api>,
79        wgpu_queue_family_index: u32,
80        device_descriptor: &VulkanDeviceDescriptor,
81        device: Arc<Device>,
82        required_extensions: Vec<&'static std::ffi::CStr>,
83    ) -> Result<Self, WgpuInitError> {
84        let VulkanDeviceDescriptor {
85            wgpu_features,
86            wgpu_experimental_features,
87            wgpu_limits,
88        } = device_descriptor.clone();
89
90        let wgpu_features = wgpu_features | wgpu::Features::TEXTURE_FORMAT_NV12;
91        let wgpu_device = unsafe {
92            wgpu_adapter.adapter.device_from_raw(
93                device.device.clone(),
94                Some(Box::new(move || {
95                    drop(device);
96                })),
97                &required_extensions,
98                wgpu_features,
99                &wgpu_limits,
100                &wgpu::MemoryHints::default(),
101                wgpu_queue_family_index,
102                0,
103            )?
104        };
105
106        let wgpu_adapter = unsafe { instance.wgpu_instance.create_adapter_from_hal(wgpu_adapter) };
107        let (wgpu_device, wgpu_queue) = unsafe {
108            wgpu_adapter.create_device_from_hal(
109                wgpu_device,
110                &wgpu::DeviceDescriptor {
111                    label: Some("wgpu device created by the vulkan video decoder"),
112                    memory_hints: wgpu::MemoryHints::default(),
113                    required_limits: wgpu_limits,
114                    required_features: wgpu_features,
115                    trace: wgpu::Trace::Off,
116                    experimental_features: wgpu_experimental_features,
117                },
118            )?
119        };
120
121        Ok(Self {
122            wgpu_device,
123            wgpu_queue,
124            wgpu_adapter,
125        })
126    }
127}
128
129pub(crate) fn append_wgpu_device_extensions(
130    adapter: &VulkanAdapter<'_>,
131    wgpu_features: wgpu::Features,
132    required_extensions: &mut Vec<&'static std::ffi::CStr>,
133) {
134    let wgpu_features = wgpu_features | wgpu::Features::TEXTURE_FORMAT_NV12;
135    let mut wgpu_extensions = adapter
136        .wgpu_adapter
137        .adapter
138        .required_device_extensions(wgpu_features);
139
140    required_extensions.append(&mut wgpu_extensions);
141}