• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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                                 &current_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