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
|
||||
};
|
||||
|
||||
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
|
||||
{
|
||||
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 srvDesc = new D3D12_SHADER_RESOURCE_VIEW_DESC
|
||||
@@ -48,6 +48,15 @@ internal sealed unsafe partial class D3D12ResourceAllocator
|
||||
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)
|
||||
{
|
||||
case D3D12_RESOURCE_DIMENSION_TEXTURE1D:
|
||||
@@ -251,7 +260,7 @@ internal sealed unsafe partial class D3D12ResourceAllocator
|
||||
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 dsvDesc = new D3D12_DEPTH_STENCIL_VIEW_DESC
|
||||
@@ -276,7 +285,7 @@ internal sealed unsafe partial class D3D12ResourceAllocator
|
||||
break;
|
||||
}
|
||||
|
||||
dsvDesc.Format = resourceDesc.Format;
|
||||
dsvDesc.Format = originalFormat == TextureFormat.Unknown ? resourceDesc.Format : originalFormat.ToDXGIFormat();
|
||||
|
||||
var isArray =
|
||||
dsvDesc.ViewDimension == D3D12_DSV_DIMENSION_TEXTURE2DARRAY ||
|
||||
@@ -644,7 +653,7 @@ internal sealed unsafe partial class D3D12ResourceAllocator : IResourceAllocator
|
||||
var cpuHandle = _descriptorAllocator.GetCpuHandle(resourceDescriptor.srv);
|
||||
|
||||
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);
|
||||
_descriptorAllocator.CopyToShaderVisible(resourceDescriptor.srv);
|
||||
@@ -663,7 +672,7 @@ internal sealed unsafe partial class D3D12ResourceAllocator : IResourceAllocator
|
||||
{
|
||||
resourceDescriptor.dsv = _descriptorAllocator.AllocateDSV();
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -140,6 +140,8 @@ internal static unsafe class D3D12Utility
|
||||
TextureFormat.R32G32B32A32_Float => DXGI_FORMAT_R32G32B32A32_FLOAT,
|
||||
TextureFormat.D24_UNorm_S8_UInt => DXGI_FORMAT_D24_UNORM_S8_UINT,
|
||||
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."),
|
||||
};
|
||||
}
|
||||
@@ -154,6 +156,8 @@ internal static unsafe class D3D12Utility
|
||||
DXGI_FORMAT_R32G32B32A32_FLOAT => TextureFormat.R32G32B32A32_Float,
|
||||
DXGI_FORMAT_D24_UNORM_S8_UINT => TextureFormat.D24_UNorm_S8_UInt,
|
||||
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.")
|
||||
};
|
||||
}
|
||||
@@ -385,6 +389,19 @@ internal static unsafe class D3D12Utility
|
||||
public static D3D12_RESOURCE_DESC ToD3D12ResourceDesc(this in TextureDesc desc)
|
||||
{
|
||||
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 mipLevels = desc.MipLevels == 0
|
||||
? (ushort)(1 + Math.Floor(Math.Log2(maxDimension)))
|
||||
|
||||
@@ -454,6 +454,10 @@ public struct PassDepthStencilDesc
|
||||
get; set;
|
||||
}
|
||||
|
||||
public bool HasStencil
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1287,7 +1291,10 @@ public enum TextureFormat
|
||||
R16G16B16A16_Float,
|
||||
R32G32B32A32_Float,
|
||||
D24_UNorm_S8_UInt,
|
||||
D32_Float
|
||||
D32_Float,
|
||||
|
||||
R32_Typeless,
|
||||
R24G8_Typeless,
|
||||
}
|
||||
|
||||
[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();
|
||||
|
||||
|
||||
@@ -144,11 +144,13 @@ internal sealed class RenderGraphExecutor
|
||||
? nativePass.depthAttachment.storeOp
|
||||
: AttachmentStoreOp.DontCare,
|
||||
StencilLoadOp = nativePass.hasDepthAttachment
|
||||
? nativePass.depthAttachment.loadOp
|
||||
? nativePass.depthAttachment.stencilLoadOp
|
||||
: AttachmentLoadOp.DontCare,
|
||||
StencilStoreOp = nativePass.hasDepthAttachment
|
||||
? nativePass.depthAttachment.storeOp
|
||||
: AttachmentStoreOp.DontCare
|
||||
? nativePass.depthAttachment.stencilStoreOp
|
||||
: 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);
|
||||
|
||||
@@ -365,6 +365,18 @@ internal sealed class RenderGraphNativePassBuilder
|
||||
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 AttachmentLoadOp loadOp;
|
||||
public AttachmentStoreOp storeOp;
|
||||
public AttachmentLoadOp stencilLoadOp;
|
||||
public AttachmentStoreOp stencilStoreOp;
|
||||
public float clearDepth;
|
||||
public byte clearStencil;
|
||||
}
|
||||
Reference in New Issue
Block a user