glsl: additional interface redeclaration check for SSO programs

Patch adds additional linker check for SSO programs to make sure they
are redeclaring built-in blocks as required by the desktop spec.

This fixes following Piglit tests:
   arb_separate_shader_objects/linker/pervertex-*

Signed-off-by: Tapani Pälli <tapani.palli@intel.com>
Reviewed-by: Timothy Arceri <tarceri@itsqueeze.com>
This commit is contained in:
Tapani Pälli 2019-11-05 15:00:25 +02:00
parent 2d26cc077d
commit 272ef5d39a
1 changed files with 54 additions and 0 deletions

View File

@ -401,12 +401,56 @@ validate_interstage_inout_blocks(struct gl_shader_program *prog,
return;
}
/* Desktop OpenGL requires redeclaration of the built-in interfaces for
* SSO programs. Passes above implement following rules:
*
* From Section 7.4 (Program Pipeline Objects) of the OpenGL 4.6 Core
* spec:
*
* "To use any built-in input or output in the gl_PerVertex and
* gl_PerFragment blocks in separable program objects, shader code
* must redeclare those blocks prior to use. A separable program
* will fail to link if:
*
* it contains multiple shaders of a single type with different
* redeclarations of these built-in input and output blocks; or
*
* any shader uses a built-in block member not found in the
* redeclaration of that block."
*
* ARB_separate_shader_objects issues section (issue #28) states that
* redeclaration is not required for GLSL shaders using #version 140 or
* earlier (since interface blocks are not possible with older versions).
*
* From Section 7.4.1 (Shader Interface Matching) of the OpenGL ES 3.1
* spec:
*
* "Built-in inputs or outputs do not affect interface matching."
*
* GL_OES_shader_io_blocks adds following:
*
* "When using any built-in input or output in the gl_PerVertex block
* in separable program objects, shader code may redeclare that block
* prior to use. If the shader does not redeclare the block, the
* intrinsically declared definition of that block will be used."
*/
/* Add output interfaces from the producer to the symbol table. */
foreach_in_list(ir_instruction, node, producer->ir) {
ir_variable *var = node->as_variable();
if (!var || !var->get_interface_type() || var->data.mode != ir_var_shader_out)
continue;
/* Built-in interface redeclaration check. */
if (prog->SeparateShader && !prog->IsES && prog->data->Version >= 150 &&
var->data.how_declared == ir_var_declared_implicitly &&
var->data.used && !producer_iface) {
linker_error(prog, "missing output builtin block %s redeclaration "
"in separable shader program",
var->get_interface_type()->name);
return;
}
definitions.store(var);
}
@ -418,6 +462,16 @@ validate_interstage_inout_blocks(struct gl_shader_program *prog,
ir_variable *producer_def = definitions.lookup(var);
/* Built-in interface redeclaration check. */
if (prog->SeparateShader && !prog->IsES && prog->data->Version >= 150 &&
var->data.how_declared == ir_var_declared_implicitly &&
var->data.used && !producer_iface) {
linker_error(prog, "missing input builtin block %s redeclaration "
"in separable shader program",
var->get_interface_type()->name);
return;
}
/* The producer doesn't generate this input: fail to link. Skip built-in
* 'gl_in[]' since that may not be present if the producer does not
* write to any of the pre-defined outputs (e.g. if the vertex shader