Skip to content

Commit c623399

Browse files
authored
Wgpu 26 (#2)
Upgrade to wgpu v26
1 parent 9e751fd commit c623399

File tree

8 files changed

+272
-240
lines changed

8 files changed

+272
-240
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ version = "1.0.0"
44
edition = "2024"
55

66
[dependencies]
7-
wgpu = { version = "25", default-features = false, features = ["vulkan"] }
7+
wgpu = { version = "26", default-features = false, features = ["vulkan"] }
88
ash = "0.38"
99
glam = "0.29"
1010
uuid = "1"

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ A wrapper for using [DLSS](https://www.nvidia.com/en-us/geforce/technologies/dls
77

88
| dlss_wgpu | dlss | wgpu |
99
|:---------:|:--------:|:----:|
10-
| v1.0 | v310.3.0 | v25 |
10+
| v1.0 | v310.3.0 | v26 |
1111

1212
## Downloading The DLSS SDK
1313
The DLSS SDK cannot be redistributed by this crate. You will need to download the SDK as follows:

src/context.rs

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
use crate::{DlssExposure, DlssRenderParameters, DlssSdk, nvsdk_ngx::*};
1+
use crate::{
2+
DlssExposure, DlssRenderParameters, DlssSdk, nvsdk_ngx::*,
3+
render_parameters::texture_to_ngx_resource,
4+
};
25
use glam::{UVec2, Vec2};
36
use std::{
47
iter,
@@ -122,7 +125,7 @@ impl DlssContext {
122125
exposure_scale,
123126
pre_exposure,
124127
} => (
125-
&mut exposure.as_resource(adapter) as *mut _,
128+
&mut texture_to_ngx_resource(exposure, adapter) as *mut _,
126129
exposure_scale.unwrap_or(1.0),
127130
pre_exposure.unwrap_or(0.0),
128131
),
@@ -131,12 +134,16 @@ impl DlssContext {
131134

132135
let mut dlss_eval_params = NVSDK_NGX_VK_DLSS_Eval_Params {
133136
Feature: NVSDK_NGX_VK_Feature_Eval_Params {
134-
pInColor: &mut render_parameters.color.as_resource(adapter),
135-
pInOutput: &mut render_parameters.dlss_output.as_resource(adapter),
137+
pInColor: &mut texture_to_ngx_resource(render_parameters.color, adapter) as *mut _,
138+
pInOutput: &mut texture_to_ngx_resource(render_parameters.dlss_output, adapter)
139+
as *mut _,
136140
InSharpness: 0.0,
137141
},
138-
pInDepth: &mut render_parameters.depth.as_resource(adapter),
139-
pInMotionVectors: &mut render_parameters.motion_vectors.as_resource(adapter),
142+
pInDepth: &mut texture_to_ngx_resource(render_parameters.depth, adapter) as *mut _,
143+
pInMotionVectors: &mut texture_to_ngx_resource(
144+
render_parameters.motion_vectors,
145+
adapter,
146+
) as *mut _,
140147
InJitterOffsetX: render_parameters.jitter_offset.x,
141148
InJitterOffsetY: render_parameters.jitter_offset.y,
142149
InRenderSubrectDimensions: NVSDK_NGX_Dimensions {
@@ -149,7 +156,7 @@ impl DlssContext {
149156
pInTransparencyMask: ptr::null_mut(),
150157
pInExposureTexture: exposure,
151158
pInBiasCurrentColorMask: match &render_parameters.bias {
152-
Some(bias) => &mut bias.as_resource(adapter),
159+
Some(bias) => &mut texture_to_ngx_resource(bias, adapter) as *mut _,
153160
None => ptr::null_mut(),
154161
},
155162
InColorSubrectBase: NVSDK_NGX_Coordinates { X: 0, Y: 0 },
@@ -225,16 +232,14 @@ impl DlssContext {
225232
impl Drop for DlssContext {
226233
fn drop(&mut self) {
227234
unsafe {
228-
self.device.as_hal::<Vulkan, _, _>(|device| {
229-
device
230-
.unwrap()
231-
.raw_device()
232-
.device_wait_idle()
233-
.expect("Failed to wait for idle device when destroying DlssContext");
234-
235-
check_ngx_result(NVSDK_NGX_VULKAN_ReleaseFeature(self.feature))
236-
.expect("Failed to destroy DlssContext feature");
237-
});
235+
let hal_device = self.device.as_hal::<Vulkan>().unwrap();
236+
hal_device
237+
.raw_device()
238+
.device_wait_idle()
239+
.expect("Failed to wait for idle device when destroying DlssContext");
240+
241+
check_ngx_result(NVSDK_NGX_VULKAN_ReleaseFeature(self.feature))
242+
.expect("Failed to destroy DlssContext feature");
238243
}
239244
}
240245
}

src/initialization.rs

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
use crate::{
2+
feature_info::with_feature_info,
3+
nvsdk_ngx::{
4+
DlssError, NVSDK_NGX_VULKAN_GetFeatureDeviceExtensionRequirements,
5+
NVSDK_NGX_VULKAN_GetFeatureInstanceExtensionRequirements, check_ngx_result,
6+
},
7+
};
8+
use ash::{Entry, vk::PhysicalDevice};
9+
use std::{ffi::CStr, ptr, slice};
10+
use uuid::Uuid;
11+
use wgpu::{
12+
Adapter, Device, DeviceDescriptor, Instance, InstanceDescriptor, Queue, RequestDeviceError,
13+
hal::{DeviceError, InstanceError, api::Vulkan},
14+
};
15+
16+
/// Creates a wgpu [`Instance`] with the extensions required for DLSS.
17+
///
18+
/// If the system does not support DLSS, it will set `dlss_supported` to false.
19+
pub fn create_instance(
20+
project_id: Uuid,
21+
instance_descriptor: &InstanceDescriptor,
22+
dlss_supported: &mut bool,
23+
) -> Result<Instance, InitializationError> {
24+
unsafe {
25+
let mut result = Ok(());
26+
let raw_instance = wgpu::hal::vulkan::Instance::init_with_callback(
27+
&wgpu::hal::InstanceDescriptor {
28+
name: "wgpu",
29+
flags: instance_descriptor.flags,
30+
memory_budget_thresholds: instance_descriptor.memory_budget_thresholds,
31+
backend_options: instance_descriptor.backend_options.clone(),
32+
},
33+
Some(Box::new(|args| {
34+
match required_instance_extensions(project_id, args.entry) {
35+
Ok((extensions, true)) => args.extensions.extend(extensions),
36+
Ok((_, false)) => *dlss_supported = false,
37+
Err(err) => result = Err(err),
38+
}
39+
})),
40+
)?;
41+
result?;
42+
43+
Ok(Instance::from_hal::<Vulkan>(raw_instance))
44+
}
45+
}
46+
47+
/// Creates a wgpu [`Device`] and [`Queue`] with the extensions required for DLSS.
48+
///
49+
/// If the system does not support DLSS, it will set `dlss_supported` to false.
50+
///
51+
/// The provided [`Adapter`] must be using the Vulkan backend.
52+
pub fn request_device(
53+
project_id: Uuid,
54+
adapter: &Adapter,
55+
device_descriptor: &DeviceDescriptor,
56+
dlss_supported: &mut bool,
57+
) -> Result<(Device, Queue), InitializationError> {
58+
unsafe {
59+
let raw_adapter = adapter
60+
.as_hal::<Vulkan>()
61+
.ok_or(InitializationError::UnsupportedBackend)?;
62+
let raw_instance = raw_adapter.shared_instance().raw_instance();
63+
let raw_physical_device = raw_adapter.raw_physical_device();
64+
65+
let mut result = Ok(());
66+
let open_device = raw_adapter.open_with_callback(
67+
device_descriptor.required_features,
68+
&device_descriptor.memory_hints,
69+
Some(Box::new(|args| {
70+
match required_device_extensions(
71+
project_id,
72+
&raw_adapter,
73+
raw_instance.handle(),
74+
raw_physical_device,
75+
) {
76+
Ok((extensions, true)) => args.extensions.extend(extensions),
77+
Ok((_, false)) => *dlss_supported = false,
78+
Err(err) => result = Err(err),
79+
}
80+
})),
81+
)?;
82+
result?;
83+
84+
Ok(adapter.create_device_from_hal::<Vulkan>(open_device, device_descriptor)?)
85+
}
86+
}
87+
88+
fn required_instance_extensions(
89+
project_id: Uuid,
90+
entry: &Entry,
91+
) -> Result<(impl Iterator<Item = &'static CStr>, bool), InitializationError> {
92+
with_feature_info(project_id, |feature_info| unsafe {
93+
// Get required extension names
94+
let mut required_extensions = ptr::null_mut();
95+
let mut required_extension_count = 0;
96+
check_ngx_result(NVSDK_NGX_VULKAN_GetFeatureInstanceExtensionRequirements(
97+
feature_info,
98+
&mut required_extension_count,
99+
&mut required_extensions,
100+
))?;
101+
let required_extensions =
102+
slice::from_raw_parts(required_extensions, required_extension_count as usize);
103+
let required_extensions = required_extensions
104+
.iter()
105+
.map(|extension| CStr::from_ptr(extension.extension_name.as_ptr()));
106+
107+
// Check that the required extensions are supported
108+
let supported_extensions = entry.enumerate_instance_extension_properties(None)?;
109+
let extensions_supported = required_extensions.clone().all(|required_extension| {
110+
supported_extensions
111+
.iter()
112+
.any(|extension| extension.extension_name_as_c_str() == Ok(required_extension))
113+
});
114+
115+
Ok((required_extensions, extensions_supported))
116+
})
117+
}
118+
119+
fn required_device_extensions(
120+
project_id: Uuid,
121+
raw_adapter: &wgpu::hal::vulkan::Adapter,
122+
raw_instance: ash::vk::Instance,
123+
raw_physical_device: PhysicalDevice,
124+
) -> Result<(impl Iterator<Item = &'static CStr>, bool), InitializationError> {
125+
with_feature_info(project_id, |feature_info| unsafe {
126+
// Get required extension names
127+
let mut required_extensions = ptr::null_mut();
128+
let mut required_extension_count = 0;
129+
check_ngx_result(NVSDK_NGX_VULKAN_GetFeatureDeviceExtensionRequirements(
130+
raw_instance,
131+
raw_physical_device,
132+
feature_info,
133+
&mut required_extension_count,
134+
&mut required_extensions,
135+
))?;
136+
let required_extensions =
137+
slice::from_raw_parts(required_extensions, required_extension_count as usize);
138+
let required_extensions = required_extensions
139+
.iter()
140+
.map(|extension| CStr::from_ptr(extension.extension_name.as_ptr()));
141+
142+
// Check that the required extensions are supported
143+
let extensions_supported = required_extensions.clone().all(|required_extension| {
144+
raw_adapter
145+
.physical_device_capabilities()
146+
.supports_extension(required_extension)
147+
});
148+
149+
Ok((required_extensions, extensions_supported))
150+
})
151+
}
152+
153+
/// Error returned by [`request_device`].
154+
#[derive(thiserror::Error, Debug)]
155+
pub enum InitializationError {
156+
#[error(transparent)]
157+
InstanceError(#[from] InstanceError),
158+
#[error(transparent)]
159+
RequestDeviceError(#[from] RequestDeviceError),
160+
#[error(transparent)]
161+
DeviceError(#[from] DeviceError),
162+
#[error(transparent)]
163+
VulkanError(#[from] ash::vk::Result),
164+
#[error(transparent)]
165+
DlssError(#[from] DlssError),
166+
#[error("Provided adapter is not using the Vulkan backend")]
167+
UnsupportedBackend,
168+
}

src/lib.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,15 @@
1414
//! use dlss_wgpu::{DlssSdk, DlssContext, DlssPerfQualityMode, DlssFeatureFlags, DlssRenderParameters};
1515
//!
1616
//! let project_id = Uuid::parse_str("...").unwrap();
17+
//! let mut dlss_supported = true;
1718
//!
18-
//! // Request a wgpu device and queue
19-
//! let ((device, queue), dlss_supported) = {
20-
//! match dlss_wgpu::request_device(project_id, &adapter, &device_descriptor) {
21-
//! Ok(x) => (x, true),
22-
//! // Fallback to standard device request if DLSS is not supported
23-
//! Err(_) => (adapter.request_device(&device_descriptor).await.unwrap(), false),
24-
//! }
25-
//! };
19+
//! // Initialize wgpu
20+
//! let instance = dlss_wgpu::create_instance(project_id, &instance_descriptor, &mut dlss_supported).unwrap();
21+
//! let adapter = instance.request_adapter(&adapter_options).await.unwrap();
22+
//! let (device, queue) = dlss_wgpu::request_device(project_id, &adapter, &device_descriptor, &mut dlss_supported).unwrap();
23+
//!
24+
//! // Check `dlss_supported`, if false don't create DLSS resources
25+
//! println!("DLSS supported: {dlss_supported}");
2626
//!
2727
//! // Create the SDK once per application
2828
//! let sdk = DlssSdk::new(project_id, device).expect("Failed to create DLSS SDK");
@@ -51,13 +51,13 @@
5151
5252
mod context;
5353
mod feature_info;
54+
mod initialization;
5455
mod nvsdk_ngx;
5556
mod render_parameters;
56-
mod request_device;
5757
mod sdk;
5858

5959
pub use context::DlssContext;
60+
pub use initialization::{InitializationError, create_instance, request_device};
6061
pub use nvsdk_ngx::{DlssError, DlssFeatureFlags, DlssPerfQualityMode};
61-
pub use render_parameters::{DlssExposure, DlssRenderParameters, DlssTexture};
62-
pub use request_device::{RequestDeviceError, request_device};
62+
pub use render_parameters::{DlssExposure, DlssRenderParameters};
6363
pub use sdk::DlssSdk;

0 commit comments

Comments
 (0)