glsl: call uniform resource checks from the nir linker
[mesa.git] / src / compiler / glsl / gl_nir_linker.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.h"
26 #include "gl_nir_linker.h"
27 #include "linker_util.h"
28 #include "main/mtypes.h"
29 #include "main/shaderobj.h"
30 #include "ir_uniform.h" /* for gl_uniform_storage */
31
32 /* This file included general link methods, using NIR, instead of IR as
33 * the counter-part glsl/linker.cpp
34 *
35 * Also note that this is tailored for ARB_gl_spirv needs and particularities
36 */
37
38 /**
39 * Built-in / reserved GL variables names start with "gl_"
40 */
41 static inline bool
42 is_gl_identifier(const char *s)
43 {
44 return s && s[0] == 'g' && s[1] == 'l' && s[2] == '_';
45 }
46
47 static bool
48 inout_has_same_location(const nir_variable *var, unsigned stage)
49 {
50 if (!var->data.patch &&
51 ((var->data.mode == nir_var_shader_out &&
52 stage == MESA_SHADER_TESS_CTRL) ||
53 (var->data.mode == nir_var_shader_in &&
54 (stage == MESA_SHADER_TESS_CTRL || stage == MESA_SHADER_TESS_EVAL ||
55 stage == MESA_SHADER_GEOMETRY))))
56 return true;
57 else
58 return false;
59 }
60
61 /**
62 * Create gl_shader_variable from nir_variable.
63 */
64 static struct gl_shader_variable *
65 create_shader_variable(struct gl_shader_program *shProg,
66 const nir_variable *in,
67 const char *name, const struct glsl_type *type,
68 const struct glsl_type *interface_type,
69 bool use_implicit_location, int location,
70 const struct glsl_type *outermost_struct_type)
71 {
72 /* Allocate zero-initialized memory to ensure that bitfield padding
73 * is zero.
74 */
75 struct gl_shader_variable *out = rzalloc(shProg,
76 struct gl_shader_variable);
77 if (!out)
78 return NULL;
79
80 /* Since gl_VertexID may be lowered to gl_VertexIDMESA, but applications
81 * expect to see gl_VertexID in the program resource list. Pretend.
82 */
83 if (in->data.mode == nir_var_system_value &&
84 in->data.location == SYSTEM_VALUE_VERTEX_ID_ZERO_BASE) {
85 out->name = ralloc_strdup(shProg, "gl_VertexID");
86 } else if ((in->data.mode == nir_var_shader_out &&
87 in->data.location == VARYING_SLOT_TESS_LEVEL_OUTER) ||
88 (in->data.mode == nir_var_system_value &&
89 in->data.location == SYSTEM_VALUE_TESS_LEVEL_OUTER)) {
90 out->name = ralloc_strdup(shProg, "gl_TessLevelOuter");
91 type = glsl_array_type(glsl_float_type(), 4, 0);
92 } else if ((in->data.mode == nir_var_shader_out &&
93 in->data.location == VARYING_SLOT_TESS_LEVEL_INNER) ||
94 (in->data.mode == nir_var_system_value &&
95 in->data.location == SYSTEM_VALUE_TESS_LEVEL_INNER)) {
96 out->name = ralloc_strdup(shProg, "gl_TessLevelInner");
97 type = glsl_array_type(glsl_float_type(), 2, 0);
98 } else {
99 out->name = ralloc_strdup(shProg, name);
100 }
101
102 if (!out->name)
103 return NULL;
104
105 /* The ARB_program_interface_query spec says:
106 *
107 * "Not all active variables are assigned valid locations; the
108 * following variables will have an effective location of -1:
109 *
110 * * uniforms declared as atomic counters;
111 *
112 * * members of a uniform block;
113 *
114 * * built-in inputs, outputs, and uniforms (starting with "gl_"); and
115 *
116 * * inputs or outputs not declared with a "location" layout
117 * qualifier, except for vertex shader inputs and fragment shader
118 * outputs."
119 */
120 if (glsl_get_base_type(in->type) == GLSL_TYPE_ATOMIC_UINT ||
121 is_gl_identifier(in->name) ||
122 !(in->data.explicit_location || use_implicit_location)) {
123 out->location = -1;
124 } else {
125 out->location = location;
126 }
127
128 out->type = type;
129 out->outermost_struct_type = outermost_struct_type;
130 out->interface_type = interface_type;
131 out->component = in->data.location_frac;
132 out->index = in->data.index;
133 out->patch = in->data.patch;
134 out->mode = in->data.mode;
135 out->interpolation = in->data.interpolation;
136 out->precision = in->data.precision;
137 out->explicit_location = in->data.explicit_location;
138
139 return out;
140 }
141
142 static bool
143 add_shader_variable(const struct gl_context *ctx,
144 struct gl_shader_program *shProg,
145 struct set *resource_set,
146 unsigned stage_mask,
147 GLenum programInterface, nir_variable *var,
148 const char *name, const struct glsl_type *type,
149 bool use_implicit_location, int location,
150 bool inouts_share_location,
151 const struct glsl_type *outermost_struct_type)
152 {
153 const struct glsl_type *interface_type = var->interface_type;
154
155 if (outermost_struct_type == NULL) {
156 if (var->data.from_named_ifc_block) {
157 const char *interface_name = glsl_get_type_name(interface_type);
158
159 if (glsl_type_is_array(interface_type)) {
160 /* Issue #16 of the ARB_program_interface_query spec says:
161 *
162 * "* If a variable is a member of an interface block without an
163 * instance name, it is enumerated using just the variable name.
164 *
165 * * If a variable is a member of an interface block with an
166 * instance name, it is enumerated as "BlockName.Member", where
167 * "BlockName" is the name of the interface block (not the
168 * instance name) and "Member" is the name of the variable."
169 *
170 * In particular, it indicates that it should be "BlockName",
171 * not "BlockName[array length]". The conformance suite and
172 * dEQP both require this behavior.
173 *
174 * Here, we unwrap the extra array level added by named interface
175 * block array lowering so we have the correct variable type. We
176 * also unwrap the interface type when constructing the name.
177 *
178 * We leave interface_type the same so that ES 3.x SSO pipeline
179 * validation can enforce the rules requiring array length to
180 * match on interface blocks.
181 */
182 type = glsl_get_array_element(type);
183
184 interface_name =
185 glsl_get_type_name(glsl_get_array_element(interface_type));
186 }
187
188 name = ralloc_asprintf(shProg, "%s.%s", interface_name, name);
189 }
190 }
191
192 switch (glsl_get_base_type(type)) {
193 case GLSL_TYPE_STRUCT: {
194 /* The ARB_program_interface_query spec says:
195 *
196 * "For an active variable declared as a structure, a separate entry
197 * will be generated for each active structure member. The name of
198 * each entry is formed by concatenating the name of the structure,
199 * the "." character, and the name of the structure member. If a
200 * structure member to enumerate is itself a structure or array,
201 * these enumeration rules are applied recursively."
202 */
203 if (outermost_struct_type == NULL)
204 outermost_struct_type = type;
205
206 unsigned field_location = location;
207 for (unsigned i = 0; i < glsl_get_length(type); i++) {
208 const struct glsl_type *field_type = glsl_get_struct_field(type, i);
209 const struct glsl_struct_field *field =
210 glsl_get_struct_field_data(type, i);
211
212 char *field_name = ralloc_asprintf(shProg, "%s.%s", name, field->name);
213 if (!add_shader_variable(ctx, shProg, resource_set,
214 stage_mask, programInterface,
215 var, field_name, field_type,
216 use_implicit_location, field_location,
217 false, outermost_struct_type))
218 return false;
219
220 field_location += glsl_count_attribute_slots(field_type, false);
221 }
222 return true;
223 }
224
225 case GLSL_TYPE_ARRAY: {
226 /* The ARB_program_interface_query spec says:
227 *
228 * "For an active variable declared as an array of basic types, a
229 * single entry will be generated, with its name string formed by
230 * concatenating the name of the array and the string "[0]"."
231 *
232 * "For an active variable declared as an array of an aggregate data
233 * type (structures or arrays), a separate entry will be generated
234 * for each active array element, unless noted immediately below.
235 * The name of each entry is formed by concatenating the name of
236 * the array, the "[" character, an integer identifying the element
237 * number, and the "]" character. These enumeration rules are
238 * applied recursively, treating each enumerated array element as a
239 * separate active variable."
240 */
241 const struct glsl_type *array_type = glsl_get_array_element(type);
242 if (glsl_get_base_type(array_type) == GLSL_TYPE_STRUCT ||
243 glsl_get_base_type(array_type) == GLSL_TYPE_ARRAY) {
244 unsigned elem_location = location;
245 unsigned stride = inouts_share_location ? 0 :
246 glsl_count_attribute_slots(array_type, false);
247 for (unsigned i = 0; i < glsl_get_length(type); i++) {
248 char *elem = ralloc_asprintf(shProg, "%s[%d]", name, i);
249 if (!add_shader_variable(ctx, shProg, resource_set,
250 stage_mask, programInterface,
251 var, elem, array_type,
252 use_implicit_location, elem_location,
253 false, outermost_struct_type))
254 return false;
255 elem_location += stride;
256 }
257 return true;
258 }
259 /* fallthrough */
260 }
261
262 default: {
263 /* The ARB_program_interface_query spec says:
264 *
265 * "For an active variable declared as a single instance of a basic
266 * type, a single entry will be generated, using the variable name
267 * from the shader source."
268 */
269 struct gl_shader_variable *sha_v =
270 create_shader_variable(shProg, var, name, type, interface_type,
271 use_implicit_location, location,
272 outermost_struct_type);
273 if (!sha_v)
274 return false;
275
276 return link_util_add_program_resource(shProg, resource_set,
277 programInterface, sha_v, stage_mask);
278 }
279 }
280 }
281
282 static bool
283 add_vars_from_list(const struct gl_context *ctx,
284 struct gl_shader_program *prog, struct set *resource_set,
285 const struct exec_list *var_list, unsigned stage,
286 GLenum programInterface)
287 {
288 nir_foreach_variable(var, var_list) {
289 if (var->data.how_declared == nir_var_hidden)
290 continue;
291
292 int loc_bias = 0;
293 switch(var->data.mode) {
294 case nir_var_system_value:
295 case nir_var_shader_in:
296 if (programInterface != GL_PROGRAM_INPUT)
297 continue;
298 loc_bias = (stage == MESA_SHADER_VERTEX) ? VERT_ATTRIB_GENERIC0
299 : VARYING_SLOT_VAR0;
300 break;
301 case nir_var_shader_out:
302 if (programInterface != GL_PROGRAM_OUTPUT)
303 continue;
304 loc_bias = (stage == MESA_SHADER_FRAGMENT) ? FRAG_RESULT_DATA0
305 : VARYING_SLOT_VAR0;
306 break;
307 default:
308 continue;
309 }
310
311 if (var->data.patch)
312 loc_bias = VARYING_SLOT_PATCH0;
313
314 if (prog->data->spirv) {
315 struct gl_shader_variable *sh_var =
316 rzalloc(prog, struct gl_shader_variable);
317
318 /* In the ARB_gl_spirv spec, names are considered optional debug info, so
319 * the linker needs to work without them. Returning them is optional.
320 * For simplicity, we ignore names.
321 */
322 sh_var->name = NULL;
323 sh_var->type = var->type;
324 sh_var->location = var->data.location - loc_bias;
325 sh_var->index = var->data.index;
326
327 if (!link_util_add_program_resource(prog, resource_set,
328 programInterface,
329 sh_var, 1 << stage)) {
330 return false;
331 }
332 } else {
333 /* Skip packed varyings, packed varyings are handled separately
334 * by add_packed_varyings in the GLSL IR
335 * build_program_resource_list() call.
336 * TODO: handle packed varyings here instead. We likely want a NIR
337 * based packing pass first.
338 */
339 if (strncmp(var->name, "packed:", 7) == 0)
340 continue;
341
342 const bool vs_input_or_fs_output =
343 (stage == MESA_SHADER_VERTEX &&
344 var->data.mode == nir_var_shader_in) ||
345 (stage == MESA_SHADER_FRAGMENT &&
346 var->data.mode == nir_var_shader_out);
347
348 if (!add_shader_variable(ctx, prog, resource_set,
349 1 << stage, programInterface,
350 var, var->name, var->type,
351 vs_input_or_fs_output,
352 var->data.location - loc_bias,
353 inout_has_same_location(var, stage),
354 NULL))
355 return false;
356 }
357 }
358
359 return true;
360 }
361
362 static bool
363 add_interface_variables(const struct gl_context *ctx,
364 struct gl_shader_program *prog,
365 struct set *resource_set,
366 unsigned stage, GLenum programInterface)
367 {
368 struct gl_linked_shader *sh = prog->_LinkedShaders[stage];
369 if (!sh)
370 return true;
371
372 nir_shader *nir = sh->Program->nir;
373 assert(nir);
374
375 switch (programInterface) {
376 case GL_PROGRAM_INPUT: {
377 bool result = add_vars_from_list(ctx, prog, resource_set,
378 &nir->inputs, stage, programInterface);
379 result &= add_vars_from_list(ctx, prog, resource_set, &nir->system_values,
380 stage, programInterface);
381 return result;
382 }
383 case GL_PROGRAM_OUTPUT:
384 return add_vars_from_list(ctx, prog, resource_set, &nir->outputs, stage,
385 programInterface);
386 default:
387 assert("!Should not get here");
388 break;
389 }
390
391 return false;
392 }
393
394 /* TODO: as we keep adding features, this method is becoming more and more
395 * similar to its GLSL counterpart at linker.cpp. Eventually it would be good
396 * to check if they could be refactored, and reduce code duplication somehow
397 */
398 void
399 nir_build_program_resource_list(struct gl_context *ctx,
400 struct gl_shader_program *prog,
401 bool rebuild_resourse_list)
402 {
403 /* Rebuild resource list. */
404 if (prog->data->ProgramResourceList && rebuild_resourse_list) {
405 ralloc_free(prog->data->ProgramResourceList);
406 prog->data->ProgramResourceList = NULL;
407 prog->data->NumProgramResourceList = 0;
408 }
409
410 int input_stage = MESA_SHADER_STAGES, output_stage = 0;
411
412 /* Determine first input and final output stage. These are used to
413 * detect which variables should be enumerated in the resource list
414 * for GL_PROGRAM_INPUT and GL_PROGRAM_OUTPUT.
415 */
416 for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
417 if (!prog->_LinkedShaders[i])
418 continue;
419 if (input_stage == MESA_SHADER_STAGES)
420 input_stage = i;
421 output_stage = i;
422 }
423
424 /* Empty shader, no resources. */
425 if (input_stage == MESA_SHADER_STAGES && output_stage == 0)
426 return;
427
428 struct set *resource_set = _mesa_pointer_set_create(NULL);
429
430 /* Add inputs and outputs to the resource list. */
431 if (!add_interface_variables(ctx, prog, resource_set, input_stage,
432 GL_PROGRAM_INPUT)) {
433 return;
434 }
435
436 if (!add_interface_variables(ctx, prog, resource_set, output_stage,
437 GL_PROGRAM_OUTPUT)) {
438 return;
439 }
440
441 /* Add transform feedback varyings and buffers. */
442 if (prog->last_vert_prog) {
443 struct gl_transform_feedback_info *linked_xfb =
444 prog->last_vert_prog->sh.LinkedTransformFeedback;
445
446 /* Add varyings. */
447 if (linked_xfb->NumVarying > 0) {
448 for (int i = 0; i < linked_xfb->NumVarying; i++) {
449 if (!link_util_add_program_resource(prog, resource_set,
450 GL_TRANSFORM_FEEDBACK_VARYING,
451 &linked_xfb->Varyings[i], 0))
452 return;
453 }
454 }
455
456 /* Add buffers. */
457 for (unsigned i = 0; i < ctx->Const.MaxTransformFeedbackBuffers; i++) {
458 if ((linked_xfb->ActiveBuffers >> i) & 1) {
459 linked_xfb->Buffers[i].Binding = i;
460 if (!link_util_add_program_resource(prog, resource_set,
461 GL_TRANSFORM_FEEDBACK_BUFFER,
462 &linked_xfb->Buffers[i], 0))
463 return;
464 }
465 }
466 }
467
468 /* Add uniforms
469 *
470 * Here, it is expected that nir_link_uniforms() has already been
471 * called, so that UniformStorage table is already available.
472 */
473 int top_level_array_base_offset = -1;
474 int top_level_array_size_in_bytes = -1;
475 int second_element_offset = -1;
476 int block_index = -1;
477 for (unsigned i = 0; i < prog->data->NumUniformStorage; i++) {
478 struct gl_uniform_storage *uniform = &prog->data->UniformStorage[i];
479
480 if (uniform->hidden) {
481 for (int j = MESA_SHADER_VERTEX; j < MESA_SHADER_STAGES; j++) {
482 if (!uniform->opaque[j].active ||
483 glsl_get_base_type(uniform->type) != GLSL_TYPE_SUBROUTINE)
484 continue;
485
486 GLenum type =
487 _mesa_shader_stage_to_subroutine_uniform((gl_shader_stage)j);
488 /* add shader subroutines */
489 if (!link_util_add_program_resource(prog, resource_set,
490 type, uniform, 0))
491 return;
492 }
493
494 continue;
495 }
496
497 if (!link_util_should_add_buffer_variable(prog, uniform,
498 top_level_array_base_offset,
499 top_level_array_size_in_bytes,
500 second_element_offset, block_index))
501 continue;
502
503
504 if (prog->data->UniformStorage[i].offset >= second_element_offset) {
505 top_level_array_base_offset =
506 prog->data->UniformStorage[i].offset;
507
508 top_level_array_size_in_bytes =
509 prog->data->UniformStorage[i].top_level_array_size *
510 prog->data->UniformStorage[i].top_level_array_stride;
511
512 /* Set or reset the second element offset. For non arrays this
513 * will be set to -1.
514 */
515 second_element_offset = top_level_array_size_in_bytes ?
516 top_level_array_base_offset +
517 prog->data->UniformStorage[i].top_level_array_stride : -1;
518 }
519 block_index = uniform->block_index;
520
521
522 GLenum interface = uniform->is_shader_storage ? GL_BUFFER_VARIABLE : GL_UNIFORM;
523 if (!link_util_add_program_resource(prog, resource_set, interface, uniform,
524 uniform->active_shader_mask)) {
525 return;
526 }
527 }
528
529
530 for (unsigned i = 0; i < prog->data->NumUniformBlocks; i++) {
531 if (!link_util_add_program_resource(prog, resource_set, GL_UNIFORM_BLOCK,
532 &prog->data->UniformBlocks[i],
533 prog->data->UniformBlocks[i].stageref))
534 return;
535 }
536
537 for (unsigned i = 0; i < prog->data->NumShaderStorageBlocks; i++) {
538 if (!link_util_add_program_resource(prog, resource_set, GL_SHADER_STORAGE_BLOCK,
539 &prog->data->ShaderStorageBlocks[i],
540 prog->data->ShaderStorageBlocks[i].stageref))
541 return;
542 }
543
544 /* Add atomic counter buffers. */
545 for (unsigned i = 0; i < prog->data->NumAtomicBuffers; i++) {
546 if (!link_util_add_program_resource(prog, resource_set, GL_ATOMIC_COUNTER_BUFFER,
547 &prog->data->AtomicBuffers[i], 0))
548 return;
549 }
550
551 unsigned mask = prog->data->linked_stages;
552 while (mask) {
553 const int i = u_bit_scan(&mask);
554 struct gl_program *p = prog->_LinkedShaders[i]->Program;
555
556 GLuint type = _mesa_shader_stage_to_subroutine((gl_shader_stage)i);
557 for (unsigned j = 0; j < p->sh.NumSubroutineFunctions; j++) {
558 if (!link_util_add_program_resource(prog, resource_set,
559 type,
560 &p->sh.SubroutineFunctions[j],
561 0))
562 return;
563 }
564 }
565
566 _mesa_set_destroy(resource_set, NULL);
567 }
568
569 bool
570 gl_nir_link_spirv(struct gl_context *ctx, struct gl_shader_program *prog,
571 const struct gl_nir_linker_options *options)
572 {
573 if (!gl_nir_link_uniform_blocks(ctx, prog))
574 return false;
575
576 if (!gl_nir_link_uniforms(ctx, prog, options->fill_parameters))
577 return false;
578
579 gl_nir_link_assign_atomic_counter_resources(ctx, prog);
580 gl_nir_link_assign_xfb_resources(ctx, prog);
581
582 return true;
583 }
584
585 /**
586 * Validate shader image resources.
587 */
588 static void
589 check_image_resources(struct gl_context *ctx, struct gl_shader_program *prog)
590 {
591 unsigned total_image_units = 0;
592 unsigned fragment_outputs = 0;
593 unsigned total_shader_storage_blocks = 0;
594
595 if (!ctx->Extensions.ARB_shader_image_load_store)
596 return;
597
598 for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
599 struct gl_linked_shader *sh = prog->_LinkedShaders[i];
600 if (!sh)
601 continue;
602
603 total_image_units += sh->Program->info.num_images;
604 total_shader_storage_blocks += sh->Program->info.num_ssbos;
605 }
606
607 if (total_image_units > ctx->Const.MaxCombinedImageUniforms)
608 linker_error(prog, "Too many combined image uniforms\n");
609
610 struct gl_linked_shader *frag_sh =
611 prog->_LinkedShaders[MESA_SHADER_FRAGMENT];
612 if (frag_sh) {
613 uint64_t frag_outputs_written = frag_sh->Program->info.outputs_written;
614 fragment_outputs = util_bitcount64(frag_outputs_written);
615 }
616
617 if (total_image_units + fragment_outputs + total_shader_storage_blocks >
618 ctx->Const.MaxCombinedShaderOutputResources)
619 linker_error(prog, "Too many combined image uniforms, shader storage "
620 " buffers and fragment outputs\n");
621 }
622
623 bool
624 gl_nir_link_glsl(struct gl_context *ctx, struct gl_shader_program *prog)
625 {
626 link_util_check_uniform_resources(ctx, prog);
627 link_util_check_subroutine_resources(prog);
628 check_image_resources(ctx, prog);
629 gl_nir_link_assign_atomic_counter_resources(ctx, prog);
630 gl_nir_link_check_atomic_counter_resources(ctx, prog);
631
632 if (prog->data->LinkStatus == LINKING_FAILURE)
633 return false;
634
635 return true;
636 }