Readonly storage buffer - Vulkan backend
This change implements Vulkan backend for readonly storage buffer. It also adds a few end2end tests to verify the implementation. BUG=dawn:180 Change-Id: I0d680654fa490192c357eccdcdce8e56a8037bce Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/14200 Commit-Queue: Yunchao He <yunchao.he@intel.com> Reviewed-by: Austin Eng <enga@chromium.org> Reviewed-by: Kai Ninomiya <kainino@chromium.org> Reviewed-by: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
parent
4ff9eaf1b7
commit
ce8bf128ec
|
@ -56,6 +56,7 @@ namespace dawn_native { namespace vulkan {
|
||||||
case wgpu::BindingType::SampledTexture:
|
case wgpu::BindingType::SampledTexture:
|
||||||
return VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
|
return VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE;
|
||||||
case wgpu::BindingType::StorageBuffer:
|
case wgpu::BindingType::StorageBuffer:
|
||||||
|
case wgpu::BindingType::ReadonlyStorageBuffer:
|
||||||
if (isDynamic) {
|
if (isDynamic) {
|
||||||
return VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
|
return VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,8 @@ namespace dawn_native { namespace vulkan {
|
||||||
|
|
||||||
switch (layoutInfo.types[bindingIndex]) {
|
switch (layoutInfo.types[bindingIndex]) {
|
||||||
case wgpu::BindingType::UniformBuffer:
|
case wgpu::BindingType::UniformBuffer:
|
||||||
case wgpu::BindingType::StorageBuffer: {
|
case wgpu::BindingType::StorageBuffer:
|
||||||
|
case wgpu::BindingType::ReadonlyStorageBuffer: {
|
||||||
BufferBinding binding = GetBindingAsBufferBinding(bindingIndex);
|
BufferBinding binding = GetBindingAsBufferBinding(bindingIndex);
|
||||||
|
|
||||||
writeBufferInfo[numWrites].buffer = ToBackend(binding.buffer)->GetHandle();
|
writeBufferInfo[numWrites].buffer = ToBackend(binding.buffer)->GetHandle();
|
||||||
|
|
|
@ -66,7 +66,8 @@ namespace dawn_native { namespace vulkan {
|
||||||
if (usage & (wgpu::BufferUsage::Index | wgpu::BufferUsage::Vertex)) {
|
if (usage & (wgpu::BufferUsage::Index | wgpu::BufferUsage::Vertex)) {
|
||||||
flags |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT;
|
flags |= VK_PIPELINE_STAGE_VERTEX_INPUT_BIT;
|
||||||
}
|
}
|
||||||
if (usage & (wgpu::BufferUsage::Uniform | wgpu::BufferUsage::Storage)) {
|
if (usage &
|
||||||
|
(wgpu::BufferUsage::Uniform | wgpu::BufferUsage::Storage | kReadOnlyStorage)) {
|
||||||
flags |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT |
|
flags |= VK_PIPELINE_STAGE_VERTEX_SHADER_BIT |
|
||||||
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
|
VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT |
|
||||||
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
|
VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT;
|
||||||
|
|
|
@ -467,8 +467,9 @@ class MultipleWriteThenMultipleReadTests : public DawnTest {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Write into a few storage buffers in compute pass. Then read that data in a render pass. The
|
// Write into a few storage buffers in compute pass. Then read that data in a render pass. The
|
||||||
// readonly buffers in render pass include vertex buffer, index buffer, and uniform buffer. Data to
|
// readonly buffers in render pass include vertex buffer, index buffer, uniform buffer, and readonly
|
||||||
// be read in all of these buffers in render pass depend on the write operation in compute pass.
|
// storage buffer. Data to be read in all of these buffers in render pass depend on the write
|
||||||
|
// operation in compute pass.
|
||||||
TEST_P(MultipleWriteThenMultipleReadTests, SeparateBuffers) {
|
TEST_P(MultipleWriteThenMultipleReadTests, SeparateBuffers) {
|
||||||
// Create pipeline, bind group, and different buffers for compute pass.
|
// Create pipeline, bind group, and different buffers for compute pass.
|
||||||
wgpu::ShaderModule csModule =
|
wgpu::ShaderModule csModule =
|
||||||
|
@ -482,11 +483,11 @@ TEST_P(MultipleWriteThenMultipleReadTests, SeparateBuffers) {
|
||||||
ivec4 indices[2];
|
ivec4 indices[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
layout(std140, set = 0, binding = 2) buffer UniformContents0 {
|
layout(std140, set = 0, binding = 2) buffer UniformContents {
|
||||||
float color0;
|
float color0;
|
||||||
};
|
};
|
||||||
|
|
||||||
layout(std140, set = 0, binding = 3) buffer UniformContents1 {
|
layout(std140, set = 0, binding = 3) buffer ReadonlyStorageContents {
|
||||||
float color1;
|
float color1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -522,15 +523,14 @@ TEST_P(MultipleWriteThenMultipleReadTests, SeparateBuffers) {
|
||||||
wgpu::Buffer indexBuffer = CreateZeroedBuffer(
|
wgpu::Buffer indexBuffer = CreateZeroedBuffer(
|
||||||
sizeof(int) * 4 * 2,
|
sizeof(int) * 4 * 2,
|
||||||
wgpu::BufferUsage::Index | wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopyDst);
|
wgpu::BufferUsage::Index | wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopyDst);
|
||||||
wgpu::Buffer uniformBuffer0 =
|
wgpu::Buffer uniformBuffer =
|
||||||
CreateZeroedBuffer(sizeof(float), wgpu::BufferUsage::Uniform | wgpu::BufferUsage::Storage |
|
|
||||||
wgpu::BufferUsage::CopyDst);
|
|
||||||
wgpu::Buffer uniformBuffer1 =
|
|
||||||
CreateZeroedBuffer(sizeof(float), wgpu::BufferUsage::Uniform | wgpu::BufferUsage::Storage |
|
CreateZeroedBuffer(sizeof(float), wgpu::BufferUsage::Uniform | wgpu::BufferUsage::Storage |
|
||||||
wgpu::BufferUsage::CopyDst);
|
wgpu::BufferUsage::CopyDst);
|
||||||
|
wgpu::Buffer readonlyStorageBuffer =
|
||||||
|
CreateZeroedBuffer(sizeof(float), wgpu::BufferUsage::Storage | wgpu::BufferUsage::CopyDst);
|
||||||
wgpu::BindGroup bindGroup0 = utils::MakeBindGroup(
|
wgpu::BindGroup bindGroup0 = utils::MakeBindGroup(
|
||||||
device, bgl0,
|
device, bgl0,
|
||||||
{{0, vertexBuffer}, {1, indexBuffer}, {2, uniformBuffer0}, {3, uniformBuffer1}});
|
{{0, vertexBuffer}, {1, indexBuffer}, {2, uniformBuffer}, {3, readonlyStorageBuffer}});
|
||||||
|
|
||||||
// Write data into storage buffers in compute pass.
|
// Write data into storage buffers in compute pass.
|
||||||
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
wgpu::CommandEncoder encoder = device.CreateCommandEncoder();
|
||||||
|
@ -552,11 +552,11 @@ TEST_P(MultipleWriteThenMultipleReadTests, SeparateBuffers) {
|
||||||
wgpu::ShaderModule fsModule =
|
wgpu::ShaderModule fsModule =
|
||||||
utils::CreateShaderModule(device, utils::SingleShaderStage::Fragment, R"(
|
utils::CreateShaderModule(device, utils::SingleShaderStage::Fragment, R"(
|
||||||
#version 450
|
#version 450
|
||||||
layout (set = 0, binding = 0) uniform uniformBuffer0 {
|
layout (set = 0, binding = 0) uniform UniformBuffer {
|
||||||
float color0;
|
float color0;
|
||||||
};
|
};
|
||||||
|
|
||||||
layout (set = 0, binding = 1) uniform uniformBuffer1 {
|
layout (set = 0, binding = 1) readonly buffer ReadonlyStorageBuffer {
|
||||||
float color1;
|
float color1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -568,7 +568,7 @@ TEST_P(MultipleWriteThenMultipleReadTests, SeparateBuffers) {
|
||||||
wgpu::BindGroupLayout bgl1 = utils::MakeBindGroupLayout(
|
wgpu::BindGroupLayout bgl1 = utils::MakeBindGroupLayout(
|
||||||
device, {
|
device, {
|
||||||
{0, wgpu::ShaderStage::Fragment, wgpu::BindingType::UniformBuffer},
|
{0, wgpu::ShaderStage::Fragment, wgpu::BindingType::UniformBuffer},
|
||||||
{1, wgpu::ShaderStage::Fragment, wgpu::BindingType::UniformBuffer},
|
{1, wgpu::ShaderStage::Fragment, wgpu::BindingType::ReadonlyStorageBuffer},
|
||||||
});
|
});
|
||||||
wgpu::PipelineLayout pipelineLayout = utils::MakeBasicPipelineLayout(device, &bgl1);
|
wgpu::PipelineLayout pipelineLayout = utils::MakeBasicPipelineLayout(device, &bgl1);
|
||||||
|
|
||||||
|
@ -588,7 +588,7 @@ TEST_P(MultipleWriteThenMultipleReadTests, SeparateBuffers) {
|
||||||
wgpu::RenderPipeline rp = device.CreateRenderPipeline(&rpDesc);
|
wgpu::RenderPipeline rp = device.CreateRenderPipeline(&rpDesc);
|
||||||
|
|
||||||
wgpu::BindGroup bindGroup1 =
|
wgpu::BindGroup bindGroup1 =
|
||||||
utils::MakeBindGroup(device, bgl1, {{0, uniformBuffer0}, {1, uniformBuffer1}});
|
utils::MakeBindGroup(device, bgl1, {{0, uniformBuffer}, {1, readonlyStorageBuffer}});
|
||||||
|
|
||||||
// Read data in buffers in render pass.
|
// Read data in buffers in render pass.
|
||||||
wgpu::RenderPassEncoder pass1 = encoder.BeginRenderPass(&renderPass.renderPassInfo);
|
wgpu::RenderPassEncoder pass1 = encoder.BeginRenderPass(&renderPass.renderPassInfo);
|
||||||
|
@ -611,8 +611,8 @@ TEST_P(MultipleWriteThenMultipleReadTests, SeparateBuffers) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write into a storage buffer in compute pass. Then read that data in buffer in a render pass. The
|
// Write into a storage buffer in compute pass. Then read that data in buffer in a render pass. The
|
||||||
// buffer is composed of vertices, indices, and uniforms. Data to be read in the buffer in render
|
// buffer is composed of vertices, indices, uniforms and readonly storage. Data to be read in the
|
||||||
// pass depend on the write operation in compute pass.
|
// buffer in render pass depend on the write operation in compute pass.
|
||||||
TEST_P(MultipleWriteThenMultipleReadTests, OneBuffer) {
|
TEST_P(MultipleWriteThenMultipleReadTests, OneBuffer) {
|
||||||
// Create pipeline, bind group, and a complex buffer for compute pass.
|
// Create pipeline, bind group, and a complex buffer for compute pass.
|
||||||
wgpu::ShaderModule csModule =
|
wgpu::ShaderModule csModule =
|
||||||
|
@ -688,11 +688,11 @@ TEST_P(MultipleWriteThenMultipleReadTests, OneBuffer) {
|
||||||
wgpu::ShaderModule fsModule =
|
wgpu::ShaderModule fsModule =
|
||||||
utils::CreateShaderModule(device, utils::SingleShaderStage::Fragment, R"(
|
utils::CreateShaderModule(device, utils::SingleShaderStage::Fragment, R"(
|
||||||
#version 450
|
#version 450
|
||||||
layout (set = 0, binding = 0) uniform uniformBuffer0 {
|
layout (set = 0, binding = 0) uniform UniformBuffer {
|
||||||
float color0;
|
float color0;
|
||||||
};
|
};
|
||||||
|
|
||||||
layout (set = 0, binding = 1) uniform uniformBuffer1 {
|
layout (set = 0, binding = 1) readonly buffer ReadonlyStorageBuffer {
|
||||||
float color1;
|
float color1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -704,7 +704,7 @@ TEST_P(MultipleWriteThenMultipleReadTests, OneBuffer) {
|
||||||
wgpu::BindGroupLayout bgl1 = utils::MakeBindGroupLayout(
|
wgpu::BindGroupLayout bgl1 = utils::MakeBindGroupLayout(
|
||||||
device, {
|
device, {
|
||||||
{0, wgpu::ShaderStage::Fragment, wgpu::BindingType::UniformBuffer},
|
{0, wgpu::ShaderStage::Fragment, wgpu::BindingType::UniformBuffer},
|
||||||
{1, wgpu::ShaderStage::Fragment, wgpu::BindingType::UniformBuffer},
|
{1, wgpu::ShaderStage::Fragment, wgpu::BindingType::ReadonlyStorageBuffer},
|
||||||
});
|
});
|
||||||
wgpu::PipelineLayout pipelineLayout = utils::MakeBasicPipelineLayout(device, &bgl1);
|
wgpu::PipelineLayout pipelineLayout = utils::MakeBasicPipelineLayout(device, &bgl1);
|
||||||
|
|
||||||
|
@ -749,7 +749,4 @@ TEST_P(MultipleWriteThenMultipleReadTests, OneBuffer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
DAWN_INSTANTIATE_TEST(MultipleWriteThenMultipleReadTests,
|
DAWN_INSTANTIATE_TEST(MultipleWriteThenMultipleReadTests,
|
||||||
D3D12Backend,
|
|
||||||
MetalBackend,
|
|
||||||
OpenGLBackend,
|
|
||||||
VulkanBackend);
|
VulkanBackend);
|
||||||
|
|
Loading…
Reference in New Issue