SPV: Address superset of issue #151: missing OpCapability instructions.
authorJohn Kessenich <cepheus@frii.com>
Mon, 1 Feb 2016 20:45:25 +0000 (13:45 -0700)
committerJohn Kessenich <cepheus@frii.com>
Mon, 1 Feb 2016 20:45:25 +0000 (13:45 -0700)
This commit adds:
CapabilityGeometryPointSize
CapabilityTessellationPointSize
CapabilityClipDistance
CapabilityCullDistance
CapabilityMultiViewport
CapabilityTransformFeedback
CapabilityGeometryStreams
CapabilityDerivativeControl
CapabilityInterpolationFunction

14 files changed:
SPIRV/GlslangToSpv.cpp
SPIRV/SpvBuilder.h
Test/baseResults/spv.130.frag.out
Test/baseResults/spv.140.frag.out
Test/baseResults/spv.150.geom.out
Test/baseResults/spv.150.vert.out
Test/baseResults/spv.330.geom.out
Test/baseResults/spv.400.frag.out
Test/baseResults/spv.400.tesc.out
Test/baseResults/spv.400.tese.out
Test/baseResults/spv.420.geom.out
Test/baseResults/spv.430.vert.out
Test/baseResults/spv.bool.vert.out
Test/baseResults/spv.interpOps.frag.out

index 2a11d8e..a75c7ca 100755 (executable)
@@ -88,6 +88,7 @@ public:
     void dumpSpv(std::vector<unsigned int>& out);
 
 protected:
+    spv::BuiltIn TranslateBuiltInDecoration(glslang::TBuiltInVariable);
     spv::Id createSpvVariable(const glslang::TIntermSymbol*);
     spv::Id getSampledType(const glslang::TSampler&);
     spv::Id convertGlslangToSpvType(const glslang::TType& type);
@@ -120,6 +121,7 @@ protected:
     void addDecoration(spv::Id id, spv::Decoration dec);
     void addDecoration(spv::Id id, spv::Decoration dec, unsigned value);
     void addMemberDecoration(spv::Id id, int member, spv::Decoration dec);
+    void addMemberDecoration(spv::Id id, int member, spv::Decoration dec, unsigned value);
     spv::Id createSpvSpecConstant(const glslang::TIntermTyped&);
     spv::Id createSpvConstant(const glslang::TType& type, const glslang::TConstUnionArray&, int& nextConst, bool specConstant);
     bool isTrivialLeaf(const glslang::TIntermTyped* node);
@@ -319,7 +321,7 @@ spv::Decoration TranslateInterpolationDecoration(const glslang::TQualifier& qual
         return (spv::Decoration)spv::BadValue;
 }
 
-// If glslang type is invaraiant, return SPIR-V invariant decoration.
+// If glslang type is invariant, return SPIR-V invariant decoration.
 spv::Decoration TranslateInvariantDecoration(const glslang::TQualifier& qualifier)
 {
     if (qualifier.invariant)
@@ -329,13 +331,34 @@ spv::Decoration TranslateInvariantDecoration(const glslang::TQualifier& qualifie
 }
 
 // Translate glslang built-in variable to SPIR-V built in decoration.
-spv::BuiltIn TranslateBuiltInDecoration(glslang::TBuiltInVariable builtIn)
+spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltInVariable builtIn)
 {
     switch (builtIn) {
+    case glslang::EbvPointSize:
+        switch (glslangIntermediate->getStage()) {
+        case EShLangGeometry:
+            builder.addCapability(spv::CapabilityGeometryPointSize);
+            break;
+        case EShLangTessControl:
+        case EShLangTessEvaluation:
+            builder.addCapability(spv::CapabilityTessellationPointSize);
+            break;
+        }
+        return spv::BuiltInPointSize;
+
+    case glslang::EbvClipDistance:
+        builder.addCapability(spv::CapabilityClipDistance);
+        return spv::BuiltInClipDistance;
+
+    case glslang::EbvCullDistance:
+        builder.addCapability(spv::CapabilityCullDistance);
+        return spv::BuiltInCullDistance;
+
+    case glslang::EbvViewportIndex:
+        // TODO: builder.addCapability(spv::CapabilityMultiViewport);
+        return spv::BuiltInViewportIndex;
+
     case glslang::EbvPosition:             return spv::BuiltInPosition;
-    case glslang::EbvPointSize:            return spv::BuiltInPointSize;
-    case glslang::EbvClipDistance:         return spv::BuiltInClipDistance;
-    case glslang::EbvCullDistance:         return spv::BuiltInCullDistance;
     case glslang::EbvVertexId:             return spv::BuiltInVertexId;
     case glslang::EbvInstanceId:           return spv::BuiltInInstanceId;
     case glslang::EbvBaseVertex:
@@ -347,7 +370,6 @@ spv::BuiltIn TranslateBuiltInDecoration(glslang::TBuiltInVariable builtIn)
     case glslang::EbvPrimitiveId:          return spv::BuiltInPrimitiveId;
     case glslang::EbvInvocationId:         return spv::BuiltInInvocationId;
     case glslang::EbvLayer:                return spv::BuiltInLayer;
-    case glslang::EbvViewportIndex:        return spv::BuiltInViewportIndex;
     case glslang::EbvTessLevelInner:       return spv::BuiltInTessLevelInner;
     case glslang::EbvTessLevelOuter:       return spv::BuiltInTessLevelOuter;
     case glslang::EbvTessCoord:            return spv::BuiltInTessCoord;
@@ -476,8 +498,10 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(const glslang::TIntermediate* gls
 
     // Add the top-level modes for this shader.
 
-    if (glslangIntermediate->getXfbMode())
+    if (glslangIntermediate->getXfbMode()) {
+        builder.addCapability(spv::CapabilityTransformFeedback);
         builder.addExecutionMode(shaderEntry, spv::ExecutionModeXfb);
+    }
 
     unsigned int mode;
     switch (glslangIntermediate->getStage()) {
@@ -1659,16 +1683,19 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
                     // built-in variable decorations
                     spv::BuiltIn builtIn = TranslateBuiltInDecoration(glslangType.getQualifier().builtIn);
                     if (builtIn != spv::BadValue)
-                        builder.addMemberDecoration(spvType, member, spv::DecorationBuiltIn, (int)builtIn);
+                        addMemberDecoration(spvType, member, spv::DecorationBuiltIn, (int)builtIn);
                 }
             }
 
             // Decorate the structure
             addDecoration(spvType, TranslateLayoutDecoration(type, qualifier.layoutMatrix));
             addDecoration(spvType, TranslateBlockDecoration(type));
-            if (type.getQualifier().hasStream())
+            if (type.getQualifier().hasStream()) {
+                builder.addCapability(spv::CapabilityGeometryStreams);
                 builder.addDecoration(spvType, spv::DecorationStream, type.getQualifier().layoutStream);
+            }
             if (glslangIntermediate->getXfbMode()) {
+                builder.addCapability(spv::CapabilityTransformFeedback);
                 if (type.getQualifier().hasXfbStride())
                     builder.addDecoration(spvType, spv::DecorationXfbStride, type.getQualifier().layoutXfbStride);
                 if (type.getQualifier().hasXfbBuffer())
@@ -2787,24 +2814,31 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, spv:
         unaryOp = spv::OpFwidth;
         break;
     case glslang::EOpDPdxFine:
+        builder.addCapability(spv::CapabilityDerivativeControl);
         unaryOp = spv::OpDPdxFine;
         break;
     case glslang::EOpDPdyFine:
+        builder.addCapability(spv::CapabilityDerivativeControl);
         unaryOp = spv::OpDPdyFine;
         break;
     case glslang::EOpFwidthFine:
+        builder.addCapability(spv::CapabilityDerivativeControl);
         unaryOp = spv::OpFwidthFine;
         break;
     case glslang::EOpDPdxCoarse:
+        builder.addCapability(spv::CapabilityDerivativeControl);
         unaryOp = spv::OpDPdxCoarse;
         break;
     case glslang::EOpDPdyCoarse:
+        builder.addCapability(spv::CapabilityDerivativeControl);
         unaryOp = spv::OpDPdyCoarse;
         break;
     case glslang::EOpFwidthCoarse:
+        builder.addCapability(spv::CapabilityDerivativeControl);
         unaryOp = spv::OpFwidthCoarse;
         break;
     case glslang::EOpInterpolateAtCentroid:
+        builder.addCapability(spv::CapabilityInterpolationFunction);
         libCall = spv::GLSLstd450InterpolateAtCentroid;
         break;
     case glslang::EOpAny:
@@ -3180,9 +3214,11 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::
         libCall = spv::GLSLstd450Refract;
         break;
     case glslang::EOpInterpolateAtSample:
+        builder.addCapability(spv::CapabilityInterpolationFunction);
         libCall = spv::GLSLstd450InterpolateAtSample;
         break;
     case glslang::EOpInterpolateAtOffset:
+        builder.addCapability(spv::CapabilityInterpolationFunction);
         libCall = spv::GLSLstd450InterpolateAtOffset;
         break;
     case glslang::EOpAddCarry:
@@ -3352,6 +3388,7 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
         if (symbol->getQualifier().hasComponent())
             builder.addDecoration(id, spv::DecorationComponent, symbol->getQualifier().layoutComponent);
         if (glslangIntermediate->getXfbMode()) {
+            builder.addCapability(spv::CapabilityTransformFeedback);
             if (symbol->getQualifier().hasXfbStride())
                 builder.addDecoration(id, spv::DecorationXfbStride, symbol->getQualifier().layoutXfbStride);
             if (symbol->getQualifier().hasXfbBuffer())
@@ -3362,13 +3399,16 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
     }
 
     addDecoration(id, TranslateInvariantDecoration(symbol->getType().getQualifier()));
-    if (symbol->getQualifier().hasStream())
+    if (symbol->getQualifier().hasStream()) {
+        builder.addCapability(spv::CapabilityGeometryStreams);
         builder.addDecoration(id, spv::DecorationStream, symbol->getQualifier().layoutStream);
+    }
     if (symbol->getQualifier().hasSet())
         builder.addDecoration(id, spv::DecorationDescriptorSet, symbol->getQualifier().layoutSet);
     if (symbol->getQualifier().hasBinding())
         builder.addDecoration(id, spv::DecorationBinding, symbol->getQualifier().layoutBinding);
     if (glslangIntermediate->getXfbMode()) {
+        builder.addCapability(spv::CapabilityTransformFeedback);
         if (symbol->getQualifier().hasXfbStride())
             builder.addDecoration(id, spv::DecorationXfbStride, symbol->getQualifier().layoutXfbStride);
         if (symbol->getQualifier().hasXfbBuffer())
@@ -3378,7 +3418,7 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
     // built-in variable decorations
     spv::BuiltIn builtIn = TranslateBuiltInDecoration(symbol->getQualifier().builtIn);
     if (builtIn != spv::BadValue)
-        builder.addDecoration(id, spv::DecorationBuiltIn, (int)builtIn);
+        addDecoration(id, spv::DecorationBuiltIn, (int)builtIn);
 
     return id;
 }
@@ -3404,6 +3444,13 @@ void TGlslangToSpvTraverser::addMemberDecoration(spv::Id id, int member, spv::De
         builder.addMemberDecoration(id, (unsigned)member, dec);
 }
 
+// If 'dec' is valid, add a one-operand decoration to a struct member
+void TGlslangToSpvTraverser::addMemberDecoration(spv::Id id, int member, spv::Decoration dec, unsigned value)
+{
+    if (dec != spv::BadValue)
+        builder.addMemberDecoration(id, (unsigned)member, dec, value);
+}
+
 // Make a full tree of instructions to build a SPIR-V specialization constant,
 // or regularly constant if possible.
 //
index 33c3ec4..fbfbfad 100755 (executable)
@@ -55,6 +55,7 @@
 #include <memory>
 #include <stack>
 #include <map>
+#include <set>
 
 namespace spv {
 
@@ -78,7 +79,7 @@ public:
         memoryModel = mem;
     }
 
-    void addCapability(spv::Capability cap) { capabilities.push_back(cap); }
+    void addCapability(spv::Capability cap) { capabilities.insert(cap); }
 
     // To get a new <id> for anything needing a new one.
     Id getUniqueId() { return ++uniqueId; }
@@ -525,7 +526,7 @@ public:
     std::vector<const char*> extensions;
     AddressingModel addressModel;
     MemoryModel memoryModel;
-    std::vector<spv::Capability> capabilities;
+    std::set<spv::Capability> capabilities;
     int builderNumber;
     Module module;
     Block* buildPoint;
index 7091d5a..6b47b7d 100644 (file)
@@ -10,6 +10,7 @@ Linked fragment stage:
 // Id's are bound by 213
 
                               Capability Shader
+                              Capability ClipDistance
                1:             ExtInstImport  "GLSL.std.450"
                               MemoryModel Logical GLSL450
                               EntryPoint Fragment 4  "main" 17 68 79 99 173 184 185 186
index 01b2e47..6028f60 100755 (executable)
@@ -8,6 +8,7 @@ Linked fragment stage:
 // Id's are bound by 101
 
                               Capability Shader
+                              Capability ClipDistance
                1:             ExtInstImport  "GLSL.std.450"
                               MemoryModel Logical GLSL450
                               EntryPoint Fragment 4  "main" 16 28 33 43
index 31fda5f..b09f0c0 100755 (executable)
@@ -8,6 +8,9 @@ Linked geometry stage:
 // Id's are bound by 71
 
                               Capability Geometry
+                              Capability GeometryPointSize
+                              Capability ClipDistance
+                              Capability GeometryStreams
                1:             ExtInstImport  "GLSL.std.450"
                               MemoryModel Logical GLSL450
                               EntryPoint Geometry 4  "main" 10 18 29 33 47 49 51 70
index 8767bf8..2a347b4 100755 (executable)
@@ -8,6 +8,7 @@ Linked vertex stage:
 // Id's are bound by 50
 
                               Capability Shader
+                              Capability ClipDistance
                1:             ExtInstImport  "GLSL.std.450"
                               MemoryModel Logical GLSL450
                               EntryPoint Vertex 4  "main" 13 17 39 48 49
index fb409a9..55ee35c 100755 (executable)
@@ -8,6 +8,8 @@ Linked geometry stage:
 // Id's are bound by 32
 
                               Capability Geometry
+                              Capability ClipDistance
+                              Capability GeometryStreams
                1:             ExtInstImport  "GLSL.std.450"
                               MemoryModel Logical GLSL450
                               EntryPoint Geometry 4  "main" 13 20
index f070974..1dcfbd3 100644 (file)
@@ -10,6 +10,7 @@ Linked fragment stage:
 // Id's are bound by 1104
 
                               Capability Shader
+                              Capability ClipDistance
                1:             ExtInstImport  "GLSL.std.450"
                               MemoryModel Logical GLSL450
                               EntryPoint Fragment 4  "main" 13 1025 1031 1036 1048 1074 1095 1097
index 6905c4a..eea07ce 100755 (executable)
@@ -10,6 +10,8 @@ Linked tessellation control stage:
 // Id's are bound by 93
 
                               Capability Tessellation
+                              Capability TessellationPointSize
+                              Capability ClipDistance
                1:             ExtInstImport  "GLSL.std.450"
                               MemoryModel Logical GLSL450
                               EntryPoint TessellationControl 4  "main" 23 40 43 46 52 66 73 79 83 84 87 88 91 92
index 325da15..03e181c 100755 (executable)
@@ -10,6 +10,8 @@ Linked tessellation evaluation stage:
 // Id's are bound by 98
 
                               Capability Tessellation
+                              Capability TessellationPointSize
+                              Capability ClipDistance
                1:             ExtInstImport  "GLSL.std.450"
                               MemoryModel Logical GLSL450
                               EntryPoint TessellationEvaluation 4  "main" 21 38 41 47 53 61 68 77 81 82 86 90 93 94 97
index 3ba3dac..0d659c5 100644 (file)
@@ -10,6 +10,8 @@ Linked geometry stage:
 // Id's are bound by 74
 
                               Capability Geometry
+                              Capability GeometryPointSize
+                              Capability GeometryStreams
                1:             ExtInstImport  "GLSL.std.450"
                               MemoryModel Logical GLSL450
                               EntryPoint Geometry 4  "main" 14 23 28 33 46
index 750fff0..2bf2aaf 100755 (executable)
@@ -10,6 +10,7 @@ Linked vertex stage:
 // Id's are bound by 69
 
                               Capability Shader
+                              Capability ClipDistance
                1:             ExtInstImport  "GLSL.std.450"
                               MemoryModel Logical GLSL450
                               EntryPoint Vertex 4  "main" 12 23 34 44 45 65 67 68
index 0fece20..7f85e6b 100644 (file)
@@ -10,6 +10,8 @@ Linked vertex stage:
 // Id's are bound by 50
 
                               Capability Shader
+                              Capability ClipDistance
+                              Capability CullDistance
                1:             ExtInstImport  "GLSL.std.450"
                               MemoryModel Logical GLSL450
                               EntryPoint Vertex 4  "main" 24 48 49
index ef701f0..c132b44 100644 (file)
@@ -10,6 +10,7 @@ Linked fragment stage:
 // Id's are bound by 101
 
                               Capability Shader
+                              Capability InterpolationFunction
                1:             ExtInstImport  "GLSL.std.450"
                               MemoryModel Logical GLSL450
                               EntryPoint Fragment 4  "main" 13 24 33 41 99