Port BindGroupValidationTests to WGSL

Bug: dawn:572
Change-Id: Ifccb349e756c5b2ca9f8ce2ab64f431d53856e6f
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/33823
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: Corentin Wallez <cwallez@chromium.org>
Auto-Submit: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
Corentin Wallez 2020-11-26 15:23:56 +00:00 committed by Commit Bot service account
parent 218a3d71c3
commit fe22ba525d
1 changed files with 95 additions and 129 deletions

View File

@ -1063,29 +1063,21 @@ class SetBindGroupValidationTest : public ValidationTest {
wgpu::BindGroupLayout mBindGroupLayout; wgpu::BindGroupLayout mBindGroupLayout;
wgpu::RenderPipeline CreateRenderPipeline() { wgpu::RenderPipeline CreateRenderPipeline() {
wgpu::ShaderModule vsModule = wgpu::ShaderModule vsModule = utils::CreateShaderModuleFromWGSL(device, R"(
utils::CreateShaderModule(device, utils::SingleShaderStage::Vertex, R"( [[stage(vertex)]] fn main() -> void {
#version 450
void main() {
})"); })");
wgpu::ShaderModule fsModule = wgpu::ShaderModule fsModule = utils::CreateShaderModuleFromWGSL(device, R"(
utils::CreateShaderModule(device, utils::SingleShaderStage::Fragment, R"( [[block]] struct S {
#version 450 [[offset(0)]] value : vec2<f32>;
layout(std140, set = 0, binding = 0) uniform uBufferDynamic {
vec2 value0;
}; };
layout(std140, set = 0, binding = 1) uniform uBuffer {
vec2 value1; [[set(0), binding(0)]] var<uniform> uBufferDynamic : S;
}; [[set(0), binding(1)]] var<uniform> uBuffer : S;
layout(std140, set = 0, binding = 2) buffer SBufferDynamic { [[set(0), binding(2)]] var<storage_buffer> sBufferDynamic : [[access(read_write)]] S;
vec2 value2; [[set(0), binding(3)]] var<storage_buffer> sReadonlyBufferDynamic : [[access(read)]] S;
} sBuffer;
layout(std140, set = 0, binding = 3) readonly buffer RBufferDynamic { [[stage(fragment)]] fn main() -> void {
vec2 value3;
} rBuffer;
layout(location = 0) out vec4 fragColor;
void main() {
})"); })");
utils::ComboRenderPipelineDescriptor pipelineDescriptor(device); utils::ComboRenderPipelineDescriptor pipelineDescriptor(device);
@ -1098,26 +1090,17 @@ class SetBindGroupValidationTest : public ValidationTest {
} }
wgpu::ComputePipeline CreateComputePipeline() { wgpu::ComputePipeline CreateComputePipeline() {
wgpu::ShaderModule csModule = wgpu::ShaderModule csModule = utils::CreateShaderModuleFromWGSL(device, R"(
utils::CreateShaderModule(device, utils::SingleShaderStage::Compute, R"( [[block]] struct S {
#version 450 [[offset(0)]] value : vec2<f32>;
const uint kTileSize = 4; };
const uint kInstances = 11;
layout(local_size_x = kTileSize, local_size_y = kTileSize, local_size_z = 1) in; [[set(0), binding(0)]] var<uniform> uBufferDynamic : S;
layout(std140, set = 0, binding = 0) uniform UniformBufferDynamic { [[set(0), binding(1)]] var<uniform> uBuffer : S;
float value0; [[set(0), binding(2)]] var<storage_buffer> sBufferDynamic : [[access(read_write)]] S;
}; [[set(0), binding(3)]] var<storage_buffer> sReadonlyBufferDynamic : [[access(read)]] S;
layout(std140, set = 0, binding = 1) uniform UniformBuffer {
float value1; [[stage(compute), workgroup_size(4, 4, 1)]] fn main() -> void {
};
layout(std140, set = 0, binding = 2) buffer SBufferDynamic {
float value2;
} dst;
layout(std140, set = 0, binding = 3) readonly buffer RBufferDynamic {
readonly float value3;
} rdst;
void main() {
})"); })");
wgpu::PipelineLayout pipelineLayout = wgpu::PipelineLayout pipelineLayout =
@ -1483,10 +1466,9 @@ class SetBindGroupPersistenceValidationTest : public ValidationTest {
void SetUp() override { void SetUp() override {
ValidationTest::SetUp(); ValidationTest::SetUp();
mVsModule = utils::CreateShaderModule(device, utils::SingleShaderStage::Vertex, R"( mVsModule = utils::CreateShaderModuleFromWGSL(device, R"(
#version 450 [[stage(vertex)]] fn main() -> void {
void main() { })");
})");
} }
wgpu::Buffer CreateBuffer(uint64_t bufferSize, wgpu::BufferUsage usage) { wgpu::Buffer CreateBuffer(uint64_t bufferSize, wgpu::BufferUsage usage) {
@ -1529,7 +1511,7 @@ class SetBindGroupPersistenceValidationTest : public ValidationTest {
device.CreatePipelineLayout(&pipelineLayoutDescriptor); device.CreatePipelineLayout(&pipelineLayoutDescriptor);
std::stringstream ss; std::stringstream ss;
ss << "#version 450\n"; ss << "[[block]] struct S { [[offset(0)]] value : vec2<f32>; };";
// Build a shader which has bindings that match the pipeline layout. // Build a shader which has bindings that match the pipeline layout.
for (uint32_t l = 0; l < layouts.size(); ++l) { for (uint32_t l = 0; l < layouts.size(); ++l) {
@ -1537,26 +1519,24 @@ class SetBindGroupPersistenceValidationTest : public ValidationTest {
for (uint32_t b = 0; b < layout.size(); ++b) { for (uint32_t b = 0; b < layout.size(); ++b) {
wgpu::BindingType binding = layout[b]; wgpu::BindingType binding = layout[b];
ss << "layout(std140, set = " << l << ", binding = " << b << ") "; ss << "[[set(" << l << "), binding(" << b << ")]] ";
switch (binding) { switch (binding) {
case wgpu::BindingType::StorageBuffer: case wgpu::BindingType::StorageBuffer:
ss << "buffer SBuffer"; ss << "var<storage_buffer> set" << l << "_binding" << b
<< " : [[access(read_write)]] S;";
break; break;
case wgpu::BindingType::UniformBuffer: case wgpu::BindingType::UniformBuffer:
ss << "uniform UBuffer"; ss << "var<uniform> set" << l << "_binding" << b << " : S;";
break; break;
default: default:
UNREACHABLE(); UNREACHABLE();
} }
ss << l << "_" << b << " { vec2 set" << l << "_binding" << b << "; };\n";
} }
} }
ss << "layout(location = 0) out vec4 fragColor;\n"; ss << "[[stage(fragment)]] fn main() -> void {}";
ss << "void main() { fragColor = vec4(0.0, 1.0, 0.0, 1.0); }\n";
wgpu::ShaderModule fsModule = wgpu::ShaderModule fsModule = utils::CreateShaderModuleFromWGSL(device, ss.str().c_str());
utils::CreateShaderModule(device, utils::SingleShaderStage::Fragment, ss.str().c_str());
utils::ComboRenderPipelineDescriptor pipelineDescriptor(device); utils::ComboRenderPipelineDescriptor pipelineDescriptor(device);
pipelineDescriptor.vertexStage.module = mVsModule; pipelineDescriptor.vertexStage.module = mVsModule;
@ -1687,14 +1667,11 @@ class BindGroupLayoutCompatibilityTest : public ValidationTest {
wgpu::RenderPipeline CreateFSRenderPipeline( wgpu::RenderPipeline CreateFSRenderPipeline(
const char* fsShader, const char* fsShader,
std::vector<wgpu::BindGroupLayout> bindGroupLayout) { std::vector<wgpu::BindGroupLayout> bindGroupLayout) {
wgpu::ShaderModule vsModule = wgpu::ShaderModule vsModule = utils::CreateShaderModuleFromWGSL(device, R"(
utils::CreateShaderModule(device, utils::SingleShaderStage::Vertex, R"( [[stage(vertex)]] fn main() -> void {
#version 450
void main() {
})"); })");
wgpu::ShaderModule fsModule = wgpu::ShaderModule fsModule = utils::CreateShaderModuleFromWGSL(device, fsShader);
utils::CreateShaderModule(device, utils::SingleShaderStage::Fragment, fsShader);
wgpu::PipelineLayoutDescriptor descriptor; wgpu::PipelineLayoutDescriptor descriptor;
descriptor.bindGroupLayoutCount = bindGroupLayout.size(); descriptor.bindGroupLayoutCount = bindGroupLayout.size();
@ -1707,26 +1684,24 @@ class BindGroupLayoutCompatibilityTest : public ValidationTest {
return device.CreateRenderPipeline(&pipelineDescriptor); return device.CreateRenderPipeline(&pipelineDescriptor);
} }
wgpu::RenderPipeline CreateRenderPipeline(std::vector<wgpu::BindGroupLayout> bindGroupLayout) { wgpu::RenderPipeline CreateRenderPipeline(std::vector<wgpu::BindGroupLayout> bindGroupLayouts) {
return CreateFSRenderPipeline(R"( return CreateFSRenderPipeline(R"(
#version 450 [[block]] struct S {
layout(std140, set = 0, binding = 0) buffer SBuffer { [[offset(0)]] value : vec2<f32>;
vec2 value2; };
} sBuffer;
layout(std140, set = 1, binding = 0) readonly buffer RBuffer { [[set(0), binding(0)]] var<storage_buffer> sBufferDynamic : [[access(read_write)]] S;
vec2 value3; [[set(1), binding(0)]] var<storage_buffer> sReadonlyBufferDynamic : [[access(read)]] S;
} rBuffer;
layout(location = 0) out vec4 fragColor; [[stage(fragment)]] fn main() -> void {
void main() { })",
})", std::move(bindGroupLayouts));
std::move(bindGroupLayout));
} }
wgpu::ComputePipeline CreateComputePipeline( wgpu::ComputePipeline CreateComputePipeline(
const char* shader, const char* shader,
std::vector<wgpu::BindGroupLayout> bindGroupLayout) { std::vector<wgpu::BindGroupLayout> bindGroupLayout) {
wgpu::ShaderModule csModule = wgpu::ShaderModule csModule = utils::CreateShaderModuleFromWGSL(device, shader);
utils::CreateShaderModule(device, utils::SingleShaderStage::Compute, shader);
wgpu::PipelineLayoutDescriptor descriptor; wgpu::PipelineLayoutDescriptor descriptor;
descriptor.bindGroupLayoutCount = bindGroupLayout.size(); descriptor.bindGroupLayoutCount = bindGroupLayout.size();
@ -1742,22 +1717,18 @@ class BindGroupLayoutCompatibilityTest : public ValidationTest {
} }
wgpu::ComputePipeline CreateComputePipeline( wgpu::ComputePipeline CreateComputePipeline(
std::vector<wgpu::BindGroupLayout> bindGroupLayout) { std::vector<wgpu::BindGroupLayout> bindGroupLayouts) {
return CreateComputePipeline(R"( return CreateComputePipeline(R"(
#version 450 [[block]] struct S {
const uint kTileSize = 4; [[offset(0)]] value : vec2<f32>;
const uint kInstances = 11; };
layout(local_size_x = kTileSize, local_size_y = kTileSize, local_size_z = 1) in; [[set(0), binding(0)]] var<storage_buffer> sBufferDynamic : [[access(read_write)]] S;
layout(std140, set = 0, binding = 0) buffer SBuffer { [[set(1), binding(0)]] var<storage_buffer> sReadonlyBufferDynamic : [[access(read)]] S;
float value2;
} dst; [[stage(compute), workgroup_size(4, 4, 1)]] fn main() -> void {
layout(std140, set = 1, binding = 0) readonly buffer RBuffer { })",
readonly float value3; std::move(bindGroupLayouts));
} rdst;
void main() {
})",
std::move(bindGroupLayout));
} }
}; };
@ -1794,70 +1765,76 @@ TEST_F(BindGroupLayoutCompatibilityTest, ROStorageInBGLWithRWStorageInShader) {
} }
TEST_F(BindGroupLayoutCompatibilityTest, TextureViewDimension) { TEST_F(BindGroupLayoutCompatibilityTest, TextureViewDimension) {
constexpr char kTexture2DShader[] = R"( constexpr char kTexture2DShaderFS[] = R"(
#version 450 [[set(0), binding(0)]] var<uniform_constant> myTexture : texture_sampled_2d<f32>;
layout(set = 0, binding = 0) uniform texture2D texture; [[stage(fragment)]] fn main() -> void {
void main() { })";
constexpr char kTexture2DShaderCS[] = R"(
[[set(0), binding(0)]] var<uniform_constant> myTexture : texture_sampled_2d<f32>;
[[stage(compute)]] fn main() -> void {
})"; })";
// Render: Test that 2D texture with 2D view dimension works // Render: Test that 2D texture with 2D view dimension works
CreateFSRenderPipeline( CreateFSRenderPipeline(
kTexture2DShader, kTexture2DShaderFS,
{utils::MakeBindGroupLayout( {utils::MakeBindGroupLayout(
device, {{0, wgpu::ShaderStage::Fragment, wgpu::BindingType::SampledTexture, false, 0, device, {{0, wgpu::ShaderStage::Fragment, wgpu::BindingType::SampledTexture, false, 0,
wgpu::TextureViewDimension::e2D}})}); wgpu::TextureViewDimension::e2D}})});
// Render: Test that 2D texture with 2D array view dimension is invalid // Render: Test that 2D texture with 2D array view dimension is invalid
ASSERT_DEVICE_ERROR(CreateFSRenderPipeline( ASSERT_DEVICE_ERROR(CreateFSRenderPipeline(
kTexture2DShader, kTexture2DShaderFS,
{utils::MakeBindGroupLayout( {utils::MakeBindGroupLayout(
device, {{0, wgpu::ShaderStage::Fragment, wgpu::BindingType::SampledTexture, false, 0, device, {{0, wgpu::ShaderStage::Fragment, wgpu::BindingType::SampledTexture, false, 0,
wgpu::TextureViewDimension::e2DArray}})})); wgpu::TextureViewDimension::e2DArray}})}));
// Compute: Test that 2D texture with 2D view dimension works // Compute: Test that 2D texture with 2D view dimension works
CreateComputePipeline( CreateComputePipeline(
kTexture2DShader, kTexture2DShaderCS,
{utils::MakeBindGroupLayout( {utils::MakeBindGroupLayout(
device, {{0, wgpu::ShaderStage::Compute, wgpu::BindingType::SampledTexture, false, 0, device, {{0, wgpu::ShaderStage::Compute, wgpu::BindingType::SampledTexture, false, 0,
wgpu::TextureViewDimension::e2D}})}); wgpu::TextureViewDimension::e2D}})});
// Compute: Test that 2D texture with 2D array view dimension is invalid // Compute: Test that 2D texture with 2D array view dimension is invalid
ASSERT_DEVICE_ERROR(CreateComputePipeline( ASSERT_DEVICE_ERROR(CreateComputePipeline(
kTexture2DShader, kTexture2DShaderCS,
{utils::MakeBindGroupLayout( {utils::MakeBindGroupLayout(
device, {{0, wgpu::ShaderStage::Compute, wgpu::BindingType::SampledTexture, false, 0, device, {{0, wgpu::ShaderStage::Compute, wgpu::BindingType::SampledTexture, false, 0,
wgpu::TextureViewDimension::e2DArray}})})); wgpu::TextureViewDimension::e2DArray}})}));
constexpr char kTexture2DArrayShader[] = R"( constexpr char kTexture2DArrayShaderFS[] = R"(
#version 450 [[set(0), binding(0)]] var<uniform_constant> myTexture : texture_sampled_2d_array<f32>;
layout(set = 0, binding = 0) uniform texture2DArray texture; [[stage(fragment)]] fn main() -> void {
void main() { })";
constexpr char kTexture2DArrayShaderCS[] = R"(
[[set(0), binding(0)]] var<uniform_constant> myTexture : texture_sampled_2d_array<f32>;
[[stage(compute)]] fn main() -> void {
})"; })";
// Render: Test that 2D texture array with 2D array view dimension works // Render: Test that 2D texture array with 2D array view dimension works
CreateFSRenderPipeline( CreateFSRenderPipeline(
kTexture2DArrayShader, kTexture2DArrayShaderFS,
{utils::MakeBindGroupLayout( {utils::MakeBindGroupLayout(
device, {{0, wgpu::ShaderStage::Fragment, wgpu::BindingType::SampledTexture, false, 0, device, {{0, wgpu::ShaderStage::Fragment, wgpu::BindingType::SampledTexture, false, 0,
wgpu::TextureViewDimension::e2DArray}})}); wgpu::TextureViewDimension::e2DArray}})});
// Render: Test that 2D texture array with 2D view dimension is invalid // Render: Test that 2D texture array with 2D view dimension is invalid
ASSERT_DEVICE_ERROR(CreateFSRenderPipeline( ASSERT_DEVICE_ERROR(CreateFSRenderPipeline(
kTexture2DArrayShader, kTexture2DArrayShaderFS,
{utils::MakeBindGroupLayout( {utils::MakeBindGroupLayout(
device, {{0, wgpu::ShaderStage::Fragment, wgpu::BindingType::SampledTexture, false, 0, device, {{0, wgpu::ShaderStage::Fragment, wgpu::BindingType::SampledTexture, false, 0,
wgpu::TextureViewDimension::e2D}})})); wgpu::TextureViewDimension::e2D}})}));
// Compute: Test that 2D texture array with 2D array view dimension works // Compute: Test that 2D texture array with 2D array view dimension works
CreateComputePipeline( CreateComputePipeline(
kTexture2DArrayShader, kTexture2DArrayShaderCS,
{utils::MakeBindGroupLayout( {utils::MakeBindGroupLayout(
device, {{0, wgpu::ShaderStage::Compute, wgpu::BindingType::SampledTexture, false, 0, device, {{0, wgpu::ShaderStage::Compute, wgpu::BindingType::SampledTexture, false, 0,
wgpu::TextureViewDimension::e2DArray}})}); wgpu::TextureViewDimension::e2DArray}})});
// Compute: Test that 2D texture array with 2D view dimension is invalid // Compute: Test that 2D texture array with 2D view dimension is invalid
ASSERT_DEVICE_ERROR(CreateComputePipeline( ASSERT_DEVICE_ERROR(CreateComputePipeline(
kTexture2DArrayShader, kTexture2DArrayShaderCS,
{utils::MakeBindGroupLayout( {utils::MakeBindGroupLayout(
device, {{0, wgpu::ShaderStage::Compute, wgpu::BindingType::SampledTexture, false, 0, device, {{0, wgpu::ShaderStage::Compute, wgpu::BindingType::SampledTexture, false, 0,
wgpu::TextureViewDimension::e2D}})})); wgpu::TextureViewDimension::e2D}})}));
@ -2054,14 +2031,11 @@ class ComparisonSamplerBindingTest : public ValidationTest {
protected: protected:
wgpu::RenderPipeline CreateFragmentPipeline(wgpu::BindGroupLayout* bindGroupLayout, wgpu::RenderPipeline CreateFragmentPipeline(wgpu::BindGroupLayout* bindGroupLayout,
const char* fragmentSource) { const char* fragmentSource) {
wgpu::ShaderModule vsModule = wgpu::ShaderModule vsModule = utils::CreateShaderModuleFromWGSL(device, R"(
utils::CreateShaderModule(device, utils::SingleShaderStage::Vertex, R"( [[stage(vertex)]] fn main() -> void {
#version 450 })");
void main() {
})");
wgpu::ShaderModule fsModule = wgpu::ShaderModule fsModule = utils::CreateShaderModuleFromWGSL(device, fragmentSource);
utils::CreateShaderModule(device, utils::SingleShaderStage::Fragment, fragmentSource);
utils::ComboRenderPipelineDescriptor pipelineDescriptor(device); utils::ComboRenderPipelineDescriptor pipelineDescriptor(device);
pipelineDescriptor.vertexStage.module = vsModule; pipelineDescriptor.vertexStage.module = vsModule;
@ -2082,11 +2056,9 @@ TEST_F(ComparisonSamplerBindingTest, DISABLED_ShaderAndBGLMatches) {
device, {{0, wgpu::ShaderStage::Fragment, wgpu::BindingType::Sampler}}); device, {{0, wgpu::ShaderStage::Fragment, wgpu::BindingType::Sampler}});
CreateFragmentPipeline(&bindGroupLayout, R"( CreateFragmentPipeline(&bindGroupLayout, R"(
#version 450 [[set(0), binding(0)]] var<uniform_constant> mySampler: sampler;
layout(set = 0, binding = 0) uniform sampler samp; [[stage(fragment)]] fn main() -> void {
})");
void main() {
})");
} }
// Test that comparison sampler binding works with shadow sampler in the shader. // Test that comparison sampler binding works with shadow sampler in the shader.
@ -2095,11 +2067,9 @@ TEST_F(ComparisonSamplerBindingTest, DISABLED_ShaderAndBGLMatches) {
device, {{0, wgpu::ShaderStage::Fragment, wgpu::BindingType::ComparisonSampler}}); device, {{0, wgpu::ShaderStage::Fragment, wgpu::BindingType::ComparisonSampler}});
CreateFragmentPipeline(&bindGroupLayout, R"( CreateFragmentPipeline(&bindGroupLayout, R"(
#version 450 [[set(0), binding(0)]] var<uniform_constant> mySampler: sampler_comparison;
layout(set = 0, binding = 0) uniform samplerShadow samp; [[stage(fragment)]] fn main() -> void {
})");
void main() {
})");
} }
// Test that sampler binding does not work with comparison sampler in the shader. // Test that sampler binding does not work with comparison sampler in the shader.
@ -2108,11 +2078,9 @@ TEST_F(ComparisonSamplerBindingTest, DISABLED_ShaderAndBGLMatches) {
device, {{0, wgpu::ShaderStage::Fragment, wgpu::BindingType::Sampler}}); device, {{0, wgpu::ShaderStage::Fragment, wgpu::BindingType::Sampler}});
ASSERT_DEVICE_ERROR(CreateFragmentPipeline(&bindGroupLayout, R"( ASSERT_DEVICE_ERROR(CreateFragmentPipeline(&bindGroupLayout, R"(
#version 450 [[set(0), binding(0)]] var<uniform_constant> mySampler: sampler_comparison;
layout(set = 0, binding = 0) uniform samplerShadow samp; [[stage(fragment)]] fn main() -> void {
})"));
void main() {
})"));
} }
// Test that comparison sampler binding does not work with normal sampler in the shader. // Test that comparison sampler binding does not work with normal sampler in the shader.
@ -2121,11 +2089,9 @@ TEST_F(ComparisonSamplerBindingTest, DISABLED_ShaderAndBGLMatches) {
device, {{0, wgpu::ShaderStage::Fragment, wgpu::BindingType::ComparisonSampler}}); device, {{0, wgpu::ShaderStage::Fragment, wgpu::BindingType::ComparisonSampler}});
ASSERT_DEVICE_ERROR(CreateFragmentPipeline(&bindGroupLayout, R"( ASSERT_DEVICE_ERROR(CreateFragmentPipeline(&bindGroupLayout, R"(
#version 450 [[set(0), binding(0)]] var<uniform_constant> mySampler: sampler;
layout(set = 0, binding = 0) uniform sampler samp; [[stage(fragment)]] fn main() -> void {
})"));
void main() {
})"));
} }
} }