From 771d89fc3607c19ba883009b9ff4d4e4ff2858c5 Mon Sep 17 00:00:00 2001 From: chaoc Date: Fri, 13 Jan 2017 01:10:53 -0800 Subject: [PATCH] support SPV_NV_viewport_array2 and SPV_NV_stereo_view_rendering --- SPIRV/GLSL.ext.NV.h | 33 ++++++- SPIRV/GlslangToSpv.cpp | 80 ++++++++++++++++- SPIRV/disassemble.cpp | 22 +++-- SPIRV/doc.cpp | 10 +++ Test/baseResults/310.tesc.out | 20 ++--- Test/baseResults/310.tese.out | 16 ++-- .../spv.stereoViewRendering.tesc.out | 86 +++++++++++++++++++ .../spv.stereoViewRendering.vert.out | 69 +++++++++++++++ Test/baseResults/spv.viewportArray2.tesc.out | 59 +++++++++++++ Test/baseResults/spv.viewportArray2.vert.out | 48 +++++++++++ Test/spv.stereoViewRendering.tesc | 18 ++++ Test/spv.stereoViewRendering.vert | 12 +++ Test/spv.viewportArray2.tesc | 16 ++++ Test/spv.viewportArray2.vert | 10 +++ glslang/Include/BaseTypes.h | 10 +++ glslang/Include/Types.h | 15 ++++ glslang/MachineIndependent/Initialize.cpp | 74 ++++++++++++++++ glslang/MachineIndependent/ParseHelper.cpp | 44 +++++++++- glslang/MachineIndependent/Versions.cpp | 4 + glslang/MachineIndependent/Versions.h | 13 ++- gtests/Spv.FromFile.cpp | 31 ++++++- 21 files changed, 654 insertions(+), 36 deletions(-) create mode 100644 Test/baseResults/spv.stereoViewRendering.tesc.out create mode 100644 Test/baseResults/spv.stereoViewRendering.vert.out create mode 100644 Test/baseResults/spv.viewportArray2.tesc.out create mode 100644 Test/baseResults/spv.viewportArray2.vert.out create mode 100644 Test/spv.stereoViewRendering.tesc create mode 100644 Test/spv.stereoViewRendering.vert create mode 100644 Test/spv.viewportArray2.tesc create mode 100644 Test/spv.viewportArray2.vert diff --git a/SPIRV/GLSL.ext.NV.h b/SPIRV/GLSL.ext.NV.h index adfcb0f34..89f0a5c03 100644 --- a/SPIRV/GLSL.ext.NV.h +++ b/SPIRV/GLSL.ext.NV.h @@ -30,20 +30,45 @@ 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(5248); +static const Decoration DecorationOverrideCoverageNV = static_cast(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(5250); +static const Decoration DecorationPassthroughNV = static_cast(5250); + +static const Capability CapabilityGeometryShaderPassthroughNV = static_cast(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(5252); + +static const BuiltIn BuiltInViewportMaskNV = static_cast(5253); + +static const Capability CapabilityShaderViewportIndexLayerNV = static_cast(5254); +static const Capability CapabilityShaderViewportMaskNV = static_cast(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(5256); + +static const BuiltIn BuiltInSecondaryPositionNV = static_cast(5257); +static const BuiltIn BuiltInSecondaryViewportMaskNV = static_cast(5258); + +static const Capability CapabilityShaderStereoViewNV = static_cast(5259); -static const Capability GeometryShaderPassthroughNV = static_cast(5251); #endif // #ifndef GLSLextNV_H \ No newline at end of file diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp index 81243f9f9..f83d82fe8 100755 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -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 diff --git a/SPIRV/disassemble.cpp b/SPIRV/disassemble.cpp index a8049b876..74ae40767 100644 --- a/SPIRV/disassemble.cpp +++ b/SPIRV/disassemble.cpp @@ -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"; diff --git a/SPIRV/doc.cpp b/SPIRV/doc.cpp index 0bb9e0177..871809978 100755 --- a/SPIRV/doc.cpp +++ b/SPIRV/doc.cpp @@ -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 } diff --git a/Test/baseResults/310.tesc.out b/Test/baseResults/310.tesc.out index ab27198f6..d004fa166 100644 --- a/Test/baseResults/310.tesc.out +++ b/Test/baseResults/310.tesc.out @@ -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: diff --git a/Test/baseResults/310.tese.out b/Test/baseResults/310.tese.out index 62894ec79..c6ce6650b 100644 --- a/Test/baseResults/310.tese.out +++ b/Test/baseResults/310.tese.out @@ -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 index 000000000..c8f9642c1 --- /dev/null +++ b/Test/baseResults/spv.stereoViewRendering.tesc.out @@ -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 index 000000000..d6c695601 --- /dev/null +++ b/Test/baseResults/spv.stereoViewRendering.vert.out @@ -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 index 000000000..6d73fc399 --- /dev/null +++ b/Test/baseResults/spv.viewportArray2.tesc.out @@ -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 index 000000000..766685f69 --- /dev/null +++ b/Test/baseResults/spv.viewportArray2.vert.out @@ -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 index 000000000..62fc956be --- /dev/null +++ b/Test/spv.stereoViewRendering.tesc @@ -0,0 +1,18 @@ +#version 450 + +#extension GL_NV_viewport_array2 :require +#extension GL_NV_stereo_view_rendering : require + +layout(vertices = 4) out; + +out gl_PerVertex { + int gl_SecondaryViewportMaskNV[2]; + vec4 gl_SecondaryPositionNV; + layout (viewport_relative, secondary_view_offset = 1) out highp int gl_Layer; +} gl_out[4]; + +void main() +{ + gl_out[gl_InvocationID].gl_SecondaryViewportMaskNV[0] = 1; + gl_out[gl_InvocationID].gl_SecondaryPositionNV = gl_in[1].gl_Position; +} diff --git a/Test/spv.stereoViewRendering.vert b/Test/spv.stereoViewRendering.vert new file mode 100644 index 000000000..fc7d52e24 --- /dev/null +++ b/Test/spv.stereoViewRendering.vert @@ -0,0 +1,12 @@ +#version 450 + +#extension GL_NV_viewport_array2 :require +#extension GL_NV_stereo_view_rendering : require + +layout (viewport_relative, secondary_view_offset = 2) out highp int gl_Layer; +void main() +{ + gl_SecondaryViewportMaskNV[0] = 1; + gl_SecondaryPositionNV = gl_Position; +} + diff --git a/Test/spv.viewportArray2.tesc b/Test/spv.viewportArray2.tesc new file mode 100644 index 000000000..f629b438c --- /dev/null +++ b/Test/spv.viewportArray2.tesc @@ -0,0 +1,16 @@ +#version 450 +#extension GL_NV_viewport_array2 :require + +layout(vertices = 4) out; + +out gl_PerVertex { + int gl_ViewportMask[2]; + int gl_ViewportIndex; + layout (viewport_relative) out highp int gl_Layer; +} gl_out[4]; + +void main() +{ + gl_out[gl_InvocationID].gl_ViewportMask[0] = 1; + gl_out[gl_InvocationID].gl_ViewportIndex = 2; +} diff --git a/Test/spv.viewportArray2.vert b/Test/spv.viewportArray2.vert new file mode 100644 index 000000000..a373d5e89 --- /dev/null +++ b/Test/spv.viewportArray2.vert @@ -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 diff --git a/glslang/Include/BaseTypes.h b/glslang/Include/BaseTypes.h index f3648a64b..449e3aeac 100644 --- a/glslang/Include/BaseTypes.h +++ b/glslang/Include/BaseTypes.h @@ -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"; } } diff --git a/glslang/Include/Types.h b/glslang/Include/Types.h index f5a6e8f7d..6fce15ec3 100644 --- a/glslang/Include/Types.h +++ b/glslang/Include/Types.h @@ -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, ") "); diff --git a/glslang/MachineIndependent/Initialize.cpp b/glslang/MachineIndependent/Initialize.cpp index 6ea7b26b2..637ab29d4 100644 --- a/glslang/MachineIndependent/Initialize.cpp +++ b/glslang/MachineIndependent/Initialize.cpp @@ -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); diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index 29c5c9feb..a560966af 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -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 } } diff --git a/glslang/MachineIndependent/Versions.cpp b/glslang/MachineIndependent/Versions.cpp index 6a8c34509..9025e7612 100644 --- a/glslang/MachineIndependent/Versions.cpp +++ b/glslang/MachineIndependent/Versions.cpp @@ -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 ; } diff --git a/glslang/MachineIndependent/Versions.h b/glslang/MachineIndependent/Versions.h index 2db06018d..cf8f5e23d 100644 --- a/glslang/MachineIndependent/Versions.h +++ b/glslang/MachineIndependent/Versions.h @@ -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 diff --git a/gtests/Spv.FromFile.cpp b/gtests/Spv.FromFile.cpp index f317cdbb5..fc0ba06a6 100644 --- a/gtests/Spv.FromFile.cpp +++ b/gtests/Spv.FromFile.cpp @@ -71,6 +71,9 @@ using GlslIoMap = GlslangTest<::testing::TestWithParam>; #ifdef AMD_EXTENSIONS using CompileVulkanToSpirvTestAMD = GlslangTest<::testing::TestWithParam>; #endif +#ifdef NV_EXTENSIONS +using CompileVulkanToSpirvTestNV = GlslangTest<::testing::TestWithParam>; +#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({ + "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