Fix D3D12 depth format and stencil barrier issues in Render Graph
This commit is contained in:
@@ -537,6 +537,12 @@ internal unsafe class D3D12CommandBuffer : D3D12Object<ID3D12GraphicsCommandList
|
|||||||
_ => D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE
|
_ => D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_PRESERVE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (!depthDesc.HasStencil)
|
||||||
|
{
|
||||||
|
stencilLoadAccessType = D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_NO_ACCESS;
|
||||||
|
stencilStoreAccessType = D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_NO_ACCESS;
|
||||||
|
}
|
||||||
|
|
||||||
var desc = new D3D12_RENDER_PASS_DEPTH_STENCIL_DESC
|
var desc = new D3D12_RENDER_PASS_DEPTH_STENCIL_DESC
|
||||||
{
|
{
|
||||||
cpuDescriptor = cpuHandle,
|
cpuDescriptor = cpuHandle,
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ internal sealed unsafe partial class D3D12ResourceAllocator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static D3D12_SHADER_RESOURCE_VIEW_DESC CreateTextureSrvDesc(ID3D12Resource* pResource, uint mipLevels, uint arraySize, bool isCubeMap)
|
private static D3D12_SHADER_RESOURCE_VIEW_DESC CreateTextureSrvDesc(ID3D12Resource* pResource, uint mipLevels, uint arraySize, bool isCubeMap, TextureFormat originalFormat)
|
||||||
{
|
{
|
||||||
var resourceDesc = pResource->GetDesc();
|
var resourceDesc = pResource->GetDesc();
|
||||||
var srvDesc = new D3D12_SHADER_RESOURCE_VIEW_DESC
|
var srvDesc = new D3D12_SHADER_RESOURCE_VIEW_DESC
|
||||||
@@ -48,6 +48,15 @@ internal sealed unsafe partial class D3D12ResourceAllocator
|
|||||||
Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING
|
Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (originalFormat == TextureFormat.D32_Float)
|
||||||
|
{
|
||||||
|
srvDesc.Format = DXGI_FORMAT_R32_FLOAT;
|
||||||
|
}
|
||||||
|
else if (originalFormat == TextureFormat.D24_UNorm_S8_UInt)
|
||||||
|
{
|
||||||
|
srvDesc.Format = DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
|
||||||
|
}
|
||||||
|
|
||||||
switch (resourceDesc.Dimension)
|
switch (resourceDesc.Dimension)
|
||||||
{
|
{
|
||||||
case D3D12_RESOURCE_DIMENSION_TEXTURE1D:
|
case D3D12_RESOURCE_DIMENSION_TEXTURE1D:
|
||||||
@@ -251,7 +260,7 @@ internal sealed unsafe partial class D3D12ResourceAllocator
|
|||||||
return rtvDesc;
|
return rtvDesc;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static D3D12_DEPTH_STENCIL_VIEW_DESC CreateDsvDesc(ID3D12Resource* pResource, uint mipSlice = 0, uint firstArraySlice = 0, D3D12_DSV_FLAGS flags = D3D12_DSV_FLAG_NONE)
|
private static D3D12_DEPTH_STENCIL_VIEW_DESC CreateDsvDesc(ID3D12Resource* pResource, uint mipSlice = 0, uint firstArraySlice = 0, D3D12_DSV_FLAGS flags = D3D12_DSV_FLAG_NONE, TextureFormat originalFormat = TextureFormat.Unknown)
|
||||||
{
|
{
|
||||||
var resourceDesc = pResource->GetDesc();
|
var resourceDesc = pResource->GetDesc();
|
||||||
var dsvDesc = new D3D12_DEPTH_STENCIL_VIEW_DESC
|
var dsvDesc = new D3D12_DEPTH_STENCIL_VIEW_DESC
|
||||||
@@ -276,7 +285,7 @@ internal sealed unsafe partial class D3D12ResourceAllocator
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
dsvDesc.Format = resourceDesc.Format;
|
dsvDesc.Format = originalFormat == TextureFormat.Unknown ? resourceDesc.Format : originalFormat.ToDXGIFormat();
|
||||||
|
|
||||||
var isArray =
|
var isArray =
|
||||||
dsvDesc.ViewDimension == D3D12_DSV_DIMENSION_TEXTURE2DARRAY ||
|
dsvDesc.ViewDimension == D3D12_DSV_DIMENSION_TEXTURE2DARRAY ||
|
||||||
@@ -644,7 +653,7 @@ internal sealed unsafe partial class D3D12ResourceAllocator : IResourceAllocator
|
|||||||
var cpuHandle = _descriptorAllocator.GetCpuHandle(resourceDescriptor.srv);
|
var cpuHandle = _descriptorAllocator.GetCpuHandle(resourceDescriptor.srv);
|
||||||
|
|
||||||
var isCubeMap = desc.Dimension == TextureDimension.TextureCube || desc.Dimension == TextureDimension.TextureCubeArray;
|
var isCubeMap = desc.Dimension == TextureDimension.TextureCube || desc.Dimension == TextureDimension.TextureCubeArray;
|
||||||
var srvDesc = CreateTextureSrvDesc(pResource, resourceDesc.MipLevels, resourceDesc.DepthOrArraySize, isCubeMap);
|
var srvDesc = CreateTextureSrvDesc(pResource, resourceDesc.MipLevels, resourceDesc.DepthOrArraySize, isCubeMap, desc.Format);
|
||||||
|
|
||||||
_device.NativeObject.Get()->CreateShaderResourceView(pResource, &srvDesc, cpuHandle);
|
_device.NativeObject.Get()->CreateShaderResourceView(pResource, &srvDesc, cpuHandle);
|
||||||
_descriptorAllocator.CopyToShaderVisible(resourceDescriptor.srv);
|
_descriptorAllocator.CopyToShaderVisible(resourceDescriptor.srv);
|
||||||
@@ -663,7 +672,7 @@ internal sealed unsafe partial class D3D12ResourceAllocator : IResourceAllocator
|
|||||||
{
|
{
|
||||||
resourceDescriptor.dsv = _descriptorAllocator.AllocateDSV();
|
resourceDescriptor.dsv = _descriptorAllocator.AllocateDSV();
|
||||||
var cpuHandle = _descriptorAllocator.GetCpuHandle(resourceDescriptor.dsv);
|
var cpuHandle = _descriptorAllocator.GetCpuHandle(resourceDescriptor.dsv);
|
||||||
var dsvDesc = CreateDsvDesc(pResource);
|
var dsvDesc = CreateDsvDesc(pResource, 0, 0, D3D12_DSV_FLAG_NONE, desc.Format);
|
||||||
|
|
||||||
_device.NativeObject.Get()->CreateDepthStencilView(pResource, &dsvDesc, cpuHandle);
|
_device.NativeObject.Get()->CreateDepthStencilView(pResource, &dsvDesc, cpuHandle);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -140,6 +140,8 @@ internal static unsafe class D3D12Utility
|
|||||||
TextureFormat.R32G32B32A32_Float => DXGI_FORMAT_R32G32B32A32_FLOAT,
|
TextureFormat.R32G32B32A32_Float => DXGI_FORMAT_R32G32B32A32_FLOAT,
|
||||||
TextureFormat.D24_UNorm_S8_UInt => DXGI_FORMAT_D24_UNORM_S8_UINT,
|
TextureFormat.D24_UNorm_S8_UInt => DXGI_FORMAT_D24_UNORM_S8_UINT,
|
||||||
TextureFormat.D32_Float => DXGI_FORMAT_D32_FLOAT,
|
TextureFormat.D32_Float => DXGI_FORMAT_D32_FLOAT,
|
||||||
|
TextureFormat.R32_Typeless => DXGI_FORMAT_R32_TYPELESS,
|
||||||
|
TextureFormat.R24G8_Typeless => DXGI_FORMAT_R24G8_TYPELESS,
|
||||||
_ => throw new NotSupportedException($"Texture format {format} is not supported."),
|
_ => throw new NotSupportedException($"Texture format {format} is not supported."),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -154,6 +156,8 @@ internal static unsafe class D3D12Utility
|
|||||||
DXGI_FORMAT_R32G32B32A32_FLOAT => TextureFormat.R32G32B32A32_Float,
|
DXGI_FORMAT_R32G32B32A32_FLOAT => TextureFormat.R32G32B32A32_Float,
|
||||||
DXGI_FORMAT_D24_UNORM_S8_UINT => TextureFormat.D24_UNorm_S8_UInt,
|
DXGI_FORMAT_D24_UNORM_S8_UINT => TextureFormat.D24_UNorm_S8_UInt,
|
||||||
DXGI_FORMAT_D32_FLOAT => TextureFormat.D32_Float,
|
DXGI_FORMAT_D32_FLOAT => TextureFormat.D32_Float,
|
||||||
|
DXGI_FORMAT_R32_TYPELESS => TextureFormat.R32_Typeless,
|
||||||
|
DXGI_FORMAT_R24G8_TYPELESS => TextureFormat.R24G8_Typeless,
|
||||||
_ => throw new NotSupportedException($"DXGI format {format} is not supported.")
|
_ => throw new NotSupportedException($"DXGI format {format} is not supported.")
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -385,6 +389,19 @@ internal static unsafe class D3D12Utility
|
|||||||
public static D3D12_RESOURCE_DESC ToD3D12ResourceDesc(this in TextureDesc desc)
|
public static D3D12_RESOURCE_DESC ToD3D12ResourceDesc(this in TextureDesc desc)
|
||||||
{
|
{
|
||||||
var dxgiFormat = desc.Format.ToDXGIFormat();
|
var dxgiFormat = desc.Format.ToDXGIFormat();
|
||||||
|
|
||||||
|
if (desc.Usage.HasFlag(TextureUsage.DepthStencil) && desc.Usage.HasFlag(TextureUsage.ShaderResource))
|
||||||
|
{
|
||||||
|
if (dxgiFormat == DXGI_FORMAT_D32_FLOAT)
|
||||||
|
{
|
||||||
|
dxgiFormat = DXGI_FORMAT_R32_TYPELESS;
|
||||||
|
}
|
||||||
|
else if (dxgiFormat == DXGI_FORMAT_D24_UNORM_S8_UINT)
|
||||||
|
{
|
||||||
|
dxgiFormat = DXGI_FORMAT_R24G8_TYPELESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var maxDimension = Math.Max(desc.Width, Math.Max(desc.Height, desc.Slice));
|
var maxDimension = Math.Max(desc.Width, Math.Max(desc.Height, desc.Slice));
|
||||||
var mipLevels = desc.MipLevels == 0
|
var mipLevels = desc.MipLevels == 0
|
||||||
? (ushort)(1 + Math.Floor(Math.Log2(maxDimension)))
|
? (ushort)(1 + Math.Floor(Math.Log2(maxDimension)))
|
||||||
|
|||||||
@@ -454,6 +454,10 @@ public struct PassDepthStencilDesc
|
|||||||
get; set;
|
get; set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool HasStencil
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1287,7 +1291,10 @@ public enum TextureFormat
|
|||||||
R16G16B16A16_Float,
|
R16G16B16A16_Float,
|
||||||
R32G32B32A32_Float,
|
R32G32B32A32_Float,
|
||||||
D24_UNorm_S8_UInt,
|
D24_UNorm_S8_UInt,
|
||||||
D32_Float
|
D32_Float,
|
||||||
|
|
||||||
|
R32_Typeless,
|
||||||
|
R24G8_Typeless,
|
||||||
}
|
}
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
|
|||||||
@@ -294,7 +294,7 @@ internal class RenderGraphBuilder : IRasterRenderGraphBuilder, IComputeRenderGra
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetDepthAttachment(Identifier<RGTexture> texture, AccessFlags flags = AccessFlags.ReadWrite)
|
public void SetDepthAttachment(Identifier<RGTexture> texture, AccessFlags flags = AccessFlags.WriteAll)
|
||||||
{
|
{
|
||||||
ThrowIfDisposed();
|
ThrowIfDisposed();
|
||||||
|
|
||||||
|
|||||||
@@ -144,11 +144,13 @@ internal sealed class RenderGraphExecutor
|
|||||||
? nativePass.depthAttachment.storeOp
|
? nativePass.depthAttachment.storeOp
|
||||||
: AttachmentStoreOp.DontCare,
|
: AttachmentStoreOp.DontCare,
|
||||||
StencilLoadOp = nativePass.hasDepthAttachment
|
StencilLoadOp = nativePass.hasDepthAttachment
|
||||||
? nativePass.depthAttachment.loadOp
|
? nativePass.depthAttachment.stencilLoadOp
|
||||||
: AttachmentLoadOp.DontCare,
|
: AttachmentLoadOp.DontCare,
|
||||||
StencilStoreOp = nativePass.hasDepthAttachment
|
StencilStoreOp = nativePass.hasDepthAttachment
|
||||||
? nativePass.depthAttachment.storeOp
|
? nativePass.depthAttachment.stencilStoreOp
|
||||||
: AttachmentStoreOp.DontCare
|
: AttachmentStoreOp.DontCare,
|
||||||
|
HasStencil = nativePass.hasDepthAttachment &&
|
||||||
|
(_resources.GetResource(nativePass.depthAttachment.texture).rgTextureDesc.format == TextureFormat.D24_UNorm_S8_UInt)
|
||||||
};
|
};
|
||||||
|
|
||||||
commandBuffer.BeginRenderPass(new Span<PassRenderTargetDesc>(pPassRTDescs, nativePass.colorAttachmentCount), depthDesc);
|
commandBuffer.BeginRenderPass(new Span<PassRenderTargetDesc>(pPassRTDescs, nativePass.colorAttachmentCount), depthDesc);
|
||||||
|
|||||||
@@ -365,6 +365,18 @@ internal sealed class RenderGraphNativePassBuilder
|
|||||||
attachment.storeOp = AttachmentStoreOp.Store;
|
attachment.storeOp = AttachmentStoreOp.Store;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var hasStencil = resource.rgTextureDesc.format == TextureFormat.D24_UNorm_S8_UInt;
|
||||||
|
if (hasStencil)
|
||||||
|
{
|
||||||
|
attachment.stencilLoadOp = attachment.loadOp;
|
||||||
|
attachment.stencilStoreOp = attachment.storeOp;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
attachment.stencilLoadOp = AttachmentLoadOp.DontCare;
|
||||||
|
attachment.stencilStoreOp = AttachmentStoreOp.DontCare;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -384,6 +384,8 @@ internal struct DepthStencilInfo
|
|||||||
public AccessFlags access;
|
public AccessFlags access;
|
||||||
public AttachmentLoadOp loadOp;
|
public AttachmentLoadOp loadOp;
|
||||||
public AttachmentStoreOp storeOp;
|
public AttachmentStoreOp storeOp;
|
||||||
|
public AttachmentLoadOp stencilLoadOp;
|
||||||
|
public AttachmentStoreOp stencilStoreOp;
|
||||||
public float clearDepth;
|
public float clearDepth;
|
||||||
public byte clearStencil;
|
public byte clearStencil;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user