Fix uniform block precision matching bug
authorMika Isojärvi <misojarvi@google.com>
Fri, 22 Jan 2016 17:45:20 +0000 (09:45 -0800)
committerMika Isojärvi <misojarvi@google.com>
Fri, 22 Jan 2016 17:52:21 +0000 (09:52 -0800)
- Remove
  dEQP-GLES3.functional.shaders.linkage.uniform.block.differing_precision
  since this is not well defined in GLES3.
- Add shader uniform linkage tests to GLES31 module.

Bug: 21326228
Change-Id: I8940779e6b74e8fc98a0c646133247d3fcd78cbb

android/cts/master/com.drawelements.deqp.gles31.xml
android/cts/master/gles31-master.txt
android/cts/master/src/gles3-test-issues.txt
data/gles3/shaders/linkage.test
data/gles31/shaders/linkage_uniform.test [new file with mode: 0644]
modules/gles31/functional/es31fFunctionalTests.cpp

index ecfb489..7bb7feb 100644 (file)
                                                        <TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
                                                </Test>
                                        </TestCase>
+                                       <TestSuite name="uniform">
+                                               <TestCase name="basic">
+                                                       <Test name="precision_conflict_1">
+                                                               <TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
+                                                       </Test>
+                                                       <Test name="precision_conflict_2">
+                                                               <TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
+                                                       </Test>
+                                                       <Test name="precision_conflict_3">
+                                                               <TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
+                                                       </Test>
+                                                       <Test name="precision_conflict_4">
+                                                               <TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
+                                                       </Test>
+                                               </TestCase>
+                                               <TestCase name="struct">
+                                                       <Test name="basic">
+                                                               <TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
+                                                       </Test>
+                                                       <Test name="vertex_only">
+                                                               <TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
+                                                       </Test>
+                                                       <Test name="fragment_only">
+                                                               <TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
+                                                       </Test>
+                                                       <Test name="partial">
+                                                               <TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
+                                                       </Test>
+                                                       <Test name="vec4">
+                                                               <TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
+                                                       </Test>
+                                                       <Test name="vertex_only_vec4">
+                                                               <TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
+                                                       </Test>
+                                                       <Test name="fragment_only_vec4">
+                                                               <TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
+                                                       </Test>
+                                                       <Test name="partial_vec4">
+                                                               <TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
+                                                       </Test>
+                                                       <Test name="vec4_vec3">
+                                                               <TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
+                                                       </Test>
+                                                       <Test name="vertex_only_vec4_vec3">
+                                                               <TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
+                                                       </Test>
+                                                       <Test name="fragment_only_vec4_vec3">
+                                                               <TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
+                                                       </Test>
+                                                       <Test name="partial_vec4_vec3">
+                                                               <TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
+                                                       </Test>
+                                                       <Test name="vec4_float">
+                                                               <TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
+                                                       </Test>
+                                                       <Test name="vertex_only_vec4_float">
+                                                               <TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
+                                                       </Test>
+                                                       <Test name="fragment_only_vec4_float">
+                                                               <TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
+                                                       </Test>
+                                                       <Test name="partial_vec4_float">
+                                                               <TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
+                                                       </Test>
+                                                       <Test name="partial_vec4_struct">
+                                                               <TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
+                                                       </Test>
+                                                       <Test name="partial_vec4_vec3_struct">
+                                                               <TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
+                                                       </Test>
+                                                       <Test name="partial_vec2_vec3">
+                                                               <TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
+                                                       </Test>
+                                                       <Test name="partial_vec2_int">
+                                                               <TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
+                                                       </Test>
+                                                       <Test name="partial_int_float">
+                                                               <TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
+                                                       </Test>
+                                                       <Test name="partial_bvec2_vec2">
+                                                               <TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
+                                                       </Test>
+                                                       <Test name="partial_ivec2_vec2">
+                                                               <TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
+                                                       </Test>
+                                                       <Test name="partial_ivec2_ivec2">
+                                                               <TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
+                                                       </Test>
+                                                       <Test name="type_conflict_1">
+                                                               <TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
+                                                       </Test>
+                                                       <Test name="type_conflict_2">
+                                                               <TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
+                                                       </Test>
+                                                       <Test name="type_conflict_3">
+                                                               <TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
+                                                       </Test>
+                                                       <Test name="precision_conflict_1">
+                                                               <TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
+                                                       </Test>
+                                                       <Test name="precision_conflict_2">
+                                                               <TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
+                                                       </Test>
+                                                       <Test name="precision_conflict_3">
+                                                               <TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
+                                                       </Test>
+                                                       <Test name="precision_conflict_4">
+                                                               <TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
+                                                       </Test>
+                                                       <Test name="light_struct_highp">
+                                                               <TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
+                                                       </Test>
+                                                       <Test name="light_struct_mediump">
+                                                               <TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
+                                                       </Test>
+                                               </TestCase>
+                                               <TestCase name="block">
+                                                       <Test name="differing_precision">
+                                                               <TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
+                                                       </Test>
+                                                       <Test name="type_mismatch">
+                                                               <TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
+                                                       </Test>
+                                                       <Test name="members_mismatch">
+                                                               <TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
+                                                       </Test>
+                                                       <Test name="layout_qualifier_mismatch_1">
+                                                               <TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
+                                                       </Test>
+                                                       <Test name="layout_qualifier_mismatch_2">
+                                                               <TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
+                                                       </Test>
+                                                       <Test name="layout_qualifier_mismatch_3">
+                                                               <TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
+                                                       </Test>
+                                                       <Test name="layout_qualifier_mismatch_4">
+                                                               <TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
+                                                       </Test>
+                                                       <Test name="layout_qualifier_mismatch_5">
+                                                               <TestInstance glconfig="rgba8888d24s8ms0" rotation="unspecified" surfacetype="window"/>
+                                                       </Test>
+                                               </TestCase>
+                                       </TestSuite>
                                </TestSuite>
                                <TestSuite name="builtin_constants">
                                        <TestCase name="core">
index c39fc77..c3e4d97 100644 (file)
@@ -3925,6 +3925,51 @@ dEQP-GLES31.functional.shaders.linkage.io_block.mismatch_block_array_size
 dEQP-GLES31.functional.shaders.linkage.io_block.missing_output_block
 dEQP-GLES31.functional.shaders.linkage.io_block.ambiguous_variable_name_1
 dEQP-GLES31.functional.shaders.linkage.io_block.ambiguous_variable_name_2
+dEQP-GLES31.functional.shaders.linkage.uniform.basic.precision_conflict_1
+dEQP-GLES31.functional.shaders.linkage.uniform.basic.precision_conflict_2
+dEQP-GLES31.functional.shaders.linkage.uniform.basic.precision_conflict_3
+dEQP-GLES31.functional.shaders.linkage.uniform.basic.precision_conflict_4
+dEQP-GLES31.functional.shaders.linkage.uniform.struct.basic
+dEQP-GLES31.functional.shaders.linkage.uniform.struct.vertex_only
+dEQP-GLES31.functional.shaders.linkage.uniform.struct.fragment_only
+dEQP-GLES31.functional.shaders.linkage.uniform.struct.partial
+dEQP-GLES31.functional.shaders.linkage.uniform.struct.vec4
+dEQP-GLES31.functional.shaders.linkage.uniform.struct.vertex_only_vec4
+dEQP-GLES31.functional.shaders.linkage.uniform.struct.fragment_only_vec4
+dEQP-GLES31.functional.shaders.linkage.uniform.struct.partial_vec4
+dEQP-GLES31.functional.shaders.linkage.uniform.struct.vec4_vec3
+dEQP-GLES31.functional.shaders.linkage.uniform.struct.vertex_only_vec4_vec3
+dEQP-GLES31.functional.shaders.linkage.uniform.struct.fragment_only_vec4_vec3
+dEQP-GLES31.functional.shaders.linkage.uniform.struct.partial_vec4_vec3
+dEQP-GLES31.functional.shaders.linkage.uniform.struct.vec4_float
+dEQP-GLES31.functional.shaders.linkage.uniform.struct.vertex_only_vec4_float
+dEQP-GLES31.functional.shaders.linkage.uniform.struct.fragment_only_vec4_float
+dEQP-GLES31.functional.shaders.linkage.uniform.struct.partial_vec4_float
+dEQP-GLES31.functional.shaders.linkage.uniform.struct.partial_vec4_struct
+dEQP-GLES31.functional.shaders.linkage.uniform.struct.partial_vec4_vec3_struct
+dEQP-GLES31.functional.shaders.linkage.uniform.struct.partial_vec2_vec3
+dEQP-GLES31.functional.shaders.linkage.uniform.struct.partial_vec2_int
+dEQP-GLES31.functional.shaders.linkage.uniform.struct.partial_int_float
+dEQP-GLES31.functional.shaders.linkage.uniform.struct.partial_bvec2_vec2
+dEQP-GLES31.functional.shaders.linkage.uniform.struct.partial_ivec2_vec2
+dEQP-GLES31.functional.shaders.linkage.uniform.struct.partial_ivec2_ivec2
+dEQP-GLES31.functional.shaders.linkage.uniform.struct.type_conflict_1
+dEQP-GLES31.functional.shaders.linkage.uniform.struct.type_conflict_2
+dEQP-GLES31.functional.shaders.linkage.uniform.struct.type_conflict_3
+dEQP-GLES31.functional.shaders.linkage.uniform.struct.precision_conflict_1
+dEQP-GLES31.functional.shaders.linkage.uniform.struct.precision_conflict_2
+dEQP-GLES31.functional.shaders.linkage.uniform.struct.precision_conflict_3
+dEQP-GLES31.functional.shaders.linkage.uniform.struct.precision_conflict_4
+dEQP-GLES31.functional.shaders.linkage.uniform.struct.light_struct_highp
+dEQP-GLES31.functional.shaders.linkage.uniform.struct.light_struct_mediump
+dEQP-GLES31.functional.shaders.linkage.uniform.block.differing_precision
+dEQP-GLES31.functional.shaders.linkage.uniform.block.type_mismatch
+dEQP-GLES31.functional.shaders.linkage.uniform.block.members_mismatch
+dEQP-GLES31.functional.shaders.linkage.uniform.block.layout_qualifier_mismatch_1
+dEQP-GLES31.functional.shaders.linkage.uniform.block.layout_qualifier_mismatch_2
+dEQP-GLES31.functional.shaders.linkage.uniform.block.layout_qualifier_mismatch_3
+dEQP-GLES31.functional.shaders.linkage.uniform.block.layout_qualifier_mismatch_4
+dEQP-GLES31.functional.shaders.linkage.uniform.block.layout_qualifier_mismatch_5
 dEQP-GLES31.functional.shaders.builtin_constants.core.max_vertex_attribs
 dEQP-GLES31.functional.shaders.builtin_constants.core.max_vertex_uniform_vectors
 dEQP-GLES31.functional.shaders.builtin_constants.core.max_vertex_output_vectors
index adcde51..bb766bd 100644 (file)
@@ -152,9 +152,6 @@ dEQP-GLES3.functional.shaders.texture_functions.texturelodoffset.sampler3d_float
 dEQP-GLES3.functional.shaders.builtin_functions.precision.reflect.*mediump*.scalar
 dEQP-GLES3.functional.shaders.builtin_functions.precision.reflect.*highp*.scalar
 
-# Bug 21326228
-dEQP-GLES3.functional.shaders.linkage.uniform.block.differing_precision
-
 # Bug 23219552
 dEQP-GLES3.functional.dither.disabled.gradient_white
 dEQP-GLES3.functional.dither.disabled.gradient_red
index 56acda6..5becf60 100644 (file)
@@ -3607,43 +3607,6 @@ group uniform "Uniform linkage"
        end
 
        group block "Uniform blocks"
-               case differing_precision
-                       version 300 es
-                       expect build_successful
-                       vertex ""
-                               #version 300 es
-
-                               uniform Block
-                               {
-                                       highp vec4 val;
-                               };
-
-                               ${VERTEX_DECLARATIONS}
-                               out mediump float res;
-                               void main()
-                               {
-                                       res = val.x;
-                                       ${VERTEX_OUTPUT}
-                               }
-                       ""
-                       fragment ""
-                               #version 300 es
-
-                               uniform Block
-                               {
-                                       mediump vec4 val;
-                               };
-
-                               precision mediump float;
-                               ${FRAGMENT_DECLARATIONS}
-                               in mediump float res;
-                               void main()
-                               {
-                                       dEQP_FragColor = val;
-                               }
-                       ""
-               end
-
                case type_mismatch
                        version 300 es
                        expect link_fail
diff --git a/data/gles31/shaders/linkage_uniform.test b/data/gles31/shaders/linkage_uniform.test
new file mode 100644 (file)
index 0000000..2b5ca31
--- /dev/null
@@ -0,0 +1,1562 @@
+group basic "Default block uniforms of scalar and vector types"
+       case precision_conflict_1
+               version 310 es
+               desc "Vertex side uniform has highp, fragment side uniform mediump."
+               expect link_fail
+               values {output float out0 = 3.0;}
+               vertex ""
+                       #version 310 es
+                       ${VERTEX_DECLARATIONS}
+                       uniform highp float u_val;
+                       out mediump float res;
+                       void main()
+                       {
+                               res = u_val;
+                               ${VERTEX_OUTPUT}
+                       }
+               ""
+               fragment ""
+                       #version 310 es
+                       precision mediump float;
+                       uniform float u_val;
+                       ${FRAGMENT_DECLARATIONS}
+                       in mediump float res;
+                       void main()
+                       {
+                               out0 = u_val + res;
+                               ${FRAGMENT_OUTPUT}
+                       }
+               ""
+       end
+       case precision_conflict_2
+               version 310 es
+               desc "Vertex side uniform has highp, fragment side uniform mediump."
+               expect link_fail
+               values {output float out0 = 3.0;}
+               vertex ""
+                       #version 310 es
+                       ${VERTEX_DECLARATIONS}
+                       uniform highp float u_val;
+                       out mediump float res;
+                       void main()
+                       {
+                               res = u_val;
+                               ${VERTEX_OUTPUT}
+                       }
+               ""
+               fragment ""
+                       #version 310 es
+                       precision highp float;
+                       uniform mediump float u_val;
+                       ${FRAGMENT_DECLARATIONS}
+                       in mediump float res;
+                       void main()
+                       {
+                               out0 = u_val + res;
+                               ${FRAGMENT_OUTPUT}
+                       }
+               ""
+       end
+       case precision_conflict_3
+               version 310 es
+               desc "Vertex side uniform has lowp, fragment side uniform highp."
+               expect link_fail
+               values {output float out0 = 3.0;}
+               vertex ""
+                       #version 310 es
+                       ${VERTEX_DECLARATIONS}
+                       uniform lowp int u_val;
+                       out mediump float res;
+                       void main()
+                       {
+                               res = float(u_val);
+                               ${VERTEX_OUTPUT}
+                       }
+               ""
+               fragment ""
+                       #version 310 es
+                       precision highp float;
+                       uniform highp int u_val;
+                       ${FRAGMENT_DECLARATIONS}
+                       in mediump float res;
+                       void main()
+                       {
+                               out0 = float(u_val) + res;
+                               ${FRAGMENT_OUTPUT}
+                       }
+               ""
+       end
+       case precision_conflict_4
+               version 310 es
+               desc "Vertex side uniform has lowp, fragment side uniform mediump."
+               expect link_fail
+               values {output float out0 = 3.0;}
+               vertex ""
+                       #version 310 es
+                       ${VERTEX_DECLARATIONS}
+                       uniform lowp vec3 u_val;
+                       out mediump float res;
+                       void main()
+                       {
+                               res = u_val.y;
+                               ${VERTEX_OUTPUT}
+                       }
+               ""
+               fragment ""
+                       #version 310 es
+                       precision highp float;
+                       uniform mediump vec3 u_val;
+                       ${FRAGMENT_DECLARATIONS}
+                       in mediump float res;
+                       void main()
+                       {
+                               out0 = u_val.z + res;
+                               ${FRAGMENT_OUTPUT}
+                       }
+               ""
+       end
+end
+
+group struct "Uniform structs"
+       # Struct linkage handling
+       case basic
+               version 310 es
+               desc "Same uniform struct in both shaders"
+               values {
+                       uniform float val.a = 1.0;
+                       uniform float val.b = 2.0;
+                       output float out0 = 3.0;
+               }
+               vertex ""
+                       #version 310 es
+                       ${VERTEX_DECLARATIONS}
+                       struct Struct {mediump float a; mediump float b;};
+                       uniform Struct val;
+                       out mediump float dummy;
+                       void main()
+                       {
+                               dummy = val.a + val.b;
+                               ${VERTEX_OUTPUT}
+                       }
+               ""
+               fragment ""
+                       #version 310 es
+                       precision mediump float;
+                       struct Struct {mediump float a; mediump float b;};
+                       uniform Struct val;
+                       in mediump float dummy;
+                       ${FRAGMENT_DECLARATIONS}
+                       void main()
+                       {
+                               out0 = val.b + val.a;
+                               out0 = out0 + dummy;
+                               out0 = out0 - dummy;
+                               ${FRAGMENT_OUTPUT}
+                       }
+               ""
+       end
+
+       case vertex_only
+               version 310 es
+               desc "Uniform struct declared in both, used only in vertex."
+               values {
+                       uniform float val.a = 1.0;
+                       uniform float val.b = 2.0;
+                       output float out0 = 3.0;
+               }
+               vertex ""
+                       #version 310 es
+                       ${VERTEX_DECLARATIONS}
+                       struct Struct {mediump float a; mediump float b;};
+                       uniform Struct val;
+                       out mediump float res;
+                       void main()
+                       {
+                               res = val.a + val.b;
+                               ${VERTEX_OUTPUT}
+                       }
+               ""
+               fragment ""
+                       #version 310 es
+                       precision mediump float;
+                       struct Struct {mediump float a; mediump float b;};
+                       uniform Struct val;
+                       in mediump float res;
+                       ${FRAGMENT_DECLARATIONS}
+                       void main()
+                       {
+                               out0 = res;
+                               ${FRAGMENT_OUTPUT}
+                       }
+               ""
+       end
+
+       case fragment_only
+               version 310 es
+               desc "Uniform struct declared in both, used only in fragment."
+               values {
+                       uniform float val.a = 1.0;
+                       uniform float val.b = 2.0;
+                       output float out0 = 3.0;
+               }
+               vertex ""
+                       #version 310 es
+                       ${VERTEX_DECLARATIONS}
+                       struct Struct {mediump float a; mediump float b;};
+                       uniform Struct val;
+                       void main()
+                       {
+                               ${VERTEX_OUTPUT}
+                       }
+               ""
+               fragment ""
+                       #version 310 es
+                       precision mediump float;
+                       struct Struct {mediump float a; mediump float b;};
+                       uniform Struct val;
+                       ${FRAGMENT_DECLARATIONS}
+                       void main()
+                       {
+                               out0 = val.a + val.b;
+                               ${FRAGMENT_OUTPUT}
+                       }
+               ""
+       end
+
+       case partial
+               version 310 es
+               desc "Uniform struct declared in both, used partially in both."
+               values {
+                       uniform float val.a = 1.0;
+                       uniform float val.b = 2.0;
+                       output float out0 = 3.0;
+               }
+               vertex ""
+                       #version 310 es
+                       ${VERTEX_DECLARATIONS}
+                       struct Struct {mediump float a; mediump float b;};
+                       uniform Struct val;
+                       out mediump float res;
+                       void main()
+                       {
+                               res = val.a;
+                               ${VERTEX_OUTPUT}
+                       }
+               ""
+               fragment ""
+                       #version 310 es
+                       precision mediump float;
+                       struct Struct {mediump float a; mediump float b;};
+                       uniform Struct val;
+                       ${FRAGMENT_DECLARATIONS}
+                       in mediump float res;
+                       void main()
+                       {
+                               out0 = res + val.b;
+                               ${FRAGMENT_OUTPUT}
+                       }
+               ""
+       end
+
+       case vec4
+               version 310 es
+               desc "Same uniform struct in both shaders. Datatype vec4"
+               values {
+                       uniform vec4 val.a = vec4(1.0, 2.0, 3.0, 4.0);
+                       uniform vec4 val.b = vec4(1.0, 2.0, 3.0, 4.0);
+                       output float out0 = 3.0;
+               }
+               vertex ""
+                       #version 310 es
+                       ${VERTEX_DECLARATIONS}
+                       struct Struct {mediump vec4 a; mediump vec4 b;};
+                       uniform Struct val;
+                       out mediump float dummy;
+                       void main()
+                       {
+                               dummy = val.a.x + val.b.y;
+                               ${VERTEX_OUTPUT}
+                       }
+               ""
+               fragment ""
+                       #version 310 es
+                       precision mediump float;
+                       struct Struct {mediump vec4 a; mediump vec4 b;};
+                       uniform Struct val;
+                       in mediump float dummy;
+                       ${FRAGMENT_DECLARATIONS}
+                       void main()
+                       {
+                               out0 = val.b.y + val.a.x;
+                               out0 = out0 + dummy;
+                               out0 = out0 - dummy;
+                               ${FRAGMENT_OUTPUT}
+                       }
+               ""
+       end
+
+       case vertex_only_vec4
+               version 310 es
+               desc "Uniform struct declared in both, used only in vertex. Datatype vec4       "
+               values {
+                       uniform vec4 val.a = vec4(1.0, 2.0, 3.0, 4.0);
+                       uniform vec4 val.b = vec4(1.0, 2.0, 3.0, 4.0);
+                       output float out0 = 3.0;
+               }
+               vertex ""
+                       #version 310 es
+                       ${VERTEX_DECLARATIONS}
+                       struct Struct {mediump vec4 a; mediump vec4 b;};
+                       uniform Struct val;
+                       out mediump float res;
+                       void main()
+                       {
+                               res = val.a.x + val.b.y;
+                               ${VERTEX_OUTPUT}
+                       }
+               ""
+               fragment ""
+                       #version 310 es
+                       precision mediump float;
+                       struct Struct {mediump vec4 a; mediump vec4 b;};
+                       uniform Struct val;
+                       in mediump float res;
+                       ${FRAGMENT_DECLARATIONS}
+                       void main()
+                       {                       out0 = res;
+                               ${FRAGMENT_OUTPUT}
+                       }
+               ""
+       end
+
+       case fragment_only_vec4
+               version 310 es
+               desc "Uniform struct declared in both, used only in fragment. Datatype vec4"
+               values {
+                       uniform vec4 val.a = vec4(1.0, 2.0, 3.0, 4.0);
+                       uniform vec4 val.b = vec4(1.0, 2.0, 3.0, 4.0);
+                       output float out0 = 3.0;
+               }
+               vertex ""
+                       #version 310 es
+                       ${VERTEX_DECLARATIONS}
+                       struct Struct {mediump vec4 a; mediump vec4 b;};
+                       uniform Struct val;
+                       void main()
+                       {
+                               ${VERTEX_OUTPUT}
+                       }
+               ""
+               fragment ""
+                       #version 310 es
+                       precision mediump float;
+                       struct Struct {mediump vec4 a; mediump vec4 b;};
+                       uniform Struct val;
+                       ${FRAGMENT_DECLARATIONS}
+                       void main()
+                       {                       out0 = val.a.x + val.b.y;
+                               ${FRAGMENT_OUTPUT}
+                       }
+               ""
+       end
+
+       case partial_vec4
+               version 310 es
+               desc "Uniform struct declared in both, used partially in both. Datatype vec4"
+               values {
+                       uniform vec4 val.a = vec4(1.0, 2.0, 3.0, 4.0);
+                       uniform vec4 val.b = vec4(1.0, 2.0, 3.0, 4.0);
+                       output float out0 = 3.0;
+               }
+               vertex ""
+                       #version 310 es
+                       ${VERTEX_DECLARATIONS}
+                       struct Struct {mediump vec4 a; mediump vec4 b;};
+                       uniform Struct val;
+                       out mediump float res;
+                       void main()
+                       {
+                               res = val.a.x;
+                               ${VERTEX_OUTPUT}
+                       }
+               ""
+               fragment ""
+                       #version 310 es
+                       precision mediump float;
+                       struct Struct {mediump vec4 a; mediump vec4 b;};
+                       uniform Struct val;
+                       ${FRAGMENT_DECLARATIONS}
+                       in mediump float res;
+                       void main()
+                       {                       out0 = res + val.b.y;
+                               ${FRAGMENT_OUTPUT}
+                       }
+               ""
+       end
+
+       case vec4_vec3
+               version 310 es
+               desc "Same uniform struct in both shaders. Datatype vec4 and vec3"
+               values {
+                       uniform vec4 val.a = vec4(1.0, 2.0, 3.0, 4.0);
+                       uniform vec3 val.b = vec3(1.0, 2.0, 3.0);
+                       output float out0 = 3.0;
+               }
+               vertex ""
+                       #version 310 es
+                       ${VERTEX_DECLARATIONS}
+                       struct Struct {mediump vec4 a; mediump vec3 b;};
+                       uniform Struct val;
+                       out mediump float dummy;
+                       void main()
+                       {
+                               dummy = val.a.x + val.b.y;
+                               ${VERTEX_OUTPUT}
+                       }
+               ""
+               fragment ""
+                       #version 310 es
+                       precision mediump float;
+                       struct Struct {mediump vec4 a; mediump vec3 b;};
+                       uniform Struct val;
+                       in mediump float dummy;
+                       ${FRAGMENT_DECLARATIONS}
+                       void main()
+                       {                       out0 = val.b.y + val.a.x;
+                               out0 = out0 + dummy;
+                               out0 = out0 - dummy;
+                               ${FRAGMENT_OUTPUT}
+                       }
+               ""
+       end
+
+       case vertex_only_vec4_vec3
+               version 310 es
+               desc "Uniform struct declared in both, used only in vertex. Datatype vec4 and vec3"
+               values {
+                       uniform vec4 val.a = vec4(1.0, 2.0, 3.0, 4.0);
+                       uniform vec3 val.b = vec3(1.0, 2.0, 3.0);
+                       output float out0 = 3.0;
+               }
+               vertex ""
+                       #version 310 es
+                       ${VERTEX_DECLARATIONS}
+                       struct Struct {mediump vec4 a; mediump vec3 b;};
+                       uniform Struct val;
+                       out mediump float res;
+                       void main()
+                       {
+                               res = val.a.x + val.b.y;
+                               ${VERTEX_OUTPUT}
+                       }
+               ""
+               fragment ""
+                       #version 310 es
+                       precision mediump float;
+                       struct Struct {mediump vec4 a; mediump vec3 b;};
+                       uniform Struct val;
+                       in mediump float res;
+                       ${FRAGMENT_DECLARATIONS}
+                       void main()
+                       {                       out0 = res;
+                               ${FRAGMENT_OUTPUT}
+                       }
+               ""
+       end
+
+       case fragment_only_vec4_vec3
+               version 310 es
+               desc "Uniform struct declared in both, used only in fragment. Datatype vec4 and vec3"
+               values {
+                       uniform vec4 val.a = vec4(1.0, 2.0, 3.0, 4.0);
+                       uniform vec3 val.b = vec3(1.0, 2.0, 3.0);
+                       output float out0 = 3.0;
+               }
+               vertex ""
+                       #version 310 es
+                       ${VERTEX_DECLARATIONS}
+                       struct Struct {mediump vec4 a; mediump vec3 b;};
+                       uniform Struct val;
+                       void main()
+                       {
+                               ${VERTEX_OUTPUT}
+                       }
+               ""
+               fragment ""
+                       #version 310 es
+                       precision mediump float;
+                       struct Struct {mediump vec4 a; mediump vec3 b;};
+                       uniform Struct val;
+                       ${FRAGMENT_DECLARATIONS}
+                       void main()
+                       {                       out0 = val.a.x + val.b.y;
+                               ${FRAGMENT_OUTPUT}
+                       }
+               ""
+       end
+
+       case partial_vec4_vec3
+               version 310 es
+               desc "Uniform struct declared in both, used partially in both. Datatype vec4 and vec3"
+               values {
+                       uniform vec4 val.a = vec4(1.0, 2.0, 3.0, 4.0);
+                       uniform vec3 val.b = vec3(1.0, 2.0, 3.0);
+                       output float out0 = 3.0;
+               }
+               vertex ""
+                       #version 310 es
+                       ${VERTEX_DECLARATIONS}
+                       struct Struct {mediump vec4 a; mediump vec3 b;};
+                       uniform Struct val;
+                       out mediump float res;
+                       void main()
+                       {
+                               res = val.a.x;
+                               ${VERTEX_OUTPUT}
+                       }
+               ""
+               fragment ""
+                       #version 310 es
+                       precision mediump float;
+                       struct Struct {mediump vec4 a; mediump vec3 b;};
+                       uniform Struct val;
+                       ${FRAGMENT_DECLARATIONS}
+                       in mediump float res;
+                       void main()
+                       {                       out0 = res + val.b.y;
+                               ${FRAGMENT_OUTPUT}
+                       }
+               ""
+       end
+
+       case vec4_float
+               version 310 es
+               desc "Same uniform struct in both shaders. Datatype vec4 and float"
+               values {
+                       uniform vec4 val.a = vec4(1.0, 2.0, 3.0, 4.0);
+                       uniform float val.b = 2.0;
+                       output float out0 = 3.0;
+               }
+               vertex ""
+                       #version 310 es
+                       ${VERTEX_DECLARATIONS}
+                       struct Struct {mediump vec4 a; mediump float b;};
+                       uniform Struct val;
+                       out mediump float dummy;
+                       void main()
+                       {
+                               dummy = val.a.x + val.b;
+                               ${VERTEX_OUTPUT}
+                       }
+               ""
+               fragment ""
+                       #version 310 es
+                       precision mediump float;
+                       struct Struct {mediump vec4 a; mediump float b;};
+                       uniform Struct val;
+                       in mediump float dummy;
+                       ${FRAGMENT_DECLARATIONS}
+                       void main()
+                       {                       out0 = val.b + val.a.x;
+                               out0 = out0 + dummy;
+                               out0 = out0 - dummy;
+                               ${FRAGMENT_OUTPUT}
+                       }
+               ""
+       end
+
+       case vertex_only_vec4_float
+               version 310 es
+               desc "Uniform struct declared in both, used only in vertex. Datatype vec4 and float"
+               values {
+                       uniform vec4 val.a = vec4(1.0, 2.0, 3.0, 4.0);
+                       uniform float val.b = 2.0;
+                       output float out0 = 3.0;
+               }
+               vertex ""
+                       #version 310 es
+                       ${VERTEX_DECLARATIONS}
+                       struct Struct {mediump vec4 a; mediump float b;};
+                       uniform Struct val;
+                       out mediump float res;
+                       void main()
+                       {
+                               res = val.a.x + val.b;
+                               ${VERTEX_OUTPUT}
+                       }
+               ""
+               fragment ""
+                       #version 310 es
+                       precision mediump float;
+                       struct Struct {mediump vec4 a; mediump float b;};
+                       uniform Struct val;
+                       in mediump float res;
+                       ${FRAGMENT_DECLARATIONS}
+                       void main()
+                       {                       out0 = res;
+                               ${FRAGMENT_OUTPUT}
+                       }
+               ""
+       end
+
+       case fragment_only_vec4_float
+               version 310 es
+               desc "Uniform struct declared in both, used only in fragment. Datatype vec4 and float"
+               values {
+                       uniform vec4 val.a = vec4(1.0, 2.0, 3.0, 4.0);
+                       uniform float val.b = 2.0;
+                       output float out0 = 3.0;
+               }
+               vertex ""
+                       #version 310 es
+                       ${VERTEX_DECLARATIONS}
+                       struct Struct {mediump vec4 a; mediump float b;};
+                       uniform Struct val;
+                       void main()
+                       {
+                               ${VERTEX_OUTPUT}
+                       }
+               ""
+               fragment ""
+                       #version 310 es
+                       precision mediump float;
+                       struct Struct {mediump vec4 a; mediump float b;};
+                       uniform Struct val;
+                       ${FRAGMENT_DECLARATIONS}
+                       void main()
+                       {                       out0 = val.a.x + val.b;
+                               ${FRAGMENT_OUTPUT}
+                       }
+               ""
+       end
+
+       case partial_vec4_float
+               version 310 es
+               desc "Uniform struct declared in both, used partially in both. Datatype vec4 and float"
+               values {
+                       uniform vec4 val.a = vec4(1.0, 2.0, 3.0, 4.0);
+                       uniform float val.b = 2.0;
+                       output float out0 = 3.0;
+               }
+               vertex ""
+                       #version 310 es
+                       ${VERTEX_DECLARATIONS}
+                       struct Struct {mediump vec4 a; mediump float b;};
+                       uniform Struct val;
+                       out mediump float res;
+                       void main()
+                       {
+                               res = val.a.x;
+                               ${VERTEX_OUTPUT}
+                       }
+               ""
+               fragment ""
+                       #version 310 es
+                       precision mediump float;
+                       struct Struct {mediump vec4 a; mediump float b;};
+                       uniform Struct val;
+                       ${FRAGMENT_DECLARATIONS}
+                       in mediump float res;
+                       void main()
+                       {                       out0 = res + val.b;
+                               ${FRAGMENT_OUTPUT}
+                       }
+               ""
+       end
+
+       case partial_vec4_struct
+               version 310 es
+               desc "Uniform struct declared in both, used partially in both. Datatype vec4 and struct with vec4"
+               values {
+                       uniform vec4 val.a = vec4(1.0, 2.0, 3.0, 4.0);
+                       uniform vec4 val.b.c = vec4(1.0, 2.0, 3.0, 4.0);
+                       output float out0 = 3.0;
+               }
+               vertex ""
+                       #version 310 es
+                       ${VERTEX_DECLARATIONS}
+                       struct Inner {mediump vec4 c;};
+                       struct Struct {mediump vec4 a; Inner b;};
+                       uniform Struct val;
+                       out mediump float res;
+                       void main()
+                       {
+                               res = val.a.x;
+                               ${VERTEX_OUTPUT}
+                       }
+               ""
+               fragment ""
+                       #version 310 es
+                       precision mediump float;
+                       struct Inner {mediump vec4 c;};
+                       struct Struct {mediump vec4 a; Inner b;};
+                       uniform Struct val;
+                       ${FRAGMENT_DECLARATIONS}
+                       in mediump float res;
+                       void main()
+                       {                       out0 = res + val.b.c.y;
+                               ${FRAGMENT_OUTPUT}
+                       }
+               ""
+       end
+
+       case partial_vec4_vec3_struct
+               version 310 es
+               desc "Uniform struct declared in both, used partially in both. Datatype vec4 and struct with vec3"
+               values {
+                       uniform vec4 val.a = vec4(1.0, 2.0, 3.0, 4.0);
+                       uniform vec3 val.b.c = vec3(1.0, 2.0, 3.0);
+                       output float out0 = 3.0;
+               }
+               vertex ""
+                       #version 310 es
+                       ${VERTEX_DECLARATIONS}
+                       struct Inner {mediump vec3 c;};
+                       struct Struct {mediump vec4 a; Inner b;};
+                       uniform Struct val;
+                       out mediump float res;
+                       void main()
+                       {
+                               res = val.a.x;
+                               ${VERTEX_OUTPUT}
+                       }
+               ""
+               fragment ""
+                       #version 310 es
+                       precision mediump float;
+                       struct Inner {mediump vec3 c;};
+                       struct Struct {mediump vec4 a; Inner b;};
+                       uniform Struct val;
+                       ${FRAGMENT_DECLARATIONS}
+                       in mediump float res;
+                       void main()
+                       {                       out0 = res + val.b.c.y;
+                               ${FRAGMENT_OUTPUT}
+                       }
+               ""
+       end
+
+       case partial_vec2_vec3
+               version 310 es
+               desc "Uniform struct declared in both, used partially in both. Datatype vec2 and vec3"
+               values {
+                       uniform vec2 val.a = vec2(1.0, 2.0);
+                       uniform vec3 val.b = vec3(1.0, 2.0, 3.0);
+                       output float out0 = 3.0;
+               }
+               vertex ""
+                       #version 310 es
+                       ${VERTEX_DECLARATIONS}
+                       struct Struct {mediump vec2 a; mediump vec3 b;};
+                       uniform Struct val;
+                       out mediump float res;
+                       void main()
+                       {
+                               res = val.a.x;
+                               ${VERTEX_OUTPUT}
+                       }
+               ""
+               fragment ""
+                       #version 310 es
+                       precision mediump float;
+                       struct Struct {mediump vec2 a; mediump vec3 b;};
+                       uniform Struct val;
+                       ${FRAGMENT_DECLARATIONS}
+                       in mediump float res;
+                       void main()
+                       {                       out0 = res + val.b.y;
+                               ${FRAGMENT_OUTPUT}
+                       }
+               ""
+       end
+
+       case partial_vec2_int
+               version 310 es
+               desc "Uniform struct declared in both, used partially in both. Datatype vec2 and int"
+               values {
+                       uniform vec2 val.a = vec2(1.0, 2.0);
+                       uniform int val.b = 2;
+                       output float out0 = 3.0;
+               }
+               vertex ""
+                       #version 310 es
+                       ${VERTEX_DECLARATIONS}
+                       struct Struct {mediump vec2 a; mediump int b;};
+                       uniform Struct val;
+                       out mediump float res;
+                       void main()
+                       {
+                               res = val.a.x;
+                               ${VERTEX_OUTPUT}
+                       }
+               ""
+               fragment ""
+                       #version 310 es
+                       precision mediump float;
+                       struct Struct {mediump vec2 a; mediump int b;};
+                       uniform Struct val;
+                       ${FRAGMENT_DECLARATIONS}
+                       in mediump float res;
+                       void main()
+                       {                       out0 = res + float(val.b);
+                               ${FRAGMENT_OUTPUT}
+                       }
+               ""
+       end
+
+       case partial_int_float
+               version 310 es
+               desc "Uniform struct declared in both, used partially in both. Datatype int and float"
+               values {
+                       uniform float val.a = 1.0;
+                       uniform int val.b = 2;
+                       output float out0 = 3.0;
+               }
+               vertex ""
+                       #version 310 es
+                       ${VERTEX_DECLARATIONS}
+                       struct Struct {mediump float a; mediump int b;};
+                       uniform Struct val;
+                       out mediump float res;
+                       void main()
+                       {
+                               res = val.a;
+                               ${VERTEX_OUTPUT}
+                       }
+               ""
+               fragment ""
+                       #version 310 es
+                       precision mediump float;
+                       struct Struct {mediump float a; mediump int b;};
+                       uniform Struct val;
+                       ${FRAGMENT_DECLARATIONS}
+                       in mediump float res;
+                       void main()
+                       {                       out0 = res + float(val.b);
+                               ${FRAGMENT_OUTPUT}
+                       }
+               ""
+       end
+
+       case partial_bvec2_vec2
+               version 310 es
+               desc "Uniform struct declared in both, used partially in both. Datatype bvec2 and vec2"
+               values {
+                       uniform bvec2 val.a = bvec2(true, true);
+                       uniform vec2 val.b = vec2(1.0, 2.0);
+                       output float out0 = 3.0;
+               }
+               vertex ""
+                       #version 310 es
+                       ${VERTEX_DECLARATIONS}
+                       struct Struct {bvec2 a; mediump vec2 b;};
+                       uniform Struct val;
+                       out mediump float res;
+                       void main()
+                       {
+                               res = float(val.a.x);
+                               ${VERTEX_OUTPUT}
+                       }
+               ""
+               fragment ""
+                       #version 310 es
+                       precision mediump float;
+                       struct Struct {bvec2 a; mediump vec2 b;};
+                       uniform Struct val;
+                       ${FRAGMENT_DECLARATIONS}
+                       in mediump float res;
+                       void main()
+                       {                       out0 = res + val.b.y;
+                               ${FRAGMENT_OUTPUT}
+                       }
+               ""
+       end
+
+       case partial_ivec2_vec2
+               version 310 es
+               desc "Uniform struct declared in both, used partially in both. Datatype ivec2 and vec2"
+               values {
+                       uniform ivec2 val.a = ivec2(1, 2);
+                       uniform vec2 val.b = vec2(1.0, 2.0);
+                       output float out0 = 3.0;
+               }
+               vertex ""
+                       #version 310 es
+                       ${VERTEX_DECLARATIONS}
+                       struct Struct {mediump ivec2 a; mediump vec2 b;};
+                       uniform Struct val;
+                       out mediump float res;
+                       void main()
+                       {
+                               res = vec2(val.a).x;
+                               ${VERTEX_OUTPUT}
+                       }
+               ""
+               fragment ""
+                       #version 310 es
+                       precision mediump float;
+                       struct Struct {mediump ivec2 a; mediump vec2 b;};
+                       uniform Struct val;
+                       ${FRAGMENT_DECLARATIONS}
+                       in mediump float res;
+                       void main()
+                       {                       out0 = res + val.b.y;
+                               ${FRAGMENT_OUTPUT}
+                       }
+               ""
+       end
+
+       case partial_ivec2_ivec2
+               version 310 es
+               desc "Uniform struct declared in both, used partially in both. Datatype ivec2 and ivec2"
+               values {
+                       uniform ivec2 val.a = ivec2(1, 2);
+                       uniform ivec2 val.b = ivec2(1, 2);
+                       output float out0 = 3.0;
+               }
+               vertex ""
+                       #version 310 es
+                       ${VERTEX_DECLARATIONS}
+                       struct Struct {mediump ivec2 a; mediump ivec2 b;};
+                       uniform Struct val;
+                       out mediump float res;
+                       void main()
+                       {
+                               res = vec2(val.a).x;
+                               ${VERTEX_OUTPUT}
+                       }
+               ""
+               fragment ""
+                       #version 310 es
+                       precision mediump float;
+                       struct Struct {mediump ivec2 a; mediump ivec2 b;};
+                       uniform Struct val;
+                       ${FRAGMENT_DECLARATIONS}
+                       in mediump float res;
+                       void main()
+                       {                       out0 = res + vec2(val.b).y;
+                               ${FRAGMENT_OUTPUT}
+                       }
+               ""
+       end
+
+       case type_conflict_1
+               version 310 es
+               desc "Fragment struct has one less member than fragment version"
+               expect link_fail
+               values {output float out0 = 3.0;}
+               vertex ""
+                       #version 310 es
+                       ${VERTEX_DECLARATIONS}
+                       struct Struct {mediump float a; mediump float b;};
+                       uniform Struct val;
+                       out mediump float res;
+                       void main()
+                       {
+                               res = val.a;
+                               ${VERTEX_OUTPUT}
+                       }
+               ""
+               fragment ""
+                       #version 310 es
+                       precision mediump float;
+                       struct Struct {mediump float a;};
+                       uniform Struct val;
+                       ${FRAGMENT_DECLARATIONS}
+                       in mediump float res;
+                       void main()
+                       {                       out0 = res + val.a;
+                               ${FRAGMENT_OUTPUT}
+                       }
+               ""
+       end
+
+       case type_conflict_2
+               version 310 es
+               desc "Vertex struct has int, fragment struct has float."
+               expect link_fail
+               values {output float out0 = 3.0;}
+               vertex ""
+                       #version 310 es
+                       ${VERTEX_DECLARATIONS}
+                       struct Struct {mediump int a;};
+                       uniform Struct val;
+                       out mediump float res;
+                       void main()
+                       {
+                               res = float(val.a);
+                               ${VERTEX_OUTPUT}
+                       }
+               ""
+               fragment ""
+                       #version 310 es
+                       precision mediump float;
+                       struct Struct {mediump float a;};
+                       uniform Struct val;
+                       ${FRAGMENT_DECLARATIONS}
+                       in mediump float res;
+                       void main()
+                       {                       out0 = val.a;
+                               ${FRAGMENT_OUTPUT}
+                       }
+               ""
+       end
+
+       case type_conflict_3
+               version 310 es
+               desc "Vertex struct has vec3, fragment struct has vec4."
+               expect link_fail
+               values {output float out0 = 3.0;}
+               vertex ""
+                       #version 310 es
+                       ${VERTEX_DECLARATIONS}
+                       struct Struct {mediump vec3 a;};
+                       uniform Struct val;
+                       out mediump float res;
+                       void main()
+                       {
+                               res = float(val.a.x);
+                               ${VERTEX_OUTPUT}
+                       }
+               ""
+               fragment ""
+                       #version 310 es
+                       precision mediump float;
+                       struct Struct {mediump vec4 a;};
+                       uniform Struct val;
+                       ${FRAGMENT_DECLARATIONS}
+                       in mediump float res;
+                       void main()
+                       {                       out0 = val.a.x;
+                               ${FRAGMENT_OUTPUT}
+                       }
+               ""
+       end
+
+       case precision_conflict_1
+               version 310 es
+               desc "Vertex side struct has highp, fragment side struct mediump."
+               expect link_fail
+               values {output float out0 = 3.0;}
+               vertex ""
+                       #version 310 es
+                       ${VERTEX_DECLARATIONS}
+                       struct Struct {highp float a;};
+                       uniform Struct val;
+                       out mediump float res;
+                       void main()
+                       {
+                               res = val.a;
+                               ${VERTEX_OUTPUT}
+                       }
+               ""
+               fragment ""
+                       #version 310 es
+                       precision mediump float;
+                       struct Struct {mediump float a;};
+                       uniform Struct val;
+                       ${FRAGMENT_DECLARATIONS}
+                       in mediump float res;
+                       void main()
+                       {                       out0 = val.a;
+                               ${FRAGMENT_OUTPUT}
+                       }
+               ""
+       end
+
+       case precision_conflict_2
+               version 310 es
+               desc "Vertex side struct has mediump, fragment side struct lowp."
+               expect link_fail
+               values {output float out0 = 3.0;}
+               vertex ""
+                       #version 310 es
+                       ${VERTEX_DECLARATIONS}
+                       struct Struct {mediump float a;};
+                       uniform Struct val;
+                       out mediump float res;
+                       void main()
+                       {
+                               res = val.a;
+                               ${VERTEX_OUTPUT}
+                       }
+               ""
+               fragment ""
+                       #version 310 es
+                       precision mediump float;
+                       struct Struct {lowp float a;};
+                       uniform Struct val;
+                       ${FRAGMENT_DECLARATIONS}
+                       in mediump float res;
+                       void main()
+                       {                       out0 = val.a;
+                               ${FRAGMENT_OUTPUT}
+                       }
+               ""
+       end
+
+       case precision_conflict_3
+               version 310 es
+               desc "Vertex side struct has lowp, fragment side struct mediump."
+               expect link_fail
+               values {output float out0 = 3.0;}
+               vertex ""
+                       #version 310 es
+                       ${VERTEX_DECLARATIONS}
+                       struct Struct {lowp float a;};
+                       uniform Struct val;
+                       out mediump float res;
+                       void main()
+                       {
+                               res = val.a;
+                               ${VERTEX_OUTPUT}
+                       }
+               ""
+               fragment ""
+                       #version 310 es
+                       precision mediump float;
+                       struct Struct {mediump float a;};
+                       uniform Struct val;
+                       ${FRAGMENT_DECLARATIONS}
+                       in mediump float res;
+                       void main()
+                       {                       out0 = val.a;
+                               ${FRAGMENT_OUTPUT}
+                       }
+               ""
+       end
+
+       case precision_conflict_4
+               version 310 es
+               desc "Vertex side struct has lowp, fragment side struct implicit mediump."
+               expect link_fail
+               values {output float out0 = 3.0;}
+               vertex ""
+                       #version 310 es
+                       ${VERTEX_DECLARATIONS}
+                       struct Struct {lowp float a;};
+                       uniform Struct val;
+                       out mediump float res;
+                       void main()
+                       {
+                               res = val.a;
+                               ${VERTEX_OUTPUT}
+                       }
+               ""
+               fragment ""
+                       #version 310 es
+                       precision mediump float;
+                       struct Struct {float a;};
+                       uniform Struct val;
+                       ${FRAGMENT_DECLARATIONS}
+                       in mediump float res;
+                       void main()
+                       {                       out0 = val.a;
+                               ${FRAGMENT_OUTPUT}
+                       }
+               ""
+       end
+
+       case light_struct_highp
+               version 310 es
+               desc "Complex Light struct from use case tests."
+               values {
+                       uniform float val.constantAttenuation = 1.0;
+                       uniform float val.quadraticAttenuation = 1.0;
+                       output float out0 = 2.0;
+               }
+               vertex ""
+                       #version 310 es
+                       struct Light
+                       {
+                               mediump vec3    color;
+                               highp vec4              position;
+                               highp vec3              direction;
+                               mediump float   constantAttenuation;
+                               mediump float   linearAttenuation;
+                               mediump float   quadraticAttenuation;
+                       };
+                       ${VERTEX_DECLARATIONS}
+                       uniform Light val;
+                       out mediump float res;
+                       void main()
+                       {
+                               res = val.constantAttenuation;
+                               ${VERTEX_OUTPUT}
+                       }
+               ""
+               fragment ""
+                       #version 310 es
+                       precision mediump float;
+                       struct Light
+                       {
+                               mediump vec3    color;
+                               highp vec4              position;
+                               highp vec3              direction;
+                               mediump float   constantAttenuation;
+                               mediump float   linearAttenuation;
+                               mediump float   quadraticAttenuation;
+                       };
+                       struct Struct {float a;};
+                       uniform Light val;
+                       ${FRAGMENT_DECLARATIONS}
+                       in mediump float res;
+                       void main()
+                       {
+                               out0 = res + val.quadraticAttenuation;
+                               ${FRAGMENT_OUTPUT}
+                       }
+               ""
+       end
+
+       case light_struct_mediump
+               version 310 es
+               desc "Complex Light struct from use case tests, without highp usage"
+               values {
+                       uniform float val.constantAttenuation = 1.0;
+                       uniform float val.quadraticAttenuation = 1.0;
+                       output float out0 = 2.0;
+               }
+               vertex ""
+                       #version 310 es
+                       struct Light
+                       {
+                               mediump vec3    color;
+                               mediump vec4    position;
+                               mediump vec3    direction;
+                               mediump float   constantAttenuation;
+                               mediump float   linearAttenuation;
+                               mediump float   quadraticAttenuation;
+                       };
+                       ${VERTEX_DECLARATIONS}
+                       uniform Light val;
+                       out mediump float res;
+                       void main()
+                       {
+                               res = val.constantAttenuation;
+                               ${VERTEX_OUTPUT}
+                       }
+               ""
+               fragment ""
+                       #version 310 es
+                       precision mediump float;
+                       struct Light
+                       {
+                               mediump vec3    color;
+                               mediump vec4    position;
+                               mediump vec3    direction;
+                               mediump float   constantAttenuation;
+                               mediump float   linearAttenuation;
+                               mediump float   quadraticAttenuation;
+                       };
+                       struct Struct {float a;};
+                       uniform Light val;
+                       ${FRAGMENT_DECLARATIONS}
+                       in mediump float res;
+                       void main()
+                       {
+                               out0 = res + val.quadraticAttenuation;
+                               ${FRAGMENT_OUTPUT}
+                       }
+               ""
+       end
+end
+
+group block "Uniform blocks"
+       case differing_precision
+               version 310 es
+               expect build_successful
+               vertex ""
+                       #version 310 es
+
+                       uniform Block
+                       {
+                               highp vec4 val;
+                       };
+
+                       ${VERTEX_DECLARATIONS}
+                       out mediump float res;
+                       void main()
+                       {
+                               res = val.x;
+                               ${VERTEX_OUTPUT}
+                       }
+               ""
+               fragment ""
+                       #version 310 es
+
+                       uniform Block
+                       {
+                               mediump vec4 val;
+                       };
+
+                       precision mediump float;
+                       ${FRAGMENT_DECLARATIONS}
+                       in mediump float res;
+                       void main()
+                       {
+                               dEQP_FragColor = val;
+                       }
+               ""
+       end
+
+       case type_mismatch
+               version 310 es
+               expect link_fail
+               vertex ""
+                       #version 310 es
+
+                       uniform Block
+                       {
+                               highp vec4 val;
+                       };
+
+                       ${VERTEX_DECLARATIONS}
+                       out mediump float res;
+                       void main()
+                       {
+                               res = val.x;
+                               ${VERTEX_OUTPUT}
+                       }
+               ""
+               fragment ""
+                       #version 310 es
+
+                       uniform Block
+                       {
+                               highp vec3 val;
+                       };
+
+                       precision mediump float;
+                       ${FRAGMENT_DECLARATIONS}
+                       in mediump float res;
+                       void main()
+                       {
+                               dEQP_FragColor = vec4(val, 1.0);
+                       }
+               ""
+       end
+
+       case members_mismatch
+               version 310 es
+               expect link_fail
+               vertex ""
+                       #version 310 es
+
+                       uniform Block
+                       {
+                               highp vec4 val;
+                       };
+
+                       ${VERTEX_DECLARATIONS}
+                       out mediump float res;
+                       void main()
+                       {
+                               res = val.x;
+                               ${VERTEX_OUTPUT}
+                       }
+               ""
+               fragment ""
+                       #version 310 es
+
+                       uniform Block
+                       {
+                               highp vec4 val;
+                               lowp uint u;
+                       };
+
+                       precision mediump float;
+                       ${FRAGMENT_DECLARATIONS}
+                       in mediump float res;
+                       void main()
+                       {
+                               dEQP_FragColor = vec4(val);
+                       }
+               ""
+       end
+
+       case layout_qualifier_mismatch_1
+               version 310 es
+               expect link_fail
+               vertex ""
+                       #version 310 es
+
+                       layout(std140) uniform Block
+                       {
+                               highp vec4 val;
+                       };
+
+                       ${VERTEX_DECLARATIONS}
+                       out mediump float res;
+                       void main()
+                       {
+                               res = val.x;
+                               ${VERTEX_OUTPUT}
+                       }
+               ""
+               fragment ""
+                       #version 310 es
+
+                       uniform Block
+                       {
+                               highp vec4 val;
+                       };
+
+                       precision mediump float;
+                       ${FRAGMENT_DECLARATIONS}
+                       in mediump float res;
+                       void main()
+                       {
+                               dEQP_FragColor = vec4(val);
+                       }
+               ""
+       end
+
+       case layout_qualifier_mismatch_2
+               version 310 es
+               expect link_fail
+               vertex ""
+                       #version 310 es
+
+                       layout(shared) uniform Block
+                       {
+                               highp vec4 val;
+                       };
+
+                       ${VERTEX_DECLARATIONS}
+                       out mediump float res;
+                       void main()
+                       {
+                               res = val.x;
+                               ${VERTEX_OUTPUT}
+                       }
+               ""
+               fragment ""
+                       #version 310 es
+
+                       layout(packed) uniform Block
+                       {
+                               highp vec4 val;
+                       };
+
+                       precision mediump float;
+                       ${FRAGMENT_DECLARATIONS}
+                       in mediump float res;
+                       void main()
+                       {
+                               dEQP_FragColor = vec4(val);
+                       }
+               ""
+       end
+
+       case layout_qualifier_mismatch_3
+               version 310 es
+               expect link_fail
+               vertex ""
+                       #version 310 es
+
+                       layout(row_major) uniform Block
+                       {
+                               highp vec4 val;
+                       };
+
+                       ${VERTEX_DECLARATIONS}
+                       out mediump float res;
+                       void main()
+                       {
+                               res = val.x;
+                               ${VERTEX_OUTPUT}
+                       }
+               ""
+               fragment ""
+                       #version 310 es
+
+                       layout(column_major) uniform Block
+                       {
+                               highp vec4 val;
+                       };
+
+                       precision mediump float;
+                       ${FRAGMENT_DECLARATIONS}
+                       in mediump float res;
+                       void main()
+                       {
+                               dEQP_FragColor = vec4(val);
+                       }
+               ""
+       end
+
+       case layout_qualifier_mismatch_4
+               version 310 es
+               expect link_fail
+               vertex ""
+                       #version 310 es
+
+                       layout(row_major) uniform Block
+                       {
+                               highp mat3 val;
+                       };
+
+                       ${VERTEX_DECLARATIONS}
+                       out mediump float res;
+                       void main()
+                       {
+                               res = val[0][1];
+                               ${VERTEX_OUTPUT}
+                       }
+               ""
+               fragment ""
+                       #version 310 es
+
+                       layout(column_major) uniform Block
+                       {
+                               highp mat3 val;
+                       };
+
+                       precision mediump float;
+                       ${FRAGMENT_DECLARATIONS}
+                       in mediump float res;
+                       void main()
+                       {
+                               dEQP_FragColor = vec4(val[2], 1.0);
+                       }
+               ""
+       end
+
+       case layout_qualifier_mismatch_5
+               version 310 es
+               expect link_fail
+               vertex ""
+                       #version 310 es
+
+                       uniform Block
+                       {
+                               layout(row_major) uniform highp mat3 val;
+                       };
+
+                       ${VERTEX_DECLARATIONS}
+                       out mediump float res;
+                       void main()
+                       {
+                               res = val[0][1];
+                               ${VERTEX_OUTPUT}
+                       }
+               ""
+               fragment ""
+                       #version 310 es
+
+                       uniform Block
+                       {
+                               layout(column_major) uniform highp mat3 val;
+                       };
+
+                       precision mediump float;
+                       ${FRAGMENT_DECLARATIONS}
+                       in mediump float res;
+                       void main()
+                       {
+                               dEQP_FragColor = vec4(val[2], 1.0);
+                       }
+               ""
+       end
+end
index 0bfbcb6..784e70c 100644 (file)
@@ -172,6 +172,7 @@ public:
                addChild(new ShaderLibraryTest(m_context, "linkage_tessellation_geometry.test", "tessellation_geometry", "Tessellation and geometry shader"));
                addChild(new ShaderLibraryTest(m_context, "linkage_shader_storage_block.test", "shader_storage_block", "Shader storage blocks"));
                addChild(new ShaderLibraryTest(m_context, "linkage_io_block.test", "io_block", "Shader io blocks"));
+               addChild(new ShaderLibraryTest(m_context, "linkage_uniform.test", "uniform", "Uniform linkage"));
        }
 };