Update VertexInput (InputState) to match the spec - Part 2
This patch changed the front end code and tests and examples. BUG=dawn:80, dawn:107 Change-Id: Ia6c60232c04a1bfb862263766eb28e9afc3bc8db Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/7620 Commit-Queue: Yunchao He <yunchao.he@intel.com> Reviewed-by: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
parent
9cd21f1bf9
commit
97c0885a4a
|
@ -576,7 +576,6 @@
|
||||||
"extensible": false,
|
"extensible": false,
|
||||||
"members": [
|
"members": [
|
||||||
{"name": "shader location", "type": "uint32_t"},
|
{"name": "shader location", "type": "uint32_t"},
|
||||||
{"name": "input slot", "type": "uint32_t"},
|
|
||||||
{"name": "offset", "type": "uint64_t"},
|
{"name": "offset", "type": "uint64_t"},
|
||||||
{"name": "format", "type": "vertex format"}
|
{"name": "format", "type": "vertex format"}
|
||||||
]
|
]
|
||||||
|
@ -585,9 +584,10 @@
|
||||||
"category": "structure",
|
"category": "structure",
|
||||||
"extensible": false,
|
"extensible": false,
|
||||||
"members": [
|
"members": [
|
||||||
{"name": "input slot", "type": "uint32_t"},
|
|
||||||
{"name": "stride", "type": "uint64_t"},
|
{"name": "stride", "type": "uint64_t"},
|
||||||
{"name": "step mode", "type": "input step mode"}
|
{"name": "step mode", "type": "input step mode"},
|
||||||
|
{"name": "num attributes", "type": "uint32_t"},
|
||||||
|
{"name": "attributes", "type": "vertex attribute descriptor", "annotation": "const*", "length": "num attributes"}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"vertex input descriptor": {
|
"vertex input descriptor": {
|
||||||
|
@ -595,8 +595,6 @@
|
||||||
"extensible": true,
|
"extensible": true,
|
||||||
"members": [
|
"members": [
|
||||||
{"name": "index format", "type": "index format"},
|
{"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 buffers", "type": "uint32_t"},
|
{"name": "num buffers", "type": "uint32_t"},
|
||||||
{"name": "buffers", "type": "vertex buffer descriptor", "annotation": "const*", "length": "num buffers"}
|
{"name": "buffers", "type": "vertex buffer descriptor", "annotation": "const*", "length": "num buffers"}
|
||||||
]
|
]
|
||||||
|
|
|
@ -98,8 +98,6 @@ void init() {
|
||||||
vertexInput.indexFormat = DAWN_INDEX_FORMAT_UINT32;
|
vertexInput.indexFormat = DAWN_INDEX_FORMAT_UINT32;
|
||||||
vertexInput.numBuffers = 0;
|
vertexInput.numBuffers = 0;
|
||||||
vertexInput.buffers = nullptr;
|
vertexInput.buffers = nullptr;
|
||||||
vertexInput.numAttributes = 0;
|
|
||||||
vertexInput.attributes = nullptr;
|
|
||||||
descriptor.vertexInput = &vertexInput;
|
descriptor.vertexInput = &vertexInput;
|
||||||
|
|
||||||
DawnRasterizationStateDescriptor rasterizationState;
|
DawnRasterizationStateDescriptor rasterizationState;
|
||||||
|
|
|
@ -120,20 +120,20 @@ void initRender() {
|
||||||
descriptor.cVertexStage.module = vsModule;
|
descriptor.cVertexStage.module = vsModule;
|
||||||
descriptor.cFragmentStage.module = fsModule;
|
descriptor.cFragmentStage.module = fsModule;
|
||||||
|
|
||||||
descriptor.cVertexInput.numAttributes = 3;
|
descriptor.cVertexInput.numBuffers = 2;
|
||||||
|
descriptor.cVertexInput.cBuffers[0].stride = sizeof(Particle);
|
||||||
|
descriptor.cVertexInput.cBuffers[0].stepMode = dawn::InputStepMode::Instance;
|
||||||
|
descriptor.cVertexInput.cBuffers[0].numAttributes = 2;
|
||||||
descriptor.cVertexInput.cAttributes[0].offset = offsetof(Particle, pos);
|
descriptor.cVertexInput.cAttributes[0].offset = offsetof(Particle, pos);
|
||||||
descriptor.cVertexInput.cAttributes[0].format = dawn::VertexFormat::Float2;
|
descriptor.cVertexInput.cAttributes[0].format = dawn::VertexFormat::Float2;
|
||||||
descriptor.cVertexInput.cAttributes[1].shaderLocation = 1;
|
descriptor.cVertexInput.cAttributes[1].shaderLocation = 1;
|
||||||
descriptor.cVertexInput.cAttributes[1].offset = offsetof(Particle, vel);
|
descriptor.cVertexInput.cAttributes[1].offset = offsetof(Particle, vel);
|
||||||
descriptor.cVertexInput.cAttributes[1].format = dawn::VertexFormat::Float2;
|
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.cVertexInput.cBuffers[1].stride = sizeof(glm::vec2);
|
||||||
|
descriptor.cVertexInput.cBuffers[1].numAttributes = 1;
|
||||||
|
descriptor.cVertexInput.cBuffers[1].attributes = &descriptor.cVertexInput.cAttributes[2];
|
||||||
|
descriptor.cVertexInput.cAttributes[2].shaderLocation = 2;
|
||||||
|
descriptor.cVertexInput.cAttributes[2].format = dawn::VertexFormat::Float2;
|
||||||
descriptor.depthStencilState = &descriptor.cDepthStencilState;
|
descriptor.depthStencilState = &descriptor.cDepthStencilState;
|
||||||
descriptor.cDepthStencilState.format = dawn::TextureFormat::D32FloatS8Uint;
|
descriptor.cDepthStencilState.format = dawn::TextureFormat::D32FloatS8Uint;
|
||||||
descriptor.cColorStates[0]->format = GetPreferredSwapChainTextureFormat();
|
descriptor.cColorStates[0]->format = GetPreferredSwapChainTextureFormat();
|
||||||
|
|
|
@ -125,10 +125,10 @@ void init() {
|
||||||
descriptor.layout = utils::MakeBasicPipelineLayout(device, &bgl);
|
descriptor.layout = utils::MakeBasicPipelineLayout(device, &bgl);
|
||||||
descriptor.cVertexStage.module = vsModule;
|
descriptor.cVertexStage.module = vsModule;
|
||||||
descriptor.cFragmentStage.module = fsModule;
|
descriptor.cFragmentStage.module = fsModule;
|
||||||
descriptor.cVertexInput.numAttributes = 1;
|
|
||||||
descriptor.cVertexInput.cAttributes[0].format = dawn::VertexFormat::Float4;
|
|
||||||
descriptor.cVertexInput.numBuffers = 1;
|
descriptor.cVertexInput.numBuffers = 1;
|
||||||
descriptor.cVertexInput.cBuffers[0].stride = 4 * sizeof(float);
|
descriptor.cVertexInput.cBuffers[0].stride = 4 * sizeof(float);
|
||||||
|
descriptor.cVertexInput.cBuffers[0].numAttributes = 1;
|
||||||
|
descriptor.cVertexInput.cAttributes[0].format = dawn::VertexFormat::Float4;
|
||||||
descriptor.depthStencilState = &descriptor.cDepthStencilState;
|
descriptor.depthStencilState = &descriptor.cDepthStencilState;
|
||||||
descriptor.cDepthStencilState.format = dawn::TextureFormat::D32FloatS8Uint;
|
descriptor.cDepthStencilState.format = dawn::TextureFormat::D32FloatS8Uint;
|
||||||
descriptor.cColorStates[0]->format = GetPreferredSwapChainTextureFormat();
|
descriptor.cColorStates[0]->format = GetPreferredSwapChainTextureFormat();
|
||||||
|
|
|
@ -157,7 +157,7 @@ void init() {
|
||||||
})");
|
})");
|
||||||
|
|
||||||
utils::ComboVertexInputDescriptor vertexInput;
|
utils::ComboVertexInputDescriptor vertexInput;
|
||||||
vertexInput.numAttributes = 2;
|
vertexInput.cBuffers[0].numAttributes = 2;
|
||||||
vertexInput.cAttributes[0].format = dawn::VertexFormat::Float3;
|
vertexInput.cAttributes[0].format = dawn::VertexFormat::Float3;
|
||||||
vertexInput.cAttributes[1].shaderLocation = 1;
|
vertexInput.cAttributes[1].shaderLocation = 1;
|
||||||
vertexInput.cAttributes[1].offset = 3 * sizeof(float);
|
vertexInput.cAttributes[1].offset = 3 * sizeof(float);
|
||||||
|
|
|
@ -25,54 +25,49 @@ namespace dawn_native {
|
||||||
// Helper functions
|
// Helper functions
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
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 (buffer->stride > kMaxVertexBufferStride) {
|
|
||||||
return DAWN_VALIDATION_ERROR("Setting input stride out of bounds");
|
|
||||||
}
|
|
||||||
if ((*inputsSetMask)[buffer->inputSlot]) {
|
|
||||||
return DAWN_VALIDATION_ERROR("Setting already set vertex buffer");
|
|
||||||
}
|
|
||||||
|
|
||||||
inputsSetMask->set(buffer->inputSlot);
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
MaybeError ValidateVertexAttributeDescriptor(
|
MaybeError ValidateVertexAttributeDescriptor(
|
||||||
const VertexAttributeDescriptor* attribute,
|
const VertexAttributeDescriptor* attribute,
|
||||||
const std::bitset<kMaxVertexBuffers>* inputsSetMask,
|
uint64_t vertexBufferStride,
|
||||||
std::bitset<kMaxVertexAttributes>* attributesSetMask) {
|
std::bitset<kMaxVertexAttributes>* attributesSetMask) {
|
||||||
DAWN_TRY(ValidateVertexFormat(attribute->format));
|
DAWN_TRY(ValidateVertexFormat(attribute->format));
|
||||||
|
|
||||||
if (attribute->shaderLocation >= kMaxVertexAttributes) {
|
if (attribute->shaderLocation >= kMaxVertexAttributes) {
|
||||||
return DAWN_VALIDATION_ERROR("Setting attribute out of bounds");
|
return DAWN_VALIDATION_ERROR("Setting attribute out of bounds");
|
||||||
}
|
}
|
||||||
if (attribute->inputSlot >= kMaxVertexBuffers) {
|
|
||||||
return DAWN_VALIDATION_ERROR("Binding slot out of bounds");
|
|
||||||
}
|
|
||||||
ASSERT(kMaxVertexAttributeEnd >= VertexFormatSize(attribute->format));
|
ASSERT(kMaxVertexAttributeEnd >= VertexFormatSize(attribute->format));
|
||||||
if (attribute->offset > kMaxVertexAttributeEnd - VertexFormatSize(attribute->format)) {
|
ASSERT(vertexBufferStride == 0 ||
|
||||||
|
vertexBufferStride >= VertexFormatSize(attribute->format));
|
||||||
|
if (attribute->offset > kMaxVertexAttributeEnd - VertexFormatSize(attribute->format) ||
|
||||||
|
(vertexBufferStride > 0 &&
|
||||||
|
attribute->offset + VertexFormatSize(attribute->format) > vertexBufferStride)) {
|
||||||
return DAWN_VALIDATION_ERROR("Setting attribute offset out of bounds");
|
return DAWN_VALIDATION_ERROR("Setting attribute offset out of bounds");
|
||||||
}
|
}
|
||||||
if ((*attributesSetMask)[attribute->shaderLocation]) {
|
if ((*attributesSetMask)[attribute->shaderLocation]) {
|
||||||
return DAWN_VALIDATION_ERROR("Setting already set attribute");
|
return DAWN_VALIDATION_ERROR("Setting already set attribute");
|
||||||
}
|
}
|
||||||
if (!(*inputsSetMask)[attribute->inputSlot]) {
|
|
||||||
return DAWN_VALIDATION_ERROR(
|
|
||||||
"Vertex attribute slot doesn't match any vertex input slot");
|
|
||||||
}
|
|
||||||
|
|
||||||
attributesSetMask->set(attribute->shaderLocation);
|
attributesSetMask->set(attribute->shaderLocation);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MaybeError ValidateVertexBufferDescriptor(
|
||||||
|
const VertexBufferDescriptor* buffer,
|
||||||
|
std::bitset<kMaxVertexAttributes>* attributesSetMask) {
|
||||||
|
DAWN_TRY(ValidateInputStepMode(buffer->stepMode));
|
||||||
|
if (buffer->stride > kMaxVertexBufferStride) {
|
||||||
|
return DAWN_VALIDATION_ERROR("Setting input stride out of bounds");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < buffer->numAttributes; ++i) {
|
||||||
|
DAWN_TRY(ValidateVertexAttributeDescriptor(&buffer->attributes[i], buffer->stride,
|
||||||
|
attributesSetMask));
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
MaybeError ValidateVertexInputDescriptor(
|
MaybeError ValidateVertexInputDescriptor(
|
||||||
const VertexInputDescriptor* descriptor,
|
const VertexInputDescriptor* descriptor,
|
||||||
std::bitset<kMaxVertexBuffers>* inputsSetMask,
|
|
||||||
std::bitset<kMaxVertexAttributes>* attributesSetMask) {
|
std::bitset<kMaxVertexAttributes>* attributesSetMask) {
|
||||||
if (descriptor->nextInChain != nullptr) {
|
if (descriptor->nextInChain != nullptr) {
|
||||||
return DAWN_VALIDATION_ERROR("nextInChain must be nullptr");
|
return DAWN_VALIDATION_ERROR("nextInChain must be nullptr");
|
||||||
|
@ -82,18 +77,19 @@ namespace dawn_native {
|
||||||
if (descriptor->numBuffers > kMaxVertexBuffers) {
|
if (descriptor->numBuffers > kMaxVertexBuffers) {
|
||||||
return DAWN_VALIDATION_ERROR("Vertex Inputs number exceeds maximum");
|
return DAWN_VALIDATION_ERROR("Vertex Inputs number exceeds maximum");
|
||||||
}
|
}
|
||||||
if (descriptor->numAttributes > kMaxVertexAttributes) {
|
|
||||||
return DAWN_VALIDATION_ERROR("Vertex Attributes number exceeds maximum");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
uint32_t totalAttributesNum = 0;
|
||||||
for (uint32_t i = 0; i < descriptor->numBuffers; ++i) {
|
for (uint32_t i = 0; i < descriptor->numBuffers; ++i) {
|
||||||
DAWN_TRY(ValidateVertexBufferDescriptor(&descriptor->buffers[i], inputsSetMask));
|
DAWN_TRY(
|
||||||
|
ValidateVertexBufferDescriptor(&descriptor->buffers[i], attributesSetMask));
|
||||||
|
totalAttributesNum += descriptor->buffers[i].numAttributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t i = 0; i < descriptor->numAttributes; ++i) {
|
// Every vertex attribute has a member called shaderLocation, and there are some
|
||||||
DAWN_TRY(ValidateVertexAttributeDescriptor(&descriptor->attributes[i],
|
// requirements for shaderLocation: 1) >=0, 2) values are different across different
|
||||||
inputsSetMask, attributesSetMask));
|
// attributes, 3) can't exceed kMaxVertexAttributes. So it can ensure that total
|
||||||
}
|
// attribute number never exceed kMaxVertexAttributes.
|
||||||
|
ASSERT(totalAttributesNum <= kMaxVertexAttributes);
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -266,10 +262,8 @@ namespace dawn_native {
|
||||||
return DAWN_VALIDATION_ERROR("Input state must not be null");
|
return DAWN_VALIDATION_ERROR("Input state must not be null");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::bitset<kMaxVertexBuffers> inputsSetMask;
|
|
||||||
std::bitset<kMaxVertexAttributes> attributesSetMask;
|
std::bitset<kMaxVertexAttributes> attributesSetMask;
|
||||||
DAWN_TRY(ValidateVertexInputDescriptor(descriptor->vertexInput, &inputsSetMask,
|
DAWN_TRY(ValidateVertexInputDescriptor(descriptor->vertexInput, &attributesSetMask));
|
||||||
&attributesSetMask));
|
|
||||||
DAWN_TRY(ValidatePrimitiveTopology(descriptor->primitiveTopology));
|
DAWN_TRY(ValidatePrimitiveTopology(descriptor->primitiveTopology));
|
||||||
DAWN_TRY(ValidatePipelineStageDescriptor(device, descriptor->vertexStage,
|
DAWN_TRY(ValidatePipelineStageDescriptor(device, descriptor->vertexStage,
|
||||||
descriptor->layout, dawn::ShaderStage::Vertex));
|
descriptor->layout, dawn::ShaderStage::Vertex));
|
||||||
|
@ -344,17 +338,21 @@ namespace dawn_native {
|
||||||
mFragmentModule(descriptor->fragmentStage->module),
|
mFragmentModule(descriptor->fragmentStage->module),
|
||||||
mFragmentEntryPoint(descriptor->fragmentStage->entryPoint),
|
mFragmentEntryPoint(descriptor->fragmentStage->entryPoint),
|
||||||
mIsBlueprint(blueprint) {
|
mIsBlueprint(blueprint) {
|
||||||
uint32_t location = 0;
|
for (uint32_t slot = 0; slot < mVertexInput.numBuffers; ++slot) {
|
||||||
for (uint32_t i = 0; i < mVertexInput.numAttributes; ++i) {
|
|
||||||
location = mVertexInput.attributes[i].shaderLocation;
|
|
||||||
mAttributesSetMask.set(location);
|
|
||||||
mAttributeInfos[location] = mVertexInput.attributes[i];
|
|
||||||
}
|
|
||||||
uint32_t slot = 0;
|
|
||||||
for (uint32_t i = 0; i < mVertexInput.numBuffers; ++i) {
|
|
||||||
slot = mVertexInput.buffers[i].inputSlot;
|
|
||||||
mInputsSetMask.set(slot);
|
mInputsSetMask.set(slot);
|
||||||
mInputInfos[slot] = mVertexInput.buffers[i];
|
mInputInfos[slot].inputSlot = slot;
|
||||||
|
mInputInfos[slot].stride = mVertexInput.buffers[slot].stride;
|
||||||
|
mInputInfos[slot].stepMode = mVertexInput.buffers[slot].stepMode;
|
||||||
|
|
||||||
|
uint32_t location = 0;
|
||||||
|
for (uint32_t i = 0; i < mVertexInput.buffers[slot].numAttributes; ++i) {
|
||||||
|
location = mVertexInput.buffers[slot].attributes[i].shaderLocation;
|
||||||
|
mAttributesSetMask.set(location);
|
||||||
|
mAttributeInfos[location].shaderLocation = location;
|
||||||
|
mAttributeInfos[location].inputSlot = slot;
|
||||||
|
mAttributeInfos[location].offset = mVertexInput.buffers[slot].attributes[i].offset;
|
||||||
|
mAttributeInfos[location].format = mVertexInput.buffers[slot].attributes[i].format;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mHasDepthStencilAttachment) {
|
if (mHasDepthStencilAttachment) {
|
||||||
|
@ -413,7 +411,7 @@ namespace dawn_native {
|
||||||
return mAttributesSetMask;
|
return mAttributesSetMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
const VertexAttributeDescriptor& RenderPipelineBase::GetAttribute(uint32_t location) const {
|
const VertexAttributeInfo& RenderPipelineBase::GetAttribute(uint32_t location) const {
|
||||||
ASSERT(!IsError());
|
ASSERT(!IsError());
|
||||||
ASSERT(mAttributesSetMask[location]);
|
ASSERT(mAttributesSetMask[location]);
|
||||||
return mAttributeInfos[location];
|
return mAttributeInfos[location];
|
||||||
|
@ -424,7 +422,7 @@ namespace dawn_native {
|
||||||
return mInputsSetMask;
|
return mInputsSetMask;
|
||||||
}
|
}
|
||||||
|
|
||||||
const VertexBufferDescriptor& RenderPipelineBase::GetInput(uint32_t slot) const {
|
const VertexBufferInfo& RenderPipelineBase::GetInput(uint32_t slot) const {
|
||||||
ASSERT(!IsError());
|
ASSERT(!IsError());
|
||||||
ASSERT(mInputsSetMask[slot]);
|
ASSERT(mInputsSetMask[slot]);
|
||||||
return mInputInfos[slot];
|
return mInputInfos[slot];
|
||||||
|
@ -553,13 +551,13 @@ namespace dawn_native {
|
||||||
// Hash vertex input state
|
// Hash vertex input state
|
||||||
HashCombine(&hash, pipeline->mAttributesSetMask);
|
HashCombine(&hash, pipeline->mAttributesSetMask);
|
||||||
for (uint32_t i : IterateBitSet(pipeline->mAttributesSetMask)) {
|
for (uint32_t i : IterateBitSet(pipeline->mAttributesSetMask)) {
|
||||||
const VertexAttributeDescriptor& desc = pipeline->GetAttribute(i);
|
const VertexAttributeInfo& desc = pipeline->GetAttribute(i);
|
||||||
HashCombine(&hash, desc.shaderLocation, desc.inputSlot, desc.offset, desc.format);
|
HashCombine(&hash, desc.shaderLocation, desc.inputSlot, desc.offset, desc.format);
|
||||||
}
|
}
|
||||||
|
|
||||||
HashCombine(&hash, pipeline->mInputsSetMask);
|
HashCombine(&hash, pipeline->mInputsSetMask);
|
||||||
for (uint32_t i : IterateBitSet(pipeline->mInputsSetMask)) {
|
for (uint32_t i : IterateBitSet(pipeline->mInputsSetMask)) {
|
||||||
const VertexBufferDescriptor& desc = pipeline->GetInput(i);
|
const VertexBufferInfo& desc = pipeline->GetInput(i);
|
||||||
HashCombine(&hash, desc.inputSlot, desc.stride, desc.stepMode);
|
HashCombine(&hash, desc.inputSlot, desc.stride, desc.stepMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -644,8 +642,8 @@ namespace dawn_native {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t i : IterateBitSet(a->mAttributesSetMask)) {
|
for (uint32_t i : IterateBitSet(a->mAttributesSetMask)) {
|
||||||
const VertexAttributeDescriptor& descA = a->GetAttribute(i);
|
const VertexAttributeInfo& descA = a->GetAttribute(i);
|
||||||
const VertexAttributeDescriptor& descB = b->GetAttribute(i);
|
const VertexAttributeInfo& descB = b->GetAttribute(i);
|
||||||
if (descA.shaderLocation != descB.shaderLocation ||
|
if (descA.shaderLocation != descB.shaderLocation ||
|
||||||
descA.inputSlot != descB.inputSlot || descA.offset != descB.offset ||
|
descA.inputSlot != descB.inputSlot || descA.offset != descB.offset ||
|
||||||
descA.format != descB.format) {
|
descA.format != descB.format) {
|
||||||
|
@ -658,8 +656,8 @@ namespace dawn_native {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t i : IterateBitSet(a->mInputsSetMask)) {
|
for (uint32_t i : IterateBitSet(a->mInputsSetMask)) {
|
||||||
const VertexBufferDescriptor& descA = a->GetInput(i);
|
const VertexBufferInfo& descA = a->GetInput(i);
|
||||||
const VertexBufferDescriptor& descB = b->GetInput(i);
|
const VertexBufferInfo& descB = b->GetInput(i);
|
||||||
if (descA.inputSlot != descB.inputSlot || descA.stride != descB.stride ||
|
if (descA.inputSlot != descB.inputSlot || descA.stride != descB.stride ||
|
||||||
descA.stepMode != descB.stepMode) {
|
descA.stepMode != descB.stepMode) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -38,6 +38,19 @@ namespace dawn_native {
|
||||||
bool StencilTestEnabled(const DepthStencilStateDescriptor* mDepthStencilState);
|
bool StencilTestEnabled(const DepthStencilStateDescriptor* mDepthStencilState);
|
||||||
bool BlendEnabled(const ColorStateDescriptor* mColorState);
|
bool BlendEnabled(const ColorStateDescriptor* mColorState);
|
||||||
|
|
||||||
|
struct VertexAttributeInfo {
|
||||||
|
uint32_t shaderLocation;
|
||||||
|
uint32_t inputSlot;
|
||||||
|
uint64_t offset;
|
||||||
|
dawn::VertexFormat format;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VertexBufferInfo {
|
||||||
|
uint32_t inputSlot;
|
||||||
|
uint64_t stride;
|
||||||
|
dawn::InputStepMode stepMode;
|
||||||
|
};
|
||||||
|
|
||||||
class RenderPipelineBase : public PipelineBase {
|
class RenderPipelineBase : public PipelineBase {
|
||||||
public:
|
public:
|
||||||
RenderPipelineBase(DeviceBase* device,
|
RenderPipelineBase(DeviceBase* device,
|
||||||
|
@ -49,9 +62,9 @@ namespace dawn_native {
|
||||||
|
|
||||||
const VertexInputDescriptor* GetVertexInputDescriptor() const;
|
const VertexInputDescriptor* GetVertexInputDescriptor() const;
|
||||||
const std::bitset<kMaxVertexAttributes>& GetAttributesSetMask() const;
|
const std::bitset<kMaxVertexAttributes>& GetAttributesSetMask() const;
|
||||||
const VertexAttributeDescriptor& GetAttribute(uint32_t location) const;
|
const VertexAttributeInfo& GetAttribute(uint32_t location) const;
|
||||||
const std::bitset<kMaxVertexBuffers>& GetInputsSetMask() const;
|
const std::bitset<kMaxVertexBuffers>& GetInputsSetMask() const;
|
||||||
const VertexBufferDescriptor& GetInput(uint32_t slot) const;
|
const VertexBufferInfo& GetInput(uint32_t slot) const;
|
||||||
|
|
||||||
const ColorStateDescriptor* GetColorStateDescriptor(uint32_t attachmentSlot) const;
|
const ColorStateDescriptor* GetColorStateDescriptor(uint32_t attachmentSlot) const;
|
||||||
const DepthStencilStateDescriptor* GetDepthStencilStateDescriptor() const;
|
const DepthStencilStateDescriptor* GetDepthStencilStateDescriptor() const;
|
||||||
|
@ -85,9 +98,9 @@ namespace dawn_native {
|
||||||
// Vertex input
|
// Vertex input
|
||||||
VertexInputDescriptor mVertexInput;
|
VertexInputDescriptor mVertexInput;
|
||||||
std::bitset<kMaxVertexAttributes> mAttributesSetMask;
|
std::bitset<kMaxVertexAttributes> mAttributesSetMask;
|
||||||
std::array<VertexAttributeDescriptor, kMaxVertexAttributes> mAttributeInfos;
|
std::array<VertexAttributeInfo, kMaxVertexAttributes> mAttributeInfos;
|
||||||
std::bitset<kMaxVertexBuffers> mInputsSetMask;
|
std::bitset<kMaxVertexBuffers> mInputsSetMask;
|
||||||
std::array<VertexBufferDescriptor, kMaxVertexBuffers> mInputInfos;
|
std::array<VertexBufferInfo, kMaxVertexBuffers> mInputInfos;
|
||||||
|
|
||||||
// Attachments
|
// Attachments
|
||||||
bool mHasDepthStencilAttachment = false;
|
bool mHasDepthStencilAttachment = false;
|
||||||
|
|
|
@ -400,7 +400,7 @@ namespace dawn_native { namespace d3d12 {
|
||||||
for (auto i : IterateBitSet(GetAttributesSetMask())) {
|
for (auto i : IterateBitSet(GetAttributesSetMask())) {
|
||||||
D3D12_INPUT_ELEMENT_DESC& inputElementDescriptor = (*inputElementDescriptors)[count++];
|
D3D12_INPUT_ELEMENT_DESC& inputElementDescriptor = (*inputElementDescriptors)[count++];
|
||||||
|
|
||||||
const VertexAttributeDescriptor& attribute = GetAttribute(i);
|
const VertexAttributeInfo& attribute = GetAttribute(i);
|
||||||
|
|
||||||
// If the HLSL semantic is TEXCOORDN the SemanticName should be "TEXCOORD" and the
|
// If the HLSL semantic is TEXCOORDN the SemanticName should be "TEXCOORD" and the
|
||||||
// SemanticIndex N
|
// SemanticIndex N
|
||||||
|
@ -409,7 +409,7 @@ namespace dawn_native { namespace d3d12 {
|
||||||
inputElementDescriptor.Format = VertexFormatType(attribute.format);
|
inputElementDescriptor.Format = VertexFormatType(attribute.format);
|
||||||
inputElementDescriptor.InputSlot = attribute.inputSlot;
|
inputElementDescriptor.InputSlot = attribute.inputSlot;
|
||||||
|
|
||||||
const VertexBufferDescriptor& input = GetInput(attribute.inputSlot);
|
const VertexBufferInfo& input = GetInput(attribute.inputSlot);
|
||||||
|
|
||||||
inputElementDescriptor.AlignedByteOffset = attribute.offset;
|
inputElementDescriptor.AlignedByteOffset = attribute.offset;
|
||||||
inputElementDescriptor.InputSlotClass = InputStepModeFunction(input.stepMode);
|
inputElementDescriptor.InputSlotClass = InputStepModeFunction(input.stepMode);
|
||||||
|
|
|
@ -405,7 +405,7 @@ namespace dawn_native { namespace metal {
|
||||||
MTLVertexDescriptor* mtlVertexDescriptor = [MTLVertexDescriptor new];
|
MTLVertexDescriptor* mtlVertexDescriptor = [MTLVertexDescriptor new];
|
||||||
|
|
||||||
for (uint32_t i : IterateBitSet(GetAttributesSetMask())) {
|
for (uint32_t i : IterateBitSet(GetAttributesSetMask())) {
|
||||||
const VertexAttributeDescriptor& info = GetAttribute(i);
|
const VertexAttributeInfo& info = GetAttribute(i);
|
||||||
|
|
||||||
auto attribDesc = [MTLVertexAttributeDescriptor new];
|
auto attribDesc = [MTLVertexAttributeDescriptor new];
|
||||||
attribDesc.format = VertexFormatType(info.format);
|
attribDesc.format = VertexFormatType(info.format);
|
||||||
|
@ -416,7 +416,7 @@ namespace dawn_native { namespace metal {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t i : IterateBitSet(GetInputsSetMask())) {
|
for (uint32_t i : IterateBitSet(GetInputsSetMask())) {
|
||||||
const VertexBufferDescriptor& info = GetInput(i);
|
const VertexBufferInfo& info = GetInput(i);
|
||||||
|
|
||||||
auto layoutDesc = [MTLVertexBufferLayoutDescriptor new];
|
auto layoutDesc = [MTLVertexBufferLayoutDescriptor new];
|
||||||
if (info.stride == 0) {
|
if (info.stride == 0) {
|
||||||
|
@ -425,7 +425,7 @@ namespace dawn_native { namespace metal {
|
||||||
// max(attrib.offset + sizeof(attrib) for each attrib)
|
// max(attrib.offset + sizeof(attrib) for each attrib)
|
||||||
size_t max_stride = 0;
|
size_t max_stride = 0;
|
||||||
for (uint32_t attribIndex : IterateBitSet(GetAttributesSetMask())) {
|
for (uint32_t attribIndex : IterateBitSet(GetAttributesSetMask())) {
|
||||||
const VertexAttributeDescriptor& attrib = GetAttribute(attribIndex);
|
const VertexAttributeInfo& attrib = GetAttribute(attribIndex);
|
||||||
// Only use the attributes that use the current input
|
// Only use the attributes that use the current input
|
||||||
if (attrib.inputSlot != info.inputSlot) {
|
if (attrib.inputSlot != info.inputSlot) {
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -48,7 +48,7 @@ class DestroyTest : public DawnTest {
|
||||||
descriptor.primitiveTopology = dawn::PrimitiveTopology::TriangleStrip;
|
descriptor.primitiveTopology = dawn::PrimitiveTopology::TriangleStrip;
|
||||||
descriptor.cVertexInput.numBuffers = 1;
|
descriptor.cVertexInput.numBuffers = 1;
|
||||||
descriptor.cVertexInput.cBuffers[0].stride = 4 * sizeof(float);
|
descriptor.cVertexInput.cBuffers[0].stride = 4 * sizeof(float);
|
||||||
descriptor.cVertexInput.numAttributes = 1;
|
descriptor.cVertexInput.cBuffers[0].numAttributes = 1;
|
||||||
descriptor.cVertexInput.cAttributes[0].format = dawn::VertexFormat::Float4;
|
descriptor.cVertexInput.cAttributes[0].format = dawn::VertexFormat::Float4;
|
||||||
descriptor.cColorStates[0]->format = renderPass.colorFormat;
|
descriptor.cColorStates[0]->format = renderPass.colorFormat;
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ class DrawIndexedTest : public DawnTest {
|
||||||
descriptor.primitiveTopology = dawn::PrimitiveTopology::TriangleStrip;
|
descriptor.primitiveTopology = dawn::PrimitiveTopology::TriangleStrip;
|
||||||
descriptor.cVertexInput.numBuffers = 1;
|
descriptor.cVertexInput.numBuffers = 1;
|
||||||
descriptor.cVertexInput.cBuffers[0].stride = 4 * sizeof(float);
|
descriptor.cVertexInput.cBuffers[0].stride = 4 * sizeof(float);
|
||||||
descriptor.cVertexInput.numAttributes = 1;
|
descriptor.cVertexInput.cBuffers[0].numAttributes = 1;
|
||||||
descriptor.cVertexInput.cAttributes[0].format = dawn::VertexFormat::Float4;
|
descriptor.cVertexInput.cAttributes[0].format = dawn::VertexFormat::Float4;
|
||||||
descriptor.cColorStates[0]->format = renderPass.colorFormat;
|
descriptor.cColorStates[0]->format = renderPass.colorFormat;
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ class DrawTest : public DawnTest {
|
||||||
descriptor.primitiveTopology = dawn::PrimitiveTopology::TriangleStrip;
|
descriptor.primitiveTopology = dawn::PrimitiveTopology::TriangleStrip;
|
||||||
descriptor.cVertexInput.numBuffers = 1;
|
descriptor.cVertexInput.numBuffers = 1;
|
||||||
descriptor.cVertexInput.cBuffers[0].stride = 4 * sizeof(float);
|
descriptor.cVertexInput.cBuffers[0].stride = 4 * sizeof(float);
|
||||||
descriptor.cVertexInput.numAttributes = 1;
|
descriptor.cVertexInput.cBuffers[0].numAttributes = 1;
|
||||||
descriptor.cVertexInput.cAttributes[0].format = dawn::VertexFormat::Float4;
|
descriptor.cVertexInput.cAttributes[0].format = dawn::VertexFormat::Float4;
|
||||||
descriptor.cColorStates[0]->format = renderPass.colorFormat;
|
descriptor.cColorStates[0]->format = renderPass.colorFormat;
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ class IndexFormatTest : public DawnTest {
|
||||||
descriptor.cVertexInput.indexFormat = format;
|
descriptor.cVertexInput.indexFormat = format;
|
||||||
descriptor.cVertexInput.numBuffers = 1;
|
descriptor.cVertexInput.numBuffers = 1;
|
||||||
descriptor.cVertexInput.cBuffers[0].stride = 4 * sizeof(float);
|
descriptor.cVertexInput.cBuffers[0].stride = 4 * sizeof(float);
|
||||||
descriptor.cVertexInput.numAttributes = 1;
|
descriptor.cVertexInput.cBuffers[0].numAttributes = 1;
|
||||||
descriptor.cVertexInput.cAttributes[0].format = dawn::VertexFormat::Float4;
|
descriptor.cVertexInput.cAttributes[0].format = dawn::VertexFormat::Float4;
|
||||||
descriptor.cColorStates[0]->format = renderPass.colorFormat;
|
descriptor.cColorStates[0]->format = renderPass.colorFormat;
|
||||||
|
|
||||||
|
|
|
@ -187,7 +187,7 @@ class PrimitiveTopologyTest : public DawnTest {
|
||||||
descriptor.primitiveTopology = primitiveTopology;
|
descriptor.primitiveTopology = primitiveTopology;
|
||||||
descriptor.cVertexInput.numBuffers = 1;
|
descriptor.cVertexInput.numBuffers = 1;
|
||||||
descriptor.cVertexInput.cBuffers[0].stride = 4 * sizeof(float);
|
descriptor.cVertexInput.cBuffers[0].stride = 4 * sizeof(float);
|
||||||
descriptor.cVertexInput.numAttributes = 1;
|
descriptor.cVertexInput.cBuffers[0].numAttributes = 1;
|
||||||
descriptor.cVertexInput.cAttributes[0].format = dawn::VertexFormat::Float4;
|
descriptor.cVertexInput.cAttributes[0].format = dawn::VertexFormat::Float4;
|
||||||
descriptor.cColorStates[0]->format = renderPass.colorFormat;
|
descriptor.cColorStates[0]->format = renderPass.colorFormat;
|
||||||
|
|
||||||
|
|
|
@ -364,7 +364,7 @@ class VertexFormatTest : public DawnTest {
|
||||||
descriptor.cFragmentStage.module = fsModule;
|
descriptor.cFragmentStage.module = fsModule;
|
||||||
descriptor.cVertexInput.numBuffers = 1;
|
descriptor.cVertexInput.numBuffers = 1;
|
||||||
descriptor.cVertexInput.cBuffers[0].stride = strideBytes;
|
descriptor.cVertexInput.cBuffers[0].stride = strideBytes;
|
||||||
descriptor.cVertexInput.numAttributes = 1;
|
descriptor.cVertexInput.cBuffers[0].numAttributes = 1;
|
||||||
descriptor.cVertexInput.cAttributes[0].format = format;
|
descriptor.cVertexInput.cAttributes[0].format = format;
|
||||||
descriptor.cColorStates[0]->format = renderPass.colorFormat;
|
descriptor.cColorStates[0]->format = renderPass.colorFormat;
|
||||||
|
|
||||||
|
|
|
@ -136,40 +136,42 @@ class VertexInputTest : public DawnTest {
|
||||||
return device.CreateRenderPipeline(&descriptor);
|
return device.CreateRenderPipeline(&descriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct VertexBufferSpec {
|
struct VertexAttributeSpec {
|
||||||
uint32_t slot;
|
|
||||||
uint64_t stride;
|
|
||||||
InputStepMode step;
|
|
||||||
};
|
|
||||||
struct AttributeSpec {
|
|
||||||
uint32_t location;
|
uint32_t location;
|
||||||
uint32_t slot;
|
|
||||||
uint64_t offset;
|
uint64_t offset;
|
||||||
VertexFormat format;
|
VertexFormat format;
|
||||||
};
|
};
|
||||||
|
struct VertexBufferSpec {
|
||||||
|
uint64_t stride;
|
||||||
|
InputStepMode step;
|
||||||
|
std::vector<VertexAttributeSpec> attributes;
|
||||||
|
};
|
||||||
|
|
||||||
utils::ComboVertexInputDescriptor MakeVertexInput(
|
utils::ComboVertexInputDescriptor MakeVertexInput(
|
||||||
const std::vector<VertexBufferSpec>& buffers,
|
const std::vector<VertexBufferSpec>& buffers) {
|
||||||
const std::vector<AttributeSpec>& attributes) {
|
|
||||||
utils::ComboVertexInputDescriptor vertexInput;
|
utils::ComboVertexInputDescriptor vertexInput;
|
||||||
uint32_t numBuffers = 0;
|
uint32_t numBuffers = 0;
|
||||||
for (const auto& buffer : buffers) {
|
uint32_t totalNumAttributes = 0;
|
||||||
vertexInput.cBuffers[numBuffers].inputSlot = buffer.slot;
|
for (const VertexBufferSpec& buffer : buffers) {
|
||||||
vertexInput.cBuffers[numBuffers].stride = buffer.stride;
|
vertexInput.cBuffers[numBuffers].stride = buffer.stride;
|
||||||
vertexInput.cBuffers[numBuffers].stepMode = buffer.step;
|
vertexInput.cBuffers[numBuffers].stepMode = buffer.step;
|
||||||
|
|
||||||
|
vertexInput.cBuffers[numBuffers].attributes =
|
||||||
|
&vertexInput.cAttributes[totalNumAttributes];
|
||||||
|
|
||||||
|
for (const VertexAttributeSpec& attribute : buffer.attributes) {
|
||||||
|
vertexInput.cAttributes[totalNumAttributes].shaderLocation = attribute.location;
|
||||||
|
vertexInput.cAttributes[totalNumAttributes].offset = attribute.offset;
|
||||||
|
vertexInput.cAttributes[totalNumAttributes].format = attribute.format;
|
||||||
|
totalNumAttributes++;
|
||||||
|
}
|
||||||
|
vertexInput.cBuffers[numBuffers].numAttributes =
|
||||||
|
static_cast<uint32_t>(buffer.attributes.size());
|
||||||
|
|
||||||
numBuffers++;
|
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.numBuffers = numBuffers;
|
||||||
vertexInput.numAttributes = numAttributes;
|
|
||||||
return vertexInput;
|
return vertexInput;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,7 +234,7 @@ class VertexInputTest : public DawnTest {
|
||||||
// Test compilation and usage of the fixture :)
|
// Test compilation and usage of the fixture :)
|
||||||
TEST_P(VertexInputTest, Basic) {
|
TEST_P(VertexInputTest, Basic) {
|
||||||
utils::ComboVertexInputDescriptor vertexInput = MakeVertexInput(
|
utils::ComboVertexInputDescriptor vertexInput = MakeVertexInput(
|
||||||
{{0, 4 * sizeof(float), InputStepMode::Vertex}}, {{0, 0, 0, VertexFormat::Float4}});
|
{{4 * sizeof(float), InputStepMode::Vertex, {{0, 0, VertexFormat::Float4}}}});
|
||||||
dawn::RenderPipeline pipeline =
|
dawn::RenderPipeline pipeline =
|
||||||
MakeTestPipeline(vertexInput, 1, {{0, VertexFormat::Float4, InputStepMode::Vertex}});
|
MakeTestPipeline(vertexInput, 1, {{0, VertexFormat::Float4, InputStepMode::Vertex}});
|
||||||
|
|
||||||
|
@ -250,7 +252,7 @@ TEST_P(VertexInputTest, ZeroStride) {
|
||||||
DAWN_SKIP_TEST_IF(IsLinux() && IsOpenGL());
|
DAWN_SKIP_TEST_IF(IsLinux() && IsOpenGL());
|
||||||
|
|
||||||
utils::ComboVertexInputDescriptor vertexInput =
|
utils::ComboVertexInputDescriptor vertexInput =
|
||||||
MakeVertexInput({{0, 0, InputStepMode::Vertex}}, {{0, 0, 0, VertexFormat::Float4}});
|
MakeVertexInput({{0, InputStepMode::Vertex, {{0, 0, VertexFormat::Float4}}}});
|
||||||
dawn::RenderPipeline pipeline =
|
dawn::RenderPipeline pipeline =
|
||||||
MakeTestPipeline(vertexInput, 0, {{0, VertexFormat::Float4, InputStepMode::Vertex}});
|
MakeTestPipeline(vertexInput, 0, {{0, VertexFormat::Float4, InputStepMode::Vertex}});
|
||||||
|
|
||||||
|
@ -268,7 +270,7 @@ TEST_P(VertexInputTest, AttributeExpanding) {
|
||||||
// R32F case
|
// R32F case
|
||||||
{
|
{
|
||||||
utils::ComboVertexInputDescriptor vertexInput =
|
utils::ComboVertexInputDescriptor vertexInput =
|
||||||
MakeVertexInput({{0, 0, InputStepMode::Vertex}}, {{0, 0, 0, VertexFormat::Float}});
|
MakeVertexInput({{0, InputStepMode::Vertex, {{0, 0, VertexFormat::Float}}}});
|
||||||
dawn::RenderPipeline pipeline =
|
dawn::RenderPipeline pipeline =
|
||||||
MakeTestPipeline(vertexInput, 0, {{0, VertexFormat::Float, InputStepMode::Vertex}});
|
MakeTestPipeline(vertexInput, 0, {{0, VertexFormat::Float, InputStepMode::Vertex}});
|
||||||
|
|
||||||
|
@ -280,7 +282,7 @@ TEST_P(VertexInputTest, AttributeExpanding) {
|
||||||
// RG32F case
|
// RG32F case
|
||||||
{
|
{
|
||||||
utils::ComboVertexInputDescriptor vertexInput =
|
utils::ComboVertexInputDescriptor vertexInput =
|
||||||
MakeVertexInput({{0, 0, InputStepMode::Vertex}}, {{0, 0, 0, VertexFormat::Float2}});
|
MakeVertexInput({{0, InputStepMode::Vertex, {{0, 0, VertexFormat::Float2}}}});
|
||||||
dawn::RenderPipeline pipeline =
|
dawn::RenderPipeline pipeline =
|
||||||
MakeTestPipeline(vertexInput, 0, {{0, VertexFormat::Float2, InputStepMode::Vertex}});
|
MakeTestPipeline(vertexInput, 0, {{0, VertexFormat::Float2, InputStepMode::Vertex}});
|
||||||
|
|
||||||
|
@ -292,7 +294,7 @@ TEST_P(VertexInputTest, AttributeExpanding) {
|
||||||
// RGB32F case
|
// RGB32F case
|
||||||
{
|
{
|
||||||
utils::ComboVertexInputDescriptor vertexInput =
|
utils::ComboVertexInputDescriptor vertexInput =
|
||||||
MakeVertexInput({{0, 0, InputStepMode::Vertex}}, {{0, 0, 0, VertexFormat::Float3}});
|
MakeVertexInput({{0, InputStepMode::Vertex, {{0, 0, VertexFormat::Float3}}}});
|
||||||
dawn::RenderPipeline pipeline =
|
dawn::RenderPipeline pipeline =
|
||||||
MakeTestPipeline(vertexInput, 0, {{0, VertexFormat::Float3, InputStepMode::Vertex}});
|
MakeTestPipeline(vertexInput, 0, {{0, VertexFormat::Float3, InputStepMode::Vertex}});
|
||||||
|
|
||||||
|
@ -309,7 +311,7 @@ TEST_P(VertexInputTest, StrideLargerThanAttributes) {
|
||||||
DAWN_SKIP_TEST_IF(IsLinux() && IsOpenGL());
|
DAWN_SKIP_TEST_IF(IsLinux() && IsOpenGL());
|
||||||
|
|
||||||
utils::ComboVertexInputDescriptor vertexInput = MakeVertexInput(
|
utils::ComboVertexInputDescriptor vertexInput = MakeVertexInput(
|
||||||
{{0, 8 * sizeof(float), InputStepMode::Vertex}}, {{0, 0, 0, VertexFormat::Float4}});
|
{{8 * sizeof(float), InputStepMode::Vertex, {{0, 0, VertexFormat::Float4}}}});
|
||||||
dawn::RenderPipeline pipeline =
|
dawn::RenderPipeline pipeline =
|
||||||
MakeTestPipeline(vertexInput, 1, {{0, VertexFormat::Float4, InputStepMode::Vertex}});
|
MakeTestPipeline(vertexInput, 1, {{0, VertexFormat::Float4, InputStepMode::Vertex}});
|
||||||
|
|
||||||
|
@ -324,8 +326,9 @@ TEST_P(VertexInputTest, StrideLargerThanAttributes) {
|
||||||
// Test two attributes at an offset, vertex version
|
// Test two attributes at an offset, vertex version
|
||||||
TEST_P(VertexInputTest, TwoAttributesAtAnOffsetVertex) {
|
TEST_P(VertexInputTest, TwoAttributesAtAnOffsetVertex) {
|
||||||
utils::ComboVertexInputDescriptor vertexInput = MakeVertexInput(
|
utils::ComboVertexInputDescriptor vertexInput = MakeVertexInput(
|
||||||
{{0, 8 * sizeof(float), InputStepMode::Vertex}},
|
{{8 * sizeof(float),
|
||||||
{{0, 0, 0, VertexFormat::Float4}, {1, 0, 4 * sizeof(float), VertexFormat::Float4}});
|
InputStepMode::Vertex,
|
||||||
|
{{0, 0, VertexFormat::Float4}, {1, 4 * sizeof(float), VertexFormat::Float4}}}});
|
||||||
dawn::RenderPipeline pipeline =
|
dawn::RenderPipeline pipeline =
|
||||||
MakeTestPipeline(vertexInput, 1, {{0, VertexFormat::Float4, InputStepMode::Vertex}});
|
MakeTestPipeline(vertexInput, 1, {{0, VertexFormat::Float4, InputStepMode::Vertex}});
|
||||||
|
|
||||||
|
@ -340,8 +343,9 @@ TEST_P(VertexInputTest, TwoAttributesAtAnOffsetVertex) {
|
||||||
// Test two attributes at an offset, instance version
|
// Test two attributes at an offset, instance version
|
||||||
TEST_P(VertexInputTest, TwoAttributesAtAnOffsetInstance) {
|
TEST_P(VertexInputTest, TwoAttributesAtAnOffsetInstance) {
|
||||||
utils::ComboVertexInputDescriptor vertexInput = MakeVertexInput(
|
utils::ComboVertexInputDescriptor vertexInput = MakeVertexInput(
|
||||||
{{0, 8 * sizeof(float), InputStepMode::Instance}},
|
{{8 * sizeof(float),
|
||||||
{{0, 0, 0, VertexFormat::Float4}, {1, 0, 4 * sizeof(float), VertexFormat::Float4}});
|
InputStepMode::Instance,
|
||||||
|
{{0, 0, VertexFormat::Float4}, {1, 4 * sizeof(float), VertexFormat::Float4}}}});
|
||||||
dawn::RenderPipeline pipeline =
|
dawn::RenderPipeline pipeline =
|
||||||
MakeTestPipeline(vertexInput, 1, {{0, VertexFormat::Float4, InputStepMode::Instance}});
|
MakeTestPipeline(vertexInput, 1, {{0, VertexFormat::Float4, InputStepMode::Instance}});
|
||||||
|
|
||||||
|
@ -356,7 +360,7 @@ TEST_P(VertexInputTest, TwoAttributesAtAnOffsetInstance) {
|
||||||
// Test a pure-instance input state
|
// Test a pure-instance input state
|
||||||
TEST_P(VertexInputTest, PureInstance) {
|
TEST_P(VertexInputTest, PureInstance) {
|
||||||
utils::ComboVertexInputDescriptor vertexInput = MakeVertexInput(
|
utils::ComboVertexInputDescriptor vertexInput = MakeVertexInput(
|
||||||
{{0, 4 * sizeof(float), InputStepMode::Instance}}, {{0, 0, 0, VertexFormat::Float4}});
|
{{4 * sizeof(float), InputStepMode::Instance, {{0, 0, VertexFormat::Float4}}}});
|
||||||
dawn::RenderPipeline pipeline =
|
dawn::RenderPipeline pipeline =
|
||||||
MakeTestPipeline(vertexInput, 1, {{0, VertexFormat::Float4, InputStepMode::Instance}});
|
MakeTestPipeline(vertexInput, 1, {{0, VertexFormat::Float4, InputStepMode::Instance}});
|
||||||
|
|
||||||
|
@ -373,14 +377,12 @@ TEST_P(VertexInputTest, PureInstance) {
|
||||||
// different attribute types
|
// different attribute types
|
||||||
TEST_P(VertexInputTest, MixedEverything) {
|
TEST_P(VertexInputTest, MixedEverything) {
|
||||||
utils::ComboVertexInputDescriptor vertexInput = MakeVertexInput(
|
utils::ComboVertexInputDescriptor vertexInput = MakeVertexInput(
|
||||||
{
|
{{12 * sizeof(float),
|
||||||
{0, 12 * sizeof(float), InputStepMode::Vertex},
|
InputStepMode::Vertex,
|
||||||
{1, 10 * sizeof(float), InputStepMode::Instance},
|
{{0, 0, VertexFormat::Float}, {1, 6 * sizeof(float), VertexFormat::Float2}}},
|
||||||
},
|
{10 * sizeof(float),
|
||||||
{{0, 0, 0, VertexFormat::Float},
|
InputStepMode::Instance,
|
||||||
{1, 0, 6 * sizeof(float), VertexFormat::Float2},
|
{{2, 0, VertexFormat::Float3}, {3, 5 * sizeof(float), VertexFormat::Float4}}}});
|
||||||
{2, 1, 0, VertexFormat::Float3},
|
|
||||||
{3, 1, 5 * sizeof(float), VertexFormat::Float4}});
|
|
||||||
dawn::RenderPipeline pipeline =
|
dawn::RenderPipeline pipeline =
|
||||||
MakeTestPipeline(vertexInput, 1,
|
MakeTestPipeline(vertexInput, 1,
|
||||||
{{0, VertexFormat::Float, InputStepMode::Vertex},
|
{{0, VertexFormat::Float, InputStepMode::Vertex},
|
||||||
|
@ -406,8 +408,10 @@ TEST_P(VertexInputTest, MixedEverything) {
|
||||||
// Test input state is unaffected by unused vertex slot
|
// Test input state is unaffected by unused vertex slot
|
||||||
TEST_P(VertexInputTest, UnusedVertexSlot) {
|
TEST_P(VertexInputTest, UnusedVertexSlot) {
|
||||||
// Instance input state, using slot 1
|
// Instance input state, using slot 1
|
||||||
|
// TODO(yunchao.he@intel.com): This is not actually testing slot 1 right now,
|
||||||
|
// need to allow null for buffer[0].
|
||||||
utils::ComboVertexInputDescriptor instanceVertexInput = MakeVertexInput(
|
utils::ComboVertexInputDescriptor instanceVertexInput = MakeVertexInput(
|
||||||
{{1, 4 * sizeof(float), InputStepMode::Instance}}, {{0, 1, 0, VertexFormat::Float4}});
|
{{4 * sizeof(float), InputStepMode::Instance, {{0, 0, VertexFormat::Float4}}}});
|
||||||
dawn::RenderPipeline instancePipeline = MakeTestPipeline(
|
dawn::RenderPipeline instancePipeline = MakeTestPipeline(
|
||||||
instanceVertexInput, 1, {{0, VertexFormat::Float4, InputStepMode::Instance}});
|
instanceVertexInput, 1, {{0, VertexFormat::Float4, InputStepMode::Instance}});
|
||||||
|
|
||||||
|
@ -444,13 +448,15 @@ TEST_P(VertexInputTest, UnusedVertexSlot) {
|
||||||
TEST_P(VertexInputTest, MultiplePipelinesMixedVertexInput) {
|
TEST_P(VertexInputTest, MultiplePipelinesMixedVertexInput) {
|
||||||
// Basic input state, using slot 0
|
// Basic input state, using slot 0
|
||||||
utils::ComboVertexInputDescriptor vertexVertexInput = MakeVertexInput(
|
utils::ComboVertexInputDescriptor vertexVertexInput = MakeVertexInput(
|
||||||
{{0, 4 * sizeof(float), InputStepMode::Vertex}}, {{0, 0, 0, VertexFormat::Float4}});
|
{{4 * sizeof(float), InputStepMode::Vertex, {{0, 0, VertexFormat::Float4}}}});
|
||||||
dawn::RenderPipeline vertexPipeline =
|
dawn::RenderPipeline vertexPipeline =
|
||||||
MakeTestPipeline(vertexVertexInput, 1, {{0, VertexFormat::Float4, InputStepMode::Vertex}});
|
MakeTestPipeline(vertexVertexInput, 1, {{0, VertexFormat::Float4, InputStepMode::Vertex}});
|
||||||
|
|
||||||
// Instance input state, using slot 1
|
// Instance input state, using slot 1
|
||||||
|
// TODO(yunchao.he@intel.com): This is not actually testing slot 1 right now,
|
||||||
|
// need to allow null for buffer[0].
|
||||||
utils::ComboVertexInputDescriptor instanceVertexInput = MakeVertexInput(
|
utils::ComboVertexInputDescriptor instanceVertexInput = MakeVertexInput(
|
||||||
{{1, 4 * sizeof(float), InputStepMode::Instance}}, {{0, 1, 0, VertexFormat::Float4}});
|
{{4 * sizeof(float), InputStepMode::Instance, {{0, 0, VertexFormat::Float4}}}});
|
||||||
dawn::RenderPipeline instancePipeline = MakeTestPipeline(
|
dawn::RenderPipeline instancePipeline = MakeTestPipeline(
|
||||||
instanceVertexInput, 1, {{0, VertexFormat::Float4, InputStepMode::Instance}});
|
instanceVertexInput, 1, {{0, VertexFormat::Float4, InputStepMode::Instance}});
|
||||||
|
|
||||||
|
|
|
@ -74,13 +74,13 @@ class VertexBufferValidationTest : public ValidationTest {
|
||||||
descriptor.cFragmentStage.module = fsModule;
|
descriptor.cFragmentStage.module = fsModule;
|
||||||
|
|
||||||
for (unsigned int i = 0; i < numBuffers; ++i) {
|
for (unsigned int i = 0; i < numBuffers; ++i) {
|
||||||
|
descriptor.cVertexInput.cBuffers[i].numAttributes = 1;
|
||||||
|
descriptor.cVertexInput.cBuffers[i].attributes =
|
||||||
|
&descriptor.cVertexInput.cAttributes[i];
|
||||||
descriptor.cVertexInput.cAttributes[i].shaderLocation = i;
|
descriptor.cVertexInput.cAttributes[i].shaderLocation = i;
|
||||||
descriptor.cVertexInput.cAttributes[i].inputSlot = i;
|
|
||||||
descriptor.cVertexInput.cAttributes[i].format = dawn::VertexFormat::Float3;
|
descriptor.cVertexInput.cAttributes[i].format = dawn::VertexFormat::Float3;
|
||||||
descriptor.cVertexInput.cBuffers[i].inputSlot = i;
|
|
||||||
}
|
}
|
||||||
descriptor.cVertexInput.numBuffers = numBuffers;
|
descriptor.cVertexInput.numBuffers = numBuffers;
|
||||||
descriptor.cVertexInput.numAttributes = numBuffers;
|
|
||||||
|
|
||||||
return device.CreateRenderPipeline(&descriptor);
|
return device.CreateRenderPipeline(&descriptor);
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,8 @@ TEST_F(VertexInputTest, PipelineCompatibility) {
|
||||||
utils::ComboVertexInputDescriptor state;
|
utils::ComboVertexInputDescriptor state;
|
||||||
state.numBuffers = 1;
|
state.numBuffers = 1;
|
||||||
state.cBuffers[0].stride = 2 * sizeof(float);
|
state.cBuffers[0].stride = 2 * sizeof(float);
|
||||||
state.numAttributes = 2;
|
state.cBuffers[0].numAttributes = 2;
|
||||||
|
state.cAttributes[0].shaderLocation = 0;
|
||||||
state.cAttributes[1].shaderLocation = 1;
|
state.cAttributes[1].shaderLocation = 1;
|
||||||
state.cAttributes[1].offset = sizeof(float);
|
state.cAttributes[1].offset = sizeof(float);
|
||||||
|
|
||||||
|
@ -101,6 +102,8 @@ TEST_F(VertexInputTest, StrideZero) {
|
||||||
// Works ok without attributes
|
// Works ok without attributes
|
||||||
utils::ComboVertexInputDescriptor state;
|
utils::ComboVertexInputDescriptor state;
|
||||||
state.numBuffers = 1;
|
state.numBuffers = 1;
|
||||||
|
state.cBuffers[0].stride = 0;
|
||||||
|
state.cBuffers[0].numAttributes = 1;
|
||||||
CreatePipeline(true, state, R"(
|
CreatePipeline(true, state, R"(
|
||||||
#version 450
|
#version 450
|
||||||
void main() {
|
void main() {
|
||||||
|
@ -109,7 +112,6 @@ TEST_F(VertexInputTest, StrideZero) {
|
||||||
)");
|
)");
|
||||||
|
|
||||||
// Works ok with attributes at a large-ish offset
|
// Works ok with attributes at a large-ish offset
|
||||||
state.numAttributes = 1;
|
|
||||||
state.cAttributes[0].offset = 128;
|
state.cAttributes[0].offset = 128;
|
||||||
CreatePipeline(true, state, R"(
|
CreatePipeline(true, state, R"(
|
||||||
#version 450
|
#version 450
|
||||||
|
@ -119,11 +121,17 @@ TEST_F(VertexInputTest, StrideZero) {
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that we cannot set an already set input
|
// Check validation that vertex attribute offset should be within vertex buffer stride,
|
||||||
TEST_F(VertexInputTest, AlreadySetInput) {
|
// if vertex buffer stride is not zero.
|
||||||
// Control case
|
TEST_F(VertexInputTest, SetOffsetOutOfBounds) {
|
||||||
|
// Control case, setting correct stride and offset
|
||||||
utils::ComboVertexInputDescriptor state;
|
utils::ComboVertexInputDescriptor state;
|
||||||
state.numBuffers = 1;
|
state.numBuffers = 1;
|
||||||
|
state.cBuffers[0].stride = 2 * sizeof(float);
|
||||||
|
state.cBuffers[0].numAttributes = 2;
|
||||||
|
state.cAttributes[0].shaderLocation = 0;
|
||||||
|
state.cAttributes[1].shaderLocation = 1;
|
||||||
|
state.cAttributes[1].offset = sizeof(float);
|
||||||
CreatePipeline(true, state, R"(
|
CreatePipeline(true, state, R"(
|
||||||
#version 450
|
#version 450
|
||||||
void main() {
|
void main() {
|
||||||
|
@ -131,8 +139,44 @@ TEST_F(VertexInputTest, AlreadySetInput) {
|
||||||
}
|
}
|
||||||
)");
|
)");
|
||||||
|
|
||||||
// Oh no, input 0 is set twice
|
// Test vertex attribute offset exceed vertex buffer stride range
|
||||||
state.numBuffers = 2;
|
state.cBuffers[0].stride = sizeof(float);
|
||||||
|
CreatePipeline(false, state, R"(
|
||||||
|
#version 450
|
||||||
|
void main() {
|
||||||
|
gl_Position = vec4(0.0);
|
||||||
|
}
|
||||||
|
)");
|
||||||
|
|
||||||
|
// It's OK if stride is zero
|
||||||
|
state.cBuffers[0].stride = 0;
|
||||||
|
CreatePipeline(true, state, R"(
|
||||||
|
#version 450
|
||||||
|
void main() {
|
||||||
|
gl_Position = vec4(0.0);
|
||||||
|
}
|
||||||
|
)");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check out of bounds condition on total number of vertex buffers
|
||||||
|
TEST_F(VertexInputTest, SetVertexBuffersNumLimit) {
|
||||||
|
// Control case, setting max vertex buffer number
|
||||||
|
utils::ComboVertexInputDescriptor state;
|
||||||
|
state.numBuffers = kMaxVertexBuffers;
|
||||||
|
for (uint32_t i = 0; i < kMaxVertexBuffers; ++i) {
|
||||||
|
state.cBuffers[i].numAttributes = 1;
|
||||||
|
state.cBuffers[i].attributes = &state.cAttributes[i];
|
||||||
|
state.cAttributes[i].shaderLocation = i;
|
||||||
|
}
|
||||||
|
CreatePipeline(true, state, R"(
|
||||||
|
#version 450
|
||||||
|
void main() {
|
||||||
|
gl_Position = vec4(0.0);
|
||||||
|
}
|
||||||
|
)");
|
||||||
|
|
||||||
|
// Test vertex buffer number exceed the limit
|
||||||
|
state.numBuffers = kMaxVertexBuffers + 1;
|
||||||
CreatePipeline(false, state, R"(
|
CreatePipeline(false, state, R"(
|
||||||
#version 450
|
#version 450
|
||||||
void main() {
|
void main() {
|
||||||
|
@ -141,12 +185,15 @@ TEST_F(VertexInputTest, AlreadySetInput) {
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check out of bounds condition on input slot
|
// Check out of bounds condition on total number of vertex attributes
|
||||||
TEST_F(VertexInputTest, SetInputSlotOutOfBounds) {
|
TEST_F(VertexInputTest, SetVertexAttributesNumLimit) {
|
||||||
// Control case, setting last input slot
|
// Control case, setting max vertex attribute number
|
||||||
utils::ComboVertexInputDescriptor state;
|
utils::ComboVertexInputDescriptor state;
|
||||||
state.numBuffers = 1;
|
state.numBuffers = 2;
|
||||||
state.cBuffers[0].inputSlot = kMaxVertexBuffers - 1;
|
state.cBuffers[0].numAttributes = kMaxVertexAttributes;
|
||||||
|
for (uint32_t i = 0; i < kMaxVertexAttributes; ++i) {
|
||||||
|
state.cAttributes[i].shaderLocation = i;
|
||||||
|
}
|
||||||
CreatePipeline(true, state, R"(
|
CreatePipeline(true, state, R"(
|
||||||
#version 450
|
#version 450
|
||||||
void main() {
|
void main() {
|
||||||
|
@ -154,8 +201,9 @@ TEST_F(VertexInputTest, SetInputSlotOutOfBounds) {
|
||||||
}
|
}
|
||||||
)");
|
)");
|
||||||
|
|
||||||
// Test input slot OOB
|
// Test vertex attribute number exceed the limit
|
||||||
state.cBuffers[0].inputSlot = kMaxVertexBuffers;
|
state.cBuffers[1].numAttributes = 1;
|
||||||
|
state.cBuffers[1].attributes = &state.cAttributes[kMaxVertexAttributes - 1];
|
||||||
CreatePipeline(false, state, R"(
|
CreatePipeline(false, state, R"(
|
||||||
#version 450
|
#version 450
|
||||||
void main() {
|
void main() {
|
||||||
|
@ -170,6 +218,7 @@ TEST_F(VertexInputTest, SetInputStrideOutOfBounds) {
|
||||||
utils::ComboVertexInputDescriptor state;
|
utils::ComboVertexInputDescriptor state;
|
||||||
state.numBuffers = 1;
|
state.numBuffers = 1;
|
||||||
state.cBuffers[0].stride = kMaxVertexBufferStride;
|
state.cBuffers[0].stride = kMaxVertexBufferStride;
|
||||||
|
state.cBuffers[0].numAttributes = 1;
|
||||||
CreatePipeline(true, state, R"(
|
CreatePipeline(true, state, R"(
|
||||||
#version 450
|
#version 450
|
||||||
void main() {
|
void main() {
|
||||||
|
@ -189,10 +238,11 @@ TEST_F(VertexInputTest, SetInputStrideOutOfBounds) {
|
||||||
|
|
||||||
// Test that we cannot set an already set attribute
|
// Test that we cannot set an already set attribute
|
||||||
TEST_F(VertexInputTest, AlreadySetAttribute) {
|
TEST_F(VertexInputTest, AlreadySetAttribute) {
|
||||||
// Control case, setting last attribute
|
// Control case, setting attribute 0
|
||||||
utils::ComboVertexInputDescriptor state;
|
utils::ComboVertexInputDescriptor state;
|
||||||
state.numBuffers = 1;
|
state.numBuffers = 1;
|
||||||
state.numAttributes = 1;
|
state.cBuffers[0].numAttributes = 1;
|
||||||
|
state.cAttributes[0].shaderLocation = 0;
|
||||||
CreatePipeline(true, state, R"(
|
CreatePipeline(true, state, R"(
|
||||||
#version 450
|
#version 450
|
||||||
void main() {
|
void main() {
|
||||||
|
@ -201,7 +251,49 @@ TEST_F(VertexInputTest, AlreadySetAttribute) {
|
||||||
)");
|
)");
|
||||||
|
|
||||||
// Oh no, attribute 0 is set twice
|
// Oh no, attribute 0 is set twice
|
||||||
state.numAttributes = 2;
|
state.cBuffers[0].numAttributes = 2;
|
||||||
|
state.cAttributes[0].shaderLocation = 0;
|
||||||
|
state.cAttributes[1].shaderLocation = 0;
|
||||||
|
CreatePipeline(false, state, R"(
|
||||||
|
#version 450
|
||||||
|
void main() {
|
||||||
|
gl_Position = vec4(0.0);
|
||||||
|
}
|
||||||
|
)");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test that a stride of 0 is valid
|
||||||
|
TEST_F(VertexInputTest, SetSameShaderLocation) {
|
||||||
|
// Control case, setting different shader locations in two attributes
|
||||||
|
utils::ComboVertexInputDescriptor state;
|
||||||
|
state.numBuffers = 1;
|
||||||
|
state.cBuffers[0].numAttributes = 2;
|
||||||
|
state.cAttributes[0].shaderLocation = 0;
|
||||||
|
state.cAttributes[1].shaderLocation = 1;
|
||||||
|
state.cAttributes[1].offset = sizeof(float);
|
||||||
|
CreatePipeline(true, state, R"(
|
||||||
|
#version 450
|
||||||
|
void main() {
|
||||||
|
gl_Position = vec4(0.0);
|
||||||
|
}
|
||||||
|
)");
|
||||||
|
|
||||||
|
// Test same shader location in two attributes in the same buffer
|
||||||
|
state.cAttributes[1].shaderLocation = 0;
|
||||||
|
CreatePipeline(false, state, R"(
|
||||||
|
#version 450
|
||||||
|
void main() {
|
||||||
|
gl_Position = vec4(0.0);
|
||||||
|
}
|
||||||
|
)");
|
||||||
|
|
||||||
|
// Test same shader location in two attributes in different buffers
|
||||||
|
state.numBuffers = 2;
|
||||||
|
state.cBuffers[0].numAttributes = 1;
|
||||||
|
state.cAttributes[0].shaderLocation = 0;
|
||||||
|
state.cBuffers[1].numAttributes = 1;
|
||||||
|
state.cBuffers[1].attributes = &state.cAttributes[1];
|
||||||
|
state.cAttributes[1].shaderLocation = 0;
|
||||||
CreatePipeline(false, state, R"(
|
CreatePipeline(false, state, R"(
|
||||||
#version 450
|
#version 450
|
||||||
void main() {
|
void main() {
|
||||||
|
@ -215,7 +307,7 @@ TEST_F(VertexInputTest, SetAttributeLocationOutOfBounds) {
|
||||||
// Control case, setting last attribute shader location
|
// Control case, setting last attribute shader location
|
||||||
utils::ComboVertexInputDescriptor state;
|
utils::ComboVertexInputDescriptor state;
|
||||||
state.numBuffers = 1;
|
state.numBuffers = 1;
|
||||||
state.numAttributes = 1;
|
state.cBuffers[0].numAttributes = 1;
|
||||||
state.cAttributes[0].shaderLocation = kMaxVertexAttributes - 1;
|
state.cAttributes[0].shaderLocation = kMaxVertexAttributes - 1;
|
||||||
CreatePipeline(true, state, R"(
|
CreatePipeline(true, state, R"(
|
||||||
#version 450
|
#version 450
|
||||||
|
@ -239,7 +331,7 @@ TEST_F(VertexInputTest, SetAttributeOffsetOutOfBounds) {
|
||||||
// Control case, setting max attribute offset for FloatR32 vertex format
|
// Control case, setting max attribute offset for FloatR32 vertex format
|
||||||
utils::ComboVertexInputDescriptor state;
|
utils::ComboVertexInputDescriptor state;
|
||||||
state.numBuffers = 1;
|
state.numBuffers = 1;
|
||||||
state.numAttributes = 1;
|
state.cBuffers[0].numAttributes = 1;
|
||||||
state.cAttributes[0].offset = kMaxVertexAttributeEnd - sizeof(dawn::VertexFormat::Float);
|
state.cAttributes[0].offset = kMaxVertexAttributeEnd - sizeof(dawn::VertexFormat::Float);
|
||||||
CreatePipeline(true, state, R"(
|
CreatePipeline(true, state, R"(
|
||||||
#version 450
|
#version 450
|
||||||
|
@ -262,7 +354,7 @@ TEST_F(VertexInputTest, SetAttributeOffsetOutOfBounds) {
|
||||||
TEST_F(VertexInputTest, SetAttributeOffsetOverflow) {
|
TEST_F(VertexInputTest, SetAttributeOffsetOverflow) {
|
||||||
utils::ComboVertexInputDescriptor state;
|
utils::ComboVertexInputDescriptor state;
|
||||||
state.numBuffers = 1;
|
state.numBuffers = 1;
|
||||||
state.numAttributes = 1;
|
state.cBuffers[0].numAttributes = 1;
|
||||||
state.cAttributes[0].offset = std::numeric_limits<uint32_t>::max();
|
state.cAttributes[0].offset = std::numeric_limits<uint32_t>::max();
|
||||||
CreatePipeline(false, state, R"(
|
CreatePipeline(false, state, R"(
|
||||||
#version 450
|
#version 450
|
||||||
|
@ -271,49 +363,3 @@ TEST_F(VertexInputTest, SetAttributeOffsetOverflow) {
|
||||||
}
|
}
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that all attributes must be backed by an input
|
|
||||||
TEST_F(VertexInputTest, RequireInputForAttribute) {
|
|
||||||
// Control case
|
|
||||||
utils::ComboVertexInputDescriptor state;
|
|
||||||
state.numBuffers = 1;
|
|
||||||
state.numAttributes = 1;
|
|
||||||
CreatePipeline(true, state, R"(
|
|
||||||
#version 450
|
|
||||||
void main() {
|
|
||||||
gl_Position = vec4(0.0);
|
|
||||||
}
|
|
||||||
)");
|
|
||||||
|
|
||||||
// Attribute 0 uses input 1 which doesn't exist
|
|
||||||
state.cAttributes[0].inputSlot = 1;
|
|
||||||
CreatePipeline(false, state, R"(
|
|
||||||
#version 450
|
|
||||||
void main() {
|
|
||||||
gl_Position = vec4(0.0);
|
|
||||||
}
|
|
||||||
)");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check OOB checks for an attribute's input
|
|
||||||
TEST_F(VertexInputTest, SetAttributeOOBCheckForInputs) {
|
|
||||||
// Control case
|
|
||||||
utils::ComboVertexInputDescriptor state;
|
|
||||||
state.numBuffers = 1;
|
|
||||||
state.numAttributes = 1;
|
|
||||||
CreatePipeline(true, state, R"(
|
|
||||||
#version 450
|
|
||||||
void main() {
|
|
||||||
gl_Position = vec4(0.0);
|
|
||||||
}
|
|
||||||
)");
|
|
||||||
|
|
||||||
// Could crash if we didn't check for OOB
|
|
||||||
state.cAttributes[0].inputSlot = 1000000;
|
|
||||||
CreatePipeline(false, state, R"(
|
|
||||||
#version 450
|
|
||||||
void main() {
|
|
||||||
gl_Position = vec4(0.0);
|
|
||||||
}
|
|
||||||
)");
|
|
||||||
}
|
|
||||||
|
|
|
@ -122,8 +122,6 @@ TEST_F(WireArgumentTests, CStringArgument) {
|
||||||
vertexInput.indexFormat = DAWN_INDEX_FORMAT_UINT32;
|
vertexInput.indexFormat = DAWN_INDEX_FORMAT_UINT32;
|
||||||
vertexInput.numBuffers = 0;
|
vertexInput.numBuffers = 0;
|
||||||
vertexInput.buffers = nullptr;
|
vertexInput.buffers = nullptr;
|
||||||
vertexInput.numAttributes = 0;
|
|
||||||
vertexInput.attributes = nullptr;
|
|
||||||
|
|
||||||
// Create the rasterization state
|
// Create the rasterization state
|
||||||
DawnRasterizationStateDescriptor rasterizationState;
|
DawnRasterizationStateDescriptor rasterizationState;
|
||||||
|
|
|
@ -92,8 +92,6 @@ TEST_F(WireOptionalTests, OptionalStructPointer) {
|
||||||
vertexInput.indexFormat = DAWN_INDEX_FORMAT_UINT32;
|
vertexInput.indexFormat = DAWN_INDEX_FORMAT_UINT32;
|
||||||
vertexInput.numBuffers = 0;
|
vertexInput.numBuffers = 0;
|
||||||
vertexInput.buffers = nullptr;
|
vertexInput.buffers = nullptr;
|
||||||
vertexInput.numAttributes = 0;
|
|
||||||
vertexInput.attributes = nullptr;
|
|
||||||
|
|
||||||
// Create the rasterization state
|
// Create the rasterization state
|
||||||
DawnRasterizationStateDescriptor rasterizationState;
|
DawnRasterizationStateDescriptor rasterizationState;
|
||||||
|
|
|
@ -22,29 +22,28 @@ namespace utils {
|
||||||
dawn::VertexInputDescriptor* descriptor = this;
|
dawn::VertexInputDescriptor* descriptor = this;
|
||||||
|
|
||||||
descriptor->indexFormat = dawn::IndexFormat::Uint32;
|
descriptor->indexFormat = dawn::IndexFormat::Uint32;
|
||||||
|
|
||||||
// Fill the default values for vertexBuffer.
|
|
||||||
descriptor->numBuffers = 0;
|
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->buffers = &cBuffers[0];
|
|
||||||
|
|
||||||
// Fill the default values for vertexAttribute.
|
// Fill the default values for vertexBuffers and vertexAttributes in buffers.
|
||||||
descriptor->numAttributes = 0;
|
|
||||||
dawn::VertexAttributeDescriptor vertexAttribute;
|
dawn::VertexAttributeDescriptor vertexAttribute;
|
||||||
vertexAttribute.shaderLocation = 0;
|
vertexAttribute.shaderLocation = 0;
|
||||||
vertexAttribute.inputSlot = 0;
|
|
||||||
vertexAttribute.offset = 0;
|
vertexAttribute.offset = 0;
|
||||||
vertexAttribute.format = dawn::VertexFormat::Float;
|
vertexAttribute.format = dawn::VertexFormat::Float;
|
||||||
for (uint32_t i = 0; i < kMaxVertexAttributes; ++i) {
|
for (uint32_t i = 0; i < kMaxVertexAttributes; ++i) {
|
||||||
cAttributes[i] = vertexAttribute;
|
cAttributes[i] = vertexAttribute;
|
||||||
}
|
}
|
||||||
descriptor->attributes = &cAttributes[0];
|
for (uint32_t i = 0; i < kMaxVertexBuffers; ++i) {
|
||||||
|
cBuffers[i].stride = 0;
|
||||||
|
cBuffers[i].stepMode = dawn::InputStepMode::Vertex;
|
||||||
|
cBuffers[i].numAttributes = 0;
|
||||||
|
cBuffers[i].attributes = nullptr;
|
||||||
|
}
|
||||||
|
// cBuffers[i].attributes points to somewhere in cAttributes. cBuffers[0].attributes
|
||||||
|
// points to &cAttributes[0] by default. Assuming cBuffers[0] has two attributes, then
|
||||||
|
// cBuffers[1].attributes should point to &cAttributes[2]. Likewise, if cBuffers[1]
|
||||||
|
// has 3 attributes, then cBuffers[2].attributes should point to &cAttributes[5].
|
||||||
|
cBuffers[0].attributes = &cAttributes[0];
|
||||||
|
descriptor->buffers = &cBuffers[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
ComboRenderPipelineDescriptor::ComboRenderPipelineDescriptor(const dawn::Device& device) {
|
ComboRenderPipelineDescriptor::ComboRenderPipelineDescriptor(const dawn::Device& device) {
|
||||||
|
|
Loading…
Reference in New Issue