diff --git a/Cargo.toml b/Cargo.toml index d5fb430..412ac03 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ version = "1.0.0" edition = "2024" [dependencies] -wgpu = { version = "25", default-features = false, features = ["vulkan"] } +wgpu = { version = "26", default-features = false, features = ["vulkan"] } ash = "0.38" glam = "0.29" uuid = "1" diff --git a/README.md b/README.md index 229353c..fdf040f 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ A wrapper for using [DLSS](https://www.nvidia.com/en-us/geforce/technologies/dls | dlss_wgpu | dlss | wgpu | |:---------:|:--------:|:----:| -| v1.0 | v310.3.0 | v25 | +| v1.0 | v310.3.0 | v26 | ## Downloading The DLSS SDK The DLSS SDK cannot be redistributed by this crate. You will need to download the SDK as follows: diff --git a/src/context.rs b/src/context.rs index 75c6202..eeed576 100644 --- a/src/context.rs +++ b/src/context.rs @@ -1,4 +1,7 @@ -use crate::{DlssExposure, DlssRenderParameters, DlssSdk, nvsdk_ngx::*}; +use crate::{ + DlssExposure, DlssRenderParameters, DlssSdk, nvsdk_ngx::*, + render_parameters::texture_to_ngx_resource, +}; use glam::{UVec2, Vec2}; use std::{ iter, @@ -122,7 +125,7 @@ impl DlssContext { exposure_scale, pre_exposure, } => ( - &mut exposure.as_resource(adapter) as *mut _, + &mut texture_to_ngx_resource(exposure, adapter) as *mut _, exposure_scale.unwrap_or(1.0), pre_exposure.unwrap_or(0.0), ), @@ -131,12 +134,16 @@ impl DlssContext { let mut dlss_eval_params = NVSDK_NGX_VK_DLSS_Eval_Params { Feature: NVSDK_NGX_VK_Feature_Eval_Params { - pInColor: &mut render_parameters.color.as_resource(adapter), - pInOutput: &mut render_parameters.dlss_output.as_resource(adapter), + pInColor: &mut texture_to_ngx_resource(render_parameters.color, adapter) as *mut _, + pInOutput: &mut texture_to_ngx_resource(render_parameters.dlss_output, adapter) + as *mut _, InSharpness: 0.0, }, - pInDepth: &mut render_parameters.depth.as_resource(adapter), - pInMotionVectors: &mut render_parameters.motion_vectors.as_resource(adapter), + pInDepth: &mut texture_to_ngx_resource(render_parameters.depth, adapter) as *mut _, + pInMotionVectors: &mut texture_to_ngx_resource( + render_parameters.motion_vectors, + adapter, + ) as *mut _, InJitterOffsetX: render_parameters.jitter_offset.x, InJitterOffsetY: render_parameters.jitter_offset.y, InRenderSubrectDimensions: NVSDK_NGX_Dimensions { @@ -149,7 +156,7 @@ impl DlssContext { pInTransparencyMask: ptr::null_mut(), pInExposureTexture: exposure, pInBiasCurrentColorMask: match &render_parameters.bias { - Some(bias) => &mut bias.as_resource(adapter), + Some(bias) => &mut texture_to_ngx_resource(bias, adapter) as *mut _, None => ptr::null_mut(), }, InColorSubrectBase: NVSDK_NGX_Coordinates { X: 0, Y: 0 }, @@ -225,16 +232,14 @@ impl DlssContext { impl Drop for DlssContext { fn drop(&mut self) { unsafe { - self.device.as_hal::(|device| { - device - .unwrap() - .raw_device() - .device_wait_idle() - .expect("Failed to wait for idle device when destroying DlssContext"); - - check_ngx_result(NVSDK_NGX_VULKAN_ReleaseFeature(self.feature)) - .expect("Failed to destroy DlssContext feature"); - }); + let hal_device = self.device.as_hal::().unwrap(); + hal_device + .raw_device() + .device_wait_idle() + .expect("Failed to wait for idle device when destroying DlssContext"); + + check_ngx_result(NVSDK_NGX_VULKAN_ReleaseFeature(self.feature)) + .expect("Failed to destroy DlssContext feature"); } } } diff --git a/src/initialization.rs b/src/initialization.rs new file mode 100644 index 0000000..18d5d40 --- /dev/null +++ b/src/initialization.rs @@ -0,0 +1,168 @@ +use crate::{ + feature_info::with_feature_info, + nvsdk_ngx::{ + DlssError, NVSDK_NGX_VULKAN_GetFeatureDeviceExtensionRequirements, + NVSDK_NGX_VULKAN_GetFeatureInstanceExtensionRequirements, check_ngx_result, + }, +}; +use ash::{Entry, vk::PhysicalDevice}; +use std::{ffi::CStr, ptr, slice}; +use uuid::Uuid; +use wgpu::{ + Adapter, Device, DeviceDescriptor, Instance, InstanceDescriptor, Queue, RequestDeviceError, + hal::{DeviceError, InstanceError, api::Vulkan}, +}; + +/// Creates a wgpu [`Instance`] with the extensions required for DLSS. +/// +/// If the system does not support DLSS, it will set `dlss_supported` to false. +pub fn create_instance( + project_id: Uuid, + instance_descriptor: &InstanceDescriptor, + dlss_supported: &mut bool, +) -> Result { + unsafe { + let mut result = Ok(()); + let raw_instance = wgpu::hal::vulkan::Instance::init_with_callback( + &wgpu::hal::InstanceDescriptor { + name: "wgpu", + flags: instance_descriptor.flags, + memory_budget_thresholds: instance_descriptor.memory_budget_thresholds, + backend_options: instance_descriptor.backend_options.clone(), + }, + Some(Box::new(|args| { + match required_instance_extensions(project_id, args.entry) { + Ok((extensions, true)) => args.extensions.extend(extensions), + Ok((_, false)) => *dlss_supported = false, + Err(err) => result = Err(err), + } + })), + )?; + result?; + + Ok(Instance::from_hal::(raw_instance)) + } +} + +/// Creates a wgpu [`Device`] and [`Queue`] with the extensions required for DLSS. +/// +/// If the system does not support DLSS, it will set `dlss_supported` to false. +/// +/// The provided [`Adapter`] must be using the Vulkan backend. +pub fn request_device( + project_id: Uuid, + adapter: &Adapter, + device_descriptor: &DeviceDescriptor, + dlss_supported: &mut bool, +) -> Result<(Device, Queue), InitializationError> { + unsafe { + let raw_adapter = adapter + .as_hal::() + .ok_or(InitializationError::UnsupportedBackend)?; + let raw_instance = raw_adapter.shared_instance().raw_instance(); + let raw_physical_device = raw_adapter.raw_physical_device(); + + let mut result = Ok(()); + let open_device = raw_adapter.open_with_callback( + device_descriptor.required_features, + &device_descriptor.memory_hints, + Some(Box::new(|args| { + match required_device_extensions( + project_id, + &raw_adapter, + raw_instance.handle(), + raw_physical_device, + ) { + Ok((extensions, true)) => args.extensions.extend(extensions), + Ok((_, false)) => *dlss_supported = false, + Err(err) => result = Err(err), + } + })), + )?; + result?; + + Ok(adapter.create_device_from_hal::(open_device, device_descriptor)?) + } +} + +fn required_instance_extensions( + project_id: Uuid, + entry: &Entry, +) -> Result<(impl Iterator, bool), InitializationError> { + with_feature_info(project_id, |feature_info| unsafe { + // Get required extension names + let mut required_extensions = ptr::null_mut(); + let mut required_extension_count = 0; + check_ngx_result(NVSDK_NGX_VULKAN_GetFeatureInstanceExtensionRequirements( + feature_info, + &mut required_extension_count, + &mut required_extensions, + ))?; + let required_extensions = + slice::from_raw_parts(required_extensions, required_extension_count as usize); + let required_extensions = required_extensions + .iter() + .map(|extension| CStr::from_ptr(extension.extension_name.as_ptr())); + + // Check that the required extensions are supported + let supported_extensions = entry.enumerate_instance_extension_properties(None)?; + let extensions_supported = required_extensions.clone().all(|required_extension| { + supported_extensions + .iter() + .any(|extension| extension.extension_name_as_c_str() == Ok(required_extension)) + }); + + Ok((required_extensions, extensions_supported)) + }) +} + +fn required_device_extensions( + project_id: Uuid, + raw_adapter: &wgpu::hal::vulkan::Adapter, + raw_instance: ash::vk::Instance, + raw_physical_device: PhysicalDevice, +) -> Result<(impl Iterator, bool), InitializationError> { + with_feature_info(project_id, |feature_info| unsafe { + // Get required extension names + let mut required_extensions = ptr::null_mut(); + let mut required_extension_count = 0; + check_ngx_result(NVSDK_NGX_VULKAN_GetFeatureDeviceExtensionRequirements( + raw_instance, + raw_physical_device, + feature_info, + &mut required_extension_count, + &mut required_extensions, + ))?; + let required_extensions = + slice::from_raw_parts(required_extensions, required_extension_count as usize); + let required_extensions = required_extensions + .iter() + .map(|extension| CStr::from_ptr(extension.extension_name.as_ptr())); + + // Check that the required extensions are supported + let extensions_supported = required_extensions.clone().all(|required_extension| { + raw_adapter + .physical_device_capabilities() + .supports_extension(required_extension) + }); + + Ok((required_extensions, extensions_supported)) + }) +} + +/// Error returned by [`request_device`]. +#[derive(thiserror::Error, Debug)] +pub enum InitializationError { + #[error(transparent)] + InstanceError(#[from] InstanceError), + #[error(transparent)] + RequestDeviceError(#[from] RequestDeviceError), + #[error(transparent)] + DeviceError(#[from] DeviceError), + #[error(transparent)] + VulkanError(#[from] ash::vk::Result), + #[error(transparent)] + DlssError(#[from] DlssError), + #[error("Provided adapter is not using the Vulkan backend")] + UnsupportedBackend, +} diff --git a/src/lib.rs b/src/lib.rs index 56de3ed..f69022f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,15 +14,15 @@ //! use dlss_wgpu::{DlssSdk, DlssContext, DlssPerfQualityMode, DlssFeatureFlags, DlssRenderParameters}; //! //! let project_id = Uuid::parse_str("...").unwrap(); +//! let mut dlss_supported = true; //! -//! // Request a wgpu device and queue -//! let ((device, queue), dlss_supported) = { -//! match dlss_wgpu::request_device(project_id, &adapter, &device_descriptor) { -//! Ok(x) => (x, true), -//! // Fallback to standard device request if DLSS is not supported -//! Err(_) => (adapter.request_device(&device_descriptor).await.unwrap(), false), -//! } -//! }; +//! // Initialize wgpu +//! let instance = dlss_wgpu::create_instance(project_id, &instance_descriptor, &mut dlss_supported).unwrap(); +//! let adapter = instance.request_adapter(&adapter_options).await.unwrap(); +//! let (device, queue) = dlss_wgpu::request_device(project_id, &adapter, &device_descriptor, &mut dlss_supported).unwrap(); +//! +//! // Check `dlss_supported`, if false don't create DLSS resources +//! println!("DLSS supported: {dlss_supported}"); //! //! // Create the SDK once per application //! let sdk = DlssSdk::new(project_id, device).expect("Failed to create DLSS SDK"); @@ -51,13 +51,13 @@ mod context; mod feature_info; +mod initialization; mod nvsdk_ngx; mod render_parameters; -mod request_device; mod sdk; pub use context::DlssContext; +pub use initialization::{InitializationError, create_instance, request_device}; pub use nvsdk_ngx::{DlssError, DlssFeatureFlags, DlssPerfQualityMode}; -pub use render_parameters::{DlssExposure, DlssRenderParameters, DlssTexture}; -pub use request_device::{RequestDeviceError, request_device}; +pub use render_parameters::{DlssExposure, DlssRenderParameters}; pub use sdk::DlssSdk; diff --git a/src/render_parameters.rs b/src/render_parameters.rs index b2aa0ed..7f426c5 100644 --- a/src/render_parameters.rs +++ b/src/render_parameters.rs @@ -13,17 +13,17 @@ use wgpu::{ /// Inputs and output resources needed for rendering DLSS. pub struct DlssRenderParameters<'a> { /// Main color view of your camera. - pub color: DlssTexture<'a>, + pub color: &'a TextureView, /// Depth buffer. - pub depth: DlssTexture<'a>, + pub depth: &'a TextureView, // Motion vectors. - pub motion_vectors: DlssTexture<'a>, + pub motion_vectors: &'a TextureView, /// Camera exposure settings. pub exposure: DlssExposure<'a>, /// Optional per-pixel bias to make DLSS more reactive. - pub bias: Option>, + pub bias: Option<&'a TextureView>, /// The texture DLSS outputs to. - pub dlss_output: DlssTexture<'a>, + pub dlss_output: &'a TextureView, /// Whether DLSS should reset temporal history, useful for camera cuts. pub reset: bool, /// Subpixel jitter that was applied to your camera. @@ -42,9 +42,9 @@ impl<'a> DlssRenderParameters<'a> { } pub(crate) fn barrier_list(&self) -> impl Iterator> { - fn resource_barrier<'a>(texture: &DlssTexture<'a>) -> TextureTransition<&'a Texture> { + fn resource_barrier<'a>(texture_view: &'a TextureView) -> TextureTransition<&'a Texture> { TextureTransition { - texture: texture.texture, + texture: texture_view.texture(), selector: None, state: TextureUses::RESOURCE, } @@ -58,9 +58,9 @@ impl<'a> DlssRenderParameters<'a> { DlssExposure::Manual { exposure, .. } => Some(resource_barrier(exposure)), DlssExposure::Automatic => None, }, - self.bias.as_ref().map(resource_barrier), + self.bias.map(resource_barrier), Some(TextureTransition { - texture: self.dlss_output.texture, + texture: self.dlss_output.texture(), selector: None, state: TextureUses::STORAGE_READ_WRITE, }), @@ -74,7 +74,7 @@ impl<'a> DlssRenderParameters<'a> { pub enum DlssExposure<'a> { /// Exposure controlled by the application. Manual { - exposure: DlssTexture<'a>, + exposure: &'a TextureView, exposure_scale: Option, pre_exposure: Option, }, @@ -82,42 +82,35 @@ pub enum DlssExposure<'a> { Automatic, } -/// Wrapper for a texture(view) used by [`DlssRenderParameters`]. -pub struct DlssTexture<'a> { - pub texture: &'a Texture, - pub view: &'a TextureView, -} +pub(crate) fn texture_to_ngx_resource( + texture_view: &TextureView, + adapter: &Adapter, +) -> NVSDK_NGX_Resource_VK { + unsafe { + let raw_view = texture_view.as_hal::().unwrap().raw_handle(); + let texture = texture_view.texture(); -impl<'a> DlssTexture<'a> { - pub(crate) fn as_resource(&self, adapter: &Adapter) -> NVSDK_NGX_Resource_VK { - unsafe { - NVSDK_NGX_Create_ImageView_Resource_VK( - self.view - .as_hal::(|v| v.unwrap().raw_handle()), - self.texture - .as_hal::(|t| t.unwrap().raw_handle()), - ImageSubresourceRange { - aspect_mask: if self.texture.format().has_color_aspect() { - ImageAspectFlags::COLOR - } else { - ImageAspectFlags::DEPTH - }, - base_mip_level: 0, - level_count: REMAINING_MIP_LEVELS, - base_array_layer: 0, - layer_count: REMAINING_ARRAY_LAYERS, + NVSDK_NGX_Create_ImageView_Resource_VK( + raw_view, + texture.as_hal::().unwrap().raw_handle(), + ImageSubresourceRange { + aspect_mask: if texture.format().has_color_aspect() { + ImageAspectFlags::COLOR + } else { + ImageAspectFlags::DEPTH }, - adapter.as_hal::(|adapter| { - adapter - .unwrap() - .texture_format_as_raw(self.texture.format()) - }), - self.texture.width(), - self.texture.height(), - self.texture - .usage() - .contains(TextureUsages::STORAGE_BINDING), - ) - } + base_mip_level: 0, + level_count: REMAINING_MIP_LEVELS, + base_array_layer: 0, + layer_count: REMAINING_ARRAY_LAYERS, + }, + adapter + .as_hal::() + .unwrap() + .texture_format_as_raw(texture.format()), + texture.width(), + texture.height(), + texture.usage().contains(TextureUsages::STORAGE_BINDING), + ) } } diff --git a/src/request_device.rs b/src/request_device.rs deleted file mode 100644 index 6603faa..0000000 --- a/src/request_device.rs +++ /dev/null @@ -1,130 +0,0 @@ -use crate::{ - feature_info::with_feature_info, - nvsdk_ngx::{ - DlssError, NVSDK_NGX_VULKAN_GetFeatureDeviceExtensionRequirements, check_ngx_result, - }, -}; -use ash::vk::{DeviceCreateInfo, DeviceQueueCreateInfo, Instance, PhysicalDevice}; -use std::{ffi::CStr, ptr, slice}; -use uuid::Uuid; -use wgpu::{Adapter, Device, DeviceDescriptor, Queue, hal::api::Vulkan}; - -// TODO: Instance-level extensions (blocked on wgpu 26) - -/// Creates a wgpu [`Device`] and [`Queue`] with the extensions required for DLSS. -/// -/// If the system does not support DLSS, it will return [`DlssError::FeatureNotSupported`] wrapped in [`RequestDeviceError::DlssError`]. -/// -/// When DLSS is not supported, users should fallback to using [`wgpu::Adapter::request_device`]. -/// -/// The provided [`Adapter`] must be using the Vulkan backend. -pub fn request_device( - project_id: Uuid, - adapter: &Adapter, - device_descriptor: &DeviceDescriptor, -) -> Result<(Device, Queue), RequestDeviceError> { - unsafe { - let open_device: Result<_, RequestDeviceError> = - adapter.as_hal::(|raw_adapter| { - let raw_adapter = raw_adapter.ok_or(RequestDeviceError::UnsupportedBackend)?; - - let raw_instance = raw_adapter.shared_instance().raw_instance(); - let raw_physical_device = raw_adapter.raw_physical_device(); - - let mut enabled_extensions = - raw_adapter.required_device_extensions(device_descriptor.required_features); - enabled_extensions.extend(dlss_device_extensions( - project_id, - raw_adapter, - raw_instance.handle(), - raw_physical_device, - )?); - let mut enabled_phd_features = raw_adapter.physical_device_features( - &enabled_extensions, - device_descriptor.required_features, - ); - - let family_index = 0; - let family_info = DeviceQueueCreateInfo::default() - .queue_family_index(family_index) - .queue_priorities(&[1.0]); - let family_infos = [family_info]; - - let str_pointers = enabled_extensions - .iter() - .map(|&s| s.as_ptr()) - .collect::>(); - - let pre_info = DeviceCreateInfo::default() - .queue_create_infos(&family_infos) - .enabled_extension_names(&str_pointers); - let info = enabled_phd_features.add_to_device_create(pre_info); - - let raw_device = raw_instance.create_device(raw_physical_device, &info, None)?; - - Ok(raw_adapter.device_from_raw( - raw_device, - None, - &enabled_extensions, - device_descriptor.required_features, - &device_descriptor.memory_hints, - family_info.queue_family_index, - 0, - )?) - }); - - Ok(adapter.create_device_from_hal::(open_device?, device_descriptor)?) - } -} - -fn dlss_device_extensions( - project_id: Uuid, - raw_adapter: &wgpu::hal::vulkan::Adapter, - raw_instance: Instance, - raw_physical_device: PhysicalDevice, -) -> Result, DlssError> { - with_feature_info(project_id, |feature_info| unsafe { - let mut dlss_device_extensions = ptr::null_mut(); - let mut dlss_device_extension_count = 0; - - check_ngx_result(NVSDK_NGX_VULKAN_GetFeatureDeviceExtensionRequirements( - raw_instance, - raw_physical_device, - feature_info, - &mut dlss_device_extension_count, - &mut dlss_device_extensions, - ))?; - - let dlss_device_extensions = - slice::from_raw_parts(dlss_device_extensions, dlss_device_extension_count as usize); - - let dlss_device_extensions = dlss_device_extensions - .iter() - .map(|extension| CStr::from_ptr(extension.extension_name.as_ptr())); - - if !dlss_device_extensions.clone().all(|extension| { - raw_adapter - .physical_device_capabilities() - .supports_extension(extension) - }) { - return Err(DlssError::FeatureNotSupported); - } - - Ok(dlss_device_extensions) - }) -} - -/// Error returned by [`request_device`]. -#[derive(thiserror::Error, Debug)] -pub enum RequestDeviceError { - #[error(transparent)] - RequestDeviceError(#[from] wgpu::RequestDeviceError), - #[error(transparent)] - DeviceError(#[from] wgpu::hal::DeviceError), - #[error(transparent)] - VulkanError(#[from] ash::vk::Result), - #[error(transparent)] - DlssError(#[from] DlssError), - #[error("Provided adapter is not using the Vulkan backend")] - UnsupportedBackend, -} diff --git a/src/sdk.rs b/src/sdk.rs index e5e7961..9758762 100644 --- a/src/sdk.rs +++ b/src/sdk.rs @@ -20,32 +20,30 @@ impl DlssSdk { pub fn new(project_id: Uuid, device: Device) -> Result>, DlssError> { check_for_updates(project_id); + let mut parameters = ptr::null_mut(); unsafe { - let mut parameters = ptr::null_mut(); - device.as_hal::(|device| { - let device = device.unwrap(); - let shared_instance = device.shared_instance(); - let raw_instance = shared_instance.raw_instance(); + let hal_device = device.as_hal::().unwrap(); + let shared_instance = hal_device.shared_instance(); + let raw_instance = shared_instance.raw_instance(); - with_feature_info(project_id, |feature_info| { - check_ngx_result(NVSDK_NGX_VULKAN_Init_with_ProjectID( - feature_info.Identifier.v.ProjectDesc.ProjectId, - NVSDK_NGX_EngineType_NVSDK_NGX_ENGINE_TYPE_CUSTOM, - feature_info.Identifier.v.ProjectDesc.EngineVersion, - feature_info.ApplicationDataPath, - raw_instance.handle(), - device.raw_physical_device(), - device.raw_device().handle(), - shared_instance.entry().static_fn().get_instance_proc_addr, - raw_instance.fp_v1_0().get_device_proc_addr, - feature_info.FeatureInfo, - NVSDK_NGX_Version_NVSDK_NGX_Version_API, - )) - })?; - - check_ngx_result(NVSDK_NGX_VULKAN_GetCapabilityParameters(&mut parameters)) + with_feature_info(project_id, |feature_info| { + check_ngx_result(NVSDK_NGX_VULKAN_Init_with_ProjectID( + feature_info.Identifier.v.ProjectDesc.ProjectId, + NVSDK_NGX_EngineType_NVSDK_NGX_ENGINE_TYPE_CUSTOM, + feature_info.Identifier.v.ProjectDesc.EngineVersion, + feature_info.ApplicationDataPath, + raw_instance.handle(), + hal_device.raw_physical_device(), + hal_device.raw_device().handle(), + shared_instance.entry().static_fn().get_instance_proc_addr, + raw_instance.fp_v1_0().get_device_proc_addr, + feature_info.FeatureInfo, + NVSDK_NGX_Version_NVSDK_NGX_Version_API, + )) })?; + check_ngx_result(NVSDK_NGX_VULKAN_GetCapabilityParameters(&mut parameters))?; + let mut dlss_supported = 0; let result = check_ngx_result(NVSDK_NGX_Parameter_GetI( parameters, @@ -60,9 +58,9 @@ impl DlssSdk { check_ngx_result(NVSDK_NGX_VULKAN_DestroyParameters(parameters))?; return Err(DlssError::FeatureNotSupported); } - - Ok(Arc::new(Mutex::new(Self { parameters, device }))) } + + Ok(Arc::new(Mutex::new(Self { parameters, device }))) } /// Returns the number of bytes of VRAM allocated by DLSS. @@ -86,18 +84,16 @@ fn check_for_updates(project_id: Uuid) { impl Drop for DlssSdk { fn drop(&mut self) { unsafe { - self.device.as_hal::(|device| { - let device = device.unwrap().raw_device(); - - device - .device_wait_idle() - .expect("Failed to wait for idle device when destroying DlssSdk"); + let hal_device = self.device.as_hal::().unwrap(); + hal_device + .raw_device() + .device_wait_idle() + .expect("Failed to wait for idle device when destroying DlssSdk"); - check_ngx_result(NVSDK_NGX_VULKAN_DestroyParameters(self.parameters)) - .expect("Failed to destroy DlssSdk parameters"); - check_ngx_result(NVSDK_NGX_VULKAN_Shutdown1(device.handle())) - .expect("Failed to destroy DlssSdk"); - }); + check_ngx_result(NVSDK_NGX_VULKAN_DestroyParameters(self.parameters)) + .expect("Failed to destroy DlssSdk parameters"); + check_ngx_result(NVSDK_NGX_VULKAN_Shutdown1(hal_device.raw_device().handle())) + .expect("Failed to destroy DlssSdk"); } } }