Update naming for vertex state
- VertexInputDescriptor -> VertexStateDescriptor - VertexBufferDescriptor -> VertexBufferLayoutDescriptor - VertexBufferDescriptor.stride -> .arrayStride - VertexAttributeDescriptor.offset no longer optional gpuweb PR: https://github.com/gpuweb/gpuweb/pull/469 Bug: dawn:22 Change-Id: I5431df4ba22cfbdb1bc81e6709e562cd736892a3 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/13100 Commit-Queue: Kai Ninomiya <kainino@chromium.org> Reviewed-by: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
parent
c3284fa40e
commit
ae1f25fee8
4
BUILD.gn
4
BUILD.gn
|
@ -839,7 +839,7 @@ test("dawn_unittests") {
|
||||||
"src/tests/unittests/validation/ValidationTest.cpp",
|
"src/tests/unittests/validation/ValidationTest.cpp",
|
||||||
"src/tests/unittests/validation/ValidationTest.h",
|
"src/tests/unittests/validation/ValidationTest.h",
|
||||||
"src/tests/unittests/validation/VertexBufferValidationTests.cpp",
|
"src/tests/unittests/validation/VertexBufferValidationTests.cpp",
|
||||||
"src/tests/unittests/validation/VertexInputValidationTests.cpp",
|
"src/tests/unittests/validation/VertexStateValidationTests.cpp",
|
||||||
"src/tests/unittests/wire/WireArgumentTests.cpp",
|
"src/tests/unittests/wire/WireArgumentTests.cpp",
|
||||||
"src/tests/unittests/wire/WireBasicTests.cpp",
|
"src/tests/unittests/wire/WireBasicTests.cpp",
|
||||||
"src/tests/unittests/wire/WireBufferMappingTests.cpp",
|
"src/tests/unittests/wire/WireBufferMappingTests.cpp",
|
||||||
|
@ -918,7 +918,7 @@ source_set("dawn_end2end_tests_sources") {
|
||||||
"src/tests/end2end/TextureViewTests.cpp",
|
"src/tests/end2end/TextureViewTests.cpp",
|
||||||
"src/tests/end2end/TextureZeroInitTests.cpp",
|
"src/tests/end2end/TextureZeroInitTests.cpp",
|
||||||
"src/tests/end2end/VertexFormatTests.cpp",
|
"src/tests/end2end/VertexFormatTests.cpp",
|
||||||
"src/tests/end2end/VertexInputTests.cpp",
|
"src/tests/end2end/VertexStateTests.cpp",
|
||||||
"src/tests/end2end/ViewportOrientationTests.cpp",
|
"src/tests/end2end/ViewportOrientationTests.cpp",
|
||||||
"src/tests/end2end/ViewportTests.cpp",
|
"src/tests/end2end/ViewportTests.cpp",
|
||||||
]
|
]
|
||||||
|
|
18
dawn.json
18
dawn.json
|
@ -693,28 +693,28 @@
|
||||||
"category": "structure",
|
"category": "structure",
|
||||||
"extensible": false,
|
"extensible": false,
|
||||||
"members": [
|
"members": [
|
||||||
{"name": "shader location", "type": "uint32_t"},
|
{"name": "format", "type": "vertex format"},
|
||||||
{"name": "offset", "type": "uint64_t", "default": "0"},
|
{"name": "offset", "type": "uint64_t"},
|
||||||
{"name": "format", "type": "vertex format"}
|
{"name": "shader location", "type": "uint32_t"}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"vertex buffer descriptor": {
|
"vertex buffer layout descriptor": {
|
||||||
"category": "structure",
|
"category": "structure",
|
||||||
"extensible": false,
|
"extensible": false,
|
||||||
"members": [
|
"members": [
|
||||||
{"name": "stride", "type": "uint64_t"},
|
{"name": "array stride", "type": "uint64_t"},
|
||||||
{"name": "step mode", "type": "input step mode", "default": "vertex"},
|
{"name": "step mode", "type": "input step mode", "default": "vertex"},
|
||||||
{"name": "attribute count", "type": "uint32_t"},
|
{"name": "attribute count", "type": "uint32_t"},
|
||||||
{"name": "attributes", "type": "vertex attribute descriptor", "annotation": "const*", "length": "attribute count"}
|
{"name": "attributes", "type": "vertex attribute descriptor", "annotation": "const*", "length": "attribute count"}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"vertex input descriptor": {
|
"vertex state descriptor": {
|
||||||
"category": "structure",
|
"category": "structure",
|
||||||
"extensible": true,
|
"extensible": true,
|
||||||
"members": [
|
"members": [
|
||||||
{"name": "index format", "type": "index format", "default": "uint32"},
|
{"name": "index format", "type": "index format", "default": "uint32"},
|
||||||
{"name": "buffer count", "type": "uint32_t", "default": 0},
|
{"name": "vertex buffer count", "type": "uint32_t", "default": 0},
|
||||||
{"name": "buffers", "type": "vertex buffer descriptor", "annotation": "const*", "length": "buffer count"}
|
{"name": "vertex buffers", "type": "vertex buffer layout descriptor", "annotation": "const*", "length": "vertex buffer count"}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"input step mode": {
|
"input step mode": {
|
||||||
|
@ -1102,7 +1102,7 @@
|
||||||
{"name": "layout", "type": "pipeline layout"},
|
{"name": "layout", "type": "pipeline layout"},
|
||||||
{"name": "vertex stage", "type": "programmable stage descriptor"},
|
{"name": "vertex stage", "type": "programmable stage descriptor"},
|
||||||
{"name": "fragment stage", "type": "programmable stage descriptor", "annotation": "const*", "optional": true},
|
{"name": "fragment stage", "type": "programmable stage descriptor", "annotation": "const*", "optional": true},
|
||||||
{"name": "vertex input", "type": "vertex input descriptor", "annotation": "const*", "optional": true},
|
{"name": "vertex state", "type": "vertex state descriptor", "annotation": "const*", "optional": true},
|
||||||
{"name": "primitive topology", "type": "primitive topology"},
|
{"name": "primitive topology", "type": "primitive topology"},
|
||||||
{"name": "rasterization state", "type": "rasterization state descriptor", "annotation": "const*", "optional": true},
|
{"name": "rasterization state", "type": "rasterization state descriptor", "annotation": "const*", "optional": true},
|
||||||
{"name": "sample count", "type": "uint32_t", "default": "1"},
|
{"name": "sample count", "type": "uint32_t", "default": "1"},
|
||||||
|
|
|
@ -95,12 +95,12 @@ void init() {
|
||||||
pl.bindGroupLayouts = nullptr;
|
pl.bindGroupLayouts = nullptr;
|
||||||
descriptor.layout = wgpuDeviceCreatePipelineLayout(device, &pl);
|
descriptor.layout = wgpuDeviceCreatePipelineLayout(device, &pl);
|
||||||
|
|
||||||
WGPUVertexInputDescriptor vertexInput;
|
WGPUVertexStateDescriptor vertexState;
|
||||||
vertexInput.nextInChain = nullptr;
|
vertexState.nextInChain = nullptr;
|
||||||
vertexInput.indexFormat = WGPUIndexFormat_Uint32;
|
vertexState.indexFormat = WGPUIndexFormat_Uint32;
|
||||||
vertexInput.bufferCount = 0;
|
vertexState.vertexBufferCount = 0;
|
||||||
vertexInput.buffers = nullptr;
|
vertexState.vertexBuffers = nullptr;
|
||||||
descriptor.vertexInput = &vertexInput;
|
descriptor.vertexState = &vertexState;
|
||||||
|
|
||||||
WGPURasterizationStateDescriptor rasterizationState;
|
WGPURasterizationStateDescriptor rasterizationState;
|
||||||
rasterizationState.nextInChain = nullptr;
|
rasterizationState.nextInChain = nullptr;
|
||||||
|
|
|
@ -125,20 +125,20 @@ void initRender() {
|
||||||
descriptor.vertexStage.module = vsModule;
|
descriptor.vertexStage.module = vsModule;
|
||||||
descriptor.cFragmentStage.module = fsModule;
|
descriptor.cFragmentStage.module = fsModule;
|
||||||
|
|
||||||
descriptor.cVertexInput.bufferCount = 2;
|
descriptor.cVertexState.vertexBufferCount = 2;
|
||||||
descriptor.cVertexInput.cBuffers[0].stride = sizeof(Particle);
|
descriptor.cVertexState.cVertexBuffers[0].arrayStride = sizeof(Particle);
|
||||||
descriptor.cVertexInput.cBuffers[0].stepMode = wgpu::InputStepMode::Instance;
|
descriptor.cVertexState.cVertexBuffers[0].stepMode = wgpu::InputStepMode::Instance;
|
||||||
descriptor.cVertexInput.cBuffers[0].attributeCount = 2;
|
descriptor.cVertexState.cVertexBuffers[0].attributeCount = 2;
|
||||||
descriptor.cVertexInput.cAttributes[0].offset = offsetof(Particle, pos);
|
descriptor.cVertexState.cAttributes[0].offset = offsetof(Particle, pos);
|
||||||
descriptor.cVertexInput.cAttributes[0].format = wgpu::VertexFormat::Float2;
|
descriptor.cVertexState.cAttributes[0].format = wgpu::VertexFormat::Float2;
|
||||||
descriptor.cVertexInput.cAttributes[1].shaderLocation = 1;
|
descriptor.cVertexState.cAttributes[1].shaderLocation = 1;
|
||||||
descriptor.cVertexInput.cAttributes[1].offset = offsetof(Particle, vel);
|
descriptor.cVertexState.cAttributes[1].offset = offsetof(Particle, vel);
|
||||||
descriptor.cVertexInput.cAttributes[1].format = wgpu::VertexFormat::Float2;
|
descriptor.cVertexState.cAttributes[1].format = wgpu::VertexFormat::Float2;
|
||||||
descriptor.cVertexInput.cBuffers[1].stride = sizeof(glm::vec2);
|
descriptor.cVertexState.cVertexBuffers[1].arrayStride = sizeof(glm::vec2);
|
||||||
descriptor.cVertexInput.cBuffers[1].attributeCount = 1;
|
descriptor.cVertexState.cVertexBuffers[1].attributeCount = 1;
|
||||||
descriptor.cVertexInput.cBuffers[1].attributes = &descriptor.cVertexInput.cAttributes[2];
|
descriptor.cVertexState.cVertexBuffers[1].attributes = &descriptor.cVertexState.cAttributes[2];
|
||||||
descriptor.cVertexInput.cAttributes[2].shaderLocation = 2;
|
descriptor.cVertexState.cAttributes[2].shaderLocation = 2;
|
||||||
descriptor.cVertexInput.cAttributes[2].format = wgpu::VertexFormat::Float2;
|
descriptor.cVertexState.cAttributes[2].format = wgpu::VertexFormat::Float2;
|
||||||
descriptor.depthStencilState = &descriptor.cDepthStencilState;
|
descriptor.depthStencilState = &descriptor.cDepthStencilState;
|
||||||
descriptor.cDepthStencilState.format = wgpu::TextureFormat::Depth24PlusStencil8;
|
descriptor.cDepthStencilState.format = wgpu::TextureFormat::Depth24PlusStencil8;
|
||||||
descriptor.cColorStates[0].format = GetPreferredSwapChainTextureFormat();
|
descriptor.cColorStates[0].format = GetPreferredSwapChainTextureFormat();
|
||||||
|
|
|
@ -129,10 +129,10 @@ void init() {
|
||||||
descriptor.layout = utils::MakeBasicPipelineLayout(device, &bgl);
|
descriptor.layout = utils::MakeBasicPipelineLayout(device, &bgl);
|
||||||
descriptor.vertexStage.module = vsModule;
|
descriptor.vertexStage.module = vsModule;
|
||||||
descriptor.cFragmentStage.module = fsModule;
|
descriptor.cFragmentStage.module = fsModule;
|
||||||
descriptor.cVertexInput.bufferCount = 1;
|
descriptor.cVertexState.vertexBufferCount = 1;
|
||||||
descriptor.cVertexInput.cBuffers[0].stride = 4 * sizeof(float);
|
descriptor.cVertexState.cVertexBuffers[0].arrayStride = 4 * sizeof(float);
|
||||||
descriptor.cVertexInput.cBuffers[0].attributeCount = 1;
|
descriptor.cVertexState.cVertexBuffers[0].attributeCount = 1;
|
||||||
descriptor.cVertexInput.cAttributes[0].format = wgpu::VertexFormat::Float4;
|
descriptor.cVertexState.cAttributes[0].format = wgpu::VertexFormat::Float4;
|
||||||
descriptor.depthStencilState = &descriptor.cDepthStencilState;
|
descriptor.depthStencilState = &descriptor.cDepthStencilState;
|
||||||
descriptor.cDepthStencilState.format = wgpu::TextureFormat::Depth24PlusStencil8;
|
descriptor.cDepthStencilState.format = wgpu::TextureFormat::Depth24PlusStencil8;
|
||||||
descriptor.cColorStates[0].format = GetPreferredSwapChainTextureFormat();
|
descriptor.cColorStates[0].format = GetPreferredSwapChainTextureFormat();
|
||||||
|
|
|
@ -160,15 +160,15 @@ void init() {
|
||||||
fragColor = vec4(mix(f_col, vec3(0.5, 0.5, 0.5), 0.5), 1.0);
|
fragColor = vec4(mix(f_col, vec3(0.5, 0.5, 0.5), 0.5), 1.0);
|
||||||
})");
|
})");
|
||||||
|
|
||||||
utils::ComboVertexInputDescriptor vertexInput;
|
utils::ComboVertexStateDescriptor vertexState;
|
||||||
vertexInput.cBuffers[0].attributeCount = 2;
|
vertexState.cVertexBuffers[0].attributeCount = 2;
|
||||||
vertexInput.cAttributes[0].format = wgpu::VertexFormat::Float3;
|
vertexState.cAttributes[0].format = wgpu::VertexFormat::Float3;
|
||||||
vertexInput.cAttributes[1].shaderLocation = 1;
|
vertexState.cAttributes[1].shaderLocation = 1;
|
||||||
vertexInput.cAttributes[1].offset = 3 * sizeof(float);
|
vertexState.cAttributes[1].offset = 3 * sizeof(float);
|
||||||
vertexInput.cAttributes[1].format = wgpu::VertexFormat::Float3;
|
vertexState.cAttributes[1].format = wgpu::VertexFormat::Float3;
|
||||||
|
|
||||||
vertexInput.bufferCount = 1;
|
vertexState.vertexBufferCount = 1;
|
||||||
vertexInput.cBuffers[0].stride = 6 * sizeof(float);
|
vertexState.cVertexBuffers[0].arrayStride = 6 * sizeof(float);
|
||||||
|
|
||||||
auto bgl = utils::MakeBindGroupLayout(
|
auto bgl = utils::MakeBindGroupLayout(
|
||||||
device, {
|
device, {
|
||||||
|
@ -207,7 +207,7 @@ void init() {
|
||||||
descriptor.layout = pl;
|
descriptor.layout = pl;
|
||||||
descriptor.vertexStage.module = vsModule;
|
descriptor.vertexStage.module = vsModule;
|
||||||
descriptor.cFragmentStage.module = fsModule;
|
descriptor.cFragmentStage.module = fsModule;
|
||||||
descriptor.vertexInput = &vertexInput;
|
descriptor.vertexState = &vertexState;
|
||||||
descriptor.depthStencilState = &descriptor.cDepthStencilState;
|
descriptor.depthStencilState = &descriptor.cDepthStencilState;
|
||||||
descriptor.cDepthStencilState.format = wgpu::TextureFormat::Depth24PlusStencil8;
|
descriptor.cDepthStencilState.format = wgpu::TextureFormat::Depth24PlusStencil8;
|
||||||
descriptor.cColorStates[0].format = GetPreferredSwapChainTextureFormat();
|
descriptor.cColorStates[0].format = GetPreferredSwapChainTextureFormat();
|
||||||
|
@ -220,7 +220,7 @@ void init() {
|
||||||
pDescriptor.layout = pl;
|
pDescriptor.layout = pl;
|
||||||
pDescriptor.vertexStage.module = vsModule;
|
pDescriptor.vertexStage.module = vsModule;
|
||||||
pDescriptor.cFragmentStage.module = fsModule;
|
pDescriptor.cFragmentStage.module = fsModule;
|
||||||
pDescriptor.vertexInput = &vertexInput;
|
pDescriptor.vertexState = &vertexState;
|
||||||
pDescriptor.depthStencilState = &pDescriptor.cDepthStencilState;
|
pDescriptor.depthStencilState = &pDescriptor.cDepthStencilState;
|
||||||
pDescriptor.cDepthStencilState.format = wgpu::TextureFormat::Depth24PlusStencil8;
|
pDescriptor.cDepthStencilState.format = wgpu::TextureFormat::Depth24PlusStencil8;
|
||||||
pDescriptor.cColorStates[0].format = GetPreferredSwapChainTextureFormat();
|
pDescriptor.cColorStates[0].format = GetPreferredSwapChainTextureFormat();
|
||||||
|
@ -234,7 +234,7 @@ void init() {
|
||||||
rfDescriptor.layout = pl;
|
rfDescriptor.layout = pl;
|
||||||
rfDescriptor.vertexStage.module = vsModule;
|
rfDescriptor.vertexStage.module = vsModule;
|
||||||
rfDescriptor.cFragmentStage.module = fsReflectionModule;
|
rfDescriptor.cFragmentStage.module = fsReflectionModule;
|
||||||
rfDescriptor.vertexInput = &vertexInput;
|
rfDescriptor.vertexState = &vertexState;
|
||||||
rfDescriptor.depthStencilState = &rfDescriptor.cDepthStencilState;
|
rfDescriptor.depthStencilState = &rfDescriptor.cDepthStencilState;
|
||||||
rfDescriptor.cDepthStencilState.format = wgpu::TextureFormat::Depth24PlusStencil8;
|
rfDescriptor.cDepthStencilState.format = wgpu::TextureFormat::Depth24PlusStencil8;
|
||||||
rfDescriptor.cColorStates[0].format = GetPreferredSwapChainTextureFormat();
|
rfDescriptor.cColorStates[0].format = GetPreferredSwapChainTextureFormat();
|
||||||
|
|
|
@ -106,8 +106,9 @@ namespace dawn_native {
|
||||||
if (aspects[VALIDATION_ASPECT_VERTEX_BUFFERS]) {
|
if (aspects[VALIDATION_ASPECT_VERTEX_BUFFERS]) {
|
||||||
ASSERT(mLastRenderPipeline != nullptr);
|
ASSERT(mLastRenderPipeline != nullptr);
|
||||||
|
|
||||||
auto requiredInputs = mLastRenderPipeline->GetInputsSetMask();
|
const std::bitset<kMaxVertexBuffers>& requiredVertexBuffers =
|
||||||
if ((mInputsSet & requiredInputs) == requiredInputs) {
|
mLastRenderPipeline->GetVertexBufferSlotsUsed();
|
||||||
|
if ((mVertexBufferSlotsUsed & requiredVertexBuffers) == requiredVertexBuffers) {
|
||||||
mAspects.set(VALIDATION_ASPECT_VERTEX_BUFFERS);
|
mAspects.set(VALIDATION_ASPECT_VERTEX_BUFFERS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -153,7 +154,7 @@ namespace dawn_native {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandBufferStateTracker::SetVertexBuffer(uint32_t slot) {
|
void CommandBufferStateTracker::SetVertexBuffer(uint32_t slot) {
|
||||||
mInputsSet.set(slot);
|
mVertexBufferSlotsUsed.set(slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommandBufferStateTracker::SetPipelineCommon(PipelineBase* pipeline) {
|
void CommandBufferStateTracker::SetPipelineCommon(PipelineBase* pipeline) {
|
||||||
|
|
|
@ -53,7 +53,7 @@ namespace dawn_native {
|
||||||
ValidationAspects mAspects;
|
ValidationAspects mAspects;
|
||||||
|
|
||||||
std::array<BindGroupBase*, kMaxBindGroups> mBindgroups = {};
|
std::array<BindGroupBase*, kMaxBindGroups> mBindgroups = {};
|
||||||
std::bitset<kMaxVertexBuffers> mInputsSet;
|
std::bitset<kMaxVertexBuffers> mVertexBufferSlotsUsed;
|
||||||
|
|
||||||
PipelineLayoutBase* mLastPipelineLayout = nullptr;
|
PipelineLayoutBase* mLastPipelineLayout = nullptr;
|
||||||
RenderPipelineBase* mLastRenderPipeline = nullptr;
|
RenderPipelineBase* mLastRenderPipeline = nullptr;
|
||||||
|
|
|
@ -61,44 +61,44 @@ namespace dawn_native {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
MaybeError ValidateVertexBufferDescriptor(
|
MaybeError ValidateVertexBufferLayoutDescriptor(
|
||||||
const VertexBufferDescriptor* buffer,
|
const VertexBufferLayoutDescriptor* buffer,
|
||||||
std::bitset<kMaxVertexAttributes>* attributesSetMask) {
|
std::bitset<kMaxVertexAttributes>* attributesSetMask) {
|
||||||
DAWN_TRY(ValidateInputStepMode(buffer->stepMode));
|
DAWN_TRY(ValidateInputStepMode(buffer->stepMode));
|
||||||
if (buffer->stride > kMaxVertexBufferStride) {
|
if (buffer->arrayStride > kMaxVertexBufferStride) {
|
||||||
return DAWN_VALIDATION_ERROR("Setting input stride out of bounds");
|
return DAWN_VALIDATION_ERROR("Setting arrayStride out of bounds");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buffer->stride % 4 != 0) {
|
if (buffer->arrayStride % 4 != 0) {
|
||||||
return DAWN_VALIDATION_ERROR(
|
return DAWN_VALIDATION_ERROR(
|
||||||
"Stride of Vertex buffer needs to be a multiple of 4 bytes");
|
"arrayStride of Vertex buffer needs to be a multiple of 4 bytes");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t i = 0; i < buffer->attributeCount; ++i) {
|
for (uint32_t i = 0; i < buffer->attributeCount; ++i) {
|
||||||
DAWN_TRY(ValidateVertexAttributeDescriptor(&buffer->attributes[i], buffer->stride,
|
DAWN_TRY(ValidateVertexAttributeDescriptor(&buffer->attributes[i],
|
||||||
attributesSetMask));
|
buffer->arrayStride, attributesSetMask));
|
||||||
}
|
}
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
MaybeError ValidateVertexInputDescriptor(
|
MaybeError ValidateVertexStateDescriptor(
|
||||||
const VertexInputDescriptor* descriptor,
|
const VertexStateDescriptor* descriptor,
|
||||||
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");
|
||||||
}
|
}
|
||||||
DAWN_TRY(ValidateIndexFormat(descriptor->indexFormat));
|
DAWN_TRY(ValidateIndexFormat(descriptor->indexFormat));
|
||||||
|
|
||||||
if (descriptor->bufferCount > kMaxVertexBuffers) {
|
if (descriptor->vertexBufferCount > kMaxVertexBuffers) {
|
||||||
return DAWN_VALIDATION_ERROR("Vertex Inputs number exceeds maximum");
|
return DAWN_VALIDATION_ERROR("Vertex buffer count exceeds maximum");
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t totalAttributesNum = 0;
|
uint32_t totalAttributesNum = 0;
|
||||||
for (uint32_t i = 0; i < descriptor->bufferCount; ++i) {
|
for (uint32_t i = 0; i < descriptor->vertexBufferCount; ++i) {
|
||||||
DAWN_TRY(
|
DAWN_TRY(ValidateVertexBufferLayoutDescriptor(&descriptor->vertexBuffers[i],
|
||||||
ValidateVertexBufferDescriptor(&descriptor->buffers[i], attributesSetMask));
|
attributesSetMask));
|
||||||
totalAttributesNum += descriptor->buffers[i].attributeCount;
|
totalAttributesNum += descriptor->vertexBuffers[i].attributeCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Every vertex attribute has a member called shaderLocation, and there are some
|
// Every vertex attribute has a member called shaderLocation, and there are some
|
||||||
|
@ -288,8 +288,8 @@ namespace dawn_native {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::bitset<kMaxVertexAttributes> attributesSetMask;
|
std::bitset<kMaxVertexAttributes> attributesSetMask;
|
||||||
if (descriptor->vertexInput) {
|
if (descriptor->vertexState) {
|
||||||
DAWN_TRY(ValidateVertexInputDescriptor(descriptor->vertexInput, &attributesSetMask));
|
DAWN_TRY(ValidateVertexStateDescriptor(descriptor->vertexState, &attributesSetMask));
|
||||||
}
|
}
|
||||||
|
|
||||||
DAWN_TRY(ValidatePrimitiveTopology(descriptor->primitiveTopology));
|
DAWN_TRY(ValidatePrimitiveTopology(descriptor->primitiveTopology));
|
||||||
|
@ -305,7 +305,7 @@ namespace dawn_native {
|
||||||
if ((descriptor->vertexStage.module->GetUsedVertexAttributes() & ~attributesSetMask)
|
if ((descriptor->vertexStage.module->GetUsedVertexAttributes() & ~attributesSetMask)
|
||||||
.any()) {
|
.any()) {
|
||||||
return DAWN_VALIDATION_ERROR(
|
return DAWN_VALIDATION_ERROR(
|
||||||
"Pipeline vertex stage uses inputs not in the input state");
|
"Pipeline vertex stage uses vertex buffers not in the vertex state");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IsValidSampleCount(descriptor->sampleCount)) {
|
if (!IsValidSampleCount(descriptor->sampleCount)) {
|
||||||
|
@ -378,29 +378,31 @@ namespace dawn_native {
|
||||||
mVertexEntryPoint(descriptor->vertexStage.entryPoint),
|
mVertexEntryPoint(descriptor->vertexStage.entryPoint),
|
||||||
mFragmentModule(descriptor->fragmentStage->module),
|
mFragmentModule(descriptor->fragmentStage->module),
|
||||||
mFragmentEntryPoint(descriptor->fragmentStage->entryPoint) {
|
mFragmentEntryPoint(descriptor->fragmentStage->entryPoint) {
|
||||||
if (descriptor->vertexInput != nullptr) {
|
if (descriptor->vertexState != nullptr) {
|
||||||
mVertexInput = *descriptor->vertexInput;
|
mVertexState = *descriptor->vertexState;
|
||||||
} else {
|
} else {
|
||||||
mVertexInput = VertexInputDescriptor();
|
mVertexState = VertexStateDescriptor();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t slot = 0; slot < mVertexInput.bufferCount; ++slot) {
|
for (uint32_t slot = 0; slot < mVertexState.vertexBufferCount; ++slot) {
|
||||||
if (mVertexInput.buffers[slot].attributeCount == 0) {
|
if (mVertexState.vertexBuffers[slot].attributeCount == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
mInputsSetMask.set(slot);
|
mVertexBufferSlotsUsed.set(slot);
|
||||||
mInputInfos[slot].stride = mVertexInput.buffers[slot].stride;
|
mVertexBufferInfos[slot].arrayStride = mVertexState.vertexBuffers[slot].arrayStride;
|
||||||
mInputInfos[slot].stepMode = mVertexInput.buffers[slot].stepMode;
|
mVertexBufferInfos[slot].stepMode = mVertexState.vertexBuffers[slot].stepMode;
|
||||||
|
|
||||||
uint32_t location = 0;
|
uint32_t location = 0;
|
||||||
for (uint32_t i = 0; i < mVertexInput.buffers[slot].attributeCount; ++i) {
|
for (uint32_t i = 0; i < mVertexState.vertexBuffers[slot].attributeCount; ++i) {
|
||||||
location = mVertexInput.buffers[slot].attributes[i].shaderLocation;
|
location = mVertexState.vertexBuffers[slot].attributes[i].shaderLocation;
|
||||||
mAttributesSetMask.set(location);
|
mAttributeLocationsUsed.set(location);
|
||||||
mAttributeInfos[location].shaderLocation = location;
|
mAttributeInfos[location].shaderLocation = location;
|
||||||
mAttributeInfos[location].inputSlot = slot;
|
mAttributeInfos[location].vertexBufferSlot = slot;
|
||||||
mAttributeInfos[location].offset = mVertexInput.buffers[slot].attributes[i].offset;
|
mAttributeInfos[location].offset =
|
||||||
mAttributeInfos[location].format = mVertexInput.buffers[slot].attributes[i].format;
|
mVertexState.vertexBuffers[slot].attributes[i].offset;
|
||||||
|
mAttributeInfos[location].format =
|
||||||
|
mVertexState.vertexBuffers[slot].attributes[i].format;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -454,31 +456,31 @@ namespace dawn_native {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const VertexInputDescriptor* RenderPipelineBase::GetVertexInputDescriptor() const {
|
const VertexStateDescriptor* RenderPipelineBase::GetVertexStateDescriptor() const {
|
||||||
ASSERT(!IsError());
|
ASSERT(!IsError());
|
||||||
return &mVertexInput;
|
return &mVertexState;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::bitset<kMaxVertexAttributes>& RenderPipelineBase::GetAttributesSetMask() const {
|
const std::bitset<kMaxVertexAttributes>& RenderPipelineBase::GetAttributeLocationsUsed() const {
|
||||||
ASSERT(!IsError());
|
ASSERT(!IsError());
|
||||||
return mAttributesSetMask;
|
return mAttributeLocationsUsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
const VertexAttributeInfo& RenderPipelineBase::GetAttribute(uint32_t location) const {
|
const VertexAttributeInfo& RenderPipelineBase::GetAttribute(uint32_t location) const {
|
||||||
ASSERT(!IsError());
|
ASSERT(!IsError());
|
||||||
ASSERT(mAttributesSetMask[location]);
|
ASSERT(mAttributeLocationsUsed[location]);
|
||||||
return mAttributeInfos[location];
|
return mAttributeInfos[location];
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::bitset<kMaxVertexBuffers>& RenderPipelineBase::GetInputsSetMask() const {
|
const std::bitset<kMaxVertexBuffers>& RenderPipelineBase::GetVertexBufferSlotsUsed() const {
|
||||||
ASSERT(!IsError());
|
ASSERT(!IsError());
|
||||||
return mInputsSetMask;
|
return mVertexBufferSlotsUsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
const VertexBufferInfo& RenderPipelineBase::GetInput(uint32_t slot) const {
|
const VertexBufferInfo& RenderPipelineBase::GetVertexBuffer(uint32_t slot) const {
|
||||||
ASSERT(!IsError());
|
ASSERT(!IsError());
|
||||||
ASSERT(mInputsSetMask[slot]);
|
ASSERT(mVertexBufferSlotsUsed[slot]);
|
||||||
return mInputInfos[slot];
|
return mVertexBufferInfos[slot];
|
||||||
}
|
}
|
||||||
|
|
||||||
const ColorStateDescriptor* RenderPipelineBase::GetColorStateDescriptor(
|
const ColorStateDescriptor* RenderPipelineBase::GetColorStateDescriptor(
|
||||||
|
@ -540,10 +542,10 @@ namespace dawn_native {
|
||||||
return mAttachmentState.Get();
|
return mAttachmentState.Get();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::bitset<kMaxVertexAttributes> RenderPipelineBase::GetAttributesUsingInput(
|
std::bitset<kMaxVertexAttributes> RenderPipelineBase::GetAttributesUsingVertexBuffer(
|
||||||
uint32_t slot) const {
|
uint32_t slot) const {
|
||||||
ASSERT(!IsError());
|
ASSERT(!IsError());
|
||||||
return attributesUsingInput[slot];
|
return attributesUsingVertexBuffer[slot];
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t RenderPipelineBase::HashFunc::operator()(const RenderPipelineBase* pipeline) const {
|
size_t RenderPipelineBase::HashFunc::operator()(const RenderPipelineBase* pipeline) const {
|
||||||
|
@ -578,20 +580,21 @@ namespace dawn_native {
|
||||||
desc.stencilBack.depthFailOp, desc.stencilBack.passOp);
|
desc.stencilBack.depthFailOp, desc.stencilBack.passOp);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hash vertex input state
|
// Hash vertex state
|
||||||
HashCombine(&hash, pipeline->mAttributesSetMask);
|
HashCombine(&hash, pipeline->mAttributeLocationsUsed);
|
||||||
for (uint32_t i : IterateBitSet(pipeline->mAttributesSetMask)) {
|
for (uint32_t i : IterateBitSet(pipeline->mAttributeLocationsUsed)) {
|
||||||
const VertexAttributeInfo& 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.vertexBufferSlot, desc.offset,
|
||||||
|
desc.format);
|
||||||
}
|
}
|
||||||
|
|
||||||
HashCombine(&hash, pipeline->mInputsSetMask);
|
HashCombine(&hash, pipeline->mVertexBufferSlotsUsed);
|
||||||
for (uint32_t i : IterateBitSet(pipeline->mInputsSetMask)) {
|
for (uint32_t i : IterateBitSet(pipeline->mVertexBufferSlotsUsed)) {
|
||||||
const VertexBufferInfo& desc = pipeline->GetInput(i);
|
const VertexBufferInfo& desc = pipeline->GetVertexBuffer(i);
|
||||||
HashCombine(&hash, desc.stride, desc.stepMode);
|
HashCombine(&hash, desc.arrayStride, desc.stepMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
HashCombine(&hash, pipeline->mVertexInput.indexFormat);
|
HashCombine(&hash, pipeline->mVertexState.indexFormat);
|
||||||
|
|
||||||
// Hash rasterization state
|
// Hash rasterization state
|
||||||
{
|
{
|
||||||
|
@ -666,34 +669,34 @@ namespace dawn_native {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check vertex input state
|
// Check vertex state
|
||||||
if (a->mAttributesSetMask != b->mAttributesSetMask) {
|
if (a->mAttributeLocationsUsed != b->mAttributeLocationsUsed) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t i : IterateBitSet(a->mAttributesSetMask)) {
|
for (uint32_t i : IterateBitSet(a->mAttributeLocationsUsed)) {
|
||||||
const VertexAttributeInfo& descA = a->GetAttribute(i);
|
const VertexAttributeInfo& descA = a->GetAttribute(i);
|
||||||
const VertexAttributeInfo& 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.vertexBufferSlot != descB.vertexBufferSlot || descA.offset != descB.offset ||
|
||||||
descA.format != descB.format) {
|
descA.format != descB.format) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a->mInputsSetMask != b->mInputsSetMask) {
|
if (a->mVertexBufferSlotsUsed != b->mVertexBufferSlotsUsed) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t i : IterateBitSet(a->mInputsSetMask)) {
|
for (uint32_t i : IterateBitSet(a->mVertexBufferSlotsUsed)) {
|
||||||
const VertexBufferInfo& descA = a->GetInput(i);
|
const VertexBufferInfo& descA = a->GetVertexBuffer(i);
|
||||||
const VertexBufferInfo& descB = b->GetInput(i);
|
const VertexBufferInfo& descB = b->GetVertexBuffer(i);
|
||||||
if (descA.stride != descB.stride || descA.stepMode != descB.stepMode) {
|
if (descA.arrayStride != descB.arrayStride || descA.stepMode != descB.stepMode) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a->mVertexInput.indexFormat != b->mVertexInput.indexFormat) {
|
if (a->mVertexState.indexFormat != b->mVertexState.indexFormat) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,14 +41,14 @@ namespace dawn_native {
|
||||||
bool BlendEnabled(const ColorStateDescriptor* mColorState);
|
bool BlendEnabled(const ColorStateDescriptor* mColorState);
|
||||||
|
|
||||||
struct VertexAttributeInfo {
|
struct VertexAttributeInfo {
|
||||||
uint32_t shaderLocation;
|
|
||||||
uint32_t inputSlot;
|
|
||||||
uint64_t offset;
|
|
||||||
wgpu::VertexFormat format;
|
wgpu::VertexFormat format;
|
||||||
|
uint64_t offset;
|
||||||
|
uint32_t shaderLocation;
|
||||||
|
uint32_t vertexBufferSlot;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VertexBufferInfo {
|
struct VertexBufferInfo {
|
||||||
uint64_t stride;
|
uint64_t arrayStride;
|
||||||
wgpu::InputStepMode stepMode;
|
wgpu::InputStepMode stepMode;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -59,11 +59,11 @@ namespace dawn_native {
|
||||||
|
|
||||||
static RenderPipelineBase* MakeError(DeviceBase* device);
|
static RenderPipelineBase* MakeError(DeviceBase* device);
|
||||||
|
|
||||||
const VertexInputDescriptor* GetVertexInputDescriptor() const;
|
const VertexStateDescriptor* GetVertexStateDescriptor() const;
|
||||||
const std::bitset<kMaxVertexAttributes>& GetAttributesSetMask() const;
|
const std::bitset<kMaxVertexAttributes>& GetAttributeLocationsUsed() const;
|
||||||
const VertexAttributeInfo& GetAttribute(uint32_t location) const;
|
const VertexAttributeInfo& GetAttribute(uint32_t location) const;
|
||||||
const std::bitset<kMaxVertexBuffers>& GetInputsSetMask() const;
|
const std::bitset<kMaxVertexBuffers>& GetVertexBufferSlotsUsed() const;
|
||||||
const VertexBufferInfo& GetInput(uint32_t slot) const;
|
const VertexBufferInfo& GetVertexBuffer(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;
|
||||||
|
@ -79,8 +79,9 @@ namespace dawn_native {
|
||||||
|
|
||||||
const AttachmentState* GetAttachmentState() const;
|
const AttachmentState* GetAttachmentState() const;
|
||||||
|
|
||||||
std::bitset<kMaxVertexAttributes> GetAttributesUsingInput(uint32_t slot) const;
|
std::bitset<kMaxVertexAttributes> GetAttributesUsingVertexBuffer(uint32_t slot) const;
|
||||||
std::array<std::bitset<kMaxVertexAttributes>, kMaxVertexBuffers> attributesUsingInput;
|
std::array<std::bitset<kMaxVertexAttributes>, kMaxVertexBuffers>
|
||||||
|
attributesUsingVertexBuffer;
|
||||||
|
|
||||||
// Functors necessary for the unordered_set<RenderPipelineBase*>-based cache.
|
// Functors necessary for the unordered_set<RenderPipelineBase*>-based cache.
|
||||||
struct HashFunc {
|
struct HashFunc {
|
||||||
|
@ -93,12 +94,12 @@ namespace dawn_native {
|
||||||
private:
|
private:
|
||||||
RenderPipelineBase(DeviceBase* device, ObjectBase::ErrorTag tag);
|
RenderPipelineBase(DeviceBase* device, ObjectBase::ErrorTag tag);
|
||||||
|
|
||||||
// Vertex input
|
// Vertex state
|
||||||
VertexInputDescriptor mVertexInput;
|
VertexStateDescriptor mVertexState;
|
||||||
std::bitset<kMaxVertexAttributes> mAttributesSetMask;
|
std::bitset<kMaxVertexAttributes> mAttributeLocationsUsed;
|
||||||
std::array<VertexAttributeInfo, kMaxVertexAttributes> mAttributeInfos;
|
std::array<VertexAttributeInfo, kMaxVertexAttributes> mAttributeInfos;
|
||||||
std::bitset<kMaxVertexBuffers> mInputsSetMask;
|
std::bitset<kMaxVertexBuffers> mVertexBufferSlotsUsed;
|
||||||
std::array<VertexBufferInfo, kMaxVertexBuffers> mInputInfos;
|
std::array<VertexBufferInfo, kMaxVertexBuffers> mVertexBufferInfos;
|
||||||
|
|
||||||
// Attachments
|
// Attachments
|
||||||
Ref<AttachmentState> mAttachmentState;
|
Ref<AttachmentState> mAttachmentState;
|
||||||
|
|
|
@ -397,29 +397,30 @@ namespace dawn_native { namespace d3d12 {
|
||||||
auto* d3d12BufferView = &mD3D12BufferViews[slot];
|
auto* d3d12BufferView = &mD3D12BufferViews[slot];
|
||||||
d3d12BufferView->BufferLocation = buffer->GetVA() + offset;
|
d3d12BufferView->BufferLocation = buffer->GetVA() + offset;
|
||||||
d3d12BufferView->SizeInBytes = buffer->GetSize() - offset;
|
d3d12BufferView->SizeInBytes = buffer->GetSize() - offset;
|
||||||
// The bufferView stride is set based on the input state before a draw.
|
// The bufferView stride is set based on the vertex state before a draw.
|
||||||
}
|
}
|
||||||
|
|
||||||
void Apply(ID3D12GraphicsCommandList* commandList,
|
void Apply(ID3D12GraphicsCommandList* commandList,
|
||||||
const RenderPipeline* renderPipeline) {
|
const RenderPipeline* renderPipeline) {
|
||||||
ASSERT(renderPipeline != nullptr);
|
ASSERT(renderPipeline != nullptr);
|
||||||
|
|
||||||
std::bitset<kMaxVertexBuffers> inputsMask = renderPipeline->GetInputsSetMask();
|
std::bitset<kMaxVertexBuffers> vertexBufferSlotsUsed =
|
||||||
|
renderPipeline->GetVertexBufferSlotsUsed();
|
||||||
|
|
||||||
uint32_t startSlot = mStartSlot;
|
uint32_t startSlot = mStartSlot;
|
||||||
uint32_t endSlot = mEndSlot;
|
uint32_t endSlot = mEndSlot;
|
||||||
|
|
||||||
// If the input state has changed, we need to update the StrideInBytes
|
// If the vertex state has changed, we need to update the StrideInBytes
|
||||||
// for the D3D12 buffer views. We also need to extend the dirty range to
|
// for the D3D12 buffer views. We also need to extend the dirty range to
|
||||||
// touch all these slots because the stride may have changed.
|
// touch all these slots because the stride may have changed.
|
||||||
if (mLastAppliedRenderPipeline != renderPipeline) {
|
if (mLastAppliedRenderPipeline != renderPipeline) {
|
||||||
mLastAppliedRenderPipeline = renderPipeline;
|
mLastAppliedRenderPipeline = renderPipeline;
|
||||||
|
|
||||||
for (uint32_t slot : IterateBitSet(inputsMask)) {
|
for (uint32_t slot : IterateBitSet(vertexBufferSlotsUsed)) {
|
||||||
startSlot = std::min(startSlot, slot);
|
startSlot = std::min(startSlot, slot);
|
||||||
endSlot = std::max(endSlot, slot + 1);
|
endSlot = std::max(endSlot, slot + 1);
|
||||||
mD3D12BufferViews[slot].StrideInBytes =
|
mD3D12BufferViews[slot].StrideInBytes =
|
||||||
renderPipeline->GetInput(slot).stride;
|
renderPipeline->GetVertexBuffer(slot).arrayStride;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -462,7 +463,7 @@ namespace dawn_native { namespace d3d12 {
|
||||||
|
|
||||||
void OnSetPipeline(const RenderPipelineBase* pipeline) {
|
void OnSetPipeline(const RenderPipelineBase* pipeline) {
|
||||||
mD3D12BufferView.Format =
|
mD3D12BufferView.Format =
|
||||||
DXGIIndexFormat(pipeline->GetVertexInputDescriptor()->indexFormat);
|
DXGIIndexFormat(pipeline->GetVertexStateDescriptor()->indexFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Apply(ID3D12GraphicsCommandList* commandList) {
|
void Apply(ID3D12GraphicsCommandList* commandList) {
|
||||||
|
|
|
@ -359,7 +359,7 @@ namespace dawn_native { namespace d3d12 {
|
||||||
|
|
||||||
// D3D12 logs warnings if any empty input state is used
|
// D3D12 logs warnings if any empty input state is used
|
||||||
std::array<D3D12_INPUT_ELEMENT_DESC, kMaxVertexAttributes> inputElementDescriptors;
|
std::array<D3D12_INPUT_ELEMENT_DESC, kMaxVertexAttributes> inputElementDescriptors;
|
||||||
if (GetAttributesSetMask().any()) {
|
if (GetAttributeLocationsUsed().any()) {
|
||||||
descriptorD3D12.InputLayout = ComputeInputLayout(&inputElementDescriptors);
|
descriptorD3D12.InputLayout = ComputeInputLayout(&inputElementDescriptors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -423,7 +423,7 @@ namespace dawn_native { namespace d3d12 {
|
||||||
D3D12_INPUT_LAYOUT_DESC RenderPipeline::ComputeInputLayout(
|
D3D12_INPUT_LAYOUT_DESC RenderPipeline::ComputeInputLayout(
|
||||||
std::array<D3D12_INPUT_ELEMENT_DESC, kMaxVertexAttributes>* inputElementDescriptors) {
|
std::array<D3D12_INPUT_ELEMENT_DESC, kMaxVertexAttributes>* inputElementDescriptors) {
|
||||||
unsigned int count = 0;
|
unsigned int count = 0;
|
||||||
for (auto i : IterateBitSet(GetAttributesSetMask())) {
|
for (auto i : IterateBitSet(GetAttributeLocationsUsed())) {
|
||||||
D3D12_INPUT_ELEMENT_DESC& inputElementDescriptor = (*inputElementDescriptors)[count++];
|
D3D12_INPUT_ELEMENT_DESC& inputElementDescriptor = (*inputElementDescriptors)[count++];
|
||||||
|
|
||||||
const VertexAttributeInfo& attribute = GetAttribute(i);
|
const VertexAttributeInfo& attribute = GetAttribute(i);
|
||||||
|
@ -433,9 +433,9 @@ namespace dawn_native { namespace d3d12 {
|
||||||
inputElementDescriptor.SemanticName = "TEXCOORD";
|
inputElementDescriptor.SemanticName = "TEXCOORD";
|
||||||
inputElementDescriptor.SemanticIndex = static_cast<uint32_t>(i);
|
inputElementDescriptor.SemanticIndex = static_cast<uint32_t>(i);
|
||||||
inputElementDescriptor.Format = VertexFormatType(attribute.format);
|
inputElementDescriptor.Format = VertexFormatType(attribute.format);
|
||||||
inputElementDescriptor.InputSlot = attribute.inputSlot;
|
inputElementDescriptor.InputSlot = attribute.vertexBufferSlot;
|
||||||
|
|
||||||
const VertexBufferInfo& input = GetInput(attribute.inputSlot);
|
const VertexBufferInfo& input = GetVertexBuffer(attribute.vertexBufferSlot);
|
||||||
|
|
||||||
inputElementDescriptor.AlignedByteOffset = attribute.offset;
|
inputElementDescriptor.AlignedByteOffset = attribute.offset;
|
||||||
inputElementDescriptor.InputSlotClass = InputStepModeFunction(input.stepMode);
|
inputElementDescriptor.InputSlotClass = InputStepModeFunction(input.stepMode);
|
||||||
|
|
|
@ -549,7 +549,7 @@ namespace dawn_native { namespace metal {
|
||||||
|
|
||||||
// Keeps track of the dirty vertex buffer values so they can be lazily applied when we know
|
// Keeps track of the dirty vertex buffer values so they can be lazily applied when we know
|
||||||
// all the relevant state.
|
// all the relevant state.
|
||||||
class VertexInputBufferTracker {
|
class VertexBufferTracker {
|
||||||
public:
|
public:
|
||||||
void OnSetVertexBuffer(uint32_t slot, Buffer* buffer, uint64_t offset) {
|
void OnSetVertexBuffer(uint32_t slot, Buffer* buffer, uint64_t offset) {
|
||||||
mVertexBuffers[slot] = buffer->GetMTLBuffer();
|
mVertexBuffers[slot] = buffer->GetMTLBuffer();
|
||||||
|
@ -564,12 +564,12 @@ namespace dawn_native { namespace metal {
|
||||||
// When a new pipeline is bound we must set all the vertex buffers again because
|
// When a new pipeline is bound we must set all the vertex buffers again because
|
||||||
// they might have been offset by the pipeline layout, and they might be packed
|
// they might have been offset by the pipeline layout, and they might be packed
|
||||||
// differently from the previous pipeline.
|
// differently from the previous pipeline.
|
||||||
mDirtyVertexBuffers |= pipeline->GetInputsSetMask();
|
mDirtyVertexBuffers |= pipeline->GetVertexBufferSlotsUsed();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Apply(id<MTLRenderCommandEncoder> encoder, RenderPipeline* pipeline) {
|
void Apply(id<MTLRenderCommandEncoder> encoder, RenderPipeline* pipeline) {
|
||||||
std::bitset<kMaxVertexBuffers> vertexBuffersToApply =
|
std::bitset<kMaxVertexBuffers> vertexBuffersToApply =
|
||||||
mDirtyVertexBuffers & pipeline->GetInputsSetMask();
|
mDirtyVertexBuffers & pipeline->GetVertexBufferSlotsUsed();
|
||||||
|
|
||||||
for (uint32_t dawnIndex : IterateBitSet(vertexBuffersToApply)) {
|
for (uint32_t dawnIndex : IterateBitSet(vertexBuffersToApply)) {
|
||||||
uint32_t metalIndex = pipeline->GetMtlVertexBufferIndex(dawnIndex);
|
uint32_t metalIndex = pipeline->GetMtlVertexBufferIndex(dawnIndex);
|
||||||
|
@ -904,7 +904,7 @@ namespace dawn_native { namespace metal {
|
||||||
RenderPipeline* lastPipeline = nullptr;
|
RenderPipeline* lastPipeline = nullptr;
|
||||||
id<MTLBuffer> indexBuffer = nil;
|
id<MTLBuffer> indexBuffer = nil;
|
||||||
uint32_t indexBufferBaseOffset = 0;
|
uint32_t indexBufferBaseOffset = 0;
|
||||||
VertexInputBufferTracker vertexInputBuffers;
|
VertexBufferTracker vertexBuffers;
|
||||||
StorageBufferLengthTracker storageBufferLengths = {};
|
StorageBufferLengthTracker storageBufferLengths = {};
|
||||||
BindGroupTracker bindGroups(&storageBufferLengths);
|
BindGroupTracker bindGroups(&storageBufferLengths);
|
||||||
|
|
||||||
|
@ -917,7 +917,7 @@ namespace dawn_native { namespace metal {
|
||||||
case Command::Draw: {
|
case Command::Draw: {
|
||||||
DrawCmd* draw = iter->NextCommand<DrawCmd>();
|
DrawCmd* draw = iter->NextCommand<DrawCmd>();
|
||||||
|
|
||||||
vertexInputBuffers.Apply(encoder, lastPipeline);
|
vertexBuffers.Apply(encoder, lastPipeline);
|
||||||
bindGroups.Apply(encoder);
|
bindGroups.Apply(encoder);
|
||||||
storageBufferLengths.Apply(encoder, lastPipeline);
|
storageBufferLengths.Apply(encoder, lastPipeline);
|
||||||
|
|
||||||
|
@ -934,9 +934,9 @@ namespace dawn_native { namespace metal {
|
||||||
case Command::DrawIndexed: {
|
case Command::DrawIndexed: {
|
||||||
DrawIndexedCmd* draw = iter->NextCommand<DrawIndexedCmd>();
|
DrawIndexedCmd* draw = iter->NextCommand<DrawIndexedCmd>();
|
||||||
size_t formatSize =
|
size_t formatSize =
|
||||||
IndexFormatSize(lastPipeline->GetVertexInputDescriptor()->indexFormat);
|
IndexFormatSize(lastPipeline->GetVertexStateDescriptor()->indexFormat);
|
||||||
|
|
||||||
vertexInputBuffers.Apply(encoder, lastPipeline);
|
vertexBuffers.Apply(encoder, lastPipeline);
|
||||||
bindGroups.Apply(encoder);
|
bindGroups.Apply(encoder);
|
||||||
storageBufferLengths.Apply(encoder, lastPipeline);
|
storageBufferLengths.Apply(encoder, lastPipeline);
|
||||||
|
|
||||||
|
@ -957,7 +957,7 @@ namespace dawn_native { namespace metal {
|
||||||
case Command::DrawIndirect: {
|
case Command::DrawIndirect: {
|
||||||
DrawIndirectCmd* draw = iter->NextCommand<DrawIndirectCmd>();
|
DrawIndirectCmd* draw = iter->NextCommand<DrawIndirectCmd>();
|
||||||
|
|
||||||
vertexInputBuffers.Apply(encoder, lastPipeline);
|
vertexBuffers.Apply(encoder, lastPipeline);
|
||||||
bindGroups.Apply(encoder);
|
bindGroups.Apply(encoder);
|
||||||
storageBufferLengths.Apply(encoder, lastPipeline);
|
storageBufferLengths.Apply(encoder, lastPipeline);
|
||||||
|
|
||||||
|
@ -971,7 +971,7 @@ namespace dawn_native { namespace metal {
|
||||||
case Command::DrawIndexedIndirect: {
|
case Command::DrawIndexedIndirect: {
|
||||||
DrawIndirectCmd* draw = iter->NextCommand<DrawIndirectCmd>();
|
DrawIndirectCmd* draw = iter->NextCommand<DrawIndirectCmd>();
|
||||||
|
|
||||||
vertexInputBuffers.Apply(encoder, lastPipeline);
|
vertexBuffers.Apply(encoder, lastPipeline);
|
||||||
bindGroups.Apply(encoder);
|
bindGroups.Apply(encoder);
|
||||||
storageBufferLengths.Apply(encoder, lastPipeline);
|
storageBufferLengths.Apply(encoder, lastPipeline);
|
||||||
|
|
||||||
|
@ -1013,7 +1013,7 @@ namespace dawn_native { namespace metal {
|
||||||
SetRenderPipelineCmd* cmd = iter->NextCommand<SetRenderPipelineCmd>();
|
SetRenderPipelineCmd* cmd = iter->NextCommand<SetRenderPipelineCmd>();
|
||||||
RenderPipeline* newPipeline = ToBackend(cmd->pipeline).Get();
|
RenderPipeline* newPipeline = ToBackend(cmd->pipeline).Get();
|
||||||
|
|
||||||
vertexInputBuffers.OnSetPipeline(lastPipeline, newPipeline);
|
vertexBuffers.OnSetPipeline(lastPipeline, newPipeline);
|
||||||
bindGroups.OnSetPipeline(newPipeline);
|
bindGroups.OnSetPipeline(newPipeline);
|
||||||
|
|
||||||
[encoder setDepthStencilState:newPipeline->GetMTLDepthStencilState()];
|
[encoder setDepthStencilState:newPipeline->GetMTLDepthStencilState()];
|
||||||
|
@ -1045,8 +1045,8 @@ namespace dawn_native { namespace metal {
|
||||||
case Command::SetVertexBuffer: {
|
case Command::SetVertexBuffer: {
|
||||||
SetVertexBufferCmd* cmd = iter->NextCommand<SetVertexBufferCmd>();
|
SetVertexBufferCmd* cmd = iter->NextCommand<SetVertexBufferCmd>();
|
||||||
|
|
||||||
vertexInputBuffers.OnSetVertexBuffer(cmd->slot, ToBackend(cmd->buffer.Get()),
|
vertexBuffers.OnSetVertexBuffer(cmd->slot, ToBackend(cmd->buffer.Get()),
|
||||||
cmd->offset);
|
cmd->offset);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -313,7 +313,7 @@ namespace dawn_native { namespace metal {
|
||||||
|
|
||||||
RenderPipeline::RenderPipeline(Device* device, const RenderPipelineDescriptor* descriptor)
|
RenderPipeline::RenderPipeline(Device* device, const RenderPipelineDescriptor* descriptor)
|
||||||
: RenderPipelineBase(device, descriptor),
|
: RenderPipelineBase(device, descriptor),
|
||||||
mMtlIndexType(MTLIndexFormat(GetVertexInputDescriptor()->indexFormat)),
|
mMtlIndexType(MTLIndexFormat(GetVertexStateDescriptor()->indexFormat)),
|
||||||
mMtlPrimitiveTopology(MTLPrimitiveTopology(GetPrimitiveTopology())),
|
mMtlPrimitiveTopology(MTLPrimitiveTopology(GetPrimitiveTopology())),
|
||||||
mMtlFrontFace(MTLFrontFace(GetFrontFace())),
|
mMtlFrontFace(MTLFrontFace(GetFrontFace())),
|
||||||
mMtlCullMode(ToMTLCullMode(GetCullMode())) {
|
mMtlCullMode(ToMTLCullMode(GetCullMode())) {
|
||||||
|
@ -432,49 +432,49 @@ namespace dawn_native { namespace metal {
|
||||||
uint32_t mtlVertexBufferIndex =
|
uint32_t mtlVertexBufferIndex =
|
||||||
ToBackend(GetLayout())->GetBufferBindingCount(SingleShaderStage::Vertex);
|
ToBackend(GetLayout())->GetBufferBindingCount(SingleShaderStage::Vertex);
|
||||||
|
|
||||||
for (uint32_t dawnVertexBufferIndex : IterateBitSet(GetInputsSetMask())) {
|
for (uint32_t dawnVertexBufferSlot : IterateBitSet(GetVertexBufferSlotsUsed())) {
|
||||||
const VertexBufferInfo& info = GetInput(dawnVertexBufferIndex);
|
const VertexBufferInfo& info = GetVertexBuffer(dawnVertexBufferSlot);
|
||||||
|
|
||||||
MTLVertexBufferLayoutDescriptor* layoutDesc = [MTLVertexBufferLayoutDescriptor new];
|
MTLVertexBufferLayoutDescriptor* layoutDesc = [MTLVertexBufferLayoutDescriptor new];
|
||||||
if (info.stride == 0) {
|
if (info.arrayStride == 0) {
|
||||||
// For MTLVertexStepFunctionConstant, the stepRate must be 0,
|
// For MTLVertexStepFunctionConstant, the stepRate must be 0,
|
||||||
// but the stride must NOT be 0, so we made up it with
|
// but the arrayStride must NOT be 0, so we made up it with
|
||||||
// max(attrib.offset + sizeof(attrib) for each attrib)
|
// max(attrib.offset + sizeof(attrib) for each attrib)
|
||||||
size_t max_stride = 0;
|
size_t maxArrayStride = 0;
|
||||||
for (uint32_t attribIndex : IterateBitSet(GetAttributesSetMask())) {
|
for (uint32_t attribIndex : IterateBitSet(GetAttributeLocationsUsed())) {
|
||||||
const VertexAttributeInfo& 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 != dawnVertexBufferIndex) {
|
if (attrib.vertexBufferSlot != dawnVertexBufferSlot) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
max_stride = std::max(max_stride,
|
maxArrayStride = std::max(
|
||||||
VertexFormatSize(attrib.format) + size_t(attrib.offset));
|
maxArrayStride, VertexFormatSize(attrib.format) + size_t(attrib.offset));
|
||||||
}
|
}
|
||||||
layoutDesc.stepFunction = MTLVertexStepFunctionConstant;
|
layoutDesc.stepFunction = MTLVertexStepFunctionConstant;
|
||||||
layoutDesc.stepRate = 0;
|
layoutDesc.stepRate = 0;
|
||||||
// Metal requires the stride must be a multiple of 4 bytes, align it with next
|
// Metal requires the stride must be a multiple of 4 bytes, align it with next
|
||||||
// multiple of 4 if it's not.
|
// multiple of 4 if it's not.
|
||||||
layoutDesc.stride = Align(max_stride, 4);
|
layoutDesc.stride = Align(maxArrayStride, 4);
|
||||||
} else {
|
} else {
|
||||||
layoutDesc.stepFunction = InputStepModeFunction(info.stepMode);
|
layoutDesc.stepFunction = InputStepModeFunction(info.stepMode);
|
||||||
layoutDesc.stepRate = 1;
|
layoutDesc.stepRate = 1;
|
||||||
layoutDesc.stride = info.stride;
|
layoutDesc.stride = info.arrayStride;
|
||||||
}
|
}
|
||||||
|
|
||||||
mtlVertexDescriptor.layouts[mtlVertexBufferIndex] = layoutDesc;
|
mtlVertexDescriptor.layouts[mtlVertexBufferIndex] = layoutDesc;
|
||||||
[layoutDesc release];
|
[layoutDesc release];
|
||||||
|
|
||||||
mMtlVertexBufferIndices[dawnVertexBufferIndex] = mtlVertexBufferIndex;
|
mMtlVertexBufferIndices[dawnVertexBufferSlot] = mtlVertexBufferIndex;
|
||||||
mtlVertexBufferIndex++;
|
mtlVertexBufferIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t i : IterateBitSet(GetAttributesSetMask())) {
|
for (uint32_t i : IterateBitSet(GetAttributeLocationsUsed())) {
|
||||||
const VertexAttributeInfo& 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);
|
||||||
attribDesc.offset = info.offset;
|
attribDesc.offset = info.offset;
|
||||||
attribDesc.bufferIndex = mMtlVertexBufferIndices[info.inputSlot];
|
attribDesc.bufferIndex = mMtlVertexBufferIndices[info.vertexBufferSlot];
|
||||||
mtlVertexDescriptor.attributes[i] = attribDesc;
|
mtlVertexDescriptor.attributes[i] = attribDesc;
|
||||||
[attribDesc release];
|
[attribDesc release];
|
||||||
}
|
}
|
||||||
|
|
|
@ -133,9 +133,9 @@ namespace dawn_native { namespace opengl {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vertex buffers and index buffers are implemented as part of an OpenGL VAO that
|
// Vertex buffers and index buffers are implemented as part of an OpenGL VAO that
|
||||||
// corresponds to an VertexInput. On the contrary in Dawn they are part of the global state.
|
// corresponds to a VertexState. 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.
|
// This means that we have to re-apply these buffers on a VertexState change.
|
||||||
class InputBufferTracker {
|
class VertexStateBufferBindingTracker {
|
||||||
public:
|
public:
|
||||||
void OnSetIndexBuffer(BufferBase* buffer) {
|
void OnSetIndexBuffer(BufferBase* buffer) {
|
||||||
mIndexBufferDirty = true;
|
mIndexBufferDirty = true;
|
||||||
|
@ -157,7 +157,7 @@ namespace dawn_native { namespace opengl {
|
||||||
}
|
}
|
||||||
|
|
||||||
mIndexBufferDirty = true;
|
mIndexBufferDirty = true;
|
||||||
mDirtyVertexBuffers |= pipeline->GetInputsSetMask();
|
mDirtyVertexBuffers |= pipeline->GetVertexBufferSlotsUsed();
|
||||||
|
|
||||||
mLastPipeline = pipeline;
|
mLastPipeline = pipeline;
|
||||||
}
|
}
|
||||||
|
@ -168,30 +168,32 @@ namespace dawn_native { namespace opengl {
|
||||||
mIndexBufferDirty = false;
|
mIndexBufferDirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint32_t slot :
|
for (uint32_t slot : IterateBitSet(mDirtyVertexBuffers &
|
||||||
IterateBitSet(mDirtyVertexBuffers & mLastPipeline->GetInputsSetMask())) {
|
mLastPipeline->GetVertexBufferSlotsUsed())) {
|
||||||
for (uint32_t location :
|
for (uint32_t location :
|
||||||
IterateBitSet(mLastPipeline->GetAttributesUsingInput(slot))) {
|
IterateBitSet(mLastPipeline->GetAttributesUsingVertexBuffer(slot))) {
|
||||||
auto attribute = mLastPipeline->GetAttribute(location);
|
const VertexAttributeInfo& attribute =
|
||||||
|
mLastPipeline->GetAttribute(location);
|
||||||
|
|
||||||
GLuint buffer = mVertexBuffers[slot]->GetHandle();
|
GLuint buffer = mVertexBuffers[slot]->GetHandle();
|
||||||
uint64_t offset = mVertexBufferOffsets[slot];
|
uint64_t offset = mVertexBufferOffsets[slot];
|
||||||
|
|
||||||
auto input = mLastPipeline->GetInput(slot);
|
const VertexBufferInfo& vertexBuffer = mLastPipeline->GetVertexBuffer(slot);
|
||||||
auto components = VertexFormatNumComponents(attribute.format);
|
uint32_t components = VertexFormatNumComponents(attribute.format);
|
||||||
auto formatType = VertexFormatType(attribute.format);
|
GLenum formatType = VertexFormatType(attribute.format);
|
||||||
|
|
||||||
GLboolean normalized = VertexFormatIsNormalized(attribute.format);
|
GLboolean normalized = VertexFormatIsNormalized(attribute.format);
|
||||||
gl.BindBuffer(GL_ARRAY_BUFFER, buffer);
|
gl.BindBuffer(GL_ARRAY_BUFFER, buffer);
|
||||||
if (VertexFormatIsInt(attribute.format)) {
|
if (VertexFormatIsInt(attribute.format)) {
|
||||||
gl.VertexAttribIPointer(location, components, formatType, input.stride,
|
gl.VertexAttribIPointer(
|
||||||
reinterpret_cast<void*>(static_cast<intptr_t>(
|
location, components, formatType, vertexBuffer.arrayStride,
|
||||||
offset + attribute.offset)));
|
|
||||||
} else {
|
|
||||||
gl.VertexAttribPointer(
|
|
||||||
location, components, formatType, normalized, input.stride,
|
|
||||||
reinterpret_cast<void*>(
|
reinterpret_cast<void*>(
|
||||||
static_cast<intptr_t>(offset + attribute.offset)));
|
static_cast<intptr_t>(offset + attribute.offset)));
|
||||||
|
} else {
|
||||||
|
gl.VertexAttribPointer(location, components, formatType, normalized,
|
||||||
|
vertexBuffer.arrayStride,
|
||||||
|
reinterpret_cast<void*>(static_cast<intptr_t>(
|
||||||
|
offset + attribute.offset)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -855,14 +857,14 @@ namespace dawn_native { namespace opengl {
|
||||||
RenderPipeline* lastPipeline = nullptr;
|
RenderPipeline* lastPipeline = nullptr;
|
||||||
uint64_t indexBufferBaseOffset = 0;
|
uint64_t indexBufferBaseOffset = 0;
|
||||||
|
|
||||||
InputBufferTracker inputBuffers;
|
VertexStateBufferBindingTracker vertexStateBufferBindingTracker;
|
||||||
BindGroupTracker bindGroupTracker = {};
|
BindGroupTracker bindGroupTracker = {};
|
||||||
|
|
||||||
auto DoRenderBundleCommand = [&](CommandIterator* iter, Command type) {
|
auto DoRenderBundleCommand = [&](CommandIterator* iter, Command type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case Command::Draw: {
|
case Command::Draw: {
|
||||||
DrawCmd* draw = iter->NextCommand<DrawCmd>();
|
DrawCmd* draw = iter->NextCommand<DrawCmd>();
|
||||||
inputBuffers.Apply(gl);
|
vertexStateBufferBindingTracker.Apply(gl);
|
||||||
bindGroupTracker.Apply(gl);
|
bindGroupTracker.Apply(gl);
|
||||||
|
|
||||||
if (draw->firstInstance > 0) {
|
if (draw->firstInstance > 0) {
|
||||||
|
@ -879,11 +881,11 @@ namespace dawn_native { namespace opengl {
|
||||||
|
|
||||||
case Command::DrawIndexed: {
|
case Command::DrawIndexed: {
|
||||||
DrawIndexedCmd* draw = iter->NextCommand<DrawIndexedCmd>();
|
DrawIndexedCmd* draw = iter->NextCommand<DrawIndexedCmd>();
|
||||||
inputBuffers.Apply(gl);
|
vertexStateBufferBindingTracker.Apply(gl);
|
||||||
bindGroupTracker.Apply(gl);
|
bindGroupTracker.Apply(gl);
|
||||||
|
|
||||||
wgpu::IndexFormat indexFormat =
|
wgpu::IndexFormat indexFormat =
|
||||||
lastPipeline->GetVertexInputDescriptor()->indexFormat;
|
lastPipeline->GetVertexStateDescriptor()->indexFormat;
|
||||||
size_t formatSize = IndexFormatSize(indexFormat);
|
size_t formatSize = IndexFormatSize(indexFormat);
|
||||||
GLenum formatType = IndexFormatType(indexFormat);
|
GLenum formatType = IndexFormatType(indexFormat);
|
||||||
|
|
||||||
|
@ -905,7 +907,7 @@ namespace dawn_native { namespace opengl {
|
||||||
|
|
||||||
case Command::DrawIndirect: {
|
case Command::DrawIndirect: {
|
||||||
DrawIndirectCmd* draw = iter->NextCommand<DrawIndirectCmd>();
|
DrawIndirectCmd* draw = iter->NextCommand<DrawIndirectCmd>();
|
||||||
inputBuffers.Apply(gl);
|
vertexStateBufferBindingTracker.Apply(gl);
|
||||||
bindGroupTracker.Apply(gl);
|
bindGroupTracker.Apply(gl);
|
||||||
|
|
||||||
uint64_t indirectBufferOffset = draw->indirectOffset;
|
uint64_t indirectBufferOffset = draw->indirectOffset;
|
||||||
|
@ -919,11 +921,11 @@ namespace dawn_native { namespace opengl {
|
||||||
|
|
||||||
case Command::DrawIndexedIndirect: {
|
case Command::DrawIndexedIndirect: {
|
||||||
DrawIndexedIndirectCmd* draw = iter->NextCommand<DrawIndexedIndirectCmd>();
|
DrawIndexedIndirectCmd* draw = iter->NextCommand<DrawIndexedIndirectCmd>();
|
||||||
inputBuffers.Apply(gl);
|
vertexStateBufferBindingTracker.Apply(gl);
|
||||||
bindGroupTracker.Apply(gl);
|
bindGroupTracker.Apply(gl);
|
||||||
|
|
||||||
wgpu::IndexFormat indexFormat =
|
wgpu::IndexFormat indexFormat =
|
||||||
lastPipeline->GetVertexInputDescriptor()->indexFormat;
|
lastPipeline->GetVertexStateDescriptor()->indexFormat;
|
||||||
GLenum formatType = IndexFormatType(indexFormat);
|
GLenum formatType = IndexFormatType(indexFormat);
|
||||||
|
|
||||||
uint64_t indirectBufferOffset = draw->indirectOffset;
|
uint64_t indirectBufferOffset = draw->indirectOffset;
|
||||||
|
@ -948,7 +950,7 @@ namespace dawn_native { namespace opengl {
|
||||||
lastPipeline = ToBackend(cmd->pipeline).Get();
|
lastPipeline = ToBackend(cmd->pipeline).Get();
|
||||||
lastPipeline->ApplyNow(persistentPipelineState);
|
lastPipeline->ApplyNow(persistentPipelineState);
|
||||||
|
|
||||||
inputBuffers.OnSetPipeline(lastPipeline);
|
vertexStateBufferBindingTracker.OnSetPipeline(lastPipeline);
|
||||||
bindGroupTracker.OnSetPipeline(lastPipeline);
|
bindGroupTracker.OnSetPipeline(lastPipeline);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
@ -965,12 +967,13 @@ namespace dawn_native { namespace opengl {
|
||||||
case Command::SetIndexBuffer: {
|
case Command::SetIndexBuffer: {
|
||||||
SetIndexBufferCmd* cmd = iter->NextCommand<SetIndexBufferCmd>();
|
SetIndexBufferCmd* cmd = iter->NextCommand<SetIndexBufferCmd>();
|
||||||
indexBufferBaseOffset = cmd->offset;
|
indexBufferBaseOffset = cmd->offset;
|
||||||
inputBuffers.OnSetIndexBuffer(cmd->buffer.Get());
|
vertexStateBufferBindingTracker.OnSetIndexBuffer(cmd->buffer.Get());
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Command::SetVertexBuffer: {
|
case Command::SetVertexBuffer: {
|
||||||
SetVertexBufferCmd* cmd = iter->NextCommand<SetVertexBufferCmd>();
|
SetVertexBufferCmd* cmd = iter->NextCommand<SetVertexBufferCmd>();
|
||||||
inputBuffers.OnSetVertexBuffer(cmd->slot, cmd->buffer.Get(), cmd->offset);
|
vertexStateBufferBindingTracker.OnSetVertexBuffer(cmd->slot, cmd->buffer.Get(),
|
||||||
|
cmd->offset);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -202,7 +202,7 @@ namespace dawn_native { namespace opengl {
|
||||||
modules[SingleShaderStage::Fragment] = ToBackend(descriptor->fragmentStage->module);
|
modules[SingleShaderStage::Fragment] = ToBackend(descriptor->fragmentStage->module);
|
||||||
|
|
||||||
PipelineGL::Initialize(device->gl, ToBackend(GetLayout()), modules);
|
PipelineGL::Initialize(device->gl, ToBackend(GetLayout()), modules);
|
||||||
CreateVAOForVertexInput(descriptor->vertexInput);
|
CreateVAOForVertexState(descriptor->vertexState);
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderPipeline::~RenderPipeline() {
|
RenderPipeline::~RenderPipeline() {
|
||||||
|
@ -215,25 +215,25 @@ namespace dawn_native { namespace opengl {
|
||||||
return mGlPrimitiveTopology;
|
return mGlPrimitiveTopology;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderPipeline::CreateVAOForVertexInput(const VertexInputDescriptor* vertexInput) {
|
void RenderPipeline::CreateVAOForVertexState(const VertexStateDescriptor* vertexState) {
|
||||||
const OpenGLFunctions& gl = ToBackend(GetDevice())->gl;
|
const OpenGLFunctions& gl = ToBackend(GetDevice())->gl;
|
||||||
|
|
||||||
gl.GenVertexArrays(1, &mVertexArrayObject);
|
gl.GenVertexArrays(1, &mVertexArrayObject);
|
||||||
gl.BindVertexArray(mVertexArrayObject);
|
gl.BindVertexArray(mVertexArrayObject);
|
||||||
|
|
||||||
for (uint32_t location : IterateBitSet(GetAttributesSetMask())) {
|
for (uint32_t location : IterateBitSet(GetAttributeLocationsUsed())) {
|
||||||
const auto& attribute = GetAttribute(location);
|
const auto& attribute = GetAttribute(location);
|
||||||
gl.EnableVertexAttribArray(location);
|
gl.EnableVertexAttribArray(location);
|
||||||
|
|
||||||
attributesUsingInput[attribute.inputSlot][location] = true;
|
attributesUsingVertexBuffer[attribute.vertexBufferSlot][location] = true;
|
||||||
auto input = GetInput(attribute.inputSlot);
|
const VertexBufferInfo& vertexBuffer = GetVertexBuffer(attribute.vertexBufferSlot);
|
||||||
|
|
||||||
if (input.stride == 0) {
|
if (vertexBuffer.arrayStride == 0) {
|
||||||
// Emulate a stride of zero (constant vertex attribute) by
|
// Emulate a stride of zero (constant vertex attribute) by
|
||||||
// setting the attribute instance divisor to a huge number.
|
// setting the attribute instance divisor to a huge number.
|
||||||
gl.VertexAttribDivisor(location, 0xffffffff);
|
gl.VertexAttribDivisor(location, 0xffffffff);
|
||||||
} else {
|
} else {
|
||||||
switch (input.stepMode) {
|
switch (vertexBuffer.stepMode) {
|
||||||
case wgpu::InputStepMode::Vertex:
|
case wgpu::InputStepMode::Vertex:
|
||||||
break;
|
break;
|
||||||
case wgpu::InputStepMode::Instance:
|
case wgpu::InputStepMode::Instance:
|
||||||
|
|
|
@ -37,7 +37,7 @@ namespace dawn_native { namespace opengl {
|
||||||
void ApplyNow(PersistentPipelineState& persistentPipelineState);
|
void ApplyNow(PersistentPipelineState& persistentPipelineState);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void CreateVAOForVertexInput(const VertexInputDescriptor* vertexInput);
|
void CreateVAOForVertexState(const VertexStateDescriptor* vertexState);
|
||||||
|
|
||||||
// TODO(yunchao.he@intel.com): vao need to be deduplicated between pipelines.
|
// TODO(yunchao.he@intel.com): vao need to be deduplicated between pipelines.
|
||||||
GLuint mVertexArrayObject;
|
GLuint mVertexArrayObject;
|
||||||
|
|
|
@ -867,7 +867,7 @@ namespace dawn_native { namespace vulkan {
|
||||||
// and rebind if needed on pipeline change
|
// and rebind if needed on pipeline change
|
||||||
ASSERT(lastPipeline != nullptr);
|
ASSERT(lastPipeline != nullptr);
|
||||||
VkIndexType indexType =
|
VkIndexType indexType =
|
||||||
VulkanIndexType(lastPipeline->GetVertexInputDescriptor()->indexFormat);
|
VulkanIndexType(lastPipeline->GetVertexStateDescriptor()->indexFormat);
|
||||||
device->fn.CmdBindIndexBuffer(
|
device->fn.CmdBindIndexBuffer(
|
||||||
commands, indexBuffer, static_cast<VkDeviceSize>(cmd->offset), indexType);
|
commands, indexBuffer, static_cast<VkDeviceSize>(cmd->offset), indexType);
|
||||||
} break;
|
} break;
|
||||||
|
|
|
@ -351,11 +351,9 @@ namespace dawn_native { namespace vulkan {
|
||||||
shaderStages[1].pName = descriptor->fragmentStage->entryPoint;
|
shaderStages[1].pName = descriptor->fragmentStage->entryPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::array<VkVertexInputBindingDescription, kMaxVertexBuffers> mBindings;
|
PipelineVertexInputStateCreateInfoTemporaryAllocations tempAllocations;
|
||||||
std::array<VkVertexInputAttributeDescription, kMaxVertexAttributes> mAttributes;
|
|
||||||
const VertexInputDescriptor* vertexInput = GetVertexInputDescriptor();
|
|
||||||
VkPipelineVertexInputStateCreateInfo vertexInputCreateInfo =
|
VkPipelineVertexInputStateCreateInfo vertexInputCreateInfo =
|
||||||
ComputeVertexInputDesc(vertexInput, &mBindings, &mAttributes);
|
ComputeVertexInputDesc(&tempAllocations);
|
||||||
|
|
||||||
VkPipelineInputAssemblyStateCreateInfo inputAssembly;
|
VkPipelineInputAssemblyStateCreateInfo inputAssembly;
|
||||||
inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
|
inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
|
||||||
|
@ -507,32 +505,31 @@ namespace dawn_native { namespace vulkan {
|
||||||
}
|
}
|
||||||
|
|
||||||
VkPipelineVertexInputStateCreateInfo RenderPipeline::ComputeVertexInputDesc(
|
VkPipelineVertexInputStateCreateInfo RenderPipeline::ComputeVertexInputDesc(
|
||||||
const VertexInputDescriptor* vertexInput,
|
PipelineVertexInputStateCreateInfoTemporaryAllocations* tempAllocations) {
|
||||||
std::array<VkVertexInputBindingDescription, kMaxVertexBuffers>* mBindings,
|
|
||||||
std::array<VkVertexInputAttributeDescription, kMaxVertexAttributes>* mAttributes) {
|
|
||||||
// Fill in the "binding info" that will be chained in the create info
|
// Fill in the "binding info" that will be chained in the create info
|
||||||
uint32_t bindingCount = 0;
|
uint32_t bindingCount = 0;
|
||||||
for (uint32_t i : IterateBitSet(GetInputsSetMask())) {
|
for (uint32_t i : IterateBitSet(GetVertexBufferSlotsUsed())) {
|
||||||
const auto& bindingInfo = GetInput(i);
|
const VertexBufferInfo& bindingInfo = GetVertexBuffer(i);
|
||||||
|
|
||||||
auto& bindingDesc = (*mBindings)[bindingCount];
|
VkVertexInputBindingDescription* bindingDesc = &tempAllocations->bindings[bindingCount];
|
||||||
bindingDesc.binding = i;
|
bindingDesc->binding = i;
|
||||||
bindingDesc.stride = bindingInfo.stride;
|
bindingDesc->stride = bindingInfo.arrayStride;
|
||||||
bindingDesc.inputRate = VulkanInputRate(bindingInfo.stepMode);
|
bindingDesc->inputRate = VulkanInputRate(bindingInfo.stepMode);
|
||||||
|
|
||||||
bindingCount++;
|
bindingCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fill in the "attribute info" that will be chained in the create info
|
// Fill in the "attribute info" that will be chained in the create info
|
||||||
uint32_t attributeCount = 0;
|
uint32_t attributeCount = 0;
|
||||||
for (uint32_t i : IterateBitSet(GetAttributesSetMask())) {
|
for (uint32_t i : IterateBitSet(GetAttributeLocationsUsed())) {
|
||||||
const auto& attributeInfo = GetAttribute(i);
|
const VertexAttributeInfo& attributeInfo = GetAttribute(i);
|
||||||
|
|
||||||
auto& attributeDesc = (*mAttributes)[attributeCount];
|
VkVertexInputAttributeDescription* attributeDesc =
|
||||||
attributeDesc.location = i;
|
&tempAllocations->attributes[attributeCount];
|
||||||
attributeDesc.binding = attributeInfo.inputSlot;
|
attributeDesc->location = i;
|
||||||
attributeDesc.format = VulkanVertexFormat(attributeInfo.format);
|
attributeDesc->binding = attributeInfo.vertexBufferSlot;
|
||||||
attributeDesc.offset = attributeInfo.offset;
|
attributeDesc->format = VulkanVertexFormat(attributeInfo.format);
|
||||||
|
attributeDesc->offset = attributeInfo.offset;
|
||||||
|
|
||||||
attributeCount++;
|
attributeCount++;
|
||||||
}
|
}
|
||||||
|
@ -543,9 +540,9 @@ namespace dawn_native { namespace vulkan {
|
||||||
mCreateInfo.pNext = nullptr;
|
mCreateInfo.pNext = nullptr;
|
||||||
mCreateInfo.flags = 0;
|
mCreateInfo.flags = 0;
|
||||||
mCreateInfo.vertexBindingDescriptionCount = bindingCount;
|
mCreateInfo.vertexBindingDescriptionCount = bindingCount;
|
||||||
mCreateInfo.pVertexBindingDescriptions = &(*mBindings)[0];
|
mCreateInfo.pVertexBindingDescriptions = tempAllocations->bindings.data();
|
||||||
mCreateInfo.vertexAttributeDescriptionCount = attributeCount;
|
mCreateInfo.vertexAttributeDescriptionCount = attributeCount;
|
||||||
mCreateInfo.pVertexAttributeDescriptions = &(*mAttributes)[0];
|
mCreateInfo.pVertexAttributeDescriptions = tempAllocations->attributes.data();
|
||||||
return mCreateInfo;
|
return mCreateInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,10 +36,12 @@ namespace dawn_native { namespace vulkan {
|
||||||
using RenderPipelineBase::RenderPipelineBase;
|
using RenderPipelineBase::RenderPipelineBase;
|
||||||
MaybeError Initialize(const RenderPipelineDescriptor* descriptor);
|
MaybeError Initialize(const RenderPipelineDescriptor* descriptor);
|
||||||
|
|
||||||
|
struct PipelineVertexInputStateCreateInfoTemporaryAllocations {
|
||||||
|
std::array<VkVertexInputBindingDescription, kMaxVertexBuffers> bindings;
|
||||||
|
std::array<VkVertexInputAttributeDescription, kMaxVertexAttributes> attributes;
|
||||||
|
};
|
||||||
VkPipelineVertexInputStateCreateInfo ComputeVertexInputDesc(
|
VkPipelineVertexInputStateCreateInfo ComputeVertexInputDesc(
|
||||||
const VertexInputDescriptor* vertexInput,
|
PipelineVertexInputStateCreateInfoTemporaryAllocations* temporaryAllocations);
|
||||||
std::array<VkVertexInputBindingDescription, kMaxVertexBuffers>* mBindings,
|
|
||||||
std::array<VkVertexInputAttributeDescription, kMaxVertexAttributes>* mAttributes);
|
|
||||||
|
|
||||||
VkPipeline mHandle = VK_NULL_HANDLE;
|
VkPipeline mHandle = VK_NULL_HANDLE;
|
||||||
};
|
};
|
||||||
|
|
|
@ -46,10 +46,10 @@ class DestroyTest : public DawnTest {
|
||||||
descriptor.vertexStage.module = vsModule;
|
descriptor.vertexStage.module = vsModule;
|
||||||
descriptor.cFragmentStage.module = fsModule;
|
descriptor.cFragmentStage.module = fsModule;
|
||||||
descriptor.primitiveTopology = wgpu::PrimitiveTopology::TriangleStrip;
|
descriptor.primitiveTopology = wgpu::PrimitiveTopology::TriangleStrip;
|
||||||
descriptor.cVertexInput.bufferCount = 1;
|
descriptor.cVertexState.vertexBufferCount = 1;
|
||||||
descriptor.cVertexInput.cBuffers[0].stride = 4 * sizeof(float);
|
descriptor.cVertexState.cVertexBuffers[0].arrayStride = 4 * sizeof(float);
|
||||||
descriptor.cVertexInput.cBuffers[0].attributeCount = 1;
|
descriptor.cVertexState.cVertexBuffers[0].attributeCount = 1;
|
||||||
descriptor.cVertexInput.cAttributes[0].format = wgpu::VertexFormat::Float4;
|
descriptor.cVertexState.cAttributes[0].format = wgpu::VertexFormat::Float4;
|
||||||
descriptor.cColorStates[0].format = renderPass.colorFormat;
|
descriptor.cColorStates[0].format = renderPass.colorFormat;
|
||||||
|
|
||||||
pipeline = device.CreateRenderPipeline(&descriptor);
|
pipeline = device.CreateRenderPipeline(&descriptor);
|
||||||
|
|
|
@ -46,10 +46,10 @@ class DrawIndexedIndirectTest : public DawnTest {
|
||||||
descriptor.vertexStage.module = vsModule;
|
descriptor.vertexStage.module = vsModule;
|
||||||
descriptor.cFragmentStage.module = fsModule;
|
descriptor.cFragmentStage.module = fsModule;
|
||||||
descriptor.primitiveTopology = wgpu::PrimitiveTopology::TriangleStrip;
|
descriptor.primitiveTopology = wgpu::PrimitiveTopology::TriangleStrip;
|
||||||
descriptor.cVertexInput.bufferCount = 1;
|
descriptor.cVertexState.vertexBufferCount = 1;
|
||||||
descriptor.cVertexInput.cBuffers[0].stride = 4 * sizeof(float);
|
descriptor.cVertexState.cVertexBuffers[0].arrayStride = 4 * sizeof(float);
|
||||||
descriptor.cVertexInput.cBuffers[0].attributeCount = 1;
|
descriptor.cVertexState.cVertexBuffers[0].attributeCount = 1;
|
||||||
descriptor.cVertexInput.cAttributes[0].format = wgpu::VertexFormat::Float4;
|
descriptor.cVertexState.cAttributes[0].format = wgpu::VertexFormat::Float4;
|
||||||
descriptor.cColorStates[0].format = renderPass.colorFormat;
|
descriptor.cColorStates[0].format = renderPass.colorFormat;
|
||||||
|
|
||||||
pipeline = device.CreateRenderPipeline(&descriptor);
|
pipeline = device.CreateRenderPipeline(&descriptor);
|
||||||
|
|
|
@ -46,10 +46,10 @@ class DrawIndexedTest : public DawnTest {
|
||||||
descriptor.vertexStage.module = vsModule;
|
descriptor.vertexStage.module = vsModule;
|
||||||
descriptor.cFragmentStage.module = fsModule;
|
descriptor.cFragmentStage.module = fsModule;
|
||||||
descriptor.primitiveTopology = wgpu::PrimitiveTopology::TriangleStrip;
|
descriptor.primitiveTopology = wgpu::PrimitiveTopology::TriangleStrip;
|
||||||
descriptor.cVertexInput.bufferCount = 1;
|
descriptor.cVertexState.vertexBufferCount = 1;
|
||||||
descriptor.cVertexInput.cBuffers[0].stride = 4 * sizeof(float);
|
descriptor.cVertexState.cVertexBuffers[0].arrayStride = 4 * sizeof(float);
|
||||||
descriptor.cVertexInput.cBuffers[0].attributeCount = 1;
|
descriptor.cVertexState.cVertexBuffers[0].attributeCount = 1;
|
||||||
descriptor.cVertexInput.cAttributes[0].format = wgpu::VertexFormat::Float4;
|
descriptor.cVertexState.cAttributes[0].format = wgpu::VertexFormat::Float4;
|
||||||
descriptor.cColorStates[0].format = renderPass.colorFormat;
|
descriptor.cColorStates[0].format = renderPass.colorFormat;
|
||||||
|
|
||||||
pipeline = device.CreateRenderPipeline(&descriptor);
|
pipeline = device.CreateRenderPipeline(&descriptor);
|
||||||
|
|
|
@ -46,10 +46,10 @@ class DrawIndirectTest : public DawnTest {
|
||||||
descriptor.vertexStage.module = vsModule;
|
descriptor.vertexStage.module = vsModule;
|
||||||
descriptor.cFragmentStage.module = fsModule;
|
descriptor.cFragmentStage.module = fsModule;
|
||||||
descriptor.primitiveTopology = wgpu::PrimitiveTopology::TriangleStrip;
|
descriptor.primitiveTopology = wgpu::PrimitiveTopology::TriangleStrip;
|
||||||
descriptor.cVertexInput.bufferCount = 1;
|
descriptor.cVertexState.vertexBufferCount = 1;
|
||||||
descriptor.cVertexInput.cBuffers[0].stride = 4 * sizeof(float);
|
descriptor.cVertexState.cVertexBuffers[0].arrayStride = 4 * sizeof(float);
|
||||||
descriptor.cVertexInput.cBuffers[0].attributeCount = 1;
|
descriptor.cVertexState.cVertexBuffers[0].attributeCount = 1;
|
||||||
descriptor.cVertexInput.cAttributes[0].format = wgpu::VertexFormat::Float4;
|
descriptor.cVertexState.cAttributes[0].format = wgpu::VertexFormat::Float4;
|
||||||
descriptor.cColorStates[0].format = renderPass.colorFormat;
|
descriptor.cColorStates[0].format = renderPass.colorFormat;
|
||||||
|
|
||||||
pipeline = device.CreateRenderPipeline(&descriptor);
|
pipeline = device.CreateRenderPipeline(&descriptor);
|
||||||
|
|
|
@ -46,10 +46,10 @@ class DrawTest : public DawnTest {
|
||||||
descriptor.vertexStage.module = vsModule;
|
descriptor.vertexStage.module = vsModule;
|
||||||
descriptor.cFragmentStage.module = fsModule;
|
descriptor.cFragmentStage.module = fsModule;
|
||||||
descriptor.primitiveTopology = wgpu::PrimitiveTopology::TriangleStrip;
|
descriptor.primitiveTopology = wgpu::PrimitiveTopology::TriangleStrip;
|
||||||
descriptor.cVertexInput.bufferCount = 1;
|
descriptor.cVertexState.vertexBufferCount = 1;
|
||||||
descriptor.cVertexInput.cBuffers[0].stride = 4 * sizeof(float);
|
descriptor.cVertexState.cVertexBuffers[0].arrayStride = 4 * sizeof(float);
|
||||||
descriptor.cVertexInput.cBuffers[0].attributeCount = 1;
|
descriptor.cVertexState.cVertexBuffers[0].attributeCount = 1;
|
||||||
descriptor.cVertexInput.cAttributes[0].format = wgpu::VertexFormat::Float4;
|
descriptor.cVertexState.cAttributes[0].format = wgpu::VertexFormat::Float4;
|
||||||
descriptor.cColorStates[0].format = renderPass.colorFormat;
|
descriptor.cColorStates[0].format = renderPass.colorFormat;
|
||||||
|
|
||||||
pipeline = device.CreateRenderPipeline(&descriptor);
|
pipeline = device.CreateRenderPipeline(&descriptor);
|
||||||
|
|
|
@ -51,11 +51,11 @@ class IndexFormatTest : public DawnTest {
|
||||||
descriptor.vertexStage.module = vsModule;
|
descriptor.vertexStage.module = vsModule;
|
||||||
descriptor.cFragmentStage.module = fsModule;
|
descriptor.cFragmentStage.module = fsModule;
|
||||||
descriptor.primitiveTopology = wgpu::PrimitiveTopology::TriangleStrip;
|
descriptor.primitiveTopology = wgpu::PrimitiveTopology::TriangleStrip;
|
||||||
descriptor.cVertexInput.indexFormat = format;
|
descriptor.cVertexState.indexFormat = format;
|
||||||
descriptor.cVertexInput.bufferCount = 1;
|
descriptor.cVertexState.vertexBufferCount = 1;
|
||||||
descriptor.cVertexInput.cBuffers[0].stride = 4 * sizeof(float);
|
descriptor.cVertexState.cVertexBuffers[0].arrayStride = 4 * sizeof(float);
|
||||||
descriptor.cVertexInput.cBuffers[0].attributeCount = 1;
|
descriptor.cVertexState.cVertexBuffers[0].attributeCount = 1;
|
||||||
descriptor.cVertexInput.cAttributes[0].format = wgpu::VertexFormat::Float4;
|
descriptor.cVertexState.cAttributes[0].format = wgpu::VertexFormat::Float4;
|
||||||
descriptor.cColorStates[0].format = renderPass.colorFormat;
|
descriptor.cColorStates[0].format = renderPass.colorFormat;
|
||||||
|
|
||||||
return device.CreateRenderPipeline(&descriptor);
|
return device.CreateRenderPipeline(&descriptor);
|
||||||
|
|
|
@ -187,10 +187,10 @@ class PrimitiveTopologyTest : public DawnTest {
|
||||||
descriptor.vertexStage.module = vsModule;
|
descriptor.vertexStage.module = vsModule;
|
||||||
descriptor.cFragmentStage.module = fsModule;
|
descriptor.cFragmentStage.module = fsModule;
|
||||||
descriptor.primitiveTopology = primitiveTopology;
|
descriptor.primitiveTopology = primitiveTopology;
|
||||||
descriptor.cVertexInput.bufferCount = 1;
|
descriptor.cVertexState.vertexBufferCount = 1;
|
||||||
descriptor.cVertexInput.cBuffers[0].stride = 4 * sizeof(float);
|
descriptor.cVertexState.cVertexBuffers[0].arrayStride = 4 * sizeof(float);
|
||||||
descriptor.cVertexInput.cBuffers[0].attributeCount = 1;
|
descriptor.cVertexState.cVertexBuffers[0].attributeCount = 1;
|
||||||
descriptor.cVertexInput.cAttributes[0].format = wgpu::VertexFormat::Float4;
|
descriptor.cVertexState.cAttributes[0].format = wgpu::VertexFormat::Float4;
|
||||||
descriptor.cColorStates[0].format = renderPass.colorFormat;
|
descriptor.cColorStates[0].format = renderPass.colorFormat;
|
||||||
|
|
||||||
wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor);
|
wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor);
|
||||||
|
|
|
@ -77,10 +77,10 @@ class RenderBundleTest : public DawnTest {
|
||||||
descriptor.vertexStage.module = vsModule;
|
descriptor.vertexStage.module = vsModule;
|
||||||
descriptor.cFragmentStage.module = fsModule;
|
descriptor.cFragmentStage.module = fsModule;
|
||||||
descriptor.primitiveTopology = wgpu::PrimitiveTopology::TriangleStrip;
|
descriptor.primitiveTopology = wgpu::PrimitiveTopology::TriangleStrip;
|
||||||
descriptor.cVertexInput.bufferCount = 1;
|
descriptor.cVertexState.vertexBufferCount = 1;
|
||||||
descriptor.cVertexInput.cBuffers[0].stride = 4 * sizeof(float);
|
descriptor.cVertexState.cVertexBuffers[0].arrayStride = 4 * sizeof(float);
|
||||||
descriptor.cVertexInput.cBuffers[0].attributeCount = 1;
|
descriptor.cVertexState.cVertexBuffers[0].attributeCount = 1;
|
||||||
descriptor.cVertexInput.cAttributes[0].format = wgpu::VertexFormat::Float4;
|
descriptor.cVertexState.cAttributes[0].format = wgpu::VertexFormat::Float4;
|
||||||
descriptor.cColorStates[0].format = renderPass.colorFormat;
|
descriptor.cColorStates[0].format = renderPass.colorFormat;
|
||||||
|
|
||||||
pipeline = device.CreateRenderPipeline(&descriptor);
|
pipeline = device.CreateRenderPipeline(&descriptor);
|
||||||
|
|
|
@ -362,10 +362,10 @@ class VertexFormatTest : public DawnTest {
|
||||||
utils::ComboRenderPipelineDescriptor descriptor(device);
|
utils::ComboRenderPipelineDescriptor descriptor(device);
|
||||||
descriptor.vertexStage.module = vsModule;
|
descriptor.vertexStage.module = vsModule;
|
||||||
descriptor.cFragmentStage.module = fsModule;
|
descriptor.cFragmentStage.module = fsModule;
|
||||||
descriptor.cVertexInput.bufferCount = 1;
|
descriptor.cVertexState.vertexBufferCount = 1;
|
||||||
descriptor.cVertexInput.cBuffers[0].stride = strideBytes;
|
descriptor.cVertexState.cVertexBuffers[0].arrayStride = strideBytes;
|
||||||
descriptor.cVertexInput.cBuffers[0].attributeCount = 1;
|
descriptor.cVertexState.cVertexBuffers[0].attributeCount = 1;
|
||||||
descriptor.cVertexInput.cAttributes[0].format = format;
|
descriptor.cVertexState.cAttributes[0].format = format;
|
||||||
descriptor.cColorStates[0].format = renderPass.colorFormat;
|
descriptor.cColorStates[0].format = renderPass.colorFormat;
|
||||||
|
|
||||||
return device.CreateRenderPipeline(&descriptor);
|
return device.CreateRenderPipeline(&descriptor);
|
||||||
|
|
|
@ -21,10 +21,11 @@
|
||||||
using wgpu::InputStepMode;
|
using wgpu::InputStepMode;
|
||||||
using wgpu::VertexFormat;
|
using wgpu::VertexFormat;
|
||||||
|
|
||||||
// Input state tests all work the same way: the test will render triangles in a grid up to 4x4. Each triangle
|
// Input state tests all work the same way: the test will render triangles in a grid up to 4x4. Each
|
||||||
// is position in the grid such that X will correspond to the "triangle number" and the Y to the instance number.
|
// triangle is position in the grid such that X will correspond to the "triangle number" and the Y
|
||||||
// Each test will set up an input state and buffers, and the vertex shader will check that the vertex attributes
|
// to the instance number. Each test will set up an input state and buffers, and the vertex shader
|
||||||
// corresponds to predetermined values. On success it outputs green, otherwise red.
|
// 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
|
// The predetermined values are "K * gl_VertexID + componentIndex" for vertex-indexed buffers, and
|
||||||
// "K * gl_InstanceID + componentIndex" for instance-indexed buffers.
|
// "K * gl_InstanceID + componentIndex" for instance-indexed buffers.
|
||||||
|
@ -33,7 +34,7 @@ constexpr static unsigned int kRTSize = 400;
|
||||||
constexpr static unsigned int kRTCellOffset = 50;
|
constexpr static unsigned int kRTCellOffset = 50;
|
||||||
constexpr static unsigned int kRTCellSize = 100;
|
constexpr static unsigned int kRTCellSize = 100;
|
||||||
|
|
||||||
class VertexInputTest : public DawnTest {
|
class VertexStateTest : public DawnTest {
|
||||||
protected:
|
protected:
|
||||||
void TestSetUp() override {
|
void TestSetUp() override {
|
||||||
DawnTest::TestSetUp();
|
DawnTest::TestSetUp();
|
||||||
|
@ -64,7 +65,7 @@ class VertexInputTest : public DawnTest {
|
||||||
VertexFormat format;
|
VertexFormat format;
|
||||||
InputStepMode step;
|
InputStepMode step;
|
||||||
};
|
};
|
||||||
wgpu::RenderPipeline MakeTestPipeline(const wgpu::VertexInputDescriptor& vertexInput,
|
wgpu::RenderPipeline MakeTestPipeline(const wgpu::VertexStateDescriptor& vertexState,
|
||||||
int multiplier,
|
int multiplier,
|
||||||
const std::vector<ShaderTestSpec>& testSpec) {
|
const std::vector<ShaderTestSpec>& testSpec) {
|
||||||
std::ostringstream vs;
|
std::ostringstream vs;
|
||||||
|
@ -131,7 +132,7 @@ class VertexInputTest : public DawnTest {
|
||||||
utils::ComboRenderPipelineDescriptor descriptor(device);
|
utils::ComboRenderPipelineDescriptor descriptor(device);
|
||||||
descriptor.vertexStage.module = vsModule;
|
descriptor.vertexStage.module = vsModule;
|
||||||
descriptor.cFragmentStage.module = fsModule;
|
descriptor.cFragmentStage.module = fsModule;
|
||||||
descriptor.vertexInput = &vertexInput;
|
descriptor.vertexState = &vertexState;
|
||||||
descriptor.cColorStates[0].format = renderPass.colorFormat;
|
descriptor.cColorStates[0].format = renderPass.colorFormat;
|
||||||
|
|
||||||
return device.CreateRenderPipeline(&descriptor);
|
return device.CreateRenderPipeline(&descriptor);
|
||||||
|
@ -143,37 +144,37 @@ class VertexInputTest : public DawnTest {
|
||||||
VertexFormat format;
|
VertexFormat format;
|
||||||
};
|
};
|
||||||
struct VertexBufferSpec {
|
struct VertexBufferSpec {
|
||||||
uint64_t stride;
|
uint64_t arrayStride;
|
||||||
InputStepMode step;
|
InputStepMode step;
|
||||||
std::vector<VertexAttributeSpec> attributes;
|
std::vector<VertexAttributeSpec> attributes;
|
||||||
};
|
};
|
||||||
|
|
||||||
utils::ComboVertexInputDescriptor MakeVertexInput(
|
utils::ComboVertexStateDescriptor MakeVertexState(
|
||||||
const std::vector<VertexBufferSpec>& buffers) {
|
const std::vector<VertexBufferSpec>& buffers) {
|
||||||
utils::ComboVertexInputDescriptor vertexInput;
|
utils::ComboVertexStateDescriptor vertexState;
|
||||||
uint32_t bufferCount = 0;
|
uint32_t vertexBufferCount = 0;
|
||||||
uint32_t totalNumAttributes = 0;
|
uint32_t totalNumAttributes = 0;
|
||||||
for (const VertexBufferSpec& buffer : buffers) {
|
for (const VertexBufferSpec& buffer : buffers) {
|
||||||
vertexInput.cBuffers[bufferCount].stride = buffer.stride;
|
vertexState.cVertexBuffers[vertexBufferCount].arrayStride = buffer.arrayStride;
|
||||||
vertexInput.cBuffers[bufferCount].stepMode = buffer.step;
|
vertexState.cVertexBuffers[vertexBufferCount].stepMode = buffer.step;
|
||||||
|
|
||||||
vertexInput.cBuffers[bufferCount].attributes =
|
vertexState.cVertexBuffers[vertexBufferCount].attributes =
|
||||||
&vertexInput.cAttributes[totalNumAttributes];
|
&vertexState.cAttributes[totalNumAttributes];
|
||||||
|
|
||||||
for (const VertexAttributeSpec& attribute : buffer.attributes) {
|
for (const VertexAttributeSpec& attribute : buffer.attributes) {
|
||||||
vertexInput.cAttributes[totalNumAttributes].shaderLocation = attribute.location;
|
vertexState.cAttributes[totalNumAttributes].shaderLocation = attribute.location;
|
||||||
vertexInput.cAttributes[totalNumAttributes].offset = attribute.offset;
|
vertexState.cAttributes[totalNumAttributes].offset = attribute.offset;
|
||||||
vertexInput.cAttributes[totalNumAttributes].format = attribute.format;
|
vertexState.cAttributes[totalNumAttributes].format = attribute.format;
|
||||||
totalNumAttributes++;
|
totalNumAttributes++;
|
||||||
}
|
}
|
||||||
vertexInput.cBuffers[bufferCount].attributeCount =
|
vertexState.cVertexBuffers[vertexBufferCount].attributeCount =
|
||||||
static_cast<uint32_t>(buffer.attributes.size());
|
static_cast<uint32_t>(buffer.attributes.size());
|
||||||
|
|
||||||
bufferCount++;
|
vertexBufferCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
vertexInput.bufferCount = bufferCount;
|
vertexState.vertexBufferCount = vertexBufferCount;
|
||||||
return vertexInput;
|
return vertexState;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -232,11 +233,11 @@ class VertexInputTest : public DawnTest {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Test compilation and usage of the fixture :)
|
// Test compilation and usage of the fixture :)
|
||||||
TEST_P(VertexInputTest, Basic) {
|
TEST_P(VertexStateTest, Basic) {
|
||||||
utils::ComboVertexInputDescriptor vertexInput = MakeVertexInput(
|
utils::ComboVertexStateDescriptor vertexState = MakeVertexState(
|
||||||
{{4 * sizeof(float), InputStepMode::Vertex, {{0, 0, VertexFormat::Float4}}}});
|
{{4 * sizeof(float), InputStepMode::Vertex, {{0, 0, VertexFormat::Float4}}}});
|
||||||
wgpu::RenderPipeline pipeline =
|
wgpu::RenderPipeline pipeline =
|
||||||
MakeTestPipeline(vertexInput, 1, {{0, VertexFormat::Float4, InputStepMode::Vertex}});
|
MakeTestPipeline(vertexState, 1, {{0, VertexFormat::Float4, InputStepMode::Vertex}});
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
wgpu::Buffer buffer0 = MakeVertexBuffer<float>({
|
wgpu::Buffer buffer0 = MakeVertexBuffer<float>({
|
||||||
|
@ -249,14 +250,14 @@ TEST_P(VertexInputTest, Basic) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test a stride of 0 works
|
// Test a stride of 0 works
|
||||||
TEST_P(VertexInputTest, ZeroStride) {
|
TEST_P(VertexStateTest, ZeroStride) {
|
||||||
// This test was failing only on AMD but the OpenGL backend doesn't gather PCI info yet.
|
// This test was failing only on AMD but the OpenGL backend doesn't gather PCI info yet.
|
||||||
DAWN_SKIP_TEST_IF(IsLinux() && IsOpenGL());
|
DAWN_SKIP_TEST_IF(IsLinux() && IsOpenGL());
|
||||||
|
|
||||||
utils::ComboVertexInputDescriptor vertexInput =
|
utils::ComboVertexStateDescriptor vertexState =
|
||||||
MakeVertexInput({{0, InputStepMode::Vertex, {{0, 0, VertexFormat::Float4}}}});
|
MakeVertexState({{0, InputStepMode::Vertex, {{0, 0, VertexFormat::Float4}}}});
|
||||||
wgpu::RenderPipeline pipeline =
|
wgpu::RenderPipeline pipeline =
|
||||||
MakeTestPipeline(vertexInput, 0, {{0, VertexFormat::Float4, InputStepMode::Vertex}});
|
MakeTestPipeline(vertexState, 0, {{0, VertexFormat::Float4, InputStepMode::Vertex}});
|
||||||
|
|
||||||
wgpu::Buffer buffer0 = MakeVertexBuffer<float>({
|
wgpu::Buffer buffer0 = MakeVertexBuffer<float>({
|
||||||
0,
|
0,
|
||||||
|
@ -268,36 +269,36 @@ TEST_P(VertexInputTest, ZeroStride) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test attributes defaults to (0, 0, 0, 1) if the input state doesn't have all components
|
// Test attributes defaults to (0, 0, 0, 1) if the input state doesn't have all components
|
||||||
TEST_P(VertexInputTest, AttributeExpanding) {
|
TEST_P(VertexStateTest, AttributeExpanding) {
|
||||||
// This test was failing only on AMD but the OpenGL backend doesn't gather PCI info yet.
|
// This test was failing only on AMD but the OpenGL backend doesn't gather PCI info yet.
|
||||||
DAWN_SKIP_TEST_IF(IsLinux() && IsOpenGL());
|
DAWN_SKIP_TEST_IF(IsLinux() && IsOpenGL());
|
||||||
|
|
||||||
// R32F case
|
// R32F case
|
||||||
{
|
{
|
||||||
utils::ComboVertexInputDescriptor vertexInput =
|
utils::ComboVertexStateDescriptor vertexState =
|
||||||
MakeVertexInput({{0, InputStepMode::Vertex, {{0, 0, VertexFormat::Float}}}});
|
MakeVertexState({{0, InputStepMode::Vertex, {{0, 0, VertexFormat::Float}}}});
|
||||||
wgpu::RenderPipeline pipeline =
|
wgpu::RenderPipeline pipeline =
|
||||||
MakeTestPipeline(vertexInput, 0, {{0, VertexFormat::Float, InputStepMode::Vertex}});
|
MakeTestPipeline(vertexState, 0, {{0, VertexFormat::Float, InputStepMode::Vertex}});
|
||||||
|
|
||||||
wgpu::Buffer buffer0 = MakeVertexBuffer<float>({0, 1, 2, 3});
|
wgpu::Buffer buffer0 = MakeVertexBuffer<float>({0, 1, 2, 3});
|
||||||
DoTestDraw(pipeline, 1, 1, {DrawVertexBuffer{0, &buffer0}});
|
DoTestDraw(pipeline, 1, 1, {DrawVertexBuffer{0, &buffer0}});
|
||||||
}
|
}
|
||||||
// RG32F case
|
// RG32F case
|
||||||
{
|
{
|
||||||
utils::ComboVertexInputDescriptor vertexInput =
|
utils::ComboVertexStateDescriptor vertexState =
|
||||||
MakeVertexInput({{0, InputStepMode::Vertex, {{0, 0, VertexFormat::Float2}}}});
|
MakeVertexState({{0, InputStepMode::Vertex, {{0, 0, VertexFormat::Float2}}}});
|
||||||
wgpu::RenderPipeline pipeline =
|
wgpu::RenderPipeline pipeline =
|
||||||
MakeTestPipeline(vertexInput, 0, {{0, VertexFormat::Float2, InputStepMode::Vertex}});
|
MakeTestPipeline(vertexState, 0, {{0, VertexFormat::Float2, InputStepMode::Vertex}});
|
||||||
|
|
||||||
wgpu::Buffer buffer0 = MakeVertexBuffer<float>({0, 1, 2, 3});
|
wgpu::Buffer buffer0 = MakeVertexBuffer<float>({0, 1, 2, 3});
|
||||||
DoTestDraw(pipeline, 1, 1, {DrawVertexBuffer{0, &buffer0}});
|
DoTestDraw(pipeline, 1, 1, {DrawVertexBuffer{0, &buffer0}});
|
||||||
}
|
}
|
||||||
// RGB32F case
|
// RGB32F case
|
||||||
{
|
{
|
||||||
utils::ComboVertexInputDescriptor vertexInput =
|
utils::ComboVertexStateDescriptor vertexState =
|
||||||
MakeVertexInput({{0, InputStepMode::Vertex, {{0, 0, VertexFormat::Float3}}}});
|
MakeVertexState({{0, InputStepMode::Vertex, {{0, 0, VertexFormat::Float3}}}});
|
||||||
wgpu::RenderPipeline pipeline =
|
wgpu::RenderPipeline pipeline =
|
||||||
MakeTestPipeline(vertexInput, 0, {{0, VertexFormat::Float3, InputStepMode::Vertex}});
|
MakeTestPipeline(vertexState, 0, {{0, VertexFormat::Float3, InputStepMode::Vertex}});
|
||||||
|
|
||||||
wgpu::Buffer buffer0 = MakeVertexBuffer<float>({0, 1, 2, 3});
|
wgpu::Buffer buffer0 = MakeVertexBuffer<float>({0, 1, 2, 3});
|
||||||
DoTestDraw(pipeline, 1, 1, {DrawVertexBuffer{0, &buffer0}});
|
DoTestDraw(pipeline, 1, 1, {DrawVertexBuffer{0, &buffer0}});
|
||||||
|
@ -305,14 +306,14 @@ TEST_P(VertexInputTest, AttributeExpanding) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test a stride larger than the attributes
|
// Test a stride larger than the attributes
|
||||||
TEST_P(VertexInputTest, StrideLargerThanAttributes) {
|
TEST_P(VertexStateTest, StrideLargerThanAttributes) {
|
||||||
// This test was failing only on AMD but the OpenGL backend doesn't gather PCI info yet.
|
// This test was failing only on AMD but the OpenGL backend doesn't gather PCI info yet.
|
||||||
DAWN_SKIP_TEST_IF(IsLinux() && IsOpenGL());
|
DAWN_SKIP_TEST_IF(IsLinux() && IsOpenGL());
|
||||||
|
|
||||||
utils::ComboVertexInputDescriptor vertexInput = MakeVertexInput(
|
utils::ComboVertexStateDescriptor vertexState = MakeVertexState(
|
||||||
{{8 * sizeof(float), InputStepMode::Vertex, {{0, 0, VertexFormat::Float4}}}});
|
{{8 * sizeof(float), InputStepMode::Vertex, {{0, 0, VertexFormat::Float4}}}});
|
||||||
wgpu::RenderPipeline pipeline =
|
wgpu::RenderPipeline pipeline =
|
||||||
MakeTestPipeline(vertexInput, 1, {{0, VertexFormat::Float4, InputStepMode::Vertex}});
|
MakeTestPipeline(vertexState, 1, {{0, VertexFormat::Float4, InputStepMode::Vertex}});
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
wgpu::Buffer buffer0 = MakeVertexBuffer<float>({
|
wgpu::Buffer buffer0 = MakeVertexBuffer<float>({
|
||||||
|
@ -325,13 +326,13 @@ 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(VertexStateTest, TwoAttributesAtAnOffsetVertex) {
|
||||||
utils::ComboVertexInputDescriptor vertexInput = MakeVertexInput(
|
utils::ComboVertexStateDescriptor vertexState = MakeVertexState(
|
||||||
{{8 * sizeof(float),
|
{{8 * sizeof(float),
|
||||||
InputStepMode::Vertex,
|
InputStepMode::Vertex,
|
||||||
{{0, 0, VertexFormat::Float4}, {1, 4 * sizeof(float), VertexFormat::Float4}}}});
|
{{0, 0, VertexFormat::Float4}, {1, 4 * sizeof(float), VertexFormat::Float4}}}});
|
||||||
wgpu::RenderPipeline pipeline =
|
wgpu::RenderPipeline pipeline =
|
||||||
MakeTestPipeline(vertexInput, 1, {{0, VertexFormat::Float4, InputStepMode::Vertex}});
|
MakeTestPipeline(vertexState, 1, {{0, VertexFormat::Float4, InputStepMode::Vertex}});
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
wgpu::Buffer buffer0 = MakeVertexBuffer<float>({
|
wgpu::Buffer buffer0 = MakeVertexBuffer<float>({
|
||||||
|
@ -344,13 +345,13 @@ 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(VertexStateTest, TwoAttributesAtAnOffsetInstance) {
|
||||||
utils::ComboVertexInputDescriptor vertexInput = MakeVertexInput(
|
utils::ComboVertexStateDescriptor vertexState = MakeVertexState(
|
||||||
{{8 * sizeof(float),
|
{{8 * sizeof(float),
|
||||||
InputStepMode::Instance,
|
InputStepMode::Instance,
|
||||||
{{0, 0, VertexFormat::Float4}, {1, 4 * sizeof(float), VertexFormat::Float4}}}});
|
{{0, 0, VertexFormat::Float4}, {1, 4 * sizeof(float), VertexFormat::Float4}}}});
|
||||||
wgpu::RenderPipeline pipeline =
|
wgpu::RenderPipeline pipeline =
|
||||||
MakeTestPipeline(vertexInput, 1, {{0, VertexFormat::Float4, InputStepMode::Instance}});
|
MakeTestPipeline(vertexState, 1, {{0, VertexFormat::Float4, InputStepMode::Instance}});
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
wgpu::Buffer buffer0 = MakeVertexBuffer<float>({
|
wgpu::Buffer buffer0 = MakeVertexBuffer<float>({
|
||||||
|
@ -363,11 +364,11 @@ TEST_P(VertexInputTest, TwoAttributesAtAnOffsetInstance) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test a pure-instance input state
|
// Test a pure-instance input state
|
||||||
TEST_P(VertexInputTest, PureInstance) {
|
TEST_P(VertexStateTest, PureInstance) {
|
||||||
utils::ComboVertexInputDescriptor vertexInput = MakeVertexInput(
|
utils::ComboVertexStateDescriptor vertexState = MakeVertexState(
|
||||||
{{4 * sizeof(float), InputStepMode::Instance, {{0, 0, VertexFormat::Float4}}}});
|
{{4 * sizeof(float), InputStepMode::Instance, {{0, 0, VertexFormat::Float4}}}});
|
||||||
wgpu::RenderPipeline pipeline =
|
wgpu::RenderPipeline pipeline =
|
||||||
MakeTestPipeline(vertexInput, 1, {{0, VertexFormat::Float4, InputStepMode::Instance}});
|
MakeTestPipeline(vertexState, 1, {{0, VertexFormat::Float4, InputStepMode::Instance}});
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
wgpu::Buffer buffer0 = MakeVertexBuffer<float>({
|
wgpu::Buffer buffer0 = MakeVertexBuffer<float>({
|
||||||
|
@ -382,8 +383,8 @@ TEST_P(VertexInputTest, PureInstance) {
|
||||||
|
|
||||||
// Test with mixed everything, vertex vs. instance, different stride and offsets
|
// Test with mixed everything, vertex vs. instance, different stride and offsets
|
||||||
// different attribute types
|
// different attribute types
|
||||||
TEST_P(VertexInputTest, MixedEverything) {
|
TEST_P(VertexStateTest, MixedEverything) {
|
||||||
utils::ComboVertexInputDescriptor vertexInput = MakeVertexInput(
|
utils::ComboVertexStateDescriptor vertexState = MakeVertexState(
|
||||||
{{12 * sizeof(float),
|
{{12 * sizeof(float),
|
||||||
InputStepMode::Vertex,
|
InputStepMode::Vertex,
|
||||||
{{0, 0, VertexFormat::Float}, {1, 6 * sizeof(float), VertexFormat::Float2}}},
|
{{0, 0, VertexFormat::Float}, {1, 6 * sizeof(float), VertexFormat::Float2}}},
|
||||||
|
@ -391,7 +392,7 @@ TEST_P(VertexInputTest, MixedEverything) {
|
||||||
InputStepMode::Instance,
|
InputStepMode::Instance,
|
||||||
{{2, 0, VertexFormat::Float3}, {3, 5 * sizeof(float), VertexFormat::Float4}}}});
|
{{2, 0, VertexFormat::Float3}, {3, 5 * sizeof(float), VertexFormat::Float4}}}});
|
||||||
wgpu::RenderPipeline pipeline =
|
wgpu::RenderPipeline pipeline =
|
||||||
MakeTestPipeline(vertexInput, 1,
|
MakeTestPipeline(vertexState, 1,
|
||||||
{{0, VertexFormat::Float, InputStepMode::Vertex},
|
{{0, VertexFormat::Float, InputStepMode::Vertex},
|
||||||
{1, VertexFormat::Float2, InputStepMode::Vertex},
|
{1, VertexFormat::Float2, InputStepMode::Vertex},
|
||||||
{2, VertexFormat::Float3, InputStepMode::Instance},
|
{2, VertexFormat::Float3, InputStepMode::Instance},
|
||||||
|
@ -415,13 +416,13 @@ 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(VertexStateTest, UnusedVertexSlot) {
|
||||||
// Instance input state, using slot 1
|
// Instance input state, using slot 1
|
||||||
utils::ComboVertexInputDescriptor instanceVertexInput = MakeVertexInput(
|
utils::ComboVertexStateDescriptor instanceVertexState = MakeVertexState(
|
||||||
{{0, InputStepMode::Vertex, {}},
|
{{0, InputStepMode::Vertex, {}},
|
||||||
{4 * sizeof(float), InputStepMode::Instance, {{0, 0, VertexFormat::Float4}}}});
|
{4 * sizeof(float), InputStepMode::Instance, {{0, 0, VertexFormat::Float4}}}});
|
||||||
wgpu::RenderPipeline instancePipeline = MakeTestPipeline(
|
wgpu::RenderPipeline instancePipeline = MakeTestPipeline(
|
||||||
instanceVertexInput, 1, {{0, VertexFormat::Float4, InputStepMode::Instance}});
|
instanceVertexState, 1, {{0, VertexFormat::Float4, InputStepMode::Instance}});
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
wgpu::Buffer buffer = MakeVertexBuffer<float>({
|
wgpu::Buffer buffer = MakeVertexBuffer<float>({
|
||||||
|
@ -454,19 +455,19 @@ TEST_P(VertexInputTest, UnusedVertexSlot) {
|
||||||
// This was a problem with the D3D12 backend where SetVertexBuffer
|
// This was a problem with the D3D12 backend where SetVertexBuffer
|
||||||
// was getting the input from the last set pipeline, not the current.
|
// was getting the input from the last set pipeline, not the current.
|
||||||
// SetVertexBuffer should be reapplied when the input state changes.
|
// SetVertexBuffer should be reapplied when the input state changes.
|
||||||
TEST_P(VertexInputTest, MultiplePipelinesMixedVertexInput) {
|
TEST_P(VertexStateTest, MultiplePipelinesMixedVertexState) {
|
||||||
// Basic input state, using slot 0
|
// Basic input state, using slot 0
|
||||||
utils::ComboVertexInputDescriptor vertexVertexInput = MakeVertexInput(
|
utils::ComboVertexStateDescriptor vertexVertexState = MakeVertexState(
|
||||||
{{4 * sizeof(float), InputStepMode::Vertex, {{0, 0, VertexFormat::Float4}}}});
|
{{4 * sizeof(float), InputStepMode::Vertex, {{0, 0, VertexFormat::Float4}}}});
|
||||||
wgpu::RenderPipeline vertexPipeline =
|
wgpu::RenderPipeline vertexPipeline =
|
||||||
MakeTestPipeline(vertexVertexInput, 1, {{0, VertexFormat::Float4, InputStepMode::Vertex}});
|
MakeTestPipeline(vertexVertexState, 1, {{0, VertexFormat::Float4, InputStepMode::Vertex}});
|
||||||
|
|
||||||
// Instance input state, using slot 1
|
// Instance input state, using slot 1
|
||||||
utils::ComboVertexInputDescriptor instanceVertexInput = MakeVertexInput(
|
utils::ComboVertexStateDescriptor instanceVertexState = MakeVertexState(
|
||||||
{{0, InputStepMode::Instance, {}},
|
{{0, InputStepMode::Instance, {}},
|
||||||
{4 * sizeof(float), InputStepMode::Instance, {{0, 0, VertexFormat::Float4}}}});
|
{4 * sizeof(float), InputStepMode::Instance, {{0, 0, VertexFormat::Float4}}}});
|
||||||
wgpu::RenderPipeline instancePipeline = MakeTestPipeline(
|
wgpu::RenderPipeline instancePipeline = MakeTestPipeline(
|
||||||
instanceVertexInput, 1, {{0, VertexFormat::Float4, InputStepMode::Instance}});
|
instanceVertexState, 1, {{0, VertexFormat::Float4, InputStepMode::Instance}});
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
wgpu::Buffer buffer = MakeVertexBuffer<float>({
|
wgpu::Buffer buffer = MakeVertexBuffer<float>({
|
||||||
|
@ -499,28 +500,28 @@ TEST_P(VertexInputTest, MultiplePipelinesMixedVertexInput) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checks that using the last vertex buffer doesn't overflow the vertex buffer table in Metal.
|
// Checks that using the last vertex buffer doesn't overflow the vertex buffer table in Metal.
|
||||||
TEST_P(VertexInputTest, LastAllowedVertexBuffer) {
|
TEST_P(VertexStateTest, LastAllowedVertexBuffer) {
|
||||||
constexpr uint32_t kBufferIndex = kMaxVertexBuffers - 1;
|
constexpr uint32_t kBufferIndex = kMaxVertexBuffers - 1;
|
||||||
|
|
||||||
utils::ComboVertexInputDescriptor vertexInput;
|
utils::ComboVertexStateDescriptor vertexState;
|
||||||
// All the other vertex buffers default to no attributes
|
// All the other vertex buffers default to no attributes
|
||||||
vertexInput.bufferCount = kMaxVertexBuffers;
|
vertexState.vertexBufferCount = kMaxVertexBuffers;
|
||||||
vertexInput.cBuffers[kBufferIndex].stride = 4 * sizeof(float);
|
vertexState.cVertexBuffers[kBufferIndex].arrayStride = 4 * sizeof(float);
|
||||||
vertexInput.cBuffers[kBufferIndex].stepMode = InputStepMode::Vertex;
|
vertexState.cVertexBuffers[kBufferIndex].stepMode = InputStepMode::Vertex;
|
||||||
vertexInput.cBuffers[kBufferIndex].attributeCount = 1;
|
vertexState.cVertexBuffers[kBufferIndex].attributeCount = 1;
|
||||||
vertexInput.cBuffers[kBufferIndex].attributes = &vertexInput.cAttributes[0];
|
vertexState.cVertexBuffers[kBufferIndex].attributes = &vertexState.cAttributes[0];
|
||||||
vertexInput.cAttributes[0].shaderLocation = 0;
|
vertexState.cAttributes[0].shaderLocation = 0;
|
||||||
vertexInput.cAttributes[0].offset = 0;
|
vertexState.cAttributes[0].offset = 0;
|
||||||
vertexInput.cAttributes[0].format = VertexFormat::Float4;
|
vertexState.cAttributes[0].format = VertexFormat::Float4;
|
||||||
|
|
||||||
wgpu::RenderPipeline pipeline =
|
wgpu::RenderPipeline pipeline =
|
||||||
MakeTestPipeline(vertexInput, 1, {{0, VertexFormat::Float4, InputStepMode::Vertex}});
|
MakeTestPipeline(vertexState, 1, {{0, VertexFormat::Float4, InputStepMode::Vertex}});
|
||||||
|
|
||||||
wgpu::Buffer buffer0 = MakeVertexBuffer<float>({0, 1, 2, 3, 1, 2, 3, 4, 2, 3, 4, 5});
|
wgpu::Buffer buffer0 = MakeVertexBuffer<float>({0, 1, 2, 3, 1, 2, 3, 4, 2, 3, 4, 5});
|
||||||
DoTestDraw(pipeline, 1, 1, {DrawVertexBuffer{kMaxVertexBuffers - 1, &buffer0}});
|
DoTestDraw(pipeline, 1, 1, {DrawVertexBuffer{kMaxVertexBuffers - 1, &buffer0}});
|
||||||
}
|
}
|
||||||
|
|
||||||
DAWN_INSTANTIATE_TEST(VertexInputTest, D3D12Backend, MetalBackend, OpenGLBackend, VulkanBackend);
|
DAWN_INSTANTIATE_TEST(VertexStateTest, D3D12Backend, MetalBackend, OpenGLBackend, VulkanBackend);
|
||||||
|
|
||||||
// TODO for the input state:
|
// TODO for the input state:
|
||||||
// - Add more vertex formats
|
// - Add more vertex formats
|
||||||
|
@ -530,10 +531,10 @@ DAWN_INSTANTIATE_TEST(VertexInputTest, D3D12Backend, MetalBackend, OpenGLBackend
|
||||||
// - Check for attribute narrowing
|
// - Check for attribute narrowing
|
||||||
// - Check that the input state and the pipeline vertex input types match
|
// - Check that the input state and the pipeline vertex input types match
|
||||||
|
|
||||||
class OptionalVertexInputTest : public DawnTest {};
|
class OptionalVertexStateTest : public DawnTest {};
|
||||||
|
|
||||||
// Test that vertex input is not required in render pipeline descriptor.
|
// Test that vertex input is not required in render pipeline descriptor.
|
||||||
TEST_P(OptionalVertexInputTest, Basic) {
|
TEST_P(OptionalVertexStateTest, Basic) {
|
||||||
utils::BasicRenderPass renderPass = utils::CreateBasicRenderPass(device, 3, 3);
|
utils::BasicRenderPass renderPass = utils::CreateBasicRenderPass(device, 3, 3);
|
||||||
|
|
||||||
wgpu::ShaderModule vsModule =
|
wgpu::ShaderModule vsModule =
|
||||||
|
@ -556,7 +557,7 @@ TEST_P(OptionalVertexInputTest, Basic) {
|
||||||
descriptor.vertexStage.module = vsModule;
|
descriptor.vertexStage.module = vsModule;
|
||||||
descriptor.cFragmentStage.module = fsModule;
|
descriptor.cFragmentStage.module = fsModule;
|
||||||
descriptor.primitiveTopology = wgpu::PrimitiveTopology::PointList;
|
descriptor.primitiveTopology = wgpu::PrimitiveTopology::PointList;
|
||||||
descriptor.vertexInput = nullptr;
|
descriptor.vertexState = nullptr;
|
||||||
|
|
||||||
wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor);
|
wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor);
|
||||||
|
|
||||||
|
@ -574,7 +575,7 @@ TEST_P(OptionalVertexInputTest, Basic) {
|
||||||
EXPECT_PIXEL_RGBA8_EQ(RGBA8(0, 255, 0, 255), renderPass.color, 1, 1);
|
EXPECT_PIXEL_RGBA8_EQ(RGBA8(0, 255, 0, 255), renderPass.color, 1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
DAWN_INSTANTIATE_TEST(OptionalVertexInputTest,
|
DAWN_INSTANTIATE_TEST(OptionalVertexStateTest,
|
||||||
D3D12Backend,
|
D3D12Backend,
|
||||||
MetalBackend,
|
MetalBackend,
|
||||||
OpenGLBackend,
|
OpenGLBackend,
|
|
@ -346,10 +346,10 @@ void DrawCallPerf::TestSetUp() {
|
||||||
|
|
||||||
// Setup the base render pipeline descriptor.
|
// Setup the base render pipeline descriptor.
|
||||||
utils::ComboRenderPipelineDescriptor renderPipelineDesc(device);
|
utils::ComboRenderPipelineDescriptor renderPipelineDesc(device);
|
||||||
renderPipelineDesc.cVertexInput.bufferCount = 1;
|
renderPipelineDesc.cVertexState.vertexBufferCount = 1;
|
||||||
renderPipelineDesc.cVertexInput.cBuffers[0].stride = 4 * sizeof(float);
|
renderPipelineDesc.cVertexState.cVertexBuffers[0].arrayStride = 4 * sizeof(float);
|
||||||
renderPipelineDesc.cVertexInput.cBuffers[0].attributeCount = 1;
|
renderPipelineDesc.cVertexState.cVertexBuffers[0].attributeCount = 1;
|
||||||
renderPipelineDesc.cVertexInput.cAttributes[0].format = wgpu::VertexFormat::Float4;
|
renderPipelineDesc.cVertexState.cAttributes[0].format = wgpu::VertexFormat::Float4;
|
||||||
renderPipelineDesc.depthStencilState = &renderPipelineDesc.cDepthStencilState;
|
renderPipelineDesc.depthStencilState = &renderPipelineDesc.cDepthStencilState;
|
||||||
renderPipelineDesc.cDepthStencilState.format = wgpu::TextureFormat::Depth24PlusStencil8;
|
renderPipelineDesc.cDepthStencilState.format = wgpu::TextureFormat::Depth24PlusStencil8;
|
||||||
renderPipelineDesc.cColorStates[0].format = wgpu::TextureFormat::RGBA8Unorm;
|
renderPipelineDesc.cColorStates[0].format = wgpu::TextureFormat::RGBA8Unorm;
|
||||||
|
|
|
@ -98,11 +98,11 @@ namespace {
|
||||||
descriptor->layout = pipelineLayout;
|
descriptor->layout = pipelineLayout;
|
||||||
descriptor->vertexStage.module = vsModule;
|
descriptor->vertexStage.module = vsModule;
|
||||||
descriptor->cFragmentStage.module = fsModule;
|
descriptor->cFragmentStage.module = fsModule;
|
||||||
descriptor->cVertexInput.bufferCount = 1;
|
descriptor->cVertexState.vertexBufferCount = 1;
|
||||||
descriptor->cVertexInput.cBuffers[0].stride = 2 * sizeof(float);
|
descriptor->cVertexState.cVertexBuffers[0].arrayStride = 2 * sizeof(float);
|
||||||
descriptor->cVertexInput.cBuffers[0].attributeCount = 1;
|
descriptor->cVertexState.cVertexBuffers[0].attributeCount = 1;
|
||||||
descriptor->cVertexInput.cAttributes[0].format = wgpu::VertexFormat::Float2;
|
descriptor->cVertexState.cAttributes[0].format = wgpu::VertexFormat::Float2;
|
||||||
descriptor->cVertexInput.cAttributes[0].shaderLocation = 0;
|
descriptor->cVertexState.cAttributes[0].shaderLocation = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
wgpu::ShaderModule vsModule;
|
wgpu::ShaderModule vsModule;
|
||||||
|
|
|
@ -57,7 +57,7 @@ TEST_F(RenderPipelineValidationTest, CreationSuccess) {
|
||||||
utils::ComboRenderPipelineDescriptor descriptor(device);
|
utils::ComboRenderPipelineDescriptor descriptor(device);
|
||||||
descriptor.vertexStage.module = vsModule;
|
descriptor.vertexStage.module = vsModule;
|
||||||
descriptor.cFragmentStage.module = fsModule;
|
descriptor.cFragmentStage.module = fsModule;
|
||||||
descriptor.vertexInput = nullptr;
|
descriptor.vertexState = nullptr;
|
||||||
|
|
||||||
device.CreateRenderPipeline(&descriptor);
|
device.CreateRenderPipeline(&descriptor);
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,13 +70,13 @@ class VertexBufferValidationTest : public ValidationTest {
|
||||||
descriptor.cFragmentStage.module = fsModule;
|
descriptor.cFragmentStage.module = fsModule;
|
||||||
|
|
||||||
for (unsigned int i = 0; i < bufferCount; ++i) {
|
for (unsigned int i = 0; i < bufferCount; ++i) {
|
||||||
descriptor.cVertexInput.cBuffers[i].attributeCount = 1;
|
descriptor.cVertexState.cVertexBuffers[i].attributeCount = 1;
|
||||||
descriptor.cVertexInput.cBuffers[i].attributes =
|
descriptor.cVertexState.cVertexBuffers[i].attributes =
|
||||||
&descriptor.cVertexInput.cAttributes[i];
|
&descriptor.cVertexState.cAttributes[i];
|
||||||
descriptor.cVertexInput.cAttributes[i].shaderLocation = i;
|
descriptor.cVertexState.cAttributes[i].shaderLocation = i;
|
||||||
descriptor.cVertexInput.cAttributes[i].format = wgpu::VertexFormat::Float3;
|
descriptor.cVertexState.cAttributes[i].format = wgpu::VertexFormat::Float3;
|
||||||
}
|
}
|
||||||
descriptor.cVertexInput.bufferCount = bufferCount;
|
descriptor.cVertexState.vertexBufferCount = bufferCount;
|
||||||
|
|
||||||
return device.CreateRenderPipeline(&descriptor);
|
return device.CreateRenderPipeline(&descriptor);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,10 +17,10 @@
|
||||||
#include "utils/ComboRenderPipelineDescriptor.h"
|
#include "utils/ComboRenderPipelineDescriptor.h"
|
||||||
#include "utils/WGPUHelpers.h"
|
#include "utils/WGPUHelpers.h"
|
||||||
|
|
||||||
class VertexInputTest : public ValidationTest {
|
class VertexStateTest : public ValidationTest {
|
||||||
protected:
|
protected:
|
||||||
void CreatePipeline(bool success,
|
void CreatePipeline(bool success,
|
||||||
const utils::ComboVertexInputDescriptor& state,
|
const utils::ComboVertexStateDescriptor& state,
|
||||||
std::string vertexSource) {
|
std::string vertexSource) {
|
||||||
wgpu::ShaderModule vsModule = utils::CreateShaderModule(
|
wgpu::ShaderModule vsModule = utils::CreateShaderModule(
|
||||||
device, utils::SingleShaderStage::Vertex, vertexSource.c_str());
|
device, utils::SingleShaderStage::Vertex, vertexSource.c_str());
|
||||||
|
@ -36,7 +36,7 @@ class VertexInputTest : public ValidationTest {
|
||||||
utils::ComboRenderPipelineDescriptor descriptor(device);
|
utils::ComboRenderPipelineDescriptor descriptor(device);
|
||||||
descriptor.vertexStage.module = vsModule;
|
descriptor.vertexStage.module = vsModule;
|
||||||
descriptor.cFragmentStage.module = fsModule;
|
descriptor.cFragmentStage.module = fsModule;
|
||||||
descriptor.vertexInput = &state;
|
descriptor.vertexState = &state;
|
||||||
descriptor.cColorStates[0].format = wgpu::TextureFormat::RGBA8Unorm;
|
descriptor.cColorStates[0].format = wgpu::TextureFormat::RGBA8Unorm;
|
||||||
|
|
||||||
if (!success) {
|
if (!success) {
|
||||||
|
@ -48,8 +48,8 @@ class VertexInputTest : public ValidationTest {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Check an empty vertex input is valid
|
// Check an empty vertex input is valid
|
||||||
TEST_F(VertexInputTest, EmptyIsOk) {
|
TEST_F(VertexStateTest, EmptyIsOk) {
|
||||||
utils::ComboVertexInputDescriptor state;
|
utils::ComboVertexStateDescriptor state;
|
||||||
CreatePipeline(true, state, R"(
|
CreatePipeline(true, state, R"(
|
||||||
#version 450
|
#version 450
|
||||||
void main() {
|
void main() {
|
||||||
|
@ -59,13 +59,13 @@ TEST_F(VertexInputTest, EmptyIsOk) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check null buffer is valid
|
// Check null buffer is valid
|
||||||
TEST_F(VertexInputTest, NullBufferIsOk) {
|
TEST_F(VertexStateTest, NullBufferIsOk) {
|
||||||
utils::ComboVertexInputDescriptor state;
|
utils::ComboVertexStateDescriptor state;
|
||||||
// One null buffer (buffer[0]) is OK
|
// One null buffer (buffer[0]) is OK
|
||||||
state.bufferCount = 1;
|
state.vertexBufferCount = 1;
|
||||||
state.cBuffers[0].stride = 0;
|
state.cVertexBuffers[0].arrayStride = 0;
|
||||||
state.cBuffers[0].attributeCount = 0;
|
state.cVertexBuffers[0].attributeCount = 0;
|
||||||
state.cBuffers[0].attributes = nullptr;
|
state.cVertexBuffers[0].attributes = nullptr;
|
||||||
CreatePipeline(true, state, R"(
|
CreatePipeline(true, state, R"(
|
||||||
#version 450
|
#version 450
|
||||||
void main() {
|
void main() {
|
||||||
|
@ -74,10 +74,10 @@ TEST_F(VertexInputTest, NullBufferIsOk) {
|
||||||
)");
|
)");
|
||||||
|
|
||||||
// One null buffer (buffer[0]) followed by a buffer (buffer[1]) is OK
|
// One null buffer (buffer[0]) followed by a buffer (buffer[1]) is OK
|
||||||
state.bufferCount = 2;
|
state.vertexBufferCount = 2;
|
||||||
state.cBuffers[1].stride = 0;
|
state.cVertexBuffers[1].arrayStride = 0;
|
||||||
state.cBuffers[1].attributeCount = 1;
|
state.cVertexBuffers[1].attributeCount = 1;
|
||||||
state.cBuffers[1].attributes = &state.cAttributes[0];
|
state.cVertexBuffers[1].attributes = &state.cAttributes[0];
|
||||||
state.cAttributes[0].shaderLocation = 0;
|
state.cAttributes[0].shaderLocation = 0;
|
||||||
CreatePipeline(true, state, R"(
|
CreatePipeline(true, state, R"(
|
||||||
#version 450
|
#version 450
|
||||||
|
@ -87,11 +87,11 @@ TEST_F(VertexInputTest, NullBufferIsOk) {
|
||||||
)");
|
)");
|
||||||
|
|
||||||
// Null buffer (buffer[2]) sitting between buffers (buffer[1] and buffer[3]) is OK
|
// Null buffer (buffer[2]) sitting between buffers (buffer[1] and buffer[3]) is OK
|
||||||
state.bufferCount = 4;
|
state.vertexBufferCount = 4;
|
||||||
state.cBuffers[2].attributeCount = 0;
|
state.cVertexBuffers[2].attributeCount = 0;
|
||||||
state.cBuffers[2].attributes = nullptr;
|
state.cVertexBuffers[2].attributes = nullptr;
|
||||||
state.cBuffers[3].attributeCount = 1;
|
state.cVertexBuffers[3].attributeCount = 1;
|
||||||
state.cBuffers[3].attributes = &state.cAttributes[1];
|
state.cVertexBuffers[3].attributes = &state.cAttributes[1];
|
||||||
state.cAttributes[1].shaderLocation = 1;
|
state.cAttributes[1].shaderLocation = 1;
|
||||||
CreatePipeline(true, state, R"(
|
CreatePipeline(true, state, R"(
|
||||||
#version 450
|
#version 450
|
||||||
|
@ -103,11 +103,11 @@ TEST_F(VertexInputTest, NullBufferIsOk) {
|
||||||
|
|
||||||
// Check validation that pipeline vertex buffers are backed by attributes in the vertex input
|
// Check validation that pipeline vertex buffers are backed by attributes in the vertex input
|
||||||
// Check validation that pipeline vertex buffers are backed by attributes in the vertex input
|
// Check validation that pipeline vertex buffers are backed by attributes in the vertex input
|
||||||
TEST_F(VertexInputTest, PipelineCompatibility) {
|
TEST_F(VertexStateTest, PipelineCompatibility) {
|
||||||
utils::ComboVertexInputDescriptor state;
|
utils::ComboVertexStateDescriptor state;
|
||||||
state.bufferCount = 1;
|
state.vertexBufferCount = 1;
|
||||||
state.cBuffers[0].stride = 2 * sizeof(float);
|
state.cVertexBuffers[0].arrayStride = 2 * sizeof(float);
|
||||||
state.cBuffers[0].attributeCount = 2;
|
state.cVertexBuffers[0].attributeCount = 2;
|
||||||
state.cAttributes[0].shaderLocation = 0;
|
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);
|
||||||
|
@ -122,7 +122,7 @@ TEST_F(VertexInputTest, PipelineCompatibility) {
|
||||||
}
|
}
|
||||||
)");
|
)");
|
||||||
|
|
||||||
// Check it is valid for the pipeline to use a subset of the VertexInput
|
// Check it is valid for the pipeline to use a subset of the VertexState
|
||||||
CreatePipeline(true, state, R"(
|
CreatePipeline(true, state, R"(
|
||||||
#version 450
|
#version 450
|
||||||
layout(location = 0) in vec4 a;
|
layout(location = 0) in vec4 a;
|
||||||
|
@ -141,13 +141,13 @@ TEST_F(VertexInputTest, PipelineCompatibility) {
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that a stride of 0 is valid
|
// Test that a arrayStride of 0 is valid
|
||||||
TEST_F(VertexInputTest, StrideZero) {
|
TEST_F(VertexStateTest, StrideZero) {
|
||||||
// Works ok without attributes
|
// Works ok without attributes
|
||||||
utils::ComboVertexInputDescriptor state;
|
utils::ComboVertexStateDescriptor state;
|
||||||
state.bufferCount = 1;
|
state.vertexBufferCount = 1;
|
||||||
state.cBuffers[0].stride = 0;
|
state.cVertexBuffers[0].arrayStride = 0;
|
||||||
state.cBuffers[0].attributeCount = 1;
|
state.cVertexBuffers[0].attributeCount = 1;
|
||||||
CreatePipeline(true, state, R"(
|
CreatePipeline(true, state, R"(
|
||||||
#version 450
|
#version 450
|
||||||
void main() {
|
void main() {
|
||||||
|
@ -165,14 +165,14 @@ TEST_F(VertexInputTest, StrideZero) {
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check validation that vertex attribute offset should be within vertex buffer stride,
|
// Check validation that vertex attribute offset should be within vertex buffer arrayStride,
|
||||||
// if vertex buffer stride is not zero.
|
// if vertex buffer arrayStride is not zero.
|
||||||
TEST_F(VertexInputTest, SetOffsetOutOfBounds) {
|
TEST_F(VertexStateTest, SetOffsetOutOfBounds) {
|
||||||
// Control case, setting correct stride and offset
|
// Control case, setting correct arrayStride and offset
|
||||||
utils::ComboVertexInputDescriptor state;
|
utils::ComboVertexStateDescriptor state;
|
||||||
state.bufferCount = 1;
|
state.vertexBufferCount = 1;
|
||||||
state.cBuffers[0].stride = 2 * sizeof(float);
|
state.cVertexBuffers[0].arrayStride = 2 * sizeof(float);
|
||||||
state.cBuffers[0].attributeCount = 2;
|
state.cVertexBuffers[0].attributeCount = 2;
|
||||||
state.cAttributes[0].shaderLocation = 0;
|
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);
|
||||||
|
@ -183,8 +183,8 @@ TEST_F(VertexInputTest, SetOffsetOutOfBounds) {
|
||||||
}
|
}
|
||||||
)");
|
)");
|
||||||
|
|
||||||
// Test vertex attribute offset exceed vertex buffer stride range
|
// Test vertex attribute offset exceed vertex buffer arrayStride range
|
||||||
state.cBuffers[0].stride = sizeof(float);
|
state.cVertexBuffers[0].arrayStride = sizeof(float);
|
||||||
CreatePipeline(false, state, R"(
|
CreatePipeline(false, state, R"(
|
||||||
#version 450
|
#version 450
|
||||||
void main() {
|
void main() {
|
||||||
|
@ -192,8 +192,8 @@ TEST_F(VertexInputTest, SetOffsetOutOfBounds) {
|
||||||
}
|
}
|
||||||
)");
|
)");
|
||||||
|
|
||||||
// It's OK if stride is zero
|
// It's OK if arrayStride is zero
|
||||||
state.cBuffers[0].stride = 0;
|
state.cVertexBuffers[0].arrayStride = 0;
|
||||||
CreatePipeline(true, state, R"(
|
CreatePipeline(true, state, R"(
|
||||||
#version 450
|
#version 450
|
||||||
void main() {
|
void main() {
|
||||||
|
@ -203,13 +203,13 @@ TEST_F(VertexInputTest, SetOffsetOutOfBounds) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check out of bounds condition on total number of vertex buffers
|
// Check out of bounds condition on total number of vertex buffers
|
||||||
TEST_F(VertexInputTest, SetVertexBuffersNumLimit) {
|
TEST_F(VertexStateTest, SetVertexBuffersNumLimit) {
|
||||||
// Control case, setting max vertex buffer number
|
// Control case, setting max vertex buffer number
|
||||||
utils::ComboVertexInputDescriptor state;
|
utils::ComboVertexStateDescriptor state;
|
||||||
state.bufferCount = kMaxVertexBuffers;
|
state.vertexBufferCount = kMaxVertexBuffers;
|
||||||
for (uint32_t i = 0; i < kMaxVertexBuffers; ++i) {
|
for (uint32_t i = 0; i < kMaxVertexBuffers; ++i) {
|
||||||
state.cBuffers[i].attributeCount = 1;
|
state.cVertexBuffers[i].attributeCount = 1;
|
||||||
state.cBuffers[i].attributes = &state.cAttributes[i];
|
state.cVertexBuffers[i].attributes = &state.cAttributes[i];
|
||||||
state.cAttributes[i].shaderLocation = i;
|
state.cAttributes[i].shaderLocation = i;
|
||||||
}
|
}
|
||||||
CreatePipeline(true, state, R"(
|
CreatePipeline(true, state, R"(
|
||||||
|
@ -220,7 +220,7 @@ TEST_F(VertexInputTest, SetVertexBuffersNumLimit) {
|
||||||
)");
|
)");
|
||||||
|
|
||||||
// Test vertex buffer number exceed the limit
|
// Test vertex buffer number exceed the limit
|
||||||
state.bufferCount = kMaxVertexBuffers + 1;
|
state.vertexBufferCount = kMaxVertexBuffers + 1;
|
||||||
CreatePipeline(false, state, R"(
|
CreatePipeline(false, state, R"(
|
||||||
#version 450
|
#version 450
|
||||||
void main() {
|
void main() {
|
||||||
|
@ -230,11 +230,11 @@ TEST_F(VertexInputTest, SetVertexBuffersNumLimit) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check out of bounds condition on total number of vertex attributes
|
// Check out of bounds condition on total number of vertex attributes
|
||||||
TEST_F(VertexInputTest, SetVertexAttributesNumLimit) {
|
TEST_F(VertexStateTest, SetVertexAttributesNumLimit) {
|
||||||
// Control case, setting max vertex attribute number
|
// Control case, setting max vertex attribute number
|
||||||
utils::ComboVertexInputDescriptor state;
|
utils::ComboVertexStateDescriptor state;
|
||||||
state.bufferCount = 2;
|
state.vertexBufferCount = 2;
|
||||||
state.cBuffers[0].attributeCount = kMaxVertexAttributes;
|
state.cVertexBuffers[0].attributeCount = kMaxVertexAttributes;
|
||||||
for (uint32_t i = 0; i < kMaxVertexAttributes; ++i) {
|
for (uint32_t i = 0; i < kMaxVertexAttributes; ++i) {
|
||||||
state.cAttributes[i].shaderLocation = i;
|
state.cAttributes[i].shaderLocation = i;
|
||||||
}
|
}
|
||||||
|
@ -246,8 +246,8 @@ TEST_F(VertexInputTest, SetVertexAttributesNumLimit) {
|
||||||
)");
|
)");
|
||||||
|
|
||||||
// Test vertex attribute number exceed the limit
|
// Test vertex attribute number exceed the limit
|
||||||
state.cBuffers[1].attributeCount = 1;
|
state.cVertexBuffers[1].attributeCount = 1;
|
||||||
state.cBuffers[1].attributes = &state.cAttributes[kMaxVertexAttributes - 1];
|
state.cVertexBuffers[1].attributes = &state.cAttributes[kMaxVertexAttributes - 1];
|
||||||
CreatePipeline(false, state, R"(
|
CreatePipeline(false, state, R"(
|
||||||
#version 450
|
#version 450
|
||||||
void main() {
|
void main() {
|
||||||
|
@ -256,13 +256,13 @@ TEST_F(VertexInputTest, SetVertexAttributesNumLimit) {
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check out of bounds condition on input stride
|
// Check out of bounds condition on input arrayStride
|
||||||
TEST_F(VertexInputTest, SetInputStrideOutOfBounds) {
|
TEST_F(VertexStateTest, SetInputStrideOutOfBounds) {
|
||||||
// Control case, setting max input stride
|
// Control case, setting max input arrayStride
|
||||||
utils::ComboVertexInputDescriptor state;
|
utils::ComboVertexStateDescriptor state;
|
||||||
state.bufferCount = 1;
|
state.vertexBufferCount = 1;
|
||||||
state.cBuffers[0].stride = kMaxVertexBufferStride;
|
state.cVertexBuffers[0].arrayStride = kMaxVertexBufferStride;
|
||||||
state.cBuffers[0].attributeCount = 1;
|
state.cVertexBuffers[0].attributeCount = 1;
|
||||||
CreatePipeline(true, state, R"(
|
CreatePipeline(true, state, R"(
|
||||||
#version 450
|
#version 450
|
||||||
void main() {
|
void main() {
|
||||||
|
@ -270,8 +270,8 @@ TEST_F(VertexInputTest, SetInputStrideOutOfBounds) {
|
||||||
}
|
}
|
||||||
)");
|
)");
|
||||||
|
|
||||||
// Test input stride OOB
|
// Test input arrayStride OOB
|
||||||
state.cBuffers[0].stride = kMaxVertexBufferStride + 1;
|
state.cVertexBuffers[0].arrayStride = kMaxVertexBufferStride + 1;
|
||||||
CreatePipeline(false, state, R"(
|
CreatePipeline(false, state, R"(
|
||||||
#version 450
|
#version 450
|
||||||
void main() {
|
void main() {
|
||||||
|
@ -280,13 +280,13 @@ TEST_F(VertexInputTest, SetInputStrideOutOfBounds) {
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check multiple of 4 bytes constraint on input stride
|
// Check multiple of 4 bytes constraint on input arrayStride
|
||||||
TEST_F(VertexInputTest, SetInputStrideNotAligned) {
|
TEST_F(VertexStateTest, SetInputStrideNotAligned) {
|
||||||
// Control case, setting input stride 4 bytes.
|
// Control case, setting input arrayStride 4 bytes.
|
||||||
utils::ComboVertexInputDescriptor state;
|
utils::ComboVertexStateDescriptor state;
|
||||||
state.bufferCount = 1;
|
state.vertexBufferCount = 1;
|
||||||
state.cBuffers[0].stride = 4;
|
state.cVertexBuffers[0].arrayStride = 4;
|
||||||
state.cBuffers[0].attributeCount = 1;
|
state.cVertexBuffers[0].attributeCount = 1;
|
||||||
CreatePipeline(true, state, R"(
|
CreatePipeline(true, state, R"(
|
||||||
#version 450
|
#version 450
|
||||||
void main() {
|
void main() {
|
||||||
|
@ -294,8 +294,8 @@ TEST_F(VertexInputTest, SetInputStrideNotAligned) {
|
||||||
}
|
}
|
||||||
)");
|
)");
|
||||||
|
|
||||||
// Test input stride not multiple of 4 bytes
|
// Test input arrayStride not multiple of 4 bytes
|
||||||
state.cBuffers[0].stride = 2;
|
state.cVertexBuffers[0].arrayStride = 2;
|
||||||
CreatePipeline(false, state, R"(
|
CreatePipeline(false, state, R"(
|
||||||
#version 450
|
#version 450
|
||||||
void main() {
|
void main() {
|
||||||
|
@ -305,11 +305,11 @@ TEST_F(VertexInputTest, SetInputStrideNotAligned) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that we cannot set an already set attribute
|
// Test that we cannot set an already set attribute
|
||||||
TEST_F(VertexInputTest, AlreadySetAttribute) {
|
TEST_F(VertexStateTest, AlreadySetAttribute) {
|
||||||
// Control case, setting attribute 0
|
// Control case, setting attribute 0
|
||||||
utils::ComboVertexInputDescriptor state;
|
utils::ComboVertexStateDescriptor state;
|
||||||
state.bufferCount = 1;
|
state.vertexBufferCount = 1;
|
||||||
state.cBuffers[0].attributeCount = 1;
|
state.cVertexBuffers[0].attributeCount = 1;
|
||||||
state.cAttributes[0].shaderLocation = 0;
|
state.cAttributes[0].shaderLocation = 0;
|
||||||
CreatePipeline(true, state, R"(
|
CreatePipeline(true, state, R"(
|
||||||
#version 450
|
#version 450
|
||||||
|
@ -319,7 +319,7 @@ TEST_F(VertexInputTest, AlreadySetAttribute) {
|
||||||
)");
|
)");
|
||||||
|
|
||||||
// Oh no, attribute 0 is set twice
|
// Oh no, attribute 0 is set twice
|
||||||
state.cBuffers[0].attributeCount = 2;
|
state.cVertexBuffers[0].attributeCount = 2;
|
||||||
state.cAttributes[0].shaderLocation = 0;
|
state.cAttributes[0].shaderLocation = 0;
|
||||||
state.cAttributes[1].shaderLocation = 0;
|
state.cAttributes[1].shaderLocation = 0;
|
||||||
CreatePipeline(false, state, R"(
|
CreatePipeline(false, state, R"(
|
||||||
|
@ -330,12 +330,12 @@ TEST_F(VertexInputTest, AlreadySetAttribute) {
|
||||||
)");
|
)");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that a stride of 0 is valid
|
// Test that a arrayStride of 0 is valid
|
||||||
TEST_F(VertexInputTest, SetSameShaderLocation) {
|
TEST_F(VertexStateTest, SetSameShaderLocation) {
|
||||||
// Control case, setting different shader locations in two attributes
|
// Control case, setting different shader locations in two attributes
|
||||||
utils::ComboVertexInputDescriptor state;
|
utils::ComboVertexStateDescriptor state;
|
||||||
state.bufferCount = 1;
|
state.vertexBufferCount = 1;
|
||||||
state.cBuffers[0].attributeCount = 2;
|
state.cVertexBuffers[0].attributeCount = 2;
|
||||||
state.cAttributes[0].shaderLocation = 0;
|
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);
|
||||||
|
@ -356,11 +356,11 @@ TEST_F(VertexInputTest, SetSameShaderLocation) {
|
||||||
)");
|
)");
|
||||||
|
|
||||||
// Test same shader location in two attributes in different buffers
|
// Test same shader location in two attributes in different buffers
|
||||||
state.bufferCount = 2;
|
state.vertexBufferCount = 2;
|
||||||
state.cBuffers[0].attributeCount = 1;
|
state.cVertexBuffers[0].attributeCount = 1;
|
||||||
state.cAttributes[0].shaderLocation = 0;
|
state.cAttributes[0].shaderLocation = 0;
|
||||||
state.cBuffers[1].attributeCount = 1;
|
state.cVertexBuffers[1].attributeCount = 1;
|
||||||
state.cBuffers[1].attributes = &state.cAttributes[1];
|
state.cVertexBuffers[1].attributes = &state.cAttributes[1];
|
||||||
state.cAttributes[1].shaderLocation = 0;
|
state.cAttributes[1].shaderLocation = 0;
|
||||||
CreatePipeline(false, state, R"(
|
CreatePipeline(false, state, R"(
|
||||||
#version 450
|
#version 450
|
||||||
|
@ -371,11 +371,11 @@ TEST_F(VertexInputTest, SetSameShaderLocation) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check out of bounds condition on attribute shader location
|
// Check out of bounds condition on attribute shader location
|
||||||
TEST_F(VertexInputTest, SetAttributeLocationOutOfBounds) {
|
TEST_F(VertexStateTest, SetAttributeLocationOutOfBounds) {
|
||||||
// Control case, setting last attribute shader location
|
// Control case, setting last attribute shader location
|
||||||
utils::ComboVertexInputDescriptor state;
|
utils::ComboVertexStateDescriptor state;
|
||||||
state.bufferCount = 1;
|
state.vertexBufferCount = 1;
|
||||||
state.cBuffers[0].attributeCount = 1;
|
state.cVertexBuffers[0].attributeCount = 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
|
||||||
|
@ -395,11 +395,11 @@ TEST_F(VertexInputTest, SetAttributeLocationOutOfBounds) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check attribute offset out of bounds
|
// Check attribute offset out of bounds
|
||||||
TEST_F(VertexInputTest, SetAttributeOffsetOutOfBounds) {
|
TEST_F(VertexStateTest, 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::ComboVertexStateDescriptor state;
|
||||||
state.bufferCount = 1;
|
state.vertexBufferCount = 1;
|
||||||
state.cBuffers[0].attributeCount = 1;
|
state.cVertexBuffers[0].attributeCount = 1;
|
||||||
state.cAttributes[0].offset = kMaxVertexAttributeEnd - sizeof(wgpu::VertexFormat::Float);
|
state.cAttributes[0].offset = kMaxVertexAttributeEnd - sizeof(wgpu::VertexFormat::Float);
|
||||||
CreatePipeline(true, state, R"(
|
CreatePipeline(true, state, R"(
|
||||||
#version 450
|
#version 450
|
||||||
|
@ -419,11 +419,11 @@ TEST_F(VertexInputTest, SetAttributeOffsetOutOfBounds) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check multiple of 4 bytes constraint on offset
|
// Check multiple of 4 bytes constraint on offset
|
||||||
TEST_F(VertexInputTest, SetOffsetNotAligned) {
|
TEST_F(VertexStateTest, SetOffsetNotAligned) {
|
||||||
// Control case, setting offset 4 bytes.
|
// Control case, setting offset 4 bytes.
|
||||||
utils::ComboVertexInputDescriptor state;
|
utils::ComboVertexStateDescriptor state;
|
||||||
state.bufferCount = 1;
|
state.vertexBufferCount = 1;
|
||||||
state.cBuffers[0].attributeCount = 1;
|
state.cVertexBuffers[0].attributeCount = 1;
|
||||||
state.cAttributes[0].offset = 4;
|
state.cAttributes[0].offset = 4;
|
||||||
CreatePipeline(true, state, R"(
|
CreatePipeline(true, state, R"(
|
||||||
#version 450
|
#version 450
|
||||||
|
@ -443,10 +443,10 @@ TEST_F(VertexInputTest, SetOffsetNotAligned) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check attribute offset overflow
|
// Check attribute offset overflow
|
||||||
TEST_F(VertexInputTest, SetAttributeOffsetOverflow) {
|
TEST_F(VertexStateTest, SetAttributeOffsetOverflow) {
|
||||||
utils::ComboVertexInputDescriptor state;
|
utils::ComboVertexStateDescriptor state;
|
||||||
state.bufferCount = 1;
|
state.vertexBufferCount = 1;
|
||||||
state.cBuffers[0].attributeCount = 1;
|
state.cVertexBuffers[0].attributeCount = 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
|
||||||
|
@ -457,11 +457,11 @@ TEST_F(VertexInputTest, SetAttributeOffsetOverflow) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for some potential underflow in the vertex input validation
|
// Check for some potential underflow in the vertex input validation
|
||||||
TEST_F(VertexInputTest, VertexFormatLargerThanNonZeroStride) {
|
TEST_F(VertexStateTest, VertexFormatLargerThanNonZeroStride) {
|
||||||
utils::ComboVertexInputDescriptor state;
|
utils::ComboVertexStateDescriptor state;
|
||||||
state.bufferCount = 1;
|
state.vertexBufferCount = 1;
|
||||||
state.cBuffers[0].stride = 4;
|
state.cVertexBuffers[0].arrayStride = 4;
|
||||||
state.cBuffers[0].attributeCount = 1;
|
state.cVertexBuffers[0].attributeCount = 1;
|
||||||
state.cAttributes[0].format = wgpu::VertexFormat::Float4;
|
state.cAttributes[0].format = wgpu::VertexFormat::Float4;
|
||||||
CreatePipeline(false, state, R"(
|
CreatePipeline(false, state, R"(
|
||||||
#version 450
|
#version 450
|
|
@ -117,11 +117,11 @@ TEST_F(WireArgumentTests, CStringArgument) {
|
||||||
colorStateDescriptor.writeMask = WGPUColorWriteMask_All;
|
colorStateDescriptor.writeMask = WGPUColorWriteMask_All;
|
||||||
|
|
||||||
// Create the input state
|
// Create the input state
|
||||||
WGPUVertexInputDescriptor vertexInput;
|
WGPUVertexStateDescriptor vertexState;
|
||||||
vertexInput.nextInChain = nullptr;
|
vertexState.nextInChain = nullptr;
|
||||||
vertexInput.indexFormat = WGPUIndexFormat_Uint32;
|
vertexState.indexFormat = WGPUIndexFormat_Uint32;
|
||||||
vertexInput.bufferCount = 0;
|
vertexState.vertexBufferCount = 0;
|
||||||
vertexInput.buffers = nullptr;
|
vertexState.vertexBuffers = nullptr;
|
||||||
|
|
||||||
// Create the rasterization state
|
// Create the rasterization state
|
||||||
WGPURasterizationStateDescriptor rasterizationState;
|
WGPURasterizationStateDescriptor rasterizationState;
|
||||||
|
@ -179,7 +179,7 @@ TEST_F(WireArgumentTests, CStringArgument) {
|
||||||
pipelineDescriptor.sampleMask = 0xFFFFFFFF;
|
pipelineDescriptor.sampleMask = 0xFFFFFFFF;
|
||||||
pipelineDescriptor.alphaToCoverageEnabled = false;
|
pipelineDescriptor.alphaToCoverageEnabled = false;
|
||||||
pipelineDescriptor.layout = layout;
|
pipelineDescriptor.layout = layout;
|
||||||
pipelineDescriptor.vertexInput = &vertexInput;
|
pipelineDescriptor.vertexState = &vertexState;
|
||||||
pipelineDescriptor.primitiveTopology = WGPUPrimitiveTopology_TriangleList;
|
pipelineDescriptor.primitiveTopology = WGPUPrimitiveTopology_TriangleList;
|
||||||
pipelineDescriptor.rasterizationState = &rasterizationState;
|
pipelineDescriptor.rasterizationState = &rasterizationState;
|
||||||
pipelineDescriptor.depthStencilState = &depthStencilState;
|
pipelineDescriptor.depthStencilState = &depthStencilState;
|
||||||
|
|
|
@ -90,11 +90,11 @@ TEST_F(WireOptionalTests, OptionalStructPointer) {
|
||||||
colorStateDescriptor.writeMask = WGPUColorWriteMask_All;
|
colorStateDescriptor.writeMask = WGPUColorWriteMask_All;
|
||||||
|
|
||||||
// Create the input state
|
// Create the input state
|
||||||
WGPUVertexInputDescriptor vertexInput;
|
WGPUVertexStateDescriptor vertexState;
|
||||||
vertexInput.nextInChain = nullptr;
|
vertexState.nextInChain = nullptr;
|
||||||
vertexInput.indexFormat = WGPUIndexFormat_Uint32;
|
vertexState.indexFormat = WGPUIndexFormat_Uint32;
|
||||||
vertexInput.bufferCount = 0;
|
vertexState.vertexBufferCount = 0;
|
||||||
vertexInput.buffers = nullptr;
|
vertexState.vertexBuffers = nullptr;
|
||||||
|
|
||||||
// Create the rasterization state
|
// Create the rasterization state
|
||||||
WGPURasterizationStateDescriptor rasterizationState;
|
WGPURasterizationStateDescriptor rasterizationState;
|
||||||
|
@ -154,7 +154,7 @@ TEST_F(WireOptionalTests, OptionalStructPointer) {
|
||||||
pipelineDescriptor.sampleMask = 0xFFFFFFFF;
|
pipelineDescriptor.sampleMask = 0xFFFFFFFF;
|
||||||
pipelineDescriptor.alphaToCoverageEnabled = false;
|
pipelineDescriptor.alphaToCoverageEnabled = false;
|
||||||
pipelineDescriptor.layout = layout;
|
pipelineDescriptor.layout = layout;
|
||||||
pipelineDescriptor.vertexInput = &vertexInput;
|
pipelineDescriptor.vertexState = &vertexState;
|
||||||
pipelineDescriptor.primitiveTopology = WGPUPrimitiveTopology_TriangleList;
|
pipelineDescriptor.primitiveTopology = WGPUPrimitiveTopology_TriangleList;
|
||||||
pipelineDescriptor.rasterizationState = &rasterizationState;
|
pipelineDescriptor.rasterizationState = &rasterizationState;
|
||||||
|
|
||||||
|
|
|
@ -18,11 +18,11 @@
|
||||||
|
|
||||||
namespace utils {
|
namespace utils {
|
||||||
|
|
||||||
ComboVertexInputDescriptor::ComboVertexInputDescriptor() {
|
ComboVertexStateDescriptor::ComboVertexStateDescriptor() {
|
||||||
wgpu::VertexInputDescriptor* descriptor = this;
|
wgpu::VertexStateDescriptor* descriptor = this;
|
||||||
|
|
||||||
descriptor->indexFormat = wgpu::IndexFormat::Uint32;
|
descriptor->indexFormat = wgpu::IndexFormat::Uint32;
|
||||||
descriptor->bufferCount = 0;
|
descriptor->vertexBufferCount = 0;
|
||||||
|
|
||||||
// Fill the default values for vertexBuffers and vertexAttributes in buffers.
|
// Fill the default values for vertexBuffers and vertexAttributes in buffers.
|
||||||
wgpu::VertexAttributeDescriptor vertexAttribute;
|
wgpu::VertexAttributeDescriptor vertexAttribute;
|
||||||
|
@ -33,17 +33,18 @@ namespace utils {
|
||||||
cAttributes[i] = vertexAttribute;
|
cAttributes[i] = vertexAttribute;
|
||||||
}
|
}
|
||||||
for (uint32_t i = 0; i < kMaxVertexBuffers; ++i) {
|
for (uint32_t i = 0; i < kMaxVertexBuffers; ++i) {
|
||||||
cBuffers[i].stride = 0;
|
cVertexBuffers[i].arrayStride = 0;
|
||||||
cBuffers[i].stepMode = wgpu::InputStepMode::Vertex;
|
cVertexBuffers[i].stepMode = wgpu::InputStepMode::Vertex;
|
||||||
cBuffers[i].attributeCount = 0;
|
cVertexBuffers[i].attributeCount = 0;
|
||||||
cBuffers[i].attributes = nullptr;
|
cVertexBuffers[i].attributes = nullptr;
|
||||||
}
|
}
|
||||||
// cBuffers[i].attributes points to somewhere in cAttributes. cBuffers[0].attributes
|
// cVertexBuffers[i].attributes points to somewhere in cAttributes.
|
||||||
// points to &cAttributes[0] by default. Assuming cBuffers[0] has two attributes, then
|
// cVertexBuffers[0].attributes points to &cAttributes[0] by default. Assuming
|
||||||
// cBuffers[1].attributes should point to &cAttributes[2]. Likewise, if cBuffers[1]
|
// cVertexBuffers[0] has two attributes, then cVertexBuffers[1].attributes should point to
|
||||||
// has 3 attributes, then cBuffers[2].attributes should point to &cAttributes[5].
|
// &cAttributes[2]. Likewise, if cVertexBuffers[1] has 3 attributes, then
|
||||||
cBuffers[0].attributes = &cAttributes[0];
|
// cVertexBuffers[2].attributes should point to &cAttributes[5].
|
||||||
descriptor->buffers = &cBuffers[0];
|
cVertexBuffers[0].attributes = &cAttributes[0];
|
||||||
|
descriptor->vertexBuffers = &cVertexBuffers[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
ComboRenderPipelineDescriptor::ComboRenderPipelineDescriptor(const wgpu::Device& device) {
|
ComboRenderPipelineDescriptor::ComboRenderPipelineDescriptor(const wgpu::Device& device) {
|
||||||
|
@ -62,7 +63,7 @@ namespace utils {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set defaults for the input state descriptors.
|
// Set defaults for the input state descriptors.
|
||||||
descriptor->vertexInput = &cVertexInput;
|
descriptor->vertexState = &cVertexState;
|
||||||
|
|
||||||
// Set defaults for the rasterization state descriptor.
|
// Set defaults for the rasterization state descriptor.
|
||||||
{
|
{
|
||||||
|
|
|
@ -23,11 +23,11 @@
|
||||||
|
|
||||||
namespace utils {
|
namespace utils {
|
||||||
|
|
||||||
class ComboVertexInputDescriptor : public wgpu::VertexInputDescriptor {
|
class ComboVertexStateDescriptor : public wgpu::VertexStateDescriptor {
|
||||||
public:
|
public:
|
||||||
ComboVertexInputDescriptor();
|
ComboVertexStateDescriptor();
|
||||||
|
|
||||||
std::array<wgpu::VertexBufferDescriptor, kMaxVertexBuffers> cBuffers;
|
std::array<wgpu::VertexBufferLayoutDescriptor, kMaxVertexBuffers> cVertexBuffers;
|
||||||
std::array<wgpu::VertexAttributeDescriptor, kMaxVertexAttributes> cAttributes;
|
std::array<wgpu::VertexAttributeDescriptor, kMaxVertexAttributes> cAttributes;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ namespace utils {
|
||||||
|
|
||||||
wgpu::ProgrammableStageDescriptor cFragmentStage;
|
wgpu::ProgrammableStageDescriptor cFragmentStage;
|
||||||
|
|
||||||
ComboVertexInputDescriptor cVertexInput;
|
ComboVertexStateDescriptor cVertexState;
|
||||||
wgpu::RasterizationStateDescriptor cRasterizationState;
|
wgpu::RasterizationStateDescriptor cRasterizationState;
|
||||||
std::array<wgpu::ColorStateDescriptor, kMaxColorAttachments> cColorStates;
|
std::array<wgpu::ColorStateDescriptor, kMaxColorAttachments> cColorStates;
|
||||||
wgpu::DepthStencilStateDescriptor cDepthStencilState;
|
wgpu::DepthStencilStateDescriptor cDepthStencilState;
|
||||||
|
|
Loading…
Reference in New Issue