From 4338283ec620291f5e044f6379c307a0d0dcd6f3 Mon Sep 17 00:00:00 2001 From: chyyran Date: Sun, 29 Sep 2024 01:41:02 -0400 Subject: [PATCH] rt(d3d12): allow creating input view without a CPU handle --- librashader-cli/src/render/d3d12/mod.rs | 2 +- librashader-runtime-d3d12/src/filter_chain.rs | 4 +- librashader-runtime-d3d12/src/texture.rs | 60 ++++++++++++++----- .../tests/hello_triangle/mod.rs | 2 +- 4 files changed, 48 insertions(+), 20 deletions(-) diff --git a/librashader-cli/src/render/d3d12/mod.rs b/librashader-cli/src/render/d3d12/mod.rs index b905cdc4..15712a57 100644 --- a/librashader-cli/src/render/d3d12/mod.rs +++ b/librashader-cli/src/render/d3d12/mod.rs @@ -156,7 +156,7 @@ impl RenderTest for Direct3D12 { &cmd, D3D12InputImage { resource: self.texture.to_ref(), - descriptor: *self._heap_slot.as_ref(), + descriptor: None, }, &viewport, frame, diff --git a/librashader-runtime-d3d12/src/filter_chain.rs b/librashader-runtime-d3d12/src/filter_chain.rs index 91d19d13..d39ce1ba 100644 --- a/librashader-runtime-d3d12/src/filter_chain.rs +++ b/librashader-runtime-d3d12/src/filter_chain.rs @@ -336,7 +336,7 @@ impl FilterChainD3D12 { let rtv_heap = unsafe { D3D12DescriptorHeap::new( device, - (MAX_BINDINGS_COUNT as usize) * shader_count + (1 + MAX_BINDINGS_COUNT as usize) * shader_count + MIPMAP_RESERVED_WORKHEAP_DESCRIPTORS + lut_count, ) @@ -735,7 +735,7 @@ impl FilterChainD3D12 { Some(fbo.create_shader_resource_view(&mut self.staging_heap, filter, wrap_mode)?); } - let original = unsafe { InputTexture::new_from_raw(input, filter, wrap_mode) }; + let original = unsafe { InputTexture::new_from_raw(input, filter, wrap_mode, &self.common.d3d12, &mut self.staging_heap)? }; let mut source = original.clone(); // swap output and feedback **before** recording command buffers diff --git a/librashader-runtime-d3d12/src/texture.rs b/librashader-runtime-d3d12/src/texture.rs index 6f429865..1813151f 100644 --- a/librashader-runtime-d3d12/src/texture.rs +++ b/librashader-runtime-d3d12/src/texture.rs @@ -6,12 +6,9 @@ use librashader_common::{FilterMode, GetSize, Size, WrapMode}; use std::mem::ManuallyDrop; use std::ops::Deref; use windows::core::InterfaceRef; -use windows::Win32::Graphics::Direct3D12::{ - ID3D12Device, ID3D12Resource, D3D12_CPU_DESCRIPTOR_HANDLE, D3D12_RENDER_TARGET_VIEW_DESC, - D3D12_RENDER_TARGET_VIEW_DESC_0, D3D12_RESOURCE_DIMENSION_TEXTURE2D, - D3D12_RTV_DIMENSION_TEXTURE2D, D3D12_TEX2D_RTV, -}; +use windows::Win32::Graphics::Direct3D12::{ID3D12Device, ID3D12Resource, D3D12_CPU_DESCRIPTOR_HANDLE, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING, D3D12_RENDER_TARGET_VIEW_DESC, D3D12_RENDER_TARGET_VIEW_DESC_0, D3D12_RESOURCE_DIMENSION_TEXTURE2D, D3D12_RTV_DIMENSION_TEXTURE2D, D3D12_SHADER_RESOURCE_VIEW_DESC, D3D12_SHADER_RESOURCE_VIEW_DESC_0, D3D12_SRV_DIMENSION_TEXTURE2D, D3D12_TEX2D_RTV, D3D12_TEX2D_SRV}; use windows::Win32::Graphics::Dxgi::Common::DXGI_FORMAT; +use crate::error::FilterChainError; /// A **non-owning** reference to a ID3D12Resource. /// This does not `AddRef` or `Release` the underlying interface. @@ -21,7 +18,16 @@ pub type D3D12ResourceRef<'a> = InterfaceRef<'a, ID3D12Resource>; #[derive(Clone)] pub struct D3D12InputImage<'a> { pub resource: InterfaceRef<'a, ID3D12Resource>, - pub descriptor: D3D12_CPU_DESCRIPTOR_HANDLE, + pub descriptor: Option, +} + +impl<'a> From> for D3D12InputImage<'a> { + fn from(value: InterfaceRef<'a, ID3D12Resource>) -> Self { + Self { + resource: value, + descriptor: None + } + } } #[derive(Clone)] @@ -30,12 +36,6 @@ pub(crate) enum InputDescriptor { Raw(D3D12_CPU_DESCRIPTOR_HANDLE), } -impl InputDescriptor { - fn is_raw(&self) -> bool { - matches!(self, InputDescriptor::Raw(_)) - } -} - #[derive(Clone)] pub(crate) enum OutputDescriptor { Owned(D3D12DescriptorHeapSlot), @@ -186,17 +186,45 @@ impl InputTexture { image: D3D12InputImage, filter: FilterMode, wrap_mode: WrapMode, - ) -> InputTexture { + device: &ID3D12Device, + heap: &mut D3D12DescriptorHeap, + ) -> error::Result { let desc = unsafe { image.resource.GetDesc() }; - InputTexture { + if desc.Dimension != D3D12_RESOURCE_DIMENSION_TEXTURE2D { + return Err(FilterChainError::InvalidDimensionError(desc.Dimension)); + } + + let descriptor = image.descriptor.map_or_else(|| { + let slot = heap.allocate_descriptor()?; + unsafe { + let srv_desc = D3D12_SHADER_RESOURCE_VIEW_DESC { + Format: desc.Format, + ViewDimension: D3D12_SRV_DIMENSION_TEXTURE2D, + Shader4ComponentMapping: D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING, + Anonymous: D3D12_SHADER_RESOURCE_VIEW_DESC_0 { + Texture2D: D3D12_TEX2D_SRV { + MipLevels: desc.MipLevels as u32, + ..Default::default() + }, + }, + }; + device.CreateShaderResourceView(image.resource.deref(), Some(&srv_desc), *slot.as_ref()); + } + + Ok::<_, FilterChainError>(InputDescriptor::Owned(slot)) + }, |raw| Ok(InputDescriptor::Raw(raw)))?; + + Ok(InputTexture { resource: unsafe { std::mem::transmute(image.resource) }, - descriptor: InputDescriptor::Raw(image.descriptor), + descriptor, size: Size::new(desc.Width as u32, desc.Height), format: desc.Format, wrap_mode, filter, - } + }) } + + } impl Clone for InputTexture { diff --git a/librashader-runtime-d3d12/tests/hello_triangle/mod.rs b/librashader-runtime-d3d12/tests/hello_triangle/mod.rs index fa983804..5d9fe564 100644 --- a/librashader-runtime-d3d12/tests/hello_triangle/mod.rs +++ b/librashader-runtime-d3d12/tests/hello_triangle/mod.rs @@ -621,7 +621,7 @@ pub mod d3d12_hello_triangle { command_list, D3D12InputImage { resource: resources.framebuffer.to_ref(), - descriptor: framebuffer, + descriptor: Some(framebuffer), }, &Viewport { x: 0.0,