1b8e80941Smrg/* 2b8e80941Smrg * Copyright © 2011 Intel Corporation 3b8e80941Smrg * 4b8e80941Smrg * Permission is hereby granted, free of charge, to any person obtaining a 5b8e80941Smrg * copy of this software and associated documentation files (the "Software"), 6b8e80941Smrg * to deal in the Software without restriction, including without limitation 7b8e80941Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8b8e80941Smrg * and/or sell copies of the Software, and to permit persons to whom the 9b8e80941Smrg * Software is furnished to do so, subject to the following conditions: 10b8e80941Smrg * 11b8e80941Smrg * The above copyright notice and this permission notice (including the next 12b8e80941Smrg * paragraph) shall be included in all copies or substantial portions of the 13b8e80941Smrg * Software. 14b8e80941Smrg * 15b8e80941Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16b8e80941Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17b8e80941Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18b8e80941Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19b8e80941Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20b8e80941Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21b8e80941Smrg * DEALINGS IN THE SOFTWARE. 22b8e80941Smrg */ 23b8e80941Smrg 24b8e80941Smrg#include "ir.h" 25b8e80941Smrg#include "linker.h" 26b8e80941Smrg#include "ir_uniform.h" 27b8e80941Smrg#include "glsl_symbol_table.h" 28b8e80941Smrg#include "program.h" 29b8e80941Smrg#include "string_to_uint_map.h" 30b8e80941Smrg#include "ir_array_refcount.h" 31b8e80941Smrg#include "main/mtypes.h" 32b8e80941Smrg 33b8e80941Smrg/** 34b8e80941Smrg * \file link_uniforms.cpp 35b8e80941Smrg * Assign locations for GLSL uniforms. 36b8e80941Smrg * 37b8e80941Smrg * \author Ian Romanick <ian.d.romanick@intel.com> 38b8e80941Smrg */ 39b8e80941Smrg 40b8e80941Smrg/** 41b8e80941Smrg * Used by linker to indicate uniforms that have no location set. 42b8e80941Smrg */ 43b8e80941Smrg#define UNMAPPED_UNIFORM_LOC ~0u 44b8e80941Smrg 45b8e80941Smrgvoid 46b8e80941Smrgprogram_resource_visitor::process(const glsl_type *type, const char *name, 47b8e80941Smrg bool use_std430_as_default) 48b8e80941Smrg{ 49b8e80941Smrg assert(type->without_array()->is_struct() 50b8e80941Smrg || type->without_array()->is_interface()); 51b8e80941Smrg 52b8e80941Smrg unsigned record_array_count = 1; 53b8e80941Smrg char *name_copy = ralloc_strdup(NULL, name); 54b8e80941Smrg 55b8e80941Smrg enum glsl_interface_packing packing = 56b8e80941Smrg type->get_internal_ifc_packing(use_std430_as_default); 57b8e80941Smrg 58b8e80941Smrg recursion(type, &name_copy, strlen(name), false, NULL, packing, false, 59b8e80941Smrg record_array_count, NULL); 60b8e80941Smrg ralloc_free(name_copy); 61b8e80941Smrg} 62b8e80941Smrg 63b8e80941Smrgvoid 64b8e80941Smrgprogram_resource_visitor::process(ir_variable *var, bool use_std430_as_default) 65b8e80941Smrg{ 66b8e80941Smrg const glsl_type *t = 67b8e80941Smrg var->data.from_named_ifc_block ? var->get_interface_type() : var->type; 68b8e80941Smrg process(var, t, use_std430_as_default); 69b8e80941Smrg} 70b8e80941Smrg 71b8e80941Smrgvoid 72b8e80941Smrgprogram_resource_visitor::process(ir_variable *var, const glsl_type *var_type, 73b8e80941Smrg bool use_std430_as_default) 74b8e80941Smrg{ 75b8e80941Smrg unsigned record_array_count = 1; 76b8e80941Smrg const bool row_major = 77b8e80941Smrg var->data.matrix_layout == GLSL_MATRIX_LAYOUT_ROW_MAJOR; 78b8e80941Smrg 79b8e80941Smrg enum glsl_interface_packing packing = var->get_interface_type() ? 80b8e80941Smrg var->get_interface_type()-> 81b8e80941Smrg get_internal_ifc_packing(use_std430_as_default) : 82b8e80941Smrg var->type->get_internal_ifc_packing(use_std430_as_default); 83b8e80941Smrg 84b8e80941Smrg const glsl_type *t = var_type; 85b8e80941Smrg const glsl_type *t_without_array = t->without_array(); 86b8e80941Smrg 87b8e80941Smrg /* false is always passed for the row_major parameter to the other 88b8e80941Smrg * processing functions because no information is available to do 89b8e80941Smrg * otherwise. See the warning in linker.h. 90b8e80941Smrg */ 91b8e80941Smrg if (t_without_array->is_struct() || 92b8e80941Smrg (t->is_array() && t->fields.array->is_array())) { 93b8e80941Smrg char *name = ralloc_strdup(NULL, var->name); 94b8e80941Smrg recursion(var->type, &name, strlen(name), row_major, NULL, packing, 95b8e80941Smrg false, record_array_count, NULL); 96b8e80941Smrg ralloc_free(name); 97b8e80941Smrg } else if (t_without_array->is_interface()) { 98b8e80941Smrg char *name = ralloc_strdup(NULL, t_without_array->name); 99b8e80941Smrg const glsl_struct_field *ifc_member = var->data.from_named_ifc_block ? 100b8e80941Smrg &t_without_array-> 101b8e80941Smrg fields.structure[t_without_array->field_index(var->name)] : NULL; 102b8e80941Smrg 103b8e80941Smrg recursion(t, &name, strlen(name), row_major, NULL, packing, 104b8e80941Smrg false, record_array_count, ifc_member); 105b8e80941Smrg ralloc_free(name); 106b8e80941Smrg } else { 107b8e80941Smrg this->set_record_array_count(record_array_count); 108b8e80941Smrg this->visit_field(t, var->name, row_major, NULL, packing, false); 109b8e80941Smrg } 110b8e80941Smrg} 111b8e80941Smrg 112b8e80941Smrgvoid 113b8e80941Smrgprogram_resource_visitor::recursion(const glsl_type *t, char **name, 114b8e80941Smrg size_t name_length, bool row_major, 115b8e80941Smrg const glsl_type *record_type, 116b8e80941Smrg const enum glsl_interface_packing packing, 117b8e80941Smrg bool last_field, 118b8e80941Smrg unsigned record_array_count, 119b8e80941Smrg const glsl_struct_field *named_ifc_member) 120b8e80941Smrg{ 121b8e80941Smrg /* Records need to have each field processed individually. 122b8e80941Smrg * 123b8e80941Smrg * Arrays of records need to have each array element processed 124b8e80941Smrg * individually, then each field of the resulting array elements processed 125b8e80941Smrg * individually. 126b8e80941Smrg */ 127b8e80941Smrg if (t->is_interface() && named_ifc_member) { 128b8e80941Smrg ralloc_asprintf_rewrite_tail(name, &name_length, ".%s", 129b8e80941Smrg named_ifc_member->name); 130b8e80941Smrg recursion(named_ifc_member->type, name, name_length, row_major, NULL, 131b8e80941Smrg packing, false, record_array_count, NULL); 132b8e80941Smrg } else if (t->is_struct() || t->is_interface()) { 133b8e80941Smrg if (record_type == NULL && t->is_struct()) 134b8e80941Smrg record_type = t; 135b8e80941Smrg 136b8e80941Smrg if (t->is_struct()) 137b8e80941Smrg this->enter_record(t, *name, row_major, packing); 138b8e80941Smrg 139b8e80941Smrg for (unsigned i = 0; i < t->length; i++) { 140b8e80941Smrg const char *field = t->fields.structure[i].name; 141b8e80941Smrg size_t new_length = name_length; 142b8e80941Smrg 143b8e80941Smrg if (t->is_interface() && t->fields.structure[i].offset != -1) 144b8e80941Smrg this->set_buffer_offset(t->fields.structure[i].offset); 145b8e80941Smrg 146b8e80941Smrg /* Append '.field' to the current variable name. */ 147b8e80941Smrg if (name_length == 0) { 148b8e80941Smrg ralloc_asprintf_rewrite_tail(name, &new_length, "%s", field); 149b8e80941Smrg } else { 150b8e80941Smrg ralloc_asprintf_rewrite_tail(name, &new_length, ".%s", field); 151b8e80941Smrg } 152b8e80941Smrg 153b8e80941Smrg /* The layout of structures at the top level of the block is set 154b8e80941Smrg * during parsing. For matrices contained in multiple levels of 155b8e80941Smrg * structures in the block, the inner structures have no layout. 156b8e80941Smrg * These cases must potentially inherit the layout from the outer 157b8e80941Smrg * levels. 158b8e80941Smrg */ 159b8e80941Smrg bool field_row_major = row_major; 160b8e80941Smrg const enum glsl_matrix_layout matrix_layout = 161b8e80941Smrg glsl_matrix_layout(t->fields.structure[i].matrix_layout); 162b8e80941Smrg if (matrix_layout == GLSL_MATRIX_LAYOUT_ROW_MAJOR) { 163b8e80941Smrg field_row_major = true; 164b8e80941Smrg } else if (matrix_layout == GLSL_MATRIX_LAYOUT_COLUMN_MAJOR) { 165b8e80941Smrg field_row_major = false; 166b8e80941Smrg } 167b8e80941Smrg 168b8e80941Smrg recursion(t->fields.structure[i].type, name, new_length, 169b8e80941Smrg field_row_major, 170b8e80941Smrg record_type, 171b8e80941Smrg packing, 172b8e80941Smrg (i + 1) == t->length, record_array_count, NULL); 173b8e80941Smrg 174b8e80941Smrg /* Only the first leaf-field of the record gets called with the 175b8e80941Smrg * record type pointer. 176b8e80941Smrg */ 177b8e80941Smrg record_type = NULL; 178b8e80941Smrg } 179b8e80941Smrg 180b8e80941Smrg if (t->is_struct()) { 181b8e80941Smrg (*name)[name_length] = '\0'; 182b8e80941Smrg this->leave_record(t, *name, row_major, packing); 183b8e80941Smrg } 184b8e80941Smrg } else if (t->without_array()->is_struct() || 185b8e80941Smrg t->without_array()->is_interface() || 186b8e80941Smrg (t->is_array() && t->fields.array->is_array())) { 187b8e80941Smrg if (record_type == NULL && t->fields.array->is_struct()) 188b8e80941Smrg record_type = t->fields.array; 189b8e80941Smrg 190b8e80941Smrg unsigned length = t->length; 191b8e80941Smrg 192b8e80941Smrg /* Shader storage block unsized arrays: add subscript [0] to variable 193b8e80941Smrg * names. 194b8e80941Smrg */ 195b8e80941Smrg if (t->is_unsized_array()) 196b8e80941Smrg length = 1; 197b8e80941Smrg 198b8e80941Smrg record_array_count *= length; 199b8e80941Smrg 200b8e80941Smrg for (unsigned i = 0; i < length; i++) { 201b8e80941Smrg size_t new_length = name_length; 202b8e80941Smrg 203b8e80941Smrg /* Append the subscript to the current variable name */ 204b8e80941Smrg ralloc_asprintf_rewrite_tail(name, &new_length, "[%u]", i); 205b8e80941Smrg 206b8e80941Smrg recursion(t->fields.array, name, new_length, row_major, 207b8e80941Smrg record_type, 208b8e80941Smrg packing, 209b8e80941Smrg (i + 1) == t->length, record_array_count, 210b8e80941Smrg named_ifc_member); 211b8e80941Smrg 212b8e80941Smrg /* Only the first leaf-field of the record gets called with the 213b8e80941Smrg * record type pointer. 214b8e80941Smrg */ 215b8e80941Smrg record_type = NULL; 216b8e80941Smrg } 217b8e80941Smrg } else { 218b8e80941Smrg this->set_record_array_count(record_array_count); 219b8e80941Smrg this->visit_field(t, *name, row_major, record_type, packing, last_field); 220b8e80941Smrg } 221b8e80941Smrg} 222b8e80941Smrg 223b8e80941Smrgvoid 224b8e80941Smrgprogram_resource_visitor::enter_record(const glsl_type *, const char *, bool, 225b8e80941Smrg const enum glsl_interface_packing) 226b8e80941Smrg{ 227b8e80941Smrg} 228b8e80941Smrg 229b8e80941Smrgvoid 230b8e80941Smrgprogram_resource_visitor::leave_record(const glsl_type *, const char *, bool, 231b8e80941Smrg const enum glsl_interface_packing) 232b8e80941Smrg{ 233b8e80941Smrg} 234b8e80941Smrg 235b8e80941Smrgvoid 236b8e80941Smrgprogram_resource_visitor::set_buffer_offset(unsigned) 237b8e80941Smrg{ 238b8e80941Smrg} 239b8e80941Smrg 240b8e80941Smrgvoid 241b8e80941Smrgprogram_resource_visitor::set_record_array_count(unsigned) 242b8e80941Smrg{ 243b8e80941Smrg} 244b8e80941Smrg 245b8e80941Smrgnamespace { 246b8e80941Smrg 247b8e80941Smrg/** 248b8e80941Smrg * Class to help calculate the storage requirements for a set of uniforms 249b8e80941Smrg * 250b8e80941Smrg * As uniforms are added to the active set the number of active uniforms and 251b8e80941Smrg * the storage requirements for those uniforms are accumulated. The active 252b8e80941Smrg * uniforms are added to the hash table supplied to the constructor. 253b8e80941Smrg * 254b8e80941Smrg * If the same uniform is added multiple times (i.e., once for each shader 255b8e80941Smrg * target), it will only be accounted once. 256b8e80941Smrg */ 257b8e80941Smrgclass count_uniform_size : public program_resource_visitor { 258b8e80941Smrgpublic: 259b8e80941Smrg count_uniform_size(struct string_to_uint_map *map, 260b8e80941Smrg struct string_to_uint_map *hidden_map, 261b8e80941Smrg bool use_std430_as_default) 262b8e80941Smrg : num_active_uniforms(0), num_hidden_uniforms(0), num_values(0), 263b8e80941Smrg num_shader_samplers(0), num_shader_images(0), 264b8e80941Smrg num_shader_uniform_components(0), num_shader_subroutines(0), 265b8e80941Smrg is_buffer_block(false), is_shader_storage(false), map(map), 266b8e80941Smrg hidden_map(hidden_map), current_var(NULL), 267b8e80941Smrg use_std430_as_default(use_std430_as_default) 268b8e80941Smrg { 269b8e80941Smrg /* empty */ 270b8e80941Smrg } 271b8e80941Smrg 272b8e80941Smrg void start_shader() 273b8e80941Smrg { 274b8e80941Smrg this->num_shader_samplers = 0; 275b8e80941Smrg this->num_shader_images = 0; 276b8e80941Smrg this->num_shader_uniform_components = 0; 277b8e80941Smrg this->num_shader_subroutines = 0; 278b8e80941Smrg } 279b8e80941Smrg 280b8e80941Smrg void process(ir_variable *var) 281b8e80941Smrg { 282b8e80941Smrg this->current_var = var; 283b8e80941Smrg this->is_buffer_block = var->is_in_buffer_block(); 284b8e80941Smrg this->is_shader_storage = var->is_in_shader_storage_block(); 285b8e80941Smrg if (var->is_interface_instance()) 286b8e80941Smrg program_resource_visitor::process(var->get_interface_type(), 287b8e80941Smrg var->get_interface_type()->name, 288b8e80941Smrg use_std430_as_default); 289b8e80941Smrg else 290b8e80941Smrg program_resource_visitor::process(var, use_std430_as_default); 291b8e80941Smrg } 292b8e80941Smrg 293b8e80941Smrg /** 294b8e80941Smrg * Total number of active uniforms counted 295b8e80941Smrg */ 296b8e80941Smrg unsigned num_active_uniforms; 297b8e80941Smrg 298b8e80941Smrg unsigned num_hidden_uniforms; 299b8e80941Smrg 300b8e80941Smrg /** 301b8e80941Smrg * Number of data values required to back the storage for the active uniforms 302b8e80941Smrg */ 303b8e80941Smrg unsigned num_values; 304b8e80941Smrg 305b8e80941Smrg /** 306b8e80941Smrg * Number of samplers used 307b8e80941Smrg */ 308b8e80941Smrg unsigned num_shader_samplers; 309b8e80941Smrg 310b8e80941Smrg /** 311b8e80941Smrg * Number of images used 312b8e80941Smrg */ 313b8e80941Smrg unsigned num_shader_images; 314b8e80941Smrg 315b8e80941Smrg /** 316b8e80941Smrg * Number of uniforms used in the current shader 317b8e80941Smrg */ 318b8e80941Smrg unsigned num_shader_uniform_components; 319b8e80941Smrg 320b8e80941Smrg /** 321b8e80941Smrg * Number of subroutine uniforms used 322b8e80941Smrg */ 323b8e80941Smrg unsigned num_shader_subroutines; 324b8e80941Smrg 325b8e80941Smrg bool is_buffer_block; 326b8e80941Smrg bool is_shader_storage; 327b8e80941Smrg 328b8e80941Smrg struct string_to_uint_map *map; 329b8e80941Smrg 330b8e80941Smrgprivate: 331b8e80941Smrg virtual void visit_field(const glsl_type *type, const char *name, 332b8e80941Smrg bool /* row_major */, 333b8e80941Smrg const glsl_type * /* record_type */, 334b8e80941Smrg const enum glsl_interface_packing, 335b8e80941Smrg bool /* last_field */) 336b8e80941Smrg { 337b8e80941Smrg assert(!type->without_array()->is_struct()); 338b8e80941Smrg assert(!type->without_array()->is_interface()); 339b8e80941Smrg assert(!(type->is_array() && type->fields.array->is_array())); 340b8e80941Smrg 341b8e80941Smrg /* Count the number of samplers regardless of whether the uniform is 342b8e80941Smrg * already in the hash table. The hash table prevents adding the same 343b8e80941Smrg * uniform for multiple shader targets, but in this case we want to 344b8e80941Smrg * count it for each shader target. 345b8e80941Smrg */ 346b8e80941Smrg const unsigned values = type->component_slots(); 347b8e80941Smrg if (type->contains_subroutine()) { 348b8e80941Smrg this->num_shader_subroutines += values; 349b8e80941Smrg } else if (type->contains_sampler() && !current_var->data.bindless) { 350b8e80941Smrg /* Samplers (bound or bindless) are counted as two components as 351b8e80941Smrg * specified by ARB_bindless_texture. */ 352b8e80941Smrg this->num_shader_samplers += values / 2; 353b8e80941Smrg } else if (type->contains_image() && !current_var->data.bindless) { 354b8e80941Smrg /* Images (bound or bindless) are counted as two components as 355b8e80941Smrg * specified by ARB_bindless_texture. */ 356b8e80941Smrg this->num_shader_images += values / 2; 357b8e80941Smrg 358b8e80941Smrg /* As drivers are likely to represent image uniforms as 359b8e80941Smrg * scalar indices, count them against the limit of uniform 360b8e80941Smrg * components in the default block. The spec allows image 361b8e80941Smrg * uniforms to use up no more than one scalar slot. 362b8e80941Smrg */ 363b8e80941Smrg if (!is_shader_storage) 364b8e80941Smrg this->num_shader_uniform_components += values; 365b8e80941Smrg } else { 366b8e80941Smrg /* Accumulate the total number of uniform slots used by this shader. 367b8e80941Smrg * Note that samplers do not count against this limit because they 368b8e80941Smrg * don't use any storage on current hardware. 369b8e80941Smrg */ 370b8e80941Smrg if (!is_buffer_block) 371b8e80941Smrg this->num_shader_uniform_components += values; 372b8e80941Smrg } 373b8e80941Smrg 374b8e80941Smrg /* If the uniform is already in the map, there's nothing more to do. 375b8e80941Smrg */ 376b8e80941Smrg unsigned id; 377b8e80941Smrg if (this->map->get(id, name)) 378b8e80941Smrg return; 379b8e80941Smrg 380b8e80941Smrg if (this->current_var->data.how_declared == ir_var_hidden) { 381b8e80941Smrg this->hidden_map->put(this->num_hidden_uniforms, name); 382b8e80941Smrg this->num_hidden_uniforms++; 383b8e80941Smrg } else { 384b8e80941Smrg this->map->put(this->num_active_uniforms-this->num_hidden_uniforms, 385b8e80941Smrg name); 386b8e80941Smrg } 387b8e80941Smrg 388b8e80941Smrg /* Each leaf uniform occupies one entry in the list of active 389b8e80941Smrg * uniforms. 390b8e80941Smrg */ 391b8e80941Smrg this->num_active_uniforms++; 392b8e80941Smrg 393b8e80941Smrg if(!is_gl_identifier(name) && !is_shader_storage && !is_buffer_block) 394b8e80941Smrg this->num_values += values; 395b8e80941Smrg } 396b8e80941Smrg 397b8e80941Smrg struct string_to_uint_map *hidden_map; 398b8e80941Smrg 399b8e80941Smrg /** 400b8e80941Smrg * Current variable being processed. 401b8e80941Smrg */ 402b8e80941Smrg ir_variable *current_var; 403b8e80941Smrg 404b8e80941Smrg bool use_std430_as_default; 405b8e80941Smrg}; 406b8e80941Smrg 407b8e80941Smrg} /* anonymous namespace */ 408b8e80941Smrg 409b8e80941Smrgunsigned 410b8e80941Smrglink_calculate_matrix_stride(const glsl_type *matrix, bool row_major, 411b8e80941Smrg enum glsl_interface_packing packing) 412b8e80941Smrg{ 413b8e80941Smrg const unsigned N = matrix->is_double() ? 8 : 4; 414b8e80941Smrg const unsigned items = 415b8e80941Smrg row_major ? matrix->matrix_columns : matrix->vector_elements; 416b8e80941Smrg 417b8e80941Smrg assert(items <= 4); 418b8e80941Smrg 419b8e80941Smrg /* Matrix stride for std430 mat2xY matrices are not rounded up to 420b8e80941Smrg * vec4 size. 421b8e80941Smrg * 422b8e80941Smrg * Section 7.6.2.2 "Standard Uniform Block Layout" of the OpenGL 4.3 spec 423b8e80941Smrg * says: 424b8e80941Smrg * 425b8e80941Smrg * 2. If the member is a two- or four-component vector with components 426b8e80941Smrg * consuming N basic machine units, the base alignment is 2N or 4N, 427b8e80941Smrg * respectively. 428b8e80941Smrg * ... 429b8e80941Smrg * 4. If the member is an array of scalars or vectors, the base 430b8e80941Smrg * alignment and array stride are set to match the base alignment of 431b8e80941Smrg * a single array element, according to rules (1), (2), and (3), and 432b8e80941Smrg * rounded up to the base alignment of a vec4. 433b8e80941Smrg * ... 434b8e80941Smrg * 7. If the member is a row-major matrix with C columns and R rows, the 435b8e80941Smrg * matrix is stored identically to an array of R row vectors with C 436b8e80941Smrg * components each, according to rule (4). 437b8e80941Smrg * ... 438b8e80941Smrg * 439b8e80941Smrg * When using the std430 storage layout, shader storage blocks will be 440b8e80941Smrg * laid out in buffer storage identically to uniform and shader storage 441b8e80941Smrg * blocks using the std140 layout, except that the base alignment and 442b8e80941Smrg * stride of arrays of scalars and vectors in rule 4 and of structures 443b8e80941Smrg * in rule 9 are not rounded up a multiple of the base alignment of a 444b8e80941Smrg * vec4. 445b8e80941Smrg */ 446b8e80941Smrg return packing == GLSL_INTERFACE_PACKING_STD430 447b8e80941Smrg ? (items < 3 ? items * N : glsl_align(items * N, 16)) 448b8e80941Smrg : glsl_align(items * N, 16); 449b8e80941Smrg} 450b8e80941Smrg 451b8e80941Smrg/** 452b8e80941Smrg * Class to help parcel out pieces of backing storage to uniforms 453b8e80941Smrg * 454b8e80941Smrg * Each uniform processed has some range of the \c gl_constant_value 455b8e80941Smrg * structures associated with it. The association is done by finding 456b8e80941Smrg * the uniform in the \c string_to_uint_map and using the value from 457b8e80941Smrg * the map to connect that slot in the \c gl_uniform_storage table 458b8e80941Smrg * with the next available slot in the \c gl_constant_value array. 459b8e80941Smrg * 460b8e80941Smrg * \warning 461b8e80941Smrg * This class assumes that every uniform that will be processed is 462b8e80941Smrg * already in the \c string_to_uint_map. In addition, it assumes that 463b8e80941Smrg * the \c gl_uniform_storage and \c gl_constant_value arrays are "big 464b8e80941Smrg * enough." 465b8e80941Smrg */ 466b8e80941Smrgclass parcel_out_uniform_storage : public program_resource_visitor { 467b8e80941Smrgpublic: 468b8e80941Smrg parcel_out_uniform_storage(struct gl_shader_program *prog, 469b8e80941Smrg struct string_to_uint_map *map, 470b8e80941Smrg struct gl_uniform_storage *uniforms, 471b8e80941Smrg union gl_constant_value *values, 472b8e80941Smrg bool use_std430_as_default) 473b8e80941Smrg : prog(prog), map(map), uniforms(uniforms), 474b8e80941Smrg use_std430_as_default(use_std430_as_default), values(values), 475b8e80941Smrg bindless_targets(NULL), bindless_access(NULL) 476b8e80941Smrg { 477b8e80941Smrg } 478b8e80941Smrg 479b8e80941Smrg virtual ~parcel_out_uniform_storage() 480b8e80941Smrg { 481b8e80941Smrg free(this->bindless_targets); 482b8e80941Smrg free(this->bindless_access); 483b8e80941Smrg } 484b8e80941Smrg 485b8e80941Smrg void start_shader(gl_shader_stage shader_type) 486b8e80941Smrg { 487b8e80941Smrg assert(shader_type < MESA_SHADER_STAGES); 488b8e80941Smrg this->shader_type = shader_type; 489b8e80941Smrg 490b8e80941Smrg this->shader_samplers_used = 0; 491b8e80941Smrg this->shader_shadow_samplers = 0; 492b8e80941Smrg this->next_sampler = 0; 493b8e80941Smrg this->next_image = 0; 494b8e80941Smrg this->next_subroutine = 0; 495b8e80941Smrg this->record_array_count = 1; 496b8e80941Smrg memset(this->targets, 0, sizeof(this->targets)); 497b8e80941Smrg 498b8e80941Smrg this->num_bindless_samplers = 0; 499b8e80941Smrg this->next_bindless_sampler = 0; 500b8e80941Smrg free(this->bindless_targets); 501b8e80941Smrg this->bindless_targets = NULL; 502b8e80941Smrg 503b8e80941Smrg this->num_bindless_images = 0; 504b8e80941Smrg this->next_bindless_image = 0; 505b8e80941Smrg free(this->bindless_access); 506b8e80941Smrg this->bindless_access = NULL; 507b8e80941Smrg this->shader_storage_blocks_write_access = 0; 508b8e80941Smrg } 509b8e80941Smrg 510b8e80941Smrg void set_and_process(ir_variable *var) 511b8e80941Smrg { 512b8e80941Smrg current_var = var; 513b8e80941Smrg field_counter = 0; 514b8e80941Smrg this->record_next_sampler = new string_to_uint_map; 515b8e80941Smrg this->record_next_bindless_sampler = new string_to_uint_map; 516b8e80941Smrg this->record_next_image = new string_to_uint_map; 517b8e80941Smrg this->record_next_bindless_image = new string_to_uint_map; 518b8e80941Smrg 519b8e80941Smrg buffer_block_index = -1; 520b8e80941Smrg if (var->is_in_buffer_block()) { 521b8e80941Smrg struct gl_uniform_block *blks = var->is_in_shader_storage_block() ? 522b8e80941Smrg prog->data->ShaderStorageBlocks : prog->data->UniformBlocks; 523b8e80941Smrg unsigned num_blks = var->is_in_shader_storage_block() ? 524b8e80941Smrg prog->data->NumShaderStorageBlocks : prog->data->NumUniformBlocks; 525b8e80941Smrg bool is_interface_array = 526b8e80941Smrg var->is_interface_instance() && var->type->is_array(); 527b8e80941Smrg 528b8e80941Smrg if (is_interface_array) { 529b8e80941Smrg unsigned l = strlen(var->get_interface_type()->name); 530b8e80941Smrg 531b8e80941Smrg for (unsigned i = 0; i < num_blks; i++) { 532b8e80941Smrg if (strncmp(var->get_interface_type()->name, blks[i].Name, l) 533b8e80941Smrg == 0 && blks[i].Name[l] == '[') { 534b8e80941Smrg buffer_block_index = i; 535b8e80941Smrg break; 536b8e80941Smrg } 537b8e80941Smrg } 538b8e80941Smrg } else { 539b8e80941Smrg for (unsigned i = 0; i < num_blks; i++) { 540b8e80941Smrg if (strcmp(var->get_interface_type()->name, blks[i].Name) == 0) { 541b8e80941Smrg buffer_block_index = i; 542b8e80941Smrg break; 543b8e80941Smrg } 544b8e80941Smrg } 545b8e80941Smrg } 546b8e80941Smrg assert(buffer_block_index != -1); 547b8e80941Smrg 548b8e80941Smrg if (var->is_in_shader_storage_block() && 549b8e80941Smrg !var->data.memory_read_only) { 550b8e80941Smrg unsigned array_size = is_interface_array ? 551b8e80941Smrg var->type->array_size() : 1; 552b8e80941Smrg 553b8e80941Smrg STATIC_ASSERT(MAX_SHADER_STORAGE_BUFFERS <= 32); 554b8e80941Smrg 555b8e80941Smrg /* Shaders that use too many SSBOs will fail to compile, which 556b8e80941Smrg * we don't care about. 557b8e80941Smrg * 558b8e80941Smrg * This is true for shaders that do not use too many SSBOs: 559b8e80941Smrg */ 560b8e80941Smrg if (buffer_block_index + array_size <= 32) { 561b8e80941Smrg shader_storage_blocks_write_access |= 562b8e80941Smrg u_bit_consecutive(buffer_block_index, array_size); 563b8e80941Smrg } 564b8e80941Smrg } 565b8e80941Smrg 566b8e80941Smrg /* Uniform blocks that were specified with an instance name must be 567b8e80941Smrg * handled a little bit differently. The name of the variable is the 568b8e80941Smrg * name used to reference the uniform block instead of being the name 569b8e80941Smrg * of a variable within the block. Therefore, searching for the name 570b8e80941Smrg * within the block will fail. 571b8e80941Smrg */ 572b8e80941Smrg if (var->is_interface_instance()) { 573b8e80941Smrg ubo_byte_offset = 0; 574b8e80941Smrg process(var->get_interface_type(), 575b8e80941Smrg var->get_interface_type()->name, 576b8e80941Smrg use_std430_as_default); 577b8e80941Smrg } else { 578b8e80941Smrg const struct gl_uniform_block *const block = 579b8e80941Smrg &blks[buffer_block_index]; 580b8e80941Smrg 581b8e80941Smrg assert(var->data.location != -1); 582b8e80941Smrg 583b8e80941Smrg const struct gl_uniform_buffer_variable *const ubo_var = 584b8e80941Smrg &block->Uniforms[var->data.location]; 585b8e80941Smrg 586b8e80941Smrg ubo_byte_offset = ubo_var->Offset; 587b8e80941Smrg process(var, use_std430_as_default); 588b8e80941Smrg } 589b8e80941Smrg } else { 590b8e80941Smrg /* Store any explicit location and reset data location so we can 591b8e80941Smrg * reuse this variable for storing the uniform slot number. 592b8e80941Smrg */ 593b8e80941Smrg this->explicit_location = current_var->data.location; 594b8e80941Smrg current_var->data.location = -1; 595b8e80941Smrg 596b8e80941Smrg process(var, use_std430_as_default); 597b8e80941Smrg } 598b8e80941Smrg delete this->record_next_sampler; 599b8e80941Smrg delete this->record_next_bindless_sampler; 600b8e80941Smrg delete this->record_next_image; 601b8e80941Smrg delete this->record_next_bindless_image; 602b8e80941Smrg } 603b8e80941Smrg 604b8e80941Smrg int buffer_block_index; 605b8e80941Smrg int ubo_byte_offset; 606b8e80941Smrg gl_shader_stage shader_type; 607b8e80941Smrg 608b8e80941Smrgprivate: 609b8e80941Smrg bool set_opaque_indices(const glsl_type *base_type, 610b8e80941Smrg struct gl_uniform_storage *uniform, 611b8e80941Smrg const char *name, unsigned &next_index, 612b8e80941Smrg struct string_to_uint_map *record_next_index) 613b8e80941Smrg { 614b8e80941Smrg assert(base_type->is_sampler() || base_type->is_image()); 615b8e80941Smrg 616b8e80941Smrg if (this->record_array_count > 1) { 617b8e80941Smrg unsigned inner_array_size = MAX2(1, uniform->array_elements); 618b8e80941Smrg char *name_copy = ralloc_strdup(NULL, name); 619b8e80941Smrg 620b8e80941Smrg /* Remove all array subscripts from the sampler/image name */ 621b8e80941Smrg char *str_start; 622b8e80941Smrg const char *str_end; 623b8e80941Smrg while((str_start = strchr(name_copy, '[')) && 624b8e80941Smrg (str_end = strchr(name_copy, ']'))) { 625b8e80941Smrg memmove(str_start, str_end + 1, 1 + strlen(str_end + 1)); 626b8e80941Smrg } 627b8e80941Smrg 628b8e80941Smrg unsigned index = 0; 629b8e80941Smrg if (record_next_index->get(index, name_copy)) { 630b8e80941Smrg /* In this case, we've already seen this uniform so we just use the 631b8e80941Smrg * next sampler/image index recorded the last time we visited. 632b8e80941Smrg */ 633b8e80941Smrg uniform->opaque[shader_type].index = index; 634b8e80941Smrg index = inner_array_size + uniform->opaque[shader_type].index; 635b8e80941Smrg record_next_index->put(index, name_copy); 636b8e80941Smrg 637b8e80941Smrg ralloc_free(name_copy); 638b8e80941Smrg /* Return as everything else has already been initialised in a 639b8e80941Smrg * previous pass. 640b8e80941Smrg */ 641b8e80941Smrg return false; 642b8e80941Smrg } else { 643b8e80941Smrg /* We've never seen this uniform before so we need to allocate 644b8e80941Smrg * enough indices to store it. 645b8e80941Smrg * 646b8e80941Smrg * Nested struct arrays behave like arrays of arrays so we need to 647b8e80941Smrg * increase the index by the total number of elements of the 648b8e80941Smrg * sampler/image in case there is more than one sampler/image 649b8e80941Smrg * inside the structs. This allows the offset to be easily 650b8e80941Smrg * calculated for indirect indexing. 651b8e80941Smrg */ 652b8e80941Smrg uniform->opaque[shader_type].index = next_index; 653b8e80941Smrg next_index += inner_array_size * this->record_array_count; 654b8e80941Smrg 655b8e80941Smrg /* Store the next index for future passes over the struct array 656b8e80941Smrg */ 657b8e80941Smrg index = uniform->opaque[shader_type].index + inner_array_size; 658b8e80941Smrg record_next_index->put(index, name_copy); 659b8e80941Smrg ralloc_free(name_copy); 660b8e80941Smrg } 661b8e80941Smrg } else { 662b8e80941Smrg /* Increment the sampler/image by 1 for non-arrays and by the number 663b8e80941Smrg * of array elements for arrays. 664b8e80941Smrg */ 665b8e80941Smrg uniform->opaque[shader_type].index = next_index; 666b8e80941Smrg next_index += MAX2(1, uniform->array_elements); 667b8e80941Smrg } 668b8e80941Smrg return true; 669b8e80941Smrg } 670b8e80941Smrg 671b8e80941Smrg void handle_samplers(const glsl_type *base_type, 672b8e80941Smrg struct gl_uniform_storage *uniform, const char *name) 673b8e80941Smrg { 674b8e80941Smrg if (base_type->is_sampler()) { 675b8e80941Smrg uniform->opaque[shader_type].active = true; 676b8e80941Smrg 677b8e80941Smrg const gl_texture_index target = base_type->sampler_index(); 678b8e80941Smrg const unsigned shadow = base_type->sampler_shadow; 679b8e80941Smrg 680b8e80941Smrg if (current_var->data.bindless) { 681b8e80941Smrg if (!set_opaque_indices(base_type, uniform, name, 682b8e80941Smrg this->next_bindless_sampler, 683b8e80941Smrg this->record_next_bindless_sampler)) 684b8e80941Smrg return; 685b8e80941Smrg 686b8e80941Smrg this->num_bindless_samplers = this->next_bindless_sampler; 687b8e80941Smrg 688b8e80941Smrg this->bindless_targets = (gl_texture_index *) 689b8e80941Smrg realloc(this->bindless_targets, 690b8e80941Smrg this->num_bindless_samplers * sizeof(gl_texture_index)); 691b8e80941Smrg 692b8e80941Smrg for (unsigned i = uniform->opaque[shader_type].index; 693b8e80941Smrg i < this->num_bindless_samplers; 694b8e80941Smrg i++) { 695b8e80941Smrg this->bindless_targets[i] = target; 696b8e80941Smrg } 697b8e80941Smrg } else { 698b8e80941Smrg if (!set_opaque_indices(base_type, uniform, name, 699b8e80941Smrg this->next_sampler, 700b8e80941Smrg this->record_next_sampler)) 701b8e80941Smrg return; 702b8e80941Smrg 703b8e80941Smrg for (unsigned i = uniform->opaque[shader_type].index; 704b8e80941Smrg i < MIN2(this->next_sampler, MAX_SAMPLERS); 705b8e80941Smrg i++) { 706b8e80941Smrg this->targets[i] = target; 707b8e80941Smrg this->shader_samplers_used |= 1U << i; 708b8e80941Smrg this->shader_shadow_samplers |= shadow << i; 709b8e80941Smrg } 710b8e80941Smrg } 711b8e80941Smrg } 712b8e80941Smrg } 713b8e80941Smrg 714b8e80941Smrg void handle_images(const glsl_type *base_type, 715b8e80941Smrg struct gl_uniform_storage *uniform, const char *name) 716b8e80941Smrg { 717b8e80941Smrg if (base_type->is_image()) { 718b8e80941Smrg uniform->opaque[shader_type].active = true; 719b8e80941Smrg 720b8e80941Smrg /* Set image access qualifiers */ 721b8e80941Smrg const GLenum access = 722b8e80941Smrg current_var->data.memory_read_only ? 723b8e80941Smrg (current_var->data.memory_write_only ? GL_NONE : 724b8e80941Smrg GL_READ_ONLY) : 725b8e80941Smrg (current_var->data.memory_write_only ? GL_WRITE_ONLY : 726b8e80941Smrg GL_READ_WRITE); 727b8e80941Smrg 728b8e80941Smrg if (current_var->data.bindless) { 729b8e80941Smrg if (!set_opaque_indices(base_type, uniform, name, 730b8e80941Smrg this->next_bindless_image, 731b8e80941Smrg this->record_next_bindless_image)) 732b8e80941Smrg return; 733b8e80941Smrg 734b8e80941Smrg this->num_bindless_images = this->next_bindless_image; 735b8e80941Smrg 736b8e80941Smrg this->bindless_access = (GLenum *) 737b8e80941Smrg realloc(this->bindless_access, 738b8e80941Smrg this->num_bindless_images * sizeof(GLenum)); 739b8e80941Smrg 740b8e80941Smrg for (unsigned i = uniform->opaque[shader_type].index; 741b8e80941Smrg i < this->num_bindless_images; 742b8e80941Smrg i++) { 743b8e80941Smrg this->bindless_access[i] = access; 744b8e80941Smrg } 745b8e80941Smrg } else { 746b8e80941Smrg if (!set_opaque_indices(base_type, uniform, name, 747b8e80941Smrg this->next_image, 748b8e80941Smrg this->record_next_image)) 749b8e80941Smrg return; 750b8e80941Smrg 751b8e80941Smrg for (unsigned i = uniform->opaque[shader_type].index; 752b8e80941Smrg i < MIN2(this->next_image, MAX_IMAGE_UNIFORMS); 753b8e80941Smrg i++) { 754b8e80941Smrg prog->_LinkedShaders[shader_type]->Program->sh.ImageAccess[i] = access; 755b8e80941Smrg } 756b8e80941Smrg } 757b8e80941Smrg } 758b8e80941Smrg } 759b8e80941Smrg 760b8e80941Smrg void handle_subroutines(const glsl_type *base_type, 761b8e80941Smrg struct gl_uniform_storage *uniform) 762b8e80941Smrg { 763b8e80941Smrg if (base_type->is_subroutine()) { 764b8e80941Smrg uniform->opaque[shader_type].index = this->next_subroutine; 765b8e80941Smrg uniform->opaque[shader_type].active = true; 766b8e80941Smrg 767b8e80941Smrg prog->_LinkedShaders[shader_type]->Program->sh.NumSubroutineUniforms++; 768b8e80941Smrg 769b8e80941Smrg /* Increment the subroutine index by 1 for non-arrays and by the 770b8e80941Smrg * number of array elements for arrays. 771b8e80941Smrg */ 772b8e80941Smrg this->next_subroutine += MAX2(1, uniform->array_elements); 773b8e80941Smrg 774b8e80941Smrg } 775b8e80941Smrg } 776b8e80941Smrg 777b8e80941Smrg virtual void set_buffer_offset(unsigned offset) 778b8e80941Smrg { 779b8e80941Smrg this->ubo_byte_offset = offset; 780b8e80941Smrg } 781b8e80941Smrg 782b8e80941Smrg virtual void set_record_array_count(unsigned record_array_count) 783b8e80941Smrg { 784b8e80941Smrg this->record_array_count = record_array_count; 785b8e80941Smrg } 786b8e80941Smrg 787b8e80941Smrg virtual void enter_record(const glsl_type *type, const char *, 788b8e80941Smrg bool row_major, 789b8e80941Smrg const enum glsl_interface_packing packing) 790b8e80941Smrg { 791b8e80941Smrg assert(type->is_struct()); 792b8e80941Smrg if (this->buffer_block_index == -1) 793b8e80941Smrg return; 794b8e80941Smrg if (packing == GLSL_INTERFACE_PACKING_STD430) 795b8e80941Smrg this->ubo_byte_offset = glsl_align( 796b8e80941Smrg this->ubo_byte_offset, type->std430_base_alignment(row_major)); 797b8e80941Smrg else 798b8e80941Smrg this->ubo_byte_offset = glsl_align( 799b8e80941Smrg this->ubo_byte_offset, type->std140_base_alignment(row_major)); 800b8e80941Smrg } 801b8e80941Smrg 802b8e80941Smrg virtual void leave_record(const glsl_type *type, const char *, 803b8e80941Smrg bool row_major, 804b8e80941Smrg const enum glsl_interface_packing packing) 805b8e80941Smrg { 806b8e80941Smrg assert(type->is_struct()); 807b8e80941Smrg if (this->buffer_block_index == -1) 808b8e80941Smrg return; 809b8e80941Smrg if (packing == GLSL_INTERFACE_PACKING_STD430) 810b8e80941Smrg this->ubo_byte_offset = glsl_align( 811b8e80941Smrg this->ubo_byte_offset, type->std430_base_alignment(row_major)); 812b8e80941Smrg else 813b8e80941Smrg this->ubo_byte_offset = glsl_align( 814b8e80941Smrg this->ubo_byte_offset, type->std140_base_alignment(row_major)); 815b8e80941Smrg } 816b8e80941Smrg 817b8e80941Smrg virtual void visit_field(const glsl_type *type, const char *name, 818b8e80941Smrg bool row_major, const glsl_type * /* record_type */, 819b8e80941Smrg const enum glsl_interface_packing packing, 820b8e80941Smrg bool /* last_field */) 821b8e80941Smrg { 822b8e80941Smrg assert(!type->without_array()->is_struct()); 823b8e80941Smrg assert(!type->without_array()->is_interface()); 824b8e80941Smrg assert(!(type->is_array() && type->fields.array->is_array())); 825b8e80941Smrg 826b8e80941Smrg unsigned id; 827b8e80941Smrg bool found = this->map->get(id, name); 828b8e80941Smrg assert(found); 829b8e80941Smrg 830b8e80941Smrg if (!found) 831b8e80941Smrg return; 832b8e80941Smrg 833b8e80941Smrg const glsl_type *base_type; 834b8e80941Smrg if (type->is_array()) { 835b8e80941Smrg this->uniforms[id].array_elements = type->length; 836b8e80941Smrg base_type = type->fields.array; 837b8e80941Smrg } else { 838b8e80941Smrg this->uniforms[id].array_elements = 0; 839b8e80941Smrg base_type = type; 840b8e80941Smrg } 841b8e80941Smrg 842b8e80941Smrg /* Initialise opaque data */ 843b8e80941Smrg this->uniforms[id].opaque[shader_type].index = ~0; 844b8e80941Smrg this->uniforms[id].opaque[shader_type].active = false; 845b8e80941Smrg 846b8e80941Smrg this->uniforms[id].active_shader_mask |= 1 << shader_type; 847b8e80941Smrg 848b8e80941Smrg /* This assigns uniform indices to sampler and image uniforms. */ 849b8e80941Smrg handle_samplers(base_type, &this->uniforms[id], name); 850b8e80941Smrg handle_images(base_type, &this->uniforms[id], name); 851b8e80941Smrg handle_subroutines(base_type, &this->uniforms[id]); 852b8e80941Smrg 853b8e80941Smrg /* For array of arrays or struct arrays the base location may have 854b8e80941Smrg * already been set so don't set it again. 855b8e80941Smrg */ 856b8e80941Smrg if (buffer_block_index == -1 && current_var->data.location == -1) { 857b8e80941Smrg current_var->data.location = id; 858b8e80941Smrg } 859b8e80941Smrg 860b8e80941Smrg /* If there is already storage associated with this uniform or if the 861b8e80941Smrg * uniform is set as builtin, it means that it was set while processing 862b8e80941Smrg * an earlier shader stage. For example, we may be processing the 863b8e80941Smrg * uniform in the fragment shader, but the uniform was already processed 864b8e80941Smrg * in the vertex shader. 865b8e80941Smrg */ 866b8e80941Smrg if (this->uniforms[id].storage != NULL || this->uniforms[id].builtin) { 867b8e80941Smrg return; 868b8e80941Smrg } 869b8e80941Smrg 870b8e80941Smrg /* Assign explicit locations. */ 871b8e80941Smrg if (current_var->data.explicit_location) { 872b8e80941Smrg /* Set sequential locations for struct fields. */ 873b8e80941Smrg if (current_var->type->without_array()->is_struct() || 874b8e80941Smrg current_var->type->is_array_of_arrays()) { 875b8e80941Smrg const unsigned entries = MAX2(1, this->uniforms[id].array_elements); 876b8e80941Smrg this->uniforms[id].remap_location = 877b8e80941Smrg this->explicit_location + field_counter; 878b8e80941Smrg field_counter += entries; 879b8e80941Smrg } else { 880b8e80941Smrg this->uniforms[id].remap_location = this->explicit_location; 881b8e80941Smrg } 882b8e80941Smrg } else { 883b8e80941Smrg /* Initialize to to indicate that no location is set */ 884b8e80941Smrg this->uniforms[id].remap_location = UNMAPPED_UNIFORM_LOC; 885b8e80941Smrg } 886b8e80941Smrg 887b8e80941Smrg this->uniforms[id].name = ralloc_strdup(this->uniforms, name); 888b8e80941Smrg this->uniforms[id].type = base_type; 889b8e80941Smrg this->uniforms[id].num_driver_storage = 0; 890b8e80941Smrg this->uniforms[id].driver_storage = NULL; 891b8e80941Smrg this->uniforms[id].atomic_buffer_index = -1; 892b8e80941Smrg this->uniforms[id].hidden = 893b8e80941Smrg current_var->data.how_declared == ir_var_hidden; 894b8e80941Smrg this->uniforms[id].builtin = is_gl_identifier(name); 895b8e80941Smrg 896b8e80941Smrg this->uniforms[id].is_shader_storage = 897b8e80941Smrg current_var->is_in_shader_storage_block(); 898b8e80941Smrg this->uniforms[id].is_bindless = current_var->data.bindless; 899b8e80941Smrg 900b8e80941Smrg /* Do not assign storage if the uniform is a builtin or buffer object */ 901b8e80941Smrg if (!this->uniforms[id].builtin && 902b8e80941Smrg !this->uniforms[id].is_shader_storage && 903b8e80941Smrg this->buffer_block_index == -1) 904b8e80941Smrg this->uniforms[id].storage = this->values; 905b8e80941Smrg 906b8e80941Smrg if (this->buffer_block_index != -1) { 907b8e80941Smrg this->uniforms[id].block_index = this->buffer_block_index; 908b8e80941Smrg 909b8e80941Smrg unsigned alignment = type->std140_base_alignment(row_major); 910b8e80941Smrg if (packing == GLSL_INTERFACE_PACKING_STD430) 911b8e80941Smrg alignment = type->std430_base_alignment(row_major); 912b8e80941Smrg this->ubo_byte_offset = glsl_align(this->ubo_byte_offset, alignment); 913b8e80941Smrg this->uniforms[id].offset = this->ubo_byte_offset; 914b8e80941Smrg if (packing == GLSL_INTERFACE_PACKING_STD430) 915b8e80941Smrg this->ubo_byte_offset += type->std430_size(row_major); 916b8e80941Smrg else 917b8e80941Smrg this->ubo_byte_offset += type->std140_size(row_major); 918b8e80941Smrg 919b8e80941Smrg if (type->is_array()) { 920b8e80941Smrg if (packing == GLSL_INTERFACE_PACKING_STD430) 921b8e80941Smrg this->uniforms[id].array_stride = 922b8e80941Smrg type->without_array()->std430_array_stride(row_major); 923b8e80941Smrg else 924b8e80941Smrg this->uniforms[id].array_stride = 925b8e80941Smrg glsl_align(type->without_array()->std140_size(row_major), 926b8e80941Smrg 16); 927b8e80941Smrg } else { 928b8e80941Smrg this->uniforms[id].array_stride = 0; 929b8e80941Smrg } 930b8e80941Smrg 931b8e80941Smrg if (type->without_array()->is_matrix()) { 932b8e80941Smrg this->uniforms[id].matrix_stride = 933b8e80941Smrg link_calculate_matrix_stride(type->without_array(), 934b8e80941Smrg row_major, 935b8e80941Smrg packing); 936b8e80941Smrg this->uniforms[id].row_major = row_major; 937b8e80941Smrg } else { 938b8e80941Smrg this->uniforms[id].matrix_stride = 0; 939b8e80941Smrg this->uniforms[id].row_major = false; 940b8e80941Smrg } 941b8e80941Smrg } else { 942b8e80941Smrg this->uniforms[id].block_index = -1; 943b8e80941Smrg this->uniforms[id].offset = -1; 944b8e80941Smrg this->uniforms[id].array_stride = -1; 945b8e80941Smrg this->uniforms[id].matrix_stride = -1; 946b8e80941Smrg this->uniforms[id].row_major = false; 947b8e80941Smrg } 948b8e80941Smrg 949b8e80941Smrg if (!this->uniforms[id].builtin && 950b8e80941Smrg !this->uniforms[id].is_shader_storage && 951b8e80941Smrg this->buffer_block_index == -1) 952b8e80941Smrg this->values += type->component_slots(); 953b8e80941Smrg } 954b8e80941Smrg 955b8e80941Smrg /** 956b8e80941Smrg * Current program being processed. 957b8e80941Smrg */ 958b8e80941Smrg struct gl_shader_program *prog; 959b8e80941Smrg 960b8e80941Smrg struct string_to_uint_map *map; 961b8e80941Smrg 962b8e80941Smrg struct gl_uniform_storage *uniforms; 963b8e80941Smrg unsigned next_sampler; 964b8e80941Smrg unsigned next_bindless_sampler; 965b8e80941Smrg unsigned next_image; 966b8e80941Smrg unsigned next_bindless_image; 967b8e80941Smrg unsigned next_subroutine; 968b8e80941Smrg 969b8e80941Smrg bool use_std430_as_default; 970b8e80941Smrg 971b8e80941Smrg /** 972b8e80941Smrg * Field counter is used to take care that uniform structures 973b8e80941Smrg * with explicit locations get sequential locations. 974b8e80941Smrg */ 975b8e80941Smrg unsigned field_counter; 976b8e80941Smrg 977b8e80941Smrg /** 978b8e80941Smrg * Current variable being processed. 979b8e80941Smrg */ 980b8e80941Smrg ir_variable *current_var; 981b8e80941Smrg 982b8e80941Smrg /* Used to store the explicit location from current_var so that we can 983b8e80941Smrg * reuse the location field for storing the uniform slot id. 984b8e80941Smrg */ 985b8e80941Smrg int explicit_location; 986b8e80941Smrg 987b8e80941Smrg /* Stores total struct array elements including nested structs */ 988b8e80941Smrg unsigned record_array_count; 989b8e80941Smrg 990b8e80941Smrg /* Map for temporarily storing next sampler index when handling samplers in 991b8e80941Smrg * struct arrays. 992b8e80941Smrg */ 993b8e80941Smrg struct string_to_uint_map *record_next_sampler; 994b8e80941Smrg 995b8e80941Smrg /* Map for temporarily storing next imager index when handling images in 996b8e80941Smrg * struct arrays. 997b8e80941Smrg */ 998b8e80941Smrg struct string_to_uint_map *record_next_image; 999b8e80941Smrg 1000b8e80941Smrg /* Map for temporarily storing next bindless sampler index when handling 1001b8e80941Smrg * bindless samplers in struct arrays. 1002b8e80941Smrg */ 1003b8e80941Smrg struct string_to_uint_map *record_next_bindless_sampler; 1004b8e80941Smrg 1005b8e80941Smrg /* Map for temporarily storing next bindless image index when handling 1006b8e80941Smrg * bindless images in struct arrays. 1007b8e80941Smrg */ 1008b8e80941Smrg struct string_to_uint_map *record_next_bindless_image; 1009b8e80941Smrg 1010b8e80941Smrgpublic: 1011b8e80941Smrg union gl_constant_value *values; 1012b8e80941Smrg 1013b8e80941Smrg gl_texture_index targets[MAX_SAMPLERS]; 1014b8e80941Smrg 1015b8e80941Smrg /** 1016b8e80941Smrg * Mask of samplers used by the current shader stage. 1017b8e80941Smrg */ 1018b8e80941Smrg unsigned shader_samplers_used; 1019b8e80941Smrg 1020b8e80941Smrg /** 1021b8e80941Smrg * Mask of samplers used by the current shader stage for shadows. 1022b8e80941Smrg */ 1023b8e80941Smrg unsigned shader_shadow_samplers; 1024b8e80941Smrg 1025b8e80941Smrg /** 1026b8e80941Smrg * Number of bindless samplers used by the current shader stage. 1027b8e80941Smrg */ 1028b8e80941Smrg unsigned num_bindless_samplers; 1029b8e80941Smrg 1030b8e80941Smrg /** 1031b8e80941Smrg * Texture targets for bindless samplers used by the current stage. 1032b8e80941Smrg */ 1033b8e80941Smrg gl_texture_index *bindless_targets; 1034b8e80941Smrg 1035b8e80941Smrg /** 1036b8e80941Smrg * Number of bindless images used by the current shader stage. 1037b8e80941Smrg */ 1038b8e80941Smrg unsigned num_bindless_images; 1039b8e80941Smrg 1040b8e80941Smrg /** 1041b8e80941Smrg * Access types for bindless images used by the current stage. 1042b8e80941Smrg */ 1043b8e80941Smrg GLenum *bindless_access; 1044b8e80941Smrg 1045b8e80941Smrg /** 1046b8e80941Smrg * Bitmask of shader storage blocks not declared as read-only. 1047b8e80941Smrg */ 1048b8e80941Smrg unsigned shader_storage_blocks_write_access; 1049b8e80941Smrg}; 1050b8e80941Smrg 1051b8e80941Smrgstatic bool 1052b8e80941Smrgvariable_is_referenced(ir_array_refcount_visitor &v, ir_variable *var) 1053b8e80941Smrg{ 1054b8e80941Smrg ir_array_refcount_entry *const entry = v.get_variable_entry(var); 1055b8e80941Smrg 1056b8e80941Smrg return entry->is_referenced; 1057b8e80941Smrg 1058b8e80941Smrg} 1059b8e80941Smrg 1060b8e80941Smrg/** 1061b8e80941Smrg * Walks the IR and update the references to uniform blocks in the 1062b8e80941Smrg * ir_variables to point at linked shader's list (previously, they 1063b8e80941Smrg * would point at the uniform block list in one of the pre-linked 1064b8e80941Smrg * shaders). 1065b8e80941Smrg */ 1066b8e80941Smrgstatic void 1067b8e80941Smrglink_update_uniform_buffer_variables(struct gl_linked_shader *shader, 1068b8e80941Smrg unsigned stage) 1069b8e80941Smrg{ 1070b8e80941Smrg ir_array_refcount_visitor v; 1071b8e80941Smrg 1072b8e80941Smrg v.run(shader->ir); 1073b8e80941Smrg 1074b8e80941Smrg foreach_in_list(ir_instruction, node, shader->ir) { 1075b8e80941Smrg ir_variable *const var = node->as_variable(); 1076b8e80941Smrg 1077b8e80941Smrg if (var == NULL || !var->is_in_buffer_block()) 1078b8e80941Smrg continue; 1079b8e80941Smrg 1080b8e80941Smrg assert(var->data.mode == ir_var_uniform || 1081b8e80941Smrg var->data.mode == ir_var_shader_storage); 1082b8e80941Smrg 1083b8e80941Smrg unsigned num_blocks = var->data.mode == ir_var_uniform ? 1084b8e80941Smrg shader->Program->info.num_ubos : shader->Program->info.num_ssbos; 1085b8e80941Smrg struct gl_uniform_block **blks = var->data.mode == ir_var_uniform ? 1086b8e80941Smrg shader->Program->sh.UniformBlocks : 1087b8e80941Smrg shader->Program->sh.ShaderStorageBlocks; 1088b8e80941Smrg 1089b8e80941Smrg if (var->is_interface_instance()) { 1090b8e80941Smrg const ir_array_refcount_entry *const entry = v.get_variable_entry(var); 1091b8e80941Smrg 1092b8e80941Smrg if (entry->is_referenced) { 1093b8e80941Smrg /* Since this is an interface instance, the instance type will be 1094b8e80941Smrg * same as the array-stripped variable type. If the variable type 1095b8e80941Smrg * is an array, then the block names will be suffixed with [0] 1096b8e80941Smrg * through [n-1]. Unlike for non-interface instances, there will 1097b8e80941Smrg * not be structure types here, so the only name sentinel that we 1098b8e80941Smrg * have to worry about is [. 1099b8e80941Smrg */ 1100b8e80941Smrg assert(var->type->without_array() == var->get_interface_type()); 1101b8e80941Smrg const char sentinel = var->type->is_array() ? '[' : '\0'; 1102b8e80941Smrg 1103b8e80941Smrg const ptrdiff_t len = strlen(var->get_interface_type()->name); 1104b8e80941Smrg for (unsigned i = 0; i < num_blocks; i++) { 1105b8e80941Smrg const char *const begin = blks[i]->Name; 1106b8e80941Smrg const char *const end = strchr(begin, sentinel); 1107b8e80941Smrg 1108b8e80941Smrg if (end == NULL) 1109b8e80941Smrg continue; 1110b8e80941Smrg 1111b8e80941Smrg if (len != (end - begin)) 1112b8e80941Smrg continue; 1113b8e80941Smrg 1114b8e80941Smrg /* Even when a match is found, do not "break" here. This could 1115b8e80941Smrg * be an array of instances, and all elements of the array need 1116b8e80941Smrg * to be marked as referenced. 1117b8e80941Smrg */ 1118b8e80941Smrg if (strncmp(begin, var->get_interface_type()->name, len) == 0 && 1119b8e80941Smrg (!var->type->is_array() || 1120b8e80941Smrg entry->is_linearized_index_referenced(blks[i]->linearized_array_index))) { 1121b8e80941Smrg blks[i]->stageref |= 1U << stage; 1122b8e80941Smrg } 1123b8e80941Smrg } 1124b8e80941Smrg } 1125b8e80941Smrg 1126b8e80941Smrg var->data.location = 0; 1127b8e80941Smrg continue; 1128b8e80941Smrg } 1129b8e80941Smrg 1130b8e80941Smrg bool found = false; 1131b8e80941Smrg char sentinel = '\0'; 1132b8e80941Smrg 1133b8e80941Smrg if (var->type->is_struct()) { 1134b8e80941Smrg sentinel = '.'; 1135b8e80941Smrg } else if (var->type->is_array() && (var->type->fields.array->is_array() 1136b8e80941Smrg || var->type->without_array()->is_struct())) { 1137b8e80941Smrg sentinel = '['; 1138b8e80941Smrg } 1139b8e80941Smrg 1140b8e80941Smrg const unsigned l = strlen(var->name); 1141b8e80941Smrg for (unsigned i = 0; i < num_blocks; i++) { 1142b8e80941Smrg for (unsigned j = 0; j < blks[i]->NumUniforms; j++) { 1143b8e80941Smrg if (sentinel) { 1144b8e80941Smrg const char *begin = blks[i]->Uniforms[j].Name; 1145b8e80941Smrg const char *end = strchr(begin, sentinel); 1146b8e80941Smrg 1147b8e80941Smrg if (end == NULL) 1148b8e80941Smrg continue; 1149b8e80941Smrg 1150b8e80941Smrg if ((ptrdiff_t) l != (end - begin)) 1151b8e80941Smrg continue; 1152b8e80941Smrg 1153b8e80941Smrg found = strncmp(var->name, begin, l) == 0; 1154b8e80941Smrg } else { 1155b8e80941Smrg found = strcmp(var->name, blks[i]->Uniforms[j].Name) == 0; 1156b8e80941Smrg } 1157b8e80941Smrg 1158b8e80941Smrg if (found) { 1159b8e80941Smrg var->data.location = j; 1160b8e80941Smrg 1161b8e80941Smrg if (variable_is_referenced(v, var)) 1162b8e80941Smrg blks[i]->stageref |= 1U << stage; 1163b8e80941Smrg 1164b8e80941Smrg break; 1165b8e80941Smrg } 1166b8e80941Smrg } 1167b8e80941Smrg 1168b8e80941Smrg if (found) 1169b8e80941Smrg break; 1170b8e80941Smrg } 1171b8e80941Smrg assert(found); 1172b8e80941Smrg } 1173b8e80941Smrg} 1174b8e80941Smrg 1175b8e80941Smrg/** 1176b8e80941Smrg * Combine the hidden uniform hash map with the uniform hash map so that the 1177b8e80941Smrg * hidden uniforms will be given indicies at the end of the uniform storage 1178b8e80941Smrg * array. 1179b8e80941Smrg */ 1180b8e80941Smrgstatic void 1181b8e80941Smrgassign_hidden_uniform_slot_id(const char *name, unsigned hidden_id, 1182b8e80941Smrg void *closure) 1183b8e80941Smrg{ 1184b8e80941Smrg count_uniform_size *uniform_size = (count_uniform_size *) closure; 1185b8e80941Smrg unsigned hidden_uniform_start = uniform_size->num_active_uniforms - 1186b8e80941Smrg uniform_size->num_hidden_uniforms; 1187b8e80941Smrg 1188b8e80941Smrg uniform_size->map->put(hidden_uniform_start + hidden_id, name); 1189b8e80941Smrg} 1190b8e80941Smrg 1191b8e80941Smrgstatic void 1192b8e80941Smrglink_setup_uniform_remap_tables(struct gl_context *ctx, 1193b8e80941Smrg struct gl_shader_program *prog) 1194b8e80941Smrg{ 1195b8e80941Smrg unsigned total_entries = prog->NumExplicitUniformLocations; 1196b8e80941Smrg unsigned empty_locs = prog->NumUniformRemapTable - total_entries; 1197b8e80941Smrg 1198b8e80941Smrg /* Reserve all the explicit locations of the active uniforms. */ 1199b8e80941Smrg for (unsigned i = 0; i < prog->data->NumUniformStorage; i++) { 1200b8e80941Smrg if (prog->data->UniformStorage[i].type->is_subroutine() || 1201b8e80941Smrg prog->data->UniformStorage[i].is_shader_storage) 1202b8e80941Smrg continue; 1203b8e80941Smrg 1204b8e80941Smrg if (prog->data->UniformStorage[i].remap_location != 1205b8e80941Smrg UNMAPPED_UNIFORM_LOC) { 1206b8e80941Smrg /* How many new entries for this uniform? */ 1207b8e80941Smrg const unsigned entries = 1208b8e80941Smrg MAX2(1, prog->data->UniformStorage[i].array_elements); 1209b8e80941Smrg 1210b8e80941Smrg /* Set remap table entries point to correct gl_uniform_storage. */ 1211b8e80941Smrg for (unsigned j = 0; j < entries; j++) { 1212b8e80941Smrg unsigned element_loc = 1213b8e80941Smrg prog->data->UniformStorage[i].remap_location + j; 1214b8e80941Smrg assert(prog->UniformRemapTable[element_loc] == 1215b8e80941Smrg INACTIVE_UNIFORM_EXPLICIT_LOCATION); 1216b8e80941Smrg prog->UniformRemapTable[element_loc] = 1217b8e80941Smrg &prog->data->UniformStorage[i]; 1218b8e80941Smrg } 1219b8e80941Smrg } 1220b8e80941Smrg } 1221b8e80941Smrg 1222b8e80941Smrg /* Reserve locations for rest of the uniforms. */ 1223b8e80941Smrg for (unsigned i = 0; i < prog->data->NumUniformStorage; i++) { 1224b8e80941Smrg 1225b8e80941Smrg if (prog->data->UniformStorage[i].type->is_subroutine() || 1226b8e80941Smrg prog->data->UniformStorage[i].is_shader_storage) 1227b8e80941Smrg continue; 1228b8e80941Smrg 1229b8e80941Smrg /* Built-in uniforms should not get any location. */ 1230b8e80941Smrg if (prog->data->UniformStorage[i].builtin) 1231b8e80941Smrg continue; 1232b8e80941Smrg 1233b8e80941Smrg /* Explicit ones have been set already. */ 1234b8e80941Smrg if (prog->data->UniformStorage[i].remap_location != UNMAPPED_UNIFORM_LOC) 1235b8e80941Smrg continue; 1236b8e80941Smrg 1237b8e80941Smrg /* how many new entries for this uniform? */ 1238b8e80941Smrg const unsigned entries = 1239b8e80941Smrg MAX2(1, prog->data->UniformStorage[i].array_elements); 1240b8e80941Smrg 1241b8e80941Smrg /* Find UniformRemapTable for empty blocks where we can fit this uniform. */ 1242b8e80941Smrg int chosen_location = -1; 1243b8e80941Smrg 1244b8e80941Smrg if (empty_locs) 1245b8e80941Smrg chosen_location = link_util_find_empty_block(prog, &prog->data->UniformStorage[i]); 1246b8e80941Smrg 1247b8e80941Smrg /* Add new entries to the total amount for checking against MAX_UNIFORM- 1248b8e80941Smrg * _LOCATIONS. This only applies to the default uniform block (-1), 1249b8e80941Smrg * because locations of uniform block entries are not assignable. 1250b8e80941Smrg */ 1251b8e80941Smrg if (prog->data->UniformStorage[i].block_index == -1) 1252b8e80941Smrg total_entries += entries; 1253b8e80941Smrg 1254b8e80941Smrg if (chosen_location != -1) { 1255b8e80941Smrg empty_locs -= entries; 1256b8e80941Smrg } else { 1257b8e80941Smrg chosen_location = prog->NumUniformRemapTable; 1258b8e80941Smrg 1259b8e80941Smrg /* resize remap table to fit new entries */ 1260b8e80941Smrg prog->UniformRemapTable = 1261b8e80941Smrg reralloc(prog, 1262b8e80941Smrg prog->UniformRemapTable, 1263b8e80941Smrg gl_uniform_storage *, 1264b8e80941Smrg prog->NumUniformRemapTable + entries); 1265b8e80941Smrg prog->NumUniformRemapTable += entries; 1266b8e80941Smrg } 1267b8e80941Smrg 1268b8e80941Smrg /* set pointers for this uniform */ 1269b8e80941Smrg for (unsigned j = 0; j < entries; j++) 1270b8e80941Smrg prog->UniformRemapTable[chosen_location + j] = 1271b8e80941Smrg &prog->data->UniformStorage[i]; 1272b8e80941Smrg 1273b8e80941Smrg /* set the base location in remap table for the uniform */ 1274b8e80941Smrg prog->data->UniformStorage[i].remap_location = chosen_location; 1275b8e80941Smrg } 1276b8e80941Smrg 1277b8e80941Smrg /* Verify that total amount of entries for explicit and implicit locations 1278b8e80941Smrg * is less than MAX_UNIFORM_LOCATIONS. 1279b8e80941Smrg */ 1280b8e80941Smrg 1281b8e80941Smrg if (total_entries > ctx->Const.MaxUserAssignableUniformLocations) { 1282b8e80941Smrg linker_error(prog, "count of uniform locations > MAX_UNIFORM_LOCATIONS" 1283b8e80941Smrg "(%u > %u)", total_entries, 1284b8e80941Smrg ctx->Const.MaxUserAssignableUniformLocations); 1285b8e80941Smrg } 1286b8e80941Smrg 1287b8e80941Smrg /* Reserve all the explicit locations of the active subroutine uniforms. */ 1288b8e80941Smrg for (unsigned i = 0; i < prog->data->NumUniformStorage; i++) { 1289b8e80941Smrg if (!prog->data->UniformStorage[i].type->is_subroutine()) 1290b8e80941Smrg continue; 1291b8e80941Smrg 1292b8e80941Smrg if (prog->data->UniformStorage[i].remap_location == UNMAPPED_UNIFORM_LOC) 1293b8e80941Smrg continue; 1294b8e80941Smrg 1295b8e80941Smrg /* How many new entries for this uniform? */ 1296b8e80941Smrg const unsigned entries = 1297b8e80941Smrg MAX2(1, prog->data->UniformStorage[i].array_elements); 1298b8e80941Smrg 1299b8e80941Smrg unsigned mask = prog->data->linked_stages; 1300b8e80941Smrg while (mask) { 1301b8e80941Smrg const int j = u_bit_scan(&mask); 1302b8e80941Smrg struct gl_program *p = prog->_LinkedShaders[j]->Program; 1303b8e80941Smrg 1304b8e80941Smrg if (!prog->data->UniformStorage[i].opaque[j].active) 1305b8e80941Smrg continue; 1306b8e80941Smrg 1307b8e80941Smrg /* Set remap table entries point to correct gl_uniform_storage. */ 1308b8e80941Smrg for (unsigned k = 0; k < entries; k++) { 1309b8e80941Smrg unsigned element_loc = 1310b8e80941Smrg prog->data->UniformStorage[i].remap_location + k; 1311b8e80941Smrg assert(p->sh.SubroutineUniformRemapTable[element_loc] == 1312b8e80941Smrg INACTIVE_UNIFORM_EXPLICIT_LOCATION); 1313b8e80941Smrg p->sh.SubroutineUniformRemapTable[element_loc] = 1314b8e80941Smrg &prog->data->UniformStorage[i]; 1315b8e80941Smrg } 1316b8e80941Smrg } 1317b8e80941Smrg } 1318b8e80941Smrg 1319b8e80941Smrg /* reserve subroutine locations */ 1320b8e80941Smrg for (unsigned i = 0; i < prog->data->NumUniformStorage; i++) { 1321b8e80941Smrg if (!prog->data->UniformStorage[i].type->is_subroutine()) 1322b8e80941Smrg continue; 1323b8e80941Smrg 1324b8e80941Smrg if (prog->data->UniformStorage[i].remap_location != 1325b8e80941Smrg UNMAPPED_UNIFORM_LOC) 1326b8e80941Smrg continue; 1327b8e80941Smrg 1328b8e80941Smrg const unsigned entries = 1329b8e80941Smrg MAX2(1, prog->data->UniformStorage[i].array_elements); 1330b8e80941Smrg 1331b8e80941Smrg unsigned mask = prog->data->linked_stages; 1332b8e80941Smrg while (mask) { 1333b8e80941Smrg const int j = u_bit_scan(&mask); 1334b8e80941Smrg struct gl_program *p = prog->_LinkedShaders[j]->Program; 1335b8e80941Smrg 1336b8e80941Smrg if (!prog->data->UniformStorage[i].opaque[j].active) 1337b8e80941Smrg continue; 1338b8e80941Smrg 1339b8e80941Smrg p->sh.SubroutineUniformRemapTable = 1340b8e80941Smrg reralloc(p, 1341b8e80941Smrg p->sh.SubroutineUniformRemapTable, 1342b8e80941Smrg gl_uniform_storage *, 1343b8e80941Smrg p->sh.NumSubroutineUniformRemapTable + entries); 1344b8e80941Smrg 1345b8e80941Smrg for (unsigned k = 0; k < entries; k++) { 1346b8e80941Smrg p->sh.SubroutineUniformRemapTable[p->sh.NumSubroutineUniformRemapTable + k] = 1347b8e80941Smrg &prog->data->UniformStorage[i]; 1348b8e80941Smrg } 1349b8e80941Smrg prog->data->UniformStorage[i].remap_location = 1350b8e80941Smrg p->sh.NumSubroutineUniformRemapTable; 1351b8e80941Smrg p->sh.NumSubroutineUniformRemapTable += entries; 1352b8e80941Smrg } 1353b8e80941Smrg } 1354b8e80941Smrg} 1355b8e80941Smrg 1356b8e80941Smrgstatic void 1357b8e80941Smrglink_assign_uniform_storage(struct gl_context *ctx, 1358b8e80941Smrg struct gl_shader_program *prog, 1359b8e80941Smrg const unsigned num_data_slots) 1360b8e80941Smrg{ 1361b8e80941Smrg /* On the outside chance that there were no uniforms, bail out. 1362b8e80941Smrg */ 1363b8e80941Smrg if (prog->data->NumUniformStorage == 0) 1364b8e80941Smrg return; 1365b8e80941Smrg 1366b8e80941Smrg unsigned int boolean_true = ctx->Const.UniformBooleanTrue; 1367b8e80941Smrg 1368b8e80941Smrg union gl_constant_value *data; 1369b8e80941Smrg if (prog->data->UniformStorage == NULL) { 1370b8e80941Smrg prog->data->UniformStorage = rzalloc_array(prog->data, 1371b8e80941Smrg struct gl_uniform_storage, 1372b8e80941Smrg prog->data->NumUniformStorage); 1373b8e80941Smrg data = rzalloc_array(prog->data->UniformStorage, 1374b8e80941Smrg union gl_constant_value, num_data_slots); 1375b8e80941Smrg prog->data->UniformDataDefaults = 1376b8e80941Smrg rzalloc_array(prog->data->UniformStorage, 1377b8e80941Smrg union gl_constant_value, num_data_slots); 1378b8e80941Smrg } else { 1379b8e80941Smrg data = prog->data->UniformDataSlots; 1380b8e80941Smrg } 1381b8e80941Smrg 1382b8e80941Smrg#ifndef NDEBUG 1383b8e80941Smrg union gl_constant_value *data_end = &data[num_data_slots]; 1384b8e80941Smrg#endif 1385b8e80941Smrg 1386b8e80941Smrg parcel_out_uniform_storage parcel(prog, prog->UniformHash, 1387b8e80941Smrg prog->data->UniformStorage, data, 1388b8e80941Smrg ctx->Const.UseSTD430AsDefaultPacking); 1389b8e80941Smrg 1390b8e80941Smrg for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 1391b8e80941Smrg struct gl_linked_shader *shader = prog->_LinkedShaders[i]; 1392b8e80941Smrg 1393b8e80941Smrg if (!shader) 1394b8e80941Smrg continue; 1395b8e80941Smrg 1396b8e80941Smrg parcel.start_shader((gl_shader_stage)i); 1397b8e80941Smrg 1398b8e80941Smrg foreach_in_list(ir_instruction, node, shader->ir) { 1399b8e80941Smrg ir_variable *const var = node->as_variable(); 1400b8e80941Smrg 1401b8e80941Smrg if ((var == NULL) || (var->data.mode != ir_var_uniform && 1402b8e80941Smrg var->data.mode != ir_var_shader_storage)) 1403b8e80941Smrg continue; 1404b8e80941Smrg 1405b8e80941Smrg parcel.set_and_process(var); 1406b8e80941Smrg } 1407b8e80941Smrg 1408b8e80941Smrg shader->Program->SamplersUsed = parcel.shader_samplers_used; 1409b8e80941Smrg shader->shadow_samplers = parcel.shader_shadow_samplers; 1410b8e80941Smrg shader->Program->sh.ShaderStorageBlocksWriteAccess = 1411b8e80941Smrg parcel.shader_storage_blocks_write_access; 1412b8e80941Smrg 1413b8e80941Smrg if (parcel.num_bindless_samplers > 0) { 1414b8e80941Smrg shader->Program->sh.NumBindlessSamplers = parcel.num_bindless_samplers; 1415b8e80941Smrg shader->Program->sh.BindlessSamplers = 1416b8e80941Smrg rzalloc_array(shader->Program, gl_bindless_sampler, 1417b8e80941Smrg parcel.num_bindless_samplers); 1418b8e80941Smrg for (unsigned j = 0; j < parcel.num_bindless_samplers; j++) { 1419b8e80941Smrg shader->Program->sh.BindlessSamplers[j].target = 1420b8e80941Smrg parcel.bindless_targets[j]; 1421b8e80941Smrg } 1422b8e80941Smrg } 1423b8e80941Smrg 1424b8e80941Smrg if (parcel.num_bindless_images > 0) { 1425b8e80941Smrg shader->Program->sh.NumBindlessImages = parcel.num_bindless_images; 1426b8e80941Smrg shader->Program->sh.BindlessImages = 1427b8e80941Smrg rzalloc_array(shader->Program, gl_bindless_image, 1428b8e80941Smrg parcel.num_bindless_images); 1429b8e80941Smrg for (unsigned j = 0; j < parcel.num_bindless_images; j++) { 1430b8e80941Smrg shader->Program->sh.BindlessImages[j].access = 1431b8e80941Smrg parcel.bindless_access[j]; 1432b8e80941Smrg } 1433b8e80941Smrg } 1434b8e80941Smrg 1435b8e80941Smrg STATIC_ASSERT(ARRAY_SIZE(shader->Program->sh.SamplerTargets) == 1436b8e80941Smrg ARRAY_SIZE(parcel.targets)); 1437b8e80941Smrg for (unsigned j = 0; j < ARRAY_SIZE(parcel.targets); j++) 1438b8e80941Smrg shader->Program->sh.SamplerTargets[j] = parcel.targets[j]; 1439b8e80941Smrg } 1440b8e80941Smrg 1441b8e80941Smrg#ifndef NDEBUG 1442b8e80941Smrg for (unsigned i = 0; i < prog->data->NumUniformStorage; i++) { 1443b8e80941Smrg assert(prog->data->UniformStorage[i].storage != NULL || 1444b8e80941Smrg prog->data->UniformStorage[i].builtin || 1445b8e80941Smrg prog->data->UniformStorage[i].is_shader_storage || 1446b8e80941Smrg prog->data->UniformStorage[i].block_index != -1); 1447b8e80941Smrg } 1448b8e80941Smrg 1449b8e80941Smrg assert(parcel.values == data_end); 1450b8e80941Smrg#endif 1451b8e80941Smrg 1452b8e80941Smrg link_setup_uniform_remap_tables(ctx, prog); 1453b8e80941Smrg 1454b8e80941Smrg /* Set shader cache fields */ 1455b8e80941Smrg prog->data->NumUniformDataSlots = num_data_slots; 1456b8e80941Smrg prog->data->UniformDataSlots = data; 1457b8e80941Smrg 1458b8e80941Smrg link_set_uniform_initializers(prog, boolean_true); 1459b8e80941Smrg} 1460b8e80941Smrg 1461b8e80941Smrgvoid 1462b8e80941Smrglink_assign_uniform_locations(struct gl_shader_program *prog, 1463b8e80941Smrg struct gl_context *ctx) 1464b8e80941Smrg{ 1465b8e80941Smrg ralloc_free(prog->data->UniformStorage); 1466b8e80941Smrg prog->data->UniformStorage = NULL; 1467b8e80941Smrg prog->data->NumUniformStorage = 0; 1468b8e80941Smrg 1469b8e80941Smrg if (prog->UniformHash != NULL) { 1470b8e80941Smrg prog->UniformHash->clear(); 1471b8e80941Smrg } else { 1472b8e80941Smrg prog->UniformHash = new string_to_uint_map; 1473b8e80941Smrg } 1474b8e80941Smrg 1475b8e80941Smrg /* First pass: Count the uniform resources used by the user-defined 1476b8e80941Smrg * uniforms. While this happens, each active uniform will have an index 1477b8e80941Smrg * assigned to it. 1478b8e80941Smrg * 1479b8e80941Smrg * Note: this is *NOT* the index that is returned to the application by 1480b8e80941Smrg * glGetUniformLocation. 1481b8e80941Smrg */ 1482b8e80941Smrg struct string_to_uint_map *hiddenUniforms = new string_to_uint_map; 1483b8e80941Smrg count_uniform_size uniform_size(prog->UniformHash, hiddenUniforms, 1484b8e80941Smrg ctx->Const.UseSTD430AsDefaultPacking); 1485b8e80941Smrg for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 1486b8e80941Smrg struct gl_linked_shader *sh = prog->_LinkedShaders[i]; 1487b8e80941Smrg 1488b8e80941Smrg if (sh == NULL) 1489b8e80941Smrg continue; 1490b8e80941Smrg 1491b8e80941Smrg link_update_uniform_buffer_variables(sh, i); 1492b8e80941Smrg 1493b8e80941Smrg /* Reset various per-shader target counts. 1494b8e80941Smrg */ 1495b8e80941Smrg uniform_size.start_shader(); 1496b8e80941Smrg 1497b8e80941Smrg foreach_in_list(ir_instruction, node, sh->ir) { 1498b8e80941Smrg ir_variable *const var = node->as_variable(); 1499b8e80941Smrg 1500b8e80941Smrg if ((var == NULL) || (var->data.mode != ir_var_uniform && 1501b8e80941Smrg var->data.mode != ir_var_shader_storage)) 1502b8e80941Smrg continue; 1503b8e80941Smrg 1504b8e80941Smrg uniform_size.process(var); 1505b8e80941Smrg } 1506b8e80941Smrg 1507b8e80941Smrg sh->Program->info.num_textures = uniform_size.num_shader_samplers; 1508b8e80941Smrg sh->Program->info.num_images = uniform_size.num_shader_images; 1509b8e80941Smrg sh->num_uniform_components = uniform_size.num_shader_uniform_components; 1510b8e80941Smrg sh->num_combined_uniform_components = sh->num_uniform_components; 1511b8e80941Smrg 1512b8e80941Smrg for (unsigned i = 0; i < sh->Program->info.num_ubos; i++) { 1513b8e80941Smrg sh->num_combined_uniform_components += 1514b8e80941Smrg sh->Program->sh.UniformBlocks[i]->UniformBufferSize / 4; 1515b8e80941Smrg } 1516b8e80941Smrg } 1517b8e80941Smrg 1518b8e80941Smrg prog->data->NumUniformStorage = uniform_size.num_active_uniforms; 1519b8e80941Smrg prog->data->NumHiddenUniforms = uniform_size.num_hidden_uniforms; 1520b8e80941Smrg 1521b8e80941Smrg /* assign hidden uniforms a slot id */ 1522b8e80941Smrg hiddenUniforms->iterate(assign_hidden_uniform_slot_id, &uniform_size); 1523b8e80941Smrg delete hiddenUniforms; 1524b8e80941Smrg 1525b8e80941Smrg link_assign_uniform_storage(ctx, prog, uniform_size.num_values); 1526b8e80941Smrg} 1527