mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 07:28:11 +02:00
glsl: validate MS/FS interstage in/out block
Mesh shader output block is always in array type, need to validate if the mesh shader output array element type match the fragment shader input type. Reviewed-by: Ian Romanick <ian.d.romanick@intel.com> Acked-by: Marek Olšák <marek.olsak@amd.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36405>
This commit is contained in:
parent
ae3c0ac9e9
commit
faa9fea7d2
1 changed files with 26 additions and 11 deletions
|
|
@ -404,13 +404,15 @@ intrastage_match(nir_variable *a,
|
|||
* Check if two interfaces match, according to interstage (in/out) interface
|
||||
* matching rules.
|
||||
*
|
||||
* 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.
|
||||
* If \c producer_extra_array_level and/or \c consumer_extra_array_level is true,
|
||||
* the producer and/or consumer interface is required to be an array.
|
||||
* This is used for tessellation control and geometry shader consumers,
|
||||
* or mesh shader producers.
|
||||
*/
|
||||
static bool
|
||||
interstage_match(struct gl_shader_program *prog, nir_variable *producer,
|
||||
nir_variable *consumer, bool extra_array_level)
|
||||
nir_variable *consumer, bool producer_extra_array_level,
|
||||
bool consumer_extra_array_level)
|
||||
{
|
||||
/* Types must match. */
|
||||
if (consumer->interface_type != producer->interface_type) {
|
||||
|
|
@ -432,12 +434,20 @@ interstage_match(struct gl_shader_program *prog, nir_variable *producer,
|
|||
|
||||
/* Ignore outermost array if geom shader */
|
||||
const glsl_type *consumer_instance_type;
|
||||
if (extra_array_level) {
|
||||
if (consumer_extra_array_level) {
|
||||
consumer_instance_type = glsl_get_array_element(consumer->type);
|
||||
} else {
|
||||
consumer_instance_type = consumer->type;
|
||||
}
|
||||
|
||||
/* Ignore outermost array if mesh shader */
|
||||
const glsl_type *producer_instance_type;
|
||||
if (producer_extra_array_level) {
|
||||
producer_instance_type = glsl_get_array_element(producer->type);
|
||||
} else {
|
||||
producer_instance_type = producer->type;
|
||||
}
|
||||
|
||||
/* 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.
|
||||
|
|
@ -445,8 +455,8 @@ interstage_match(struct gl_shader_program *prog, nir_variable *producer,
|
|||
if ((is_interface_instance(consumer) &&
|
||||
glsl_type_is_array(consumer_instance_type)) ||
|
||||
(is_interface_instance(producer) &&
|
||||
glsl_type_is_array(producer->type))) {
|
||||
if (consumer_instance_type != producer->type)
|
||||
glsl_type_is_array(producer_instance_type))) {
|
||||
if (consumer_instance_type != producer_instance_type)
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -614,9 +624,13 @@ gl_nir_validate_interstage_inout_blocks(struct gl_shader_program *prog,
|
|||
_mesa_key_string_equal);
|
||||
|
||||
/* 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;
|
||||
const bool consumer_extra_array_level =
|
||||
(producer->Stage == MESA_SHADER_VERTEX &&
|
||||
consumer->Stage != MESA_SHADER_FRAGMENT) ||
|
||||
consumer->Stage == MESA_SHADER_GEOMETRY;
|
||||
|
||||
/* MS -> FS */
|
||||
const bool producer_extra_array_level = producer->Stage == MESA_SHADER_MESH;
|
||||
|
||||
/* Check that block re-declarations of gl_PerVertex are compatible
|
||||
* across shaders: From OpenGL Shading Language 4.5, section
|
||||
|
|
@ -739,7 +753,8 @@ gl_nir_validate_interstage_inout_blocks(struct gl_shader_program *prog,
|
|||
}
|
||||
|
||||
if (producer_def &&
|
||||
!interstage_match(prog, producer_def, var, extra_array_level)) {
|
||||
!interstage_match(prog, producer_def, var, producer_extra_array_level,
|
||||
consumer_extra_array_level)) {
|
||||
linker_error(prog, "definitions of interface block `%s' do not "
|
||||
"match\n", glsl_get_type_name(var->interface_type));
|
||||
ralloc_free(mem_ctx);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue