support SPV_NV_viewport_array2 and SPV_NV_stereo_view_rendering
authorchaoc <chaoc@nvidia.com>
Fri, 13 Jan 2017 09:10:53 +0000 (01:10 -0800)
committerchaoc <chaoc@nvidia.com>
Sat, 21 Jan 2017 00:48:26 +0000 (16:48 -0800)
21 files changed:
SPIRV/GLSL.ext.NV.h
SPIRV/GlslangToSpv.cpp
SPIRV/disassemble.cpp
SPIRV/doc.cpp
Test/baseResults/310.tesc.out
Test/baseResults/310.tese.out
Test/baseResults/spv.stereoViewRendering.tesc.out [new file with mode: 0644]
Test/baseResults/spv.stereoViewRendering.vert.out [new file with mode: 0644]
Test/baseResults/spv.viewportArray2.tesc.out [new file with mode: 0644]
Test/baseResults/spv.viewportArray2.vert.out [new file with mode: 0644]
Test/spv.stereoViewRendering.tesc [new file with mode: 0644]
Test/spv.stereoViewRendering.vert [new file with mode: 0644]
Test/spv.viewportArray2.tesc [new file with mode: 0644]
Test/spv.viewportArray2.vert [new file with mode: 0644]
glslang/Include/BaseTypes.h
glslang/Include/Types.h
glslang/MachineIndependent/Initialize.cpp
glslang/MachineIndependent/ParseHelper.cpp
glslang/MachineIndependent/Versions.cpp
glslang/MachineIndependent/Versions.h
gtests/Spv.FromFile.cpp

index adfcb0f345c51b763fc29ef315f1dd90ae582e14..89f0a5c0338d71fdebbc0abd065df45a4d448b98 100644 (file)
 enum BuiltIn;
 enum Decoration;
 enum Op;
+enum Capability;
 
 static const int GLSLextNVVersion = 100;
-static const int GLSLextNVRevision = 2;
+static const int GLSLextNVRevision = 4;
 
 //SPV_NV_sample_mask_override_coverage
 const char* const E_SPV_NV_sample_mask_override_coverage = "SPV_NV_sample_mask_override_coverage";
 
-static const Decoration OverrideCoverageNV = static_cast<Decoration>(5248);
+static const Decoration DecorationOverrideCoverageNV = static_cast<Decoration>(5248);
 
 
 //SPV_NV_geometry_shader_passthrough
 const char* const E_SPV_NV_geometry_shader_passthrough = "SPV_NV_geometry_shader_passthrough";
 
-static const Decoration PassthroughNV = static_cast<Decoration>(5250);
+static const Decoration DecorationPassthroughNV = static_cast<Decoration>(5250);
+
+static const Capability CapabilityGeometryShaderPassthroughNV = static_cast<Capability>(5251);
+
+
+//SPV_NV_viewport_array2
+const char* const E_SPV_NV_viewport_array2 = "SPV_NV_viewport_array2";
+const char* const E_ARB_shader_viewport_layer_array = "SPV_ARB_shader_viewport_layer_array";
+
+static const Decoration DecorationViewportRelativeNV = static_cast<Decoration>(5252);
+
+static const BuiltIn BuiltInViewportMaskNV = static_cast<BuiltIn>(5253);
+
+static const Capability CapabilityShaderViewportIndexLayerNV = static_cast<Capability>(5254);
+static const Capability CapabilityShaderViewportMaskNV       = static_cast<Capability>(5255);
+
+
+//SPV_NV_stereo_view_rendering
+const char* const E_SPV_NV_stereo_view_rendering = "SPV_NV_stereo_view_rendering";
+
+static const Decoration DecorationSecondaryViewportRelativeNV = static_cast<Decoration>(5256);
+
+static const BuiltIn BuiltInSecondaryPositionNV = static_cast<BuiltIn>(5257);
+static const BuiltIn BuiltInSecondaryViewportMaskNV = static_cast<BuiltIn>(5258);
+
+static const Capability CapabilityShaderStereoViewNV = static_cast<Capability>(5259);
 
-static const Capability GeometryShaderPassthroughNV = static_cast<Capability>(5251);
 #endif  // #ifndef GLSLextNV_H
\ No newline at end of file
index 81243f9f92c7a5a6f0b519fcca7d999fe4e381d7..f83d82fe843d8d20e388ffce82de0db940cf513b 100755 (executable)
@@ -482,6 +482,15 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI
 
     case glslang::EbvViewportIndex:
         builder.addCapability(spv::CapabilityMultiViewport);
+#ifdef NV_EXTENSIONS
+        if (glslangIntermediate->getStage() == EShLangVertex ||
+            glslangIntermediate->getStage() == EShLangTessControl ||
+            glslangIntermediate->getStage() == EShLangTessEvaluation)
+        {
+            builder.addExtension(spv::E_SPV_NV_viewport_array2);
+            builder.addCapability(spv::CapabilityShaderViewportIndexLayerNV);
+        }
+#endif
         return spv::BuiltInViewportIndex;
 
     case glslang::EbvSampleId:
@@ -498,6 +507,18 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI
 
     case glslang::EbvLayer:
         builder.addCapability(spv::CapabilityGeometry);
+#ifdef NV_EXTENSIONS
+        if (!memberDeclaration)
+        {
+            if (glslangIntermediate->getStage() == EShLangVertex ||
+                glslangIntermediate->getStage() == EShLangTessControl ||
+                glslangIntermediate->getStage() == EShLangTessEvaluation)
+            {
+                builder.addExtension(spv::E_SPV_NV_viewport_array2);
+                builder.addCapability(spv::CapabilityShaderViewportIndexLayerNV);
+            }
+        }
+#endif
         return spv::BuiltInLayer;
 
     case glslang::EbvPosition:             return spv::BuiltInPosition;
@@ -607,6 +628,21 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI
         builder.addExtension(spv::E_SPV_AMD_shader_explicit_vertex_parameter);
         return spv::BuiltInBaryCoordPullModelAMD;
 #endif
+
+#ifdef NV_EXTENSIONS
+    case glslang::EbvViewportMaskNV:
+        builder.addExtension(spv::E_SPV_NV_viewport_array2);
+        builder.addCapability(spv::CapabilityShaderViewportMaskNV);
+        return spv::BuiltInViewportMaskNV;
+    case glslang::EbvSecondaryPositionNV:
+        builder.addExtension(spv::E_SPV_NV_stereo_view_rendering);
+        builder.addCapability(spv::CapabilityShaderStereoViewNV);
+        return spv::BuiltInSecondaryPositionNV;
+    case glslang::EbvSecondaryViewportMaskNV:
+        builder.addExtension(spv::E_SPV_NV_stereo_view_rendering);
+        builder.addCapability(spv::CapabilityShaderStereoViewNV);
+        return spv::BuiltInSecondaryViewportMaskNV;
+#endif 
     default:                               return spv::BuiltInMax;
     }
 }
@@ -2275,6 +2311,22 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type,
             spv::BuiltIn builtIn = TranslateBuiltInDecoration(glslangMember.getQualifier().builtIn, true);
             if (builtIn != spv::BuiltInMax)
                 addMemberDecoration(spvType, member, spv::DecorationBuiltIn, (int)builtIn);
+
+#ifdef NV_EXTENSIONS
+            if (builtIn == spv::BuiltInLayer) {
+                // SPV_NV_viewport_array2 extension
+                if (glslangMember.getQualifier().layoutViewportRelative){
+                    addMemberDecoration(spvType, member, (spv::Decoration)spv::DecorationViewportRelativeNV);
+                    builder.addCapability(spv::CapabilityShaderViewportMaskNV);
+                    builder.addExtension(spv::E_SPV_NV_viewport_array2);
+                }
+                if (glslangMember.getQualifier().layoutSecondaryViewportRelativeOffset != -2048){
+                    addMemberDecoration(spvType, member, (spv::Decoration)spv::DecorationSecondaryViewportRelativeNV, glslangMember.getQualifier().layoutSecondaryViewportRelativeOffset);
+                    builder.addCapability(spv::CapabilityShaderStereoViewNV);
+                    builder.addExtension(spv::E_SPV_NV_stereo_view_rendering);
+                }
+            }
+#endif
         }
     }
 
@@ -2546,6 +2598,12 @@ void TGlslangToSpvTraverser::declareUseOfStructMember(const glslang::TTypeList&
     case glslang::EbvClipDistance:
     case glslang::EbvCullDistance:
     case glslang::EbvPointSize:
+#ifdef NV_EXTENSIONS
+    case glslang::EbvLayer:
+    case glslang::EbvViewportMaskNV:
+    case glslang::EbvSecondaryPositionNV:
+    case glslang::EbvSecondaryViewportMaskNV:
+#endif
         // 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.
@@ -4800,7 +4858,7 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
           spv::Decoration decoration;
           // GL_NV_sample_mask_override_coverage extension
           if (glslangIntermediate->getLayoutOverrideCoverage())
-              decoration = (spv::Decoration)spv::OverrideCoverageNV;
+              decoration = (spv::Decoration)spv::DecorationOverrideCoverageNV;
           else
               decoration = (spv::Decoration)spv::DecorationMax;
         addDecoration(id, decoration);
@@ -4808,9 +4866,25 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
             builder.addExtension(spv::E_SPV_NV_sample_mask_override_coverage);
         }
     }
+    else if (builtIn == spv::BuiltInLayer) {
+        // SPV_NV_viewport_array2 extension
+        if (symbol->getQualifier().layoutViewportRelative)
+        {
+            addDecoration(id, (spv::Decoration)spv::DecorationViewportRelativeNV);
+            builder.addCapability(spv::CapabilityShaderViewportMaskNV);
+            builder.addExtension(spv::E_SPV_NV_viewport_array2);
+        }
+        if(symbol->getQualifier().layoutSecondaryViewportRelativeOffset != -2048)
+        {
+            addDecoration(id, (spv::Decoration)spv::DecorationSecondaryViewportRelativeNV, symbol->getQualifier().layoutSecondaryViewportRelativeOffset);
+            builder.addCapability(spv::CapabilityShaderStereoViewNV);
+            builder.addExtension(spv::E_SPV_NV_stereo_view_rendering);
+        }
+    }
+
     if (symbol->getQualifier().layoutPassthrough) {
-        addDecoration(id, spv::PassthroughNV);
-        builder.addCapability(spv::GeometryShaderPassthroughNV);
+        addDecoration(id, spv::DecorationPassthroughNV);
+        builder.addCapability(spv::CapabilityGeometryShaderPassthroughNV);
         builder.addExtension(spv::E_SPV_NV_geometry_shader_passthrough);
     }
 #endif
index a8049b876b14838cab202a57d4535ed0d722a0cc..74ae40767f88f0aa8cd4dab9672e4232069fa143 100644 (file)
@@ -482,7 +482,8 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
 #endif
 #ifdef NV_EXTENSIONS
                 }else if (strcmp(spv::E_SPV_NV_sample_mask_override_coverage, name) == 0 ||
-                          strcmp(spv::E_SPV_NV_geometry_shader_passthrough, name) == 0) {
+                          strcmp(spv::E_SPV_NV_geometry_shader_passthrough, name) == 0 ||
+                          strcmp(spv::E_SPV_NV_viewport_array2, name) == 0) {
                     extInstSet = GLSLextNVInst;
 #endif
                 }
@@ -656,12 +657,21 @@ static const char* GLSLextAMDGetDebugNames(const char* name, unsigned entrypoint
 static const char* GLSLextNVGetDebugNames(const char* name, unsigned entrypoint)
 {
     if (strcmp(name, spv::E_SPV_NV_sample_mask_override_coverage) == 0 ||
-        strcmp(name, spv::E_SPV_NV_geometry_shader_passthrough) == 0) {
+        strcmp(name, spv::E_SPV_NV_geometry_shader_passthrough) == 0 ||
+        strcmp(name, spv::E_ARB_shader_viewport_layer_array) == 0 ||
+        strcmp(name, spv::E_SPV_NV_viewport_array2) == 0){
         switch (entrypoint) {
-        case OverrideCoverageNV:          return "OverrideCoverageNV";
-        case PassthroughNV:               return "PassthroughNV";
-        case GeometryShaderPassthroughNV: return "GeometryShaderPassthroughNV";
-        default:                          return "Bad";
+        case DecorationOverrideCoverageNV:          return "OverrideCoverageNV";
+        case DecorationPassthroughNV:               return "PassthroughNV";
+        case CapabilityGeometryShaderPassthroughNV: return "GeometryShaderPassthroughNV";
+        case DecorationViewportRelativeNV:          return "ViewportRelativeNV";
+        case BuiltInViewportMaskNV:                 return "ViewportMaskNV";
+        case CapabilityShaderViewportMaskNV:        return "ShaderViewportMaskNV";
+        case DecorationSecondaryViewportRelativeNV: return "SecondaryViewportRelativeNV";
+        case BuiltInSecondaryPositionNV:            return "SecondaryPositionNV";
+        case BuiltInSecondaryViewportMaskNV:        return "SecondaryViewportMaskNV";
+        case CapabilityShaderStereoViewNV:          return "ShaderStereoViewNV";
+        default:                                    return "Bad";
         }
     }
     return "Bad";
index 0bb9e017719df539ae233a201fe986fb04be4a34..87180997867f38aef75c684ca9d76363f3af8815 100755 (executable)
@@ -262,6 +262,8 @@ const char* DecorationString(int decoration)
 #ifdef NV_EXTENSIONS
     case 5248: return "OverrideCoverageNV";
     case 5250: return "PassthroughNV";
+    case 5252: return "ViewportRelativeNV";
+    case 5256: return "SecondaryViewportRelativeNV";
 #endif
     }
 }
@@ -337,6 +339,11 @@ const char* BuiltInString(int builtIn)
     case 4996: return "BaryCoordSmoothCentroidAMD";
     case 4997: return "BaryCoordSmoothSampleAMD";
     case 4998: return "BaryCoordPullModelAMD";
+#endif
+#ifdef NV_EXTENSIONS
+    case 5253: return "ViewportMaskNV";
+    case 5257: return "SecondaryPositionNV";
+    case 5258: return "SecondaryViewportMaskNV";
 #endif
     }
 }
@@ -823,6 +830,9 @@ const char* CapabilityString(int info)
 
 #ifdef NV_EXTENSIONS
     case 5251: return "GeometryShaderPassthroughNV";
+    case 5254: return "ShaderViewportIndexLayerNV";
+    case 5255: return "ShaderViewportMaskNV";
+    case 5259: return "ShaderStereoViewNV";
 #endif
 
     }
index ab27198f61e9d442fce03fa594bb813633a10dbc..d004fa166c2ca9256fbcd96eb3496e049da0adbe 100644 (file)
@@ -71,8 +71,8 @@ ERROR: node is still EOpNull!
 0:25        move second child to first child (temp highp 4-component vector of float)
 0:25          'p' (temp highp 4-component vector of float)
 0:25          gl_Position: direct index for structure (in highp 4-component vector of float Position)
-0:25            direct index (temp block{in highp 4-component vector of float Position gl_Position, in highp float PointSize gl_PointSize})
-0:25              'gl_in' (in 32-element array of block{in highp 4-component vector of float Position gl_Position, in highp float PointSize gl_PointSize})
+0:25            direct index (temp block{in highp 4-component vector of float Position gl_Position, in highp float PointSize gl_PointSize, in highp 4-component vector of float gl_SecondaryPositionNV})
+0:25              'gl_in' (in 32-element array of block{in highp 4-component vector of float Position gl_Position, in highp float PointSize gl_PointSize, in highp 4-component vector of float gl_SecondaryPositionNV})
 0:25              Constant:
 0:25                1 (const int)
 0:25            Constant:
@@ -81,8 +81,8 @@ ERROR: node is still EOpNull!
 0:26        move second child to first child (temp highp float)
 0:26          'ps' (temp highp float)
 0:26          gl_PointSize: direct index for structure (in highp float PointSize)
-0:26            direct index (temp block{in highp 4-component vector of float Position gl_Position, in highp float PointSize gl_PointSize})
-0:26              'gl_in' (in 32-element array of block{in highp 4-component vector of float Position gl_Position, in highp float PointSize gl_PointSize})
+0:26            direct index (temp block{in highp 4-component vector of float Position gl_Position, in highp float PointSize gl_PointSize, in highp 4-component vector of float gl_SecondaryPositionNV})
+0:26              'gl_in' (in 32-element array of block{in highp 4-component vector of float Position gl_Position, in highp float PointSize gl_PointSize, in highp 4-component vector of float gl_SecondaryPositionNV})
 0:26              Constant:
 0:26                1 (const int)
 0:26            Constant:
@@ -210,8 +210,8 @@ ERROR: node is still EOpNull!
 0:114        move second child to first child (temp highp float)
 0:114          'ps' (temp highp float)
 0:114          gl_PointSize: direct index for structure (in highp float PointSize)
-0:114            direct index (temp block{in highp 4-component vector of float Position gl_Position, in highp float PointSize gl_PointSize})
-0:114              'gl_in' (in 32-element array of block{in highp 4-component vector of float Position gl_Position, in highp float PointSize gl_PointSize})
+0:114            direct index (temp block{in highp 4-component vector of float Position gl_Position, in highp float PointSize gl_PointSize, in highp 4-component vector of float gl_SecondaryPositionNV})
+0:114              'gl_in' (in 32-element array of block{in highp 4-component vector of float Position gl_Position, in highp float PointSize gl_PointSize, in highp 4-component vector of float gl_SecondaryPositionNV})
 0:114              Constant:
 0:114                1 (const int)
 0:114            Constant:
@@ -402,8 +402,8 @@ ERROR: node is still EOpNull!
 0:25        move second child to first child (temp highp 4-component vector of float)
 0:25          'p' (temp highp 4-component vector of float)
 0:25          gl_Position: direct index for structure (in highp 4-component vector of float Position)
-0:25            direct index (temp block{in highp 4-component vector of float Position gl_Position, in highp float PointSize gl_PointSize})
-0:25              'gl_in' (in 32-element array of block{in highp 4-component vector of float Position gl_Position, in highp float PointSize gl_PointSize})
+0:25            direct index (temp block{in highp 4-component vector of float Position gl_Position, in highp float PointSize gl_PointSize, in highp 4-component vector of float gl_SecondaryPositionNV})
+0:25              'gl_in' (in 32-element array of block{in highp 4-component vector of float Position gl_Position, in highp float PointSize gl_PointSize, in highp 4-component vector of float gl_SecondaryPositionNV})
 0:25              Constant:
 0:25                1 (const int)
 0:25            Constant:
@@ -412,8 +412,8 @@ ERROR: node is still EOpNull!
 0:26        move second child to first child (temp highp float)
 0:26          'ps' (temp highp float)
 0:26          gl_PointSize: direct index for structure (in highp float PointSize)
-0:26            direct index (temp block{in highp 4-component vector of float Position gl_Position, in highp float PointSize gl_PointSize})
-0:26              'gl_in' (in 32-element array of block{in highp 4-component vector of float Position gl_Position, in highp float PointSize gl_PointSize})
+0:26            direct index (temp block{in highp 4-component vector of float Position gl_Position, in highp float PointSize gl_PointSize, in highp 4-component vector of float gl_SecondaryPositionNV})
+0:26              'gl_in' (in 32-element array of block{in highp 4-component vector of float Position gl_Position, in highp float PointSize gl_PointSize, in highp 4-component vector of float gl_SecondaryPositionNV})
 0:26              Constant:
 0:26                1 (const int)
 0:26            Constant:
index 62894ec79786e3f3bdec4c35949127394dfc37d7..c6ce6650bd3cd0b661bda7d66324680990288a26 100644 (file)
@@ -78,8 +78,8 @@ ERROR: node is still EOpNull!
 0:36        move second child to first child (temp highp 4-component vector of float)
 0:36          'p' (temp highp 4-component vector of float)
 0:36          gl_Position: direct index for structure (in highp 4-component vector of float Position)
-0:36            direct index (temp block{in highp 4-component vector of float Position gl_Position, in highp float PointSize gl_PointSize})
-0:36              'gl_in' (in 32-element array of block{in highp 4-component vector of float Position gl_Position, in highp float PointSize gl_PointSize})
+0:36            direct index (temp block{in highp 4-component vector of float Position gl_Position, in highp float PointSize gl_PointSize, in highp 4-component vector of float gl_SecondaryPositionNV})
+0:36              'gl_in' (in 32-element array of block{in highp 4-component vector of float Position gl_Position, in highp float PointSize gl_PointSize, in highp 4-component vector of float gl_SecondaryPositionNV})
 0:36              Constant:
 0:36                1 (const int)
 0:36            Constant:
@@ -88,8 +88,8 @@ ERROR: node is still EOpNull!
 0:37        move second child to first child (temp highp float)
 0:37          'ps' (temp highp float)
 0:37          gl_PointSize: direct index for structure (in highp float PointSize)
-0:37            direct index (temp block{in highp 4-component vector of float Position gl_Position, in highp float PointSize gl_PointSize})
-0:37              'gl_in' (in 32-element array of block{in highp 4-component vector of float Position gl_Position, in highp float PointSize gl_PointSize})
+0:37            direct index (temp block{in highp 4-component vector of float Position gl_Position, in highp float PointSize gl_PointSize, in highp 4-component vector of float gl_SecondaryPositionNV})
+0:37              'gl_in' (in 32-element array of block{in highp 4-component vector of float Position gl_Position, in highp float PointSize gl_PointSize, in highp 4-component vector of float gl_SecondaryPositionNV})
 0:37              Constant:
 0:37                1 (const int)
 0:37            Constant:
@@ -211,8 +211,8 @@ ERROR: node is still EOpNull!
 0:36        move second child to first child (temp highp 4-component vector of float)
 0:36          'p' (temp highp 4-component vector of float)
 0:36          gl_Position: direct index for structure (in highp 4-component vector of float Position)
-0:36            direct index (temp block{in highp 4-component vector of float Position gl_Position, in highp float PointSize gl_PointSize})
-0:36              'gl_in' (in 32-element array of block{in highp 4-component vector of float Position gl_Position, in highp float PointSize gl_PointSize})
+0:36            direct index (temp block{in highp 4-component vector of float Position gl_Position, in highp float PointSize gl_PointSize, in highp 4-component vector of float gl_SecondaryPositionNV})
+0:36              'gl_in' (in 32-element array of block{in highp 4-component vector of float Position gl_Position, in highp float PointSize gl_PointSize, in highp 4-component vector of float gl_SecondaryPositionNV})
 0:36              Constant:
 0:36                1 (const int)
 0:36            Constant:
@@ -221,8 +221,8 @@ ERROR: node is still EOpNull!
 0:37        move second child to first child (temp highp float)
 0:37          'ps' (temp highp float)
 0:37          gl_PointSize: direct index for structure (in highp float PointSize)
-0:37            direct index (temp block{in highp 4-component vector of float Position gl_Position, in highp float PointSize gl_PointSize})
-0:37              'gl_in' (in 32-element array of block{in highp 4-component vector of float Position gl_Position, in highp float PointSize gl_PointSize})
+0:37            direct index (temp block{in highp 4-component vector of float Position gl_Position, in highp float PointSize gl_PointSize, in highp 4-component vector of float gl_SecondaryPositionNV})
+0:37              'gl_in' (in 32-element array of block{in highp 4-component vector of float Position gl_Position, in highp float PointSize gl_PointSize, in highp 4-component vector of float gl_SecondaryPositionNV})
 0:37              Constant:
 0:37                1 (const int)
 0:37            Constant:
diff --git a/Test/baseResults/spv.stereoViewRendering.tesc.out b/Test/baseResults/spv.stereoViewRendering.tesc.out
new file mode 100644 (file)
index 0000000..c8f9642
--- /dev/null
@@ -0,0 +1,86 @@
+spv.stereoViewRendering.tesc
+Warning, version 450 is not yet complete; most version-specific features are present, but some are missing.
+
+// Module Version 10000
+// Generated by (magic number): 80001
+// Id's are bound by 38
+
+                              Capability Geometry
+                              Capability Tessellation
+                              Capability ShaderViewportMaskNV
+                              Capability ShaderStereoViewNV
+                              Extension  "SPV_NV_stereo_view_rendering"
+                              Extension  "SPV_NV_viewport_array2"
+               1:             ExtInstImport  "GLSL.std.450"
+                              MemoryModel Logical GLSL450
+                              EntryPoint TessellationControl 4  "main" 16 18 32
+                              ExecutionMode 4 OutputVertices 4
+                              Source GLSL 450
+                              SourceExtension  "GL_NV_stereo_view_rendering"
+                              SourceExtension  "GL_NV_viewport_array2"
+                              Name 4  "main"
+                              Name 12  "gl_PerVertex"
+                              MemberName 12(gl_PerVertex) 0  "gl_Layer"
+                              MemberName 12(gl_PerVertex) 1  "gl_SecondaryPositionNV"
+                              MemberName 12(gl_PerVertex) 2  "gl_SecondaryViewportMaskNV"
+                              Name 16  "gl_out"
+                              Name 18  "gl_InvocationID"
+                              Name 28  "gl_PerVertex"
+                              MemberName 28(gl_PerVertex) 0  "gl_Position"
+                              MemberName 28(gl_PerVertex) 1  "gl_PointSize"
+                              MemberName 28(gl_PerVertex) 2  "gl_ClipDistance"
+                              MemberName 28(gl_PerVertex) 3  "gl_CullDistance"
+                              MemberName 28(gl_PerVertex) 4  "gl_SecondaryPositionNV"
+                              Name 32  "gl_in"
+                              MemberDecorate 12(gl_PerVertex) 0 BuiltIn Layer
+                              MemberDecorate 12(gl_PerVertex) 0 ViewportRelativeNV
+                              MemberDecorate 12(gl_PerVertex) 0 SecondaryViewportRelativeNV 1
+                              MemberDecorate 12(gl_PerVertex) 1 BuiltIn SecondaryPositionNV
+                              MemberDecorate 12(gl_PerVertex) 2 BuiltIn SecondaryViewportMaskNV
+                              Decorate 12(gl_PerVertex) Block
+                              Decorate 18(gl_InvocationID) BuiltIn InvocationId
+                              MemberDecorate 28(gl_PerVertex) 0 BuiltIn Position
+                              MemberDecorate 28(gl_PerVertex) 1 BuiltIn PointSize
+                              MemberDecorate 28(gl_PerVertex) 2 BuiltIn ClipDistance
+                              MemberDecorate 28(gl_PerVertex) 3 BuiltIn CullDistance
+                              Decorate 28(gl_PerVertex) Block
+               2:             TypeVoid
+               3:             TypeFunction 2
+               6:             TypeInt 32 1
+               7:             TypeFloat 32
+               8:             TypeVector 7(float) 4
+               9:             TypeInt 32 0
+              10:      9(int) Constant 2
+              11:             TypeArray 6(int) 10
+12(gl_PerVertex):             TypeStruct 6(int) 8(fvec4) 11
+              13:      9(int) Constant 4
+              14:             TypeArray 12(gl_PerVertex) 13
+              15:             TypePointer Output 14
+      16(gl_out):     15(ptr) Variable Output
+              17:             TypePointer Input 6(int)
+18(gl_InvocationID):     17(ptr) Variable Input
+              20:      6(int) Constant 2
+              21:      6(int) Constant 0
+              22:      6(int) Constant 1
+              23:             TypePointer Output 6(int)
+              26:      9(int) Constant 1
+              27:             TypeArray 7(float) 26
+28(gl_PerVertex):             TypeStruct 8(fvec4) 7(float) 27 27 8(fvec4)
+              29:      9(int) Constant 32
+              30:             TypeArray 28(gl_PerVertex) 29
+              31:             TypePointer Input 30
+       32(gl_in):     31(ptr) Variable Input
+              33:             TypePointer Input 8(fvec4)
+              36:             TypePointer Output 8(fvec4)
+         4(main):           2 Function None 3
+               5:             Label
+              19:      6(int) Load 18(gl_InvocationID)
+              24:     23(ptr) AccessChain 16(gl_out) 19 20 21
+                              Store 24 22
+              25:      6(int) Load 18(gl_InvocationID)
+              34:     33(ptr) AccessChain 32(gl_in) 22 21
+              35:    8(fvec4) Load 34
+              37:     36(ptr) AccessChain 16(gl_out) 25 22
+                              Store 37 35
+                              Return
+                              FunctionEnd
diff --git a/Test/baseResults/spv.stereoViewRendering.vert.out b/Test/baseResults/spv.stereoViewRendering.vert.out
new file mode 100644 (file)
index 0000000..d6c6956
--- /dev/null
@@ -0,0 +1,69 @@
+spv.stereoViewRendering.vert
+Warning, version 450 is not yet complete; most version-specific features are present, but some are missing.
+
+// Module Version 10000
+// Generated by (magic number): 80001
+// Id's are bound by 27
+
+                              Capability Shader
+                              Capability Geometry
+                              Capability ShaderViewportIndexLayerNV
+                              Capability ShaderViewportMaskNV
+                              Capability ShaderStereoViewNV
+                              Extension  "SPV_NV_stereo_view_rendering"
+                              Extension  "SPV_NV_viewport_array2"
+               1:             ExtInstImport  "GLSL.std.450"
+                              MemoryModel Logical GLSL450
+                              EntryPoint Vertex 4  "main" 11 19 23 26
+                              Source GLSL 450
+                              SourceExtension  "GL_NV_stereo_view_rendering"
+                              SourceExtension  "GL_NV_viewport_array2"
+                              Name 4  "main"
+                              Name 11  "gl_SecondaryViewportMaskNV"
+                              Name 19  "gl_SecondaryPositionNV"
+                              Name 21  "gl_PerVertex"
+                              MemberName 21(gl_PerVertex) 0  "gl_Position"
+                              MemberName 21(gl_PerVertex) 1  "gl_PointSize"
+                              MemberName 21(gl_PerVertex) 2  "gl_ClipDistance"
+                              MemberName 21(gl_PerVertex) 3  "gl_CullDistance"
+                              Name 23  ""
+                              Name 26  "gl_Layer"
+                              Decorate 11(gl_SecondaryViewportMaskNV) BuiltIn SecondaryViewportMaskNV
+                              Decorate 19(gl_SecondaryPositionNV) BuiltIn SecondaryPositionNV
+                              MemberDecorate 21(gl_PerVertex) 0 BuiltIn Position
+                              MemberDecorate 21(gl_PerVertex) 1 BuiltIn PointSize
+                              MemberDecorate 21(gl_PerVertex) 2 BuiltIn ClipDistance
+                              MemberDecorate 21(gl_PerVertex) 3 BuiltIn CullDistance
+                              Decorate 21(gl_PerVertex) Block
+                              Decorate 26(gl_Layer) BuiltIn Layer
+                              Decorate 26(gl_Layer) ViewportRelativeNV
+                              Decorate 26(gl_Layer) SecondaryViewportRelativeNV 2
+               2:             TypeVoid
+               3:             TypeFunction 2
+               6:             TypeInt 32 1
+               7:             TypeInt 32 0
+               8:      7(int) Constant 1
+               9:             TypeArray 6(int) 8
+              10:             TypePointer Output 9
+11(gl_SecondaryViewportMaskNV):     10(ptr) Variable Output
+              12:      6(int) Constant 0
+              13:      6(int) Constant 1
+              14:             TypePointer Output 6(int)
+              16:             TypeFloat 32
+              17:             TypeVector 16(float) 4
+              18:             TypePointer Output 17(fvec4)
+19(gl_SecondaryPositionNV):     18(ptr) Variable Output
+              20:             TypeArray 16(float) 8
+21(gl_PerVertex):             TypeStruct 17(fvec4) 16(float) 20 20
+              22:             TypePointer Output 21(gl_PerVertex)
+              23:     22(ptr) Variable Output
+    26(gl_Layer):     14(ptr) Variable Output
+         4(main):           2 Function None 3
+               5:             Label
+              15:     14(ptr) AccessChain 11(gl_SecondaryViewportMaskNV) 12
+                              Store 15 13
+              24:     18(ptr) AccessChain 23 12
+              25:   17(fvec4) Load 24
+                              Store 19(gl_SecondaryPositionNV) 25
+                              Return
+                              FunctionEnd
diff --git a/Test/baseResults/spv.viewportArray2.tesc.out b/Test/baseResults/spv.viewportArray2.tesc.out
new file mode 100644 (file)
index 0000000..6d73fc3
--- /dev/null
@@ -0,0 +1,59 @@
+spv.viewportArray2.tesc
+Warning, version 450 is not yet complete; most version-specific features are present, but some are missing.
+
+// Module Version 10000
+// Generated by (magic number): 80001
+// Id's are bound by 25
+
+                              Capability Geometry
+                              Capability Tessellation
+                              Capability MultiViewport
+                              Capability ShaderViewportIndexLayerNV
+                              Capability ShaderViewportMaskNV
+                              Extension  "SPV_NV_viewport_array2"
+               1:             ExtInstImport  "GLSL.std.450"
+                              MemoryModel Logical GLSL450
+                              EntryPoint TessellationControl 4  "main" 14 16
+                              ExecutionMode 4 OutputVertices 4
+                              Source GLSL 450
+                              SourceExtension  "GL_NV_viewport_array2"
+                              Name 4  "main"
+                              Name 10  "gl_PerVertex"
+                              MemberName 10(gl_PerVertex) 0  "gl_ViewportIndex"
+                              MemberName 10(gl_PerVertex) 1  "gl_Layer"
+                              MemberName 10(gl_PerVertex) 2  "gl_ViewportMask"
+                              Name 14  "gl_out"
+                              Name 16  "gl_InvocationID"
+                              MemberDecorate 10(gl_PerVertex) 0 BuiltIn ViewportIndex
+                              MemberDecorate 10(gl_PerVertex) 1 BuiltIn Layer
+                              MemberDecorate 10(gl_PerVertex) 1 ViewportRelativeNV
+                              MemberDecorate 10(gl_PerVertex) 2 BuiltIn ViewportMaskNV
+                              Decorate 10(gl_PerVertex) Block
+                              Decorate 16(gl_InvocationID) BuiltIn InvocationId
+               2:             TypeVoid
+               3:             TypeFunction 2
+               6:             TypeInt 32 1
+               7:             TypeInt 32 0
+               8:      7(int) Constant 2
+               9:             TypeArray 6(int) 8
+10(gl_PerVertex):             TypeStruct 6(int) 6(int) 9
+              11:      7(int) Constant 4
+              12:             TypeArray 10(gl_PerVertex) 11
+              13:             TypePointer Output 12
+      14(gl_out):     13(ptr) Variable Output
+              15:             TypePointer Input 6(int)
+16(gl_InvocationID):     15(ptr) Variable Input
+              18:      6(int) Constant 2
+              19:      6(int) Constant 0
+              20:      6(int) Constant 1
+              21:             TypePointer Output 6(int)
+         4(main):           2 Function None 3
+               5:             Label
+              17:      6(int) Load 16(gl_InvocationID)
+              22:     21(ptr) AccessChain 14(gl_out) 17 18 19
+                              Store 22 20
+              23:      6(int) Load 16(gl_InvocationID)
+              24:     21(ptr) AccessChain 14(gl_out) 23 19
+                              Store 24 18
+                              Return
+                              FunctionEnd
diff --git a/Test/baseResults/spv.viewportArray2.vert.out b/Test/baseResults/spv.viewportArray2.vert.out
new file mode 100644 (file)
index 0000000..766685f
--- /dev/null
@@ -0,0 +1,48 @@
+spv.viewportArray2.vert
+Warning, version 450 is not yet complete; most version-specific features are present, but some are missing.
+
+// Module Version 10000
+// Generated by (magic number): 80001
+// Id's are bound by 19
+
+                              Capability Shader
+                              Capability Geometry
+                              Capability MultiViewport
+                              Capability ShaderViewportIndexLayerNV
+                              Capability ShaderViewportMaskNV
+                              Extension  "SPV_NV_viewport_array2"
+               1:             ExtInstImport  "GLSL.std.450"
+                              MemoryModel Logical GLSL450
+                              EntryPoint Vertex 4  "main" 11 16 18
+                              Source GLSL 450
+                              SourceExtension  "GL_ARB_shader_viewport_layer_array"
+                              SourceExtension  "GL_NV_viewport_array2"
+                              Name 4  "main"
+                              Name 11  "gl_ViewportMask"
+                              Name 16  "gl_ViewportIndex"
+                              Name 18  "gl_Layer"
+                              Decorate 11(gl_ViewportMask) BuiltIn ViewportMaskNV
+                              Decorate 16(gl_ViewportIndex) BuiltIn ViewportIndex
+                              Decorate 18(gl_Layer) BuiltIn Layer
+                              Decorate 18(gl_Layer) ViewportRelativeNV
+               2:             TypeVoid
+               3:             TypeFunction 2
+               6:             TypeInt 32 1
+               7:             TypeInt 32 0
+               8:      7(int) Constant 1
+               9:             TypeArray 6(int) 8
+              10:             TypePointer Output 9
+11(gl_ViewportMask):     10(ptr) Variable Output
+              12:      6(int) Constant 0
+              13:      6(int) Constant 1
+              14:             TypePointer Output 6(int)
+16(gl_ViewportIndex):     14(ptr) Variable Output
+              17:      6(int) Constant 2
+    18(gl_Layer):     14(ptr) Variable Output
+         4(main):           2 Function None 3
+               5:             Label
+              15:     14(ptr) AccessChain 11(gl_ViewportMask) 12
+                              Store 15 13
+                              Store 16(gl_ViewportIndex) 17
+                              Return
+                              FunctionEnd
diff --git a/Test/spv.stereoViewRendering.tesc b/Test/spv.stereoViewRendering.tesc
new file mode 100644 (file)
index 0000000..62fc956
--- /dev/null
@@ -0,0 +1,18 @@
+#version 450\r
+\r
+#extension GL_NV_viewport_array2 :require\r
+#extension GL_NV_stereo_view_rendering : require\r
+\r
+layout(vertices = 4) out;\r
+\r
+out gl_PerVertex {\r
+    int gl_SecondaryViewportMaskNV[2];\r
+    vec4 gl_SecondaryPositionNV;\r
+    layout (viewport_relative, secondary_view_offset = 1) out highp int gl_Layer;\r
+} gl_out[4];\r
+\r
+void main()\r
+{\r
+    gl_out[gl_InvocationID].gl_SecondaryViewportMaskNV[0]            = 1;\r
+    gl_out[gl_InvocationID].gl_SecondaryPositionNV                   = gl_in[1].gl_Position;\r
+}\r
diff --git a/Test/spv.stereoViewRendering.vert b/Test/spv.stereoViewRendering.vert
new file mode 100644 (file)
index 0000000..fc7d52e
--- /dev/null
@@ -0,0 +1,12 @@
+#version 450\r
+\r
+#extension GL_NV_viewport_array2 :require\r
+#extension GL_NV_stereo_view_rendering : require\r
+\r
+layout (viewport_relative, secondary_view_offset = 2) out highp int gl_Layer;\r
+void main()\r
+{\r
+    gl_SecondaryViewportMaskNV[0] = 1;\r
+    gl_SecondaryPositionNV        = gl_Position;\r
+}\r
+\r
diff --git a/Test/spv.viewportArray2.tesc b/Test/spv.viewportArray2.tesc
new file mode 100644 (file)
index 0000000..f629b43
--- /dev/null
@@ -0,0 +1,16 @@
+#version 450\r
+#extension GL_NV_viewport_array2 :require\r
+\r
+layout(vertices = 4) out;\r
+\r
+out gl_PerVertex {\r
+    int gl_ViewportMask[2];\r
+    int gl_ViewportIndex;\r
+    layout (viewport_relative) out highp int gl_Layer;\r
+} gl_out[4];\r
+\r
+void main()\r
+{\r
+    gl_out[gl_InvocationID].gl_ViewportMask[0]                  = 1;\r
+    gl_out[gl_InvocationID].gl_ViewportIndex                    = 2;\r
+}\r
diff --git a/Test/spv.viewportArray2.vert b/Test/spv.viewportArray2.vert
new file mode 100644 (file)
index 0000000..a373d5e
--- /dev/null
@@ -0,0 +1,10 @@
+#version 450
+#extension GL_ARB_shader_viewport_layer_array : require
+#extension GL_NV_viewport_array2 : require
+
+layout (viewport_relative) out highp int gl_Layer;
+void main()
+{
+    gl_ViewportMask[0]            = 1;
+    gl_ViewportIndex              = 2;
+}
\ No newline at end of file
index f3648a64bde5e9dfc1344105963cf36c1fa0faef..449e3aeacf8ebd5155d40678ca2cadc8bbacffe2 100644 (file)
@@ -203,6 +203,11 @@ enum TBuiltInVariable {
     EbvBaryCoordPullModel,
 #endif
 
+#ifdef NV_EXTENSIONS
+    EbvViewportMaskNV,
+    EbvSecondaryPositionNV,
+    EbvSecondaryViewportMaskNV,
+#endif 
     // HLSL built-ins that live only temporarily, until they get remapped
     // to one of the above.
     EbvFragDepthGreater,
@@ -316,6 +321,11 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v)
     case EbvBaryCoordSmoothSample:      return "BaryCoordSmoothSample";
     case EbvBaryCoordPullModel:         return "BaryCoordPullModel";
 #endif
+#ifdef NV_EXTENSIONS
+    case EbvViewportMaskNV:             return "ViewportMaskNV";
+    case EbvSecondaryPositionNV:        return "SecondaryPositionNV";
+    case EbvSecondaryViewportMaskNV:    return "SecondaryViewportMaskNV";
+#endif 
     default:                      return "unknown built-in variable";
     }
 }
index f5a6e8f7de28b5a0061091269151b320ddcfec4d..6fce15ec3fafde8633e99628f4fcb997077a7a72 100644 (file)
@@ -601,6 +601,9 @@ public:
         layoutPushConstant = false;
 #ifdef NV_EXTENSIONS
         layoutPassthrough = false;
+        layoutViewportRelative = false;
+        // -2048 as the default vaule indicating layoutSecondaryViewportRelative is not set
+        layoutSecondaryViewportRelativeOffset = -2048;
 #endif
     }
     bool hasLayout() const
@@ -657,6 +660,8 @@ public:
 
 #ifdef NV_EXTENSIONS
     bool layoutPassthrough;
+    bool layoutViewportRelative;
+    int layoutSecondaryViewportRelativeOffset;
 #endif
 
     bool hasUniformLayout() const
@@ -1336,6 +1341,12 @@ public:
         case EbvPointSize:
         case EbvClipDistance:
         case EbvCullDistance:
+#ifdef NV_EXTENSIONS
+        case EbvLayer:
+        case EbvViewportMaskNV:
+        case EbvSecondaryPositionNV:
+        case EbvSecondaryViewportMaskNV:
+#endif
             return true;
         default:
             return false;
@@ -1604,6 +1615,10 @@ public:
 #ifdef NV_EXTENSIONS
                 if (qualifier.layoutPassthrough)
                     p += snprintf(p, end - p, "passthrough ");
+                if (qualifier.layoutViewportRelative)
+                    p += snprintf(p, end - p, "layoutViewportRelative ");
+                if (qualifier.layoutSecondaryViewportRelativeOffset != -2048)
+                    p += snprintf(p, end - p, "layoutSecondaryViewportRelativeOffset=%d ", qualifier.layoutSecondaryViewportRelativeOffset);
 #endif
 
                 p += snprintf(p, end - p, ") ");
index 6ea7b26b2f91ef983004cb4c75ab238fb1444b00..637ab29d4492108336b7e75f25e9ef21e9254e9a 100644 (file)
@@ -3240,6 +3240,18 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
                 "in int gl_DrawIDARB;"
                 );
         }
+
+#ifdef NV_EXTENSIONS
+        if (version >= 450)
+            stageBuiltins[EShLangVertex].append(
+                "out int gl_ViewportIndex;"
+                "out int gl_Layer;"
+                "out int gl_ViewportMask[];"
+                "out int gl_SecondaryViewportMaskNV[];"
+                "out vec4 gl_SecondaryPositionNV;"
+                );
+#endif
+
     } else {
         // ES profile
         if (version == 100) {
@@ -3299,6 +3311,9 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
         if (version >= 450)
             stageBuiltins[EShLangGeometry].append(
                 "float gl_CullDistance[];"
+#ifdef NV_EXTENSIONS
+                "vec4 gl_SecondaryPositionNV;"
+#endif
                 );
         stageBuiltins[EShLangGeometry].append(
             "} gl_in[];"
@@ -3343,6 +3358,16 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
             stageBuiltins[EShLangGeometry].append(
             "out int gl_ViewportIndex;"
             );
+
+#ifdef NV_EXTENSIONS
+        if (version >= 450)
+            stageBuiltins[EShLangGeometry].append(
+            "out int gl_ViewportMask[];"
+            "out int gl_SecondaryViewportMaskNV[];"
+            "out vec4 gl_SecondaryPositionNV;"
+            );
+#endif
+
         stageBuiltins[EShLangGeometry].append("\n");
     } else if (profile == EEsProfile && version >= 310) {
         stageBuiltins[EShLangGeometry].append(
@@ -3398,6 +3423,13 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
         if (version >= 450)
             stageBuiltins[EShLangTessControl].append(
                 "float gl_CullDistance[];"
+#ifdef NV_EXTENSIONS
+                "int gl_ViewportIndex;"
+                "int gl_Layer;"
+                "int gl_ViewportMask[];"
+                "vec4 gl_SecondaryPositionNV;"
+                "int gl_SecondaryViewportMaskNV[];"
+#endif
                 );
         stageBuiltins[EShLangTessControl].append(
             "} gl_out[];"
@@ -3467,6 +3499,18 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
         stageBuiltins[EShLangTessEvaluation].append(
             "};"
             "\n");
+
+#ifdef NV_EXTENSIONS
+        if (version >= 450)
+            stageBuiltins[EShLangTessEvaluation].append(
+                "out int gl_ViewportIndex;"
+                "out int gl_Layer;"
+                "out int gl_ViewportMask[];"
+                "out vec4 gl_SecondaryPositionNV;"
+                "out int gl_SecondaryViewportMaskNV[];"
+                );
+#endif
+
     } else if (profile == EEsProfile && version >= 310) {
         // Note:  "in gl_PerVertex {...} gl_in[gl_MaxPatchVertices];" is declared in initialize() below,
         // as it depends on the resource sizing of gl_MaxPatchVertices.
@@ -4400,6 +4444,9 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf
                     "in gl_PerVertex {"
                         "highp vec4 gl_Position;"
                         "highp float gl_PointSize;"
+#ifdef NV_EXTENSIONS
+                        "highp vec4 gl_SecondaryPositionNV;"
+#endif
                     "} gl_in[gl_MaxPatchVertices];"
                     "\n");
             }
@@ -4586,6 +4633,9 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf
                 if (profile != EEsProfile && version >= 450)
                     s.append(
                         "float gl_CullDistance[];"
+#ifdef NV_EXTENSIONS
+                        "vec4 gl_SecondaryPositionNV;"
+#endif
                        );
                 s.append(
                     "} gl_in[gl_MaxPatchVertices];"
@@ -4974,6 +5024,30 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
         BuiltInVariable("gl_InvocationID",    EbvInvocationId,   symbolTable);
         BuiltInVariable("gl_Layer",           EbvLayer,          symbolTable);
         BuiltInVariable("gl_ViewportIndex",   EbvViewportIndex,  symbolTable);
+
+#ifdef NV_EXTENSIONS
+        if (language != EShLangGeometry) {
+            symbolTable.setVariableExtensions("gl_Layer",         Num_viewportEXTs, viewportEXTs);
+            symbolTable.setVariableExtensions("gl_ViewportIndex", Num_viewportEXTs, viewportEXTs);
+        }
+        symbolTable.setVariableExtensions("gl_ViewportMask",            1, &E_GL_NV_viewport_array2);
+        symbolTable.setVariableExtensions("gl_SecondaryPositionNV",     1, &E_GL_NV_stereo_view_rendering);
+        symbolTable.setVariableExtensions("gl_SecondaryViewportMaskNV", 1, &E_GL_NV_stereo_view_rendering);
+
+        BuiltInVariable("gl_ViewportMask",              EbvViewportMaskNV,          symbolTable);
+        BuiltInVariable("gl_SecondaryPositionNV",       EbvSecondaryPositionNV,     symbolTable);
+        BuiltInVariable("gl_SecondaryViewportMaskNV",   EbvSecondaryViewportMaskNV, symbolTable);
+
+        if (language != EShLangVertex) 
+            BuiltInVariable("gl_in", "gl_SecondaryPositionNV", EbvSecondaryPositionNV, symbolTable);
+
+        BuiltInVariable("gl_out", "gl_Layer",                   EbvLayer,                   symbolTable);
+        BuiltInVariable("gl_out", "gl_ViewportIndex",           EbvViewportIndex,           symbolTable);
+        BuiltInVariable("gl_out", "gl_ViewportMask",            EbvViewportMaskNV,          symbolTable);
+        BuiltInVariable("gl_out", "gl_SecondaryPositionNV",     EbvSecondaryPositionNV,     symbolTable);
+        BuiltInVariable("gl_out", "gl_SecondaryViewportMaskNV", EbvSecondaryViewportMaskNV, symbolTable);
+#endif
+
         BuiltInVariable("gl_PatchVerticesIn", EbvPatchVertices,  symbolTable);
         BuiltInVariable("gl_TessLevelOuter",  EbvTessLevelOuter, symbolTable);
         BuiltInVariable("gl_TessLevelInner",  EbvTessLevelInner, symbolTable);
index 29c5c9feb954bb27c8da55232e398625546cf839..a560966af4607128152833bf10076d9f09fc0232 100644 (file)
@@ -3205,6 +3205,7 @@ TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TS
         (identifier == "gl_Color"               && language == EShLangFragment)                     ||
 #ifdef NV_EXTENSIONS
          identifier == "gl_SampleMask"                                                              ||
+         identifier == "gl_Layer"                                                                   ||
 #endif
          identifier == "gl_TexCoord") {
 
@@ -3291,6 +3292,12 @@ TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TS
             }
             intermediate.setLayoutOverrideCoverage();
         }
+        else if (identifier == "gl_Layer") {
+            if (!qualifier.layoutViewportRelative && qualifier.layoutSecondaryViewportRelativeOffset == -2048)
+                error(loc, "redeclaration only allowed for viewport_relative or secondary_view_offset layout", "redeclaration", symbol->getName().c_str());
+            symbolQualifier.layoutViewportRelative = qualifier.layoutViewportRelative;
+            symbolQualifier.layoutSecondaryViewportRelativeOffset = qualifier.layoutSecondaryViewportRelativeOffset;
+        }
 #endif
 
         // TODO: semantics quality: separate smooth from nothing declared, then use IsInterpolation for several tests above
@@ -3417,8 +3424,16 @@ void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newT
             oldType.getQualifier().flat = newType.getQualifier().flat;
             oldType.getQualifier().nopersp = newType.getQualifier().nopersp;
 
+#ifdef NV_EXTENSIONS
+            if (member->type->getFieldName() == "gl_Layer") {
+                if (!newType.getQualifier().layoutViewportRelative && newType.getQualifier().layoutSecondaryViewportRelativeOffset == -2048)
+                    error(loc, "redeclaration only allowed for viewport_relative or secondary_view_offset layout", "redeclaration", member->type->getFieldName().c_str());
+                oldType.getQualifier().layoutViewportRelative = newType.getQualifier().layoutViewportRelative;
+                oldType.getQualifier().layoutSecondaryViewportRelativeOffset = newType.getQualifier().layoutSecondaryViewportRelativeOffset;
+            }
             if (oldType.isImplicitlySizedArray() && newType.isExplicitlySizedArray())
                 oldType.changeOuterArraySize(newType.getOuterArraySize());
+#endif
 
             // go to next member
             ++member;
@@ -3943,8 +3958,18 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
             publicType.shaderQualifiers.layoutOverrideCoverage = true;
             return;
         }
-#endif
     }
+    if (language == EShLangVertex ||
+        language == EShLangTessControl ||
+        language == EShLangTessEvaluation ||
+        language == EShLangGeometry ) {
+        if (id == "viewport_relative") {
+            requireExtensions(loc, 1, &E_GL_NV_viewport_array2, "view port array2");
+            publicType.qualifier.layoutViewportRelative = true;
+            return;
+        }
+    }
+#endif
     error(loc, "unrecognized layout identifier, or qualifier requires assignment (e.g., binding = 4)", id.c_str(), "");
 }
 
@@ -4090,6 +4115,19 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
         return;
     }
 
+#if NV_EXTENSIONS
+    if (language == EShLangVertex ||
+        language == EShLangTessControl ||
+        language == EShLangTessEvaluation ||
+        language == EShLangGeometry) {
+        if (id == "secondary_view_offset") {
+            requireExtensions(loc, 1, &E_GL_NV_stereo_view_rendering, "stereo view rendering");
+            publicType.qualifier.layoutSecondaryViewportRelativeOffset = value;
+            return;
+        }
+    }
+#endif
+
     switch (language) {
     case EShLangVertex:
         break;
@@ -4253,6 +4291,10 @@ void TParseContext::mergeObjectLayoutQualifiers(TQualifier& dst, const TQualifie
 #ifdef NV_EXTENSIONS
         if (src.layoutPassthrough)
             dst.layoutPassthrough = true;
+        if (src.layoutViewportRelative)
+            dst.layoutViewportRelative = true;
+        if (src.layoutSecondaryViewportRelativeOffset != -2048)
+            dst.layoutSecondaryViewportRelativeOffset = src.layoutSecondaryViewportRelativeOffset;
 #endif
     }
 }
index 6a8c3450996664a93001c03b7c075123f91dfccc..9025e7612f43783c94265089b7f080a03d4be43d 100644 (file)
@@ -198,6 +198,9 @@ void TParseVersions::initializeExtensionBehavior()
 #ifdef NV_EXTENSIONS
     extensionBehavior[E_GL_NV_sample_mask_override_coverage]         = EBhDisable;
     extensionBehavior[E_SPV_NV_geometry_shader_passthrough]          = EBhDisable;
+    extensionBehavior[E_GL_ARB_shader_viewport_layer_array]          = EBhDisable;
+    extensionBehavior[E_GL_NV_viewport_array2]                       = EBhDisable;
+    extensionBehavior[E_GL_NV_stereo_view_rendering]                 = EBhDisable;
 #endif
 
     // AEP
@@ -311,6 +314,7 @@ void TParseVersions::getPreamble(std::string& preamble)
 #ifdef NV_EXTENSIONS
             "#define GL_NV_sample_mask_override_coverage 1\n"
             "#define GL_NV_geometry_shader_passthrough 1\n"
+            "#define GL_NV_viewport_array2 1\n"
 #endif
             ;
     }
index 2db06018d2dc985804b4e52d43f1ff74a48a177e..cf8f5e23dd38c86128d40a8c73db94201c9dc503 100644 (file)
@@ -143,8 +143,17 @@ const char* const E_GL_AMD_gcn_shader                           = "GL_AMD_gcn_sh
 const char* const E_GL_AMD_gpu_shader_half_float                = "GL_AMD_gpu_shader_half_float";
 #endif
 #ifdef NV_EXTENSIONS
-const char* const E_GL_NV_sample_mask_override_coverage = "GL_NV_sample_mask_override_coverage";
-const char* const E_SPV_NV_geometry_shader_passthrough = "GL_NV_geometry_shader_passthrough";
+
+const char* const E_GL_NV_sample_mask_override_coverage         = "GL_NV_sample_mask_override_coverage";
+const char* const E_SPV_NV_geometry_shader_passthrough          = "GL_NV_geometry_shader_passthrough";
+const char* const E_GL_ARB_shader_viewport_layer_array          = "GL_ARB_shader_viewport_layer_array";
+const char* const E_GL_NV_viewport_array2                       = "GL_NV_viewport_array2";
+const char* const E_GL_NV_stereo_view_rendering                 = "GL_NV_stereo_view_rendering";
+
+// Arrays of extensions for the above viewportEXTs duplications
+
+const char* const viewportEXTs[] = { E_GL_ARB_shader_viewport_layer_array, E_GL_NV_viewport_array2 };
+const int Num_viewportEXTs = sizeof(viewportEXTs) / sizeof(viewportEXTs[0]);
 #endif
 
 // AEP
index f317cdbb5ac738549c9070714b4d45433f4b89c7..fc0ba06a66deb0ae042ec281aba144981578989c 100644 (file)
@@ -71,6 +71,9 @@ using GlslIoMap = GlslangTest<::testing::TestWithParam<IoMapData>>;
 #ifdef AMD_EXTENSIONS
 using CompileVulkanToSpirvTestAMD = GlslangTest<::testing::TestWithParam<std::string>>;
 #endif
+#ifdef NV_EXTENSIONS
+using CompileVulkanToSpirvTestNV = GlslangTest<::testing::TestWithParam<std::string>>;
+#endif
 
 // Compiling GLSL to SPIR-V under Vulkan semantics. Expected to successfully
 // generate SPIR-V.
@@ -155,6 +158,17 @@ TEST_P(CompileVulkanToSpirvTestAMD, FromFile)
 }
 #endif
 
+#ifdef NV_EXTENSIONS
+// Compiling GLSL to SPIR-V under Vulkan semantics (AMD extensions enabled).
+// Expected to successfully generate SPIR-V.
+TEST_P(CompileVulkanToSpirvTestNV, FromFile)
+{
+    loadFileCompileAndCheck(GlobalTestSettings.testRoot, GetParam(),
+        Source::GLSL, Semantics::Vulkan,
+        Target::Spv);
+}
+#endif
+
 // clang-format off
 INSTANTIATE_TEST_CASE_P(
     Glsl, CompileVulkanToSpirvTest,
@@ -216,7 +230,6 @@ INSTANTIATE_TEST_CASE_P(
         "spv.forwardFun.frag",
         "spv.functionCall.frag",
         "spv.functionSemantics.frag",
-        "spv.GeometryShaderPassthrough.geom",
         "spv.interpOps.frag",
         "spv.int64.frag",
         "spv.layoutNested.vert",
@@ -241,7 +254,6 @@ INSTANTIATE_TEST_CASE_P(
         "spv.precision.frag",
         "spv.prepost.frag",
         "spv.qualifiers.vert",
-        "spv.sampleMaskOverrideCoverage.frag",
         "spv.shaderBallot.comp",
         "spv.shaderDrawParams.vert",
         "spv.shaderGroupVote.comp",
@@ -363,6 +375,21 @@ INSTANTIATE_TEST_CASE_P(
     FileNameAsCustomTestSuffix
 );
 #endif
+
+#ifdef NV_EXTENSIONS
+INSTANTIATE_TEST_CASE_P(
+    Glsl, CompileVulkanToSpirvTestNV,
+    ::testing::ValuesIn(std::vector<std::string>({
+    "spv.sampleMaskOverrideCoverage.frag",
+    "spv.GeometryShaderPassthrough.geom",
+    "spv.viewportArray2.vert",
+    "spv.viewportArray2.tesc",
+    "spv.stereoViewRendering.vert",
+    "spv.stereoViewRendering.tesc",
+})),
+FileNameAsCustomTestSuffix
+);
+#endif
 // clang-format on
 
 }  // anonymous namespace