Merge pull request #333 from dneto0/defer-capabilities-for-some-struct-members-until-used
SPV: Defer capability decl for ClipDistance, CullDistance, PointSize until…
This commit is contained in:
commit
5022d681d1
@ -109,7 +109,7 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
spv::Decoration TranslateAuxiliaryStorageDecoration(const glslang::TQualifier& qualifier);
|
spv::Decoration TranslateAuxiliaryStorageDecoration(const glslang::TQualifier& qualifier);
|
||||||
spv::BuiltIn TranslateBuiltInDecoration(glslang::TBuiltInVariable, bool member);
|
spv::BuiltIn TranslateBuiltInDecoration(glslang::TBuiltInVariable, bool memberDeclaration);
|
||||||
spv::ImageFormat TranslateImageFormat(const glslang::TType& type);
|
spv::ImageFormat TranslateImageFormat(const glslang::TType& type);
|
||||||
spv::Id createSpvVariable(const glslang::TIntermSymbol*);
|
spv::Id createSpvVariable(const glslang::TIntermSymbol*);
|
||||||
spv::Id getSampledType(const glslang::TSampler&);
|
spv::Id getSampledType(const glslang::TSampler&);
|
||||||
@ -122,7 +122,7 @@ protected:
|
|||||||
int getArrayStride(const glslang::TType& arrayType, glslang::TLayoutPacking, glslang::TLayoutMatrix);
|
int getArrayStride(const glslang::TType& arrayType, glslang::TLayoutPacking, glslang::TLayoutMatrix);
|
||||||
int getMatrixStride(const glslang::TType& matrixType, glslang::TLayoutPacking, glslang::TLayoutMatrix);
|
int getMatrixStride(const glslang::TType& matrixType, glslang::TLayoutPacking, glslang::TLayoutMatrix);
|
||||||
void updateMemberOffset(const glslang::TType& structType, const glslang::TType& memberType, int& currentOffset, int& nextOffset, glslang::TLayoutPacking, glslang::TLayoutMatrix);
|
void updateMemberOffset(const glslang::TType& structType, const glslang::TType& memberType, int& currentOffset, int& nextOffset, glslang::TLayoutPacking, glslang::TLayoutMatrix);
|
||||||
void declareClipCullCapability(const glslang::TTypeList& members, int member);
|
void declareUseOfStructMember(const glslang::TTypeList& members, int glslangMember);
|
||||||
|
|
||||||
bool isShaderEntrypoint(const glslang::TIntermAggregate* node);
|
bool isShaderEntrypoint(const glslang::TIntermAggregate* node);
|
||||||
void makeFunctions(const glslang::TIntermSequence&);
|
void makeFunctions(const glslang::TIntermSequence&);
|
||||||
@ -401,21 +401,28 @@ spv::Decoration TranslateNoContractionDecoration(const glslang::TQualifier& qual
|
|||||||
return (spv::Decoration)spv::BadValue;
|
return (spv::Decoration)spv::BadValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Translate glslang built-in variable to SPIR-V built in decoration.
|
// Translate a glslang built-in variable to a SPIR-V built in decoration. Also generate
|
||||||
spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltInVariable builtIn, bool member)
|
// associated capabilities when required. For some built-in variables, a capability
|
||||||
|
// is generated only when using the variable in an executable instruction, but not when
|
||||||
|
// just declaring a struct member variable with it. This is true for PointSize,
|
||||||
|
// ClipDistance, and CullDistance.
|
||||||
|
spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltInVariable builtIn, bool memberDeclaration)
|
||||||
{
|
{
|
||||||
switch (builtIn) {
|
switch (builtIn) {
|
||||||
case glslang::EbvPointSize:
|
case glslang::EbvPointSize:
|
||||||
switch (glslangIntermediate->getStage()) {
|
// Defer adding the capability until the built-in is actually used.
|
||||||
case EShLangGeometry:
|
if (!memberDeclaration) {
|
||||||
builder.addCapability(spv::CapabilityGeometryPointSize);
|
switch (glslangIntermediate->getStage()) {
|
||||||
break;
|
case EShLangGeometry:
|
||||||
case EShLangTessControl:
|
builder.addCapability(spv::CapabilityGeometryPointSize);
|
||||||
case EShLangTessEvaluation:
|
break;
|
||||||
builder.addCapability(spv::CapabilityTessellationPointSize);
|
case EShLangTessControl:
|
||||||
break;
|
case EShLangTessEvaluation:
|
||||||
default:
|
builder.addCapability(spv::CapabilityTessellationPointSize);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return spv::BuiltInPointSize;
|
return spv::BuiltInPointSize;
|
||||||
|
|
||||||
@ -426,13 +433,13 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI
|
|||||||
// use needed is to trigger the capability.
|
// use needed is to trigger the capability.
|
||||||
//
|
//
|
||||||
case glslang::EbvClipDistance:
|
case glslang::EbvClipDistance:
|
||||||
if (! member)
|
if (!memberDeclaration)
|
||||||
builder.addCapability(spv::CapabilityClipDistance);
|
builder.addCapability(spv::CapabilityClipDistance);
|
||||||
return spv::BuiltInClipDistance;
|
return spv::BuiltInClipDistance;
|
||||||
|
|
||||||
case glslang::EbvCullDistance:
|
case glslang::EbvCullDistance:
|
||||||
if (! member)
|
if (!memberDeclaration)
|
||||||
builder.addCapability(spv::CapabilityCullDistance);
|
builder.addCapability(spv::CapabilityCullDistance);
|
||||||
return spv::BuiltInCullDistance;
|
return spv::BuiltInCullDistance;
|
||||||
|
|
||||||
case glslang::EbvViewportIndex:
|
case glslang::EbvViewportIndex:
|
||||||
@ -923,30 +930,34 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
|
|||||||
|
|
||||||
// Add the next element in the chain
|
// Add the next element in the chain
|
||||||
|
|
||||||
int index = node->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst();
|
const int glslangIndex = node->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst();
|
||||||
if (node->getLeft()->getBasicType() == glslang::EbtBlock && node->getOp() == glslang::EOpIndexDirectStruct) {
|
|
||||||
// This may be, e.g., an anonymous block-member selection, which generally need
|
|
||||||
// index remapping due to hidden members in anonymous blocks.
|
|
||||||
std::vector<int>& remapper = memberRemapper[node->getLeft()->getType().getStruct()];
|
|
||||||
assert(remapper.size() > 0);
|
|
||||||
index = remapper[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! node->getLeft()->getType().isArray() &&
|
if (! node->getLeft()->getType().isArray() &&
|
||||||
node->getLeft()->getType().isVector() &&
|
node->getLeft()->getType().isVector() &&
|
||||||
node->getOp() == glslang::EOpIndexDirect) {
|
node->getOp() == glslang::EOpIndexDirect) {
|
||||||
// This is essentially a hard-coded vector swizzle of size 1,
|
// This is essentially a hard-coded vector swizzle of size 1,
|
||||||
// so short circuit the access-chain stuff with a swizzle.
|
// so short circuit the access-chain stuff with a swizzle.
|
||||||
std::vector<unsigned> swizzle;
|
std::vector<unsigned> swizzle;
|
||||||
swizzle.push_back(node->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst());
|
swizzle.push_back(glslangIndex);
|
||||||
builder.accessChainPushSwizzle(swizzle, convertGlslangToSpvType(node->getLeft()->getType()));
|
builder.accessChainPushSwizzle(swizzle, convertGlslangToSpvType(node->getLeft()->getType()));
|
||||||
} else {
|
} else {
|
||||||
// normal case for indexing array or structure or block
|
int spvIndex = glslangIndex;
|
||||||
builder.accessChainPush(builder.makeIntConstant(index));
|
if (node->getLeft()->getBasicType() == glslang::EbtBlock &&
|
||||||
|
node->getOp() == glslang::EOpIndexDirectStruct)
|
||||||
|
{
|
||||||
|
// This may be, e.g., an anonymous block-member selection, which generally need
|
||||||
|
// index remapping due to hidden members in anonymous blocks.
|
||||||
|
std::vector<int>& remapper = memberRemapper[node->getLeft()->getType().getStruct()];
|
||||||
|
assert(remapper.size() > 0);
|
||||||
|
spvIndex = remapper[glslangIndex];
|
||||||
|
}
|
||||||
|
|
||||||
// Add capabilities here for accessing clip/cull distance
|
// normal case for indexing array or structure or block
|
||||||
|
builder.accessChainPush(builder.makeIntConstant(spvIndex));
|
||||||
|
|
||||||
|
// Add capabilities here for accessing PointSize and clip/cull distance.
|
||||||
|
// We have deferred generation of associated capabilities until now.
|
||||||
if (node->getLeft()->getType().isStruct() && ! node->getLeft()->getType().isArray())
|
if (node->getLeft()->getType().isStruct() && ! node->getLeft()->getType().isArray())
|
||||||
declareClipCullCapability(*node->getLeft()->getType().getStruct(), index);
|
declareUseOfStructMember(*(node->getLeft()->getType().getStruct()), glslangIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -2203,12 +2214,23 @@ void TGlslangToSpvTraverser::updateMemberOffset(const glslang::TType& /*structTy
|
|||||||
nextOffset = currentOffset + memberSize;
|
nextOffset = currentOffset + memberSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TGlslangToSpvTraverser::declareClipCullCapability(const glslang::TTypeList& members, int member)
|
void TGlslangToSpvTraverser::declareUseOfStructMember(const glslang::TTypeList& members, int glslangMember)
|
||||||
{
|
{
|
||||||
if (members[member].type->getQualifier().builtIn == glslang::EbvClipDistance)
|
const glslang::TBuiltInVariable glslangBuiltIn = members[glslangMember].type->getQualifier().builtIn;
|
||||||
builder.addCapability(spv::CapabilityClipDistance);
|
switch (glslangBuiltIn)
|
||||||
if (members[member].type->getQualifier().builtIn == glslang::EbvCullDistance)
|
{
|
||||||
builder.addCapability(spv::CapabilityCullDistance);
|
case glslang::EbvClipDistance:
|
||||||
|
case glslang::EbvCullDistance:
|
||||||
|
case glslang::EbvPointSize:
|
||||||
|
// Generate the associated capability. Delegate to TranslateBuiltInDecoration.
|
||||||
|
// Alternately, we could just call this for any glslang built-in, since the
|
||||||
|
// capability already guards against duplicates.
|
||||||
|
TranslateBuiltInDecoration(glslangBuiltIn, false);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Capabilities were already generated when the struct was declared.
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TGlslangToSpvTraverser::isShaderEntrypoint(const glslang::TIntermAggregate* node)
|
bool TGlslangToSpvTraverser::isShaderEntrypoint(const glslang::TIntermAggregate* node)
|
||||||
|
|||||||
@ -10,6 +10,7 @@ Linked vertex stage:
|
|||||||
// Id's are bound by 66
|
// Id's are bound by 66
|
||||||
|
|
||||||
Capability Shader
|
Capability Shader
|
||||||
|
Capability ClipDistance
|
||||||
1: ExtInstImport "GLSL.std.450"
|
1: ExtInstImport "GLSL.std.450"
|
||||||
MemoryModel Logical GLSL450
|
MemoryModel Logical GLSL450
|
||||||
EntryPoint Vertex 4 "main" 12 23 34 38 41 42 62 65
|
EntryPoint Vertex 4 "main" 12 23 34 38 41 42 62 65
|
||||||
|
|||||||
@ -10,7 +10,6 @@ Linked tessellation evaluation stage:
|
|||||||
// Id's are bound by 119
|
// Id's are bound by 119
|
||||||
|
|
||||||
Capability Tessellation
|
Capability Tessellation
|
||||||
Capability TessellationPointSize
|
|
||||||
1: ExtInstImport "GLSL.std.450"
|
1: ExtInstImport "GLSL.std.450"
|
||||||
MemoryModel Logical GLSL450
|
MemoryModel Logical GLSL450
|
||||||
EntryPoint TessellationEvaluation 4 "main" 12 21 62 112
|
EntryPoint TessellationEvaluation 4 "main" 12 21 62 112
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user