From 01759d3fb2f8da642b3ee2a7e17589fe8f94efb4 Mon Sep 17 00:00:00 2001 From: Emma Anholt Date: Mon, 2 Aug 2021 12:49:56 -0700 Subject: [PATCH] nir: Set .driver_location for GLSL UBO/SSBOs when we lower to block indices. Without this, there's no way to match the UBO nir_variable declarations to the load_ubo intrinsics referencing their data. Reviewed-by: Adam Jackson Acked-by: Mike Blumenkrantz Part-of: --- src/compiler/glsl/gl_nir_lower_buffers.c | 13 ++++++++++--- src/compiler/nir/nir.h | 3 ++- src/compiler/nir/nir_lower_uniforms_to_ubo.c | 2 ++ 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/compiler/glsl/gl_nir_lower_buffers.c b/src/compiler/glsl/gl_nir_lower_buffers.c index d427d4a98be..b0ce128c196 100644 --- a/src/compiler/glsl/gl_nir_lower_buffers.c +++ b/src/compiler/glsl/gl_nir_lower_buffers.c @@ -39,7 +39,7 @@ get_block_array_index(nir_builder *b, nir_deref_instr *deref, * blocks later on as well as an optional dynamic index which gets added * to the block index later. */ - int binding = 0; + int const_array_offset = 0; const char *block_name = ""; nir_ssa_def *nonconst_index = NULL; while (deref->deref_type == nir_deref_type_array) { @@ -54,7 +54,7 @@ get_block_array_index(nir_builder *b, nir_deref_instr *deref, block_name = ralloc_asprintf(b->shader, "[%u]%s", arr_index, block_name); - binding += arr_index * array_elements; + const_array_offset += arr_index * array_elements; } else { nir_ssa_def *arr_index = nir_ssa_for_src(b, deref->arr.index, 1); arr_index = nir_umin(b, arr_index, nir_imm_int(b, arr_size - 1)); @@ -73,7 +73,7 @@ get_block_array_index(nir_builder *b, nir_deref_instr *deref, } assert(deref->deref_type == nir_deref_type_var); - binding += deref->var->data.binding; + int binding = const_array_offset + deref->var->data.binding; block_name = ralloc_asprintf(b->shader, "%s%s", glsl_get_type_name(deref->var->interface_type), block_name); @@ -98,6 +98,7 @@ get_block_array_index(nir_builder *b, nir_deref_instr *deref, for (unsigned i = 0; i < num_blocks; i++) { if (( use_bindings && binding == blocks[i]->Binding) || (!use_bindings && strcmp(block_name, blocks[i]->Name) == 0)) { + deref->var->data.driver_location = i - const_array_offset; if (nonconst_index) return nir_iadd_imm(b, nonconst_index, i); else @@ -144,6 +145,7 @@ get_block_index_offset(nir_variable *var, const char *block_name = glsl_get_type_name(var->interface_type); if (( use_bindings && blocks[i]->Binding == var->data.binding) || (!use_bindings && strcmp(block_name, blocks[i]->Name) == 0)) { + var->data.driver_location = i; *index = i; *offset = blocks[i]->Uniforms[var->data.location].Offset; return; @@ -329,6 +331,11 @@ gl_nir_lower_buffers(nir_shader *shader, { bool progress = false; + nir_foreach_variable_with_modes(var, shader, nir_var_mem_ubo | nir_var_mem_ssbo) { + var->data.driver_location = -1; + progress = true; + } + /* First, we lower the derefs to turn block variable and array derefs into * a nir_address_format_32bit_index_offset pointer. From there forward, * we leave the derefs in place and let nir_lower_explicit_io handle them. diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index 07688b57f9d..fbd7cfda291 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -567,7 +567,8 @@ typedef struct nir_variable { /** * The actual location of the variable in the IR. Only valid for inputs, - * outputs, and uniforms (including samplers and images). + * outputs, uniforms (including samplers and images), and for UBO and SSBO + * variables in GLSL. */ unsigned driver_location; diff --git a/src/compiler/nir/nir_lower_uniforms_to_ubo.c b/src/compiler/nir/nir_lower_uniforms_to_ubo.c index 0b37b705ef8..b1116e07a9d 100644 --- a/src/compiler/nir/nir_lower_uniforms_to_ubo.c +++ b/src/compiler/nir/nir_lower_uniforms_to_ubo.c @@ -135,6 +135,8 @@ nir_lower_uniforms_to_ubo(nir_shader *shader, bool dword_packed, bool load_vec4) if (!shader->info.first_ubo_is_default_ubo) { nir_foreach_variable_with_modes(var, shader, nir_var_mem_ubo) { var->data.binding++; + if (var->data.driver_location != -1) + var->data.driver_location++; /* only increment location for ubo arrays */ if (glsl_without_array(var->type) == var->interface_type && glsl_type_is_array(var->type))