dx12: mipmap stuff

This commit is contained in:
chyyran 2023-01-26 17:57:54 -05:00 committed by Ronny Chan
parent 8bb02d31e9
commit d7da5c175f
4 changed files with 91 additions and 12 deletions

View file

@ -88,8 +88,7 @@ impl FilterChainD3D12 {
&image, &image,
texture.filter_mode, texture.filter_mode,
texture.wrap_mode, texture.wrap_mode,
// todo: mipmaps texture.mipmap,
false,
)?; )?;
luts.insert(index, texture); luts.insert(index, texture);
residuals.push(staging); residuals.push(staging);

View file

@ -18,6 +18,7 @@ pub trait D3D12ShaderVisibleHeapType: D3D12HeapType {}
pub struct SamplerPaletteHeap; pub struct SamplerPaletteHeap;
pub struct LutTextureHeap; pub struct LutTextureHeap;
pub struct ResourceWorkHeap;
impl D3D12ShaderVisibleHeapType for SamplerPaletteHeap {} 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<T> { pub struct D3D12DescriptorHeapSlot<T> {
cpu_handle: D3D12_CPU_DESCRIPTOR_HANDLE, cpu_handle: D3D12_CPU_DESCRIPTOR_HANDLE,
gpu_handle: Option<D3D12_GPU_DESCRIPTOR_HANDLE>, gpu_handle: Option<D3D12_GPU_DESCRIPTOR_HANDLE>,
@ -75,6 +89,7 @@ impl<T: D3D12ShaderVisibleHeapType> AsRef<D3D12_GPU_DESCRIPTOR_HANDLE>
} }
struct D3D12DescriptorHeapInner { struct D3D12DescriptorHeapInner {
device: ID3D12Device,
heap: ID3D12DescriptorHeap, heap: ID3D12DescriptorHeap,
desc: D3D12_DESCRIPTOR_HEAP_DESC, desc: D3D12_DESCRIPTOR_HEAP_DESC,
cpu_start: D3D12_CPU_DESCRIPTOR_HANDLE, cpu_start: D3D12_CPU_DESCRIPTOR_HANDLE,
@ -116,6 +131,7 @@ impl<T> D3D12DescriptorHeap<T> {
Ok(D3D12DescriptorHeap( Ok(D3D12DescriptorHeap(
Arc::new(RefCell::new(D3D12DescriptorHeapInner { Arc::new(RefCell::new(D3D12DescriptorHeapInner {
device: device.clone(),
heap, heap,
desc, desc,
cpu_start, cpu_start,
@ -157,6 +173,26 @@ impl<T> D3D12DescriptorHeap<T> {
todo!("error need to fail"); todo!("error need to fail");
} }
pub fn copy_descriptors<const NUM_DESC: usize>(&mut self,
source: &[impl AsRef<D3D12_CPU_DESCRIPTOR_HANDLE>; NUM_DESC])
-> error::Result<[D3D12DescriptorHeapSlot<T>; 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<T> Drop for D3D12DescriptorHeapSlot<T> { impl<T> Drop for D3D12DescriptorHeapSlot<T> {

View file

@ -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 librashader_common::Size;
use crate::error; 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<float4> SrcMip : register(t0);
RWTexture2D<float4> 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 { pub struct D3D12MipmapGen {
device: ID3D12Device, device: ID3D12Device,
root_signature: ID3D12RootSignature, root_signature: ID3D12RootSignature,
@ -13,7 +57,9 @@ impl D3D12MipmapGen {
todo!() todo!()
} }
pub fn generate_mipmaps(miplevels: u16, size: Size<u32>, handle: D3D12_GPU_DESCRIPTOR_HANDLE) { pub fn generate_mipmaps(miplevels: u16,
size: Size<u32>,
handle: D3D12_CPU_DESCRIPTOR_HANDLE) {
} }
} }

View file

@ -7,6 +7,7 @@ use librashader_common::{FilterMode, ImageFormat, Size, WrapMode};
use librashader_runtime::image::Image; 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::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 windows::Win32::Graphics::Dxgi::Common::DXGI_SAMPLE_DESC;
use librashader_runtime::scaling::MipmapSize;
pub struct LutTexture { pub struct LutTexture {
resource: ID3D12Resource, resource: ID3D12Resource,
@ -33,8 +34,7 @@ impl LutTexture {
Width: source.size.width as u64, Width: source.size.width as u64,
Height: source.size.height, Height: source.size.height,
DepthOrArraySize: 1, DepthOrArraySize: 1,
MipLevels: 1, // todo: mipmaps MipLevels: if mipmap { source.size.calculate_miplevels() as u16 } else { 1 },
// MipLevels: if mipmap { u16::MAX } else { 1 },
Format: ImageFormat::R8G8B8A8Unorm.into(), Format: ImageFormat::R8G8B8A8Unorm.into(),
SampleDesc: DXGI_SAMPLE_DESC { SampleDesc: DXGI_SAMPLE_DESC {
Count: 1, Count: 1,
@ -94,8 +94,6 @@ impl LutTexture {
}; };
let mut layout = D3D12_PLACED_SUBRESOURCE_FOOTPRINT::default(); let mut layout = D3D12_PLACED_SUBRESOURCE_FOOTPRINT::default();
// let mut numrows = 0;
// let mut rowsize = 0;
let mut total = 0; let mut total = 0;
// texture upload // texture upload
unsafe { unsafe {
@ -105,7 +103,8 @@ impl LutTexture {
1, 1,
0, 0,
Some(&mut layout), Some(&mut layout),
None, None, None,
None,
Some(&mut total), 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) d3d12_resource_transition(cmd, &resource, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE)
} }
// todo: upload image data to textur // todo: upload image data to textur
Ok((LutTexture { Ok((LutTexture {
@ -161,6 +162,3 @@ impl LutTexture {
}, upload)) }, upload))
} }
} }
// todo https://github.com/microsoft/DirectX-Graphics-Samples/blob/master/Libraries/D3D12RaytracingFallback/Include/d3dx12.h#L1893