diff --git a/librashader-runtime-d3d11/src/filter_chain.rs b/librashader-runtime-d3d11/src/filter_chain.rs index 5c34d92..90f800d 100644 --- a/librashader-runtime-d3d11/src/filter_chain.rs +++ b/librashader-runtime-d3d11/src/filter_chain.rs @@ -17,7 +17,8 @@ use windows::core::PCSTR; use windows::s; use windows::Win32::Graphics::Direct3D11::{D3D11_BIND_CONSTANT_BUFFER, D3D11_BIND_SHADER_RESOURCE, D3D11_BUFFER_DESC, D3D11_CPU_ACCESS_WRITE, D3D11_INPUT_ELEMENT_DESC, D3D11_INPUT_PER_VERTEX_DATA, D3D11_RESOURCE_MISC_FLAG, D3D11_RESOURCE_MISC_GENERATE_MIPS, D3D11_SAMPLER_DESC, D3D11_TEXTURE2D_DESC, D3D11_USAGE_DEFAULT, D3D11_USAGE_DYNAMIC, ID3D11Buffer, ID3D11Device, ID3D11DeviceContext, ID3D11RenderTargetView, ID3D11ShaderResourceView}; use windows::Win32::Graphics::Dxgi::Common::{DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_SAMPLE_DESC}; -use crate::filter_pass::{ConstantBuffer, ConstantBufferBinding, FilterPass}; +use librashader_runtime::uniforms::UniformStorage; +use crate::filter_pass::{ConstantBufferBinding, FilterPass}; use crate::framebuffer::OutputFramebuffer; use crate::quad_render::DrawQuad; use crate::render_target::RenderTarget; @@ -126,6 +127,17 @@ impl FilterChain { None }; + let uniform_storage = UniformStorage::new(reflection + .ubo + .as_ref() + .map(|ubo| ubo.size as usize) + .unwrap_or(0), + reflection + .push_constant + .as_ref() + .map(|push| push.size as usize) + .unwrap_or(0)); + let mut uniform_bindings = FxHashMap::default(); for param in reflection.meta.parameter_meta.values() { uniform_bindings.insert( @@ -155,8 +167,9 @@ impl FilterChain { vertex_layout: vao, pixel_shader: ps, uniform_bindings, - uniform_buffer: ConstantBuffer::new(ubo_cbuffer), - push_buffer: ConstantBuffer::new(push_cbuffer), + uniform_storage, + uniform_buffer: ubo_cbuffer, + push_buffer: push_cbuffer, source, config: config.clone(), }) diff --git a/librashader-runtime-d3d11/src/filter_pass.rs b/librashader-runtime-d3d11/src/filter_pass.rs index e74ed0a..3b8dbf3 100644 --- a/librashader-runtime-d3d11/src/filter_pass.rs +++ b/librashader-runtime-d3d11/src/filter_pass.rs @@ -12,6 +12,7 @@ use std::error::Error; use windows::core::ConstBuffer; use windows::Win32::Graphics::Direct3D::ID3DBlob; use windows::Win32::Graphics::Direct3D11::{ID3D11Buffer, ID3D11PixelShader, ID3D11SamplerState, ID3D11ShaderResourceView, ID3D11VertexShader, D3D11_MAP_WRITE_DISCARD, ID3D11InputLayout}; +use librashader_runtime::uniforms::UniformStorage; use crate::render_target::RenderTarget; use crate::samplers::SamplerSet; @@ -22,21 +23,6 @@ pub struct ConstantBufferBinding { pub buffer: ID3D11Buffer, } -pub struct ConstantBuffer { - pub binding: Option, - pub storage: Box<[u8]>, -} - -impl ConstantBuffer { - pub fn new(binding: Option) -> Self { - let storage = vec![0u8; binding.as_ref().map(|c| c.size as usize).unwrap_or(0)].into_boxed_slice(); - Self { - binding, - storage - } - } -} - // slang_process.cpp 141 pub struct FilterPass { pub reflection: ShaderReflection, @@ -47,8 +33,9 @@ pub struct FilterPass { pub uniform_bindings: FxHashMap, - pub uniform_buffer: ConstantBuffer, - pub push_buffer: ConstantBuffer, + pub uniform_storage: UniformStorage, + pub uniform_buffer: Option, + pub push_buffer: Option, pub source: ShaderSource, pub config: ShaderPassConfig, } @@ -104,22 +91,12 @@ impl FilterPass { // Bind MVP if let Some(offset) = self.uniform_bindings.get(&VariableSemantics::MVP.into()) { - let mvp_size = mvp.len() * std::mem::size_of::(); - let (buffer, offset) = match offset { - MemberOffset::Ubo(offset) => (&mut self.uniform_buffer.storage, *offset), - MemberOffset::PushConstant(offset) => (&mut self.push_buffer.storage, *offset), - }; - FilterPass::build_mvp(&mut buffer[offset..][..mvp_size], mvp) + self.uniform_storage.bind_mat4(*offset, mvp, None); } // bind OutputSize if let Some(offset) = self.uniform_bindings.get(&VariableSemantics::Output.into()) { - let (buffer, offset) = match offset { - MemberOffset::Ubo(offset) => (&mut self.uniform_buffer.storage, *offset), - MemberOffset::PushConstant(offset) => (&mut self.push_buffer.storage, *offset), - }; - - FilterPass::build_vec4(&mut buffer[offset..][..16], fb_size) + self.uniform_storage.bind_vec4(*offset, fb_size, None); } // bind FinalViewportSize @@ -127,14 +104,7 @@ impl FilterPass { .uniform_bindings .get(&VariableSemantics::FinalViewport.into()) { - let (buffer, offset) = match offset { - MemberOffset::Ubo(offset) => (&mut self.uniform_buffer.storage, *offset), - MemberOffset::PushConstant(offset) => (&mut self.push_buffer.storage, *offset), - }; - FilterPass::build_vec4( - &mut buffer[offset..][..16], - viewport_size, - ) + self.uniform_storage.bind_vec4(*offset, viewport_size, None); } // bind FrameCount @@ -142,11 +112,7 @@ impl FilterPass { .uniform_bindings .get(&VariableSemantics::FrameCount.into()) { - let (buffer, offset) = match offset { - MemberOffset::Ubo(offset) => (&mut self.uniform_buffer.storage, *offset), - MemberOffset::PushConstant(offset) => (&mut self.push_buffer.storage, *offset), - }; - FilterPass::build_uniform(&mut buffer[offset..][..4], frame_count) + self.uniform_storage.bind_scalar(*offset, frame_count, None); } // bind FrameDirection @@ -154,11 +120,7 @@ impl FilterPass { .uniform_bindings .get(&VariableSemantics::FrameDirection.into()) { - let (buffer, offset) = match offset { - MemberOffset::Ubo(offset) => (&mut self.uniform_buffer.storage, *offset), - MemberOffset::PushConstant(offset) => (&mut self.push_buffer.storage, *offset), - }; - FilterPass::build_uniform(&mut buffer[offset..][..4], frame_direction) + self.uniform_storage.bind_scalar(*offset, frame_direction, None); } // bind Original sampler @@ -176,11 +138,7 @@ impl FilterPass { .uniform_bindings .get(&TextureSemantics::Original.semantics(0).into()) { - let (buffer, offset) = match offset { - MemberOffset::Ubo(offset) => (&mut self.uniform_buffer.storage, *offset), - MemberOffset::PushConstant(offset) => (&mut self.push_buffer.storage, *offset), - }; - FilterPass::build_vec4(&mut buffer[offset..][..16], original.view.size); + self.uniform_storage.bind_vec4(*offset, original.view.size, None); } // bind Source sampler @@ -199,11 +157,7 @@ impl FilterPass { .uniform_bindings .get(&TextureSemantics::Source.semantics(0).into()) { - let (buffer, offset) = match offset { - MemberOffset::Ubo(offset) => (&mut self.uniform_buffer.storage, *offset), - MemberOffset::PushConstant(offset) => (&mut self.push_buffer.storage, *offset), - }; - FilterPass::build_vec4(&mut buffer[offset..][..16], source.view.size); + self.uniform_storage.bind_vec4(*offset, source.view.size, None); } if let Some(binding) = self @@ -219,11 +173,7 @@ impl FilterPass { .uniform_bindings .get(&TextureSemantics::OriginalHistory.semantics(0).into()) { - let (buffer, offset) = match offset { - MemberOffset::Ubo(offset) => (&mut self.uniform_buffer.storage, *offset), - MemberOffset::PushConstant(offset) => (&mut self.push_buffer.storage, *offset), - }; - FilterPass::build_vec4(&mut buffer[offset..][..16], original.view.size); + self.uniform_storage.bind_vec4(*offset, original.view.size, None); } // for (index, output) in parent.history_textures.iter().enumerate() { @@ -318,10 +268,6 @@ impl FilterPass { }) { let id = id.as_str(); - let (buffer, offset) = match offset { - MemberOffset::Ubo(offset) => (&mut self.uniform_buffer.storage, *offset), - MemberOffset::PushConstant(offset) => (&mut self.push_buffer.storage, *offset), - }; // todo: cache parameters. // presets override params @@ -341,7 +287,7 @@ impl FilterPass { .map(|p| p.value) .unwrap_or(default); - FilterPass::build_uniform(&mut buffer[offset..][..4], value) + self.uniform_storage.bind_scalar(*offset, value, None); } // bind luts @@ -359,14 +305,7 @@ impl FilterPass { .uniform_bindings .get(&TextureSemantics::User.semantics(*index).into()) { - let (buffer, offset) = match offset { - MemberOffset::Ubo(offset) => (&mut self.uniform_buffer.storage, *offset), - MemberOffset::PushConstant(offset) => (&mut self.push_buffer.storage, *offset), - }; - FilterPass::build_vec4( - &mut buffer[offset..][..16], - lut.image.view.size, - ); + self.uniform_storage.bind_vec4(*offset, lut.image.view.size, None); } } @@ -397,11 +336,11 @@ impl FilterPass { - if let Some(ubo) = &self.uniform_buffer.binding { + if let Some(ubo) = &self.uniform_buffer { // upload uniforms unsafe { let map = context.Map(&ubo.buffer, 0, D3D11_MAP_WRITE_DISCARD, 0)?; - std::ptr::copy_nonoverlapping(self.uniform_buffer.storage.as_ptr(), map.pData.cast(), ubo.size as usize); + std::ptr::copy_nonoverlapping(self.uniform_storage.ubo.as_ptr(), map.pData.cast(), ubo.size as usize); context.Unmap(&ubo.buffer, 0); } @@ -417,11 +356,11 @@ impl FilterPass { } } - if let Some(push) = &self.push_buffer.binding { + if let Some(push) = &self.push_buffer { // upload push constants unsafe { let map = context.Map(&push.buffer, 0, D3D11_MAP_WRITE_DISCARD, 0)?; - std::ptr::copy_nonoverlapping(self.push_buffer.storage.as_ptr(), map.pData.cast(), push.size as usize); + std::ptr::copy_nonoverlapping(self.uniform_storage.push.as_ptr(), map.pData.cast(), push.size as usize); context.Unmap(&push.buffer, 0); } diff --git a/librashader-runtime-d3d11/src/hello_triangle.rs b/librashader-runtime-d3d11/src/hello_triangle.rs index a94fadb..fed1bfd 100644 --- a/librashader-runtime-d3d11/src/hello_triangle.rs +++ b/librashader-runtime-d3d11/src/hello_triangle.rs @@ -474,7 +474,8 @@ pub mod d3d11_hello_triangle { width: tex2d_desc.Width, height: tex2d_desc.Height, } }, OutputFramebuffer { - rtv, + rtv: resources.rtv.clone(), + // rtv, size: Size { width: tex2d_desc.Width, height: tex2d_desc.Height, @@ -488,6 +489,8 @@ pub mod d3d11_hello_triangle { MaxDepth: 1.0, }, }).unwrap(); + + // self.context.CopyResource(&resources.backbuffer, &backup); } unsafe { diff --git a/librashader-runtime-d3d11/src/lib.rs b/librashader-runtime-d3d11/src/lib.rs index ef5efa6..198d96d 100644 --- a/librashader-runtime-d3d11/src/lib.rs +++ b/librashader-runtime-d3d11/src/lib.rs @@ -35,6 +35,7 @@ mod tests { #[test] fn triangle_d3d11() { let sample = hello_triangle::d3d11_hello_triangle::Sample::new("../test/slang-shaders/crt/crt-royale.slangp").unwrap(); + // let sample = hello_triangle::d3d11_hello_triangle::Sample::new("../test/basic.slangp").unwrap(); hello_triangle::main(sample).unwrap();