[2/2] arb_program_interface_query: correct rendez-vous by name matching

Submitted by Andres Gomez on Feb. 8, 2019, 4:57 p.m.

Details

Message ID 20190208165721.28952-3-agomez@igalia.com
State Accepted
Headers show
Series "arb_program_interface_query: series correcting existing tests" ( rev: 1 ) in Piglit

Not browsing as part of any series.

Commit Message

Andres Gomez Feb. 8, 2019, 4:57 p.m.
Previuosly, this was overlooked asuming that, since they were SSOs, no
inner interface matching check was needed.

From the ARB_separate_shader_objects spec v.25:

  " With separable program objects, interfaces between shader stages
    may involve the outputs from one program object and the inputs
    from a second program object.  For such interfaces, it is not
    possible to detect mismatches at link time, because the programs
    are linked separately.  When each such program is linked, all
    inputs or outputs interfacing with another program stage are
    treated as active.  The linker will generate an executable that
    assumes the presence of a compatible program on the other side of
    the interface.  If a mismatch between programs occurs, no GL error
    will be generated, but some or all of the inputs on the interface
    will be undefined."

Cc: Timothy Arceri <tarceri@itsqueeze.com>
Cc: Tapani Pälli <tapani.palli@intel.com>
Cc: Ilia Mirkin <imirkin@alum.mit.edu>
Cc: Martin Peres <martin.peres@linux.intel.com>
Signed-off-by: Andres Gomez <agomez@igalia.com>
---
 .../spec/arb_program_interface_query/common.h | 61 ++++++++++++++++---
 .../getprogramresourceiv.c                    |  8 +--
 .../resource-query.c                          | 48 +++++++--------
 3 files changed, 79 insertions(+), 38 deletions(-)

Patch hide | download patch | download mbox

diff --git a/tests/spec/arb_program_interface_query/common.h b/tests/spec/arb_program_interface_query/common.h
index 371b0338b..c0a99ea64 100755
--- a/tests/spec/arb_program_interface_query/common.h
+++ b/tests/spec/arb_program_interface_query/common.h
@@ -74,9 +74,11 @@  static const char vs_std[] =
 	"uniform vs_struct sa[2];\n"
 	"in vec4 vs_input0;\n"
 	"in vec4 vs_input1;\n"
+	"out vec4 vs_output1;\n"
 	"void main() {\n"
 	"	gl_Position = vs_input0 * vs_test * vs_input1 + sa[0].a[1] +"
 	"	              sa[1].a[1];\n"
+	"	vs_output1 = vs_input0;\n"
 	"}";
 
 const char gs_std[] =
@@ -86,18 +88,38 @@  const char gs_std[] =
 	"uniform gs_uniform_block {\n"
 	"	vec4 gs_test;\n"
 	"};\n"
-	"in vec4 gs_input[3];\n"
-	"out vec4 gs_output0;\n"
+	"in vec4 vs_output1[3];\n"
+	"out vec4 fs_input1;\n"
 	"void main() {\n"
 	"	for (int i = 0; i < 6; i++) {\n"
-	"		gl_Position = gs_input[i % 3] *"
+	"		gl_Position = vs_output1[i % 3] *"
 	"		              gl_in[i % 3].gl_Position * gs_test;\n"
-	"		gs_output0 = gs_input[0];\n"
+	"		fs_input1 = vs_output1[0];\n"
 	"		EmitVertex();\n"
 	"	}\n"
 	"}\n";
 
 static const char fs_std[] =
+	"#version 150\n"
+	"uniform fs_uniform_block {"
+	"	vec4 fs_color;\n"
+	"	float fs_array[4];\n"
+	"};\n"
+	"uniform fs_array_uniform_block {\n"
+	"	vec4 fs_color;\n"
+	"	float fs_array[4];\n"
+	"} faub[4];\n"
+	"in vec4 vs_output1;\n"
+	"out vec4 fs_output0;\n"
+	"out vec4 fs_output1;\n"
+	"void main() {\n"
+		"fs_output0 = fs_color * vs_output1 * fs_array[2] * \n"
+		"	      faub[0].fs_array[2] * faub[2].fs_array[2];\n"
+		"fs_output1 = fs_color * vs_output1 * fs_array[3] * \n"
+		"             faub[1].fs_array[3] * faub[3].fs_array[3];\n"
+	"}";
+
+static const char fs_in[] =
 	"#version 150\n"
 	"uniform fs_uniform_block {"
 	"	vec4 fs_color;\n"
@@ -296,8 +318,8 @@  static const char tcs_sub[] =
 	"uniform tcs_uniform_block {\n"
 	"	vec4 tcs_test;\n"
 	"};\n"
-	"out vec4 tcs_output[3];\n"
-	"in vec4 tcs_input[gl_MaxPatchVertices];\n"
+	"out vec4 tes_input1[3];\n"
+	"in vec4 vs_output1[gl_MaxPatchVertices];\n"
 	"patch out vec4 tcs_patch;\n"
 	"subroutine vec4 tcs_offset();\n"
 	"subroutine uniform tcs_offset TESS_CONTROL;\n"
@@ -306,7 +328,7 @@  static const char tcs_sub[] =
 	"	gl_out[gl_InvocationID].gl_Position = tcs_test +"
 	"	                                      gl_in[0].gl_Position *"
 	"	                                      TESS_CONTROL();\n"
-	"	tcs_output[gl_InvocationID] = tcs_input[0] + TESS_CONTROL();\n"
+	"	tes_input1[gl_InvocationID] = vs_output1[0] + TESS_CONTROL();\n"
 	"}";
 
 static const char tes_sub[] =
@@ -317,15 +339,34 @@  static const char tes_sub[] =
 	"uniform tes_uniform_block {\n"
 	"	vec4 tes_test;\n"
 	"};\n"
-	"out vec4 tes_output[1];\n"
-	"in vec4 tes_input[gl_MaxPatchVertices];\n"
+	"out vec4 tes_output1;\n"
+	"in vec4 vs_output1[gl_MaxPatchVertices];\n"
+	"subroutine vec4 tes_offset();\n"
+	"subroutine uniform tes_offset TESS_EVALUATION;\n"
+	"subroutine (tes_offset) vec4 tess() { return vec4(1, 0, 0, 0); }\n"
+	"void main() {\n"
+	"	gl_Position = tes_test + gl_in[0].gl_Position +"
+	"	              TESS_EVALUATION();\n"
+	"	tes_output1 = vs_output1[0] + TESS_EVALUATION();\n"
+	"}";
+
+static const char tes_in[] =
+	"#version 150\n"
+	"#extension GL_ARB_shader_subroutine : require\n"
+	"#extension GL_ARB_tessellation_shader : require\n"
+	"layout(triangles) in;\n"
+	"uniform tes_uniform_block {\n"
+	"	vec4 tes_test;\n"
+	"};\n"
+	"out vec4 vs_output1;\n"
+	"in vec4 tes_input1[gl_MaxPatchVertices];\n"
 	"subroutine vec4 tes_offset();\n"
 	"subroutine uniform tes_offset TESS_EVALUATION;\n"
 	"subroutine (tes_offset) vec4 tess() { return vec4(1, 0, 0, 0); }\n"
 	"void main() {\n"
 	"	gl_Position = tes_test + gl_in[0].gl_Position +"
 	"	              TESS_EVALUATION();\n"
-	"	tes_output[0] = tes_input[0] + TESS_EVALUATION();\n"
+	"	vs_output1 = tes_input1[0] + TESS_EVALUATION();\n"
 	"}";
 
 static const char cs_sub[] =
diff --git a/tests/spec/arb_program_interface_query/getprogramresourceiv.c b/tests/spec/arb_program_interface_query/getprogramresourceiv.c
index 70212350e..e55cf96ac 100755
--- a/tests/spec/arb_program_interface_query/getprogramresourceiv.c
+++ b/tests/spec/arb_program_interface_query/getprogramresourceiv.c
@@ -567,8 +567,8 @@  static const struct subtest_t subtests[] = {
 	{ GL_REFERENCED_BY_COMPUTE_SHADER, 1, { 0 } },
 	{ 0, 0, { 0 } }}
  },
- { &prog_std, GL_TRANSFORM_FEEDBACK_VARYING, "gs_output0", NULL, {
-	{ GL_NAME_LENGTH, 1, { 11 } },
+ { &prog_std, GL_TRANSFORM_FEEDBACK_VARYING, "fs_input1", NULL, {
+	{ GL_NAME_LENGTH, 1, { 10 } },
 	{ GL_ARRAY_SIZE, 1, { 1 } },
 	{ 0, 0, { 0 } }}
  },
@@ -1012,7 +1012,7 @@  report_result:
 void
 piglit_init(int argc, char **argv)
 {
-	static const char *st_r_tf_varying[] = {"gs_output0", NULL};
+	static const char *st_r_tf_varying[] = {"fs_input1", NULL};
 
 	piglit_require_extension("GL_ARB_program_interface_query");
 	piglit_require_extension("GL_ARB_separate_shader_objects");
@@ -1021,7 +1021,7 @@  piglit_init(int argc, char **argv)
 	prog_std = piglit_build_simple_program_unlinked_multiple_shaders(
 					GL_VERTEX_SHADER, vs_std,
 					GL_GEOMETRY_SHADER, gs_std,
-					GL_FRAGMENT_SHADER, fs_std,
+					GL_FRAGMENT_SHADER, fs_in,
 					0);
 	glTransformFeedbackVaryings(prog_std, 1, st_r_tf_varying,
 				    GL_INTERLEAVED_ATTRIBS);
diff --git a/tests/spec/arb_program_interface_query/resource-query.c b/tests/spec/arb_program_interface_query/resource-query.c
index bf60dde93..f47431a30 100755
--- a/tests/spec/arb_program_interface_query/resource-query.c
+++ b/tests/spec/arb_program_interface_query/resource-query.c
@@ -209,25 +209,25 @@  static const char *st_r_tess_uniform_block[] = {"tcs_uniform_block",
 						"tes_uniform_block", NULL};
 static const char *st_r_cs_uniform_block[] = {"cs_uniform_block", NULL};
 static const char *st_r_in_vs[] = {"vs_input0", "vs_input1", NULL};
-static const char *st_r_in_gs[] = {"gs_input[0]", "gl_PerVertex.gl_Position", NULL};
+static const char *st_r_in_gs[] = {"vs_output1[0]", "gl_PerVertex.gl_Position", NULL};
 static const char *st_r_in_fs[] = {"fs_input1", NULL};
-static const char *st_r_in_tes[] = {"tes_input[0]", "gl_PerVertex.gl_Position", NULL};
-static const char *st_r_in_tcs[] = {"tcs_input[0]",
+static const char *st_r_in_tes[] = {"tes_input1[0]", "gl_PerVertex.gl_Position", NULL};
+static const char *st_r_in_tcs[] = {"vs_output1[0]",
 				    "gl_InvocationID",
 				    "gl_PerVertex.gl_Position",
 				    NULL};
-static const char *st_r_out_vs[] = {"gl_Position", NULL};
-static const char *st_r_out_gs[] = {"gs_output0", "gl_Position", NULL};
+static const char *st_r_out_vs[] = {"vs_output1", "gl_Position", NULL};
+static const char *st_r_out_gs[] = {"fs_input1", "gl_Position", NULL};
 static const char *st_r_out_fs[] = {"fs_output0", "fs_output1", NULL};
-static const char *st_r_out_tes[] = {"tes_output[0]", "gl_Position", NULL};
-static const char *st_r_out_tcs[] = {"tcs_output[0]", "tcs_patch",
+static const char *st_r_out_tes[] = {"vs_output1", "gl_Position", NULL};
+static const char *st_r_out_tcs[] = {"tes_input1[0]", "tcs_patch",
 				     "gl_PerVertex.gl_Position",
 				     NULL};
 static const char *st_r_buffer[] = {"vs_buf_var", "gs_buf_var", "fs_buf_var",
 				    NULL};
 static const char *st_r_stor_block[] = {"vs_buffer_block", "gs_buffer_block",
 					"fs_buffer_block", NULL};
-static const char *st_r_tf_varying[] = {"gl_Position", "gs_output0", NULL};
+static const char *st_r_tf_varying[] = {"gl_Position", "fs_input1", NULL};
 static const char *st_r_vs_sub[] = {"vss", "vss2", NULL};
 static const char *st_r_gs_sub[] = {"gss", NULL};
 static const char *st_r_fs_sub[] = {"fss", NULL};
@@ -353,35 +353,35 @@  struct subtest_t {
 }
 
 static const struct subtest_t subtests[] = {
- ST( 8, 35, -1, -1,  vs_std,    NULL,    NULL,  gs_std,  fs_std,   NULL, GL_UNIFORM, "(vs,gs,fs)", st_r_uniform),
- ST( 2,  9, -1, -1,    NULL, tcs_sub, tes_sub,    NULL,    NULL,   NULL, GL_UNIFORM, "(tes,tcs)", st_r_tess_uniform),
+ ST( 8, 35, -1, -1,  vs_std,    NULL,    NULL,  gs_std,   fs_in,   NULL, GL_UNIFORM, "(vs,gs,fs)", st_r_uniform),
+ ST( 2,  9, -1, -1,    NULL, tcs_sub,  tes_in,    NULL,    NULL,   NULL, GL_UNIFORM, "(tes,tcs)", st_r_tess_uniform),
  ST( 2,  8, -1, -1,    NULL,    NULL,    NULL,    NULL,    NULL, cs_sub, GL_UNIFORM, "(cs)", st_r_cs_uniform),
- ST( 7, 26,  2, -1,  vs_std,    NULL,    NULL,  gs_std,  fs_std,   NULL, GL_UNIFORM_BLOCK, "(vs,gs,fs)", st_r_uniform_block),
- ST( 2, 18, -1, -1,    NULL, tcs_sub, tes_sub,    NULL,    NULL,   NULL, GL_UNIFORM_BLOCK, "(tcs,tes)", st_r_tess_uniform_block),
+ ST( 7, 26,  2, -1,  vs_std,    NULL,    NULL,  gs_std,   fs_in,   NULL, GL_UNIFORM_BLOCK, "(vs,gs,fs)", st_r_uniform_block),
+ ST( 2, 18, -1, -1,    NULL, tcs_sub,  tes_in,    NULL,    NULL,   NULL, GL_UNIFORM_BLOCK, "(tcs,tes)", st_r_tess_uniform_block),
  ST( 1, 17, -1, -1,    NULL,    NULL,    NULL,    NULL,    NULL, cs_sub, GL_UNIFORM_BLOCK, "(cs)", st_r_cs_uniform_block),
  ST( 2, 10, -1, -1,  vs_std,    NULL,    NULL,    NULL,    NULL,   NULL, GL_PROGRAM_INPUT, "(vs)", st_r_in_vs),
  ST( 2, 25, -1, -1,    NULL,    NULL,    NULL,  gs_std,    NULL,   NULL, GL_PROGRAM_INPUT, "(gs)", st_r_in_gs),
- ST( 1, 10, -1, -1,    NULL,    NULL,    NULL,    NULL,  fs_std,   NULL, GL_PROGRAM_INPUT, "(fs)", st_r_in_fs),
+ ST( 1, 10, -1, -1,    NULL,    NULL,    NULL,    NULL,   fs_in,   NULL, GL_PROGRAM_INPUT, "(fs)", st_r_in_fs),
  ST( 2, 10, -1, -1,  vs_std,    NULL,    NULL,    NULL,  fs_std,   NULL, GL_PROGRAM_INPUT, "(vs,fs)", st_r_in_vs),
  ST( 2, 10, -1, -1,  vs_std,    NULL,    NULL,  gs_std,    NULL,   NULL, GL_PROGRAM_INPUT, "(vs,gs)", st_r_in_vs),
- ST( 2, 25, -1, -1,    NULL,    NULL,    NULL,  gs_std,  fs_std,   NULL, GL_PROGRAM_INPUT, "(gs,fs)", st_r_in_gs),
- ST( 2, 10, -1, -1,  vs_std,    NULL,    NULL,  gs_std,  fs_std,   NULL, GL_PROGRAM_INPUT, "(vs,gs,fs)", st_r_in_vs),
- ST( 2, 25, -1, -1,    NULL,    NULL, tes_sub,    NULL,    NULL,   NULL, GL_PROGRAM_INPUT, "(tes)", st_r_in_tes),
+ ST( 2, 25, -1, -1,    NULL,    NULL,    NULL,  gs_std,   fs_in,   NULL, GL_PROGRAM_INPUT, "(gs,fs)", st_r_in_gs),
+ ST( 2, 10, -1, -1,  vs_std,    NULL,    NULL,  gs_std,   fs_in,   NULL, GL_PROGRAM_INPUT, "(vs,gs,fs)", st_r_in_vs),
+ ST( 2, 25, -1, -1,    NULL,    NULL,  tes_in,    NULL,    NULL,   NULL, GL_PROGRAM_INPUT, "(tes)", st_r_in_tes),
  ST( 3, 25, -1, -1,    NULL, tcs_sub,    NULL,    NULL,    NULL,   NULL, GL_PROGRAM_INPUT, "(tcs)", st_r_in_tcs),
- ST( 3, 25, -1, -1,    NULL, tcs_sub, tes_sub,    NULL,    NULL,   NULL, GL_PROGRAM_INPUT, "(tcs,tes)", st_r_in_tcs),
- ST( 2, 10, -1, -1,  vs_std, tcs_sub, tes_sub,    NULL,    NULL,   NULL, GL_PROGRAM_INPUT, "(vs,tcs,tes)", st_r_in_vs),
+ ST( 3, 25, -1, -1,    NULL, tcs_sub,  tes_in,    NULL,    NULL,   NULL, GL_PROGRAM_INPUT, "(tcs,tes)", st_r_in_tcs),
+ ST( 2, 10, -1, -1,  vs_std, tcs_sub,  tes_in,    NULL,    NULL,   NULL, GL_PROGRAM_INPUT, "(vs,tcs,tes)", st_r_in_vs),
  ST( 0,  0, -1, -1,    NULL,    NULL,    NULL,    NULL,    NULL, cs_sub, GL_PROGRAM_INPUT, "(cs)", NULL),
- ST( 1, 12, -1, -1,  vs_std,    NULL,    NULL,    NULL,    NULL,   NULL, GL_PROGRAM_OUTPUT, "(vs)", st_r_out_vs),
+ ST( 2, 12, -1, -1,  vs_std,    NULL,    NULL,    NULL,    NULL,   NULL, GL_PROGRAM_OUTPUT, "(vs)", st_r_out_vs),
  ST( 2, 12, -1, -1,    NULL,    NULL,    NULL,  gs_std,    NULL,   NULL, GL_PROGRAM_OUTPUT, "(gs)", st_r_out_gs),
  ST( 2, 11, -1, -1,    NULL,    NULL,    NULL,    NULL,  fs_std,   NULL, GL_PROGRAM_OUTPUT, "(fs)", st_r_out_fs),
  ST( 2, 11, -1, -1,  vs_std,    NULL,    NULL,    NULL,  fs_std,   NULL, GL_PROGRAM_OUTPUT, "(vs,fs)", st_r_out_fs),
  ST( 2, 12, -1, -1,  vs_std,    NULL,    NULL,  gs_std,    NULL,   NULL, GL_PROGRAM_OUTPUT, "(vs,gs)", st_r_out_gs),
- ST( 2, 11, -1, -1,    NULL,    NULL,    NULL,  gs_std,  fs_std,   NULL, GL_PROGRAM_OUTPUT, "(gs,fs)", st_r_out_fs),
- ST( 2, 11, -1, -1,  vs_std,    NULL,    NULL,  gs_std,  fs_std,   NULL, GL_PROGRAM_OUTPUT, "(vs,gs,fs)", st_r_out_fs),
- ST( 2, 14, -1, -1,    NULL,    NULL, tes_sub,    NULL,    NULL,   NULL, GL_PROGRAM_OUTPUT, "(tes)", st_r_out_tes),
+ ST( 2, 11, -1, -1,    NULL,    NULL,    NULL,  gs_std,   fs_in,   NULL, GL_PROGRAM_OUTPUT, "(gs,fs)", st_r_out_fs),
+ ST( 2, 11, -1, -1,  vs_std,    NULL,    NULL,  gs_std,   fs_in,   NULL, GL_PROGRAM_OUTPUT, "(vs,gs,fs)", st_r_out_fs),
+ ST( 2, 12, -1, -1,    NULL,    NULL,  tes_in,    NULL,    NULL,   NULL, GL_PROGRAM_OUTPUT, "(tes)", st_r_out_tes),
  ST( 3, 25, -1, -1,    NULL, tcs_sub,    NULL,    NULL,    NULL,   NULL, GL_PROGRAM_OUTPUT, "(tcs)", st_r_out_tcs),
- ST( 2, 14, -1, -1,    NULL, tcs_sub, tes_sub,    NULL,    NULL,   NULL, GL_PROGRAM_OUTPUT, "(tcs,tes)", st_r_out_tes),
- ST( 2, 12, -1, -1,    NULL, tcs_sub, tes_sub,  gs_std,    NULL,   NULL, GL_PROGRAM_OUTPUT, "(tcs,tes,gs)", st_r_out_gs),
+ ST( 2, 12, -1, -1,    NULL, tcs_sub,  tes_in,    NULL,    NULL,   NULL, GL_PROGRAM_OUTPUT, "(tcs,tes)", st_r_out_tes),
+ ST( 2, 12, -1, -1,    NULL, tcs_sub,  tes_in,  gs_std,    NULL,   NULL, GL_PROGRAM_OUTPUT, "(tcs,tes,gs)", st_r_out_gs),
  ST( 0,  0, -1, -1,    NULL,    NULL,    NULL,    NULL,    NULL, cs_sub, GL_PROGRAM_OUTPUT, "(cs)", st_r_cs_sub),
  ST( 3, 11, -1, -1, vs_stor,    NULL,    NULL, gs_stor, fs_stor,   NULL, GL_BUFFER_VARIABLE, "", st_r_buffer),
  ST( 3, 16,  1, -1, vs_stor,    NULL,    NULL, gs_stor, fs_stor,   NULL, GL_SHADER_STORAGE_BLOCK, "", st_r_stor_block),

Comments

It would be great if you could run this test on the Nvidia binary blob 
to confirm the results. If everything works as expected the series is:

Reviewed-by: Timothy Arceri <tarceri@itsqueeze.com>

Thanks for fixing all this!

On 9/2/19 3:57 am, Andres Gomez wrote:
> Previuosly, this was overlooked asuming that, since they were SSOs, no
> inner interface matching check was needed.
> 
>  From the ARB_separate_shader_objects spec v.25:
> 
>    " With separable program objects, interfaces between shader stages
>      may involve the outputs from one program object and the inputs
>      from a second program object.  For such interfaces, it is not
>      possible to detect mismatches at link time, because the programs
>      are linked separately.  When each such program is linked, all
>      inputs or outputs interfacing with another program stage are
>      treated as active.  The linker will generate an executable that
>      assumes the presence of a compatible program on the other side of
>      the interface.  If a mismatch between programs occurs, no GL error
>      will be generated, but some or all of the inputs on the interface
>      will be undefined."
> 
> Cc: Timothy Arceri <tarceri@itsqueeze.com>
> Cc: Tapani Pälli <tapani.palli@intel.com>
> Cc: Ilia Mirkin <imirkin@alum.mit.edu>
> Cc: Martin Peres <martin.peres@linux.intel.com>
> Signed-off-by: Andres Gomez <agomez@igalia.com>
> ---
>   .../spec/arb_program_interface_query/common.h | 61 ++++++++++++++++---
>   .../getprogramresourceiv.c                    |  8 +--
>   .../resource-query.c                          | 48 +++++++--------
>   3 files changed, 79 insertions(+), 38 deletions(-)
> 
> diff --git a/tests/spec/arb_program_interface_query/common.h b/tests/spec/arb_program_interface_query/common.h
> index 371b0338b..c0a99ea64 100755
> --- a/tests/spec/arb_program_interface_query/common.h
> +++ b/tests/spec/arb_program_interface_query/common.h
> @@ -74,9 +74,11 @@ static const char vs_std[] =
>   	"uniform vs_struct sa[2];\n"
>   	"in vec4 vs_input0;\n"
>   	"in vec4 vs_input1;\n"
> +	"out vec4 vs_output1;\n"
>   	"void main() {\n"
>   	"	gl_Position = vs_input0 * vs_test * vs_input1 + sa[0].a[1] +"
>   	"	              sa[1].a[1];\n"
> +	"	vs_output1 = vs_input0;\n"
>   	"}";
>   
>   const char gs_std[] =
> @@ -86,18 +88,38 @@ const char gs_std[] =
>   	"uniform gs_uniform_block {\n"
>   	"	vec4 gs_test;\n"
>   	"};\n"
> -	"in vec4 gs_input[3];\n"
> -	"out vec4 gs_output0;\n"
> +	"in vec4 vs_output1[3];\n"
> +	"out vec4 fs_input1;\n"
>   	"void main() {\n"
>   	"	for (int i = 0; i < 6; i++) {\n"
> -	"		gl_Position = gs_input[i % 3] *"
> +	"		gl_Position = vs_output1[i % 3] *"
>   	"		              gl_in[i % 3].gl_Position * gs_test;\n"
> -	"		gs_output0 = gs_input[0];\n"
> +	"		fs_input1 = vs_output1[0];\n"
>   	"		EmitVertex();\n"
>   	"	}\n"
>   	"}\n";
>   
>   static const char fs_std[] =
> +	"#version 150\n"
> +	"uniform fs_uniform_block {"
> +	"	vec4 fs_color;\n"
> +	"	float fs_array[4];\n"
> +	"};\n"
> +	"uniform fs_array_uniform_block {\n"
> +	"	vec4 fs_color;\n"
> +	"	float fs_array[4];\n"
> +	"} faub[4];\n"
> +	"in vec4 vs_output1;\n"
> +	"out vec4 fs_output0;\n"
> +	"out vec4 fs_output1;\n"
> +	"void main() {\n"
> +		"fs_output0 = fs_color * vs_output1 * fs_array[2] * \n"
> +		"	      faub[0].fs_array[2] * faub[2].fs_array[2];\n"
> +		"fs_output1 = fs_color * vs_output1 * fs_array[3] * \n"
> +		"             faub[1].fs_array[3] * faub[3].fs_array[3];\n"
> +	"}";
> +
> +static const char fs_in[] =
>   	"#version 150\n"
>   	"uniform fs_uniform_block {"
>   	"	vec4 fs_color;\n"
> @@ -296,8 +318,8 @@ static const char tcs_sub[] =
>   	"uniform tcs_uniform_block {\n"
>   	"	vec4 tcs_test;\n"
>   	"};\n"
> -	"out vec4 tcs_output[3];\n"
> -	"in vec4 tcs_input[gl_MaxPatchVertices];\n"
> +	"out vec4 tes_input1[3];\n"
> +	"in vec4 vs_output1[gl_MaxPatchVertices];\n"
>   	"patch out vec4 tcs_patch;\n"
>   	"subroutine vec4 tcs_offset();\n"
>   	"subroutine uniform tcs_offset TESS_CONTROL;\n"
> @@ -306,7 +328,7 @@ static const char tcs_sub[] =
>   	"	gl_out[gl_InvocationID].gl_Position = tcs_test +"
>   	"	                                      gl_in[0].gl_Position *"
>   	"	                                      TESS_CONTROL();\n"
> -	"	tcs_output[gl_InvocationID] = tcs_input[0] + TESS_CONTROL();\n"
> +	"	tes_input1[gl_InvocationID] = vs_output1[0] + TESS_CONTROL();\n"
>   	"}";
>   
>   static const char tes_sub[] =
> @@ -317,15 +339,34 @@ static const char tes_sub[] =
>   	"uniform tes_uniform_block {\n"
>   	"	vec4 tes_test;\n"
>   	"};\n"
> -	"out vec4 tes_output[1];\n"
> -	"in vec4 tes_input[gl_MaxPatchVertices];\n"
> +	"out vec4 tes_output1;\n"
> +	"in vec4 vs_output1[gl_MaxPatchVertices];\n"
> +	"subroutine vec4 tes_offset();\n"
> +	"subroutine uniform tes_offset TESS_EVALUATION;\n"
> +	"subroutine (tes_offset) vec4 tess() { return vec4(1, 0, 0, 0); }\n"
> +	"void main() {\n"
> +	"	gl_Position = tes_test + gl_in[0].gl_Position +"
> +	"	              TESS_EVALUATION();\n"
> +	"	tes_output1 = vs_output1[0] + TESS_EVALUATION();\n"
> +	"}";
> +
> +static const char tes_in[] =
> +	"#version 150\n"
> +	"#extension GL_ARB_shader_subroutine : require\n"
> +	"#extension GL_ARB_tessellation_shader : require\n"
> +	"layout(triangles) in;\n"
> +	"uniform tes_uniform_block {\n"
> +	"	vec4 tes_test;\n"
> +	"};\n"
> +	"out vec4 vs_output1;\n"
> +	"in vec4 tes_input1[gl_MaxPatchVertices];\n"
>   	"subroutine vec4 tes_offset();\n"
>   	"subroutine uniform tes_offset TESS_EVALUATION;\n"
>   	"subroutine (tes_offset) vec4 tess() { return vec4(1, 0, 0, 0); }\n"
>   	"void main() {\n"
>   	"	gl_Position = tes_test + gl_in[0].gl_Position +"
>   	"	              TESS_EVALUATION();\n"
> -	"	tes_output[0] = tes_input[0] + TESS_EVALUATION();\n"
> +	"	vs_output1 = tes_input1[0] + TESS_EVALUATION();\n"
>   	"}";
>   
>   static const char cs_sub[] =
> diff --git a/tests/spec/arb_program_interface_query/getprogramresourceiv.c b/tests/spec/arb_program_interface_query/getprogramresourceiv.c
> index 70212350e..e55cf96ac 100755
> --- a/tests/spec/arb_program_interface_query/getprogramresourceiv.c
> +++ b/tests/spec/arb_program_interface_query/getprogramresourceiv.c
> @@ -567,8 +567,8 @@ static const struct subtest_t subtests[] = {
>   	{ GL_REFERENCED_BY_COMPUTE_SHADER, 1, { 0 } },
>   	{ 0, 0, { 0 } }}
>    },
> - { &prog_std, GL_TRANSFORM_FEEDBACK_VARYING, "gs_output0", NULL, {
> -	{ GL_NAME_LENGTH, 1, { 11 } },
> + { &prog_std, GL_TRANSFORM_FEEDBACK_VARYING, "fs_input1", NULL, {
> +	{ GL_NAME_LENGTH, 1, { 10 } },
>   	{ GL_ARRAY_SIZE, 1, { 1 } },
>   	{ 0, 0, { 0 } }}
>    },
> @@ -1012,7 +1012,7 @@ report_result:
>   void
>   piglit_init(int argc, char **argv)
>   {
> -	static const char *st_r_tf_varying[] = {"gs_output0", NULL};
> +	static const char *st_r_tf_varying[] = {"fs_input1", NULL};
>   
>   	piglit_require_extension("GL_ARB_program_interface_query");
>   	piglit_require_extension("GL_ARB_separate_shader_objects");
> @@ -1021,7 +1021,7 @@ piglit_init(int argc, char **argv)
>   	prog_std = piglit_build_simple_program_unlinked_multiple_shaders(
>   					GL_VERTEX_SHADER, vs_std,
>   					GL_GEOMETRY_SHADER, gs_std,
> -					GL_FRAGMENT_SHADER, fs_std,
> +					GL_FRAGMENT_SHADER, fs_in,
>   					0);
>   	glTransformFeedbackVaryings(prog_std, 1, st_r_tf_varying,
>   				    GL_INTERLEAVED_ATTRIBS);
> diff --git a/tests/spec/arb_program_interface_query/resource-query.c b/tests/spec/arb_program_interface_query/resource-query.c
> index bf60dde93..f47431a30 100755
> --- a/tests/spec/arb_program_interface_query/resource-query.c
> +++ b/tests/spec/arb_program_interface_query/resource-query.c
> @@ -209,25 +209,25 @@ static const char *st_r_tess_uniform_block[] = {"tcs_uniform_block",
>   						"tes_uniform_block", NULL};
>   static const char *st_r_cs_uniform_block[] = {"cs_uniform_block", NULL};
>   static const char *st_r_in_vs[] = {"vs_input0", "vs_input1", NULL};
> -static const char *st_r_in_gs[] = {"gs_input[0]", "gl_PerVertex.gl_Position", NULL};
> +static const char *st_r_in_gs[] = {"vs_output1[0]", "gl_PerVertex.gl_Position", NULL};
>   static const char *st_r_in_fs[] = {"fs_input1", NULL};
> -static const char *st_r_in_tes[] = {"tes_input[0]", "gl_PerVertex.gl_Position", NULL};
> -static const char *st_r_in_tcs[] = {"tcs_input[0]",
> +static const char *st_r_in_tes[] = {"tes_input1[0]", "gl_PerVertex.gl_Position", NULL};
> +static const char *st_r_in_tcs[] = {"vs_output1[0]",
>   				    "gl_InvocationID",
>   				    "gl_PerVertex.gl_Position",
>   				    NULL};
> -static const char *st_r_out_vs[] = {"gl_Position", NULL};
> -static const char *st_r_out_gs[] = {"gs_output0", "gl_Position", NULL};
> +static const char *st_r_out_vs[] = {"vs_output1", "gl_Position", NULL};
> +static const char *st_r_out_gs[] = {"fs_input1", "gl_Position", NULL};
>   static const char *st_r_out_fs[] = {"fs_output0", "fs_output1", NULL};
> -static const char *st_r_out_tes[] = {"tes_output[0]", "gl_Position", NULL};
> -static const char *st_r_out_tcs[] = {"tcs_output[0]", "tcs_patch",
> +static const char *st_r_out_tes[] = {"vs_output1", "gl_Position", NULL};
> +static const char *st_r_out_tcs[] = {"tes_input1[0]", "tcs_patch",
>   				     "gl_PerVertex.gl_Position",
>   				     NULL};
>   static const char *st_r_buffer[] = {"vs_buf_var", "gs_buf_var", "fs_buf_var",
>   				    NULL};
>   static const char *st_r_stor_block[] = {"vs_buffer_block", "gs_buffer_block",
>   					"fs_buffer_block", NULL};
> -static const char *st_r_tf_varying[] = {"gl_Position", "gs_output0", NULL};
> +static const char *st_r_tf_varying[] = {"gl_Position", "fs_input1", NULL};
>   static const char *st_r_vs_sub[] = {"vss", "vss2", NULL};
>   static const char *st_r_gs_sub[] = {"gss", NULL};
>   static const char *st_r_fs_sub[] = {"fss", NULL};
> @@ -353,35 +353,35 @@ struct subtest_t {
>   }
>   
>   static const struct subtest_t subtests[] = {
> - ST( 8, 35, -1, -1,  vs_std,    NULL,    NULL,  gs_std,  fs_std,   NULL, GL_UNIFORM, "(vs,gs,fs)", st_r_uniform),
> - ST( 2,  9, -1, -1,    NULL, tcs_sub, tes_sub,    NULL,    NULL,   NULL, GL_UNIFORM, "(tes,tcs)", st_r_tess_uniform),
> + ST( 8, 35, -1, -1,  vs_std,    NULL,    NULL,  gs_std,   fs_in,   NULL, GL_UNIFORM, "(vs,gs,fs)", st_r_uniform),
> + ST( 2,  9, -1, -1,    NULL, tcs_sub,  tes_in,    NULL,    NULL,   NULL, GL_UNIFORM, "(tes,tcs)", st_r_tess_uniform),
>    ST( 2,  8, -1, -1,    NULL,    NULL,    NULL,    NULL,    NULL, cs_sub, GL_UNIFORM, "(cs)", st_r_cs_uniform),
> - ST( 7, 26,  2, -1,  vs_std,    NULL,    NULL,  gs_std,  fs_std,   NULL, GL_UNIFORM_BLOCK, "(vs,gs,fs)", st_r_uniform_block),
> - ST( 2, 18, -1, -1,    NULL, tcs_sub, tes_sub,    NULL,    NULL,   NULL, GL_UNIFORM_BLOCK, "(tcs,tes)", st_r_tess_uniform_block),
> + ST( 7, 26,  2, -1,  vs_std,    NULL,    NULL,  gs_std,   fs_in,   NULL, GL_UNIFORM_BLOCK, "(vs,gs,fs)", st_r_uniform_block),
> + ST( 2, 18, -1, -1,    NULL, tcs_sub,  tes_in,    NULL,    NULL,   NULL, GL_UNIFORM_BLOCK, "(tcs,tes)", st_r_tess_uniform_block),
>    ST( 1, 17, -1, -1,    NULL,    NULL,    NULL,    NULL,    NULL, cs_sub, GL_UNIFORM_BLOCK, "(cs)", st_r_cs_uniform_block),
>    ST( 2, 10, -1, -1,  vs_std,    NULL,    NULL,    NULL,    NULL,   NULL, GL_PROGRAM_INPUT, "(vs)", st_r_in_vs),
>    ST( 2, 25, -1, -1,    NULL,    NULL,    NULL,  gs_std,    NULL,   NULL, GL_PROGRAM_INPUT, "(gs)", st_r_in_gs),
> - ST( 1, 10, -1, -1,    NULL,    NULL,    NULL,    NULL,  fs_std,   NULL, GL_PROGRAM_INPUT, "(fs)", st_r_in_fs),
> + ST( 1, 10, -1, -1,    NULL,    NULL,    NULL,    NULL,   fs_in,   NULL, GL_PROGRAM_INPUT, "(fs)", st_r_in_fs),
>    ST( 2, 10, -1, -1,  vs_std,    NULL,    NULL,    NULL,  fs_std,   NULL, GL_PROGRAM_INPUT, "(vs,fs)", st_r_in_vs),
>    ST( 2, 10, -1, -1,  vs_std,    NULL,    NULL,  gs_std,    NULL,   NULL, GL_PROGRAM_INPUT, "(vs,gs)", st_r_in_vs),
> - ST( 2, 25, -1, -1,    NULL,    NULL,    NULL,  gs_std,  fs_std,   NULL, GL_PROGRAM_INPUT, "(gs,fs)", st_r_in_gs),
> - ST( 2, 10, -1, -1,  vs_std,    NULL,    NULL,  gs_std,  fs_std,   NULL, GL_PROGRAM_INPUT, "(vs,gs,fs)", st_r_in_vs),
> - ST( 2, 25, -1, -1,    NULL,    NULL, tes_sub,    NULL,    NULL,   NULL, GL_PROGRAM_INPUT, "(tes)", st_r_in_tes),
> + ST( 2, 25, -1, -1,    NULL,    NULL,    NULL,  gs_std,   fs_in,   NULL, GL_PROGRAM_INPUT, "(gs,fs)", st_r_in_gs),
> + ST( 2, 10, -1, -1,  vs_std,    NULL,    NULL,  gs_std,   fs_in,   NULL, GL_PROGRAM_INPUT, "(vs,gs,fs)", st_r_in_vs),
> + ST( 2, 25, -1, -1,    NULL,    NULL,  tes_in,    NULL,    NULL,   NULL, GL_PROGRAM_INPUT, "(tes)", st_r_in_tes),
>    ST( 3, 25, -1, -1,    NULL, tcs_sub,    NULL,    NULL,    NULL,   NULL, GL_PROGRAM_INPUT, "(tcs)", st_r_in_tcs),
> - ST( 3, 25, -1, -1,    NULL, tcs_sub, tes_sub,    NULL,    NULL,   NULL, GL_PROGRAM_INPUT, "(tcs,tes)", st_r_in_tcs),
> - ST( 2, 10, -1, -1,  vs_std, tcs_sub, tes_sub,    NULL,    NULL,   NULL, GL_PROGRAM_INPUT, "(vs,tcs,tes)", st_r_in_vs),
> + ST( 3, 25, -1, -1,    NULL, tcs_sub,  tes_in,    NULL,    NULL,   NULL, GL_PROGRAM_INPUT, "(tcs,tes)", st_r_in_tcs),
> + ST( 2, 10, -1, -1,  vs_std, tcs_sub,  tes_in,    NULL,    NULL,   NULL, GL_PROGRAM_INPUT, "(vs,tcs,tes)", st_r_in_vs),
>    ST( 0,  0, -1, -1,    NULL,    NULL,    NULL,    NULL,    NULL, cs_sub, GL_PROGRAM_INPUT, "(cs)", NULL),
> - ST( 1, 12, -1, -1,  vs_std,    NULL,    NULL,    NULL,    NULL,   NULL, GL_PROGRAM_OUTPUT, "(vs)", st_r_out_vs),
> + ST( 2, 12, -1, -1,  vs_std,    NULL,    NULL,    NULL,    NULL,   NULL, GL_PROGRAM_OUTPUT, "(vs)", st_r_out_vs),
>    ST( 2, 12, -1, -1,    NULL,    NULL,    NULL,  gs_std,    NULL,   NULL, GL_PROGRAM_OUTPUT, "(gs)", st_r_out_gs),
>    ST( 2, 11, -1, -1,    NULL,    NULL,    NULL,    NULL,  fs_std,   NULL, GL_PROGRAM_OUTPUT, "(fs)", st_r_out_fs),
>    ST( 2, 11, -1, -1,  vs_std,    NULL,    NULL,    NULL,  fs_std,   NULL, GL_PROGRAM_OUTPUT, "(vs,fs)", st_r_out_fs),
>    ST( 2, 12, -1, -1,  vs_std,    NULL,    NULL,  gs_std,    NULL,   NULL, GL_PROGRAM_OUTPUT, "(vs,gs)", st_r_out_gs),
> - ST( 2, 11, -1, -1,    NULL,    NULL,    NULL,  gs_std,  fs_std,   NULL, GL_PROGRAM_OUTPUT, "(gs,fs)", st_r_out_fs),
> - ST( 2, 11, -1, -1,  vs_std,    NULL,    NULL,  gs_std,  fs_std,   NULL, GL_PROGRAM_OUTPUT, "(vs,gs,fs)", st_r_out_fs),
> - ST( 2, 14, -1, -1,    NULL,    NULL, tes_sub,    NULL,    NULL,   NULL, GL_PROGRAM_OUTPUT, "(tes)", st_r_out_tes),
> + ST( 2, 11, -1, -1,    NULL,    NULL,    NULL,  gs_std,   fs_in,   NULL, GL_PROGRAM_OUTPUT, "(gs,fs)", st_r_out_fs),
> + ST( 2, 11, -1, -1,  vs_std,    NULL,    NULL,  gs_std,   fs_in,   NULL, GL_PROGRAM_OUTPUT, "(vs,gs,fs)", st_r_out_fs),
> + ST( 2, 12, -1, -1,    NULL,    NULL,  tes_in,    NULL,    NULL,   NULL, GL_PROGRAM_OUTPUT, "(tes)", st_r_out_tes),
>    ST( 3, 25, -1, -1,    NULL, tcs_sub,    NULL,    NULL,    NULL,   NULL, GL_PROGRAM_OUTPUT, "(tcs)", st_r_out_tcs),
> - ST( 2, 14, -1, -1,    NULL, tcs_sub, tes_sub,    NULL,    NULL,   NULL, GL_PROGRAM_OUTPUT, "(tcs,tes)", st_r_out_tes),
> - ST( 2, 12, -1, -1,    NULL, tcs_sub, tes_sub,  gs_std,    NULL,   NULL, GL_PROGRAM_OUTPUT, "(tcs,tes,gs)", st_r_out_gs),
> + ST( 2, 12, -1, -1,    NULL, tcs_sub,  tes_in,    NULL,    NULL,   NULL, GL_PROGRAM_OUTPUT, "(tcs,tes)", st_r_out_tes),
> + ST( 2, 12, -1, -1,    NULL, tcs_sub,  tes_in,  gs_std,    NULL,   NULL, GL_PROGRAM_OUTPUT, "(tcs,tes,gs)", st_r_out_gs),
>    ST( 0,  0, -1, -1,    NULL,    NULL,    NULL,    NULL,    NULL, cs_sub, GL_PROGRAM_OUTPUT, "(cs)", st_r_cs_sub),
>    ST( 3, 11, -1, -1, vs_stor,    NULL,    NULL, gs_stor, fs_stor,   NULL, GL_BUFFER_VARIABLE, "", st_r_buffer),
>    ST( 3, 16,  1, -1, vs_stor,    NULL,    NULL, gs_stor, fs_stor,   NULL, GL_SHADER_STORAGE_BLOCK, "", st_r_stor_block),
>
On Sat, 2019-02-16 at 10:22 +1100, Timothy Arceri wrote:
> It would be great if you could run this test on the Nvidia binary blob 
> to confirm the results. If everything works as expected the series is:

The problem is that nVIDIA shows many other failures in these tests due
to other conditions. However, the results do not change after this
patch.

Additionally, I've tried to address all the other failures exhibited by
nVIDIA in a series that I'll send shortly after. I other words, the
nVIDIA blob likes this changes. It just happens that it needs several
additional other.

Hence, I'll understand I can land this series with your Rb.


> Reviewed-by: Timothy Arceri <tarceri@itsqueeze.com>
> 
> Thanks for fixing all this!
> 
> On 9/2/19 3:57 am, Andres Gomez wrote:
> > Previuosly, this was overlooked asuming that, since they were SSOs, no
> > inner interface matching check was needed.
> > 
> >  From the ARB_separate_shader_objects spec v.25:
> > 
> >    " With separable program objects, interfaces between shader stages
> >      may involve the outputs from one program object and the inputs
> >      from a second program object.  For such interfaces, it is not
> >      possible to detect mismatches at link time, because the programs
> >      are linked separately.  When each such program is linked, all
> >      inputs or outputs interfacing with another program stage are
> >      treated as active.  The linker will generate an executable that
> >      assumes the presence of a compatible program on the other side of
> >      the interface.  If a mismatch between programs occurs, no GL error
> >      will be generated, but some or all of the inputs on the interface
> >      will be undefined."
> > 
> > Cc: Timothy Arceri <tarceri@itsqueeze.com>
> > Cc: Tapani Pälli <tapani.palli@intel.com>
> > Cc: Ilia Mirkin <imirkin@alum.mit.edu>
> > Cc: Martin Peres <martin.peres@linux.intel.com>
> > Signed-off-by: Andres Gomez <agomez@igalia.com>
> > ---
> >   .../spec/arb_program_interface_query/common.h | 61 ++++++++++++++++---
> >   .../getprogramresourceiv.c                    |  8 +--
> >   .../resource-query.c                          | 48 +++++++--------
> >   3 files changed, 79 insertions(+), 38 deletions(-)
> > 
> > diff --git a/tests/spec/arb_program_interface_query/common.h b/tests/spec/arb_program_interface_query/common.h
> > index 371b0338b..c0a99ea64 100755
> > --- a/tests/spec/arb_program_interface_query/common.h
> > +++ b/tests/spec/arb_program_interface_query/common.h
> > @@ -74,9 +74,11 @@ static const char vs_std[] =
> >   	"uniform vs_struct sa[2];\n"
> >   	"in vec4 vs_input0;\n"
> >   	"in vec4 vs_input1;\n"
> > +	"out vec4 vs_output1;\n"
> >   	"void main() {\n"
> >   	"	gl_Position = vs_input0 * vs_test * vs_input1 + sa[0].a[1] +"
> >   	"	              sa[1].a[1];\n"
> > +	"	vs_output1 = vs_input0;\n"
> >   	"}";
> >   
> >   const char gs_std[] =
> > @@ -86,18 +88,38 @@ const char gs_std[] =
> >   	"uniform gs_uniform_block {\n"
> >   	"	vec4 gs_test;\n"
> >   	"};\n"
> > -	"in vec4 gs_input[3];\n"
> > -	"out vec4 gs_output0;\n"
> > +	"in vec4 vs_output1[3];\n"
> > +	"out vec4 fs_input1;\n"
> >   	"void main() {\n"
> >   	"	for (int i = 0; i < 6; i++) {\n"
> > -	"		gl_Position = gs_input[i % 3] *"
> > +	"		gl_Position = vs_output1[i % 3] *"
> >   	"		              gl_in[i % 3].gl_Position * gs_test;\n"
> > -	"		gs_output0 = gs_input[0];\n"
> > +	"		fs_input1 = vs_output1[0];\n"
> >   	"		EmitVertex();\n"
> >   	"	}\n"
> >   	"}\n";
> >   
> >   static const char fs_std[] =
> > +	"#version 150\n"
> > +	"uniform fs_uniform_block {"
> > +	"	vec4 fs_color;\n"
> > +	"	float fs_array[4];\n"
> > +	"};\n"
> > +	"uniform fs_array_uniform_block {\n"
> > +	"	vec4 fs_color;\n"
> > +	"	float fs_array[4];\n"
> > +	"} faub[4];\n"
> > +	"in vec4 vs_output1;\n"
> > +	"out vec4 fs_output0;\n"
> > +	"out vec4 fs_output1;\n"
> > +	"void main() {\n"
> > +		"fs_output0 = fs_color * vs_output1 * fs_array[2] * \n"
> > +		"	      faub[0].fs_array[2] * faub[2].fs_array[2];\n"
> > +		"fs_output1 = fs_color * vs_output1 * fs_array[3] * \n"
> > +		"             faub[1].fs_array[3] * faub[3].fs_array[3];\n"
> > +	"}";
> > +
> > +static const char fs_in[] =
> >   	"#version 150\n"
> >   	"uniform fs_uniform_block {"
> >   	"	vec4 fs_color;\n"
> > @@ -296,8 +318,8 @@ static const char tcs_sub[] =
> >   	"uniform tcs_uniform_block {\n"
> >   	"	vec4 tcs_test;\n"
> >   	"};\n"
> > -	"out vec4 tcs_output[3];\n"
> > -	"in vec4 tcs_input[gl_MaxPatchVertices];\n"
> > +	"out vec4 tes_input1[3];\n"
> > +	"in vec4 vs_output1[gl_MaxPatchVertices];\n"
> >   	"patch out vec4 tcs_patch;\n"
> >   	"subroutine vec4 tcs_offset();\n"
> >   	"subroutine uniform tcs_offset TESS_CONTROL;\n"
> > @@ -306,7 +328,7 @@ static const char tcs_sub[] =
> >   	"	gl_out[gl_InvocationID].gl_Position = tcs_test +"
> >   	"	                                      gl_in[0].gl_Position *"
> >   	"	                                      TESS_CONTROL();\n"
> > -	"	tcs_output[gl_InvocationID] = tcs_input[0] + TESS_CONTROL();\n"
> > +	"	tes_input1[gl_InvocationID] = vs_output1[0] + TESS_CONTROL();\n"
> >   	"}";
> >   
> >   static const char tes_sub[] =
> > @@ -317,15 +339,34 @@ static const char tes_sub[] =
> >   	"uniform tes_uniform_block {\n"
> >   	"	vec4 tes_test;\n"
> >   	"};\n"
> > -	"out vec4 tes_output[1];\n"
> > -	"in vec4 tes_input[gl_MaxPatchVertices];\n"
> > +	"out vec4 tes_output1;\n"
> > +	"in vec4 vs_output1[gl_MaxPatchVertices];\n"
> > +	"subroutine vec4 tes_offset();\n"
> > +	"subroutine uniform tes_offset TESS_EVALUATION;\n"
> > +	"subroutine (tes_offset) vec4 tess() { return vec4(1, 0, 0, 0); }\n"
> > +	"void main() {\n"
> > +	"	gl_Position = tes_test + gl_in[0].gl_Position +"
> > +	"	              TESS_EVALUATION();\n"
> > +	"	tes_output1 = vs_output1[0] + TESS_EVALUATION();\n"
> > +	"}";
> > +
> > +static const char tes_in[] =
> > +	"#version 150\n"
> > +	"#extension GL_ARB_shader_subroutine : require\n"
> > +	"#extension GL_ARB_tessellation_shader : require\n"
> > +	"layout(triangles) in;\n"
> > +	"uniform tes_uniform_block {\n"
> > +	"	vec4 tes_test;\n"
> > +	"};\n"
> > +	"out vec4 vs_output1;\n"
> > +	"in vec4 tes_input1[gl_MaxPatchVertices];\n"
> >   	"subroutine vec4 tes_offset();\n"
> >   	"subroutine uniform tes_offset TESS_EVALUATION;\n"
> >   	"subroutine (tes_offset) vec4 tess() { return vec4(1, 0, 0, 0); }\n"
> >   	"void main() {\n"
> >   	"	gl_Position = tes_test + gl_in[0].gl_Position +"
> >   	"	              TESS_EVALUATION();\n"
> > -	"	tes_output[0] = tes_input[0] + TESS_EVALUATION();\n"
> > +	"	vs_output1 = tes_input1[0] + TESS_EVALUATION();\n"
> >   	"}";
> >   
> >   static const char cs_sub[] =
> > diff --git a/tests/spec/arb_program_interface_query/getprogramresourceiv.c b/tests/spec/arb_program_interface_query/getprogramresourceiv.c
> > index 70212350e..e55cf96ac 100755
> > --- a/tests/spec/arb_program_interface_query/getprogramresourceiv.c
> > +++ b/tests/spec/arb_program_interface_query/getprogramresourceiv.c
> > @@ -567,8 +567,8 @@ static const struct subtest_t subtests[] = {
> >   	{ GL_REFERENCED_BY_COMPUTE_SHADER, 1, { 0 } },
> >   	{ 0, 0, { 0 } }}
> >    },
> > - { &prog_std, GL_TRANSFORM_FEEDBACK_VARYING, "gs_output0", NULL, {
> > -	{ GL_NAME_LENGTH, 1, { 11 } },
> > + { &prog_std, GL_TRANSFORM_FEEDBACK_VARYING, "fs_input1", NULL, {
> > +	{ GL_NAME_LENGTH, 1, { 10 } },
> >   	{ GL_ARRAY_SIZE, 1, { 1 } },
> >   	{ 0, 0, { 0 } }}
> >    },
> > @@ -1012,7 +1012,7 @@ report_result:
> >   void
> >   piglit_init(int argc, char **argv)
> >   {
> > -	static const char *st_r_tf_varying[] = {"gs_output0", NULL};
> > +	static const char *st_r_tf_varying[] = {"fs_input1", NULL};
> >   
> >   	piglit_require_extension("GL_ARB_program_interface_query");
> >   	piglit_require_extension("GL_ARB_separate_shader_objects");
> > @@ -1021,7 +1021,7 @@ piglit_init(int argc, char **argv)
> >   	prog_std = piglit_build_simple_program_unlinked_multiple_shaders(
> >   					GL_VERTEX_SHADER, vs_std,
> >   					GL_GEOMETRY_SHADER, gs_std,
> > -					GL_FRAGMENT_SHADER, fs_std,
> > +					GL_FRAGMENT_SHADER, fs_in,
> >   					0);
> >   	glTransformFeedbackVaryings(prog_std, 1, st_r_tf_varying,
> >   				    GL_INTERLEAVED_ATTRIBS);
> > diff --git a/tests/spec/arb_program_interface_query/resource-query.c b/tests/spec/arb_program_interface_query/resource-query.c
> > index bf60dde93..f47431a30 100755
> > --- a/tests/spec/arb_program_interface_query/resource-query.c
> > +++ b/tests/spec/arb_program_interface_query/resource-query.c
> > @@ -209,25 +209,25 @@ static const char *st_r_tess_uniform_block[] = {"tcs_uniform_block",
> >   						"tes_uniform_block", NULL};
> >   static const char *st_r_cs_uniform_block[] = {"cs_uniform_block", NULL};
> >   static const char *st_r_in_vs[] = {"vs_input0", "vs_input1", NULL};
> > -static const char *st_r_in_gs[] = {"gs_input[0]", "gl_PerVertex.gl_Position", NULL};
> > +static const char *st_r_in_gs[] = {"vs_output1[0]", "gl_PerVertex.gl_Position", NULL};
> >   static const char *st_r_in_fs[] = {"fs_input1", NULL};
> > -static const char *st_r_in_tes[] = {"tes_input[0]", "gl_PerVertex.gl_Position", NULL};
> > -static const char *st_r_in_tcs[] = {"tcs_input[0]",
> > +static const char *st_r_in_tes[] = {"tes_input1[0]", "gl_PerVertex.gl_Position", NULL};
> > +static const char *st_r_in_tcs[] = {"vs_output1[0]",
> >   				    "gl_InvocationID",
> >   				    "gl_PerVertex.gl_Position",
> >   				    NULL};
> > -static const char *st_r_out_vs[] = {"gl_Position", NULL};
> > -static const char *st_r_out_gs[] = {"gs_output0", "gl_Position", NULL};
> > +static const char *st_r_out_vs[] = {"vs_output1", "gl_Position", NULL};
> > +static const char *st_r_out_gs[] = {"fs_input1", "gl_Position", NULL};
> >   static const char *st_r_out_fs[] = {"fs_output0", "fs_output1", NULL};
> > -static const char *st_r_out_tes[] = {"tes_output[0]", "gl_Position", NULL};
> > -static const char *st_r_out_tcs[] = {"tcs_output[0]", "tcs_patch",
> > +static const char *st_r_out_tes[] = {"vs_output1", "gl_Position", NULL};
> > +static const char *st_r_out_tcs[] = {"tes_input1[0]", "tcs_patch",
> >   				     "gl_PerVertex.gl_Position",
> >   				     NULL};
> >   static const char *st_r_buffer[] = {"vs_buf_var", "gs_buf_var", "fs_buf_var",
> >   				    NULL};
> >   static const char *st_r_stor_block[] = {"vs_buffer_block", "gs_buffer_block",
> >   					"fs_buffer_block", NULL};
> > -static const char *st_r_tf_varying[] = {"gl_Position", "gs_output0", NULL};
> > +static const char *st_r_tf_varying[] = {"gl_Position", "fs_input1", NULL};
> >   static const char *st_r_vs_sub[] = {"vss", "vss2", NULL};
> >   static const char *st_r_gs_sub[] = {"gss", NULL};
> >   static const char *st_r_fs_sub[] = {"fss", NULL};
> > @@ -353,35 +353,35 @@ struct subtest_t {
> >   }
> >   
> >   static const struct subtest_t subtests[] = {
> > - ST( 8, 35, -1, -1,  vs_std,    NULL,    NULL,  gs_std,  fs_std,   NULL, GL_UNIFORM, "(vs,gs,fs)", st_r_uniform),
> > - ST( 2,  9, -1, -1,    NULL, tcs_sub, tes_sub,    NULL,    NULL,   NULL, GL_UNIFORM, "(tes,tcs)", st_r_tess_uniform),
> > + ST( 8, 35, -1, -1,  vs_std,    NULL,    NULL,  gs_std,   fs_in,   NULL, GL_UNIFORM, "(vs,gs,fs)", st_r_uniform),
> > + ST( 2,  9, -1, -1,    NULL, tcs_sub,  tes_in,    NULL,    NULL,   NULL, GL_UNIFORM, "(tes,tcs)", st_r_tess_uniform),
> >    ST( 2,  8, -1, -1,    NULL,    NULL,    NULL,    NULL,    NULL, cs_sub, GL_UNIFORM, "(cs)", st_r_cs_uniform),
> > - ST( 7, 26,  2, -1,  vs_std,    NULL,    NULL,  gs_std,  fs_std,   NULL, GL_UNIFORM_BLOCK, "(vs,gs,fs)", st_r_uniform_block),
> > - ST( 2, 18, -1, -1,    NULL, tcs_sub, tes_sub,    NULL,    NULL,   NULL, GL_UNIFORM_BLOCK, "(tcs,tes)", st_r_tess_uniform_block),
> > + ST( 7, 26,  2, -1,  vs_std,    NULL,    NULL,  gs_std,   fs_in,   NULL, GL_UNIFORM_BLOCK, "(vs,gs,fs)", st_r_uniform_block),
> > + ST( 2, 18, -1, -1,    NULL, tcs_sub,  tes_in,    NULL,    NULL,   NULL, GL_UNIFORM_BLOCK, "(tcs,tes)", st_r_tess_uniform_block),
> >    ST( 1, 17, -1, -1,    NULL,    NULL,    NULL,    NULL,    NULL, cs_sub, GL_UNIFORM_BLOCK, "(cs)", st_r_cs_uniform_block),
> >    ST( 2, 10, -1, -1,  vs_std,    NULL,    NULL,    NULL,    NULL,   NULL, GL_PROGRAM_INPUT, "(vs)", st_r_in_vs),
> >    ST( 2, 25, -1, -1,    NULL,    NULL,    NULL,  gs_std,    NULL,   NULL, GL_PROGRAM_INPUT, "(gs)", st_r_in_gs),
> > - ST( 1, 10, -1, -1,    NULL,    NULL,    NULL,    NULL,  fs_std,   NULL, GL_PROGRAM_INPUT, "(fs)", st_r_in_fs),
> > + ST( 1, 10, -1, -1,    NULL,    NULL,    NULL,    NULL,   fs_in,   NULL, GL_PROGRAM_INPUT, "(fs)", st_r_in_fs),
> >    ST( 2, 10, -1, -1,  vs_std,    NULL,    NULL,    NULL,  fs_std,   NULL, GL_PROGRAM_INPUT, "(vs,fs)", st_r_in_vs),
> >    ST( 2, 10, -1, -1,  vs_std,    NULL,    NULL,  gs_std,    NULL,   NULL, GL_PROGRAM_INPUT, "(vs,gs)", st_r_in_vs),
> > - ST( 2, 25, -1, -1,    NULL,    NULL,    NULL,  gs_std,  fs_std,   NULL, GL_PROGRAM_INPUT, "(gs,fs)", st_r_in_gs),
> > - ST( 2, 10, -1, -1,  vs_std,    NULL,    NULL,  gs_std,  fs_std,   NULL, GL_PROGRAM_INPUT, "(vs,gs,fs)", st_r_in_vs),
> > - ST( 2, 25, -1, -1,    NULL,    NULL, tes_sub,    NULL,    NULL,   NULL, GL_PROGRAM_INPUT, "(tes)", st_r_in_tes),
> > + ST( 2, 25, -1, -1,    NULL,    NULL,    NULL,  gs_std,   fs_in,   NULL, GL_PROGRAM_INPUT, "(gs,fs)", st_r_in_gs),
> > + ST( 2, 10, -1, -1,  vs_std,    NULL,    NULL,  gs_std,   fs_in,   NULL, GL_PROGRAM_INPUT, "(vs,gs,fs)", st_r_in_vs),
> > + ST( 2, 25, -1, -1,    NULL,    NULL,  tes_in,    NULL,    NULL,   NULL, GL_PROGRAM_INPUT, "(tes)", st_r_in_tes),
> >    ST( 3, 25, -1, -1,    NULL, tcs_sub,    NULL,    NULL,    NULL,   NULL, GL_PROGRAM_INPUT, "(tcs)", st_r_in_tcs),
> > - ST( 3, 25, -1, -1,    NULL, tcs_sub, tes_sub,    NULL,    NULL,   NULL, GL_PROGRAM_INPUT, "(tcs,tes)", st_r_in_tcs),
> > - ST( 2, 10, -1, -1,  vs_std, tcs_sub, tes_sub,    NULL,    NULL,   NULL, GL_PROGRAM_INPUT, "(vs,tcs,tes)", st_r_in_vs),
> > + ST( 3, 25, -1, -1,    NULL, tcs_sub,  tes_in,    NULL,    NULL,   NULL, GL_PROGRAM_INPUT, "(tcs,tes)", st_r_in_tcs),
> > + ST( 2, 10, -1, -1,  vs_std, tcs_sub,  tes_in,    NULL,    NULL,   NULL, GL_PROGRAM_INPUT, "(vs,tcs,tes)", st_r_in_vs),
> >    ST( 0,  0, -1, -1,    NULL,    NULL,    NULL,    NULL,    NULL, cs_sub, GL_PROGRAM_INPUT, "(cs)", NULL),
> > - ST( 1, 12, -1, -1,  vs_std,    NULL,    NULL,    NULL,    NULL,   NULL, GL_PROGRAM_OUTPUT, "(vs)", st_r_out_vs),
> > + ST( 2, 12, -1, -1,  vs_std,    NULL,    NULL,    NULL,    NULL,   NULL, GL_PROGRAM_OUTPUT, "(vs)", st_r_out_vs),
> >    ST( 2, 12, -1, -1,    NULL,    NULL,    NULL,  gs_std,    NULL,   NULL, GL_PROGRAM_OUTPUT, "(gs)", st_r_out_gs),
> >    ST( 2, 11, -1, -1,    NULL,    NULL,    NULL,    NULL,  fs_std,   NULL, GL_PROGRAM_OUTPUT, "(fs)", st_r_out_fs),
> >    ST( 2, 11, -1, -1,  vs_std,    NULL,    NULL,    NULL,  fs_std,   NULL, GL_PROGRAM_OUTPUT, "(vs,fs)", st_r_out_fs),
> >    ST( 2, 12, -1, -1,  vs_std,    NULL,    NULL,  gs_std,    NULL,   NULL, GL_PROGRAM_OUTPUT, "(vs,gs)", st_r_out_gs),
> > - ST( 2, 11, -1, -1,    NULL,    NULL,    NULL,  gs_std,  fs_std,   NULL, GL_PROGRAM_OUTPUT, "(gs,fs)", st_r_out_fs),
> > - ST( 2, 11, -1, -1,  vs_std,    NULL,    NULL,  gs_std,  fs_std,   NULL, GL_PROGRAM_OUTPUT, "(vs,gs,fs)", st_r_out_fs),
> > - ST( 2, 14, -1, -1,    NULL,    NULL, tes_sub,    NULL,    NULL,   NULL, GL_PROGRAM_OUTPUT, "(tes)", st_r_out_tes),
> > + ST( 2, 11, -1, -1,    NULL,    NULL,    NULL,  gs_std,   fs_in,   NULL, GL_PROGRAM_OUTPUT, "(gs,fs)", st_r_out_fs),
> > + ST( 2, 11, -1, -1,  vs_std,    NULL,    NULL,  gs_std,   fs_in,   NULL, GL_PROGRAM_OUTPUT, "(vs,gs,fs)", st_r_out_fs),
> > + ST( 2, 12, -1, -1,    NULL,    NULL,  tes_in,    NULL,    NULL,   NULL, GL_PROGRAM_OUTPUT, "(tes)", st_r_out_tes),
> >    ST( 3, 25, -1, -1,    NULL, tcs_sub,    NULL,    NULL,    NULL,   NULL, GL_PROGRAM_OUTPUT, "(tcs)", st_r_out_tcs),
> > - ST( 2, 14, -1, -1,    NULL, tcs_sub, tes_sub,    NULL,    NULL,   NULL, GL_PROGRAM_OUTPUT, "(tcs,tes)", st_r_out_tes),
> > - ST( 2, 12, -1, -1,    NULL, tcs_sub, tes_sub,  gs_std,    NULL,   NULL, GL_PROGRAM_OUTPUT, "(tcs,tes,gs)", st_r_out_gs),
> > + ST( 2, 12, -1, -1,    NULL, tcs_sub,  tes_in,    NULL,    NULL,   NULL, GL_PROGRAM_OUTPUT, "(tcs,tes)", st_r_out_tes),
> > + ST( 2, 12, -1, -1,    NULL, tcs_sub,  tes_in,  gs_std,    NULL,   NULL, GL_PROGRAM_OUTPUT, "(tcs,tes,gs)", st_r_out_gs),
> >    ST( 0,  0, -1, -1,    NULL,    NULL,    NULL,    NULL,    NULL, cs_sub, GL_PROGRAM_OUTPUT, "(cs)", st_r_cs_sub),
> >    ST( 3, 11, -1, -1, vs_stor,    NULL,    NULL, gs_stor, fs_stor,   NULL, GL_BUFFER_VARIABLE, "", st_r_buffer),
> >    ST( 3, 16,  1, -1, vs_stor,    NULL,    NULL, gs_stor, fs_stor,   NULL, GL_SHADER_STORAGE_BLOCK, "", st_r_stor_block),
> >
On Tue, 2019-03-19 at 16:14 +0200, Andres Gomez wrote:
> On Sat, 2019-02-16 at 10:22 +1100, Timothy Arceri wrote:
> > It would be great if you could run this test on the Nvidia binary blob 
> > to confirm the results. If everything works as expected the series is:
> 
> The problem is that nVIDIA shows many other failures in these tests due
> to other conditions. However, the results do not change after this
> patch.
> 
> Additionally, I've tried to address all the other failures exhibited by
> nVIDIA in a series that I'll send shortly after.

See:
https://gitlab.freedesktop.org/mesa/piglit/merge_requests/20
https://gitlab.freedesktop.org/mesa/piglit/merge_requests/21

> In other words, the
> nVIDIA blob likes this changes. It just happens that it needs several
> additional other.
> 
> Hence, I'll understand I can land this series with your Rb.
> 
> 
> > Reviewed-by: Timothy Arceri <tarceri@itsqueeze.com>
> > 
> > Thanks for fixing all this!
> > 
> > On 9/2/19 3:57 am, Andres Gomez wrote:
> > > Previuosly, this was overlooked asuming that, since they were SSOs, no
> > > inner interface matching check was needed.
> > > 
> > >  From the ARB_separate_shader_objects spec v.25:
> > > 
> > >    " With separable program objects, interfaces between shader stages
> > >      may involve the outputs from one program object and the inputs
> > >      from a second program object.  For such interfaces, it is not
> > >      possible to detect mismatches at link time, because the programs
> > >      are linked separately.  When each such program is linked, all
> > >      inputs or outputs interfacing with another program stage are
> > >      treated as active.  The linker will generate an executable that
> > >      assumes the presence of a compatible program on the other side of
> > >      the interface.  If a mismatch between programs occurs, no GL error
> > >      will be generated, but some or all of the inputs on the interface
> > >      will be undefined."
> > > 
> > > Cc: Timothy Arceri <tarceri@itsqueeze.com>
> > > Cc: Tapani Pälli <tapani.palli@intel.com>
> > > Cc: Ilia Mirkin <imirkin@alum.mit.edu>
> > > Cc: Martin Peres <martin.peres@linux.intel.com>
> > > Signed-off-by: Andres Gomez <agomez@igalia.com>
> > > ---
> > >   .../spec/arb_program_interface_query/common.h | 61 ++++++++++++++++---
> > >   .../getprogramresourceiv.c                    |  8 +--
> > >   .../resource-query.c                          | 48 +++++++--------
> > >   3 files changed, 79 insertions(+), 38 deletions(-)
> > > 
> > > diff --git a/tests/spec/arb_program_interface_query/common.h b/tests/spec/arb_program_interface_query/common.h
> > > index 371b0338b..c0a99ea64 100755
> > > --- a/tests/spec/arb_program_interface_query/common.h
> > > +++ b/tests/spec/arb_program_interface_query/common.h
> > > @@ -74,9 +74,11 @@ static const char vs_std[] =
> > >   	"uniform vs_struct sa[2];\n"
> > >   	"in vec4 vs_input0;\n"
> > >   	"in vec4 vs_input1;\n"
> > > +	"out vec4 vs_output1;\n"
> > >   	"void main() {\n"
> > >   	"	gl_Position = vs_input0 * vs_test * vs_input1 + sa[0].a[1] +"
> > >   	"	              sa[1].a[1];\n"
> > > +	"	vs_output1 = vs_input0;\n"
> > >   	"}";
> > >   
> > >   const char gs_std[] =
> > > @@ -86,18 +88,38 @@ const char gs_std[] =
> > >   	"uniform gs_uniform_block {\n"
> > >   	"	vec4 gs_test;\n"
> > >   	"};\n"
> > > -	"in vec4 gs_input[3];\n"
> > > -	"out vec4 gs_output0;\n"
> > > +	"in vec4 vs_output1[3];\n"
> > > +	"out vec4 fs_input1;\n"
> > >   	"void main() {\n"
> > >   	"	for (int i = 0; i < 6; i++) {\n"
> > > -	"		gl_Position = gs_input[i % 3] *"
> > > +	"		gl_Position = vs_output1[i % 3] *"
> > >   	"		              gl_in[i % 3].gl_Position * gs_test;\n"
> > > -	"		gs_output0 = gs_input[0];\n"
> > > +	"		fs_input1 = vs_output1[0];\n"
> > >   	"		EmitVertex();\n"
> > >   	"	}\n"
> > >   	"}\n";
> > >   
> > >   static const char fs_std[] =
> > > +	"#version 150\n"
> > > +	"uniform fs_uniform_block {"
> > > +	"	vec4 fs_color;\n"
> > > +	"	float fs_array[4];\n"
> > > +	"};\n"
> > > +	"uniform fs_array_uniform_block {\n"
> > > +	"	vec4 fs_color;\n"
> > > +	"	float fs_array[4];\n"
> > > +	"} faub[4];\n"
> > > +	"in vec4 vs_output1;\n"
> > > +	"out vec4 fs_output0;\n"
> > > +	"out vec4 fs_output1;\n"
> > > +	"void main() {\n"
> > > +		"fs_output0 = fs_color * vs_output1 * fs_array[2] * \n"
> > > +		"	      faub[0].fs_array[2] * faub[2].fs_array[2];\n"
> > > +		"fs_output1 = fs_color * vs_output1 * fs_array[3] * \n"
> > > +		"             faub[1].fs_array[3] * faub[3].fs_array[3];\n"
> > > +	"}";
> > > +
> > > +static const char fs_in[] =
> > >   	"#version 150\n"
> > >   	"uniform fs_uniform_block {"
> > >   	"	vec4 fs_color;\n"
> > > @@ -296,8 +318,8 @@ static const char tcs_sub[] =
> > >   	"uniform tcs_uniform_block {\n"
> > >   	"	vec4 tcs_test;\n"
> > >   	"};\n"
> > > -	"out vec4 tcs_output[3];\n"
> > > -	"in vec4 tcs_input[gl_MaxPatchVertices];\n"
> > > +	"out vec4 tes_input1[3];\n"
> > > +	"in vec4 vs_output1[gl_MaxPatchVertices];\n"
> > >   	"patch out vec4 tcs_patch;\n"
> > >   	"subroutine vec4 tcs_offset();\n"
> > >   	"subroutine uniform tcs_offset TESS_CONTROL;\n"
> > > @@ -306,7 +328,7 @@ static const char tcs_sub[] =
> > >   	"	gl_out[gl_InvocationID].gl_Position = tcs_test +"
> > >   	"	                                      gl_in[0].gl_Position *"
> > >   	"	                                      TESS_CONTROL();\n"
> > > -	"	tcs_output[gl_InvocationID] = tcs_input[0] + TESS_CONTROL();\n"
> > > +	"	tes_input1[gl_InvocationID] = vs_output1[0] + TESS_CONTROL();\n"
> > >   	"}";
> > >   
> > >   static const char tes_sub[] =
> > > @@ -317,15 +339,34 @@ static const char tes_sub[] =
> > >   	"uniform tes_uniform_block {\n"
> > >   	"	vec4 tes_test;\n"
> > >   	"};\n"
> > > -	"out vec4 tes_output[1];\n"
> > > -	"in vec4 tes_input[gl_MaxPatchVertices];\n"
> > > +	"out vec4 tes_output1;\n"
> > > +	"in vec4 vs_output1[gl_MaxPatchVertices];\n"
> > > +	"subroutine vec4 tes_offset();\n"
> > > +	"subroutine uniform tes_offset TESS_EVALUATION;\n"
> > > +	"subroutine (tes_offset) vec4 tess() { return vec4(1, 0, 0, 0); }\n"
> > > +	"void main() {\n"
> > > +	"	gl_Position = tes_test + gl_in[0].gl_Position +"
> > > +	"	              TESS_EVALUATION();\n"
> > > +	"	tes_output1 = vs_output1[0] + TESS_EVALUATION();\n"
> > > +	"}";
> > > +
> > > +static const char tes_in[] =
> > > +	"#version 150\n"
> > > +	"#extension GL_ARB_shader_subroutine : require\n"
> > > +	"#extension GL_ARB_tessellation_shader : require\n"
> > > +	"layout(triangles) in;\n"
> > > +	"uniform tes_uniform_block {\n"
> > > +	"	vec4 tes_test;\n"
> > > +	"};\n"
> > > +	"out vec4 vs_output1;\n"
> > > +	"in vec4 tes_input1[gl_MaxPatchVertices];\n"
> > >   	"subroutine vec4 tes_offset();\n"
> > >   	"subroutine uniform tes_offset TESS_EVALUATION;\n"
> > >   	"subroutine (tes_offset) vec4 tess() { return vec4(1, 0, 0, 0); }\n"
> > >   	"void main() {\n"
> > >   	"	gl_Position = tes_test + gl_in[0].gl_Position +"
> > >   	"	              TESS_EVALUATION();\n"
> > > -	"	tes_output[0] = tes_input[0] + TESS_EVALUATION();\n"
> > > +	"	vs_output1 = tes_input1[0] + TESS_EVALUATION();\n"
> > >   	"}";
> > >   
> > >   static const char cs_sub[] =
> > > diff --git a/tests/spec/arb_program_interface_query/getprogramresourceiv.c b/tests/spec/arb_program_interface_query/getprogramresourceiv.c
> > > index 70212350e..e55cf96ac 100755
> > > --- a/tests/spec/arb_program_interface_query/getprogramresourceiv.c
> > > +++ b/tests/spec/arb_program_interface_query/getprogramresourceiv.c
> > > @@ -567,8 +567,8 @@ static const struct subtest_t subtests[] = {
> > >   	{ GL_REFERENCED_BY_COMPUTE_SHADER, 1, { 0 } },
> > >   	{ 0, 0, { 0 } }}
> > >    },
> > > - { &prog_std, GL_TRANSFORM_FEEDBACK_VARYING, "gs_output0", NULL, {
> > > -	{ GL_NAME_LENGTH, 1, { 11 } },
> > > + { &prog_std, GL_TRANSFORM_FEEDBACK_VARYING, "fs_input1", NULL, {
> > > +	{ GL_NAME_LENGTH, 1, { 10 } },
> > >   	{ GL_ARRAY_SIZE, 1, { 1 } },
> > >   	{ 0, 0, { 0 } }}
> > >    },
> > > @@ -1012,7 +1012,7 @@ report_result:
> > >   void
> > >   piglit_init(int argc, char **argv)
> > >   {
> > > -	static const char *st_r_tf_varying[] = {"gs_output0", NULL};
> > > +	static const char *st_r_tf_varying[] = {"fs_input1", NULL};
> > >   
> > >   	piglit_require_extension("GL_ARB_program_interface_query");
> > >   	piglit_require_extension("GL_ARB_separate_shader_objects");
> > > @@ -1021,7 +1021,7 @@ piglit_init(int argc, char **argv)
> > >   	prog_std = piglit_build_simple_program_unlinked_multiple_shaders(
> > >   					GL_VERTEX_SHADER, vs_std,
> > >   					GL_GEOMETRY_SHADER, gs_std,
> > > -					GL_FRAGMENT_SHADER, fs_std,
> > > +					GL_FRAGMENT_SHADER, fs_in,
> > >   					0);
> > >   	glTransformFeedbackVaryings(prog_std, 1, st_r_tf_varying,
> > >   				    GL_INTERLEAVED_ATTRIBS);
> > > diff --git a/tests/spec/arb_program_interface_query/resource-query.c b/tests/spec/arb_program_interface_query/resource-query.c
> > > index bf60dde93..f47431a30 100755
> > > --- a/tests/spec/arb_program_interface_query/resource-query.c
> > > +++ b/tests/spec/arb_program_interface_query/resource-query.c
> > > @@ -209,25 +209,25 @@ static const char *st_r_tess_uniform_block[] = {"tcs_uniform_block",
> > >   						"tes_uniform_block", NULL};
> > >   static const char *st_r_cs_uniform_block[] = {"cs_uniform_block", NULL};
> > >   static const char *st_r_in_vs[] = {"vs_input0", "vs_input1", NULL};
> > > -static const char *st_r_in_gs[] = {"gs_input[0]", "gl_PerVertex.gl_Position", NULL};
> > > +static const char *st_r_in_gs[] = {"vs_output1[0]", "gl_PerVertex.gl_Position", NULL};
> > >   static const char *st_r_in_fs[] = {"fs_input1", NULL};
> > > -static const char *st_r_in_tes[] = {"tes_input[0]", "gl_PerVertex.gl_Position", NULL};
> > > -static const char *st_r_in_tcs[] = {"tcs_input[0]",
> > > +static const char *st_r_in_tes[] = {"tes_input1[0]", "gl_PerVertex.gl_Position", NULL};
> > > +static const char *st_r_in_tcs[] = {"vs_output1[0]",
> > >   				    "gl_InvocationID",
> > >   				    "gl_PerVertex.gl_Position",
> > >   				    NULL};
> > > -static const char *st_r_out_vs[] = {"gl_Position", NULL};
> > > -static const char *st_r_out_gs[] = {"gs_output0", "gl_Position", NULL};
> > > +static const char *st_r_out_vs[] = {"vs_output1", "gl_Position", NULL};
> > > +static const char *st_r_out_gs[] = {"fs_input1", "gl_Position", NULL};
> > >   static const char *st_r_out_fs[] = {"fs_output0", "fs_output1", NULL};
> > > -static const char *st_r_out_tes[] = {"tes_output[0]", "gl_Position", NULL};
> > > -static const char *st_r_out_tcs[] = {"tcs_output[0]", "tcs_patch",
> > > +static const char *st_r_out_tes[] = {"vs_output1", "gl_Position", NULL};
> > > +static const char *st_r_out_tcs[] = {"tes_input1[0]", "tcs_patch",
> > >   				     "gl_PerVertex.gl_Position",
> > >   				     NULL};
> > >   static const char *st_r_buffer[] = {"vs_buf_var", "gs_buf_var", "fs_buf_var",
> > >   				    NULL};
> > >   static const char *st_r_stor_block[] = {"vs_buffer_block", "gs_buffer_block",
> > >   					"fs_buffer_block", NULL};
> > > -static const char *st_r_tf_varying[] = {"gl_Position", "gs_output0", NULL};
> > > +static const char *st_r_tf_varying[] = {"gl_Position", "fs_input1", NULL};
> > >   static const char *st_r_vs_sub[] = {"vss", "vss2", NULL};
> > >   static const char *st_r_gs_sub[] = {"gss", NULL};
> > >   static const char *st_r_fs_sub[] = {"fss", NULL};
> > > @@ -353,35 +353,35 @@ struct subtest_t {
> > >   }
> > >   
> > >   static const struct subtest_t subtests[] = {
> > > - ST( 8, 35, -1, -1,  vs_std,    NULL,    NULL,  gs_std,  fs_std,   NULL, GL_UNIFORM, "(vs,gs,fs)", st_r_uniform),
> > > - ST( 2,  9, -1, -1,    NULL, tcs_sub, tes_sub,    NULL,    NULL,   NULL, GL_UNIFORM, "(tes,tcs)", st_r_tess_uniform),
> > > + ST( 8, 35, -1, -1,  vs_std,    NULL,    NULL,  gs_std,   fs_in,   NULL, GL_UNIFORM, "(vs,gs,fs)", st_r_uniform),
> > > + ST( 2,  9, -1, -1,    NULL, tcs_sub,  tes_in,    NULL,    NULL,   NULL, GL_UNIFORM, "(tes,tcs)", st_r_tess_uniform),
> > >    ST( 2,  8, -1, -1,    NULL,    NULL,    NULL,    NULL,    NULL, cs_sub, GL_UNIFORM, "(cs)", st_r_cs_uniform),
> > > - ST( 7, 26,  2, -1,  vs_std,    NULL,    NULL,  gs_std,  fs_std,   NULL, GL_UNIFORM_BLOCK, "(vs,gs,fs)", st_r_uniform_block),
> > > - ST( 2, 18, -1, -1,    NULL, tcs_sub, tes_sub,    NULL,    NULL,   NULL, GL_UNIFORM_BLOCK, "(tcs,tes)", st_r_tess_uniform_block),
> > > + ST( 7, 26,  2, -1,  vs_std,    NULL,    NULL,  gs_std,   fs_in,   NULL, GL_UNIFORM_BLOCK, "(vs,gs,fs)", st_r_uniform_block),
> > > + ST( 2, 18, -1, -1,    NULL, tcs_sub,  tes_in,    NULL,    NULL,   NULL, GL_UNIFORM_BLOCK, "(tcs,tes)", st_r_tess_uniform_block),
> > >    ST( 1, 17, -1, -1,    NULL,    NULL,    NULL,    NULL,    NULL, cs_sub, GL_UNIFORM_BLOCK, "(cs)", st_r_cs_uniform_block),
> > >    ST( 2, 10, -1, -1,  vs_std,    NULL,    NULL,    NULL,    NULL,   NULL, GL_PROGRAM_INPUT, "(vs)", st_r_in_vs),
> > >    ST( 2, 25, -1, -1,    NULL,    NULL,    NULL,  gs_std,    NULL,   NULL, GL_PROGRAM_INPUT, "(gs)", st_r_in_gs),
> > > - ST( 1, 10, -1, -1,    NULL,    NULL,    NULL,    NULL,  fs_std,   NULL, GL_PROGRAM_INPUT, "(fs)", st_r_in_fs),
> > > + ST( 1, 10, -1, -1,    NULL,    NULL,    NULL,    NULL,   fs_in,   NULL, GL_PROGRAM_INPUT, "(fs)", st_r_in_fs),
> > >    ST( 2, 10, -1, -1,  vs_std,    NULL,    NULL,    NULL,  fs_std,   NULL, GL_PROGRAM_INPUT, "(vs,fs)", st_r_in_vs),
> > >    ST( 2, 10, -1, -1,  vs_std,    NULL,    NULL,  gs_std,    NULL,   NULL, GL_PROGRAM_INPUT, "(vs,gs)", st_r_in_vs),
> > > - ST( 2, 25, -1, -1,    NULL,    NULL,    NULL,  gs_std,  fs_std,   NULL, GL_PROGRAM_INPUT, "(gs,fs)", st_r_in_gs),
> > > - ST( 2, 10, -1, -1,  vs_std,    NULL,    NULL,  gs_std,  fs_std,   NULL, GL_PROGRAM_INPUT, "(vs,gs,fs)", st_r_in_vs),
> > > - ST( 2, 25, -1, -1,    NULL,    NULL, tes_sub,    NULL,    NULL,   NULL, GL_PROGRAM_INPUT, "(tes)", st_r_in_tes),
> > > + ST( 2, 25, -1, -1,    NULL,    NULL,    NULL,  gs_std,   fs_in,   NULL, GL_PROGRAM_INPUT, "(gs,fs)", st_r_in_gs),
> > > + ST( 2, 10, -1, -1,  vs_std,    NULL,    NULL,  gs_std,   fs_in,   NULL, GL_PROGRAM_INPUT, "(vs,gs,fs)", st_r_in_vs),
> > > + ST( 2, 25, -1, -1,    NULL,    NULL,  tes_in,    NULL,    NULL,   NULL, GL_PROGRAM_INPUT, "(tes)", st_r_in_tes),
> > >    ST( 3, 25, -1, -1,    NULL, tcs_sub,    NULL,    NULL,    NULL,   NULL, GL_PROGRAM_INPUT, "(tcs)", st_r_in_tcs),
> > > - ST( 3, 25, -1, -1,    NULL, tcs_sub, tes_sub,    NULL,    NULL,   NULL, GL_PROGRAM_INPUT, "(tcs,tes)", st_r_in_tcs),
> > > - ST( 2, 10, -1, -1,  vs_std, tcs_sub, tes_sub,    NULL,    NULL,   NULL, GL_PROGRAM_INPUT, "(vs,tcs,tes)", st_r_in_vs),
> > > + ST( 3, 25, -1, -1,    NULL, tcs_sub,  tes_in,    NULL,    NULL,   NULL, GL_PROGRAM_INPUT, "(tcs,tes)", st_r_in_tcs),
> > > + ST( 2, 10, -1, -1,  vs_std, tcs_sub,  tes_in,    NULL,    NULL,   NULL, GL_PROGRAM_INPUT, "(vs,tcs,tes)", st_r_in_vs),
> > >    ST( 0,  0, -1, -1,    NULL,    NULL,    NULL,    NULL,    NULL, cs_sub, GL_PROGRAM_INPUT, "(cs)", NULL),
> > > - ST( 1, 12, -1, -1,  vs_std,    NULL,    NULL,    NULL,    NULL,   NULL, GL_PROGRAM_OUTPUT, "(vs)", st_r_out_vs),
> > > + ST( 2, 12, -1, -1,  vs_std,    NULL,    NULL,    NULL,    NULL,   NULL, GL_PROGRAM_OUTPUT, "(vs)", st_r_out_vs),
> > >    ST( 2, 12, -1, -1,    NULL,    NULL,    NULL,  gs_std,    NULL,   NULL, GL_PROGRAM_OUTPUT, "(gs)", st_r_out_gs),
> > >    ST( 2, 11, -1, -1,    NULL,    NULL,    NULL,    NULL,  fs_std,   NULL, GL_PROGRAM_OUTPUT, "(fs)", st_r_out_fs),
> > >    ST( 2, 11, -1, -1,  vs_std,    NULL,    NULL,    NULL,  fs_std,   NULL, GL_PROGRAM_OUTPUT, "(vs,fs)", st_r_out_fs),
> > >    ST( 2, 12, -1, -1,  vs_std,    NULL,    NULL,  gs_std,    NULL,   NULL, GL_PROGRAM_OUTPUT, "(vs,gs)", st_r_out_gs),
> > > - ST( 2, 11, -1, -1,    NULL,    NULL,    NULL,  gs_std,  fs_std,   NULL, GL_PROGRAM_OUTPUT, "(gs,fs)", st_r_out_fs),
> > > - ST( 2, 11, -1, -1,  vs_std,    NULL,    NULL,  gs_std,  fs_std,   NULL, GL_PROGRAM_OUTPUT, "(vs,gs,fs)", st_r_out_fs),
> > > - ST( 2, 14, -1, -1,    NULL,    NULL, tes_sub,    NULL,    NULL,   NULL, GL_PROGRAM_OUTPUT, "(tes)", st_r_out_tes),
> > > + ST( 2, 11, -1, -1,    NULL,    NULL,    NULL,  gs_std,   fs_in,   NULL, GL_PROGRAM_OUTPUT, "(gs,fs)", st_r_out_fs),
> > > + ST( 2, 11, -1, -1,  vs_std,    NULL,    NULL,  gs_std,   fs_in,   NULL, GL_PROGRAM_OUTPUT, "(vs,gs,fs)", st_r_out_fs),
> > > + ST( 2, 12, -1, -1,    NULL,    NULL,  tes_in,    NULL,    NULL,   NULL, GL_PROGRAM_OUTPUT, "(tes)", st_r_out_tes),
> > >    ST( 3, 25, -1, -1,    NULL, tcs_sub,    NULL,    NULL,    NULL,   NULL, GL_PROGRAM_OUTPUT, "(tcs)", st_r_out_tcs),
> > > - ST( 2, 14, -1, -1,    NULL, tcs_sub, tes_sub,    NULL,    NULL,   NULL, GL_PROGRAM_OUTPUT, "(tcs,tes)", st_r_out_tes),
> > > - ST( 2, 12, -1, -1,    NULL, tcs_sub, tes_sub,  gs_std,    NULL,   NULL, GL_PROGRAM_OUTPUT, "(tcs,tes,gs)", st_r_out_gs),
> > > + ST( 2, 12, -1, -1,    NULL, tcs_sub,  tes_in,    NULL,    NULL,   NULL, GL_PROGRAM_OUTPUT, "(tcs,tes)", st_r_out_tes),
> > > + ST( 2, 12, -1, -1,    NULL, tcs_sub,  tes_in,  gs_std,    NULL,   NULL, GL_PROGRAM_OUTPUT, "(tcs,tes,gs)", st_r_out_gs),
> > >    ST( 0,  0, -1, -1,    NULL,    NULL,    NULL,    NULL,    NULL, cs_sub, GL_PROGRAM_OUTPUT, "(cs)", st_r_cs_sub),
> > >    ST( 3, 11, -1, -1, vs_stor,    NULL,    NULL, gs_stor, fs_stor,   NULL, GL_BUFFER_VARIABLE, "", st_r_buffer),
> > >    ST( 3, 16,  1, -1, vs_stor,    NULL,    NULL, gs_stor, fs_stor,   NULL, GL_SHADER_STORAGE_BLOCK, "", st_r_stor_block),
> > >