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 <ctype.h>
25
26 #include "glsl_types.h"
27 #include "linker_util.h"
28 #include "util/bitscan.h"
29 #include "util/set.h"
30 #include "main/consts_exts.h"
31
32 void
linker_error(gl_shader_program * prog,const char * fmt,...)33 linker_error(gl_shader_program *prog, const char *fmt, ...)
34 {
35 va_list ap;
36
37 ralloc_strcat(&prog->data->InfoLog, "error: ");
38 va_start(ap, fmt);
39 ralloc_vasprintf_append(&prog->data->InfoLog, fmt, ap);
40 va_end(ap);
41
42 prog->data->LinkStatus = LINKING_FAILURE;
43 }
44
45 void
linker_warning(gl_shader_program * prog,const char * fmt,...)46 linker_warning(gl_shader_program *prog, const char *fmt, ...)
47 {
48 va_list ap;
49
50 ralloc_strcat(&prog->data->InfoLog, "warning: ");
51 va_start(ap, fmt);
52 ralloc_vasprintf_append(&prog->data->InfoLog, fmt, ap);
53 va_end(ap);
54
55 }
56
57 void
link_shaders_init(struct gl_context * ctx,struct gl_shader_program * prog)58 link_shaders_init(struct gl_context *ctx, struct gl_shader_program *prog)
59 {
60 prog->data->LinkStatus = LINKING_SUCCESS; /* All error paths will set this to false */
61 prog->data->Validated = false;
62
63 /* Section 7.3 (Program Objects) of the OpenGL 4.5 Core Profile spec says:
64 *
65 * "Linking can fail for a variety of reasons as specified in the
66 * OpenGL Shading Language Specification, as well as any of the
67 * following reasons:
68 *
69 * - No shader objects are attached to program."
70 *
71 * The Compatibility Profile specification does not list the error. In
72 * Compatibility Profile missing shader stages are replaced by
73 * fixed-function. This applies to the case where all stages are
74 * missing.
75 */
76 if (prog->NumShaders == 0) {
77 if (ctx->API != API_OPENGL_COMPAT)
78 linker_error(prog, "no shaders attached to the program\n");
79 return;
80 }
81 }
82
83 /**
84 * Given a string identifying a program resource, break it into a base name
85 * and an optional array index in square brackets.
86 *
87 * If an array index is present, \c out_base_name_end is set to point to the
88 * "[" that precedes the array index, and the array index itself is returned
89 * as a long.
90 *
91 * If no array index is present (or if the array index is negative or
92 * mal-formed), \c out_base_name_end, is set to point to the null terminator
93 * at the end of the input string, and -1 is returned.
94 *
95 * Only the final array index is parsed; if the string contains other array
96 * indices (or structure field accesses), they are left in the base name.
97 *
98 * No attempt is made to check that the base name is properly formed;
99 * typically the caller will look up the base name in a hash table, so
100 * ill-formed base names simply turn into hash table lookup failures.
101 */
102 long
link_util_parse_program_resource_name(const GLchar * name,const size_t len,const GLchar ** out_base_name_end)103 link_util_parse_program_resource_name(const GLchar *name, const size_t len,
104 const GLchar **out_base_name_end)
105 {
106 /* Section 7.3.1 ("Program Interfaces") of the OpenGL 4.3 spec says:
107 *
108 * "When an integer array element or block instance number is part of
109 * the name string, it will be specified in decimal form without a "+"
110 * or "-" sign or any extra leading zeroes. Additionally, the name
111 * string will not include white space anywhere in the string."
112 */
113
114 *out_base_name_end = name + len;
115
116 if (len == 0 || name[len-1] != ']')
117 return -1;
118
119 /* Walk backwards over the string looking for a non-digit character. This
120 * had better be the opening bracket for an array index.
121 *
122 * Initially, i specifies the location of the ']'. Since the string may
123 * contain only the ']' charcater, walk backwards very carefully.
124 */
125 unsigned i;
126 for (i = len - 1; (i > 0) && isdigit(name[i-1]); --i)
127 /* empty */ ;
128
129 if ((i == 0) || name[i-1] != '[')
130 return -1;
131
132 long array_index = strtol(&name[i], NULL, 10);
133 if (array_index < 0)
134 return -1;
135
136 /* Check for leading zero */
137 if (name[i] == '0' && name[i+1] != ']')
138 return -1;
139
140 *out_base_name_end = name + (i - 1);
141 return array_index;
142 }
143
144 /* Utility methods shared between the GLSL IR and the NIR */
145
146 /* From the OpenGL 4.6 specification, 7.3.1.1 Naming Active Resources:
147 *
148 * "For an active shader storage block member declared as an array of an
149 * aggregate type, an entry will be generated only for the first array
150 * element, regardless of its type. Such block members are referred to as
151 * top-level arrays. If the block member is an aggregate type, the
152 * enumeration rules are then applied recursively."
153 */
154 bool
link_util_should_add_buffer_variable(struct gl_shader_program * prog,struct gl_uniform_storage * uniform,int top_level_array_base_offset,int top_level_array_size_in_bytes,int second_element_offset,int block_index)155 link_util_should_add_buffer_variable(struct gl_shader_program *prog,
156 struct gl_uniform_storage *uniform,
157 int top_level_array_base_offset,
158 int top_level_array_size_in_bytes,
159 int second_element_offset,
160 int block_index)
161 {
162 /* If the uniform is not a shader storage buffer or is not an array return
163 * true.
164 */
165 if (!uniform->is_shader_storage || top_level_array_size_in_bytes == 0)
166 return true;
167
168 int after_top_level_array = top_level_array_base_offset +
169 top_level_array_size_in_bytes;
170
171 /* Check for a new block, or that we are not dealing with array elements of
172 * a top member array other than the first element.
173 */
174 if (block_index != uniform->block_index ||
175 uniform->offset >= after_top_level_array ||
176 uniform->offset < second_element_offset) {
177 return true;
178 }
179
180 return false;
181 }
182
183 bool
link_util_add_program_resource(struct gl_shader_program * prog,struct set * resource_set,GLenum type,const void * data,uint8_t stages)184 link_util_add_program_resource(struct gl_shader_program *prog,
185 struct set *resource_set,
186 GLenum type, const void *data, uint8_t stages)
187 {
188 assert(data);
189
190 /* If resource already exists, do not add it again. */
191 if (_mesa_set_search(resource_set, data))
192 return true;
193
194 prog->data->ProgramResourceList =
195 reralloc(prog->data,
196 prog->data->ProgramResourceList,
197 gl_program_resource,
198 prog->data->NumProgramResourceList + 1);
199
200 if (!prog->data->ProgramResourceList) {
201 linker_error(prog, "Out of memory during linking.\n");
202 return false;
203 }
204
205 struct gl_program_resource *res =
206 &prog->data->ProgramResourceList[prog->data->NumProgramResourceList];
207
208 res->Type = type;
209 res->Data = data;
210 res->StageReferences = stages;
211
212 prog->data->NumProgramResourceList++;
213
214 _mesa_set_add(resource_set, data);
215
216 return true;
217 }
218
219 /**
220 * Search through the list of empty blocks to find one that fits the current
221 * uniform.
222 */
223 int
link_util_find_empty_block(struct gl_shader_program * prog,struct gl_uniform_storage * uniform)224 link_util_find_empty_block(struct gl_shader_program *prog,
225 struct gl_uniform_storage *uniform)
226 {
227 const unsigned entries = MAX2(1, uniform->array_elements);
228
229 foreach_list_typed(struct empty_uniform_block, block, link,
230 &prog->EmptyUniformLocations) {
231 /* Found a block with enough slots to fit the uniform */
232 if (block->slots == entries) {
233 unsigned start = block->start;
234 exec_node_remove(&block->link);
235 ralloc_free(block);
236
237 return start;
238 /* Found a block with more slots than needed. It can still be used. */
239 } else if (block->slots > entries) {
240 unsigned start = block->start;
241 block->start += entries;
242 block->slots -= entries;
243
244 return start;
245 }
246 }
247
248 return -1;
249 }
250
251 void
link_util_update_empty_uniform_locations(struct gl_shader_program * prog)252 link_util_update_empty_uniform_locations(struct gl_shader_program *prog)
253 {
254 struct empty_uniform_block *current_block = NULL;
255
256 for (unsigned i = 0; i < prog->NumUniformRemapTable; i++) {
257 /* We found empty space in UniformRemapTable. */
258 if (prog->UniformRemapTable[i] == NULL) {
259 /* We've found the beginning of a new continous block of empty slots */
260 if (!current_block || current_block->start + current_block->slots != i) {
261 current_block = rzalloc(prog, struct empty_uniform_block);
262 current_block->start = i;
263 exec_list_push_tail(&prog->EmptyUniformLocations,
264 ¤t_block->link);
265 }
266
267 /* The current block continues, so we simply increment its slots */
268 current_block->slots++;
269 }
270 }
271 }
272
273 void
link_util_check_subroutine_resources(struct gl_shader_program * prog)274 link_util_check_subroutine_resources(struct gl_shader_program *prog)
275 {
276 unsigned mask = prog->data->linked_stages;
277 while (mask) {
278 const int i = u_bit_scan(&mask);
279 struct gl_program *p = prog->_LinkedShaders[i]->Program;
280
281 if (p->sh.NumSubroutineUniformRemapTable > MAX_SUBROUTINE_UNIFORM_LOCATIONS) {
282 linker_error(prog, "Too many %s shader subroutine uniforms\n",
283 _mesa_shader_stage_to_string(i));
284 }
285 }
286 }
287
288 #if defined(_MSC_VER) && DETECT_ARCH_AARCH64
289 // Work around https://developercommunity.visualstudio.com/t/Incorrect-ARM64-codegen-with-optimizatio/10564605
290 #pragma optimize("", off)
291 #endif
292 /**
293 * Validate uniform resources used by a program versus the implementation limits
294 */
295 void
link_util_check_uniform_resources(const struct gl_constants * consts,struct gl_shader_program * prog)296 link_util_check_uniform_resources(const struct gl_constants *consts,
297 struct gl_shader_program *prog)
298 {
299 unsigned total_uniform_blocks = 0;
300 unsigned total_shader_storage_blocks = 0;
301
302 for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
303 struct gl_linked_shader *sh = prog->_LinkedShaders[i];
304
305 if (sh == NULL)
306 continue;
307
308 if (sh->num_uniform_components >
309 consts->Program[i].MaxUniformComponents) {
310 if (consts->GLSLSkipStrictMaxUniformLimitCheck) {
311 linker_warning(prog, "Too many %s shader default uniform block "
312 "components, but the driver will try to optimize "
313 "them out; this is non-portable out-of-spec "
314 "behavior\n",
315 _mesa_shader_stage_to_string(i));
316 } else {
317 linker_error(prog, "Too many %s shader default uniform block "
318 "components\n",
319 _mesa_shader_stage_to_string(i));
320 }
321 }
322
323 if (sh->num_combined_uniform_components >
324 consts->Program[i].MaxCombinedUniformComponents) {
325 if (consts->GLSLSkipStrictMaxUniformLimitCheck) {
326 linker_warning(prog, "Too many %s shader uniform components, "
327 "but the driver will try to optimize them out; "
328 "this is non-portable out-of-spec behavior\n",
329 _mesa_shader_stage_to_string(i));
330 } else {
331 linker_error(prog, "Too many %s shader uniform components\n",
332 _mesa_shader_stage_to_string(i));
333 }
334 }
335
336 total_shader_storage_blocks += sh->Program->info.num_ssbos;
337 total_uniform_blocks += sh->Program->info.num_ubos;
338 }
339
340 if (total_uniform_blocks > consts->MaxCombinedUniformBlocks) {
341 linker_error(prog, "Too many combined uniform blocks (%d/%d)\n",
342 total_uniform_blocks, consts->MaxCombinedUniformBlocks);
343 }
344
345 if (total_shader_storage_blocks > consts->MaxCombinedShaderStorageBlocks) {
346 linker_error(prog, "Too many combined shader storage blocks (%d/%d)\n",
347 total_shader_storage_blocks,
348 consts->MaxCombinedShaderStorageBlocks);
349 }
350
351 for (unsigned i = 0; i < prog->data->NumUniformBlocks; i++) {
352 if (prog->data->UniformBlocks[i].UniformBufferSize >
353 consts->MaxUniformBlockSize) {
354 linker_error(prog, "Uniform block %s too big (%d/%d)\n",
355 prog->data->UniformBlocks[i].name.string,
356 prog->data->UniformBlocks[i].UniformBufferSize,
357 consts->MaxUniformBlockSize);
358 }
359 }
360
361 for (unsigned i = 0; i < prog->data->NumShaderStorageBlocks; i++) {
362 if (prog->data->ShaderStorageBlocks[i].UniformBufferSize >
363 consts->MaxShaderStorageBlockSize) {
364 linker_error(prog, "Shader storage block %s too big (%d/%d)\n",
365 prog->data->ShaderStorageBlocks[i].name.string,
366 prog->data->ShaderStorageBlocks[i].UniformBufferSize,
367 consts->MaxShaderStorageBlockSize);
368 }
369 }
370 }
371 #if defined(_MSC_VER) && DETECT_ARCH_AARCH64
372 #pragma optimize("", on)
373 #endif
374
375 void
link_util_calculate_subroutine_compat(struct gl_shader_program * prog)376 link_util_calculate_subroutine_compat(struct gl_shader_program *prog)
377 {
378 unsigned mask = prog->data->linked_stages;
379 while (mask) {
380 const int i = u_bit_scan(&mask);
381 struct gl_program *p = prog->_LinkedShaders[i]->Program;
382
383 for (unsigned j = 0; j < p->sh.NumSubroutineUniformRemapTable; j++) {
384 if (p->sh.SubroutineUniformRemapTable[j] == INACTIVE_UNIFORM_EXPLICIT_LOCATION)
385 continue;
386
387 struct gl_uniform_storage *uni = p->sh.SubroutineUniformRemapTable[j];
388
389 if (!uni)
390 continue;
391
392 int count = 0;
393 if (p->sh.NumSubroutineFunctions == 0) {
394 linker_error(prog, "subroutine uniform %s defined but no valid functions found\n", glsl_get_type_name(uni->type));
395 continue;
396 }
397 for (unsigned f = 0; f < p->sh.NumSubroutineFunctions; f++) {
398 struct gl_subroutine_function *fn = &p->sh.SubroutineFunctions[f];
399 for (int k = 0; k < fn->num_compat_types; k++) {
400 if (fn->types[k] == uni->type) {
401 count++;
402 break;
403 }
404 }
405 }
406 uni->num_compatible_subroutines = count;
407 }
408 }
409 }
410
411 /**
412 * Recursive part of the public mark_array_elements_referenced function.
413 *
414 * The recursion occurs when an entire array-of- is accessed. See the
415 * implementation for more details.
416 *
417 * \param dr List of array_deref_range elements to be
418 * processed.
419 * \param count Number of array_deref_range elements to be
420 * processed.
421 * \param scale Current offset scale.
422 * \param linearized_index Current accumulated linearized array index.
423 */
424 void
_mark_array_elements_referenced(const struct array_deref_range * dr,unsigned count,unsigned scale,unsigned linearized_index,BITSET_WORD * bits)425 _mark_array_elements_referenced(const struct array_deref_range *dr,
426 unsigned count, unsigned scale,
427 unsigned linearized_index,
428 BITSET_WORD *bits)
429 {
430 /* Walk through the list of array dereferences in least- to
431 * most-significant order. Along the way, accumulate the current
432 * linearized offset and the scale factor for each array-of-.
433 */
434 for (unsigned i = 0; i < count; i++) {
435 if (dr[i].index < dr[i].size) {
436 linearized_index += dr[i].index * scale;
437 scale *= dr[i].size;
438 } else {
439 /* For each element in the current array, update the count and
440 * offset, then recurse to process the remaining arrays.
441 *
442 * There is some inefficency here if the last eBITSET_WORD *bitslement in the
443 * array_deref_range list specifies the entire array. In that case,
444 * the loop will make recursive calls with count == 0. In the call,
445 * all that will happen is the bit will be set.
446 */
447 for (unsigned j = 0; j < dr[i].size; j++) {
448 _mark_array_elements_referenced(&dr[i + 1],
449 count - (i + 1),
450 scale * dr[i].size,
451 linearized_index + (j * scale),
452 bits);
453 }
454
455 return;
456 }
457 }
458
459 BITSET_SET(bits, linearized_index);
460 }
461
462 /**
463 * Mark a set of array elements as accessed.
464 *
465 * If every \c array_deref_range is for a single index, only a single
466 * element will be marked. If any \c array_deref_range is for an entire
467 * array-of-, then multiple elements will be marked.
468 *
469 * Items in the \c array_deref_range list appear in least- to
470 * most-significant order. This is the \b opposite order the indices
471 * appear in the GLSL shader text. An array access like
472 *
473 * x = y[1][i][3];
474 *
475 * would appear as
476 *
477 * { { 3, n }, { m, m }, { 1, p } }
478 *
479 * where n, m, and p are the sizes of the arrays-of-arrays.
480 *
481 * The set of marked array elements can later be queried by
482 * \c ::is_linearized_index_referenced.
483 *
484 * \param dr List of array_deref_range elements to be processed.
485 * \param count Number of array_deref_range elements to be processed.
486 */
487 void
link_util_mark_array_elements_referenced(const struct array_deref_range * dr,unsigned count,unsigned array_depth,BITSET_WORD * bits)488 link_util_mark_array_elements_referenced(const struct array_deref_range *dr,
489 unsigned count, unsigned array_depth,
490 BITSET_WORD *bits)
491 {
492 if (count != array_depth)
493 return;
494
495 _mark_array_elements_referenced(dr, count, 1, 0, bits);
496 }
497
498 const char *
interpolation_string(unsigned interpolation)499 interpolation_string(unsigned interpolation)
500 {
501 switch (interpolation) {
502 case INTERP_MODE_NONE: return "no";
503 case INTERP_MODE_SMOOTH: return "smooth";
504 case INTERP_MODE_FLAT: return "flat";
505 case INTERP_MODE_NOPERSPECTIVE: return "noperspective";
506 }
507
508 assert(!"Should not get here.");
509 return "";
510 }
511
512 bool
_mesa_glsl_can_implicitly_convert(const glsl_type * from,const glsl_type * desired,bool has_implicit_conversions,bool has_implicit_int_to_uint_conversion)513 _mesa_glsl_can_implicitly_convert(const glsl_type *from, const glsl_type *desired,
514 bool has_implicit_conversions,
515 bool has_implicit_int_to_uint_conversion)
516 {
517 if (from == desired)
518 return true;
519
520 /* GLSL 1.10 and ESSL do not allow implicit conversions. */
521 if (!has_implicit_conversions)
522 return false;
523
524 /* There is no conversion among matrix types. */
525 if (from->matrix_columns > 1 || desired->matrix_columns > 1)
526 return false;
527
528 /* Vector size must match. */
529 if (from->vector_elements != desired->vector_elements)
530 return false;
531
532 /* int and uint can be converted to float. */
533 if (glsl_type_is_float(desired) && (glsl_type_is_integer_32(from) ||
534 glsl_type_is_float_16(from)))
535 return true;
536
537 /* With GLSL 4.0, ARB_gpu_shader5, or MESA_shader_integer_functions, int
538 * can be converted to uint. Note that state may be NULL here, when
539 * resolving function calls in the linker. By this time, all the
540 * state-dependent checks have already happened though, so allow anything
541 * that's allowed in any shader version.
542 */
543 if (has_implicit_int_to_uint_conversion &&
544 desired->base_type == GLSL_TYPE_UINT && from->base_type == GLSL_TYPE_INT)
545 return true;
546
547 /* No implicit conversions from double. */
548 if (glsl_type_is_double(from))
549 return false;
550
551 /* Conversions from different types to double. */
552 if (glsl_type_is_double(desired)) {
553 if (glsl_type_is_float_16_32(from))
554 return true;
555 if (glsl_type_is_integer_32(from))
556 return true;
557 }
558
559 return false;
560 }
561
562 void
resource_name_updated(struct gl_resource_name * name)563 resource_name_updated(struct gl_resource_name *name)
564 {
565 if (name->string) {
566 name->length = strlen(name->string);
567
568 const char *last_square_bracket = strrchr(name->string, '[');
569 if (last_square_bracket) {
570 name->last_square_bracket = last_square_bracket - name->string;
571 name->suffix_is_zero_square_bracketed =
572 strcmp(last_square_bracket, "[0]") == 0;
573 } else {
574 name->last_square_bracket = -1;
575 name->suffix_is_zero_square_bracketed = false;
576 }
577 } else {
578 name->length = 0;
579 name->last_square_bracket = -1;
580 name->suffix_is_zero_square_bracketed = false;
581 }
582 }
583