HLSL: allow non-vec3 tessellation coordinate declarations
HLSL requires vec2 tessellation coordinate declarations in some cases (e.g, isoline topology), where SPIR-V requires the TessCoord qualified builtin to be a vec3 in all cases. This alters the IO form of the variable to be a vec3, which will be copied to the shader's declared type if needed. This is not a validation; the shader type must be correct.
This commit is contained in:
@@ -1042,7 +1042,7 @@ TType& HlslParseContext::split(TType& type, TString name, const TType* outerStru
|
||||
if (arraySizes)
|
||||
ioVar->getWritableType().newArraySizes(*arraySizes);
|
||||
|
||||
fixBuiltInArrayType(ioVar->getWritableType());
|
||||
fixBuiltInIoType(ioVar->getWritableType());
|
||||
|
||||
interstageBuiltInIo[tInterstageIoData(memberType, *outerStructType)] = ioVar;
|
||||
|
||||
@@ -1382,28 +1382,44 @@ void HlslParseContext::trackLinkage(TSymbol& symbol)
|
||||
// Some types require fixed array sizes in SPIR-V, but can be scalars or
|
||||
// arrays of sizes SPIR-V doesn't allow. For example, tessellation factors.
|
||||
// This creates the right size. A conversion is performed when the internal
|
||||
// type is copied to or from the external type.
|
||||
void HlslParseContext::fixBuiltInArrayType(TType& type)
|
||||
// type is copied to or from the external type. This corrects the externally
|
||||
// facing input or output type to abide downstream semantics.
|
||||
void HlslParseContext::fixBuiltInIoType(TType& type)
|
||||
{
|
||||
int requiredSize = 0;
|
||||
int requiredArraySize = 0;
|
||||
|
||||
switch (type.getQualifier().builtIn) {
|
||||
case EbvTessLevelOuter: requiredSize = 4; break;
|
||||
case EbvTessLevelInner: requiredSize = 2; break;
|
||||
case EbvTessLevelOuter: requiredArraySize = 4; break;
|
||||
case EbvTessLevelInner: requiredArraySize = 2; break;
|
||||
case EbvClipDistance: // TODO: ...
|
||||
case EbvCullDistance: // TODO: ...
|
||||
return;
|
||||
case EbvTessCoord:
|
||||
{
|
||||
// tesscoord is always a vec3 for the IO variable, no matter the shader's
|
||||
// declared vector size.
|
||||
TType tessCoordType(type.getBasicType(), type.getQualifier().storage, 3);
|
||||
|
||||
tessCoordType.getQualifier() = type.getQualifier();
|
||||
type.shallowCopy(tessCoordType);
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
if (type.isArray()) {
|
||||
// Already an array. Fix the size.
|
||||
type.changeOuterArraySize(requiredSize);
|
||||
} else {
|
||||
// it wasn't an array, but needs to be.
|
||||
TArraySizes arraySizes;
|
||||
arraySizes.addInnerSize(requiredSize);
|
||||
type.newArraySizes(arraySizes);
|
||||
// Alter or set array size as needed.
|
||||
if (requiredArraySize > 0) {
|
||||
if (type.isArray()) {
|
||||
// Already an array. Fix the size.
|
||||
type.changeOuterArraySize(requiredArraySize);
|
||||
} else {
|
||||
// it wasn't an array, but needs to be.
|
||||
TArraySizes arraySizes;
|
||||
arraySizes.addInnerSize(requiredArraySize);
|
||||
type.newArraySizes(arraySizes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1985,6 +2001,8 @@ void HlslParseContext::remapEntryPointIO(TFunction& function, TVariable*& return
|
||||
}
|
||||
ioVariable->getWritableType().getQualifier().storage = storage;
|
||||
|
||||
fixBuiltInIoType(ioVariable->getWritableType());
|
||||
|
||||
return ioVariable;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user