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:
parent
7f83d473ba
commit
9f64cc4bef
@ -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*.
|
||||
|
||||
|
||||
|
@ -1 +1 @@
|
||||
b10f5d48c959c5600c5e103a6b955b6b1b59cdff
|
||||
96a276c2ca86e81530313786e99e2b95623898ca
|
||||
|
@ -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:
|
||||
|
@ -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.
|
||||
|
@ -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 -
|
||||
|
Loading…
x
Reference in New Issue
Block a user