From f0bc2d92af04bcf15f036296761ef2b42aaa7687 Mon Sep 17 00:00:00 2001 From: chyyran Date: Sat, 26 Nov 2022 23:57:22 -0500 Subject: [PATCH] d3d11: load shaders and buffers --- README.md | 2 ++ librashader-reflect/src/reflect/semantics.rs | 3 ++ librashader-runtime-d3d11/src/filter_chain.rs | 30 ++++++++----------- librashader-runtime-d3d11/src/filter_pass.rs | 21 +++++++++++-- librashader-runtime-d3d11/src/texture.rs | 9 ++---- librashader-runtime-gl/src/lib.rs | 2 +- 6 files changed, 39 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index f0c1b48..7373c30 100644 --- a/README.md +++ b/README.md @@ -53,8 +53,10 @@ Please report an issue if you run into a shader that works in RetroArch, but not * Copying of in-flight framebuffer contents is done via `glBlitFramebuffer` rather than drawing a quad into an intermediate FBO. * Sampler objects are used rather than `glTexParameter`. * Sampler inputs and outputs are not renamed. This is useful for debugging shaders in RenderDoc. + * UBO and Push Constant Buffer sizes are padded to 16-byte boundaries. * Direct3D 11 * The staging buffer is not kept around when loading static textures (LUTs). + * HDR10 support is not part of the shader runtime and is not supported. ## License The core parts of librashader such as the preprocessor, the preset parser, diff --git a/librashader-reflect/src/reflect/semantics.rs b/librashader-reflect/src/reflect/semantics.rs index 3e74c06..35ee892 100644 --- a/librashader-reflect/src/reflect/semantics.rs +++ b/librashader-reflect/src/reflect/semantics.rs @@ -142,12 +142,15 @@ impl BindingStage { #[derive(Debug)] pub struct UboReflection { pub binding: u32, + /// Get this size of this UBO buffer. + /// The size returned by reflection is always aligned to a 16 byte boundary. pub size: u32, pub stage_mask: BindingStage, } #[derive(Debug)] pub struct PushReflection { + /// The size returned by reflection is always aligned to a 16 byte boundary. pub size: u32, pub stage_mask: BindingStage, } diff --git a/librashader-runtime-d3d11/src/filter_chain.rs b/librashader-runtime-d3d11/src/filter_chain.rs index 9baa406..5835f0a 100644 --- a/librashader-runtime-d3d11/src/filter_chain.rs +++ b/librashader-runtime-d3d11/src/filter_chain.rs @@ -17,7 +17,7 @@ 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}; use windows::Win32::Graphics::Dxgi::Common::{DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_R8G8B8A8_UNORM, DXGI_SAMPLE_DESC}; -use crate::filter_pass::{ConstantBuffer, FilterPass}; +use crate::filter_pass::{ConstantBuffer, ConstantBufferBinding, FilterPass}; use crate::samplers::SamplerSet; use crate::util; use crate::util::d3d11_compile_bound_shader; @@ -40,6 +40,7 @@ struct D3D11VertexLayout { pub struct FilterChain { pub common: FilterCommon, + pub passes: Vec, } pub struct Direct3D11 { @@ -104,7 +105,7 @@ impl FilterChain { } fn create_constant_buffer(device: &ID3D11Device, size: u32) -> util::Result { - + eprintln!("{size}"); unsafe { let buffer = device.CreateBuffer(&D3D11_BUFFER_DESC { ByteWidth: size, @@ -123,7 +124,7 @@ impl FilterChain { device: &ID3D11Device, passes: Vec, semantics: &ReflectSemantics, - ) -> util::Result<()> + ) -> util::Result> { // let mut filters = Vec::new(); let mut filters = Vec::new(); @@ -172,28 +173,24 @@ impl FilterChain { let ubo_cbuffer = if let Some(ubo) = &reflection.ubo && ubo.size != 0 { - let size = (ubo.size + 0xf) & !0xf; - let buffer = FilterChain::create_constant_buffer(device, size)?; - Some(ConstantBuffer { + let buffer = FilterChain::create_constant_buffer(device, ubo.size)?; + Some(ConstantBufferBinding { binding: ubo.binding, size: ubo.size, stage_mask: ubo.stage_mask, buffer, - storage: vec![0u8; size as usize].into_boxed_slice(), }) } else { None }; let push_cbuffer = if let Some(push) = &reflection.push_constant && push.size != 0 { - let size = (push.size + 0xf) & !0xf; - let buffer = FilterChain::create_constant_buffer(device, size)?; - Some(ConstantBuffer { + let buffer = FilterChain::create_constant_buffer(device, push.size)?; + Some(ConstantBufferBinding { binding: if ubo_cbuffer.is_some() { 1 } else { 0 }, size: push.size, stage_mask: push.stage_mask, buffer, - storage: vec![0u8; size as usize].into_boxed_slice(), }) } else { None @@ -228,14 +225,14 @@ impl FilterChain { vertex_layout: vertex_ia, pixel_shader: ps, uniform_bindings, - uniform_buffer: ubo_cbuffer, - push_buffer: push_cbuffer, + uniform_buffer: ConstantBuffer::new(ubo_cbuffer), + push_buffer: ConstantBuffer::new(push_cbuffer), source, config: config.clone(), }) } - Ok(()) + Ok(filters) } /// Load a filter chain from a pre-parsed `ShaderPreset`. pub fn load_from_preset(device: &ID3D11Device, preset: ShaderPreset) -> util::Result { @@ -244,7 +241,7 @@ impl FilterChain { let samplers = SamplerSet::new(device)?; // initialize passes - let filters = FilterChain::init_passes(device, passes, &semantics)?; + let filters = FilterChain::init_passes(device, passes, &semantics).unwrap(); // let default_filter = filters.first().map(|f| f.config.filter).unwrap_or_default(); // let default_wrap = filters @@ -271,7 +268,7 @@ impl FilterChain { // FilterChain::init_history(&filters, default_filter, default_wrap); Ok(FilterChain { - // passes: filters, + passes: filters, // output_framebuffers: output_framebuffers.into_boxed_slice(), // feedback_framebuffers: feedback_framebuffers.into_boxed_slice(), // history_framebuffers, @@ -285,7 +282,6 @@ impl FilterChain { // we don't need the reflect semantics once all locations have been bound per pass. // semantics, preset, - // luts, // output_textures: output_textures.into_boxed_slice(), // feedback_textures: feedback_textures.into_boxed_slice(), // history_textures, diff --git a/librashader-runtime-d3d11/src/filter_pass.rs b/librashader-runtime-d3d11/src/filter_pass.rs index ce882cc..ce7faba 100644 --- a/librashader-runtime-d3d11/src/filter_pass.rs +++ b/librashader-runtime-d3d11/src/filter_pass.rs @@ -12,17 +12,32 @@ use librashader_reflect::reflect::semantics::{ use librashader_reflect::reflect::ShaderReflection; use rustc_hash::FxHashMap; 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}; -pub struct ConstantBuffer { +pub struct ConstantBufferBinding { pub binding: u32, pub size: u32, pub stage_mask: BindingStage, 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, @@ -33,8 +48,8 @@ pub struct FilterPass { pub uniform_bindings: FxHashMap, - pub uniform_buffer: Option, - pub push_buffer: Option, + pub uniform_buffer: ConstantBuffer, + pub push_buffer: ConstantBuffer, pub source: ShaderSource, pub config: ShaderPassConfig, } diff --git a/librashader-runtime-d3d11/src/texture.rs b/librashader-runtime-d3d11/src/texture.rs index bf06a90..d9fbc8f 100644 --- a/librashader-runtime-d3d11/src/texture.rs +++ b/librashader-runtime-d3d11/src/texture.rs @@ -70,14 +70,9 @@ impl OwnedTexture { format_support |= D3D11_FORMAT_SUPPORT_RENDER_TARGET.0; } - eprintln!("s {:?}, p {:?}, l {:?}", source.size, source.pitch, source.bytes.len()); - eprintln!("{:#?}", desc); + // eprintln!("s {:?}, p {:?}, l {:?}", source.size, source.pitch, source.bytes.len()); + // eprintln!("{:#?}", desc); - // let data = Some(&D3D11_SUBRESOURCE_DATA { - // pSysMem: source.bytes.as_ptr().cast(), - // SysMemPitch: source.pitch as u32, - // SysMemSlicePitch: 0 - // }); unsafe { let handle = device.CreateTexture2D(&desc, None).unwrap(); diff --git a/librashader-runtime-gl/src/lib.rs b/librashader-runtime-gl/src/lib.rs index ecce0e7..10686c3 100644 --- a/librashader-runtime-gl/src/lib.rs +++ b/librashader-runtime-gl/src/lib.rs @@ -29,7 +29,7 @@ mod tests { fn triangle_gl() { let (glfw, window, events, shader, vao) = hello_triangle::setup(); let mut filter = - FilterChain::load_from_path("../test/slang-shaders/vhs/VHSPro.slangp") + FilterChain::load_from_path("../test/slang-shaders/crt/crt-royale.slangp") .unwrap(); hello_triangle::do_loop(glfw, window, events, shader, vao, &mut filter); }