Add support for es extension GL_EXT_blend_func_extended
authorPankaj Mistry <pmistry@nvidia.com>
Tue, 21 Apr 2020 18:33:57 +0000 (11:33 -0700)
committerPankaj Mistry <pmistry@nvidia.com>
Fri, 1 May 2020 06:21:14 +0000 (23:21 -0700)
* Introduces builtin variables gl_SecondaryFragColorEXT and gl_SecondaryFragDataEXT
* Introduces builtin constant gl_MaxDualSourceDrawBuffersEXT
* enables support for layout qualifier "index" in es profile

14 files changed:
StandAlone/ResourceLimits.cpp
Test/100.frag
Test/300.frag
Test/baseResults/100.frag.out
Test/baseResults/300.frag.out
Test/baseResults/test.conf
glslang/Include/BaseTypes.h
glslang/Include/ResourceLimits.h
glslang/Include/glslang_c_interface.h
glslang/MachineIndependent/Initialize.cpp
glslang/MachineIndependent/ParseHelper.cpp
glslang/MachineIndependent/Versions.cpp
glslang/MachineIndependent/Versions.h
glslang/OSDependent/Web/glslang.js.cpp

index 028caa6..7c7f4c4 100644 (file)
@@ -134,6 +134,7 @@ const TBuiltInResource DefaultTBuiltInResource = {
     /* .maxTaskWorkGroupSizeY_NV = */ 1,
     /* .maxTaskWorkGroupSizeZ_NV = */ 1,
     /* .maxMeshViewCountNV = */ 4,
+    /* .maxDualSourceDrawBuffersEXT = */ 1,
 
     /* .limits = */ {
         /* .nonInductiveForLoops = */ 1,
@@ -243,6 +244,7 @@ std::string GetDefaultTBuiltInResourceString()
             << "MaxTaskWorkGroupSizeY_NV "                  << DefaultTBuiltInResource.maxTaskWorkGroupSizeY_NV << "\n"
             << "MaxTaskWorkGroupSizeZ_NV "                  << DefaultTBuiltInResource.maxTaskWorkGroupSizeZ_NV << "\n"
             << "MaxMeshViewCountNV "                        << DefaultTBuiltInResource.maxMeshViewCountNV << "\n"
+            << "MaxDualSourceDrawBuffersEXT "               << DefaultTBuiltInResource.maxDualSourceDrawBuffersEXT << "\n"
             << "nonInductiveForLoops "                      << DefaultTBuiltInResource.limits.nonInductiveForLoops << "\n"
             << "whileLoops "                                << DefaultTBuiltInResource.limits.whileLoops << "\n"
             << "doWhileLoops "                              << DefaultTBuiltInResource.limits.doWhileLoops << "\n"
index 0508ea9..439fc6c 100644 (file)
@@ -201,6 +201,19 @@ float fooinittest()
     return fooinit();\r
 }\r
 \r
+// Test extension GL_EXT_blend_func_extended\r
+void blendFuncFail() // Error since extension GL_EXT_blend_func_extended is disabled\r
+{\r
+    gl_SecondaryFragColorEXT = vec4(1.0);   \r
+    gl_SecondaryFragDataEXT[gl_MaxDualSourceDrawBuffersEXT - 1] = vec4(0.1);\r
+}\r
+#extension GL_EXT_blend_func_extended : enable\r
+void blendFunc() \r
+{\r
+    gl_SecondaryFragColorEXT = vec4(1.0);\r
+    gl_SecondaryFragDataEXT[gl_MaxDualSourceDrawBuffersEXT - 1] = vec4(0.1);\r
+}\r
+\r
 // Test extra-function initializers\r
 const float fi1 = 3.0;\r
 const float fi2 = 4.0;\r
index ab45c6d..279864a 100644 (file)
@@ -177,6 +177,11 @@ void testmixFail()
     int ival  = mix(x, y, b); // Error since extenson GL_EXT_shader_integer_mix is disabled
 }
 
+// Test layout qualifier "index" with extension GL_EXT_blend_func_extended
+layout(location = 0, index = 1) out vec4 outVarFail; // Error Index supported with extension GL_EXT_blend_func_extended enabled
+#extension GL_EXT_blend_func_extended : enable
+layout(location = 0, index = 2) out vec4 outVarPass;
+
 #ifndef GL_FRAGMENT_PRECISION_HIGH
 #error missing GL_FRAGMENT_PRECISION_HIGH
 #endif
index 8dd31e3..2ac6054 100644 (file)
@@ -82,15 +82,19 @@ ERROR: 0:192: '.' : cannot apply to an array: nothing
 ERROR: 0:193: '.length' : not supported for this version or the enabled extensions 
 ERROR: 0:194: '.' : cannot apply to an array: method
 ERROR: 0:194: 'a' : can't use function syntax on variable 
-ERROR: 0:214: 'non-constant global initializer (needs GL_EXT_shader_non_constant_global_initializers)' : not supported for this version or the enabled extensions 
-ERROR: 0:222: '#define' : names containing consecutive underscores are reserved, and an error if version < 300: A__B
-ERROR: 0:223: 'a__b' : identifiers containing consecutive underscores ("__") are reserved, and an error if version < 300 
+ERROR: 0:207: 'gl_SecondaryFragColorEXT' : required extension not requested: GL_EXT_blend_func_extended
+ERROR: 0:208: 'gl_SecondaryFragDataEXT' : required extension not requested: GL_EXT_blend_func_extended
+ERROR: 0:208: 'gl_MaxDualSourceDrawBuffersEXT' : required extension not requested: GL_EXT_blend_func_extended
+ERROR: 0:227: 'non-constant global initializer (needs GL_EXT_shader_non_constant_global_initializers)' : not supported for this version or the enabled extensions 
+ERROR: 0:235: '#define' : names containing consecutive underscores are reserved, and an error if version < 300: A__B
+ERROR: 0:236: 'a__b' : identifiers containing consecutive underscores ("__") are reserved, and an error if version < 300 
 ERROR: 0:3000: '#error' : line of this error should be 3000  
 ERROR: 0:3002: '' :  syntax error, unexpected IDENTIFIER, expecting LEFT_BRACE or COMMA or SEMICOLON
-ERROR: 79 compilation errors.  No code generated.
+ERROR: 82 compilation errors.  No code generated.
 
 
 Shader version: 100
+Requested GL_EXT_blend_func_extended
 Requested GL_EXT_frag_depth
 Requested GL_EXT_shader_non_constant_global_initializers
 Requested GL_EXT_shader_texture_lod
@@ -361,36 +365,76 @@ ERROR: node is still EOpNull!
 0:201    Sequence
 0:201      Branch: Return with expression
 0:201        Function Call: fooinit( ( global mediump float)
-0:209  Function Definition: fooinit( ( global mediump float)
-0:209    Function Parameters: 
-0:211    Sequence
-0:211      Branch: Return with expression
-0:211        Constant:
-0:211          12.000000
-0:214  Sequence
-0:214    move second child to first child ( temp mediump int)
-0:214      'init1' ( global mediump int)
-0:214      Test condition and select ( temp mediump int)
-0:214        Condition
-0:214        'gl_FrontFacing' ( gl_FrontFacing bool Face)
-0:214        true case
+0:205  Function Definition: blendFuncFail( ( global void)
+0:205    Function Parameters: 
+0:207    Sequence
+0:207      move second child to first child ( temp mediump 4-component vector of float)
+0:207        'gl_SecondaryFragColorEXT' ( out mediump 4-component vector of float SecondaryFragColorEXT)
+0:207        Constant:
+0:207          1.000000
+0:207          1.000000
+0:207          1.000000
+0:207          1.000000
+0:208      move second child to first child ( temp mediump 4-component vector of float)
+0:208        direct index ( temp mediump 4-component vector of float SecondaryFragDataEXT)
+0:208          'gl_SecondaryFragDataEXT' ( out 1-element array of mediump 4-component vector of float SecondaryFragDataEXT)
+0:208          Constant:
+0:208            0 (const int)
+0:208        Constant:
+0:208          0.100000
+0:208          0.100000
+0:208          0.100000
+0:208          0.100000
+0:211  Function Definition: blendFunc( ( global void)
+0:211    Function Parameters: 
+0:213    Sequence
+0:213      move second child to first child ( temp mediump 4-component vector of float)
+0:213        'gl_SecondaryFragColorEXT' ( out mediump 4-component vector of float SecondaryFragColorEXT)
+0:213        Constant:
+0:213          1.000000
+0:213          1.000000
+0:213          1.000000
+0:213          1.000000
+0:214      move second child to first child ( temp mediump 4-component vector of float)
+0:214        direct index ( temp mediump 4-component vector of float SecondaryFragDataEXT)
+0:214          'gl_SecondaryFragDataEXT' ( out 1-element array of mediump 4-component vector of float SecondaryFragDataEXT)
+0:214          Constant:
+0:214            0 (const int)
 0:214        Constant:
-0:214          1 (const int)
-0:214        false case
-0:214        Constant:
-0:214          2 (const int)
-0:220  Sequence
-0:220    move second child to first child ( temp mediump int)
-0:220      'init2' ( global mediump int)
-0:220      Test condition and select ( temp mediump int)
-0:220        Condition
-0:220        'gl_FrontFacing' ( gl_FrontFacing bool Face)
-0:220        true case
-0:220        Constant:
-0:220          1 (const int)
-0:220        false case
-0:220        Constant:
-0:220          2 (const int)
+0:214          0.100000
+0:214          0.100000
+0:214          0.100000
+0:214          0.100000
+0:222  Function Definition: fooinit( ( global mediump float)
+0:222    Function Parameters: 
+0:224    Sequence
+0:224      Branch: Return with expression
+0:224        Constant:
+0:224          12.000000
+0:227  Sequence
+0:227    move second child to first child ( temp mediump int)
+0:227      'init1' ( global mediump int)
+0:227      Test condition and select ( temp mediump int)
+0:227        Condition
+0:227        'gl_FrontFacing' ( gl_FrontFacing bool Face)
+0:227        true case
+0:227        Constant:
+0:227          1 (const int)
+0:227        false case
+0:227        Constant:
+0:227          2 (const int)
+0:233  Sequence
+0:233    move second child to first child ( temp mediump int)
+0:233      'init2' ( global mediump int)
+0:233      Test condition and select ( temp mediump int)
+0:233        Condition
+0:233        'gl_FrontFacing' ( gl_FrontFacing bool Face)
+0:233        true case
+0:233        Constant:
+0:233          1 (const int)
+0:233        false case
+0:233        Constant:
+0:233          2 (const int)
 0:?   Linker Objects
 0:?     'a' ( global 3-element array of mediump int)
 0:?     'uint' ( global mediump int)
@@ -430,6 +474,7 @@ Linked fragment stage:
 
 
 Shader version: 100
+Requested GL_EXT_blend_func_extended
 Requested GL_EXT_frag_depth
 Requested GL_EXT_shader_non_constant_global_initializers
 Requested GL_EXT_shader_texture_lod
@@ -520,30 +565,30 @@ ERROR: node is still EOpNull!
 0:152      'f124' ( global mediump float)
 0:152      Constant:
 0:152        50000000000.000000
-0:214  Sequence
-0:214    move second child to first child ( temp mediump int)
-0:214      'init1' ( global mediump int)
-0:214      Test condition and select ( temp mediump int)
-0:214        Condition
-0:214        'gl_FrontFacing' ( gl_FrontFacing bool Face)
-0:214        true case
-0:214        Constant:
-0:214          1 (const int)
-0:214        false case
-0:214        Constant:
-0:214          2 (const int)
-0:220  Sequence
-0:220    move second child to first child ( temp mediump int)
-0:220      'init2' ( global mediump int)
-0:220      Test condition and select ( temp mediump int)
-0:220        Condition
-0:220        'gl_FrontFacing' ( gl_FrontFacing bool Face)
-0:220        true case
-0:220        Constant:
-0:220          1 (const int)
-0:220        false case
-0:220        Constant:
-0:220          2 (const int)
+0:227  Sequence
+0:227    move second child to first child ( temp mediump int)
+0:227      'init1' ( global mediump int)
+0:227      Test condition and select ( temp mediump int)
+0:227        Condition
+0:227        'gl_FrontFacing' ( gl_FrontFacing bool Face)
+0:227        true case
+0:227        Constant:
+0:227          1 (const int)
+0:227        false case
+0:227        Constant:
+0:227          2 (const int)
+0:233  Sequence
+0:233    move second child to first child ( temp mediump int)
+0:233      'init2' ( global mediump int)
+0:233      Test condition and select ( temp mediump int)
+0:233        Condition
+0:233        'gl_FrontFacing' ( gl_FrontFacing bool Face)
+0:233        true case
+0:233        Constant:
+0:233          1 (const int)
+0:233        false case
+0:233        Constant:
+0:233          2 (const int)
 0:?   Linker Objects
 0:?     'a' ( global 3-element array of mediump int)
 0:?     'uint' ( global mediump int)
index 0b88aa3..50a6b07 100644 (file)
@@ -41,15 +41,18 @@ ERROR: 0:129: 'texel offset' : value is out of range: [gl_MinProgramTexelOffset,
 ERROR: 0:148: 'qualifier' : cannot use auxiliary, memory, interpolation, or precision qualifier in a default qualifier declaration (declaration with no type) 
 ERROR: 0:150: 'early_fragment_tests' : not supported for this version or the enabled extensions 
 ERROR: 0:177: 'specific signature of builtin mix' : required extension not requested: GL_EXT_shader_integer_mix
-ERROR: 0:184: 'invariant' : can only apply to an output 
-ERROR: 0:185: 'invariant' : can only apply to an output 
-ERROR: 0:186: 'invariant' : can only apply to an output 
-ERROR: 0:188: 'imageBuffer' : Reserved word. 
-ERROR: 0:188: '' :  syntax error, unexpected IMAGEBUFFER, expecting COMMA or SEMICOLON
-ERROR: 47 compilation errors.  No code generated.
+ERROR: 0:181: 'index layout qualifier on fragment output' : not supported for this version or the enabled extensions 
+ERROR: 0:183: 'index' : value must be 0 or 1 
+ERROR: 0:189: 'invariant' : can only apply to an output 
+ERROR: 0:190: 'invariant' : can only apply to an output 
+ERROR: 0:191: 'invariant' : can only apply to an output 
+ERROR: 0:193: 'imageBuffer' : Reserved word. 
+ERROR: 0:193: '' :  syntax error, unexpected IMAGEBUFFER, expecting COMMA or SEMICOLON
+ERROR: 49 compilation errors.  No code generated.
 
 
 Shader version: 300
+Requested GL_EXT_blend_func_extended
 Requested GL_EXT_shader_integer_mix
 using early_fragment_tests
 ERROR: node is still EOpNull!
@@ -530,6 +533,8 @@ ERROR: node is still EOpNull!
 0:?     'y' ( global mediump int)
 0:?     'z' ( global mediump uint)
 0:?     'w' ( global mediump uint)
+0:?     'outVarFail' (layout( location=0 index=1) out lowp 4-component vector of float)
+0:?     'outVarPass' (layout( location=0 index=0) out lowp 4-component vector of float)
 0:?     'fooinv' ( invariant smooth in lowp 4-component vector of float)
 
 
@@ -538,6 +543,7 @@ Linked fragment stage:
 ERROR: Linking fragment stage: when more than one fragment shader output, all must have location qualifiers
 
 Shader version: 300
+Requested GL_EXT_blend_func_extended
 Requested GL_EXT_shader_integer_mix
 using early_fragment_tests
 ERROR: node is still EOpNull!
@@ -769,5 +775,7 @@ ERROR: node is still EOpNull!
 0:?     'y' ( global mediump int)
 0:?     'z' ( global mediump uint)
 0:?     'w' ( global mediump uint)
+0:?     'outVarFail' (layout( location=0 index=1) out lowp 4-component vector of float)
+0:?     'outVarPass' (layout( location=0 index=0) out lowp 4-component vector of float)
 0:?     'fooinv' ( invariant smooth in lowp 4-component vector of float)
 
index cff7716..98b2a84 100644 (file)
@@ -90,6 +90,7 @@ MaxTaskWorkGroupSizeX_NV 32
 MaxTaskWorkGroupSizeY_NV 1
 MaxTaskWorkGroupSizeZ_NV 1
 MaxMeshViewCountNV 4
+MaxDualSourceDrawBuffersEXT 1
 nonInductiveForLoops 1
 whileLoops 1
 doWhileLoops 1
index 816b179..b69eaeb 100644 (file)
@@ -231,6 +231,9 @@ enum TBuiltInVariable {
     EbvFragSizeEXT,
     EbvFragInvocationCountEXT,
 
+    EbvSecondaryFragDataEXT,
+    EbvSecondaryFragColorEXT,
+
     EbvViewportMaskNV,
     EbvSecondaryPositionNV,
     EbvSecondaryViewportMaskNV,
@@ -433,6 +436,9 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v)
     case EbvFragSizeEXT:                return "FragSizeEXT";
     case EbvFragInvocationCountEXT:     return "FragInvocationCountEXT";
 
+    case EbvSecondaryFragDataEXT:       return "SecondaryFragDataEXT";
+    case EbvSecondaryFragColorEXT:      return "SecondaryFragColorEXT";
+
     case EbvViewportMaskNV:             return "ViewportMaskNV";
     case EbvSecondaryPositionNV:        return "SecondaryPositionNV";
     case EbvSecondaryViewportMaskNV:    return "SecondaryViewportMaskNV";
index 106b21d..b670cf1 100644 (file)
@@ -142,6 +142,7 @@ struct TBuiltInResource {
     int maxTaskWorkGroupSizeY_NV;
     int maxTaskWorkGroupSizeZ_NV;
     int maxMeshViewCountNV;
+    int maxDualSourceDrawBuffersEXT;
 
     TLimits limits;
 };
index 5a450e0..50e95b7 100644 (file)
@@ -148,6 +148,7 @@ typedef struct glslang_resource_s {
     int max_task_work_group_size_y_nv;
     int max_task_work_group_size_z_nv;
     int max_mesh_view_count_nv;
+    int maxDualSourceDrawBuffersEXT;
 
     glslang_limits_t limits;
 } glslang_resource_t;
index 5410f82..36c35a8 100644 (file)
@@ -6755,6 +6755,18 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf
             s.append(builtInConstant);
         }
 
+        if (version >= 100) {
+            // GL_EXT_blend_func_extended
+            snprintf(builtInConstant, maxSize, "const mediump int gl_MaxDualSourceDrawBuffersEXT = %d;", resources.maxDualSourceDrawBuffersEXT);
+            s.append(builtInConstant);
+            // this is here instead of with the others in initialize(version, profile) due to the dependence on gl_MaxDualSourceDrawBuffersEXT
+            if (language == EShLangFragment) {
+                s.append(
+                    "mediump vec4 gl_SecondaryFragColorEXT;"
+                    "mediump vec4 gl_SecondaryFragDataEXT[gl_MaxDualSourceDrawBuffersEXT];"
+                    "\n");
+            }
+        }
     } else {
         // non-ES profile
 
@@ -9119,6 +9131,16 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
             symbolTable.insert(*new TVariable(NewPoolTString("gl_FragData"), fragData));
             SpecialQualifier("gl_FragData", EvqFragColor, EbvFragData, symbolTable);
         }
+
+        // GL_EXT_blend_func_extended
+        if (profile == EEsProfile && version >= 100) {
+           symbolTable.setVariableExtensions("gl_MaxDualSourceDrawBuffersEXT",    1, &E_GL_EXT_blend_func_extended);
+           symbolTable.setVariableExtensions("gl_SecondaryFragColorEXT",    1, &E_GL_EXT_blend_func_extended);
+           symbolTable.setVariableExtensions("gl_SecondaryFragDataEXT",    1, &E_GL_EXT_blend_func_extended);
+           SpecialQualifier("gl_SecondaryFragColorEXT", EvqVaryingOut, EbvSecondaryFragColorEXT, symbolTable);
+           SpecialQualifier("gl_SecondaryFragDataEXT", EvqVaryingOut, EbvSecondaryFragDataEXT, symbolTable);
+        }
+
         break;
 
     case EShLangTessControl:
index 137cb5e..8bc7814 100644 (file)
@@ -5412,10 +5412,10 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
 
     case EShLangFragment:
         if (id == "index") {
-            requireProfile(loc, ECompatibilityProfile | ECoreProfile, "index layout qualifier on fragment output");
+            requireProfile(loc, ECompatibilityProfile | ECoreProfile | EEsProfile, "index layout qualifier on fragment output");
             const char* exts[2] = { E_GL_ARB_separate_shader_objects, E_GL_ARB_explicit_attrib_location };
             profileRequires(loc, ECompatibilityProfile | ECoreProfile, 330, 2, exts, "index layout qualifier on fragment output");
-
+            profileRequires(loc, EEsProfile ,310, E_GL_EXT_blend_func_extended, "index layout qualifier on fragment output");
             // "It is also a compile-time error if a fragment shader sets a layout index to less than 0 or greater than 1."
             if (value < 0 || value > 1) {
                 value = 0;
index 82ccabc..30313b2 100644 (file)
@@ -306,6 +306,7 @@ void TParseVersions::initializeExtensionBehavior()
     extensionBehavior[E_GL_EXT_ray_tracing]                 = EBhDisable;
     extensionBehavior[E_GL_EXT_ray_query]                   = EBhDisable;
     extensionBehavior[E_GL_EXT_ray_flags_primitive_culling] = EBhDisable;
+    extensionBehavior[E_GL_EXT_blend_func_extended]         = EBhDisable;
 
     // OVR extensions
     extensionBehavior[E_GL_OVR_multiview]                = EBhDisable;
@@ -365,6 +366,7 @@ void TParseVersions::getPreamble(std::string& preamble)
             "#define GL_EXT_texture_buffer 1\n"
             "#define GL_EXT_texture_cube_map_array 1\n"
             "#define GL_EXT_shader_integer_mix 1\n"
+            "#define GL_EXT_blend_func_extended 1\n"
 
             // OES matching AEP
             "#define GL_OES_geometry_shader 1\n"
index 7a9e673..cde6c23 100644 (file)
@@ -196,6 +196,7 @@ const char* const E_GL_EXT_debug_printf                     = "GL_EXT_debug_prin
 const char* const E_GL_EXT_ray_tracing                      = "GL_EXT_ray_tracing";
 const char* const E_GL_EXT_ray_query                        = "GL_EXT_ray_query";
 const char* const E_GL_EXT_ray_flags_primitive_culling      = "GL_EXT_ray_flags_primitive_culling";
+const char* const E_GL_EXT_blend_func_extended              = "GL_EXT_blend_func_extended";
 
 // Arrays of extensions for the above viewportEXTs duplications
 
index 854d293..f2306a6 100644 (file)
@@ -141,6 +141,7 @@ const TBuiltInResource DefaultTBuiltInResource = {
     /* .maxTaskWorkGroupSizeY_NV = */ 1,
     /* .maxTaskWorkGroupSizeZ_NV = */ 1,
     /* .maxMeshViewCountNV = */ 4,
+    /* .maxDualSourceDrawBuffersEXT = */ 1,
 
     /* .limits = */ {
         /* .nonInductiveForLoops = */ 1,