diff --git a/src/dawn_native/d3d12/BindGroupD3D12.cpp b/src/dawn_native/d3d12/BindGroupD3D12.cpp index 38ca3a4c97..60a67d2072 100644 --- a/src/dawn_native/d3d12/BindGroupD3D12.cpp +++ b/src/dawn_native/d3d12/BindGroupD3D12.cpp @@ -86,6 +86,26 @@ namespace dawn_native { namespace d3d12 { cbvUavSrvHeapStart.GetCPUHandle(*cbvUavSrvHeapOffset + bindingOffsets[bindingIndex])); } break; + case wgpu::BindingType::ReadonlyStorageBuffer: { + BufferBinding binding = GetBindingAsBufferBinding(bindingIndex); + + // Like StorageBuffer, SPIRV-Cross outputs HLSL shaders for readonly storage + // buffer with ByteAddressBuffer. So we must use D3D12_BUFFER_SRV_FLAG_RAW + // when making the SRV descriptor. And it has similar requirement for format, + // element size, etc. + D3D12_SHADER_RESOURCE_VIEW_DESC desc; + desc.Format = DXGI_FORMAT_R32_TYPELESS; + desc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER; + desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; + desc.Buffer.FirstElement = binding.offset / 4; + desc.Buffer.NumElements = binding.size / 4; + desc.Buffer.StructureByteStride = 0; + desc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_RAW; + d3d12Device->CreateShaderResourceView( + ToBackend(binding.buffer)->GetD3D12Resource().Get(), &desc, + cbvUavSrvHeapStart.GetCPUHandle(*cbvUavSrvHeapOffset + + bindingOffsets[bindingIndex])); + } break; case wgpu::BindingType::SampledTexture: { auto* view = ToBackend(GetBindingAsTextureView(bindingIndex)); auto& srv = view->GetSRVDescriptor(); @@ -103,7 +123,6 @@ namespace dawn_native { namespace d3d12 { } break; case wgpu::BindingType::StorageTexture: - case wgpu::BindingType::ReadonlyStorageBuffer: UNREACHABLE(); break; diff --git a/src/dawn_native/d3d12/BindGroupLayoutD3D12.cpp b/src/dawn_native/d3d12/BindGroupLayoutD3D12.cpp index b810710842..cce919634e 100644 --- a/src/dawn_native/d3d12/BindGroupLayoutD3D12.cpp +++ b/src/dawn_native/d3d12/BindGroupLayoutD3D12.cpp @@ -39,6 +39,7 @@ namespace dawn_native { namespace d3d12 { mBindingOffsets[binding] = mDescriptorCounts[UAV]++; break; case wgpu::BindingType::SampledTexture: + case wgpu::BindingType::ReadonlyStorageBuffer: mBindingOffsets[binding] = mDescriptorCounts[SRV]++; break; case wgpu::BindingType::Sampler: @@ -46,7 +47,6 @@ namespace dawn_native { namespace d3d12 { break; case wgpu::BindingType::StorageTexture: - case wgpu::BindingType::ReadonlyStorageBuffer: UNREACHABLE(); break; } @@ -101,12 +101,12 @@ namespace dawn_native { namespace d3d12 { switch (groupInfo.types[binding]) { case wgpu::BindingType::UniformBuffer: case wgpu::BindingType::StorageBuffer: + case wgpu::BindingType::ReadonlyStorageBuffer: mBindingOffsets[binding] = baseRegister++; break; case wgpu::BindingType::SampledTexture: case wgpu::BindingType::Sampler: case wgpu::BindingType::StorageTexture: - case wgpu::BindingType::ReadonlyStorageBuffer: UNREACHABLE(); break; } @@ -121,6 +121,7 @@ namespace dawn_native { namespace d3d12 { mBindingOffsets[binding] += descriptorOffsets[UAV]; break; case wgpu::BindingType::SampledTexture: + case wgpu::BindingType::ReadonlyStorageBuffer: mBindingOffsets[binding] += descriptorOffsets[SRV]; break; case wgpu::BindingType::Sampler: @@ -128,7 +129,6 @@ namespace dawn_native { namespace d3d12 { break; case wgpu::BindingType::StorageTexture: - case wgpu::BindingType::ReadonlyStorageBuffer: UNREACHABLE(); break; diff --git a/src/dawn_native/d3d12/BufferD3D12.cpp b/src/dawn_native/d3d12/BufferD3D12.cpp index b875403bf9..8f32c36091 100644 --- a/src/dawn_native/d3d12/BufferD3D12.cpp +++ b/src/dawn_native/d3d12/BufferD3D12.cpp @@ -52,6 +52,10 @@ namespace dawn_native { namespace d3d12 { if (usage & wgpu::BufferUsage::Storage) { resourceState |= D3D12_RESOURCE_STATE_UNORDERED_ACCESS; } + if (usage & kReadOnlyStorage) { + resourceState |= (D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE | + D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE); + } if (usage & wgpu::BufferUsage::Indirect) { resourceState |= D3D12_RESOURCE_STATE_INDIRECT_ARGUMENT; } diff --git a/src/dawn_native/d3d12/CommandBufferD3D12.cpp b/src/dawn_native/d3d12/CommandBufferD3D12.cpp index 1b8118ea6a..ac3f9cbb40 100644 --- a/src/dawn_native/d3d12/CommandBufferD3D12.cpp +++ b/src/dawn_native/d3d12/CommandBufferD3D12.cpp @@ -237,10 +237,18 @@ namespace dawn_native { namespace d3d12 { bufferLocation); } break; + case wgpu::BindingType::ReadonlyStorageBuffer: + if (mInCompute) { + commandList->SetComputeRootShaderResourceView(parameterIndex, + bufferLocation); + } else { + commandList->SetGraphicsRootShaderResourceView(parameterIndex, + bufferLocation); + } + break; case wgpu::BindingType::SampledTexture: case wgpu::BindingType::Sampler: case wgpu::BindingType::StorageTexture: - case wgpu::BindingType::ReadonlyStorageBuffer: UNREACHABLE(); break; } diff --git a/src/dawn_native/d3d12/PipelineLayoutD3D12.cpp b/src/dawn_native/d3d12/PipelineLayoutD3D12.cpp index 2cdd6cf1db..8d3dd175eb 100644 --- a/src/dawn_native/d3d12/PipelineLayoutD3D12.cpp +++ b/src/dawn_native/d3d12/PipelineLayoutD3D12.cpp @@ -46,10 +46,11 @@ namespace dawn_native { namespace d3d12 { return D3D12_ROOT_PARAMETER_TYPE_CBV; case wgpu::BindingType::StorageBuffer: return D3D12_ROOT_PARAMETER_TYPE_UAV; + case wgpu::BindingType::ReadonlyStorageBuffer: + return D3D12_ROOT_PARAMETER_TYPE_SRV; case wgpu::BindingType::SampledTexture: case wgpu::BindingType::Sampler: case wgpu::BindingType::StorageTexture: - case wgpu::BindingType::ReadonlyStorageBuffer: UNREACHABLE(); } } diff --git a/src/tests/end2end/GpuMemorySynchronizationTests.cpp b/src/tests/end2end/GpuMemorySynchronizationTests.cpp index ee6e045a7a..69f506ba46 100644 --- a/src/tests/end2end/GpuMemorySynchronizationTests.cpp +++ b/src/tests/end2end/GpuMemorySynchronizationTests.cpp @@ -688,5 +688,4 @@ TEST_P(MultipleWriteThenMultipleReadTests, OneBuffer) { EXPECT_PIXEL_RGBA8_EQ(RGBA8::kYellow, renderPass.color, max, max); } -DAWN_INSTANTIATE_TEST(MultipleWriteThenMultipleReadTests, - VulkanBackend); +DAWN_INSTANTIATE_TEST(MultipleWriteThenMultipleReadTests, D3D12Backend, VulkanBackend);