diff --git a/Cargo.toml b/Cargo.toml index 019ce0c6e9059..ec6fb0540be01 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -331,6 +331,9 @@ meshlet_processor = ["bevy_internal/meshlet_processor"] # Enable support for the ios_simulator by downgrading some rendering capabilities ios_simulator = ["bevy_internal/ios_simulator"] +# Enable support for FidelityFX Super Resolution +fsr = ["bevy_internal/fsr"] + [dependencies] bevy_dylib = { path = "crates/bevy_dylib", version = "0.14.0-dev", default-features = false, optional = true } bevy_internal = { path = "crates/bevy_internal", version = "0.14.0-dev", default-features = false } @@ -348,6 +351,10 @@ crossbeam-channel = "0.5.0" argh = "0.1.12" thiserror = "1.0" +[patch.crates-io] +wgpu = { git = "https://github.com/JMS55/wgpu", branch = "more_hal" } +naga = { git = "https://github.com/JMS55/wgpu", branch = "more_hal" } + [[example]] name = "hello_world" path = "examples/hello_world.rs" diff --git a/crates/bevy_color/Cargo.toml b/crates/bevy_color/Cargo.toml index 733a0ad3cceb7..c706e441d388b 100644 --- a/crates/bevy_color/Cargo.toml +++ b/crates/bevy_color/Cargo.toml @@ -16,7 +16,7 @@ bevy_reflect = { path = "../bevy_reflect", version = "0.14.0-dev", features = [ bytemuck = "1" serde = { version = "1.0", features = ["derive"], optional = true } thiserror = "1.0" -wgpu = { version = "0.19.3", default-features = false } +wgpu = { git = "https://github.com/JMS55/wgpu", branch = "more_hal", default-features = false } encase = { version = "0.7", default-features = false } [features] diff --git a/crates/bevy_core_pipeline/Cargo.toml b/crates/bevy_core_pipeline/Cargo.toml index e6846d0ec161d..c1409aeced343 100644 --- a/crates/bevy_core_pipeline/Cargo.toml +++ b/crates/bevy_core_pipeline/Cargo.toml @@ -18,6 +18,7 @@ trace = [] webgl = [] webgpu = [] tonemapping_luts = ["bevy_render/ktx2", "bevy_render/zstd"] +fsr = ["dep:fsr", "bevy_time"] [dependencies] # bevy @@ -29,10 +30,13 @@ bevy_derive = { path = "../bevy_derive", version = "0.14.0-dev" } bevy_ecs = { path = "../bevy_ecs", version = "0.14.0-dev" } bevy_reflect = { path = "../bevy_reflect", version = "0.14.0-dev" } bevy_render = { path = "../bevy_render", version = "0.14.0-dev" } +bevy_time = { path = "../bevy_time", version = "0.14.0-dev", optional = true } bevy_transform = { path = "../bevy_transform", version = "0.14.0-dev" } bevy_math = { path = "../bevy_math", version = "0.14.0-dev" } bevy_utils = { path = "../bevy_utils", version = "0.14.0-dev" } +fsr = { path = "../fsr", version = "2.2", optional = true } + serde = { version = "1", features = ["derive"] } bitflags = "2.3" radsort = "0.1" diff --git a/crates/bevy_core_pipeline/src/fsr/fsr_manager.rs b/crates/bevy_core_pipeline/src/fsr/fsr_manager.rs new file mode 100644 index 0000000000000..10938b179e55b --- /dev/null +++ b/crates/bevy_core_pipeline/src/fsr/fsr_manager.rs @@ -0,0 +1,266 @@ +use super::{ + util::{call_hal, ffx_check_result, ffx_get_texture, ffx_null_texture}, + FsrQualityMode, +}; +use bevy_core::FrameCount; +use bevy_ecs::system::Resource; +use bevy_math::UVec2; +use bevy_render::{ + camera::{Exposure, PerspectiveProjection, TemporalJitter}, + render_resource::{hal::vulkan::VulkanApi, CommandBuffer, CommandEncoderDescriptor}, + renderer::RenderDevice, + texture::CachedTexture, +}; +use bevy_time::Time; +use fsr::*; +use std::mem::MaybeUninit; + +#[derive(Resource)] +pub struct FsrManager { + interface: FfxFsr2Interface, + context: Option, + _scratch_buffer: Box<[u8]>, + render_device: RenderDevice, + + current_context_max_input_resolution: UVec2, + current_context_max_upscaled_resolution: UVec2, + current_context_hdr: bool, +} + +impl FsrManager { + pub fn new(render_device: RenderDevice) -> Option { + let r = render_device.clone(); + call_hal(&render_device, |device| { + let physical_device = device.raw_physical_device(); + let get_device_proc_addr = device + .shared_instance() + .raw_instance() + .fp_v1_0() + .get_device_proc_addr; + + let scratch_buffer_size = unsafe { ffxFsr2GetScratchMemorySizeVK(physical_device) }; + let mut _scratch_buffer = vec![0_u8; scratch_buffer_size].into_boxed_slice(); + + let mut interface = MaybeUninit::::uninit(); + ffx_check_result(unsafe { + ffxFsr2GetInterfaceVK( + interface.as_mut_ptr(), + _scratch_buffer.as_mut_ptr() as *mut _, + scratch_buffer_size, + physical_device, + get_device_proc_addr, + ) + })?; + let interface = unsafe { interface.assume_init() }; + + Some(Self { + interface, + context: None, + _scratch_buffer, + render_device: r, + current_context_max_input_resolution: UVec2::ZERO, + current_context_max_upscaled_resolution: UVec2::ZERO, + current_context_hdr: false, + }) + }) + } + + pub fn recreate_context_if_needed( + &mut self, + max_input_resolution: UVec2, + max_upscaled_resolution: UVec2, + hdr: bool, + ) { + if max_input_resolution.x > self.current_context_max_input_resolution.x + || max_input_resolution.y > self.current_context_max_input_resolution.y + || max_upscaled_resolution.x > self.current_context_max_upscaled_resolution.x + || max_upscaled_resolution.y > self.current_context_max_upscaled_resolution.y + || hdr != self.current_context_hdr + { + self.current_context_max_input_resolution = max_input_resolution; + self.current_context_max_upscaled_resolution = max_upscaled_resolution; + self.current_context_hdr = hdr; + } else { + return; + } + + self.destroy_context(); + + call_hal(&self.render_device, |device| { + let mut flags = FfxFsr2InitializationFlagBits_FFX_FSR2_ENABLE_DEPTH_INFINITE + | FfxFsr2InitializationFlagBits_FFX_FSR2_ENABLE_DEPTH_INVERTED; + if hdr { + flags |= FfxFsr2InitializationFlagBits_FFX_FSR2_ENABLE_HIGH_DYNAMIC_RANGE; + } + + let context_description = FfxFsr2ContextDescription { + flags, + maxRenderSize: FfxDimensions2D { + width: max_input_resolution.x, + height: max_input_resolution.y, + }, + displaySize: FfxDimensions2D { + width: max_upscaled_resolution.x, + height: max_upscaled_resolution.y, + }, + callbacks: self.interface, + device: unsafe { ffxGetDeviceVK(device.raw_device().handle()) }, + }; + + let mut context = MaybeUninit::::uninit(); + ffx_check_result(unsafe { + ffxFsr2ContextCreate(context.as_mut_ptr(), &context_description) + })?; + self.context = Some(unsafe { context.assume_init() }); + + Some(()) + }) + .expect("Failed to create FSR context"); + } + + pub fn get_input_resolution(upscaled_resolution: UVec2, quality_mode: FsrQualityMode) -> UVec2 { + let quality_mode = match quality_mode { + FsrQualityMode::Native => todo!(), + FsrQualityMode::Quality => FfxFsr2QualityMode_FFX_FSR2_QUALITY_MODE_QUALITY, + FsrQualityMode::Balanced => FfxFsr2QualityMode_FFX_FSR2_QUALITY_MODE_BALANCED, + FsrQualityMode::Peformance => FfxFsr2QualityMode_FFX_FSR2_QUALITY_MODE_PERFORMANCE, + FsrQualityMode::UltraPerformance => { + FfxFsr2QualityMode_FFX_FSR2_QUALITY_MODE_ULTRA_PERFORMANCE + } + }; + + let mut input_resolution = UVec2::default(); + ffx_check_result(unsafe { + ffxFsr2GetRenderResolutionFromQualityMode( + &mut input_resolution.x, + &mut input_resolution.y, + upscaled_resolution.x, + upscaled_resolution.y, + quality_mode, + ) + }) + .expect("Failed to determine input resolution from FsrQualityMode"); + input_resolution + } + + pub fn get_temporal_jitter( + input_resolution: UVec2, + upscaled_resolution: UVec2, + frame_count: FrameCount, + ) -> TemporalJitter { + let phase_count = unsafe { + ffxFsr2GetJitterPhaseCount(input_resolution.x as i32, upscaled_resolution.x as i32) + }; + + let mut temporal_jitter = TemporalJitter::default(); + ffx_check_result(unsafe { + ffxFsr2GetJitterOffset( + &mut temporal_jitter.offset.x, + &mut temporal_jitter.offset.y, + frame_count.0 as i32, + phase_count, + ) + }) + .expect("Failed to get FSR temporal jitter"); + + temporal_jitter + } + + pub fn get_mip_bias(quality_mode: FsrQualityMode) -> f32 { + match quality_mode { + FsrQualityMode::Native => todo!(), + FsrQualityMode::Quality => -1.58, + FsrQualityMode::Balanced => -1.76, + FsrQualityMode::Peformance => -2.0, + FsrQualityMode::UltraPerformance => -2.58, + } + } + + pub fn record_command_buffer(&mut self, resources: FsrCameraResources) -> CommandBuffer { + let context = self.context.as_mut().expect("FSR context does not exist"); + + let mut command_encoder = + self.render_device + .create_command_encoder(&CommandEncoderDescriptor { + label: Some("fsr_command_encoder"), + }); + + // TODO: Dispatch dummy compute shader with read_write on all input textures to ensure barriers + + unsafe { + command_encoder.as_hal_mut::(|command_encoder| { + let dispatch_description = FfxFsr2DispatchDescription { + commandList: ffxGetCommandListVK(command_encoder.unwrap().raw_handle()), + color: ffx_get_texture(&resources.frame_input, context), + depth: ffx_get_texture(&resources.depth, context), + motionVectors: ffx_get_texture(&resources.motion_vectors, context), + exposure: ffx_null_texture(context), + reactive: ffx_null_texture(context), + transparencyAndComposition: ffx_null_texture(context), + output: ffx_get_texture(&resources.upscaled_output, context), + jitterOffset: FfxFloatCoords2D { + x: resources.temporal_jitter.offset.x, + y: resources.temporal_jitter.offset.y, + }, + motionVectorScale: FfxFloatCoords2D { + x: resources.frame_input.texture.width() as f32, + y: resources.frame_input.texture.height() as f32, + }, + renderSize: FfxDimensions2D { + width: resources.frame_input.texture.width(), + height: resources.frame_input.texture.height(), + }, + enableSharpening: false, + sharpness: 0.0, + frameTimeDelta: resources.time.delta_seconds() * 1000.0, + preExposure: resources.exposure.exposure(), + reset: resources.reset, + cameraNear: resources.camera_projection.near, + cameraFar: resources.camera_projection.far, + cameraFovAngleVertical: resources.camera_projection.fov, + }; + + ffx_check_result(ffxFsr2ContextDispatch(context, &dispatch_description)) + }) + } + .flatten() + .expect("Failed to dispatch FSR"); + + // TODO: Dispatch dummy compute shader with read_write on all input textures to ensure barriers + + command_encoder.finish() + } + + fn destroy_context(&mut self) { + if let Some(mut context) = self.context.take() { + call_hal(&self.render_device, |device| { + unsafe { device.raw_device().device_wait_idle() } + .expect("Failed to wait for GPU to be idle"); + + ffx_check_result(unsafe { ffxFsr2ContextDestroy(&mut context) }) + }) + .expect("Failed to destroy FSR context"); + } + } +} + +impl Drop for FsrManager { + fn drop(&mut self) { + self.destroy_context(); + } +} + +unsafe impl Send for FsrManager {} +unsafe impl Sync for FsrManager {} + +pub struct FsrCameraResources { + pub frame_input: CachedTexture, + pub depth: CachedTexture, + pub motion_vectors: CachedTexture, + pub upscaled_output: CachedTexture, + pub temporal_jitter: TemporalJitter, + pub exposure: Exposure, + pub camera_projection: PerspectiveProjection, + pub time: Time, + pub reset: bool, +} diff --git a/crates/bevy_core_pipeline/src/fsr/mod.rs b/crates/bevy_core_pipeline/src/fsr/mod.rs new file mode 100644 index 0000000000000..fad486978b651 --- /dev/null +++ b/crates/bevy_core_pipeline/src/fsr/mod.rs @@ -0,0 +1,140 @@ +mod fsr_manager; +mod settings; +mod util; + +pub use self::settings::{FsrBundle, FsrQualityMode, FsrSettings}; + +use self::fsr_manager::FsrManager; +use crate::{ + core_3d::{ + graph::{Core3d, Node3d}, + Camera3d, + }, + prepass::{DepthPrepass, MotionVectorPrepass, ViewPrepassTextures}, +}; +use bevy_app::{App, Plugin}; +use bevy_core::FrameCount; +use bevy_ecs::{ + entity::Entity, + query::{QueryItem, With}, + schedule::IntoSystemConfigs, + system::{Commands, Query, Res, ResMut}, + world::World, +}; +use bevy_math::Vec4Swizzles; +use bevy_render::{ + camera::{Camera, MipBias, Projection, TemporalJitter}, + render_graph::{NodeRunError, RenderGraphApp, RenderGraphContext, ViewNode, ViewNodeRunner}, + renderer::{RenderContext, RenderDevice}, + view::{ExtractedView, Msaa, ViewTarget}, + ExtractSchedule, MainWorld, Render, RenderApp, RenderSet, +}; + +pub struct FsrPlugin; + +impl Plugin for FsrPlugin { + fn build(&self, app: &mut App) { + app.insert_resource(Msaa::Off) + .register_type::() + .register_type::(); + } + + fn finish(&self, app: &mut App) { + let Some(render_device) = app + .world + .get_resource::() + .map(RenderDevice::clone) + else { + return; + }; + + app.sub_app_mut(RenderApp) + .insert_resource( + FsrManager::new(render_device).expect("Failed to initialize FsrPlugin"), + ) + .add_systems(ExtractSchedule, extract_fsr_settings) + .add_systems(Render, prepare_fsr.in_set(RenderSet::Prepare)) + .add_render_graph_node::>(Core3d, Node3d::Taa) + .add_render_graph_edges( + Core3d, + ( + Node3d::EndMainPass, + Node3d::Taa, + Node3d::Bloom, + Node3d::Tonemapping, + ), + ); + } +} + +fn extract_fsr_settings(mut commands: Commands, mut main_world: ResMut) { + let mut cameras_3d = main_world + .query_filtered::<(Entity, &Camera, &Projection, &mut FsrSettings), ( + With, + With, + With, + With, + )>(); + + for (entity, camera, camera_projection, mut fsr_settings) in + cameras_3d.iter_mut(&mut main_world) + { + if camera.is_active { + if let Projection::Perspective(perspective_projection) = camera_projection { + commands + .get_or_spawn(entity) + .insert((fsr_settings.clone(), perspective_projection.clone())); + fsr_settings.reset = false; + } + } + } +} + +fn prepare_fsr( + mut query: Query<( + &FsrSettings, + &ExtractedView, + &mut TemporalJitter, + &mut MipBias, + )>, + mut fsr_manager: ResMut, + frame_count: Res, +) { + for (fsr_settings, view, mut temporal_jitter, mut mip_bias) in &mut query { + let upscaled_resolution = view.viewport.zw(); + let input_resolution = + FsrManager::get_input_resolution(upscaled_resolution, fsr_settings.quality_mode); + + fsr_manager.recreate_context_if_needed(input_resolution, upscaled_resolution, view.hdr); + + // TODO: Set internal render resolution and upscale resolution + + *temporal_jitter = + FsrManager::get_temporal_jitter(input_resolution, upscaled_resolution, *frame_count); + + mip_bias.0 = FsrManager::get_mip_bias(fsr_settings.quality_mode); + } +} + +#[derive(Default)] +pub struct FsrNode; + +impl ViewNode for FsrNode { + type ViewQuery = ( + &'static FsrSettings, + &'static ViewTarget, + &'static ViewPrepassTextures, + ); + + fn run( + &self, + _graph: &mut RenderGraphContext, + _render_context: &mut RenderContext, + (_fsr_settings, _view_target, _prepass_textures): QueryItem, + _world: &World, + ) -> Result<(), NodeRunError> { + // TODO + + Ok(()) + } +} diff --git a/crates/bevy_core_pipeline/src/fsr/settings.rs b/crates/bevy_core_pipeline/src/fsr/settings.rs new file mode 100644 index 0000000000000..353130e73e80a --- /dev/null +++ b/crates/bevy_core_pipeline/src/fsr/settings.rs @@ -0,0 +1,43 @@ +use crate::{DepthPrepass, MotionVectorPrepass}; +use bevy_ecs::{bundle::Bundle, component::Component, reflect::ReflectComponent}; +use bevy_reflect::Reflect; +use bevy_render::camera::{MipBias, TemporalJitter}; + +#[derive(Bundle, Default)] +pub struct FsrBundle { + pub settings: FsrSettings, + pub jitter: TemporalJitter, + pub mip_bias: MipBias, + pub depth_prepass: DepthPrepass, + pub motion_vector_prepass: MotionVectorPrepass, +} + +#[derive(Component, Reflect, Clone)] +#[reflect(Component)] +pub struct FsrSettings { + pub quality_mode: FsrQualityMode, + pub reset: bool, +} + +impl Default for FsrSettings { + fn default() -> Self { + Self { + quality_mode: FsrQualityMode::Balanced, + reset: false, + } + } +} + +#[derive(Reflect, Clone, Copy, Debug)] +pub enum FsrQualityMode { + /// No upscaling, just antialiasing. + Native, + /// Upscale by 1.5x. + Quality, + /// Upscale by 1.7x. + Balanced, + /// Upscale by 2.0x. + Peformance, + /// Upscale by 3.0x. + UltraPerformance, +} diff --git a/crates/bevy_core_pipeline/src/fsr/util.rs b/crates/bevy_core_pipeline/src/fsr/util.rs new file mode 100644 index 0000000000000..10f275603f494 --- /dev/null +++ b/crates/bevy_core_pipeline/src/fsr/util.rs @@ -0,0 +1,75 @@ +use bevy_render::{ + render_resource::{ + hal::vulkan::{Device, VulkanApi}, + TextureFormat, + }, + renderer::RenderDevice, + texture::CachedTexture, +}; +use fsr::{ + ffxGetTextureResourceVK, FfxErrorCode, FfxFsr2Context, FfxResource, + FfxResourceStates_FFX_RESOURCE_STATE_COMPUTE_READ, VkFormat, VkImage, VkImageView, FFX_OK, +}; +use std::ptr; + +pub fn call_hal( + render_device: &RenderDevice, + f: impl FnOnce(&Device) -> Option, +) -> Option { + let wgpu_device = render_device.wgpu_device(); + unsafe { + wgpu_device.as_hal::(|device| { + (f)(device.expect("FsrPlugin can only be used on the Vulkan graphics backend")) + }) + } + .flatten() +} + +pub fn ffx_get_texture(texture: &CachedTexture, context: &mut FfxFsr2Context) -> FfxResource { + unsafe { + ffxGetTextureResourceVK( + context, + texture + .texture + .as_hal::(|t| t.unwrap().raw_handle()), + texture + .default_view + .as_hal::(|t| t.unwrap().raw_handle()), + texture.texture.width(), + texture.texture.height(), + match texture.texture.format() { + TextureFormat::Rgba8UnormSrgb => VkFormat::R8G8B8A8_SRGB, + TextureFormat::Rgba16Float => VkFormat::R16G16B16A16_SFLOAT, + TextureFormat::Depth32Float => VkFormat::D32_SFLOAT, + TextureFormat::Rg16Float => VkFormat::R16G16_SFLOAT, + _ => unreachable!("Invalid FSR texture format"), + }, + ptr::null_mut(), + FfxResourceStates_FFX_RESOURCE_STATE_COMPUTE_READ, + ) + } +} + +pub fn ffx_null_texture(context: &mut FfxFsr2Context) -> FfxResource { + unsafe { + ffxGetTextureResourceVK( + context, + VkImage::null(), + VkImageView::null(), + 1, + 1, + VkFormat::UNDEFINED, + ptr::null_mut(), + FfxResourceStates_FFX_RESOURCE_STATE_COMPUTE_READ, + ) + } +} + +// TODO: Proper Result type +pub(crate) fn ffx_check_result(result: FfxErrorCode) -> Option<()> { + if result == FFX_OK { + Some(()) + } else { + None + } +} diff --git a/crates/bevy_core_pipeline/src/lib.rs b/crates/bevy_core_pipeline/src/lib.rs index 9bb44c4e33116..7d1eb23447813 100644 --- a/crates/bevy_core_pipeline/src/lib.rs +++ b/crates/bevy_core_pipeline/src/lib.rs @@ -1,6 +1,6 @@ // FIXME(3492): remove once docs are ready #![allow(missing_docs)] -#![forbid(unsafe_code)] +#![allow(unsafe_code)] #![cfg_attr(docsrs, feature(doc_auto_cfg))] #![doc( html_logo_url = "https://bevyengine.org/assets/icon.png", @@ -13,6 +13,8 @@ pub mod contrast_adaptive_sharpening; pub mod core_2d; pub mod core_3d; pub mod deferred; +#[cfg(feature = "fsr")] +pub mod fsr; pub mod fullscreen_vertex_shader; pub mod fxaa; pub mod msaa_writeback; diff --git a/crates/bevy_internal/Cargo.toml b/crates/bevy_internal/Cargo.toml index 25476de016e50..94058b72bcb20 100644 --- a/crates/bevy_internal/Cargo.toml +++ b/crates/bevy_internal/Cargo.toml @@ -171,6 +171,9 @@ bevy_dev_tools = ["dep:bevy_dev_tools"] # Enable support for the ios_simulator by downgrading some rendering capabilities ios_simulator = ["bevy_pbr?/ios_simulator", "bevy_render?/ios_simulator"] +# Enable support for FidelityFX Super Resolution +fsr = ["bevy_core_pipeline?/fsr"] + [dependencies] # bevy bevy_a11y = { path = "../bevy_a11y", version = "0.14.0-dev" } diff --git a/crates/bevy_render/Cargo.toml b/crates/bevy_render/Cargo.toml index cbc25b9146b56..95366a46e42a8 100644 --- a/crates/bevy_render/Cargo.toml +++ b/crates/bevy_render/Cargo.toml @@ -69,7 +69,7 @@ codespan-reporting = "0.11.0" # It is enabled for now to avoid having to do a significant overhaul of the renderer just for wasm. # When the 'atomics' feature is enabled `fragile-send-sync-non-atomic` does nothing # and Bevy instead wraps `wgpu` types to verify they are not used off their origin thread. -wgpu = { version = "0.19.3", default-features = false, features = [ +wgpu = { git = "https://github.com/JMS55/wgpu", branch = "more_hal", default-features = false, features = [ "wgsl", "dx12", "metal", diff --git a/crates/bevy_render/src/render_resource/mod.rs b/crates/bevy_render/src/render_resource/mod.rs index 388bf0fb08ea3..33b00885cfba2 100644 --- a/crates/bevy_render/src/render_resource/mod.rs +++ b/crates/bevy_render/src/render_resource/mod.rs @@ -37,23 +37,29 @@ pub use wgpu::{ BindGroupLayoutDescriptor, BindGroupLayoutEntry, BindingResource, BindingType, BlendComponent, BlendFactor, BlendOperation, BlendState, BufferAddress, BufferAsyncError, BufferBinding, BufferBindingType, BufferDescriptor, BufferSize, BufferUsages, ColorTargetState, ColorWrites, - CommandEncoder, CommandEncoderDescriptor, CompareFunction, ComputePass, ComputePassDescriptor, - ComputePipelineDescriptor as RawComputePipelineDescriptor, DepthBiasState, DepthStencilState, - Extent3d, Face, Features as WgpuFeatures, FilterMode, FragmentState as RawFragmentState, - FrontFace, ImageCopyBuffer, ImageCopyBufferBase, ImageCopyTexture, ImageCopyTextureBase, - ImageDataLayout, ImageSubresourceRange, IndexFormat, Limits as WgpuLimits, LoadOp, Maintain, - MapMode, MultisampleState, Operations, Origin3d, PipelineLayout, PipelineLayoutDescriptor, - PolygonMode, PrimitiveState, PrimitiveTopology, PushConstantRange, RenderPassColorAttachment, - RenderPassDepthStencilAttachment, RenderPassDescriptor, - RenderPipelineDescriptor as RawRenderPipelineDescriptor, SamplerBindingType, SamplerDescriptor, - ShaderModule, ShaderModuleDescriptor, ShaderSource, ShaderStages, StencilFaceState, - StencilOperation, StencilState, StorageTextureAccess, StoreOp, TextureAspect, - TextureDescriptor, TextureDimension, TextureFormat, TextureSampleType, TextureUsages, - TextureViewDescriptor, TextureViewDimension, VertexAttribute, + CommandBuffer, CommandEncoder, CommandEncoderDescriptor, CompareFunction, ComputePass, + ComputePassDescriptor, ComputePipelineDescriptor as RawComputePipelineDescriptor, + DepthBiasState, DepthStencilState, Extent3d, Face, Features as WgpuFeatures, FilterMode, + FragmentState as RawFragmentState, FrontFace, ImageCopyBuffer, ImageCopyBufferBase, + ImageCopyTexture, ImageCopyTextureBase, ImageDataLayout, ImageSubresourceRange, IndexFormat, + Limits as WgpuLimits, LoadOp, Maintain, MapMode, MultisampleState, Operations, Origin3d, + PipelineLayout, PipelineLayoutDescriptor, PolygonMode, PrimitiveState, PrimitiveTopology, + PushConstantRange, RenderPassColorAttachment, RenderPassDepthStencilAttachment, + RenderPassDescriptor, RenderPipelineDescriptor as RawRenderPipelineDescriptor, + SamplerBindingType, SamplerDescriptor, ShaderModule, ShaderModuleDescriptor, ShaderSource, + ShaderStages, StencilFaceState, StencilOperation, StencilState, StorageTextureAccess, StoreOp, + TextureAspect, TextureDescriptor, TextureDimension, TextureFormat, TextureSampleType, + TextureUsages, TextureViewDescriptor, TextureViewDimension, VertexAttribute, VertexBufferLayout as RawVertexBufferLayout, VertexFormat, VertexState as RawVertexState, VertexStepMode, COPY_BUFFER_ALIGNMENT, }; +pub mod hal { + pub mod vulkan { + pub use wgpu::hal::{api::Vulkan as VulkanApi, vulkan::Device}; + } +} + pub mod encase { pub use bevy_encase_derive::ShaderType; pub use encase::*; diff --git a/crates/bevy_render/src/renderer/mod.rs b/crates/bevy_render/src/renderer/mod.rs index 3f1620ae876fe..0473ca3ec2fd2 100644 --- a/crates/bevy_render/src/renderer/mod.rs +++ b/crates/bevy_render/src/renderer/mod.rs @@ -317,6 +317,12 @@ pub async fn initialize_renderer( max_non_sampler_bindings: limits .max_non_sampler_bindings .min(constrained_limits.max_non_sampler_bindings), + max_color_attachment_bytes_per_sample: limits + .max_color_attachment_bytes_per_sample + .min(constrained_limits.max_color_attachment_bytes_per_sample), + max_color_attachments: limits + .max_color_attachments + .min(constrained_limits.max_color_attachments), }; } diff --git a/crates/fsr/Cargo.toml b/crates/fsr/Cargo.toml new file mode 100644 index 0000000000000..b473d69499b5f --- /dev/null +++ b/crates/fsr/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "fsr" +version = "2.2.1" +edition = "2021" +authors = [ + "Bevy Contributors ", + "Carter Anderson ", +] +description = "FidelityFX Super Resolution" + +[dependencies] +ash = "0.37" diff --git a/crates/fsr/LICENSE.txt b/crates/fsr/LICENSE.txt new file mode 100644 index 0000000000000..c066ae106362b --- /dev/null +++ b/crates/fsr/LICENSE.txt @@ -0,0 +1,21 @@ +FidelityFX Super Resolution 2.2 +================================= +Copyright (c) 2022-2023 Advanced Micro Devices, Inc. All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/crates/fsr/build.rs b/crates/fsr/build.rs new file mode 100644 index 0000000000000..10a339caac7cb --- /dev/null +++ b/crates/fsr/build.rs @@ -0,0 +1,15 @@ +fn main() { + let search_path = std::env::current_dir().unwrap().join("fsr").join("lib"); + println!("cargo:rustc-link-search=native={}", search_path.display()); + + #[cfg(debug_assertions)] + { + println!("cargo:rustc-link-lib=static=ffx_fsr2_api_x64d"); + println!("cargo:rustc-link-lib=static=ffx_fsr2_api_vk_x64d"); + } + #[cfg(not(debug_assertions))] + { + println!("cargo:rustc-link-lib=static=ffx_fsr2_api_x64"); + println!("cargo:rustc-link-lib=static=ffx_fsr2_api_vk_x64"); + } +} diff --git a/crates/fsr/fsr/include/ffx_assert.h b/crates/fsr/fsr/include/ffx_assert.h new file mode 100644 index 0000000000000..f96b1570e5ab9 --- /dev/null +++ b/crates/fsr/fsr/include/ffx_assert.h @@ -0,0 +1,132 @@ +// This file is part of the FidelityFX SDK. +// +// Copyright (c) 2022 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#pragma once + +#include "ffx_types.h" +#include "ffx_util.h" + +#ifdef __cplusplus +extern "C" { +#endif // #ifdef __cplusplus + +#ifdef _DEBUG +#ifdef _WIN32 + +#ifdef DISABLE_FFX_DEBUG_BREAK +#define FFX_DEBUG_BREAK \ + { \ + } +#else +/// Macro to force the debugger to break at this point in the code. +#define FFX_DEBUG_BREAK __debugbreak(); +#endif +#else +#define FFX_DEBUG_BREAK \ + { \ + } +#endif +#else +// don't allow debug break in release builds. +#define FFX_DEBUG_BREAK +#endif + +/// A typedef for the callback function for assert printing. +/// +/// This can be used to re-route printing of assert messages from the FFX backend +/// to another destination. For example instead of the default behaviour of printing +/// the assert messages to the debugger's TTY the message can be re-routed to a +/// MessageBox in a GUI application. +/// +/// @param [in] message The message generated by the assert. +/// +typedef void (*FfxAssertCallback)(const char* message); + +/// Function to report an assert. +/// +/// @param [in] file The name of the file as a string. +/// @param [in] line The index of the line in the file. +/// @param [in] condition The boolean condition that was tested. +/// @param [in] msg The optional message to print. +/// +/// @returns +/// Always returns true. +/// +FFX_API bool ffxAssertReport(const char* file, int32_t line, const char* condition, const char* msg); + +/// Provides the ability to set a callback for assert messages. +/// +/// @param [in] callback The callback function that will receive assert messages. +/// +FFX_API void ffxAssertSetPrintingCallback(FfxAssertCallback callback); + +#ifdef _DEBUG +/// Standard assert macro. +#define FFX_ASSERT(condition) \ + do \ + { \ + if (!(condition) && ffxAssertReport(__FILE__, __LINE__, #condition, NULL)) \ + FFX_DEBUG_BREAK \ + } while (0) + +/// Assert macro with message. +#define FFX_ASSERT_MESSAGE(condition, msg) \ + do \ + { \ + if (!(condition) && ffxAssertReport(__FILE__, __LINE__, #condition, msg)) \ + FFX_DEBUG_BREAK \ + } while (0) + +/// Assert macro that always fails. +#define FFX_ASSERT_FAIL(message) \ + do \ + { \ + ffxAssertReport(__FILE__, __LINE__, NULL, message); \ + FFX_DEBUG_BREAK \ + } while (0) +#else +// asserts disabled +#define FFX_ASSERT(condition) \ + do \ + { \ + FFX_UNUSED(condition); \ + } while (0) + +#define FFX_ASSERT_MESSAGE(condition, message) \ + do \ + { \ + FFX_UNUSED(condition); \ + FFX_UNUSED(message); \ + } while (0) + +#define FFX_ASSERT_FAIL(message) \ + do \ + { \ + FFX_UNUSED(message); \ + } while (0) +#endif // #if _DEBUG + +/// Simple static assert. +#define FFX_STATIC_ASSERT(condition) static_assert(condition, #condition) + +#ifdef __cplusplus +} +#endif // #ifdef __cplusplus diff --git a/crates/fsr/fsr/include/ffx_error.h b/crates/fsr/fsr/include/ffx_error.h new file mode 100644 index 0000000000000..39d885e7f6e4d --- /dev/null +++ b/crates/fsr/fsr/include/ffx_error.h @@ -0,0 +1,59 @@ +// This file is part of the FidelityFX SDK. +// +// Copyright (c) 2022 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#pragma once + +#include "ffx_types.h" + +/// Typedef for error codes returned from functions in the FidelityFX SDK. +typedef int32_t FfxErrorCode; + +static const FfxErrorCode FFX_OK = 0; ///< The operation completed successfully. +static const FfxErrorCode FFX_ERROR_INVALID_POINTER = 0x80000000; ///< The operation failed due to an invalid pointer. +static const FfxErrorCode FFX_ERROR_INVALID_ALIGNMENT = 0x80000001; ///< The operation failed due to an invalid alignment. +static const FfxErrorCode FFX_ERROR_INVALID_SIZE = 0x80000002; ///< The operation failed due to an invalid size. +static const FfxErrorCode FFX_EOF = 0x80000003; ///< The end of the file was encountered. +static const FfxErrorCode FFX_ERROR_INVALID_PATH = 0x80000004; ///< The operation failed because the specified path was invalid. +static const FfxErrorCode FFX_ERROR_EOF = 0x80000005; ///< The operation failed because end of file was reached. +static const FfxErrorCode FFX_ERROR_MALFORMED_DATA = 0x80000006; ///< The operation failed because of some malformed data. +static const FfxErrorCode FFX_ERROR_OUT_OF_MEMORY = 0x80000007; ///< The operation failed because it ran out memory. +static const FfxErrorCode FFX_ERROR_INCOMPLETE_INTERFACE = 0x80000008; ///< The operation failed because the interface was not fully configured. +static const FfxErrorCode FFX_ERROR_INVALID_ENUM = 0x80000009; ///< The operation failed because of an invalid enumeration value. +static const FfxErrorCode FFX_ERROR_INVALID_ARGUMENT = 0x8000000a; ///< The operation failed because an argument was invalid. +static const FfxErrorCode FFX_ERROR_OUT_OF_RANGE = 0x8000000b; ///< The operation failed because a value was out of range. +static const FfxErrorCode FFX_ERROR_NULL_DEVICE = 0x8000000c; ///< The operation failed because a device was null. +static const FfxErrorCode FFX_ERROR_BACKEND_API_ERROR = 0x8000000d; ///< The operation failed because the backend API returned an error code. +static const FfxErrorCode FFX_ERROR_INSUFFICIENT_MEMORY = 0x8000000e; ///< The operation failed because there was not enough memory. + +/// Helper macro to return error code y from a function when a specific condition, x, is not met. +#define FFX_RETURN_ON_ERROR(x, y) \ + if (!(x)) \ + { \ + return (y); \ + } + +/// Helper macro to return error code x from a function when it is not FFX_OK. +#define FFX_VALIDATE(x) \ + { \ + FfxErrorCode ret = x; \ + FFX_RETURN_ON_ERROR(ret == FFX_OK, ret); \ + } + diff --git a/crates/fsr/fsr/include/ffx_fsr2.h b/crates/fsr/fsr/include/ffx_fsr2.h new file mode 100644 index 0000000000000..ee2ff7d06342d --- /dev/null +++ b/crates/fsr/fsr/include/ffx_fsr2.h @@ -0,0 +1,441 @@ +// This file is part of the FidelityFX SDK. +// +// Copyright (c) 2022 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + + +// @defgroup FSR2 + +#pragma once + +// Include the interface for the backend of the FSR2 API. +#include "ffx_fsr2_interface.h" + +/// FidelityFX Super Resolution 2 major version. +/// +/// @ingroup FSR2 +#define FFX_FSR2_VERSION_MAJOR (2) + +/// FidelityFX Super Resolution 2 minor version. +/// +/// @ingroup FSR2 +#define FFX_FSR2_VERSION_MINOR (1) + +/// FidelityFX Super Resolution 2 patch version. +/// +/// @ingroup FSR2 +#define FFX_FSR2_VERSION_PATCH (2) + +/// The size of the context specified in 32bit values. +/// +/// @ingroup FSR2 +#define FFX_FSR2_CONTEXT_SIZE (16536) + +#if defined(__cplusplus) +extern "C" { +#endif // #if defined(__cplusplus) + +/// An enumeration of all the quality modes supported by FidelityFX Super +/// Resolution 2 upscaling. +/// +/// In order to provide a consistent user experience across multiple +/// applications which implement FSR2. It is strongly recommended that the +/// following preset scaling factors are made available through your +/// application's user interface. +/// +/// If your application does not expose the notion of preset scaling factors +/// for upscaling algorithms (perhaps instead implementing a fixed ratio which +/// is immutable) or implementing a more dynamic scaling scheme (such as +/// dynamic resolution scaling), then there is no need to use these presets. +/// +/// Please note that FFX_FSR2_QUALITY_MODE_ULTRA_PERFORMANCE is +/// an optional mode which may introduce significant quality degradation in the +/// final image. As such it is recommended that you evaluate the final results +/// of using this scaling mode before deciding if you should include it in your +/// application. +/// +/// @ingroup FSR2 +typedef enum FfxFsr2QualityMode { + + FFX_FSR2_QUALITY_MODE_QUALITY = 1, ///< Perform upscaling with a per-dimension upscaling ratio of 1.5x. + FFX_FSR2_QUALITY_MODE_BALANCED = 2, ///< Perform upscaling with a per-dimension upscaling ratio of 1.7x. + FFX_FSR2_QUALITY_MODE_PERFORMANCE = 3, ///< Perform upscaling with a per-dimension upscaling ratio of 2.0x. + FFX_FSR2_QUALITY_MODE_ULTRA_PERFORMANCE = 4 ///< Perform upscaling with a per-dimension upscaling ratio of 3.0x. +} FfxFsr2QualityMode; + +/// An enumeration of bit flags used when creating a +/// FfxFsr2Context. See FfxFsr2ContextDescription. +/// +/// @ingroup FSR2 +typedef enum FfxFsr2InitializationFlagBits { + + FFX_FSR2_ENABLE_HIGH_DYNAMIC_RANGE = (1<<0), ///< A bit indicating if the input color data provided is using a high-dynamic range. + FFX_FSR2_ENABLE_DISPLAY_RESOLUTION_MOTION_VECTORS = (1<<1), ///< A bit indicating if the motion vectors are rendered at display resolution. + FFX_FSR2_ENABLE_MOTION_VECTORS_JITTER_CANCELLATION = (1<<2), ///< A bit indicating that the motion vectors have the jittering pattern applied to them. + FFX_FSR2_ENABLE_DEPTH_INVERTED = (1<<3), ///< A bit indicating that the input depth buffer data provided is inverted [1..0]. + FFX_FSR2_ENABLE_DEPTH_INFINITE = (1<<4), ///< A bit indicating that the input depth buffer data provided is using an infinite far plane. + FFX_FSR2_ENABLE_AUTO_EXPOSURE = (1<<5), ///< A bit indicating if automatic exposure should be applied to input color data. + FFX_FSR2_ENABLE_DYNAMIC_RESOLUTION = (1<<6), ///< A bit indicating that the application uses dynamic resolution scaling. + FFX_FSR2_ENABLE_TEXTURE1D_USAGE = (1<<7) ///< A bit indicating that the backend should use 1D textures. +} FfxFsr2InitializationFlagBits; + +/// A structure encapsulating the parameters required to initialize FidelityFX +/// Super Resolution 2 upscaling. +/// +/// @ingroup FSR2 +typedef struct FfxFsr2ContextDescription { + + uint32_t flags; ///< A collection of FfxFsr2InitializationFlagBits. + FfxDimensions2D maxRenderSize; ///< The maximum size that rendering will be performed at. + FfxDimensions2D displaySize; ///< The size of the presentation resolution targeted by the upscaling process. + FfxFsr2Interface callbacks; ///< A set of pointers to the backend implementation for FSR 2.0. + FfxDevice device; ///< The abstracted device which is passed to some callback functions. +} FfxFsr2ContextDescription; + +/// A structure encapsulating the parameters for dispatching the various passes +/// of FidelityFX Super Resolution 2. +/// +/// @ingroup FSR2 +typedef struct FfxFsr2DispatchDescription { + + FfxCommandList commandList; ///< The FfxCommandList to record FSR2 rendering commands into. + FfxResource color; ///< A FfxResource containing the color buffer for the current frame (at render resolution). + FfxResource depth; ///< A FfxResource containing 32bit depth values for the current frame (at render resolution). + FfxResource motionVectors; ///< A FfxResource containing 2-dimensional motion vectors (at render resolution if FFX_FSR2_ENABLE_DISPLAY_RESOLUTION_MOTION_VECTORS is not set). + FfxResource exposure; ///< A optional FfxResource containing a 1x1 exposure value. + FfxResource reactive; ///< A optional FfxResource containing alpha value of reactive objects in the scene. + FfxResource transparencyAndComposition; ///< A optional FfxResource containing alpha value of special objects in the scene. + FfxResource output; ///< A FfxResource containing the output color buffer for the current frame (at presentation resolution). + FfxFloatCoords2D jitterOffset; ///< The subpixel jitter offset applied to the camera. + FfxFloatCoords2D motionVectorScale; ///< The scale factor to apply to motion vectors. + FfxDimensions2D renderSize; ///< The resolution that was used for rendering the input resources. + bool enableSharpening; ///< Enable an additional sharpening pass. + float sharpness; ///< The sharpness value between 0 and 1, where 0 is no additional sharpness and 1 is maximum additional sharpness. + float frameTimeDelta; ///< The time elapsed since the last frame (expressed in milliseconds). + float preExposure; ///< The exposure value if not using FFX_FSR2_ENABLE_AUTO_EXPOSURE. + bool reset; ///< A boolean value which when set to true, indicates the camera has moved discontinuously. + float cameraNear; ///< The distance to the near plane of the camera. + float cameraFar; ///< The distance to the far plane of the camera. This is used only used in case of non infinite depth. + float cameraFovAngleVertical; ///< The camera angle field of view in the vertical direction (expressed in radians). +} FfxFsr2DispatchDescription; + +/// A structure encapsulating the parameters for automatic generation of a reactive mask +/// +/// @ingroup FSR2 +typedef struct FfxFsr2GenerateReactiveDescription { + + FfxCommandList commandList; ///< The FfxCommandList to record FSR2 rendering commands into. + FfxResource colorOpaqueOnly; ///< A FfxResource containing the opaque only color buffer for the current frame (at render resolution). + FfxResource colorPreUpscale; ///< A FfxResource containing the opaque+translucent color buffer for the current frame (at render resolution). + FfxResource outReactive; ///< A FfxResource containing the surface to generate the reactive mask into. + FfxDimensions2D renderSize; ///< The resolution that was used for rendering the input resources. + float scale; ///< A value to scale the output + float cutoffThreshold; ///< A threshold value to generate a binary reactive mask + float binaryValue; ///< A value to set for the binary reactive mask + uint32_t flags; ///< Flags to determine how to generate the reactive mask +} FfxFsr2GenerateReactiveDescription; + +/// A structure encapsulating the FidelityFX Super Resolution 2 context. +/// +/// This sets up an object which contains all persistent internal data and +/// resources that are required by FSR2. +/// +/// The FfxFsr2Context object should have a lifetime matching +/// your use of FSR2. Before destroying the FSR2 context care should be taken +/// to ensure the GPU is not accessing the resources created or used by FSR2. +/// It is therefore recommended that the GPU is idle before destroying the +/// FSR2 context. +/// +/// @ingroup FSR2 +typedef struct FfxFsr2Context { + + uint32_t data[FFX_FSR2_CONTEXT_SIZE]; ///< An opaque set of uint32_t which contain the data for the context. +} FfxFsr2Context; + +/// Create a FidelityFX Super Resolution 2 context from the parameters +/// programmed to the FfxFsr2CreateParams structure. +/// +/// The context structure is the main object used to interact with the FSR2 +/// API, and is responsible for the management of the internal resources used +/// by the FSR2 algorithm. When this API is called, multiple calls will be +/// made via the pointers contained in the callbacks structure. +/// These callbacks will attempt to retreive the device capabilities, and +/// create the internal resources, and pipelines required by FSR2's +/// frame-to-frame function. Depending on the precise configuration used when +/// creating the FfxFsr2Context a different set of resources and +/// pipelines might be requested via the callback functions. +/// +/// The flags included in the flags field of +/// FfxFsr2Context how match the configuration of your +/// application as well as the intended use of FSR2. It is important that these +/// flags are set correctly (as well as a correct programmed +/// FfxFsr2DispatchDescription) to ensure correct operation. It is +/// recommended to consult the overview documentation for further details on +/// how FSR2 should be integerated into an application. +/// +/// When the FfxFsr2Context is created, you should use the +/// ffxFsr2ContextDispatch function each frame where FSR2 +/// upscaling should be applied. See the documentation of +/// ffxFsr2ContextDispatch for more details. +/// +/// The FfxFsr2Context should be destroyed when use of it is +/// completed, typically when an application is unloaded or FSR2 upscaling is +/// disabled by a user. To destroy the FSR2 context you should call +/// ffxFsr2ContextDestroy. +/// +/// @param [out] context A pointer to a FfxFsr2Context structure to populate. +/// @param [in] contextDescription A pointer to a FfxFsr2ContextDescription structure. +/// +/// @retval +/// FFX_OK The operation completed successfully. +/// @retval +/// FFX_ERROR_CODE_NULL_POINTER The operation failed because either context or contextDescription was NULL. +/// @retval +/// FFX_ERROR_INCOMPLETE_INTERFACE The operation failed because the FfxFsr2ContextDescription.callbacks was not fully specified. +/// @retval +/// FFX_ERROR_BACKEND_API_ERROR The operation failed because of an error returned from the backend. +/// +/// @ingroup FSR2 +FFX_API FfxErrorCode ffxFsr2ContextCreate(FfxFsr2Context* context, const FfxFsr2ContextDescription* contextDescription); + +/// Dispatch the various passes that constitute FidelityFX Super Resolution 2. +/// +/// FSR2 is a composite effect, meaning that it is compromised of multiple +/// constituent passes (implemented as one or more clears, copies and compute +/// dispatches). The ffxFsr2ContextDispatch function is the +/// function which (via the use of the functions contained in the +/// callbacks field of the FfxFsr2Context +/// structure) utlimately generates the sequence of graphics API calls required +/// each frame. +/// +/// As with the creation of the FfxFsr2Context correctly +/// programming the FfxFsr2DispatchDescription is key to ensuring +/// the correct operation of FSR2. It is particularly important to ensure that +/// camera jitter is correctly applied to your application's projection matrix +/// (or camera origin for raytraced applications). FSR2 provides the +/// ffxFsr2GetJitterPhaseCount and +/// ffxFsr2GetJitterOffset entry points to help applications +/// correctly compute the camera jitter. Whatever jitter pattern is used by the +/// application it should be correctly programmed to the +/// jitterOffset field of the dispatchDescription +/// structure. For more guidance on camera jitter please consult the +/// documentation for ffxFsr2GetJitterOffset as well as the +/// accompanying overview documentation for FSR2. +/// +/// @param [in] context A pointer to a FfxFsr2Context structure. +/// @param [in] dispatchDescription A pointer to a FfxFsr2DispatchDescription structure. +/// +/// @retval +/// FFX_OK The operation completed successfully. +/// @retval +/// FFX_ERROR_CODE_NULL_POINTER The operation failed because either context or dispatchDescription was NULL. +/// @retval +/// FFX_ERROR_OUT_OF_RANGE The operation failed because dispatchDescription.renderSize was larger than the maximum render resolution. +/// @retval +/// FFX_ERROR_NULL_DEVICE The operation failed because the device inside the context was NULL. +/// @retval +/// FFX_ERROR_BACKEND_API_ERROR The operation failed because of an error returned from the backend. +/// +/// @ingroup FSR2 +FFX_API FfxErrorCode ffxFsr2ContextDispatch(FfxFsr2Context* context, const FfxFsr2DispatchDescription* dispatchDescription); + +/// A helper function generate a Reactive mask from an opaque only texure and one containing translucent objects. +/// +/// @param [in] context A pointer to a FfxFsr2Context structure. +/// @param [in] params A pointer to a FfxFsr2GenerateReactiveDescription structure +/// +/// @retval +/// FFX_OK The operation completed successfully. +/// +/// @ingroup FSR2 +FFX_API FfxErrorCode ffxFsr2ContextGenerateReactiveMask(FfxFsr2Context* context, const FfxFsr2GenerateReactiveDescription* params); + +/// Destroy the FidelityFX Super Resolution context. +/// +/// @param [out] context A pointer to a FfxFsr2Context structure to destroy. +/// +/// @retval +/// FFX_OK The operation completed successfully. +/// @retval +/// FFX_ERROR_CODE_NULL_POINTER The operation failed because either context was NULL. +/// +/// @ingroup FSR2 +FFX_API FfxErrorCode ffxFsr2ContextDestroy(FfxFsr2Context* context); + +/// Get the upscale ratio from the quality mode. +/// +/// The following table enumerates the mapping of the quality modes to +/// per-dimension scaling ratios. +/// +/// Quality preset | Scale factor +/// ----------------------------------------------------- | ------------- +/// FFX_FSR2_QUALITY_MODE_QUALITY | 1.5x +/// FFX_FSR2_QUALITY_MODE_BALANCED | 1.7x +/// FFX_FSR2_QUALITY_MODE_PERFORMANCE | 2.0x +/// FFX_FSR2_QUALITY_MODE_ULTRA_PERFORMANCE | 3.0x +/// +/// Passing an invalid qualityMode will return 0.0f. +/// +/// @param [in] qualityMode The quality mode preset. +/// +/// @returns +/// The upscaling the per-dimension upscaling ratio for +/// qualityMode according to the table above. +/// +/// @ingroup FSR2 +FFX_API float ffxFsr2GetUpscaleRatioFromQualityMode(FfxFsr2QualityMode qualityMode); + +/// A helper function to calculate the rendering resolution from a target +/// resolution and desired quality level. +/// +/// This function applies the scaling factor returned by +/// ffxFsr2GetUpscaleRatioFromQualityMode to each dimension. +/// +/// @param [out] renderWidth A pointer to a uint32_t which will hold the calculated render resolution width. +/// @param [out] renderHeight A pointer to a uint32_t which will hold the calculated render resolution height. +/// @param [in] displayWidth The target display resolution width. +/// @param [in] displayHeight The target display resolution height. +/// @param [in] qualityMode The desired quality mode for FSR 2 upscaling. +/// +/// @retval +/// FFX_OK The operation completed successfully. +/// @retval +/// FFX_ERROR_INVALID_POINTER Either renderWidth or renderHeight was NULL. +/// @retval +/// FFX_ERROR_INVALID_ENUM An invalid quality mode was specified. +/// +/// @ingroup FSR2 +FFX_API FfxErrorCode ffxFsr2GetRenderResolutionFromQualityMode( + uint32_t* renderWidth, + uint32_t* renderHeight, + uint32_t displayWidth, + uint32_t displayHeight, + FfxFsr2QualityMode qualityMode); + +/// A helper function to calculate the jitter phase count from display +/// resolution. +/// +/// For more detailed information about the application of camera jitter to +/// your application's rendering please refer to the +/// ffxFsr2GetJitterOffset function. +/// +/// The table below shows the jitter phase count which this function +/// would return for each of the quality presets. +/// +/// Quality preset | Scale factor | Phase count +/// ----------------------------------------------------- | ------------- | --------------- +/// FFX_FSR2_QUALITY_MODE_QUALITY | 1.5x | 18 +/// FFX_FSR2_QUALITY_MODE_BALANCED | 1.7x | 23 +/// FFX_FSR2_QUALITY_MODE_PERFORMANCE | 2.0x | 32 +/// FFX_FSR2_QUALITY_MODE_ULTRA_PERFORMANCE | 3.0x | 72 +/// Custom | [1..n]x | ceil(8*n^2) +/// +/// @param [in] renderWidth The render resolution width. +/// @param [in] displayWidth The display resolution width. +/// +/// @returns +/// The jitter phase count for the scaling factor between renderWidth and displayWidth. +/// +/// @ingroup FSR2 +FFX_API int32_t ffxFsr2GetJitterPhaseCount(int32_t renderWidth, int32_t displayWidth); + +/// A helper function to calculate the subpixel jitter offset. +/// +/// FSR2 relies on the application to apply sub-pixel jittering while rendering. +/// This is typically included in the projection matrix of the camera. To make +/// the application of camera jitter simple, the FSR2 API provides a small set +/// of utility function which computes the sub-pixel jitter offset for a +/// particular frame within a sequence of separate jitter offsets. To begin, the +/// index within the jitter phase must be computed. To calculate the +/// sequence's length, you can call the ffxFsr2GetJitterPhaseCount +/// function. The index should be a value which is incremented each frame modulo +/// the length of the sequence computed by ffxFsr2GetJitterPhaseCount. +/// The index within the jitter phase is passed to +/// ffxFsr2GetJitterOffset via the index parameter. +/// +/// This function uses a Halton(2,3) sequence to compute the jitter offset. +/// The ultimate index used for the sequence is index % +/// phaseCount. +/// +/// It is important to understand that the values returned from the +/// ffxFsr2GetJitterOffset function are in unit pixel space, and +/// in order to composite this correctly into a projection matrix we must +/// convert them into projection offsets. This is done as per the pseudo code +/// listing which is shown below. +/// +/// const int32_t jitterPhaseCount = ffxFsr2GetJitterPhaseCount(renderWidth, displayWidth); +/// +/// float jitterX = 0; +/// float jitterY = 0; +/// ffxFsr2GetJitterOffset(&jitterX, &jitterY, index, jitterPhaseCount); +/// +/// const float jitterX = 2.0f * jitterX / (float)renderWidth; +/// const float jitterY = -2.0f * jitterY / (float)renderHeight; +/// const Matrix4 jitterTranslationMatrix = translateMatrix(Matrix3::identity, Vector3(jitterX, jitterY, 0)); +/// const Matrix4 jitteredProjectionMatrix = jitterTranslationMatrix * projectionMatrix; +/// +/// Jitter should be applied to all rendering. This includes opaque, alpha +/// transparent, and raytraced objects. For rasterized objects, the sub-pixel +/// jittering values calculated by the iffxFsr2GetJitterOffset +/// function can be applied to the camera projection matrix which is ultimately +/// used to perform transformations during vertex shading. For raytraced +/// rendering, the sub-pixel jitter should be applied to the ray's origin, +/// often the camera's position. +/// +/// Whether you elect to use the ffxFsr2GetJitterOffset function +/// or your own sequence generator, you must program the +/// jitterOffset field of the +/// FfxFsr2DispatchParameters structure in order to inform FSR2 +/// of the jitter offset that has been applied in order to render each frame. +/// +/// If not using the recommended ffxFsr2GetJitterOffset function, +/// care should be taken that your jitter sequence never generates a null vector; +/// that is value of 0 in both the X and Y dimensions. +/// +/// @param [out] outX A pointer to a float which will contain the subpixel jitter offset for the x dimension. +/// @param [out] outY A pointer to a float which will contain the subpixel jitter offset for the y dimension. +/// @param [in] index The index within the jitter sequence. +/// @param [in] phaseCount The length of jitter phase. See ffxFsr2GetJitterPhaseCount. +/// +/// @retval +/// FFX_OK The operation completed successfully. +/// @retval +/// FFX_ERROR_INVALID_POINTER Either outX or outY was NULL. +/// @retval +/// FFX_ERROR_INVALID_ARGUMENT Argument phaseCount must be greater than 0. +/// +/// @ingroup FSR2 +FFX_API FfxErrorCode ffxFsr2GetJitterOffset(float* outX, float* outY, int32_t index, int32_t phaseCount); + +/// A helper function to check if a resource is +/// FFX_FSR2_RESOURCE_IDENTIFIER_NULL. +/// +/// @param [in] resource A FfxResource. +/// +/// @returns +/// true The resource was not FFX_FSR2_RESOURCE_IDENTIFIER_NULL. +/// @returns +/// false The resource was FFX_FSR2_RESOURCE_IDENTIFIER_NULL. +/// +/// @ingroup FSR2 +FFX_API bool ffxFsr2ResourceIsNull(FfxResource resource); + +#if defined(__cplusplus) +} +#endif // #if defined(__cplusplus) diff --git a/crates/fsr/fsr/include/ffx_fsr2_interface.h b/crates/fsr/fsr/include/ffx_fsr2_interface.h new file mode 100644 index 0000000000000..db13fd0f29138 --- /dev/null +++ b/crates/fsr/fsr/include/ffx_fsr2_interface.h @@ -0,0 +1,376 @@ +// This file is part of the FidelityFX SDK. +// +// Copyright (c) 2022 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#pragma once + +#include "ffx_assert.h" +#include "ffx_types.h" +#include "ffx_error.h" + +// Include the FSR2 resources defined in the HLSL code. This shared here to avoid getting out of sync. +#define FFX_CPU +#include "shaders/ffx_fsr2_resources.h" +#include "shaders/ffx_fsr2_common.h" + +#if defined(__cplusplus) +extern "C" { +#endif // #if defined(__cplusplus) + +FFX_FORWARD_DECLARE(FfxFsr2Interface); + +/// An enumeration of all the passes which constitute the FSR2 algorithm. +/// +/// FSR2 is implemented as a composite of several compute passes each +/// computing a key part of the final result. Each call to the +/// FfxFsr2ScheduleGpuJobFunc callback function will +/// correspond to a single pass included in FfxFsr2Pass. For a +/// more comprehensive description of each pass, please refer to the FSR2 +/// reference documentation. +/// +/// Please note in some cases e.g.: FFX_FSR2_PASS_ACCUMULATE +/// and FFX_FSR2_PASS_ACCUMULATE_SHARPEN either one pass or the +/// other will be used (they are mutually exclusive). The choice of which will +/// depend on the way the FfxFsr2Context is created and the +/// precise contents of FfxFsr2DispatchParamters each time a call +/// is made to ffxFsr2ContextDispatch. +/// +/// @ingroup FSR2 +typedef enum FfxFsr2Pass { + + FFX_FSR2_PASS_PREPARE_INPUT_COLOR = 0, ///< A pass which prepares input colors for subsequent use. + FFX_FSR2_PASS_DEPTH_CLIP = 1, ///< A pass which performs depth clipping. + FFX_FSR2_PASS_RECONSTRUCT_PREVIOUS_DEPTH = 2, ///< A pass which performs reconstruction of previous frame's depth. + FFX_FSR2_PASS_LOCK = 3, ///< A pass which calculates pixel locks. + FFX_FSR2_PASS_ACCUMULATE = 4, ///< A pass which performs upscaling. + FFX_FSR2_PASS_ACCUMULATE_SHARPEN = 5, ///< A pass which performs upscaling when sharpening is used. + FFX_FSR2_PASS_RCAS = 6, ///< A pass which performs sharpening. + FFX_FSR2_PASS_COMPUTE_LUMINANCE_PYRAMID = 7, ///< A pass which generates the luminance mipmap chain for the current frame. + FFX_FSR2_PASS_GENERATE_REACTIVE = 8, ///< An optional pass to generate a reactive mask + + FFX_FSR2_PASS_COUNT ///< The number of passes performed by FSR2. +} FfxFsr2Pass; + +/// Create and initialize the backend context. +/// +/// The callback function sets up the backend context for rendering. +/// It will create or reference the device and create required internal data structures. +/// +/// @param [in] backendInterface A pointer to the backend interface. +/// @param [in] device The FfxDevice obtained by ffxGetDevice(DX12/VK/...). +/// +/// @retval +/// FFX_OK The operation completed successfully. +/// @retval +/// Anything else The operation failed. +/// +/// @ingroup FSR2 +typedef FfxErrorCode (*FfxFsr2CreateBackendContextFunc)( + FfxFsr2Interface* backendInterface, + FfxDevice device); + +/// Get a list of capabilities of the device. +/// +/// When creating an FfxFsr2Context it is desirable for the FSR2 +/// core implementation to be aware of certain characteristics of the platform +/// that is being targetted. This is because some optimizations which FSR2 +/// attempts to perform are more effective on certain classes of hardware than +/// others, or are not supported by older hardware. In order to avoid cases +/// where optimizations actually have the effect of decreasing performance, or +/// reduce the breadth of support provided by FSR2, FSR2 queries the +/// capabilities of the device to make such decisions. +/// +/// For target platforms with fixed hardware support you need not implement +/// this callback function by querying the device, but instead may hardcore +/// what features are available on the platform. +/// +/// @param [in] backendInterface A pointer to the backend interface. +/// @param [out] outDeviceCapabilities The device capabilities structure to fill out. +/// @param [in] device The device to query for capabilities. +/// +/// @retval +/// FFX_OK The operation completed successfully. +/// @retval +/// Anything else The operation failed. +/// +/// @ingroup FSR2 +typedef FfxErrorCode(*FfxFsr2GetDeviceCapabilitiesFunc)( + FfxFsr2Interface* backendInterface, + FfxDeviceCapabilities* outDeviceCapabilities, + FfxDevice device); + +/// Destroy the backend context and dereference the device. +/// +/// This function is called when the FfxFsr2Context is destroyed. +/// +/// @param [in] backendInterface A pointer to the backend interface. +/// +/// @retval +/// FFX_OK The operation completed successfully. +/// @retval +/// Anything else The operation failed. +/// +/// @ingroup FSR2 +typedef FfxErrorCode(*FfxFsr2DestroyBackendContextFunc)( + FfxFsr2Interface* backendInterface); + +/// Create a resource. +/// +/// This callback is intended for the backend to create internal resources. +/// +/// Please note: It is also possible that the creation of resources might +/// itself cause additional resources to be created by simply calling the +/// FfxFsr2CreateResourceFunc function pointer again. This is +/// useful when handling the initial creation of resources which must be +/// initialized. The flow in such a case would be an initial call to create the +/// CPU-side resource, another to create the GPU-side resource, and then a call +/// to schedule a copy render job to move the data between the two. Typically +/// this type of function call flow is only seen during the creation of an +/// FfxFsr2Context. +/// +/// @param [in] backendInterface A pointer to the backend interface. +/// @param [in] createResourceDescription A pointer to a FfxCreateResourceDescription. +/// @param [out] outResource A pointer to a FfxResource object. +/// +/// @retval +/// FFX_OK The operation completed successfully. +/// @retval +/// Anything else The operation failed. +/// +/// @ingroup FSR2 +typedef FfxErrorCode (*FfxFsr2CreateResourceFunc)( + FfxFsr2Interface* backendInterface, + const FfxCreateResourceDescription* createResourceDescription, + FfxResourceInternal* outResource); + +/// Register a resource in the backend for the current frame. +/// +/// Since FSR2 and the backend are not aware how many different +/// resources will get passed to FSR2 over time, it's not safe +/// to register all resources simultaneously in the backend. +/// Also passed resources may not be valid after the dispatch call. +/// As a result it's safest to register them as FfxResourceInternal +/// and clear them at the end of the dispatch call. +/// +/// @param [in] backendInterface A pointer to the backend interface. +/// @param [in] inResource A pointer to a FfxResource. +/// @param [out] outResource A pointer to a FfxResourceInternal object. +/// +/// @retval +/// FFX_OK The operation completed successfully. +/// @retval +/// Anything else The operation failed. +/// +/// @ingroup FSR2 +typedef FfxErrorCode(*FfxFsr2RegisterResourceFunc)( + FfxFsr2Interface* backendInterface, + const FfxResource* inResource, + FfxResourceInternal* outResource); + +/// Unregister all temporary FfxResourceInternal from the backend. +/// +/// Unregister FfxResourceInternal referencing resources passed to +/// a function as a parameter. +/// +/// @param [in] backendInterface A pointer to the backend interface. +/// +/// @retval +/// FFX_OK The operation completed successfully. +/// @retval +/// Anything else The operation failed. +/// +/// @ingroup FSR2 +typedef FfxErrorCode(*FfxFsr2UnregisterResourcesFunc)( + FfxFsr2Interface* backendInterface); + +/// Retrieve a FfxResourceDescription matching a +/// FfxResource structure. +/// +/// @param [in] backendInterface A pointer to the backend interface. +/// @param [in] resource A pointer to a FfxResource object. +/// +/// @returns +/// A description of the resource. +/// +/// @ingroup FSR2 +typedef FfxResourceDescription (*FfxFsr2GetResourceDescriptionFunc)( + FfxFsr2Interface* backendInterface, + FfxResourceInternal resource); + +/// Destroy a resource +/// +/// This callback is intended for the backend to release an internal resource. +/// +/// @param [in] backendInterface A pointer to the backend interface. +/// @param [in] resource A pointer to a FfxResource object. +/// +/// @retval +/// FFX_OK The operation completed successfully. +/// @retval +/// Anything else The operation failed. +/// +/// @ingroup FSR2 +typedef FfxErrorCode (*FfxFsr2DestroyResourceFunc)( + FfxFsr2Interface* backendInterface, + FfxResourceInternal resource); + +/// Create a render pipeline. +/// +/// A rendering pipeline contains the shader as well as resource bindpoints +/// and samplers. +/// +/// @param [in] backendInterface A pointer to the backend interface. +/// @param [in] pass The identifier for the pass. +/// @param [in] pipelineDescription A pointer to a FfxPipelineDescription describing the pipeline to be created. +/// @param [out] outPipeline A pointer to a FfxPipelineState structure which should be populated. +/// +/// @retval +/// FFX_OK The operation completed successfully. +/// @retval +/// Anything else The operation failed. +/// +/// @ingroup FSR2 +typedef FfxErrorCode (*FfxFsr2CreatePipelineFunc)( + FfxFsr2Interface* backendInterface, + FfxFsr2Pass pass, + const FfxPipelineDescription* pipelineDescription, + FfxPipelineState* outPipeline); + +/// Destroy a render pipeline. +/// +/// @param [in] backendInterface A pointer to the backend interface. +/// @param [out] pipeline A pointer to a FfxPipelineState structure which should be released. +/// +/// @retval +/// FFX_OK The operation completed successfully. +/// @retval +/// Anything else The operation failed. +/// +/// @ingroup FSR2 +typedef FfxErrorCode (*FfxFsr2DestroyPipelineFunc)( + FfxFsr2Interface* backendInterface, + FfxPipelineState* pipeline); + +/// Schedule a render job to be executed on the next call of +/// FfxFsr2ExecuteGpuJobsFunc. +/// +/// Render jobs can perform one of three different tasks: clear, copy or +/// compute dispatches. +/// +/// @param [in] backendInterface A pointer to the backend interface. +/// @param [in] job A pointer to a FfxGpuJobDescription structure. +/// +/// @retval +/// FFX_OK The operation completed successfully. +/// @retval +/// Anything else The operation failed. +/// +/// @ingroup FSR2 +typedef FfxErrorCode (*FfxFsr2ScheduleGpuJobFunc)( + FfxFsr2Interface* backendInterface, + const FfxGpuJobDescription* job); + +/// Execute scheduled render jobs on the comandList provided. +/// +/// The recording of the graphics API commands should take place in this +/// callback function, the render jobs which were previously enqueued (via +/// callbacks made to FfxFsr2ScheduleGpuJobFunc) should be +/// processed in the order they were received. Advanced users might choose to +/// reorder the rendering jobs, but should do so with care to respect the +/// resource dependencies. +/// +/// Depending on the precise contents of FfxFsr2DispatchDescription a +/// different number of render jobs might have previously been enqueued (for +/// example if sharpening is toggled on and off). +/// +/// @param [in] backendInterface A pointer to the backend interface. +/// @param [in] commandList A pointer to a FfxCommandList structure. +/// +/// @retval +/// FFX_OK The operation completed successfully. +/// @retval +/// Anything else The operation failed. +/// +/// @ingroup FSR2 +typedef FfxErrorCode (*FfxFsr2ExecuteGpuJobsFunc)( + FfxFsr2Interface* backendInterface, + FfxCommandList commandList); + +/// A structure encapsulating the interface between the core implentation of +/// the FSR2 algorithm and any graphics API that it should ultimately call. +/// +/// This set of functions serves as an abstraction layer between FSR2 and the +/// API used to implement it. While FSR2 ships with backends for DirectX12 and +/// Vulkan, it is possible to implement your own backend for other platforms or +/// which sits ontop of your engine's own abstraction layer. For details on the +/// expectations of what each function should do you should refer the +/// description of the following function pointer types: +/// +/// FfxFsr2CreateDeviceFunc +/// FfxFsr2GetDeviceCapabilitiesFunc +/// FfxFsr2DestroyDeviceFunc +/// FfxFsr2CreateResourceFunc +/// FfxFsr2GetResourceDescriptionFunc +/// FfxFsr2DestroyResourceFunc +/// FfxFsr2CreatePipelineFunc +/// FfxFsr2DestroyPipelineFunc +/// FfxFsr2ScheduleGpuJobFunc +/// FfxFsr2ExecuteGpuJobsFunc +/// +/// Depending on the graphics API that is abstracted by the backend, it may be +/// required that the backend is to some extent stateful. To ensure that +/// applications retain full control to manage the memory used by FSR2, the +/// scratchBuffer and scratchBufferSize fields are +/// provided. A backend should provide a means of specifying how much scratch +/// memory is required for its internal implementation (e.g: via a function +/// or constant value). The application is that responsible for allocating that +/// memory and providing it when setting up the FSR2 backend. Backends provided +/// with FSR2 do not perform dynamic memory allocations, and instead +/// suballocate all memory from the scratch buffers provided. +/// +/// The scratchBuffer and scratchBufferSize fields +/// should be populated according to the requirements of each backend. For +/// example, if using the DirectX 12 backend you should call the +/// ffxFsr2GetScratchMemorySizeDX12 function. It is not required +/// that custom backend implementations use a scratch buffer. +/// +/// @ingroup FSR2 +typedef struct FfxFsr2Interface { + + FfxFsr2CreateBackendContextFunc fpCreateBackendContext; ///< A callback function to create and initialize the backend context. + FfxFsr2GetDeviceCapabilitiesFunc fpGetDeviceCapabilities; ///< A callback function to query device capabilites. + FfxFsr2DestroyBackendContextFunc fpDestroyBackendContext; ///< A callback function to destroy the backendcontext. This also dereferences the device. + FfxFsr2CreateResourceFunc fpCreateResource; ///< A callback function to create a resource. + FfxFsr2RegisterResourceFunc fpRegisterResource; ///< A callback function to register an external resource. + FfxFsr2UnregisterResourcesFunc fpUnregisterResources; ///< A callback function to unregister external resource. + FfxFsr2GetResourceDescriptionFunc fpGetResourceDescription; ///< A callback function to retrieve a resource description. + FfxFsr2DestroyResourceFunc fpDestroyResource; ///< A callback function to destroy a resource. + FfxFsr2CreatePipelineFunc fpCreatePipeline; ///< A callback function to create a render or compute pipeline. + FfxFsr2DestroyPipelineFunc fpDestroyPipeline; ///< A callback function to destroy a render or compute pipeline. + FfxFsr2ScheduleGpuJobFunc fpScheduleGpuJob; ///< A callback function to schedule a render job. + FfxFsr2ExecuteGpuJobsFunc fpExecuteGpuJobs; ///< A callback function to execute all queued render jobs. + + void* scratchBuffer; ///< A preallocated buffer for memory utilized internally by the backend. + size_t scratchBufferSize; ///< Size of the buffer pointed to by scratchBuffer. +} FfxFsr2Interface; + +#if defined(__cplusplus) +} +#endif // #if defined(__cplusplus) diff --git a/crates/fsr/fsr/include/ffx_types.h b/crates/fsr/fsr/include/ffx_types.h new file mode 100644 index 0000000000000..1f575a7deca1e --- /dev/null +++ b/crates/fsr/fsr/include/ffx_types.h @@ -0,0 +1,353 @@ +// This file is part of the FidelityFX SDK. +// +// Copyright (c) 2022 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#pragma once + +#include +#include + +#if defined (FFX_GCC) +/// FidelityFX exported functions +#define FFX_API +#else +/// FidelityFX exported functions +#define FFX_API __declspec(dllexport) +#endif // #if defined (FFX_GCC) + +/// Maximum supported number of simultaneously bound SRVs. +#define FFX_MAX_NUM_SRVS 16 + +/// Maximum supported number of simultaneously bound UAVs. +#define FFX_MAX_NUM_UAVS 8 + +/// Maximum number of constant buffers bound. +#define FFX_MAX_NUM_CONST_BUFFERS 2 + +/// Maximum size of bound constant buffers. +#define FFX_MAX_CONST_SIZE 64 + +/// Off by default warnings +#pragma warning(disable : 4365 4710 4820 5039) + +#ifdef __cplusplus +extern "C" { +#endif // #ifdef __cplusplus + +/// An enumeration of surface formats. +typedef enum FfxSurfaceFormat { + + FFX_SURFACE_FORMAT_UNKNOWN, ///< Unknown format + FFX_SURFACE_FORMAT_R32G32B32A32_TYPELESS, ///< 32 bit per channel, 4 channel typeless format + FFX_SURFACE_FORMAT_R32G32B32A32_FLOAT, ///< 32 bit per channel, 4 channel float format + FFX_SURFACE_FORMAT_R16G16B16A16_FLOAT, ///< 16 bit per channel, 4 channel float format + FFX_SURFACE_FORMAT_R16G16B16A16_UNORM, ///< 16 bit per channel, 4 channel unsigned normalized format + FFX_SURFACE_FORMAT_R32G32_FLOAT, ///< 32 bit per channel, 2 channel float format + FFX_SURFACE_FORMAT_R32_UINT, ///< 32 bit per channel, 1 channel float format + FFX_SURFACE_FORMAT_R8G8B8A8_TYPELESS, ///< 8 bit per channel, 4 channel float format + FFX_SURFACE_FORMAT_R8G8B8A8_UNORM, ///< 8 bit per channel, 4 channel unsigned normalized format + FFX_SURFACE_FORMAT_R11G11B10_FLOAT, ///< 32 bit 3 channel float format + FFX_SURFACE_FORMAT_R16G16_FLOAT, ///< 16 bit per channel, 2 channel float format + FFX_SURFACE_FORMAT_R16G16_UINT, ///< 16 bit per channel, 2 channel unsigned int format + FFX_SURFACE_FORMAT_R16_FLOAT, ///< 16 bit per channel, 1 channel float format + FFX_SURFACE_FORMAT_R16_UINT, ///< 16 bit per channel, 1 channel unsigned int format + FFX_SURFACE_FORMAT_R16_UNORM, ///< 16 bit per channel, 1 channel unsigned normalized format + FFX_SURFACE_FORMAT_R16_SNORM, ///< 16 bit per channel, 1 channel signed normalized format + FFX_SURFACE_FORMAT_R8_UNORM, ///< 8 bit per channel, 1 channel unsigned normalized format + FFX_SURFACE_FORMAT_R8G8_UNORM, ///< 8 bit per channel, 2 channel unsigned normalized format + FFX_SURFACE_FORMAT_R32_FLOAT ///< 32 bit per channel, 1 channel float format +} FfxSurfaceFormat; + +/// An enumeration of resource usage. +typedef enum FfxResourceUsage { + + FFX_RESOURCE_USAGE_READ_ONLY = 0, ///< No usage flags indicate a resource is read only. + FFX_RESOURCE_USAGE_RENDERTARGET = (1<<0), ///< Indicates a resource will be used as render target. + FFX_RESOURCE_USAGE_UAV = (1<<1), ///< Indicates a resource will be used as UAV. +} FfxResourceUsage; + +/// An enumeration of resource states. +typedef enum FfxResourceStates { + + FFX_RESOURCE_STATE_UNORDERED_ACCESS = (1<<0), ///< Indicates a resource is in the state to be used as UAV. + FFX_RESOURCE_STATE_COMPUTE_READ = (1 << 1), ///< Indicates a resource is in the state to be read by compute shaders. + FFX_RESOURCE_STATE_COPY_SRC = (1 << 2), ///< Indicates a resource is in the state to be used as source in a copy command. + FFX_RESOURCE_STATE_COPY_DEST = (1 << 3), ///< Indicates a resource is in the state to be used as destination in a copy command. + FFX_RESOURCE_STATE_GENERIC_READ = (FFX_RESOURCE_STATE_COPY_SRC | FFX_RESOURCE_STATE_COMPUTE_READ), ///< Indicates a resource is in generic (slow) read state. +} FfxResourceStates; + +/// An enumeration of surface dimensions. +typedef enum FfxResourceDimension { + + FFX_RESOURCE_DIMENSION_TEXTURE_1D, ///< A resource with a single dimension. + FFX_RESOURCE_DIMENSION_TEXTURE_2D, ///< A resource with two dimensions. +} FfxResourceDimension; + +/// An enumeration of surface dimensions. +typedef enum FfxResourceFlags { + + FFX_RESOURCE_FLAGS_NONE = 0, ///< No flags. + FFX_RESOURCE_FLAGS_ALIASABLE = (1<<0), ///< A bit indicating a resource does not need to persist across frames. +} FfxResourceFlags; + +/// An enumeration of all resource view types. +typedef enum FfxResourceViewType { + + FFX_RESOURCE_VIEW_UNORDERED_ACCESS, ///< The resource view is an unordered access view (UAV). + FFX_RESOURCE_VIEW_SHADER_READ, ///< The resource view is a shader resource view (SRV). +} FfxResourceViewType; + +/// The type of filtering to perform when reading a texture. +typedef enum FfxFilterType { + + FFX_FILTER_TYPE_POINT, ///< Point sampling. + FFX_FILTER_TYPE_LINEAR ///< Sampling with interpolation. +} FfxFilterType; + +/// An enumeration of all supported shader models. +typedef enum FfxShaderModel { + + FFX_SHADER_MODEL_5_1, ///< Shader model 5.1. + FFX_SHADER_MODEL_6_0, ///< Shader model 6.0. + FFX_SHADER_MODEL_6_1, ///< Shader model 6.1. + FFX_SHADER_MODEL_6_2, ///< Shader model 6.2. + FFX_SHADER_MODEL_6_3, ///< Shader model 6.3. + FFX_SHADER_MODEL_6_4, ///< Shader model 6.4. + FFX_SHADER_MODEL_6_5, ///< Shader model 6.5. + FFX_SHADER_MODEL_6_6, ///< Shader model 6.6. + FFX_SHADER_MODEL_6_7, ///< Shader model 6.7. +} FfxShaderModel; + +// An enumeration for different resource types +typedef enum FfxResourceType { + + FFX_RESOURCE_TYPE_BUFFER, ///< The resource is a buffer. + FFX_RESOURCE_TYPE_TEXTURE1D, ///< The resource is a 1-dimensional texture. + FFX_RESOURCE_TYPE_TEXTURE2D, ///< The resource is a 2-dimensional texture. + FFX_RESOURCE_TYPE_TEXTURE3D, ///< The resource is a 3-dimensional texture. +} FfxResourceType; + +/// An enumeration for different heap types +typedef enum FfxHeapType { + + FFX_HEAP_TYPE_DEFAULT = 0, ///< Local memory. + FFX_HEAP_TYPE_UPLOAD ///< Heap used for uploading resources. +} FfxHeapType; + +/// An enumberation for different render job types +typedef enum FfxGpuJobType { + + FFX_GPU_JOB_CLEAR_FLOAT = 0, ///< The GPU job is performing a floating-point clear. + FFX_GPU_JOB_COPY = 1, ///< The GPU job is performing a copy. + FFX_GPU_JOB_COMPUTE = 2, ///< The GPU job is performing a compute dispatch. +} FfxGpuJobType; + +/// A typedef representing the graphics device. +typedef void* FfxDevice; + +/// A typedef representing a command list or command buffer. +typedef void* FfxCommandList; + +/// A typedef for a root signature. +typedef void* FfxRootSignature; + +/// A typedef for a pipeline state object. +typedef void* FfxPipeline; + +/// A structure encapasulating a collection of device capabilities. +typedef struct FfxDeviceCapabilities { + + FfxShaderModel minimumSupportedShaderModel; ///< The minimum shader model supported by the device. + uint32_t waveLaneCountMin; ///< The minimum supported wavefront width. + uint32_t waveLaneCountMax; ///< The maximum supported wavefront width. + bool fp16Supported; ///< The device supports FP16 in hardware. + bool raytracingSupported; ///< The device supports raytracing. +} FfxDeviceCapabilities; + +/// A structure encapsulating a 2-dimensional point, using 32bit unsigned integers. +typedef struct FfxDimensions2D { + + uint32_t width; ///< The width of a 2-dimensional range. + uint32_t height; ///< The height of a 2-dimensional range. +} FfxDimensions2D; + +/// A structure encapsulating a 2-dimensional point, +typedef struct FfxIntCoords2D { + + int32_t x; ///< The x coordinate of a 2-dimensional point. + int32_t y; ///< The y coordinate of a 2-dimensional point. +} FfxIntCoords2D; + +/// A structure encapsulating a 2-dimensional set of floating point coordinates. +typedef struct FfxFloatCoords2D { + + float x; ///< The x coordinate of a 2-dimensional point. + float y; ///< The y coordinate of a 2-dimensional point. +} FfxFloatCoords2D; + +/// A structure describing a resource. +typedef struct FfxResourceDescription { + + FfxResourceType type; ///< The type of the resource. + FfxSurfaceFormat format; ///< The surface format. + uint32_t width; ///< The width of the resource. + uint32_t height; ///< The height of the resource. + uint32_t depth; ///< The depth of the resource. + uint32_t mipCount; ///< Number of mips (or 0 for full mipchain). + FfxResourceFlags flags; ///< A set of FfxResourceFlags flags. +} FfxResourceDescription; + +/// An outward facing structure containing a resource +typedef struct FfxResource { + void* resource; ///< pointer to the resource. + wchar_t name[64]; + FfxResourceDescription description; + FfxResourceStates state; + bool isDepth; + uint64_t descriptorData; +} FfxResource; + +/// An internal structure containing a handle to a resource and resource views +typedef struct FfxResourceInternal { + int32_t internalIndex; ///< The index of the resource. +} FfxResourceInternal; + + +/// A structure defining a resource bind point +typedef struct FfxResourceBinding +{ + uint32_t slotIndex; + uint32_t resourceIdentifier; + wchar_t name[64]; +}FfxResourceBinding; + +/// A structure encapsulating a single pass of an algorithm. +typedef struct FfxPipelineState { + + FfxRootSignature rootSignature; ///< The pipelines rootSignature + FfxPipeline pipeline; ///< The pipeline object + uint32_t uavCount; ///< Count of UAVs used in this pipeline + uint32_t srvCount; ///< Count of SRVs used in this pipeline + uint32_t constCount; ///< Count of constant buffers used in this pipeline + + FfxResourceBinding uavResourceBindings[FFX_MAX_NUM_UAVS]; ///< Array of ResourceIdentifiers bound as UAVs + FfxResourceBinding srvResourceBindings[FFX_MAX_NUM_SRVS]; ///< Array of ResourceIdentifiers bound as SRVs + FfxResourceBinding cbResourceBindings[FFX_MAX_NUM_CONST_BUFFERS]; ///< Array of ResourceIdentifiers bound as CBs +} FfxPipelineState; + +/// A structure containing the data required to create a resource. +typedef struct FfxCreateResourceDescription { + + FfxHeapType heapType; ///< The heap type to hold the resource, typically FFX_HEAP_TYPE_DEFAULT. + FfxResourceDescription resourceDescription; ///< A resource description. + FfxResourceStates initalState; ///< The initial resource state. + uint32_t initDataSize; ///< Size of initial data buffer. + void* initData; ///< Buffer containing data to fill the resource. + const wchar_t* name; ///< Name of the resource. + FfxResourceUsage usage; ///< Resource usage flags. + uint32_t id; ///< Internal resource ID. +} FfxCreateResourceDescription; + +/// A structure containing the description used to create a +/// FfxPipeline structure. +/// +/// A pipeline is the name given to a shader and the collection of state that +/// is required to dispatch it. In the context of FSR2 and its architecture +/// this means that a FfxPipelineDescription will map to either a +/// monolithic object in an explicit API (such as a +/// PipelineStateObject in DirectX 12). Or a shader and some +/// ancillary API objects (in something like DirectX 11). +/// +/// The contextFlags field contains a copy of the flags passed +/// to ffxFsr2ContextCreate via the flags field of +/// the FfxFsr2InitializationParams structure. These flags are +/// used to determine which permutation of a pipeline for a specific +/// FfxFsr2Pass should be used to implement the features required +/// by each application, as well as to acheive the best performance on specific +/// target hardware configurations. +/// +/// When using one of the provided backends for FSR2 (such as DirectX 12 or +/// Vulkan) the data required to create a pipeline is compiled offline and +/// included into the backend library that you are using. For cases where the +/// backend interface is overriden by providing custom callback function +/// implementations care should be taken to respect the contents of the +/// contextFlags field in order to correctly support the options +/// provided by FSR2, and acheive best performance. +/// +/// @ingroup FSR2 +typedef struct FfxPipelineDescription { + + uint32_t contextFlags; ///< A collection of FfxFsr2InitializationFlagBits which were passed to the context. + FfxFilterType* samplers; ///< Array of static samplers. + size_t samplerCount; ///< The number of samples contained inside samplers. + const uint32_t* rootConstantBufferSizes; ///< Array containing the sizes of the root constant buffers (count of 32 bit elements). + uint32_t rootConstantBufferCount; ///< The number of root constants contained within rootConstantBufferSizes. +} FfxPipelineDescription; + +/// A structure containing a constant buffer. +typedef struct FfxConstantBuffer { + + uint32_t uint32Size; ///< Size of 32 bit chunks used in the constant buffer + uint32_t data[FFX_MAX_CONST_SIZE]; ///< Constant buffer data +}FfxConstantBuffer; + +/// A structure describing a clear render job. +typedef struct FfxClearFloatJobDescription { + + float color[4]; ///< The clear color of the resource. + FfxResourceInternal target; ///< The resource to be cleared. +} FfxClearFloatJobDescription; + +/// A structure describing a compute render job. +typedef struct FfxComputeJobDescription { + + FfxPipelineState pipeline; ///< Compute pipeline for the render job. + uint32_t dimensions[3]; ///< Dispatch dimensions. + FfxResourceInternal srvs[FFX_MAX_NUM_SRVS]; ///< SRV resources to be bound in the compute job. + wchar_t srvNames[FFX_MAX_NUM_SRVS][64]; + FfxResourceInternal uavs[FFX_MAX_NUM_UAVS]; ///< UAV resources to be bound in the compute job. + uint32_t uavMip[FFX_MAX_NUM_UAVS]; ///< Mip level of UAV resources to be bound in the compute job. + wchar_t uavNames[FFX_MAX_NUM_UAVS][64]; + FfxConstantBuffer cbs[FFX_MAX_NUM_CONST_BUFFERS]; ///< Constant buffers to be bound in the compute job. + wchar_t cbNames[FFX_MAX_NUM_CONST_BUFFERS][64]; +} FfxComputeJobDescription; + +/// A structure describing a copy render job. +typedef struct FfxCopyJobDescription +{ + FfxResourceInternal src; ///< Source resource for the copy. + FfxResourceInternal dst; ///< Destination resource for the copy. +} FfxCopyJobDescription; + +/// A structure describing a single render job. +typedef struct FfxGpuJobDescription{ + + FfxGpuJobType jobType; ///< Type of the job. + + union { + FfxClearFloatJobDescription clearJobDescriptor; ///< Clear job descriptor. Valid when jobType is FFX_RENDER_JOB_CLEAR_FLOAT. + FfxCopyJobDescription copyJobDescriptor; ///< Copy job descriptor. Valid when jobType is FFX_RENDER_JOB_COPY. + FfxComputeJobDescription computeJobDescriptor; ///< Compute job descriptor. Valid when jobType is FFX_RENDER_JOB_COMPUTE. + }; +} FfxGpuJobDescription; + +#ifdef __cplusplus +} +#endif // #ifdef __cplusplus diff --git a/crates/fsr/fsr/include/ffx_util.h b/crates/fsr/fsr/include/ffx_util.h new file mode 100644 index 0000000000000..aca9183838218 --- /dev/null +++ b/crates/fsr/fsr/include/ffx_util.h @@ -0,0 +1,78 @@ +// This file is part of the FidelityFX SDK. +// +// Copyright (c) 2022 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#pragma once + +#include "ffx_types.h" + +/// The value of Pi. +const float FFX_PI = 3.141592653589793f; + +/// An epsilon value for floating point numbers. +const float FFX_EPSILON = 1e-06f; + +/// Helper macro to create the version number. +#define FFX_MAKE_VERSION(major, minor, patch) ((major << 22) | (minor << 12) | patch) + +///< Use this to specify no version. +#define FFX_UNSPECIFIED_VERSION 0xFFFFAD00 + +/// Helper macro to avoid warnings about unused variables. +#define FFX_UNUSED(x) ((void)(x)) + +/// Helper macro to align an integer to the specified power of 2 boundary +#define FFX_ALIGN_UP(x, y) (((x) + ((y)-1)) & ~((y)-1)) + +/// Helper macro to check if a value is aligned. +#define FFX_IS_ALIGNED(x) (((x) != 0) && ((x) & ((x)-1))) + +/// Helper macro to stringify a value. +#define FFX_STR(s) FFX_XSTR(s) +#define FFX_XSTR(s) #s + +/// Helper macro to forward declare a structure. +#define FFX_FORWARD_DECLARE(x) typedef struct x x + +/// Helper macro to return the maximum of two values. +#define FFX_MAXIMUM(x, y) (((x) > (y)) ? (x) : (y)) + +/// Helper macro to return the minimum of two values. +#define FFX_MINIMUM(x, y) (((x) < (y)) ? (x) : (y)) + +/// Helper macro to do safe free on a pointer. +#define FFX_SAFE_FREE(x) \ + if (x) \ + free(x) + +/// Helper macro to return the abs of an integer value. +#define FFX_ABSOLUTE(x) (((x) < 0) ? (-(x)) : (x)) + +/// Helper macro to return sign of a value. +#define FFX_SIGN(x) (((x) < 0) ? -1 : 1) + +/// Helper macro to work out the number of elements in an array. +#define FFX_ARRAY_ELEMENTS(x) (int32_t)((sizeof(x) / sizeof(0 [x])) / ((size_t)(!(sizeof(x) % sizeof(0 [x]))))) + +/// The maximum length of a path that can be specified to the FidelityFX API. +#define FFX_MAXIMUM_PATH (260) + +/// Helper macro to check if the specified key is set in a bitfield. +#define FFX_CONTAINS_FLAG(options, key) ((options & key) == key) diff --git a/crates/fsr/fsr/include/shaders/ffx_fsr2_common.h b/crates/fsr/fsr/include/shaders/ffx_fsr2_common.h new file mode 100644 index 0000000000000..7f6acf2bb8f53 --- /dev/null +++ b/crates/fsr/fsr/include/shaders/ffx_fsr2_common.h @@ -0,0 +1,422 @@ +// This file is part of the FidelityFX SDK. +// +// Copyright (c) 2022 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#if !defined(FFX_FSR2_COMMON_H) +#define FFX_FSR2_COMMON_H + +#if defined(FFX_CPU) || defined(FFX_GPU) +//Locks +#define LOCK_LIFETIME_REMAINING 0 +#define LOCK_TEMPORAL_LUMA 1 +#define LOCK_TRUST 2 +#endif // #if defined(FFX_CPU) || defined(FFX_GPU) + +#if defined(FFX_GPU) +FFX_STATIC const FfxFloat32 FSR2_EPSILON = 1e-03f; +FFX_STATIC const FfxFloat32 FSR2_TONEMAP_EPSILON = 1e-03f; +FFX_STATIC const FfxFloat32 FSR2_FLT_MAX = 3.402823466e+38f; +FFX_STATIC const FfxFloat32 FSR2_FLT_MIN = 1.175494351e-38f; + +// treat vector truncation warnings as errors +#pragma warning(error: 3206) + +// suppress warnings +#pragma warning(disable: 3205) // conversion from larger type to smaller +#pragma warning(disable: 3571) // in ffxPow(f, e), f could be negative + +// Reconstructed depth usage +FFX_STATIC const FfxFloat32 reconstructedDepthBilinearWeightThreshold = 0.05f; + +// Accumulation +FFX_STATIC const FfxFloat32 averageLanczosWeightPerFrame = 0.74f; // Average lanczos weight for jitter accumulated samples +FFX_STATIC const FfxFloat32 accumulationMaxOnMotion = 4.0f; + +// Auto exposure +FFX_STATIC const FfxFloat32 resetAutoExposureAverageSmoothing = 1e8f; + +struct LockState +{ + FfxBoolean NewLock; //Set for both unique new and re-locked new + FfxBoolean WasLockedPrevFrame; //Set to identify if the pixel was already locked (relock) +}; + +FfxFloat32 GetNormalizedRemainingLockLifetime(FfxFloat32x3 fLockStatus) +{ + const FfxFloat32 fTrust = fLockStatus[LOCK_TRUST]; + + return ffxSaturate(fLockStatus[LOCK_LIFETIME_REMAINING] - LockInitialLifetime()) / LockInitialLifetime() * fTrust; +} + +#if FFX_HALF +FFX_MIN16_F GetNormalizedRemainingLockLifetime(FFX_MIN16_F3 fLockStatus) +{ + const FFX_MIN16_F fTrust = fLockStatus[LOCK_TRUST]; + const FFX_MIN16_F fInitialLockLifetime = FFX_MIN16_F(LockInitialLifetime()); + + return ffxSaturate(fLockStatus[LOCK_LIFETIME_REMAINING] - fInitialLockLifetime) / fInitialLockLifetime * fTrust; +} +#endif + +void InitializeNewLockSample(FFX_PARAMETER_OUT FfxFloat32x3 fLockStatus) +{ + fLockStatus = FfxFloat32x3(0, 0, 1); // LOCK_TRUST to 1 +} + +#if FFX_HALF +void InitializeNewLockSample(FFX_PARAMETER_OUT FFX_MIN16_F3 fLockStatus) +{ + fLockStatus = FFX_MIN16_F3(0, 0, 1); // LOCK_TRUST to 1 +} +#endif + + +void KillLock(FFX_PARAMETER_INOUT FfxFloat32x3 fLockStatus) +{ + fLockStatus[LOCK_LIFETIME_REMAINING] = 0; +} + +#if FFX_HALF +void KillLock(FFX_PARAMETER_INOUT FFX_MIN16_F3 fLockStatus) +{ + fLockStatus[LOCK_LIFETIME_REMAINING] = FFX_MIN16_F(0); +} +#endif + +struct RectificationBoxData +{ + FfxFloat32x3 boxCenter; + FfxFloat32x3 boxVec; + FfxFloat32x3 aabbMin; + FfxFloat32x3 aabbMax; +}; +#if FFX_HALF +struct RectificationBoxDataMin16 +{ + FFX_MIN16_F3 boxCenter; + FFX_MIN16_F3 boxVec; + FFX_MIN16_F3 aabbMin; + FFX_MIN16_F3 aabbMax; +}; +#endif + +struct RectificationBox +{ + RectificationBoxData data_; + FfxFloat32 fBoxCenterWeight; +}; +#if FFX_HALF +struct RectificationBoxMin16 +{ + RectificationBoxDataMin16 data_; + FFX_MIN16_F fBoxCenterWeight; +}; +#endif + +void RectificationBoxReset(FFX_PARAMETER_INOUT RectificationBox rectificationBox, const FfxFloat32x3 initialColorSample) +{ + rectificationBox.fBoxCenterWeight = FfxFloat32(0); + + rectificationBox.data_.boxCenter = FfxFloat32x3(0, 0, 0); + rectificationBox.data_.boxVec = FfxFloat32x3(0, 0, 0); + rectificationBox.data_.aabbMin = initialColorSample; + rectificationBox.data_.aabbMax = initialColorSample; +} +#if FFX_HALF +void RectificationBoxReset(FFX_PARAMETER_INOUT RectificationBoxMin16 rectificationBox, const FFX_MIN16_F3 initialColorSample) +{ + rectificationBox.fBoxCenterWeight = FFX_MIN16_F(0); + + rectificationBox.data_.boxCenter = FFX_MIN16_F3(0, 0, 0); + rectificationBox.data_.boxVec = FFX_MIN16_F3(0, 0, 0); + rectificationBox.data_.aabbMin = initialColorSample; + rectificationBox.data_.aabbMax = initialColorSample; +} +#endif + +void RectificationBoxAddSample(FFX_PARAMETER_INOUT RectificationBox rectificationBox, const FfxFloat32x3 colorSample, const FfxFloat32 fSampleWeight) +{ + rectificationBox.data_.aabbMin = ffxMin(rectificationBox.data_.aabbMin, colorSample); + rectificationBox.data_.aabbMax = ffxMax(rectificationBox.data_.aabbMax, colorSample); + FfxFloat32x3 weightedSample = colorSample * fSampleWeight; + rectificationBox.data_.boxCenter += weightedSample; + rectificationBox.data_.boxVec += colorSample * weightedSample; + rectificationBox.fBoxCenterWeight += fSampleWeight; +} +#if FFX_HALF +void RectificationBoxAddSample(FFX_PARAMETER_INOUT RectificationBoxMin16 rectificationBox, const FFX_MIN16_F3 colorSample, const FFX_MIN16_F fSampleWeight) +{ + rectificationBox.data_.aabbMin = ffxMin(rectificationBox.data_.aabbMin, colorSample); + rectificationBox.data_.aabbMax = ffxMax(rectificationBox.data_.aabbMax, colorSample); + FFX_MIN16_F3 weightedSample = colorSample * fSampleWeight; + rectificationBox.data_.boxCenter += weightedSample; + rectificationBox.data_.boxVec += colorSample * weightedSample; + rectificationBox.fBoxCenterWeight += fSampleWeight; +} +#endif + +void RectificationBoxComputeVarianceBoxData(FFX_PARAMETER_INOUT RectificationBox rectificationBox) +{ + rectificationBox.fBoxCenterWeight = (abs(rectificationBox.fBoxCenterWeight) > FfxFloat32(FSR2_EPSILON) ? rectificationBox.fBoxCenterWeight : FfxFloat32(1.f)); + rectificationBox.data_.boxCenter /= rectificationBox.fBoxCenterWeight; + rectificationBox.data_.boxVec /= rectificationBox.fBoxCenterWeight; + FfxFloat32x3 stdDev = sqrt(abs(rectificationBox.data_.boxVec - rectificationBox.data_.boxCenter * rectificationBox.data_.boxCenter)); + rectificationBox.data_.boxVec = stdDev; +} +#if FFX_HALF +void RectificationBoxComputeVarianceBoxData(FFX_PARAMETER_INOUT RectificationBoxMin16 rectificationBox) +{ + rectificationBox.fBoxCenterWeight = (abs(rectificationBox.fBoxCenterWeight) > FFX_MIN16_F(FSR2_EPSILON) ? rectificationBox.fBoxCenterWeight : FFX_MIN16_F(1.f)); + rectificationBox.data_.boxCenter /= rectificationBox.fBoxCenterWeight; + rectificationBox.data_.boxVec /= rectificationBox.fBoxCenterWeight; + FFX_MIN16_F3 stdDev = sqrt(abs(rectificationBox.data_.boxVec - rectificationBox.data_.boxCenter * rectificationBox.data_.boxCenter)); + rectificationBox.data_.boxVec = stdDev; +} +#endif + +RectificationBoxData RectificationBoxGetData(FFX_PARAMETER_INOUT RectificationBox rectificationBox) +{ + return rectificationBox.data_; +} +#if FFX_HALF +RectificationBoxDataMin16 RectificationBoxGetData(FFX_PARAMETER_INOUT RectificationBoxMin16 rectificationBox) +{ + return rectificationBox.data_; +} +#endif + +FfxFloat32x3 SafeRcp3(FfxFloat32x3 v) +{ + return (all(FFX_NOT_EQUAL(v, FfxFloat32x3(0, 0, 0)))) ? (FfxFloat32x3(1, 1, 1) / v) : FfxFloat32x3(0, 0, 0); +} +#if FFX_HALF +FFX_MIN16_F3 SafeRcp3(FFX_MIN16_F3 v) +{ + return (all(FFX_NOT_EQUAL(v, FFX_MIN16_F3(0, 0, 0)))) ? (FFX_MIN16_F3(1, 1, 1) / v) : FFX_MIN16_F3(0, 0, 0); +} +#endif + +FfxFloat32 MinDividedByMax(const FfxFloat32 v0, const FfxFloat32 v1) +{ + const FfxFloat32 m = ffxMax(v0, v1); + return m != 0 ? ffxMin(v0, v1) / m : 0; +} + +#if FFX_HALF +FFX_MIN16_F MinDividedByMax(const FFX_MIN16_F v0, const FFX_MIN16_F v1) +{ + const FFX_MIN16_F m = ffxMax(v0, v1); + return m != FFX_MIN16_F(0) ? ffxMin(v0, v1) / m : FFX_MIN16_F(0); +} +#endif + +FfxFloat32x3 YCoCgToRGB(FfxFloat32x3 fYCoCg) +{ + FfxFloat32x3 fRgb; + + fYCoCg.yz -= FfxFloat32x2(0.5f, 0.5f); // [0,1] -> [-0.5,0.5] + + fRgb = FfxFloat32x3( + fYCoCg.x + fYCoCg.y - fYCoCg.z, + fYCoCg.x + fYCoCg.z, + fYCoCg.x - fYCoCg.y - fYCoCg.z); + + return fRgb; +} +#if FFX_HALF +FFX_MIN16_F3 YCoCgToRGB(FFX_MIN16_F3 fYCoCg) +{ + FFX_MIN16_F3 fRgb; + + fYCoCg.yz -= FFX_MIN16_F2(0.5f, 0.5f); // [0,1] -> [-0.5,0.5] + + fRgb = FFX_MIN16_F3( + fYCoCg.x + fYCoCg.y - fYCoCg.z, + fYCoCg.x + fYCoCg.z, + fYCoCg.x - fYCoCg.y - fYCoCg.z); + + return fRgb; +} +#endif + +FfxFloat32x3 RGBToYCoCg(FfxFloat32x3 fRgb) +{ + FfxFloat32x3 fYCoCg; + + fYCoCg = FfxFloat32x3( + 0.25f * fRgb.r + 0.5f * fRgb.g + 0.25f * fRgb.b, + 0.5f * fRgb.r - 0.5f * fRgb.b, + -0.25f * fRgb.r + 0.5f * fRgb.g - 0.25f * fRgb.b); + + fYCoCg.yz += FfxFloat32x2(0.5f, 0.5f); // [-0.5,0.5] -> [0,1] + + return fYCoCg; +} +#if FFX_HALF +FFX_MIN16_F3 RGBToYCoCg(FFX_MIN16_F3 fRgb) +{ + FFX_MIN16_F3 fYCoCg; + + fYCoCg = FFX_MIN16_F3( + 0.25 * fRgb.r + 0.5 * fRgb.g + 0.25 * fRgb.b, + 0.5 * fRgb.r - 0.5 * fRgb.b, + -0.25 * fRgb.r + 0.5 * fRgb.g - 0.25 * fRgb.b); + + fYCoCg.yz += FFX_MIN16_F2(0.5, 0.5); // [-0.5,0.5] -> [0,1] + + return fYCoCg; +} +#endif + +FfxFloat32 RGBToLuma(FfxFloat32x3 fLinearRgb) +{ + return dot(fLinearRgb, FfxFloat32x3(0.2126f, 0.7152f, 0.0722f)); +} +#if FFX_HALF +FFX_MIN16_F RGBToLuma(FFX_MIN16_F3 fLinearRgb) +{ + return dot(fLinearRgb, FFX_MIN16_F3(0.2126f, 0.7152f, 0.0722f)); +} +#endif + +FfxFloat32 RGBToPerceivedLuma(FfxFloat32x3 fLinearRgb) +{ + FfxFloat32 fLuminance = RGBToLuma(fLinearRgb); + + FfxFloat32 fPercievedLuminance = 0; + if (fLuminance <= 216.0f / 24389.0f) { + fPercievedLuminance = fLuminance * (24389.0f / 27.0f); + } else { + fPercievedLuminance = ffxPow(fLuminance, 1.0f / 3.0f) * 116.0f - 16.0f; + } + + return fPercievedLuminance * 0.01f; +} +#if FFX_HALF +FFX_MIN16_F RGBToPerceivedLuma(FFX_MIN16_F3 fLinearRgb) +{ + FFX_MIN16_F fLuminance = RGBToLuma(fLinearRgb); + + FFX_MIN16_F fPercievedLuminance = FFX_MIN16_F(0); + if (fLuminance <= FFX_MIN16_F(216.0f / 24389.0f)) { + fPercievedLuminance = fLuminance * FFX_MIN16_F(24389.0f / 27.0f); + } + else { + fPercievedLuminance = ffxPow(fLuminance, FFX_MIN16_F(1.0f / 3.0f)) * FFX_MIN16_F(116.0f) - FFX_MIN16_F(16.0f); + } + + return fPercievedLuminance * FFX_MIN16_F(0.01f); +} +#endif + + +FfxFloat32x3 Tonemap(FfxFloat32x3 fRgb) +{ + return fRgb / (ffxMax(ffxMax(0.f, fRgb.r), ffxMax(fRgb.g, fRgb.b)) + 1.f).xxx; +} + +FfxFloat32x3 InverseTonemap(FfxFloat32x3 fRgb) +{ + return fRgb / ffxMax(FSR2_TONEMAP_EPSILON, 1.f - ffxMax(fRgb.r, ffxMax(fRgb.g, fRgb.b))).xxx; +} + +#if FFX_HALF +FFX_MIN16_F3 Tonemap(FFX_MIN16_F3 fRgb) +{ + return fRgb / (ffxMax(ffxMax(FFX_MIN16_F(0.f), fRgb.r), ffxMax(fRgb.g, fRgb.b)) + FFX_MIN16_F(1.f)).xxx; +} + +FFX_MIN16_F3 InverseTonemap(FFX_MIN16_F3 fRgb) +{ + return fRgb / ffxMax(FFX_MIN16_F(FSR2_TONEMAP_EPSILON), FFX_MIN16_F(1.f) - ffxMax(fRgb.r, ffxMax(fRgb.g, fRgb.b))).xxx; +} +#endif + +FfxInt32x2 ClampLoad(FfxInt32x2 iPxSample, FfxInt32x2 iPxOffset, FfxInt32x2 iTextureSize) +{ + return clamp(iPxSample + iPxOffset, FfxInt32x2(0, 0), iTextureSize - FfxInt32x2(1, 1)); +} +#if FFX_HALF +FFX_MIN16_I2 ClampLoad(FFX_MIN16_I2 iPxSample, FFX_MIN16_I2 iPxOffset, FFX_MIN16_I2 iTextureSize) +{ + return clamp(iPxSample + iPxOffset, FFX_MIN16_I2(0, 0), iTextureSize - FFX_MIN16_I2(1, 1)); +} +#endif + +FfxBoolean IsOnScreen(FfxInt32x2 pos, FfxInt32x2 size) +{ + return all(FFX_GREATER_THAN_EQUAL(pos, FfxInt32x2(0, 0))) && all(FFX_LESS_THAN(pos, size)); +} +#if FFX_HALF +FfxBoolean IsOnScreen(FFX_MIN16_I2 pos, FFX_MIN16_I2 size) +{ + return all(FFX_GREATER_THAN_EQUAL(pos, FFX_MIN16_I2(0, 0))) && all(FFX_LESS_THAN(pos, size)); +} +#endif + +FfxFloat32 ComputeAutoExposureFromLavg(FfxFloat32 Lavg) +{ + Lavg = exp(Lavg); + + const FfxFloat32 S = 100.0f; //ISO arithmetic speed + const FfxFloat32 K = 12.5f; + FfxFloat32 ExposureISO100 = log2((Lavg * S) / K); + + const FfxFloat32 q = 0.65f; + FfxFloat32 Lmax = (78.0f / (q * S)) * ffxPow(2.0f, ExposureISO100); + + return 1 / Lmax; +} +#if FFX_HALF +FFX_MIN16_F ComputeAutoExposureFromLavg(FFX_MIN16_F Lavg) +{ + Lavg = exp(Lavg); + + const FFX_MIN16_F S = FFX_MIN16_F(100.0f); //ISO arithmetic speed + const FFX_MIN16_F K = FFX_MIN16_F(12.5f); + const FFX_MIN16_F ExposureISO100 = log2((Lavg * S) / K); + + const FFX_MIN16_F q = FFX_MIN16_F(0.65f); + const FFX_MIN16_F Lmax = (FFX_MIN16_F(78.0f) / (q * S)) * ffxPow(FFX_MIN16_F(2.0f), ExposureISO100); + + return FFX_MIN16_F(1) / Lmax; +} +#endif + +FfxInt32x2 ComputeHrPosFromLrPos(FfxInt32x2 iPxLrPos) +{ + FfxFloat32x2 fSrcJitteredPos = FfxFloat32x2(iPxLrPos) + 0.5f - Jitter(); + FfxFloat32x2 fLrPosInHr = (fSrcJitteredPos / RenderSize()) * DisplaySize(); + FfxFloat32x2 fHrPos = floor(fLrPosInHr) + 0.5f; + return FfxInt32x2(fHrPos); +} +#if FFX_HALF +FFX_MIN16_I2 ComputeHrPosFromLrPos(FFX_MIN16_I2 iPxLrPos) +{ + FFX_MIN16_F2 fSrcJitteredPos = FFX_MIN16_F2(iPxLrPos) + FFX_MIN16_F(0.5f) - FFX_MIN16_F2(Jitter()); + FFX_MIN16_F2 fLrPosInHr = (fSrcJitteredPos / FFX_MIN16_F2(RenderSize())) * FFX_MIN16_F2(DisplaySize()); + FFX_MIN16_F2 fHrPos = floor(fLrPosInHr) + FFX_MIN16_F(0.5); + return FFX_MIN16_I2(fHrPos); +} +#endif + +#endif // #if defined(FFX_GPU) + +#endif //!defined(FFX_FSR2_COMMON_H) diff --git a/crates/fsr/fsr/include/shaders/ffx_fsr2_resources.h b/crates/fsr/fsr/include/shaders/ffx_fsr2_resources.h new file mode 100644 index 0000000000000..89734f6219194 --- /dev/null +++ b/crates/fsr/fsr/include/shaders/ffx_fsr2_resources.h @@ -0,0 +1,88 @@ +// This file is part of the FidelityFX SDK. +// +// Copyright (c) 2022 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#ifndef FFX_FSR2_RESOURCES_H +#define FFX_FSR2_RESOURCES_H + +#if defined(FFX_CPU) || defined(FFX_GPU) +#define FFX_FSR2_RESOURCE_IDENTIFIER_NULL 0 +#define FFX_FSR2_RESOURCE_IDENTIFIER_INPUT_COLOR 1 +#define FFX_FSR2_RESOURCE_IDENTIFIER_INPUT_MOTION_VECTORS 2 +#define FFX_FSR2_RESOURCE_IDENTIFIER_INPUT_DEPTH 3 +#define FFX_FSR2_RESOURCE_IDENTIFIER_INPUT_EXPOSURE 4 +#define FFX_FSR2_RESOURCE_IDENTIFIER_INPUT_REACTIVE_MASK 5 +#define FFX_FSR2_RESOURCE_IDENTIFIER_INPUT_TRANSPARENCY_AND_COMPOSITION_MASK 6 +#define FFX_FSR2_RESOURCE_IDENTIFIER_RECONSTRUCTED_PREVIOUS_NEAREST_DEPTH 7 +#define FFX_FSR2_RESOURCE_IDENTIFIER_DILATED_MOTION_VECTORS 8 +#define FFX_FSR2_RESOURCE_IDENTIFIER_DILATED_DEPTH 9 +#define FFX_FSR2_RESOURCE_IDENTIFIER_INTERNAL_UPSCALED_COLOR 10 +#define FFX_FSR2_RESOURCE_IDENTIFIER_LOCK_STATUS 11 +#define FFX_FSR2_RESOURCE_IDENTIFIER_DEPTH_CLIP 12 +#define FFX_FSR2_RESOURCE_IDENTIFIER_PREPARED_INPUT_COLOR 13 +#define FFX_FSR2_RESOURCE_IDENTIFIER_LUMA_HISTORY 14 +#define FFX_FSR2_RESOURCE_IDENTIFIER_DEBUG_OUTPUT 15 +#define FFX_FSR2_RESOURCE_IDENTIFIER_LANCZOS_LUT 16 +#define FFX_FSR2_RESOURCE_IDENTIFIER_SPD_ATOMIC_COUNT 17 +#define FFX_FSR2_RESOURCE_IDENTIFIER_UPSCALED_OUTPUT 18 +#define FFX_FSR2_RESOURCE_IDENTIFIER_RCAS_INPUT 19 +#define FFX_FSR2_RESOURCE_IDENTIFIER_LOCK_STATUS_1 20 +#define FFX_FSR2_RESOURCE_IDENTIFIER_LOCK_STATUS_2 21 +#define FFX_FSR2_RESOURCE_IDENTIFIER_INTERNAL_UPSCALED_COLOR_1 22 +#define FFX_FSR2_RESOURCE_IDENTIFIER_INTERNAL_UPSCALED_COLOR_2 23 +#define FFX_FSR2_RESOURCE_IDENTIFIER_INTERNAL_DEFAULT_REACTIVITY 24 +#define FFX_FSR2_RESOURCE_IDENTIFIER_INTERNAL_DEFAULT_TRANSPARENCY_AND_COMPOSITION 25 +#define FFX_FSR2_RESOURCE_IDENTITIER_UPSAMPLE_MAXIMUM_BIAS_LUT 26 +#define FFX_FSR2_RESOURCE_IDENTIFIER_DILATED_REACTIVE_MASKS 27 +#define FFX_FSR2_RESOURCE_IDENTIFIER_AUTO_EXPOSURE 28 // same as FFX_FSR2_RESOURCE_IDENTIFIER_AUTO_EXPOSURE_MIPMAP_0 +#define FFX_FSR2_RESOURCE_IDENTIFIER_AUTO_EXPOSURE_MIPMAP_0 28 +#define FFX_FSR2_RESOURCE_IDENTIFIER_AUTO_EXPOSURE_MIPMAP_1 29 +#define FFX_FSR2_RESOURCE_IDENTIFIER_AUTO_EXPOSURE_MIPMAP_2 30 +#define FFX_FSR2_RESOURCE_IDENTIFIER_AUTO_EXPOSURE_MIPMAP_3 31 +#define FFX_FSR2_RESOURCE_IDENTIFIER_AUTO_EXPOSURE_MIPMAP_4 32 +#define FFX_FSR2_RESOURCE_IDENTIFIER_AUTO_EXPOSURE_MIPMAP_5 33 +#define FFX_FSR2_RESOURCE_IDENTIFIER_AUTO_EXPOSURE_MIPMAP_6 34 +#define FFX_FSR2_RESOURCE_IDENTIFIER_AUTO_EXPOSURE_MIPMAP_7 35 +#define FFX_FSR2_RESOURCE_IDENTIFIER_AUTO_EXPOSURE_MIPMAP_8 36 +#define FFX_FSR2_RESOURCE_IDENTIFIER_AUTO_EXPOSURE_MIPMAP_9 37 +#define FFX_FSR2_RESOURCE_IDENTIFIER_AUTO_EXPOSURE_MIPMAP_10 38 +#define FFX_FSR2_RESOURCE_IDENTIFIER_AUTO_EXPOSURE_MIPMAP_11 39 +#define FFX_FSR2_RESOURCE_IDENTIFIER_AUTO_EXPOSURE_MIPMAP_12 40 +#define FFX_FSR2_RESOURCE_IDENTIFIER_INTERNAL_DEFAULT_EXPOSURE 41 +#define FFX_FSR2_RESOURCE_IDENTIFIER_EXPOSURE 42 + +// Shading change detection mip level setting, value must be in the range [FFX_FSR2_RESOURCE_IDENTIFIER_AUTO_EXPOSURE_MIPMAP_0, FFX_FSR2_RESOURCE_IDENTIFIER_AUTO_EXPOSURE_MIPMAP_12] +#define FFX_FSR2_RESOURCE_IDENTIFIER_AUTO_EXPOSURE_MIPMAP_SHADING_CHANGE FFX_FSR2_RESOURCE_IDENTIFIER_AUTO_EXPOSURE_MIPMAP_4 +#define FFX_FSR2_SHADING_CHANGE_MIP_LEVEL (FFX_FSR2_RESOURCE_IDENTIFIER_AUTO_EXPOSURE_MIPMAP_SHADING_CHANGE - FFX_FSR2_RESOURCE_IDENTIFIER_AUTO_EXPOSURE) + +#define FFX_FSR2_RESOURCE_IDENTIFIER_COUNT 43 + +#define FFX_FSR2_CONSTANTBUFFER_IDENTIFIER_FSR2 0 +#define FFX_FSR2_CONSTANTBUFFER_IDENTIFIER_SPD 1 +#define FFX_FSR2_CONSTANTBUFFER_IDENTIFIER_RCAS 2 + +#define FFX_FSR2_AUTOREACTIVEFLAGS_APPLY_TONEMAP 1 +#define FFX_FSR2_AUTOREACTIVEFLAGS_APPLY_INVERSETONEMAP 2 +#define FFX_FSR2_AUTOREACTIVEFLAGS_APPLY_THRESHOLD 4 +#define FFX_FSR2_AUTOREACTIVEFLAGS_USE_COMPONENTS_MAX 8 + +#endif // #if defined(FFX_CPU) || defined(FFX_GPU) + +#endif //!defined( FFX_FSR2_RESOURCES_H ) diff --git a/crates/fsr/fsr/include/vk/ffx_fsr2_vk.h b/crates/fsr/fsr/include/vk/ffx_fsr2_vk.h new file mode 100644 index 0000000000000..e0e226a9f4e3f --- /dev/null +++ b/crates/fsr/fsr/include/vk/ffx_fsr2_vk.h @@ -0,0 +1,158 @@ +// This file is part of the FidelityFX SDK. +// +// Copyright (c) 2022 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +// @defgroup VK + +#pragma once + +#include +#include "../ffx_fsr2_interface.h" + +#if defined(__cplusplus) +extern "C" { +#endif // #if defined(__cplusplus) + + /// Query how much memory is required for the Vulkan backend's scratch buffer. + /// + /// @returns + /// The size (in bytes) of the required scratch memory buffer for the VK backend. + FFX_API size_t ffxFsr2GetScratchMemorySizeVK(VkPhysicalDevice physicalDevice); + + /// Populate an interface with pointers for the VK backend. + /// + /// @param [out] fsr2Interface A pointer to a FfxFsr2Interface structure to populate with pointers. + /// @param [in] device A Vulkan device. + /// @param [in] scratchBuffer A pointer to a buffer of memory which can be used by the DirectX(R)12 backend. + /// @param [in] scratchBufferSize The size (in bytes) of the buffer pointed to by scratchBuffer. + /// @param [in] physicalDevice The Vulkan physical device that FSR 2.0 will be executed on. + /// @param [in] getDeviceProcAddr A function pointer to vkGetDeviceProcAddr which is used to obtain all the other Vulkan functions. + /// + /// @retval + /// FFX_OK The operation completed successfully. + /// @retval + /// FFX_ERROR_CODE_INVALID_POINTER The interface pointer was NULL. + /// + /// @ingroup FSR2 VK + FFX_API FfxErrorCode ffxFsr2GetInterfaceVK( + FfxFsr2Interface* outInterface, + void* scratchBuffer, + size_t scratchBufferSize, + VkPhysicalDevice physicalDevice, + PFN_vkGetDeviceProcAddr getDeviceProcAddr); + + /// Create a FfxFsr2Device from a VkDevice. + /// + /// @param [in] device A pointer to the Vulkan logical device. + /// + /// @returns + /// An abstract FidelityFX device. + /// + /// @ingroup FSR2 VK + FFX_API FfxDevice ffxGetDeviceVK(VkDevice device); + + /// Create a FfxCommandList from a VkCommandBuffer. + /// + /// @param [in] cmdBuf A pointer to the Vulkan command buffer. + /// + /// @returns + /// An abstract FidelityFX command list. + /// + /// @ingroup FSR2 VK + FFX_API FfxCommandList ffxGetCommandListVK(VkCommandBuffer cmdBuf); + + /// Create a FfxResource from a VkImage. + /// + /// @param [in] context A pointer to a FfxFsr2Context structure. + /// @param [in] imgVk A Vulkan image resource. + /// @param [in] imageView An image view of the given image resource. + /// @param [in] width The width of the image resource. + /// @param [in] height The height of the image resource. + /// @param [in] imgFormat The format of the image resource. + /// @param [in] name (optional) A name string to identify the resource in debug mode. + /// @param [in] state The state the resource is currently in. + /// + /// @returns + /// An abstract FidelityFX resources. + /// + /// @ingroup FSR2 VK + FFX_API FfxResource ffxGetTextureResourceVK(FfxFsr2Context* context, + VkImage imgVk, + VkImageView imageView, + uint32_t width, + uint32_t height, + VkFormat imgFormat, + wchar_t* name = nullptr, + FfxResourceStates state = FFX_RESOURCE_STATE_COMPUTE_READ); + + /// Create a FfxResource from a VkBuffer. + /// + /// @param [in] context A pointer to a FfxFsr2Context structure. + /// @param [in] bufVk A Vulkan buffer resource. + /// @param [in] size The size of the buffer resource. + /// @param [in] name (optional) A name string to identify the resource in debug mode. + /// @param [in] state The state the resource is currently in. + /// + /// @returns + /// An abstract FidelityFX resources. + /// + /// @ingroup FSR2 VK + FFX_API FfxResource ffxGetBufferResourceVK(FfxFsr2Context* context, + VkBuffer bufVk, + uint32_t size, + wchar_t* name = nullptr, + FfxResourceStates state = FFX_RESOURCE_STATE_COMPUTE_READ); + + /// Convert a FfxResource value to a VkImage. + /// + /// @param [in] context A pointer to a FfxFsr2Context structure. + /// @param [in] resId A resourceID. + /// + /// @returns + /// A VkImage. + /// + /// @ingroup FSR2 VK + FFX_API VkImage ffxGetVkImage(FfxFsr2Context* context, uint32_t resId); + + /// Convert a FfxResource value to a VkImageView. + /// + /// @param [in] context A pointer to a FfxFsr2Context structure. + /// @param [in] resId A resourceID. + /// + /// @returns + /// A VkImage. + /// + /// @ingroup FSR2 VK + FFX_API VkImageView ffxGetVkImageView(FfxFsr2Context* context, uint32_t resId); + + /// Convert a FfxResource value to a VkImageLayout. + /// + /// @param [in] context A pointer to a FfxFsr2Context structure. + /// @param [in] resId A resourceID. + /// + /// @returns + /// A VkImage. + /// + /// @ingroup FSR2 VK + FFX_API VkImageLayout ffxGetVkImageLayout(FfxFsr2Context* context, uint32_t resId); + +#if defined(__cplusplus) +} +#endif // #if defined(__cplusplus) \ No newline at end of file diff --git a/crates/fsr/fsr/include/vk/shaders/ffx_fsr2_shaders_vk.h b/crates/fsr/fsr/include/vk/shaders/ffx_fsr2_shaders_vk.h new file mode 100644 index 0000000000000..da581c771da3a --- /dev/null +++ b/crates/fsr/fsr/include/vk/shaders/ffx_fsr2_shaders_vk.h @@ -0,0 +1,65 @@ +// This file is part of the FidelityFX SDK. +// +// Copyright (c) 2022 Advanced Micro Devices, Inc. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#pragma once + +#include +#include "../../ffx_fsr2_interface.h" + +#if defined(__cplusplus) +extern "C" { +#endif // #if defined(__cplusplus) + + // A single shader blob and a description of its resources. + typedef struct Fsr2ShaderBlobVK { + + const uint8_t* data; // A pointer to the blob + const uint32_t size; // Size in bytes. + const uint32_t storageImageCount; // Number of storage images. + const uint32_t sampledImageCount; // Number of sampled images. + const uint32_t uniformBufferCount; // Number of uniform buffers. + const char** boundStorageImageNames; + const uint32_t* boundStorageImageBindings; // Pointer to an array of bound UAV resources. + const char** boundSampledImageNames; + const uint32_t* boundSampledImageBindings; // Pointer to an array of bound SRV resources. + const char** boundUniformBufferNames; + const uint32_t* boundUniformBufferBindings; // Pointer to an array of bound ConstantBuffers. + } Fsr2ShaderBlobVK; + + // The different options which contribute to permutations. + typedef enum Fs2ShaderPermutationOptionsVK { + + FSR2_SHADER_PERMUTATION_REPROJECT_USE_LANCZOS_TYPE = (1 << 0), // FFX_FSR2_OPTION_REPROJECT_USE_LANCZOS_TYPE + FSR2_SHADER_PERMUTATION_HDR_COLOR_INPUT = (1 << 1), // FFX_FSR2_OPTION_HDR_COLOR_INPUT + FSR2_SHADER_PERMUTATION_LOW_RES_MOTION_VECTORS = (1 << 2), // FFX_FSR2_OPTION_LOW_RESOLUTION_MOTION_VECTORS + FSR2_SHADER_PERMUTATION_JITTER_MOTION_VECTORS = (1 << 3), // FFX_FSR2_OPTION_JITTERED_MOTION_VECTORS + FSR2_SHADER_PERMUTATION_DEPTH_INVERTED = (1 << 4), // FFX_FSR2_OPTION_INVERTED_DEPTH + FSR2_SHADER_PERMUTATION_ENABLE_SHARPENING = (1 << 5), // FFX_FSR2_OPTION_APPLY_SHARPENING + FSR2_SHADER_PERMUTATION_FORCE_WAVE64 = (1 << 6), // doesn't map to a define, selects different table + FSR2_SHADER_PERMUTATION_ALLOW_FP16 = (1 << 7), // FFX_USE_16BIT + } Fs2ShaderPermutationOptionsVK; + + // Get a VK shader blob for the specified pass and permutation index. + Fsr2ShaderBlobVK fsr2GetPermutationBlobByIndex(FfxFsr2Pass passId, uint32_t permutationOptions); + +#if defined(__cplusplus) +} +#endif // #if defined(__cplusplus) diff --git a/crates/fsr/fsr/include/wrapper.h b/crates/fsr/fsr/include/wrapper.h new file mode 100644 index 0000000000000..730988851b8e4 --- /dev/null +++ b/crates/fsr/fsr/include/wrapper.h @@ -0,0 +1,2 @@ +#include "ffx_fsr2.h" +#include "vk/ffx_fsr2_vk.h" diff --git a/crates/fsr/fsr/lib/ffx_fsr2_api_vk_x64.lib b/crates/fsr/fsr/lib/ffx_fsr2_api_vk_x64.lib new file mode 100644 index 0000000000000..64988b501265e Binary files /dev/null and b/crates/fsr/fsr/lib/ffx_fsr2_api_vk_x64.lib differ diff --git a/crates/fsr/fsr/lib/ffx_fsr2_api_vk_x64d.lib b/crates/fsr/fsr/lib/ffx_fsr2_api_vk_x64d.lib new file mode 100644 index 0000000000000..690749ceab056 Binary files /dev/null and b/crates/fsr/fsr/lib/ffx_fsr2_api_vk_x64d.lib differ diff --git a/crates/fsr/fsr/lib/ffx_fsr2_api_x64.lib b/crates/fsr/fsr/lib/ffx_fsr2_api_x64.lib new file mode 100644 index 0000000000000..aa80c987ae0a0 Binary files /dev/null and b/crates/fsr/fsr/lib/ffx_fsr2_api_x64.lib differ diff --git a/crates/fsr/fsr/lib/ffx_fsr2_api_x64d.lib b/crates/fsr/fsr/lib/ffx_fsr2_api_x64d.lib new file mode 100644 index 0000000000000..7267d5c32d446 Binary files /dev/null and b/crates/fsr/fsr/lib/ffx_fsr2_api_x64d.lib differ diff --git a/crates/fsr/fsr/lib/libffx_fsr2_api_vk_x64.a b/crates/fsr/fsr/lib/libffx_fsr2_api_vk_x64.a new file mode 100644 index 0000000000000..862f725d7853c Binary files /dev/null and b/crates/fsr/fsr/lib/libffx_fsr2_api_vk_x64.a differ diff --git a/crates/fsr/fsr/lib/libffx_fsr2_api_vk_x64d.a b/crates/fsr/fsr/lib/libffx_fsr2_api_vk_x64d.a new file mode 100644 index 0000000000000..a4402b2b1ebc7 Binary files /dev/null and b/crates/fsr/fsr/lib/libffx_fsr2_api_vk_x64d.a differ diff --git a/crates/fsr/fsr/lib/libffx_fsr2_api_x64.a b/crates/fsr/fsr/lib/libffx_fsr2_api_x64.a new file mode 100644 index 0000000000000..f2eeca8c0093b Binary files /dev/null and b/crates/fsr/fsr/lib/libffx_fsr2_api_x64.a differ diff --git a/crates/fsr/fsr/lib/libffx_fsr2_api_x64d.a b/crates/fsr/fsr/lib/libffx_fsr2_api_x64d.a new file mode 100644 index 0000000000000..27417340877f1 Binary files /dev/null and b/crates/fsr/fsr/lib/libffx_fsr2_api_x64d.a differ diff --git a/crates/fsr/generate_bindings.sh b/crates/fsr/generate_bindings.sh new file mode 100755 index 0000000000000..2ab1a8d71b1f4 --- /dev/null +++ b/crates/fsr/generate_bindings.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +bindgen fsr/include/wrapper.h \ + --allowlist-item ".*[fF][fF][xX].*" \ + --blocklist-item ".*[vV]k.*" \ + -o src/bindings.rs \ + --no-layout-tests \ + -- \ + -x c++ \ + -fdeclspec \ + -I $VULKAN_SDK/include diff --git a/crates/fsr/src/bindings.rs b/crates/fsr/src/bindings.rs new file mode 100644 index 0000000000000..7ed7115f8d1b3 --- /dev/null +++ b/crates/fsr/src/bindings.rs @@ -0,0 +1,828 @@ +/* automatically generated by rust-bindgen 0.69.4 */ + +pub const FFX_MAX_NUM_SRVS: u32 = 16; +pub const FFX_MAX_NUM_UAVS: u32 = 8; +pub const FFX_MAX_NUM_CONST_BUFFERS: u32 = 2; +pub const FFX_MAX_CONST_SIZE: u32 = 64; +pub const FFX_UNSPECIFIED_VERSION: u32 = 4294946048; +pub const FFX_MAXIMUM_PATH: u32 = 260; +pub const FFX_FSR2_RESOURCE_IDENTIFIER_NULL: u32 = 0; +pub const FFX_FSR2_RESOURCE_IDENTIFIER_INPUT_COLOR: u32 = 1; +pub const FFX_FSR2_RESOURCE_IDENTIFIER_INPUT_MOTION_VECTORS: u32 = 2; +pub const FFX_FSR2_RESOURCE_IDENTIFIER_INPUT_DEPTH: u32 = 3; +pub const FFX_FSR2_RESOURCE_IDENTIFIER_INPUT_EXPOSURE: u32 = 4; +pub const FFX_FSR2_RESOURCE_IDENTIFIER_INPUT_REACTIVE_MASK: u32 = 5; +pub const FFX_FSR2_RESOURCE_IDENTIFIER_INPUT_TRANSPARENCY_AND_COMPOSITION_MASK: u32 = 6; +pub const FFX_FSR2_RESOURCE_IDENTIFIER_RECONSTRUCTED_PREVIOUS_NEAREST_DEPTH: u32 = 7; +pub const FFX_FSR2_RESOURCE_IDENTIFIER_DILATED_MOTION_VECTORS: u32 = 8; +pub const FFX_FSR2_RESOURCE_IDENTIFIER_DILATED_DEPTH: u32 = 9; +pub const FFX_FSR2_RESOURCE_IDENTIFIER_INTERNAL_UPSCALED_COLOR: u32 = 10; +pub const FFX_FSR2_RESOURCE_IDENTIFIER_LOCK_STATUS: u32 = 11; +pub const FFX_FSR2_RESOURCE_IDENTIFIER_DEPTH_CLIP: u32 = 12; +pub const FFX_FSR2_RESOURCE_IDENTIFIER_PREPARED_INPUT_COLOR: u32 = 13; +pub const FFX_FSR2_RESOURCE_IDENTIFIER_LUMA_HISTORY: u32 = 14; +pub const FFX_FSR2_RESOURCE_IDENTIFIER_DEBUG_OUTPUT: u32 = 15; +pub const FFX_FSR2_RESOURCE_IDENTIFIER_LANCZOS_LUT: u32 = 16; +pub const FFX_FSR2_RESOURCE_IDENTIFIER_SPD_ATOMIC_COUNT: u32 = 17; +pub const FFX_FSR2_RESOURCE_IDENTIFIER_UPSCALED_OUTPUT: u32 = 18; +pub const FFX_FSR2_RESOURCE_IDENTIFIER_RCAS_INPUT: u32 = 19; +pub const FFX_FSR2_RESOURCE_IDENTIFIER_LOCK_STATUS_1: u32 = 20; +pub const FFX_FSR2_RESOURCE_IDENTIFIER_LOCK_STATUS_2: u32 = 21; +pub const FFX_FSR2_RESOURCE_IDENTIFIER_INTERNAL_UPSCALED_COLOR_1: u32 = 22; +pub const FFX_FSR2_RESOURCE_IDENTIFIER_INTERNAL_UPSCALED_COLOR_2: u32 = 23; +pub const FFX_FSR2_RESOURCE_IDENTIFIER_INTERNAL_DEFAULT_REACTIVITY: u32 = 24; +pub const FFX_FSR2_RESOURCE_IDENTIFIER_INTERNAL_DEFAULT_TRANSPARENCY_AND_COMPOSITION: u32 = 25; +pub const FFX_FSR2_RESOURCE_IDENTITIER_UPSAMPLE_MAXIMUM_BIAS_LUT: u32 = 26; +pub const FFX_FSR2_RESOURCE_IDENTIFIER_DILATED_REACTIVE_MASKS: u32 = 27; +pub const FFX_FSR2_RESOURCE_IDENTIFIER_AUTO_EXPOSURE: u32 = 28; +pub const FFX_FSR2_RESOURCE_IDENTIFIER_AUTO_EXPOSURE_MIPMAP_0: u32 = 28; +pub const FFX_FSR2_RESOURCE_IDENTIFIER_AUTO_EXPOSURE_MIPMAP_1: u32 = 29; +pub const FFX_FSR2_RESOURCE_IDENTIFIER_AUTO_EXPOSURE_MIPMAP_2: u32 = 30; +pub const FFX_FSR2_RESOURCE_IDENTIFIER_AUTO_EXPOSURE_MIPMAP_3: u32 = 31; +pub const FFX_FSR2_RESOURCE_IDENTIFIER_AUTO_EXPOSURE_MIPMAP_4: u32 = 32; +pub const FFX_FSR2_RESOURCE_IDENTIFIER_AUTO_EXPOSURE_MIPMAP_5: u32 = 33; +pub const FFX_FSR2_RESOURCE_IDENTIFIER_AUTO_EXPOSURE_MIPMAP_6: u32 = 34; +pub const FFX_FSR2_RESOURCE_IDENTIFIER_AUTO_EXPOSURE_MIPMAP_7: u32 = 35; +pub const FFX_FSR2_RESOURCE_IDENTIFIER_AUTO_EXPOSURE_MIPMAP_8: u32 = 36; +pub const FFX_FSR2_RESOURCE_IDENTIFIER_AUTO_EXPOSURE_MIPMAP_9: u32 = 37; +pub const FFX_FSR2_RESOURCE_IDENTIFIER_AUTO_EXPOSURE_MIPMAP_10: u32 = 38; +pub const FFX_FSR2_RESOURCE_IDENTIFIER_AUTO_EXPOSURE_MIPMAP_11: u32 = 39; +pub const FFX_FSR2_RESOURCE_IDENTIFIER_AUTO_EXPOSURE_MIPMAP_12: u32 = 40; +pub const FFX_FSR2_RESOURCE_IDENTIFIER_INTERNAL_DEFAULT_EXPOSURE: u32 = 41; +pub const FFX_FSR2_RESOURCE_IDENTIFIER_EXPOSURE: u32 = 42; +pub const FFX_FSR2_RESOURCE_IDENTIFIER_AUTO_EXPOSURE_MIPMAP_SHADING_CHANGE: u32 = 32; +pub const FFX_FSR2_SHADING_CHANGE_MIP_LEVEL: u32 = 4; +pub const FFX_FSR2_RESOURCE_IDENTIFIER_COUNT: u32 = 43; +pub const FFX_FSR2_CONSTANTBUFFER_IDENTIFIER_FSR2: u32 = 0; +pub const FFX_FSR2_CONSTANTBUFFER_IDENTIFIER_SPD: u32 = 1; +pub const FFX_FSR2_CONSTANTBUFFER_IDENTIFIER_RCAS: u32 = 2; +pub const FFX_FSR2_AUTOREACTIVEFLAGS_APPLY_TONEMAP: u32 = 1; +pub const FFX_FSR2_AUTOREACTIVEFLAGS_APPLY_INVERSETONEMAP: u32 = 2; +pub const FFX_FSR2_AUTOREACTIVEFLAGS_APPLY_THRESHOLD: u32 = 4; +pub const FFX_FSR2_AUTOREACTIVEFLAGS_USE_COMPONENTS_MAX: u32 = 8; +pub const FFX_FSR2_VERSION_MAJOR: u32 = 2; +pub const FFX_FSR2_VERSION_MINOR: u32 = 1; +pub const FFX_FSR2_VERSION_PATCH: u32 = 2; +pub const FFX_FSR2_CONTEXT_SIZE: u32 = 16536; +#[doc = "< Unknown format"] +pub const FfxSurfaceFormat_FFX_SURFACE_FORMAT_UNKNOWN: FfxSurfaceFormat = 0; +#[doc = "< 32 bit per channel, 4 channel typeless format"] +pub const FfxSurfaceFormat_FFX_SURFACE_FORMAT_R32G32B32A32_TYPELESS: FfxSurfaceFormat = 1; +#[doc = "< 32 bit per channel, 4 channel float format"] +pub const FfxSurfaceFormat_FFX_SURFACE_FORMAT_R32G32B32A32_FLOAT: FfxSurfaceFormat = 2; +#[doc = "< 16 bit per channel, 4 channel float format"] +pub const FfxSurfaceFormat_FFX_SURFACE_FORMAT_R16G16B16A16_FLOAT: FfxSurfaceFormat = 3; +#[doc = "< 16 bit per channel, 4 channel unsigned normalized format"] +pub const FfxSurfaceFormat_FFX_SURFACE_FORMAT_R16G16B16A16_UNORM: FfxSurfaceFormat = 4; +#[doc = "< 32 bit per channel, 2 channel float format"] +pub const FfxSurfaceFormat_FFX_SURFACE_FORMAT_R32G32_FLOAT: FfxSurfaceFormat = 5; +#[doc = "< 32 bit per channel, 1 channel float format"] +pub const FfxSurfaceFormat_FFX_SURFACE_FORMAT_R32_UINT: FfxSurfaceFormat = 6; +#[doc = "< 8 bit per channel, 4 channel float format"] +pub const FfxSurfaceFormat_FFX_SURFACE_FORMAT_R8G8B8A8_TYPELESS: FfxSurfaceFormat = 7; +#[doc = "< 8 bit per channel, 4 channel unsigned normalized format"] +pub const FfxSurfaceFormat_FFX_SURFACE_FORMAT_R8G8B8A8_UNORM: FfxSurfaceFormat = 8; +#[doc = "< 32 bit 3 channel float format"] +pub const FfxSurfaceFormat_FFX_SURFACE_FORMAT_R11G11B10_FLOAT: FfxSurfaceFormat = 9; +#[doc = "< 16 bit per channel, 2 channel float format"] +pub const FfxSurfaceFormat_FFX_SURFACE_FORMAT_R16G16_FLOAT: FfxSurfaceFormat = 10; +#[doc = "< 16 bit per channel, 2 channel unsigned int format"] +pub const FfxSurfaceFormat_FFX_SURFACE_FORMAT_R16G16_UINT: FfxSurfaceFormat = 11; +#[doc = "< 16 bit per channel, 1 channel float format"] +pub const FfxSurfaceFormat_FFX_SURFACE_FORMAT_R16_FLOAT: FfxSurfaceFormat = 12; +#[doc = "< 16 bit per channel, 1 channel unsigned int format"] +pub const FfxSurfaceFormat_FFX_SURFACE_FORMAT_R16_UINT: FfxSurfaceFormat = 13; +#[doc = "< 16 bit per channel, 1 channel unsigned normalized format"] +pub const FfxSurfaceFormat_FFX_SURFACE_FORMAT_R16_UNORM: FfxSurfaceFormat = 14; +#[doc = "< 16 bit per channel, 1 channel signed normalized format"] +pub const FfxSurfaceFormat_FFX_SURFACE_FORMAT_R16_SNORM: FfxSurfaceFormat = 15; +#[doc = "< 8 bit per channel, 1 channel unsigned normalized format"] +pub const FfxSurfaceFormat_FFX_SURFACE_FORMAT_R8_UNORM: FfxSurfaceFormat = 16; +#[doc = "< 8 bit per channel, 2 channel unsigned normalized format"] +pub const FfxSurfaceFormat_FFX_SURFACE_FORMAT_R8G8_UNORM: FfxSurfaceFormat = 17; +#[doc = "< 32 bit per channel, 1 channel float format"] +pub const FfxSurfaceFormat_FFX_SURFACE_FORMAT_R32_FLOAT: FfxSurfaceFormat = 18; +#[doc = " An enumeration of surface formats."] +pub type FfxSurfaceFormat = ::std::os::raw::c_uint; +#[doc = "< No usage flags indicate a resource is read only."] +pub const FfxResourceUsage_FFX_RESOURCE_USAGE_READ_ONLY: FfxResourceUsage = 0; +#[doc = "< Indicates a resource will be used as render target."] +pub const FfxResourceUsage_FFX_RESOURCE_USAGE_RENDERTARGET: FfxResourceUsage = 1; +#[doc = "< Indicates a resource will be used as UAV."] +pub const FfxResourceUsage_FFX_RESOURCE_USAGE_UAV: FfxResourceUsage = 2; +#[doc = " An enumeration of resource usage."] +pub type FfxResourceUsage = ::std::os::raw::c_uint; +#[doc = "< Indicates a resource is in the state to be used as UAV."] +pub const FfxResourceStates_FFX_RESOURCE_STATE_UNORDERED_ACCESS: FfxResourceStates = 1; +#[doc = "< Indicates a resource is in the state to be read by compute shaders."] +pub const FfxResourceStates_FFX_RESOURCE_STATE_COMPUTE_READ: FfxResourceStates = 2; +#[doc = "< Indicates a resource is in the state to be used as source in a copy command."] +pub const FfxResourceStates_FFX_RESOURCE_STATE_COPY_SRC: FfxResourceStates = 4; +#[doc = "< Indicates a resource is in the state to be used as destination in a copy command."] +pub const FfxResourceStates_FFX_RESOURCE_STATE_COPY_DEST: FfxResourceStates = 8; +#[doc = "< Indicates a resource is in generic (slow) read state."] +pub const FfxResourceStates_FFX_RESOURCE_STATE_GENERIC_READ: FfxResourceStates = 6; +#[doc = " An enumeration of resource states."] +pub type FfxResourceStates = ::std::os::raw::c_uint; +#[doc = "< A resource with a single dimension."] +pub const FfxResourceDimension_FFX_RESOURCE_DIMENSION_TEXTURE_1D: FfxResourceDimension = 0; +#[doc = "< A resource with two dimensions."] +pub const FfxResourceDimension_FFX_RESOURCE_DIMENSION_TEXTURE_2D: FfxResourceDimension = 1; +#[doc = " An enumeration of surface dimensions."] +pub type FfxResourceDimension = ::std::os::raw::c_uint; +#[doc = "< No flags."] +pub const FfxResourceFlags_FFX_RESOURCE_FLAGS_NONE: FfxResourceFlags = 0; +#[doc = "< A bit indicating a resource does not need to persist across frames."] +pub const FfxResourceFlags_FFX_RESOURCE_FLAGS_ALIASABLE: FfxResourceFlags = 1; +#[doc = " An enumeration of surface dimensions."] +pub type FfxResourceFlags = ::std::os::raw::c_uint; +#[doc = "< The resource view is an unordered access view (UAV)."] +pub const FfxResourceViewType_FFX_RESOURCE_VIEW_UNORDERED_ACCESS: FfxResourceViewType = 0; +#[doc = "< The resource view is a shader resource view (SRV)."] +pub const FfxResourceViewType_FFX_RESOURCE_VIEW_SHADER_READ: FfxResourceViewType = 1; +#[doc = " An enumeration of all resource view types."] +pub type FfxResourceViewType = ::std::os::raw::c_uint; +#[doc = "< Point sampling."] +pub const FfxFilterType_FFX_FILTER_TYPE_POINT: FfxFilterType = 0; +#[doc = "< Sampling with interpolation."] +pub const FfxFilterType_FFX_FILTER_TYPE_LINEAR: FfxFilterType = 1; +#[doc = " The type of filtering to perform when reading a texture."] +pub type FfxFilterType = ::std::os::raw::c_uint; +#[doc = "< Shader model 5.1."] +pub const FfxShaderModel_FFX_SHADER_MODEL_5_1: FfxShaderModel = 0; +#[doc = "< Shader model 6.0."] +pub const FfxShaderModel_FFX_SHADER_MODEL_6_0: FfxShaderModel = 1; +#[doc = "< Shader model 6.1."] +pub const FfxShaderModel_FFX_SHADER_MODEL_6_1: FfxShaderModel = 2; +#[doc = "< Shader model 6.2."] +pub const FfxShaderModel_FFX_SHADER_MODEL_6_2: FfxShaderModel = 3; +#[doc = "< Shader model 6.3."] +pub const FfxShaderModel_FFX_SHADER_MODEL_6_3: FfxShaderModel = 4; +#[doc = "< Shader model 6.4."] +pub const FfxShaderModel_FFX_SHADER_MODEL_6_4: FfxShaderModel = 5; +#[doc = "< Shader model 6.5."] +pub const FfxShaderModel_FFX_SHADER_MODEL_6_5: FfxShaderModel = 6; +#[doc = "< Shader model 6.6."] +pub const FfxShaderModel_FFX_SHADER_MODEL_6_6: FfxShaderModel = 7; +#[doc = "< Shader model 6.7."] +pub const FfxShaderModel_FFX_SHADER_MODEL_6_7: FfxShaderModel = 8; +#[doc = " An enumeration of all supported shader models."] +pub type FfxShaderModel = ::std::os::raw::c_uint; +#[doc = "< The resource is a buffer."] +pub const FfxResourceType_FFX_RESOURCE_TYPE_BUFFER: FfxResourceType = 0; +#[doc = "< The resource is a 1-dimensional texture."] +pub const FfxResourceType_FFX_RESOURCE_TYPE_TEXTURE1D: FfxResourceType = 1; +#[doc = "< The resource is a 2-dimensional texture."] +pub const FfxResourceType_FFX_RESOURCE_TYPE_TEXTURE2D: FfxResourceType = 2; +#[doc = "< The resource is a 3-dimensional texture."] +pub const FfxResourceType_FFX_RESOURCE_TYPE_TEXTURE3D: FfxResourceType = 3; +pub type FfxResourceType = ::std::os::raw::c_uint; +#[doc = "< Local memory."] +pub const FfxHeapType_FFX_HEAP_TYPE_DEFAULT: FfxHeapType = 0; +#[doc = "< Heap used for uploading resources."] +pub const FfxHeapType_FFX_HEAP_TYPE_UPLOAD: FfxHeapType = 1; +#[doc = " An enumeration for different heap types"] +pub type FfxHeapType = ::std::os::raw::c_uint; +#[doc = "< The GPU job is performing a floating-point clear."] +pub const FfxGpuJobType_FFX_GPU_JOB_CLEAR_FLOAT: FfxGpuJobType = 0; +#[doc = "< The GPU job is performing a copy."] +pub const FfxGpuJobType_FFX_GPU_JOB_COPY: FfxGpuJobType = 1; +#[doc = "< The GPU job is performing a compute dispatch."] +pub const FfxGpuJobType_FFX_GPU_JOB_COMPUTE: FfxGpuJobType = 2; +#[doc = " An enumberation for different render job types"] +pub type FfxGpuJobType = ::std::os::raw::c_uint; +#[doc = " A typedef representing the graphics device."] +pub type FfxDevice = *mut ::std::os::raw::c_void; +#[doc = " A typedef representing a command list or command buffer."] +pub type FfxCommandList = *mut ::std::os::raw::c_void; +#[doc = " A typedef for a root signature."] +pub type FfxRootSignature = *mut ::std::os::raw::c_void; +#[doc = " A typedef for a pipeline state object."] +pub type FfxPipeline = *mut ::std::os::raw::c_void; +#[doc = " A structure encapasulating a collection of device capabilities."] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct FfxDeviceCapabilities { + #[doc = "< The minimum shader model supported by the device."] + pub minimumSupportedShaderModel: FfxShaderModel, + #[doc = "< The minimum supported wavefront width."] + pub waveLaneCountMin: u32, + #[doc = "< The maximum supported wavefront width."] + pub waveLaneCountMax: u32, + #[doc = "< The device supports FP16 in hardware."] + pub fp16Supported: bool, + #[doc = "< The device supports raytracing."] + pub raytracingSupported: bool, +} +#[doc = " A structure encapsulating a 2-dimensional point, using 32bit unsigned integers."] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct FfxDimensions2D { + #[doc = "< The width of a 2-dimensional range."] + pub width: u32, + #[doc = "< The height of a 2-dimensional range."] + pub height: u32, +} +#[doc = " A structure encapsulating a 2-dimensional point,"] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct FfxIntCoords2D { + #[doc = "< The x coordinate of a 2-dimensional point."] + pub x: i32, + #[doc = "< The y coordinate of a 2-dimensional point."] + pub y: i32, +} +#[doc = " A structure encapsulating a 2-dimensional set of floating point coordinates."] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct FfxFloatCoords2D { + #[doc = "< The x coordinate of a 2-dimensional point."] + pub x: f32, + #[doc = "< The y coordinate of a 2-dimensional point."] + pub y: f32, +} +#[doc = " A structure describing a resource."] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct FfxResourceDescription { + #[doc = "< The type of the resource."] + pub type_: FfxResourceType, + #[doc = "< The surface format."] + pub format: FfxSurfaceFormat, + #[doc = "< The width of the resource."] + pub width: u32, + #[doc = "< The height of the resource."] + pub height: u32, + #[doc = "< The depth of the resource."] + pub depth: u32, + #[doc = "< Number of mips (or 0 for full mipchain)."] + pub mipCount: u32, + #[doc = "< A set of FfxResourceFlags flags."] + pub flags: FfxResourceFlags, +} +#[doc = " An outward facing structure containing a resource"] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct FfxResource { + #[doc = "< pointer to the resource."] + pub resource: *mut ::std::os::raw::c_void, + pub name: [u32; 64usize], + pub description: FfxResourceDescription, + pub state: FfxResourceStates, + pub isDepth: bool, + pub descriptorData: u64, +} +#[doc = " An internal structure containing a handle to a resource and resource views"] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct FfxResourceInternal { + #[doc = "< The index of the resource."] + pub internalIndex: i32, +} +#[doc = " A structure defining a resource bind point"] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct FfxResourceBinding { + pub slotIndex: u32, + pub resourceIdentifier: u32, + pub name: [u32; 64usize], +} +#[doc = " A structure encapsulating a single pass of an algorithm."] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct FfxPipelineState { + #[doc = "< The pipelines rootSignature"] + pub rootSignature: FfxRootSignature, + #[doc = "< The pipeline object"] + pub pipeline: FfxPipeline, + #[doc = "< Count of UAVs used in this pipeline"] + pub uavCount: u32, + #[doc = "< Count of SRVs used in this pipeline"] + pub srvCount: u32, + #[doc = "< Count of constant buffers used in this pipeline"] + pub constCount: u32, + #[doc = "< Array of ResourceIdentifiers bound as UAVs"] + pub uavResourceBindings: [FfxResourceBinding; 8usize], + #[doc = "< Array of ResourceIdentifiers bound as SRVs"] + pub srvResourceBindings: [FfxResourceBinding; 16usize], + #[doc = "< Array of ResourceIdentifiers bound as CBs"] + pub cbResourceBindings: [FfxResourceBinding; 2usize], +} +#[doc = " A structure containing the data required to create a resource."] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct FfxCreateResourceDescription { + #[doc = "< The heap type to hold the resource, typically FFX_HEAP_TYPE_DEFAULT."] + pub heapType: FfxHeapType, + #[doc = "< A resource description."] + pub resourceDescription: FfxResourceDescription, + #[doc = "< The initial resource state."] + pub initalState: FfxResourceStates, + #[doc = "< Size of initial data buffer."] + pub initDataSize: u32, + #[doc = "< Buffer containing data to fill the resource."] + pub initData: *mut ::std::os::raw::c_void, + #[doc = "< Name of the resource."] + pub name: *const u32, + #[doc = "< Resource usage flags."] + pub usage: FfxResourceUsage, + #[doc = "< Internal resource ID."] + pub id: u32, +} +#[doc = " A structure containing the description used to create a\n FfxPipeline structure.\n\n A pipeline is the name given to a shader and the collection of state that\n is required to dispatch it. In the context of FSR2 and its architecture\n this means that a FfxPipelineDescription will map to either a\n monolithic object in an explicit API (such as a\n PipelineStateObject in DirectX 12). Or a shader and some\n ancillary API objects (in something like DirectX 11).\n\n The contextFlags field contains a copy of the flags passed\n to ffxFsr2ContextCreate via the flags field of\n the FfxFsr2InitializationParams structure. These flags are\n used to determine which permutation of a pipeline for a specific\n FfxFsr2Pass should be used to implement the features required\n by each application, as well as to acheive the best performance on specific\n target hardware configurations.\n\n When using one of the provided backends for FSR2 (such as DirectX 12 or\n Vulkan) the data required to create a pipeline is compiled offline and\n included into the backend library that you are using. For cases where the\n backend interface is overriden by providing custom callback function\n implementations care should be taken to respect the contents of the\n contextFlags field in order to correctly support the options\n provided by FSR2, and acheive best performance.\n\n @ingroup FSR2"] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct FfxPipelineDescription { + #[doc = "< A collection of FfxFsr2InitializationFlagBits which were passed to the context."] + pub contextFlags: u32, + #[doc = "< Array of static samplers."] + pub samplers: *mut FfxFilterType, + #[doc = "< The number of samples contained inside samplers."] + pub samplerCount: usize, + #[doc = "< Array containing the sizes of the root constant buffers (count of 32 bit elements)."] + pub rootConstantBufferSizes: *const u32, + #[doc = "< The number of root constants contained within rootConstantBufferSizes."] + pub rootConstantBufferCount: u32, +} +#[doc = " A structure containing a constant buffer."] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct FfxConstantBuffer { + #[doc = "< Size of 32 bit chunks used in the constant buffer"] + pub uint32Size: u32, + #[doc = "< Constant buffer data"] + pub data: [u32; 64usize], +} +#[doc = " A structure describing a clear render job."] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct FfxClearFloatJobDescription { + #[doc = "< The clear color of the resource."] + pub color: [f32; 4usize], + #[doc = "< The resource to be cleared."] + pub target: FfxResourceInternal, +} +#[doc = " A structure describing a compute render job."] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct FfxComputeJobDescription { + #[doc = "< Compute pipeline for the render job."] + pub pipeline: FfxPipelineState, + #[doc = "< Dispatch dimensions."] + pub dimensions: [u32; 3usize], + #[doc = "< SRV resources to be bound in the compute job."] + pub srvs: [FfxResourceInternal; 16usize], + pub srvNames: [[u32; 64usize]; 16usize], + #[doc = "< UAV resources to be bound in the compute job."] + pub uavs: [FfxResourceInternal; 8usize], + #[doc = "< Mip level of UAV resources to be bound in the compute job."] + pub uavMip: [u32; 8usize], + pub uavNames: [[u32; 64usize]; 8usize], + #[doc = "< Constant buffers to be bound in the compute job."] + pub cbs: [FfxConstantBuffer; 2usize], + pub cbNames: [[u32; 64usize]; 2usize], +} +#[doc = " A structure describing a copy render job."] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct FfxCopyJobDescription { + #[doc = "< Source resource for the copy."] + pub src: FfxResourceInternal, + #[doc = "< Destination resource for the copy."] + pub dst: FfxResourceInternal, +} +#[doc = " A structure describing a single render job."] +#[repr(C)] +#[derive(Copy, Clone)] +pub struct FfxGpuJobDescription { + #[doc = "< Type of the job."] + pub jobType: FfxGpuJobType, + pub __bindgen_anon_1: FfxGpuJobDescription__bindgen_ty_1, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union FfxGpuJobDescription__bindgen_ty_1 { + #[doc = "< Clear job descriptor. Valid when jobType is FFX_RENDER_JOB_CLEAR_FLOAT."] + pub clearJobDescriptor: FfxClearFloatJobDescription, + #[doc = "< Copy job descriptor. Valid when jobType is FFX_RENDER_JOB_COPY."] + pub copyJobDescriptor: FfxCopyJobDescription, + #[doc = "< Compute job descriptor. Valid when jobType is FFX_RENDER_JOB_COMPUTE."] + pub computeJobDescriptor: FfxComputeJobDescription, +} +#[doc = " The value of Pi."] +pub const FFX_PI: f32 = 3.1415927410125732; +#[doc = " An epsilon value for floating point numbers."] +pub const FFX_EPSILON: f32 = 0.0000009999999974752427; +#[doc = " A typedef for the callback function for assert printing.\n\n This can be used to re-route printing of assert messages from the FFX backend\n to another destination. For example instead of the default behaviour of printing\n the assert messages to the debugger's TTY the message can be re-routed to a\n MessageBox in a GUI application.\n\n @param [in] message The message generated by the assert.\n"] +pub type FfxAssertCallback = + ::std::option::Option; +extern "C" { + #[doc = " Function to report an assert.\n\n @param [in] file The name of the file as a string.\n @param [in] line The index of the line in the file.\n @param [in] condition The boolean condition that was tested.\n @param [in] msg The optional message to print.\n\n @returns\n Always returns true.\n"] + pub fn ffxAssertReport( + file: *const ::std::os::raw::c_char, + line: i32, + condition: *const ::std::os::raw::c_char, + msg: *const ::std::os::raw::c_char, + ) -> bool; +} +extern "C" { + #[doc = " Provides the ability to set a callback for assert messages.\n\n @param [in] callback The callback function that will receive assert messages.\n"] + pub fn ffxAssertSetPrintingCallback(callback: FfxAssertCallback); +} +#[doc = " Typedef for error codes returned from functions in the FidelityFX SDK."] +pub type FfxErrorCode = i32; +#[doc = "< The operation completed successfully."] +pub const FFX_OK: FfxErrorCode = 0; +#[doc = "< The operation failed due to an invalid pointer."] +pub const FFX_ERROR_INVALID_POINTER: FfxErrorCode = -2147483648; +#[doc = "< The operation failed due to an invalid alignment."] +pub const FFX_ERROR_INVALID_ALIGNMENT: FfxErrorCode = -2147483647; +#[doc = "< The operation failed due to an invalid size."] +pub const FFX_ERROR_INVALID_SIZE: FfxErrorCode = -2147483646; +#[doc = "< The end of the file was encountered."] +pub const FFX_EOF: FfxErrorCode = -2147483645; +#[doc = "< The operation failed because the specified path was invalid."] +pub const FFX_ERROR_INVALID_PATH: FfxErrorCode = -2147483644; +#[doc = "< The operation failed because end of file was reached."] +pub const FFX_ERROR_EOF: FfxErrorCode = -2147483643; +#[doc = "< The operation failed because of some malformed data."] +pub const FFX_ERROR_MALFORMED_DATA: FfxErrorCode = -2147483642; +#[doc = "< The operation failed because it ran out memory."] +pub const FFX_ERROR_OUT_OF_MEMORY: FfxErrorCode = -2147483641; +#[doc = "< The operation failed because the interface was not fully configured."] +pub const FFX_ERROR_INCOMPLETE_INTERFACE: FfxErrorCode = -2147483640; +#[doc = "< The operation failed because of an invalid enumeration value."] +pub const FFX_ERROR_INVALID_ENUM: FfxErrorCode = -2147483639; +#[doc = "< The operation failed because an argument was invalid."] +pub const FFX_ERROR_INVALID_ARGUMENT: FfxErrorCode = -2147483638; +#[doc = "< The operation failed because a value was out of range."] +pub const FFX_ERROR_OUT_OF_RANGE: FfxErrorCode = -2147483637; +#[doc = "< The operation failed because a device was null."] +pub const FFX_ERROR_NULL_DEVICE: FfxErrorCode = -2147483636; +#[doc = "< The operation failed because the backend API returned an error code."] +pub const FFX_ERROR_BACKEND_API_ERROR: FfxErrorCode = -2147483635; +#[doc = "< The operation failed because there was not enough memory."] +pub const FFX_ERROR_INSUFFICIENT_MEMORY: FfxErrorCode = -2147483634; +#[doc = "< A pass which prepares input colors for subsequent use."] +pub const FfxFsr2Pass_FFX_FSR2_PASS_PREPARE_INPUT_COLOR: FfxFsr2Pass = 0; +#[doc = "< A pass which performs depth clipping."] +pub const FfxFsr2Pass_FFX_FSR2_PASS_DEPTH_CLIP: FfxFsr2Pass = 1; +#[doc = "< A pass which performs reconstruction of previous frame's depth."] +pub const FfxFsr2Pass_FFX_FSR2_PASS_RECONSTRUCT_PREVIOUS_DEPTH: FfxFsr2Pass = 2; +#[doc = "< A pass which calculates pixel locks."] +pub const FfxFsr2Pass_FFX_FSR2_PASS_LOCK: FfxFsr2Pass = 3; +#[doc = "< A pass which performs upscaling."] +pub const FfxFsr2Pass_FFX_FSR2_PASS_ACCUMULATE: FfxFsr2Pass = 4; +#[doc = "< A pass which performs upscaling when sharpening is used."] +pub const FfxFsr2Pass_FFX_FSR2_PASS_ACCUMULATE_SHARPEN: FfxFsr2Pass = 5; +#[doc = "< A pass which performs sharpening."] +pub const FfxFsr2Pass_FFX_FSR2_PASS_RCAS: FfxFsr2Pass = 6; +#[doc = "< A pass which generates the luminance mipmap chain for the current frame."] +pub const FfxFsr2Pass_FFX_FSR2_PASS_COMPUTE_LUMINANCE_PYRAMID: FfxFsr2Pass = 7; +#[doc = "< An optional pass to generate a reactive mask"] +pub const FfxFsr2Pass_FFX_FSR2_PASS_GENERATE_REACTIVE: FfxFsr2Pass = 8; +#[doc = "< The number of passes performed by FSR2."] +pub const FfxFsr2Pass_FFX_FSR2_PASS_COUNT: FfxFsr2Pass = 9; +#[doc = " An enumeration of all the passes which constitute the FSR2 algorithm.\n\n FSR2 is implemented as a composite of several compute passes each\n computing a key part of the final result. Each call to the\n FfxFsr2ScheduleGpuJobFunc callback function will\n correspond to a single pass included in FfxFsr2Pass. For a\n more comprehensive description of each pass, please refer to the FSR2\n reference documentation.\n\n Please note in some cases e.g.: FFX_FSR2_PASS_ACCUMULATE\n and FFX_FSR2_PASS_ACCUMULATE_SHARPEN either one pass or the\n other will be used (they are mutually exclusive). The choice of which will\n depend on the way the FfxFsr2Context is created and the\n precise contents of FfxFsr2DispatchParamters each time a call\n is made to ffxFsr2ContextDispatch.\n\n @ingroup FSR2"] +pub type FfxFsr2Pass = ::std::os::raw::c_uint; +#[doc = " Create and initialize the backend context.\n\n The callback function sets up the backend context for rendering.\n It will create or reference the device and create required internal data structures.\n\n @param [in] backendInterface A pointer to the backend interface.\n @param [in] device The FfxDevice obtained by ffxGetDevice(DX12/VK/...).\n\n @retval\n FFX_OK The operation completed successfully.\n @retval\n Anything else The operation failed.\n\n @ingroup FSR2"] +pub type FfxFsr2CreateBackendContextFunc = ::std::option::Option< + unsafe extern "C" fn( + backendInterface: *mut FfxFsr2Interface, + device: FfxDevice, + ) -> FfxErrorCode, +>; +#[doc = " Get a list of capabilities of the device.\n\n When creating an FfxFsr2Context it is desirable for the FSR2\n core implementation to be aware of certain characteristics of the platform\n that is being targetted. This is because some optimizations which FSR2\n attempts to perform are more effective on certain classes of hardware than\n others, or are not supported by older hardware. In order to avoid cases\n where optimizations actually have the effect of decreasing performance, or\n reduce the breadth of support provided by FSR2, FSR2 queries the\n capabilities of the device to make such decisions.\n\n For target platforms with fixed hardware support you need not implement\n this callback function by querying the device, but instead may hardcore\n what features are available on the platform.\n\n @param [in] backendInterface A pointer to the backend interface.\n @param [out] outDeviceCapabilities The device capabilities structure to fill out.\n @param [in] device The device to query for capabilities.\n\n @retval\n FFX_OK The operation completed successfully.\n @retval\n Anything else The operation failed.\n\n @ingroup FSR2"] +pub type FfxFsr2GetDeviceCapabilitiesFunc = ::std::option::Option< + unsafe extern "C" fn( + backendInterface: *mut FfxFsr2Interface, + outDeviceCapabilities: *mut FfxDeviceCapabilities, + device: FfxDevice, + ) -> FfxErrorCode, +>; +#[doc = " Destroy the backend context and dereference the device.\n\n This function is called when the FfxFsr2Context is destroyed.\n\n @param [in] backendInterface A pointer to the backend interface.\n\n @retval\n FFX_OK The operation completed successfully.\n @retval\n Anything else The operation failed.\n\n @ingroup FSR2"] +pub type FfxFsr2DestroyBackendContextFunc = ::std::option::Option< + unsafe extern "C" fn(backendInterface: *mut FfxFsr2Interface) -> FfxErrorCode, +>; +#[doc = " Create a resource.\n\n This callback is intended for the backend to create internal resources.\n\n Please note: It is also possible that the creation of resources might\n itself cause additional resources to be created by simply calling the\n FfxFsr2CreateResourceFunc function pointer again. This is\n useful when handling the initial creation of resources which must be\n initialized. The flow in such a case would be an initial call to create the\n CPU-side resource, another to create the GPU-side resource, and then a call\n to schedule a copy render job to move the data between the two. Typically\n this type of function call flow is only seen during the creation of an\n FfxFsr2Context.\n\n @param [in] backendInterface A pointer to the backend interface.\n @param [in] createResourceDescription A pointer to a FfxCreateResourceDescription.\n @param [out] outResource A pointer to a FfxResource object.\n\n @retval\n FFX_OK The operation completed successfully.\n @retval\n Anything else The operation failed.\n\n @ingroup FSR2"] +pub type FfxFsr2CreateResourceFunc = ::std::option::Option< + unsafe extern "C" fn( + backendInterface: *mut FfxFsr2Interface, + createResourceDescription: *const FfxCreateResourceDescription, + outResource: *mut FfxResourceInternal, + ) -> FfxErrorCode, +>; +#[doc = " Register a resource in the backend for the current frame.\n\n Since FSR2 and the backend are not aware how many different\n resources will get passed to FSR2 over time, it's not safe\n to register all resources simultaneously in the backend.\n Also passed resources may not be valid after the dispatch call.\n As a result it's safest to register them as FfxResourceInternal\n and clear them at the end of the dispatch call.\n\n @param [in] backendInterface A pointer to the backend interface.\n @param [in] inResource A pointer to a FfxResource.\n @param [out] outResource A pointer to a FfxResourceInternal object.\n\n @retval\n FFX_OK The operation completed successfully.\n @retval\n Anything else The operation failed.\n\n @ingroup FSR2"] +pub type FfxFsr2RegisterResourceFunc = ::std::option::Option< + unsafe extern "C" fn( + backendInterface: *mut FfxFsr2Interface, + inResource: *const FfxResource, + outResource: *mut FfxResourceInternal, + ) -> FfxErrorCode, +>; +#[doc = " Unregister all temporary FfxResourceInternal from the backend.\n\n Unregister FfxResourceInternal referencing resources passed to\n a function as a parameter.\n\n @param [in] backendInterface A pointer to the backend interface.\n\n @retval\n FFX_OK The operation completed successfully.\n @retval\n Anything else The operation failed.\n\n @ingroup FSR2"] +pub type FfxFsr2UnregisterResourcesFunc = ::std::option::Option< + unsafe extern "C" fn(backendInterface: *mut FfxFsr2Interface) -> FfxErrorCode, +>; +#[doc = " Retrieve a FfxResourceDescription matching a\n FfxResource structure.\n\n @param [in] backendInterface A pointer to the backend interface.\n @param [in] resource A pointer to a FfxResource object.\n\n @returns\n A description of the resource.\n\n @ingroup FSR2"] +pub type FfxFsr2GetResourceDescriptionFunc = ::std::option::Option< + unsafe extern "C" fn( + backendInterface: *mut FfxFsr2Interface, + resource: FfxResourceInternal, + ) -> FfxResourceDescription, +>; +#[doc = " Destroy a resource\n\n This callback is intended for the backend to release an internal resource.\n\n @param [in] backendInterface A pointer to the backend interface.\n @param [in] resource A pointer to a FfxResource object.\n\n @retval\n FFX_OK The operation completed successfully.\n @retval\n Anything else The operation failed.\n\n @ingroup FSR2"] +pub type FfxFsr2DestroyResourceFunc = ::std::option::Option< + unsafe extern "C" fn( + backendInterface: *mut FfxFsr2Interface, + resource: FfxResourceInternal, + ) -> FfxErrorCode, +>; +#[doc = " Create a render pipeline.\n\n A rendering pipeline contains the shader as well as resource bindpoints\n and samplers.\n\n @param [in] backendInterface A pointer to the backend interface.\n @param [in] pass The identifier for the pass.\n @param [in] pipelineDescription A pointer to a FfxPipelineDescription describing the pipeline to be created.\n @param [out] outPipeline A pointer to a FfxPipelineState structure which should be populated.\n\n @retval\n FFX_OK The operation completed successfully.\n @retval\n Anything else The operation failed.\n\n @ingroup FSR2"] +pub type FfxFsr2CreatePipelineFunc = ::std::option::Option< + unsafe extern "C" fn( + backendInterface: *mut FfxFsr2Interface, + pass: FfxFsr2Pass, + pipelineDescription: *const FfxPipelineDescription, + outPipeline: *mut FfxPipelineState, + ) -> FfxErrorCode, +>; +#[doc = " Destroy a render pipeline.\n\n @param [in] backendInterface A pointer to the backend interface.\n @param [out] pipeline A pointer to a FfxPipelineState structure which should be released.\n\n @retval\n FFX_OK The operation completed successfully.\n @retval\n Anything else The operation failed.\n\n @ingroup FSR2"] +pub type FfxFsr2DestroyPipelineFunc = ::std::option::Option< + unsafe extern "C" fn( + backendInterface: *mut FfxFsr2Interface, + pipeline: *mut FfxPipelineState, + ) -> FfxErrorCode, +>; +#[doc = " Schedule a render job to be executed on the next call of\n FfxFsr2ExecuteGpuJobsFunc.\n\n Render jobs can perform one of three different tasks: clear, copy or\n compute dispatches.\n\n @param [in] backendInterface A pointer to the backend interface.\n @param [in] job A pointer to a FfxGpuJobDescription structure.\n\n @retval\n FFX_OK The operation completed successfully.\n @retval\n Anything else The operation failed.\n\n @ingroup FSR2"] +pub type FfxFsr2ScheduleGpuJobFunc = ::std::option::Option< + unsafe extern "C" fn( + backendInterface: *mut FfxFsr2Interface, + job: *const FfxGpuJobDescription, + ) -> FfxErrorCode, +>; +#[doc = " Execute scheduled render jobs on the comandList provided.\n\n The recording of the graphics API commands should take place in this\n callback function, the render jobs which were previously enqueued (via\n callbacks made to FfxFsr2ScheduleGpuJobFunc) should be\n processed in the order they were received. Advanced users might choose to\n reorder the rendering jobs, but should do so with care to respect the\n resource dependencies.\n\n Depending on the precise contents of FfxFsr2DispatchDescription a\n different number of render jobs might have previously been enqueued (for\n example if sharpening is toggled on and off).\n\n @param [in] backendInterface A pointer to the backend interface.\n @param [in] commandList A pointer to a FfxCommandList structure.\n\n @retval\n FFX_OK The operation completed successfully.\n @retval\n Anything else The operation failed.\n\n @ingroup FSR2"] +pub type FfxFsr2ExecuteGpuJobsFunc = ::std::option::Option< + unsafe extern "C" fn( + backendInterface: *mut FfxFsr2Interface, + commandList: FfxCommandList, + ) -> FfxErrorCode, +>; +#[doc = " A structure encapsulating the interface between the core implentation of\n the FSR2 algorithm and any graphics API that it should ultimately call.\n\n This set of functions serves as an abstraction layer between FSR2 and the\n API used to implement it. While FSR2 ships with backends for DirectX12 and\n Vulkan, it is possible to implement your own backend for other platforms or\n which sits ontop of your engine's own abstraction layer. For details on the\n expectations of what each function should do you should refer the\n description of the following function pointer types:\n\n FfxFsr2CreateDeviceFunc\n FfxFsr2GetDeviceCapabilitiesFunc\n FfxFsr2DestroyDeviceFunc\n FfxFsr2CreateResourceFunc\n FfxFsr2GetResourceDescriptionFunc\n FfxFsr2DestroyResourceFunc\n FfxFsr2CreatePipelineFunc\n FfxFsr2DestroyPipelineFunc\n FfxFsr2ScheduleGpuJobFunc\n FfxFsr2ExecuteGpuJobsFunc\n\n Depending on the graphics API that is abstracted by the backend, it may be\n required that the backend is to some extent stateful. To ensure that\n applications retain full control to manage the memory used by FSR2, the\n scratchBuffer and scratchBufferSize fields are\n provided. A backend should provide a means of specifying how much scratch\n memory is required for its internal implementation (e.g: via a function\n or constant value). The application is that responsible for allocating that\n memory and providing it when setting up the FSR2 backend. Backends provided\n with FSR2 do not perform dynamic memory allocations, and instead\n suballocate all memory from the scratch buffers provided.\n\n The scratchBuffer and scratchBufferSize fields\n should be populated according to the requirements of each backend. For\n example, if using the DirectX 12 backend you should call the\n ffxFsr2GetScratchMemorySizeDX12 function. It is not required\n that custom backend implementations use a scratch buffer.\n\n @ingroup FSR2"] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct FfxFsr2Interface { + #[doc = "< A callback function to create and initialize the backend context."] + pub fpCreateBackendContext: FfxFsr2CreateBackendContextFunc, + #[doc = "< A callback function to query device capabilites."] + pub fpGetDeviceCapabilities: FfxFsr2GetDeviceCapabilitiesFunc, + #[doc = "< A callback function to destroy the backendcontext. This also dereferences the device."] + pub fpDestroyBackendContext: FfxFsr2DestroyBackendContextFunc, + #[doc = "< A callback function to create a resource."] + pub fpCreateResource: FfxFsr2CreateResourceFunc, + #[doc = "< A callback function to register an external resource."] + pub fpRegisterResource: FfxFsr2RegisterResourceFunc, + #[doc = "< A callback function to unregister external resource."] + pub fpUnregisterResources: FfxFsr2UnregisterResourcesFunc, + #[doc = "< A callback function to retrieve a resource description."] + pub fpGetResourceDescription: FfxFsr2GetResourceDescriptionFunc, + #[doc = "< A callback function to destroy a resource."] + pub fpDestroyResource: FfxFsr2DestroyResourceFunc, + #[doc = "< A callback function to create a render or compute pipeline."] + pub fpCreatePipeline: FfxFsr2CreatePipelineFunc, + #[doc = "< A callback function to destroy a render or compute pipeline."] + pub fpDestroyPipeline: FfxFsr2DestroyPipelineFunc, + #[doc = "< A callback function to schedule a render job."] + pub fpScheduleGpuJob: FfxFsr2ScheduleGpuJobFunc, + #[doc = "< A callback function to execute all queued render jobs."] + pub fpExecuteGpuJobs: FfxFsr2ExecuteGpuJobsFunc, + #[doc = "< A preallocated buffer for memory utilized internally by the backend."] + pub scratchBuffer: *mut ::std::os::raw::c_void, + #[doc = "< Size of the buffer pointed to by scratchBuffer."] + pub scratchBufferSize: usize, +} +#[doc = "< Perform upscaling with a per-dimension upscaling ratio of 1.5x."] +pub const FfxFsr2QualityMode_FFX_FSR2_QUALITY_MODE_QUALITY: FfxFsr2QualityMode = 1; +#[doc = "< Perform upscaling with a per-dimension upscaling ratio of 1.7x."] +pub const FfxFsr2QualityMode_FFX_FSR2_QUALITY_MODE_BALANCED: FfxFsr2QualityMode = 2; +#[doc = "< Perform upscaling with a per-dimension upscaling ratio of 2.0x."] +pub const FfxFsr2QualityMode_FFX_FSR2_QUALITY_MODE_PERFORMANCE: FfxFsr2QualityMode = 3; +#[doc = "< Perform upscaling with a per-dimension upscaling ratio of 3.0x."] +pub const FfxFsr2QualityMode_FFX_FSR2_QUALITY_MODE_ULTRA_PERFORMANCE: FfxFsr2QualityMode = 4; +#[doc = " An enumeration of all the quality modes supported by FidelityFX Super\n Resolution 2 upscaling.\n\n In order to provide a consistent user experience across multiple\n applications which implement FSR2. It is strongly recommended that the\n following preset scaling factors are made available through your\n application's user interface.\n\n If your application does not expose the notion of preset scaling factors\n for upscaling algorithms (perhaps instead implementing a fixed ratio which\n is immutable) or implementing a more dynamic scaling scheme (such as\n dynamic resolution scaling), then there is no need to use these presets.\n\n Please note that FFX_FSR2_QUALITY_MODE_ULTRA_PERFORMANCE is\n an optional mode which may introduce significant quality degradation in the\n final image. As such it is recommended that you evaluate the final results\n of using this scaling mode before deciding if you should include it in your\n application.\n\n @ingroup FSR2"] +pub type FfxFsr2QualityMode = ::std::os::raw::c_uint; +#[doc = "< A bit indicating if the input color data provided is using a high-dynamic range."] +pub const FfxFsr2InitializationFlagBits_FFX_FSR2_ENABLE_HIGH_DYNAMIC_RANGE: + FfxFsr2InitializationFlagBits = 1; +#[doc = "< A bit indicating if the motion vectors are rendered at display resolution."] +pub const FfxFsr2InitializationFlagBits_FFX_FSR2_ENABLE_DISPLAY_RESOLUTION_MOTION_VECTORS: + FfxFsr2InitializationFlagBits = 2; +#[doc = "< A bit indicating that the motion vectors have the jittering pattern applied to them."] +pub const FfxFsr2InitializationFlagBits_FFX_FSR2_ENABLE_MOTION_VECTORS_JITTER_CANCELLATION: + FfxFsr2InitializationFlagBits = 4; +#[doc = "< A bit indicating that the input depth buffer data provided is inverted [1..0]."] +pub const FfxFsr2InitializationFlagBits_FFX_FSR2_ENABLE_DEPTH_INVERTED: + FfxFsr2InitializationFlagBits = 8; +#[doc = "< A bit indicating that the input depth buffer data provided is using an infinite far plane."] +pub const FfxFsr2InitializationFlagBits_FFX_FSR2_ENABLE_DEPTH_INFINITE: + FfxFsr2InitializationFlagBits = 16; +#[doc = "< A bit indicating if automatic exposure should be applied to input color data."] +pub const FfxFsr2InitializationFlagBits_FFX_FSR2_ENABLE_AUTO_EXPOSURE: + FfxFsr2InitializationFlagBits = 32; +#[doc = "< A bit indicating that the application uses dynamic resolution scaling."] +pub const FfxFsr2InitializationFlagBits_FFX_FSR2_ENABLE_DYNAMIC_RESOLUTION: + FfxFsr2InitializationFlagBits = 64; +#[doc = "< A bit indicating that the backend should use 1D textures."] +pub const FfxFsr2InitializationFlagBits_FFX_FSR2_ENABLE_TEXTURE1D_USAGE: + FfxFsr2InitializationFlagBits = 128; +#[doc = " An enumeration of bit flags used when creating a\n FfxFsr2Context. See FfxFsr2ContextDescription.\n\n @ingroup FSR2"] +pub type FfxFsr2InitializationFlagBits = ::std::os::raw::c_uint; +#[doc = " A structure encapsulating the parameters required to initialize FidelityFX\n Super Resolution 2 upscaling.\n\n @ingroup FSR2"] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct FfxFsr2ContextDescription { + #[doc = "< A collection of FfxFsr2InitializationFlagBits."] + pub flags: u32, + #[doc = "< The maximum size that rendering will be performed at."] + pub maxRenderSize: FfxDimensions2D, + #[doc = "< The size of the presentation resolution targeted by the upscaling process."] + pub displaySize: FfxDimensions2D, + #[doc = "< A set of pointers to the backend implementation for FSR 2.0."] + pub callbacks: FfxFsr2Interface, + #[doc = "< The abstracted device which is passed to some callback functions."] + pub device: FfxDevice, +} +#[doc = " A structure encapsulating the parameters for dispatching the various passes\n of FidelityFX Super Resolution 2.\n\n @ingroup FSR2"] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct FfxFsr2DispatchDescription { + #[doc = "< The FfxCommandList to record FSR2 rendering commands into."] + pub commandList: FfxCommandList, + #[doc = "< A FfxResource containing the color buffer for the current frame (at render resolution)."] + pub color: FfxResource, + #[doc = "< A FfxResource containing 32bit depth values for the current frame (at render resolution)."] + pub depth: FfxResource, + #[doc = "< A FfxResource containing 2-dimensional motion vectors (at render resolution if FFX_FSR2_ENABLE_DISPLAY_RESOLUTION_MOTION_VECTORS is not set)."] + pub motionVectors: FfxResource, + #[doc = "< A optional FfxResource containing a 1x1 exposure value."] + pub exposure: FfxResource, + #[doc = "< A optional FfxResource containing alpha value of reactive objects in the scene."] + pub reactive: FfxResource, + #[doc = "< A optional FfxResource containing alpha value of special objects in the scene."] + pub transparencyAndComposition: FfxResource, + #[doc = "< A FfxResource containing the output color buffer for the current frame (at presentation resolution)."] + pub output: FfxResource, + #[doc = "< The subpixel jitter offset applied to the camera."] + pub jitterOffset: FfxFloatCoords2D, + #[doc = "< The scale factor to apply to motion vectors."] + pub motionVectorScale: FfxFloatCoords2D, + #[doc = "< The resolution that was used for rendering the input resources."] + pub renderSize: FfxDimensions2D, + #[doc = "< Enable an additional sharpening pass."] + pub enableSharpening: bool, + #[doc = "< The sharpness value between 0 and 1, where 0 is no additional sharpness and 1 is maximum additional sharpness."] + pub sharpness: f32, + #[doc = "< The time elapsed since the last frame (expressed in milliseconds)."] + pub frameTimeDelta: f32, + #[doc = "< The exposure value if not using FFX_FSR2_ENABLE_AUTO_EXPOSURE."] + pub preExposure: f32, + #[doc = "< A boolean value which when set to true, indicates the camera has moved discontinuously."] + pub reset: bool, + #[doc = "< The distance to the near plane of the camera."] + pub cameraNear: f32, + #[doc = "< The distance to the far plane of the camera. This is used only used in case of non infinite depth."] + pub cameraFar: f32, + #[doc = "< The camera angle field of view in the vertical direction (expressed in radians)."] + pub cameraFovAngleVertical: f32, +} +#[doc = " A structure encapsulating the parameters for automatic generation of a reactive mask\n\n @ingroup FSR2"] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct FfxFsr2GenerateReactiveDescription { + #[doc = "< The FfxCommandList to record FSR2 rendering commands into."] + pub commandList: FfxCommandList, + #[doc = "< A FfxResource containing the opaque only color buffer for the current frame (at render resolution)."] + pub colorOpaqueOnly: FfxResource, + #[doc = "< A FfxResource containing the opaque+translucent color buffer for the current frame (at render resolution)."] + pub colorPreUpscale: FfxResource, + #[doc = "< A FfxResource containing the surface to generate the reactive mask into."] + pub outReactive: FfxResource, + #[doc = "< The resolution that was used for rendering the input resources."] + pub renderSize: FfxDimensions2D, + #[doc = "< A value to scale the output"] + pub scale: f32, + #[doc = "< A threshold value to generate a binary reactive mask"] + pub cutoffThreshold: f32, + #[doc = "< A value to set for the binary reactive mask"] + pub binaryValue: f32, + #[doc = "< Flags to determine how to generate the reactive mask"] + pub flags: u32, +} +#[doc = " A structure encapsulating the FidelityFX Super Resolution 2 context.\n\n This sets up an object which contains all persistent internal data and\n resources that are required by FSR2.\n\n The FfxFsr2Context object should have a lifetime matching\n your use of FSR2. Before destroying the FSR2 context care should be taken\n to ensure the GPU is not accessing the resources created or used by FSR2.\n It is therefore recommended that the GPU is idle before destroying the\n FSR2 context.\n\n @ingroup FSR2"] +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct FfxFsr2Context { + #[doc = "< An opaque set of uint32_t which contain the data for the context."] + pub data: [u32; 16536usize], +} +extern "C" { + #[doc = " Create a FidelityFX Super Resolution 2 context from the parameters\n programmed to the FfxFsr2CreateParams structure.\n\n The context structure is the main object used to interact with the FSR2\n API, and is responsible for the management of the internal resources used\n by the FSR2 algorithm. When this API is called, multiple calls will be\n made via the pointers contained in the callbacks structure.\n These callbacks will attempt to retreive the device capabilities, and\n create the internal resources, and pipelines required by FSR2's\n frame-to-frame function. Depending on the precise configuration used when\n creating the FfxFsr2Context a different set of resources and\n pipelines might be requested via the callback functions.\n\n The flags included in the flags field of\n FfxFsr2Context how match the configuration of your\n application as well as the intended use of FSR2. It is important that these\n flags are set correctly (as well as a correct programmed\n FfxFsr2DispatchDescription) to ensure correct operation. It is\n recommended to consult the overview documentation for further details on\n how FSR2 should be integerated into an application.\n\n When the FfxFsr2Context is created, you should use the\n ffxFsr2ContextDispatch function each frame where FSR2\n upscaling should be applied. See the documentation of\n ffxFsr2ContextDispatch for more details.\n\n The FfxFsr2Context should be destroyed when use of it is\n completed, typically when an application is unloaded or FSR2 upscaling is\n disabled by a user. To destroy the FSR2 context you should call\n ffxFsr2ContextDestroy.\n\n @param [out] context A pointer to a FfxFsr2Context structure to populate.\n @param [in] contextDescription A pointer to a FfxFsr2ContextDescription structure.\n\n @retval\n FFX_OK The operation completed successfully.\n @retval\n FFX_ERROR_CODE_NULL_POINTER The operation failed because either context or contextDescription was NULL.\n @retval\n FFX_ERROR_INCOMPLETE_INTERFACE The operation failed because the FfxFsr2ContextDescription.callbacks was not fully specified.\n @retval\n FFX_ERROR_BACKEND_API_ERROR The operation failed because of an error returned from the backend.\n\n @ingroup FSR2"] + pub fn ffxFsr2ContextCreate( + context: *mut FfxFsr2Context, + contextDescription: *const FfxFsr2ContextDescription, + ) -> FfxErrorCode; +} +extern "C" { + #[doc = " Dispatch the various passes that constitute FidelityFX Super Resolution 2.\n\n FSR2 is a composite effect, meaning that it is compromised of multiple\n constituent passes (implemented as one or more clears, copies and compute\n dispatches). The ffxFsr2ContextDispatch function is the\n function which (via the use of the functions contained in the\n callbacks field of the FfxFsr2Context\n structure) utlimately generates the sequence of graphics API calls required\n each frame.\n\n As with the creation of the FfxFsr2Context correctly\n programming the FfxFsr2DispatchDescription is key to ensuring\n the correct operation of FSR2. It is particularly important to ensure that\n camera jitter is correctly applied to your application's projection matrix\n (or camera origin for raytraced applications). FSR2 provides the\n ffxFsr2GetJitterPhaseCount and\n ffxFsr2GetJitterOffset entry points to help applications\n correctly compute the camera jitter. Whatever jitter pattern is used by the\n application it should be correctly programmed to the\n jitterOffset field of the dispatchDescription\n structure. For more guidance on camera jitter please consult the\n documentation for ffxFsr2GetJitterOffset as well as the\n accompanying overview documentation for FSR2.\n\n @param [in] context A pointer to a FfxFsr2Context structure.\n @param [in] dispatchDescription A pointer to a FfxFsr2DispatchDescription structure.\n\n @retval\n FFX_OK The operation completed successfully.\n @retval\n FFX_ERROR_CODE_NULL_POINTER The operation failed because either context or dispatchDescription was NULL.\n @retval\n FFX_ERROR_OUT_OF_RANGE The operation failed because dispatchDescription.renderSize was larger than the maximum render resolution.\n @retval\n FFX_ERROR_NULL_DEVICE The operation failed because the device inside the context was NULL.\n @retval\n FFX_ERROR_BACKEND_API_ERROR The operation failed because of an error returned from the backend.\n\n @ingroup FSR2"] + pub fn ffxFsr2ContextDispatch( + context: *mut FfxFsr2Context, + dispatchDescription: *const FfxFsr2DispatchDescription, + ) -> FfxErrorCode; +} +extern "C" { + #[doc = " A helper function generate a Reactive mask from an opaque only texure and one containing translucent objects.\n\n @param [in] context A pointer to a FfxFsr2Context structure.\n @param [in] params A pointer to a FfxFsr2GenerateReactiveDescription structure\n\n @retval\n FFX_OK The operation completed successfully.\n\n @ingroup FSR2"] + pub fn ffxFsr2ContextGenerateReactiveMask( + context: *mut FfxFsr2Context, + params: *const FfxFsr2GenerateReactiveDescription, + ) -> FfxErrorCode; +} +extern "C" { + #[doc = " Destroy the FidelityFX Super Resolution context.\n\n @param [out] context A pointer to a FfxFsr2Context structure to destroy.\n\n @retval\n FFX_OK The operation completed successfully.\n @retval\n FFX_ERROR_CODE_NULL_POINTER The operation failed because either context was NULL.\n\n @ingroup FSR2"] + pub fn ffxFsr2ContextDestroy(context: *mut FfxFsr2Context) -> FfxErrorCode; +} +extern "C" { + #[doc = " Get the upscale ratio from the quality mode.\n\n The following table enumerates the mapping of the quality modes to\n per-dimension scaling ratios.\n\n Quality preset | Scale factor\n ----------------------------------------------------- | -------------\n FFX_FSR2_QUALITY_MODE_QUALITY | 1.5x\n FFX_FSR2_QUALITY_MODE_BALANCED | 1.7x\n FFX_FSR2_QUALITY_MODE_PERFORMANCE | 2.0x\n FFX_FSR2_QUALITY_MODE_ULTRA_PERFORMANCE | 3.0x\n\n Passing an invalid qualityMode will return 0.0f.\n\n @param [in] qualityMode The quality mode preset.\n\n @returns\n The upscaling the per-dimension upscaling ratio for\n qualityMode according to the table above.\n\n @ingroup FSR2"] + pub fn ffxFsr2GetUpscaleRatioFromQualityMode(qualityMode: FfxFsr2QualityMode) -> f32; +} +extern "C" { + #[doc = " A helper function to calculate the rendering resolution from a target\n resolution and desired quality level.\n\n This function applies the scaling factor returned by\n ffxFsr2GetUpscaleRatioFromQualityMode to each dimension.\n\n @param [out] renderWidth A pointer to a uint32_t which will hold the calculated render resolution width.\n @param [out] renderHeight A pointer to a uint32_t which will hold the calculated render resolution height.\n @param [in] displayWidth The target display resolution width.\n @param [in] displayHeight The target display resolution height.\n @param [in] qualityMode The desired quality mode for FSR 2 upscaling.\n\n @retval\n FFX_OK The operation completed successfully.\n @retval\n FFX_ERROR_INVALID_POINTER Either renderWidth or renderHeight was NULL.\n @retval\n FFX_ERROR_INVALID_ENUM An invalid quality mode was specified.\n\n @ingroup FSR2"] + pub fn ffxFsr2GetRenderResolutionFromQualityMode( + renderWidth: *mut u32, + renderHeight: *mut u32, + displayWidth: u32, + displayHeight: u32, + qualityMode: FfxFsr2QualityMode, + ) -> FfxErrorCode; +} +extern "C" { + #[doc = " A helper function to calculate the jitter phase count from display\n resolution.\n\n For more detailed information about the application of camera jitter to\n your application's rendering please refer to the\n ffxFsr2GetJitterOffset function.\n\n The table below shows the jitter phase count which this function\n would return for each of the quality presets.\n\n Quality preset | Scale factor | Phase count\n ----------------------------------------------------- | ------------- | ---------------\n FFX_FSR2_QUALITY_MODE_QUALITY | 1.5x | 18\n FFX_FSR2_QUALITY_MODE_BALANCED | 1.7x | 23\n FFX_FSR2_QUALITY_MODE_PERFORMANCE | 2.0x | 32\n FFX_FSR2_QUALITY_MODE_ULTRA_PERFORMANCE | 3.0x | 72\n Custom | [1..n]x | ceil(8*n^2)\n\n @param [in] renderWidth The render resolution width.\n @param [in] displayWidth The display resolution width.\n\n @returns\n The jitter phase count for the scaling factor between renderWidth and displayWidth.\n\n @ingroup FSR2"] + pub fn ffxFsr2GetJitterPhaseCount(renderWidth: i32, displayWidth: i32) -> i32; +} +extern "C" { + #[doc = " A helper function to calculate the subpixel jitter offset.\n\n FSR2 relies on the application to apply sub-pixel jittering while rendering.\n This is typically included in the projection matrix of the camera. To make\n the application of camera jitter simple, the FSR2 API provides a small set\n of utility function which computes the sub-pixel jitter offset for a\n particular frame within a sequence of separate jitter offsets. To begin, the\n index within the jitter phase must be computed. To calculate the\n sequence's length, you can call the ffxFsr2GetJitterPhaseCount\n function. The index should be a value which is incremented each frame modulo\n the length of the sequence computed by ffxFsr2GetJitterPhaseCount.\n The index within the jitter phase is passed to\n ffxFsr2GetJitterOffset via the index parameter.\n\n This function uses a Halton(2,3) sequence to compute the jitter offset.\n The ultimate index used for the sequence is index %\n phaseCount.\n\n It is important to understand that the values returned from the\n ffxFsr2GetJitterOffset function are in unit pixel space, and\n in order to composite this correctly into a projection matrix we must\n convert them into projection offsets. This is done as per the pseudo code\n listing which is shown below.\n\n const int32_t jitterPhaseCount = ffxFsr2GetJitterPhaseCount(renderWidth, displayWidth);\n\n float jitterX = 0;\n float jitterY = 0;\n ffxFsr2GetJitterOffset(&jitterX, &jitterY, index, jitterPhaseCount);\n\n const float jitterX = 2.0f * jitterX / (float)renderWidth;\n const float jitterY = -2.0f * jitterY / (float)renderHeight;\n const Matrix4 jitterTranslationMatrix = translateMatrix(Matrix3::identity, Vector3(jitterX, jitterY, 0));\n const Matrix4 jitteredProjectionMatrix = jitterTranslationMatrix * projectionMatrix;\n\n Jitter should be applied to all rendering. This includes opaque, alpha\n transparent, and raytraced objects. For rasterized objects, the sub-pixel\n jittering values calculated by the iffxFsr2GetJitterOffset\n function can be applied to the camera projection matrix which is ultimately\n used to perform transformations during vertex shading. For raytraced\n rendering, the sub-pixel jitter should be applied to the ray's origin,\n often the camera's position.\n\n Whether you elect to use the ffxFsr2GetJitterOffset function\n or your own sequence generator, you must program the\n jitterOffset field of the\n FfxFsr2DispatchParameters structure in order to inform FSR2\n of the jitter offset that has been applied in order to render each frame.\n\n If not using the recommended ffxFsr2GetJitterOffset function,\n care should be taken that your jitter sequence never generates a null vector;\n that is value of 0 in both the X and Y dimensions.\n\n @param [out] outX A pointer to a float which will contain the subpixel jitter offset for the x dimension.\n @param [out] outY A pointer to a float which will contain the subpixel jitter offset for the y dimension.\n @param [in] index The index within the jitter sequence.\n @param [in] phaseCount The length of jitter phase. See ffxFsr2GetJitterPhaseCount.\n\n @retval\n FFX_OK The operation completed successfully.\n @retval\n FFX_ERROR_INVALID_POINTER Either outX or outY was NULL.\n @retval\n FFX_ERROR_INVALID_ARGUMENT Argument phaseCount must be greater than 0.\n\n @ingroup FSR2"] + pub fn ffxFsr2GetJitterOffset( + outX: *mut f32, + outY: *mut f32, + index: i32, + phaseCount: i32, + ) -> FfxErrorCode; +} +extern "C" { + #[doc = " A helper function to check if a resource is\n FFX_FSR2_RESOURCE_IDENTIFIER_NULL.\n\n @param [in] resource A FfxResource.\n\n @returns\n true The resource was not FFX_FSR2_RESOURCE_IDENTIFIER_NULL.\n @returns\n false The resource was FFX_FSR2_RESOURCE_IDENTIFIER_NULL.\n\n @ingroup FSR2"] + pub fn ffxFsr2ResourceIsNull(resource: FfxResource) -> bool; +} +extern "C" { + #[doc = " Query how much memory is required for the Vulkan backend's scratch buffer.\n\n @returns\n The size (in bytes) of the required scratch memory buffer for the VK backend."] + pub fn ffxFsr2GetScratchMemorySizeVK(physicalDevice: VkPhysicalDevice) -> usize; +} +extern "C" { + #[doc = " Populate an interface with pointers for the VK backend.\n\n @param [out] fsr2Interface A pointer to a FfxFsr2Interface structure to populate with pointers.\n @param [in] device A Vulkan device.\n @param [in] scratchBuffer A pointer to a buffer of memory which can be used by the DirectX(R)12 backend.\n @param [in] scratchBufferSize The size (in bytes) of the buffer pointed to by scratchBuffer.\n @param [in] physicalDevice The Vulkan physical device that FSR 2.0 will be executed on.\n @param [in] getDeviceProcAddr A function pointer to vkGetDeviceProcAddr which is used to obtain all the other Vulkan functions.\n\n @retval\n FFX_OK The operation completed successfully.\n @retval\n FFX_ERROR_CODE_INVALID_POINTER The interface pointer was NULL.\n\n @ingroup FSR2 VK"] + pub fn ffxFsr2GetInterfaceVK( + outInterface: *mut FfxFsr2Interface, + scratchBuffer: *mut ::std::os::raw::c_void, + scratchBufferSize: usize, + physicalDevice: VkPhysicalDevice, + getDeviceProcAddr: PFN_vkGetDeviceProcAddr, + ) -> FfxErrorCode; +} +extern "C" { + #[doc = " Create a FfxFsr2Device from a VkDevice.\n\n @param [in] device A pointer to the Vulkan logical device.\n\n @returns\n An abstract FidelityFX device.\n\n @ingroup FSR2 VK"] + pub fn ffxGetDeviceVK(device: VkDevice) -> FfxDevice; +} +extern "C" { + #[doc = " Create a FfxCommandList from a VkCommandBuffer.\n\n @param [in] cmdBuf A pointer to the Vulkan command buffer.\n\n @returns\n An abstract FidelityFX command list.\n\n @ingroup FSR2 VK"] + pub fn ffxGetCommandListVK(cmdBuf: VkCommandBuffer) -> FfxCommandList; +} +extern "C" { + #[doc = " Create a FfxResource from a VkImage.\n\n @param [in] context A pointer to a FfxFsr2Context structure.\n @param [in] imgVk A Vulkan image resource.\n @param [in] imageView An image view of the given image resource.\n @param [in] width The width of the image resource.\n @param [in] height The height of the image resource.\n @param [in] imgFormat The format of the image resource.\n @param [in] name (optional) A name string to identify the resource in debug mode.\n @param [in] state The state the resource is currently in.\n\n @returns\n An abstract FidelityFX resources.\n\n @ingroup FSR2 VK"] + pub fn ffxGetTextureResourceVK( + context: *mut FfxFsr2Context, + imgVk: VkImage, + imageView: VkImageView, + width: u32, + height: u32, + imgFormat: VkFormat, + name: *mut u32, + state: FfxResourceStates, + ) -> FfxResource; +} +extern "C" { + #[doc = " Create a FfxResource from a VkBuffer.\n\n @param [in] context A pointer to a FfxFsr2Context structure.\n @param [in] bufVk A Vulkan buffer resource.\n @param [in] size The size of the buffer resource.\n @param [in] name (optional) A name string to identify the resource in debug mode.\n @param [in] state The state the resource is currently in.\n\n @returns\n An abstract FidelityFX resources.\n\n @ingroup FSR2 VK"] + pub fn ffxGetBufferResourceVK( + context: *mut FfxFsr2Context, + bufVk: VkBuffer, + size: u32, + name: *mut u32, + state: FfxResourceStates, + ) -> FfxResource; +} diff --git a/crates/fsr/src/lib.rs b/crates/fsr/src/lib.rs new file mode 100644 index 0000000000000..11d53548765b4 --- /dev/null +++ b/crates/fsr/src/lib.rs @@ -0,0 +1,17 @@ +#![allow(improper_ctypes)] // https://github.com/rust-lang/rust-bindgen/issues/1549 +#![allow(non_camel_case_types)] +#![allow(non_snake_case)] +#![allow(non_upper_case_globals)] +#![allow(rustdoc::broken_intra_doc_links)] +#![allow(unused)] + +include!("bindings.rs"); + +type PFN_vkGetDeviceProcAddr = ash::vk::PFN_vkGetDeviceProcAddr; +type VkBuffer = ash::vk::Buffer; +type VkCommandBuffer = ash::vk::CommandBuffer; +type VkDevice = ash::vk::Device; +pub type VkFormat = ash::vk::Format; +pub type VkImage = ash::vk::Image; +pub type VkImageView = ash::vk::ImageView; +type VkPhysicalDevice = ash::vk::PhysicalDevice; diff --git a/docs/cargo_features.md b/docs/cargo_features.md index ff4d5313efc3c..619484cb7b455 100644 --- a/docs/cargo_features.md +++ b/docs/cargo_features.md @@ -61,6 +61,7 @@ The default feature set enables most of the expected features of a game engine, |exr|EXR image format support| |file_watcher|Enables watching the filesystem for Bevy Asset hot-reloading| |flac|FLAC audio format support| +|fsr|Enable support for FidelityFX Super Resolution| |glam_assert|Enable assertions to check the validity of parameters passed to glam| |ios_simulator|Enable support for the ios_simulator by downgrading some rendering capabilities| |jpeg|JPEG image format support|