Implement readonly storage buffer on D3D12 backend

This change implements D3D12 backend for readonly storage buffer.
It uses SRV in root signature at API side and ByteAddressBuffer at
shader side (has already been done in spirv-cross) for readonly
storage buffer.

BUG=dawn:180, dawn:284

Change-Id: Iafcd24835a75349ce719e9735752de50210a846f
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/14300
Reviewed-by: Austin Eng <enga@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Yunchao He <yunchao.he@intel.com>
This commit is contained in:
Yunchao He 2019-12-09 21:01:28 +00:00 committed by Commit Bot service account
parent 4326a8a6f2
commit 5554283717
6 changed files with 39 additions and 8 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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();
}
}

View File

@ -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);