From: David Neto Date: Wed, 8 Jun 2016 13:11:40 +0000 (+0100) Subject: Defer capability decl for ClipDistance, CullDistance, PointSize until actual use X-Git-Tag: upstream/0.1~140^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a901ffed40f219c87757c1ff6dbcda3082c116bd;p=platform%2Fupstream%2Fglslang.git Defer capability decl for ClipDistance, CullDistance, PointSize until actual use The compiler will mark struct members with those builtins, but won't declare the capability until that member is accessed by some executable instruction. Test changes: - spv.430.vert: was missing ClipDistance capability. - spv.precise.tese: remove TessellationPointSize capability. --- diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp index cfbee00..e08bff6 100755 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -109,7 +109,7 @@ public: protected: 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::Id createSpvVariable(const glslang::TIntermSymbol*); spv::Id getSampledType(const glslang::TSampler&); @@ -122,7 +122,7 @@ protected: int getArrayStride(const glslang::TType& arrayType, 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 declareClipCullCapability(const glslang::TTypeList& members, int member); + void declareUseOfStructMember(const glslang::TTypeList& members, int glslangMember); bool isShaderEntrypoint(const glslang::TIntermAggregate* node); void makeFunctions(const glslang::TIntermSequence&); @@ -401,21 +401,28 @@ spv::Decoration TranslateNoContractionDecoration(const glslang::TQualifier& qual return (spv::Decoration)spv::BadValue; } -// Translate glslang built-in variable to SPIR-V built in decoration. -spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltInVariable builtIn, bool member) +// Translate a glslang built-in variable to a SPIR-V built in decoration. Also generate +// 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) { case glslang::EbvPointSize: - switch (glslangIntermediate->getStage()) { - case EShLangGeometry: - builder.addCapability(spv::CapabilityGeometryPointSize); - break; - case EShLangTessControl: - case EShLangTessEvaluation: - builder.addCapability(spv::CapabilityTessellationPointSize); - break; - default: - break; + // Defer adding the capability until the built-in is actually used. + if (!memberDeclaration) { + switch (glslangIntermediate->getStage()) { + case EShLangGeometry: + builder.addCapability(spv::CapabilityGeometryPointSize); + break; + case EShLangTessControl: + case EShLangTessEvaluation: + builder.addCapability(spv::CapabilityTessellationPointSize); + break; + default: + break; + } } return spv::BuiltInPointSize; @@ -426,13 +433,13 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI // use needed is to trigger the capability. // case glslang::EbvClipDistance: - if (! member) - builder.addCapability(spv::CapabilityClipDistance); + if (!memberDeclaration) + builder.addCapability(spv::CapabilityClipDistance); return spv::BuiltInClipDistance; case glslang::EbvCullDistance: - if (! member) - builder.addCapability(spv::CapabilityCullDistance); + if (!memberDeclaration) + builder.addCapability(spv::CapabilityCullDistance); return spv::BuiltInCullDistance; case glslang::EbvViewportIndex: @@ -923,30 +930,34 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T // Add the next element in the chain - int index = 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& remapper = memberRemapper[node->getLeft()->getType().getStruct()]; - assert(remapper.size() > 0); - index = remapper[index]; - } - + const int glslangIndex = node->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst(); if (! node->getLeft()->getType().isArray() && node->getLeft()->getType().isVector() && node->getOp() == glslang::EOpIndexDirect) { // This is essentially a hard-coded vector swizzle of size 1, // so short circuit the access-chain stuff with a swizzle. std::vector swizzle; - swizzle.push_back(node->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst()); + swizzle.push_back(glslangIndex); builder.accessChainPushSwizzle(swizzle, convertGlslangToSpvType(node->getLeft()->getType())); } else { + int spvIndex = glslangIndex; + 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& remapper = memberRemapper[node->getLeft()->getType().getStruct()]; + assert(remapper.size() > 0); + spvIndex = remapper[glslangIndex]; + } + // normal case for indexing array or structure or block - builder.accessChainPush(builder.makeIntConstant(index)); + builder.accessChainPush(builder.makeIntConstant(spvIndex)); - // Add capabilities here for accessing clip/cull distance + // 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()) - declareClipCullCapability(*node->getLeft()->getType().getStruct(), index); + declareUseOfStructMember(*(node->getLeft()->getType().getStruct()), glslangIndex); } } return false; @@ -2203,12 +2214,23 @@ void TGlslangToSpvTraverser::updateMemberOffset(const glslang::TType& /*structTy 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) - builder.addCapability(spv::CapabilityClipDistance); - if (members[member].type->getQualifier().builtIn == glslang::EbvCullDistance) - builder.addCapability(spv::CapabilityCullDistance); + const glslang::TBuiltInVariable glslangBuiltIn = members[glslangMember].type->getQualifier().builtIn; + switch (glslangBuiltIn) + { + 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) diff --git a/Test/baseResults/spv.430.vert.out b/Test/baseResults/spv.430.vert.out index f84fa55..d5332d2 100755 --- a/Test/baseResults/spv.430.vert.out +++ b/Test/baseResults/spv.430.vert.out @@ -10,6 +10,7 @@ Linked vertex stage: // Id's are bound by 66 Capability Shader + Capability ClipDistance 1: ExtInstImport "GLSL.std.450" MemoryModel Logical GLSL450 EntryPoint Vertex 4 "main" 12 23 34 38 41 42 62 65 diff --git a/Test/baseResults/spv.precise.tese.out b/Test/baseResults/spv.precise.tese.out index 231ea33..4033981 100644 --- a/Test/baseResults/spv.precise.tese.out +++ b/Test/baseResults/spv.precise.tese.out @@ -10,7 +10,6 @@ Linked tessellation evaluation stage: // Id's are bound by 119 Capability Tessellation - Capability TessellationPointSize 1: ExtInstImport "GLSL.std.450" MemoryModel Logical GLSL450 EntryPoint TessellationEvaluation 4 "main" 12 21 62 112