Construct VertexInputDescriptor, in order to match web idl

BUG=dawn:107

Change-Id: Ic219fb98a88a7ac597fbdc592f604f27b76d756b
Reviewed-on: https://dawn-review.googlesource.com/c/4721
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
Commit-Queue: Yunchao He <yunchao.he@intel.com>
This commit is contained in:
Yunchao He 2019-02-14 23:56:07 +00:00 committed by Commit Bot service account
parent e7bb3fd119
commit 4dec7371a2
14 changed files with 136 additions and 65 deletions

View File

@ -598,6 +598,15 @@
{"name": "format", "type": "vertex format"} {"name": "format", "type": "vertex format"}
] ]
}, },
"vertex input descriptor": {
"category": "structure",
"extensible": false,
"members": [
{"name": "input slot", "type": "uint32_t"},
{"name": "stride", "type": "uint32_t"},
{"name": "step mode", "type": "input step mode"}
]
},
"input state": { "input state": {
"category": "object" "category": "object"
}, },
@ -617,9 +626,7 @@
{ {
"name": "set input", "name": "set input",
"args": [ "args": [
{"name": "binding slot", "type": "uint32_t"}, {"name": "input", "type": "vertex input descriptor", "annotation": "const*"}
{"name": "stride", "type": "uint32_t"},
{"name": "step mode", "type": "input step mode"}
] ]
} }
] ]

View File

@ -126,18 +126,28 @@ void initRender() {
attribute2.offset = offsetof(Particle, vel); attribute2.offset = offsetof(Particle, vel);
attribute2.format = dawn::VertexFormat::FloatR32G32; attribute2.format = dawn::VertexFormat::FloatR32G32;
dawn::VertexInputDescriptor input1;
input1.inputSlot = 0;
input1.stride = sizeof(Particle);
input1.stepMode = dawn::InputStepMode::Instance;
dawn::VertexAttributeDescriptor attribute3; dawn::VertexAttributeDescriptor attribute3;
attribute3.shaderLocation = 2; attribute3.shaderLocation = 2;
attribute3.inputSlot = 1; attribute3.inputSlot = 1;
attribute3.offset = 0; attribute3.offset = 0;
attribute3.format = dawn::VertexFormat::FloatR32G32; attribute3.format = dawn::VertexFormat::FloatR32G32;
dawn::VertexInputDescriptor input2;
input2.inputSlot = 1;
input2.stride = sizeof(glm::vec2);
input2.stepMode = dawn::InputStepMode::Vertex;
dawn::InputState inputState = device.CreateInputStateBuilder() dawn::InputState inputState = device.CreateInputStateBuilder()
.SetAttribute(&attribute1) .SetAttribute(&attribute1)
.SetAttribute(&attribute2) .SetAttribute(&attribute2)
.SetInput(0, sizeof(Particle), dawn::InputStepMode::Instance) .SetInput(&input1)
.SetAttribute(&attribute3) .SetAttribute(&attribute3)
.SetInput(1, sizeof(glm::vec2), dawn::InputStepMode::Vertex) .SetInput(&input2)
.GetResult(); .GetResult();
depthStencilView = CreateDefaultDepthStencilView(device); depthStencilView = CreateDefaultDepthStencilView(device);

View File

@ -116,10 +116,14 @@ void init() {
attribute.inputSlot = 0; attribute.inputSlot = 0;
attribute.offset = 0; attribute.offset = 0;
attribute.format = dawn::VertexFormat::FloatR32G32B32A32; attribute.format = dawn::VertexFormat::FloatR32G32B32A32;
auto inputState = device.CreateInputStateBuilder()
.SetAttribute(&attribute) dawn::VertexInputDescriptor input;
.SetInput(0, 4 * sizeof(float), dawn::InputStepMode::Vertex) input.inputSlot = 0;
.GetResult(); input.stride = 4 * sizeof(float);
input.stepMode = dawn::InputStepMode::Vertex;
auto inputState =
device.CreateInputStateBuilder().SetAttribute(&attribute).SetInput(&input).GetResult();
auto bgl = utils::MakeBindGroupLayout( auto bgl = utils::MakeBindGroupLayout(
device, { device, {

View File

@ -168,10 +168,15 @@ void init() {
attribute2.offset = 3 * sizeof(float); attribute2.offset = 3 * sizeof(float);
attribute2.format = dawn::VertexFormat::FloatR32G32B32; attribute2.format = dawn::VertexFormat::FloatR32G32B32;
dawn::VertexInputDescriptor input;
input.inputSlot = 0;
input.stride = 6 * sizeof(float);
input.stepMode = dawn::InputStepMode::Vertex;
auto inputState = device.CreateInputStateBuilder() auto inputState = device.CreateInputStateBuilder()
.SetAttribute(&attribute1) .SetAttribute(&attribute1)
.SetAttribute(&attribute2) .SetAttribute(&attribute2)
.SetInput(0, 6 * sizeof(float), dawn::InputStepMode::Vertex) .SetInput(&input)
.GetResult(); .GetResult();
auto bgl = utils::MakeBindGroupLayout( auto bgl = utils::MakeBindGroupLayout(

View File

@ -250,23 +250,32 @@ namespace {
dawn::VertexAttributeDescriptor attribute; dawn::VertexAttributeDescriptor attribute;
attribute.offset = 0; attribute.offset = 0;
attribute.format = format; attribute.format = format;
dawn::VertexInputDescriptor input;
input.stepMode = dawn::InputStepMode::Vertex;
if (iParameter.semantic == "POSITION") { if (iParameter.semantic == "POSITION") {
attribute.shaderLocation = 0; attribute.shaderLocation = 0;
attribute.inputSlot = 0; attribute.inputSlot = 0;
input.inputSlot = 0;
input.stride = static_cast<uint32_t>(stridePos);
builder.SetAttribute(&attribute); builder.SetAttribute(&attribute);
builder.SetInput(0, static_cast<uint32_t>(stridePos), dawn::InputStepMode::Vertex); builder.SetInput(&input);
slotsSet.set(0); slotsSet.set(0);
} else if (iParameter.semantic == "NORMAL") { } else if (iParameter.semantic == "NORMAL") {
attribute.shaderLocation = 1; attribute.shaderLocation = 1;
attribute.inputSlot = 1; attribute.inputSlot = 1;
input.inputSlot = 1;
input.stride = static_cast<uint32_t>(strideNor);
builder.SetAttribute(&attribute); builder.SetAttribute(&attribute);
builder.SetInput(1, static_cast<uint32_t>(strideNor), dawn::InputStepMode::Vertex); builder.SetInput(&input);
slotsSet.set(1); slotsSet.set(1);
} else if (iParameter.semantic == "TEXCOORD_0") { } else if (iParameter.semantic == "TEXCOORD_0") {
attribute.shaderLocation = 2; attribute.shaderLocation = 2;
attribute.inputSlot = 2; attribute.inputSlot = 2;
input.inputSlot = 2;
input.stride = static_cast<uint32_t>(strideTxc);
builder.SetAttribute(&attribute); builder.SetAttribute(&attribute);
builder.SetInput(2, static_cast<uint32_t>(strideTxc), dawn::InputStepMode::Vertex); builder.SetInput(&input);
slotsSet.set(2); slotsSet.set(2);
} else { } else {
fprintf(stderr, "unsupported technique attribute semantic %s\n", iParameter.semantic.c_str()); fprintf(stderr, "unsupported technique attribute semantic %s\n", iParameter.semantic.c_str());
@ -283,8 +292,13 @@ namespace {
attribute.inputSlot = i; attribute.inputSlot = i;
attribute.format = dawn::VertexFormat::FloatR32G32B32A32; attribute.format = dawn::VertexFormat::FloatR32G32B32A32;
dawn::VertexInputDescriptor input;
input.inputSlot = i;
input.stride = 0;
input.stepMode = dawn::InputStepMode::Vertex;
builder.SetAttribute(&attribute); builder.SetAttribute(&attribute);
builder.SetInput(i, 0, dawn::InputStepMode::Vertex); builder.SetInput(&input);
} }
auto inputState = builder.GetResult(); auto inputState = builder.GetResult();

View File

@ -147,22 +147,20 @@ namespace dawn_native {
info.format = attribute->format; info.format = attribute->format;
} }
void InputStateBuilder::SetInput(uint32_t bindingSlot, void InputStateBuilder::SetInput(const VertexInputDescriptor* input) {
uint32_t stride, if (input->inputSlot >= kMaxVertexInputs) {
dawn::InputStepMode stepMode) {
if (bindingSlot >= kMaxVertexInputs) {
HandleError("Setting input out of bounds"); HandleError("Setting input out of bounds");
return; return;
} }
if (mInputsSetMask[bindingSlot]) { if (mInputsSetMask[input->inputSlot]) {
HandleError("Setting already set input"); HandleError("Setting already set input");
return; return;
} }
mInputsSetMask.set(bindingSlot); mInputsSetMask.set(input->inputSlot);
auto& info = mInputInfos[bindingSlot]; auto& info = mInputInfos[input->inputSlot];
info.stride = stride; info.stride = input->stride;
info.stepMode = stepMode; info.stepMode = input->stepMode;
} }
} // namespace dawn_native } // namespace dawn_native

View File

@ -65,7 +65,7 @@ namespace dawn_native {
// Dawn API // Dawn API
void SetAttribute(const VertexAttributeDescriptor* attribute); void SetAttribute(const VertexAttributeDescriptor* attribute);
void SetInput(uint32_t bindingSlot, uint32_t stride, dawn::InputStepMode stepMode); void SetInput(const VertexInputDescriptor* input);
private: private:
friend class InputStateBase; friend class InputStateBase;

View File

@ -26,17 +26,21 @@ class DrawIndexedTest : public DawnTest {
renderPass = utils::CreateBasicRenderPass(device, kRTSize, kRTSize); 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; dawn::VertexAttributeDescriptor attribute;
attribute.shaderLocation = 0; attribute.shaderLocation = 0;
attribute.inputSlot = 0; attribute.inputSlot = 0;
attribute.offset = 0; attribute.offset = 0;
attribute.format = dawn::VertexFormat::FloatR32G32B32A32; attribute.format = dawn::VertexFormat::FloatR32G32B32A32;
dawn::InputState inputState = dawn::InputState inputState = device.CreateInputStateBuilder()
device.CreateInputStateBuilder() .SetInput(&input)
.SetInput(0, 4 * sizeof(float), dawn::InputStepMode::Vertex) .SetAttribute(&attribute)
.SetAttribute(&attribute) .GetResult();
.GetResult();
dawn::ShaderModule vsModule = utils::CreateShaderModule(device, dawn::ShaderStage::Vertex, R"( dawn::ShaderModule vsModule = utils::CreateShaderModule(device, dawn::ShaderStage::Vertex, R"(
#version 450 #version 450

View File

@ -26,6 +26,11 @@ class DrawTest : public DawnTest {
renderPass = utils::CreateBasicRenderPass(device, kRTSize, kRTSize); 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; dawn::VertexAttributeDescriptor attribute;
attribute.shaderLocation = 0; attribute.shaderLocation = 0;
attribute.inputSlot = 0; attribute.inputSlot = 0;
@ -33,10 +38,7 @@ class DrawTest : public DawnTest {
attribute.format = dawn::VertexFormat::FloatR32G32B32A32; attribute.format = dawn::VertexFormat::FloatR32G32B32A32;
dawn::InputState inputState = dawn::InputState inputState =
device.CreateInputStateBuilder() device.CreateInputStateBuilder().SetInput(&input).SetAttribute(&attribute).GetResult();
.SetInput(0, 4 * sizeof(float), dawn::InputStepMode::Vertex)
.SetAttribute(&attribute)
.GetResult();
dawn::ShaderModule vsModule = dawn::ShaderModule vsModule =
utils::CreateShaderModule(device, dawn::ShaderStage::Vertex, R"( utils::CreateShaderModule(device, dawn::ShaderStage::Vertex, R"(

View File

@ -31,17 +31,21 @@ class IndexFormatTest : public DawnTest {
utils::BasicRenderPass renderPass; utils::BasicRenderPass renderPass;
dawn::RenderPipeline MakeTestPipeline(dawn::IndexFormat format) { 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; dawn::VertexAttributeDescriptor attribute;
attribute.shaderLocation = 0; attribute.shaderLocation = 0;
attribute.inputSlot = 0; attribute.inputSlot = 0;
attribute.offset = 0; attribute.offset = 0;
attribute.format = dawn::VertexFormat::FloatR32G32B32A32; attribute.format = dawn::VertexFormat::FloatR32G32B32A32;
dawn::InputState inputState = dawn::InputState inputState = device.CreateInputStateBuilder()
device.CreateInputStateBuilder() .SetInput(&input)
.SetInput(0, 4 * sizeof(float), dawn::InputStepMode::Vertex) .SetAttribute(&attribute)
.SetAttribute(&attribute) .GetResult();
.GetResult();
dawn::ShaderModule vsModule = utils::CreateShaderModule(device, dawn::ShaderStage::Vertex, R"( dawn::ShaderModule vsModule = utils::CreateShaderModule(device, dawn::ShaderStage::Vertex, R"(
#version 450 #version 450

View File

@ -145,7 +145,11 @@ class InputStateTest : public DawnTest {
dawn::InputStateBuilder builder = device.CreateInputStateBuilder(); dawn::InputStateBuilder builder = device.CreateInputStateBuilder();
for (const auto& input : inputs) { for (const auto& input : inputs) {
builder.SetInput(input.slot, input.stride, input.step); dawn::VertexInputDescriptor descriptor;
descriptor.inputSlot = input.slot;
descriptor.stride = input.stride;
descriptor.stepMode = input.step;
builder.SetInput(&descriptor);
} }
for (const auto& attribute : attributes) { for (const auto& attribute : attributes) {

View File

@ -171,9 +171,14 @@ class PrimitiveTopologyTest : public DawnTest {
attribute.offset = 0; attribute.offset = 0;
attribute.format = dawn::VertexFormat::FloatR32G32B32A32; attribute.format = dawn::VertexFormat::FloatR32G32B32A32;
dawn::VertexInputDescriptor input;
input.inputSlot = 0;
input.stride = 4 * sizeof(float);
input.stepMode = dawn::InputStepMode::Vertex;
inputState = device.CreateInputStateBuilder() inputState = device.CreateInputStateBuilder()
.SetAttribute(&attribute) .SetAttribute(&attribute)
.SetInput(0, 4 * sizeof(float), dawn::InputStepMode::Vertex) .SetInput(&input)
.GetResult(); .GetResult();
vertexBuffer = utils::CreateBufferFromData(device, kVertices, sizeof(kVertices), dawn::BufferUsageBit::Vertex); vertexBuffer = utils::CreateBufferFromData(device, kVertices, sizeof(kVertices), dawn::BufferUsageBit::Vertex);

View File

@ -17,6 +17,12 @@
#include "utils/ComboRenderPipelineDescriptor.h" #include "utils/ComboRenderPipelineDescriptor.h"
#include "utils/DawnHelpers.h" #include "utils/DawnHelpers.h"
constexpr static dawn::VertexInputDescriptor kBaseInput = {
0, // inputSlot
0, // stride
dawn::InputStepMode::Vertex, // stepMode
};
class InputStateTest : public ValidationTest { class InputStateTest : public ValidationTest {
protected: protected:
void CreatePipeline(bool success, const dawn::InputState& inputState, std::string vertexSource) { void CreatePipeline(bool success, const dawn::InputState& inputState, std::string vertexSource) {
@ -70,8 +76,13 @@ TEST_F(InputStateTest, PipelineCompatibility) {
attribute2.offset = sizeof(float); attribute2.offset = sizeof(float);
attribute2.format = dawn::VertexFormat::FloatR32; attribute2.format = dawn::VertexFormat::FloatR32;
dawn::VertexInputDescriptor input;
input.inputSlot = 0;
input.stride = 2 * sizeof(float);
input.stepMode = dawn::InputStepMode::Vertex;
dawn::InputState state = AssertWillBeSuccess(device.CreateInputStateBuilder()) dawn::InputState state = AssertWillBeSuccess(device.CreateInputStateBuilder())
.SetInput(0, 2 * sizeof(float), dawn::InputStepMode::Vertex) .SetInput(&input)
.SetAttribute(&attribute1) .SetAttribute(&attribute1)
.SetAttribute(&attribute2) .SetAttribute(&attribute2)
.GetResult(); .GetResult();
@ -108,9 +119,7 @@ TEST_F(InputStateTest, PipelineCompatibility) {
// Test that a stride of 0 is valid // Test that a stride of 0 is valid
TEST_F(InputStateTest, StrideZero) { TEST_F(InputStateTest, StrideZero) {
// Works ok without attributes // Works ok without attributes
AssertWillBeSuccess(device.CreateInputStateBuilder()) AssertWillBeSuccess(device.CreateInputStateBuilder()).SetInput(&kBaseInput).GetResult();
.SetInput(0, 0, dawn::InputStepMode::Vertex)
.GetResult();
// Works ok with attributes at a large-ish offset // Works ok with attributes at a large-ish offset
dawn::VertexAttributeDescriptor attribute; dawn::VertexAttributeDescriptor attribute;
@ -120,7 +129,7 @@ TEST_F(InputStateTest, StrideZero) {
attribute.format = dawn::VertexFormat::FloatR32; attribute.format = dawn::VertexFormat::FloatR32;
AssertWillBeSuccess(device.CreateInputStateBuilder()) AssertWillBeSuccess(device.CreateInputStateBuilder())
.SetInput(0, 0, dawn::InputStepMode::Vertex) .SetInput(&kBaseInput)
.SetAttribute(&attribute) .SetAttribute(&attribute)
.GetResult(); .GetResult();
} }
@ -128,28 +137,28 @@ TEST_F(InputStateTest, StrideZero) {
// Test that we cannot set an already set input // Test that we cannot set an already set input
TEST_F(InputStateTest, AlreadySetInput) { TEST_F(InputStateTest, AlreadySetInput) {
// Control case // Control case
AssertWillBeSuccess(device.CreateInputStateBuilder()) AssertWillBeSuccess(device.CreateInputStateBuilder()).SetInput(&kBaseInput).GetResult();
.SetInput(0, 0, dawn::InputStepMode::Vertex)
.GetResult();
// Oh no, input 0 is set twice // Oh no, input 0 is set twice
AssertWillBeError(device.CreateInputStateBuilder()) AssertWillBeError(device.CreateInputStateBuilder())
.SetInput(0, 0, dawn::InputStepMode::Vertex) .SetInput(&kBaseInput)
.SetInput(0, 0, dawn::InputStepMode::Vertex) .SetInput(&kBaseInput)
.GetResult(); .GetResult();
} }
// Check out of bounds condition on SetInput // Check out of bounds condition on SetInput
TEST_F(InputStateTest, SetInputOutOfBounds) { TEST_F(InputStateTest, SetInputOutOfBounds) {
// Control case, setting last input // Control case, setting last input
AssertWillBeSuccess(device.CreateInputStateBuilder()) dawn::VertexInputDescriptor input;
.SetInput(kMaxVertexInputs - 1, 0, dawn::InputStepMode::Vertex) input.inputSlot = kMaxVertexInputs - 1;
.GetResult(); input.stride = 0;
input.stepMode = dawn::InputStepMode::Vertex;
AssertWillBeSuccess(device.CreateInputStateBuilder()).SetInput(&input).GetResult();
// Test OOB // Test OOB
AssertWillBeError(device.CreateInputStateBuilder()) input.inputSlot = kMaxVertexInputs;
.SetInput(kMaxVertexInputs, 0, dawn::InputStepMode::Vertex) AssertWillBeError(device.CreateInputStateBuilder()).SetInput(&input).GetResult();
.GetResult();
} }
// Test that we cannot set an already set attribute // Test that we cannot set an already set attribute
@ -162,13 +171,13 @@ TEST_F(InputStateTest, AlreadySetAttribute) {
attribute.format = dawn::VertexFormat::FloatR32; attribute.format = dawn::VertexFormat::FloatR32;
AssertWillBeSuccess(device.CreateInputStateBuilder()) AssertWillBeSuccess(device.CreateInputStateBuilder())
.SetInput(0, 0, dawn::InputStepMode::Vertex) .SetInput(&kBaseInput)
.SetAttribute(&attribute) .SetAttribute(&attribute)
.GetResult(); .GetResult();
// Oh no, attribute 0 is set twice // Oh no, attribute 0 is set twice
AssertWillBeError(device.CreateInputStateBuilder()) AssertWillBeError(device.CreateInputStateBuilder())
.SetInput(0, 0, dawn::InputStepMode::Vertex) .SetInput(&kBaseInput)
.SetAttribute(&attribute) .SetAttribute(&attribute)
.SetAttribute(&attribute) .SetAttribute(&attribute)
.GetResult(); .GetResult();
@ -184,14 +193,14 @@ TEST_F(InputStateTest, SetAttributeOutOfBounds) {
attribute.format = dawn::VertexFormat::FloatR32; attribute.format = dawn::VertexFormat::FloatR32;
AssertWillBeSuccess(device.CreateInputStateBuilder()) AssertWillBeSuccess(device.CreateInputStateBuilder())
.SetInput(0, 0, dawn::InputStepMode::Vertex) .SetInput(&kBaseInput)
.SetAttribute(&attribute) .SetAttribute(&attribute)
.GetResult(); .GetResult();
// Test OOB // Test OOB
attribute.shaderLocation = kMaxVertexAttributes; attribute.shaderLocation = kMaxVertexAttributes;
AssertWillBeError(device.CreateInputStateBuilder()) AssertWillBeError(device.CreateInputStateBuilder())
.SetInput(0, 0, dawn::InputStepMode::Vertex) .SetInput(&kBaseInput)
.SetAttribute(&attribute) .SetAttribute(&attribute)
.GetResult(); .GetResult();
} }
@ -206,14 +215,14 @@ TEST_F(InputStateTest, RequireInputForAttribute) {
attribute.format = dawn::VertexFormat::FloatR32; attribute.format = dawn::VertexFormat::FloatR32;
AssertWillBeSuccess(device.CreateInputStateBuilder()) AssertWillBeSuccess(device.CreateInputStateBuilder())
.SetInput(0, 0, dawn::InputStepMode::Vertex) .SetInput(&kBaseInput)
.SetAttribute(&attribute) .SetAttribute(&attribute)
.GetResult(); .GetResult();
// Attribute 0 uses input 1 which doesn't exist // Attribute 0 uses input 1 which doesn't exist
attribute.inputSlot = 1; attribute.inputSlot = 1;
AssertWillBeError(device.CreateInputStateBuilder()) AssertWillBeError(device.CreateInputStateBuilder())
.SetInput(0, 0, dawn::InputStepMode::Vertex) .SetInput(&kBaseInput)
.SetAttribute(&attribute) .SetAttribute(&attribute)
.GetResult(); .GetResult();
} }
@ -228,14 +237,14 @@ TEST_F(InputStateTest, SetAttributeOOBCheckForInputs) {
attribute.format = dawn::VertexFormat::FloatR32; attribute.format = dawn::VertexFormat::FloatR32;
AssertWillBeSuccess(device.CreateInputStateBuilder()) AssertWillBeSuccess(device.CreateInputStateBuilder())
.SetInput(0, 0, dawn::InputStepMode::Vertex) .SetInput(&kBaseInput)
.SetAttribute(&attribute) .SetAttribute(&attribute)
.GetResult(); .GetResult();
// Could crash if we didn't check for OOB // Could crash if we didn't check for OOB
attribute.inputSlot = 1000000; attribute.inputSlot = 1000000;
AssertWillBeError(device.CreateInputStateBuilder()) AssertWillBeError(device.CreateInputStateBuilder())
.SetInput(0, 0, dawn::InputStepMode::Vertex) .SetInput(&kBaseInput)
.SetAttribute(&attribute) .SetAttribute(&attribute)
.GetResult(); .GetResult();
} }

View File

@ -75,11 +75,16 @@ class VertexBufferValidationTest : public ValidationTest {
attribute.offset = 0; attribute.offset = 0;
attribute.format = dawn::VertexFormat::FloatR32G32B32; attribute.format = dawn::VertexFormat::FloatR32G32B32;
dawn::VertexInputDescriptor input;
input.stride = 0;
input.stepMode = dawn::InputStepMode::Vertex;
for (unsigned int i = 0; i < numInputs; ++i) { for (unsigned int i = 0; i < numInputs; ++i) {
attribute.shaderLocation = i; attribute.shaderLocation = i;
attribute.inputSlot = i; attribute.inputSlot = i;
input.inputSlot = i;
builder.SetAttribute(&attribute); builder.SetAttribute(&attribute);
builder.SetInput(i, 0, dawn::InputStepMode::Vertex); builder.SetInput(&input);
} }
return builder.GetResult(); return builder.GetResult();
} }