group varying "Varying linkage" group rules "Rules" case type_mismatch version 310 es desc "Tessellation output and geometry input type mismatch" expect link_fail require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation } require extension { "GL_OES_geometry_shader" | "GL_EXT_geometry_shader" } in { geometry } values { input float in0 = 1.0; output float out0 = 1.0; } vertex "" #version 310 es ${VERTEX_DECLARATIONS} out mediump float vtx_out; void main() { vtx_out = in0; ${VERTEX_OUTPUT} } "" tessellation_control "" #version 310 es ${TESSELLATION_CONTROL_DECLARATIONS} in mediump float vtx_out[]; out mediump float tc_out[]; void main() { tc_out[gl_InvocationID] = vtx_out[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} } "" geometry "" #version 310 es ${GEOMETRY_DECLARATIONS} in mediump vec2 te_out[]; out mediump float geo_out; void main() { for (int ndx = 0; ndx < gl_in.length(); ++ndx) { geo_out = te_out[ndx].y; gl_Position = gl_in[ndx].gl_Position; EmitVertex(); } } "" fragment "" #version 310 es precision mediump float; ${FRAGMENT_DECLARATIONS} in mediump float geo_out; void main() { out0 = geo_out; ${FRAGMENT_OUTPUT} } "" end case different_precision version 310 es desc "Tessellation output and geometry input precisions are different" require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation } require extension { "GL_OES_geometry_shader" | "GL_EXT_geometry_shader" } in { geometry } values { input float in0 = 1.0; output float out0 = 1.0; } vertex "" #version 310 es ${VERTEX_DECLARATIONS} out mediump float vtx_out; void main() { vtx_out = in0; ${VERTEX_OUTPUT} } "" tessellation_control "" #version 310 es ${TESSELLATION_CONTROL_DECLARATIONS} in mediump float vtx_out[]; out mediump float tc_out[]; void main() { tc_out[gl_InvocationID] = vtx_out[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} } "" geometry "" #version 310 es ${GEOMETRY_DECLARATIONS} in highp float te_out[]; out mediump float geo_out; void main() { for (int ndx = 0; ndx < gl_in.length(); ++ndx) { geo_out = te_out[ndx]; gl_Position = gl_in[ndx].gl_Position; EmitVertex(); } } "" fragment "" #version 310 es precision mediump float; ${FRAGMENT_DECLARATIONS} in mediump float geo_out; void main() { out0 = geo_out; ${FRAGMENT_OUTPUT} } "" end case no_output_declaration version 310 es desc "Geometry input has no matching output" expect link_fail require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation } require extension { "GL_OES_geometry_shader" | "GL_EXT_geometry_shader" } in { geometry } values { input float in0 = 1.0; output float out0 = 1.0; } vertex "" #version 310 es ${VERTEX_DECLARATIONS} out mediump float vtx_out; void main() { vtx_out = in0; ${VERTEX_OUTPUT} } "" tessellation_control "" #version 310 es ${TESSELLATION_CONTROL_DECLARATIONS} in mediump float vtx_out[]; out mediump float tc_out[]; void main() { tc_out[gl_InvocationID] = vtx_out[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} } "" geometry "" #version 310 es ${GEOMETRY_DECLARATIONS} in mediump float te_out[]; in mediump float te_out_nonexistent[]; out mediump float geo_out; void main() { for (int ndx = 0; ndx < gl_in.length(); ++ndx) { geo_out = te_out[ndx] + te_out_nonexistent[ndx]; gl_Position = gl_in[ndx].gl_Position; EmitVertex(); } } "" fragment "" #version 310 es precision mediump float; ${FRAGMENT_DECLARATIONS} in mediump float geo_out; void main() { out0 = geo_out; ${FRAGMENT_OUTPUT} } "" end case superfluous_output_declaration version 310 es desc "Tessellation shader output is never used" require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation } require extension { "GL_OES_geometry_shader" | "GL_EXT_geometry_shader" } in { geometry } values { input float in0 = 1.0; output float out0 = 1.0; } vertex "" #version 310 es ${VERTEX_DECLARATIONS} out mediump float vtx_out; void main() { vtx_out = in0; ${VERTEX_OUTPUT} } "" tessellation_control "" #version 310 es ${TESSELLATION_CONTROL_DECLARATIONS} in mediump float vtx_out[]; out mediump float tc_out[]; void main() { tc_out[gl_InvocationID] = vtx_out[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_nonexistent; void main() { te_out = tc_out[2]; te_out_nonexistent = tc_out[0]; ${TESSELLATION_EVALUATION_OUTPUT} } "" geometry "" #version 310 es ${GEOMETRY_DECLARATIONS} in mediump float te_out[]; out mediump float geo_out; void main() { for (int ndx = 0; ndx < gl_in.length(); ++ndx) { geo_out = te_out[ndx]; gl_Position = gl_in[ndx].gl_Position; EmitVertex(); } } "" fragment "" #version 310 es precision mediump float; ${FRAGMENT_DECLARATIONS} in mediump float geo_out; void main() { out0 = geo_out; ${FRAGMENT_OUTPUT} } "" end case vertex_geometry_same_varying_name_1 version 310 es desc "Vertex output and geometry input share the same name" require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation } require extension { "GL_OES_geometry_shader" | "GL_EXT_geometry_shader" } in { geometry } values { input float in0 = 1.0; output float out0 = 1.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 = tc_out[2]; ${TESSELLATION_EVALUATION_OUTPUT} } "" geometry "" #version 310 es ${GEOMETRY_DECLARATIONS} in mediump float sharedVaringName[]; out mediump float geo_out; void main() { for (int ndx = 0; ndx < gl_in.length(); ++ndx) { geo_out = sharedVaringName[ndx]; gl_Position = gl_in[ndx].gl_Position; EmitVertex(); } } "" fragment "" #version 310 es precision mediump float; ${FRAGMENT_DECLARATIONS} in mediump float geo_out; void main() { out0 = geo_out; ${FRAGMENT_OUTPUT} } "" end case vertex_geometry_same_varying_name_2 version 310 es desc "Vertex output and geometry input share the same name" require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation } require extension { "GL_OES_geometry_shader" | "GL_EXT_geometry_shader" } in { geometry } values { input vec2 in0 = vec2(1.0, 1.0); output float out0 = 1.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] = 2.0 * 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} } "" geometry "" #version 310 es ${GEOMETRY_DECLARATIONS} in mediump float sharedVaringName[]; out mediump float geo_out; void main() { for (int ndx = 0; ndx < gl_in.length(); ++ndx) { geo_out = sharedVaringName[ndx]; gl_Position = gl_in[ndx].gl_Position; EmitVertex(); } } "" fragment "" #version 310 es precision mediump float; ${FRAGMENT_DECLARATIONS} in mediump float geo_out; void main() { out0 = geo_out; ${FRAGMENT_OUTPUT} } "" end case io_block version 310 es desc "Use of io block between tessellation and geometry shaders" require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation } require extension { "GL_OES_geometry_shader" | "GL_EXT_geometry_shader" } in { geometry } values { input float in0 = 1.0; output float out0 = 1.0; } vertex "" #version 310 es ${VERTEX_DECLARATIONS} out mediump float vtx_out; void main() { vtx_out = in0; ${VERTEX_OUTPUT} } "" tessellation_control "" #version 310 es ${TESSELLATION_CONTROL_DECLARATIONS} in mediump float vtx_out[]; out mediump float tc_out[]; void main() { tc_out[gl_InvocationID] = vtx_out[gl_InvocationID]; ${TESSELLATION_CONTROL_OUTPUT} } "" tessellation_evaluation "" #version 310 es ${TESSELLATION_EVALUATION_DECLARATIONS} in mediump float tc_out[]; out IOBlockName { mediump float val; } instanceName; void main() { instanceName.val = tc_out[2]; ${TESSELLATION_EVALUATION_OUTPUT} } "" geometry "" #version 310 es ${GEOMETRY_DECLARATIONS} in IOBlockName { mediump float val; } instanceName[]; out mediump float geo_out; void main() { geo_out = instanceName[0].val; gl_Position = gl_in[0].gl_Position; EmitVertex(); geo_out = instanceName[1].val; gl_Position = gl_in[1].gl_Position; EmitVertex(); geo_out = instanceName[2].val; gl_Position = gl_in[2].gl_Position; EmitVertex(); } "" fragment "" #version 310 es precision mediump float; ${FRAGMENT_DECLARATIONS} in mediump float geo_out; void main() { out0 = geo_out; ${FRAGMENT_OUTPUT} } "" end case array_in_io_block version 310 es desc "Float array in a io block between tessellation and geometry shaders" require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation } require extension { "GL_OES_geometry_shader" | "GL_EXT_geometry_shader" } in { geometry } values { input float in0 = 1.0; output float out0 = 1.0; } vertex "" #version 310 es ${VERTEX_DECLARATIONS} out mediump float vtx_out; void main() { vtx_out = in0; ${VERTEX_OUTPUT} } "" tessellation_control "" #version 310 es ${TESSELLATION_CONTROL_DECLARATIONS} in mediump float vtx_out[]; out mediump float tc_out[]; void main() { tc_out[gl_InvocationID] = vtx_out[gl_InvocationID]; ${TESSELLATION_CONTROL_OUTPUT} } "" tessellation_evaluation "" #version 310 es ${TESSELLATION_EVALUATION_DECLARATIONS} in mediump float tc_out[]; out IOBlockName { mediump float val[2]; } instanceName; void main() { instanceName.val[0] = tc_out[2] + 1.0; instanceName.val[1] = -1.0; ${TESSELLATION_EVALUATION_OUTPUT} } "" geometry "" #version 310 es ${GEOMETRY_DECLARATIONS} in IOBlockName { mediump float val[2]; } instanceName[]; out mediump float geo_out; void main() { geo_out = instanceName[0].val[0] + instanceName[0].val[1]; gl_Position = gl_in[0].gl_Position; EmitVertex(); geo_out = instanceName[1].val[0] + instanceName[1].val[1]; gl_Position = gl_in[1].gl_Position; EmitVertex(); geo_out = instanceName[2].val[0] + instanceName[2].val[1]; gl_Position = gl_in[2].gl_Position; EmitVertex(); } "" fragment "" #version 310 es precision mediump float; ${FRAGMENT_DECLARATIONS} in mediump float geo_out; void main() { out0 = geo_out; ${FRAGMENT_OUTPUT} } "" end end import "linkage_tessellation_geometry_varying_types.test" end group uniform "Uniform linkage" group rules "Rules" case type_mismatch_1 version 310 es desc "Uniform type mismatch" require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation } require extension { "GL_OES_geometry_shader" | "GL_EXT_geometry_shader" } in { geometry } expect 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 ${TESSELLATION_EVALUATION_DECLARATIONS} uniform mediump float u_value; out mediump float te_out; void main() { te_out = u_value; ${TESSELLATION_EVALUATION_OUTPUT} } "" geometry "" #version 310 es ${GEOMETRY_DECLARATIONS} uniform mediump vec2 u_value; in mediump float te_out[]; out mediump float geo_out; void main() { for (int ndx = 0; ndx < gl_in.length(); ++ndx) { geo_out = te_out[ndx] + u_value.y; gl_Position = gl_in[ndx].gl_Position; EmitVertex(); } } "" fragment "" #version 310 es precision mediump float; ${FRAGMENT_DECLARATIONS} in mediump float geo_out; void main() { ${FRAG_COLOR} = vec4(geo_out); } "" end case precision_mismatch_1 version 310 es desc "Uniform precision mismatch" require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation } require extension { "GL_OES_geometry_shader" | "GL_EXT_geometry_shader" } in { geometry } expect 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 ${TESSELLATION_EVALUATION_DECLARATIONS} uniform mediump float u_value; out mediump float te_out; void main() { te_out = u_value; ${TESSELLATION_EVALUATION_OUTPUT} } "" geometry "" #version 310 es ${GEOMETRY_DECLARATIONS} uniform highp float u_value; in mediump float te_out[]; out mediump float geo_out; void main() { for (int ndx = 0; ndx < gl_in.length(); ++ndx) { geo_out = te_out[ndx] + u_value; gl_Position = gl_in[ndx].gl_Position; EmitVertex(); } } "" fragment "" #version 310 es precision mediump float; ${FRAGMENT_DECLARATIONS} in mediump float geo_out; void main() { ${FRAG_COLOR} = vec4(geo_out); } "" end case struct_partial_usage version 310 es desc "Uniform precision mismatch" require extension { "GL_OES_tessellation_shader" | "GL_EXT_tessellation_shader" } in { tessellation_control, tessellation_evaluation } require extension { "GL_OES_geometry_shader" | "GL_EXT_geometry_shader" } in { geometry } values { uniform float u_value.teVal = 1.0; uniform float u_value.geoVal = 2.0; output float out0 = 5.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} struct S { mediump float teVal; mediump float geoVal; }; uniform S u_value; out mediump float te_out; void main() { te_out = u_value.teVal; ${TESSELLATION_EVALUATION_OUTPUT} } "" geometry "" #version 310 es ${GEOMETRY_DECLARATIONS} struct S { mediump float teVal; mediump float geoVal; }; uniform S u_value; in mediump float te_out[]; out mediump float geo_out; void main() { for (int ndx = 0; ndx < gl_in.length(); ++ndx) { geo_out = te_out[ndx] + 2.0 * u_value.geoVal; gl_Position = gl_in[ndx].gl_Position; EmitVertex(); } } "" fragment "" #version 310 es precision mediump float; ${FRAGMENT_DECLARATIONS} in mediump float geo_out; void main() { out0 = geo_out; ${FRAGMENT_OUTPUT} } "" end end end