mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-14 15:46:28 +00:00
Reuse BGL validation in default layout computations.
Instead of calling validation functions directly in PipelineLayoutBase::CreateDefault, use ValidateBGLDesc and ValidatePipelineLayoutDesc. Also makes the visibility of the default layout match the aggregation as in the WebGPU spec. Also makes refcounting of BGLs a bit less manual at the bottom of CreateDefault. Also adds tests for minBufferBindingSize and visiblity aggregation in the default layout computations. Bug: dawn:527 Change-Id: I6bbd5f3de8b235dddf6cbd2bedfd34a094fcb277 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/28560 Commit-Queue: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Stephen White <senorblanco@chromium.org>
This commit is contained in:
committed by
Commit Bot service account
parent
52a588f3c9
commit
aeda49ba50
@@ -19,9 +19,6 @@
|
||||
|
||||
class GetBindGroupLayoutTests : public ValidationTest {
|
||||
protected:
|
||||
static constexpr wgpu::ShaderStage kVisibilityAll =
|
||||
wgpu::ShaderStage::Compute | wgpu::ShaderStage::Fragment | wgpu::ShaderStage::Vertex;
|
||||
|
||||
wgpu::RenderPipeline RenderPipelineFromFragmentShader(const char* shader) {
|
||||
wgpu::ShaderModule vsModule =
|
||||
utils::CreateShaderModule(device, utils::SingleShaderStage::Vertex, R"(
|
||||
@@ -78,19 +75,21 @@ TEST_F(GetBindGroupLayoutTests, SameObject) {
|
||||
|
||||
wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor);
|
||||
|
||||
// The same value is returned for the same index.
|
||||
EXPECT_EQ(pipeline.GetBindGroupLayout(0).Get(), pipeline.GetBindGroupLayout(0).Get());
|
||||
|
||||
EXPECT_EQ(pipeline.GetBindGroupLayout(1).Get(), pipeline.GetBindGroupLayout(1).Get());
|
||||
|
||||
// Matching bind group layouts at different indices are the same object.
|
||||
EXPECT_EQ(pipeline.GetBindGroupLayout(0).Get(), pipeline.GetBindGroupLayout(1).Get());
|
||||
|
||||
EXPECT_EQ(pipeline.GetBindGroupLayout(0).Get(), pipeline.GetBindGroupLayout(2).Get());
|
||||
// BGLs with different bindings types are different objects.
|
||||
EXPECT_NE(pipeline.GetBindGroupLayout(2).Get(), pipeline.GetBindGroupLayout(3).Get());
|
||||
|
||||
EXPECT_NE(pipeline.GetBindGroupLayout(0).Get(), pipeline.GetBindGroupLayout(3).Get());
|
||||
// BGLs with different visibilities are different objects.
|
||||
EXPECT_NE(pipeline.GetBindGroupLayout(0).Get(), pipeline.GetBindGroupLayout(2).Get());
|
||||
}
|
||||
|
||||
// Test that getBindGroupLayout defaults are correct
|
||||
// - shader stage visibility is All
|
||||
// - shader stage visibility is the stage that adds the binding.
|
||||
// - dynamic offsets is false
|
||||
TEST_F(GetBindGroupLayoutTests, DefaultShaderStageAndDynamicOffsets) {
|
||||
wgpu::RenderPipeline pipeline = RenderPipelineFromFragmentShader(R"(
|
||||
@@ -114,22 +113,19 @@ TEST_F(GetBindGroupLayoutTests, DefaultShaderStageAndDynamicOffsets) {
|
||||
|
||||
// Check that visibility and dynamic offsets match
|
||||
binding.hasDynamicOffset = false;
|
||||
binding.visibility = kVisibilityAll;
|
||||
binding.visibility = wgpu::ShaderStage::Fragment;
|
||||
EXPECT_EQ(device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get());
|
||||
|
||||
// Check that any change in visibility doesn't match.
|
||||
binding.visibility = wgpu::ShaderStage::Vertex;
|
||||
EXPECT_NE(device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get());
|
||||
|
||||
binding.visibility = wgpu::ShaderStage::Fragment;
|
||||
EXPECT_NE(device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get());
|
||||
|
||||
binding.visibility = wgpu::ShaderStage::Compute;
|
||||
EXPECT_NE(device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get());
|
||||
|
||||
// Check that any change in hasDynamicOffsets doesn't match.
|
||||
binding.hasDynamicOffset = true;
|
||||
binding.visibility = kVisibilityAll;
|
||||
binding.visibility = wgpu::ShaderStage::Fragment;
|
||||
EXPECT_NE(device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get());
|
||||
}
|
||||
|
||||
@@ -154,7 +150,7 @@ TEST_F(GetBindGroupLayoutTests, ComputePipeline) {
|
||||
wgpu::BindGroupLayoutEntry binding = {};
|
||||
binding.binding = 0;
|
||||
binding.type = wgpu::BindingType::UniformBuffer;
|
||||
binding.visibility = kVisibilityAll;
|
||||
binding.visibility = wgpu::ShaderStage::Compute;
|
||||
binding.hasDynamicOffset = false;
|
||||
binding.minBufferBindingSize = 4 * sizeof(float);
|
||||
|
||||
@@ -172,6 +168,7 @@ TEST_F(GetBindGroupLayoutTests, BindingType) {
|
||||
binding.hasDynamicOffset = false;
|
||||
binding.multisampled = false;
|
||||
binding.minBufferBindingSize = 4 * sizeof(float);
|
||||
binding.visibility = wgpu::ShaderStage::Fragment;
|
||||
|
||||
wgpu::BindGroupLayoutDescriptor desc = {};
|
||||
desc.entryCount = 1;
|
||||
@@ -179,7 +176,7 @@ TEST_F(GetBindGroupLayoutTests, BindingType) {
|
||||
|
||||
{
|
||||
// Storage buffer binding is not supported in vertex shader.
|
||||
binding.visibility = wgpu::ShaderStage::Compute | wgpu::ShaderStage::Fragment;
|
||||
binding.visibility = wgpu::ShaderStage::Fragment;
|
||||
binding.type = wgpu::BindingType::StorageBuffer;
|
||||
wgpu::RenderPipeline pipeline = RenderPipelineFromFragmentShader(R"(
|
||||
#version 450
|
||||
@@ -190,8 +187,6 @@ TEST_F(GetBindGroupLayoutTests, BindingType) {
|
||||
void main() {})");
|
||||
EXPECT_EQ(device.CreateBindGroupLayout(&desc).Get(), pipeline.GetBindGroupLayout(0).Get());
|
||||
}
|
||||
|
||||
binding.visibility = kVisibilityAll;
|
||||
{
|
||||
binding.type = wgpu::BindingType::UniformBuffer;
|
||||
wgpu::RenderPipeline pipeline = RenderPipelineFromFragmentShader(R"(
|
||||
@@ -243,7 +238,7 @@ TEST_F(GetBindGroupLayoutTests, Multisampled) {
|
||||
wgpu::BindGroupLayoutEntry binding = {};
|
||||
binding.binding = 0;
|
||||
binding.type = wgpu::BindingType::SampledTexture;
|
||||
binding.visibility = kVisibilityAll;
|
||||
binding.visibility = wgpu::ShaderStage::Fragment;
|
||||
binding.hasDynamicOffset = false;
|
||||
|
||||
wgpu::BindGroupLayoutDescriptor desc = {};
|
||||
@@ -276,7 +271,7 @@ TEST_F(GetBindGroupLayoutTests, ViewDimension) {
|
||||
wgpu::BindGroupLayoutEntry binding = {};
|
||||
binding.binding = 0;
|
||||
binding.type = wgpu::BindingType::SampledTexture;
|
||||
binding.visibility = kVisibilityAll;
|
||||
binding.visibility = wgpu::ShaderStage::Fragment;
|
||||
binding.hasDynamicOffset = false;
|
||||
binding.multisampled = false;
|
||||
|
||||
@@ -350,7 +345,7 @@ TEST_F(GetBindGroupLayoutTests, TextureComponentType) {
|
||||
wgpu::BindGroupLayoutEntry binding = {};
|
||||
binding.binding = 0;
|
||||
binding.type = wgpu::BindingType::SampledTexture;
|
||||
binding.visibility = kVisibilityAll;
|
||||
binding.visibility = wgpu::ShaderStage::Fragment;
|
||||
binding.hasDynamicOffset = false;
|
||||
binding.multisampled = false;
|
||||
|
||||
@@ -393,7 +388,7 @@ TEST_F(GetBindGroupLayoutTests, TextureComponentType) {
|
||||
TEST_F(GetBindGroupLayoutTests, BindingIndices) {
|
||||
wgpu::BindGroupLayoutEntry binding = {};
|
||||
binding.type = wgpu::BindingType::UniformBuffer;
|
||||
binding.visibility = kVisibilityAll;
|
||||
binding.visibility = wgpu::ShaderStage::Fragment;
|
||||
binding.hasDynamicOffset = false;
|
||||
binding.multisampled = false;
|
||||
binding.minBufferBindingSize = 4 * sizeof(float);
|
||||
@@ -471,6 +466,152 @@ TEST_F(GetBindGroupLayoutTests, DuplicateBinding) {
|
||||
device.CreateRenderPipeline(&descriptor);
|
||||
}
|
||||
|
||||
// Test that minBufferSize is set on the BGL and that the max of the min buffer sizes is used.
|
||||
TEST_F(GetBindGroupLayoutTests, MinBufferSize) {
|
||||
wgpu::ShaderModule vsModule4 =
|
||||
utils::CreateShaderModule(device, utils::SingleShaderStage::Vertex, R"(
|
||||
#version 450
|
||||
layout(set = 0, binding = 0) uniform UniformBuffer {
|
||||
float pos;
|
||||
};
|
||||
void main() {})");
|
||||
|
||||
wgpu::ShaderModule vsModule64 =
|
||||
utils::CreateShaderModule(device, utils::SingleShaderStage::Vertex, R"(
|
||||
#version 450
|
||||
layout(set = 0, binding = 0) uniform UniformBuffer1 {
|
||||
mat4 pos;
|
||||
};
|
||||
void main() {})");
|
||||
|
||||
wgpu::ShaderModule fsModule4 =
|
||||
utils::CreateShaderModule(device, utils::SingleShaderStage::Fragment, R"(
|
||||
#version 450
|
||||
layout(set = 0, binding = 0) uniform UniformBuffer {
|
||||
float pos;
|
||||
};
|
||||
|
||||
void main() {})");
|
||||
|
||||
wgpu::ShaderModule fsModule64 =
|
||||
utils::CreateShaderModule(device, utils::SingleShaderStage::Fragment, R"(
|
||||
#version 450
|
||||
layout(set = 0, binding = 0) uniform UniformBuffer {
|
||||
mat4 pos;
|
||||
};
|
||||
|
||||
void main() {})");
|
||||
|
||||
// Create BGLs with minBufferBindingSize 4 and 64.
|
||||
wgpu::BindGroupLayoutEntry binding = {};
|
||||
binding.binding = 0;
|
||||
binding.type = wgpu::BindingType::UniformBuffer;
|
||||
binding.visibility = wgpu::ShaderStage::Fragment | wgpu::ShaderStage::Vertex;
|
||||
|
||||
wgpu::BindGroupLayoutDescriptor desc = {};
|
||||
desc.entryCount = 1;
|
||||
desc.entries = &binding;
|
||||
|
||||
binding.minBufferBindingSize = 4;
|
||||
wgpu::BindGroupLayout bgl4 = device.CreateBindGroupLayout(&desc);
|
||||
binding.minBufferBindingSize = 64;
|
||||
wgpu::BindGroupLayout bgl64 = device.CreateBindGroupLayout(&desc);
|
||||
|
||||
utils::ComboRenderPipelineDescriptor descriptor(device);
|
||||
descriptor.layout = nullptr;
|
||||
|
||||
// Check with both stages using 4 bytes.
|
||||
{
|
||||
descriptor.vertexStage.module = vsModule4;
|
||||
descriptor.cFragmentStage.module = fsModule4;
|
||||
wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor);
|
||||
EXPECT_EQ(pipeline.GetBindGroupLayout(0).Get(), bgl4.Get());
|
||||
}
|
||||
|
||||
// Check that the max is taken between 4 and 64.
|
||||
{
|
||||
descriptor.vertexStage.module = vsModule64;
|
||||
descriptor.cFragmentStage.module = fsModule4;
|
||||
wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor);
|
||||
EXPECT_EQ(pipeline.GetBindGroupLayout(0).Get(), bgl64.Get());
|
||||
}
|
||||
|
||||
// Check that the order doesn't change that the max is taken.
|
||||
{
|
||||
descriptor.vertexStage.module = vsModule4;
|
||||
descriptor.cFragmentStage.module = fsModule64;
|
||||
wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor);
|
||||
EXPECT_EQ(pipeline.GetBindGroupLayout(0).Get(), bgl64.Get());
|
||||
}
|
||||
}
|
||||
|
||||
// Test that the visibility is correctly aggregated if two stages have the exact same binding.
|
||||
TEST_F(GetBindGroupLayoutTests, StageAggregation) {
|
||||
wgpu::ShaderModule vsModuleNoSampler =
|
||||
utils::CreateShaderModule(device, utils::SingleShaderStage::Vertex, R"(
|
||||
#version 450
|
||||
void main() {})");
|
||||
|
||||
wgpu::ShaderModule vsModuleSampler =
|
||||
utils::CreateShaderModule(device, utils::SingleShaderStage::Vertex, R"(
|
||||
#version 450
|
||||
layout(set = 0, binding = 0) uniform sampler mySampler;
|
||||
void main() {})");
|
||||
|
||||
wgpu::ShaderModule fsModuleNoSampler =
|
||||
utils::CreateShaderModule(device, utils::SingleShaderStage::Fragment, R"(
|
||||
#version 450
|
||||
void main() {})");
|
||||
|
||||
wgpu::ShaderModule fsModuleSampler =
|
||||
utils::CreateShaderModule(device, utils::SingleShaderStage::Fragment, R"(
|
||||
#version 450
|
||||
layout(set = 0, binding = 0) uniform sampler mySampler;
|
||||
void main() {})");
|
||||
|
||||
// Create BGLs with minBufferBindingSize 4 and 64.
|
||||
wgpu::BindGroupLayoutEntry binding = {};
|
||||
binding.binding = 0;
|
||||
binding.type = wgpu::BindingType::Sampler;
|
||||
|
||||
wgpu::BindGroupLayoutDescriptor desc = {};
|
||||
desc.entryCount = 1;
|
||||
desc.entries = &binding;
|
||||
|
||||
utils::ComboRenderPipelineDescriptor descriptor(device);
|
||||
descriptor.layout = nullptr;
|
||||
|
||||
// Check with only the vertex shader using the sampler
|
||||
{
|
||||
descriptor.vertexStage.module = vsModuleSampler;
|
||||
descriptor.cFragmentStage.module = fsModuleNoSampler;
|
||||
wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor);
|
||||
|
||||
binding.visibility = wgpu::ShaderStage::Vertex;
|
||||
EXPECT_EQ(pipeline.GetBindGroupLayout(0).Get(), device.CreateBindGroupLayout(&desc).Get());
|
||||
}
|
||||
|
||||
// Check with only the fragment shader using the sampler
|
||||
{
|
||||
descriptor.vertexStage.module = vsModuleNoSampler;
|
||||
descriptor.cFragmentStage.module = fsModuleSampler;
|
||||
wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor);
|
||||
|
||||
binding.visibility = wgpu::ShaderStage::Fragment;
|
||||
EXPECT_EQ(pipeline.GetBindGroupLayout(0).Get(), device.CreateBindGroupLayout(&desc).Get());
|
||||
}
|
||||
|
||||
// Check with both shaders using the sampler
|
||||
{
|
||||
descriptor.vertexStage.module = vsModuleSampler;
|
||||
descriptor.cFragmentStage.module = fsModuleSampler;
|
||||
wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor);
|
||||
|
||||
binding.visibility = wgpu::ShaderStage::Fragment | wgpu::ShaderStage::Vertex;
|
||||
EXPECT_EQ(pipeline.GetBindGroupLayout(0).Get(), device.CreateBindGroupLayout(&desc).Get());
|
||||
}
|
||||
}
|
||||
|
||||
// Test it is invalid to have conflicting binding types in the shaders.
|
||||
TEST_F(GetBindGroupLayoutTests, ConflictingBindingType) {
|
||||
wgpu::ShaderModule vsModule =
|
||||
@@ -500,8 +641,7 @@ TEST_F(GetBindGroupLayoutTests, ConflictingBindingType) {
|
||||
}
|
||||
|
||||
// Test it is invalid to have conflicting binding texture multisampling in the shaders.
|
||||
// TODO: Support multisampling
|
||||
TEST_F(GetBindGroupLayoutTests, DISABLED_ConflictingBindingTextureMultisampling) {
|
||||
TEST_F(GetBindGroupLayoutTests, ConflictingBindingTextureMultisampling) {
|
||||
wgpu::ShaderModule vsModule =
|
||||
utils::CreateShaderModule(device, utils::SingleShaderStage::Vertex, R"(
|
||||
#version 450
|
||||
|
||||
Reference in New Issue
Block a user