2013-05-20 23:42:49 -07:00
|
|
|
/*
|
|
|
|
|
* Copyright © 2013 Intel Corporation
|
|
|
|
|
*
|
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
|
|
|
* to deal in the Software without restriction, including without limitation
|
|
|
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
|
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
|
|
|
* Software is furnished to do so, subject to the following conditions:
|
|
|
|
|
*
|
|
|
|
|
* The above copyright notice and this permission notice (including the next
|
|
|
|
|
* paragraph) shall be included in all copies or substantial portions of the
|
|
|
|
|
* Software.
|
|
|
|
|
*
|
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
|
|
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
|
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
|
|
|
* DEALINGS IN THE SOFTWARE.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* \file link_interface_blocks.cpp
|
|
|
|
|
* Linker support for GLSL's interface blocks.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "ir.h"
|
|
|
|
|
#include "glsl_symbol_table.h"
|
|
|
|
|
#include "linker.h"
|
|
|
|
|
#include "main/macros.h"
|
2015-12-02 17:53:19 +11:00
|
|
|
#include "util/hash_table.h"
|
glsl: Rework interface block linking.
Previously, when doing intrastage and interstage interface block
linking, we only checked the interface type; this prevented us from
catching some link errors.
We now check the following additional constraints:
- For intrastage linking, the presence/absence of interface names must
match.
- For shader ins/outs, the interface names themselves must match when
doing intrastage linking (note: it's not clear from the spec whether
this is necessary, but Mesa's implementation currently relies on
it).
- Array vs. nonarray must be consistent, taking into account the
special rules for vertex-geometry linkage.
- Array sizes must be consistent (exception: during intrastage
linking, an unsized array matches a sized array).
Note: validate_interstage_interface_blocks currently handles both
uniforms and in/out variables. As a result, if all three shader types
are present (VS, GS, and FS), and a uniform interface block is
mentioned in the VS and FS but not the GS, it won't be validated. I
plan to address this in later patches.
Fixes the following piglit tests in spec/glsl-1.50/linker:
- interface-blocks-vs-fs-array-size-mismatch
- interface-vs-array-to-fs-unnamed
- interface-vs-unnamed-to-fs-array
- intrastage-interface-unnamed-array
v2: Simplify logic in intrastage_match() for handling array sizes.
Make extra_array_level const. Use an unnamed temporary
interface_block_definition in validate_interstage_interface_blocks()'s
first call to definitions->store().
Cc: "10.0" <mesa-stable@lists.freedesktop.org>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2013-10-29 14:41:32 -07:00
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
2016-03-08 22:25:58 +11:00
|
|
|
/**
|
|
|
|
|
* Return true if interface members mismatch and its not allowed by GLSL.
|
|
|
|
|
*/
|
|
|
|
|
static bool
|
|
|
|
|
interstage_member_mismatch(struct gl_shader_program *prog,
|
|
|
|
|
const glsl_type *c, const glsl_type *p) {
|
|
|
|
|
|
|
|
|
|
if (c->length != p->length)
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
for (unsigned i = 0; i < c->length; i++) {
|
|
|
|
|
if (c->fields.structure[i].type != p->fields.structure[i].type)
|
|
|
|
|
return true;
|
|
|
|
|
if (strcmp(c->fields.structure[i].name,
|
|
|
|
|
p->fields.structure[i].name) != 0)
|
|
|
|
|
return true;
|
|
|
|
|
if (c->fields.structure[i].location !=
|
|
|
|
|
p->fields.structure[i].location)
|
|
|
|
|
return true;
|
|
|
|
|
if (c->fields.structure[i].patch !=
|
|
|
|
|
p->fields.structure[i].patch)
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
/* From Section 4.5 (Interpolation Qualifiers) of the GLSL 4.40 spec:
|
|
|
|
|
*
|
|
|
|
|
* "It is a link-time error if, within the same stage, the
|
|
|
|
|
* interpolation qualifiers of variables of the same name do not
|
|
|
|
|
* match."
|
|
|
|
|
*/
|
|
|
|
|
if (prog->IsES || prog->Version < 440)
|
|
|
|
|
if (c->fields.structure[i].interpolation !=
|
|
|
|
|
p->fields.structure[i].interpolation)
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
/* From Section 4.3.4 (Input Variables) of the GLSL ES 3.0 spec:
|
|
|
|
|
*
|
|
|
|
|
* "The output of the vertex shader and the input of the fragment
|
|
|
|
|
* shader form an interface. For this interface, vertex shader
|
|
|
|
|
* output variables and fragment shader input variables of the same
|
|
|
|
|
* name must match in type and qualification (other than precision
|
|
|
|
|
* and out matching to in).
|
|
|
|
|
*
|
|
|
|
|
* The table in Section 9.2.1 Linked Shaders of the GLSL ES 3.1 spec
|
|
|
|
|
* says that centroid no longer needs to match for varyings.
|
|
|
|
|
*
|
|
|
|
|
* The table in Section 9.2.1 Linked Shaders of the GLSL ES 3.2 spec
|
|
|
|
|
* says that sample need not match for varyings.
|
|
|
|
|
*/
|
|
|
|
|
if (!prog->IsES || prog->Version < 310)
|
|
|
|
|
if (c->fields.structure[i].centroid !=
|
|
|
|
|
p->fields.structure[i].centroid)
|
|
|
|
|
return true;
|
|
|
|
|
if (!prog->IsES)
|
|
|
|
|
if (c->fields.structure[i].sample !=
|
|
|
|
|
p->fields.structure[i].sample)
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
glsl: Rework interface block linking.
Previously, when doing intrastage and interstage interface block
linking, we only checked the interface type; this prevented us from
catching some link errors.
We now check the following additional constraints:
- For intrastage linking, the presence/absence of interface names must
match.
- For shader ins/outs, the interface names themselves must match when
doing intrastage linking (note: it's not clear from the spec whether
this is necessary, but Mesa's implementation currently relies on
it).
- Array vs. nonarray must be consistent, taking into account the
special rules for vertex-geometry linkage.
- Array sizes must be consistent (exception: during intrastage
linking, an unsized array matches a sized array).
Note: validate_interstage_interface_blocks currently handles both
uniforms and in/out variables. As a result, if all three shader types
are present (VS, GS, and FS), and a uniform interface block is
mentioned in the VS and FS but not the GS, it won't be validated. I
plan to address this in later patches.
Fixes the following piglit tests in spec/glsl-1.50/linker:
- interface-blocks-vs-fs-array-size-mismatch
- interface-vs-array-to-fs-unnamed
- interface-vs-unnamed-to-fs-array
- intrastage-interface-unnamed-array
v2: Simplify logic in intrastage_match() for handling array sizes.
Make extra_array_level const. Use an unnamed temporary
interface_block_definition in validate_interstage_interface_blocks()'s
first call to definitions->store().
Cc: "10.0" <mesa-stable@lists.freedesktop.org>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2013-10-29 14:41:32 -07:00
|
|
|
|
2016-10-18 10:52:58 +02:00
|
|
|
/**
|
|
|
|
|
* Check if two interfaces match, according to intrastage interface matching
|
|
|
|
|
* rules. If they do, and the first interface uses an unsized array, it will
|
|
|
|
|
* be updated to reflect the array size declared in the second interface.
|
|
|
|
|
*/
|
|
|
|
|
bool
|
|
|
|
|
intrastage_match(ir_variable *a,
|
|
|
|
|
ir_variable *b,
|
|
|
|
|
struct gl_shader_program *prog)
|
|
|
|
|
{
|
|
|
|
|
/* Types must match. */
|
|
|
|
|
if (a->get_interface_type() != b->get_interface_type()) {
|
|
|
|
|
/* Exception: if both the interface blocks are implicitly declared,
|
|
|
|
|
* don't force their types to match. They might mismatch due to the two
|
|
|
|
|
* shaders using different GLSL versions, and that's ok.
|
|
|
|
|
*/
|
2016-10-18 09:38:30 +02:00
|
|
|
if ((a->data.how_declared != ir_var_declared_implicitly ||
|
|
|
|
|
b->data.how_declared != ir_var_declared_implicitly) &&
|
|
|
|
|
(!prog->IsES || prog->Version != 310 ||
|
|
|
|
|
interstage_member_mismatch(prog, a->get_interface_type(),
|
|
|
|
|
b->get_interface_type())))
|
2016-10-18 10:52:58 +02:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Presence/absence of interface names must match. */
|
|
|
|
|
if (a->is_interface_instance() != b->is_interface_instance())
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
/* For uniforms, instance names need not match. For shader ins/outs,
|
|
|
|
|
* it's not clear from the spec whether they need to match, but
|
|
|
|
|
* Mesa's implementation relies on them matching.
|
|
|
|
|
*/
|
|
|
|
|
if (a->is_interface_instance() && b->data.mode != ir_var_uniform &&
|
|
|
|
|
b->data.mode != ir_var_shader_storage &&
|
|
|
|
|
strcmp(a->name, b->name) != 0) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* If a block is an array then it must match across the shader.
|
|
|
|
|
* Unsized arrays are also processed and matched agaist sized arrays.
|
|
|
|
|
*/
|
|
|
|
|
if (b->type != a->type &&
|
|
|
|
|
(b->is_interface_instance() || a->is_interface_instance()) &&
|
|
|
|
|
!validate_intrastage_arrays(prog, b, a))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
glsl: Rework interface block linking.
Previously, when doing intrastage and interstage interface block
linking, we only checked the interface type; this prevented us from
catching some link errors.
We now check the following additional constraints:
- For intrastage linking, the presence/absence of interface names must
match.
- For shader ins/outs, the interface names themselves must match when
doing intrastage linking (note: it's not clear from the spec whether
this is necessary, but Mesa's implementation currently relies on
it).
- Array vs. nonarray must be consistent, taking into account the
special rules for vertex-geometry linkage.
- Array sizes must be consistent (exception: during intrastage
linking, an unsized array matches a sized array).
Note: validate_interstage_interface_blocks currently handles both
uniforms and in/out variables. As a result, if all three shader types
are present (VS, GS, and FS), and a uniform interface block is
mentioned in the VS and FS but not the GS, it won't be validated. I
plan to address this in later patches.
Fixes the following piglit tests in spec/glsl-1.50/linker:
- interface-blocks-vs-fs-array-size-mismatch
- interface-vs-array-to-fs-unnamed
- interface-vs-unnamed-to-fs-array
- intrastage-interface-unnamed-array
v2: Simplify logic in intrastage_match() for handling array sizes.
Make extra_array_level const. Use an unnamed temporary
interface_block_definition in validate_interstage_interface_blocks()'s
first call to definitions->store().
Cc: "10.0" <mesa-stable@lists.freedesktop.org>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2013-10-29 14:41:32 -07:00
|
|
|
/**
|
|
|
|
|
* Check if two interfaces match, according to interstage (in/out) interface
|
|
|
|
|
* matching rules.
|
|
|
|
|
*
|
2014-09-21 13:33:14 +12:00
|
|
|
* If \c extra_array_level is true, the consumer interface is required to be
|
|
|
|
|
* an array and the producer interface is required to be a non-array.
|
|
|
|
|
* This is used for tessellation control and geometry shader consumers.
|
glsl: Rework interface block linking.
Previously, when doing intrastage and interstage interface block
linking, we only checked the interface type; this prevented us from
catching some link errors.
We now check the following additional constraints:
- For intrastage linking, the presence/absence of interface names must
match.
- For shader ins/outs, the interface names themselves must match when
doing intrastage linking (note: it's not clear from the spec whether
this is necessary, but Mesa's implementation currently relies on
it).
- Array vs. nonarray must be consistent, taking into account the
special rules for vertex-geometry linkage.
- Array sizes must be consistent (exception: during intrastage
linking, an unsized array matches a sized array).
Note: validate_interstage_interface_blocks currently handles both
uniforms and in/out variables. As a result, if all three shader types
are present (VS, GS, and FS), and a uniform interface block is
mentioned in the VS and FS but not the GS, it won't be validated. I
plan to address this in later patches.
Fixes the following piglit tests in spec/glsl-1.50/linker:
- interface-blocks-vs-fs-array-size-mismatch
- interface-vs-array-to-fs-unnamed
- interface-vs-unnamed-to-fs-array
- intrastage-interface-unnamed-array
v2: Simplify logic in intrastage_match() for handling array sizes.
Make extra_array_level const. Use an unnamed temporary
interface_block_definition in validate_interstage_interface_blocks()'s
first call to definitions->store().
Cc: "10.0" <mesa-stable@lists.freedesktop.org>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2013-10-29 14:41:32 -07:00
|
|
|
*/
|
2016-03-08 22:33:44 +11:00
|
|
|
static bool
|
2016-03-08 22:25:58 +11:00
|
|
|
interstage_match(struct gl_shader_program *prog, ir_variable *producer,
|
|
|
|
|
ir_variable *consumer, bool extra_array_level)
|
glsl: Rework interface block linking.
Previously, when doing intrastage and interstage interface block
linking, we only checked the interface type; this prevented us from
catching some link errors.
We now check the following additional constraints:
- For intrastage linking, the presence/absence of interface names must
match.
- For shader ins/outs, the interface names themselves must match when
doing intrastage linking (note: it's not clear from the spec whether
this is necessary, but Mesa's implementation currently relies on
it).
- Array vs. nonarray must be consistent, taking into account the
special rules for vertex-geometry linkage.
- Array sizes must be consistent (exception: during intrastage
linking, an unsized array matches a sized array).
Note: validate_interstage_interface_blocks currently handles both
uniforms and in/out variables. As a result, if all three shader types
are present (VS, GS, and FS), and a uniform interface block is
mentioned in the VS and FS but not the GS, it won't be validated. I
plan to address this in later patches.
Fixes the following piglit tests in spec/glsl-1.50/linker:
- interface-blocks-vs-fs-array-size-mismatch
- interface-vs-array-to-fs-unnamed
- interface-vs-unnamed-to-fs-array
- intrastage-interface-unnamed-array
v2: Simplify logic in intrastage_match() for handling array sizes.
Make extra_array_level const. Use an unnamed temporary
interface_block_definition in validate_interstage_interface_blocks()'s
first call to definitions->store().
Cc: "10.0" <mesa-stable@lists.freedesktop.org>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2013-10-29 14:41:32 -07:00
|
|
|
{
|
|
|
|
|
/* Types must match. */
|
2015-12-02 17:53:19 +11:00
|
|
|
if (consumer->get_interface_type() != producer->get_interface_type()) {
|
2013-11-19 17:48:02 -08:00
|
|
|
/* Exception: if both the interface blocks are implicitly declared,
|
|
|
|
|
* don't force their types to match. They might mismatch due to the two
|
|
|
|
|
* shaders using different GLSL versions, and that's ok.
|
2016-03-08 22:25:58 +11:00
|
|
|
*
|
|
|
|
|
* Also we store some member information such as interpolation in
|
|
|
|
|
* glsl_type that doesn't always have to match across shader stages.
|
|
|
|
|
* Therefore we make a pass over the members glsl_struct_field to make
|
|
|
|
|
* sure we don't reject shaders where fields don't need to match.
|
2013-11-19 17:48:02 -08:00
|
|
|
*/
|
2016-03-08 22:25:58 +11:00
|
|
|
if ((consumer->data.how_declared != ir_var_declared_implicitly ||
|
|
|
|
|
producer->data.how_declared != ir_var_declared_implicitly) &&
|
|
|
|
|
interstage_member_mismatch(prog, consumer->get_interface_type(),
|
|
|
|
|
producer->get_interface_type()))
|
2013-11-19 17:48:02 -08:00
|
|
|
return false;
|
|
|
|
|
}
|
2015-02-22 22:52:48 +11:00
|
|
|
|
|
|
|
|
/* Ignore outermost array if geom shader */
|
|
|
|
|
const glsl_type *consumer_instance_type;
|
glsl: Rework interface block linking.
Previously, when doing intrastage and interstage interface block
linking, we only checked the interface type; this prevented us from
catching some link errors.
We now check the following additional constraints:
- For intrastage linking, the presence/absence of interface names must
match.
- For shader ins/outs, the interface names themselves must match when
doing intrastage linking (note: it's not clear from the spec whether
this is necessary, but Mesa's implementation currently relies on
it).
- Array vs. nonarray must be consistent, taking into account the
special rules for vertex-geometry linkage.
- Array sizes must be consistent (exception: during intrastage
linking, an unsized array matches a sized array).
Note: validate_interstage_interface_blocks currently handles both
uniforms and in/out variables. As a result, if all three shader types
are present (VS, GS, and FS), and a uniform interface block is
mentioned in the VS and FS but not the GS, it won't be validated. I
plan to address this in later patches.
Fixes the following piglit tests in spec/glsl-1.50/linker:
- interface-blocks-vs-fs-array-size-mismatch
- interface-vs-array-to-fs-unnamed
- interface-vs-unnamed-to-fs-array
- intrastage-interface-unnamed-array
v2: Simplify logic in intrastage_match() for handling array sizes.
Make extra_array_level const. Use an unnamed temporary
interface_block_definition in validate_interstage_interface_blocks()'s
first call to definitions->store().
Cc: "10.0" <mesa-stable@lists.freedesktop.org>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2013-10-29 14:41:32 -07:00
|
|
|
if (extra_array_level) {
|
2015-12-02 17:53:19 +11:00
|
|
|
consumer_instance_type = consumer->type->fields.array;
|
glsl: Rework interface block linking.
Previously, when doing intrastage and interstage interface block
linking, we only checked the interface type; this prevented us from
catching some link errors.
We now check the following additional constraints:
- For intrastage linking, the presence/absence of interface names must
match.
- For shader ins/outs, the interface names themselves must match when
doing intrastage linking (note: it's not clear from the spec whether
this is necessary, but Mesa's implementation currently relies on
it).
- Array vs. nonarray must be consistent, taking into account the
special rules for vertex-geometry linkage.
- Array sizes must be consistent (exception: during intrastage
linking, an unsized array matches a sized array).
Note: validate_interstage_interface_blocks currently handles both
uniforms and in/out variables. As a result, if all three shader types
are present (VS, GS, and FS), and a uniform interface block is
mentioned in the VS and FS but not the GS, it won't be validated. I
plan to address this in later patches.
Fixes the following piglit tests in spec/glsl-1.50/linker:
- interface-blocks-vs-fs-array-size-mismatch
- interface-vs-array-to-fs-unnamed
- interface-vs-unnamed-to-fs-array
- intrastage-interface-unnamed-array
v2: Simplify logic in intrastage_match() for handling array sizes.
Make extra_array_level const. Use an unnamed temporary
interface_block_definition in validate_interstage_interface_blocks()'s
first call to definitions->store().
Cc: "10.0" <mesa-stable@lists.freedesktop.org>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2013-10-29 14:41:32 -07:00
|
|
|
} else {
|
2015-12-02 17:53:19 +11:00
|
|
|
consumer_instance_type = consumer->type;
|
2015-02-22 22:52:48 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* If a block is an array then it must match across shaders.
|
|
|
|
|
* Since unsized arrays have been ruled out, we can check this by just
|
|
|
|
|
* making sure the types are equal.
|
|
|
|
|
*/
|
2015-12-02 17:53:19 +11:00
|
|
|
if ((consumer->is_interface_instance() &&
|
2015-02-22 22:52:48 +11:00
|
|
|
consumer_instance_type->is_array()) ||
|
2015-12-02 17:53:19 +11:00
|
|
|
(producer->is_interface_instance() &&
|
|
|
|
|
producer->type->is_array())) {
|
|
|
|
|
if (consumer_instance_type != producer->type)
|
glsl: Rework interface block linking.
Previously, when doing intrastage and interstage interface block
linking, we only checked the interface type; this prevented us from
catching some link errors.
We now check the following additional constraints:
- For intrastage linking, the presence/absence of interface names must
match.
- For shader ins/outs, the interface names themselves must match when
doing intrastage linking (note: it's not clear from the spec whether
this is necessary, but Mesa's implementation currently relies on
it).
- Array vs. nonarray must be consistent, taking into account the
special rules for vertex-geometry linkage.
- Array sizes must be consistent (exception: during intrastage
linking, an unsized array matches a sized array).
Note: validate_interstage_interface_blocks currently handles both
uniforms and in/out variables. As a result, if all three shader types
are present (VS, GS, and FS), and a uniform interface block is
mentioned in the VS and FS but not the GS, it won't be validated. I
plan to address this in later patches.
Fixes the following piglit tests in spec/glsl-1.50/linker:
- interface-blocks-vs-fs-array-size-mismatch
- interface-vs-array-to-fs-unnamed
- interface-vs-unnamed-to-fs-array
- intrastage-interface-unnamed-array
v2: Simplify logic in intrastage_match() for handling array sizes.
Make extra_array_level const. Use an unnamed temporary
interface_block_definition in validate_interstage_interface_blocks()'s
first call to definitions->store().
Cc: "10.0" <mesa-stable@lists.freedesktop.org>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2013-10-29 14:41:32 -07:00
|
|
|
return false;
|
|
|
|
|
}
|
2015-02-22 22:52:48 +11:00
|
|
|
|
glsl: Rework interface block linking.
Previously, when doing intrastage and interstage interface block
linking, we only checked the interface type; this prevented us from
catching some link errors.
We now check the following additional constraints:
- For intrastage linking, the presence/absence of interface names must
match.
- For shader ins/outs, the interface names themselves must match when
doing intrastage linking (note: it's not clear from the spec whether
this is necessary, but Mesa's implementation currently relies on
it).
- Array vs. nonarray must be consistent, taking into account the
special rules for vertex-geometry linkage.
- Array sizes must be consistent (exception: during intrastage
linking, an unsized array matches a sized array).
Note: validate_interstage_interface_blocks currently handles both
uniforms and in/out variables. As a result, if all three shader types
are present (VS, GS, and FS), and a uniform interface block is
mentioned in the VS and FS but not the GS, it won't be validated. I
plan to address this in later patches.
Fixes the following piglit tests in spec/glsl-1.50/linker:
- interface-blocks-vs-fs-array-size-mismatch
- interface-vs-array-to-fs-unnamed
- interface-vs-unnamed-to-fs-array
- intrastage-interface-unnamed-array
v2: Simplify logic in intrastage_match() for handling array sizes.
Make extra_array_level const. Use an unnamed temporary
interface_block_definition in validate_interstage_interface_blocks()'s
first call to definitions->store().
Cc: "10.0" <mesa-stable@lists.freedesktop.org>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2013-10-29 14:41:32 -07:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* This class keeps track of a mapping from an interface block name to the
|
|
|
|
|
* necessary information about that interface block to determine whether to
|
|
|
|
|
* generate a link error.
|
|
|
|
|
*
|
|
|
|
|
* Note: this class is expected to be short lived, so it doesn't make copies
|
|
|
|
|
* of the strings it references; it simply borrows the pointers from the
|
|
|
|
|
* ir_variable class.
|
|
|
|
|
*/
|
|
|
|
|
class interface_block_definitions
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
interface_block_definitions()
|
|
|
|
|
: mem_ctx(ralloc_context(NULL)),
|
2015-12-02 17:53:19 +11:00
|
|
|
ht(_mesa_hash_table_create(NULL, _mesa_key_hash_string,
|
|
|
|
|
_mesa_key_string_equal))
|
glsl: Rework interface block linking.
Previously, when doing intrastage and interstage interface block
linking, we only checked the interface type; this prevented us from
catching some link errors.
We now check the following additional constraints:
- For intrastage linking, the presence/absence of interface names must
match.
- For shader ins/outs, the interface names themselves must match when
doing intrastage linking (note: it's not clear from the spec whether
this is necessary, but Mesa's implementation currently relies on
it).
- Array vs. nonarray must be consistent, taking into account the
special rules for vertex-geometry linkage.
- Array sizes must be consistent (exception: during intrastage
linking, an unsized array matches a sized array).
Note: validate_interstage_interface_blocks currently handles both
uniforms and in/out variables. As a result, if all three shader types
are present (VS, GS, and FS), and a uniform interface block is
mentioned in the VS and FS but not the GS, it won't be validated. I
plan to address this in later patches.
Fixes the following piglit tests in spec/glsl-1.50/linker:
- interface-blocks-vs-fs-array-size-mismatch
- interface-vs-array-to-fs-unnamed
- interface-vs-unnamed-to-fs-array
- intrastage-interface-unnamed-array
v2: Simplify logic in intrastage_match() for handling array sizes.
Make extra_array_level const. Use an unnamed temporary
interface_block_definition in validate_interstage_interface_blocks()'s
first call to definitions->store().
Cc: "10.0" <mesa-stable@lists.freedesktop.org>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2013-10-29 14:41:32 -07:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
~interface_block_definitions()
|
|
|
|
|
{
|
|
|
|
|
ralloc_free(mem_ctx);
|
2015-12-02 17:53:19 +11:00
|
|
|
_mesa_hash_table_destroy(ht, NULL);
|
glsl: Rework interface block linking.
Previously, when doing intrastage and interstage interface block
linking, we only checked the interface type; this prevented us from
catching some link errors.
We now check the following additional constraints:
- For intrastage linking, the presence/absence of interface names must
match.
- For shader ins/outs, the interface names themselves must match when
doing intrastage linking (note: it's not clear from the spec whether
this is necessary, but Mesa's implementation currently relies on
it).
- Array vs. nonarray must be consistent, taking into account the
special rules for vertex-geometry linkage.
- Array sizes must be consistent (exception: during intrastage
linking, an unsized array matches a sized array).
Note: validate_interstage_interface_blocks currently handles both
uniforms and in/out variables. As a result, if all three shader types
are present (VS, GS, and FS), and a uniform interface block is
mentioned in the VS and FS but not the GS, it won't be validated. I
plan to address this in later patches.
Fixes the following piglit tests in spec/glsl-1.50/linker:
- interface-blocks-vs-fs-array-size-mismatch
- interface-vs-array-to-fs-unnamed
- interface-vs-unnamed-to-fs-array
- intrastage-interface-unnamed-array
v2: Simplify logic in intrastage_match() for handling array sizes.
Make extra_array_level const. Use an unnamed temporary
interface_block_definition in validate_interstage_interface_blocks()'s
first call to definitions->store().
Cc: "10.0" <mesa-stable@lists.freedesktop.org>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2013-10-29 14:41:32 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2015-12-02 17:53:19 +11:00
|
|
|
* Lookup the interface definition. Return NULL if none is found.
|
glsl: Rework interface block linking.
Previously, when doing intrastage and interstage interface block
linking, we only checked the interface type; this prevented us from
catching some link errors.
We now check the following additional constraints:
- For intrastage linking, the presence/absence of interface names must
match.
- For shader ins/outs, the interface names themselves must match when
doing intrastage linking (note: it's not clear from the spec whether
this is necessary, but Mesa's implementation currently relies on
it).
- Array vs. nonarray must be consistent, taking into account the
special rules for vertex-geometry linkage.
- Array sizes must be consistent (exception: during intrastage
linking, an unsized array matches a sized array).
Note: validate_interstage_interface_blocks currently handles both
uniforms and in/out variables. As a result, if all three shader types
are present (VS, GS, and FS), and a uniform interface block is
mentioned in the VS and FS but not the GS, it won't be validated. I
plan to address this in later patches.
Fixes the following piglit tests in spec/glsl-1.50/linker:
- interface-blocks-vs-fs-array-size-mismatch
- interface-vs-array-to-fs-unnamed
- interface-vs-unnamed-to-fs-array
- intrastage-interface-unnamed-array
v2: Simplify logic in intrastage_match() for handling array sizes.
Make extra_array_level const. Use an unnamed temporary
interface_block_definition in validate_interstage_interface_blocks()'s
first call to definitions->store().
Cc: "10.0" <mesa-stable@lists.freedesktop.org>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2013-10-29 14:41:32 -07:00
|
|
|
*/
|
2015-12-02 17:53:19 +11:00
|
|
|
ir_variable *lookup(ir_variable *var)
|
glsl: Rework interface block linking.
Previously, when doing intrastage and interstage interface block
linking, we only checked the interface type; this prevented us from
catching some link errors.
We now check the following additional constraints:
- For intrastage linking, the presence/absence of interface names must
match.
- For shader ins/outs, the interface names themselves must match when
doing intrastage linking (note: it's not clear from the spec whether
this is necessary, but Mesa's implementation currently relies on
it).
- Array vs. nonarray must be consistent, taking into account the
special rules for vertex-geometry linkage.
- Array sizes must be consistent (exception: during intrastage
linking, an unsized array matches a sized array).
Note: validate_interstage_interface_blocks currently handles both
uniforms and in/out variables. As a result, if all three shader types
are present (VS, GS, and FS), and a uniform interface block is
mentioned in the VS and FS but not the GS, it won't be validated. I
plan to address this in later patches.
Fixes the following piglit tests in spec/glsl-1.50/linker:
- interface-blocks-vs-fs-array-size-mismatch
- interface-vs-array-to-fs-unnamed
- interface-vs-unnamed-to-fs-array
- intrastage-interface-unnamed-array
v2: Simplify logic in intrastage_match() for handling array sizes.
Make extra_array_level const. Use an unnamed temporary
interface_block_definition in validate_interstage_interface_blocks()'s
first call to definitions->store().
Cc: "10.0" <mesa-stable@lists.freedesktop.org>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2013-10-29 14:41:32 -07:00
|
|
|
{
|
2015-12-01 10:34:18 +11:00
|
|
|
if (var->data.explicit_location &&
|
|
|
|
|
var->data.location >= VARYING_SLOT_VAR0) {
|
|
|
|
|
char location_str[11];
|
|
|
|
|
snprintf(location_str, 11, "%d", var->data.location);
|
|
|
|
|
|
|
|
|
|
const struct hash_entry *entry =
|
|
|
|
|
_mesa_hash_table_search(ht, location_str);
|
|
|
|
|
return entry ? (ir_variable *) entry->data : NULL;
|
|
|
|
|
} else {
|
|
|
|
|
const struct hash_entry *entry =
|
2016-03-11 16:15:02 +11:00
|
|
|
_mesa_hash_table_search(ht,
|
|
|
|
|
var->get_interface_type()->without_array()->name);
|
2015-12-01 10:34:18 +11:00
|
|
|
return entry ? (ir_variable *) entry->data : NULL;
|
|
|
|
|
}
|
glsl: Rework interface block linking.
Previously, when doing intrastage and interstage interface block
linking, we only checked the interface type; this prevented us from
catching some link errors.
We now check the following additional constraints:
- For intrastage linking, the presence/absence of interface names must
match.
- For shader ins/outs, the interface names themselves must match when
doing intrastage linking (note: it's not clear from the spec whether
this is necessary, but Mesa's implementation currently relies on
it).
- Array vs. nonarray must be consistent, taking into account the
special rules for vertex-geometry linkage.
- Array sizes must be consistent (exception: during intrastage
linking, an unsized array matches a sized array).
Note: validate_interstage_interface_blocks currently handles both
uniforms and in/out variables. As a result, if all three shader types
are present (VS, GS, and FS), and a uniform interface block is
mentioned in the VS and FS but not the GS, it won't be validated. I
plan to address this in later patches.
Fixes the following piglit tests in spec/glsl-1.50/linker:
- interface-blocks-vs-fs-array-size-mismatch
- interface-vs-array-to-fs-unnamed
- interface-vs-unnamed-to-fs-array
- intrastage-interface-unnamed-array
v2: Simplify logic in intrastage_match() for handling array sizes.
Make extra_array_level const. Use an unnamed temporary
interface_block_definition in validate_interstage_interface_blocks()'s
first call to definitions->store().
Cc: "10.0" <mesa-stable@lists.freedesktop.org>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2013-10-29 14:41:32 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Add a new interface definition.
|
|
|
|
|
*/
|
2015-12-02 17:53:19 +11:00
|
|
|
void store(ir_variable *var)
|
glsl: Rework interface block linking.
Previously, when doing intrastage and interstage interface block
linking, we only checked the interface type; this prevented us from
catching some link errors.
We now check the following additional constraints:
- For intrastage linking, the presence/absence of interface names must
match.
- For shader ins/outs, the interface names themselves must match when
doing intrastage linking (note: it's not clear from the spec whether
this is necessary, but Mesa's implementation currently relies on
it).
- Array vs. nonarray must be consistent, taking into account the
special rules for vertex-geometry linkage.
- Array sizes must be consistent (exception: during intrastage
linking, an unsized array matches a sized array).
Note: validate_interstage_interface_blocks currently handles both
uniforms and in/out variables. As a result, if all three shader types
are present (VS, GS, and FS), and a uniform interface block is
mentioned in the VS and FS but not the GS, it won't be validated. I
plan to address this in later patches.
Fixes the following piglit tests in spec/glsl-1.50/linker:
- interface-blocks-vs-fs-array-size-mismatch
- interface-vs-array-to-fs-unnamed
- interface-vs-unnamed-to-fs-array
- intrastage-interface-unnamed-array
v2: Simplify logic in intrastage_match() for handling array sizes.
Make extra_array_level const. Use an unnamed temporary
interface_block_definition in validate_interstage_interface_blocks()'s
first call to definitions->store().
Cc: "10.0" <mesa-stable@lists.freedesktop.org>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2013-10-29 14:41:32 -07:00
|
|
|
{
|
2015-12-01 10:34:18 +11:00
|
|
|
if (var->data.explicit_location &&
|
|
|
|
|
var->data.location >= VARYING_SLOT_VAR0) {
|
|
|
|
|
/* If explicit location is given then lookup the variable by location.
|
|
|
|
|
* We turn the location into a string and use this as the hash key
|
|
|
|
|
* rather than the name. Note: We allocate enough space for a 32-bit
|
|
|
|
|
* unsigned location value which is overkill but future proof.
|
|
|
|
|
*/
|
|
|
|
|
char location_str[11];
|
|
|
|
|
snprintf(location_str, 11, "%d", var->data.location);
|
|
|
|
|
_mesa_hash_table_insert(ht, ralloc_strdup(mem_ctx, location_str), var);
|
|
|
|
|
} else {
|
2016-03-11 16:15:02 +11:00
|
|
|
_mesa_hash_table_insert(ht,
|
|
|
|
|
var->get_interface_type()->without_array()->name, var);
|
2015-12-01 10:34:18 +11:00
|
|
|
}
|
glsl: Rework interface block linking.
Previously, when doing intrastage and interstage interface block
linking, we only checked the interface type; this prevented us from
catching some link errors.
We now check the following additional constraints:
- For intrastage linking, the presence/absence of interface names must
match.
- For shader ins/outs, the interface names themselves must match when
doing intrastage linking (note: it's not clear from the spec whether
this is necessary, but Mesa's implementation currently relies on
it).
- Array vs. nonarray must be consistent, taking into account the
special rules for vertex-geometry linkage.
- Array sizes must be consistent (exception: during intrastage
linking, an unsized array matches a sized array).
Note: validate_interstage_interface_blocks currently handles both
uniforms and in/out variables. As a result, if all three shader types
are present (VS, GS, and FS), and a uniform interface block is
mentioned in the VS and FS but not the GS, it won't be validated. I
plan to address this in later patches.
Fixes the following piglit tests in spec/glsl-1.50/linker:
- interface-blocks-vs-fs-array-size-mismatch
- interface-vs-array-to-fs-unnamed
- interface-vs-unnamed-to-fs-array
- intrastage-interface-unnamed-array
v2: Simplify logic in intrastage_match() for handling array sizes.
Make extra_array_level const. Use an unnamed temporary
interface_block_definition in validate_interstage_interface_blocks()'s
first call to definitions->store().
Cc: "10.0" <mesa-stable@lists.freedesktop.org>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2013-10-29 14:41:32 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
/**
|
|
|
|
|
* Ralloc context for data structures allocated by this class.
|
|
|
|
|
*/
|
|
|
|
|
void *mem_ctx;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Hash table mapping interface block name to an \c
|
2015-12-02 17:53:19 +11:00
|
|
|
* ir_variable.
|
glsl: Rework interface block linking.
Previously, when doing intrastage and interstage interface block
linking, we only checked the interface type; this prevented us from
catching some link errors.
We now check the following additional constraints:
- For intrastage linking, the presence/absence of interface names must
match.
- For shader ins/outs, the interface names themselves must match when
doing intrastage linking (note: it's not clear from the spec whether
this is necessary, but Mesa's implementation currently relies on
it).
- Array vs. nonarray must be consistent, taking into account the
special rules for vertex-geometry linkage.
- Array sizes must be consistent (exception: during intrastage
linking, an unsized array matches a sized array).
Note: validate_interstage_interface_blocks currently handles both
uniforms and in/out variables. As a result, if all three shader types
are present (VS, GS, and FS), and a uniform interface block is
mentioned in the VS and FS but not the GS, it won't be validated. I
plan to address this in later patches.
Fixes the following piglit tests in spec/glsl-1.50/linker:
- interface-blocks-vs-fs-array-size-mismatch
- interface-vs-array-to-fs-unnamed
- interface-vs-unnamed-to-fs-array
- intrastage-interface-unnamed-array
v2: Simplify logic in intrastage_match() for handling array sizes.
Make extra_array_level const. Use an unnamed temporary
interface_block_definition in validate_interstage_interface_blocks()'s
first call to definitions->store().
Cc: "10.0" <mesa-stable@lists.freedesktop.org>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2013-10-29 14:41:32 -07:00
|
|
|
*/
|
|
|
|
|
hash_table *ht;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}; /* anonymous namespace */
|
|
|
|
|
|
2013-05-20 23:42:49 -07:00
|
|
|
|
2013-07-27 11:08:31 -07:00
|
|
|
void
|
2013-07-27 14:58:43 -07:00
|
|
|
validate_intrastage_interface_blocks(struct gl_shader_program *prog,
|
|
|
|
|
const gl_shader **shader_list,
|
2013-05-20 23:42:49 -07:00
|
|
|
unsigned num_shaders)
|
|
|
|
|
{
|
glsl: Rework interface block linking.
Previously, when doing intrastage and interstage interface block
linking, we only checked the interface type; this prevented us from
catching some link errors.
We now check the following additional constraints:
- For intrastage linking, the presence/absence of interface names must
match.
- For shader ins/outs, the interface names themselves must match when
doing intrastage linking (note: it's not clear from the spec whether
this is necessary, but Mesa's implementation currently relies on
it).
- Array vs. nonarray must be consistent, taking into account the
special rules for vertex-geometry linkage.
- Array sizes must be consistent (exception: during intrastage
linking, an unsized array matches a sized array).
Note: validate_interstage_interface_blocks currently handles both
uniforms and in/out variables. As a result, if all three shader types
are present (VS, GS, and FS), and a uniform interface block is
mentioned in the VS and FS but not the GS, it won't be validated. I
plan to address this in later patches.
Fixes the following piglit tests in spec/glsl-1.50/linker:
- interface-blocks-vs-fs-array-size-mismatch
- interface-vs-array-to-fs-unnamed
- interface-vs-unnamed-to-fs-array
- intrastage-interface-unnamed-array
v2: Simplify logic in intrastage_match() for handling array sizes.
Make extra_array_level const. Use an unnamed temporary
interface_block_definition in validate_interstage_interface_blocks()'s
first call to definitions->store().
Cc: "10.0" <mesa-stable@lists.freedesktop.org>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2013-10-29 14:41:32 -07:00
|
|
|
interface_block_definitions in_interfaces;
|
|
|
|
|
interface_block_definitions out_interfaces;
|
|
|
|
|
interface_block_definitions uniform_interfaces;
|
2015-05-13 11:17:23 +02:00
|
|
|
interface_block_definitions buffer_interfaces;
|
2013-05-20 23:42:49 -07:00
|
|
|
|
|
|
|
|
for (unsigned int i = 0; i < num_shaders; i++) {
|
|
|
|
|
if (shader_list[i] == NULL)
|
|
|
|
|
continue;
|
|
|
|
|
|
2014-06-24 21:34:05 -07:00
|
|
|
foreach_in_list(ir_instruction, node, shader_list[i]->ir) {
|
|
|
|
|
ir_variable *var = node->as_variable();
|
2013-05-20 23:42:49 -07:00
|
|
|
if (!var)
|
|
|
|
|
continue;
|
|
|
|
|
|
2013-09-24 14:30:29 -07:00
|
|
|
const glsl_type *iface_type = var->get_interface_type();
|
2013-05-20 23:42:49 -07:00
|
|
|
|
|
|
|
|
if (iface_type == NULL)
|
|
|
|
|
continue;
|
|
|
|
|
|
glsl: Rework interface block linking.
Previously, when doing intrastage and interstage interface block
linking, we only checked the interface type; this prevented us from
catching some link errors.
We now check the following additional constraints:
- For intrastage linking, the presence/absence of interface names must
match.
- For shader ins/outs, the interface names themselves must match when
doing intrastage linking (note: it's not clear from the spec whether
this is necessary, but Mesa's implementation currently relies on
it).
- Array vs. nonarray must be consistent, taking into account the
special rules for vertex-geometry linkage.
- Array sizes must be consistent (exception: during intrastage
linking, an unsized array matches a sized array).
Note: validate_interstage_interface_blocks currently handles both
uniforms and in/out variables. As a result, if all three shader types
are present (VS, GS, and FS), and a uniform interface block is
mentioned in the VS and FS but not the GS, it won't be validated. I
plan to address this in later patches.
Fixes the following piglit tests in spec/glsl-1.50/linker:
- interface-blocks-vs-fs-array-size-mismatch
- interface-vs-array-to-fs-unnamed
- interface-vs-unnamed-to-fs-array
- intrastage-interface-unnamed-array
v2: Simplify logic in intrastage_match() for handling array sizes.
Make extra_array_level const. Use an unnamed temporary
interface_block_definition in validate_interstage_interface_blocks()'s
first call to definitions->store().
Cc: "10.0" <mesa-stable@lists.freedesktop.org>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2013-10-29 14:41:32 -07:00
|
|
|
interface_block_definitions *definitions;
|
2013-12-12 13:51:01 +02:00
|
|
|
switch (var->data.mode) {
|
glsl: Rework interface block linking.
Previously, when doing intrastage and interstage interface block
linking, we only checked the interface type; this prevented us from
catching some link errors.
We now check the following additional constraints:
- For intrastage linking, the presence/absence of interface names must
match.
- For shader ins/outs, the interface names themselves must match when
doing intrastage linking (note: it's not clear from the spec whether
this is necessary, but Mesa's implementation currently relies on
it).
- Array vs. nonarray must be consistent, taking into account the
special rules for vertex-geometry linkage.
- Array sizes must be consistent (exception: during intrastage
linking, an unsized array matches a sized array).
Note: validate_interstage_interface_blocks currently handles both
uniforms and in/out variables. As a result, if all three shader types
are present (VS, GS, and FS), and a uniform interface block is
mentioned in the VS and FS but not the GS, it won't be validated. I
plan to address this in later patches.
Fixes the following piglit tests in spec/glsl-1.50/linker:
- interface-blocks-vs-fs-array-size-mismatch
- interface-vs-array-to-fs-unnamed
- interface-vs-unnamed-to-fs-array
- intrastage-interface-unnamed-array
v2: Simplify logic in intrastage_match() for handling array sizes.
Make extra_array_level const. Use an unnamed temporary
interface_block_definition in validate_interstage_interface_blocks()'s
first call to definitions->store().
Cc: "10.0" <mesa-stable@lists.freedesktop.org>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2013-10-29 14:41:32 -07:00
|
|
|
case ir_var_shader_in:
|
|
|
|
|
definitions = &in_interfaces;
|
|
|
|
|
break;
|
|
|
|
|
case ir_var_shader_out:
|
|
|
|
|
definitions = &out_interfaces;
|
|
|
|
|
break;
|
|
|
|
|
case ir_var_uniform:
|
|
|
|
|
definitions = &uniform_interfaces;
|
|
|
|
|
break;
|
2015-05-13 11:17:23 +02:00
|
|
|
case ir_var_shader_storage:
|
|
|
|
|
definitions = &buffer_interfaces;
|
|
|
|
|
break;
|
glsl: Rework interface block linking.
Previously, when doing intrastage and interstage interface block
linking, we only checked the interface type; this prevented us from
catching some link errors.
We now check the following additional constraints:
- For intrastage linking, the presence/absence of interface names must
match.
- For shader ins/outs, the interface names themselves must match when
doing intrastage linking (note: it's not clear from the spec whether
this is necessary, but Mesa's implementation currently relies on
it).
- Array vs. nonarray must be consistent, taking into account the
special rules for vertex-geometry linkage.
- Array sizes must be consistent (exception: during intrastage
linking, an unsized array matches a sized array).
Note: validate_interstage_interface_blocks currently handles both
uniforms and in/out variables. As a result, if all three shader types
are present (VS, GS, and FS), and a uniform interface block is
mentioned in the VS and FS but not the GS, it won't be validated. I
plan to address this in later patches.
Fixes the following piglit tests in spec/glsl-1.50/linker:
- interface-blocks-vs-fs-array-size-mismatch
- interface-vs-array-to-fs-unnamed
- interface-vs-unnamed-to-fs-array
- intrastage-interface-unnamed-array
v2: Simplify logic in intrastage_match() for handling array sizes.
Make extra_array_level const. Use an unnamed temporary
interface_block_definition in validate_interstage_interface_blocks()'s
first call to definitions->store().
Cc: "10.0" <mesa-stable@lists.freedesktop.org>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2013-10-29 14:41:32 -07:00
|
|
|
default:
|
|
|
|
|
/* Only in, out, and uniform interfaces are legal, so we should
|
|
|
|
|
* never get here.
|
|
|
|
|
*/
|
|
|
|
|
assert(!"illegal interface type");
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2013-05-20 23:42:49 -07:00
|
|
|
|
2015-12-02 17:53:19 +11:00
|
|
|
ir_variable *prev_def = definitions->lookup(var);
|
glsl: Rework interface block linking.
Previously, when doing intrastage and interstage interface block
linking, we only checked the interface type; this prevented us from
catching some link errors.
We now check the following additional constraints:
- For intrastage linking, the presence/absence of interface names must
match.
- For shader ins/outs, the interface names themselves must match when
doing intrastage linking (note: it's not clear from the spec whether
this is necessary, but Mesa's implementation currently relies on
it).
- Array vs. nonarray must be consistent, taking into account the
special rules for vertex-geometry linkage.
- Array sizes must be consistent (exception: during intrastage
linking, an unsized array matches a sized array).
Note: validate_interstage_interface_blocks currently handles both
uniforms and in/out variables. As a result, if all three shader types
are present (VS, GS, and FS), and a uniform interface block is
mentioned in the VS and FS but not the GS, it won't be validated. I
plan to address this in later patches.
Fixes the following piglit tests in spec/glsl-1.50/linker:
- interface-blocks-vs-fs-array-size-mismatch
- interface-vs-array-to-fs-unnamed
- interface-vs-unnamed-to-fs-array
- intrastage-interface-unnamed-array
v2: Simplify logic in intrastage_match() for handling array sizes.
Make extra_array_level const. Use an unnamed temporary
interface_block_definition in validate_interstage_interface_blocks()'s
first call to definitions->store().
Cc: "10.0" <mesa-stable@lists.freedesktop.org>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2013-10-29 14:41:32 -07:00
|
|
|
if (prev_def == NULL) {
|
2013-05-20 23:42:49 -07:00
|
|
|
/* This is the first time we've seen the interface, so save
|
glsl: Rework interface block linking.
Previously, when doing intrastage and interstage interface block
linking, we only checked the interface type; this prevented us from
catching some link errors.
We now check the following additional constraints:
- For intrastage linking, the presence/absence of interface names must
match.
- For shader ins/outs, the interface names themselves must match when
doing intrastage linking (note: it's not clear from the spec whether
this is necessary, but Mesa's implementation currently relies on
it).
- Array vs. nonarray must be consistent, taking into account the
special rules for vertex-geometry linkage.
- Array sizes must be consistent (exception: during intrastage
linking, an unsized array matches a sized array).
Note: validate_interstage_interface_blocks currently handles both
uniforms and in/out variables. As a result, if all three shader types
are present (VS, GS, and FS), and a uniform interface block is
mentioned in the VS and FS but not the GS, it won't be validated. I
plan to address this in later patches.
Fixes the following piglit tests in spec/glsl-1.50/linker:
- interface-blocks-vs-fs-array-size-mismatch
- interface-vs-array-to-fs-unnamed
- interface-vs-unnamed-to-fs-array
- intrastage-interface-unnamed-array
v2: Simplify logic in intrastage_match() for handling array sizes.
Make extra_array_level const. Use an unnamed temporary
interface_block_definition in validate_interstage_interface_blocks()'s
first call to definitions->store().
Cc: "10.0" <mesa-stable@lists.freedesktop.org>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
2013-10-29 14:41:32 -07:00
|
|
|
* it into the appropriate data structure.
|
2013-05-20 23:42:49 -07:00
|
|
|
*/
|
2015-12-02 17:53:19 +11:00
|
|
|
definitions->store(var);
|
|
|
|
|
} else if (!intrastage_match(prev_def, var, prog)) {
|
2013-07-27 14:58:43 -07:00
|
|
|
linker_error(prog, "definitions of interface block `%s' do not"
|
|
|
|
|
" match\n", iface_type->name);
|
2013-07-27 11:08:31 -07:00
|
|
|
return;
|
2013-05-20 23:42:49 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2013-05-20 23:46:16 -07:00
|
|
|
|
glsl: validate output blocks against input blocks
Until now were validating in/out blocks by listing the inputs in the
consumer stage and then, for each output of the producer, we checked that
it was a match if it was consumed. This method does not catch the case
where the consumer has an input that is not present as an output in the
producer stage, because it only generates link errors for outputs present
in the producer stage that don't match the inputs in the consumer stage.
The current method does catch the case were an output from the producer
stage is not consumed, which is irrelevant and is ignored.
By reversing the way we do this, we can detect this situation, so this
patch lists the outputs of the producer stage and then validates inputs
of the consumer stage against them. If we see an input in the consumer
for which there is no associated output in the producer, we produce a
link error.
The only exception to this is the special built-in input block gl_in[],
since this is implicitly generated for geometry and tessellation stages,
but we don't generate it if the producer stage does not write to any of
the pre-defined outputs (for example, if the vertex shader does not write
to gl_Position, etc). Since writing to these is not mandatory, do not
produce a link error in that case. There is a CTS tessellation test
(GL45-CTS.tessellation_shader.program_object_properties) that has an
empty vertex shader (so it does not produce gl_in[]) and would fail to
link if we don't do this.
This fixes the following dEQP test:
dEQP-GLES31.functional.shaders.linkage.io_block.missing_output_block
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=98245
Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
2016-11-04 13:37:58 +01:00
|
|
|
static bool
|
|
|
|
|
is_builtin_gl_in_block(ir_variable *var, int consumer_stage)
|
|
|
|
|
{
|
|
|
|
|
return !strcmp(var->name, "gl_in") &&
|
|
|
|
|
(consumer_stage == MESA_SHADER_TESS_CTRL ||
|
|
|
|
|
consumer_stage == MESA_SHADER_TESS_EVAL ||
|
|
|
|
|
consumer_stage == MESA_SHADER_GEOMETRY);
|
|
|
|
|
}
|
|
|
|
|
|
2013-07-27 11:08:31 -07:00
|
|
|
void
|
glsl: Fix interstage uniform interface block link error detection.
Previously, we checked for interstage uniform interface block link
errors in validate_interstage_interface_blocks(), which is only called
on pairs of adjacent shader stages. Therefore, we failed to detect
uniform interface block mismatches between non-adjacent shader stages.
Before the introduction of geometry shaders, this wasn't a problem,
because the only supported shader stages were vertex and fragment
shaders, therefore they were always adjacent. However, now that we
allow a program to contain vertex, geometry, and fragment shaders,
that is no longer the case.
Fixes piglit test "skip-stage-uniform-block-array-size-mismatch".
Cc: "10.0" <mesa-stable@lists.freedesktop.org>
v2: Rename validate_interstage_interface_blocks() to
validate_interstage_inout_blocks() to reflect the fact that it no
longer validates uniform blocks.
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
v3: Make validate_interstage_inout_blocks() skip uniform blocks.
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
2013-11-15 14:23:45 -08:00
|
|
|
validate_interstage_inout_blocks(struct gl_shader_program *prog,
|
2016-06-30 14:55:40 +10:00
|
|
|
const gl_linked_shader *producer,
|
|
|
|
|
const gl_linked_shader *consumer)
|
2013-05-20 23:46:16 -07:00
|
|
|
{
|
glsl: Fix interstage uniform interface block link error detection.
Previously, we checked for interstage uniform interface block link
errors in validate_interstage_interface_blocks(), which is only called
on pairs of adjacent shader stages. Therefore, we failed to detect
uniform interface block mismatches between non-adjacent shader stages.
Before the introduction of geometry shaders, this wasn't a problem,
because the only supported shader stages were vertex and fragment
shaders, therefore they were always adjacent. However, now that we
allow a program to contain vertex, geometry, and fragment shaders,
that is no longer the case.
Fixes piglit test "skip-stage-uniform-block-array-size-mismatch".
Cc: "10.0" <mesa-stable@lists.freedesktop.org>
v2: Rename validate_interstage_interface_blocks() to
validate_interstage_inout_blocks() to reflect the fact that it no
longer validates uniform blocks.
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
v3: Make validate_interstage_inout_blocks() skip uniform blocks.
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
2013-11-15 14:23:45 -08:00
|
|
|
interface_block_definitions definitions;
|
2014-09-21 13:33:14 +12:00
|
|
|
/* VS -> GS, VS -> TCS, VS -> TES, TES -> GS */
|
|
|
|
|
const bool extra_array_level = (producer->Stage == MESA_SHADER_VERTEX &&
|
|
|
|
|
consumer->Stage != MESA_SHADER_FRAGMENT) ||
|
|
|
|
|
consumer->Stage == MESA_SHADER_GEOMETRY;
|
2013-05-20 23:46:16 -07:00
|
|
|
|
glsl: validate output blocks against input blocks
Until now were validating in/out blocks by listing the inputs in the
consumer stage and then, for each output of the producer, we checked that
it was a match if it was consumed. This method does not catch the case
where the consumer has an input that is not present as an output in the
producer stage, because it only generates link errors for outputs present
in the producer stage that don't match the inputs in the consumer stage.
The current method does catch the case were an output from the producer
stage is not consumed, which is irrelevant and is ignored.
By reversing the way we do this, we can detect this situation, so this
patch lists the outputs of the producer stage and then validates inputs
of the consumer stage against them. If we see an input in the consumer
for which there is no associated output in the producer, we produce a
link error.
The only exception to this is the special built-in input block gl_in[],
since this is implicitly generated for geometry and tessellation stages,
but we don't generate it if the producer stage does not write to any of
the pre-defined outputs (for example, if the vertex shader does not write
to gl_Position, etc). Since writing to these is not mandatory, do not
produce a link error in that case. There is a CTS tessellation test
(GL45-CTS.tessellation_shader.program_object_properties) that has an
empty vertex shader (so it does not produce gl_in[]) and would fail to
link if we don't do this.
This fixes the following dEQP test:
dEQP-GLES31.functional.shaders.linkage.io_block.missing_output_block
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=98245
Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
2016-11-04 13:37:58 +01:00
|
|
|
/* Add output interfaces from the producer to the symbol table. */
|
|
|
|
|
foreach_in_list(ir_instruction, node, producer->ir) {
|
2014-06-24 21:34:05 -07:00
|
|
|
ir_variable *var = node->as_variable();
|
glsl: validate output blocks against input blocks
Until now were validating in/out blocks by listing the inputs in the
consumer stage and then, for each output of the producer, we checked that
it was a match if it was consumed. This method does not catch the case
where the consumer has an input that is not present as an output in the
producer stage, because it only generates link errors for outputs present
in the producer stage that don't match the inputs in the consumer stage.
The current method does catch the case were an output from the producer
stage is not consumed, which is irrelevant and is ignored.
By reversing the way we do this, we can detect this situation, so this
patch lists the outputs of the producer stage and then validates inputs
of the consumer stage against them. If we see an input in the consumer
for which there is no associated output in the producer, we produce a
link error.
The only exception to this is the special built-in input block gl_in[],
since this is implicitly generated for geometry and tessellation stages,
but we don't generate it if the producer stage does not write to any of
the pre-defined outputs (for example, if the vertex shader does not write
to gl_Position, etc). Since writing to these is not mandatory, do not
produce a link error in that case. There is a CTS tessellation test
(GL45-CTS.tessellation_shader.program_object_properties) that has an
empty vertex shader (so it does not produce gl_in[]) and would fail to
link if we don't do this.
This fixes the following dEQP test:
dEQP-GLES31.functional.shaders.linkage.io_block.missing_output_block
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=98245
Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
2016-11-04 13:37:58 +01:00
|
|
|
if (!var || !var->get_interface_type() || var->data.mode != ir_var_shader_out)
|
2013-05-20 23:46:16 -07:00
|
|
|
continue;
|
|
|
|
|
|
2015-12-02 17:53:19 +11:00
|
|
|
definitions.store(var);
|
2013-05-20 23:46:16 -07:00
|
|
|
}
|
|
|
|
|
|
glsl: validate output blocks against input blocks
Until now were validating in/out blocks by listing the inputs in the
consumer stage and then, for each output of the producer, we checked that
it was a match if it was consumed. This method does not catch the case
where the consumer has an input that is not present as an output in the
producer stage, because it only generates link errors for outputs present
in the producer stage that don't match the inputs in the consumer stage.
The current method does catch the case were an output from the producer
stage is not consumed, which is irrelevant and is ignored.
By reversing the way we do this, we can detect this situation, so this
patch lists the outputs of the producer stage and then validates inputs
of the consumer stage against them. If we see an input in the consumer
for which there is no associated output in the producer, we produce a
link error.
The only exception to this is the special built-in input block gl_in[],
since this is implicitly generated for geometry and tessellation stages,
but we don't generate it if the producer stage does not write to any of
the pre-defined outputs (for example, if the vertex shader does not write
to gl_Position, etc). Since writing to these is not mandatory, do not
produce a link error in that case. There is a CTS tessellation test
(GL45-CTS.tessellation_shader.program_object_properties) that has an
empty vertex shader (so it does not produce gl_in[]) and would fail to
link if we don't do this.
This fixes the following dEQP test:
dEQP-GLES31.functional.shaders.linkage.io_block.missing_output_block
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=98245
Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
2016-11-04 13:37:58 +01:00
|
|
|
/* Verify that the consumer's input interfaces match. */
|
|
|
|
|
foreach_in_list(ir_instruction, node, consumer->ir) {
|
2014-06-24 21:34:05 -07:00
|
|
|
ir_variable *var = node->as_variable();
|
glsl: validate output blocks against input blocks
Until now were validating in/out blocks by listing the inputs in the
consumer stage and then, for each output of the producer, we checked that
it was a match if it was consumed. This method does not catch the case
where the consumer has an input that is not present as an output in the
producer stage, because it only generates link errors for outputs present
in the producer stage that don't match the inputs in the consumer stage.
The current method does catch the case were an output from the producer
stage is not consumed, which is irrelevant and is ignored.
By reversing the way we do this, we can detect this situation, so this
patch lists the outputs of the producer stage and then validates inputs
of the consumer stage against them. If we see an input in the consumer
for which there is no associated output in the producer, we produce a
link error.
The only exception to this is the special built-in input block gl_in[],
since this is implicitly generated for geometry and tessellation stages,
but we don't generate it if the producer stage does not write to any of
the pre-defined outputs (for example, if the vertex shader does not write
to gl_Position, etc). Since writing to these is not mandatory, do not
produce a link error in that case. There is a CTS tessellation test
(GL45-CTS.tessellation_shader.program_object_properties) that has an
empty vertex shader (so it does not produce gl_in[]) and would fail to
link if we don't do this.
This fixes the following dEQP test:
dEQP-GLES31.functional.shaders.linkage.io_block.missing_output_block
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=98245
Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
2016-11-04 13:37:58 +01:00
|
|
|
if (!var || !var->get_interface_type() || var->data.mode != ir_var_shader_in)
|
2013-05-20 23:46:16 -07:00
|
|
|
continue;
|
|
|
|
|
|
glsl: validate output blocks against input blocks
Until now were validating in/out blocks by listing the inputs in the
consumer stage and then, for each output of the producer, we checked that
it was a match if it was consumed. This method does not catch the case
where the consumer has an input that is not present as an output in the
producer stage, because it only generates link errors for outputs present
in the producer stage that don't match the inputs in the consumer stage.
The current method does catch the case were an output from the producer
stage is not consumed, which is irrelevant and is ignored.
By reversing the way we do this, we can detect this situation, so this
patch lists the outputs of the producer stage and then validates inputs
of the consumer stage against them. If we see an input in the consumer
for which there is no associated output in the producer, we produce a
link error.
The only exception to this is the special built-in input block gl_in[],
since this is implicitly generated for geometry and tessellation stages,
but we don't generate it if the producer stage does not write to any of
the pre-defined outputs (for example, if the vertex shader does not write
to gl_Position, etc). Since writing to these is not mandatory, do not
produce a link error in that case. There is a CTS tessellation test
(GL45-CTS.tessellation_shader.program_object_properties) that has an
empty vertex shader (so it does not produce gl_in[]) and would fail to
link if we don't do this.
This fixes the following dEQP test:
dEQP-GLES31.functional.shaders.linkage.io_block.missing_output_block
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=98245
Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
2016-11-04 13:37:58 +01:00
|
|
|
ir_variable *producer_def = definitions.lookup(var);
|
2013-05-20 23:46:16 -07:00
|
|
|
|
glsl: validate output blocks against input blocks
Until now were validating in/out blocks by listing the inputs in the
consumer stage and then, for each output of the producer, we checked that
it was a match if it was consumed. This method does not catch the case
where the consumer has an input that is not present as an output in the
producer stage, because it only generates link errors for outputs present
in the producer stage that don't match the inputs in the consumer stage.
The current method does catch the case were an output from the producer
stage is not consumed, which is irrelevant and is ignored.
By reversing the way we do this, we can detect this situation, so this
patch lists the outputs of the producer stage and then validates inputs
of the consumer stage against them. If we see an input in the consumer
for which there is no associated output in the producer, we produce a
link error.
The only exception to this is the special built-in input block gl_in[],
since this is implicitly generated for geometry and tessellation stages,
but we don't generate it if the producer stage does not write to any of
the pre-defined outputs (for example, if the vertex shader does not write
to gl_Position, etc). Since writing to these is not mandatory, do not
produce a link error in that case. There is a CTS tessellation test
(GL45-CTS.tessellation_shader.program_object_properties) that has an
empty vertex shader (so it does not produce gl_in[]) and would fail to
link if we don't do this.
This fixes the following dEQP test:
dEQP-GLES31.functional.shaders.linkage.io_block.missing_output_block
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=98245
Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
2016-11-04 13:37:58 +01:00
|
|
|
/* 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
|
|
|
|
|
* does not write to gl_Position, etc), which is allowed and results in
|
|
|
|
|
* undefined behavior.
|
|
|
|
|
*/
|
|
|
|
|
if (producer_def == NULL &&
|
|
|
|
|
!is_builtin_gl_in_block(var, consumer->Stage)) {
|
|
|
|
|
linker_error(prog, "Input block `%s' is not an output of "
|
|
|
|
|
"the previous stage\n", var->get_interface_type()->name);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2013-05-20 23:46:16 -07:00
|
|
|
|
glsl: validate output blocks against input blocks
Until now were validating in/out blocks by listing the inputs in the
consumer stage and then, for each output of the producer, we checked that
it was a match if it was consumed. This method does not catch the case
where the consumer has an input that is not present as an output in the
producer stage, because it only generates link errors for outputs present
in the producer stage that don't match the inputs in the consumer stage.
The current method does catch the case were an output from the producer
stage is not consumed, which is irrelevant and is ignored.
By reversing the way we do this, we can detect this situation, so this
patch lists the outputs of the producer stage and then validates inputs
of the consumer stage against them. If we see an input in the consumer
for which there is no associated output in the producer, we produce a
link error.
The only exception to this is the special built-in input block gl_in[],
since this is implicitly generated for geometry and tessellation stages,
but we don't generate it if the producer stage does not write to any of
the pre-defined outputs (for example, if the vertex shader does not write
to gl_Position, etc). Since writing to these is not mandatory, do not
produce a link error in that case. There is a CTS tessellation test
(GL45-CTS.tessellation_shader.program_object_properties) that has an
empty vertex shader (so it does not produce gl_in[]) and would fail to
link if we don't do this.
This fixes the following dEQP test:
dEQP-GLES31.functional.shaders.linkage.io_block.missing_output_block
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=98245
Reviewed-by: Nicolai Hähnle <nicolai.haehnle@amd.com>
2016-11-04 13:37:58 +01:00
|
|
|
if (producer_def &&
|
|
|
|
|
!interstage_match(prog, producer_def, var, extra_array_level)) {
|
2013-07-27 15:24:46 -07:00
|
|
|
linker_error(prog, "definitions of interface block `%s' do not "
|
2013-09-24 14:30:29 -07:00
|
|
|
"match\n", var->get_interface_type()->name);
|
2013-07-27 11:08:31 -07:00
|
|
|
return;
|
|
|
|
|
}
|
2013-05-20 23:46:16 -07:00
|
|
|
}
|
|
|
|
|
}
|
glsl: Fix interstage uniform interface block link error detection.
Previously, we checked for interstage uniform interface block link
errors in validate_interstage_interface_blocks(), which is only called
on pairs of adjacent shader stages. Therefore, we failed to detect
uniform interface block mismatches between non-adjacent shader stages.
Before the introduction of geometry shaders, this wasn't a problem,
because the only supported shader stages were vertex and fragment
shaders, therefore they were always adjacent. However, now that we
allow a program to contain vertex, geometry, and fragment shaders,
that is no longer the case.
Fixes piglit test "skip-stage-uniform-block-array-size-mismatch".
Cc: "10.0" <mesa-stable@lists.freedesktop.org>
v2: Rename validate_interstage_interface_blocks() to
validate_interstage_inout_blocks() to reflect the fact that it no
longer validates uniform blocks.
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
v3: Make validate_interstage_inout_blocks() skip uniform blocks.
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
2013-11-15 14:23:45 -08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
validate_interstage_uniform_blocks(struct gl_shader_program *prog,
|
2016-06-30 14:55:40 +10:00
|
|
|
gl_linked_shader **stages)
|
glsl: Fix interstage uniform interface block link error detection.
Previously, we checked for interstage uniform interface block link
errors in validate_interstage_interface_blocks(), which is only called
on pairs of adjacent shader stages. Therefore, we failed to detect
uniform interface block mismatches between non-adjacent shader stages.
Before the introduction of geometry shaders, this wasn't a problem,
because the only supported shader stages were vertex and fragment
shaders, therefore they were always adjacent. However, now that we
allow a program to contain vertex, geometry, and fragment shaders,
that is no longer the case.
Fixes piglit test "skip-stage-uniform-block-array-size-mismatch".
Cc: "10.0" <mesa-stable@lists.freedesktop.org>
v2: Rename validate_interstage_interface_blocks() to
validate_interstage_inout_blocks() to reflect the fact that it no
longer validates uniform blocks.
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
v3: Make validate_interstage_inout_blocks() skip uniform blocks.
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
2013-11-15 14:23:45 -08:00
|
|
|
{
|
|
|
|
|
interface_block_definitions definitions;
|
|
|
|
|
|
2016-06-30 14:55:40 +10:00
|
|
|
for (int i = 0; i < MESA_SHADER_STAGES; i++) {
|
glsl: Fix interstage uniform interface block link error detection.
Previously, we checked for interstage uniform interface block link
errors in validate_interstage_interface_blocks(), which is only called
on pairs of adjacent shader stages. Therefore, we failed to detect
uniform interface block mismatches between non-adjacent shader stages.
Before the introduction of geometry shaders, this wasn't a problem,
because the only supported shader stages were vertex and fragment
shaders, therefore they were always adjacent. However, now that we
allow a program to contain vertex, geometry, and fragment shaders,
that is no longer the case.
Fixes piglit test "skip-stage-uniform-block-array-size-mismatch".
Cc: "10.0" <mesa-stable@lists.freedesktop.org>
v2: Rename validate_interstage_interface_blocks() to
validate_interstage_inout_blocks() to reflect the fact that it no
longer validates uniform blocks.
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
v3: Make validate_interstage_inout_blocks() skip uniform blocks.
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
2013-11-15 14:23:45 -08:00
|
|
|
if (stages[i] == NULL)
|
|
|
|
|
continue;
|
|
|
|
|
|
2016-06-30 14:55:40 +10:00
|
|
|
const gl_linked_shader *stage = stages[i];
|
2014-06-24 21:34:05 -07:00
|
|
|
foreach_in_list(ir_instruction, node, stage->ir) {
|
|
|
|
|
ir_variable *var = node->as_variable();
|
2015-05-13 11:17:23 +02:00
|
|
|
if (!var || !var->get_interface_type() ||
|
|
|
|
|
(var->data.mode != ir_var_uniform &&
|
|
|
|
|
var->data.mode != ir_var_shader_storage))
|
glsl: Fix interstage uniform interface block link error detection.
Previously, we checked for interstage uniform interface block link
errors in validate_interstage_interface_blocks(), which is only called
on pairs of adjacent shader stages. Therefore, we failed to detect
uniform interface block mismatches between non-adjacent shader stages.
Before the introduction of geometry shaders, this wasn't a problem,
because the only supported shader stages were vertex and fragment
shaders, therefore they were always adjacent. However, now that we
allow a program to contain vertex, geometry, and fragment shaders,
that is no longer the case.
Fixes piglit test "skip-stage-uniform-block-array-size-mismatch".
Cc: "10.0" <mesa-stable@lists.freedesktop.org>
v2: Rename validate_interstage_interface_blocks() to
validate_interstage_inout_blocks() to reflect the fact that it no
longer validates uniform blocks.
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
v3: Make validate_interstage_inout_blocks() skip uniform blocks.
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
2013-11-15 14:23:45 -08:00
|
|
|
continue;
|
|
|
|
|
|
2015-12-02 17:53:19 +11:00
|
|
|
ir_variable *old_def = definitions.lookup(var);
|
glsl: Fix interstage uniform interface block link error detection.
Previously, we checked for interstage uniform interface block link
errors in validate_interstage_interface_blocks(), which is only called
on pairs of adjacent shader stages. Therefore, we failed to detect
uniform interface block mismatches between non-adjacent shader stages.
Before the introduction of geometry shaders, this wasn't a problem,
because the only supported shader stages were vertex and fragment
shaders, therefore they were always adjacent. However, now that we
allow a program to contain vertex, geometry, and fragment shaders,
that is no longer the case.
Fixes piglit test "skip-stage-uniform-block-array-size-mismatch".
Cc: "10.0" <mesa-stable@lists.freedesktop.org>
v2: Rename validate_interstage_interface_blocks() to
validate_interstage_inout_blocks() to reflect the fact that it no
longer validates uniform blocks.
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
v3: Make validate_interstage_inout_blocks() skip uniform blocks.
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
2013-11-15 14:23:45 -08:00
|
|
|
if (old_def == NULL) {
|
2015-12-02 17:53:19 +11:00
|
|
|
definitions.store(var);
|
glsl: Fix interstage uniform interface block link error detection.
Previously, we checked for interstage uniform interface block link
errors in validate_interstage_interface_blocks(), which is only called
on pairs of adjacent shader stages. Therefore, we failed to detect
uniform interface block mismatches between non-adjacent shader stages.
Before the introduction of geometry shaders, this wasn't a problem,
because the only supported shader stages were vertex and fragment
shaders, therefore they were always adjacent. However, now that we
allow a program to contain vertex, geometry, and fragment shaders,
that is no longer the case.
Fixes piglit test "skip-stage-uniform-block-array-size-mismatch".
Cc: "10.0" <mesa-stable@lists.freedesktop.org>
v2: Rename validate_interstage_interface_blocks() to
validate_interstage_inout_blocks() to reflect the fact that it no
longer validates uniform blocks.
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
v3: Make validate_interstage_inout_blocks() skip uniform blocks.
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
2013-11-15 14:23:45 -08:00
|
|
|
} else {
|
|
|
|
|
/* Interstage uniform matching rules are the same as intrastage
|
|
|
|
|
* uniform matchin rules (for uniforms, it is as though all
|
|
|
|
|
* shaders are in the same shader stage).
|
|
|
|
|
*/
|
2015-12-02 17:53:19 +11:00
|
|
|
if (!intrastage_match(old_def, var, prog)) {
|
2016-05-26 07:42:16 +10:00
|
|
|
linker_error(prog, "definitions of uniform block `%s' do not "
|
glsl: Fix interstage uniform interface block link error detection.
Previously, we checked for interstage uniform interface block link
errors in validate_interstage_interface_blocks(), which is only called
on pairs of adjacent shader stages. Therefore, we failed to detect
uniform interface block mismatches between non-adjacent shader stages.
Before the introduction of geometry shaders, this wasn't a problem,
because the only supported shader stages were vertex and fragment
shaders, therefore they were always adjacent. However, now that we
allow a program to contain vertex, geometry, and fragment shaders,
that is no longer the case.
Fixes piglit test "skip-stage-uniform-block-array-size-mismatch".
Cc: "10.0" <mesa-stable@lists.freedesktop.org>
v2: Rename validate_interstage_interface_blocks() to
validate_interstage_inout_blocks() to reflect the fact that it no
longer validates uniform blocks.
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
v3: Make validate_interstage_inout_blocks() skip uniform blocks.
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
2013-11-15 14:23:45 -08:00
|
|
|
"match\n", var->get_interface_type()->name);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|