From 1fc9d5223eead0d1c76337849f16db8164f70c68 Mon Sep 17 00:00:00 2001 From: Timothy Arceri Date: Tue, 25 Jun 2024 15:45:24 +1000 Subject: [PATCH] glsl: make gl_nir_validate_intrastage_arrays() more flexible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This will allow us to use it before shaders from the same stage have been linked and merged. Acked-by: Marek Olšák Part-of: --- .../glsl/gl_nir_link_interface_blocks.c | 21 ++++++++++--------- src/compiler/glsl/gl_nir_linker.c | 12 +++++------ src/compiler/glsl/gl_nir_linker.h | 2 +- 3 files changed, 17 insertions(+), 18 deletions(-) diff --git a/src/compiler/glsl/gl_nir_link_interface_blocks.c b/src/compiler/glsl/gl_nir_link_interface_blocks.c index 599d27e803a..4c0a7c748ed 100644 --- a/src/compiler/glsl/gl_nir_link_interface_blocks.c +++ b/src/compiler/glsl/gl_nir_link_interface_blocks.c @@ -115,7 +115,7 @@ static bool intrastage_match(nir_variable *a, nir_variable *b, struct gl_shader_program *prog, - unsigned a_stage, + nir_shader *a_shader, bool match_precision) { /* From section 4.7 "Precision and Precision Qualifiers" in GLSL 4.50: @@ -165,7 +165,8 @@ intrastage_match(nir_variable *a, */ if (!type_match && (glsl_type_is_array(b->type) || glsl_type_is_array(a->type)) && (is_interface_instance(b) || is_interface_instance(a)) && - !gl_nir_validate_intrastage_arrays(prog, b, a, a_stage, match_precision)) + !gl_nir_validate_intrastage_arrays(prog, b, a, a_shader, + match_precision)) return false; return true; @@ -225,7 +226,7 @@ interstage_match(struct gl_shader_program *prog, nir_variable *producer, } struct ifc_var { - unsigned stage; + nir_shader *shader; nir_variable *var; }; @@ -256,11 +257,11 @@ ifc_lookup(struct hash_table *ht, nir_variable *var) */ static void ifc_store(void *mem_ctx, struct hash_table *ht, nir_variable *var, - unsigned stage) + nir_shader *shader) { struct ifc_var *ifc_var = ralloc(mem_ctx, struct ifc_var); ifc_var->var = var; - ifc_var->stage = stage; + ifc_var->shader = shader; if (var->data.explicit_location && var->data.location >= VARYING_SLOT_VAR0) { @@ -349,10 +350,10 @@ gl_nir_validate_intrastage_interface_blocks(struct gl_shader_program *prog, * it into the appropriate data structure. */ ifc_store(mem_ctx, definitions, var, - shader_list[i]->nir->info.stage); + shader_list[i]->nir); } else { nir_variable *prev_def = ifc_var->var; - if (!intrastage_match(prev_def, var, prog, ifc_var->stage, + if (!intrastage_match(prev_def, var, prog, ifc_var->shader, true /* match_precision */)) { linker_error(prog, "definitions of interface block `%s' do not" " match\n", glsl_get_type_name(var->interface_type)); @@ -466,7 +467,7 @@ gl_nir_validate_interstage_inout_blocks(struct gl_shader_program *prog, return; } - ifc_store(mem_ctx, ht, var, producer->Program->nir->info.stage); + ifc_store(mem_ctx, ht, var, producer->Program->nir); } /* Verify that the consumer's input interfaces match. */ @@ -543,14 +544,14 @@ gl_nir_validate_interstage_uniform_blocks(struct gl_shader_program *prog, struct ifc_var *ifc_var = ifc_lookup(ht, var); if (ifc_var == NULL) { - ifc_store(mem_ctx, ht, var, i); + ifc_store(mem_ctx, ht, var, stage->Program->nir); } 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). */ nir_variable *old_def = ifc_var->var; - if (!intrastage_match(old_def, var, prog, ifc_var->stage, false)) { + if (!intrastage_match(old_def, var, prog, ifc_var->shader, false)) { linker_error(prog, "definitions of uniform block `%s' do not " "match\n", glsl_get_type_name(var->interface_type)); ralloc_free(mem_ctx); diff --git a/src/compiler/glsl/gl_nir_linker.c b/src/compiler/glsl/gl_nir_linker.c index 9a585857671..db8679ba055 100644 --- a/src/compiler/glsl/gl_nir_linker.c +++ b/src/compiler/glsl/gl_nir_linker.c @@ -1623,7 +1623,7 @@ gl_nir_link_spirv(const struct gl_constants *consts, bool gl_nir_validate_intrastage_arrays(struct gl_shader_program *prog, nir_variable *var, nir_variable *existing, - unsigned existing_stage, + nir_shader *existing_shader, bool match_precision) { /* Consider the types to be "the same" if both types are arrays @@ -1655,9 +1655,7 @@ gl_nir_validate_intrastage_arrays(struct gl_shader_program *prog, existing->data.max_array_access); } existing->type = var->type; - - nir_shader *s = prog->_LinkedShaders[existing_stage]->Program->nir; - nir_fixup_deref_types(s); + nir_fixup_deref_types(existing_shader); return true; } else if (glsl_array_size(existing->type) != 0) { if((int)glsl_array_size(existing->type) <= var->data.max_array_access && @@ -1695,7 +1693,7 @@ nir_constant_compare(const nir_constant *c1, const nir_constant *c2) } struct ifc_var { - unsigned stage; + nir_shader *shader; nir_variable *var; }; @@ -1747,7 +1745,7 @@ cross_validate_globals(void *mem_ctx, const struct gl_constants *consts, /* Check if types match. */ if (var->type != existing->type) { if (!gl_nir_validate_intrastage_arrays(prog, var, existing, - existing_ifc->stage, true)) { + existing_ifc->shader, true)) { /* If it is an unsized array in a Shader Storage Block, * two different shaders can access to different elements. * Because of that, they might be converted to different @@ -1985,7 +1983,7 @@ cross_validate_globals(void *mem_ctx, const struct gl_constants *consts, } else { struct ifc_var *ifc_var = ralloc(mem_ctx, struct ifc_var); ifc_var->var = var; - ifc_var->stage = shader->info.stage; + ifc_var->shader = shader; _mesa_hash_table_insert(variables, var->name, ifc_var); } } diff --git a/src/compiler/glsl/gl_nir_linker.h b/src/compiler/glsl/gl_nir_linker.h index 3c7f73c7725..da516f0906d 100644 --- a/src/compiler/glsl/gl_nir_linker.h +++ b/src/compiler/glsl/gl_nir_linker.h @@ -81,7 +81,7 @@ const char * gl_nir_mode_string(const nir_variable *var); bool gl_nir_validate_intrastage_arrays(struct gl_shader_program *prog, nir_variable *var, nir_variable *existing, - unsigned existing_stage, + nir_shader *existing_shader, bool match_precision); struct nir_xfb_info *