Add basic supports of storage textures on D3D12
This patch adds the basic supports of read-only and write-only storage
textures on D3D12.
The subresource tracking and barriers on the subresources used as
read-only and write-only storage textures are not included in this
patch.
BUG=dawn:267
TEST=dawn_end2end_tests
Change-Id: Ie29a3a9962cd1a79217bc87815ed0bd27623e3a8
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/21140
Reviewed-by: Austin Eng <enga@chromium.org>
Commit-Queue: Jiawei Shao <jiawei.shao@intel.com>
diff --git a/src/dawn_native/d3d12/BindGroupD3D12.cpp b/src/dawn_native/d3d12/BindGroupD3D12.cpp
index 4e32874..5aeaf56 100644
--- a/src/dawn_native/d3d12/BindGroupD3D12.cpp
+++ b/src/dawn_native/d3d12/BindGroupD3D12.cpp
@@ -115,7 +115,11 @@
viewAllocation.OffsetFrom(viewSizeIncrement, bindingOffsets[bindingIndex]));
break;
}
- case wgpu::BindingType::SampledTexture: {
+
+ // Readonly storage is implemented as SRV so it can be used at the same time as a
+ // sampled texture.
+ case wgpu::BindingType::SampledTexture:
+ case wgpu::BindingType::ReadonlyStorageTexture: {
auto* view = ToBackend(GetBindingAsTextureView(bindingIndex));
auto& srv = view->GetSRVDescriptor();
d3d12Device->CreateShaderResourceView(
@@ -133,9 +137,16 @@
break;
}
+ case wgpu::BindingType::WriteonlyStorageTexture: {
+ TextureView* view = ToBackend(GetBindingAsTextureView(bindingIndex));
+ D3D12_UNORDERED_ACCESS_VIEW_DESC uav = view->GetUAVDescriptor();
+ d3d12Device->CreateUnorderedAccessView(
+ ToBackend(view->GetTexture())->GetD3D12Resource(), nullptr, &uav,
+ viewAllocation.OffsetFrom(viewSizeIncrement, bindingOffsets[bindingIndex]));
+ break;
+ }
+
case wgpu::BindingType::StorageTexture:
- case wgpu::BindingType::ReadonlyStorageTexture:
- case wgpu::BindingType::WriteonlyStorageTexture:
UNREACHABLE();
break;
diff --git a/src/dawn_native/d3d12/CommandBufferD3D12.cpp b/src/dawn_native/d3d12/CommandBufferD3D12.cpp
index 6f96262..72377f7 100644
--- a/src/dawn_native/d3d12/CommandBufferD3D12.cpp
+++ b/src/dawn_native/d3d12/CommandBufferD3D12.cpp
@@ -166,9 +166,21 @@
wgpu::BufferUsage::Storage);
break;
- case wgpu::BindingType::StorageTexture:
case wgpu::BindingType::ReadonlyStorageTexture:
+ ToBackend(static_cast<TextureView*>(mBindings[index][binding])
+ ->GetTexture())
+ ->TrackUsageAndTransitionNow(commandContext,
+ kReadonlyStorageTexture);
+ break;
+
case wgpu::BindingType::WriteonlyStorageTexture:
+ ToBackend(static_cast<TextureView*>(mBindings[index][binding])
+ ->GetTexture())
+ ->TrackUsageAndTransitionNow(commandContext,
+ wgpu::TextureUsage::Storage);
+ break;
+
+ case wgpu::BindingType::StorageTexture:
// Not implemented.
case wgpu::BindingType::UniformBuffer:
diff --git a/src/dawn_native/d3d12/ShaderModuleD3D12.cpp b/src/dawn_native/d3d12/ShaderModuleD3D12.cpp
index e006d6f..d6410aa 100644
--- a/src/dawn_native/d3d12/ShaderModuleD3D12.cpp
+++ b/src/dawn_native/d3d12/ShaderModuleD3D12.cpp
@@ -51,6 +51,7 @@
// See https://github.com/gpuweb/gpuweb/issues/332
options.SetHLSLPointCoordCompat(true);
options.SetHLSLPointSizeCompat(true);
+ options.SetHLSLNonWritableUAVTextureAsSRV(true);
DAWN_TRY(CheckSpvcSuccess(
mSpvcContext.InitializeForHlsl(spirv.data(), spirv.size(), options),
@@ -90,6 +91,7 @@
// See https://github.com/gpuweb/gpuweb/issues/332
options_hlsl.point_coord_compat = true;
options_hlsl.point_size_compat = true;
+ options_hlsl.nonwritable_uav_texture_as_srv = true;
compilerImpl = std::make_unique<spirv_cross::CompilerHLSL>(spirv);
compiler = compilerImpl.get();
diff --git a/src/dawn_native/d3d12/TextureD3D12.cpp b/src/dawn_native/d3d12/TextureD3D12.cpp
index 865bc2b..bcd4d26 100644
--- a/src/dawn_native/d3d12/TextureD3D12.cpp
+++ b/src/dawn_native/d3d12/TextureD3D12.cpp
@@ -48,7 +48,7 @@
if (usage & wgpu::TextureUsage::CopyDst) {
resourceState |= D3D12_RESOURCE_STATE_COPY_DEST;
}
- if (usage & wgpu::TextureUsage::Sampled) {
+ if (usage & (wgpu::TextureUsage::Sampled | kReadonlyStorageTexture)) {
resourceState |= (D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE |
D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
}
@@ -830,4 +830,17 @@
->GetDSVDescriptor(mipLevel, GetBaseArrayLayer(), GetLayerCount());
}
+ D3D12_UNORDERED_ACCESS_VIEW_DESC TextureView::GetUAVDescriptor() const {
+ D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc;
+ uavDesc.Format = GetD3D12Format();
+
+ ASSERT(!GetTexture()->IsMultisampledTexture());
+ uavDesc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2DARRAY;
+ uavDesc.Texture2DArray.FirstArraySlice = GetBaseArrayLayer();
+ uavDesc.Texture2DArray.ArraySize = GetLayerCount();
+ uavDesc.Texture2DArray.MipSlice = GetBaseMipLevel();
+ uavDesc.Texture2DArray.PlaneSlice = 0;
+ return uavDesc;
+ }
+
}} // namespace dawn_native::d3d12
diff --git a/src/dawn_native/d3d12/TextureD3D12.h b/src/dawn_native/d3d12/TextureD3D12.h
index 88a24f4..45443c1 100644
--- a/src/dawn_native/d3d12/TextureD3D12.h
+++ b/src/dawn_native/d3d12/TextureD3D12.h
@@ -116,6 +116,7 @@
const D3D12_SHADER_RESOURCE_VIEW_DESC& GetSRVDescriptor() const;
D3D12_RENDER_TARGET_VIEW_DESC GetRTVDescriptor() const;
D3D12_DEPTH_STENCIL_VIEW_DESC GetDSVDescriptor() const;
+ D3D12_UNORDERED_ACCESS_VIEW_DESC GetUAVDescriptor() const;
private:
D3D12_SHADER_RESOURCE_VIEW_DESC mSrvDesc;
diff --git a/src/tests/end2end/StorageTextureTests.cpp b/src/tests/end2end/StorageTextureTests.cpp
index 9e6764c..047351a 100644
--- a/src/tests/end2end/StorageTextureTests.cpp
+++ b/src/tests/end2end/StorageTextureTests.cpp
@@ -237,8 +237,14 @@
// Test that read-only storage textures are supported in compute shader.
TEST_P(StorageTextureTests, ReadonlyStorageTextureInComputeShader) {
- // TODO(jiawei.shao@intel.com): support read-only storage texture on D3D12 and OpenGL.
- DAWN_SKIP_TEST_IF(IsD3D12() || IsOpenGL());
+ // TODO(jiawei.shao@intel.com): support read-only storage texture on OpenGL.
+ DAWN_SKIP_TEST_IF(IsOpenGL());
+
+ // When we run dawn_end2end_tests with "--use-spvc-parser", extracting the binding type of a
+ // read-only image will always return shaderc_spvc_binding_type_writeonly_storage_texture.
+ // TODO(jiawei.shao@intel.com): enable this test when we specify "--use-spvc-parser" after the
+ // bug in spvc parser is fixed.
+ DAWN_SKIP_TEST_IF(IsD3D12() && IsSpvcParserBeingUsed());
// Prepare the read-only storage texture and fill it with the expected data.
// TODO(jiawei.shao@intel.com): test more texture formats.
@@ -292,8 +298,8 @@
// Test that read-only storage textures are supported in vertex shader.
TEST_P(StorageTextureTests, ReadonlyStorageTextureInVertexShader) {
- // TODO(jiawei.shao@intel.com): support read-only storage texture on D3D12 and OpenGL.
- DAWN_SKIP_TEST_IF(IsD3D12() || IsOpenGL());
+ // TODO(jiawei.shao@intel.com): support read-only storage texture on OpenGL.
+ DAWN_SKIP_TEST_IF(IsOpenGL());
// When we run dawn_end2end_tests with "--use-spvc-parser", extracting the binding type of a
// read-only image will always return shaderc_spvc_binding_type_writeonly_storage_texture.
@@ -336,8 +342,8 @@
// Test that read-only storage textures are supported in fragment shader.
TEST_P(StorageTextureTests, ReadonlyStorageTextureInFragmentShader) {
- // TODO(jiawei.shao@intel.com): support read-only storage texture on D3D12 and OpenGL.
- DAWN_SKIP_TEST_IF(IsD3D12() || IsOpenGL());
+ // TODO(jiawei.shao@intel.com): support read-only storage texture on OpenGL.
+ DAWN_SKIP_TEST_IF(IsOpenGL());
// When we run dawn_end2end_tests with "--use-spvc-parser", extracting the binding type of a
// read-only image will always return shaderc_spvc_binding_type_writeonly_storage_texture.
@@ -373,7 +379,13 @@
// Test that write-only storage textures are supported in compute shader.
TEST_P(StorageTextureTests, WriteonlyStorageTextureInComputeShader) {
// TODO(jiawei.shao@intel.com): support read-only storage texture on D3D12 and OpenGL.
- DAWN_SKIP_TEST_IF(IsD3D12() || IsOpenGL());
+ DAWN_SKIP_TEST_IF(IsOpenGL());
+
+ // When we run dawn_end2end_tests with "--use-spvc-parser", extracting the binding type of a
+ // read-only image will always return shaderc_spvc_binding_type_writeonly_storage_texture.
+ // TODO(jiawei.shao@intel.com): enable this test when we specify "--use-spvc-parser" after the
+ // bug in spvc parser is fixed.
+ DAWN_SKIP_TEST_IF(IsD3D12() && IsSpvcParserBeingUsed());
// Prepare the write-only storage texture.
// TODO(jiawei.shao@intel.com): test more texture formats.
@@ -403,7 +415,13 @@
// Test that write-only storage textures are supported in fragment shader.
TEST_P(StorageTextureTests, WriteonlyStorageTextureInFragmentShader) {
// TODO(jiawei.shao@intel.com): support read-only storage texture on D3D12 and OpenGL.
- DAWN_SKIP_TEST_IF(IsD3D12() || IsOpenGL());
+ DAWN_SKIP_TEST_IF(IsOpenGL());
+
+ // When we run dawn_end2end_tests with "--use-spvc-parser", extracting the binding type of a
+ // read-only image will always return shaderc_spvc_binding_type_writeonly_storage_texture.
+ // TODO(jiawei.shao@intel.com): enable this test when we specify "--use-spvc-parser" after the
+ // bug in spvc parser is fixed.
+ DAWN_SKIP_TEST_IF(IsD3D12() && IsSpvcParserBeingUsed());
// Prepare the write-only storage texture.
// TODO(jiawei.shao@intel.com): test more texture formats.