Fix stride of stage input arrays to tessellation shaders.

These should be set to the alignment of the first member of the output
struct. This fixes the `dEQP-VK.tessellation.common_edge.*` tests.
This commit is contained in:
Chip Davis 2019-02-24 11:09:45 -06:00
parent 069ee53ac5
commit cb8a678c28

View File

@ -576,7 +576,7 @@ MTLComputePipelineDescriptor* MVKGraphicsPipeline::getMTLTessControlStageDescrip
} }
if (vtxOutputs.size() > 0) { if (vtxOutputs.size() > 0) {
plDesc.stageInputDescriptor.layouts[kMVKTessCtlInputBufferIndex].stepFunction = MTLStepFunctionThreadPositionInGridX; plDesc.stageInputDescriptor.layouts[kMVKTessCtlInputBufferIndex].stepFunction = MTLStepFunctionThreadPositionInGridX;
plDesc.stageInputDescriptor.layouts[kMVKTessCtlInputBufferIndex].stride = offset; plDesc.stageInputDescriptor.layouts[kMVKTessCtlInputBufferIndex].stride = mvkAlignByteOffset(offset, sizeOfOutput(vtxOutputs[0]));
} }
plDesc.stageInputDescriptor.indexBufferIndex = kMVKTessCtlIndexBufferIndex; plDesc.stageInputDescriptor.indexBufferIndex = kMVKTessCtlIndexBufferIndex;
@ -609,12 +609,15 @@ MTLRenderPipelineDescriptor* MVKGraphicsPipeline::getMTLTessRasterStageDescripto
// Stage input // Stage input
plDesc.vertexDescriptor = [MTLVertexDescriptor vertexDescriptor]; plDesc.vertexDescriptor = [MTLVertexDescriptor vertexDescriptor];
uint32_t offset = 0, patchOffset = 0, outerLoc = -1, innerLoc = -1; uint32_t offset = 0, patchOffset = 0, outerLoc = -1, innerLoc = -1;
const SPIRVShaderOutput* firstVertex = nullptr, * firstPatch = nullptr;
for (const SPIRVShaderOutput& output : tcOutputs) { for (const SPIRVShaderOutput& output : tcOutputs) {
if (output.builtin == spv::BuiltInPointSize && !reflectData.pointMode) { continue; } if (output.builtin == spv::BuiltInPointSize && !reflectData.pointMode) { continue; }
if (!shaderContext.isVertexAttributeLocationUsed(output.location)) { if (!shaderContext.isVertexAttributeLocationUsed(output.location)) {
if (output.perPatch && !(output.builtin == spv::BuiltInTessLevelOuter || output.builtin == spv::BuiltInTessLevelInner) ) { if (output.perPatch && !(output.builtin == spv::BuiltInTessLevelOuter || output.builtin == spv::BuiltInTessLevelInner) ) {
if (!firstPatch) { firstPatch = &output; }
patchOffset += sizeOfOutput(output); patchOffset += sizeOfOutput(output);
} else if (!output.perPatch) { } else if (!output.perPatch) {
if (!firstVertex) { firstVertex = &output; }
offset += sizeOfOutput(output); offset += sizeOfOutput(output);
} }
continue; continue;
@ -652,21 +655,23 @@ MTLRenderPipelineDescriptor* MVKGraphicsPipeline::getMTLTessRasterStageDescripto
plDesc.vertexDescriptor.attributes[output.location].format = mvkMTLVertexFormatFromVkFormat(mvkFormatFromOutput(output)); plDesc.vertexDescriptor.attributes[output.location].format = mvkMTLVertexFormatFromVkFormat(mvkFormatFromOutput(output));
plDesc.vertexDescriptor.attributes[output.location].offset = patchOffset; plDesc.vertexDescriptor.attributes[output.location].offset = patchOffset;
patchOffset += sizeOfOutput(output); patchOffset += sizeOfOutput(output);
if (!firstPatch) { firstPatch = &output; }
} else { } else {
offset = (uint32_t)mvkAlignByteOffset(offset, sizeOfOutput(output)); offset = (uint32_t)mvkAlignByteOffset(offset, sizeOfOutput(output));
plDesc.vertexDescriptor.attributes[output.location].bufferIndex = kMVKTessEvalInputBufferIndex; plDesc.vertexDescriptor.attributes[output.location].bufferIndex = kMVKTessEvalInputBufferIndex;
plDesc.vertexDescriptor.attributes[output.location].format = mvkMTLVertexFormatFromVkFormat(mvkFormatFromOutput(output)); plDesc.vertexDescriptor.attributes[output.location].format = mvkMTLVertexFormatFromVkFormat(mvkFormatFromOutput(output));
plDesc.vertexDescriptor.attributes[output.location].offset = offset; plDesc.vertexDescriptor.attributes[output.location].offset = offset;
offset += sizeOfOutput(output); offset += sizeOfOutput(output);
if (!firstVertex) { firstVertex = &output; }
} }
} }
if (offset > 0) { if (offset > 0) {
plDesc.vertexDescriptor.layouts[kMVKTessEvalInputBufferIndex].stepFunction = MTLVertexStepFunctionPerPatchControlPoint; plDesc.vertexDescriptor.layouts[kMVKTessEvalInputBufferIndex].stepFunction = MTLVertexStepFunctionPerPatchControlPoint;
plDesc.vertexDescriptor.layouts[kMVKTessEvalInputBufferIndex].stride = offset; plDesc.vertexDescriptor.layouts[kMVKTessEvalInputBufferIndex].stride = mvkAlignByteOffset(offset, sizeOfOutput(*firstVertex));
} }
if (patchOffset > 0) { if (patchOffset > 0) {
plDesc.vertexDescriptor.layouts[kMVKTessEvalPatchInputBufferIndex].stepFunction = MTLVertexStepFunctionPerPatch; plDesc.vertexDescriptor.layouts[kMVKTessEvalPatchInputBufferIndex].stepFunction = MTLVertexStepFunctionPerPatch;
plDesc.vertexDescriptor.layouts[kMVKTessEvalPatchInputBufferIndex].stride = patchOffset; plDesc.vertexDescriptor.layouts[kMVKTessEvalPatchInputBufferIndex].stride = mvkAlignByteOffset(patchOffset, sizeOfOutput(*firstPatch));
} }
if (outerLoc != (uint32_t)(-1) || innerLoc != (uint32_t)(-1)) { if (outerLoc != (uint32_t)(-1) || innerLoc != (uint32_t)(-1)) {
plDesc.vertexDescriptor.layouts[kMVKTessEvalLevelBufferIndex].stepFunction = MTLVertexStepFunctionPerPatch; plDesc.vertexDescriptor.layouts[kMVKTessEvalLevelBufferIndex].stepFunction = MTLVertexStepFunctionPerPatch;