Fix a bug for 3D texture clear on D3D12

When we clear an uninitialized 3D texture, we should clear all depth
slices for each mip level. The current implementation only clears one
slice (the first slice) for each mip level. This change fixes this
bug. Dawn end2end tests of NonzeroTextureCreationTests can pass with
this fix. These tests fail on D3D12 without the fix.

This change also renames arguments for GetRTVDescriptor() for 3D
texture: change baseArrayLayer/layerCount to baseSlice/sliceCount.

Bug: dawn:547
Change-Id: Ic56f28e9e6430058c31aaa2bb21f4e42f7b7621c
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/57840
Reviewed-by: Austin Eng <enga@chromium.org>
Reviewed-by: Jiawei Shao <jiawei.shao@intel.com>
Commit-Queue: Yunchao He <yunchao.he@intel.com>
This commit is contained in:
Yunchao He 2021-07-13 15:55:15 +00:00 committed by Dawn LUCI CQ
parent 0a58972309
commit 5a78bde770
3 changed files with 19 additions and 13 deletions

View File

@ -810,15 +810,15 @@ namespace dawn_native { namespace d3d12 {
}
D3D12_RENDER_TARGET_VIEW_DESC Texture::GetRTVDescriptor(uint32_t mipLevel,
uint32_t baseArrayLayer,
uint32_t layerCount) const {
uint32_t baseSlice,
uint32_t sliceCount) const {
D3D12_RENDER_TARGET_VIEW_DESC rtvDesc;
rtvDesc.Format = GetD3D12Format();
if (IsMultisampledTexture()) {
ASSERT(GetDimension() == wgpu::TextureDimension::e2D);
ASSERT(GetNumMipLevels() == 1);
ASSERT(layerCount == 1);
ASSERT(baseArrayLayer == 0);
ASSERT(sliceCount == 1);
ASSERT(baseSlice == 0);
ASSERT(mipLevel == 0);
rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2DMS;
return rtvDesc;
@ -832,16 +832,16 @@ namespace dawn_native { namespace d3d12 {
// https://docs.microsoft.com/en-us/windows/desktop/api/d3d12/ns-d3d12-d3d12_tex2d_array
// _rtv
rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2DARRAY;
rtvDesc.Texture2DArray.FirstArraySlice = baseArrayLayer;
rtvDesc.Texture2DArray.ArraySize = layerCount;
rtvDesc.Texture2DArray.FirstArraySlice = baseSlice;
rtvDesc.Texture2DArray.ArraySize = sliceCount;
rtvDesc.Texture2DArray.MipSlice = mipLevel;
rtvDesc.Texture2DArray.PlaneSlice = 0;
break;
case wgpu::TextureDimension::e3D:
rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE3D;
rtvDesc.Texture3D.MipSlice = mipLevel;
rtvDesc.Texture3D.FirstWSlice = baseArrayLayer;
rtvDesc.Texture3D.WSize = layerCount;
rtvDesc.Texture3D.FirstWSlice = baseSlice;
rtvDesc.Texture3D.WSize = sliceCount;
break;
case wgpu::TextureDimension::e1D:
UNREACHABLE();
@ -953,7 +953,14 @@ namespace dawn_native { namespace d3d12 {
device->GetRenderTargetViewAllocator()->AllocateTransientCPUDescriptors());
const D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = rtvHeap.GetBaseDescriptor();
D3D12_RENDER_TARGET_VIEW_DESC rtvDesc = GetRTVDescriptor(level, layer, 1);
uint32_t baseSlice = layer;
uint32_t sliceCount = 1;
if (GetDimension() == wgpu::TextureDimension::e3D) {
baseSlice = 0;
sliceCount = std::max(GetDepth() >> level, 1u);
}
D3D12_RENDER_TARGET_VIEW_DESC rtvDesc =
GetRTVDescriptor(level, baseSlice, sliceCount);
device->GetD3D12Device()->CreateRenderTargetView(GetD3D12Resource(), &rtvDesc,
rtvHandle);
commandList->ClearRenderTargetView(rtvHandle, clearColorRGBA, 0, nullptr);

View File

@ -55,8 +55,8 @@ namespace dawn_native { namespace d3d12 {
DXGI_FORMAT GetD3D12CopyableSubresourceFormat(Aspect aspect) const;
D3D12_RENDER_TARGET_VIEW_DESC GetRTVDescriptor(uint32_t mipLevel,
uint32_t baseArrayLayer,
uint32_t layerCount) const;
uint32_t baseSlice,
uint32_t sliceCount) const;
D3D12_DEPTH_STENCIL_VIEW_DESC GetDSVDescriptor(uint32_t mipLevel,
uint32_t baseArrayLayer,
uint32_t layerCount) const;

View File

@ -92,10 +92,9 @@ namespace {
DAWN_TEST_UNSUPPORTED_IF(GetParam().mFormat == wgpu::TextureFormat::RGBA8Snorm &&
HasToggleEnabled("disable_snorm_read"));
// TODO(crbug.com/dawn/547): 3D texture copies not fully implemented on D3D12.
// TODO(crbug.com/angleproject/5967): This texture readback hits an assert in ANGLE.
DAWN_SUPPRESS_TEST_IF(GetParam().mDimension == wgpu::TextureDimension::e3D &&
(IsANGLE() || IsD3D12()));
IsANGLE());
// TODO(crbug.com/dawn/791): Determine Intel specific platforms this occurs on, and
// implement a workaround on all backends (happens on Windows too, but not on our test