Implement GL_ARB_derivative_control.


git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@27713 e7fa87d3-cd2b-0410-9028-fcbf551c1848
diff --git a/Test/400.frag b/Test/400.frag
index e0b14d7..8f83b1c 100644
--- a/Test/400.frag
+++ b/Test/400.frag
@@ -61,4 +61,25 @@
 {
     dvec3 df, di;
     df = modf(outp.xyz, di);
-}
\ No newline at end of file
+}
+
+in float in1;
+in vec2 in2;
+in vec3 in3;
+in vec4 in4;
+
+void foodc1()
+{
+    vec2 v2 = dFdxFine(in2);           // ERROR
+    vec3 v3 = dFdyCoarse(in3);         // ERROR
+    vec4 v4 = fwidthCoarse(in4) + fwidthFine(in4);   // ERROR
+}
+
+#extension GL_ARB_derivative_control : enable
+
+void foodc2()
+{
+    vec2 v2 = dFdxFine(in2);
+    vec3 v3 = dFdyCoarse(in3);
+    vec4 v4 = fwidthCoarse(in4) + fwidthFine(in4);
+}
diff --git a/Test/450.frag b/Test/450.frag
new file mode 100644
index 0000000..5c50e54
--- /dev/null
+++ b/Test/450.frag
@@ -0,0 +1,17 @@
+#version 450 core

+

+in float in1;

+in vec2 in2;

+in vec3 in3;

+in vec4 in4;

+

+void main()

+{

+    vec2 v2 = dFdxFine(in2);

+    vec3 v3 = dFdyCoarse(in3);

+    vec4 v4 = fwidth(in4);

+    v4 = dFdyFine(in4);

+    v3 = dFdyFine(in3);

+    float f = dFdx(in1) + dFdxFine(in1) + dFdxCoarse(in1);

+    v4 = fwidthCoarse(in4) + fwidthFine(in4);

+}

diff --git a/Test/baseResults/400.frag.out b/Test/baseResults/400.frag.out
index 3cc1c69..7a10db1 100644
--- a/Test/baseResults/400.frag.out
+++ b/Test/baseResults/400.frag.out
@@ -15,10 +15,15 @@
 ERROR: 0:54: 'texel offset' : value is out of range: [gl_MinProgramTexelOffset, gl_MaxProgramTexelOffset]

 ERROR: 0:57: 'patch' : not supported in this stage: fragment

 ERROR: 0:58: 'patch' : not supported in this stage: fragment

-ERROR: 15 compilation errors.  No code generated.

+ERROR: 0:73: 'dFdxFine' : required extension not requested: GL_ARB_derivative_control

+ERROR: 0:74: 'dFdyCoarse' : required extension not requested: GL_ARB_derivative_control

+ERROR: 0:75: 'fwidthCoarse' : required extension not requested: GL_ARB_derivative_control

+ERROR: 0:75: 'fwidthFine' : required extension not requested: GL_ARB_derivative_control

+ERROR: 19 compilation errors.  No code generated.

 

 

 Shader version: 400

+Requested GL_ARB_derivative_control

 Requested GL_ARB_separate_shader_objects

 gl_FragCoord pixel center is integer

 gl_FragCoord origin is upper left

@@ -217,6 +222,48 @@
 0:63              Convert float to double (3-component vector of double)

 0:63                'tempArg' (3-component vector of float)

 0:63            'tempReturn' (3-component vector of float)

+0:71  Function Definition: foodc1( (void)

+0:71    Function Parameters: 

+0:73    Sequence

+0:73      Sequence

+0:73        move second child to first child (2-component vector of float)

+0:73          'v2' (2-component vector of float)

+0:73          dPdxFine (2-component vector of float)

+0:73            'in2' (smooth in 2-component vector of float)

+0:74      Sequence

+0:74        move second child to first child (3-component vector of float)

+0:74          'v3' (3-component vector of float)

+0:74          dPdyCoarse (3-component vector of float)

+0:74            'in3' (smooth in 3-component vector of float)

+0:75      Sequence

+0:75        move second child to first child (4-component vector of float)

+0:75          'v4' (4-component vector of float)

+0:75          add (4-component vector of float)

+0:75            fwidthCoarse (4-component vector of float)

+0:75              'in4' (smooth in 4-component vector of float)

+0:75            fwidthFine (4-component vector of float)

+0:75              'in4' (smooth in 4-component vector of float)

+0:80  Function Definition: foodc2( (void)

+0:80    Function Parameters: 

+0:82    Sequence

+0:82      Sequence

+0:82        move second child to first child (2-component vector of float)

+0:82          'v2' (2-component vector of float)

+0:82          dPdxFine (2-component vector of float)

+0:82            'in2' (smooth in 2-component vector of float)

+0:83      Sequence

+0:83        move second child to first child (3-component vector of float)

+0:83          'v3' (3-component vector of float)

+0:83          dPdyCoarse (3-component vector of float)

+0:83            'in3' (smooth in 3-component vector of float)

+0:84      Sequence

+0:84        move second child to first child (4-component vector of float)

+0:84          'v4' (4-component vector of float)

+0:84          add (4-component vector of float)

+0:84            fwidthCoarse (4-component vector of float)

+0:84              'in4' (smooth in 4-component vector of float)

+0:84            fwidthFine (4-component vector of float)

+0:84              'in4' (smooth in 4-component vector of float)

 0:?   Linker Objects

 0:?     'c2D' (smooth in 2-component vector of float)

 0:?     'i' (flat in int)

@@ -235,12 +282,17 @@
 0:?     'u2drs' (uniform sampler2DRectShadow)

 0:?     'patchIn' (smooth patch in 4-component vector of float)

 0:?     'patchOut' (patch out 4-component vector of float)

+0:?     'in1' (smooth in float)

+0:?     'in2' (smooth in 2-component vector of float)

+0:?     'in3' (smooth in 3-component vector of float)

+0:?     'in4' (smooth in 4-component vector of float)

 

 

 Linked fragment stage:

 

 

 Shader version: 400

+Requested GL_ARB_derivative_control

 Requested GL_ARB_separate_shader_objects

 gl_FragCoord pixel center is integer

 gl_FragCoord origin is upper left

@@ -439,6 +491,48 @@
 0:63              Convert float to double (3-component vector of double)

 0:63                'tempArg' (3-component vector of float)

 0:63            'tempReturn' (3-component vector of float)

+0:71  Function Definition: foodc1( (void)

+0:71    Function Parameters: 

+0:73    Sequence

+0:73      Sequence

+0:73        move second child to first child (2-component vector of float)

+0:73          'v2' (2-component vector of float)

+0:73          dPdxFine (2-component vector of float)

+0:73            'in2' (smooth in 2-component vector of float)

+0:74      Sequence

+0:74        move second child to first child (3-component vector of float)

+0:74          'v3' (3-component vector of float)

+0:74          dPdyCoarse (3-component vector of float)

+0:74            'in3' (smooth in 3-component vector of float)

+0:75      Sequence

+0:75        move second child to first child (4-component vector of float)

+0:75          'v4' (4-component vector of float)

+0:75          add (4-component vector of float)

+0:75            fwidthCoarse (4-component vector of float)

+0:75              'in4' (smooth in 4-component vector of float)

+0:75            fwidthFine (4-component vector of float)

+0:75              'in4' (smooth in 4-component vector of float)

+0:80  Function Definition: foodc2( (void)

+0:80    Function Parameters: 

+0:82    Sequence

+0:82      Sequence

+0:82        move second child to first child (2-component vector of float)

+0:82          'v2' (2-component vector of float)

+0:82          dPdxFine (2-component vector of float)

+0:82            'in2' (smooth in 2-component vector of float)

+0:83      Sequence

+0:83        move second child to first child (3-component vector of float)

+0:83          'v3' (3-component vector of float)

+0:83          dPdyCoarse (3-component vector of float)

+0:83            'in3' (smooth in 3-component vector of float)

+0:84      Sequence

+0:84        move second child to first child (4-component vector of float)

+0:84          'v4' (4-component vector of float)

+0:84          add (4-component vector of float)

+0:84            fwidthCoarse (4-component vector of float)

+0:84              'in4' (smooth in 4-component vector of float)

+0:84            fwidthFine (4-component vector of float)

+0:84              'in4' (smooth in 4-component vector of float)

 0:?   Linker Objects

 0:?     'c2D' (smooth in 2-component vector of float)

 0:?     'i' (flat in int)

@@ -457,4 +551,8 @@
 0:?     'u2drs' (uniform sampler2DRectShadow)

 0:?     'patchIn' (smooth patch in 4-component vector of float)

 0:?     'patchOut' (patch out 4-component vector of float)

+0:?     'in1' (smooth in float)

+0:?     'in2' (smooth in 2-component vector of float)

+0:?     'in3' (smooth in 3-component vector of float)

+0:?     'in4' (smooth in 4-component vector of float)

 

diff --git a/Test/baseResults/450.frag.out b/Test/baseResults/450.frag.out
new file mode 100644
index 0000000..02f2c33
--- /dev/null
+++ b/Test/baseResults/450.frag.out
@@ -0,0 +1,111 @@
+450.frag

+Warning, version 450 is not yet complete; most version-specific features are present, but some are missing.

+

+Shader version: 450

+0:? Sequence

+0:8  Function Definition: main( (void)

+0:8    Function Parameters: 

+0:10    Sequence

+0:10      Sequence

+0:10        move second child to first child (2-component vector of float)

+0:10          'v2' (2-component vector of float)

+0:10          dPdxFine (2-component vector of float)

+0:10            'in2' (smooth in 2-component vector of float)

+0:11      Sequence

+0:11        move second child to first child (3-component vector of float)

+0:11          'v3' (3-component vector of float)

+0:11          dPdyCoarse (3-component vector of float)

+0:11            'in3' (smooth in 3-component vector of float)

+0:12      Sequence

+0:12        move second child to first child (4-component vector of float)

+0:12          'v4' (4-component vector of float)

+0:12          fwidth (4-component vector of float)

+0:12            'in4' (smooth in 4-component vector of float)

+0:13      move second child to first child (4-component vector of float)

+0:13        'v4' (4-component vector of float)

+0:13        dPdyFine (4-component vector of float)

+0:13          'in4' (smooth in 4-component vector of float)

+0:14      move second child to first child (3-component vector of float)

+0:14        'v3' (3-component vector of float)

+0:14        dPdyFine (3-component vector of float)

+0:14          'in3' (smooth in 3-component vector of float)

+0:15      Sequence

+0:15        move second child to first child (float)

+0:15          'f' (float)

+0:15          add (float)

+0:15            add (float)

+0:15              dPdx (float)

+0:15                'in1' (smooth in float)

+0:15              dPdxFine (float)

+0:15                'in1' (smooth in float)

+0:15            dPdxCoarse (float)

+0:15              'in1' (smooth in float)

+0:16      move second child to first child (4-component vector of float)

+0:16        'v4' (4-component vector of float)

+0:16        add (4-component vector of float)

+0:16          fwidthCoarse (4-component vector of float)

+0:16            'in4' (smooth in 4-component vector of float)

+0:16          fwidthFine (4-component vector of float)

+0:16            'in4' (smooth in 4-component vector of float)

+0:?   Linker Objects

+0:?     'in1' (smooth in float)

+0:?     'in2' (smooth in 2-component vector of float)

+0:?     'in3' (smooth in 3-component vector of float)

+0:?     'in4' (smooth in 4-component vector of float)

+

+

+Linked fragment stage:

+

+

+Shader version: 450

+0:? Sequence

+0:8  Function Definition: main( (void)

+0:8    Function Parameters: 

+0:10    Sequence

+0:10      Sequence

+0:10        move second child to first child (2-component vector of float)

+0:10          'v2' (2-component vector of float)

+0:10          dPdxFine (2-component vector of float)

+0:10            'in2' (smooth in 2-component vector of float)

+0:11      Sequence

+0:11        move second child to first child (3-component vector of float)

+0:11          'v3' (3-component vector of float)

+0:11          dPdyCoarse (3-component vector of float)

+0:11            'in3' (smooth in 3-component vector of float)

+0:12      Sequence

+0:12        move second child to first child (4-component vector of float)

+0:12          'v4' (4-component vector of float)

+0:12          fwidth (4-component vector of float)

+0:12            'in4' (smooth in 4-component vector of float)

+0:13      move second child to first child (4-component vector of float)

+0:13        'v4' (4-component vector of float)

+0:13        dPdyFine (4-component vector of float)

+0:13          'in4' (smooth in 4-component vector of float)

+0:14      move second child to first child (3-component vector of float)

+0:14        'v3' (3-component vector of float)

+0:14        dPdyFine (3-component vector of float)

+0:14          'in3' (smooth in 3-component vector of float)

+0:15      Sequence

+0:15        move second child to first child (float)

+0:15          'f' (float)

+0:15          add (float)

+0:15            add (float)

+0:15              dPdx (float)

+0:15                'in1' (smooth in float)

+0:15              dPdxFine (float)

+0:15                'in1' (smooth in float)

+0:15            dPdxCoarse (float)

+0:15              'in1' (smooth in float)

+0:16      move second child to first child (4-component vector of float)

+0:16        'v4' (4-component vector of float)

+0:16        add (4-component vector of float)

+0:16          fwidthCoarse (4-component vector of float)

+0:16            'in4' (smooth in 4-component vector of float)

+0:16          fwidthFine (4-component vector of float)

+0:16            'in4' (smooth in 4-component vector of float)

+0:?   Linker Objects

+0:?     'in1' (smooth in float)

+0:?     'in2' (smooth in 2-component vector of float)

+0:?     'in3' (smooth in 3-component vector of float)

+0:?     'in4' (smooth in 4-component vector of float)

+

diff --git a/Test/testlist b/Test/testlist
index ba21ea1..5d4b52b 100644
--- a/Test/testlist
+++ b/Test/testlist
@@ -71,6 +71,7 @@
 430.comp
 440.vert
 440.frag
+450.frag
 dce.frag
 atomic_uint.frag
 ../../LunarGLASS/test/aggOps.frag
diff --git a/glslang/Include/intermediate.h b/glslang/Include/intermediate.h
index 2ce2409..19e0c41 100644
--- a/glslang/Include/intermediate.h
+++ b/glslang/Include/intermediate.h
@@ -208,6 +208,12 @@
     EOpDPdx,            // Fragment only
     EOpDPdy,            // Fragment only
     EOpFwidth,          // Fragment only
+    EOpDPdxFine,        // Fragment only
+    EOpDPdyFine,        // Fragment only
+    EOpFwidthFine,      // Fragment only
+    EOpDPdxCoarse,      // Fragment only
+    EOpDPdyCoarse,      // Fragment only
+    EOpFwidthCoarse,    // Fragment only
 
     EOpMatrixTimesMatrix,
     EOpOuterProduct,
diff --git a/glslang/MachineIndependent/Constant.cpp b/glslang/MachineIndependent/Constant.cpp
index 4648b55..728245a 100644
--- a/glslang/MachineIndependent/Constant.cpp
+++ b/glslang/MachineIndependent/Constant.cpp
@@ -451,6 +451,12 @@
         case EOpDPdx:
         case EOpDPdy:
         case EOpFwidth:
+        case EOpDPdxFine:
+        case EOpDPdyFine:
+        case EOpFwidthFine:
+        case EOpDPdxCoarse:
+        case EOpDPdyCoarse:
+        case EOpFwidthCoarse:
             // The derivatives are all mandated to create a constant 0.
             newConstArray[i].setDConst(0.0);
             break;
diff --git a/glslang/MachineIndependent/Initialize.cpp b/glslang/MachineIndependent/Initialize.cpp
index dcd11b8..89116bc 100644
--- a/glslang/MachineIndependent/Initialize.cpp
+++ b/glslang/MachineIndependent/Initialize.cpp
@@ -933,6 +933,45 @@
             
         "\n");
 
+    // GL_ARB_derivative_control
+    if (profile != EEsProfile && version >= 400) {
+	    stageBuiltins[EShLangFragment].append(
+            "float dFdxFine(float p);"
+            "vec2  dFdxFine(vec2  p);"
+            "vec3  dFdxFine(vec3  p);"
+            "vec4  dFdxFine(vec4  p);"
+                 
+            "float dFdyFine(float p);"
+            "vec2  dFdyFine(vec2  p);"
+            "vec3  dFdyFine(vec3  p);"
+            "vec4  dFdyFine(vec4  p);"
+                 
+            "float fwidthFine(float p);"
+            "vec2  fwidthFine(vec2  p);"
+            "vec3  fwidthFine(vec3  p);"
+            "vec4  fwidthFine(vec4  p);"
+            
+            "\n");
+
+	    stageBuiltins[EShLangFragment].append(
+            "float dFdxCoarse(float p);"
+            "vec2  dFdxCoarse(vec2  p);"
+            "vec3  dFdxCoarse(vec3  p);"
+            "vec4  dFdxCoarse(vec4  p);"
+                 
+            "float dFdyCoarse(float p);"
+            "vec2  dFdyCoarse(vec2  p);"
+            "vec3  dFdyCoarse(vec3  p);"
+            "vec4  dFdyCoarse(vec4  p);"
+                 
+            "float fwidthCoarse(float p);"
+            "vec2  fwidthCoarse(vec2  p);"
+            "vec3  fwidthCoarse(vec3  p);"
+            "vec4  fwidthCoarse(vec4  p);"
+            
+            "\n");
+    }
+
     //============================================================================
     //
     // Standard Uniforms
@@ -2383,6 +2422,16 @@
             symbolTable.setFunctionExtensions("atomicCounter"         , 1, &GL_ARB_shader_atomic_counters);
         }
 
+        // GL_ARB_derivative_control
+        if (profile != EEsProfile && version < 450) {
+            symbolTable.setFunctionExtensions("dFdxFine",     1, &GL_ARB_derivative_control);
+            symbolTable.setFunctionExtensions("dFdyFine",     1, &GL_ARB_derivative_control);
+            symbolTable.setFunctionExtensions("fwidthFine",   1, &GL_ARB_derivative_control);
+            symbolTable.setFunctionExtensions("dFdxCoarse",   1, &GL_ARB_derivative_control);
+            symbolTable.setFunctionExtensions("dFdyCoarse",   1, &GL_ARB_derivative_control);
+            symbolTable.setFunctionExtensions("fwidthCoarse", 1, &GL_ARB_derivative_control);
+        }
+
         symbolTable.setVariableExtensions("gl_FragDepthEXT", 1, &GL_EXT_frag_depth);
         break;
 
@@ -2512,6 +2561,14 @@
         symbolTable.relateToOperator("dFdx",         EOpDPdx);
         symbolTable.relateToOperator("dFdy",         EOpDPdy);
         symbolTable.relateToOperator("fwidth",       EOpFwidth);
+        if (profile != EEsProfile && version >= 400) {
+            symbolTable.relateToOperator("dFdxFine",     EOpDPdxFine);
+            symbolTable.relateToOperator("dFdyFine",     EOpDPdyFine);
+            symbolTable.relateToOperator("fwidthFine",   EOpFwidthFine);
+            symbolTable.relateToOperator("dFdxCoarse",   EOpDPdxCoarse);
+            symbolTable.relateToOperator("dFdyCoarse",   EOpDPdyCoarse);
+            symbolTable.relateToOperator("fwidthCoarse", EOpFwidthCoarse);
+        }
         break;
 
     case EShLangCompute:
diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp
index 13681d9..06dd278 100644
--- a/glslang/MachineIndependent/ParseHelper.cpp
+++ b/glslang/MachineIndependent/ParseHelper.cpp
@@ -3347,7 +3347,7 @@
                     error(loc, "cannot specify on a variable declaration", "offset", "");
                 if (qualifier.hasOffset() && ! qualifier.hasBinding() && type.getBasicType() == EbtAtomicUint)
                     error(loc, "a binding is required", "offset", "");
-                if (qualifier.hasBinding() && qualifier.layoutBinding >= resources.maxAtomicCounterBindings && type.getBasicType() == EbtAtomicUint)
+                if (qualifier.hasBinding() && (int)qualifier.layoutBinding >= resources.maxAtomicCounterBindings && type.getBasicType() == EbtAtomicUint)
                     error(loc, "cannot be greater-than-or-equal to gl_MaxAtomicCounterBindings", "binding", "");
                 // "The align qualifier can only be used on blocks or block members..."
                 if (qualifier.hasAlign())
diff --git a/glslang/MachineIndependent/Versions.cpp b/glslang/MachineIndependent/Versions.cpp
index 0562bdd..2f700f2 100644
--- a/glslang/MachineIndependent/Versions.cpp
+++ b/glslang/MachineIndependent/Versions.cpp
@@ -168,6 +168,7 @@
     extensionBehavior[GL_ARB_explicit_attrib_location] = EBhDisablePartial; // "index" for fragment outputs is missing
     extensionBehavior[GL_ARB_shader_image_load_store]  = EBhDisable;
     extensionBehavior[GL_ARB_shader_atomic_counters]   = EBhDisable;
+    extensionBehavior[GL_ARB_derivative_control]       = EBhDisable;
 }
 
 // Get code that is not part of a shared symbol table, is specific to this shader,
@@ -207,7 +208,9 @@
             "#define GL_ARB_shader_texture_lod 1\n"
             "#define GL_ARB_explicit_attrib_location 1\n"
             "#define GL_ARB_shader_image_load_store 1\n"
-            "#define GL_ARB_shader_atomic_counters 1\n";
+            "#define GL_ARB_shader_atomic_counters 1\n"
+            "#define GL_ARB_derivative_control 1\n"
+            ;
     }
 }
 
diff --git a/glslang/MachineIndependent/Versions.h b/glslang/MachineIndependent/Versions.h
index f8a6da4..48ebbed 100644
--- a/glslang/MachineIndependent/Versions.h
+++ b/glslang/MachineIndependent/Versions.h
@@ -92,6 +92,7 @@
 const char* const GL_ARB_explicit_attrib_location = "GL_ARB_explicit_attrib_location";
 const char* const GL_ARB_shader_image_load_store  = "GL_ARB_shader_image_load_store";
 const char* const GL_ARB_shader_atomic_counters   = "GL_ARB_shader_atomic_counters";
+const char* const GL_ARB_derivative_control       = "GL_ARB_derivative_control";
 
 } // end namespace glslang
 
diff --git a/glslang/MachineIndependent/intermOut.cpp b/glslang/MachineIndependent/intermOut.cpp
index 4914070..f711225 100644
--- a/glslang/MachineIndependent/intermOut.cpp
+++ b/glslang/MachineIndependent/intermOut.cpp
@@ -250,6 +250,12 @@
     case EOpDPdx:           out.debug << "dPdx";                 break;
     case EOpDPdy:           out.debug << "dPdy";                 break;
     case EOpFwidth:         out.debug << "fwidth";               break;
+    case EOpDPdxFine:       out.debug << "dPdxFine";             break;
+    case EOpDPdyFine:       out.debug << "dPdyFine";             break;
+    case EOpFwidthFine:     out.debug << "fwidthFine";           break;
+    case EOpDPdxCoarse:     out.debug << "dPdxCoarse";           break;
+    case EOpDPdyCoarse:     out.debug << "dPdyCoarse";           break;
+    case EOpFwidthCoarse:   out.debug << "fwidthCoarse";         break;
     case EOpDeterminant:    out.debug << "determinant";          break;
     case EOpMatrixInverse:  out.debug << "inverse";              break;
     case EOpTranspose:      out.debug << "transpose";            break;