Update VertexInput (InputState) to match spec - Part 1
This is only a renaming: change VertexInput to VertexBuffer, and
change InputState to VertexInput.
The next two patches will do as follows:
1) change the structure of vertex input descriptor related stuff.
2) change num to count.
BUG=dawn:80, dawn:107
Change-Id: Ie76aa653a527759a9c3b4a4792e3254689f053b8
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/7420
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
Commit-Queue: Yunchao He <yunchao.he@intel.com>
diff --git a/BUILD.gn b/BUILD.gn
index 0110ac5..2ae8d92 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -573,7 +573,6 @@
"src/tests/unittests/validation/DebugMarkerValidationTests.cpp",
"src/tests/unittests/validation/DynamicStateCommandValidationTests.cpp",
"src/tests/unittests/validation/FenceValidationTests.cpp",
- "src/tests/unittests/validation/InputStateValidationTests.cpp",
"src/tests/unittests/validation/PushConstantsValidationTests.cpp",
"src/tests/unittests/validation/QueueSubmitValidationTests.cpp",
"src/tests/unittests/validation/RenderPassDescriptorValidationTests.cpp",
@@ -587,6 +586,7 @@
"src/tests/unittests/validation/ValidationTest.cpp",
"src/tests/unittests/validation/ValidationTest.h",
"src/tests/unittests/validation/VertexBufferValidationTests.cpp",
+ "src/tests/unittests/validation/VertexInputValidationTests.cpp",
"src/tests/unittests/wire/WireArgumentTests.cpp",
"src/tests/unittests/wire/WireBasicTests.cpp",
"src/tests/unittests/wire/WireBufferMappingTests.cpp",
@@ -642,7 +642,6 @@
"src/tests/end2end/DrawTests.cpp",
"src/tests/end2end/FenceTests.cpp",
"src/tests/end2end/IndexFormatTests.cpp",
- "src/tests/end2end/InputStateTests.cpp",
"src/tests/end2end/MultisampledRenderingTests.cpp",
"src/tests/end2end/NonzeroTextureCreationTests.cpp",
"src/tests/end2end/ObjectCachingTests.cpp",
@@ -654,6 +653,7 @@
"src/tests/end2end/ScissorTests.cpp",
"src/tests/end2end/TextureViewTests.cpp",
"src/tests/end2end/VertexFormatTests.cpp",
+ "src/tests/end2end/VertexInputTests.cpp",
"src/tests/end2end/ViewportOrientationTests.cpp",
]
diff --git a/dawn.json b/dawn.json
index b7a18ce..45bed41 100644
--- a/dawn.json
+++ b/dawn.json
@@ -597,7 +597,7 @@
{"name": "format", "type": "vertex format"}
]
},
- "vertex input descriptor": {
+ "vertex buffer descriptor": {
"category": "structure",
"extensible": false,
"members": [
@@ -606,15 +606,15 @@
{"name": "step mode", "type": "input step mode"}
]
},
- "input state descriptor": {
+ "vertex input descriptor": {
"category": "structure",
"extensible": true,
"members": [
{"name": "index format", "type": "index format"},
{"name": "num attributes", "type": "uint32_t"},
{"name": "attributes", "type": "vertex attribute descriptor", "annotation": "const*", "length": "num attributes"},
- {"name": "num inputs", "type": "uint32_t"},
- {"name": "inputs", "type": "vertex input descriptor", "annotation": "const*", "length": "num inputs"}
+ {"name": "num buffers", "type": "uint32_t"},
+ {"name": "buffers", "type": "vertex buffer descriptor", "annotation": "const*", "length": "num buffers"}
]
},
"input step mode": {
@@ -864,7 +864,7 @@
{"name": "layout", "type": "pipeline layout"},
{"name": "vertex stage", "type": "pipeline stage descriptor", "annotation": "const*"},
{"name": "fragment stage", "type": "pipeline stage descriptor", "annotation": "const*"},
- {"name": "input state", "type": "input state descriptor", "annotation": "const*"},
+ {"name": "vertex input", "type": "vertex input descriptor", "annotation": "const*"},
{"name": "primitive topology", "type": "primitive topology"},
{"name": "rasterization state", "type": "rasterization state descriptor", "annotation": "const*"},
{"name": "sample count", "type": "uint32_t"},
diff --git a/examples/CHelloTriangle.cpp b/examples/CHelloTriangle.cpp
index 5a5d8bb..d487253 100644
--- a/examples/CHelloTriangle.cpp
+++ b/examples/CHelloTriangle.cpp
@@ -93,14 +93,14 @@
pl.bindGroupLayouts = nullptr;
descriptor.layout = dawnDeviceCreatePipelineLayout(device, &pl);
- DawnInputStateDescriptor inputState;
- inputState.nextInChain = nullptr;
- inputState.indexFormat = DAWN_INDEX_FORMAT_UINT32;
- inputState.numInputs = 0;
- inputState.inputs = nullptr;
- inputState.numAttributes = 0;
- inputState.attributes = nullptr;
- descriptor.inputState = &inputState;
+ DawnVertexInputDescriptor vertexInput;
+ vertexInput.nextInChain = nullptr;
+ vertexInput.indexFormat = DAWN_INDEX_FORMAT_UINT32;
+ vertexInput.numBuffers = 0;
+ vertexInput.buffers = nullptr;
+ vertexInput.numAttributes = 0;
+ vertexInput.attributes = nullptr;
+ descriptor.vertexInput = &vertexInput;
DawnRasterizationStateDescriptor rasterizationState;
rasterizationState.nextInChain = nullptr;
diff --git a/examples/ComputeBoids.cpp b/examples/ComputeBoids.cpp
index ae4234c..beeffa4 100644
--- a/examples/ComputeBoids.cpp
+++ b/examples/ComputeBoids.cpp
@@ -120,20 +120,20 @@
descriptor.cVertexStage.module = vsModule;
descriptor.cFragmentStage.module = fsModule;
- descriptor.cInputState.numAttributes = 3;
- 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.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.cVertexInput.numAttributes = 3;
+ descriptor.cVertexInput.cAttributes[0].offset = offsetof(Particle, pos);
+ descriptor.cVertexInput.cAttributes[0].format = dawn::VertexFormat::Float2;
+ descriptor.cVertexInput.cAttributes[1].shaderLocation = 1;
+ descriptor.cVertexInput.cAttributes[1].offset = offsetof(Particle, vel);
+ descriptor.cVertexInput.cAttributes[1].format = dawn::VertexFormat::Float2;
+ descriptor.cVertexInput.cAttributes[2].shaderLocation = 2;
+ descriptor.cVertexInput.cAttributes[2].inputSlot = 1;
+ descriptor.cVertexInput.cAttributes[2].format = dawn::VertexFormat::Float2;
+ descriptor.cVertexInput.numBuffers = 2;
+ descriptor.cVertexInput.cBuffers[0].stride = sizeof(Particle);
+ descriptor.cVertexInput.cBuffers[0].stepMode = dawn::InputStepMode::Instance;
+ descriptor.cVertexInput.cBuffers[1].inputSlot = 1;
+ descriptor.cVertexInput.cBuffers[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 b560d79..a23b3e4 100644
--- a/examples/CppHelloTriangle.cpp
+++ b/examples/CppHelloTriangle.cpp
@@ -125,10 +125,10 @@
descriptor.layout = utils::MakeBasicPipelineLayout(device, &bgl);
descriptor.cVertexStage.module = vsModule;
descriptor.cFragmentStage.module = fsModule;
- descriptor.cInputState.numAttributes = 1;
- descriptor.cInputState.cAttributes[0].format = dawn::VertexFormat::Float4;
- descriptor.cInputState.numInputs = 1;
- descriptor.cInputState.cInputs[0].stride = 4 * sizeof(float);
+ descriptor.cVertexInput.numAttributes = 1;
+ descriptor.cVertexInput.cAttributes[0].format = dawn::VertexFormat::Float4;
+ descriptor.cVertexInput.numBuffers = 1;
+ descriptor.cVertexInput.cBuffers[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 56263d4..a848938 100644
--- a/examples/CubeReflection.cpp
+++ b/examples/CubeReflection.cpp
@@ -156,15 +156,15 @@
fragColor = vec4(mix(f_col, vec3(0.5, 0.5, 0.5), 0.5), 1.0);
})");
- utils::ComboInputStateDescriptor inputState;
- inputState.numAttributes = 2;
- 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;
+ utils::ComboVertexInputDescriptor vertexInput;
+ vertexInput.numAttributes = 2;
+ vertexInput.cAttributes[0].format = dawn::VertexFormat::Float3;
+ vertexInput.cAttributes[1].shaderLocation = 1;
+ vertexInput.cAttributes[1].offset = 3 * sizeof(float);
+ vertexInput.cAttributes[1].format = dawn::VertexFormat::Float3;
- inputState.numInputs = 1;
- inputState.cInputs[0].stride = 6 * sizeof(float);
+ vertexInput.numBuffers = 1;
+ vertexInput.cBuffers[0].stride = 6 * sizeof(float);
auto bgl = utils::MakeBindGroupLayout(
device, {
@@ -201,7 +201,7 @@
descriptor.layout = pl;
descriptor.cVertexStage.module = vsModule;
descriptor.cFragmentStage.module = fsModule;
- descriptor.inputState = &inputState;
+ descriptor.vertexInput = &vertexInput;
descriptor.depthStencilState = &descriptor.cDepthStencilState;
descriptor.cDepthStencilState.format = dawn::TextureFormat::D32FloatS8Uint;
descriptor.cColorStates[0]->format = GetPreferredSwapChainTextureFormat();
@@ -214,7 +214,7 @@
pDescriptor.layout = pl;
pDescriptor.cVertexStage.module = vsModule;
pDescriptor.cFragmentStage.module = fsModule;
- pDescriptor.inputState = &inputState;
+ pDescriptor.vertexInput = &vertexInput;
pDescriptor.depthStencilState = &pDescriptor.cDepthStencilState;
pDescriptor.cDepthStencilState.format = dawn::TextureFormat::D32FloatS8Uint;
pDescriptor.cColorStates[0]->format = GetPreferredSwapChainTextureFormat();
@@ -228,7 +228,7 @@
rfDescriptor.layout = pl;
rfDescriptor.cVertexStage.module = vsModule;
rfDescriptor.cFragmentStage.module = fsReflectionModule;
- rfDescriptor.inputState = &inputState;
+ rfDescriptor.vertexInput = &vertexInput;
rfDescriptor.depthStencilState = &rfDescriptor.cDepthStencilState;
rfDescriptor.cDepthStencilState.format = dawn::TextureFormat::D32FloatS8Uint;
rfDescriptor.cColorStates[0]->format = GetPreferredSwapChainTextureFormat();
diff --git a/src/common/Constants.h b/src/common/Constants.h
index 0a41dff..aa04501 100644
--- a/src/common/Constants.h
+++ b/src/common/Constants.h
@@ -24,12 +24,13 @@
static constexpr uint32_t kMaxVertexAttributes = 16u;
// Vulkan has a standalone limit named maxVertexInputAttributeOffset (2047u at least) for vertex
// attribute offset. The limit might be meaningless because Vulkan has another limit named
-// maxVertexInputBindingStride (2048u at least). We use maxVertexAttributeEnd (2048u) here to verify
-// vertex attribute offset, which equals to maxOffset + smallest size of vertex format (char). We
-// may use maxVertexInputStride instead in future.
+// maxVertexInputBindingStride (2048u at least). We use maxVertexAttributeEnd (2048u) here to
+// verify vertex attribute offset, which equals to maxOffset + smallest size of vertex format
+// (char). We may use maxVertexInputBindingStride (maxVertexBufferStride below) instead to replace
+// maxVertexAttributeEnd in future.
static constexpr uint32_t kMaxVertexAttributeEnd = 2048u;
-static constexpr uint32_t kMaxVertexInputs = 16u;
-static constexpr uint32_t kMaxVertexInputStride = 2048u;
+static constexpr uint32_t kMaxVertexBuffers = 16u;
+static constexpr uint32_t kMaxVertexBufferStride = 2048u;
static constexpr uint32_t kNumStages = 3;
static constexpr uint32_t kMaxColorAttachments = 4u;
static constexpr uint32_t kTextureRowPitchAlignment = 256u;
diff --git a/src/dawn_native/CommandBufferStateTracker.h b/src/dawn_native/CommandBufferStateTracker.h
index f2580e4..2009dd7 100644
--- a/src/dawn_native/CommandBufferStateTracker.h
+++ b/src/dawn_native/CommandBufferStateTracker.h
@@ -53,7 +53,7 @@
ValidationAspects mAspects;
std::array<BindGroupBase*, kMaxBindGroups> mBindgroups = {};
- std::bitset<kMaxVertexInputs> mInputsSet;
+ std::bitset<kMaxVertexBuffers> mInputsSet;
PipelineLayoutBase* mLastPipelineLayout = nullptr;
RenderPipelineBase* mLastRenderPipeline = nullptr;
diff --git a/src/dawn_native/RenderPipeline.cpp b/src/dawn_native/RenderPipeline.cpp
index e44d287..699c992 100644
--- a/src/dawn_native/RenderPipeline.cpp
+++ b/src/dawn_native/RenderPipeline.cpp
@@ -25,33 +25,33 @@
// Helper functions
namespace {
- MaybeError ValidateVertexInputDescriptor(const VertexInputDescriptor* input,
- std::bitset<kMaxVertexInputs>* inputsSetMask) {
- DAWN_TRY(ValidateInputStepMode(input->stepMode));
- if (input->inputSlot >= kMaxVertexInputs) {
- return DAWN_VALIDATION_ERROR("Setting input out of bounds");
+ MaybeError ValidateVertexBufferDescriptor(const VertexBufferDescriptor* buffer,
+ std::bitset<kMaxVertexBuffers>* inputsSetMask) {
+ DAWN_TRY(ValidateInputStepMode(buffer->stepMode));
+ if (buffer->inputSlot >= kMaxVertexBuffers) {
+ return DAWN_VALIDATION_ERROR("Setting vertex buffer out of bounds");
}
- if (input->stride > kMaxVertexInputStride) {
+ if (buffer->stride > kMaxVertexBufferStride) {
return DAWN_VALIDATION_ERROR("Setting input stride out of bounds");
}
- if ((*inputsSetMask)[input->inputSlot]) {
- return DAWN_VALIDATION_ERROR("Setting already set input");
+ if ((*inputsSetMask)[buffer->inputSlot]) {
+ return DAWN_VALIDATION_ERROR("Setting already set vertex buffer");
}
- inputsSetMask->set(input->inputSlot);
+ inputsSetMask->set(buffer->inputSlot);
return {};
}
MaybeError ValidateVertexAttributeDescriptor(
const VertexAttributeDescriptor* attribute,
- const std::bitset<kMaxVertexInputs>* inputsSetMask,
+ const std::bitset<kMaxVertexBuffers>* inputsSetMask,
std::bitset<kMaxVertexAttributes>* attributesSetMask) {
DAWN_TRY(ValidateVertexFormat(attribute->format));
if (attribute->shaderLocation >= kMaxVertexAttributes) {
return DAWN_VALIDATION_ERROR("Setting attribute out of bounds");
}
- if (attribute->inputSlot >= kMaxVertexInputs) {
+ if (attribute->inputSlot >= kMaxVertexBuffers) {
return DAWN_VALIDATION_ERROR("Binding slot out of bounds");
}
ASSERT(kMaxVertexAttributeEnd >= VertexFormatSize(attribute->format));
@@ -70,24 +70,24 @@
return {};
}
- MaybeError ValidateInputStateDescriptor(
- const InputStateDescriptor* descriptor,
- std::bitset<kMaxVertexInputs>* inputsSetMask,
+ MaybeError ValidateVertexInputDescriptor(
+ const VertexInputDescriptor* descriptor,
+ std::bitset<kMaxVertexBuffers>* inputsSetMask,
std::bitset<kMaxVertexAttributes>* attributesSetMask) {
if (descriptor->nextInChain != nullptr) {
return DAWN_VALIDATION_ERROR("nextInChain must be nullptr");
}
DAWN_TRY(ValidateIndexFormat(descriptor->indexFormat));
- if (descriptor->numInputs > kMaxVertexInputs) {
+ if (descriptor->numBuffers > kMaxVertexBuffers) {
return DAWN_VALIDATION_ERROR("Vertex Inputs number exceeds maximum");
}
if (descriptor->numAttributes > kMaxVertexAttributes) {
return DAWN_VALIDATION_ERROR("Vertex Attributes number exceeds maximum");
}
- for (uint32_t i = 0; i < descriptor->numInputs; ++i) {
- DAWN_TRY(ValidateVertexInputDescriptor(&descriptor->inputs[i], inputsSetMask));
+ for (uint32_t i = 0; i < descriptor->numBuffers; ++i) {
+ DAWN_TRY(ValidateVertexBufferDescriptor(&descriptor->buffers[i], inputsSetMask));
}
for (uint32_t i = 0; i < descriptor->numAttributes; ++i) {
@@ -262,14 +262,14 @@
DAWN_TRY(device->ValidateObject(descriptor->layout));
- if (descriptor->inputState == nullptr) {
+ if (descriptor->vertexInput == nullptr) {
return DAWN_VALIDATION_ERROR("Input state must not be null");
}
- std::bitset<kMaxVertexInputs> inputsSetMask;
+ std::bitset<kMaxVertexBuffers> inputsSetMask;
std::bitset<kMaxVertexAttributes> attributesSetMask;
- DAWN_TRY(ValidateInputStateDescriptor(descriptor->inputState, &inputsSetMask,
- &attributesSetMask));
+ DAWN_TRY(ValidateVertexInputDescriptor(descriptor->vertexInput, &inputsSetMask,
+ &attributesSetMask));
DAWN_TRY(ValidatePrimitiveTopology(descriptor->primitiveTopology));
DAWN_TRY(ValidatePipelineStageDescriptor(device, descriptor->vertexStage,
descriptor->layout, dawn::ShaderStage::Vertex));
@@ -334,7 +334,7 @@
: PipelineBase(device,
descriptor->layout,
dawn::ShaderStageBit::Vertex | dawn::ShaderStageBit::Fragment),
- mInputState(*descriptor->inputState),
+ mVertexInput(*descriptor->vertexInput),
mHasDepthStencilAttachment(descriptor->depthStencilState != nullptr),
mPrimitiveTopology(descriptor->primitiveTopology),
mRasterizationState(*descriptor->rasterizationState),
@@ -345,16 +345,16 @@
mFragmentEntryPoint(descriptor->fragmentStage->entryPoint),
mIsBlueprint(blueprint) {
uint32_t location = 0;
- for (uint32_t i = 0; i < mInputState.numAttributes; ++i) {
- location = mInputState.attributes[i].shaderLocation;
+ for (uint32_t i = 0; i < mVertexInput.numAttributes; ++i) {
+ location = mVertexInput.attributes[i].shaderLocation;
mAttributesSetMask.set(location);
- mAttributeInfos[location] = mInputState.attributes[i];
+ mAttributeInfos[location] = mVertexInput.attributes[i];
}
uint32_t slot = 0;
- for (uint32_t i = 0; i < mInputState.numInputs; ++i) {
- slot = mInputState.inputs[i].inputSlot;
+ for (uint32_t i = 0; i < mVertexInput.numBuffers; ++i) {
+ slot = mVertexInput.buffers[i].inputSlot;
mInputsSetMask.set(slot);
- mInputInfos[slot] = mInputState.inputs[i];
+ mInputInfos[slot] = mVertexInput.buffers[i];
}
if (mHasDepthStencilAttachment) {
@@ -405,9 +405,9 @@
}
}
- const InputStateDescriptor* RenderPipelineBase::GetInputStateDescriptor() const {
+ const VertexInputDescriptor* RenderPipelineBase::GetVertexInputDescriptor() const {
ASSERT(!IsError());
- return &mInputState;
+ return &mVertexInput;
}
const std::bitset<kMaxVertexAttributes>& RenderPipelineBase::GetAttributesSetMask() const {
@@ -421,12 +421,12 @@
return mAttributeInfos[location];
}
- const std::bitset<kMaxVertexInputs>& RenderPipelineBase::GetInputsSetMask() const {
+ const std::bitset<kMaxVertexBuffers>& RenderPipelineBase::GetInputsSetMask() const {
ASSERT(!IsError());
return mInputsSetMask;
}
- const VertexInputDescriptor& RenderPipelineBase::GetInput(uint32_t slot) const {
+ const VertexBufferDescriptor& RenderPipelineBase::GetInput(uint32_t slot) const {
ASSERT(!IsError());
ASSERT(mInputsSetMask[slot]);
return mInputInfos[slot];
@@ -561,11 +561,11 @@
HashCombine(&hash, pipeline->mInputsSetMask);
for (uint32_t i : IterateBitSet(pipeline->mInputsSetMask)) {
- const VertexInputDescriptor& desc = pipeline->GetInput(i);
+ const VertexBufferDescriptor& desc = pipeline->GetInput(i);
HashCombine(&hash, desc.inputSlot, desc.stride, desc.stepMode);
}
- HashCombine(&hash, pipeline->mInputState.indexFormat);
+ HashCombine(&hash, pipeline->mVertexInput.indexFormat);
// Hash rasterization state
{
@@ -660,15 +660,15 @@
}
for (uint32_t i : IterateBitSet(a->mInputsSetMask)) {
- const VertexInputDescriptor& descA = a->GetInput(i);
- const VertexInputDescriptor& descB = b->GetInput(i);
+ const VertexBufferDescriptor& descA = a->GetInput(i);
+ const VertexBufferDescriptor& descB = b->GetInput(i);
if (descA.inputSlot != descB.inputSlot || descA.stride != descB.stride ||
descA.stepMode != descB.stepMode) {
return false;
}
}
- if (a->mInputState.indexFormat != b->mInputState.indexFormat) {
+ if (a->mVertexInput.indexFormat != b->mVertexInput.indexFormat) {
return false;
}
diff --git a/src/dawn_native/RenderPipeline.h b/src/dawn_native/RenderPipeline.h
index 98fc1ad..df4bf58 100644
--- a/src/dawn_native/RenderPipeline.h
+++ b/src/dawn_native/RenderPipeline.h
@@ -47,11 +47,11 @@
static RenderPipelineBase* MakeError(DeviceBase* device);
- const InputStateDescriptor* GetInputStateDescriptor() const;
+ const VertexInputDescriptor* GetVertexInputDescriptor() const;
const std::bitset<kMaxVertexAttributes>& GetAttributesSetMask() const;
const VertexAttributeDescriptor& GetAttribute(uint32_t location) const;
- const std::bitset<kMaxVertexInputs>& GetInputsSetMask() const;
- const VertexInputDescriptor& GetInput(uint32_t slot) const;
+ const std::bitset<kMaxVertexBuffers>& GetInputsSetMask() const;
+ const VertexBufferDescriptor& GetInput(uint32_t slot) const;
const ColorStateDescriptor* GetColorStateDescriptor(uint32_t attachmentSlot) const;
const DepthStencilStateDescriptor* GetDepthStencilStateDescriptor() const;
@@ -69,7 +69,7 @@
// attachments in the render pass. This returns whether it is the case.
bool IsCompatibleWith(const BeginRenderPassCmd* renderPassCmd) const;
std::bitset<kMaxVertexAttributes> GetAttributesUsingInput(uint32_t slot) const;
- std::array<std::bitset<kMaxVertexAttributes>, kMaxVertexInputs> attributesUsingInput;
+ std::array<std::bitset<kMaxVertexAttributes>, kMaxVertexBuffers> attributesUsingInput;
// Functors necessary for the unordered_set<RenderPipelineBase*>-based cache.
struct HashFunc {
@@ -83,11 +83,11 @@
RenderPipelineBase(DeviceBase* device, ObjectBase::ErrorTag tag);
// Vertex input
- InputStateDescriptor mInputState;
+ VertexInputDescriptor mVertexInput;
std::bitset<kMaxVertexAttributes> mAttributesSetMask;
std::array<VertexAttributeDescriptor, kMaxVertexAttributes> mAttributeInfos;
- std::bitset<kMaxVertexInputs> mInputsSetMask;
- std::array<VertexInputDescriptor, kMaxVertexInputs> mInputInfos;
+ std::bitset<kMaxVertexBuffers> mInputsSetMask;
+ std::array<VertexBufferDescriptor, kMaxVertexBuffers> mInputInfos;
// Attachments
bool mHasDepthStencilAttachment = false;
diff --git a/src/dawn_native/d3d12/CommandBufferD3D12.cpp b/src/dawn_native/d3d12/CommandBufferD3D12.cpp
index 18e6d1c..d9c7d52 100644
--- a/src/dawn_native/d3d12/CommandBufferD3D12.cpp
+++ b/src/dawn_native/d3d12/CommandBufferD3D12.cpp
@@ -653,7 +653,7 @@
commandList->IASetVertexBuffers(startSlot, count,
&vertexBuffersInfo->d3d12BufferViews[startSlot]);
- vertexBuffersInfo->startSlot = kMaxVertexInputs;
+ vertexBuffersInfo->startSlot = kMaxVertexBuffers;
vertexBuffersInfo->endSlot = 0;
}
@@ -893,7 +893,7 @@
// this will break if the pipeline is changed for one with a different index
// format after SetIndexBuffer
bufferView.Format =
- DXGIIndexFormat(lastPipeline->GetInputStateDescriptor()->indexFormat);
+ DXGIIndexFormat(lastPipeline->GetVertexInputDescriptor()->indexFormat);
commandList->IASetIndexBuffer(&bufferView);
} break;
diff --git a/src/dawn_native/d3d12/CommandBufferD3D12.h b/src/dawn_native/d3d12/CommandBufferD3D12.h
index 694f98c..ed50885 100644
--- a/src/dawn_native/d3d12/CommandBufferD3D12.h
+++ b/src/dawn_native/d3d12/CommandBufferD3D12.h
@@ -41,9 +41,9 @@
// represent the union of the dirty ranges (the union may have non-dirty
// data in the middle of the range).
const RenderPipeline* lastRenderPipeline = nullptr;
- uint32_t startSlot = kMaxVertexInputs;
+ uint32_t startSlot = kMaxVertexBuffers;
uint32_t endSlot = 0;
- std::array<D3D12_VERTEX_BUFFER_VIEW, kMaxVertexInputs> d3d12BufferViews = {};
+ std::array<D3D12_VERTEX_BUFFER_VIEW, kMaxVertexBuffers> d3d12BufferViews = {};
};
class CommandBuffer : public CommandBufferBase {
diff --git a/src/dawn_native/d3d12/RenderPipelineD3D12.cpp b/src/dawn_native/d3d12/RenderPipelineD3D12.cpp
index 5df00b1..c8b11ea 100644
--- a/src/dawn_native/d3d12/RenderPipelineD3D12.cpp
+++ b/src/dawn_native/d3d12/RenderPipelineD3D12.cpp
@@ -409,7 +409,7 @@
inputElementDescriptor.Format = VertexFormatType(attribute.format);
inputElementDescriptor.InputSlot = attribute.inputSlot;
- const VertexInputDescriptor& input = GetInput(attribute.inputSlot);
+ const VertexBufferDescriptor& input = GetInput(attribute.inputSlot);
inputElementDescriptor.AlignedByteOffset = attribute.offset;
inputElementDescriptor.InputSlotClass = InputStepModeFunction(input.stepMode);
diff --git a/src/dawn_native/metal/CommandBufferMTL.mm b/src/dawn_native/metal/CommandBufferMTL.mm
index d44740e..1c30164 100644
--- a/src/dawn_native/metal/CommandBufferMTL.mm
+++ b/src/dawn_native/metal/CommandBufferMTL.mm
@@ -804,7 +804,7 @@
case Command::DrawIndexed: {
DrawIndexedCmd* draw = mCommands.NextCommand<DrawIndexedCmd>();
size_t formatSize =
- IndexFormatSize(lastPipeline->GetInputStateDescriptor()->indexFormat);
+ IndexFormatSize(lastPipeline->GetVertexInputDescriptor()->indexFormat);
// The index and instance count must be non-zero, otherwise no-op
if (draw->indexCount != 0 && draw->instanceCount != 0) {
@@ -926,8 +926,8 @@
auto buffers = mCommands.NextData<Ref<BufferBase>>(cmd->count);
auto offsets = mCommands.NextData<uint64_t>(cmd->count);
- std::array<id<MTLBuffer>, kMaxVertexInputs> mtlBuffers;
- std::array<NSUInteger, kMaxVertexInputs> mtlOffsets;
+ std::array<id<MTLBuffer>, kMaxVertexBuffers> mtlBuffers;
+ std::array<NSUInteger, kMaxVertexBuffers> mtlOffsets;
// Perhaps an "array of vertex buffers(+offsets?)" should be
// a Dawn API primitive to avoid reconstructing this array?
diff --git a/src/dawn_native/metal/RenderPipelineMTL.mm b/src/dawn_native/metal/RenderPipelineMTL.mm
index 0a92c93..078a081 100644
--- a/src/dawn_native/metal/RenderPipelineMTL.mm
+++ b/src/dawn_native/metal/RenderPipelineMTL.mm
@@ -307,7 +307,7 @@
RenderPipeline::RenderPipeline(Device* device, const RenderPipelineDescriptor* descriptor)
: RenderPipelineBase(device, descriptor),
- mMtlIndexType(MTLIndexFormat(GetInputStateDescriptor()->indexFormat)),
+ mMtlIndexType(MTLIndexFormat(GetVertexInputDescriptor()->indexFormat)),
mMtlPrimitiveTopology(MTLPrimitiveTopology(GetPrimitiveTopology())),
mMtlFrontFace(MTLFrontFace(GetFrontFace())),
mMtlCullMode(ToMTLCullMode(GetCullMode())) {
@@ -416,7 +416,7 @@
}
for (uint32_t i : IterateBitSet(GetInputsSetMask())) {
- const VertexInputDescriptor& info = GetInput(i);
+ const VertexBufferDescriptor& info = GetInput(i);
auto layoutDesc = [MTLVertexBufferLayoutDescriptor new];
if (info.stride == 0) {
diff --git a/src/dawn_native/opengl/CommandBufferGL.cpp b/src/dawn_native/opengl/CommandBufferGL.cpp
index 686f9db..7973d44 100644
--- a/src/dawn_native/opengl/CommandBufferGL.cpp
+++ b/src/dawn_native/opengl/CommandBufferGL.cpp
@@ -210,8 +210,8 @@
};
// Vertex buffers and index buffers are implemented as part of an OpenGL VAO that
- // corresponds to an InputState. On the contrary in Dawn they are part of the global state.
- // This means that we have to re-apply these buffers on an InputState change.
+ // corresponds to an VertexInput. On the contrary in Dawn they are part of the global state.
+ // This means that we have to re-apply these buffers on an VertexInput change.
class InputBufferTracker {
public:
void OnSetIndexBuffer(BufferBase* buffer) {
@@ -230,7 +230,7 @@
}
// Use 64 bit masks and make sure there are no shift UB
- static_assert(kMaxVertexInputs <= 8 * sizeof(unsigned long long) - 1, "");
+ static_assert(kMaxVertexBuffers <= 8 * sizeof(unsigned long long) - 1, "");
mDirtyVertexBuffers |= ((1ull << count) - 1ull) << startSlot;
}
@@ -286,9 +286,9 @@
bool mIndexBufferDirty = false;
Buffer* mIndexBuffer = nullptr;
- std::bitset<kMaxVertexInputs> mDirtyVertexBuffers;
- std::array<Buffer*, kMaxVertexInputs> mVertexBuffers;
- std::array<uint64_t, kMaxVertexInputs> mVertexBufferOffsets;
+ std::bitset<kMaxVertexBuffers> mDirtyVertexBuffers;
+ std::array<Buffer*, kMaxVertexBuffers> mVertexBuffers;
+ std::array<uint64_t, kMaxVertexBuffers> mVertexBufferOffsets;
RenderPipelineBase* mLastPipeline = nullptr;
};
@@ -772,7 +772,7 @@
inputBuffers.Apply();
dawn::IndexFormat indexFormat =
- lastPipeline->GetInputStateDescriptor()->indexFormat;
+ lastPipeline->GetVertexInputDescriptor()->indexFormat;
size_t formatSize = IndexFormatSize(indexFormat);
GLenum formatType = IndexFormatType(indexFormat);
diff --git a/src/dawn_native/opengl/RenderPipelineGL.cpp b/src/dawn_native/opengl/RenderPipelineGL.cpp
index ada39b2..5e3f2d6 100644
--- a/src/dawn_native/opengl/RenderPipelineGL.cpp
+++ b/src/dawn_native/opengl/RenderPipelineGL.cpp
@@ -182,7 +182,7 @@
modules[dawn::ShaderStage::Fragment] = ToBackend(descriptor->fragmentStage->module);
PipelineGL::Initialize(ToBackend(GetLayout()), modules);
- CreateVAOForInputState(descriptor->inputState);
+ CreateVAOForVertexInput(descriptor->vertexInput);
}
RenderPipeline::~RenderPipeline() {
@@ -194,7 +194,7 @@
return mGlPrimitiveTopology;
}
- void RenderPipeline::CreateVAOForInputState(const InputStateDescriptor* inputState) {
+ void RenderPipeline::CreateVAOForVertexInput(const VertexInputDescriptor* vertexInput) {
glGenVertexArrays(1, &mVertexArrayObject);
glBindVertexArray(mVertexArrayObject);
for (uint32_t location : IterateBitSet(GetAttributesSetMask())) {
diff --git a/src/dawn_native/opengl/RenderPipelineGL.h b/src/dawn_native/opengl/RenderPipelineGL.h
index dc51f6f..6dc3c14 100644
--- a/src/dawn_native/opengl/RenderPipelineGL.h
+++ b/src/dawn_native/opengl/RenderPipelineGL.h
@@ -38,7 +38,7 @@
void ApplyNow(PersistentPipelineState& persistentPipelineState);
private:
- void CreateVAOForInputState(const InputStateDescriptor* inputState);
+ void CreateVAOForVertexInput(const VertexInputDescriptor* vertexInput);
// TODO(yunchao.he@intel.com): vao need to be deduplicated between pipelines.
GLuint mVertexArrayObject;
diff --git a/src/dawn_native/vulkan/CommandBufferVk.cpp b/src/dawn_native/vulkan/CommandBufferVk.cpp
index e65f537..3c81af4 100644
--- a/src/dawn_native/vulkan/CommandBufferVk.cpp
+++ b/src/dawn_native/vulkan/CommandBufferVk.cpp
@@ -575,7 +575,7 @@
// and rebind if needed on pipeline change
ASSERT(lastPipeline != nullptr);
VkIndexType indexType =
- VulkanIndexType(lastPipeline->GetInputStateDescriptor()->indexFormat);
+ VulkanIndexType(lastPipeline->GetVertexInputDescriptor()->indexFormat);
device->fn.CmdBindIndexBuffer(
commands, indexBuffer, static_cast<VkDeviceSize>(cmd->offset), indexType);
} break;
@@ -613,8 +613,8 @@
auto buffers = mCommands.NextData<Ref<BufferBase>>(cmd->count);
auto offsets = mCommands.NextData<uint64_t>(cmd->count);
- std::array<VkBuffer, kMaxVertexInputs> vkBuffers;
- std::array<VkDeviceSize, kMaxVertexInputs> vkOffsets;
+ std::array<VkBuffer, kMaxVertexBuffers> vkBuffers;
+ std::array<VkDeviceSize, kMaxVertexBuffers> vkOffsets;
for (uint32_t i = 0; i < cmd->count; ++i) {
Buffer* buffer = ToBackend(buffers[i].Get());
diff --git a/src/dawn_native/vulkan/RenderPipelineVk.cpp b/src/dawn_native/vulkan/RenderPipelineVk.cpp
index e2cbca9..581e303 100644
--- a/src/dawn_native/vulkan/RenderPipelineVk.cpp
+++ b/src/dawn_native/vulkan/RenderPipelineVk.cpp
@@ -296,11 +296,11 @@
shaderStages[1].pName = descriptor->fragmentStage->entryPoint;
}
- std::array<VkVertexInputBindingDescription, kMaxVertexInputs> mBindings;
+ std::array<VkVertexInputBindingDescription, kMaxVertexBuffers> mBindings;
std::array<VkVertexInputAttributeDescription, kMaxVertexAttributes> mAttributes;
- const InputStateDescriptor* inputState = GetInputStateDescriptor();
- VkPipelineVertexInputStateCreateInfo inputStateCreateInfo =
- ComputeInputStateDesc(inputState, &mBindings, &mAttributes);
+ const VertexInputDescriptor* vertexInput = GetVertexInputDescriptor();
+ VkPipelineVertexInputStateCreateInfo vertexInputCreateInfo =
+ ComputeVertexInputDesc(vertexInput, &mBindings, &mAttributes);
VkPipelineInputAssemblyStateCreateInfo inputAssembly;
inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
@@ -427,7 +427,7 @@
createInfo.flags = 0;
createInfo.stageCount = 2;
createInfo.pStages = shaderStages;
- createInfo.pVertexInputState = &inputStateCreateInfo;
+ createInfo.pVertexInputState = &vertexInputCreateInfo;
createInfo.pInputAssemblyState = &inputAssembly;
createInfo.pTessellationState = nullptr;
createInfo.pViewportState = &viewport;
@@ -448,9 +448,9 @@
}
}
- VkPipelineVertexInputStateCreateInfo RenderPipeline::ComputeInputStateDesc(
- const InputStateDescriptor* inputState,
- std::array<VkVertexInputBindingDescription, kMaxVertexInputs>* mBindings,
+ VkPipelineVertexInputStateCreateInfo RenderPipeline::ComputeVertexInputDesc(
+ const VertexInputDescriptor* vertexInput,
+ std::array<VkVertexInputBindingDescription, kMaxVertexBuffers>* mBindings,
std::array<VkVertexInputAttributeDescription, kMaxVertexAttributes>* mAttributes) {
// Fill in the "binding info" that will be chained in the create info
uint32_t bindingCount = 0;
diff --git a/src/dawn_native/vulkan/RenderPipelineVk.h b/src/dawn_native/vulkan/RenderPipelineVk.h
index 5d58fa7..083c3ab 100644
--- a/src/dawn_native/vulkan/RenderPipelineVk.h
+++ b/src/dawn_native/vulkan/RenderPipelineVk.h
@@ -31,9 +31,9 @@
VkPipeline GetHandle() const;
private:
- VkPipelineVertexInputStateCreateInfo ComputeInputStateDesc(
- const InputStateDescriptor* inputState,
- std::array<VkVertexInputBindingDescription, kMaxVertexInputs>* mBindings,
+ VkPipelineVertexInputStateCreateInfo ComputeVertexInputDesc(
+ const VertexInputDescriptor* vertexInput,
+ std::array<VkVertexInputBindingDescription, kMaxVertexBuffers>* mBindings,
std::array<VkVertexInputAttributeDescription, kMaxVertexAttributes>* mAttributes);
VkPipeline mHandle = VK_NULL_HANDLE;
diff --git a/src/tests/end2end/DestroyTests.cpp b/src/tests/end2end/DestroyTests.cpp
index 8bd4cda..3deaeaa 100644
--- a/src/tests/end2end/DestroyTests.cpp
+++ b/src/tests/end2end/DestroyTests.cpp
@@ -46,10 +46,10 @@
descriptor.cVertexStage.module = vsModule;
descriptor.cFragmentStage.module = fsModule;
descriptor.primitiveTopology = dawn::PrimitiveTopology::TriangleStrip;
- descriptor.cInputState.numInputs = 1;
- descriptor.cInputState.cInputs[0].stride = 4 * sizeof(float);
- descriptor.cInputState.numAttributes = 1;
- descriptor.cInputState.cAttributes[0].format = dawn::VertexFormat::Float4;
+ descriptor.cVertexInput.numBuffers = 1;
+ descriptor.cVertexInput.cBuffers[0].stride = 4 * sizeof(float);
+ descriptor.cVertexInput.numAttributes = 1;
+ descriptor.cVertexInput.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 02421c7..44baa2b 100644
--- a/src/tests/end2end/DrawIndexedTests.cpp
+++ b/src/tests/end2end/DrawIndexedTests.cpp
@@ -46,10 +46,10 @@
descriptor.cVertexStage.module = vsModule;
descriptor.cFragmentStage.module = fsModule;
descriptor.primitiveTopology = dawn::PrimitiveTopology::TriangleStrip;
- descriptor.cInputState.numInputs = 1;
- descriptor.cInputState.cInputs[0].stride = 4 * sizeof(float);
- descriptor.cInputState.numAttributes = 1;
- descriptor.cInputState.cAttributes[0].format = dawn::VertexFormat::Float4;
+ descriptor.cVertexInput.numBuffers = 1;
+ descriptor.cVertexInput.cBuffers[0].stride = 4 * sizeof(float);
+ descriptor.cVertexInput.numAttributes = 1;
+ descriptor.cVertexInput.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 b2c36f7..c09e337 100644
--- a/src/tests/end2end/DrawTests.cpp
+++ b/src/tests/end2end/DrawTests.cpp
@@ -46,10 +46,10 @@
descriptor.cVertexStage.module = vsModule;
descriptor.cFragmentStage.module = fsModule;
descriptor.primitiveTopology = dawn::PrimitiveTopology::TriangleStrip;
- descriptor.cInputState.numInputs = 1;
- descriptor.cInputState.cInputs[0].stride = 4 * sizeof(float);
- descriptor.cInputState.numAttributes = 1;
- descriptor.cInputState.cAttributes[0].format = dawn::VertexFormat::Float4;
+ descriptor.cVertexInput.numBuffers = 1;
+ descriptor.cVertexInput.cBuffers[0].stride = 4 * sizeof(float);
+ descriptor.cVertexInput.numAttributes = 1;
+ descriptor.cVertexInput.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 d4b2acb..f7122c7 100644
--- a/src/tests/end2end/IndexFormatTests.cpp
+++ b/src/tests/end2end/IndexFormatTests.cpp
@@ -52,11 +52,11 @@
descriptor.cVertexStage.module = vsModule;
descriptor.cFragmentStage.module = fsModule;
descriptor.primitiveTopology = dawn::PrimitiveTopology::TriangleStrip;
- descriptor.cInputState.indexFormat = format;
- descriptor.cInputState.numInputs = 1;
- descriptor.cInputState.cInputs[0].stride = 4 * sizeof(float);
- descriptor.cInputState.numAttributes = 1;
- descriptor.cInputState.cAttributes[0].format = dawn::VertexFormat::Float4;
+ descriptor.cVertexInput.indexFormat = format;
+ descriptor.cVertexInput.numBuffers = 1;
+ descriptor.cVertexInput.cBuffers[0].stride = 4 * sizeof(float);
+ descriptor.cVertexInput.numAttributes = 1;
+ descriptor.cVertexInput.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
deleted file mode 100644
index c463dc1..0000000
--- a/src/tests/end2end/InputStateTests.cpp
+++ /dev/null
@@ -1,494 +0,0 @@
-// Copyright 2017 The Dawn Authors
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "tests/DawnTest.h"
-
-#include "common/Assert.h"
-#include "utils/ComboRenderPipelineDescriptor.h"
-#include "utils/DawnHelpers.h"
-
-using dawn::InputStepMode;
-using dawn::VertexFormat;
-
-// Input state tests all work the same way: the test will render triangles in a grid up to 4x4. Each triangle
-// is position in the grid such that X will correspond to the "triangle number" and the Y to the instance number.
-// Each test will set up an input state and buffers, and the vertex shader will check that the vertex attributes
-// corresponds to predetermined values. On success it outputs green, otherwise red.
-//
-// The predetermined values are "K * gl_VertexID + componentIndex" for vertex-indexed buffers, and
-// "K * gl_InstanceID + componentIndex" for instance-indexed buffers.
-
-constexpr static unsigned int kRTSize = 400;
-constexpr static unsigned int kRTCellOffset = 50;
-constexpr static unsigned int kRTCellSize = 100;
-
-class InputStateTest : public DawnTest {
- protected:
- void SetUp() override {
- DawnTest::SetUp();
-
- renderPass = utils::CreateBasicRenderPass(device, kRTSize, kRTSize);
- }
-
- bool ShouldComponentBeDefault(VertexFormat format, int component) {
- EXPECT_TRUE(component >= 0 && component < 4);
- switch (format) {
- case VertexFormat::Float4:
- case VertexFormat::UChar4Norm:
- return component >= 4;
- case VertexFormat::Float3:
- return component >= 3;
- case VertexFormat::Float2:
- case VertexFormat::UChar2Norm:
- return component >= 2;
- case VertexFormat::Float:
- return component >= 1;
- default:
- DAWN_UNREACHABLE();
- }
- }
-
- struct ShaderTestSpec {
- uint32_t location;
- VertexFormat format;
- InputStepMode step;
- };
- dawn::RenderPipeline MakeTestPipeline(const dawn::InputStateDescriptor& inputState,
- int multiplier,
- const std::vector<ShaderTestSpec>& testSpec) {
- std::ostringstream vs;
- vs << "#version 450\n";
-
- // TODO(cwallez@chromium.org): this only handles float attributes, we should extend it to other types
- // Adds line of the form
- // layout(location=1) in vec4 input1;
- for (const auto& input : testSpec) {
- vs << "layout(location=" << input.location << ") in vec4 input" << input.location << ";\n";
- }
-
- vs << "layout(location = 0) out vec4 color;\n";
- vs << "void main() {\n";
-
- // Hard code the triangle in the shader so that we don't have to add a vertex input for it.
- // Also this places the triangle in the grid based on its VertexID and InstanceID
- vs << " const vec2 pos[3] = vec2[3](vec2(0.5f, 1.0f), vec2(0.0f, 0.0f), vec2(1.0f, 0.0f));\n";
- vs << " vec2 offset = vec2(float(gl_VertexIndex / 3), float(gl_InstanceIndex));\n";
- vs << " vec2 worldPos = pos[gl_VertexIndex % 3] + offset;\n";
- vs << " gl_Position = vec4(worldPos / 2 - vec2(1.0f), 0.0f, 1.0f);\n";
-
- // Perform the checks by successively ANDing a boolean
- vs << " bool success = true;\n";
- for (const auto& input : testSpec) {
- for (int component = 0; component < 4; ++component) {
- vs << " success = success && (input" << input.location << "[" << component << "] == ";
- if (ShouldComponentBeDefault(input.format, component)) {
- vs << (component == 3 ? "1.0f" : "0.0f");
- } else {
- if (input.step == InputStepMode::Vertex) {
- vs << multiplier << " * gl_VertexIndex + " << component << ".0f";
- } else {
- vs << multiplier << " * gl_InstanceIndex + " << component << ".0f";
- }
- }
- vs << ");\n";
- }
- }
-
- // Choose the color
- vs << " if (success) {\n";
- vs << " color = vec4(0.0f, 1.0f, 0.0f, 1.0f);\n";
- vs << " } else {\n";
- vs << " color = vec4(1.0f, 0.0f, 0.0f, 1.0f);\n";
- vs << " }\n;";
- vs << "}\n";
-
- dawn::ShaderModule vsModule = utils::CreateShaderModule(device, dawn::ShaderStage::Vertex, vs.str().c_str());
- dawn::ShaderModule fsModule = utils::CreateShaderModule(device, dawn::ShaderStage::Fragment, R"(
- #version 450
- layout(location = 0) in vec4 color;
- layout(location = 0) out vec4 fragColor;
- void main() {
- fragColor = color;
- })"
- );
-
- utils::ComboRenderPipelineDescriptor descriptor(device);
- descriptor.cVertexStage.module = vsModule;
- descriptor.cFragmentStage.module = fsModule;
- descriptor.inputState = &inputState;
- descriptor.cColorStates[0]->format = renderPass.colorFormat;
-
- return device.CreateRenderPipeline(&descriptor);
- }
-
- struct InputSpec {
- uint32_t slot;
- uint64_t stride;
- InputStepMode step;
- };
- struct AttributeSpec {
- uint32_t location;
- uint32_t slot;
- uint64_t offset;
- VertexFormat format;
- };
-
- utils::ComboInputStateDescriptor MakeInputState(
- const std::vector<InputSpec>& inputs,
- const std::vector<AttributeSpec>& attributes) {
- utils::ComboInputStateDescriptor inputState;
- uint32_t numInputs = 0;
- for (const auto& input : inputs) {
- 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) {
- 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.numAttributes = numAttributes;
- return inputState;
- }
-
- template<typename T>
- dawn::Buffer MakeVertexBuffer(std::vector<T> data) {
- return utils::CreateBufferFromData(device, data.data(), static_cast<uint32_t>(data.size() * sizeof(T)), dawn::BufferUsageBit::Vertex);
- }
-
- struct DrawVertexBuffer {
- uint32_t location;
- dawn::Buffer* buffer;
- };
- void DoTestDraw(const dawn::RenderPipeline& pipeline, unsigned int triangles, unsigned int instances, std::vector<DrawVertexBuffer> vertexBuffers) {
- EXPECT_LE(triangles, 4u);
- EXPECT_LE(instances, 4u);
-
- dawn::CommandEncoder encoder = device.CreateCommandEncoder();
-
- dawn::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass.renderPassInfo);
- pass.SetPipeline(pipeline);
-
- uint64_t zeroOffset = 0;
- for (const auto& buffer : vertexBuffers) {
- pass.SetVertexBuffers(buffer.location, 1, buffer.buffer, &zeroOffset);
- }
-
- pass.Draw(triangles * 3, instances, 0, 0);
- pass.EndPass();
-
- dawn::CommandBuffer commands = encoder.Finish();
- queue.Submit(1, &commands);
-
- CheckResult(triangles, instances);
- }
-
- void CheckResult(unsigned int triangles, unsigned int instances) {
- // Check that the center of each triangle is pure green, so that if a single vertex shader
- // instance fails, linear interpolation makes the pixel check fail.
- for (unsigned int triangle = 0; triangle < 4; triangle++) {
- for (unsigned int instance = 0; instance < 4; instance++) {
- unsigned int x = kRTCellOffset + kRTCellSize * triangle;
- unsigned int y = kRTCellOffset + kRTCellSize * instance;
- if (triangle < triangles && instance < instances) {
- EXPECT_PIXEL_RGBA8_EQ(RGBA8(0, 255, 0, 255), renderPass.color, x, y);
- } else {
- EXPECT_PIXEL_RGBA8_EQ(RGBA8(0, 0, 0, 0), renderPass.color, x, y);
- }
- }
- }
- }
-
- utils::BasicRenderPass renderPass;
-};
-
-// Test compilation and usage of the fixture :)
-TEST_P(InputStateTest, Basic) {
- 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}
- });
-
- dawn::Buffer buffer0 = MakeVertexBuffer<float>({
- 0, 1, 2, 3,
- 1, 2, 3, 4,
- 2, 3, 4, 5
- });
- DoTestDraw(pipeline, 1, 1, {DrawVertexBuffer{0, &buffer0}});
-}
-
-// Test a stride of 0 works
-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());
-
- utils::ComboInputStateDescriptor inputState =
- MakeInputState({{0, 0, InputStepMode::Vertex}}, {{0, 0, 0, VertexFormat::Float4}});
- dawn::RenderPipeline pipeline = MakeTestPipeline(inputState, 0, {
- {0, VertexFormat::Float4, InputStepMode::Vertex}
- });
-
- dawn::Buffer buffer0 = MakeVertexBuffer<float>({
- 0, 1, 2, 3,
- });
- DoTestDraw(pipeline, 1, 1, {DrawVertexBuffer{0, &buffer0}});
-}
-
-// Test attributes defaults to (0, 0, 0, 1) if the input state doesn't have all components
-TEST_P(InputStateTest, AttributeExpanding) {
- // This test was failing only on AMD but the OpenGL backend doesn't gather PCI info yet.
- DAWN_SKIP_TEST_IF(IsLinux() && IsOpenGL());
-
- // R32F case
- {
- utils::ComboInputStateDescriptor inputState =
- MakeInputState({{0, 0, InputStepMode::Vertex}}, {{0, 0, 0, VertexFormat::Float}});
- dawn::RenderPipeline pipeline = MakeTestPipeline(inputState, 0, {
- {0, VertexFormat::Float, InputStepMode::Vertex}
- });
-
- dawn::Buffer buffer0 = MakeVertexBuffer<float>({
- 0, 1, 2, 3
- });
- DoTestDraw(pipeline, 1, 1, {DrawVertexBuffer{0, &buffer0}});
- }
- // RG32F case
- {
- utils::ComboInputStateDescriptor inputState =
- MakeInputState({{0, 0, InputStepMode::Vertex}}, {{0, 0, 0, VertexFormat::Float2}});
- dawn::RenderPipeline pipeline = MakeTestPipeline(inputState, 0, {
- {0, VertexFormat::Float2, InputStepMode::Vertex}
- });
-
- dawn::Buffer buffer0 = MakeVertexBuffer<float>({
- 0, 1, 2, 3
- });
- DoTestDraw(pipeline, 1, 1, {DrawVertexBuffer{0, &buffer0}});
- }
- // RGB32F case
- {
- utils::ComboInputStateDescriptor inputState =
- MakeInputState({{0, 0, InputStepMode::Vertex}}, {{0, 0, 0, VertexFormat::Float3}});
- dawn::RenderPipeline pipeline = MakeTestPipeline(inputState, 0, {
- {0, VertexFormat::Float3, InputStepMode::Vertex}
- });
-
- dawn::Buffer buffer0 = MakeVertexBuffer<float>({
- 0, 1, 2, 3
- });
- DoTestDraw(pipeline, 1, 1, {DrawVertexBuffer{0, &buffer0}});
- }
-}
-
-// Test a stride larger than the attributes
-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());
-
- 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}
- });
-
- dawn::Buffer buffer0 = MakeVertexBuffer<float>({
- 0, 1, 2, 3, 0, 0, 0, 0,
- 1, 2, 3, 4, 0, 0, 0, 0,
- 2, 3, 4, 5, 0, 0, 0, 0,
- });
- DoTestDraw(pipeline, 1, 1, {DrawVertexBuffer{0, &buffer0}});
-}
-
-// Test two attributes at an offset, vertex version
-TEST_P(InputStateTest, TwoAttributesAtAnOffsetVertex) {
- 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, {
- {0, VertexFormat::Float4, InputStepMode::Vertex}
- });
-
- dawn::Buffer buffer0 = MakeVertexBuffer<float>({
- 0, 1, 2, 3, 0, 1, 2, 3,
- 1, 2, 3, 4, 1, 2, 3, 4,
- 2, 3, 4, 5, 2, 3, 4, 5,
- });
- DoTestDraw(pipeline, 1, 1, {DrawVertexBuffer{0, &buffer0}});
-}
-
-// Test two attributes at an offset, instance version
-TEST_P(InputStateTest, TwoAttributesAtAnOffsetInstance) {
- 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, {
- {0, VertexFormat::Float4, InputStepMode::Instance}
- });
-
- dawn::Buffer buffer0 = MakeVertexBuffer<float>({
- 0, 1, 2, 3, 0, 1, 2, 3,
- 1, 2, 3, 4, 1, 2, 3, 4,
- 2, 3, 4, 5, 2, 3, 4, 5,
- });
- DoTestDraw(pipeline, 1, 1, {DrawVertexBuffer{0, &buffer0}});
-}
-
-// Test a pure-instance input state
-TEST_P(InputStateTest, PureInstance) {
- 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}
- });
-
- dawn::Buffer buffer0 = MakeVertexBuffer<float>({
- 0, 1, 2, 3,
- 1, 2, 3, 4,
- 2, 3, 4, 5,
- 3, 4, 5, 6,
- });
- DoTestDraw(pipeline, 1, 4, {DrawVertexBuffer{0, &buffer0}});
-}
-
-// Test with mixed everything, vertex vs. instance, different stride and offsets
-// different attribute types
-TEST_P(InputStateTest, MixedEverything) {
- utils::ComboInputStateDescriptor inputState = MakeInputState(
- {
- {0, 12 * sizeof(float), InputStepMode::Vertex},
- {1, 10 * sizeof(float), InputStepMode::Instance},
- },
- {{0, 0, 0, VertexFormat::Float},
- {1, 0, 6 * sizeof(float), VertexFormat::Float2},
- {2, 1, 0, VertexFormat::Float3},
- {3, 1, 5 * sizeof(float), VertexFormat::Float4}});
- dawn::RenderPipeline pipeline = MakeTestPipeline(inputState, 1, {
- {0, VertexFormat::Float, InputStepMode::Vertex},
- {1, VertexFormat::Float2, InputStepMode::Vertex},
- {2, VertexFormat::Float3, InputStepMode::Instance},
- {3, VertexFormat::Float4, InputStepMode::Instance}
- });
-
- dawn::Buffer buffer0 = MakeVertexBuffer<float>({
- 0, 1, 2, 3, 0, 0, 0, 1, 2, 3, 0, 0,
- 1, 2, 3, 4, 0, 0, 1, 2, 3, 4, 0, 0,
- 2, 3, 4, 5, 0, 0, 2, 3, 4, 5, 0, 0,
- 3, 4, 5, 6, 0, 0, 3, 4, 5, 6, 0, 0,
- });
- dawn::Buffer buffer1 = MakeVertexBuffer<float>({
- 0, 1, 2, 3, 0, 0, 1, 2, 3, 0,
- 1, 2, 3, 4, 0, 1, 2, 3, 4, 0,
- 2, 3, 4, 5, 0, 2, 3, 4, 5, 0,
- 3, 4, 5, 6, 0, 3, 4, 5, 6, 0,
- });
- DoTestDraw(pipeline, 1, 1, {{0, &buffer0}, {1, &buffer1}});
-}
-
-// Test input state is unaffected by unused vertex slot
-TEST_P(InputStateTest, UnusedVertexSlot) {
- // Instance input state, using slot 1
- 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}});
-
- dawn::Buffer buffer = MakeVertexBuffer<float>({
- 0, 1, 2, 3,
- 1, 2, 3, 4,
- 2, 3, 4, 5,
- 3, 4, 5, 6,
- });
-
- dawn::CommandEncoder encoder = device.CreateCommandEncoder();
-
- dawn::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass.renderPassInfo);
-
- uint64_t zeroOffset = 0;
- pass.SetVertexBuffers(0, 1, &buffer, &zeroOffset);
- pass.SetVertexBuffers(1, 1, &buffer, &zeroOffset);
-
- pass.SetPipeline(instancePipeline);
- pass.Draw(1 * 3, 4, 0, 0);
-
- pass.EndPass();
-
- dawn::CommandBuffer commands = encoder.Finish();
- queue.Submit(1, &commands);
-
- CheckResult(1, 4);
-}
-
-// Test setting a different pipeline with a different input state.
-// This was a problem with the D3D12 backend where SetVertexBuffers
-// was getting the input from the last set pipeline, not the current.
-// SetVertexBuffers should be reapplied when the input state changes.
-TEST_P(InputStateTest, MultiplePipelinesMixedInputState) {
- // Basic input state, using slot 0
- 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
- 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}});
-
- dawn::Buffer buffer = MakeVertexBuffer<float>({
- 0, 1, 2, 3,
- 1, 2, 3, 4,
- 2, 3, 4, 5,
- 3, 4, 5, 6,
- });
-
- dawn::CommandEncoder encoder = device.CreateCommandEncoder();
-
- dawn::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass.renderPassInfo);
-
- uint64_t zeroOffset = 0;
- pass.SetVertexBuffers(0, 1, &buffer, &zeroOffset);
- pass.SetVertexBuffers(1, 1, &buffer, &zeroOffset);
-
- pass.SetPipeline(vertexPipeline);
- pass.Draw(1 * 3, 1, 0, 0);
-
- pass.SetPipeline(instancePipeline);
- pass.Draw(1 * 3, 4, 0, 0);
-
- pass.EndPass();
-
- dawn::CommandBuffer commands = encoder.Finish();
- queue.Submit(1, &commands);
-
- CheckResult(1, 4);
-}
-
-DAWN_INSTANTIATE_TEST(InputStateTest, D3D12Backend, MetalBackend, OpenGLBackend, VulkanBackend);
-
-// TODO for the input state:
-// - Add more vertex formats
-// - Add checks that the stride is enough to contain all attributes
-// - Add checks stride less than some limit
-// - Add checks for alignement of vertex buffers and attributes if needed
-// - Check for attribute narrowing
-// - Check that the input state and the pipeline vertex input types match
diff --git a/src/tests/end2end/PrimitiveTopologyTests.cpp b/src/tests/end2end/PrimitiveTopologyTests.cpp
index 552715b..d0bd851 100644
--- a/src/tests/end2end/PrimitiveTopologyTests.cpp
+++ b/src/tests/end2end/PrimitiveTopologyTests.cpp
@@ -185,10 +185,10 @@
descriptor.cVertexStage.module = vsModule;
descriptor.cFragmentStage.module = fsModule;
descriptor.primitiveTopology = primitiveTopology;
- descriptor.cInputState.numInputs = 1;
- descriptor.cInputState.cInputs[0].stride = 4 * sizeof(float);
- descriptor.cInputState.numAttributes = 1;
- descriptor.cInputState.cAttributes[0].format = dawn::VertexFormat::Float4;
+ descriptor.cVertexInput.numBuffers = 1;
+ descriptor.cVertexInput.cBuffers[0].stride = 4 * sizeof(float);
+ descriptor.cVertexInput.numAttributes = 1;
+ descriptor.cVertexInput.cAttributes[0].format = dawn::VertexFormat::Float4;
descriptor.cColorStates[0]->format = renderPass.colorFormat;
dawn::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor);
diff --git a/src/tests/end2end/VertexFormatTests.cpp b/src/tests/end2end/VertexFormatTests.cpp
index 6d20bb8..f65e126 100644
--- a/src/tests/end2end/VertexFormatTests.cpp
+++ b/src/tests/end2end/VertexFormatTests.cpp
@@ -362,10 +362,10 @@
utils::ComboRenderPipelineDescriptor descriptor(device);
descriptor.cVertexStage.module = vsModule;
descriptor.cFragmentStage.module = fsModule;
- descriptor.cInputState.numInputs = 1;
- descriptor.cInputState.cInputs[0].stride = strideBytes;
- descriptor.cInputState.numAttributes = 1;
- descriptor.cInputState.cAttributes[0].format = format;
+ descriptor.cVertexInput.numBuffers = 1;
+ descriptor.cVertexInput.cBuffers[0].stride = strideBytes;
+ descriptor.cVertexInput.numAttributes = 1;
+ descriptor.cVertexInput.cAttributes[0].format = format;
descriptor.cColorStates[0]->format = renderPass.colorFormat;
return device.CreateRenderPipeline(&descriptor);
@@ -797,4 +797,4 @@
DoVertexFormatTest(dawn::VertexFormat::Int4, vertexData, vertexData);
}
-DAWN_INSTANTIATE_TEST(VertexFormatTest, D3D12Backend, MetalBackend, OpenGLBackend, VulkanBackend);
\ No newline at end of file
+DAWN_INSTANTIATE_TEST(VertexFormatTest, D3D12Backend, MetalBackend, OpenGLBackend, VulkanBackend);
diff --git a/src/tests/end2end/VertexInputTests.cpp b/src/tests/end2end/VertexInputTests.cpp
new file mode 100644
index 0000000..f23df73
--- /dev/null
+++ b/src/tests/end2end/VertexInputTests.cpp
@@ -0,0 +1,494 @@
+// Copyright 2017 The Dawn Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "tests/DawnTest.h"
+
+#include "common/Assert.h"
+#include "utils/ComboRenderPipelineDescriptor.h"
+#include "utils/DawnHelpers.h"
+
+using dawn::InputStepMode;
+using dawn::VertexFormat;
+
+// Input state tests all work the same way: the test will render triangles in a grid up to 4x4. Each triangle
+// is position in the grid such that X will correspond to the "triangle number" and the Y to the instance number.
+// Each test will set up an input state and buffers, and the vertex shader will check that the vertex attributes
+// corresponds to predetermined values. On success it outputs green, otherwise red.
+//
+// The predetermined values are "K * gl_VertexID + componentIndex" for vertex-indexed buffers, and
+// "K * gl_InstanceID + componentIndex" for instance-indexed buffers.
+
+constexpr static unsigned int kRTSize = 400;
+constexpr static unsigned int kRTCellOffset = 50;
+constexpr static unsigned int kRTCellSize = 100;
+
+class VertexInputTest : public DawnTest {
+ protected:
+ void SetUp() override {
+ DawnTest::SetUp();
+
+ renderPass = utils::CreateBasicRenderPass(device, kRTSize, kRTSize);
+ }
+
+ bool ShouldComponentBeDefault(VertexFormat format, int component) {
+ EXPECT_TRUE(component >= 0 && component < 4);
+ switch (format) {
+ case VertexFormat::Float4:
+ case VertexFormat::UChar4Norm:
+ return component >= 4;
+ case VertexFormat::Float3:
+ return component >= 3;
+ case VertexFormat::Float2:
+ case VertexFormat::UChar2Norm:
+ return component >= 2;
+ case VertexFormat::Float:
+ return component >= 1;
+ default:
+ DAWN_UNREACHABLE();
+ }
+ }
+
+ struct ShaderTestSpec {
+ uint32_t location;
+ VertexFormat format;
+ InputStepMode step;
+ };
+ dawn::RenderPipeline MakeTestPipeline(const dawn::VertexInputDescriptor& vertexInput,
+ int multiplier,
+ const std::vector<ShaderTestSpec>& testSpec) {
+ std::ostringstream vs;
+ vs << "#version 450\n";
+
+ // TODO(cwallez@chromium.org): this only handles float attributes, we should extend it to
+ // other types Adds line of the form
+ // layout(location=1) in vec4 input1;
+ for (const auto& input : testSpec) {
+ vs << "layout(location=" << input.location << ") in vec4 input" << input.location
+ << ";\n";
+ }
+
+ vs << "layout(location = 0) out vec4 color;\n";
+ vs << "void main() {\n";
+
+ // Hard code the triangle in the shader so that we don't have to add a vertex input for it.
+ // Also this places the triangle in the grid based on its VertexID and InstanceID
+ vs << " const vec2 pos[3] = vec2[3](vec2(0.5f, 1.0f), vec2(0.0f, 0.0f), vec2(1.0f, "
+ "0.0f));\n";
+ vs << " vec2 offset = vec2(float(gl_VertexIndex / 3), float(gl_InstanceIndex));\n";
+ vs << " vec2 worldPos = pos[gl_VertexIndex % 3] + offset;\n";
+ vs << " gl_Position = vec4(worldPos / 2 - vec2(1.0f), 0.0f, 1.0f);\n";
+
+ // Perform the checks by successively ANDing a boolean
+ vs << " bool success = true;\n";
+ for (const auto& input : testSpec) {
+ for (int component = 0; component < 4; ++component) {
+ vs << " success = success && (input" << input.location << "[" << component
+ << "] == ";
+ if (ShouldComponentBeDefault(input.format, component)) {
+ vs << (component == 3 ? "1.0f" : "0.0f");
+ } else {
+ if (input.step == InputStepMode::Vertex) {
+ vs << multiplier << " * gl_VertexIndex + " << component << ".0f";
+ } else {
+ vs << multiplier << " * gl_InstanceIndex + " << component << ".0f";
+ }
+ }
+ vs << ");\n";
+ }
+ }
+
+ // Choose the color
+ vs << " if (success) {\n";
+ vs << " color = vec4(0.0f, 1.0f, 0.0f, 1.0f);\n";
+ vs << " } else {\n";
+ vs << " color = vec4(1.0f, 0.0f, 0.0f, 1.0f);\n";
+ vs << " }\n;";
+ vs << "}\n";
+
+ dawn::ShaderModule vsModule =
+ utils::CreateShaderModule(device, dawn::ShaderStage::Vertex, vs.str().c_str());
+ dawn::ShaderModule fsModule =
+ utils::CreateShaderModule(device, dawn::ShaderStage::Fragment, R"(
+ #version 450
+ layout(location = 0) in vec4 color;
+ layout(location = 0) out vec4 fragColor;
+ void main() {
+ fragColor = color;
+ })");
+
+ utils::ComboRenderPipelineDescriptor descriptor(device);
+ descriptor.cVertexStage.module = vsModule;
+ descriptor.cFragmentStage.module = fsModule;
+ descriptor.vertexInput = &vertexInput;
+ descriptor.cColorStates[0]->format = renderPass.colorFormat;
+
+ return device.CreateRenderPipeline(&descriptor);
+ }
+
+ struct VertexBufferSpec {
+ uint32_t slot;
+ uint64_t stride;
+ InputStepMode step;
+ };
+ struct AttributeSpec {
+ uint32_t location;
+ uint32_t slot;
+ uint64_t offset;
+ VertexFormat format;
+ };
+
+ utils::ComboVertexInputDescriptor MakeVertexInput(
+ const std::vector<VertexBufferSpec>& buffers,
+ const std::vector<AttributeSpec>& attributes) {
+ utils::ComboVertexInputDescriptor vertexInput;
+ uint32_t numBuffers = 0;
+ for (const auto& buffer : buffers) {
+ vertexInput.cBuffers[numBuffers].inputSlot = buffer.slot;
+ vertexInput.cBuffers[numBuffers].stride = buffer.stride;
+ vertexInput.cBuffers[numBuffers].stepMode = buffer.step;
+ numBuffers++;
+ }
+
+ uint32_t numAttributes = 0;
+ for (const auto& attribute : attributes) {
+ vertexInput.cAttributes[numAttributes].shaderLocation = attribute.location;
+ vertexInput.cAttributes[numAttributes].inputSlot = attribute.slot;
+ vertexInput.cAttributes[numAttributes].offset = attribute.offset;
+ vertexInput.cAttributes[numAttributes].format = attribute.format;
+ numAttributes++;
+ }
+ vertexInput.numBuffers = numBuffers;
+ vertexInput.numAttributes = numAttributes;
+ return vertexInput;
+ }
+
+ template <typename T>
+ dawn::Buffer MakeVertexBuffer(std::vector<T> data) {
+ return utils::CreateBufferFromData(device, data.data(),
+ static_cast<uint32_t>(data.size() * sizeof(T)),
+ dawn::BufferUsageBit::Vertex);
+ }
+
+ struct DrawVertexBuffer {
+ uint32_t location;
+ dawn::Buffer* buffer;
+ };
+ void DoTestDraw(const dawn::RenderPipeline& pipeline,
+ unsigned int triangles,
+ unsigned int instances,
+ std::vector<DrawVertexBuffer> vertexBuffers) {
+ EXPECT_LE(triangles, 4u);
+ EXPECT_LE(instances, 4u);
+
+ dawn::CommandEncoder encoder = device.CreateCommandEncoder();
+
+ dawn::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass.renderPassInfo);
+ pass.SetPipeline(pipeline);
+
+ uint64_t zeroOffset = 0;
+ for (const auto& buffer : vertexBuffers) {
+ pass.SetVertexBuffers(buffer.location, 1, buffer.buffer, &zeroOffset);
+ }
+
+ pass.Draw(triangles * 3, instances, 0, 0);
+ pass.EndPass();
+
+ dawn::CommandBuffer commands = encoder.Finish();
+ queue.Submit(1, &commands);
+
+ CheckResult(triangles, instances);
+ }
+
+ void CheckResult(unsigned int triangles, unsigned int instances) {
+ // Check that the center of each triangle is pure green, so that if a single vertex shader
+ // instance fails, linear interpolation makes the pixel check fail.
+ for (unsigned int triangle = 0; triangle < 4; triangle++) {
+ for (unsigned int instance = 0; instance < 4; instance++) {
+ unsigned int x = kRTCellOffset + kRTCellSize * triangle;
+ unsigned int y = kRTCellOffset + kRTCellSize * instance;
+ if (triangle < triangles && instance < instances) {
+ EXPECT_PIXEL_RGBA8_EQ(RGBA8(0, 255, 0, 255), renderPass.color, x, y);
+ } else {
+ EXPECT_PIXEL_RGBA8_EQ(RGBA8(0, 0, 0, 0), renderPass.color, x, y);
+ }
+ }
+ }
+ }
+
+ utils::BasicRenderPass renderPass;
+};
+
+// Test compilation and usage of the fixture :)
+TEST_P(VertexInputTest, Basic) {
+ utils::ComboVertexInputDescriptor vertexInput = MakeVertexInput(
+ {{0, 4 * sizeof(float), InputStepMode::Vertex}}, {{0, 0, 0, VertexFormat::Float4}});
+ dawn::RenderPipeline pipeline =
+ MakeTestPipeline(vertexInput, 1, {{0, VertexFormat::Float4, InputStepMode::Vertex}});
+
+ dawn::Buffer buffer0 = MakeVertexBuffer<float>({
+ 0, 1, 2, 3,
+ 1, 2, 3, 4,
+ 2, 3, 4, 5
+ });
+ DoTestDraw(pipeline, 1, 1, {DrawVertexBuffer{0, &buffer0}});
+}
+
+// Test a stride of 0 works
+TEST_P(VertexInputTest, ZeroStride) {
+ // This test was failing only on AMD but the OpenGL backend doesn't gather PCI info yet.
+ DAWN_SKIP_TEST_IF(IsLinux() && IsOpenGL());
+
+ utils::ComboVertexInputDescriptor vertexInput =
+ MakeVertexInput({{0, 0, InputStepMode::Vertex}}, {{0, 0, 0, VertexFormat::Float4}});
+ dawn::RenderPipeline pipeline =
+ MakeTestPipeline(vertexInput, 0, {{0, VertexFormat::Float4, InputStepMode::Vertex}});
+
+ dawn::Buffer buffer0 = MakeVertexBuffer<float>({
+ 0, 1, 2, 3,
+ });
+ DoTestDraw(pipeline, 1, 1, {DrawVertexBuffer{0, &buffer0}});
+}
+
+// Test attributes defaults to (0, 0, 0, 1) if the input state doesn't have all components
+TEST_P(VertexInputTest, AttributeExpanding) {
+ // This test was failing only on AMD but the OpenGL backend doesn't gather PCI info yet.
+ DAWN_SKIP_TEST_IF(IsLinux() && IsOpenGL());
+
+ // R32F case
+ {
+ utils::ComboVertexInputDescriptor vertexInput =
+ MakeVertexInput({{0, 0, InputStepMode::Vertex}}, {{0, 0, 0, VertexFormat::Float}});
+ dawn::RenderPipeline pipeline =
+ MakeTestPipeline(vertexInput, 0, {{0, VertexFormat::Float, InputStepMode::Vertex}});
+
+ dawn::Buffer buffer0 = MakeVertexBuffer<float>({
+ 0, 1, 2, 3
+ });
+ DoTestDraw(pipeline, 1, 1, {DrawVertexBuffer{0, &buffer0}});
+ }
+ // RG32F case
+ {
+ utils::ComboVertexInputDescriptor vertexInput =
+ MakeVertexInput({{0, 0, InputStepMode::Vertex}}, {{0, 0, 0, VertexFormat::Float2}});
+ dawn::RenderPipeline pipeline =
+ MakeTestPipeline(vertexInput, 0, {{0, VertexFormat::Float2, InputStepMode::Vertex}});
+
+ dawn::Buffer buffer0 = MakeVertexBuffer<float>({
+ 0, 1, 2, 3
+ });
+ DoTestDraw(pipeline, 1, 1, {DrawVertexBuffer{0, &buffer0}});
+ }
+ // RGB32F case
+ {
+ utils::ComboVertexInputDescriptor vertexInput =
+ MakeVertexInput({{0, 0, InputStepMode::Vertex}}, {{0, 0, 0, VertexFormat::Float3}});
+ dawn::RenderPipeline pipeline =
+ MakeTestPipeline(vertexInput, 0, {{0, VertexFormat::Float3, InputStepMode::Vertex}});
+
+ dawn::Buffer buffer0 = MakeVertexBuffer<float>({
+ 0, 1, 2, 3
+ });
+ DoTestDraw(pipeline, 1, 1, {DrawVertexBuffer{0, &buffer0}});
+ }
+}
+
+// Test a stride larger than the attributes
+TEST_P(VertexInputTest, StrideLargerThanAttributes) {
+ // This test was failing only on AMD but the OpenGL backend doesn't gather PCI info yet.
+ DAWN_SKIP_TEST_IF(IsLinux() && IsOpenGL());
+
+ utils::ComboVertexInputDescriptor vertexInput = MakeVertexInput(
+ {{0, 8 * sizeof(float), InputStepMode::Vertex}}, {{0, 0, 0, VertexFormat::Float4}});
+ dawn::RenderPipeline pipeline =
+ MakeTestPipeline(vertexInput, 1, {{0, VertexFormat::Float4, InputStepMode::Vertex}});
+
+ dawn::Buffer buffer0 = MakeVertexBuffer<float>({
+ 0, 1, 2, 3, 0, 0, 0, 0,
+ 1, 2, 3, 4, 0, 0, 0, 0,
+ 2, 3, 4, 5, 0, 0, 0, 0,
+ });
+ DoTestDraw(pipeline, 1, 1, {DrawVertexBuffer{0, &buffer0}});
+}
+
+// Test two attributes at an offset, vertex version
+TEST_P(VertexInputTest, TwoAttributesAtAnOffsetVertex) {
+ utils::ComboVertexInputDescriptor vertexInput = MakeVertexInput(
+ {{0, 8 * sizeof(float), InputStepMode::Vertex}},
+ {{0, 0, 0, VertexFormat::Float4}, {1, 0, 4 * sizeof(float), VertexFormat::Float4}});
+ dawn::RenderPipeline pipeline =
+ MakeTestPipeline(vertexInput, 1, {{0, VertexFormat::Float4, InputStepMode::Vertex}});
+
+ dawn::Buffer buffer0 = MakeVertexBuffer<float>({
+ 0, 1, 2, 3, 0, 1, 2, 3,
+ 1, 2, 3, 4, 1, 2, 3, 4,
+ 2, 3, 4, 5, 2, 3, 4, 5,
+ });
+ DoTestDraw(pipeline, 1, 1, {DrawVertexBuffer{0, &buffer0}});
+}
+
+// Test two attributes at an offset, instance version
+TEST_P(VertexInputTest, TwoAttributesAtAnOffsetInstance) {
+ utils::ComboVertexInputDescriptor vertexInput = MakeVertexInput(
+ {{0, 8 * sizeof(float), InputStepMode::Instance}},
+ {{0, 0, 0, VertexFormat::Float4}, {1, 0, 4 * sizeof(float), VertexFormat::Float4}});
+ dawn::RenderPipeline pipeline =
+ MakeTestPipeline(vertexInput, 1, {{0, VertexFormat::Float4, InputStepMode::Instance}});
+
+ dawn::Buffer buffer0 = MakeVertexBuffer<float>({
+ 0, 1, 2, 3, 0, 1, 2, 3,
+ 1, 2, 3, 4, 1, 2, 3, 4,
+ 2, 3, 4, 5, 2, 3, 4, 5,
+ });
+ DoTestDraw(pipeline, 1, 1, {DrawVertexBuffer{0, &buffer0}});
+}
+
+// Test a pure-instance input state
+TEST_P(VertexInputTest, PureInstance) {
+ utils::ComboVertexInputDescriptor vertexInput = MakeVertexInput(
+ {{0, 4 * sizeof(float), InputStepMode::Instance}}, {{0, 0, 0, VertexFormat::Float4}});
+ dawn::RenderPipeline pipeline =
+ MakeTestPipeline(vertexInput, 1, {{0, VertexFormat::Float4, InputStepMode::Instance}});
+
+ dawn::Buffer buffer0 = MakeVertexBuffer<float>({
+ 0, 1, 2, 3,
+ 1, 2, 3, 4,
+ 2, 3, 4, 5,
+ 3, 4, 5, 6,
+ });
+ DoTestDraw(pipeline, 1, 4, {DrawVertexBuffer{0, &buffer0}});
+}
+
+// Test with mixed everything, vertex vs. instance, different stride and offsets
+// different attribute types
+TEST_P(VertexInputTest, MixedEverything) {
+ utils::ComboVertexInputDescriptor vertexInput = MakeVertexInput(
+ {
+ {0, 12 * sizeof(float), InputStepMode::Vertex},
+ {1, 10 * sizeof(float), InputStepMode::Instance},
+ },
+ {{0, 0, 0, VertexFormat::Float},
+ {1, 0, 6 * sizeof(float), VertexFormat::Float2},
+ {2, 1, 0, VertexFormat::Float3},
+ {3, 1, 5 * sizeof(float), VertexFormat::Float4}});
+ dawn::RenderPipeline pipeline =
+ MakeTestPipeline(vertexInput, 1,
+ {{0, VertexFormat::Float, InputStepMode::Vertex},
+ {1, VertexFormat::Float2, InputStepMode::Vertex},
+ {2, VertexFormat::Float3, InputStepMode::Instance},
+ {3, VertexFormat::Float4, InputStepMode::Instance}});
+
+ dawn::Buffer buffer0 = MakeVertexBuffer<float>({
+ 0, 1, 2, 3, 0, 0, 0, 1, 2, 3, 0, 0,
+ 1, 2, 3, 4, 0, 0, 1, 2, 3, 4, 0, 0,
+ 2, 3, 4, 5, 0, 0, 2, 3, 4, 5, 0, 0,
+ 3, 4, 5, 6, 0, 0, 3, 4, 5, 6, 0, 0,
+ });
+ dawn::Buffer buffer1 = MakeVertexBuffer<float>({
+ 0, 1, 2, 3, 0, 0, 1, 2, 3, 0,
+ 1, 2, 3, 4, 0, 1, 2, 3, 4, 0,
+ 2, 3, 4, 5, 0, 2, 3, 4, 5, 0,
+ 3, 4, 5, 6, 0, 3, 4, 5, 6, 0,
+ });
+ DoTestDraw(pipeline, 1, 1, {{0, &buffer0}, {1, &buffer1}});
+}
+
+// Test input state is unaffected by unused vertex slot
+TEST_P(VertexInputTest, UnusedVertexSlot) {
+ // Instance input state, using slot 1
+ utils::ComboVertexInputDescriptor instanceVertexInput = MakeVertexInput(
+ {{1, 4 * sizeof(float), InputStepMode::Instance}}, {{0, 1, 0, VertexFormat::Float4}});
+ dawn::RenderPipeline instancePipeline = MakeTestPipeline(
+ instanceVertexInput, 1, {{0, VertexFormat::Float4, InputStepMode::Instance}});
+
+ dawn::Buffer buffer = MakeVertexBuffer<float>({
+ 0, 1, 2, 3,
+ 1, 2, 3, 4,
+ 2, 3, 4, 5,
+ 3, 4, 5, 6,
+ });
+
+ dawn::CommandEncoder encoder = device.CreateCommandEncoder();
+
+ dawn::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass.renderPassInfo);
+
+ uint64_t zeroOffset = 0;
+ pass.SetVertexBuffers(0, 1, &buffer, &zeroOffset);
+ pass.SetVertexBuffers(1, 1, &buffer, &zeroOffset);
+
+ pass.SetPipeline(instancePipeline);
+ pass.Draw(1 * 3, 4, 0, 0);
+
+ pass.EndPass();
+
+ dawn::CommandBuffer commands = encoder.Finish();
+ queue.Submit(1, &commands);
+
+ CheckResult(1, 4);
+}
+
+// Test setting a different pipeline with a different input state.
+// This was a problem with the D3D12 backend where SetVertexBuffers
+// was getting the input from the last set pipeline, not the current.
+// SetVertexBuffers should be reapplied when the input state changes.
+TEST_P(VertexInputTest, MultiplePipelinesMixedVertexInput) {
+ // Basic input state, using slot 0
+ utils::ComboVertexInputDescriptor vertexVertexInput = MakeVertexInput(
+ {{0, 4 * sizeof(float), InputStepMode::Vertex}}, {{0, 0, 0, VertexFormat::Float4}});
+ dawn::RenderPipeline vertexPipeline =
+ MakeTestPipeline(vertexVertexInput, 1, {{0, VertexFormat::Float4, InputStepMode::Vertex}});
+
+ // Instance input state, using slot 1
+ utils::ComboVertexInputDescriptor instanceVertexInput = MakeVertexInput(
+ {{1, 4 * sizeof(float), InputStepMode::Instance}}, {{0, 1, 0, VertexFormat::Float4}});
+ dawn::RenderPipeline instancePipeline = MakeTestPipeline(
+ instanceVertexInput, 1, {{0, VertexFormat::Float4, InputStepMode::Instance}});
+
+ dawn::Buffer buffer = MakeVertexBuffer<float>({
+ 0, 1, 2, 3,
+ 1, 2, 3, 4,
+ 2, 3, 4, 5,
+ 3, 4, 5, 6,
+ });
+
+ dawn::CommandEncoder encoder = device.CreateCommandEncoder();
+
+ dawn::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass.renderPassInfo);
+
+ uint64_t zeroOffset = 0;
+ pass.SetVertexBuffers(0, 1, &buffer, &zeroOffset);
+ pass.SetVertexBuffers(1, 1, &buffer, &zeroOffset);
+
+ pass.SetPipeline(vertexPipeline);
+ pass.Draw(1 * 3, 1, 0, 0);
+
+ pass.SetPipeline(instancePipeline);
+ pass.Draw(1 * 3, 4, 0, 0);
+
+ pass.EndPass();
+
+ dawn::CommandBuffer commands = encoder.Finish();
+ queue.Submit(1, &commands);
+
+ CheckResult(1, 4);
+}
+
+DAWN_INSTANTIATE_TEST(VertexInputTest, D3D12Backend, MetalBackend, OpenGLBackend, VulkanBackend);
+
+// TODO for the input state:
+// - Add more vertex formats
+// - Add checks that the stride is enough to contain all attributes
+// - Add checks stride less than some limit
+// - Add checks for alignement of vertex buffers and attributes if needed
+// - Check for attribute narrowing
+// - Check that the input state and the pipeline vertex input types match
diff --git a/src/tests/unittests/validation/VertexBufferValidationTests.cpp b/src/tests/unittests/validation/VertexBufferValidationTests.cpp
index 36cbd4d..60561ae 100644
--- a/src/tests/unittests/validation/VertexBufferValidationTests.cpp
+++ b/src/tests/unittests/validation/VertexBufferValidationTests.cpp
@@ -45,18 +45,18 @@
return buffers;
}
- dawn::ShaderModule MakeVertexShader(unsigned int numInputs) {
+ dawn::ShaderModule MakeVertexShader(unsigned int numBuffers) {
std::ostringstream vs;
vs << "#version 450\n";
- for (unsigned int i = 0; i < numInputs; ++i) {
+ for (unsigned int i = 0; i < numBuffers; ++i) {
vs << "layout(location = " << i << ") in vec3 a_position" << i << ";\n";
}
vs << "void main() {\n";
vs << "gl_Position = vec4(";
- for (unsigned int i = 0; i < numInputs; ++i) {
+ for (unsigned int i = 0; i < numBuffers; ++i) {
vs << "a_position" << i;
- if (i != numInputs - 1) {
+ if (i != numBuffers - 1) {
vs << " + ";
}
}
@@ -68,19 +68,19 @@
}
dawn::RenderPipeline MakeRenderPipeline(const dawn::ShaderModule& vsModule,
- unsigned int numInputs) {
+ unsigned int numBuffers) {
utils::ComboRenderPipelineDescriptor descriptor(device);
descriptor.cVertexStage.module = vsModule;
descriptor.cFragmentStage.module = fsModule;
- for (unsigned int i = 0; i < numInputs; ++i) {
- 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;
+ for (unsigned int i = 0; i < numBuffers; ++i) {
+ descriptor.cVertexInput.cAttributes[i].shaderLocation = i;
+ descriptor.cVertexInput.cAttributes[i].inputSlot = i;
+ descriptor.cVertexInput.cAttributes[i].format = dawn::VertexFormat::Float3;
+ descriptor.cVertexInput.cBuffers[i].inputSlot = i;
}
- descriptor.cInputState.numInputs = numInputs;
- descriptor.cInputState.numAttributes = numInputs;
+ descriptor.cVertexInput.numBuffers = numBuffers;
+ descriptor.cVertexInput.numAttributes = numBuffers;
return device.CreateRenderPipeline(&descriptor);
}
@@ -88,7 +88,7 @@
dawn::ShaderModule fsModule;
};
-TEST_F(VertexBufferValidationTest, VertexInputsInheritedBetweenPipelines) {
+TEST_F(VertexBufferValidationTest, VertexBuffersInheritedBetweenPipelines) {
DummyRenderPass renderPass(device);
auto vsModule2 = MakeVertexShader(2);
auto vsModule1 = MakeVertexShader(1);
@@ -123,7 +123,7 @@
encoder.Finish();
}
-TEST_F(VertexBufferValidationTest, VertexInputsNotInheritedBetweenRendePasses) {
+TEST_F(VertexBufferValidationTest, VertexBuffersNotInheritedBetweenRendePasses) {
DummyRenderPass renderPass(device);
auto vsModule2 = MakeVertexShader(2);
auto vsModule1 = MakeVertexShader(1);
diff --git a/src/tests/unittests/validation/InputStateValidationTests.cpp b/src/tests/unittests/validation/VertexInputValidationTests.cpp
similarity index 70%
rename from src/tests/unittests/validation/InputStateValidationTests.cpp
rename to src/tests/unittests/validation/VertexInputValidationTests.cpp
index 4799817..d208fc3 100644
--- a/src/tests/unittests/validation/InputStateValidationTests.cpp
+++ b/src/tests/unittests/validation/VertexInputValidationTests.cpp
@@ -17,15 +17,15 @@
#include "utils/ComboRenderPipelineDescriptor.h"
#include "utils/DawnHelpers.h"
-class InputStateTest : public ValidationTest {
- protected:
- void CreatePipeline(bool success,
- const utils::ComboInputStateDescriptor& state,
- std::string vertexSource) {
- dawn::ShaderModule vsModule =
- utils::CreateShaderModule(device, dawn::ShaderStage::Vertex, vertexSource.c_str());
- dawn::ShaderModule fsModule =
- utils::CreateShaderModule(device, dawn::ShaderStage::Fragment, R"(
+class VertexInputTest : public ValidationTest {
+ protected:
+ void CreatePipeline(bool success,
+ const utils::ComboVertexInputDescriptor& state,
+ std::string vertexSource) {
+ dawn::ShaderModule vsModule =
+ utils::CreateShaderModule(device, dawn::ShaderStage::Vertex, vertexSource.c_str());
+ dawn::ShaderModule fsModule =
+ utils::CreateShaderModule(device, dawn::ShaderStage::Fragment, R"(
#version 450
layout(location = 0) out vec4 fragColor;
void main() {
@@ -33,23 +33,23 @@
}
)");
- utils::ComboRenderPipelineDescriptor descriptor(device);
- descriptor.cVertexStage.module = vsModule;
- descriptor.cFragmentStage.module = fsModule;
- descriptor.inputState = &state;
- descriptor.cColorStates[0]->format = dawn::TextureFormat::R8G8B8A8Unorm;
+ utils::ComboRenderPipelineDescriptor descriptor(device);
+ descriptor.cVertexStage.module = vsModule;
+ descriptor.cFragmentStage.module = fsModule;
+ descriptor.vertexInput = &state;
+ descriptor.cColorStates[0]->format = dawn::TextureFormat::R8G8B8A8Unorm;
- if (!success) {
- ASSERT_DEVICE_ERROR(device.CreateRenderPipeline(&descriptor));
- } else {
- device.CreateRenderPipeline(&descriptor);
- }
- }
+ if (!success) {
+ ASSERT_DEVICE_ERROR(device.CreateRenderPipeline(&descriptor));
+ } else {
+ device.CreateRenderPipeline(&descriptor);
+ }
+ }
};
// Check an empty input state is valid
-TEST_F(InputStateTest, EmptyIsOk) {
- utils::ComboInputStateDescriptor state;
+TEST_F(VertexInputTest, EmptyIsOk) {
+ utils::ComboVertexInputDescriptor state;
CreatePipeline(true, state, R"(
#version 450
void main() {
@@ -58,11 +58,11 @@
)");
}
-// Check validation that pipeline vertex inputs are backed by attributes in the input state
-TEST_F(InputStateTest, PipelineCompatibility) {
- utils::ComboInputStateDescriptor state;
- state.numInputs = 1;
- state.cInputs[0].stride = 2 * sizeof(float);
+// Check validation that pipeline vertex buffers are backed by attributes in the vertex input
+TEST_F(VertexInputTest, PipelineCompatibility) {
+ utils::ComboVertexInputDescriptor state;
+ state.numBuffers = 1;
+ state.cBuffers[0].stride = 2 * sizeof(float);
state.numAttributes = 2;
state.cAttributes[1].shaderLocation = 1;
state.cAttributes[1].offset = sizeof(float);
@@ -77,7 +77,7 @@
}
)");
- // Check it is valid for the pipeline to use a subset of the InputState
+ // Check it is valid for the pipeline to use a subset of the VertexInput
CreatePipeline(true, state, R"(
#version 450
layout(location = 0) in vec4 a;
@@ -97,10 +97,10 @@
}
// Test that a stride of 0 is valid
-TEST_F(InputStateTest, StrideZero) {
+TEST_F(VertexInputTest, StrideZero) {
// Works ok without attributes
- utils::ComboInputStateDescriptor state;
- state.numInputs = 1;
+ utils::ComboVertexInputDescriptor state;
+ state.numBuffers = 1;
CreatePipeline(true, state, R"(
#version 450
void main() {
@@ -120,10 +120,10 @@
}
// Test that we cannot set an already set input
-TEST_F(InputStateTest, AlreadySetInput) {
+TEST_F(VertexInputTest, AlreadySetInput) {
// Control case
- utils::ComboInputStateDescriptor state;
- state.numInputs = 1;
+ utils::ComboVertexInputDescriptor state;
+ state.numBuffers = 1;
CreatePipeline(true, state, R"(
#version 450
void main() {
@@ -132,7 +132,7 @@
)");
// Oh no, input 0 is set twice
- state.numInputs = 2;
+ state.numBuffers = 2;
CreatePipeline(false, state, R"(
#version 450
void main() {
@@ -142,11 +142,11 @@
}
// Check out of bounds condition on input slot
-TEST_F(InputStateTest, SetInputSlotOutOfBounds) {
+TEST_F(VertexInputTest, SetInputSlotOutOfBounds) {
// Control case, setting last input slot
- utils::ComboInputStateDescriptor state;
- state.numInputs = 1;
- state.cInputs[0].inputSlot = kMaxVertexInputs - 1;
+ utils::ComboVertexInputDescriptor state;
+ state.numBuffers = 1;
+ state.cBuffers[0].inputSlot = kMaxVertexBuffers - 1;
CreatePipeline(true, state, R"(
#version 450
void main() {
@@ -155,7 +155,7 @@
)");
// Test input slot OOB
- state.cInputs[0].inputSlot = kMaxVertexInputs;
+ state.cBuffers[0].inputSlot = kMaxVertexBuffers;
CreatePipeline(false, state, R"(
#version 450
void main() {
@@ -165,11 +165,11 @@
}
// Check out of bounds condition on input stride
-TEST_F(InputStateTest, SetInputStrideOutOfBounds) {
+TEST_F(VertexInputTest, SetInputStrideOutOfBounds) {
// Control case, setting max input stride
- utils::ComboInputStateDescriptor state;
- state.numInputs = 1;
- state.cInputs[0].stride = kMaxVertexInputStride;
+ utils::ComboVertexInputDescriptor state;
+ state.numBuffers = 1;
+ state.cBuffers[0].stride = kMaxVertexBufferStride;
CreatePipeline(true, state, R"(
#version 450
void main() {
@@ -178,7 +178,7 @@
)");
// Test input stride OOB
- state.cInputs[0].stride = kMaxVertexInputStride + 1;
+ state.cBuffers[0].stride = kMaxVertexBufferStride + 1;
CreatePipeline(false, state, R"(
#version 450
void main() {
@@ -188,10 +188,10 @@
}
// Test that we cannot set an already set attribute
-TEST_F(InputStateTest, AlreadySetAttribute) {
+TEST_F(VertexInputTest, AlreadySetAttribute) {
// Control case, setting last attribute
- utils::ComboInputStateDescriptor state;
- state.numInputs = 1;
+ utils::ComboVertexInputDescriptor state;
+ state.numBuffers = 1;
state.numAttributes = 1;
CreatePipeline(true, state, R"(
#version 450
@@ -211,10 +211,10 @@
}
// Check out of bounds condition on attribute shader location
-TEST_F(InputStateTest, SetAttributeLocationOutOfBounds) {
+TEST_F(VertexInputTest, SetAttributeLocationOutOfBounds) {
// Control case, setting last attribute shader location
- utils::ComboInputStateDescriptor state;
- state.numInputs = 1;
+ utils::ComboVertexInputDescriptor state;
+ state.numBuffers = 1;
state.numAttributes = 1;
state.cAttributes[0].shaderLocation = kMaxVertexAttributes - 1;
CreatePipeline(true, state, R"(
@@ -235,10 +235,10 @@
}
// Check attribute offset out of bounds
-TEST_F(InputStateTest, SetAttributeOffsetOutOfBounds) {
+TEST_F(VertexInputTest, SetAttributeOffsetOutOfBounds) {
// Control case, setting max attribute offset for FloatR32 vertex format
- utils::ComboInputStateDescriptor state;
- state.numInputs = 1;
+ utils::ComboVertexInputDescriptor state;
+ state.numBuffers = 1;
state.numAttributes = 1;
state.cAttributes[0].offset = kMaxVertexAttributeEnd - sizeof(dawn::VertexFormat::Float);
CreatePipeline(true, state, R"(
@@ -259,9 +259,9 @@
}
// Check attribute offset overflow
-TEST_F(InputStateTest, SetAttributeOffsetOverflow) {
- utils::ComboInputStateDescriptor state;
- state.numInputs = 1;
+TEST_F(VertexInputTest, SetAttributeOffsetOverflow) {
+ utils::ComboVertexInputDescriptor state;
+ state.numBuffers = 1;
state.numAttributes = 1;
state.cAttributes[0].offset = std::numeric_limits<uint32_t>::max();
CreatePipeline(false, state, R"(
@@ -273,10 +273,10 @@
}
// Check that all attributes must be backed by an input
-TEST_F(InputStateTest, RequireInputForAttribute) {
+TEST_F(VertexInputTest, RequireInputForAttribute) {
// Control case
- utils::ComboInputStateDescriptor state;
- state.numInputs = 1;
+ utils::ComboVertexInputDescriptor state;
+ state.numBuffers = 1;
state.numAttributes = 1;
CreatePipeline(true, state, R"(
#version 450
@@ -296,10 +296,10 @@
}
// Check OOB checks for an attribute's input
-TEST_F(InputStateTest, SetAttributeOOBCheckForInputs) {
+TEST_F(VertexInputTest, SetAttributeOOBCheckForInputs) {
// Control case
- utils::ComboInputStateDescriptor state;
- state.numInputs = 1;
+ utils::ComboVertexInputDescriptor state;
+ state.numBuffers = 1;
state.numAttributes = 1;
CreatePipeline(true, state, R"(
#version 450
diff --git a/src/tests/unittests/wire/WireArgumentTests.cpp b/src/tests/unittests/wire/WireArgumentTests.cpp
index 965ab2c..c63435a 100644
--- a/src/tests/unittests/wire/WireArgumentTests.cpp
+++ b/src/tests/unittests/wire/WireArgumentTests.cpp
@@ -97,13 +97,13 @@
colorStateDescriptor.writeMask = DAWN_COLOR_WRITE_MASK_ALL;
// Create the input state
- DawnInputStateDescriptor inputState;
- inputState.nextInChain = nullptr;
- inputState.indexFormat = DAWN_INDEX_FORMAT_UINT32;
- inputState.numInputs = 0;
- inputState.inputs = nullptr;
- inputState.numAttributes = 0;
- inputState.attributes = nullptr;
+ DawnVertexInputDescriptor vertexInput;
+ vertexInput.nextInChain = nullptr;
+ vertexInput.indexFormat = DAWN_INDEX_FORMAT_UINT32;
+ vertexInput.numBuffers = 0;
+ vertexInput.buffers = nullptr;
+ vertexInput.numAttributes = 0;
+ vertexInput.attributes = nullptr;
// Create the rasterization state
DawnRasterizationStateDescriptor rasterizationState;
@@ -162,7 +162,7 @@
pipelineDescriptor.sampleCount = 1;
pipelineDescriptor.layout = layout;
- pipelineDescriptor.inputState = &inputState;
+ pipelineDescriptor.vertexInput = &vertexInput;
pipelineDescriptor.primitiveTopology = DAWN_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
pipelineDescriptor.rasterizationState = &rasterizationState;
pipelineDescriptor.depthStencilState = &depthStencilState;
diff --git a/src/tests/unittests/wire/WireOptionalTests.cpp b/src/tests/unittests/wire/WireOptionalTests.cpp
index 02a3251..5a94a29 100644
--- a/src/tests/unittests/wire/WireOptionalTests.cpp
+++ b/src/tests/unittests/wire/WireOptionalTests.cpp
@@ -87,13 +87,13 @@
colorStateDescriptor.writeMask = DAWN_COLOR_WRITE_MASK_ALL;
// Create the input state
- DawnInputStateDescriptor inputState;
- inputState.nextInChain = nullptr;
- inputState.indexFormat = DAWN_INDEX_FORMAT_UINT32;
- inputState.numInputs = 0;
- inputState.inputs = nullptr;
- inputState.numAttributes = 0;
- inputState.attributes = nullptr;
+ DawnVertexInputDescriptor vertexInput;
+ vertexInput.nextInChain = nullptr;
+ vertexInput.indexFormat = DAWN_INDEX_FORMAT_UINT32;
+ vertexInput.numBuffers = 0;
+ vertexInput.buffers = nullptr;
+ vertexInput.numAttributes = 0;
+ vertexInput.attributes = nullptr;
// Create the rasterization state
DawnRasterizationStateDescriptor rasterizationState;
@@ -152,7 +152,7 @@
pipelineDescriptor.sampleCount = 1;
pipelineDescriptor.layout = layout;
- pipelineDescriptor.inputState = &inputState;
+ pipelineDescriptor.vertexInput = &vertexInput;
pipelineDescriptor.primitiveTopology = DAWN_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
pipelineDescriptor.rasterizationState = &rasterizationState;
diff --git a/src/utils/ComboRenderPipelineDescriptor.cpp b/src/utils/ComboRenderPipelineDescriptor.cpp
index e0a1a1a..ee0a3d5 100644
--- a/src/utils/ComboRenderPipelineDescriptor.cpp
+++ b/src/utils/ComboRenderPipelineDescriptor.cpp
@@ -18,21 +18,21 @@
namespace utils {
- ComboInputStateDescriptor::ComboInputStateDescriptor() {
- dawn::InputStateDescriptor* descriptor = this;
+ ComboVertexInputDescriptor::ComboVertexInputDescriptor() {
+ dawn::VertexInputDescriptor* descriptor = this;
descriptor->indexFormat = dawn::IndexFormat::Uint32;
- // 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;
+ // Fill the default values for vertexBuffer.
+ descriptor->numBuffers = 0;
+ dawn::VertexBufferDescriptor vertexBuffer;
+ vertexBuffer.inputSlot = 0;
+ vertexBuffer.stride = 0;
+ vertexBuffer.stepMode = dawn::InputStepMode::Vertex;
+ for (uint32_t i = 0; i < kMaxVertexBuffers; ++i) {
+ cBuffers[i] = vertexBuffer;
}
- descriptor->inputs = &cInputs[0];
+ descriptor->buffers = &cBuffers[0];
// Fill the default values for vertexAttribute.
descriptor->numAttributes = 0;
@@ -66,7 +66,7 @@
}
// Set defaults for the input state descriptors.
- descriptor->inputState = &cInputState;
+ descriptor->vertexInput = &cVertexInput;
// Set defaults for the rasterization state descriptor.
{
diff --git a/src/utils/ComboRenderPipelineDescriptor.h b/src/utils/ComboRenderPipelineDescriptor.h
index 69ab688..8be63d2 100644
--- a/src/utils/ComboRenderPipelineDescriptor.h
+++ b/src/utils/ComboRenderPipelineDescriptor.h
@@ -23,11 +23,11 @@
namespace utils {
- class ComboInputStateDescriptor : public dawn::InputStateDescriptor {
+ class ComboVertexInputDescriptor : public dawn::VertexInputDescriptor {
public:
- ComboInputStateDescriptor();
+ ComboVertexInputDescriptor();
- std::array<dawn::VertexInputDescriptor, kMaxVertexInputs> cInputs;
+ std::array<dawn::VertexBufferDescriptor, kMaxVertexBuffers> cBuffers;
std::array<dawn::VertexAttributeDescriptor, kMaxVertexAttributes> cAttributes;
};
@@ -38,7 +38,7 @@
dawn::PipelineStageDescriptor cVertexStage;
dawn::PipelineStageDescriptor cFragmentStage;
- ComboInputStateDescriptor cInputState;
+ ComboVertexInputDescriptor cVertexInput;
dawn::RasterizationStateDescriptor cRasterizationState;
std::array<dawn::ColorStateDescriptor*, kMaxColorAttachments> cColorStates;
dawn::DepthStencilStateDescriptor cDepthStencilState;