Fix tessellation break when control stage declares but does not use position builtin.

Add SPIRVShaderOutput::isUsed retrieved from shader reflection.
mvk::sizeOfOutput() returns zero if output var is not used.
Update to latest SPIRV-Cross version.
This commit is contained in:
Bill Hollings 2019-11-26 16:11:52 -05:00
parent 7f83d473ba
commit 9f64cc4bef
5 changed files with 22 additions and 11 deletions

View File

@ -19,11 +19,14 @@ MoltenVK 1.0.39
Released TBD
- Add support for extensions:
- `VK_EXT_inline_uniform_block`
- Support linear filtering when using `vkCmdBlitImage()`.
- Clamp image copy extents to image extent.
- Fix crash in `fetchDependencies` on build paths containing spaces.
- Fix image subresource sizing calculations for heap-based textures.
- Fix `MTLHeap` memory leak in `MVKDeviceMemory`.
- Fix tessellation break when control stage declares but does not use position builtin.
- Support *Xcode 11.2*.

View File

@ -1 +1 @@
b10f5d48c959c5600c5e103a6b955b6b1b59cdff
96a276c2ca86e81530313786e99e2b95623898ca

View File

@ -507,9 +507,10 @@ MTLRenderPipelineDescriptor* MVKGraphicsPipeline::newMTLTessVertexStageDescripto
}
static uint32_t sizeOfOutput(const SPIRVShaderOutput& output) {
if ( !output.isUsed ) { return 0; } // Unused outputs consume no buffer space.
uint32_t vecWidth = output.vecWidth;
// Round up to 4 elements for 3-vectors, since that reflects how Metal lays them out.
if (vecWidth == 3) { vecWidth = 4; }
if (vecWidth == 3) { vecWidth = 4; } // Metal 3-vectors consume same as 4-vectors.
switch (output.baseType) {
case SPIRType::SByte:
case SPIRType::UByte:

View File

@ -129,6 +129,7 @@ bool getShaderOutputs(const std::vector<uint32_t>& spirv, spv::ExecutionModel mo
reflect.set_entry_point(entryName, model);
}
reflect.compile();
reflect.update_active_builtins();
outputs.clear();
@ -136,11 +137,13 @@ bool getShaderOutputs(const std::vector<uint32_t>& spirv, spv::ExecutionModel mo
parser.get_parsed_ir().for_each_typed_id<SPIRV_CROSS_NAMESPACE::SPIRVariable>([&reflect, &outputs, model, addSat](uint32_t varID, const SPIRV_CROSS_NAMESPACE::SPIRVariable& var) {
if (var.storage != spv::StorageClassOutput) { return; }
bool isUsed = true;
const auto* type = &reflect.get_type(reflect.get_type_from_variable(varID).parent_type);
bool patch = reflect.has_decoration(varID, spv::DecorationPatch);
auto biType = spv::BuiltInMax;
if (reflect.has_decoration(varID, spv::DecorationBuiltIn)) {
biType = (spv::BuiltIn)reflect.get_decoration(varID, spv::DecorationBuiltIn);
isUsed = reflect.has_active_builtin(biType, var.storage);
}
uint32_t loc = -1;
if (reflect.has_decoration(varID, spv::DecorationLocation)) {
@ -160,30 +163,31 @@ bool getShaderOutputs(const std::vector<uint32_t>& spirv, spv::ExecutionModel mo
patch = reflect.has_member_decoration(type->self, i, spv::DecorationPatch);
if (reflect.has_member_decoration(type->self, i, spv::DecorationBuiltIn)) {
biType = (spv::BuiltIn)reflect.get_member_decoration(type->self, i, spv::DecorationBuiltIn);
isUsed = reflect.has_active_builtin(biType, var.storage);
}
const SPIRV_CROSS_NAMESPACE::SPIRType& memberType = reflect.get_type(type->member_types[i]);
if (memberType.columns > 1) {
for (uint32_t i = 0; i < memberType.columns; i++) {
outputs.push_back({memberType.basetype, memberType.vecsize, addSat(memberLoc, i), patch, biType});
outputs.push_back({memberType.basetype, memberType.vecsize, addSat(memberLoc, i), biType, patch, isUsed});
}
} else if (!memberType.array.empty()) {
for (uint32_t i = 0; i < memberType.array[0]; i++) {
outputs.push_back({memberType.basetype, memberType.vecsize, addSat(memberLoc, i), patch, biType});
outputs.push_back({memberType.basetype, memberType.vecsize, addSat(memberLoc, i), biType, patch, isUsed});
}
} else {
outputs.push_back({memberType.basetype, memberType.vecsize, memberLoc, patch, biType});
outputs.push_back({memberType.basetype, memberType.vecsize, memberLoc, biType, patch, isUsed});
}
}
} else if (type->columns > 1) {
for (uint32_t i = 0; i < type->columns; i++) {
outputs.push_back({type->basetype, type->vecsize, addSat(loc, i), patch, biType});
outputs.push_back({type->basetype, type->vecsize, addSat(loc, i), biType, patch, isUsed});
}
} else if (!type->array.empty()) {
for (uint32_t i = 0; i < type->array[0]; i++) {
outputs.push_back({type->basetype, type->vecsize, addSat(loc, i), patch, biType});
outputs.push_back({type->basetype, type->vecsize, addSat(loc, i), biType, patch, isUsed});
}
} else {
outputs.push_back({type->basetype, type->vecsize, loc, patch, biType});
outputs.push_back({type->basetype, type->vecsize, loc, biType, patch, isUsed});
}
});
// Sort outputs by ascending location.

View File

@ -61,11 +61,14 @@ namespace mvk {
/** The location number of the output. */
uint32_t location;
/** If this is a builtin, the kind of builtin this is. */
spv::BuiltIn builtin;
/** Whether this is a per-patch or per-vertex output. Only meaningful for tessellation control shaders. */
bool perPatch;
/** If this is a builtin, the kind of builtin this is. */
spv::BuiltIn builtin;
/** Whether this output is actually used (populated) by the shader. */
bool isUsed;
};
#pragma mark -