From 7d8c1370837a6b064a810e1bbf4d1574a5b5fbf5 Mon Sep 17 00:00:00 2001 From: chyyran Date: Sun, 5 Feb 2023 16:17:14 -0500 Subject: [PATCH] rt: abstract reusable bindingmeta ops --- librashader-runtime-d3d11/src/filter_chain.rs | 49 +-- librashader-runtime-d3d12/src/filter_chain.rs | 343 ++++++++---------- .../src/filter_chain/filter_impl.rs | 76 +--- librashader-runtime-vk/src/filter_chain.rs | 53 +-- librashader-runtime/src/binding.rs | 66 +++- 5 files changed, 254 insertions(+), 333 deletions(-) diff --git a/librashader-runtime-d3d11/src/filter_chain.rs b/librashader-runtime-d3d11/src/filter_chain.rs index d49b935..7b5e514 100644 --- a/librashader-runtime-d3d11/src/filter_chain.rs +++ b/librashader-runtime-d3d11/src/filter_chain.rs @@ -5,7 +5,9 @@ use librashader_presets::{ShaderPreset, TextureConfig}; use librashader_reflect::back::targets::HLSL; use librashader_reflect::back::{CompileReflectShader, CompileShader}; use librashader_reflect::front::GlslangCompilation; -use librashader_reflect::reflect::semantics::{ShaderSemantics, TextureSemantics, UniformBinding}; +use librashader_reflect::reflect::semantics::{ + BindingMeta, ShaderSemantics, TextureSemantics, UniformBinding, +}; use librashader_reflect::reflect::ReflectShader; use librashader_runtime::image::{Image, UVDirection}; use rustc_hash::FxHashMap; @@ -23,7 +25,8 @@ use crate::samplers::SamplerSet; use crate::util::d3d11_compile_bound_shader; use crate::{error, util, D3D11OutputView}; use librashader_reflect::reflect::presets::{CompilePresetTarget, ShaderPassArtifact}; -use librashader_runtime::binding::TextureInput; +use librashader_runtime::binding::{BindingUtil, TextureInput}; +use librashader_runtime::quad::{QuadType, IDENTITY_MVP}; use librashader_runtime::uniforms::UniformStorage; use windows::Win32::Graphics::Direct3D11::{ ID3D11Buffer, ID3D11Device, ID3D11DeviceContext, D3D11_BIND_CONSTANT_BUFFER, D3D11_BUFFER_DESC, @@ -31,7 +34,6 @@ use windows::Win32::Graphics::Direct3D11::{ D3D11_TEXTURE2D_DESC, D3D11_USAGE_DEFAULT, D3D11_USAGE_DYNAMIC, }; use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT_R8G8B8A8_UNORM; -use librashader_runtime::quad::{IDENTITY_MVP, QuadType}; pub struct FilterMutable { pub(crate) passes_enabled: usize, @@ -284,18 +286,7 @@ impl FilterChainD3D11 { .unwrap_or(0), ); - let mut uniform_bindings = FxHashMap::default(); - for param in reflection.meta.parameter_meta.values() { - uniform_bindings.insert(UniformBinding::Parameter(param.id.clone()), param.offset); - } - - for (semantics, param) in &reflection.meta.unique_meta { - uniform_bindings.insert(UniformBinding::SemanticVariable(*semantics), param.offset); - } - - for (semantics, param) in &reflection.meta.texture_size_meta { - uniform_bindings.insert(UniformBinding::TextureSize(*semantics), param.offset); - } + let uniform_bindings = reflection.meta.create_binding_map(|param| param.offset()); filters.push(FilterPass { reflection, @@ -319,28 +310,8 @@ impl FilterChainD3D11 { context: &ID3D11DeviceContext, filters: &Vec, ) -> error::Result<(VecDeque, Box<[Option]>)> { - let mut required_images = 0; - - for pass in filters { - // If a shader uses history size, but not history, we still need to keep the texture. - let texture_count = pass - .reflection - .meta - .texture_meta - .iter() - .filter(|(semantics, _)| semantics.semantics == TextureSemantics::OriginalHistory) - .count(); - let texture_size_count = pass - .reflection - .meta - .texture_size_meta - .iter() - .filter(|(semantics, _)| semantics.semantics == TextureSemantics::OriginalHistory) - .count(); - - required_images = std::cmp::max(required_images, texture_count); - required_images = std::cmp::max(required_images, texture_size_count); - } + let mut required_images = + BindingMeta::calculate_required_history(filters.iter().map(|f| &f.reflection.meta)); // not using frame history; if required_images <= 1 { @@ -522,7 +493,7 @@ impl FilterChainD3D11 { &original, &source, RenderTarget::new(target.as_output_framebuffer()?, Some(IDENTITY_MVP)), - QuadType::Offscreen + QuadType::Offscreen, )?; source = InputTexture { @@ -554,7 +525,7 @@ impl FilterChainD3D11 { &original, &source, viewport.into(), - QuadType::Final + QuadType::Final, )?; } diff --git a/librashader-runtime-d3d12/src/filter_chain.rs b/librashader-runtime-d3d12/src/filter_chain.rs index 1baedb7..2c52868 100644 --- a/librashader-runtime-d3d12/src/filter_chain.rs +++ b/librashader-runtime-d3d12/src/filter_chain.rs @@ -1,39 +1,51 @@ -use std::collections::VecDeque; -use crate::{error, graphics_pipeline, util}; -use crate::descriptor_heap::{D3D12DescriptorHeap, CpuStagingHeap, ResourceWorkHeap, SamplerWorkHeap, RenderTargetHeap}; -use crate::samplers::SamplerSet; -use crate::luts::LutTexture; -use librashader_presets::{ShaderPreset, TextureConfig}; -use librashader_reflect::back::targets::{DXIL, HLSL}; -use librashader_reflect::front::GlslangCompilation; -use librashader_reflect::reflect::presets::{CompilePresetTarget, ShaderPassArtifact}; -use librashader_runtime::image::{Image, UVDirection}; -use rustc_hash::FxHashMap; -use std::error::Error; -use std::path::Path; -use spirv_cross::hlsl::ShaderModel; -use windows::core::Interface; -use windows::w; -use windows::Win32::Foundation::CloseHandle; -use windows::Win32::Graphics::Direct3D12::{ID3D12CommandAllocator, ID3D12CommandQueue, ID3D12Device, ID3D12Fence, ID3D12GraphicsCommandList, D3D12_COMMAND_LIST_TYPE_DIRECT, D3D12_COMMAND_QUEUE_DESC, D3D12_COMMAND_QUEUE_FLAG_NONE, D3D12_FENCE_FLAG_NONE, ID3D12DescriptorHeap, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET}; -use windows::Win32::Graphics::Direct3D::Dxc::{CLSID_DxcCompiler, CLSID_DxcLibrary, CLSID_DxcValidator, DxcCreateInstance, IDxcCompiler, IDxcLibrary, IDxcUtils, IDxcValidator}; -use windows::Win32::System::Threading::{CreateEventA, ResetEvent, WaitForSingleObject}; -use windows::Win32::System::WindowsProgramming::INFINITE; -use librashader_common::{ImageFormat, Size, Viewport}; -use librashader_reflect::back::{CompileReflectShader, CompileShader}; -use librashader_reflect::reflect::ReflectShader; -use librashader_reflect::reflect::semantics::{MAX_BINDINGS_COUNT, ShaderSemantics, TextureSemantics, UniformBinding}; -use librashader_runtime::binding::TextureInput; -use librashader_runtime::quad::{DEFAULT_MVP, IDENTITY_MVP, QuadType}; -use librashader_runtime::uniforms::UniformStorage; use crate::buffer::{D3D12Buffer, D3D12ConstantBuffer}; +use crate::descriptor_heap::{ + CpuStagingHeap, D3D12DescriptorHeap, RenderTargetHeap, ResourceWorkHeap, SamplerWorkHeap, +}; use crate::filter_pass::FilterPass; use crate::framebuffer::OwnedImage; use crate::graphics_pipeline::{D3D12GraphicsPipeline, D3D12RootSignature}; +use crate::luts::LutTexture; use crate::mipmap::D3D12MipmapGen; use crate::quad_render::DrawQuad; use crate::render_target::RenderTarget; +use crate::samplers::SamplerSet; use crate::texture::{InputTexture, OutputDescriptor, OutputTexture}; +use crate::{error, graphics_pipeline, util}; +use librashader_common::{ImageFormat, Size, Viewport}; +use librashader_presets::{ShaderPreset, TextureConfig}; +use librashader_reflect::back::targets::{DXIL, HLSL}; +use librashader_reflect::back::{CompileReflectShader, CompileShader}; +use librashader_reflect::front::GlslangCompilation; +use librashader_reflect::reflect::presets::{CompilePresetTarget, ShaderPassArtifact}; +use librashader_reflect::reflect::semantics::{ + BindingMeta, ShaderSemantics, TextureSemantics, UniformBinding, MAX_BINDINGS_COUNT, +}; +use librashader_reflect::reflect::ReflectShader; +use librashader_runtime::binding::{BindingUtil, TextureInput}; +use librashader_runtime::image::{Image, UVDirection}; +use librashader_runtime::quad::{QuadType, DEFAULT_MVP, IDENTITY_MVP}; +use librashader_runtime::uniforms::UniformStorage; +use rustc_hash::FxHashMap; +use spirv_cross::hlsl::ShaderModel; +use std::collections::VecDeque; +use std::error::Error; +use std::path::Path; +use windows::core::Interface; +use windows::w; +use windows::Win32::Foundation::CloseHandle; +use windows::Win32::Graphics::Direct3D::Dxc::{ + CLSID_DxcCompiler, CLSID_DxcLibrary, CLSID_DxcValidator, DxcCreateInstance, IDxcCompiler, + IDxcLibrary, IDxcUtils, IDxcValidator, +}; +use windows::Win32::Graphics::Direct3D12::{ + ID3D12CommandAllocator, ID3D12CommandQueue, ID3D12DescriptorHeap, ID3D12Device, ID3D12Fence, + ID3D12GraphicsCommandList, D3D12_COMMAND_LIST_TYPE_DIRECT, D3D12_COMMAND_QUEUE_DESC, + D3D12_COMMAND_QUEUE_FLAG_NONE, D3D12_FENCE_FLAG_NONE, + D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET, +}; +use windows::Win32::System::Threading::{CreateEventA, ResetEvent, WaitForSingleObject}; +use windows::Win32::System::WindowsProgramming::INFINITE; type DxilShaderPassMeta = ShaderPassArtifact>; type HlslShaderPassMeta = ShaderPassArtifact>; @@ -55,7 +67,7 @@ pub struct FilterChainD3D12 { texture_heap: ID3D12DescriptorHeap, sampler_heap: ID3D12DescriptorHeap, - residuals: Vec + residuals: Vec, } pub(crate) struct FilterCommon { @@ -95,50 +107,46 @@ impl FilterChainD3D12 { let shader_copy = preset.shaders.clone(); - let (passes, semantics) = DXIL::compile_preset_passes::>( - preset.shaders, - &preset.textures, - ).unwrap(); + let (passes, semantics) = + DXIL::compile_preset_passes::>( + preset.shaders, + &preset.textures, + ) + .unwrap(); let (hlsl_passes, _) = HLSL::compile_preset_passes::>( shader_copy, &preset.textures, - ).unwrap(); + ) + .unwrap(); let samplers = SamplerSet::new(device)?; let mipmap_gen = D3D12MipmapGen::new(device).unwrap(); let draw_quad = DrawQuad::new(device)?; - let mut staging_heap = - D3D12DescriptorHeap::new(device, - (MAX_BINDINGS_COUNT as usize) * - shader_count + 2048 + lut_count)?; - let mut rtv_heap = - D3D12DescriptorHeap::new(device, - (MAX_BINDINGS_COUNT as usize) * - shader_count + 2048 + lut_count)?; + let mut staging_heap = D3D12DescriptorHeap::new( + device, + (MAX_BINDINGS_COUNT as usize) * shader_count + 2048 + lut_count, + )?; + let mut rtv_heap = D3D12DescriptorHeap::new( + device, + (MAX_BINDINGS_COUNT as usize) * shader_count + 2048 + lut_count, + )?; - - - let luts = FilterChainD3D12::load_luts(device, &mut staging_heap, &preset.textures, &mipmap_gen).unwrap(); + let luts = + FilterChainD3D12::load_luts(device, &mut staging_heap, &preset.textures, &mipmap_gen) + .unwrap(); let root_signature = D3D12RootSignature::new(device)?; - let (texture_heap, sampler_heap, filters) - = FilterChainD3D12::init_passes(device, &root_signature, passes, hlsl_passes, &semantics).unwrap(); - - - + let (texture_heap, sampler_heap, filters) = + FilterChainD3D12::init_passes(device, &root_signature, passes, hlsl_passes, &semantics) + .unwrap(); // initialize output framebuffers let mut output_framebuffers = Vec::new(); output_framebuffers.resize_with(filters.len(), || { - OwnedImage::new( - device, - Size::new(1, 1), - ImageFormat::R8G8B8A8Unorm, - false, - ) + OwnedImage::new(device, Size::new(1, 1), ImageFormat::R8G8B8A8Unorm, false) }); // resolve all results @@ -154,12 +162,7 @@ impl FilterChainD3D12 { // // initialize feedback framebuffers let mut feedback_framebuffers = Vec::new(); feedback_framebuffers.resize_with(filters.len(), || { - OwnedImage::new( - device, - Size::new(1, 1), - ImageFormat::R8G8B8A8Unorm, - false, - ) + OwnedImage::new(device, Size::new(1, 1), ImageFormat::R8G8B8A8Unorm, false) }); // resolve all results @@ -200,7 +203,7 @@ impl FilterChainD3D12 { history_framebuffers, texture_heap, sampler_heap, - residuals: Vec::new() + residuals: Vec::new(), }) } @@ -208,28 +211,8 @@ impl FilterChainD3D12 { device: &ID3D12Device, filters: &Vec, ) -> error::Result<(VecDeque, Box<[Option]>)> { - let mut required_images = 0; - - for pass in filters { - // If a shader uses history size, but not history, we still need to keep the texture. - let texture_count = pass - .reflection - .meta - .texture_meta - .iter() - .filter(|(semantics, _)| semantics.semantics == TextureSemantics::OriginalHistory) - .count(); - let texture_size_count = pass - .reflection - .meta - .texture_size_meta - .iter() - .filter(|(semantics, _)| semantics.semantics == TextureSemantics::OriginalHistory) - .count(); - - required_images = std::cmp::max(required_images, texture_count); - required_images = std::cmp::max(required_images, texture_size_count); - } + let mut required_images = + BindingMeta::calculate_required_history(filters.iter().map(|f| &f.reflection.meta)); // not using frame history; if required_images <= 1 { @@ -242,12 +225,7 @@ impl FilterChainD3D12 { // eprintln!("[history] using frame history with {required_images} images"); let mut framebuffers = VecDeque::with_capacity(required_images); framebuffers.resize_with(required_images, || { - OwnedImage::new( - device, - Size::new(1, 1), - ImageFormat::R8G8B8A8Unorm, - false, - ) + OwnedImage::new(device, Size::new(1, 1), ImageFormat::R8G8B8A8Unorm, false) }); let framebuffers = framebuffers @@ -260,14 +238,14 @@ impl FilterChainD3D12 { Ok((framebuffers, history_textures.into_boxed_slice())) } - fn load_luts( device: &ID3D12Device, heap: &mut D3D12DescriptorHeap, textures: &[TextureConfig], - mipmap_gen: &D3D12MipmapGen + mipmap_gen: &D3D12MipmapGen, ) -> error::Result> { - let mut work_heap: D3D12DescriptorHeap = D3D12DescriptorHeap::new(device, u16::MAX as usize)?; + let mut work_heap: D3D12DescriptorHeap = + D3D12DescriptorHeap::new(device, u16::MAX as usize)?; unsafe { // 1 time queue infrastructure for lut uploads let command_pool: ID3D12CommandAllocator = @@ -290,7 +268,6 @@ impl FilterChainD3D12 { let mut luts = FxHashMap::default(); - for (index, texture) in textures.iter().enumerate() { let image = Image::load(&texture.path, UVDirection::TopLeft)?; @@ -324,8 +301,7 @@ impl FilterChainD3D12 { cmd.Reset(&command_pool, None).unwrap(); - let residuals = mipmap_gen - .mipmapping_context(&cmd, &mut work_heap, |context| { + let residuals = mipmap_gen.mipmapping_context(&cmd, &mut work_heap, |context| { for lut in luts.values() { lut.generate_mipmaps(context).unwrap() } @@ -350,54 +326,48 @@ impl FilterChainD3D12 { } } - fn init_passes(device: &ID3D12Device, - root_signature: &D3D12RootSignature, - passes: Vec, - hlsl_passes: Vec, - semantics: &ShaderSemantics,) - -> error::Result<(ID3D12DescriptorHeap, ID3D12DescriptorHeap, Vec)> { - let validator: IDxcValidator = unsafe { - DxcCreateInstance(&CLSID_DxcValidator)? - }; + fn init_passes( + device: &ID3D12Device, + root_signature: &D3D12RootSignature, + passes: Vec, + hlsl_passes: Vec, + semantics: &ShaderSemantics, + ) -> error::Result<(ID3D12DescriptorHeap, ID3D12DescriptorHeap, Vec)> { + let validator: IDxcValidator = unsafe { DxcCreateInstance(&CLSID_DxcValidator)? }; - let library: IDxcUtils = unsafe { - DxcCreateInstance(&CLSID_DxcLibrary)? - }; + let library: IDxcUtils = unsafe { DxcCreateInstance(&CLSID_DxcLibrary)? }; - let compiler: IDxcCompiler = unsafe { - DxcCreateInstance(&CLSID_DxcCompiler)? - }; + let compiler: IDxcCompiler = unsafe { DxcCreateInstance(&CLSID_DxcCompiler)? }; let mut filters = Vec::new(); let shader_count = passes.len(); - let work_heap = - D3D12DescriptorHeap::::new(device, - (MAX_BINDINGS_COUNT as usize) * - shader_count)?; - let (work_heaps, texture_heap_handle) = unsafe { - work_heap.suballocate(MAX_BINDINGS_COUNT as usize) - }; - + let work_heap = D3D12DescriptorHeap::::new( + device, + (MAX_BINDINGS_COUNT as usize) * shader_count, + )?; + let (work_heaps, texture_heap_handle) = + unsafe { work_heap.suballocate(MAX_BINDINGS_COUNT as usize) }; let sampler_work_heap = - D3D12DescriptorHeap::new(device, - (MAX_BINDINGS_COUNT as usize) * shader_count)?; + D3D12DescriptorHeap::new(device, (MAX_BINDINGS_COUNT as usize) * shader_count)?; - let (sampler_work_heaps, sampler_heap_handle) = unsafe { - sampler_work_heap.suballocate(MAX_BINDINGS_COUNT as usize) - }; + let (sampler_work_heaps, sampler_heap_handle) = + unsafe { sampler_work_heap.suballocate(MAX_BINDINGS_COUNT as usize) }; - for (index, ((((config, source, mut dxil), (_, _, mut hlsl)), - mut texture_heap), mut sampler_heap)) - in passes.into_iter() + for ( + index, + ((((config, source, mut dxil), (_, _, mut hlsl)), mut texture_heap), mut sampler_heap), + ) in passes + .into_iter() .zip(hlsl_passes) .zip(work_heaps) .zip(sampler_work_heaps) - .enumerate() { - + .enumerate() + { let dxil_reflection = dxil.reflect(index, semantics)?; - let dxil = dxil.compile(Some(librashader_reflect::back::dxil::ShaderModel::ShaderModel6_0))?; - + let dxil = dxil.compile(Some( + librashader_reflect::back::dxil::ShaderModel::ShaderModel6_0, + ))?; let hlsl_reflection = hlsl.reflect(index, semantics)?; let hlsl = hlsl.compile(Some(ShaderModel::V6_0))?; @@ -408,27 +378,30 @@ impl FilterChainD3D12 { source.format } else { ImageFormat::R8G8B8A8Unorm - }.into(); + } + .into(); eprintln!("building pipeline for pass {:?}", index); /// incredibly cursed. let (reflection, graphics_pipeline) = if let Ok(graphics_pipeline) = - D3D12GraphicsPipeline::new_from_dxil(device, - &library, - &validator, - &dxil, - root_signature, - render_format + D3D12GraphicsPipeline::new_from_dxil( + device, + &library, + &validator, + &dxil, + root_signature, + render_format, ) { (dxil_reflection, graphics_pipeline) } else { - let graphics_pipeline = D3D12GraphicsPipeline::new_from_hlsl(device, - &library, - &compiler, - &hlsl, - root_signature, - render_format + let graphics_pipeline = D3D12GraphicsPipeline::new_from_hlsl( + device, + &library, + &compiler, + &hlsl, + root_signature, + render_format, )?; (hlsl_reflection, graphics_pipeline) }; @@ -460,18 +433,7 @@ impl FilterChainD3D12 { None }; - let mut uniform_bindings = FxHashMap::default(); - for param in reflection.meta.parameter_meta.values() { - uniform_bindings.insert(UniformBinding::Parameter(param.id.clone()), param.offset); - } - - for (semantics, param) in &reflection.meta.unique_meta { - uniform_bindings.insert(UniformBinding::SemanticVariable(*semantics), param.offset); - } - - for (semantics, param) in &reflection.meta.texture_size_meta { - uniform_bindings.insert(UniformBinding::TextureSize(*semantics), param.offset); - } + let uniform_bindings = reflection.meta.create_binding_map(|param| param.offset()); let texture_heap = texture_heap.alloc_range()?; let sampler_heap = sampler_heap.alloc_range()?; @@ -487,7 +449,6 @@ impl FilterChainD3D12 { sampler_heap, source, }) - } Ok((texture_heap_handle, sampler_heap_handle, filters)) @@ -501,8 +462,7 @@ impl FilterChainD3D12 { viewport: &Viewport, frame_count: usize, options: Option<&()>, - ) -> error::Result<()> - { + ) -> error::Result<()> { drop(self.residuals.drain(..)); let max = std::cmp::min(self.passes.len(), self.common.config.passes_enabled); @@ -521,9 +481,11 @@ impl FilterChainD3D12 { .zip(self.feedback_framebuffers.iter()) .zip(passes.iter()) { - *texture = Some(fbo.create_shader_resource_view(&mut self.staging_heap, - pass.config.filter, - pass.config.wrap_mode)?); + *texture = Some(fbo.create_shader_resource_view( + &mut self.staging_heap, + pass.config.filter, + pass.config.wrap_mode, + )?); } for (texture, fbo) in self @@ -532,12 +494,10 @@ impl FilterChainD3D12 { .iter_mut() .zip(self.history_framebuffers.iter()) { - *texture = Some(fbo.create_shader_resource_view(&mut self.staging_heap, - filter, - wrap_mode)?); + *texture = + Some(fbo.create_shader_resource_view(&mut self.staging_heap, filter, wrap_mode)?); } - let original = input; let mut source = unsafe { original.clone() }; @@ -576,33 +536,38 @@ impl FilterChainD3D12 { // refresh inputs self.common.feedback_textures[index] = Some( - self.feedback_framebuffers[index] - .create_shader_resource_view(&mut self.staging_heap, pass.config.filter, pass.config.wrap_mode)?, - ); - self.common.output_textures[index] = Some( - self.output_framebuffers[index] - .create_shader_resource_view(&mut self.staging_heap, pass.config.filter, pass.config.wrap_mode)?, + self.feedback_framebuffers[index].create_shader_resource_view( + &mut self.staging_heap, + pass.config.filter, + pass.config.wrap_mode, + )?, ); + self.common.output_textures[index] = + Some(self.output_framebuffers[index].create_shader_resource_view( + &mut self.staging_heap, + pass.config.filter, + pass.config.wrap_mode, + )?); } let passes_len = passes.len(); let (pass, last) = passes.split_at_mut(passes_len - 1); - unsafe { let heaps = [self.texture_heap.clone(), self.sampler_heap.clone()]; cmd.SetDescriptorHeaps(&heaps); cmd.SetGraphicsRootSignature(&self.common.root_signature.handle); } for (index, pass) in pass.iter_mut().enumerate() { - source.filter = pass.config.filter; source.wrap_mode = pass.config.wrap_mode; let target = &self.output_framebuffers[index]; - util::d3d12_resource_transition(&cmd, - &target.handle, - D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, - D3D12_RESOURCE_STATE_RENDER_TARGET); + util::d3d12_resource_transition( + &cmd, + &target.handle, + D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, + D3D12_RESOURCE_STATE_RENDER_TARGET, + ); let size = target.size; let view = target.create_render_target_view(&mut self.rtv_heap)?; @@ -610,7 +575,10 @@ impl FilterChainD3D12 { x: 0.0, y: 0.0, mvp: DEFAULT_MVP, - output: OutputTexture { descriptor: view.descriptor, size }, + output: OutputTexture { + descriptor: view.descriptor, + size, + }, }; pass.draw( @@ -627,13 +595,15 @@ impl FilterChainD3D12 { &original, &source, &out, - QuadType::Offscreen + QuadType::Offscreen, )?; - util::d3d12_resource_transition(&cmd, - &target.handle, - D3D12_RESOURCE_STATE_RENDER_TARGET, - D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE); + util::d3d12_resource_transition( + &cmd, + &target.handle, + D3D12_RESOURCE_STATE_RENDER_TARGET, + D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, + ); // let target_handle = target.create_shader_resource_view( // &mut self.staging_heap, // pass.config.filter, @@ -670,12 +640,11 @@ impl FilterChainD3D12 { &original, &source, &out, - QuadType::Final + QuadType::Final, )?; } // todo: history Ok(()) } - } diff --git a/librashader-runtime-gl/src/filter_chain/filter_impl.rs b/librashader-runtime-gl/src/filter_chain/filter_impl.rs index 2fe7139..f813bcd 100644 --- a/librashader-runtime-gl/src/filter_chain/filter_impl.rs +++ b/librashader-runtime-gl/src/filter_chain/filter_impl.rs @@ -17,11 +17,12 @@ use librashader_reflect::back::targets::GLSL; use librashader_reflect::back::{CompileReflectShader, CompileShader}; use librashader_reflect::front::GlslangCompilation; use librashader_reflect::reflect::semantics::{ - ShaderSemantics, TextureSemantics, UniformBinding, UniformMeta, + BindingMeta, ShaderSemantics, TextureSemantics, UniformBinding, UniformMeta, }; use librashader_reflect::reflect::presets::{CompilePresetTarget, ShaderPassArtifact}; use librashader_reflect::reflect::ReflectShader; +use librashader_runtime::binding::BindingUtil; use rustc_hash::FxHashMap; use spirv_cross::spirv::Decoration; use std::collections::VecDeque; @@ -52,7 +53,7 @@ pub struct FilterMutable { } impl FilterChainImpl { - fn reflect_uniform_location(pipeline: GLuint, meta: &impl UniformMeta) -> VariableLocation { + fn reflect_uniform_location(pipeline: GLuint, meta: &dyn UniformMeta) -> VariableLocation { let mut location = VariableLocation { ubo: None, push: None, @@ -251,45 +252,12 @@ impl FilterChainImpl { .unwrap_or(0), ); - let mut uniform_bindings = FxHashMap::default(); - for param in reflection.meta.parameter_meta.values() { - uniform_bindings.insert( - UniformBinding::Parameter(param.id.clone()), - UniformOffset::new( - Self::reflect_uniform_location(program, param), - param.offset, - ), - ); - } - - for (semantics, param) in &reflection.meta.unique_meta { - uniform_bindings.insert( - UniformBinding::SemanticVariable(*semantics), - UniformOffset::new( - Self::reflect_uniform_location(program, param), - param.offset, - ), - ); - } - - for (semantics, param) in &reflection.meta.texture_size_meta { - uniform_bindings.insert( - UniformBinding::TextureSize(*semantics), - UniformOffset::new( - Self::reflect_uniform_location(program, param), - param.offset, - ), - ); - } - - // eprintln!("{:#?}", reflection.meta.texture_meta); - // eprintln!("{:#?}", reflection.meta); - // eprintln!("{:#?}", locations); - // eprintln!("{:#?}", reflection.push_constant); - // eprintln!("====fragment===="); - // eprintln!("{:#}", glsl.fragment); - // eprintln!("====vertex===="); - // eprintln!("{:#}", glsl.vertex); + let uniform_bindings = reflection.meta.create_binding_map(|param| { + UniformOffset::new( + Self::reflect_uniform_location(program, param), + param.offset(), + ) + }); filters.push(FilterPass { reflection, @@ -312,28 +280,8 @@ impl FilterChainImpl { filter: FilterMode, wrap_mode: WrapMode, ) -> (VecDeque, Box<[InputTexture]>) { - let mut required_images = 0; - - for pass in filters { - // If a shader uses history size, but not history, we still need to keep the texture. - let texture_count = pass - .reflection - .meta - .texture_meta - .iter() - .filter(|(semantics, _)| semantics.semantics == TextureSemantics::OriginalHistory) - .count(); - let texture_size_count = pass - .reflection - .meta - .texture_size_meta - .iter() - .filter(|(semantics, _)| semantics.semantics == TextureSemantics::OriginalHistory) - .count(); - - required_images = std::cmp::max(required_images, texture_count); - required_images = std::cmp::max(required_images, texture_size_count); - } + let mut required_images = + BindingMeta::calculate_required_history(filters.iter().map(|f| &f.reflection.meta)); // not using frame history; if required_images <= 1 { @@ -475,7 +423,7 @@ impl FilterChainImpl { source.filter = pass.config.filter; source.mip_filter = pass.config.filter; source.wrap_mode = pass.config.wrap_mode; - + pass.draw( index, &self.common, diff --git a/librashader-runtime-vk/src/filter_chain.rs b/librashader-runtime-vk/src/filter_chain.rs index 449f58a..1608f09 100644 --- a/librashader-runtime-vk/src/filter_chain.rs +++ b/librashader-runtime-vk/src/filter_chain.rs @@ -20,15 +20,18 @@ use librashader_reflect::back::targets::SPIRV; use librashader_reflect::back::{CompileReflectShader, CompileShader}; use librashader_reflect::front::GlslangCompilation; use librashader_reflect::reflect::presets::{CompilePresetTarget, ShaderPassArtifact}; -use librashader_reflect::reflect::semantics::{ShaderSemantics, TextureSemantics, UniformBinding}; +use librashader_reflect::reflect::semantics::{ + BindingMeta, ShaderSemantics, TextureSemantics, UniformBinding, +}; use librashader_reflect::reflect::ReflectShader; +use librashader_runtime::binding::BindingUtil; use librashader_runtime::image::{Image, UVDirection}; +use librashader_runtime::quad::{QuadType, DEFAULT_MVP, IDENTITY_MVP}; use librashader_runtime::uniforms::UniformStorage; use rustc_hash::FxHashMap; use std::collections::VecDeque; use std::path::Path; use std::sync::Arc; -use librashader_runtime::quad::{DEFAULT_MVP, IDENTITY_MVP, QuadType}; /// A Vulkan device and metadata that is required by the shader runtime. pub struct VulkanObjects { @@ -238,9 +241,7 @@ impl FilterChainVulkan { passes, &semantics, frames_in_flight, - options - .map(|o| o.use_render_pass) - .unwrap_or(false), + options.map(|o| o.use_render_pass).unwrap_or(false), )?; let luts = FilterChainVulkan::load_luts(&device, &preset.textures)?; @@ -336,19 +337,7 @@ impl FilterChainVulkan { .unwrap_or(0), ); - let mut uniform_bindings = FxHashMap::default(); - - for param in reflection.meta.parameter_meta.values() { - uniform_bindings.insert(UniformBinding::Parameter(param.id.clone()), param.offset); - } - - for (semantics, param) in &reflection.meta.unique_meta { - uniform_bindings.insert(UniformBinding::SemanticVariable(*semantics), param.offset); - } - - for (semantics, param) in &reflection.meta.texture_size_meta { - uniform_bindings.insert(UniformBinding::TextureSize(*semantics), param.offset); - } + let uniform_bindings = reflection.meta.create_binding_map(|param| param.offset()); let render_pass_format = if !use_render_pass { vk::Format::UNDEFINED @@ -456,28 +445,8 @@ impl FilterChainVulkan { vulkan: &VulkanObjects, filters: &[FilterPass], ) -> error::Result<(VecDeque, Box<[Option]>)> { - let mut required_images = 0; - - for pass in filters { - // If a shader uses history size, but not history, we still need to keep the texture. - let texture_count = pass - .reflection - .meta - .texture_meta - .iter() - .filter(|(semantics, _)| semantics.semantics == TextureSemantics::OriginalHistory) - .count(); - let texture_size_count = pass - .reflection - .meta - .texture_size_meta - .iter() - .filter(|(semantics, _)| semantics.semantics == TextureSemantics::OriginalHistory) - .count(); - - required_images = std::cmp::max(required_images, texture_count); - required_images = std::cmp::max(required_images, texture_size_count); - } + let mut required_images = + BindingMeta::calculate_required_history(filters.iter().map(|f| &f.reflection.meta)); // not using frame history; if required_images <= 1 { @@ -738,7 +707,7 @@ impl FilterChainVulkan { &original, &source, &out, - QuadType::Offscreen + QuadType::Offscreen, )?; if target.max_miplevels > 1 && !self.disable_mipmaps { @@ -776,7 +745,7 @@ impl FilterChainVulkan { &original, &source, &out, - QuadType::Final + QuadType::Final, )?; intermediates.dispose_outputs(out.output); diff --git a/librashader-runtime/src/binding.rs b/librashader-runtime/src/binding.rs index 1b40680..384b65b 100644 --- a/librashader-runtime/src/binding.rs +++ b/librashader-runtime/src/binding.rs @@ -2,8 +2,10 @@ use crate::uniforms::{BindUniform, NoUniformBinder, UniformStorage}; use librashader_common::Size; use librashader_preprocess::ShaderParameter; use librashader_reflect::reflect::semantics::{ - MemberOffset, Semantic, TextureBinding, TextureSemantics, UniformBinding, UniqueSemantics, + BindingMeta, MemberOffset, Semantic, TextureBinding, TextureSemantics, UniformBinding, + UniformMeta, UniqueSemantics, }; +use rustc_hash::FxHashMap; use std::collections::HashMap; use std::hash::BuildHasher; use std::ops::{Deref, DerefMut}; @@ -266,3 +268,65 @@ where } } } + +/// Trait for objects that can be used to create a binding map. +pub trait BindingUtil { + /// Create the uniform binding map with the given reflection information. + fn create_binding_map( + &self, + f: impl Fn(&dyn UniformMeta) -> T, + ) -> FxHashMap; + + /// Calculate the number of required images for history. + fn calculate_required_history<'a>(pass_meta: impl Iterator) -> usize + where + Self: 'a; +} + +impl BindingUtil for BindingMeta { + fn create_binding_map( + &self, + f: impl Fn(&dyn UniformMeta) -> T, + ) -> FxHashMap { + let mut uniform_bindings = FxHashMap::default(); + for param in self.parameter_meta.values() { + uniform_bindings.insert(UniformBinding::Parameter(param.id.clone()), f(param)); + } + + for (semantics, param) in &self.unique_meta { + uniform_bindings.insert(UniformBinding::SemanticVariable(*semantics), f(param)); + } + + for (semantics, param) in &self.texture_size_meta { + uniform_bindings.insert(UniformBinding::TextureSize(*semantics), f(param)); + } + + uniform_bindings + } + + fn calculate_required_history<'a>(pass_meta: impl Iterator) -> usize + where + Self: 'a, + { + let mut required_images = 0; + + for pass in pass_meta { + // If a shader uses history size, but not history, we still need to keep the texture. + let texture_count = pass + .texture_meta + .iter() + .filter(|(semantics, _)| semantics.semantics == TextureSemantics::OriginalHistory) + .count(); + let texture_size_count = pass + .texture_size_meta + .iter() + .filter(|(semantics, _)| semantics.semantics == TextureSemantics::OriginalHistory) + .count(); + + required_images = std::cmp::max(required_images, texture_count); + required_images = std::cmp::max(required_images, texture_size_count); + } + + required_images + } +}