From 1ba2cb8589a8be955fdf1a3738633162b7850957 Mon Sep 17 00:00:00 2001 From: Yunchao He Date: Thu, 28 Mar 2019 05:09:01 +0000 Subject: [PATCH] Construct ComboInputStateDescriptor to simplify tests and examples Bug=dawn:107 Change-Id: I900de454cacf9f62ae97213161a98ce6d4254eab Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/6020 Commit-Queue: Yunchao He Reviewed-by: Kai Ninomiya --- examples/ComputeBoids.cpp | 39 +--- examples/CppHelloTriangle.cpp | 15 +- examples/CubeReflection.cpp | 26 +-- examples/glTFViewer/glTFViewer.cpp | 40 ++-- src/tests/end2end/DestroyTests.cpp | 14 +- src/tests/end2end/DrawIndexedTests.cpp | 15 +- src/tests/end2end/DrawTests.cpp | 15 +- src/tests/end2end/IndexFormatTests.cpp | 14 +- src/tests/end2end/InputStateTests.cpp | 52 +++-- src/tests/end2end/PrimitiveTopologyTests.cpp | 15 +- .../validation/InputStateValidationTests.cpp | 209 +++++------------- .../VertexBufferValidationTests.cpp | 21 +- src/utils/ComboRenderPipelineDescriptor.cpp | 35 ++- src/utils/ComboRenderPipelineDescriptor.h | 10 +- 14 files changed, 163 insertions(+), 357 deletions(-) diff --git a/examples/ComputeBoids.cpp b/examples/ComputeBoids.cpp index 06b5ca5930..18676d6ecf 100644 --- a/examples/ComputeBoids.cpp +++ b/examples/ComputeBoids.cpp @@ -114,31 +114,6 @@ void initRender() { } )"); - dawn::VertexAttributeDescriptor attribute[3]; - attribute[0].shaderLocation = 0; - attribute[0].inputSlot = 0; - attribute[0].offset = offsetof(Particle, pos); - attribute[0].format = dawn::VertexFormat::Float2; - - attribute[1].shaderLocation = 1; - attribute[1].inputSlot = 0; - attribute[1].offset = offsetof(Particle, vel); - attribute[1].format = dawn::VertexFormat::Float2; - - attribute[2].shaderLocation = 2; - attribute[2].inputSlot = 1; - attribute[2].offset = 0; - attribute[2].format = dawn::VertexFormat::Float2; - - dawn::VertexInputDescriptor input[2]; - input[0].inputSlot = 0; - input[0].stride = sizeof(Particle); - input[0].stepMode = dawn::InputStepMode::Instance; - - input[1].inputSlot = 1; - input[1].stride = sizeof(glm::vec2); - input[1].stepMode = dawn::InputStepMode::Vertex; - depthStencilView = CreateDefaultDepthStencilView(device); utils::ComboRenderPipelineDescriptor descriptor(device); @@ -146,9 +121,19 @@ void initRender() { descriptor.cFragmentStage.module = fsModule; descriptor.cInputState.numAttributes = 3; - descriptor.cInputState.attributes = attribute; + descriptor.cInputState.cAttributes[0].offset = offsetof(Particle, pos); + descriptor.cInputState.cAttributes[0].format = dawn::VertexFormat::Float2; + descriptor.cInputState.cAttributes[1].shaderLocation = 1; + descriptor.cInputState.cAttributes[1].offset = offsetof(Particle, vel); + descriptor.cInputState.cAttributes[1].format = dawn::VertexFormat::Float2; + descriptor.cInputState.cAttributes[2].shaderLocation = 2; + descriptor.cInputState.cAttributes[2].inputSlot = 1; + descriptor.cInputState.cAttributes[2].format = dawn::VertexFormat::Float2; descriptor.cInputState.numInputs = 2; - descriptor.cInputState.inputs = input; + descriptor.cInputState.cInputs[0].stride = sizeof(Particle); + descriptor.cInputState.cInputs[0].stepMode = dawn::InputStepMode::Instance; + descriptor.cInputState.cInputs[1].inputSlot = 1; + descriptor.cInputState.cInputs[1].stride = sizeof(glm::vec2); descriptor.depthStencilState = &descriptor.cDepthStencilState; descriptor.cDepthStencilState.format = dawn::TextureFormat::D32FloatS8Uint; descriptor.cColorStates[0]->format = GetPreferredSwapChainTextureFormat(); diff --git a/examples/CppHelloTriangle.cpp b/examples/CppHelloTriangle.cpp index ca756cf1f4..1c703af3c7 100644 --- a/examples/CppHelloTriangle.cpp +++ b/examples/CppHelloTriangle.cpp @@ -111,17 +111,6 @@ void init() { fragColor = texture(sampler2D(myTexture, mySampler), gl_FragCoord.xy / vec2(640.0, 480.0)); })"); - dawn::VertexAttributeDescriptor attribute; - attribute.shaderLocation = 0; - attribute.inputSlot = 0; - attribute.offset = 0; - attribute.format = dawn::VertexFormat::Float4; - - dawn::VertexInputDescriptor input; - input.inputSlot = 0; - input.stride = 4 * sizeof(float); - input.stepMode = dawn::InputStepMode::Vertex; - auto bgl = utils::MakeBindGroupLayout( device, { {0, dawn::ShaderStageBit::Fragment, dawn::BindingType::Sampler}, @@ -137,9 +126,9 @@ void init() { descriptor.cVertexStage.module = vsModule; descriptor.cFragmentStage.module = fsModule; descriptor.cInputState.numAttributes = 1; - descriptor.cInputState.attributes = &attribute; + descriptor.cInputState.cAttributes[0].format = dawn::VertexFormat::Float4; descriptor.cInputState.numInputs = 1; - descriptor.cInputState.inputs = &input; + descriptor.cInputState.cInputs[0].stride = 4 * sizeof(float); descriptor.depthStencilState = &descriptor.cDepthStencilState; descriptor.cDepthStencilState.format = dawn::TextureFormat::D32FloatS8Uint; descriptor.cColorStates[0]->format = GetPreferredSwapChainTextureFormat(); diff --git a/examples/CubeReflection.cpp b/examples/CubeReflection.cpp index 7a7423c079..df8a191d41 100644 --- a/examples/CubeReflection.cpp +++ b/examples/CubeReflection.cpp @@ -156,27 +156,15 @@ void init() { fragColor = vec4(mix(f_col, vec3(0.5, 0.5, 0.5), 0.5), 1.0); })"); - dawn::VertexAttributeDescriptor attribute[2]; - attribute[0].shaderLocation = 0; - attribute[0].inputSlot = 0; - attribute[0].offset = 0; - attribute[0].format = dawn::VertexFormat::Float3; - - attribute[1].shaderLocation = 1; - attribute[1].inputSlot = 0; - attribute[1].offset = 3 * sizeof(float); - attribute[1].format = dawn::VertexFormat::Float3; - - dawn::VertexInputDescriptor input; - input.inputSlot = 0; - input.stride = 6 * sizeof(float); - input.stepMode = dawn::InputStepMode::Vertex; - - dawn::InputStateDescriptor inputState; + utils::ComboInputStateDescriptor inputState; inputState.numAttributes = 2; - inputState.attributes = attribute; + inputState.cAttributes[0].format = dawn::VertexFormat::Float3; + inputState.cAttributes[1].shaderLocation = 1; + inputState.cAttributes[1].offset = 3 * sizeof(float); + inputState.cAttributes[1].format = dawn::VertexFormat::Float3; + inputState.numInputs = 1; - inputState.inputs = &input; + inputState.cInputs[0].stride = 6 * sizeof(float); auto bgl = utils::MakeBindGroupLayout( device, { diff --git a/examples/glTFViewer/glTFViewer.cpp b/examples/glTFViewer/glTFViewer.cpp index f3a82683a4..7418456592 100644 --- a/examples/glTFViewer/glTFViewer.cpp +++ b/examples/glTFViewer/glTFViewer.cpp @@ -238,8 +238,6 @@ namespace { auto oFSModule = utils::CreateShaderModule(device, dawn::ShaderStage::Fragment, hasTexture ? oFSSourceTextured : oFSSourceUntextured); utils::ComboRenderPipelineDescriptor descriptor(device); - dawn::VertexAttributeDescriptor attributes[kMaxVertexAttributes]; - dawn::VertexInputDescriptor inputs[kMaxVertexInputs]; uint32_t numAttributes = 0; uint32_t numInputs = 0; std::bitset<3> slotsSet; @@ -251,31 +249,26 @@ namespace { fprintf(stderr, "unsupported technique parameter type %d\n", iParameter.type); continue; } - attributes[numAttributes].offset = 0; - attributes[numAttributes].format = format; - inputs[numInputs].stepMode = dawn::InputStepMode::Vertex; + descriptor.cInputState.cAttributes[numAttributes].format = format; if (iParameter.semantic == "POSITION") { - attributes[numAttributes].shaderLocation = 0; - attributes[numAttributes].inputSlot = 0; - inputs[numInputs].inputSlot = 0; - inputs[numInputs].stride = static_cast(stridePos); + descriptor.cInputState.cInputs[numInputs].stride = static_cast(stridePos); numAttributes++; numInputs++; slotsSet.set(0); } else if (iParameter.semantic == "NORMAL") { - attributes[numAttributes].shaderLocation = 1; - attributes[numAttributes].inputSlot = 1; - inputs[numInputs].inputSlot = 1; - inputs[numInputs].stride = static_cast(strideNor); + descriptor.cInputState.cAttributes[numAttributes].shaderLocation = 1; + descriptor.cInputState.cAttributes[numAttributes].inputSlot = 1; + descriptor.cInputState.cInputs[numInputs].inputSlot = 1; + descriptor.cInputState.cInputs[numInputs].stride = static_cast(strideNor); numAttributes++; numInputs++; slotsSet.set(1); } else if (iParameter.semantic == "TEXCOORD_0") { - attributes[numAttributes].shaderLocation = 2; - attributes[numAttributes].inputSlot = 2; - inputs[numInputs].inputSlot = 2; - inputs[numInputs].stride = static_cast(strideTxc); + descriptor.cInputState.cAttributes[numAttributes].shaderLocation = 2; + descriptor.cInputState.cAttributes[numAttributes].inputSlot = 2; + descriptor.cInputState.cInputs[numInputs].inputSlot = 2; + descriptor.cInputState.cInputs[numInputs].stride = static_cast(strideTxc); numAttributes++; numInputs++; slotsSet.set(2); @@ -287,22 +280,17 @@ namespace { if (slotsSet[i]) { continue; } - attributes[numAttributes].offset = 0; - attributes[numAttributes].shaderLocation = i; - attributes[numAttributes].inputSlot = i; - attributes[numAttributes].format = dawn::VertexFormat::Float4; + descriptor.cInputState.cAttributes[numAttributes].shaderLocation = i; + descriptor.cInputState.cAttributes[numAttributes].inputSlot = i; + descriptor.cInputState.cAttributes[numAttributes].format = dawn::VertexFormat::Float4; - inputs[numInputs].inputSlot = i; - inputs[numInputs].stride = 0; - inputs[numInputs].stepMode = dawn::InputStepMode::Vertex; + descriptor.cInputState.cInputs[numInputs].inputSlot = i; numAttributes++; numInputs++; } descriptor.cInputState.numAttributes = numAttributes; - descriptor.cInputState.attributes = attributes; descriptor.cInputState.numInputs = numInputs; - descriptor.cInputState.inputs = inputs; constexpr dawn::ShaderStageBit kNoStages{}; dawn::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout( diff --git a/src/tests/end2end/DestroyTests.cpp b/src/tests/end2end/DestroyTests.cpp index 7ac324452b..2c60de0541 100644 --- a/src/tests/end2end/DestroyTests.cpp +++ b/src/tests/end2end/DestroyTests.cpp @@ -25,16 +25,6 @@ class DestroyTest : public DawnTest { DawnTest::SetUp(); renderPass = utils::CreateBasicRenderPass(device, kRTSize, kRTSize); - dawn::VertexInputDescriptor input; - input.inputSlot = 0; - input.stride = 4 * sizeof(float); - input.stepMode = dawn::InputStepMode::Vertex; - - dawn::VertexAttributeDescriptor attribute; - attribute.shaderLocation = 0; - attribute.inputSlot = 0; - attribute.offset = 0; - attribute.format = dawn::VertexFormat::Float4; dawn::ShaderModule vsModule = utils::CreateShaderModule(device, dawn::ShaderStage::Vertex, R"( @@ -58,9 +48,9 @@ class DestroyTest : public DawnTest { descriptor.primitiveTopology = dawn::PrimitiveTopology::TriangleStrip; descriptor.indexFormat = dawn::IndexFormat::Uint32; descriptor.cInputState.numInputs = 1; - descriptor.cInputState.inputs = &input; + descriptor.cInputState.cInputs[0].stride = 4 * sizeof(float); descriptor.cInputState.numAttributes = 1; - descriptor.cInputState.attributes = &attribute; + descriptor.cInputState.cAttributes[0].format = dawn::VertexFormat::Float4; descriptor.cColorStates[0]->format = renderPass.colorFormat; pipeline = device.CreateRenderPipeline(&descriptor); diff --git a/src/tests/end2end/DrawIndexedTests.cpp b/src/tests/end2end/DrawIndexedTests.cpp index 7eca1e1b71..86e3c048ba 100644 --- a/src/tests/end2end/DrawIndexedTests.cpp +++ b/src/tests/end2end/DrawIndexedTests.cpp @@ -26,17 +26,6 @@ class DrawIndexedTest : public DawnTest { renderPass = utils::CreateBasicRenderPass(device, kRTSize, kRTSize); - dawn::VertexInputDescriptor input; - input.inputSlot = 0; - input.stride = 4 * sizeof(float); - input.stepMode = dawn::InputStepMode::Vertex; - - dawn::VertexAttributeDescriptor attribute; - attribute.shaderLocation = 0; - attribute.inputSlot = 0; - attribute.offset = 0; - attribute.format = dawn::VertexFormat::Float4; - dawn::ShaderModule vsModule = utils::CreateShaderModule(device, dawn::ShaderStage::Vertex, R"( #version 450 @@ -59,9 +48,9 @@ class DrawIndexedTest : public DawnTest { descriptor.primitiveTopology = dawn::PrimitiveTopology::TriangleStrip; descriptor.indexFormat = dawn::IndexFormat::Uint32; descriptor.cInputState.numInputs = 1; - descriptor.cInputState.inputs = &input; + descriptor.cInputState.cInputs[0].stride = 4 * sizeof(float); descriptor.cInputState.numAttributes = 1; - descriptor.cInputState.attributes = &attribute; + descriptor.cInputState.cAttributes[0].format = dawn::VertexFormat::Float4; descriptor.cColorStates[0]->format = renderPass.colorFormat; pipeline = device.CreateRenderPipeline(&descriptor); diff --git a/src/tests/end2end/DrawTests.cpp b/src/tests/end2end/DrawTests.cpp index f7292eab98..3629719878 100644 --- a/src/tests/end2end/DrawTests.cpp +++ b/src/tests/end2end/DrawTests.cpp @@ -26,17 +26,6 @@ class DrawTest : public DawnTest { renderPass = utils::CreateBasicRenderPass(device, kRTSize, kRTSize); - dawn::VertexInputDescriptor input; - input.inputSlot = 0; - input.stride = 4 * sizeof(float); - input.stepMode = dawn::InputStepMode::Vertex; - - dawn::VertexAttributeDescriptor attribute; - attribute.shaderLocation = 0; - attribute.inputSlot = 0; - attribute.offset = 0; - attribute.format = dawn::VertexFormat::Float4; - dawn::ShaderModule vsModule = utils::CreateShaderModule(device, dawn::ShaderStage::Vertex, R"( #version 450 @@ -59,9 +48,9 @@ class DrawTest : public DawnTest { descriptor.primitiveTopology = dawn::PrimitiveTopology::TriangleStrip; descriptor.indexFormat = dawn::IndexFormat::Uint32; descriptor.cInputState.numInputs = 1; - descriptor.cInputState.inputs = &input; + descriptor.cInputState.cInputs[0].stride = 4 * sizeof(float); descriptor.cInputState.numAttributes = 1; - descriptor.cInputState.attributes = &attribute; + descriptor.cInputState.cAttributes[0].format = dawn::VertexFormat::Float4; descriptor.cColorStates[0]->format = renderPass.colorFormat; pipeline = device.CreateRenderPipeline(&descriptor); diff --git a/src/tests/end2end/IndexFormatTests.cpp b/src/tests/end2end/IndexFormatTests.cpp index 3ba2325891..988bb4f6cc 100644 --- a/src/tests/end2end/IndexFormatTests.cpp +++ b/src/tests/end2end/IndexFormatTests.cpp @@ -31,16 +31,6 @@ class IndexFormatTest : public DawnTest { utils::BasicRenderPass renderPass; dawn::RenderPipeline MakeTestPipeline(dawn::IndexFormat format) { - dawn::VertexInputDescriptor input; - input.inputSlot = 0; - input.stride = 4 * sizeof(float); - input.stepMode = dawn::InputStepMode::Vertex; - - dawn::VertexAttributeDescriptor attribute; - attribute.shaderLocation = 0; - attribute.inputSlot = 0; - attribute.offset = 0; - attribute.format = dawn::VertexFormat::Float4; dawn::ShaderModule vsModule = utils::CreateShaderModule(device, dawn::ShaderStage::Vertex, R"( #version 450 @@ -64,9 +54,9 @@ class IndexFormatTest : public DawnTest { descriptor.primitiveTopology = dawn::PrimitiveTopology::TriangleStrip; descriptor.indexFormat = format; descriptor.cInputState.numInputs = 1; - descriptor.cInputState.inputs = &input; + descriptor.cInputState.cInputs[0].stride = 4 * sizeof(float); descriptor.cInputState.numAttributes = 1; - descriptor.cInputState.attributes = &attribute; + descriptor.cInputState.cAttributes[0].format = dawn::VertexFormat::Float4; descriptor.cColorStates[0]->format = renderPass.colorFormat; return device.CreateRenderPipeline(&descriptor); diff --git a/src/tests/end2end/InputStateTests.cpp b/src/tests/end2end/InputStateTests.cpp index 78c14e37fb..87c2ac070a 100644 --- a/src/tests/end2end/InputStateTests.cpp +++ b/src/tests/end2end/InputStateTests.cpp @@ -143,29 +143,29 @@ class InputStateTest : public DawnTest { uint32_t offset; VertexFormat format; }; - dawn::InputStateDescriptor MakeInputState(std::vector inputs, - std::vector attributes) { - dawn::InputStateDescriptor inputState; + + utils::ComboInputStateDescriptor MakeInputState( + const std::vector& inputs, + const std::vector& attributes) { + utils::ComboInputStateDescriptor inputState; uint32_t numInputs = 0; for (const auto& input : inputs) { - vertexInputs[numInputs].inputSlot = input.slot; - vertexInputs[numInputs].stride = input.stride; - vertexInputs[numInputs].stepMode = input.step; + inputState.cInputs[numInputs].inputSlot = input.slot; + inputState.cInputs[numInputs].stride = input.stride; + inputState.cInputs[numInputs].stepMode = input.step; numInputs++; } uint32_t numAttributes = 0; for (const auto& attribute : attributes) { - vertexAttributes[numAttributes].shaderLocation = attribute.location; - vertexAttributes[numAttributes].inputSlot = attribute.slot; - vertexAttributes[numAttributes].offset = attribute.offset; - vertexAttributes[numAttributes].format = attribute.format; + inputState.cAttributes[numAttributes].shaderLocation = attribute.location; + inputState.cAttributes[numAttributes].inputSlot = attribute.slot; + inputState.cAttributes[numAttributes].offset = attribute.offset; + inputState.cAttributes[numAttributes].format = attribute.format; numAttributes++; } inputState.numInputs = numInputs; - inputState.inputs = vertexInputs; inputState.numAttributes = numAttributes; - inputState.attributes = vertexAttributes; return inputState; } @@ -218,13 +218,11 @@ class InputStateTest : public DawnTest { } utils::BasicRenderPass renderPass; - dawn::VertexAttributeDescriptor vertexAttributes[kMaxVertexAttributes]; - dawn::VertexInputDescriptor vertexInputs[kMaxVertexInputs]; }; // Test compilation and usage of the fixture :) TEST_P(InputStateTest, Basic) { - dawn::InputStateDescriptor inputState = MakeInputState( + utils::ComboInputStateDescriptor inputState = MakeInputState( {{0, 4 * sizeof(float), InputStepMode::Vertex}}, {{0, 0, 0, VertexFormat::Float4}}); dawn::RenderPipeline pipeline = MakeTestPipeline(inputState, 1, { {0, VertexFormat::Float4, InputStepMode::Vertex} @@ -243,7 +241,7 @@ TEST_P(InputStateTest, ZeroStride) { // This test was failing only on AMD but the OpenGL backend doesn't gather PCI info yet. DAWN_SKIP_TEST_IF(IsLinux() && IsOpenGL()); - dawn::InputStateDescriptor inputState = + utils::ComboInputStateDescriptor inputState = MakeInputState({{0, 0, InputStepMode::Vertex}}, {{0, 0, 0, VertexFormat::Float4}}); dawn::RenderPipeline pipeline = MakeTestPipeline(inputState, 0, { {0, VertexFormat::Float4, InputStepMode::Vertex} @@ -262,7 +260,7 @@ TEST_P(InputStateTest, AttributeExpanding) { // R32F case { - dawn::InputStateDescriptor inputState = + utils::ComboInputStateDescriptor inputState = MakeInputState({{0, 0, InputStepMode::Vertex}}, {{0, 0, 0, VertexFormat::Float}}); dawn::RenderPipeline pipeline = MakeTestPipeline(inputState, 0, { {0, VertexFormat::Float, InputStepMode::Vertex} @@ -275,7 +273,7 @@ TEST_P(InputStateTest, AttributeExpanding) { } // RG32F case { - dawn::InputStateDescriptor inputState = + utils::ComboInputStateDescriptor inputState = MakeInputState({{0, 0, InputStepMode::Vertex}}, {{0, 0, 0, VertexFormat::Float2}}); dawn::RenderPipeline pipeline = MakeTestPipeline(inputState, 0, { {0, VertexFormat::Float2, InputStepMode::Vertex} @@ -288,7 +286,7 @@ TEST_P(InputStateTest, AttributeExpanding) { } // RGB32F case { - dawn::InputStateDescriptor inputState = + utils::ComboInputStateDescriptor inputState = MakeInputState({{0, 0, InputStepMode::Vertex}}, {{0, 0, 0, VertexFormat::Float3}}); dawn::RenderPipeline pipeline = MakeTestPipeline(inputState, 0, { {0, VertexFormat::Float3, InputStepMode::Vertex} @@ -306,7 +304,7 @@ TEST_P(InputStateTest, StrideLargerThanAttributes) { // This test was failing only on AMD but the OpenGL backend doesn't gather PCI info yet. DAWN_SKIP_TEST_IF(IsLinux() && IsOpenGL()); - dawn::InputStateDescriptor inputState = MakeInputState( + utils::ComboInputStateDescriptor inputState = MakeInputState( {{0, 8 * sizeof(float), InputStepMode::Vertex}}, {{0, 0, 0, VertexFormat::Float4}}); dawn::RenderPipeline pipeline = MakeTestPipeline(inputState, 1, { {0, VertexFormat::Float4, InputStepMode::Vertex} @@ -322,7 +320,7 @@ TEST_P(InputStateTest, StrideLargerThanAttributes) { // Test two attributes at an offset, vertex version TEST_P(InputStateTest, TwoAttributesAtAnOffsetVertex) { - dawn::InputStateDescriptor inputState = MakeInputState( + utils::ComboInputStateDescriptor inputState = MakeInputState( {{0, 8 * sizeof(float), InputStepMode::Vertex}}, {{0, 0, 0, VertexFormat::Float4}, {1, 0, 4 * sizeof(float), VertexFormat::Float4}}); dawn::RenderPipeline pipeline = MakeTestPipeline(inputState, 1, { @@ -339,7 +337,7 @@ TEST_P(InputStateTest, TwoAttributesAtAnOffsetVertex) { // Test two attributes at an offset, instance version TEST_P(InputStateTest, TwoAttributesAtAnOffsetInstance) { - dawn::InputStateDescriptor inputState = MakeInputState( + utils::ComboInputStateDescriptor inputState = MakeInputState( {{0, 8 * sizeof(float), InputStepMode::Instance}}, {{0, 0, 0, VertexFormat::Float4}, {1, 0, 4 * sizeof(float), VertexFormat::Float4}}); dawn::RenderPipeline pipeline = MakeTestPipeline(inputState, 1, { @@ -356,7 +354,7 @@ TEST_P(InputStateTest, TwoAttributesAtAnOffsetInstance) { // Test a pure-instance input state TEST_P(InputStateTest, PureInstance) { - dawn::InputStateDescriptor inputState = MakeInputState( + utils::ComboInputStateDescriptor inputState = MakeInputState( {{0, 4 * sizeof(float), InputStepMode::Instance}}, {{0, 0, 0, VertexFormat::Float4}}); dawn::RenderPipeline pipeline = MakeTestPipeline(inputState, 1, { {0, VertexFormat::Float4, InputStepMode::Instance} @@ -374,7 +372,7 @@ TEST_P(InputStateTest, PureInstance) { // Test with mixed everything, vertex vs. instance, different stride and offsets // different attribute types TEST_P(InputStateTest, MixedEverything) { - dawn::InputStateDescriptor inputState = MakeInputState( + utils::ComboInputStateDescriptor inputState = MakeInputState( { {0, 12 * sizeof(float), InputStepMode::Vertex}, {1, 10 * sizeof(float), InputStepMode::Instance}, @@ -408,7 +406,7 @@ TEST_P(InputStateTest, MixedEverything) { // Test input state is unaffected by unused vertex slot TEST_P(InputStateTest, UnusedVertexSlot) { // Instance input state, using slot 1 - dawn::InputStateDescriptor instanceInputState = MakeInputState( + utils::ComboInputStateDescriptor instanceInputState = MakeInputState( {{1, 4 * sizeof(float), InputStepMode::Instance}}, {{0, 1, 0, VertexFormat::Float4}}); dawn::RenderPipeline instancePipeline = MakeTestPipeline( instanceInputState, 1, {{0, VertexFormat::Float4, InputStepMode::Instance}}); @@ -445,13 +443,13 @@ TEST_P(InputStateTest, UnusedVertexSlot) { // SetVertexBuffers should be reapplied when the input state changes. TEST_P(InputStateTest, MultiplePipelinesMixedInputState) { // Basic input state, using slot 0 - dawn::InputStateDescriptor vertexInputState = MakeInputState( + utils::ComboInputStateDescriptor vertexInputState = MakeInputState( {{0, 4 * sizeof(float), InputStepMode::Vertex}}, {{0, 0, 0, VertexFormat::Float4}}); dawn::RenderPipeline vertexPipeline = MakeTestPipeline( vertexInputState, 1, {{0, VertexFormat::Float4, InputStepMode::Vertex}}); // Instance input state, using slot 1 - dawn::InputStateDescriptor instanceInputState = MakeInputState( + utils::ComboInputStateDescriptor instanceInputState = MakeInputState( {{1, 4 * sizeof(float), InputStepMode::Instance}}, {{0, 1, 0, VertexFormat::Float4}}); dawn::RenderPipeline instancePipeline = MakeTestPipeline( instanceInputState, 1, {{0, VertexFormat::Float4, InputStepMode::Instance}}); diff --git a/src/tests/end2end/PrimitiveTopologyTests.cpp b/src/tests/end2end/PrimitiveTopologyTests.cpp index 6c1d73af78..490c86c6a5 100644 --- a/src/tests/end2end/PrimitiveTopologyTests.cpp +++ b/src/tests/end2end/PrimitiveTopologyTests.cpp @@ -181,25 +181,14 @@ class PrimitiveTopologyTest : public DawnTest { // Draw the vertices with the given primitive topology and check the pixel values of the test locations void DoTest(dawn::PrimitiveTopology primitiveTopology, const std::vector &locationSpecs) { - dawn::VertexAttributeDescriptor attribute; - attribute.shaderLocation = 0; - attribute.inputSlot = 0; - attribute.offset = 0; - attribute.format = dawn::VertexFormat::Float4; - - dawn::VertexInputDescriptor input; - input.inputSlot = 0; - input.stride = 4 * sizeof(float); - input.stepMode = dawn::InputStepMode::Vertex; - utils::ComboRenderPipelineDescriptor descriptor(device); descriptor.cVertexStage.module = vsModule; descriptor.cFragmentStage.module = fsModule; descriptor.primitiveTopology = primitiveTopology; descriptor.cInputState.numInputs = 1; - descriptor.cInputState.inputs = &input; + descriptor.cInputState.cInputs[0].stride = 4 * sizeof(float); descriptor.cInputState.numAttributes = 1; - descriptor.cInputState.attributes = &attribute; + descriptor.cInputState.cAttributes[0].format = dawn::VertexFormat::Float4; descriptor.cColorStates[0]->format = renderPass.colorFormat; dawn::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor); diff --git a/src/tests/unittests/validation/InputStateValidationTests.cpp b/src/tests/unittests/validation/InputStateValidationTests.cpp index bcc35fdf9a..4799817217 100644 --- a/src/tests/unittests/validation/InputStateValidationTests.cpp +++ b/src/tests/unittests/validation/InputStateValidationTests.cpp @@ -17,16 +17,10 @@ #include "utils/ComboRenderPipelineDescriptor.h" #include "utils/DawnHelpers.h" -constexpr static dawn::VertexInputDescriptor kBaseInput = { - 0, // inputSlot - 0, // stride - dawn::InputStepMode::Vertex, // stepMode -}; - class InputStateTest : public ValidationTest { protected: void CreatePipeline(bool success, - const dawn::InputStateDescriptor* state, + const utils::ComboInputStateDescriptor& state, std::string vertexSource) { dawn::ShaderModule vsModule = utils::CreateShaderModule(device, dawn::ShaderStage::Vertex, vertexSource.c_str()); @@ -42,9 +36,7 @@ class InputStateTest : public ValidationTest { utils::ComboRenderPipelineDescriptor descriptor(device); descriptor.cVertexStage.module = vsModule; descriptor.cFragmentStage.module = fsModule; - if (state) { - descriptor.inputState = state; - } + descriptor.inputState = &state; descriptor.cColorStates[0]->format = dawn::TextureFormat::R8G8B8A8Unorm; if (!success) { @@ -57,7 +49,8 @@ class InputStateTest : public ValidationTest { // Check an empty input state is valid TEST_F(InputStateTest, EmptyIsOk) { - CreatePipeline(true, nullptr, R"( + utils::ComboInputStateDescriptor state; + CreatePipeline(true, state, R"( #version 450 void main() { gl_Position = vec4(0.0); @@ -67,30 +60,15 @@ TEST_F(InputStateTest, EmptyIsOk) { // Check validation that pipeline vertex inputs are backed by attributes in the input state TEST_F(InputStateTest, PipelineCompatibility) { - dawn::VertexAttributeDescriptor attribute[2]; - attribute[0].shaderLocation = 0; - attribute[0].inputSlot = 0; - attribute[0].offset = 0; - attribute[0].format = dawn::VertexFormat::Float; - - attribute[1].shaderLocation = 1; - attribute[1].inputSlot = 0; - attribute[1].offset = sizeof(float); - attribute[1].format = dawn::VertexFormat::Float; - - dawn::VertexInputDescriptor input; - input.inputSlot = 0; - input.stride = 2 * sizeof(float); - input.stepMode = dawn::InputStepMode::Vertex; - - dawn::InputStateDescriptor state; + utils::ComboInputStateDescriptor state; state.numInputs = 1; - state.inputs = &input; + state.cInputs[0].stride = 2 * sizeof(float); state.numAttributes = 2; - state.attributes = attribute; + state.cAttributes[1].shaderLocation = 1; + state.cAttributes[1].offset = sizeof(float); // Control case: pipeline with one input per attribute - CreatePipeline(true, &state, R"( + CreatePipeline(true, state, R"( #version 450 layout(location = 0) in vec4 a; layout(location = 1) in vec4 b; @@ -100,7 +78,7 @@ TEST_F(InputStateTest, PipelineCompatibility) { )"); // Check it is valid for the pipeline to use a subset of the InputState - CreatePipeline(true, &state, R"( + CreatePipeline(true, state, R"( #version 450 layout(location = 0) in vec4 a; void main() { @@ -109,7 +87,7 @@ TEST_F(InputStateTest, PipelineCompatibility) { )"); // Check for an error when the pipeline uses an attribute not in the input state - CreatePipeline(false, &state, R"( + CreatePipeline(false, state, R"( #version 450 layout(location = 2) in vec4 a; void main() { @@ -121,12 +99,9 @@ TEST_F(InputStateTest, PipelineCompatibility) { // Test that a stride of 0 is valid TEST_F(InputStateTest, StrideZero) { // Works ok without attributes - dawn::InputStateDescriptor state; + utils::ComboInputStateDescriptor state; state.numInputs = 1; - state.inputs = &kBaseInput; - state.numAttributes = 0; - - CreatePipeline(true, &state, R"( + CreatePipeline(true, state, R"( #version 450 void main() { gl_Position = vec4(0.0); @@ -134,15 +109,9 @@ TEST_F(InputStateTest, StrideZero) { )"); // Works ok with attributes at a large-ish offset - dawn::VertexAttributeDescriptor attribute; - attribute.shaderLocation = 0; - attribute.inputSlot = 0; - attribute.offset = 128; - attribute.format = dawn::VertexFormat::Float; - state.numAttributes = 1; - state.attributes = &attribute; - CreatePipeline(true, &state, R"( + state.cAttributes[0].offset = 128; + CreatePipeline(true, state, R"( #version 450 void main() { gl_Position = vec4(0.0); @@ -153,12 +122,9 @@ TEST_F(InputStateTest, StrideZero) { // Test that we cannot set an already set input TEST_F(InputStateTest, AlreadySetInput) { // Control case - dawn::InputStateDescriptor state; + utils::ComboInputStateDescriptor state; state.numInputs = 1; - state.inputs = &kBaseInput; - state.numAttributes = 0; - - CreatePipeline(true, &state, R"( + CreatePipeline(true, state, R"( #version 450 void main() { gl_Position = vec4(0.0); @@ -166,11 +132,8 @@ TEST_F(InputStateTest, AlreadySetInput) { )"); // Oh no, input 0 is set twice - dawn::VertexInputDescriptor vertexInput[2] = {kBaseInput, kBaseInput}; state.numInputs = 2; - state.inputs = vertexInput; - - CreatePipeline(false, &state, R"( + CreatePipeline(false, state, R"( #version 450 void main() { gl_Position = vec4(0.0); @@ -181,17 +144,10 @@ TEST_F(InputStateTest, AlreadySetInput) { // Check out of bounds condition on input slot TEST_F(InputStateTest, SetInputSlotOutOfBounds) { // Control case, setting last input slot - dawn::VertexInputDescriptor input; - input.inputSlot = kMaxVertexInputs - 1; - input.stride = 0; - input.stepMode = dawn::InputStepMode::Vertex; - - dawn::InputStateDescriptor state; + utils::ComboInputStateDescriptor state; state.numInputs = 1; - state.inputs = &input; - state.numAttributes = 0; - - CreatePipeline(true, &state, R"( + state.cInputs[0].inputSlot = kMaxVertexInputs - 1; + CreatePipeline(true, state, R"( #version 450 void main() { gl_Position = vec4(0.0); @@ -199,8 +155,8 @@ TEST_F(InputStateTest, SetInputSlotOutOfBounds) { )"); // Test input slot OOB - input.inputSlot = kMaxVertexInputs; - CreatePipeline(false, &state, R"( + state.cInputs[0].inputSlot = kMaxVertexInputs; + CreatePipeline(false, state, R"( #version 450 void main() { gl_Position = vec4(0.0); @@ -211,17 +167,10 @@ TEST_F(InputStateTest, SetInputSlotOutOfBounds) { // Check out of bounds condition on input stride TEST_F(InputStateTest, SetInputStrideOutOfBounds) { // Control case, setting max input stride - dawn::VertexInputDescriptor input; - input.inputSlot = 0; - input.stride = kMaxVertexInputStride; - input.stepMode = dawn::InputStepMode::Vertex; - - dawn::InputStateDescriptor state; + utils::ComboInputStateDescriptor state; state.numInputs = 1; - state.inputs = &input; - state.numAttributes = 0; - - CreatePipeline(true, &state, R"( + state.cInputs[0].stride = kMaxVertexInputStride; + CreatePipeline(true, state, R"( #version 450 void main() { gl_Position = vec4(0.0); @@ -229,8 +178,8 @@ TEST_F(InputStateTest, SetInputStrideOutOfBounds) { )"); // Test input stride OOB - input.stride = kMaxVertexInputStride + 1; - CreatePipeline(false, &state, R"( + state.cInputs[0].stride = kMaxVertexInputStride + 1; + CreatePipeline(false, state, R"( #version 450 void main() { gl_Position = vec4(0.0); @@ -241,19 +190,10 @@ TEST_F(InputStateTest, SetInputStrideOutOfBounds) { // Test that we cannot set an already set attribute TEST_F(InputStateTest, AlreadySetAttribute) { // Control case, setting last attribute - dawn::VertexAttributeDescriptor attribute; - attribute.shaderLocation = 0; - attribute.inputSlot = 0; - attribute.offset = 0; - attribute.format = dawn::VertexFormat::Float; - - dawn::InputStateDescriptor state; + utils::ComboInputStateDescriptor state; state.numInputs = 1; - state.inputs = &kBaseInput; state.numAttributes = 1; - state.attributes = &attribute; - - CreatePipeline(true, &state, R"( + CreatePipeline(true, state, R"( #version 450 void main() { gl_Position = vec4(0.0); @@ -261,11 +201,8 @@ TEST_F(InputStateTest, AlreadySetAttribute) { )"); // Oh no, attribute 0 is set twice - dawn::VertexAttributeDescriptor vertexAttribute[2] = {attribute, attribute}; state.numAttributes = 2; - state.attributes = vertexAttribute; - - CreatePipeline(false, &state, R"( + CreatePipeline(false, state, R"( #version 450 void main() { gl_Position = vec4(0.0); @@ -276,19 +213,11 @@ TEST_F(InputStateTest, AlreadySetAttribute) { // Check out of bounds condition on attribute shader location TEST_F(InputStateTest, SetAttributeLocationOutOfBounds) { // Control case, setting last attribute shader location - dawn::VertexAttributeDescriptor attribute; - attribute.shaderLocation = kMaxVertexAttributes - 1; - attribute.inputSlot = 0; - attribute.offset = 0; - attribute.format = dawn::VertexFormat::Float; - - dawn::InputStateDescriptor state; + utils::ComboInputStateDescriptor state; state.numInputs = 1; - state.inputs = &kBaseInput; state.numAttributes = 1; - state.attributes = &attribute; - - CreatePipeline(true, &state, R"( + state.cAttributes[0].shaderLocation = kMaxVertexAttributes - 1; + CreatePipeline(true, state, R"( #version 450 void main() { gl_Position = vec4(0.0); @@ -296,8 +225,8 @@ TEST_F(InputStateTest, SetAttributeLocationOutOfBounds) { )"); // Test attribute location OOB - attribute.shaderLocation = kMaxVertexAttributes; - CreatePipeline(false, &state, R"( + state.cAttributes[0].shaderLocation = kMaxVertexAttributes; + CreatePipeline(false, state, R"( #version 450 void main() { gl_Position = vec4(0.0); @@ -308,19 +237,11 @@ TEST_F(InputStateTest, SetAttributeLocationOutOfBounds) { // Check attribute offset out of bounds TEST_F(InputStateTest, SetAttributeOffsetOutOfBounds) { // Control case, setting max attribute offset for FloatR32 vertex format - dawn::VertexAttributeDescriptor attribute; - attribute.shaderLocation = 0; - attribute.inputSlot = 0; - attribute.offset = kMaxVertexAttributeEnd - sizeof(dawn::VertexFormat::Float); - attribute.format = dawn::VertexFormat::Float; - - dawn::InputStateDescriptor state; + utils::ComboInputStateDescriptor state; state.numInputs = 1; - state.inputs = &kBaseInput; state.numAttributes = 1; - state.attributes = &attribute; - - CreatePipeline(true, &state, R"( + state.cAttributes[0].offset = kMaxVertexAttributeEnd - sizeof(dawn::VertexFormat::Float); + CreatePipeline(true, state, R"( #version 450 void main() { gl_Position = vec4(0.0); @@ -328,8 +249,8 @@ TEST_F(InputStateTest, SetAttributeOffsetOutOfBounds) { )"); // Test attribute offset out of bounds - attribute.offset = kMaxVertexAttributeEnd - 1; - CreatePipeline(false, &state, R"( + state.cAttributes[0].offset = kMaxVertexAttributeEnd - 1; + CreatePipeline(false, state, R"( #version 450 void main() { gl_Position = vec4(0.0); @@ -339,19 +260,11 @@ TEST_F(InputStateTest, SetAttributeOffsetOutOfBounds) { // Check attribute offset overflow TEST_F(InputStateTest, SetAttributeOffsetOverflow) { - dawn::VertexAttributeDescriptor attribute; - attribute.shaderLocation = 0; - attribute.inputSlot = 0; - attribute.offset = std::numeric_limits::max(); - attribute.format = dawn::VertexFormat::Float; - - dawn::InputStateDescriptor state; + utils::ComboInputStateDescriptor state; state.numInputs = 1; - state.inputs = &kBaseInput; state.numAttributes = 1; - state.attributes = &attribute; - - CreatePipeline(false, &state, R"( + state.cAttributes[0].offset = std::numeric_limits::max(); + CreatePipeline(false, state, R"( #version 450 void main() { gl_Position = vec4(0.0); @@ -362,19 +275,10 @@ TEST_F(InputStateTest, SetAttributeOffsetOverflow) { // Check that all attributes must be backed by an input TEST_F(InputStateTest, RequireInputForAttribute) { // Control case - dawn::VertexAttributeDescriptor attribute; - attribute.shaderLocation = 0; - attribute.inputSlot = 0; - attribute.offset = 0; - attribute.format = dawn::VertexFormat::Float; - - dawn::InputStateDescriptor state; + utils::ComboInputStateDescriptor state; state.numInputs = 1; - state.inputs = &kBaseInput; state.numAttributes = 1; - state.attributes = &attribute; - - CreatePipeline(true, &state, R"( + CreatePipeline(true, state, R"( #version 450 void main() { gl_Position = vec4(0.0); @@ -382,8 +286,8 @@ TEST_F(InputStateTest, RequireInputForAttribute) { )"); // Attribute 0 uses input 1 which doesn't exist - attribute.inputSlot = 1; - CreatePipeline(false, &state, R"( + state.cAttributes[0].inputSlot = 1; + CreatePipeline(false, state, R"( #version 450 void main() { gl_Position = vec4(0.0); @@ -394,19 +298,10 @@ TEST_F(InputStateTest, RequireInputForAttribute) { // Check OOB checks for an attribute's input TEST_F(InputStateTest, SetAttributeOOBCheckForInputs) { // Control case - dawn::VertexAttributeDescriptor attribute; - attribute.shaderLocation = 0; - attribute.inputSlot = 0; - attribute.offset = 0; - attribute.format = dawn::VertexFormat::Float; - - dawn::InputStateDescriptor state; + utils::ComboInputStateDescriptor state; state.numInputs = 1; - state.inputs = &kBaseInput; state.numAttributes = 1; - state.attributes = &attribute; - - CreatePipeline(true, &state, R"( + CreatePipeline(true, state, R"( #version 450 void main() { gl_Position = vec4(0.0); @@ -414,8 +309,8 @@ TEST_F(InputStateTest, SetAttributeOOBCheckForInputs) { )"); // Could crash if we didn't check for OOB - attribute.inputSlot = 1000000; - CreatePipeline(false, &state, R"( + state.cAttributes[0].inputSlot = 1000000; + CreatePipeline(false, state, R"( #version 450 void main() { gl_Position = vec4(0.0); diff --git a/src/tests/unittests/validation/VertexBufferValidationTests.cpp b/src/tests/unittests/validation/VertexBufferValidationTests.cpp index 29c1c1677f..3d06cbfee8 100644 --- a/src/tests/unittests/validation/VertexBufferValidationTests.cpp +++ b/src/tests/unittests/validation/VertexBufferValidationTests.cpp @@ -73,27 +73,14 @@ class VertexBufferValidationTest : public ValidationTest { descriptor.cVertexStage.module = vsModule; descriptor.cFragmentStage.module = fsModule; - dawn::VertexAttributeDescriptor attribute; - attribute.offset = 0; - attribute.format = dawn::VertexFormat::Float3; - - dawn::VertexInputDescriptor input; - input.stride = 0; - input.stepMode = dawn::InputStepMode::Vertex; - - dawn::VertexInputDescriptor vertexInputs[kMaxVertexInputs]; - dawn::VertexAttributeDescriptor vertexAttributes[kMaxVertexAttributes]; for (unsigned int i = 0; i < numInputs; ++i) { - attribute.shaderLocation = i; - attribute.inputSlot = i; - input.inputSlot = i; - vertexInputs[i] = input; - vertexAttributes[i] = attribute; + descriptor.cInputState.cAttributes[i].shaderLocation = i; + descriptor.cInputState.cAttributes[i].inputSlot = i; + descriptor.cInputState.cAttributes[i].format = dawn::VertexFormat::Float3; + descriptor.cInputState.cInputs[i].inputSlot = i; } descriptor.cInputState.numInputs = numInputs; - descriptor.cInputState.inputs = vertexInputs; descriptor.cInputState.numAttributes = numInputs; - descriptor.cInputState.attributes = vertexAttributes; return device.CreateRenderPipeline(&descriptor); } diff --git a/src/utils/ComboRenderPipelineDescriptor.cpp b/src/utils/ComboRenderPipelineDescriptor.cpp index f7bf479405..982def8aac 100644 --- a/src/utils/ComboRenderPipelineDescriptor.cpp +++ b/src/utils/ComboRenderPipelineDescriptor.cpp @@ -18,6 +18,33 @@ namespace utils { + ComboInputStateDescriptor::ComboInputStateDescriptor() { + dawn::InputStateDescriptor* descriptor = this; + + // Fill the default values for vertexInput. + descriptor->numInputs = 0; + dawn::VertexInputDescriptor vertexInput; + vertexInput.inputSlot = 0; + vertexInput.stride = 0; + vertexInput.stepMode = dawn::InputStepMode::Vertex; + for (uint32_t i = 0; i < kMaxVertexInputs; ++i) { + cInputs[i] = vertexInput; + } + descriptor->inputs = &cInputs[0]; + + // Fill the default values for vertexAttribute. + descriptor->numAttributes = 0; + dawn::VertexAttributeDescriptor vertexAttribute; + vertexAttribute.shaderLocation = 0; + vertexAttribute.inputSlot = 0; + vertexAttribute.offset = 0; + vertexAttribute.format = dawn::VertexFormat::Float; + for (uint32_t i = 0; i < kMaxVertexAttributes; ++i) { + cAttributes[i] = vertexAttribute; + } + descriptor->attributes = &cAttributes[0]; + } + ComboRenderPipelineDescriptor::ComboRenderPipelineDescriptor(const dawn::Device& device) { dawn::RenderPipelineDescriptor* descriptor = this; @@ -38,13 +65,7 @@ namespace utils { } // Set defaults for the input state descriptors. - { - descriptor->inputState = &cInputState; - cInputState.numInputs = 0; - cInputState.inputs = nullptr; - cInputState.numAttributes = 0; - cInputState.attributes = nullptr; - } + descriptor->inputState = &cInputState; // Set defaults for the color state descriptors. { diff --git a/src/utils/ComboRenderPipelineDescriptor.h b/src/utils/ComboRenderPipelineDescriptor.h index f76d7a56cd..123f637eff 100644 --- a/src/utils/ComboRenderPipelineDescriptor.h +++ b/src/utils/ComboRenderPipelineDescriptor.h @@ -23,6 +23,14 @@ namespace utils { + class ComboInputStateDescriptor : public dawn::InputStateDescriptor { + public: + ComboInputStateDescriptor(); + + std::array cInputs; + std::array cAttributes; + }; + class ComboRenderPipelineDescriptor : public dawn::RenderPipelineDescriptor { public: ComboRenderPipelineDescriptor(const dawn::Device& device); @@ -30,7 +38,7 @@ namespace utils { dawn::PipelineStageDescriptor cVertexStage; dawn::PipelineStageDescriptor cFragmentStage; - dawn::InputStateDescriptor cInputState; + ComboInputStateDescriptor cInputState; std::array cColorStates; dawn::DepthStencilStateDescriptor cDepthStencilState;