use nvngx_sys::{
NVSDK_NGX_DLSS_Create_Params, NVSDK_NGX_DLSS_Feature_Flags, NVSDK_NGX_VK_DLSS_Eval_Params,
};
use super::*;
pub type DlssFeature = SuperSamplingFeature;
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub struct SuperSamplingOptimalSettings {
pub render_width: u32,
pub render_height: u32,
pub target_width: u32,
pub target_height: u32,
pub desired_quality_level: nvngx_sys::NVSDK_NGX_PerfQuality_Value,
pub dynamic_min_render_width: u32,
pub dynamic_max_render_width: u32,
pub dynamic_min_render_height: u32,
pub dynamic_max_render_height: u32,
}
impl SuperSamplingOptimalSettings {
pub fn get_optimal_settings(
parameters: &FeatureParameters,
target_width: u32,
target_height: u32,
desired_quality_level: nvngx_sys::NVSDK_NGX_PerfQuality_Value,
) -> Result<Self> {
let mut settings = Self {
render_width: 0,
render_height: 0,
target_width,
target_height,
desired_quality_level,
dynamic_min_render_width: 0,
dynamic_max_render_width: 0,
dynamic_min_render_height: 0,
dynamic_max_render_height: 0,
};
let mut sharpness = 0.0f32;
Result::from(unsafe {
nvngx_sys::HELPERS_NGX_DLSS_GET_OPTIMAL_SETTINGS(
parameters.0,
settings.target_width,
settings.target_height,
settings.desired_quality_level,
&mut settings.render_width as *mut _,
&mut settings.render_height as *mut _,
&mut settings.dynamic_max_render_width as *mut _,
&mut settings.dynamic_max_render_height as *mut _,
&mut settings.dynamic_min_render_width as *mut _,
&mut settings.dynamic_min_render_height as *mut _,
&mut sharpness as *mut _,
)
})?;
if settings.render_height == 0 || settings.render_width == 0 {
return Err(nvngx_sys::Error::Other(format!(
"The requested quality level isn't supported: {desired_quality_level:?}"
)));
}
Ok(settings)
}
}
#[repr(transparent)]
#[derive(Debug)]
pub struct SuperSamplingCreateParameters(pub(crate) nvngx_sys::NVSDK_NGX_DLSS_Create_Params);
impl SuperSamplingCreateParameters {
pub fn new(
render_width: u32,
render_height: u32,
target_width: u32,
target_height: u32,
quality_value: Option<NVSDK_NGX_PerfQuality_Value>,
flags: Option<NVSDK_NGX_DLSS_Feature_Flags>,
) -> Self {
let mut params: NVSDK_NGX_DLSS_Create_Params = unsafe { std::mem::zeroed() };
params.Feature.InWidth = render_width;
params.Feature.InHeight = render_height;
params.Feature.InTargetWidth = target_width;
params.Feature.InTargetHeight = target_height;
if let Some(quality_value) = quality_value {
params.Feature.InPerfQualityValue = quality_value;
}
params.InFeatureCreateFlags = flags.map(|f| f.0).unwrap_or(0);
Self(params)
}
}
impl From<SuperSamplingOptimalSettings> for SuperSamplingCreateParameters {
fn from(value: SuperSamplingOptimalSettings) -> Self {
Self::new(
value.render_width,
value.render_height,
value.target_width,
value.target_height,
Some(value.desired_quality_level),
Some(
NVSDK_NGX_DLSS_Feature_Flags::NVSDK_NGX_DLSS_Feature_Flags_AutoExposure
| NVSDK_NGX_DLSS_Feature_Flags::NVSDK_NGX_DLSS_Feature_Flags_MVLowRes,
),
)
}
}
#[derive(Debug)]
pub struct SuperSamplingEvaluationParameters {
input_color_resource: NVSDK_NGX_Resource_VK,
output_color_resource: NVSDK_NGX_Resource_VK,
depth_resource: NVSDK_NGX_Resource_VK,
motion_vectors_resource: NVSDK_NGX_Resource_VK,
parameters: NVSDK_NGX_VK_DLSS_Eval_Params,
}
impl Default for SuperSamplingEvaluationParameters {
fn default() -> Self {
unsafe { std::mem::zeroed() }
}
}
impl SuperSamplingEvaluationParameters {
pub fn new() -> Self {
Self::default()
}
pub fn set_color_input(&mut self, description: VkImageResourceDescription) {
self.input_color_resource = description.into();
self.parameters.Feature.pInColor = std::ptr::addr_of_mut!(self.input_color_resource);
}
pub fn set_color_output(&mut self, description: VkImageResourceDescription) {
self.output_color_resource = description.into();
self.parameters.Feature.pInOutput = std::ptr::addr_of_mut!(self.output_color_resource);
}
pub fn set_motions_vectors(
&mut self,
description: VkImageResourceDescription,
scale: Option<[f32; 2]>,
) {
const DEFAULT_SCALING: [f32; 2] = [1.0f32, 1.0f32];
self.motion_vectors_resource = description.into();
let scales = scale.unwrap_or(DEFAULT_SCALING);
self.parameters.pInMotionVectors = std::ptr::addr_of_mut!(self.motion_vectors_resource);
self.parameters.InMVScaleX = scales[0];
self.parameters.InMVScaleY = scales[1];
}
pub fn set_depth_buffer(&mut self, description: VkImageResourceDescription) {
self.depth_resource = description.into();
self.parameters.pInDepth = std::ptr::addr_of_mut!(self.depth_resource);
}
pub fn set_jitter_offsets(&mut self, x: f32, y: f32) {
self.parameters.InJitterOffsetX = x;
self.parameters.InJitterOffsetY = y;
}
pub fn set_reset(&mut self, should_reset: bool) {
self.parameters.InReset = if should_reset { 1 } else { 0 };
}
pub fn set_rendering_dimensions(
&mut self,
rendering_offset: [u32; 2],
rendering_size: [u32; 2],
) {
self.parameters.InColorSubrectBase = NVSDK_NGX_Coordinates {
X: rendering_offset[0],
Y: rendering_offset[1],
};
self.parameters.InDepthSubrectBase = NVSDK_NGX_Coordinates {
X: rendering_offset[0],
Y: rendering_offset[1],
};
self.parameters.InTranslucencySubrectBase = NVSDK_NGX_Coordinates {
X: rendering_offset[0],
Y: rendering_offset[1],
};
self.parameters.InMVSubrectBase = NVSDK_NGX_Coordinates {
X: rendering_offset[0],
Y: rendering_offset[1],
};
self.parameters.InRenderSubrectDimensions = NVSDK_NGX_Dimensions {
Width: rendering_size[0],
Height: rendering_size[1],
};
}
pub(crate) fn get_dlss_evaluation_parameters(
&mut self,
) -> *mut nvngx_sys::NVSDK_NGX_VK_DLSS_Eval_Params {
std::ptr::addr_of_mut!(self.parameters)
}
}
#[derive(Debug)]
pub struct SuperSamplingFeature {
feature: Feature,
parameters: SuperSamplingEvaluationParameters,
rendering_resolution: vk::Extent2D,
target_resolution: vk::Extent2D,
}
impl SuperSamplingFeature {
pub fn new(
feature: Feature,
rendering_resolution: vk::Extent2D,
target_resolution: vk::Extent2D,
) -> Result<Self> {
if !feature.is_super_sampling() {
return Err(nvngx_sys::Error::Other(
"Attempt to create a super sampling feature with another feature.".to_owned(),
));
}
Ok(Self {
feature,
parameters: SuperSamplingEvaluationParameters::new(),
rendering_resolution,
target_resolution,
})
}
pub fn get_inner(&self) -> &Feature {
&self.feature
}
pub fn get_inner_mut(&mut self) -> &mut Feature {
&mut self.feature
}
pub const fn get_rendering_resolution(&self) -> vk::Extent2D {
self.rendering_resolution
}
pub const fn get_target_resolution(&self) -> vk::Extent2D {
self.target_resolution
}
pub fn is_initialised(&self) -> bool {
self.feature
.get_parameters()
.is_super_sampling_initialised()
}
pub fn get_evaluation_parameters_mut(&mut self) -> &mut SuperSamplingEvaluationParameters {
&mut self.parameters
}
pub fn evaluate(&mut self, command_buffer: vk::CommandBuffer) -> Result {
Result::from(unsafe {
nvngx_sys::HELPERS_NGX_VULKAN_EVALUATE_DLSS_EXT(
command_buffer.as_pointer_mut(),
self.feature.handle.0,
self.feature.parameters.0,
self.parameters.get_dlss_evaluation_parameters(),
)
})
}
}