SPV: Don't add clip/cull distance capabilities unless used.

These capabalities were added on declaration of the members, but
that is considered too aggressive, as those members are automatically
declared in some shaders that don't use them.  Now, actual access
is needed to make the capabalities be declared.
This commit is contained in:
John Kessenich 2016-05-16 19:22:05 -06:00
parent e5f29393da
commit ebb505355d
5 changed files with 27 additions and 11 deletions

View File

@ -109,7 +109,7 @@ public:
protected: protected:
spv::Decoration TranslateInterpolationDecoration(const glslang::TQualifier& qualifier); spv::Decoration TranslateInterpolationDecoration(const glslang::TQualifier& qualifier);
spv::BuiltIn TranslateBuiltInDecoration(glslang::TBuiltInVariable); spv::BuiltIn TranslateBuiltInDecoration(glslang::TBuiltInVariable, bool member);
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,6 +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);
bool isShaderEntrypoint(const glslang::TIntermAggregate* node); bool isShaderEntrypoint(const glslang::TIntermAggregate* node);
void makeFunctions(const glslang::TIntermSequence&); void makeFunctions(const glslang::TIntermSequence&);
@ -393,7 +394,7 @@ spv::Decoration TranslateNoContractionDecoration(const glslang::TQualifier& qual
} }
// Translate glslang built-in variable to SPIR-V built in decoration. // Translate glslang built-in variable to SPIR-V built in decoration.
spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltInVariable builtIn) spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltInVariable builtIn, bool member)
{ {
switch (builtIn) { switch (builtIn) {
case glslang::EbvPointSize: case glslang::EbvPointSize:
@ -410,11 +411,19 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI
} }
return spv::BuiltInPointSize; return spv::BuiltInPointSize;
// These *Distance capabilities logically belong here, but if the member is declared and
// then never used, consumers of SPIR-V prefer the capability not be declared.
// They are now generated when used, rather than here when declared.
// Potentially, the specification should be more clear what the minimum
// use needed is to trigger the capability.
//
case glslang::EbvClipDistance: case glslang::EbvClipDistance:
if (! member)
builder.addCapability(spv::CapabilityClipDistance); builder.addCapability(spv::CapabilityClipDistance);
return spv::BuiltInClipDistance; return spv::BuiltInClipDistance;
case glslang::EbvCullDistance: case glslang::EbvCullDistance:
if (! member)
builder.addCapability(spv::CapabilityCullDistance); builder.addCapability(spv::CapabilityCullDistance);
return spv::BuiltInCullDistance; return spv::BuiltInCullDistance;
@ -926,6 +935,10 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
} else { } else {
// normal case for indexing array or structure or block // normal case for indexing array or structure or block
builder.accessChainPush(builder.makeIntConstant(index)); builder.accessChainPush(builder.makeIntConstant(index));
// Add capabilities here for accessing clip/cull distance
if (node->getLeft()->getType().isStruct() && ! node->getLeft()->getType().isArray())
declareClipCullCapability(*node->getLeft()->getType().getStruct(), index);
} }
} }
return false; return false;
@ -1919,7 +1932,7 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
builder.addMemberDecoration(spvType, member, spv::DecorationMatrixStride, getMatrixStride(glslangType, explicitLayout, subQualifier.layoutMatrix)); builder.addMemberDecoration(spvType, member, spv::DecorationMatrixStride, getMatrixStride(glslangType, explicitLayout, subQualifier.layoutMatrix));
// built-in variable decorations // built-in variable decorations
spv::BuiltIn builtIn = TranslateBuiltInDecoration(glslangType.getQualifier().builtIn); spv::BuiltIn builtIn = TranslateBuiltInDecoration(glslangType.getQualifier().builtIn, true);
if (builtIn != spv::BadValue) if (builtIn != spv::BadValue)
addMemberDecoration(spvType, member, spv::DecorationBuiltIn, (int)builtIn); addMemberDecoration(spvType, member, spv::DecorationBuiltIn, (int)builtIn);
} }
@ -2172,6 +2185,14 @@ void TGlslangToSpvTraverser::updateMemberOffset(const glslang::TType& /*structTy
nextOffset = currentOffset + memberSize; nextOffset = currentOffset + memberSize;
} }
void TGlslangToSpvTraverser::declareClipCullCapability(const glslang::TTypeList& members, int member)
{
if (members[member].type->getQualifier().builtIn == glslang::EbvClipDistance)
builder.addCapability(spv::CapabilityClipDistance);
if (members[member].type->getQualifier().builtIn == glslang::EbvCullDistance)
builder.addCapability(spv::CapabilityCullDistance);
}
bool TGlslangToSpvTraverser::isShaderEntrypoint(const glslang::TIntermAggregate* node) bool TGlslangToSpvTraverser::isShaderEntrypoint(const glslang::TIntermAggregate* node)
{ {
// have to ignore mangling and just look at the base name // have to ignore mangling and just look at the base name
@ -3936,7 +3957,7 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
} }
// built-in variable decorations // built-in variable decorations
spv::BuiltIn builtIn = TranslateBuiltInDecoration(symbol->getQualifier().builtIn); spv::BuiltIn builtIn = TranslateBuiltInDecoration(symbol->getQualifier().builtIn, false);
if (builtIn != spv::BadValue) if (builtIn != spv::BadValue)
addDecoration(id, spv::DecorationBuiltIn, (int)builtIn); addDecoration(id, spv::DecorationBuiltIn, (int)builtIn);

View File

@ -9,7 +9,6 @@ Linked geometry stage:
Capability Geometry Capability Geometry
Capability GeometryPointSize Capability GeometryPointSize
Capability ClipDistance
Capability GeometryStreams Capability GeometryStreams
1: ExtInstImport "GLSL.std.450" 1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450 MemoryModel Logical GLSL450

View File

@ -10,7 +10,6 @@ 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

View File

@ -10,8 +10,6 @@ Linked vertex stage:
// Id's are bound by 49 // Id's are bound by 49
Capability Shader Capability Shader
Capability ClipDistance
Capability CullDistance
1: ExtInstImport "GLSL.std.450" 1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450 MemoryModel Logical GLSL450
EntryPoint Vertex 4 "main" 24 EntryPoint Vertex 4 "main" 24

View File

@ -10,7 +10,6 @@ Linked vertex stage:
// Id's are bound by 103 // Id's are bound by 103
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" 76 81 EntryPoint Vertex 4 "main" 76 81