group varying "Varying linkage" group rules "Rules" case input_type_mismatch version 310 es desc "Tessellation control shader input type mismatch" expect 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 vec2 tc_in[]; out mediump float tc_out[]; void main() { tc_out[gl_InvocationID] = tc_in[gl_InvocationID].x; ${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 output_type_mismatch version 310 es desc "Tessellation evaluation shader output type mismatch" expect 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 ${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 vec2 te_out; void main() { out0 = te_out.x + te_out.y; ${FRAGMENT_OUTPUT} } "" end case internal_type_mismatch version 310 es desc "Tessellation control and evaluation shader varying type mismatch" expect 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 ${TESSELLATION_EVALUATION_DECLARATIONS} in mediump vec2 tc_out[]; out mediump float te_out; void main() { te_out = tc_out[2].x + tc_out[0].y; ${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_different_precision version 310 es desc "Tessellation control shader input precisions different" 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 highp float tc_in; void main() { tc_in = in0; ${VERTEX_OUTPUT} } "" tessellation_control "" #version 310 es ${TESSELLATION_CONTROL_DECLARATIONS} in lowp 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 case output_different_precision version 310 es desc "Tessellation evaluation shader output precisions different" 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 ${TESSELLATION_EVALUATION_DECLARATIONS} in mediump float tc_out[]; out highp float te_out; void main() { te_out = tc_out[2]; ${TESSELLATION_EVALUATION_OUTPUT} } "" fragment "" #version 310 es precision mediump float; ${FRAGMENT_DECLARATIONS} in lowp float te_out; void main() { out0 = te_out; ${FRAGMENT_OUTPUT} } "" end case internal_different_precision version 310 es desc "Tessellation control and evaluation shader varying precisions different" 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 highp 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 lowp 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_no_declaration version 310 es desc "Tessellation control shader input with no matching output" expect 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} void main() { ${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 ${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 output_no_declaration version 310 es desc "Tessellation evaluation shader without output for an fragment shader input" expect link_fail require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation } values { output float out0 = 1.0; } vertex "" #version 310 es ${VERTEX_DECLARATIONS} void main() { ${VERTEX_OUTPUT} } "" tessellation_control "" #version 310 es ${TESSELLATION_CONTROL_DECLARATIONS} void main() { ${TESSELLATION_CONTROL_OUTPUT} } "" tessellation_evaluation "" #version 310 es ${TESSELLATION_EVALUATION_DECLARATIONS} void main() { ${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 internal_no_declaration version 310 es desc "Tessellation evaluation shader input without matching output" expect link_fail require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation } values { output float out0 = 1.0; } vertex "" #version 310 es ${VERTEX_DECLARATIONS} void main() { ${VERTEX_OUTPUT} } "" tessellation_control "" #version 310 es ${TESSELLATION_CONTROL_DECLARATIONS} void main() { ${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_superfluous_declaration version 310 es desc "Tessellation control has no input for an output" 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; out mediump float tc_in_unused; void main() { tc_in = in0; tc_in_unused = in0 + 1.0; ${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 ${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 output_superfluous_declaration version 310 es desc "Tessellation has an output without a matching input" 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 ${TESSELLATION_EVALUATION_DECLARATIONS} in mediump float tc_out[]; out mediump float te_out; out mediump float te_out_unused; void main() { te_out = tc_out[2]; te_out_unused = tc_out[0]; ${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 internal_superfluous_declaration version 310 es desc "Tessellation control has an output without a matching input" 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[]; out mediump float tc_out_unused[]; void main() { tc_out[gl_InvocationID] = tc_in[gl_InvocationID]; tc_out_unused[gl_InvocationID] = tc_in[gl_InvocationID] + 1.0; ${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 vertex_fragment_same_varying_name_1 version 310 es desc "Tessellation control has an output without a matching input" require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation } values { input float in0 = 1.0; output float out0 = 2.0; } vertex "" #version 310 es ${VERTEX_DECLARATIONS} out mediump float sharedVaringName; void main() { sharedVaringName = in0; ${VERTEX_OUTPUT} } "" tessellation_control "" #version 310 es ${TESSELLATION_CONTROL_DECLARATIONS} in mediump float sharedVaringName[]; out mediump float tc_out[]; void main() { tc_out[gl_InvocationID] = sharedVaringName[gl_InvocationID]; ${TESSELLATION_CONTROL_OUTPUT} } "" tessellation_evaluation "" #version 310 es ${TESSELLATION_EVALUATION_DECLARATIONS} in mediump float tc_out[]; out mediump float sharedVaringName; void main() { sharedVaringName = 2.0 * tc_out[2]; ${TESSELLATION_EVALUATION_OUTPUT} } "" fragment "" #version 310 es precision mediump float; ${FRAGMENT_DECLARATIONS} in mediump float sharedVaringName; void main() { out0 = sharedVaringName; ${FRAGMENT_OUTPUT} } "" end case vertex_fragment_same_varying_name_2 version 310 es desc "Tessellation control has an output without a matching input" require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation } values { input vec2 in0 = vec2(1.0, 3.0); output float out0 = 4.0; } vertex "" #version 310 es ${VERTEX_DECLARATIONS} out mediump vec2 sharedVaringName; void main() { sharedVaringName = in0; ${VERTEX_OUTPUT} } "" tessellation_control "" #version 310 es ${TESSELLATION_CONTROL_DECLARATIONS} in mediump vec2 sharedVaringName[]; out mediump float tc_out[]; void main() { tc_out[gl_InvocationID] = sharedVaringName[gl_InvocationID].x + sharedVaringName[gl_InvocationID].y; ${TESSELLATION_CONTROL_OUTPUT} } "" tessellation_evaluation "" #version 310 es ${TESSELLATION_EVALUATION_DECLARATIONS} in mediump float tc_out[]; out mediump float sharedVaringName; void main() { sharedVaringName = tc_out[2]; ${TESSELLATION_EVALUATION_OUTPUT} } "" fragment "" #version 310 es precision mediump float; ${FRAGMENT_DECLARATIONS} in mediump float sharedVaringName; void main() { out0 = sharedVaringName; ${FRAGMENT_OUTPUT} } "" end case invalid_vertex_index version 310 es desc "Tessellation control output not indexed with gl_InvocationID" require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation } expect compile_or_link_fail vertex "" #version 310 es ${VERTEX_DECLARATIONS} void main() { ${VERTEX_OUTPUT} } "" tessellation_control "" #version 310 es ${TESSELLATION_CONTROL_DECLARATIONS} out mediump float tc_out[]; void main() { tc_out[2 - gl_InvocationID] = float(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() { ${FRAG_COLOR} = vec4(te_out); } "" end case input_non_array version 310 es desc "Tessellation control input in 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[]; void main() { tc_out[gl_InvocationID] = tc_in; ${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 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" 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[2]; // not gl_MaxPatchVertices 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 case internal_array_size_mismatch version 310 es desc "Tessellation control output array size is not consistent with layout qualifier" 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[2]; // does not match output layout qualifier 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[2]; out mediump float te_out; void main() { te_out = tc_out[1]; ${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_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" 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[]; patch out mediump float tc_out[gl_MaxPatchVertices]; 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[gl_MaxPatchVertices]; 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 per_patch_qualifier_mismatch_2 version 310 es desc "Tessellation control output is not per-patch qualified, evaluation input is" 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[gl_MaxPatchVertices]; void main() { tc_out[gl_InvocationID] = tc_in[gl_InvocationID]; ${TESSELLATION_CONTROL_OUTPUT} } "" tessellation_evaluation "" #version 310 es ${TESSELLATION_EVALUATION_DECLARATIONS} patch in mediump float tc_out[gl_MaxPatchVertices]; 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_block version 310 es desc "Tessellation control shader input block" 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 } values { output float out0 = 1.0; } vertex "" #version 310 es ${VERTEX_DECLARATIONS} out IOBlockName { mediump float var; } outputInstanceName; void main() { outputInstanceName.var = 1.0; ${VERTEX_OUTPUT} } "" tessellation_control "" #version 310 es ${TESSELLATION_CONTROL_DECLARATIONS} in IOBlockName { mediump float var; } inputInstanceName[]; out mediump float tc_out[]; void main() { tc_out[gl_InvocationID] = inputInstanceName[gl_InvocationID].var; ${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_block_non_array version 310 es 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 values { output float out0 = 1.0; } vertex "" #version 310 es ${VERTEX_DECLARATIONS} out IOBlockName { mediump float var; } outputInstanceName; void main() { outputInstanceName.var = 1.0; ${VERTEX_OUTPUT} } "" tessellation_control "" #version 310 es ${TESSELLATION_CONTROL_DECLARATIONS} in IOBlockName { mediump float var; } inputInstanceName; out mediump float tc_out[]; void main() { tc_out[gl_InvocationID] = inputInstanceName.var; ${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 geo_out; void main() { out0 = geo_out; ${FRAGMENT_OUTPUT} } "" 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" 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 IOBlockName { mediump float var; } outputInstanceName; void main() { outputInstanceName.var = 1.0; ${VERTEX_OUTPUT} } "" tessellation_control "" #version 310 es ${TESSELLATION_CONTROL_DECLARATIONS} in IOBlockName { mediump float var; } inputInstanceName[4]; // not gl_MaxPatchVertices out mediump float tc_out[]; void main() { tc_out[gl_InvocationID] = inputInstanceName[gl_InvocationID + 1].var; ${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 geo_out; void main() { out0 = geo_out; ${FRAGMENT_OUTPUT} } "" end case output_block version 310 es desc "Tessellation shader output block" 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 { fragment } values { output float out0 = 1.0; } vertex "" #version 310 es ${VERTEX_DECLARATIONS} void main() { ${VERTEX_OUTPUT} } "" tessellation_control "" #version 310 es ${TESSELLATION_CONTROL_DECLARATIONS} void main() { ${TESSELLATION_CONTROL_OUTPUT} } "" tessellation_evaluation "" #version 310 es ${TESSELLATION_EVALUATION_DECLARATIONS} out IOBlockName { mediump float var; } outputInstanceName; void main() { outputInstanceName.var = 1.0; ${TESSELLATION_EVALUATION_OUTPUT} } "" fragment "" #version 310 es precision mediump float; ${FRAGMENT_DECLARATIONS} in IOBlockName { mediump float var; } inputInstanceName; void main() { out0 = inputInstanceName.var; ${FRAGMENT_OUTPUT} } "" end case output_block_array version 310 es desc "Tessellation shader output block 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 { fragment } values { output float out0 = 1.0; } vertex "" #version 310 es ${VERTEX_DECLARATIONS} void main() { ${VERTEX_OUTPUT} } "" tessellation_control "" #version 310 es ${TESSELLATION_CONTROL_DECLARATIONS} void main() { ${TESSELLATION_CONTROL_OUTPUT} } "" tessellation_evaluation "" #version 310 es ${TESSELLATION_EVALUATION_DECLARATIONS} out IOBlockName { mediump float var; } outputInstanceName[2]; void main() { outputInstanceName[0].var = 2.0; outputInstanceName[1].var = 1.0; ${TESSELLATION_EVALUATION_OUTPUT} } "" fragment "" #version 310 es precision mediump float; ${FRAGMENT_DECLARATIONS} in IOBlockName { mediump float var; } inputInstanceName[2]; void main() { out0 = inputInstanceName[0].var - inputInstanceName[1].var; ${FRAGMENT_OUTPUT} } "" end case unspecified_vertex_count version 310 es desc "Tessellation shader unspecified vertex count" require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation } expect compile_or_link_fail vertex "" #version 310 es ${VERTEX_DECLARATIONS} void main() { ${VERTEX_OUTPUT} } "" tessellation_control "" #version 310 es void main() { ${TESSELLATION_CONTROL_OUTPUT} } "" tessellation_evaluation "" #version 310 es ${TESSELLATION_EVALUATION_DECLARATIONS} void main() { ${TESSELLATION_EVALUATION_OUTPUT} } "" fragment "" #version 310 es precision mediump float; ${FRAGMENT_DECLARATIONS} void main() { ${FRAGMENT_OUTPUT} } "" end case unspecified_primitive_mode version 310 es desc "Tessellation shader unspecified vertex count" require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation } expect compile_or_link_fail vertex "" #version 310 es ${VERTEX_DECLARATIONS} void main() { ${VERTEX_OUTPUT} } "" tessellation_control "" #version 310 es ${TESSELLATION_CONTROL_DECLARATIONS} void main() { ${TESSELLATION_CONTROL_OUTPUT} } "" tessellation_evaluation "" #version 310 es void main() { ${TESSELLATION_EVALUATION_OUTPUT} } "" fragment "" #version 310 es precision mediump float; ${FRAGMENT_DECLARATIONS} void main() { ${FRAGMENT_OUTPUT} } "" end end group qualifiers "Varying qualifiers" case smooth version 310 es desc "Smooth varying" 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} smooth out mediump float tc_in; void main() { tc_in = in0; ${VERTEX_OUTPUT} } "" tessellation_control "" #version 310 es ${TESSELLATION_CONTROL_DECLARATIONS} smooth in mediump float tc_in[]; smooth 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} smooth in mediump float tc_out[]; smooth out mediump float te_out; void main() { te_out = tc_out[2]; ${TESSELLATION_EVALUATION_OUTPUT} } "" fragment "" #version 310 es precision mediump float; ${FRAGMENT_DECLARATIONS} smooth in mediump float te_out; void main() { out0 = te_out; ${FRAGMENT_OUTPUT} } "" end case flat version 310 es desc "Flat varying" 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} flat out mediump float tc_in; void main() { tc_in = in0; ${VERTEX_OUTPUT} } "" tessellation_control "" #version 310 es ${TESSELLATION_CONTROL_DECLARATIONS} flat in mediump float tc_in[]; flat 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} flat in mediump float tc_out[]; flat out mediump float te_out; void main() { te_out = tc_out[2]; ${TESSELLATION_EVALUATION_OUTPUT} } "" fragment "" #version 310 es precision mediump float; ${FRAGMENT_DECLARATIONS} flat in mediump float te_out; void main() { out0 = te_out; ${FRAGMENT_OUTPUT} } "" end case centroid version 310 es desc "Centroid varying" 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} centroid out mediump float tc_in; void main() { tc_in = in0; ${VERTEX_OUTPUT} } "" tessellation_control "" #version 310 es ${TESSELLATION_CONTROL_DECLARATIONS} centroid in mediump float tc_in[]; centroid 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} centroid in mediump float tc_out[]; centroid out mediump float te_out; void main() { te_out = tc_out[2]; ${TESSELLATION_EVALUATION_OUTPUT} } "" fragment "" #version 310 es precision mediump float; ${FRAGMENT_DECLARATIONS} centroid in mediump float te_out; void main() { out0 = te_out; ${FRAGMENT_OUTPUT} } "" end case sample version 310 es desc "Sample varying" require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation } require extension { "GL_OES_shader_multisample_interpolation" } values { input float in0 = 1.0; output float out0 = 1.0; } vertex "" #version 310 es ${VERTEX_DECLARATIONS} sample out mediump float tc_in; void main() { tc_in = in0; ${VERTEX_OUTPUT} } "" tessellation_control "" #version 310 es ${TESSELLATION_CONTROL_DECLARATIONS} sample in mediump float tc_in[]; sample 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} sample in mediump float tc_out[]; sample out mediump float te_out; void main() { te_out = tc_out[2]; ${TESSELLATION_EVALUATION_OUTPUT} } "" fragment "" #version 310 es precision mediump float; ${FRAGMENT_DECLARATIONS} sample in mediump float te_out; void main() { out0 = te_out; ${FRAGMENT_OUTPUT} } "" end case patch version 310 es desc "Pre-patch varying" 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[]; patch out mediump float tc_out; void main() { tc_out = tc_in[gl_InvocationID]; ${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 end import "linkage_tessellation_varying_types.test" end group uniform "Uniform" group rules "Rules" case type_mismatch_1 version 310 es desc "uniform type mismatch between vertex and tessellation control shaders" expect link_fail require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation } vertex "" #version 310 es ${VERTEX_DECLARATIONS} uniform mediump float val; out mediump float vtx_out; void main() { vtx_out = val; ${VERTEX_OUTPUT} } "" tessellation_control "" #version 310 es ${TESSELLATION_CONTROL_DECLARATIONS} uniform mediump vec2 val; in mediump float vtx_out[]; out mediump float tc_out[]; void main() { tc_out[gl_InvocationID] = vtx_out[0] + val.x + val.y; ${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() { ${FRAG_COLOR} = vec4(te_out); } "" end case type_mismatch_2 version 310 es desc "uniform type mismatch between fragment and tessellation eval shaders" expect link_fail require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation } vertex "" #version 310 es ${VERTEX_DECLARATIONS} out mediump float vtx_out; void main() { ${VERTEX_OUTPUT} } "" tessellation_control "" #version 310 es ${TESSELLATION_CONTROL_DECLARATIONS} void main() { ${TESSELLATION_CONTROL_OUTPUT} } "" tessellation_evaluation "" #version 310 es ${TESSELLATION_EVALUATION_DECLARATIONS} uniform mediump vec3 val; out mediump float te_out; void main() { te_out = val.x + val.y + val.z; ${TESSELLATION_EVALUATION_OUTPUT} } "" fragment "" #version 310 es precision mediump float; ${FRAGMENT_DECLARATIONS} uniform mediump vec4 val; in mediump float te_out; void main() { ${FRAG_COLOR} = vec4(te_out) + val; } "" end case type_mismatch_3 version 310 es desc "uniform type mismatch between tessellation control and eval shaders" expect link_fail require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation } vertex "" #version 310 es ${VERTEX_DECLARATIONS} out mediump float vtx_out; void main() { ${VERTEX_OUTPUT} } "" tessellation_control "" #version 310 es ${TESSELLATION_CONTROL_DECLARATIONS} uniform mediump vec4 val; out mediump vec4 tc_out[]; void main() { tc_out[gl_InvocationID] = val; ${TESSELLATION_CONTROL_OUTPUT} } "" tessellation_evaluation "" #version 310 es ${TESSELLATION_EVALUATION_DECLARATIONS} uniform mediump vec3 val; in mediump vec4 tc_out[]; out mediump float te_out; void main() { te_out = tc_out[0].w * val.z; ${TESSELLATION_EVALUATION_OUTPUT} } "" fragment "" #version 310 es precision mediump float; ${FRAGMENT_DECLARATIONS} in mediump float te_out; void main() { ${FRAG_COLOR} = vec4(te_out); } "" end case type_mismatch_4 version 310 es desc "uniform type mismatch between vertex and tessellation control shaders" expect link_fail require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation } require limit "GL_MAX_VERTEX_ATOMIC_COUNTERS" > 0 vertex "" #version 310 es ${VERTEX_DECLARATIONS} layout(binding=0) uniform atomic_uint u_var; out mediump float vtx_out; void main() { uint result = atomicCounterIncrement(u_var); vtx_out = float(result); ${VERTEX_OUTPUT} } "" tessellation_control "" #version 310 es ${TESSELLATION_CONTROL_DECLARATIONS} uniform mediump float u_var; in mediump float vtx_out[]; out mediump float tc_out[]; void main() { tc_out[gl_InvocationID] = vtx_out[0] + u_var; ${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() { ${FRAG_COLOR} = vec4(te_out); } "" end case type_mismatch_5 version 310 es desc "uniform type mismatch between vertex and tessellation control shaders" expect link_fail require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation } require limit "GL_MAX_VERTEX_IMAGE_UNIFORMS" > 0 vertex "" #version 310 es ${VERTEX_DECLARATIONS} layout(binding=0) layout(rgba8i) uniform readonly highp iimage2D u_var; out mediump float vtx_out; void main() { int result = imageSize(u_var).x; vtx_out = float(result); ${VERTEX_OUTPUT} } "" tessellation_control "" #version 310 es ${TESSELLATION_CONTROL_DECLARATIONS} uniform mediump float u_var; in mediump float vtx_out[]; out mediump float tc_out[]; void main() { tc_out[gl_InvocationID] = vtx_out[0] + u_var; ${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() { ${FRAG_COLOR} = vec4(te_out); } "" end case precision_mismatch_1 version 310 es desc "uniform precision mismatch between tessellation control and eval shaders" expect link_fail require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation } vertex "" #version 310 es ${VERTEX_DECLARATIONS} out mediump float vtx_out; void main() { ${VERTEX_OUTPUT} } "" tessellation_control "" #version 310 es ${TESSELLATION_CONTROL_DECLARATIONS} uniform mediump vec4 val; out mediump vec4 tc_out[]; void main() { tc_out[gl_InvocationID] = val; ${TESSELLATION_CONTROL_OUTPUT} } "" tessellation_evaluation "" #version 310 es ${TESSELLATION_EVALUATION_DECLARATIONS} uniform highp vec4 val; in mediump vec4 tc_out[]; out mediump float te_out; void main() { te_out = tc_out[0].w * val.z; ${TESSELLATION_EVALUATION_OUTPUT} } "" fragment "" #version 310 es precision mediump float; ${FRAGMENT_DECLARATIONS} in mediump float te_out; void main() { ${FRAG_COLOR} = vec4(te_out); } "" end case precision_mismatch_2 version 310 es desc "uniform precision mismatch between vertex and tessellation control shaders" expect link_fail require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation } vertex "" #version 310 es ${VERTEX_DECLARATIONS} uniform highp float val; out mediump float vtx_out; void main() { vtx_out = val; ${VERTEX_OUTPUT} } "" tessellation_control "" #version 310 es ${TESSELLATION_CONTROL_DECLARATIONS} uniform mediump float val; in mediump float vtx_out[]; out mediump float tc_out[]; void main() { tc_out[gl_InvocationID] = vtx_out[0] + val; ${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() { ${FRAG_COLOR} = vec4(te_out); } "" end case struct_partial_usage version 310 es desc "uniform is partially used in different shader stages" require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation } values { uniform float val.vtxVal = 1.5; uniform float val.tcVal = 2.5; uniform float val.teVal = 6.0; uniform float val.fragVal = 11.0; output float out0 = 68.5; } vertex "" #version 310 es ${VERTEX_DECLARATIONS} struct S { mediump float vtxVal; mediump float tcVal; mediump float teVal; mediump float fragVal; }; uniform S val; out mediump float vtx_out; void main() { vtx_out = val.vtxVal; ${VERTEX_OUTPUT} } "" tessellation_control "" #version 310 es ${TESSELLATION_CONTROL_DECLARATIONS} struct S { mediump float vtxVal; mediump float tcVal; mediump float teVal; mediump float fragVal; }; uniform S val; in mediump float vtx_out[]; out mediump float tc_out[]; void main() { tc_out[gl_InvocationID] = vtx_out[0] + 2.0 * val.tcVal; ${TESSELLATION_CONTROL_OUTPUT} } "" tessellation_evaluation "" #version 310 es ${TESSELLATION_EVALUATION_DECLARATIONS} struct S { mediump float vtxVal; mediump float tcVal; mediump float teVal; mediump float fragVal; }; uniform S val; in mediump float tc_out[]; out mediump float te_out; void main() { te_out = tc_out[2] + 3.0 * val.teVal; ${TESSELLATION_EVALUATION_OUTPUT} } "" fragment "" #version 310 es precision mediump float; ${FRAGMENT_DECLARATIONS} struct S { mediump float vtxVal; mediump float tcVal; mediump float teVal; mediump float fragVal; }; uniform S val; in mediump float te_out; void main() { out0 = te_out + 4.0 * val.fragVal; ${FRAGMENT_OUTPUT}; } "" end end 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