From 10cd240868486e88c73d688e74e0348e12abe78a Mon Sep 17 00:00:00 2001 From: chyyran Date: Tue, 31 Jan 2023 19:23:57 -0500 Subject: [PATCH] d3d12: bind logic --- librashader-runtime-d3d12/src/filter_chain.rs | 3 +- librashader-runtime-d3d12/src/filter_pass.rs | 100 +++++++++++++++++- librashader-runtime-d3d12/src/heap.rs | 34 +++--- librashader-runtime-d3d12/src/luts.rs | 32 +++--- librashader-runtime-d3d12/src/texture.rs | 16 ++- 5 files changed, 142 insertions(+), 43 deletions(-) diff --git a/librashader-runtime-d3d12/src/filter_chain.rs b/librashader-runtime-d3d12/src/filter_chain.rs index 9aa57f5..bae8428 100644 --- a/librashader-runtime-d3d12/src/filter_chain.rs +++ b/librashader-runtime-d3d12/src/filter_chain.rs @@ -420,7 +420,8 @@ impl FilterChainD3D12 { pipeline: graphics_pipeline, config: config.clone(), texture_heap, - sampler_heap + sampler_heap, + source, }) } diff --git a/librashader-runtime-d3d12/src/filter_pass.rs b/librashader-runtime-d3d12/src/filter_pass.rs index 6b40637..4d09e55 100644 --- a/librashader-runtime-d3d12/src/filter_pass.rs +++ b/librashader-runtime-d3d12/src/filter_pass.rs @@ -1,13 +1,18 @@ use rustc_hash::FxHashMap; -use librashader_common::Size; +use windows::Win32::Graphics::Direct3D11::ID3D11Device; +use windows::Win32::Graphics::Direct3D12::ID3D12Device; +use librashader_common::{ImageFormat, Size}; +use librashader_preprocess::ShaderSource; use librashader_presets::ShaderPassConfig; -use librashader_reflect::reflect::semantics::{MemberOffset, UniformBinding}; +use librashader_reflect::reflect::semantics::{MemberOffset, TextureBinding, UniformBinding}; use librashader_reflect::reflect::ShaderReflection; -use librashader_runtime::binding::TextureInput; +use librashader_runtime::binding::{BindSemantics, TextureInput}; use librashader_runtime::uniforms::UniformStorage; use crate::buffer::D3D12ConstantBuffer; +use crate::filter_chain::FilterCommon; use crate::graphics_pipeline::D3D12GraphicsPipeline; -use crate::heap::{D3D12DescriptorHeap, ResourceWorkHeap, SamplerWorkHeap}; +use crate::heap::{D3D12DescriptorHeap, D3D12DescriptorHeapSlot, ResourceWorkHeap, SamplerWorkHeap}; +use crate::samplers::SamplerSet; use crate::texture::InputTexture; pub(crate) struct FilterPass { @@ -20,6 +25,8 @@ pub(crate) struct FilterPass { pub(crate) ubo_cbuffer: Option, pub(crate) texture_heap: D3D12DescriptorHeap, pub(crate) sampler_heap: D3D12DescriptorHeap, + pub source: ShaderSource, + } impl TextureInput for InputTexture { @@ -27,3 +34,88 @@ impl TextureInput for InputTexture { self.size } } +// +impl BindSemantics for FilterPass { + type InputTexture = InputTexture; + type SamplerSet = SamplerSet; + type DescriptorSet<'a> = + ( + &'a mut [D3D12DescriptorHeapSlot; 16], + &'a mut [D3D12DescriptorHeapSlot; 16], + ); + type DeviceContext = (); + type UniformOffset = MemberOffset; + + fn bind_texture<'a>( + descriptors: &mut Self::DescriptorSet<'a>, + samplers: &Self::SamplerSet, + binding: &TextureBinding, + texture: &Self::InputTexture, + _device: &Self::DeviceContext, + ) { + let (texture_binding, + sampler_binding) = descriptors; + + unsafe { + texture_binding[binding.binding as usize] + .copy_descriptor(*texture.descriptor.as_ref()); + sampler_binding[binding.binding as usize] + .copy_descriptor(*samplers.get(texture.wrap_mode, texture.filter).as_ref()) + } + } +} + +impl FilterPass { + pub fn get_format(&self) -> ImageFormat { + let fb_format = self.source.format; + if let Some(format) = self.config.get_format_override() { + format + } else if fb_format == ImageFormat::Unknown { + ImageFormat::R8G8B8A8Unorm + } else { + fb_format + } + } + + // framecount should be pre-modded + fn build_semantics<'a>( + &mut self, + pass_index: usize, + parent: &FilterCommon, + mvp: &[f32; 16], + frame_count: u32, + frame_direction: i32, + fb_size: Size, + viewport_size: Size, + mut descriptors: ( + &'a mut [D3D12DescriptorHeapSlot; 16], + &'a mut [D3D12DescriptorHeapSlot; 16], + ), + original: &InputTexture, + source: &InputTexture, + ) { + Self::bind_semantics( + &(), + &parent.samplers, + &mut self.uniform_storage, + &mut descriptors, + mvp, + frame_count, + frame_direction, + fb_size, + viewport_size, + original, + source, + &self.uniform_bindings, + &self.reflection.meta.texture_meta, + parent.output_textures[0..pass_index] + .iter() + .map(|o| o.as_ref()), + parent.feedback_textures.iter().map(|o| o.as_ref()), + parent.history_textures.iter().map(|o| o.as_ref()), + parent.luts.iter().map(|(u, i)| (*u, i.as_ref())), + &self.source.parameters, + &parent.config.parameters, + ); + } +} \ No newline at end of file diff --git a/librashader-runtime-d3d12/src/heap.rs b/librashader-runtime-d3d12/src/heap.rs index 16c3c30..81914ef 100644 --- a/librashader-runtime-d3d12/src/heap.rs +++ b/librashader-runtime-d3d12/src/heap.rs @@ -1,6 +1,7 @@ use crate::error; use std::cell::RefCell; use std::marker::PhantomData; +use std::ops::Deref; use std::sync::Arc; use windows::Win32::Graphics::Direct3D12::{ID3D12DescriptorHeap, ID3D12Device, D3D12_CPU_DESCRIPTOR_HANDLE, D3D12_DESCRIPTOR_HEAP_DESC, D3D12_DESCRIPTOR_HEAP_FLAG_NONE, D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER, D3D12_GPU_DESCRIPTOR_HANDLE, D3D12_DESCRIPTOR_HEAP_TYPE}; @@ -22,7 +23,6 @@ pub struct ResourceWorkHeap; #[derive(Clone)] pub struct SamplerWorkHeap; - impl const D3D12HeapType for SamplerPaletteHeap { // sampler palettes just get set directly fn get_desc(size: usize) -> D3D12_DESCRIPTOR_HEAP_DESC { @@ -87,6 +87,21 @@ impl D3D12DescriptorHeapSlot { pub fn index(&self) -> usize { self.slot } + + /// unsafe because type must match + pub unsafe fn copy_descriptor(&mut self, source: D3D12_CPU_DESCRIPTOR_HANDLE) { + unsafe { + let heap = self.heap.deref() + .borrow(); + + heap.device.CopyDescriptorsSimple( + 1, + self.cpu_handle, + source, + heap.ty + ) + } + } } impl AsRef for D3D12DescriptorHeapSlot { @@ -258,23 +273,8 @@ impl D3D12DescriptorHeap { todo!("error need to fail"); } - pub fn copy_descriptors(&mut self, - source: &[&D3D12_CPU_DESCRIPTOR_HANDLE; NUM_DESC]) - -> error::Result<[D3D12DescriptorHeapSlot; NUM_DESC]> { + pub fn alloc_range(&mut self)-> error::Result<[D3D12DescriptorHeapSlot; NUM_DESC]> { let dest = array_init::try_array_init(|_| self.alloc_slot())?; - let inner = self.0.borrow_mut(); - - unsafe { - // unfortunately we can't guarantee that the source and dest descriptors are contiguous so... - for i in 0..NUM_DESC { - inner.device.CopyDescriptorsSimple( - 1, - *dest[i].as_ref(), - *source[i], - inner.ty - ); - } - } Ok(dest) } } diff --git a/librashader-runtime-d3d12/src/luts.rs b/librashader-runtime-d3d12/src/luts.rs index 8b106c1..760777f 100644 --- a/librashader-runtime-d3d12/src/luts.rs +++ b/librashader-runtime-d3d12/src/luts.rs @@ -13,10 +13,7 @@ use crate::texture::InputTexture; pub struct LutTexture { resource: ID3D12Resource, - descriptor: D3D12DescriptorHeapSlot, - size: Size, - filter: FilterMode, - wrap_mode: WrapMode, + view: InputTexture, miplevels: Option, } @@ -160,12 +157,16 @@ impl LutTexture { d3d12_resource_transition(cmd, &resource, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE) } + let view = InputTexture::new( + descriptor, + source.size, + ImageFormat::R8G8B8A8Unorm, + wrap_mode, + filter, + ); Ok((LutTexture { resource, - descriptor, - size: source.size, - filter, - wrap_mode, + view, miplevels: if mipmap { Some(miplevels) } else { None } }, upload)) } @@ -174,16 +175,15 @@ impl LutTexture { if let Some(miplevels) = self.miplevels { gen_mips.generate_mipmaps(&self.resource, miplevels, - self.size, ImageFormat::R8G8B8A8Unorm.into())? + self.view.size, ImageFormat::R8G8B8A8Unorm.into())? } Ok(()) } - - pub fn as_input(&self) - -> InputTexture { - InputTexture::new(self.descriptor.clone(), - self.size, ImageFormat::R8G8B8A8Unorm, - self.wrap_mode, self.filter) - } } + +impl AsRef for LutTexture { + fn as_ref(&self) -> &InputTexture { + &self.view + } +} \ No newline at end of file diff --git a/librashader-runtime-d3d12/src/texture.rs b/librashader-runtime-d3d12/src/texture.rs index 308dcb4..863a2e9 100644 --- a/librashader-runtime-d3d12/src/texture.rs +++ b/librashader-runtime-d3d12/src/texture.rs @@ -2,12 +2,12 @@ use windows::Win32::Graphics::Direct3D12::{D3D12_CPU_DESCRIPTOR_HANDLE}; use librashader_common::{FilterMode, ImageFormat, Size, WrapMode}; use crate::heap::{CpuStagingHeap, D3D12DescriptorHeapSlot}; -enum InputDescriptor { +pub(crate) enum InputDescriptor { Owned(D3D12DescriptorHeapSlot), Raw(D3D12_CPU_DESCRIPTOR_HANDLE) } -enum OutputDescriptor { +pub(crate) enum OutputDescriptor { Owned(D3D12DescriptorHeapSlot), Raw(D3D12_CPU_DESCRIPTOR_HANDLE) } @@ -59,11 +59,11 @@ impl OutputTexture { } pub struct InputTexture { - descriptor: InputDescriptor, + pub(crate) descriptor: InputDescriptor, pub(crate) size: Size, format: ImageFormat, - wrap_mode: WrapMode, - filter: FilterMode + pub(crate) wrap_mode: WrapMode, + pub(crate) filter: FilterMode } impl InputTexture { @@ -100,3 +100,9 @@ impl InputTexture { } } + +impl AsRef for InputTexture { + fn as_ref(&self) -> &InputTexture { + self + } +} \ No newline at end of file