diff --git a/librashader-runtime-d3d12/src/filter_chain.rs b/librashader-runtime-d3d12/src/filter_chain.rs index ed43c1f..78c8a5f 100644 --- a/librashader-runtime-d3d12/src/filter_chain.rs +++ b/librashader-runtime-d3d12/src/filter_chain.rs @@ -88,8 +88,7 @@ impl FilterChainD3D12 { &image, texture.filter_mode, texture.wrap_mode, - // todo: mipmaps - false, + texture.mipmap, )?; luts.insert(index, texture); residuals.push(staging); diff --git a/librashader-runtime-d3d12/src/heap.rs b/librashader-runtime-d3d12/src/heap.rs index ca8f4f5..d3b098e 100644 --- a/librashader-runtime-d3d12/src/heap.rs +++ b/librashader-runtime-d3d12/src/heap.rs @@ -18,6 +18,7 @@ pub trait D3D12ShaderVisibleHeapType: D3D12HeapType {} pub struct SamplerPaletteHeap; pub struct LutTextureHeap; +pub struct ResourceWorkHeap; impl D3D12ShaderVisibleHeapType for SamplerPaletteHeap {} @@ -45,6 +46,19 @@ impl const D3D12HeapType for LutTextureHeap { } } +impl D3D12ShaderVisibleHeapType for ResourceWorkHeap {} +impl const D3D12HeapType for ResourceWorkHeap { + // Lut texture heaps are CPU only and get bound to the descriptor heap of the shader. + fn get_desc(size: usize) -> D3D12_DESCRIPTOR_HEAP_DESC { + D3D12_DESCRIPTOR_HEAP_DESC { + Type: D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, + NumDescriptors: size as u32, + Flags: D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE, + NodeMask: 0, + } + } +} + pub struct D3D12DescriptorHeapSlot { cpu_handle: D3D12_CPU_DESCRIPTOR_HANDLE, gpu_handle: Option, @@ -75,6 +89,7 @@ impl AsRef } struct D3D12DescriptorHeapInner { + device: ID3D12Device, heap: ID3D12DescriptorHeap, desc: D3D12_DESCRIPTOR_HEAP_DESC, cpu_start: D3D12_CPU_DESCRIPTOR_HANDLE, @@ -116,6 +131,7 @@ impl D3D12DescriptorHeap { Ok(D3D12DescriptorHeap( Arc::new(RefCell::new(D3D12DescriptorHeapInner { + device: device.clone(), heap, desc, cpu_start, @@ -157,6 +173,26 @@ impl D3D12DescriptorHeap { todo!("error need to fail"); } + + pub fn copy_descriptors(&mut self, + source: &[impl AsRef; NUM_DESC]) + -> error::Result<[D3D12DescriptorHeapSlot; NUM_DESC]> { + let dest = array_init::try_array_init(|_| self.alloc_slot())?; + let mut 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].as_ref(), + inner.desc.Type + ); + } + } + Ok(dest) + } } impl Drop for D3D12DescriptorHeapSlot { diff --git a/librashader-runtime-d3d12/src/mipmap.rs b/librashader-runtime-d3d12/src/mipmap.rs index 4ceffae..cc90ba7 100644 --- a/librashader-runtime-d3d12/src/mipmap.rs +++ b/librashader-runtime-d3d12/src/mipmap.rs @@ -1,7 +1,51 @@ -use windows::Win32::Graphics::Direct3D12::{D3D12_GPU_DESCRIPTOR_HANDLE, ID3D12Device, ID3D12PipelineState, ID3D12RootSignature}; +use windows::Win32::Graphics::Direct3D12::{D3D12_CPU_DESCRIPTOR_HANDLE, D3D12_GPU_DESCRIPTOR_HANDLE, ID3D12Device, ID3D12PipelineState, ID3D12RootSignature}; use librashader_common::Size; use crate::error; +static GENERATE_MIPS_SRC: &[u8] = b" +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. +// +// http://go.microsoft.com/fwlink/?LinkID=615561 + +#define GenerateMipsRS \\ +\"RootFlags ( DENY_VERTEX_SHADER_ROOT_ACCESS |\" \\ +\" DENY_DOMAIN_SHADER_ROOT_ACCESS |\" \\ +\" DENY_GEOMETRY_SHADER_ROOT_ACCESS |\" \\ +\" DENY_HULL_SHADER_ROOT_ACCESS |\" \\ +\" DENY_PIXEL_SHADER_ROOT_ACCESS ),\" \\ +\"RootConstants(num32BitConstants=3, b0),\" \\ +\"DescriptorTable ( SRV(t0) ),\" \\ +\"DescriptorTable ( UAV(u0) ),\" \\ +\"StaticSampler(s0,\"\\ +\" filter = FILTER_MIN_MAG_LINEAR_MIP_POINT,\"\\ +\" addressU = TEXTURE_ADDRESS_CLAMP,\"\\ +\" addressV = TEXTURE_ADDRESS_CLAMP,\"\\ +\" addressW = TEXTURE_ADDRESS_CLAMP )\" + +SamplerState Sampler : register(s0); +Texture2D SrcMip : register(t0); +RWTexture2D OutMip : register(u0); + +cbuffer MipConstants : register(b0) +{ +float2 InvOutTexelSize; // texel size for OutMip (NOT SrcMip) +uint SrcMipIndex; +} + +float4 Mip(uint2 coord) +{ + float2 uv = (coord.xy + 0.5) * InvOutTexelSize; + return SrcMip.SampleLevel(Sampler, uv, SrcMipIndex); +} + +[RootSignature(GenerateMipsRS)] +[numthreads(8, 8, 1)] +void main(uint3 DTid : SV_DispatchThreadID) +{ +OutMip[DTid.xy] = Mip(DTid.xy); +}\0"; + pub struct D3D12MipmapGen { device: ID3D12Device, root_signature: ID3D12RootSignature, @@ -13,7 +57,9 @@ impl D3D12MipmapGen { todo!() } - pub fn generate_mipmaps(miplevels: u16, size: Size, handle: D3D12_GPU_DESCRIPTOR_HANDLE) { + pub fn generate_mipmaps(miplevels: u16, + size: Size, + handle: D3D12_CPU_DESCRIPTOR_HANDLE) { } } \ No newline at end of file diff --git a/librashader-runtime-d3d12/src/texture.rs b/librashader-runtime-d3d12/src/texture.rs index 8442a37..0f62d8b 100644 --- a/librashader-runtime-d3d12/src/texture.rs +++ b/librashader-runtime-d3d12/src/texture.rs @@ -7,6 +7,7 @@ use librashader_common::{FilterMode, ImageFormat, Size, WrapMode}; use librashader_runtime::image::Image; use windows::Win32::Graphics::Direct3D12::{ID3D12CommandList, ID3D12Device, ID3D12GraphicsCommandList, ID3D12Resource, D3D12_CPU_PAGE_PROPERTY_UNKNOWN, D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING, D3D12_FEATURE_DATA_FORMAT_SUPPORT, D3D12_FORMAT_SUPPORT1_SHADER_SAMPLE, D3D12_FORMAT_SUPPORT1_TEXTURE2D, D3D12_HEAP_FLAG_NONE, D3D12_HEAP_PROPERTIES, D3D12_HEAP_TYPE_DEFAULT, D3D12_HEAP_TYPE_UPLOAD, D3D12_MEMORY_POOL_UNKNOWN, D3D12_PLACED_SUBRESOURCE_FOOTPRINT, D3D12_RESOURCE_DESC, D3D12_RESOURCE_DIMENSION_BUFFER, D3D12_RESOURCE_DIMENSION_TEXTURE2D, D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_SHADER_RESOURCE_VIEW_DESC, D3D12_SHADER_RESOURCE_VIEW_DESC_0, D3D12_SRV_DIMENSION_TEXTURE2D, D3D12_TEX2D_SRV, D3D12_TEXTURE_LAYOUT_ROW_MAJOR, D3D12_RANGE, D3D12_SUBRESOURCE_DATA, D3D12_RESOURCE_STATE_COPY_DEST}; use windows::Win32::Graphics::Dxgi::Common::DXGI_SAMPLE_DESC; +use librashader_runtime::scaling::MipmapSize; pub struct LutTexture { resource: ID3D12Resource, @@ -33,8 +34,7 @@ impl LutTexture { Width: source.size.width as u64, Height: source.size.height, DepthOrArraySize: 1, - MipLevels: 1, // todo: mipmaps - // MipLevels: if mipmap { u16::MAX } else { 1 }, + MipLevels: if mipmap { source.size.calculate_miplevels() as u16 } else { 1 }, Format: ImageFormat::R8G8B8A8Unorm.into(), SampleDesc: DXGI_SAMPLE_DESC { Count: 1, @@ -94,8 +94,6 @@ impl LutTexture { }; let mut layout = D3D12_PLACED_SUBRESOURCE_FOOTPRINT::default(); - // let mut numrows = 0; - // let mut rowsize = 0; let mut total = 0; // texture upload unsafe { @@ -105,7 +103,8 @@ impl LutTexture { 1, 0, Some(&mut layout), - None, None, + None, + None, Some(&mut total), ); @@ -150,6 +149,8 @@ impl LutTexture { d3d12_resource_transition(cmd, &resource, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE) } + + // todo: upload image data to textur Ok((LutTexture { @@ -161,6 +162,3 @@ impl LutTexture { }, upload)) } } - - -// todo https://github.com/microsoft/DirectX-Graphics-Samples/blob/master/Libraries/D3D12RaytracingFallback/Include/d3dx12.h#L1893 \ No newline at end of file