D3D12: Fix 3D UAV desc WSize being 0 in some cases.
This could happen when selecting small mip levels where depth >> mip
ends up being zero. Instead the computation should be
max(1, depth >> mip). Also adds a regression test.
Bug: dawn:2072
Change-Id: I1312d684cba77cf7314acda3e80b0be07cccaa97
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/151860
Reviewed-by: Peng Huang <penghuang@chromium.org>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Loko Kung <lokokung@google.com>
diff --git a/src/dawn/native/d3d11/TextureD3D11.cpp b/src/dawn/native/d3d11/TextureD3D11.cpp
index df920d3..b0c5032 100644
--- a/src/dawn/native/d3d11/TextureD3D11.cpp
+++ b/src/dawn/native/d3d11/TextureD3D11.cpp
@@ -1339,7 +1339,7 @@
case wgpu::TextureViewDimension::e3D:
uavDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE3D;
uavDesc.Texture3D.FirstWSlice = 0;
- uavDesc.Texture3D.WSize = GetTexture()->GetDepth() >> GetBaseMipLevel();
+ uavDesc.Texture3D.WSize = std::max(1u, GetTexture()->GetDepth() >> GetBaseMipLevel());
uavDesc.Texture3D.MipSlice = GetBaseMipLevel();
break;
// Cube and Cubemap can't be used as storage texture. So there is no need to create UAV
diff --git a/src/dawn/native/d3d12/TextureD3D12.cpp b/src/dawn/native/d3d12/TextureD3D12.cpp
index bbc83ee..5c19073 100644
--- a/src/dawn/native/d3d12/TextureD3D12.cpp
+++ b/src/dawn/native/d3d12/TextureD3D12.cpp
@@ -1116,7 +1116,7 @@
case wgpu::TextureViewDimension::e3D:
uavDesc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE3D;
uavDesc.Texture3D.FirstWSlice = 0;
- uavDesc.Texture3D.WSize = GetTexture()->GetDepth() >> GetBaseMipLevel();
+ uavDesc.Texture3D.WSize = std::max(1u, GetTexture()->GetDepth() >> GetBaseMipLevel());
uavDesc.Texture3D.MipSlice = GetBaseMipLevel();
break;
// Cube and Cubemap can't be used as storage texture. So there is no need to create UAV
diff --git a/src/dawn/tests/end2end/Texture3DTests.cpp b/src/dawn/tests/end2end/Texture3DTests.cpp
index df6fd0e..1483f7b 100644
--- a/src/dawn/tests/end2end/Texture3DTests.cpp
+++ b/src/dawn/tests/end2end/Texture3DTests.cpp
@@ -120,6 +120,45 @@
}
}
+// Regression test for crbug.com/dawn/2072 where the WSize of D3D UAV descriptor ends up being 0.
+// (which is invalid as noted by the debug layers)
+TEST_P(Texture3DTests, LatestMipClampsDepthSizeForStorageTextures) {
+ wgpu::TextureDescriptor tDesc;
+ tDesc.dimension = wgpu::TextureDimension::e3D;
+ tDesc.size = {2, 2, 1};
+ tDesc.mipLevelCount = 2;
+ tDesc.usage = wgpu::TextureUsage::StorageBinding;
+ tDesc.format = wgpu::TextureFormat::R32Uint;
+ wgpu::Texture t = device.CreateTexture(&tDesc);
+
+ wgpu::TextureViewDescriptor vDesc;
+ vDesc.baseMipLevel = 1;
+ vDesc.mipLevelCount = 1;
+ wgpu::TextureView v = t.CreateView(&vDesc);
+
+ wgpu::ComputePipelineDescriptor pDesc;
+ pDesc.compute.module = utils::CreateShaderModule(device, R"(
+ @group(0) @binding(0) var t : texture_storage_3d<r32uint, write>;
+ @compute @workgroup_size(1) fn main() {
+ _ = t;
+ }
+ )");
+ pDesc.compute.entryPoint = "main";
+ wgpu::ComputePipeline pipeline = device.CreateComputePipeline(&pDesc);
+
+ wgpu::BindGroup bg = utils::MakeBindGroup(device, pipeline.GetBindGroupLayout(0), {{0, v}});
+
+ wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
+ wgpu::ComputePassEncoder pass = encoder.BeginComputePass();
+ pass.SetBindGroup(0, bg);
+ pass.SetPipeline(pipeline);
+ pass.DispatchWorkgroups(1);
+ pass.End();
+
+ wgpu::CommandBuffer commands = encoder.Finish();
+ queue.Submit(1, &commands);
+}
+
DAWN_INSTANTIATE_TEST(Texture3DTests,
D3D11Backend(),
D3D12Backend(),