glsl: rename record_location_offset() -> struct_location_offset()
[mesa.git] / src / compiler / glsl / gl_nir_link_uniforms.c
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 "gl_nir_linker.h"
26 #include "compiler/glsl/ir_uniform.h" /* for gl_uniform_storage */
27 #include "linker_util.h"
28 #include "main/context.h"
29 #include "main/mtypes.h"
30
31 /* This file do the common link for GLSL uniforms, using NIR, instead of IR as
32 * the counter-part glsl/link_uniforms.cpp
33 *
34 * Also note that this is tailored for ARB_gl_spirv needs and particularities
35 * (like need to work/link without name available, explicit location for
36 * normal uniforms as mandatory, and so on).
37 */
38
39 #define UNMAPPED_UNIFORM_LOC ~0u
40
41 static void
42 nir_setup_uniform_remap_tables(struct gl_context *ctx,
43 struct gl_shader_program *prog)
44 {
45 prog->UniformRemapTable = rzalloc_array(prog,
46 struct gl_uniform_storage *,
47 prog->NumUniformRemapTable);
48 union gl_constant_value *data =
49 rzalloc_array(prog->data,
50 union gl_constant_value, prog->data->NumUniformDataSlots);
51 if (!prog->UniformRemapTable || !data) {
52 linker_error(prog, "Out of memory during linking.\n");
53 return;
54 }
55 prog->data->UniformDataSlots = data;
56
57 unsigned data_pos = 0;
58
59 /* Reserve all the explicit locations of the active uniforms. */
60 for (unsigned i = 0; i < prog->data->NumUniformStorage; i++) {
61 struct gl_uniform_storage *uniform = &prog->data->UniformStorage[i];
62
63 if (prog->data->UniformStorage[i].remap_location == UNMAPPED_UNIFORM_LOC)
64 continue;
65
66 /* How many new entries for this uniform? */
67 const unsigned entries = MAX2(1, uniform->array_elements);
68 unsigned num_slots = glsl_get_component_slots(uniform->type);
69
70 uniform->storage = &data[data_pos];
71
72 /* Set remap table entries point to correct gl_uniform_storage. */
73 for (unsigned j = 0; j < entries; j++) {
74 unsigned element_loc = uniform->remap_location + j;
75 prog->UniformRemapTable[element_loc] = uniform;
76
77 data_pos += num_slots;
78 }
79 }
80
81 /* Reserve locations for rest of the uniforms. */
82 link_util_update_empty_uniform_locations(prog);
83
84 for (unsigned i = 0; i < prog->data->NumUniformStorage; i++) {
85 struct gl_uniform_storage *uniform = &prog->data->UniformStorage[i];
86
87 if (uniform->is_shader_storage)
88 continue;
89
90 /* Built-in uniforms should not get any location. */
91 if (uniform->builtin)
92 continue;
93
94 /* Explicit ones have been set already. */
95 if (uniform->remap_location != UNMAPPED_UNIFORM_LOC)
96 continue;
97
98 /* How many entries for this uniform? */
99 const unsigned entries = MAX2(1, uniform->array_elements);
100
101 unsigned location =
102 link_util_find_empty_block(prog, &prog->data->UniformStorage[i]);
103
104 if (location == -1) {
105 location = prog->NumUniformRemapTable;
106
107 /* resize remap table to fit new entries */
108 prog->UniformRemapTable =
109 reralloc(prog,
110 prog->UniformRemapTable,
111 struct gl_uniform_storage *,
112 prog->NumUniformRemapTable + entries);
113 prog->NumUniformRemapTable += entries;
114 }
115
116 /* set the base location in remap table for the uniform */
117 uniform->remap_location = location;
118
119 unsigned num_slots = glsl_get_component_slots(uniform->type);
120
121 uniform->storage = &data[data_pos];
122
123 /* Set remap table entries point to correct gl_uniform_storage. */
124 for (unsigned j = 0; j < entries; j++) {
125 unsigned element_loc = uniform->remap_location + j;
126 prog->UniformRemapTable[element_loc] = uniform;
127
128 data_pos += num_slots;
129 }
130 }
131 }
132
133 static struct gl_uniform_storage *
134 find_previous_uniform_storage(struct gl_shader_program *prog,
135 int location)
136 {
137 /* This would only work for uniform with explicit location, as all the
138 * uniforms without location (ie: atomic counters) would have a initial
139 * location equal to -1. We early return in that case.
140 */
141 if (location == -1)
142 return NULL;
143
144 for (unsigned i = 0; i < prog->data->NumUniformStorage; i++)
145 if (prog->data->UniformStorage[i].remap_location == location)
146 return &prog->data->UniformStorage[i];
147
148 return NULL;
149 }
150
151 /* Used to build a tree representing the glsl_type so that we can have a place
152 * to store the next index for opaque types. Array types are expanded so that
153 * they have a single child which is used for all elements of the array.
154 * Struct types have a child for each member. The tree is walked while
155 * processing a uniform so that we can recognise when an opaque type is
156 * encountered a second time in order to reuse the same range of indices that
157 * was reserved the first time. That way the sampler indices can be arranged
158 * so that members of an array are placed sequentially even if the array is an
159 * array of structs containing other opaque members.
160 */
161 struct type_tree_entry {
162 /* For opaque types, this will be the next index to use. If we haven’t
163 * encountered this member yet, it will be UINT_MAX.
164 */
165 unsigned next_index;
166 unsigned array_size;
167 struct type_tree_entry *parent;
168 struct type_tree_entry *next_sibling;
169 struct type_tree_entry *children;
170 };
171
172 struct nir_link_uniforms_state {
173 /* per-whole program */
174 unsigned num_hidden_uniforms;
175 unsigned num_values;
176 unsigned max_uniform_location;
177 unsigned next_sampler_index;
178 unsigned next_image_index;
179
180 /* per-shader stage */
181 unsigned num_shader_samplers;
182 unsigned num_shader_images;
183 unsigned num_shader_uniform_components;
184 unsigned shader_samplers_used;
185 unsigned shader_shadow_samplers;
186
187 nir_variable *current_var;
188
189 struct type_tree_entry *current_type;
190 };
191
192 static struct type_tree_entry *
193 build_type_tree_for_type(const struct glsl_type *type)
194 {
195 struct type_tree_entry *entry = malloc(sizeof *entry);
196
197 entry->array_size = 1;
198 entry->next_index = UINT_MAX;
199 entry->children = NULL;
200 entry->next_sibling = NULL;
201 entry->parent = NULL;
202
203 if (glsl_type_is_array(type)) {
204 entry->array_size = glsl_get_length(type);
205 entry->children = build_type_tree_for_type(glsl_get_array_element(type));
206 entry->children->parent = entry;
207 } else if (glsl_type_is_struct(type)) {
208 struct type_tree_entry *last = NULL;
209
210 for (unsigned i = 0; i < glsl_get_length(type); i++) {
211 const struct glsl_type *field_type = glsl_get_struct_field(type, i);
212 struct type_tree_entry *field_entry =
213 build_type_tree_for_type(field_type);
214
215 if (last == NULL)
216 entry->children = field_entry;
217 else
218 last->next_sibling = field_entry;
219
220 field_entry->parent = entry;
221
222 last = field_entry;
223 }
224 }
225
226 return entry;
227 }
228
229 static void
230 free_type_tree(struct type_tree_entry *entry)
231 {
232 struct type_tree_entry *p, *next;
233
234 for (p = entry->children; p; p = next) {
235 next = p->next_sibling;
236 free_type_tree(p);
237 }
238
239 free(entry);
240 }
241
242 static unsigned
243 get_next_index(struct nir_link_uniforms_state *state,
244 const struct gl_uniform_storage *uniform,
245 unsigned *next_index)
246 {
247 /* If we’ve already calculated an index for this member then we can just
248 * offset from there.
249 */
250 if (state->current_type->next_index == UINT_MAX) {
251 /* Otherwise we need to reserve enough indices for all of the arrays
252 * enclosing this member.
253 */
254
255 unsigned array_size = 1;
256
257 for (const struct type_tree_entry *p = state->current_type;
258 p;
259 p = p->parent) {
260 array_size *= p->array_size;
261 }
262
263 state->current_type->next_index = *next_index;
264 *next_index += array_size;
265 }
266
267 unsigned index = state->current_type->next_index;
268
269 state->current_type->next_index += MAX2(1, uniform->array_elements);
270
271 return index;
272 }
273
274
275 /**
276 * Creates the neccessary entries in UniformStorage for the uniform. Returns
277 * the number of locations used or -1 on failure.
278 */
279 static int
280 nir_link_uniform(struct gl_context *ctx,
281 struct gl_shader_program *prog,
282 struct gl_program *stage_program,
283 gl_shader_stage stage,
284 const struct glsl_type *type,
285 int location,
286 struct nir_link_uniforms_state *state)
287 {
288 struct gl_uniform_storage *uniform = NULL;
289
290 /* gl_uniform_storage can cope with one level of array, so if the type is a
291 * composite type or an array where each element occupies more than one
292 * location than we need to recursively process it.
293 */
294 if (glsl_type_is_struct(type) ||
295 (glsl_type_is_array(type) &&
296 (glsl_type_is_array(glsl_get_array_element(type)) ||
297 glsl_type_is_struct(glsl_get_array_element(type))))) {
298 int location_count = 0;
299 struct type_tree_entry *old_type = state->current_type;
300
301 state->current_type = old_type->children;
302
303 for (unsigned i = 0; i < glsl_get_length(type); i++) {
304 const struct glsl_type *field_type;
305
306 if (glsl_type_is_struct(type))
307 field_type = glsl_get_struct_field(type, i);
308 else
309 field_type = glsl_get_array_element(type);
310
311 int entries = nir_link_uniform(ctx, prog, stage_program, stage,
312 field_type, location,
313 state);
314 if (entries == -1)
315 return -1;
316
317 if (location != -1)
318 location += entries;
319 location_count += entries;
320
321 if (glsl_type_is_struct(type))
322 state->current_type = state->current_type->next_sibling;
323 }
324
325 state->current_type = old_type;
326
327 return location_count;
328 } else {
329 /* Create a new uniform storage entry */
330 prog->data->UniformStorage =
331 reralloc(prog->data,
332 prog->data->UniformStorage,
333 struct gl_uniform_storage,
334 prog->data->NumUniformStorage + 1);
335 if (!prog->data->UniformStorage) {
336 linker_error(prog, "Out of memory during linking.\n");
337 return -1;
338 }
339
340 uniform = &prog->data->UniformStorage[prog->data->NumUniformStorage];
341 prog->data->NumUniformStorage++;
342
343 /* Initialize its members */
344 memset(uniform, 0x00, sizeof(struct gl_uniform_storage));
345 /* ARB_gl_spirv: names are considered optional debug info, so the linker
346 * needs to work without them, and returning them is optional. For
347 * simplicity we ignore names.
348 */
349 uniform->name = NULL;
350
351 const struct glsl_type *type_no_array = glsl_without_array(type);
352 if (glsl_type_is_array(type)) {
353 uniform->type = type_no_array;
354 uniform->array_elements = glsl_get_length(type);
355 } else {
356 uniform->type = type;
357 uniform->array_elements = 0;
358 }
359 uniform->active_shader_mask |= 1 << stage;
360
361 if (location >= 0) {
362 /* Uniform has an explicit location */
363 uniform->remap_location = location;
364 } else {
365 uniform->remap_location = UNMAPPED_UNIFORM_LOC;
366 }
367
368 uniform->hidden = state->current_var->data.how_declared == nir_var_hidden;
369 if (uniform->hidden)
370 state->num_hidden_uniforms++;
371
372 /* @FIXME: the initialization of the following will be done as we
373 * implement support for their specific features, like SSBO, atomics,
374 * etc.
375 */
376 uniform->block_index = -1;
377 uniform->offset = -1;
378 uniform->matrix_stride = -1;
379 uniform->array_stride = -1;
380 uniform->row_major = false;
381 uniform->builtin = false;
382 uniform->is_shader_storage = false;
383 uniform->atomic_buffer_index = -1;
384 uniform->top_level_array_size = 0;
385 uniform->top_level_array_stride = 0;
386 uniform->is_bindless = false;
387
388 /* The following are not for features not supported by ARB_gl_spirv */
389 uniform->num_compatible_subroutines = 0;
390
391 unsigned entries = MAX2(1, uniform->array_elements);
392
393 if (glsl_type_is_sampler(type_no_array)) {
394 int sampler_index =
395 get_next_index(state, uniform, &state->next_sampler_index);
396
397 state->num_shader_samplers++;
398
399 uniform->opaque[stage].active = true;
400 uniform->opaque[stage].index = sampler_index;
401
402 const unsigned shadow = glsl_sampler_type_is_shadow(type_no_array);
403
404 for (unsigned i = sampler_index;
405 i < MIN2(state->next_sampler_index, MAX_SAMPLERS);
406 i++) {
407 stage_program->sh.SamplerTargets[i] =
408 glsl_get_sampler_target(type_no_array);
409 state->shader_samplers_used |= 1U << i;
410 state->shader_shadow_samplers |= shadow << i;
411 }
412 } else if (glsl_type_is_image(type_no_array)) {
413 /* @FIXME: image_index should match that of the same image
414 * uniform in other shaders. This means we need to match image
415 * uniforms by location (GLSL does it by variable name, but we
416 * want to avoid that).
417 */
418 int image_index = state->next_image_index;
419 state->next_image_index += entries;
420
421 state->num_shader_images++;
422
423 uniform->opaque[stage].active = true;
424 uniform->opaque[stage].index = image_index;
425
426 /* Set image access qualifiers */
427 enum gl_access_qualifier image_access =
428 state->current_var->data.image.access;
429 const GLenum access =
430 (image_access & ACCESS_NON_WRITEABLE) ?
431 ((image_access & ACCESS_NON_READABLE) ? GL_NONE :
432 GL_READ_ONLY) :
433 ((image_access & ACCESS_NON_READABLE) ? GL_WRITE_ONLY :
434 GL_READ_WRITE);
435 for (unsigned i = image_index;
436 i < MIN2(state->next_image_index, MAX_IMAGE_UNIFORMS);
437 i++) {
438 stage_program->sh.ImageAccess[i] = access;
439 }
440 }
441
442 unsigned values = glsl_get_component_slots(type);
443 state->num_shader_uniform_components += values;
444 state->num_values += values;
445
446 if (state->max_uniform_location < uniform->remap_location + entries)
447 state->max_uniform_location = uniform->remap_location + entries;
448
449 return MAX2(uniform->array_elements, 1);
450 }
451 }
452
453 bool
454 gl_nir_link_uniforms(struct gl_context *ctx,
455 struct gl_shader_program *prog)
456 {
457 /* First free up any previous UniformStorage items */
458 ralloc_free(prog->data->UniformStorage);
459 prog->data->UniformStorage = NULL;
460 prog->data->NumUniformStorage = 0;
461
462 /* Iterate through all linked shaders */
463 struct nir_link_uniforms_state state = {0,};
464
465 for (unsigned shader_type = 0; shader_type < MESA_SHADER_STAGES; shader_type++) {
466 struct gl_linked_shader *sh = prog->_LinkedShaders[shader_type];
467 if (!sh)
468 continue;
469
470 nir_shader *nir = sh->Program->nir;
471 assert(nir);
472
473 state.num_shader_samplers = 0;
474 state.num_shader_images = 0;
475 state.num_shader_uniform_components = 0;
476 state.shader_samplers_used = 0;
477 state.shader_shadow_samplers = 0;
478
479 nir_foreach_variable(var, &nir->uniforms) {
480 struct gl_uniform_storage *uniform = NULL;
481
482 /* Check if the uniform has been processed already for
483 * other stage. If so, validate they are compatible and update
484 * the active stage mask.
485 */
486 uniform = find_previous_uniform_storage(prog, var->data.location);
487 if (uniform) {
488 uniform->active_shader_mask |= 1 << shader_type;
489 var->data.location = uniform - prog->data->UniformStorage;
490
491 continue;
492 }
493
494 int location = var->data.location;
495 /* From now on the variable’s location will be its uniform index */
496 var->data.location = prog->data->NumUniformStorage;
497
498 state.current_var = var;
499
500 struct type_tree_entry *type_tree =
501 build_type_tree_for_type(var->type);
502 state.current_type = type_tree;
503
504 int res = nir_link_uniform(ctx, prog, sh->Program, shader_type, var->type,
505 location, &state);
506
507 free_type_tree(type_tree);
508
509 if (res == -1)
510 return false;
511 }
512
513 sh->Program->SamplersUsed = state.shader_samplers_used;
514 sh->shadow_samplers = state.shader_shadow_samplers;
515 sh->Program->info.num_textures = state.num_shader_samplers;
516 sh->Program->info.num_images = state.num_shader_images;
517 sh->num_uniform_components = state.num_shader_uniform_components;
518 sh->num_combined_uniform_components = sh->num_uniform_components;
519 }
520
521 prog->data->NumHiddenUniforms = state.num_hidden_uniforms;
522 prog->NumUniformRemapTable = state.max_uniform_location;
523 prog->data->NumUniformDataSlots = state.num_values;
524
525 nir_setup_uniform_remap_tables(ctx, prog);
526 gl_nir_set_uniform_initializers(ctx, prog);
527
528 return true;
529 }