Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/compiler/glsl/gl_nir_link_uniforms.c
4545 views
1
/*
2
* Copyright © 2018 Intel Corporation
3
*
4
* Permission is hereby granted, free of charge, to any person obtaining a
5
* copy of this software and associated documentation files (the "Software"),
6
* to deal in the Software without restriction, including without limitation
7
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
* and/or sell copies of the Software, and to permit persons to whom the
9
* Software is furnished to do so, subject to the following conditions:
10
*
11
* The above copyright notice and this permission notice (including the next
12
* paragraph) shall be included in all copies or substantial portions of the
13
* Software.
14
*
15
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21
* IN THE SOFTWARE.
22
*/
23
24
#include "nir.h"
25
#include "nir_deref.h"
26
#include "gl_nir_linker.h"
27
#include "compiler/glsl/ir_uniform.h" /* for gl_uniform_storage */
28
#include "linker_util.h"
29
#include "main/context.h"
30
#include "main/mtypes.h"
31
32
/**
33
* This file do the common link for GLSL uniforms, using NIR, instead of IR as
34
* the counter-part glsl/link_uniforms.cpp
35
*/
36
37
#define UNMAPPED_UNIFORM_LOC ~0u
38
39
struct uniform_array_info {
40
/** List of dereferences of the uniform array. */
41
struct util_dynarray *deref_list;
42
43
/** Set of bit-flags to note which array elements have been accessed. */
44
BITSET_WORD *indices;
45
};
46
47
/**
48
* Built-in / reserved GL variables names start with "gl_"
49
*/
50
static inline bool
51
is_gl_identifier(const char *s)
52
{
53
return s && s[0] == 'g' && s[1] == 'l' && s[2] == '_';
54
}
55
56
static unsigned
57
uniform_storage_size(const struct glsl_type *type)
58
{
59
switch (glsl_get_base_type(type)) {
60
case GLSL_TYPE_STRUCT:
61
case GLSL_TYPE_INTERFACE: {
62
unsigned size = 0;
63
for (unsigned i = 0; i < glsl_get_length(type); i++)
64
size += uniform_storage_size(glsl_get_struct_field(type, i));
65
return size;
66
}
67
case GLSL_TYPE_ARRAY: {
68
const struct glsl_type *e_type = glsl_get_array_element(type);
69
enum glsl_base_type e_base_type = glsl_get_base_type(e_type);
70
if (e_base_type == GLSL_TYPE_STRUCT ||
71
e_base_type == GLSL_TYPE_INTERFACE ||
72
e_base_type == GLSL_TYPE_ARRAY) {
73
unsigned length = !glsl_type_is_unsized_array(type) ?
74
glsl_get_length(type) : 1;
75
return length * uniform_storage_size(e_type);
76
} else
77
return 1;
78
}
79
default:
80
return 1;
81
}
82
}
83
84
/**
85
* Update the sizes of linked shader uniform arrays to the maximum
86
* array index used.
87
*
88
* From page 81 (page 95 of the PDF) of the OpenGL 2.1 spec:
89
*
90
* If one or more elements of an array are active,
91
* GetActiveUniform will return the name of the array in name,
92
* subject to the restrictions listed above. The type of the array
93
* is returned in type. The size parameter contains the highest
94
* array element index used, plus one. The compiler or linker
95
* determines the highest index used. There will be only one
96
* active uniform reported by the GL per uniform array.
97
*/
98
static void
99
update_array_sizes(struct gl_shader_program *prog, nir_variable *var,
100
struct hash_table **referenced_uniforms,
101
unsigned current_var_stage)
102
{
103
/* For now we only resize 1D arrays.
104
* TODO: add support for resizing more complex array types ??
105
*/
106
if (!glsl_type_is_array(var->type) ||
107
glsl_type_is_array(glsl_get_array_element(var->type)))
108
return;
109
110
/* GL_ARB_uniform_buffer_object says that std140 uniforms
111
* will not be eliminated. Since we always do std140, just
112
* don't resize arrays in UBOs.
113
*
114
* Atomic counters are supposed to get deterministic
115
* locations assigned based on the declaration ordering and
116
* sizes, array compaction would mess that up.
117
*
118
* Subroutine uniforms are not removed.
119
*/
120
if (nir_variable_is_in_block(var) || glsl_contains_atomic(var->type) ||
121
glsl_get_base_type(glsl_without_array(var->type)) == GLSL_TYPE_SUBROUTINE ||
122
var->constant_initializer)
123
return;
124
125
struct uniform_array_info *ainfo = NULL;
126
int words = BITSET_WORDS(glsl_array_size(var->type));
127
int max_array_size = 0;
128
for (unsigned stage = 0; stage < MESA_SHADER_STAGES; stage++) {
129
struct gl_linked_shader *sh = prog->_LinkedShaders[stage];
130
if (!sh)
131
continue;
132
133
struct hash_entry *entry =
134
_mesa_hash_table_search(referenced_uniforms[stage], var->name);
135
if (entry) {
136
ainfo = (struct uniform_array_info *) entry->data;
137
max_array_size = MAX2(BITSET_LAST_BIT_SIZED(ainfo->indices, words),
138
max_array_size);
139
}
140
141
if (max_array_size == glsl_array_size(var->type))
142
return;
143
}
144
145
if (max_array_size != glsl_array_size(var->type)) {
146
/* If this is a built-in uniform (i.e., it's backed by some
147
* fixed-function state), adjust the number of state slots to
148
* match the new array size. The number of slots per array entry
149
* is not known. It seems safe to assume that the total number of
150
* slots is an integer multiple of the number of array elements.
151
* Determine the number of slots per array element by dividing by
152
* the old (total) size.
153
*/
154
const unsigned num_slots = var->num_state_slots;
155
if (num_slots > 0) {
156
var->num_state_slots =
157
(max_array_size * (num_slots / glsl_array_size(var->type)));
158
}
159
160
var->type = glsl_array_type(glsl_get_array_element(var->type),
161
max_array_size, 0);
162
163
/* Update the types of dereferences in case we changed any. */
164
struct hash_entry *entry =
165
_mesa_hash_table_search(referenced_uniforms[current_var_stage], var->name);
166
if (entry) {
167
struct uniform_array_info *ainfo =
168
(struct uniform_array_info *) entry->data;
169
util_dynarray_foreach(ainfo->deref_list, nir_deref_instr *, deref) {
170
(*deref)->type = var->type;
171
}
172
}
173
}
174
}
175
176
static void
177
nir_setup_uniform_remap_tables(struct gl_context *ctx,
178
struct gl_shader_program *prog)
179
{
180
unsigned total_entries = prog->NumExplicitUniformLocations;
181
182
/* For glsl this may have been allocated by reserve_explicit_locations() so
183
* that we can keep track of unused uniforms with explicit locations.
184
*/
185
assert(!prog->data->spirv ||
186
(prog->data->spirv && !prog->UniformRemapTable));
187
if (!prog->UniformRemapTable) {
188
prog->UniformRemapTable = rzalloc_array(prog,
189
struct gl_uniform_storage *,
190
prog->NumUniformRemapTable);
191
}
192
193
union gl_constant_value *data =
194
rzalloc_array(prog->data,
195
union gl_constant_value, prog->data->NumUniformDataSlots);
196
if (!prog->UniformRemapTable || !data) {
197
linker_error(prog, "Out of memory during linking.\n");
198
return;
199
}
200
prog->data->UniformDataSlots = data;
201
202
prog->data->UniformDataDefaults =
203
rzalloc_array(prog->data->UniformDataSlots,
204
union gl_constant_value, prog->data->NumUniformDataSlots);
205
206
unsigned data_pos = 0;
207
208
/* Reserve all the explicit locations of the active uniforms. */
209
for (unsigned i = 0; i < prog->data->NumUniformStorage; i++) {
210
struct gl_uniform_storage *uniform = &prog->data->UniformStorage[i];
211
212
if (uniform->is_shader_storage ||
213
glsl_get_base_type(uniform->type) == GLSL_TYPE_SUBROUTINE)
214
continue;
215
216
if (prog->data->UniformStorage[i].remap_location == UNMAPPED_UNIFORM_LOC)
217
continue;
218
219
/* How many new entries for this uniform? */
220
const unsigned entries = MAX2(1, uniform->array_elements);
221
unsigned num_slots = glsl_get_component_slots(uniform->type);
222
223
uniform->storage = &data[data_pos];
224
225
/* Set remap table entries point to correct gl_uniform_storage. */
226
for (unsigned j = 0; j < entries; j++) {
227
unsigned element_loc = uniform->remap_location + j;
228
prog->UniformRemapTable[element_loc] = uniform;
229
230
data_pos += num_slots;
231
}
232
}
233
234
/* Reserve locations for rest of the uniforms. */
235
if (prog->data->spirv)
236
link_util_update_empty_uniform_locations(prog);
237
238
for (unsigned i = 0; i < prog->data->NumUniformStorage; i++) {
239
struct gl_uniform_storage *uniform = &prog->data->UniformStorage[i];
240
241
if (uniform->is_shader_storage ||
242
glsl_get_base_type(uniform->type) == GLSL_TYPE_SUBROUTINE)
243
continue;
244
245
/* Built-in uniforms should not get any location. */
246
if (uniform->builtin)
247
continue;
248
249
/* Explicit ones have been set already. */
250
if (uniform->remap_location != UNMAPPED_UNIFORM_LOC)
251
continue;
252
253
/* How many entries for this uniform? */
254
const unsigned entries = MAX2(1, uniform->array_elements);
255
256
/* Add new entries to the total amount for checking against MAX_UNIFORM-
257
* _LOCATIONS. This only applies to the default uniform block (-1),
258
* because locations of uniform block entries are not assignable.
259
*/
260
if (prog->data->UniformStorage[i].block_index == -1)
261
total_entries += entries;
262
263
unsigned location =
264
link_util_find_empty_block(prog, &prog->data->UniformStorage[i]);
265
266
if (location == -1) {
267
location = prog->NumUniformRemapTable;
268
269
/* resize remap table to fit new entries */
270
prog->UniformRemapTable =
271
reralloc(prog,
272
prog->UniformRemapTable,
273
struct gl_uniform_storage *,
274
prog->NumUniformRemapTable + entries);
275
prog->NumUniformRemapTable += entries;
276
}
277
278
/* set the base location in remap table for the uniform */
279
uniform->remap_location = location;
280
281
unsigned num_slots = glsl_get_component_slots(uniform->type);
282
283
if (uniform->block_index == -1)
284
uniform->storage = &data[data_pos];
285
286
/* Set remap table entries point to correct gl_uniform_storage. */
287
for (unsigned j = 0; j < entries; j++) {
288
unsigned element_loc = uniform->remap_location + j;
289
prog->UniformRemapTable[element_loc] = uniform;
290
291
if (uniform->block_index == -1)
292
data_pos += num_slots;
293
}
294
}
295
296
/* Verify that total amount of entries for explicit and implicit locations
297
* is less than MAX_UNIFORM_LOCATIONS.
298
*/
299
if (total_entries > ctx->Const.MaxUserAssignableUniformLocations) {
300
linker_error(prog, "count of uniform locations > MAX_UNIFORM_LOCATIONS"
301
"(%u > %u)", total_entries,
302
ctx->Const.MaxUserAssignableUniformLocations);
303
}
304
305
/* Reserve all the explicit locations of the active subroutine uniforms. */
306
for (unsigned i = 0; i < prog->data->NumUniformStorage; i++) {
307
struct gl_uniform_storage *uniform = &prog->data->UniformStorage[i];
308
309
if (glsl_get_base_type(uniform->type) != GLSL_TYPE_SUBROUTINE)
310
continue;
311
312
if (prog->data->UniformStorage[i].remap_location == UNMAPPED_UNIFORM_LOC)
313
continue;
314
315
/* How many new entries for this uniform? */
316
const unsigned entries =
317
MAX2(1, prog->data->UniformStorage[i].array_elements);
318
319
uniform->storage = &data[data_pos];
320
321
unsigned num_slots = glsl_get_component_slots(uniform->type);
322
unsigned mask = prog->data->linked_stages;
323
while (mask) {
324
const int j = u_bit_scan(&mask);
325
struct gl_program *p = prog->_LinkedShaders[j]->Program;
326
327
if (!prog->data->UniformStorage[i].opaque[j].active)
328
continue;
329
330
/* Set remap table entries point to correct gl_uniform_storage. */
331
for (unsigned k = 0; k < entries; k++) {
332
unsigned element_loc =
333
prog->data->UniformStorage[i].remap_location + k;
334
p->sh.SubroutineUniformRemapTable[element_loc] =
335
&prog->data->UniformStorage[i];
336
337
data_pos += num_slots;
338
}
339
}
340
}
341
342
/* reserve subroutine locations */
343
for (unsigned i = 0; i < prog->data->NumUniformStorage; i++) {
344
struct gl_uniform_storage *uniform = &prog->data->UniformStorage[i];
345
346
if (glsl_get_base_type(uniform->type) != GLSL_TYPE_SUBROUTINE)
347
continue;
348
349
if (prog->data->UniformStorage[i].remap_location !=
350
UNMAPPED_UNIFORM_LOC)
351
continue;
352
353
const unsigned entries =
354
MAX2(1, prog->data->UniformStorage[i].array_elements);
355
356
uniform->storage = &data[data_pos];
357
358
unsigned num_slots = glsl_get_component_slots(uniform->type);
359
unsigned mask = prog->data->linked_stages;
360
while (mask) {
361
const int j = u_bit_scan(&mask);
362
struct gl_program *p = prog->_LinkedShaders[j]->Program;
363
364
if (!prog->data->UniformStorage[i].opaque[j].active)
365
continue;
366
367
p->sh.SubroutineUniformRemapTable =
368
reralloc(p,
369
p->sh.SubroutineUniformRemapTable,
370
struct gl_uniform_storage *,
371
p->sh.NumSubroutineUniformRemapTable + entries);
372
373
for (unsigned k = 0; k < entries; k++) {
374
p->sh.SubroutineUniformRemapTable[p->sh.NumSubroutineUniformRemapTable + k] =
375
&prog->data->UniformStorage[i];
376
377
data_pos += num_slots;
378
}
379
prog->data->UniformStorage[i].remap_location =
380
p->sh.NumSubroutineUniformRemapTable;
381
p->sh.NumSubroutineUniformRemapTable += entries;
382
}
383
}
384
}
385
386
static void
387
add_var_use_deref(nir_deref_instr *deref, struct hash_table *live,
388
struct array_deref_range **derefs, unsigned *derefs_size)
389
{
390
nir_deref_path path;
391
nir_deref_path_init(&path, deref, NULL);
392
393
deref = path.path[0];
394
if (deref->deref_type != nir_deref_type_var ||
395
!nir_deref_mode_is_one_of(deref, nir_var_uniform |
396
nir_var_mem_ubo |
397
nir_var_mem_ssbo)) {
398
nir_deref_path_finish(&path);
399
return;
400
}
401
402
/* Number of derefs used in current processing. */
403
unsigned num_derefs = 0;
404
405
const struct glsl_type *deref_type = deref->var->type;
406
nir_deref_instr **p = &path.path[1];
407
for (; *p; p++) {
408
if ((*p)->deref_type == nir_deref_type_array) {
409
410
/* Skip matrix derefences */
411
if (!glsl_type_is_array(deref_type))
412
break;
413
414
if ((num_derefs + 1) * sizeof(struct array_deref_range) > *derefs_size) {
415
void *ptr = reralloc_size(NULL, *derefs, *derefs_size + 4096);
416
417
if (ptr == NULL) {
418
nir_deref_path_finish(&path);
419
return;
420
}
421
422
*derefs_size += 4096;
423
*derefs = (struct array_deref_range *)ptr;
424
}
425
426
struct array_deref_range *dr = &(*derefs)[num_derefs];
427
num_derefs++;
428
429
dr->size = glsl_get_length(deref_type);
430
431
if (nir_src_is_const((*p)->arr.index)) {
432
dr->index = nir_src_as_uint((*p)->arr.index);
433
} else {
434
/* An unsized array can occur at the end of an SSBO. We can't track
435
* accesses to such an array, so bail.
436
*/
437
if (dr->size == 0) {
438
nir_deref_path_finish(&path);
439
return;
440
}
441
442
dr->index = dr->size;
443
}
444
445
deref_type = glsl_get_array_element(deref_type);
446
} else if ((*p)->deref_type == nir_deref_type_struct) {
447
/* We have reached the end of the array. */
448
break;
449
}
450
}
451
452
nir_deref_path_finish(&path);
453
454
455
struct uniform_array_info *ainfo = NULL;
456
457
struct hash_entry *entry =
458
_mesa_hash_table_search(live, deref->var->name);
459
if (!entry && glsl_type_is_array(deref->var->type)) {
460
ainfo = ralloc(live, struct uniform_array_info);
461
462
unsigned num_bits = MAX2(1, glsl_get_aoa_size(deref->var->type));
463
ainfo->indices = rzalloc_array(live, BITSET_WORD, BITSET_WORDS(num_bits));
464
465
ainfo->deref_list = ralloc(live, struct util_dynarray);
466
util_dynarray_init(ainfo->deref_list, live);
467
}
468
469
if (entry)
470
ainfo = (struct uniform_array_info *) entry->data;
471
472
if (glsl_type_is_array(deref->var->type)) {
473
/* Count the "depth" of the arrays-of-arrays. */
474
unsigned array_depth = 0;
475
for (const struct glsl_type *type = deref->var->type;
476
glsl_type_is_array(type);
477
type = glsl_get_array_element(type)) {
478
array_depth++;
479
}
480
481
link_util_mark_array_elements_referenced(*derefs, num_derefs, array_depth,
482
ainfo->indices);
483
484
util_dynarray_append(ainfo->deref_list, nir_deref_instr *, deref);
485
}
486
487
assert(deref->modes == deref->var->data.mode);
488
_mesa_hash_table_insert(live, deref->var->name, ainfo);
489
}
490
491
/* Iterate over the shader and collect infomation about uniform use */
492
static void
493
add_var_use_shader(nir_shader *shader, struct hash_table *live)
494
{
495
/* Currently allocated buffer block of derefs. */
496
struct array_deref_range *derefs = NULL;
497
498
/* Size of the derefs buffer in bytes. */
499
unsigned derefs_size = 0;
500
501
nir_foreach_function(function, shader) {
502
if (function->impl) {
503
nir_foreach_block(block, function->impl) {
504
nir_foreach_instr(instr, block) {
505
if (instr->type == nir_instr_type_intrinsic) {
506
nir_intrinsic_instr *intr = nir_instr_as_intrinsic(instr);
507
switch (intr->intrinsic) {
508
case nir_intrinsic_atomic_counter_read_deref:
509
case nir_intrinsic_atomic_counter_inc_deref:
510
case nir_intrinsic_atomic_counter_pre_dec_deref:
511
case nir_intrinsic_atomic_counter_post_dec_deref:
512
case nir_intrinsic_atomic_counter_add_deref:
513
case nir_intrinsic_atomic_counter_min_deref:
514
case nir_intrinsic_atomic_counter_max_deref:
515
case nir_intrinsic_atomic_counter_and_deref:
516
case nir_intrinsic_atomic_counter_or_deref:
517
case nir_intrinsic_atomic_counter_xor_deref:
518
case nir_intrinsic_atomic_counter_exchange_deref:
519
case nir_intrinsic_atomic_counter_comp_swap_deref:
520
case nir_intrinsic_image_deref_load:
521
case nir_intrinsic_image_deref_store:
522
case nir_intrinsic_image_deref_atomic_add:
523
case nir_intrinsic_image_deref_atomic_umin:
524
case nir_intrinsic_image_deref_atomic_imin:
525
case nir_intrinsic_image_deref_atomic_umax:
526
case nir_intrinsic_image_deref_atomic_imax:
527
case nir_intrinsic_image_deref_atomic_and:
528
case nir_intrinsic_image_deref_atomic_or:
529
case nir_intrinsic_image_deref_atomic_xor:
530
case nir_intrinsic_image_deref_atomic_exchange:
531
case nir_intrinsic_image_deref_atomic_comp_swap:
532
case nir_intrinsic_image_deref_size:
533
case nir_intrinsic_image_deref_samples:
534
case nir_intrinsic_load_deref:
535
case nir_intrinsic_store_deref:
536
add_var_use_deref(nir_src_as_deref(intr->src[0]), live,
537
&derefs, &derefs_size);
538
break;
539
540
default:
541
/* Nothing to do */
542
break;
543
}
544
} else if (instr->type == nir_instr_type_tex) {
545
nir_tex_instr *tex_instr = nir_instr_as_tex(instr);
546
int sampler_idx =
547
nir_tex_instr_src_index(tex_instr,
548
nir_tex_src_sampler_deref);
549
int texture_idx =
550
nir_tex_instr_src_index(tex_instr,
551
nir_tex_src_texture_deref);
552
553
if (sampler_idx >= 0) {
554
nir_deref_instr *deref =
555
nir_src_as_deref(tex_instr->src[sampler_idx].src);
556
add_var_use_deref(deref, live, &derefs, &derefs_size);
557
}
558
559
if (texture_idx >= 0) {
560
nir_deref_instr *deref =
561
nir_src_as_deref(tex_instr->src[texture_idx].src);
562
add_var_use_deref(deref, live, &derefs, &derefs_size);
563
}
564
}
565
}
566
}
567
}
568
}
569
570
ralloc_free(derefs);
571
}
572
573
static void
574
mark_stage_as_active(struct gl_uniform_storage *uniform,
575
unsigned stage)
576
{
577
uniform->active_shader_mask |= 1 << stage;
578
}
579
580
/* Used to build a tree representing the glsl_type so that we can have a place
581
* to store the next index for opaque types. Array types are expanded so that
582
* they have a single child which is used for all elements of the array.
583
* Struct types have a child for each member. The tree is walked while
584
* processing a uniform so that we can recognise when an opaque type is
585
* encountered a second time in order to reuse the same range of indices that
586
* was reserved the first time. That way the sampler indices can be arranged
587
* so that members of an array are placed sequentially even if the array is an
588
* array of structs containing other opaque members.
589
*/
590
struct type_tree_entry {
591
/* For opaque types, this will be the next index to use. If we haven’t
592
* encountered this member yet, it will be UINT_MAX.
593
*/
594
unsigned next_index;
595
unsigned array_size;
596
struct type_tree_entry *parent;
597
struct type_tree_entry *next_sibling;
598
struct type_tree_entry *children;
599
};
600
601
struct nir_link_uniforms_state {
602
/* per-whole program */
603
unsigned num_hidden_uniforms;
604
unsigned num_values;
605
unsigned max_uniform_location;
606
607
/* per-shader stage */
608
unsigned next_bindless_image_index;
609
unsigned next_bindless_sampler_index;
610
unsigned next_image_index;
611
unsigned next_sampler_index;
612
unsigned next_subroutine;
613
unsigned num_shader_samplers;
614
unsigned num_shader_images;
615
unsigned num_shader_uniform_components;
616
unsigned shader_samplers_used;
617
unsigned shader_shadow_samplers;
618
unsigned shader_storage_blocks_write_access;
619
struct gl_program_parameter_list *params;
620
621
/* per-variable */
622
nir_variable *current_var;
623
const struct glsl_type *current_ifc_type;
624
int offset;
625
bool var_is_in_block;
626
bool set_top_level_array;
627
int top_level_array_size;
628
int top_level_array_stride;
629
630
struct type_tree_entry *current_type;
631
struct hash_table *referenced_uniforms[MESA_SHADER_STAGES];
632
struct hash_table *uniform_hash;
633
};
634
635
static void
636
add_parameter(struct gl_uniform_storage *uniform,
637
struct gl_context *ctx,
638
struct gl_shader_program *prog,
639
const struct glsl_type *type,
640
struct nir_link_uniforms_state *state)
641
{
642
/* Builtin uniforms are backed by PROGRAM_STATE_VAR, so don't add them as
643
* uniforms.
644
*/
645
if (uniform->builtin)
646
return;
647
648
if (!state->params || uniform->is_shader_storage ||
649
(glsl_contains_opaque(type) && !state->current_var->data.bindless))
650
return;
651
652
unsigned num_params = glsl_get_aoa_size(type);
653
num_params = MAX2(num_params, 1);
654
num_params *= glsl_get_matrix_columns(glsl_without_array(type));
655
656
bool is_dual_slot = glsl_type_is_dual_slot(glsl_without_array(type));
657
if (is_dual_slot)
658
num_params *= 2;
659
660
struct gl_program_parameter_list *params = state->params;
661
int base_index = params->NumParameters;
662
_mesa_reserve_parameter_storage(params, num_params, num_params);
663
664
if (ctx->Const.PackedDriverUniformStorage) {
665
for (unsigned i = 0; i < num_params; i++) {
666
unsigned dmul = glsl_type_is_64bit(glsl_without_array(type)) ? 2 : 1;
667
unsigned comps = glsl_get_vector_elements(glsl_without_array(type)) * dmul;
668
if (is_dual_slot) {
669
if (i & 0x1)
670
comps -= 4;
671
else
672
comps = 4;
673
}
674
675
/* TODO: This will waste space with 1 and 3 16-bit components. */
676
if (glsl_type_is_16bit(glsl_without_array(type)))
677
comps = DIV_ROUND_UP(comps, 2);
678
679
_mesa_add_parameter(params, PROGRAM_UNIFORM, uniform->name, comps,
680
glsl_get_gl_type(type), NULL, NULL, false);
681
}
682
} else {
683
for (unsigned i = 0; i < num_params; i++) {
684
_mesa_add_parameter(params, PROGRAM_UNIFORM, uniform->name, 4,
685
glsl_get_gl_type(type), NULL, NULL, true);
686
}
687
}
688
689
/* Each Parameter will hold the index to the backing uniform storage.
690
* This avoids relying on names to match parameters and uniform
691
* storages.
692
*/
693
for (unsigned i = 0; i < num_params; i++) {
694
struct gl_program_parameter *param = &params->Parameters[base_index + i];
695
param->UniformStorageIndex = uniform - prog->data->UniformStorage;
696
param->MainUniformStorageIndex = state->current_var->data.location;
697
}
698
}
699
700
static unsigned
701
get_next_index(struct nir_link_uniforms_state *state,
702
const struct gl_uniform_storage *uniform,
703
unsigned *next_index, bool *initialised)
704
{
705
/* If we’ve already calculated an index for this member then we can just
706
* offset from there.
707
*/
708
if (state->current_type->next_index == UINT_MAX) {
709
/* Otherwise we need to reserve enough indices for all of the arrays
710
* enclosing this member.
711
*/
712
713
unsigned array_size = 1;
714
715
for (const struct type_tree_entry *p = state->current_type;
716
p;
717
p = p->parent) {
718
array_size *= p->array_size;
719
}
720
721
state->current_type->next_index = *next_index;
722
*next_index += array_size;
723
*initialised = true;
724
} else
725
*initialised = false;
726
727
unsigned index = state->current_type->next_index;
728
729
state->current_type->next_index += MAX2(1, uniform->array_elements);
730
731
return index;
732
}
733
734
/* Update the uniforms info for the current shader stage */
735
static void
736
update_uniforms_shader_info(struct gl_shader_program *prog,
737
struct nir_link_uniforms_state *state,
738
struct gl_uniform_storage *uniform,
739
const struct glsl_type *type,
740
unsigned stage)
741
{
742
unsigned values = glsl_get_component_slots(type);
743
const struct glsl_type *type_no_array = glsl_without_array(type);
744
745
if (glsl_type_is_sampler(type_no_array)) {
746
bool init_idx;
747
unsigned *next_index = state->current_var->data.bindless ?
748
&state->next_bindless_sampler_index :
749
&state->next_sampler_index;
750
int sampler_index = get_next_index(state, uniform, next_index, &init_idx);
751
struct gl_linked_shader *sh = prog->_LinkedShaders[stage];
752
753
if (state->current_var->data.bindless) {
754
if (init_idx) {
755
sh->Program->sh.BindlessSamplers =
756
rerzalloc(sh->Program, sh->Program->sh.BindlessSamplers,
757
struct gl_bindless_sampler,
758
sh->Program->sh.NumBindlessSamplers,
759
state->next_bindless_sampler_index);
760
761
for (unsigned j = sh->Program->sh.NumBindlessSamplers;
762
j < state->next_bindless_sampler_index; j++) {
763
sh->Program->sh.BindlessSamplers[j].target =
764
glsl_get_sampler_target(type_no_array);
765
}
766
767
sh->Program->sh.NumBindlessSamplers =
768
state->next_bindless_sampler_index;
769
}
770
771
if (!state->var_is_in_block)
772
state->num_shader_uniform_components += values;
773
} else {
774
/* Samplers (bound or bindless) are counted as two components
775
* as specified by ARB_bindless_texture.
776
*/
777
state->num_shader_samplers += values / 2;
778
779
if (init_idx) {
780
const unsigned shadow = glsl_sampler_type_is_shadow(type_no_array);
781
for (unsigned i = sampler_index;
782
i < MIN2(state->next_sampler_index, MAX_SAMPLERS); i++) {
783
sh->Program->sh.SamplerTargets[i] =
784
glsl_get_sampler_target(type_no_array);
785
state->shader_samplers_used |= 1U << i;
786
state->shader_shadow_samplers |= shadow << i;
787
}
788
}
789
}
790
791
uniform->opaque[stage].active = true;
792
uniform->opaque[stage].index = sampler_index;
793
} else if (glsl_type_is_image(type_no_array)) {
794
struct gl_linked_shader *sh = prog->_LinkedShaders[stage];
795
796
/* Set image access qualifiers */
797
enum gl_access_qualifier image_access =
798
state->current_var->data.access;
799
const GLenum access =
800
(image_access & ACCESS_NON_WRITEABLE) ?
801
((image_access & ACCESS_NON_READABLE) ? GL_NONE :
802
GL_READ_ONLY) :
803
((image_access & ACCESS_NON_READABLE) ? GL_WRITE_ONLY :
804
GL_READ_WRITE);
805
806
int image_index;
807
if (state->current_var->data.bindless) {
808
image_index = state->next_bindless_image_index;
809
state->next_bindless_image_index += MAX2(1, uniform->array_elements);
810
811
sh->Program->sh.BindlessImages =
812
rerzalloc(sh->Program, sh->Program->sh.BindlessImages,
813
struct gl_bindless_image,
814
sh->Program->sh.NumBindlessImages,
815
state->next_bindless_image_index);
816
817
for (unsigned j = sh->Program->sh.NumBindlessImages;
818
j < state->next_bindless_image_index; j++) {
819
sh->Program->sh.BindlessImages[j].access = access;
820
}
821
822
sh->Program->sh.NumBindlessImages = state->next_bindless_image_index;
823
824
} else {
825
image_index = state->next_image_index;
826
state->next_image_index += MAX2(1, uniform->array_elements);
827
828
/* Images (bound or bindless) are counted as two components as
829
* specified by ARB_bindless_texture.
830
*/
831
state->num_shader_images += values / 2;
832
833
for (unsigned i = image_index;
834
i < MIN2(state->next_image_index, MAX_IMAGE_UNIFORMS); i++) {
835
sh->Program->sh.ImageAccess[i] = access;
836
}
837
}
838
839
uniform->opaque[stage].active = true;
840
uniform->opaque[stage].index = image_index;
841
842
if (!uniform->is_shader_storage)
843
state->num_shader_uniform_components += values;
844
} else {
845
if (glsl_get_base_type(type_no_array) == GLSL_TYPE_SUBROUTINE) {
846
struct gl_linked_shader *sh = prog->_LinkedShaders[stage];
847
848
uniform->opaque[stage].index = state->next_subroutine;
849
uniform->opaque[stage].active = true;
850
851
sh->Program->sh.NumSubroutineUniforms++;
852
853
/* Increment the subroutine index by 1 for non-arrays and by the
854
* number of array elements for arrays.
855
*/
856
state->next_subroutine += MAX2(1, uniform->array_elements);
857
}
858
859
if (!state->var_is_in_block)
860
state->num_shader_uniform_components += values;
861
}
862
}
863
864
static bool
865
find_and_update_named_uniform_storage(struct gl_context *ctx,
866
struct gl_shader_program *prog,
867
struct nir_link_uniforms_state *state,
868
nir_variable *var, char **name,
869
size_t name_length,
870
const struct glsl_type *type,
871
unsigned stage, bool *first_element)
872
{
873
/* gl_uniform_storage can cope with one level of array, so if the type is a
874
* composite type or an array where each element occupies more than one
875
* location than we need to recursively process it.
876
*/
877
if (glsl_type_is_struct_or_ifc(type) ||
878
(glsl_type_is_array(type) &&
879
(glsl_type_is_array(glsl_get_array_element(type)) ||
880
glsl_type_is_struct_or_ifc(glsl_get_array_element(type))))) {
881
882
struct type_tree_entry *old_type = state->current_type;
883
state->current_type = old_type->children;
884
885
/* Shader storage block unsized arrays: add subscript [0] to variable
886
* names.
887
*/
888
unsigned length = glsl_get_length(type);
889
if (glsl_type_is_unsized_array(type))
890
length = 1;
891
892
bool result = false;
893
for (unsigned i = 0; i < length; i++) {
894
const struct glsl_type *field_type;
895
size_t new_length = name_length;
896
897
if (glsl_type_is_struct_or_ifc(type)) {
898
field_type = glsl_get_struct_field(type, i);
899
900
/* Append '.field' to the current variable name. */
901
if (name) {
902
ralloc_asprintf_rewrite_tail(name, &new_length, ".%s",
903
glsl_get_struct_elem_name(type, i));
904
}
905
} else {
906
field_type = glsl_get_array_element(type);
907
908
/* Append the subscript to the current variable name */
909
if (name)
910
ralloc_asprintf_rewrite_tail(name, &new_length, "[%u]", i);
911
}
912
913
result = find_and_update_named_uniform_storage(ctx, prog, state,
914
var, name, new_length,
915
field_type, stage,
916
first_element);
917
918
if (glsl_type_is_struct_or_ifc(type))
919
state->current_type = state->current_type->next_sibling;
920
921
if (!result) {
922
state->current_type = old_type;
923
return false;
924
}
925
}
926
927
state->current_type = old_type;
928
929
return result;
930
} else {
931
struct hash_entry *entry =
932
_mesa_hash_table_search(state->uniform_hash, *name);
933
if (entry) {
934
unsigned i = (unsigned) (intptr_t) entry->data;
935
struct gl_uniform_storage *uniform = &prog->data->UniformStorage[i];
936
937
if (*first_element && !state->var_is_in_block) {
938
*first_element = false;
939
var->data.location = uniform - prog->data->UniformStorage;
940
}
941
942
update_uniforms_shader_info(prog, state, uniform, type, stage);
943
944
const struct glsl_type *type_no_array = glsl_without_array(type);
945
struct hash_entry *entry = prog->data->spirv ? NULL :
946
_mesa_hash_table_search(state->referenced_uniforms[stage],
947
state->current_var->name);
948
if (entry != NULL ||
949
glsl_get_base_type(type_no_array) == GLSL_TYPE_SUBROUTINE ||
950
prog->data->spirv)
951
uniform->active_shader_mask |= 1 << stage;
952
953
if (!state->var_is_in_block)
954
add_parameter(uniform, ctx, prog, type, state);
955
956
return true;
957
}
958
}
959
960
return false;
961
}
962
963
/**
964
* Finds, returns, and updates the stage info for any uniform in UniformStorage
965
* defined by @var. For GLSL this is done using the name, for SPIR-V in general
966
* is this done using the explicit location, except:
967
*
968
* * UBOs/SSBOs: as they lack explicit location, binding is used to locate
969
* them. That means that more that one entry at the uniform storage can be
970
* found. In that case all of them are updated, and the first entry is
971
* returned, in order to update the location of the nir variable.
972
*
973
* * Special uniforms: like atomic counters. They lack a explicit location,
974
* so they are skipped. They will be handled and assigned a location later.
975
*
976
*/
977
static bool
978
find_and_update_previous_uniform_storage(struct gl_context *ctx,
979
struct gl_shader_program *prog,
980
struct nir_link_uniforms_state *state,
981
nir_variable *var, char *name,
982
const struct glsl_type *type,
983
unsigned stage)
984
{
985
if (!prog->data->spirv) {
986
bool first_element = true;
987
char *name_tmp = ralloc_strdup(NULL, name);
988
bool r = find_and_update_named_uniform_storage(ctx, prog, state, var,
989
&name_tmp,
990
strlen(name_tmp), type,
991
stage, &first_element);
992
ralloc_free(name_tmp);
993
994
return r;
995
}
996
997
if (nir_variable_is_in_block(var)) {
998
struct gl_uniform_storage *uniform = NULL;
999
1000
ASSERTED unsigned num_blks = nir_variable_is_in_ubo(var) ?
1001
prog->data->NumUniformBlocks :
1002
prog->data->NumShaderStorageBlocks;
1003
1004
struct gl_uniform_block *blks = nir_variable_is_in_ubo(var) ?
1005
prog->data->UniformBlocks : prog->data->ShaderStorageBlocks;
1006
1007
bool result = false;
1008
for (unsigned i = 0; i < prog->data->NumUniformStorage; i++) {
1009
/* UniformStorage contains both variables from ubos and ssbos */
1010
if ( prog->data->UniformStorage[i].is_shader_storage !=
1011
nir_variable_is_in_ssbo(var))
1012
continue;
1013
1014
int block_index = prog->data->UniformStorage[i].block_index;
1015
if (block_index != -1) {
1016
assert(block_index < num_blks);
1017
1018
if (var->data.binding == blks[block_index].Binding) {
1019
if (!uniform)
1020
uniform = &prog->data->UniformStorage[i];
1021
mark_stage_as_active(&prog->data->UniformStorage[i],
1022
stage);
1023
result = true;
1024
}
1025
}
1026
}
1027
1028
if (result)
1029
var->data.location = uniform - prog->data->UniformStorage;
1030
return result;
1031
}
1032
1033
/* Beyond blocks, there are still some corner cases of uniforms without
1034
* location (ie: atomic counters) that would have a initial location equal
1035
* to -1. We just return on that case. Those uniforms will be handled
1036
* later.
1037
*/
1038
if (var->data.location == -1)
1039
return false;
1040
1041
/* TODO: following search can be problematic with shaders with a lot of
1042
* uniforms. Would it be better to use some type of hash
1043
*/
1044
for (unsigned i = 0; i < prog->data->NumUniformStorage; i++) {
1045
if (prog->data->UniformStorage[i].remap_location == var->data.location) {
1046
mark_stage_as_active(&prog->data->UniformStorage[i], stage);
1047
1048
struct gl_uniform_storage *uniform = &prog->data->UniformStorage[i];
1049
var->data.location = uniform - prog->data->UniformStorage;
1050
add_parameter(uniform, ctx, prog, var->type, state);
1051
return true;
1052
}
1053
}
1054
1055
return false;
1056
}
1057
1058
static struct type_tree_entry *
1059
build_type_tree_for_type(const struct glsl_type *type)
1060
{
1061
struct type_tree_entry *entry = malloc(sizeof *entry);
1062
1063
entry->array_size = 1;
1064
entry->next_index = UINT_MAX;
1065
entry->children = NULL;
1066
entry->next_sibling = NULL;
1067
entry->parent = NULL;
1068
1069
if (glsl_type_is_array(type)) {
1070
entry->array_size = glsl_get_length(type);
1071
entry->children = build_type_tree_for_type(glsl_get_array_element(type));
1072
entry->children->parent = entry;
1073
} else if (glsl_type_is_struct_or_ifc(type)) {
1074
struct type_tree_entry *last = NULL;
1075
1076
for (unsigned i = 0; i < glsl_get_length(type); i++) {
1077
const struct glsl_type *field_type = glsl_get_struct_field(type, i);
1078
struct type_tree_entry *field_entry =
1079
build_type_tree_for_type(field_type);
1080
1081
if (last == NULL)
1082
entry->children = field_entry;
1083
else
1084
last->next_sibling = field_entry;
1085
1086
field_entry->parent = entry;
1087
1088
last = field_entry;
1089
}
1090
}
1091
1092
return entry;
1093
}
1094
1095
static void
1096
free_type_tree(struct type_tree_entry *entry)
1097
{
1098
struct type_tree_entry *p, *next;
1099
1100
for (p = entry->children; p; p = next) {
1101
next = p->next_sibling;
1102
free_type_tree(p);
1103
}
1104
1105
free(entry);
1106
}
1107
1108
static void
1109
hash_free_uniform_name(struct hash_entry *entry)
1110
{
1111
free((void*)entry->key);
1112
}
1113
1114
static void
1115
enter_record(struct nir_link_uniforms_state *state,
1116
struct gl_context *ctx,
1117
const struct glsl_type *type,
1118
bool row_major)
1119
{
1120
assert(glsl_type_is_struct(type));
1121
if (!state->var_is_in_block)
1122
return;
1123
1124
bool use_std430 = ctx->Const.UseSTD430AsDefaultPacking;
1125
const enum glsl_interface_packing packing =
1126
glsl_get_internal_ifc_packing(state->current_var->interface_type,
1127
use_std430);
1128
1129
if (packing == GLSL_INTERFACE_PACKING_STD430)
1130
state->offset = glsl_align(
1131
state->offset, glsl_get_std430_base_alignment(type, row_major));
1132
else
1133
state->offset = glsl_align(
1134
state->offset, glsl_get_std140_base_alignment(type, row_major));
1135
}
1136
1137
static void
1138
leave_record(struct nir_link_uniforms_state *state,
1139
struct gl_context *ctx,
1140
const struct glsl_type *type,
1141
bool row_major)
1142
{
1143
assert(glsl_type_is_struct(type));
1144
if (!state->var_is_in_block)
1145
return;
1146
1147
bool use_std430 = ctx->Const.UseSTD430AsDefaultPacking;
1148
const enum glsl_interface_packing packing =
1149
glsl_get_internal_ifc_packing(state->current_var->interface_type,
1150
use_std430);
1151
1152
if (packing == GLSL_INTERFACE_PACKING_STD430)
1153
state->offset = glsl_align(
1154
state->offset, glsl_get_std430_base_alignment(type, row_major));
1155
else
1156
state->offset = glsl_align(
1157
state->offset, glsl_get_std140_base_alignment(type, row_major));
1158
}
1159
1160
/**
1161
* Creates the neccessary entries in UniformStorage for the uniform. Returns
1162
* the number of locations used or -1 on failure.
1163
*/
1164
static int
1165
nir_link_uniform(struct gl_context *ctx,
1166
struct gl_shader_program *prog,
1167
struct gl_program *stage_program,
1168
gl_shader_stage stage,
1169
const struct glsl_type *type,
1170
unsigned index_in_parent,
1171
int location,
1172
struct nir_link_uniforms_state *state,
1173
char **name, size_t name_length, bool row_major)
1174
{
1175
struct gl_uniform_storage *uniform = NULL;
1176
1177
if (state->set_top_level_array &&
1178
nir_variable_is_in_ssbo(state->current_var)) {
1179
/* Type is the top level SSBO member */
1180
if (glsl_type_is_array(type) &&
1181
(glsl_type_is_array(glsl_get_array_element(type)) ||
1182
glsl_type_is_struct_or_ifc(glsl_get_array_element(type)))) {
1183
/* Type is a top-level array (array of aggregate types) */
1184
state->top_level_array_size = glsl_get_length(type);
1185
state->top_level_array_stride = glsl_get_explicit_stride(type);
1186
} else {
1187
state->top_level_array_size = 1;
1188
state->top_level_array_stride = 0;
1189
}
1190
1191
state->set_top_level_array = false;
1192
}
1193
1194
/* gl_uniform_storage can cope with one level of array, so if the type is a
1195
* composite type or an array where each element occupies more than one
1196
* location than we need to recursively process it.
1197
*/
1198
if (glsl_type_is_struct_or_ifc(type) ||
1199
(glsl_type_is_array(type) &&
1200
(glsl_type_is_array(glsl_get_array_element(type)) ||
1201
glsl_type_is_struct_or_ifc(glsl_get_array_element(type))))) {
1202
int location_count = 0;
1203
struct type_tree_entry *old_type = state->current_type;
1204
unsigned int struct_base_offset = state->offset;
1205
1206
state->current_type = old_type->children;
1207
1208
/* Shader storage block unsized arrays: add subscript [0] to variable
1209
* names.
1210
*/
1211
unsigned length = glsl_get_length(type);
1212
if (glsl_type_is_unsized_array(type))
1213
length = 1;
1214
1215
if (glsl_type_is_struct(type) && !prog->data->spirv)
1216
enter_record(state, ctx, type, row_major);
1217
1218
for (unsigned i = 0; i < length; i++) {
1219
const struct glsl_type *field_type;
1220
size_t new_length = name_length;
1221
bool field_row_major = row_major;
1222
1223
if (glsl_type_is_struct_or_ifc(type)) {
1224
field_type = glsl_get_struct_field(type, i);
1225
/* Use the offset inside the struct only for variables backed by
1226
* a buffer object. For variables not backed by a buffer object,
1227
* offset is -1.
1228
*/
1229
if (state->var_is_in_block) {
1230
if (prog->data->spirv) {
1231
state->offset =
1232
struct_base_offset + glsl_get_struct_field_offset(type, i);
1233
} else if (glsl_get_struct_field_offset(type, i) != -1 &&
1234
type == state->current_ifc_type) {
1235
state->offset = glsl_get_struct_field_offset(type, i);
1236
}
1237
1238
if (glsl_type_is_interface(type))
1239
state->set_top_level_array = true;
1240
}
1241
1242
/* Append '.field' to the current variable name. */
1243
if (name) {
1244
ralloc_asprintf_rewrite_tail(name, &new_length, ".%s",
1245
glsl_get_struct_elem_name(type, i));
1246
}
1247
1248
1249
/* The layout of structures at the top level of the block is set
1250
* during parsing. For matrices contained in multiple levels of
1251
* structures in the block, the inner structures have no layout.
1252
* These cases must potentially inherit the layout from the outer
1253
* levels.
1254
*/
1255
const enum glsl_matrix_layout matrix_layout =
1256
glsl_get_struct_field_data(type, i)->matrix_layout;
1257
if (matrix_layout == GLSL_MATRIX_LAYOUT_ROW_MAJOR) {
1258
field_row_major = true;
1259
} else if (matrix_layout == GLSL_MATRIX_LAYOUT_COLUMN_MAJOR) {
1260
field_row_major = false;
1261
}
1262
} else {
1263
field_type = glsl_get_array_element(type);
1264
1265
/* Append the subscript to the current variable name */
1266
if (name)
1267
ralloc_asprintf_rewrite_tail(name, &new_length, "[%u]", i);
1268
}
1269
1270
int entries = nir_link_uniform(ctx, prog, stage_program, stage,
1271
field_type, i, location,
1272
state, name, new_length,
1273
field_row_major);
1274
1275
if (entries == -1)
1276
return -1;
1277
1278
if (location != -1)
1279
location += entries;
1280
location_count += entries;
1281
1282
if (glsl_type_is_struct_or_ifc(type))
1283
state->current_type = state->current_type->next_sibling;
1284
}
1285
1286
if (glsl_type_is_struct(type) && !prog->data->spirv)
1287
leave_record(state, ctx, type, row_major);
1288
1289
state->current_type = old_type;
1290
1291
return location_count;
1292
} else {
1293
/* TODO: reallocating storage is slow, we should figure out a way to
1294
* allocate storage up front for spirv like we do for GLSL.
1295
*/
1296
if (prog->data->spirv) {
1297
/* Create a new uniform storage entry */
1298
prog->data->UniformStorage =
1299
reralloc(prog->data,
1300
prog->data->UniformStorage,
1301
struct gl_uniform_storage,
1302
prog->data->NumUniformStorage + 1);
1303
if (!prog->data->UniformStorage) {
1304
linker_error(prog, "Out of memory during linking.\n");
1305
return -1;
1306
}
1307
}
1308
1309
uniform = &prog->data->UniformStorage[prog->data->NumUniformStorage];
1310
prog->data->NumUniformStorage++;
1311
1312
/* Initialize its members */
1313
memset(uniform, 0x00, sizeof(struct gl_uniform_storage));
1314
1315
uniform->name =
1316
name ? ralloc_strdup(prog->data->UniformStorage, *name) : NULL;
1317
1318
const struct glsl_type *type_no_array = glsl_without_array(type);
1319
if (glsl_type_is_array(type)) {
1320
uniform->type = type_no_array;
1321
uniform->array_elements = glsl_get_length(type);
1322
} else {
1323
uniform->type = type;
1324
uniform->array_elements = 0;
1325
}
1326
uniform->top_level_array_size = state->top_level_array_size;
1327
uniform->top_level_array_stride = state->top_level_array_stride;
1328
1329
struct hash_entry *entry = prog->data->spirv ? NULL :
1330
_mesa_hash_table_search(state->referenced_uniforms[stage],
1331
state->current_var->name);
1332
if (entry != NULL ||
1333
glsl_get_base_type(type_no_array) == GLSL_TYPE_SUBROUTINE ||
1334
prog->data->spirv)
1335
uniform->active_shader_mask |= 1 << stage;
1336
1337
if (location >= 0) {
1338
/* Uniform has an explicit location */
1339
uniform->remap_location = location;
1340
} else {
1341
uniform->remap_location = UNMAPPED_UNIFORM_LOC;
1342
}
1343
1344
uniform->hidden = state->current_var->data.how_declared == nir_var_hidden;
1345
if (uniform->hidden)
1346
state->num_hidden_uniforms++;
1347
1348
uniform->is_shader_storage = nir_variable_is_in_ssbo(state->current_var);
1349
uniform->is_bindless = state->current_var->data.bindless;
1350
1351
/* Set fields whose default value depend on the variable being inside a
1352
* block.
1353
*
1354
* From the OpenGL 4.6 spec, 7.3 Program objects:
1355
*
1356
* "For the property ARRAY_STRIDE, ... For active variables not declared
1357
* as an array of basic types, zero is written to params. For active
1358
* variables not backed by a buffer object, -1 is written to params,
1359
* regardless of the variable type."
1360
*
1361
* "For the property MATRIX_STRIDE, ... For active variables not declared
1362
* as a matrix or array of matrices, zero is written to params. For active
1363
* variables not backed by a buffer object, -1 is written to params,
1364
* regardless of the variable type."
1365
*
1366
* For the property IS_ROW_MAJOR, ... For active variables backed by a
1367
* buffer object, declared as a single matrix or array of matrices, and
1368
* stored in row-major order, one is written to params. For all other
1369
* active variables, zero is written to params.
1370
*/
1371
uniform->array_stride = -1;
1372
uniform->matrix_stride = -1;
1373
uniform->row_major = false;
1374
1375
if (state->var_is_in_block) {
1376
uniform->array_stride = glsl_type_is_array(type) ?
1377
glsl_get_explicit_stride(type) : 0;
1378
1379
if (glsl_type_is_matrix(uniform->type)) {
1380
uniform->matrix_stride = glsl_get_explicit_stride(uniform->type);
1381
uniform->row_major = glsl_matrix_type_is_row_major(uniform->type);
1382
} else {
1383
uniform->matrix_stride = 0;
1384
}
1385
1386
if (!prog->data->spirv) {
1387
bool use_std430 = ctx->Const.UseSTD430AsDefaultPacking;
1388
const enum glsl_interface_packing packing =
1389
glsl_get_internal_ifc_packing(state->current_var->interface_type,
1390
use_std430);
1391
1392
unsigned alignment =
1393
glsl_get_std140_base_alignment(type, uniform->row_major);
1394
if (packing == GLSL_INTERFACE_PACKING_STD430) {
1395
alignment =
1396
glsl_get_std430_base_alignment(type, uniform->row_major);
1397
}
1398
state->offset = glsl_align(state->offset, alignment);
1399
}
1400
}
1401
1402
uniform->offset = state->var_is_in_block ? state->offset : -1;
1403
1404
int buffer_block_index = -1;
1405
/* If the uniform is inside a uniform block determine its block index by
1406
* comparing the bindings, we can not use names.
1407
*/
1408
if (state->var_is_in_block) {
1409
struct gl_uniform_block *blocks = nir_variable_is_in_ssbo(state->current_var) ?
1410
prog->data->ShaderStorageBlocks : prog->data->UniformBlocks;
1411
1412
int num_blocks = nir_variable_is_in_ssbo(state->current_var) ?
1413
prog->data->NumShaderStorageBlocks : prog->data->NumUniformBlocks;
1414
1415
if (!prog->data->spirv) {
1416
bool is_interface_array =
1417
glsl_without_array(state->current_var->type) == state->current_var->interface_type &&
1418
glsl_type_is_array(state->current_var->type);
1419
1420
const char *ifc_name =
1421
glsl_get_type_name(state->current_var->interface_type);
1422
if (is_interface_array) {
1423
unsigned l = strlen(ifc_name);
1424
for (unsigned i = 0; i < num_blocks; i++) {
1425
if (strncmp(ifc_name, blocks[i].Name, l) == 0 &&
1426
blocks[i].Name[l] == '[') {
1427
buffer_block_index = i;
1428
break;
1429
}
1430
}
1431
} else {
1432
for (unsigned i = 0; i < num_blocks; i++) {
1433
if (strcmp(ifc_name, blocks[i].Name) == 0) {
1434
buffer_block_index = i;
1435
break;
1436
}
1437
}
1438
}
1439
1440
/* Compute the next offset. */
1441
bool use_std430 = ctx->Const.UseSTD430AsDefaultPacking;
1442
const enum glsl_interface_packing packing =
1443
glsl_get_internal_ifc_packing(state->current_var->interface_type,
1444
use_std430);
1445
if (packing == GLSL_INTERFACE_PACKING_STD430)
1446
state->offset += glsl_get_std430_size(type, uniform->row_major);
1447
else
1448
state->offset += glsl_get_std140_size(type, uniform->row_major);
1449
} else {
1450
for (unsigned i = 0; i < num_blocks; i++) {
1451
if (state->current_var->data.binding == blocks[i].Binding) {
1452
buffer_block_index = i;
1453
break;
1454
}
1455
}
1456
1457
/* Compute the next offset. */
1458
state->offset += glsl_get_explicit_size(type, true);
1459
}
1460
assert(buffer_block_index >= 0);
1461
}
1462
1463
uniform->block_index = buffer_block_index;
1464
uniform->builtin = is_gl_identifier(uniform->name);
1465
uniform->atomic_buffer_index = -1;
1466
1467
/* The following are not for features not supported by ARB_gl_spirv */
1468
uniform->num_compatible_subroutines = 0;
1469
1470
unsigned entries = MAX2(1, uniform->array_elements);
1471
unsigned values = glsl_get_component_slots(type);
1472
1473
update_uniforms_shader_info(prog, state, uniform, type, stage);
1474
1475
if (uniform->remap_location != UNMAPPED_UNIFORM_LOC &&
1476
state->max_uniform_location < uniform->remap_location + entries)
1477
state->max_uniform_location = uniform->remap_location + entries;
1478
1479
if (!state->var_is_in_block)
1480
add_parameter(uniform, ctx, prog, type, state);
1481
1482
if (name) {
1483
_mesa_hash_table_insert(state->uniform_hash, strdup(*name),
1484
(void *) (intptr_t)
1485
(prog->data->NumUniformStorage - 1));
1486
}
1487
1488
if (!is_gl_identifier(uniform->name) && !uniform->is_shader_storage &&
1489
!state->var_is_in_block)
1490
state->num_values += values;
1491
1492
return MAX2(uniform->array_elements, 1);
1493
}
1494
}
1495
1496
bool
1497
gl_nir_link_uniforms(struct gl_context *ctx,
1498
struct gl_shader_program *prog,
1499
bool fill_parameters)
1500
{
1501
/* First free up any previous UniformStorage items */
1502
ralloc_free(prog->data->UniformStorage);
1503
prog->data->UniformStorage = NULL;
1504
prog->data->NumUniformStorage = 0;
1505
1506
/* Iterate through all linked shaders */
1507
struct nir_link_uniforms_state state = {0,};
1508
1509
if (!prog->data->spirv) {
1510
/* Gather information on uniform use */
1511
for (unsigned stage = 0; stage < MESA_SHADER_STAGES; stage++) {
1512
struct gl_linked_shader *sh = prog->_LinkedShaders[stage];
1513
if (!sh)
1514
continue;
1515
1516
state.referenced_uniforms[stage] =
1517
_mesa_hash_table_create(NULL, _mesa_hash_string,
1518
_mesa_key_string_equal);
1519
1520
nir_shader *nir = sh->Program->nir;
1521
add_var_use_shader(nir, state.referenced_uniforms[stage]);
1522
}
1523
1524
/* Resize uniform arrays based on the maximum array index */
1525
for (unsigned stage = 0; stage < MESA_SHADER_STAGES; stage++) {
1526
struct gl_linked_shader *sh = prog->_LinkedShaders[stage];
1527
if (!sh)
1528
continue;
1529
1530
nir_foreach_gl_uniform_variable(var, sh->Program->nir)
1531
update_array_sizes(prog, var, state.referenced_uniforms, stage);
1532
}
1533
}
1534
1535
/* Count total number of uniforms and allocate storage */
1536
unsigned storage_size = 0;
1537
if (!prog->data->spirv) {
1538
struct set *storage_counted =
1539
_mesa_set_create(NULL, _mesa_hash_string, _mesa_key_string_equal);
1540
for (unsigned stage = 0; stage < MESA_SHADER_STAGES; stage++) {
1541
struct gl_linked_shader *sh = prog->_LinkedShaders[stage];
1542
if (!sh)
1543
continue;
1544
1545
nir_foreach_gl_uniform_variable(var, sh->Program->nir) {
1546
const struct glsl_type *type = var->type;
1547
const char *name = var->name;
1548
if (nir_variable_is_in_block(var) &&
1549
glsl_without_array(type) == var->interface_type) {
1550
type = glsl_without_array(var->type);
1551
name = glsl_get_type_name(type);
1552
}
1553
1554
struct set_entry *entry = _mesa_set_search(storage_counted, name);
1555
if (!entry) {
1556
storage_size += uniform_storage_size(type);
1557
_mesa_set_add(storage_counted, name);
1558
}
1559
}
1560
}
1561
_mesa_set_destroy(storage_counted, NULL);
1562
1563
prog->data->UniformStorage = rzalloc_array(prog->data,
1564
struct gl_uniform_storage,
1565
storage_size);
1566
if (!prog->data->UniformStorage) {
1567
linker_error(prog, "Out of memory while linking uniforms.\n");
1568
return false;
1569
}
1570
}
1571
1572
/* Iterate through all linked shaders */
1573
state.uniform_hash = _mesa_hash_table_create(NULL, _mesa_hash_string,
1574
_mesa_key_string_equal);
1575
1576
for (unsigned shader_type = 0; shader_type < MESA_SHADER_STAGES; shader_type++) {
1577
struct gl_linked_shader *sh = prog->_LinkedShaders[shader_type];
1578
if (!sh)
1579
continue;
1580
1581
nir_shader *nir = sh->Program->nir;
1582
assert(nir);
1583
1584
state.next_bindless_image_index = 0;
1585
state.next_bindless_sampler_index = 0;
1586
state.next_image_index = 0;
1587
state.next_sampler_index = 0;
1588
state.num_shader_samplers = 0;
1589
state.num_shader_images = 0;
1590
state.num_shader_uniform_components = 0;
1591
state.shader_storage_blocks_write_access = 0;
1592
state.shader_samplers_used = 0;
1593
state.shader_shadow_samplers = 0;
1594
state.params = fill_parameters ? sh->Program->Parameters : NULL;
1595
1596
nir_foreach_gl_uniform_variable(var, nir) {
1597
state.current_var = var;
1598
state.current_ifc_type = NULL;
1599
state.offset = 0;
1600
state.var_is_in_block = nir_variable_is_in_block(var);
1601
state.set_top_level_array = false;
1602
state.top_level_array_size = 0;
1603
state.top_level_array_stride = 0;
1604
1605
/*
1606
* From ARB_program_interface spec, issue (16):
1607
*
1608
* "RESOLVED: We will follow the default rule for enumerating block
1609
* members in the OpenGL API, which is:
1610
*
1611
* * If a variable is a member of an interface block without an
1612
* instance name, it is enumerated using just the variable name.
1613
*
1614
* * If a variable is a member of an interface block with an
1615
* instance name, it is enumerated as "BlockName.Member", where
1616
* "BlockName" is the name of the interface block (not the
1617
* instance name) and "Member" is the name of the variable.
1618
*
1619
* For example, in the following code:
1620
*
1621
* uniform Block1 {
1622
* int member1;
1623
* };
1624
* uniform Block2 {
1625
* int member2;
1626
* } instance2;
1627
* uniform Block3 {
1628
* int member3;
1629
* } instance3[2]; // uses two separate buffer bindings
1630
*
1631
* the three uniforms (if active) are enumerated as "member1",
1632
* "Block2.member2", and "Block3.member3"."
1633
*
1634
* Note that in the last example, with an array of ubo, only one
1635
* uniform is generated. For that reason, while unrolling the
1636
* uniforms of a ubo, or the variables of a ssbo, we need to treat
1637
* arrays of instance as a single block.
1638
*/
1639
char *name;
1640
const struct glsl_type *type = var->type;
1641
if (state.var_is_in_block &&
1642
((!prog->data->spirv && glsl_without_array(type) == var->interface_type) ||
1643
(prog->data->spirv && type == var->interface_type))) {
1644
type = glsl_without_array(var->type);
1645
state.current_ifc_type = type;
1646
name = ralloc_strdup(NULL, glsl_get_type_name(type));
1647
} else {
1648
state.set_top_level_array = true;
1649
name = ralloc_strdup(NULL, var->name);
1650
}
1651
1652
struct type_tree_entry *type_tree =
1653
build_type_tree_for_type(type);
1654
state.current_type = type_tree;
1655
1656
int location = var->data.location;
1657
1658
struct gl_uniform_block *blocks = NULL;
1659
int num_blocks = 0;
1660
int buffer_block_index = -1;
1661
if (!prog->data->spirv && state.var_is_in_block) {
1662
/* If the uniform is inside a uniform block determine its block index by
1663
* comparing the bindings, we can not use names.
1664
*/
1665
blocks = nir_variable_is_in_ssbo(state.current_var) ?
1666
prog->data->ShaderStorageBlocks : prog->data->UniformBlocks;
1667
num_blocks = nir_variable_is_in_ssbo(state.current_var) ?
1668
prog->data->NumShaderStorageBlocks : prog->data->NumUniformBlocks;
1669
1670
bool is_interface_array =
1671
glsl_without_array(state.current_var->type) == state.current_var->interface_type &&
1672
glsl_type_is_array(state.current_var->type);
1673
1674
const char *ifc_name =
1675
glsl_get_type_name(state.current_var->interface_type);
1676
1677
if (is_interface_array) {
1678
unsigned l = strlen(ifc_name);
1679
1680
/* Even when a match is found, do not "break" here. As this is
1681
* an array of instances, all elements of the array need to be
1682
* marked as referenced.
1683
*/
1684
for (unsigned i = 0; i < num_blocks; i++) {
1685
if (strncmp(ifc_name, blocks[i].Name, l) == 0 &&
1686
blocks[i].Name[l] == '[') {
1687
if (buffer_block_index == -1)
1688
buffer_block_index = i;
1689
1690
struct hash_entry *entry =
1691
_mesa_hash_table_search(state.referenced_uniforms[shader_type],
1692
var->name);
1693
if (entry) {
1694
struct uniform_array_info *ainfo =
1695
(struct uniform_array_info *) entry->data;
1696
if (BITSET_TEST(ainfo->indices, blocks[i].linearized_array_index))
1697
blocks[i].stageref |= 1U << shader_type;
1698
}
1699
}
1700
}
1701
} else {
1702
for (unsigned i = 0; i < num_blocks; i++) {
1703
if (strcmp(ifc_name, blocks[i].Name) == 0) {
1704
buffer_block_index = i;
1705
1706
struct hash_entry *entry =
1707
_mesa_hash_table_search(state.referenced_uniforms[shader_type],
1708
var->name);
1709
if (entry)
1710
blocks[i].stageref |= 1U << shader_type;
1711
1712
break;
1713
}
1714
}
1715
}
1716
1717
if (nir_variable_is_in_ssbo(var) &&
1718
!(var->data.access & ACCESS_NON_WRITEABLE)) {
1719
unsigned array_size = is_interface_array ?
1720
glsl_get_length(var->type) : 1;
1721
1722
STATIC_ASSERT(MAX_SHADER_STORAGE_BUFFERS <= 32);
1723
1724
/* Shaders that use too many SSBOs will fail to compile, which
1725
* we don't care about.
1726
*
1727
* This is true for shaders that do not use too many SSBOs:
1728
*/
1729
if (buffer_block_index + array_size <= 32) {
1730
state.shader_storage_blocks_write_access |=
1731
u_bit_consecutive(buffer_block_index, array_size);
1732
}
1733
}
1734
}
1735
1736
if (blocks && !prog->data->spirv && state.var_is_in_block) {
1737
if (glsl_without_array(state.current_var->type) != state.current_var->interface_type) {
1738
/* this is nested at some offset inside the block */
1739
bool found = false;
1740
char sentinel = '\0';
1741
1742
if (glsl_type_is_struct(state.current_var->type)) {
1743
sentinel = '.';
1744
} else if (glsl_type_is_array(state.current_var->type) &&
1745
(glsl_type_is_array(glsl_get_array_element(state.current_var->type))
1746
|| glsl_type_is_struct(glsl_without_array(state.current_var->type)))) {
1747
sentinel = '[';
1748
}
1749
1750
const unsigned l = strlen(state.current_var->name);
1751
for (unsigned i = 0; i < num_blocks; i++) {
1752
for (unsigned j = 0; j < blocks[i].NumUniforms; j++) {
1753
if (sentinel) {
1754
const char *begin = blocks[i].Uniforms[j].Name;
1755
const char *end = strchr(begin, sentinel);
1756
1757
if (end == NULL)
1758
continue;
1759
1760
if ((ptrdiff_t) l != (end - begin))
1761
continue;
1762
found = strncmp(state.current_var->name, begin, l) == 0;
1763
} else {
1764
found = strcmp(state.current_var->name, blocks[i].Uniforms[j].Name) == 0;
1765
}
1766
1767
if (found) {
1768
location = j;
1769
1770
struct hash_entry *entry =
1771
_mesa_hash_table_search(state.referenced_uniforms[shader_type], var->name);
1772
if (entry)
1773
blocks[i].stageref |= 1U << shader_type;
1774
1775
break;
1776
}
1777
}
1778
1779
if (found)
1780
break;
1781
}
1782
assert(found);
1783
var->data.location = location;
1784
} else {
1785
/* this is the base block offset */
1786
var->data.location = buffer_block_index;
1787
location = 0;
1788
}
1789
assert(buffer_block_index >= 0);
1790
const struct gl_uniform_block *const block =
1791
&blocks[buffer_block_index];
1792
assert(location >= 0 && location < block->NumUniforms);
1793
1794
const struct gl_uniform_buffer_variable *const ubo_var =
1795
&block->Uniforms[location];
1796
1797
state.offset = ubo_var->Offset;
1798
}
1799
1800
/* Check if the uniform has been processed already for
1801
* other stage. If so, validate they are compatible and update
1802
* the active stage mask.
1803
*/
1804
if (find_and_update_previous_uniform_storage(ctx, prog, &state, var,
1805
name, type, shader_type)) {
1806
ralloc_free(name);
1807
free_type_tree(type_tree);
1808
continue;
1809
}
1810
1811
/* From now on the variable’s location will be its uniform index */
1812
if (!state.var_is_in_block)
1813
var->data.location = prog->data->NumUniformStorage;
1814
else
1815
location = -1;
1816
1817
bool row_major =
1818
var->data.matrix_layout == GLSL_MATRIX_LAYOUT_ROW_MAJOR;
1819
int res = nir_link_uniform(ctx, prog, sh->Program, shader_type, type,
1820
0, location,
1821
&state,
1822
!prog->data->spirv ? &name : NULL,
1823
!prog->data->spirv ? strlen(name) : 0,
1824
row_major);
1825
1826
free_type_tree(type_tree);
1827
ralloc_free(name);
1828
1829
if (res == -1)
1830
return false;
1831
}
1832
1833
if (!prog->data->spirv) {
1834
_mesa_hash_table_destroy(state.referenced_uniforms[shader_type],
1835
NULL);
1836
}
1837
1838
if (state.num_shader_samplers >
1839
ctx->Const.Program[shader_type].MaxTextureImageUnits) {
1840
linker_error(prog, "Too many %s shader texture samplers\n",
1841
_mesa_shader_stage_to_string(shader_type));
1842
continue;
1843
}
1844
1845
if (state.num_shader_images >
1846
ctx->Const.Program[shader_type].MaxImageUniforms) {
1847
linker_error(prog, "Too many %s shader image uniforms (%u > %u)\n",
1848
_mesa_shader_stage_to_string(shader_type),
1849
state.num_shader_images,
1850
ctx->Const.Program[shader_type].MaxImageUniforms);
1851
continue;
1852
}
1853
1854
sh->Program->SamplersUsed = state.shader_samplers_used;
1855
sh->Program->sh.ShaderStorageBlocksWriteAccess =
1856
state.shader_storage_blocks_write_access;
1857
sh->shadow_samplers = state.shader_shadow_samplers;
1858
sh->Program->info.num_textures = state.num_shader_samplers;
1859
sh->Program->info.num_images = state.num_shader_images;
1860
sh->num_uniform_components = state.num_shader_uniform_components;
1861
sh->num_combined_uniform_components = sh->num_uniform_components;
1862
}
1863
1864
prog->data->NumHiddenUniforms = state.num_hidden_uniforms;
1865
prog->data->NumUniformDataSlots = state.num_values;
1866
1867
assert(prog->data->spirv || prog->data->NumUniformStorage == storage_size);
1868
1869
if (prog->data->spirv)
1870
prog->NumUniformRemapTable = state.max_uniform_location;
1871
1872
nir_setup_uniform_remap_tables(ctx, prog);
1873
gl_nir_set_uniform_initializers(ctx, prog);
1874
1875
_mesa_hash_table_destroy(state.uniform_hash, hash_free_uniform_name);
1876
1877
return true;
1878
}
1879
1880