Path: blob/21.2-virgl/src/compiler/glsl/gl_nir_link_uniforms.c
4545 views
/*1* Copyright © 2018 Intel Corporation2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING19* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS20* IN THE SOFTWARE.21*/2223#include "nir.h"24#include "nir_deref.h"25#include "gl_nir_linker.h"26#include "compiler/glsl/ir_uniform.h" /* for gl_uniform_storage */27#include "linker_util.h"28#include "main/context.h"29#include "main/mtypes.h"3031/**32* This file do the common link for GLSL uniforms, using NIR, instead of IR as33* the counter-part glsl/link_uniforms.cpp34*/3536#define UNMAPPED_UNIFORM_LOC ~0u3738struct uniform_array_info {39/** List of dereferences of the uniform array. */40struct util_dynarray *deref_list;4142/** Set of bit-flags to note which array elements have been accessed. */43BITSET_WORD *indices;44};4546/**47* Built-in / reserved GL variables names start with "gl_"48*/49static inline bool50is_gl_identifier(const char *s)51{52return s && s[0] == 'g' && s[1] == 'l' && s[2] == '_';53}5455static unsigned56uniform_storage_size(const struct glsl_type *type)57{58switch (glsl_get_base_type(type)) {59case GLSL_TYPE_STRUCT:60case GLSL_TYPE_INTERFACE: {61unsigned size = 0;62for (unsigned i = 0; i < glsl_get_length(type); i++)63size += uniform_storage_size(glsl_get_struct_field(type, i));64return size;65}66case GLSL_TYPE_ARRAY: {67const struct glsl_type *e_type = glsl_get_array_element(type);68enum glsl_base_type e_base_type = glsl_get_base_type(e_type);69if (e_base_type == GLSL_TYPE_STRUCT ||70e_base_type == GLSL_TYPE_INTERFACE ||71e_base_type == GLSL_TYPE_ARRAY) {72unsigned length = !glsl_type_is_unsized_array(type) ?73glsl_get_length(type) : 1;74return length * uniform_storage_size(e_type);75} else76return 1;77}78default:79return 1;80}81}8283/**84* Update the sizes of linked shader uniform arrays to the maximum85* array index used.86*87* From page 81 (page 95 of the PDF) of the OpenGL 2.1 spec:88*89* If one or more elements of an array are active,90* GetActiveUniform will return the name of the array in name,91* subject to the restrictions listed above. The type of the array92* is returned in type. The size parameter contains the highest93* array element index used, plus one. The compiler or linker94* determines the highest index used. There will be only one95* active uniform reported by the GL per uniform array.96*/97static void98update_array_sizes(struct gl_shader_program *prog, nir_variable *var,99struct hash_table **referenced_uniforms,100unsigned current_var_stage)101{102/* For now we only resize 1D arrays.103* TODO: add support for resizing more complex array types ??104*/105if (!glsl_type_is_array(var->type) ||106glsl_type_is_array(glsl_get_array_element(var->type)))107return;108109/* GL_ARB_uniform_buffer_object says that std140 uniforms110* will not be eliminated. Since we always do std140, just111* don't resize arrays in UBOs.112*113* Atomic counters are supposed to get deterministic114* locations assigned based on the declaration ordering and115* sizes, array compaction would mess that up.116*117* Subroutine uniforms are not removed.118*/119if (nir_variable_is_in_block(var) || glsl_contains_atomic(var->type) ||120glsl_get_base_type(glsl_without_array(var->type)) == GLSL_TYPE_SUBROUTINE ||121var->constant_initializer)122return;123124struct uniform_array_info *ainfo = NULL;125int words = BITSET_WORDS(glsl_array_size(var->type));126int max_array_size = 0;127for (unsigned stage = 0; stage < MESA_SHADER_STAGES; stage++) {128struct gl_linked_shader *sh = prog->_LinkedShaders[stage];129if (!sh)130continue;131132struct hash_entry *entry =133_mesa_hash_table_search(referenced_uniforms[stage], var->name);134if (entry) {135ainfo = (struct uniform_array_info *) entry->data;136max_array_size = MAX2(BITSET_LAST_BIT_SIZED(ainfo->indices, words),137max_array_size);138}139140if (max_array_size == glsl_array_size(var->type))141return;142}143144if (max_array_size != glsl_array_size(var->type)) {145/* If this is a built-in uniform (i.e., it's backed by some146* fixed-function state), adjust the number of state slots to147* match the new array size. The number of slots per array entry148* is not known. It seems safe to assume that the total number of149* slots is an integer multiple of the number of array elements.150* Determine the number of slots per array element by dividing by151* the old (total) size.152*/153const unsigned num_slots = var->num_state_slots;154if (num_slots > 0) {155var->num_state_slots =156(max_array_size * (num_slots / glsl_array_size(var->type)));157}158159var->type = glsl_array_type(glsl_get_array_element(var->type),160max_array_size, 0);161162/* Update the types of dereferences in case we changed any. */163struct hash_entry *entry =164_mesa_hash_table_search(referenced_uniforms[current_var_stage], var->name);165if (entry) {166struct uniform_array_info *ainfo =167(struct uniform_array_info *) entry->data;168util_dynarray_foreach(ainfo->deref_list, nir_deref_instr *, deref) {169(*deref)->type = var->type;170}171}172}173}174175static void176nir_setup_uniform_remap_tables(struct gl_context *ctx,177struct gl_shader_program *prog)178{179unsigned total_entries = prog->NumExplicitUniformLocations;180181/* For glsl this may have been allocated by reserve_explicit_locations() so182* that we can keep track of unused uniforms with explicit locations.183*/184assert(!prog->data->spirv ||185(prog->data->spirv && !prog->UniformRemapTable));186if (!prog->UniformRemapTable) {187prog->UniformRemapTable = rzalloc_array(prog,188struct gl_uniform_storage *,189prog->NumUniformRemapTable);190}191192union gl_constant_value *data =193rzalloc_array(prog->data,194union gl_constant_value, prog->data->NumUniformDataSlots);195if (!prog->UniformRemapTable || !data) {196linker_error(prog, "Out of memory during linking.\n");197return;198}199prog->data->UniformDataSlots = data;200201prog->data->UniformDataDefaults =202rzalloc_array(prog->data->UniformDataSlots,203union gl_constant_value, prog->data->NumUniformDataSlots);204205unsigned data_pos = 0;206207/* Reserve all the explicit locations of the active uniforms. */208for (unsigned i = 0; i < prog->data->NumUniformStorage; i++) {209struct gl_uniform_storage *uniform = &prog->data->UniformStorage[i];210211if (uniform->is_shader_storage ||212glsl_get_base_type(uniform->type) == GLSL_TYPE_SUBROUTINE)213continue;214215if (prog->data->UniformStorage[i].remap_location == UNMAPPED_UNIFORM_LOC)216continue;217218/* How many new entries for this uniform? */219const unsigned entries = MAX2(1, uniform->array_elements);220unsigned num_slots = glsl_get_component_slots(uniform->type);221222uniform->storage = &data[data_pos];223224/* Set remap table entries point to correct gl_uniform_storage. */225for (unsigned j = 0; j < entries; j++) {226unsigned element_loc = uniform->remap_location + j;227prog->UniformRemapTable[element_loc] = uniform;228229data_pos += num_slots;230}231}232233/* Reserve locations for rest of the uniforms. */234if (prog->data->spirv)235link_util_update_empty_uniform_locations(prog);236237for (unsigned i = 0; i < prog->data->NumUniformStorage; i++) {238struct gl_uniform_storage *uniform = &prog->data->UniformStorage[i];239240if (uniform->is_shader_storage ||241glsl_get_base_type(uniform->type) == GLSL_TYPE_SUBROUTINE)242continue;243244/* Built-in uniforms should not get any location. */245if (uniform->builtin)246continue;247248/* Explicit ones have been set already. */249if (uniform->remap_location != UNMAPPED_UNIFORM_LOC)250continue;251252/* How many entries for this uniform? */253const unsigned entries = MAX2(1, uniform->array_elements);254255/* Add new entries to the total amount for checking against MAX_UNIFORM-256* _LOCATIONS. This only applies to the default uniform block (-1),257* because locations of uniform block entries are not assignable.258*/259if (prog->data->UniformStorage[i].block_index == -1)260total_entries += entries;261262unsigned location =263link_util_find_empty_block(prog, &prog->data->UniformStorage[i]);264265if (location == -1) {266location = prog->NumUniformRemapTable;267268/* resize remap table to fit new entries */269prog->UniformRemapTable =270reralloc(prog,271prog->UniformRemapTable,272struct gl_uniform_storage *,273prog->NumUniformRemapTable + entries);274prog->NumUniformRemapTable += entries;275}276277/* set the base location in remap table for the uniform */278uniform->remap_location = location;279280unsigned num_slots = glsl_get_component_slots(uniform->type);281282if (uniform->block_index == -1)283uniform->storage = &data[data_pos];284285/* Set remap table entries point to correct gl_uniform_storage. */286for (unsigned j = 0; j < entries; j++) {287unsigned element_loc = uniform->remap_location + j;288prog->UniformRemapTable[element_loc] = uniform;289290if (uniform->block_index == -1)291data_pos += num_slots;292}293}294295/* Verify that total amount of entries for explicit and implicit locations296* is less than MAX_UNIFORM_LOCATIONS.297*/298if (total_entries > ctx->Const.MaxUserAssignableUniformLocations) {299linker_error(prog, "count of uniform locations > MAX_UNIFORM_LOCATIONS"300"(%u > %u)", total_entries,301ctx->Const.MaxUserAssignableUniformLocations);302}303304/* Reserve all the explicit locations of the active subroutine uniforms. */305for (unsigned i = 0; i < prog->data->NumUniformStorage; i++) {306struct gl_uniform_storage *uniform = &prog->data->UniformStorage[i];307308if (glsl_get_base_type(uniform->type) != GLSL_TYPE_SUBROUTINE)309continue;310311if (prog->data->UniformStorage[i].remap_location == UNMAPPED_UNIFORM_LOC)312continue;313314/* How many new entries for this uniform? */315const unsigned entries =316MAX2(1, prog->data->UniformStorage[i].array_elements);317318uniform->storage = &data[data_pos];319320unsigned num_slots = glsl_get_component_slots(uniform->type);321unsigned mask = prog->data->linked_stages;322while (mask) {323const int j = u_bit_scan(&mask);324struct gl_program *p = prog->_LinkedShaders[j]->Program;325326if (!prog->data->UniformStorage[i].opaque[j].active)327continue;328329/* Set remap table entries point to correct gl_uniform_storage. */330for (unsigned k = 0; k < entries; k++) {331unsigned element_loc =332prog->data->UniformStorage[i].remap_location + k;333p->sh.SubroutineUniformRemapTable[element_loc] =334&prog->data->UniformStorage[i];335336data_pos += num_slots;337}338}339}340341/* reserve subroutine locations */342for (unsigned i = 0; i < prog->data->NumUniformStorage; i++) {343struct gl_uniform_storage *uniform = &prog->data->UniformStorage[i];344345if (glsl_get_base_type(uniform->type) != GLSL_TYPE_SUBROUTINE)346continue;347348if (prog->data->UniformStorage[i].remap_location !=349UNMAPPED_UNIFORM_LOC)350continue;351352const unsigned entries =353MAX2(1, prog->data->UniformStorage[i].array_elements);354355uniform->storage = &data[data_pos];356357unsigned num_slots = glsl_get_component_slots(uniform->type);358unsigned mask = prog->data->linked_stages;359while (mask) {360const int j = u_bit_scan(&mask);361struct gl_program *p = prog->_LinkedShaders[j]->Program;362363if (!prog->data->UniformStorage[i].opaque[j].active)364continue;365366p->sh.SubroutineUniformRemapTable =367reralloc(p,368p->sh.SubroutineUniformRemapTable,369struct gl_uniform_storage *,370p->sh.NumSubroutineUniformRemapTable + entries);371372for (unsigned k = 0; k < entries; k++) {373p->sh.SubroutineUniformRemapTable[p->sh.NumSubroutineUniformRemapTable + k] =374&prog->data->UniformStorage[i];375376data_pos += num_slots;377}378prog->data->UniformStorage[i].remap_location =379p->sh.NumSubroutineUniformRemapTable;380p->sh.NumSubroutineUniformRemapTable += entries;381}382}383}384385static void386add_var_use_deref(nir_deref_instr *deref, struct hash_table *live,387struct array_deref_range **derefs, unsigned *derefs_size)388{389nir_deref_path path;390nir_deref_path_init(&path, deref, NULL);391392deref = path.path[0];393if (deref->deref_type != nir_deref_type_var ||394!nir_deref_mode_is_one_of(deref, nir_var_uniform |395nir_var_mem_ubo |396nir_var_mem_ssbo)) {397nir_deref_path_finish(&path);398return;399}400401/* Number of derefs used in current processing. */402unsigned num_derefs = 0;403404const struct glsl_type *deref_type = deref->var->type;405nir_deref_instr **p = &path.path[1];406for (; *p; p++) {407if ((*p)->deref_type == nir_deref_type_array) {408409/* Skip matrix derefences */410if (!glsl_type_is_array(deref_type))411break;412413if ((num_derefs + 1) * sizeof(struct array_deref_range) > *derefs_size) {414void *ptr = reralloc_size(NULL, *derefs, *derefs_size + 4096);415416if (ptr == NULL) {417nir_deref_path_finish(&path);418return;419}420421*derefs_size += 4096;422*derefs = (struct array_deref_range *)ptr;423}424425struct array_deref_range *dr = &(*derefs)[num_derefs];426num_derefs++;427428dr->size = glsl_get_length(deref_type);429430if (nir_src_is_const((*p)->arr.index)) {431dr->index = nir_src_as_uint((*p)->arr.index);432} else {433/* An unsized array can occur at the end of an SSBO. We can't track434* accesses to such an array, so bail.435*/436if (dr->size == 0) {437nir_deref_path_finish(&path);438return;439}440441dr->index = dr->size;442}443444deref_type = glsl_get_array_element(deref_type);445} else if ((*p)->deref_type == nir_deref_type_struct) {446/* We have reached the end of the array. */447break;448}449}450451nir_deref_path_finish(&path);452453454struct uniform_array_info *ainfo = NULL;455456struct hash_entry *entry =457_mesa_hash_table_search(live, deref->var->name);458if (!entry && glsl_type_is_array(deref->var->type)) {459ainfo = ralloc(live, struct uniform_array_info);460461unsigned num_bits = MAX2(1, glsl_get_aoa_size(deref->var->type));462ainfo->indices = rzalloc_array(live, BITSET_WORD, BITSET_WORDS(num_bits));463464ainfo->deref_list = ralloc(live, struct util_dynarray);465util_dynarray_init(ainfo->deref_list, live);466}467468if (entry)469ainfo = (struct uniform_array_info *) entry->data;470471if (glsl_type_is_array(deref->var->type)) {472/* Count the "depth" of the arrays-of-arrays. */473unsigned array_depth = 0;474for (const struct glsl_type *type = deref->var->type;475glsl_type_is_array(type);476type = glsl_get_array_element(type)) {477array_depth++;478}479480link_util_mark_array_elements_referenced(*derefs, num_derefs, array_depth,481ainfo->indices);482483util_dynarray_append(ainfo->deref_list, nir_deref_instr *, deref);484}485486assert(deref->modes == deref->var->data.mode);487_mesa_hash_table_insert(live, deref->var->name, ainfo);488}489490/* Iterate over the shader and collect infomation about uniform use */491static void492add_var_use_shader(nir_shader *shader, struct hash_table *live)493{494/* Currently allocated buffer block of derefs. */495struct array_deref_range *derefs = NULL;496497/* Size of the derefs buffer in bytes. */498unsigned derefs_size = 0;499500nir_foreach_function(function, shader) {501if (function->impl) {502nir_foreach_block(block, function->impl) {503nir_foreach_instr(instr, block) {504if (instr->type == nir_instr_type_intrinsic) {505nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);506switch (intr->intrinsic) {507case nir_intrinsic_atomic_counter_read_deref:508case nir_intrinsic_atomic_counter_inc_deref:509case nir_intrinsic_atomic_counter_pre_dec_deref:510case nir_intrinsic_atomic_counter_post_dec_deref:511case nir_intrinsic_atomic_counter_add_deref:512case nir_intrinsic_atomic_counter_min_deref:513case nir_intrinsic_atomic_counter_max_deref:514case nir_intrinsic_atomic_counter_and_deref:515case nir_intrinsic_atomic_counter_or_deref:516case nir_intrinsic_atomic_counter_xor_deref:517case nir_intrinsic_atomic_counter_exchange_deref:518case nir_intrinsic_atomic_counter_comp_swap_deref:519case nir_intrinsic_image_deref_load:520case nir_intrinsic_image_deref_store:521case nir_intrinsic_image_deref_atomic_add:522case nir_intrinsic_image_deref_atomic_umin:523case nir_intrinsic_image_deref_atomic_imin:524case nir_intrinsic_image_deref_atomic_umax:525case nir_intrinsic_image_deref_atomic_imax:526case nir_intrinsic_image_deref_atomic_and:527case nir_intrinsic_image_deref_atomic_or:528case nir_intrinsic_image_deref_atomic_xor:529case nir_intrinsic_image_deref_atomic_exchange:530case nir_intrinsic_image_deref_atomic_comp_swap:531case nir_intrinsic_image_deref_size:532case nir_intrinsic_image_deref_samples:533case nir_intrinsic_load_deref:534case nir_intrinsic_store_deref:535add_var_use_deref(nir_src_as_deref(intr->src[0]), live,536&derefs, &derefs_size);537break;538539default:540/* Nothing to do */541break;542}543} else if (instr->type == nir_instr_type_tex) {544nir_tex_instr *tex_instr = nir_instr_as_tex(instr);545int sampler_idx =546nir_tex_instr_src_index(tex_instr,547nir_tex_src_sampler_deref);548int texture_idx =549nir_tex_instr_src_index(tex_instr,550nir_tex_src_texture_deref);551552if (sampler_idx >= 0) {553nir_deref_instr *deref =554nir_src_as_deref(tex_instr->src[sampler_idx].src);555add_var_use_deref(deref, live, &derefs, &derefs_size);556}557558if (texture_idx >= 0) {559nir_deref_instr *deref =560nir_src_as_deref(tex_instr->src[texture_idx].src);561add_var_use_deref(deref, live, &derefs, &derefs_size);562}563}564}565}566}567}568569ralloc_free(derefs);570}571572static void573mark_stage_as_active(struct gl_uniform_storage *uniform,574unsigned stage)575{576uniform->active_shader_mask |= 1 << stage;577}578579/* Used to build a tree representing the glsl_type so that we can have a place580* to store the next index for opaque types. Array types are expanded so that581* they have a single child which is used for all elements of the array.582* Struct types have a child for each member. The tree is walked while583* processing a uniform so that we can recognise when an opaque type is584* encountered a second time in order to reuse the same range of indices that585* was reserved the first time. That way the sampler indices can be arranged586* so that members of an array are placed sequentially even if the array is an587* array of structs containing other opaque members.588*/589struct type_tree_entry {590/* For opaque types, this will be the next index to use. If we haven’t591* encountered this member yet, it will be UINT_MAX.592*/593unsigned next_index;594unsigned array_size;595struct type_tree_entry *parent;596struct type_tree_entry *next_sibling;597struct type_tree_entry *children;598};599600struct nir_link_uniforms_state {601/* per-whole program */602unsigned num_hidden_uniforms;603unsigned num_values;604unsigned max_uniform_location;605606/* per-shader stage */607unsigned next_bindless_image_index;608unsigned next_bindless_sampler_index;609unsigned next_image_index;610unsigned next_sampler_index;611unsigned next_subroutine;612unsigned num_shader_samplers;613unsigned num_shader_images;614unsigned num_shader_uniform_components;615unsigned shader_samplers_used;616unsigned shader_shadow_samplers;617unsigned shader_storage_blocks_write_access;618struct gl_program_parameter_list *params;619620/* per-variable */621nir_variable *current_var;622const struct glsl_type *current_ifc_type;623int offset;624bool var_is_in_block;625bool set_top_level_array;626int top_level_array_size;627int top_level_array_stride;628629struct type_tree_entry *current_type;630struct hash_table *referenced_uniforms[MESA_SHADER_STAGES];631struct hash_table *uniform_hash;632};633634static void635add_parameter(struct gl_uniform_storage *uniform,636struct gl_context *ctx,637struct gl_shader_program *prog,638const struct glsl_type *type,639struct nir_link_uniforms_state *state)640{641/* Builtin uniforms are backed by PROGRAM_STATE_VAR, so don't add them as642* uniforms.643*/644if (uniform->builtin)645return;646647if (!state->params || uniform->is_shader_storage ||648(glsl_contains_opaque(type) && !state->current_var->data.bindless))649return;650651unsigned num_params = glsl_get_aoa_size(type);652num_params = MAX2(num_params, 1);653num_params *= glsl_get_matrix_columns(glsl_without_array(type));654655bool is_dual_slot = glsl_type_is_dual_slot(glsl_without_array(type));656if (is_dual_slot)657num_params *= 2;658659struct gl_program_parameter_list *params = state->params;660int base_index = params->NumParameters;661_mesa_reserve_parameter_storage(params, num_params, num_params);662663if (ctx->Const.PackedDriverUniformStorage) {664for (unsigned i = 0; i < num_params; i++) {665unsigned dmul = glsl_type_is_64bit(glsl_without_array(type)) ? 2 : 1;666unsigned comps = glsl_get_vector_elements(glsl_without_array(type)) * dmul;667if (is_dual_slot) {668if (i & 0x1)669comps -= 4;670else671comps = 4;672}673674/* TODO: This will waste space with 1 and 3 16-bit components. */675if (glsl_type_is_16bit(glsl_without_array(type)))676comps = DIV_ROUND_UP(comps, 2);677678_mesa_add_parameter(params, PROGRAM_UNIFORM, uniform->name, comps,679glsl_get_gl_type(type), NULL, NULL, false);680}681} else {682for (unsigned i = 0; i < num_params; i++) {683_mesa_add_parameter(params, PROGRAM_UNIFORM, uniform->name, 4,684glsl_get_gl_type(type), NULL, NULL, true);685}686}687688/* Each Parameter will hold the index to the backing uniform storage.689* This avoids relying on names to match parameters and uniform690* storages.691*/692for (unsigned i = 0; i < num_params; i++) {693struct gl_program_parameter *param = ¶ms->Parameters[base_index + i];694param->UniformStorageIndex = uniform - prog->data->UniformStorage;695param->MainUniformStorageIndex = state->current_var->data.location;696}697}698699static unsigned700get_next_index(struct nir_link_uniforms_state *state,701const struct gl_uniform_storage *uniform,702unsigned *next_index, bool *initialised)703{704/* If we’ve already calculated an index for this member then we can just705* offset from there.706*/707if (state->current_type->next_index == UINT_MAX) {708/* Otherwise we need to reserve enough indices for all of the arrays709* enclosing this member.710*/711712unsigned array_size = 1;713714for (const struct type_tree_entry *p = state->current_type;715p;716p = p->parent) {717array_size *= p->array_size;718}719720state->current_type->next_index = *next_index;721*next_index += array_size;722*initialised = true;723} else724*initialised = false;725726unsigned index = state->current_type->next_index;727728state->current_type->next_index += MAX2(1, uniform->array_elements);729730return index;731}732733/* Update the uniforms info for the current shader stage */734static void735update_uniforms_shader_info(struct gl_shader_program *prog,736struct nir_link_uniforms_state *state,737struct gl_uniform_storage *uniform,738const struct glsl_type *type,739unsigned stage)740{741unsigned values = glsl_get_component_slots(type);742const struct glsl_type *type_no_array = glsl_without_array(type);743744if (glsl_type_is_sampler(type_no_array)) {745bool init_idx;746unsigned *next_index = state->current_var->data.bindless ?747&state->next_bindless_sampler_index :748&state->next_sampler_index;749int sampler_index = get_next_index(state, uniform, next_index, &init_idx);750struct gl_linked_shader *sh = prog->_LinkedShaders[stage];751752if (state->current_var->data.bindless) {753if (init_idx) {754sh->Program->sh.BindlessSamplers =755rerzalloc(sh->Program, sh->Program->sh.BindlessSamplers,756struct gl_bindless_sampler,757sh->Program->sh.NumBindlessSamplers,758state->next_bindless_sampler_index);759760for (unsigned j = sh->Program->sh.NumBindlessSamplers;761j < state->next_bindless_sampler_index; j++) {762sh->Program->sh.BindlessSamplers[j].target =763glsl_get_sampler_target(type_no_array);764}765766sh->Program->sh.NumBindlessSamplers =767state->next_bindless_sampler_index;768}769770if (!state->var_is_in_block)771state->num_shader_uniform_components += values;772} else {773/* Samplers (bound or bindless) are counted as two components774* as specified by ARB_bindless_texture.775*/776state->num_shader_samplers += values / 2;777778if (init_idx) {779const unsigned shadow = glsl_sampler_type_is_shadow(type_no_array);780for (unsigned i = sampler_index;781i < MIN2(state->next_sampler_index, MAX_SAMPLERS); i++) {782sh->Program->sh.SamplerTargets[i] =783glsl_get_sampler_target(type_no_array);784state->shader_samplers_used |= 1U << i;785state->shader_shadow_samplers |= shadow << i;786}787}788}789790uniform->opaque[stage].active = true;791uniform->opaque[stage].index = sampler_index;792} else if (glsl_type_is_image(type_no_array)) {793struct gl_linked_shader *sh = prog->_LinkedShaders[stage];794795/* Set image access qualifiers */796enum gl_access_qualifier image_access =797state->current_var->data.access;798const GLenum access =799(image_access & ACCESS_NON_WRITEABLE) ?800((image_access & ACCESS_NON_READABLE) ? GL_NONE :801GL_READ_ONLY) :802((image_access & ACCESS_NON_READABLE) ? GL_WRITE_ONLY :803GL_READ_WRITE);804805int image_index;806if (state->current_var->data.bindless) {807image_index = state->next_bindless_image_index;808state->next_bindless_image_index += MAX2(1, uniform->array_elements);809810sh->Program->sh.BindlessImages =811rerzalloc(sh->Program, sh->Program->sh.BindlessImages,812struct gl_bindless_image,813sh->Program->sh.NumBindlessImages,814state->next_bindless_image_index);815816for (unsigned j = sh->Program->sh.NumBindlessImages;817j < state->next_bindless_image_index; j++) {818sh->Program->sh.BindlessImages[j].access = access;819}820821sh->Program->sh.NumBindlessImages = state->next_bindless_image_index;822823} else {824image_index = state->next_image_index;825state->next_image_index += MAX2(1, uniform->array_elements);826827/* Images (bound or bindless) are counted as two components as828* specified by ARB_bindless_texture.829*/830state->num_shader_images += values / 2;831832for (unsigned i = image_index;833i < MIN2(state->next_image_index, MAX_IMAGE_UNIFORMS); i++) {834sh->Program->sh.ImageAccess[i] = access;835}836}837838uniform->opaque[stage].active = true;839uniform->opaque[stage].index = image_index;840841if (!uniform->is_shader_storage)842state->num_shader_uniform_components += values;843} else {844if (glsl_get_base_type(type_no_array) == GLSL_TYPE_SUBROUTINE) {845struct gl_linked_shader *sh = prog->_LinkedShaders[stage];846847uniform->opaque[stage].index = state->next_subroutine;848uniform->opaque[stage].active = true;849850sh->Program->sh.NumSubroutineUniforms++;851852/* Increment the subroutine index by 1 for non-arrays and by the853* number of array elements for arrays.854*/855state->next_subroutine += MAX2(1, uniform->array_elements);856}857858if (!state->var_is_in_block)859state->num_shader_uniform_components += values;860}861}862863static bool864find_and_update_named_uniform_storage(struct gl_context *ctx,865struct gl_shader_program *prog,866struct nir_link_uniforms_state *state,867nir_variable *var, char **name,868size_t name_length,869const struct glsl_type *type,870unsigned stage, bool *first_element)871{872/* gl_uniform_storage can cope with one level of array, so if the type is a873* composite type or an array where each element occupies more than one874* location than we need to recursively process it.875*/876if (glsl_type_is_struct_or_ifc(type) ||877(glsl_type_is_array(type) &&878(glsl_type_is_array(glsl_get_array_element(type)) ||879glsl_type_is_struct_or_ifc(glsl_get_array_element(type))))) {880881struct type_tree_entry *old_type = state->current_type;882state->current_type = old_type->children;883884/* Shader storage block unsized arrays: add subscript [0] to variable885* names.886*/887unsigned length = glsl_get_length(type);888if (glsl_type_is_unsized_array(type))889length = 1;890891bool result = false;892for (unsigned i = 0; i < length; i++) {893const struct glsl_type *field_type;894size_t new_length = name_length;895896if (glsl_type_is_struct_or_ifc(type)) {897field_type = glsl_get_struct_field(type, i);898899/* Append '.field' to the current variable name. */900if (name) {901ralloc_asprintf_rewrite_tail(name, &new_length, ".%s",902glsl_get_struct_elem_name(type, i));903}904} else {905field_type = glsl_get_array_element(type);906907/* Append the subscript to the current variable name */908if (name)909ralloc_asprintf_rewrite_tail(name, &new_length, "[%u]", i);910}911912result = find_and_update_named_uniform_storage(ctx, prog, state,913var, name, new_length,914field_type, stage,915first_element);916917if (glsl_type_is_struct_or_ifc(type))918state->current_type = state->current_type->next_sibling;919920if (!result) {921state->current_type = old_type;922return false;923}924}925926state->current_type = old_type;927928return result;929} else {930struct hash_entry *entry =931_mesa_hash_table_search(state->uniform_hash, *name);932if (entry) {933unsigned i = (unsigned) (intptr_t) entry->data;934struct gl_uniform_storage *uniform = &prog->data->UniformStorage[i];935936if (*first_element && !state->var_is_in_block) {937*first_element = false;938var->data.location = uniform - prog->data->UniformStorage;939}940941update_uniforms_shader_info(prog, state, uniform, type, stage);942943const struct glsl_type *type_no_array = glsl_without_array(type);944struct hash_entry *entry = prog->data->spirv ? NULL :945_mesa_hash_table_search(state->referenced_uniforms[stage],946state->current_var->name);947if (entry != NULL ||948glsl_get_base_type(type_no_array) == GLSL_TYPE_SUBROUTINE ||949prog->data->spirv)950uniform->active_shader_mask |= 1 << stage;951952if (!state->var_is_in_block)953add_parameter(uniform, ctx, prog, type, state);954955return true;956}957}958959return false;960}961962/**963* Finds, returns, and updates the stage info for any uniform in UniformStorage964* defined by @var. For GLSL this is done using the name, for SPIR-V in general965* is this done using the explicit location, except:966*967* * UBOs/SSBOs: as they lack explicit location, binding is used to locate968* them. That means that more that one entry at the uniform storage can be969* found. In that case all of them are updated, and the first entry is970* returned, in order to update the location of the nir variable.971*972* * Special uniforms: like atomic counters. They lack a explicit location,973* so they are skipped. They will be handled and assigned a location later.974*975*/976static bool977find_and_update_previous_uniform_storage(struct gl_context *ctx,978struct gl_shader_program *prog,979struct nir_link_uniforms_state *state,980nir_variable *var, char *name,981const struct glsl_type *type,982unsigned stage)983{984if (!prog->data->spirv) {985bool first_element = true;986char *name_tmp = ralloc_strdup(NULL, name);987bool r = find_and_update_named_uniform_storage(ctx, prog, state, var,988&name_tmp,989strlen(name_tmp), type,990stage, &first_element);991ralloc_free(name_tmp);992993return r;994}995996if (nir_variable_is_in_block(var)) {997struct gl_uniform_storage *uniform = NULL;998999ASSERTED unsigned num_blks = nir_variable_is_in_ubo(var) ?1000prog->data->NumUniformBlocks :1001prog->data->NumShaderStorageBlocks;10021003struct gl_uniform_block *blks = nir_variable_is_in_ubo(var) ?1004prog->data->UniformBlocks : prog->data->ShaderStorageBlocks;10051006bool result = false;1007for (unsigned i = 0; i < prog->data->NumUniformStorage; i++) {1008/* UniformStorage contains both variables from ubos and ssbos */1009if ( prog->data->UniformStorage[i].is_shader_storage !=1010nir_variable_is_in_ssbo(var))1011continue;10121013int block_index = prog->data->UniformStorage[i].block_index;1014if (block_index != -1) {1015assert(block_index < num_blks);10161017if (var->data.binding == blks[block_index].Binding) {1018if (!uniform)1019uniform = &prog->data->UniformStorage[i];1020mark_stage_as_active(&prog->data->UniformStorage[i],1021stage);1022result = true;1023}1024}1025}10261027if (result)1028var->data.location = uniform - prog->data->UniformStorage;1029return result;1030}10311032/* Beyond blocks, there are still some corner cases of uniforms without1033* location (ie: atomic counters) that would have a initial location equal1034* to -1. We just return on that case. Those uniforms will be handled1035* later.1036*/1037if (var->data.location == -1)1038return false;10391040/* TODO: following search can be problematic with shaders with a lot of1041* uniforms. Would it be better to use some type of hash1042*/1043for (unsigned i = 0; i < prog->data->NumUniformStorage; i++) {1044if (prog->data->UniformStorage[i].remap_location == var->data.location) {1045mark_stage_as_active(&prog->data->UniformStorage[i], stage);10461047struct gl_uniform_storage *uniform = &prog->data->UniformStorage[i];1048var->data.location = uniform - prog->data->UniformStorage;1049add_parameter(uniform, ctx, prog, var->type, state);1050return true;1051}1052}10531054return false;1055}10561057static struct type_tree_entry *1058build_type_tree_for_type(const struct glsl_type *type)1059{1060struct type_tree_entry *entry = malloc(sizeof *entry);10611062entry->array_size = 1;1063entry->next_index = UINT_MAX;1064entry->children = NULL;1065entry->next_sibling = NULL;1066entry->parent = NULL;10671068if (glsl_type_is_array(type)) {1069entry->array_size = glsl_get_length(type);1070entry->children = build_type_tree_for_type(glsl_get_array_element(type));1071entry->children->parent = entry;1072} else if (glsl_type_is_struct_or_ifc(type)) {1073struct type_tree_entry *last = NULL;10741075for (unsigned i = 0; i < glsl_get_length(type); i++) {1076const struct glsl_type *field_type = glsl_get_struct_field(type, i);1077struct type_tree_entry *field_entry =1078build_type_tree_for_type(field_type);10791080if (last == NULL)1081entry->children = field_entry;1082else1083last->next_sibling = field_entry;10841085field_entry->parent = entry;10861087last = field_entry;1088}1089}10901091return entry;1092}10931094static void1095free_type_tree(struct type_tree_entry *entry)1096{1097struct type_tree_entry *p, *next;10981099for (p = entry->children; p; p = next) {1100next = p->next_sibling;1101free_type_tree(p);1102}11031104free(entry);1105}11061107static void1108hash_free_uniform_name(struct hash_entry *entry)1109{1110free((void*)entry->key);1111}11121113static void1114enter_record(struct nir_link_uniforms_state *state,1115struct gl_context *ctx,1116const struct glsl_type *type,1117bool row_major)1118{1119assert(glsl_type_is_struct(type));1120if (!state->var_is_in_block)1121return;11221123bool use_std430 = ctx->Const.UseSTD430AsDefaultPacking;1124const enum glsl_interface_packing packing =1125glsl_get_internal_ifc_packing(state->current_var->interface_type,1126use_std430);11271128if (packing == GLSL_INTERFACE_PACKING_STD430)1129state->offset = glsl_align(1130state->offset, glsl_get_std430_base_alignment(type, row_major));1131else1132state->offset = glsl_align(1133state->offset, glsl_get_std140_base_alignment(type, row_major));1134}11351136static void1137leave_record(struct nir_link_uniforms_state *state,1138struct gl_context *ctx,1139const struct glsl_type *type,1140bool row_major)1141{1142assert(glsl_type_is_struct(type));1143if (!state->var_is_in_block)1144return;11451146bool use_std430 = ctx->Const.UseSTD430AsDefaultPacking;1147const enum glsl_interface_packing packing =1148glsl_get_internal_ifc_packing(state->current_var->interface_type,1149use_std430);11501151if (packing == GLSL_INTERFACE_PACKING_STD430)1152state->offset = glsl_align(1153state->offset, glsl_get_std430_base_alignment(type, row_major));1154else1155state->offset = glsl_align(1156state->offset, glsl_get_std140_base_alignment(type, row_major));1157}11581159/**1160* Creates the neccessary entries in UniformStorage for the uniform. Returns1161* the number of locations used or -1 on failure.1162*/1163static int1164nir_link_uniform(struct gl_context *ctx,1165struct gl_shader_program *prog,1166struct gl_program *stage_program,1167gl_shader_stage stage,1168const struct glsl_type *type,1169unsigned index_in_parent,1170int location,1171struct nir_link_uniforms_state *state,1172char **name, size_t name_length, bool row_major)1173{1174struct gl_uniform_storage *uniform = NULL;11751176if (state->set_top_level_array &&1177nir_variable_is_in_ssbo(state->current_var)) {1178/* Type is the top level SSBO member */1179if (glsl_type_is_array(type) &&1180(glsl_type_is_array(glsl_get_array_element(type)) ||1181glsl_type_is_struct_or_ifc(glsl_get_array_element(type)))) {1182/* Type is a top-level array (array of aggregate types) */1183state->top_level_array_size = glsl_get_length(type);1184state->top_level_array_stride = glsl_get_explicit_stride(type);1185} else {1186state->top_level_array_size = 1;1187state->top_level_array_stride = 0;1188}11891190state->set_top_level_array = false;1191}11921193/* gl_uniform_storage can cope with one level of array, so if the type is a1194* composite type or an array where each element occupies more than one1195* location than we need to recursively process it.1196*/1197if (glsl_type_is_struct_or_ifc(type) ||1198(glsl_type_is_array(type) &&1199(glsl_type_is_array(glsl_get_array_element(type)) ||1200glsl_type_is_struct_or_ifc(glsl_get_array_element(type))))) {1201int location_count = 0;1202struct type_tree_entry *old_type = state->current_type;1203unsigned int struct_base_offset = state->offset;12041205state->current_type = old_type->children;12061207/* Shader storage block unsized arrays: add subscript [0] to variable1208* names.1209*/1210unsigned length = glsl_get_length(type);1211if (glsl_type_is_unsized_array(type))1212length = 1;12131214if (glsl_type_is_struct(type) && !prog->data->spirv)1215enter_record(state, ctx, type, row_major);12161217for (unsigned i = 0; i < length; i++) {1218const struct glsl_type *field_type;1219size_t new_length = name_length;1220bool field_row_major = row_major;12211222if (glsl_type_is_struct_or_ifc(type)) {1223field_type = glsl_get_struct_field(type, i);1224/* Use the offset inside the struct only for variables backed by1225* a buffer object. For variables not backed by a buffer object,1226* offset is -1.1227*/1228if (state->var_is_in_block) {1229if (prog->data->spirv) {1230state->offset =1231struct_base_offset + glsl_get_struct_field_offset(type, i);1232} else if (glsl_get_struct_field_offset(type, i) != -1 &&1233type == state->current_ifc_type) {1234state->offset = glsl_get_struct_field_offset(type, i);1235}12361237if (glsl_type_is_interface(type))1238state->set_top_level_array = true;1239}12401241/* Append '.field' to the current variable name. */1242if (name) {1243ralloc_asprintf_rewrite_tail(name, &new_length, ".%s",1244glsl_get_struct_elem_name(type, i));1245}124612471248/* The layout of structures at the top level of the block is set1249* during parsing. For matrices contained in multiple levels of1250* structures in the block, the inner structures have no layout.1251* These cases must potentially inherit the layout from the outer1252* levels.1253*/1254const enum glsl_matrix_layout matrix_layout =1255glsl_get_struct_field_data(type, i)->matrix_layout;1256if (matrix_layout == GLSL_MATRIX_LAYOUT_ROW_MAJOR) {1257field_row_major = true;1258} else if (matrix_layout == GLSL_MATRIX_LAYOUT_COLUMN_MAJOR) {1259field_row_major = false;1260}1261} else {1262field_type = glsl_get_array_element(type);12631264/* Append the subscript to the current variable name */1265if (name)1266ralloc_asprintf_rewrite_tail(name, &new_length, "[%u]", i);1267}12681269int entries = nir_link_uniform(ctx, prog, stage_program, stage,1270field_type, i, location,1271state, name, new_length,1272field_row_major);12731274if (entries == -1)1275return -1;12761277if (location != -1)1278location += entries;1279location_count += entries;12801281if (glsl_type_is_struct_or_ifc(type))1282state->current_type = state->current_type->next_sibling;1283}12841285if (glsl_type_is_struct(type) && !prog->data->spirv)1286leave_record(state, ctx, type, row_major);12871288state->current_type = old_type;12891290return location_count;1291} else {1292/* TODO: reallocating storage is slow, we should figure out a way to1293* allocate storage up front for spirv like we do for GLSL.1294*/1295if (prog->data->spirv) {1296/* Create a new uniform storage entry */1297prog->data->UniformStorage =1298reralloc(prog->data,1299prog->data->UniformStorage,1300struct gl_uniform_storage,1301prog->data->NumUniformStorage + 1);1302if (!prog->data->UniformStorage) {1303linker_error(prog, "Out of memory during linking.\n");1304return -1;1305}1306}13071308uniform = &prog->data->UniformStorage[prog->data->NumUniformStorage];1309prog->data->NumUniformStorage++;13101311/* Initialize its members */1312memset(uniform, 0x00, sizeof(struct gl_uniform_storage));13131314uniform->name =1315name ? ralloc_strdup(prog->data->UniformStorage, *name) : NULL;13161317const struct glsl_type *type_no_array = glsl_without_array(type);1318if (glsl_type_is_array(type)) {1319uniform->type = type_no_array;1320uniform->array_elements = glsl_get_length(type);1321} else {1322uniform->type = type;1323uniform->array_elements = 0;1324}1325uniform->top_level_array_size = state->top_level_array_size;1326uniform->top_level_array_stride = state->top_level_array_stride;13271328struct hash_entry *entry = prog->data->spirv ? NULL :1329_mesa_hash_table_search(state->referenced_uniforms[stage],1330state->current_var->name);1331if (entry != NULL ||1332glsl_get_base_type(type_no_array) == GLSL_TYPE_SUBROUTINE ||1333prog->data->spirv)1334uniform->active_shader_mask |= 1 << stage;13351336if (location >= 0) {1337/* Uniform has an explicit location */1338uniform->remap_location = location;1339} else {1340uniform->remap_location = UNMAPPED_UNIFORM_LOC;1341}13421343uniform->hidden = state->current_var->data.how_declared == nir_var_hidden;1344if (uniform->hidden)1345state->num_hidden_uniforms++;13461347uniform->is_shader_storage = nir_variable_is_in_ssbo(state->current_var);1348uniform->is_bindless = state->current_var->data.bindless;13491350/* Set fields whose default value depend on the variable being inside a1351* block.1352*1353* From the OpenGL 4.6 spec, 7.3 Program objects:1354*1355* "For the property ARRAY_STRIDE, ... For active variables not declared1356* as an array of basic types, zero is written to params. For active1357* variables not backed by a buffer object, -1 is written to params,1358* regardless of the variable type."1359*1360* "For the property MATRIX_STRIDE, ... For active variables not declared1361* as a matrix or array of matrices, zero is written to params. For active1362* variables not backed by a buffer object, -1 is written to params,1363* regardless of the variable type."1364*1365* For the property IS_ROW_MAJOR, ... For active variables backed by a1366* buffer object, declared as a single matrix or array of matrices, and1367* stored in row-major order, one is written to params. For all other1368* active variables, zero is written to params.1369*/1370uniform->array_stride = -1;1371uniform->matrix_stride = -1;1372uniform->row_major = false;13731374if (state->var_is_in_block) {1375uniform->array_stride = glsl_type_is_array(type) ?1376glsl_get_explicit_stride(type) : 0;13771378if (glsl_type_is_matrix(uniform->type)) {1379uniform->matrix_stride = glsl_get_explicit_stride(uniform->type);1380uniform->row_major = glsl_matrix_type_is_row_major(uniform->type);1381} else {1382uniform->matrix_stride = 0;1383}13841385if (!prog->data->spirv) {1386bool use_std430 = ctx->Const.UseSTD430AsDefaultPacking;1387const enum glsl_interface_packing packing =1388glsl_get_internal_ifc_packing(state->current_var->interface_type,1389use_std430);13901391unsigned alignment =1392glsl_get_std140_base_alignment(type, uniform->row_major);1393if (packing == GLSL_INTERFACE_PACKING_STD430) {1394alignment =1395glsl_get_std430_base_alignment(type, uniform->row_major);1396}1397state->offset = glsl_align(state->offset, alignment);1398}1399}14001401uniform->offset = state->var_is_in_block ? state->offset : -1;14021403int buffer_block_index = -1;1404/* If the uniform is inside a uniform block determine its block index by1405* comparing the bindings, we can not use names.1406*/1407if (state->var_is_in_block) {1408struct gl_uniform_block *blocks = nir_variable_is_in_ssbo(state->current_var) ?1409prog->data->ShaderStorageBlocks : prog->data->UniformBlocks;14101411int num_blocks = nir_variable_is_in_ssbo(state->current_var) ?1412prog->data->NumShaderStorageBlocks : prog->data->NumUniformBlocks;14131414if (!prog->data->spirv) {1415bool is_interface_array =1416glsl_without_array(state->current_var->type) == state->current_var->interface_type &&1417glsl_type_is_array(state->current_var->type);14181419const char *ifc_name =1420glsl_get_type_name(state->current_var->interface_type);1421if (is_interface_array) {1422unsigned l = strlen(ifc_name);1423for (unsigned i = 0; i < num_blocks; i++) {1424if (strncmp(ifc_name, blocks[i].Name, l) == 0 &&1425blocks[i].Name[l] == '[') {1426buffer_block_index = i;1427break;1428}1429}1430} else {1431for (unsigned i = 0; i < num_blocks; i++) {1432if (strcmp(ifc_name, blocks[i].Name) == 0) {1433buffer_block_index = i;1434break;1435}1436}1437}14381439/* Compute the next offset. */1440bool use_std430 = ctx->Const.UseSTD430AsDefaultPacking;1441const enum glsl_interface_packing packing =1442glsl_get_internal_ifc_packing(state->current_var->interface_type,1443use_std430);1444if (packing == GLSL_INTERFACE_PACKING_STD430)1445state->offset += glsl_get_std430_size(type, uniform->row_major);1446else1447state->offset += glsl_get_std140_size(type, uniform->row_major);1448} else {1449for (unsigned i = 0; i < num_blocks; i++) {1450if (state->current_var->data.binding == blocks[i].Binding) {1451buffer_block_index = i;1452break;1453}1454}14551456/* Compute the next offset. */1457state->offset += glsl_get_explicit_size(type, true);1458}1459assert(buffer_block_index >= 0);1460}14611462uniform->block_index = buffer_block_index;1463uniform->builtin = is_gl_identifier(uniform->name);1464uniform->atomic_buffer_index = -1;14651466/* The following are not for features not supported by ARB_gl_spirv */1467uniform->num_compatible_subroutines = 0;14681469unsigned entries = MAX2(1, uniform->array_elements);1470unsigned values = glsl_get_component_slots(type);14711472update_uniforms_shader_info(prog, state, uniform, type, stage);14731474if (uniform->remap_location != UNMAPPED_UNIFORM_LOC &&1475state->max_uniform_location < uniform->remap_location + entries)1476state->max_uniform_location = uniform->remap_location + entries;14771478if (!state->var_is_in_block)1479add_parameter(uniform, ctx, prog, type, state);14801481if (name) {1482_mesa_hash_table_insert(state->uniform_hash, strdup(*name),1483(void *) (intptr_t)1484(prog->data->NumUniformStorage - 1));1485}14861487if (!is_gl_identifier(uniform->name) && !uniform->is_shader_storage &&1488!state->var_is_in_block)1489state->num_values += values;14901491return MAX2(uniform->array_elements, 1);1492}1493}14941495bool1496gl_nir_link_uniforms(struct gl_context *ctx,1497struct gl_shader_program *prog,1498bool fill_parameters)1499{1500/* First free up any previous UniformStorage items */1501ralloc_free(prog->data->UniformStorage);1502prog->data->UniformStorage = NULL;1503prog->data->NumUniformStorage = 0;15041505/* Iterate through all linked shaders */1506struct nir_link_uniforms_state state = {0,};15071508if (!prog->data->spirv) {1509/* Gather information on uniform use */1510for (unsigned stage = 0; stage < MESA_SHADER_STAGES; stage++) {1511struct gl_linked_shader *sh = prog->_LinkedShaders[stage];1512if (!sh)1513continue;15141515state.referenced_uniforms[stage] =1516_mesa_hash_table_create(NULL, _mesa_hash_string,1517_mesa_key_string_equal);15181519nir_shader *nir = sh->Program->nir;1520add_var_use_shader(nir, state.referenced_uniforms[stage]);1521}15221523/* Resize uniform arrays based on the maximum array index */1524for (unsigned stage = 0; stage < MESA_SHADER_STAGES; stage++) {1525struct gl_linked_shader *sh = prog->_LinkedShaders[stage];1526if (!sh)1527continue;15281529nir_foreach_gl_uniform_variable(var, sh->Program->nir)1530update_array_sizes(prog, var, state.referenced_uniforms, stage);1531}1532}15331534/* Count total number of uniforms and allocate storage */1535unsigned storage_size = 0;1536if (!prog->data->spirv) {1537struct set *storage_counted =1538_mesa_set_create(NULL, _mesa_hash_string, _mesa_key_string_equal);1539for (unsigned stage = 0; stage < MESA_SHADER_STAGES; stage++) {1540struct gl_linked_shader *sh = prog->_LinkedShaders[stage];1541if (!sh)1542continue;15431544nir_foreach_gl_uniform_variable(var, sh->Program->nir) {1545const struct glsl_type *type = var->type;1546const char *name = var->name;1547if (nir_variable_is_in_block(var) &&1548glsl_without_array(type) == var->interface_type) {1549type = glsl_without_array(var->type);1550name = glsl_get_type_name(type);1551}15521553struct set_entry *entry = _mesa_set_search(storage_counted, name);1554if (!entry) {1555storage_size += uniform_storage_size(type);1556_mesa_set_add(storage_counted, name);1557}1558}1559}1560_mesa_set_destroy(storage_counted, NULL);15611562prog->data->UniformStorage = rzalloc_array(prog->data,1563struct gl_uniform_storage,1564storage_size);1565if (!prog->data->UniformStorage) {1566linker_error(prog, "Out of memory while linking uniforms.\n");1567return false;1568}1569}15701571/* Iterate through all linked shaders */1572state.uniform_hash = _mesa_hash_table_create(NULL, _mesa_hash_string,1573_mesa_key_string_equal);15741575for (unsigned shader_type = 0; shader_type < MESA_SHADER_STAGES; shader_type++) {1576struct gl_linked_shader *sh = prog->_LinkedShaders[shader_type];1577if (!sh)1578continue;15791580nir_shader *nir = sh->Program->nir;1581assert(nir);15821583state.next_bindless_image_index = 0;1584state.next_bindless_sampler_index = 0;1585state.next_image_index = 0;1586state.next_sampler_index = 0;1587state.num_shader_samplers = 0;1588state.num_shader_images = 0;1589state.num_shader_uniform_components = 0;1590state.shader_storage_blocks_write_access = 0;1591state.shader_samplers_used = 0;1592state.shader_shadow_samplers = 0;1593state.params = fill_parameters ? sh->Program->Parameters : NULL;15941595nir_foreach_gl_uniform_variable(var, nir) {1596state.current_var = var;1597state.current_ifc_type = NULL;1598state.offset = 0;1599state.var_is_in_block = nir_variable_is_in_block(var);1600state.set_top_level_array = false;1601state.top_level_array_size = 0;1602state.top_level_array_stride = 0;16031604/*1605* From ARB_program_interface spec, issue (16):1606*1607* "RESOLVED: We will follow the default rule for enumerating block1608* members in the OpenGL API, which is:1609*1610* * If a variable is a member of an interface block without an1611* instance name, it is enumerated using just the variable name.1612*1613* * If a variable is a member of an interface block with an1614* instance name, it is enumerated as "BlockName.Member", where1615* "BlockName" is the name of the interface block (not the1616* instance name) and "Member" is the name of the variable.1617*1618* For example, in the following code:1619*1620* uniform Block1 {1621* int member1;1622* };1623* uniform Block2 {1624* int member2;1625* } instance2;1626* uniform Block3 {1627* int member3;1628* } instance3[2]; // uses two separate buffer bindings1629*1630* the three uniforms (if active) are enumerated as "member1",1631* "Block2.member2", and "Block3.member3"."1632*1633* Note that in the last example, with an array of ubo, only one1634* uniform is generated. For that reason, while unrolling the1635* uniforms of a ubo, or the variables of a ssbo, we need to treat1636* arrays of instance as a single block.1637*/1638char *name;1639const struct glsl_type *type = var->type;1640if (state.var_is_in_block &&1641((!prog->data->spirv && glsl_without_array(type) == var->interface_type) ||1642(prog->data->spirv && type == var->interface_type))) {1643type = glsl_without_array(var->type);1644state.current_ifc_type = type;1645name = ralloc_strdup(NULL, glsl_get_type_name(type));1646} else {1647state.set_top_level_array = true;1648name = ralloc_strdup(NULL, var->name);1649}16501651struct type_tree_entry *type_tree =1652build_type_tree_for_type(type);1653state.current_type = type_tree;16541655int location = var->data.location;16561657struct gl_uniform_block *blocks = NULL;1658int num_blocks = 0;1659int buffer_block_index = -1;1660if (!prog->data->spirv && state.var_is_in_block) {1661/* If the uniform is inside a uniform block determine its block index by1662* comparing the bindings, we can not use names.1663*/1664blocks = nir_variable_is_in_ssbo(state.current_var) ?1665prog->data->ShaderStorageBlocks : prog->data->UniformBlocks;1666num_blocks = nir_variable_is_in_ssbo(state.current_var) ?1667prog->data->NumShaderStorageBlocks : prog->data->NumUniformBlocks;16681669bool is_interface_array =1670glsl_without_array(state.current_var->type) == state.current_var->interface_type &&1671glsl_type_is_array(state.current_var->type);16721673const char *ifc_name =1674glsl_get_type_name(state.current_var->interface_type);16751676if (is_interface_array) {1677unsigned l = strlen(ifc_name);16781679/* Even when a match is found, do not "break" here. As this is1680* an array of instances, all elements of the array need to be1681* marked as referenced.1682*/1683for (unsigned i = 0; i < num_blocks; i++) {1684if (strncmp(ifc_name, blocks[i].Name, l) == 0 &&1685blocks[i].Name[l] == '[') {1686if (buffer_block_index == -1)1687buffer_block_index = i;16881689struct hash_entry *entry =1690_mesa_hash_table_search(state.referenced_uniforms[shader_type],1691var->name);1692if (entry) {1693struct uniform_array_info *ainfo =1694(struct uniform_array_info *) entry->data;1695if (BITSET_TEST(ainfo->indices, blocks[i].linearized_array_index))1696blocks[i].stageref |= 1U << shader_type;1697}1698}1699}1700} else {1701for (unsigned i = 0; i < num_blocks; i++) {1702if (strcmp(ifc_name, blocks[i].Name) == 0) {1703buffer_block_index = i;17041705struct hash_entry *entry =1706_mesa_hash_table_search(state.referenced_uniforms[shader_type],1707var->name);1708if (entry)1709blocks[i].stageref |= 1U << shader_type;17101711break;1712}1713}1714}17151716if (nir_variable_is_in_ssbo(var) &&1717!(var->data.access & ACCESS_NON_WRITEABLE)) {1718unsigned array_size = is_interface_array ?1719glsl_get_length(var->type) : 1;17201721STATIC_ASSERT(MAX_SHADER_STORAGE_BUFFERS <= 32);17221723/* Shaders that use too many SSBOs will fail to compile, which1724* we don't care about.1725*1726* This is true for shaders that do not use too many SSBOs:1727*/1728if (buffer_block_index + array_size <= 32) {1729state.shader_storage_blocks_write_access |=1730u_bit_consecutive(buffer_block_index, array_size);1731}1732}1733}17341735if (blocks && !prog->data->spirv && state.var_is_in_block) {1736if (glsl_without_array(state.current_var->type) != state.current_var->interface_type) {1737/* this is nested at some offset inside the block */1738bool found = false;1739char sentinel = '\0';17401741if (glsl_type_is_struct(state.current_var->type)) {1742sentinel = '.';1743} else if (glsl_type_is_array(state.current_var->type) &&1744(glsl_type_is_array(glsl_get_array_element(state.current_var->type))1745|| glsl_type_is_struct(glsl_without_array(state.current_var->type)))) {1746sentinel = '[';1747}17481749const unsigned l = strlen(state.current_var->name);1750for (unsigned i = 0; i < num_blocks; i++) {1751for (unsigned j = 0; j < blocks[i].NumUniforms; j++) {1752if (sentinel) {1753const char *begin = blocks[i].Uniforms[j].Name;1754const char *end = strchr(begin, sentinel);17551756if (end == NULL)1757continue;17581759if ((ptrdiff_t) l != (end - begin))1760continue;1761found = strncmp(state.current_var->name, begin, l) == 0;1762} else {1763found = strcmp(state.current_var->name, blocks[i].Uniforms[j].Name) == 0;1764}17651766if (found) {1767location = j;17681769struct hash_entry *entry =1770_mesa_hash_table_search(state.referenced_uniforms[shader_type], var->name);1771if (entry)1772blocks[i].stageref |= 1U << shader_type;17731774break;1775}1776}17771778if (found)1779break;1780}1781assert(found);1782var->data.location = location;1783} else {1784/* this is the base block offset */1785var->data.location = buffer_block_index;1786location = 0;1787}1788assert(buffer_block_index >= 0);1789const struct gl_uniform_block *const block =1790&blocks[buffer_block_index];1791assert(location >= 0 && location < block->NumUniforms);17921793const struct gl_uniform_buffer_variable *const ubo_var =1794&block->Uniforms[location];17951796state.offset = ubo_var->Offset;1797}17981799/* Check if the uniform has been processed already for1800* other stage. If so, validate they are compatible and update1801* the active stage mask.1802*/1803if (find_and_update_previous_uniform_storage(ctx, prog, &state, var,1804name, type, shader_type)) {1805ralloc_free(name);1806free_type_tree(type_tree);1807continue;1808}18091810/* From now on the variable’s location will be its uniform index */1811if (!state.var_is_in_block)1812var->data.location = prog->data->NumUniformStorage;1813else1814location = -1;18151816bool row_major =1817var->data.matrix_layout == GLSL_MATRIX_LAYOUT_ROW_MAJOR;1818int res = nir_link_uniform(ctx, prog, sh->Program, shader_type, type,18190, location,1820&state,1821!prog->data->spirv ? &name : NULL,1822!prog->data->spirv ? strlen(name) : 0,1823row_major);18241825free_type_tree(type_tree);1826ralloc_free(name);18271828if (res == -1)1829return false;1830}18311832if (!prog->data->spirv) {1833_mesa_hash_table_destroy(state.referenced_uniforms[shader_type],1834NULL);1835}18361837if (state.num_shader_samplers >1838ctx->Const.Program[shader_type].MaxTextureImageUnits) {1839linker_error(prog, "Too many %s shader texture samplers\n",1840_mesa_shader_stage_to_string(shader_type));1841continue;1842}18431844if (state.num_shader_images >1845ctx->Const.Program[shader_type].MaxImageUniforms) {1846linker_error(prog, "Too many %s shader image uniforms (%u > %u)\n",1847_mesa_shader_stage_to_string(shader_type),1848state.num_shader_images,1849ctx->Const.Program[shader_type].MaxImageUniforms);1850continue;1851}18521853sh->Program->SamplersUsed = state.shader_samplers_used;1854sh->Program->sh.ShaderStorageBlocksWriteAccess =1855state.shader_storage_blocks_write_access;1856sh->shadow_samplers = state.shader_shadow_samplers;1857sh->Program->info.num_textures = state.num_shader_samplers;1858sh->Program->info.num_images = state.num_shader_images;1859sh->num_uniform_components = state.num_shader_uniform_components;1860sh->num_combined_uniform_components = sh->num_uniform_components;1861}18621863prog->data->NumHiddenUniforms = state.num_hidden_uniforms;1864prog->data->NumUniformDataSlots = state.num_values;18651866assert(prog->data->spirv || prog->data->NumUniformStorage == storage_size);18671868if (prog->data->spirv)1869prog->NumUniformRemapTable = state.max_uniform_location;18701871nir_setup_uniform_remap_tables(ctx, prog);1872gl_nir_set_uniform_initializers(ctx, prog);18731874_mesa_hash_table_destroy(state.uniform_hash, hash_free_uniform_name);18751876return true;1877}187818791880