Add support for extension GL_EXT_shader_implicit_conversions
authorPankaj Mistry <pmistry@nvidia.com>
Mon, 27 Apr 2020 00:52:31 +0000 (17:52 -0700)
committerPankaj Mistry <pmistry@nvidia.com>
Thu, 30 Apr 2020 15:41:23 +0000 (08:41 -0700)
Updated extension management in TIntermediate class.

SPIRV/GlslangToSpv.cpp
Test/310.frag
Test/baseResults/310.frag.out
Test/baseResults/versionsErrors.frag.out
glslang/MachineIndependent/Intermediate.cpp
glslang/MachineIndependent/ParseHelper.cpp
glslang/MachineIndependent/Versions.cpp
glslang/MachineIndependent/Versions.h
glslang/MachineIndependent/intermOut.cpp
glslang/MachineIndependent/localintermediate.h

index 071dad3..3bed678 100644 (file)
@@ -1439,7 +1439,7 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
     // Add the source extensions
     const auto& sourceExtensions = glslangIntermediate->getRequestedExtensions();
     for (auto it = sourceExtensions.begin(); it != sourceExtensions.end(); ++it)
-        builder.addSourceExtension(it->c_str());
+        builder.addSourceExtension(it->first.c_str());
 
     // Add the top-level modes for this shader.
 
index 8a11f67..5cdcca7 100755 (executable)
@@ -448,4 +448,40 @@ void devie()
 {
     gl_DeviceIndex;
     gl_ViewIndex;
-}
+}\r
+\r
+#extension GL_EXT_shader_implicit_conversions : enable\r
+\r
+// Test function overloading\r
+void func(uint a, uvec4 b)\r
+{\r
+\r
+}\r
+\r
+int func(uint a, uvec4 b) // Error function overloading because of same signature and different return type\r
+{\r
+    return 0;\r
+}\r
+\r
+int b;\r
+\r
+void testimplicit() {\r
+\r
+    uint a = b; // int->uint\r
+    mediump vec4 col = vec4(1, 2, 3, 4); // ivec4 -> vec4\r
+    int  b = a + 2; // ERROR: cannot convert from ' temp uint' to ' temp int'\r
+\r
+    // Test binary ops\r
+    uint c = b * 3; \r
+    uint d = b * 3u;\r
+    uint e = b%3;\r
+    uint f = (b > 3)? b : c;     \r
+    func(b, ivec4(1,2,3,4)); \r
+}\r
+\r
+#extension GL_EXT_shader_implicit_conversions : disable\r
+\r
+void testimplicitFail() {\r
+    uint a = b; // Error GL_EXT_shader_implicit_conversions is disabled\r
+}\r
+\r
index fab3d46..9fe93e9 100644 (file)
@@ -134,12 +134,18 @@ ERROR: 0:429: 'blend_support' : unknown blend equation
 ERROR: 0:431: 'fragment-shader array-of-array output' : not supported with this profile: es
 ERROR: 0:435: 'gl_DeviceIndex' : required extension not requested: GL_EXT_device_group
 ERROR: 0:436: 'gl_ViewIndex' : required extension not requested: GL_EXT_multiview
-ERROR: 127 compilation errors.  No code generated.
+ERROR: 0:461: 'func' : overloaded functions must have the same return type 
+ERROR: 0:461: 'func' : function already has a body 
+ERROR: 0:463: 'return' : void function cannot return a value 
+ERROR: 0:472: '=' :  cannot convert from ' temp mediump uint' to ' temp mediump int'
+ERROR: 0:485: '=' :  cannot convert from ' global mediump int' to ' temp mediump uint'
+ERROR: 132 compilation errors.  No code generated.
 
 
 Shader version: 310
 Requested GL_EXT_device_group
 Requested GL_EXT_multiview
+Requested GL_EXT_shader_implicit_conversions
 Requested GL_EXT_shader_io_blocks
 Requested GL_EXT_texture_cube_map_array
 Requested GL_KHR_blend_equation_advanced
@@ -939,6 +945,80 @@ ERROR: node is still EOpNull!
 0:449    Sequence
 0:449      'gl_DeviceIndex' ( flat in highp int DeviceIndex)
 0:450      'gl_ViewIndex' ( flat in highp int ViewIndex)
+0:456  Function Definition: func(u1;vu4; ( global void)
+0:456    Function Parameters: 
+0:456      'a' ( in mediump uint)
+0:456      'b' ( in mediump 4-component vector of uint)
+0:461  Function Definition: func(u1;vu4; ( global mediump int)
+0:461    Function Parameters: 
+0:461      'a' ( in mediump uint)
+0:461      'b' ( in mediump 4-component vector of uint)
+0:463    Sequence
+0:463      Branch: Return
+0:468  Function Definition: testimplicit( ( global void)
+0:468    Function Parameters: 
+0:470    Sequence
+0:470      Sequence
+0:470        move second child to first child ( temp mediump uint)
+0:470          'a' ( temp mediump uint)
+0:470          Convert int to uint ( temp mediump uint)
+0:470            'b' ( global mediump int)
+0:471      Sequence
+0:471        move second child to first child ( temp mediump 4-component vector of float)
+0:471          'col' ( temp mediump 4-component vector of float)
+0:471          Constant:
+0:471            1.000000
+0:471            2.000000
+0:471            3.000000
+0:471            4.000000
+0:475      Sequence
+0:475        move second child to first child ( temp mediump uint)
+0:475          'c' ( temp mediump uint)
+0:475          Convert int to uint ( temp mediump uint)
+0:475            component-wise multiply ( temp mediump int)
+0:475              'b' ( temp mediump int)
+0:475              Constant:
+0:475                3 (const int)
+0:476      Sequence
+0:476        move second child to first child ( temp mediump uint)
+0:476          'd' ( temp mediump uint)
+0:476          component-wise multiply ( temp mediump uint)
+0:476            Convert int to uint ( temp mediump uint)
+0:476              'b' ( temp mediump int)
+0:476            Constant:
+0:476              3 (const uint)
+0:477      Sequence
+0:477        move second child to first child ( temp mediump uint)
+0:477          'e' ( temp mediump uint)
+0:477          Convert int to uint ( temp mediump uint)
+0:477            mod ( temp mediump int)
+0:477              'b' ( temp mediump int)
+0:477              Constant:
+0:477                3 (const int)
+0:478      Sequence
+0:478        move second child to first child ( temp mediump uint)
+0:478          'f' ( temp mediump uint)
+0:478          Test condition and select ( temp mediump uint)
+0:478            Condition
+0:478            Compare Greater Than ( temp bool)
+0:478              'b' ( temp mediump int)
+0:478              Constant:
+0:478                3 (const int)
+0:478            true case
+0:478            Convert int to uint ( temp uint)
+0:478              'b' ( temp mediump int)
+0:478            false case
+0:478            'c' ( temp mediump uint)
+0:479      Function Call: func(u1;vu4; ( global void)
+0:479        Convert int to uint ( temp uint)
+0:479          'b' ( temp mediump int)
+0:479        Constant:
+0:479          1 (const uint)
+0:479          2 (const uint)
+0:479          3 (const uint)
+0:479          4 (const uint)
+0:484  Function Definition: testimplicitFail( ( global void)
+0:484    Function Parameters: 
 0:?   Linker Objects
 0:?     'gl_FragCoord' ( smooth in mediump 4-component vector of float)
 0:?     'v3' (layout( location=2) smooth in mediump 3-component vector of float)
@@ -1033,6 +1113,7 @@ ERROR: node is still EOpNull!
 0:?     'sampInArray' ( smooth sample in 4-element array of mediump 3-component vector of float)
 0:?     'badout' ( out mediump 4-component vector of float)
 0:?     'outAA' ( out 2-element array of 2-element array of mediump 4-component vector of float)
+0:?     'b' ( global mediump int)
 
 
 Linked fragment stage:
@@ -1042,6 +1123,7 @@ ERROR: Linking fragment stage: when more than one fragment shader output, all mu
 Shader version: 310
 Requested GL_EXT_device_group
 Requested GL_EXT_multiview
+Requested GL_EXT_shader_implicit_conversions
 Requested GL_EXT_shader_io_blocks
 Requested GL_EXT_texture_cube_map_array
 Requested GL_KHR_blend_equation_advanced
@@ -1244,4 +1326,5 @@ ERROR: node is still EOpNull!
 0:?     'sampInArray' ( smooth sample in 4-element array of mediump 3-component vector of float)
 0:?     'badout' ( out mediump 4-component vector of float)
 0:?     'outAA' ( out 2-element array of 2-element array of mediump 4-component vector of float)
+0:?     'b' ( global mediump int)
 
index dbeb941..b072669 100644 (file)
@@ -7,6 +7,7 @@ ERROR: 4 compilation errors.  No code generated.
 
 
 Shader version: 110
+Requested GL_ARB_texture_rectangle
 ERROR: node is still EOpNull!
 0:42  Function Definition: main( ( global void)
 0:42    Function Parameters: 
@@ -27,6 +28,7 @@ Linked fragment stage:
 
 
 Shader version: 110
+Requested GL_ARB_texture_rectangle
 ERROR: node is still EOpNull!
 0:42  Function Definition: main( ( global void)
 0:42    Function Parameters: 
index f6a5e7f..d7049d8 100755 (executable)
@@ -1620,7 +1620,7 @@ bool TIntermediate::isFPIntegralConversion(TBasicType from, TBasicType to) const
 //
 bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperator op) const
 {
-    if (isEsProfile() || version == 110)
+    if ((isEsProfile() && version < 310 ) || version == 110)
         return false;
 
     if (from == to)
@@ -1667,7 +1667,7 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
                                 extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_float16) ||
                                 extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_float32) ||
                                 extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_float64);
-
+    
     if (explicitTypesEnabled) {
         // integral promotions
         if (isIntegralPromotion(from, to)) {
@@ -1699,6 +1699,30 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
             if (from == EbtBool && (to == EbtInt || to == EbtUint || to == EbtFloat))
                 return true;
         }
+    } else if (isEsProfile()) {
+        switch (to) {
+            case EbtFloat:
+                switch (from) {
+                case EbtInt:
+                case EbtUint:
+                    return extensionRequested(E_GL_EXT_shader_implicit_conversions);
+                case EbtFloat:
+                    return true;
+                default:
+                    return false;
+                }
+            case EbtUint:
+                switch (from) {
+                case EbtInt:
+                    return extensionRequested(E_GL_EXT_shader_implicit_conversions);
+                case EbtUint:
+                    return true;
+                default:
+                    return false;
+                }
+            default:
+                return false;
+        }        
     } else {
         switch (to) {
         case EbtDouble:
@@ -1731,15 +1755,14 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
                 return extensionRequested(E_GL_AMD_gpu_shader_int16);
             case EbtFloat16:
                 return 
-                    extensionRequested(E_GL_AMD_gpu_shader_half_float) ||
-                    getSource() == EShSourceHlsl;
+                    extensionRequested(E_GL_AMD_gpu_shader_half_float) || getSource() == EShSourceHlsl;
             default:
                  return false;
             }
         case EbtUint:
             switch (from) {
             case EbtInt:
-                 return version >= 400 || getSource() == EShSourceHlsl;
+                return version >= 400 || getSource() == EShSourceHlsl;
             case EbtUint:
                 return true;
             case EbtBool:
@@ -1931,7 +1954,9 @@ std::tuple<TBasicType, TBasicType> TIntermediate::getConversionDestinatonType(TB
     TBasicType res0 = EbtNumTypes;
     TBasicType res1 = EbtNumTypes;
 
-    if (isEsProfile() || version == 110)
+    if ((isEsProfile() && 
+        (version < 310 || !extensionRequested(E_GL_EXT_shader_implicit_conversions))) || 
+        version == 110)
         return std::make_tuple(res0, res1);
 
     if (getSource() == EShSourceHlsl) {
index 31b09f0..f95e120 100644 (file)
@@ -6140,7 +6140,10 @@ const TFunction* TParseContext::findFunction(const TSourceLoc& loc, const TFunct
                                 extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float32) ||
                                 extensionTurnedOn(E_GL_EXT_shader_explicit_arithmetic_types_float64);
 
-    if (isEsProfile() || version < 120)
+    if (isEsProfile())
+        function = (extensionTurnedOn(E_GL_EXT_shader_implicit_conversions) && version >= 310) ?
+                    findFunction120(loc, call, builtIn) : findFunctionExact(loc, call, builtIn);
+    else if (version < 120)
         function = findFunctionExact(loc, call, builtIn);
     else if (version < 400)
         function = extensionTurnedOn(E_GL_ARB_gpu_shader_fp64) ? findFunction400(loc, call, builtIn) : findFunction120(loc, call, builtIn);
index cdcba3b..f3357f8 100644 (file)
@@ -305,6 +305,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_shader_implicit_conversions] = EBhDisable;
 
     // OVR extensions
     extensionBehavior[E_GL_OVR_multiview]                = EBhDisable;
@@ -363,6 +364,7 @@ void TParseVersions::getPreamble(std::string& preamble)
             "#define GL_EXT_tessellation_point_size 1\n"
             "#define GL_EXT_texture_buffer 1\n"
             "#define GL_EXT_texture_cube_map_array 1\n"
+            "#define GL_EXT_shader_implicit_conversions 1\n"
 
             // OES matching AEP
             "#define GL_OES_geometry_shader 1\n"
@@ -919,8 +921,8 @@ void TParseVersions::updateExtensionBehavior(const char* extension, TExtensionBe
         } else {
             if (iter->second == EBhDisablePartial)
                 warn(getCurrentLoc(), "extension is only partially supported:", "#extension", extension);
-            if (behavior == EBhEnable || behavior == EBhRequire)
-                intermediate.addRequestedExtension(extension);
+            if (behavior == EBhEnable || behavior == EBhRequire || behavior == EBhDisable)
+                intermediate.updateRequestedExtension(extension, behavior);
             iter->second = behavior;
         }
     }
index f5ea06f..9446ea3 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_shader_implicit_conversions      = "GL_EXT_shader_implicit_conversions";
 
 // Arrays of extensions for the above viewportEXTs duplications
 
index 593ed6f..86edcfe 100644 (file)
@@ -1466,7 +1466,7 @@ void TIntermediate::output(TInfoSink& infoSink, bool tree)
     infoSink.debug << "Shader version: " << version << "\n";
     if (requestedExtensions.size() > 0) {
         for (auto extIt = requestedExtensions.begin(); extIt != requestedExtensions.end(); ++extIt)
-            infoSink.debug << "Requested " << *extIt << "\n";
+            infoSink.debug << "Requested " << extIt->first << "\n";
     }
 
     if (xfbMode)
index 66f5a88..996e347 100644 (file)
@@ -356,8 +356,15 @@ public:
     }
     const SpvVersion& getSpv() const { return spvVersion; }
     EShLanguage getStage() const { return language; }
-    void addRequestedExtension(const char* extension) { requestedExtensions.insert(extension); }
-    const std::set<std::string>& getRequestedExtensions() const { return requestedExtensions; }
+    void updateRequestedExtension(const char* extension, TExtensionBehavior behavior) { 
+        if(requestedExtensions.find(extension) != requestedExtensions.end()) {
+            requestedExtensions[extension] = behavior; 
+        } else {
+            requestedExtensions.insert(std::make_pair(extension, behavior)); 
+        }
+    }
+
+    const std::map<std::string, TExtensionBehavior>& getRequestedExtensions() const { return requestedExtensions; }
 
     void setTreeRoot(TIntermNode* r) { treeRoot = r; }
     TIntermNode* getTreeRoot() const { return treeRoot; }
@@ -902,7 +909,13 @@ protected:
 #ifdef GLSLANG_WEB
     bool extensionRequested(const char *extension) const { return false; }
 #else
-    bool extensionRequested(const char *extension) const {return requestedExtensions.find(extension) != requestedExtensions.end();}
+    bool extensionRequested(const char *extension) const {
+        auto it = requestedExtensions.find(extension);
+        if (it != requestedExtensions.end()) {
+            return (it->second == EBhDisable) ? false : true;
+        }
+        return false;
+    }
 #endif
 
     static const char* getResourceName(TResourceType);
@@ -917,7 +930,7 @@ protected:
     int version;                                // source version
     SpvVersion spvVersion;
     TIntermNode* treeRoot;
-    std::set<std::string> requestedExtensions;  // cumulation of all enabled or required extensions; not connected to what subset of the shader used them
+    std::map<std::string, TExtensionBehavior> requestedExtensions;  // cumulation of all enabled or required extensions; not connected to what subset of the shader used them
     TBuiltInResource resources;
     int numEntryPoints;
     int numErrors;