use nvngx_sys::{
NVSDK_NGX_DLSSD_Create_Params, NVSDK_NGX_DLSS_Denoise_Mode, NVSDK_NGX_DLSS_Depth_Type,
NVSDK_NGX_DLSS_Roughness_Mode, NVSDK_NGX_VK_DLSSD_Eval_Params,
};
use super::*;
impl From<SuperSamplingOptimalSettings> for RayReconstructionCreateParameters {
fn from(value: SuperSamplingOptimalSettings) -> Self {
Self::new(
value.render_width,
value.render_height,
value.target_width,
value.target_height,
Some(value.desired_quality_level),
None,
None,
None,
)
}
}
#[repr(transparent)]
#[derive(Debug)]
pub struct RayReconstructionCreateParameters(pub(crate) nvngx_sys::NVSDK_NGX_DLSSD_Create_Params);
impl RayReconstructionCreateParameters {
pub fn new(
render_width: u32,
render_height: u32,
target_width: u32,
target_height: u32,
quality_value: Option<NVSDK_NGX_PerfQuality_Value>,
denoise_mode: Option<NVSDK_NGX_DLSS_Denoise_Mode>,
roughness_mode: Option<NVSDK_NGX_DLSS_Roughness_Mode>,
depth_type: Option<NVSDK_NGX_DLSS_Depth_Type>,
) -> Self {
let mut params: NVSDK_NGX_DLSSD_Create_Params = unsafe { std::mem::zeroed() };
params.InWidth = render_width;
params.InHeight = render_height;
params.InTargetWidth = target_width;
params.InTargetHeight = target_height;
if let Some(quality_value) = quality_value {
params.InPerfQualityValue = quality_value;
}
params.InDenoiseMode = denoise_mode
.unwrap_or(NVSDK_NGX_DLSS_Denoise_Mode::NVSDK_NGX_DLSS_Denoise_Mode_DLUnified);
params.InRoughnessMode = roughness_mode
.unwrap_or(NVSDK_NGX_DLSS_Roughness_Mode::NVSDK_NGX_DLSS_Roughness_Mode_Unpacked);
params.InUseHWDepth =
depth_type.unwrap_or(NVSDK_NGX_DLSS_Depth_Type::NVSDK_NGX_DLSS_Depth_Type_Linear);
Self(params)
}
}
#[derive(Debug)]
pub struct RayReconstructionEvaluationParameters {
pub(crate) input_color_resource: NVSDK_NGX_Resource_VK,
pub(crate) output_color_resource: NVSDK_NGX_Resource_VK,
pub(crate) depth_resource: NVSDK_NGX_Resource_VK,
pub(crate) motion_vectors_resource: NVSDK_NGX_Resource_VK,
pub(crate) parameters: NVSDK_NGX_VK_DLSSD_Eval_Params,
}
impl Default for RayReconstructionEvaluationParameters {
fn default() -> Self {
unsafe { std::mem::zeroed() }
}
}
impl RayReconstructionEvaluationParameters {
pub fn new() -> Self {
Self::default()
}
pub fn set_color_input(&mut self, description: VkImageResourceDescription) {
self.input_color_resource = description.into();
self.parameters.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.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_rr_evaluation_parameters(
&mut self,
) -> *mut nvngx_sys::NVSDK_NGX_VK_DLSSD_Eval_Params {
std::ptr::addr_of_mut!(self.parameters)
}
}
pub type RRFeature = RayReconstructionFeature;
#[derive(Debug)]
pub struct RayReconstructionFeature {
feature: Feature,
parameters: RayReconstructionEvaluationParameters,
rendering_resolution: vk::Extent2D,
target_resolution: vk::Extent2D,
}
impl RayReconstructionFeature {
pub fn new(
feature: Feature,
rendering_resolution: vk::Extent2D,
target_resolution: vk::Extent2D,
) -> Result<Self> {
if !feature.is_ray_reconstruction() {
return Err(nvngx_sys::Error::Other(
"Attempt to create a ray reconstruction feature with another feature.".to_owned(),
));
}
Ok(Self {
feature,
parameters: RayReconstructionEvaluationParameters::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 RayReconstructionEvaluationParameters {
&mut self.parameters
}
pub fn evaluate(&mut self, command_buffer: vk::CommandBuffer) -> Result {
Result::from(unsafe {
nvngx_sys::HELPERS_NGX_VULKAN_EVALUATE_DLSSD_EXT(
command_buffer.as_pointer_mut(),
self.feature.handle.0,
self.feature.parameters.0,
self.parameters.get_rr_evaluation_parameters(),
)
})
}
}