Add new tessellation negative coverage tests
authorJohn Richardson <john.richardson@mobica.com>
Wed, 9 Nov 2016 08:34:43 +0000 (08:34 +0000)
committerJohn Richardson <john.richardson@mobica.com>
Mon, 30 Jan 2017 16:51:19 +0000 (16:51 +0000)
Test groups added to:
- dEQP-GLES31.functional.shaders.linkage.tessellation.varying.rules
- dEQP-GLES31.functional.shaders.linkage.tessellation.layout_declarations.rules (new)
- dEQP-GLES31.functional.shaders.linkage.tessellation.barriers.rules (new)
- dEQP-GLES31.functional.debug.negative_coverage.*.tessellation (new)

New tests:
- output_non_array
- invalid_patch_in_usage
- invalid_patch_out_usage
- invalid_per_patch_qualifier_usage
- output_block_non_array

- invalid_barrier_usage_within_control_flow
- invalid_barrier_usage_after_return

- primitive_mode_mismatch
- spacing_mode_mismatch
- vertex_order_mismatch
- vertex_count_mismatch

- single_tessellation_stage
- invalid_primitive_mode
- tessellation_not_active
- invalid_program_state
- get_programiv
- invalid_program_queries
- tessellation_control_invalid_vertex_count

Change-Id: I0c4f4b407bfe80e09546af51fdb2d184cf310757

Android.mk
android/cts/master/gles31-master.txt
data/gles31/shaders/linkage_tessellation.test
modules/gles31/functional/CMakeLists.txt
modules/gles31/functional/es31fDebugTests.cpp
modules/gles31/functional/es31fNegativeTessellationTests.cpp [new file with mode: 0644]
modules/gles31/functional/es31fNegativeTessellationTests.hpp [new file with mode: 0644]

index cf95dd8..fa93f8b 100644 (file)
@@ -591,6 +591,7 @@ LOCAL_SRC_FILES := \
        modules/gles31/functional/es31fNegativeShaderImageLoadStoreTests.cpp \
        modules/gles31/functional/es31fNegativeShaderStorageTests.cpp \
        modules/gles31/functional/es31fNegativeStateApiTests.cpp \
+       modules/gles31/functional/es31fNegativeTessellationTests.cpp \
        modules/gles31/functional/es31fNegativeTestShared.cpp \
        modules/gles31/functional/es31fNegativeTextureApiTests.cpp \
        modules/gles31/functional/es31fNegativeVertexArrayApiTests.cpp \
index 5d762d6..0e65aeb 100644 (file)
@@ -4089,12 +4089,17 @@ dEQP-GLES31.functional.shaders.linkage.tessellation.varying.rules.vertex_fragmen
 dEQP-GLES31.functional.shaders.linkage.tessellation.varying.rules.vertex_fragment_same_varying_name_2
 dEQP-GLES31.functional.shaders.linkage.tessellation.varying.rules.invalid_vertex_index
 dEQP-GLES31.functional.shaders.linkage.tessellation.varying.rules.input_non_array
+dEQP-GLES31.functional.shaders.linkage.tessellation.varying.rules.output_non_array
 dEQP-GLES31.functional.shaders.linkage.tessellation.varying.rules.input_array_size_mismatch
 dEQP-GLES31.functional.shaders.linkage.tessellation.varying.rules.internal_array_size_mismatch
+dEQP-GLES31.functional.shaders.linkage.tessellation.varying.rules.invalid_patch_in_usage
+dEQP-GLES31.functional.shaders.linkage.tessellation.varying.rules.invalid_patch_out_usage
+dEQP-GLES31.functional.shaders.linkage.tessellation.varying.rules.invalid_per_patch_qualifier_usage
 dEQP-GLES31.functional.shaders.linkage.tessellation.varying.rules.per_patch_qualifier_mismatch_1
 dEQP-GLES31.functional.shaders.linkage.tessellation.varying.rules.per_patch_qualifier_mismatch_2
 dEQP-GLES31.functional.shaders.linkage.tessellation.varying.rules.input_block
 dEQP-GLES31.functional.shaders.linkage.tessellation.varying.rules.input_block_non_array
+dEQP-GLES31.functional.shaders.linkage.tessellation.varying.rules.output_block_non_array
 dEQP-GLES31.functional.shaders.linkage.tessellation.varying.rules.input_block_array_size_mismatch
 dEQP-GLES31.functional.shaders.linkage.tessellation.varying.rules.output_block
 dEQP-GLES31.functional.shaders.linkage.tessellation.varying.rules.output_block_array
@@ -4158,6 +4163,12 @@ dEQP-GLES31.functional.shaders.linkage.tessellation.uniform.types.uvec2
 dEQP-GLES31.functional.shaders.linkage.tessellation.uniform.types.uvec3
 dEQP-GLES31.functional.shaders.linkage.tessellation.uniform.types.uvec4
 dEQP-GLES31.functional.shaders.linkage.tessellation.uniform.types.float_struct
+dEQP-GLES31.functional.shaders.linkage.tessellation.layout_declarations.rules.primitive_mode_mismatch
+dEQP-GLES31.functional.shaders.linkage.tessellation.layout_declarations.rules.spacing_mode_mismatch
+dEQP-GLES31.functional.shaders.linkage.tessellation.layout_declarations.rules.vertex_order_mismatch
+dEQP-GLES31.functional.shaders.linkage.tessellation.layout_declarations.rules.vertex_count_mismatch
+dEQP-GLES31.functional.shaders.linkage.tessellation.barriers.rules.invalid_barrier_usage_within_control_flow
+dEQP-GLES31.functional.shaders.linkage.tessellation.barriers.rules.invalid_barrier_usage_after_return
 dEQP-GLES31.functional.shaders.linkage.tessellation_geometry.varying.rules.type_mismatch
 dEQP-GLES31.functional.shaders.linkage.tessellation_geometry.varying.rules.different_precision
 dEQP-GLES31.functional.shaders.linkage.tessellation_geometry.varying.rules.no_output_declaration
@@ -16765,6 +16776,13 @@ dEQP-GLES31.functional.debug.negative_coverage.callbacks.advanced_blend.blend_qu
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.advanced_blend.attachment_advanced_equation
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.shader_storage.block_number_limits
 dEQP-GLES31.functional.debug.negative_coverage.callbacks.shader_storage.max_combined_block_number_limit
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.tessellation.single_tessellation_stage
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.tessellation.invalid_primitive_mode
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.tessellation.tessellation_not_active
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.tessellation.invalid_program_state
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.tessellation.get_programiv
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.tessellation.invalid_program_queries
+dEQP-GLES31.functional.debug.negative_coverage.callbacks.tessellation.tessellation_control_invalid_vertex_count
 dEQP-GLES31.functional.debug.negative_coverage.log.buffer.bind_buffer
 dEQP-GLES31.functional.debug.negative_coverage.log.buffer.delete_buffers
 dEQP-GLES31.functional.debug.negative_coverage.log.buffer.gen_buffers
@@ -17213,6 +17231,13 @@ dEQP-GLES31.functional.debug.negative_coverage.log.advanced_blend.blend_qualifie
 dEQP-GLES31.functional.debug.negative_coverage.log.advanced_blend.attachment_advanced_equation
 dEQP-GLES31.functional.debug.negative_coverage.log.shader_storage.block_number_limits
 dEQP-GLES31.functional.debug.negative_coverage.log.shader_storage.max_combined_block_number_limit
+dEQP-GLES31.functional.debug.negative_coverage.log.tessellation.single_tessellation_stage
+dEQP-GLES31.functional.debug.negative_coverage.log.tessellation.invalid_primitive_mode
+dEQP-GLES31.functional.debug.negative_coverage.log.tessellation.tessellation_not_active
+dEQP-GLES31.functional.debug.negative_coverage.log.tessellation.invalid_program_state
+dEQP-GLES31.functional.debug.negative_coverage.log.tessellation.get_programiv
+dEQP-GLES31.functional.debug.negative_coverage.log.tessellation.invalid_program_queries
+dEQP-GLES31.functional.debug.negative_coverage.log.tessellation.tessellation_control_invalid_vertex_count
 dEQP-GLES31.functional.debug.negative_coverage.get_error.buffer.bind_buffer
 dEQP-GLES31.functional.debug.negative_coverage.get_error.buffer.delete_buffers
 dEQP-GLES31.functional.debug.negative_coverage.get_error.buffer.gen_buffers
@@ -17659,6 +17684,13 @@ dEQP-GLES31.functional.debug.negative_coverage.get_error.advanced_blend.blend_qu
 dEQP-GLES31.functional.debug.negative_coverage.get_error.advanced_blend.attachment_advanced_equation
 dEQP-GLES31.functional.debug.negative_coverage.get_error.shader_storage.block_number_limits
 dEQP-GLES31.functional.debug.negative_coverage.get_error.shader_storage.max_combined_block_number_limit
+dEQP-GLES31.functional.debug.negative_coverage.get_error.tessellation.single_tessellation_stage
+dEQP-GLES31.functional.debug.negative_coverage.get_error.tessellation.invalid_primitive_mode
+dEQP-GLES31.functional.debug.negative_coverage.get_error.tessellation.tessellation_not_active
+dEQP-GLES31.functional.debug.negative_coverage.get_error.tessellation.invalid_program_state
+dEQP-GLES31.functional.debug.negative_coverage.get_error.tessellation.get_programiv
+dEQP-GLES31.functional.debug.negative_coverage.get_error.tessellation.invalid_program_queries
+dEQP-GLES31.functional.debug.negative_coverage.get_error.tessellation.tessellation_control_invalid_vertex_count
 dEQP-GLES31.functional.debug.externally_generated.application_messages
 dEQP-GLES31.functional.debug.externally_generated.third_party_messages
 dEQP-GLES31.functional.debug.externally_generated.push_pop_stack
index b26dd82..bdb3dc8 100644 (file)
@@ -854,6 +854,61 @@ group varying "Varying linkage"
                        ""
                end
 
+               case output_non_array
+                       version 310 es
+                       desc "Tessellation control output out not an array"
+                       require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation }
+                       expect compile_or_link_fail
+                       values
+                       {
+                               input float in0 = 1.0;
+                               output float out0 = 1.0;
+                       }
+                       vertex ""
+                               #version 310 es
+                               ${VERTEX_DECLARATIONS}
+                               out mediump float tc_in;
+                               void main()
+                               {
+                                       tc_in = in0;
+                                       ${VERTEX_OUTPUT}
+                               }
+                       ""
+                       tessellation_control ""
+                               #version 310 es
+                               ${TESSELLATION_CONTROL_DECLARATIONS}
+                               in mediump float tc_in[];
+                               out mediump float tc_out; // not an array
+                               void main()
+                               {
+                                       tc_out = tc_in[gl_InvocationID];
+                                       ${TESSELLATION_CONTROL_OUTPUT}
+                               }
+                       ""
+                       tessellation_evaluation ""
+                               #version 310 es
+                               ${TESSELLATION_EVALUATION_DECLARATIONS}
+                               in mediump float tc_out[];
+                               out mediump float te_out;
+                               void main()
+                               {
+                                       te_out = tc_out[2];
+                                       ${TESSELLATION_EVALUATION_OUTPUT}
+                               }
+                       ""
+                       fragment ""
+                               #version 310 es
+                               precision mediump float;
+                               ${FRAGMENT_DECLARATIONS}
+                               in mediump float te_out;
+                               void main()
+                               {
+                                       out0 = te_out;
+                                       ${FRAGMENT_OUTPUT}
+                               }
+                       ""
+               end
+
                case input_array_size_mismatch
                        version 310 es
                        desc "Tessellation control input array size is not gl_MaxPatchVertices"
@@ -964,6 +1019,133 @@ group varying "Varying linkage"
                        ""
                end
 
+               case invalid_patch_in_usage
+                       version 310 es
+                       desc "Invalid use of the patch_in qualifier in a non-tessellation shader"
+                       expect compile_or_link_fail
+                       require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation }
+                       values
+                       {
+                               input float in0 = 1.0;
+                               output float out0 = 1.0;
+                       }
+                       vertex ""
+                               #version 310 es
+                               ${VERTEX_DECLARATIONS}
+                               out mediump float frag_in;
+                               out mediump float var;
+                               void main()
+                               {
+                                       frag_in = in0;
+                                       var = 2.0;
+                                       ${VERTEX_OUTPUT}
+                               }
+                       ""
+                       fragment ""
+                               #version 310 es
+                               precision mediump float;
+                               ${FRAGMENT_DECLARATIONS}
+                               patch in mediump float var; // invalid use of patch_in
+                               in mediump float frag_in;
+                               void main()
+                               {
+                                       out0 = frag_in * var;
+                                       ${FRAGMENT_OUTPUT}
+                               }
+                       ""
+               end
+
+               case invalid_patch_out_usage
+                       version 310 es
+                       desc "Invalid use of the patch_out qualifier in a non-tessellation shader"
+                       expect compile_or_link_fail
+                       require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation }
+                       values
+                       {
+                               input float in0 = 1.0;
+                               output float out0 = 1.0;
+                       }
+                       vertex ""
+                               #version 310 es
+                               ${VERTEX_DECLARATIONS}
+                               out mediump float frag_in;
+                               patch out mediump float var;
+                               void main()
+                               {
+                                       frag_in = in0;
+                                       var = 2.0;
+                                       ${VERTEX_OUTPUT}
+                               }
+                       ""
+                       fragment ""
+                               #version 310 es
+                               precision mediump float;
+                               ${FRAGMENT_DECLARATIONS}
+                               in mediump float var; // invalid use of patch_out
+                               in mediump float frag_in;
+                               void main()
+                               {
+                                       out0 = frag_in * var;
+                                       ${FRAGMENT_OUTPUT}
+                               }
+                       ""
+               end
+
+               case invalid_per_patch_qualifier_usage
+                       version 310 es
+                       desc "Invalid use of per-patch qualifier on input variable in tessellation control shader"
+                       require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation }
+                       expect compile_or_link_fail
+                       values
+                       {
+                               input float in0 = 1.0;
+                               output float out0 = 1.0;
+                       }
+                       vertex ""
+                               #version 310 es
+                               ${VERTEX_DECLARATIONS}
+                               out mediump float tc_in;
+                               void main()
+                               {
+                                       tc_in = in0;
+                                       ${VERTEX_OUTPUT}
+                               }
+                       ""
+                       tessellation_control ""
+                               #version 310 es
+                               ${TESSELLATION_CONTROL_DECLARATIONS}
+                               patch in mediump float tc_in; // patch in not allowed in TCS
+                               patch out mediump float tc_out;
+                               void main()
+                               {
+                                       tc_out = tc_in;
+                                       ${TESSELLATION_CONTROL_OUTPUT}
+                               }
+                       ""
+                       tessellation_evaluation ""
+                               #version 310 es
+                               ${TESSELLATION_EVALUATION_DECLARATIONS}
+                               patch in mediump float tc_out;
+                               out mediump float te_out;
+                               void main()
+                               {
+                                       te_out = tc_out;
+                                       ${TESSELLATION_EVALUATION_OUTPUT}
+                               }
+                       ""
+                       fragment ""
+                               #version 310 es
+                               precision mediump float;
+                               ${FRAGMENT_DECLARATIONS}
+                               in mediump float te_out;
+                               void main()
+                               {
+                                       out0 = te_out;
+                                       ${FRAGMENT_OUTPUT}
+                               }
+                       ""
+               end
+
                case per_patch_qualifier_mismatch_1
                        version 310 es
                        desc "Tessellation control output is per-patch qualified, evaluation input is not"
@@ -1133,7 +1315,7 @@ group varying "Varying linkage"
 
                case input_block_non_array
                        version 310 es
-                       desc "Tessellation control shader input block with explicit array"
+                       desc "Tessellation control shader input block without explicit array"
                        require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation }
                        require extension { "GL_OES_shader_io_blocks" | "GL_EXT_shader_io_blocks" } in { vertex }
                        expect compile_or_link_fail
@@ -1189,6 +1371,64 @@ group varying "Varying linkage"
                        ""
                end
 
+               case output_block_non_array
+                       version 310 es
+                       desc "Tessellation control shader output block without explicit array"
+                       require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation }
+                       require extension { "GL_OES_shader_io_blocks" | "GL_EXT_shader_io_blocks" } in { vertex }
+                       expect compile_or_link_fail
+                       values { output float out0 = 1.0; }
+                       vertex ""
+                               #version 310 es
+                               ${VERTEX_DECLARATIONS}
+                               out mediump float tc_in;
+                               void main()
+                               {
+                                       tc_in = 1.0;
+                                       ${VERTEX_OUTPUT}
+                               }
+                       ""
+                       tessellation_control ""
+                               #version 310 es
+                               ${TESSELLATION_CONTROL_DECLARATIONS}
+                               in mediump float tc_in[];
+                               out IOBlockName
+                               {
+                                       mediump float var;
+                               } outputInstanceName; // not an array
+                               void main()
+                               {
+                                       outputInstanceName.var = tc_in[gl_InvocationID];
+                                       ${TESSELLATION_CONTROL_OUTPUT}
+                               }
+                       ""
+                       tessellation_evaluation ""
+                               #version 310 es
+                               ${TESSELLATION_EVALUATION_DECLARATIONS}
+                               in IOBlockName
+                               {
+                                       mediump float var;
+                               } outputInstanceName[];
+                               out mediump float te_out;
+                               void main()
+                               {
+                                       te_out = outputInstanceName[2].var;
+                                       ${TESSELLATION_EVALUATION_OUTPUT}
+                               }
+                       ""
+                       fragment ""
+                               #version 310 es
+                               precision mediump float;
+                               ${FRAGMENT_DECLARATIONS}
+                               in mediump float te_out;
+                               void main()
+                               {
+                                       out0 = te_out;
+                                       ${FRAGMENT_OUTPUT}
+                               }
+                       ""
+               end
+
                case input_block_array_size_mismatch
                        version 310 es
                        desc "Tessellation control shader input block array, size not gl_MaxPatchVertices"
@@ -2151,3 +2391,355 @@ group uniform "Uniform"
 
        import "linkage_tessellation_uniform_types.test"
 end
+
+group layout_declarations "Layout linkage"
+       group rules "Rules"
+
+               case primitive_mode_mismatch
+                       version 310 es
+                       desc "Tessellation evaluation shader primitive mode mismatch"
+                       expect compile_or_link_fail
+                       require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation }
+                       values
+                       {
+                               input float in0 = 1.0;
+                               output float out0 = 1.0;
+                       }
+                       vertex ""
+                               #version 310 es
+                               ${VERTEX_DECLARATIONS}
+                               out mediump float tc_in;
+                               void main()
+                               {
+                                       tc_in = in0;
+                                       ${VERTEX_OUTPUT}
+                               }
+                       ""
+                       tessellation_control ""
+                               #version 310 es
+                               ${TESSELLATION_CONTROL_DECLARATIONS}
+                               in mediump float tc_in[];
+                               out mediump float tc_out[];
+                               void main()
+                               {
+                                       tc_out[gl_InvocationID] = tc_in[gl_InvocationID];
+                                       ${TESSELLATION_CONTROL_OUTPUT}
+                               }
+                       ""
+                       tessellation_evaluation ""
+                               #version 310 es
+                               layout (triangles) in;
+                               layout (isolines) in;
+                               in mediump float tc_out[];
+                               out mediump float te_out;
+                               void main()
+                               {
+                                       te_out = tc_out[2];
+                                       ${TESSELLATION_EVALUATION_OUTPUT}
+                               }
+                       ""
+                       fragment ""
+                               #version 310 es
+                               precision mediump float;
+                               ${FRAGMENT_DECLARATIONS}
+                               in mediump float te_out;
+                               void main()
+                               {
+                                       out0 = te_out;
+                                       ${FRAGMENT_OUTPUT}
+                               }
+                       ""
+               end
+
+               case spacing_mode_mismatch
+                       version 310 es
+                       desc "Tessellation evaluation shader spacing mode mismatch"
+                       expect compile_or_link_fail
+                       require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation }
+                       values
+                       {
+                               input float in0 = 1.0;
+                               output float out0 = 1.0;
+                       }
+                       vertex ""
+                               #version 310 es
+                               ${VERTEX_DECLARATIONS}
+                               out mediump float tc_in;
+                               void main()
+                               {
+                                       tc_in = in0;
+                                       ${VERTEX_OUTPUT}
+                               }
+                       ""
+                       tessellation_control ""
+                               #version 310 es
+                               ${TESSELLATION_CONTROL_DECLARATIONS}
+                               in mediump float tc_in[];
+                               out mediump float tc_out[];
+                               void main()
+                               {
+                                       tc_out[gl_InvocationID] = tc_in[gl_InvocationID];
+                                       ${TESSELLATION_CONTROL_OUTPUT}
+                               }
+                       ""
+                       tessellation_evaluation ""
+                               #version 310 es
+                               layout (triangles, equal_spacing) in;
+                               layout (triangles, fractional_odd_spacing) in;
+                               in mediump float tc_out[];
+                               out mediump float te_out;
+                               void main()
+                               {
+                                       te_out = tc_out[2];
+                                       ${TESSELLATION_EVALUATION_OUTPUT}
+                               }
+                       ""
+                       fragment ""
+                               #version 310 es
+                               precision mediump float;
+                               ${FRAGMENT_DECLARATIONS}
+                               in mediump float te_out;
+                               void main()
+                               {
+                                       out0 = te_out;
+                                       ${FRAGMENT_OUTPUT}
+                               }
+                       ""
+               end
+
+               case vertex_order_mismatch
+                       version 310 es
+                       desc "Tessellation evaluation shader vertex order mismatch"
+                       expect compile_or_link_fail
+                       require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation }
+                       values
+                       {
+                               input float in0 = 1.0;
+                               output float out0 = 1.0;
+                       }
+                       vertex ""
+                               #version 310 es
+                               ${VERTEX_DECLARATIONS}
+                               out mediump float tc_in;
+                               void main()
+                               {
+                                       tc_in = in0;
+                                       ${VERTEX_OUTPUT}
+                               }
+                       ""
+                       tessellation_control ""
+                               #version 310 es
+                               ${TESSELLATION_CONTROL_DECLARATIONS}
+                               in mediump float tc_in[];
+                               out mediump float tc_out[];
+                               void main()
+                               {
+                                       tc_out[gl_InvocationID] = tc_in[gl_InvocationID];
+                                       ${TESSELLATION_CONTROL_OUTPUT}
+                               }
+                       ""
+                       tessellation_evaluation ""
+                               #version 310 es
+                               layout (triangles, cw) in;
+                               layout (triangles, ccw) in;
+                                   in mediump float tc_out[];
+                               out mediump float te_out;
+                               void main()
+                               {
+                                       te_out = tc_out[2];
+                                       ${TESSELLATION_EVALUATION_OUTPUT}
+                               }
+                       ""
+                       fragment ""
+                               #version 310 es
+                               precision mediump float;
+                               ${FRAGMENT_DECLARATIONS}
+                               in mediump float te_out;
+                               void main()
+                               {
+                                       out0 = te_out;
+                                       ${FRAGMENT_OUTPUT}
+                               }
+                       ""
+               end
+
+               case vertex_count_mismatch
+                       version 310 es
+                       desc "Tessellation control shader vertex count mismatch"
+                       expect compile_or_link_fail
+                       require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation }
+                       values
+                       {
+                               input float in0 = 1.0;
+                               output float out0 = 1.0;
+                       }
+                       vertex ""
+                               #version 310 es
+                               ${VERTEX_DECLARATIONS}
+                               out mediump float tc_in;
+                               void main()
+                               {
+                                       tc_in = in0;
+                                       ${VERTEX_OUTPUT}
+                               }
+                       ""
+                       tessellation_control ""
+                               #version 310 es
+                               layout (vertices=3) out;
+                               layout (vertices=4) out;
+                               in mediump float tc_in[];
+                               out mediump float tc_out[];
+                               void main()
+                               {
+                                       tc_out[gl_InvocationID] = tc_in[gl_InvocationID];
+                                       ${TESSELLATION_CONTROL_OUTPUT}
+                               }
+                       ""
+                       tessellation_evaluation ""
+                               #version 310 es
+                               ${TESSELLATION_EVALUATION_DECLARATIONS}
+                               in mediump float tc_out[];
+                               out mediump float te_out;
+                               void main()
+                               {
+                                       te_out = tc_out[2];
+                                       ${TESSELLATION_EVALUATION_OUTPUT}
+                               }
+                       ""
+                       fragment ""
+                               #version 310 es
+                               precision mediump float;
+                               ${FRAGMENT_DECLARATIONS}
+                               in mediump float te_out;
+                               void main()
+                               {
+                                       out0 = te_out;
+                                       ${FRAGMENT_OUTPUT}
+                               }
+                       ""
+               end
+       end
+end
+
+group barriers "Barriers"
+       group rules "Rules"
+
+               case invalid_barrier_usage_within_control_flow
+                       version 310 es
+                       desc "Tessellation control shader invalid barrier usage within control flow statement"
+                       expect compile_or_link_fail
+                       require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation }
+                       values
+                       {
+                               input float in0 = 1.0;
+                               output float out0 = 1.0;
+                       }
+                       vertex ""
+                               #version 310 es
+                               ${VERTEX_DECLARATIONS}
+                               out mediump float tc_in;
+                               void main()
+                               {
+                                       tc_in = in0;
+                                       ${VERTEX_OUTPUT}
+                               }
+                       ""
+                       tessellation_control ""
+                               #version 310 es
+                               ${TESSELLATION_CONTROL_DECLARATIONS}
+                               in mediump float tc_in[];
+                               out mediump float tc_out[];
+
+                               void main()
+                               {
+                                       if (gl_InvocationID == 0)
+                                               barrier(); // error: within control flow
+
+                                       tc_out[gl_InvocationID] = tc_in[gl_InvocationID];
+                                       ${TESSELLATION_CONTROL_OUTPUT}
+                               }
+                       ""
+                       tessellation_evaluation ""
+                               #version 310 es
+                               ${TESSELLATION_EVALUATION_DECLARATIONS}
+                               in mediump float tc_out[];
+                               out mediump float te_out;
+                               void main()
+                               {
+                                       te_out = tc_out[2];
+                                       ${TESSELLATION_EVALUATION_OUTPUT}
+                               }
+                       ""
+                       fragment ""
+                               #version 310 es
+                               precision mediump float;
+                               ${FRAGMENT_DECLARATIONS}
+                               in mediump float te_out;
+                               void main()
+                               {
+                                       out0 = te_out;
+                                       ${FRAGMENT_OUTPUT}
+                               }
+                       ""
+               end
+
+               case invalid_barrier_usage_after_return
+                       version 310 es
+                       desc "Tessellation control shader invalid barrier usage after main() returns"
+                       expect compile_or_link_fail
+                       require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation }
+                       values
+                       {
+                               input float in0 = 1.0;
+                               output float out0 = 1.0;
+                       }
+                       vertex ""
+                               #version 310 es
+                               ${VERTEX_DECLARATIONS}
+                               out mediump float tc_in;
+                               void main()
+                               {
+                                       tc_in = in0;
+                                       ${VERTEX_OUTPUT}
+                               }
+                       ""
+                       tessellation_control ""
+                               #version 310 es
+                               ${TESSELLATION_CONTROL_DECLARATIONS}
+                               in mediump float tc_in[];
+                               out mediump float tc_out[];
+
+                               void main()
+                               {
+                                       tc_out[gl_InvocationID] = tc_in[gl_InvocationID];
+                                       ${TESSELLATION_CONTROL_OUTPUT}
+
+                                       return;
+                                       barrier(); // error: barrier() after return
+                               }
+                       ""
+                       tessellation_evaluation ""
+                               #version 310 es
+                               ${TESSELLATION_EVALUATION_DECLARATIONS}
+                               in mediump float tc_out[];
+                               out mediump float te_out;
+                               void main()
+                               {
+                                       te_out = tc_out[2];
+                                       ${TESSELLATION_EVALUATION_OUTPUT}
+                               }
+                       ""
+                       fragment ""
+                               #version 310 es
+                               precision mediump float;
+                               ${FRAGMENT_DECLARATIONS}
+                               in mediump float te_out;
+                               void main()
+                               {
+                                       out0 = te_out;
+                                       ${FRAGMENT_OUTPUT}
+                               }
+                       ""
+               end
+       end
+end
index db7a8b9..4cf4687 100644 (file)
@@ -157,6 +157,8 @@ set(DEQP_GLES31_FUNCTIONAL_SRCS
        es31fNegativePreciseTests.hpp
        es31fNegativeAdvancedBlendEquationTests.cpp
        es31fNegativeAdvancedBlendEquationTests.hpp
+       es31fNegativeTessellationTests.cpp
+       es31fNegativeTessellationTests.hpp
        es31fTextureGatherTests.cpp
        es31fTextureGatherTests.hpp
        es31fTextureFormatTests.cpp
index b44d7e5..5fd3b68 100644 (file)
@@ -37,6 +37,7 @@
 #include "es31fNegativePreciseTests.hpp"
 #include "es31fNegativeAdvancedBlendEquationTests.hpp"
 #include "es31fNegativeShaderStorageTests.hpp"
+#include "es31fNegativeTessellationTests.hpp"
 
 #include "deUniquePtr.hpp"
 #include "deRandom.hpp"
@@ -2946,6 +2947,7 @@ void DebugTests::init (void)
        const vector<FunctionContainer> fragmentFuncs                    = wrapCoreFunctions(NegativeTestShared::getNegativeFragmentApiTestFunctions());
        const vector<FunctionContainer> vaFuncs                                  = wrapCoreFunctions(NegativeTestShared::getNegativeVertexArrayApiTestFunctions());
        const vector<FunctionContainer> stateFuncs                               = wrapCoreFunctions(NegativeTestShared::getNegativeStateApiTestFunctions());
+       const vector<FunctionContainer> tessellationFuncs                = wrapCoreFunctions(NegativeTestShared::getNegativeTessellationTestFunctions());
        const vector<FunctionContainer> atomicCounterFuncs               = wrapCoreFunctions(NegativeTestShared::getNegativeAtomicCounterTestFunctions());
        const vector<FunctionContainer> imageLoadFuncs                   = wrapCoreFunctions(NegativeTestShared::getNegativeShaderImageLoadTestFunctions());
        const vector<FunctionContainer> imageStoreFuncs                  = wrapCoreFunctions(NegativeTestShared::getNegativeShaderImageStoreTestFunctions());
@@ -3062,6 +3064,7 @@ void DebugTests::init (void)
                        host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "precise",                                        "Negative Precise Cases",                                                       preciseFuncs));
                        host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "advanced_blend",                         "Negative Advanced Blend Equation Cases",                       advancedBlendFuncs));
                        host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "shader_storage",                         "Negative Shader Storage Cases",                                        shaderStorageFuncs));
+                       host->addChild(createChildCases(CASETYPE_CALLBACK, m_context, "tessellation",                           "Negative Tessellation Cases",                                          tessellationFuncs));
                }
 
                {
@@ -3085,6 +3088,7 @@ void DebugTests::init (void)
                        host->addChild(createChildCases(CASETYPE_LOG, m_context, "precise",                                     "Negative Precise Cases",                                                       preciseFuncs));
                        host->addChild(createChildCases(CASETYPE_LOG, m_context, "advanced_blend",                      "Negative Advanced Blend Equation Cases",                       advancedBlendFuncs));
                        host->addChild(createChildCases(CASETYPE_LOG, m_context, "shader_storage",                      "Negative Shader Storage Cases",                                        shaderStorageFuncs));
+                       host->addChild(createChildCases(CASETYPE_LOG, m_context, "tessellation",                        "Negative Tessellation Cases",                                          tessellationFuncs));
                }
 
                {
@@ -3108,6 +3112,7 @@ void DebugTests::init (void)
                        host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "precise",                                        "Negative Precise Cases",                                                       preciseFuncs));
                        host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "advanced_blend",                         "Negative Advanced Blend Equation Cases",                       advancedBlendFuncs));
                        host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "shader_storage",                         "Negative Shader Storage Cases",                                        shaderStorageFuncs));
+                       host->addChild(createChildCases(CASETYPE_GETERROR, m_context, "tessellation",                           "Negative Tessellation Cases",                                          tessellationFuncs));
                }
        }
 
diff --git a/modules/gles31/functional/es31fNegativeTessellationTests.cpp b/modules/gles31/functional/es31fNegativeTessellationTests.cpp
new file mode 100644 (file)
index 0000000..e72f480
--- /dev/null
@@ -0,0 +1,380 @@
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES 3.1 Module
+ * -------------------------------------------------
+ *
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Negative Tessellation tests.
+ *//*--------------------------------------------------------------------*/
+
+#include "es31fNegativeTessellationTests.hpp"
+#include "gluContextInfo.hpp"
+#include "gluShaderProgram.hpp"
+#include "glwDefs.hpp"
+#include "glwEnums.hpp"
+#include "tcuStringTemplate.hpp"
+
+namespace deqp
+{
+
+using std::string;
+using std::map;
+
+namespace gles31
+{
+namespace Functional
+{
+namespace NegativeTestShared
+{
+
+using tcu::TestLog;
+using namespace glw;
+
+static const char* vertexShaderSource          =       "${GLSL_VERSION_STRING}\n"
+                                                                                               "\n"
+                                                                                               "void main (void)\n"
+                                                                                               "{\n"
+                                                                                               "       gl_Position = vec4(0.0);\n"
+                                                                                               "}\n";
+
+static const char* fragmentShaderSource                =       "${GLSL_VERSION_STRING}\n"
+                                                                                               "precision mediump float;\n"
+                                                                                               "layout(location = 0) out mediump vec4 fragColor;\n"
+                                                                                               "\n"
+                                                                                               "void main (void)\n"
+                                                                                               "{\n"
+                                                                                               "       fragColor = vec4(1.0);\n"
+                                                                                               "}\n";
+
+static const char* tessControlShaderSource     =       "${GLSL_VERSION_STRING}\n"
+                                                                                               "${GLSL_TESS_EXTENSION_STRING}\n"
+                                                                                               "layout (vertices=3) out;\n"
+                                                                                               "\n"
+                                                                                               "void main()\n"
+                                                                                               "{\n"
+                                                                                               "       gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
+                                                                                               "}\n";
+
+static const char* tessEvalShaderSource                =       "${GLSL_VERSION_STRING}\n"
+                                                                                               "${GLSL_TESS_EXTENSION_STRING}\n"
+                                                                                               "layout(triangles) in;\n"
+                                                                                               "\n"
+                                                                                               "void main()\n"
+                                                                                               "{\n"
+                                                                                               "       gl_Position = gl_TessCoord[0] * gl_in[0].gl_Position;\n"
+                                                                                               "}\n";
+
+static void checkExtensionSupport (NegativeTestContext& ctx, const char* extName)
+{
+       if (!ctx.getContextInfo().isExtensionSupported(extName))
+               throw tcu::NotSupportedError(string(extName) + " not supported");
+}
+
+static void checkTessellationSupport (NegativeTestContext& ctx)
+{
+       checkExtensionSupport(ctx, "GL_EXT_tessellation_shader");
+}
+
+// Helper for constructing tessellation pipeline sources.
+static glu::ProgramSources makeTessPipelineSources (const std::string& vertexSrc, const std::string& fragmentSrc, const std::string& tessCtrlSrc, const std::string& tessEvalSrc)
+{
+       glu::ProgramSources sources;
+       sources.sources[glu::SHADERTYPE_VERTEX].push_back(vertexSrc);
+       sources.sources[glu::SHADERTYPE_FRAGMENT].push_back(fragmentSrc);
+
+       if (!tessCtrlSrc.empty())
+               sources.sources[glu::SHADERTYPE_TESSELLATION_CONTROL].push_back(tessCtrlSrc);
+
+       if (!tessEvalSrc.empty())
+               sources.sources[glu::SHADERTYPE_TESSELLATION_EVALUATION].push_back(tessEvalSrc);
+
+       return sources;
+}
+
+// Incomplete active tess shaders
+void single_tessellation_stage (NegativeTestContext& ctx)
+{
+       const bool                                      isES32  = glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
+       map<string, string>                     args;
+       args["GLSL_VERSION_STRING"]                     = isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
+       args["GLSL_TESS_EXTENSION_STRING"]      = isES32 ? "" : "#extension GL_EXT_tessellation_shader : require";
+
+       checkTessellationSupport(ctx);
+
+       {
+               glu::ShaderProgram program(ctx.getRenderContext(),
+                                                                  makeTessPipelineSources(tcu::StringTemplate(vertexShaderSource).specialize(args),
+                                                                                                                  tcu::StringTemplate(fragmentShaderSource).specialize(args),
+                                                                                                                  tcu::StringTemplate(tessControlShaderSource).specialize(args),
+                                                                                                                  "")); // missing tessEvalShaderSource
+               tcu::TestLog& log = ctx.getLog();
+               log << program;
+
+               ctx.glUseProgram(program.getProgram());
+               ctx.expectError(GL_NO_ERROR);
+
+               ctx.beginSection("GL_INVALID_OPERATION is generated if current program state has tessellation control shader but no tessellation evaluation shader.");
+               ctx.glDrawArrays(GL_PATCHES, 0, 3);
+               ctx.expectError(GL_INVALID_OPERATION);
+               ctx.endSection();
+
+               ctx.glUseProgram(0);
+       }
+
+       {
+               glu::ShaderProgram program(ctx.getRenderContext(),
+                                                                  makeTessPipelineSources(tcu::StringTemplate(vertexShaderSource).specialize(args),
+                                                                                                                  tcu::StringTemplate(fragmentShaderSource).specialize(args),
+                                                                                                                  "", // missing tessControlShaderSource
+                                                                                                                  tcu::StringTemplate(tessEvalShaderSource).specialize(args)));
+               tcu::TestLog& log = ctx.getLog();
+               log << program;
+
+               ctx.glUseProgram(program.getProgram());
+               ctx.expectError(GL_NO_ERROR);
+
+               ctx.beginSection("GL_INVALID_OPERATION is generated if current program state has tessellation evaluation shader but no tessellation control shader.");
+               ctx.glDrawArrays(GL_PATCHES, 0, 3);
+               ctx.expectError(GL_INVALID_OPERATION);
+               ctx.endSection();
+
+               ctx.glUseProgram(0);
+       }
+}
+
+// Complete active tess shaders invalid primitive mode
+void invalid_primitive_mode (NegativeTestContext& ctx)
+{
+       checkTessellationSupport(ctx);
+
+       const bool                                      isES32  = glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
+       map<string, string>                     args;
+       args["GLSL_VERSION_STRING"]                     = isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
+       args["GLSL_TESS_EXTENSION_STRING"]      = isES32 ? "" : "#extension GL_EXT_tessellation_shader : require";
+
+       glu::ShaderProgram program(ctx.getRenderContext(),
+                                                          makeTessPipelineSources(tcu::StringTemplate(vertexShaderSource).specialize(args),
+                                                                                                          tcu::StringTemplate(fragmentShaderSource).specialize(args),
+                                                                                                          tcu::StringTemplate(tessControlShaderSource).specialize(args),
+                                                                                                          tcu::StringTemplate(tessEvalShaderSource).specialize(args)));
+       tcu::TestLog& log = ctx.getLog();
+       log << program;
+
+       ctx.glUseProgram(program.getProgram());
+       ctx.expectError(GL_NO_ERROR);
+
+       ctx.beginSection("GL_INVALID_OPERATION is generated if tessellation is active and primitive mode is not GL_PATCHES.");
+       ctx.glDrawArrays(GL_TRIANGLES, 0, 3);
+       ctx.expectError(GL_INVALID_OPERATION);
+       ctx.endSection();
+
+       ctx.glUseProgram(0);
+}
+
+void tessellation_not_active (NegativeTestContext& ctx)
+{
+       checkTessellationSupport(ctx);
+
+       const bool                                      isES32  = glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
+       map<string, string>                     args;
+       args["GLSL_VERSION_STRING"]                     = isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
+       args["GLSL_TESS_EXTENSION_STRING"]      = isES32 ? "" : "#extension GL_EXT_tessellation_shader : require";
+
+       glu::ShaderProgram program(ctx.getRenderContext(),
+                                                          makeTessPipelineSources(tcu::StringTemplate(vertexShaderSource).specialize(args),
+                                                                                                          tcu::StringTemplate(fragmentShaderSource).specialize(args),
+                                                                                                          "",          // missing tessControlShaderSource
+                                                                                                          ""));        // missing tessEvalShaderSource
+       tcu::TestLog& log = ctx.getLog();
+       log << program;
+
+       ctx.glUseProgram(program.getProgram());
+       ctx.expectError(GL_NO_ERROR);
+
+       ctx.beginSection("GL_INVALID_OPERATION is generated if tessellation is not active and primitive mode is GL_PATCHES.");
+       ctx.glDrawArrays(GL_PATCHES, 0, 3);
+       ctx.expectError(GL_INVALID_OPERATION);
+       ctx.endSection();
+
+       ctx.glUseProgram(0);
+}
+
+void invalid_program_state (NegativeTestContext& ctx)
+{
+       checkTessellationSupport(ctx);
+
+       const bool                                      isES32  = glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
+       map<string, string>                     args;
+       args["GLSL_VERSION_STRING"]                     = isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
+       args["GLSL_TESS_EXTENSION_STRING"]      = isES32 ? "" : "#extension GL_EXT_tessellation_shader : require";
+
+       glu::FragmentSource frgSource(tcu::StringTemplate(fragmentShaderSource).specialize(args));
+       glu::TessellationControlSource tessCtrlSource(tcu::StringTemplate(tessControlShaderSource).specialize(args));
+       glu::TessellationEvaluationSource tessEvalSource(tcu::StringTemplate(tessEvalShaderSource).specialize(args));
+
+       glu::ProgramPipeline pipeline(ctx.getRenderContext());
+
+       glu::ShaderProgram      fragProgram     (ctx.getRenderContext(), glu::ProgramSources() << glu::ProgramSeparable(true) << frgSource);
+       glu::ShaderProgram      tessCtrlProgram (ctx.getRenderContext(), glu::ProgramSources() << glu::ProgramSeparable(true) << tessCtrlSource);
+       glu::ShaderProgram      tessEvalProgram (ctx.getRenderContext(), glu::ProgramSources() << glu::ProgramSeparable(true) << tessEvalSource);
+
+       tcu::TestLog& log = ctx.getLog();
+       log << fragProgram << tessCtrlProgram << tessEvalProgram;
+
+       if (!fragProgram.isOk() || !tessCtrlProgram.isOk() || !tessEvalProgram.isOk())
+               throw tcu::TestError("failed to build program");
+
+       ctx.glBindProgramPipeline(pipeline.getPipeline());
+       ctx.expectError(GL_NO_ERROR);
+
+       ctx.glUseProgramStages(pipeline.getPipeline(), GL_FRAGMENT_SHADER_BIT, fragProgram.getProgram());
+       ctx.glUseProgramStages(pipeline.getPipeline(), GL_TESS_CONTROL_SHADER_BIT, tessCtrlProgram.getProgram());
+       ctx.glUseProgramStages(pipeline.getPipeline(), GL_TESS_EVALUATION_SHADER_BIT, tessEvalProgram.getProgram());
+       ctx.expectError(GL_NO_ERROR);
+
+       ctx.beginSection("GL_INVALID_OPERATION is generated if tessellation is active and vertex shader is missing.");
+       ctx.glDrawArrays(GL_PATCHES, 0, 3);
+       ctx.expectError(GL_INVALID_OPERATION);
+       ctx.endSection();
+
+       ctx.glBindProgramPipeline(0);
+       ctx.expectError(GL_NO_ERROR);
+}
+
+void tessellation_control_invalid_vertex_count (NegativeTestContext& ctx)
+{
+       checkTessellationSupport(ctx);
+
+       const char* const tessControlVertLimitSource    =       "${GLSL_VERSION_STRING}\n"
+                                                                                                               "${GLSL_TESS_EXTENSION_STRING}\n"
+                                                                                                               "layout (vertices=${GL_MAX_PATCH_LIMIT}) out;\n"
+                                                                                                               "void main()\n"
+                                                                                                               "{\n"
+                                                                                                               "       gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
+                                                                                                               "}\n";
+
+       const bool                                      isES32  = glu::contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
+       map<string, string>                     args;
+       args["GLSL_VERSION_STRING"]                     = isES32 ? getGLSLVersionDeclaration(glu::GLSL_VERSION_320_ES) : getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES);
+       args["GLSL_TESS_EXTENSION_STRING"]      = isES32 ? "" : "#extension GL_EXT_tessellation_shader : require";
+
+       int maxPatchVertices= 0;
+
+       ctx.beginSection("Output vertex count exceeds GL_MAX_PATCH_VERTICES.");
+       ctx.glGetIntegerv(GL_MAX_PATCH_VERTICES, &maxPatchVertices);
+       ctx.expectError(GL_NO_ERROR);
+
+       std::ostringstream                              oss;
+       oss << (maxPatchVertices + 1);
+       args["GL_MAX_PATCH_LIMIT"] =    oss.str();
+
+
+       glu::ShaderProgram program(ctx.getRenderContext(),
+                                                          makeTessPipelineSources(tcu::StringTemplate(vertexShaderSource).specialize(args),
+                                                                                                          tcu::StringTemplate(fragmentShaderSource).specialize(args),
+                                                                                                          tcu::StringTemplate(tessControlVertLimitSource).specialize(args),
+                                                                                                          tcu::StringTemplate(tessEvalShaderSource).specialize(args)));
+       tcu::TestLog& log = ctx.getLog();
+       log << program;
+
+       bool testFailed = program.getProgramInfo().linkOk;
+
+       if (testFailed)
+               ctx.fail("Program was not expected to link");
+
+       ctx.endSection();
+}
+
+void invalid_get_programiv (NegativeTestContext& ctx)
+{
+       checkTessellationSupport(ctx);
+
+       GLuint  program         = ctx.glCreateProgram();
+       GLint   params[1]       = { 0 };
+
+       ctx.beginSection("GL_INVALID_OPERATION is generated if GL_TESS_CONTROL_OUTPUT_VERTICES is queried for a program which has not been linked properly.");
+       ctx.glGetProgramiv(program, GL_TESS_CONTROL_OUTPUT_VERTICES, &params[0]);
+       ctx.expectError(GL_INVALID_OPERATION);
+       ctx.endSection();
+
+       ctx.beginSection("GL_INVALID_OPERATION is generated if GL_TESS_GEN_MODE is queried for a program which has not been linked properly.");
+       ctx.glGetProgramiv(program, GL_TESS_GEN_MODE, &params[0]);
+       ctx.expectError(GL_INVALID_OPERATION);
+       ctx.endSection();
+
+       ctx.beginSection("GL_INVALID_OPERATION is generated if GL_TESS_GEN_SPACING is queried for a program which has not been linked properly.");
+       ctx.glGetProgramiv(program, GL_TESS_GEN_SPACING, &params[0]);
+       ctx.expectError(GL_INVALID_OPERATION);
+       ctx.endSection();
+
+       ctx.beginSection("GL_INVALID_OPERATION is generated if GL_TESS_GEN_VERTEX_ORDER is queried for a program which has not been linked properly.");
+       ctx.glGetProgramiv(program, GL_TESS_GEN_VERTEX_ORDER, &params[0]);
+       ctx.expectError(GL_INVALID_OPERATION);
+       ctx.endSection();
+
+       ctx.beginSection("GL_INVALID_OPERATION is generated if GL_TESS_GEN_POINT_MODE is queried for a program which has not been linked properly.");
+       ctx.glGetProgramiv(program, GL_TESS_GEN_POINT_MODE, &params[0]);
+       ctx.expectError(GL_INVALID_OPERATION);
+       ctx.endSection();
+
+       ctx.glDeleteProgram(program);
+}
+
+void invalid_patch_parameteri (NegativeTestContext& ctx)
+{
+       checkTessellationSupport(ctx);
+
+       ctx.beginSection("GL_INVALID_ENUM is generated if pname is not GL_PATCH_VERTICES.");
+       ctx.glPatchParameteri(-1, 1);
+       ctx.expectError(GL_INVALID_ENUM);
+       ctx.endSection();
+
+       ctx.beginSection("GL_INVALID_VALUE is generated if value is less than or equal to zero.");
+       ctx.glPatchParameteri(GL_PATCH_VERTICES, 0);
+       ctx.expectError(GL_INVALID_VALUE);
+       ctx.endSection();
+
+       int maxPatchVertices= 0;
+       ctx.glGetIntegerv(GL_MAX_PATCH_VERTICES, &maxPatchVertices);
+       ctx.expectError(GL_NO_ERROR);
+
+       ctx.beginSection("GL_INVALID_VALUE is generated if value is greater than GL_MAX_PATCH_VERTICES.");
+       ctx.glPatchParameteri(GL_PATCH_VERTICES, maxPatchVertices + 1);
+       ctx.expectError(GL_INVALID_VALUE);
+       ctx.endSection();
+}
+
+std::vector<FunctionContainer> getNegativeTessellationTestFunctions (void)
+{
+       const FunctionContainer funcs[] =
+       {
+               { single_tessellation_stage,                                    "single_tessellation_stage",                                    "Invalid program state with single tessellation stage"                                                  },
+               { invalid_primitive_mode,                                               "invalid_primitive_mode",                                               "Invalid primitive mode when tessellation is active"                                                    },
+               { tessellation_not_active,                                              "tessellation_not_active",                                              "Use of GL_PATCHES when tessellation is not active"                                                             },
+               { invalid_program_state,                                                "invalid_program_state",                                                "Invalid program state when tessellation active but no vertex shader present"   },
+               { invalid_get_programiv,                                                "get_programiv",                                                                "Invalid glGetProgramiv() usage"                                                                                                },
+               { invalid_patch_parameteri,                                             "invalid_program_queries",                                              "Invalid glPatchParameteri() usage"                                                                                             },
+               { tessellation_control_invalid_vertex_count,    "tessellation_control_invalid_vertex_count",    "Exceed vertex count limit in tessellation control shader"                                              },
+       };
+
+       return std::vector<FunctionContainer>(DE_ARRAY_BEGIN(funcs), DE_ARRAY_END(funcs));
+}
+
+} // NegativeTestShared
+} // Functional
+} // gles31
+} // deqp
diff --git a/modules/gles31/functional/es31fNegativeTessellationTests.hpp b/modules/gles31/functional/es31fNegativeTessellationTests.hpp
new file mode 100644 (file)
index 0000000..d376656
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef _ES31FNEGATIVETESSELLATIONTESTS_HPP
+#define _ES31FNEGATIVETESSELLATIONTESTS_HPP
+/*-------------------------------------------------------------------------
+ * drawElements Quality Program OpenGL ES 3.1 Module
+ * -------------------------------------------------
+ *
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *//*!
+ * \file
+ * \brief Negative Tessellation tests.
+ *//*--------------------------------------------------------------------*/
+
+#include "tcuDefs.hpp"
+#include "es31fNegativeTestShared.hpp"
+
+namespace deqp
+{
+namespace gles31
+{
+namespace Functional
+{
+namespace NegativeTestShared
+{
+
+std::vector<FunctionContainer> getNegativeTessellationTestFunctions (void);
+
+} // NegativeTestShared
+} // Functional
+} // gles3
+} // deqp
+
+#endif // _ES31FNEGATIVETESSELLATIONTESTS_HPP