1/*
2 * Copyright © 2011 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
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24/**
25 * \file shader_query.cpp
26 * C-to-C++ bridge functions to query GLSL shader data
27 *
28 * \author Ian Romanick <ian.d.romanick@intel.com>
29 */
30
31#include "main/context.h"
32#include "main/enums.h"
33#include "main/shaderapi.h"
34#include "main/shaderobj.h"
35#include "main/uniforms.h"
36#include "compiler/glsl/glsl_symbol_table.h"
37#include "compiler/glsl/ir.h"
38#include "compiler/glsl/linker_util.h"
39#include "compiler/glsl/string_to_uint_map.h"
40#include "util/mesa-sha1.h"
41#include "c99_alloca.h"
42#include "api_exec_decl.h"
43
44static GLint
45program_resource_location(struct gl_program_resource *res,
46                          unsigned array_index);
47
48/**
49 * Declare convenience functions to return resource data in a given type.
50 * Warning! this is not type safe so be *very* careful when using these.
51 */
52#define DECL_RESOURCE_FUNC(name, type) \
53const type * RESOURCE_ ## name (gl_program_resource *res) { \
54   assert(res->Data); \
55   return (type *) res->Data; \
56}
57
58DECL_RESOURCE_FUNC(VAR, gl_shader_variable);
59DECL_RESOURCE_FUNC(UBO, gl_uniform_block);
60DECL_RESOURCE_FUNC(UNI, gl_uniform_storage);
61DECL_RESOURCE_FUNC(ATC, gl_active_atomic_buffer);
62DECL_RESOURCE_FUNC(XFV, gl_transform_feedback_varying_info);
63DECL_RESOURCE_FUNC(XFB, gl_transform_feedback_buffer);
64DECL_RESOURCE_FUNC(SUB, gl_subroutine_function);
65
66static GLenum
67mediump_to_highp_type(GLenum type)
68{
69   switch (type) {
70   case GL_FLOAT16_NV:
71      return GL_FLOAT;
72   case GL_FLOAT16_VEC2_NV:
73      return GL_FLOAT_VEC2;
74   case GL_FLOAT16_VEC3_NV:
75      return GL_FLOAT_VEC3;
76   case GL_FLOAT16_VEC4_NV:
77      return GL_FLOAT_VEC4;
78   case GL_FLOAT16_MAT2_AMD:
79      return GL_FLOAT_MAT2;
80   case GL_FLOAT16_MAT3_AMD:
81      return GL_FLOAT_MAT3;
82   case GL_FLOAT16_MAT4_AMD:
83      return GL_FLOAT_MAT4;
84   case GL_FLOAT16_MAT2x3_AMD:
85      return GL_FLOAT_MAT2x3;
86   case GL_FLOAT16_MAT2x4_AMD:
87      return GL_FLOAT_MAT2x4;
88   case GL_FLOAT16_MAT3x2_AMD:
89      return GL_FLOAT_MAT3x2;
90   case GL_FLOAT16_MAT3x4_AMD:
91      return GL_FLOAT_MAT3x4;
92   case GL_FLOAT16_MAT4x2_AMD:
93      return GL_FLOAT_MAT4x2;
94   case GL_FLOAT16_MAT4x3_AMD:
95      return GL_FLOAT_MAT4x3;
96   default:
97      return type;
98   }
99}
100
101static void
102bind_attrib_location(struct gl_context *ctx,
103                     struct gl_shader_program *const shProg, GLuint index,
104                     const GLchar *name, bool no_error)
105{
106   if (!name)
107      return;
108
109   if (!no_error) {
110      if (strncmp(name, "gl_", 3) == 0) {
111         _mesa_error(ctx, GL_INVALID_OPERATION,
112                     "glBindAttribLocation(illegal name)");
113         return;
114      }
115
116      if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
117         _mesa_error(ctx, GL_INVALID_VALUE, "glBindAttribLocation(%u >= %u)",
118                     index, ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs);
119         return;
120      }
121   }
122
123   /* Replace the current value if it's already in the list.  Add
124    * VERT_ATTRIB_GENERIC0 because that's how the linker differentiates
125    * between built-in attributes and user-defined attributes.
126    */
127   shProg->AttributeBindings->put(index + VERT_ATTRIB_GENERIC0, name);
128
129   /*
130    * Note that this attribute binding won't go into effect until
131    * glLinkProgram is called again.
132    */
133}
134
135void GLAPIENTRY
136_mesa_BindAttribLocation_no_error(GLuint program, GLuint index,
137                                  const GLchar *name)
138{
139   GET_CURRENT_CONTEXT(ctx);
140
141   struct gl_shader_program *const shProg =
142      _mesa_lookup_shader_program(ctx, program);
143   bind_attrib_location(ctx, shProg, index, name, true);
144}
145
146void GLAPIENTRY
147_mesa_BindAttribLocation(GLuint program, GLuint index,
148                         const GLchar *name)
149{
150   GET_CURRENT_CONTEXT(ctx);
151
152   struct gl_shader_program *const shProg =
153      _mesa_lookup_shader_program_err(ctx, program, "glBindAttribLocation");
154   if (!shProg)
155      return;
156
157   bind_attrib_location(ctx, shProg, index, name, false);
158}
159
160void GLAPIENTRY
161_mesa_GetActiveAttrib(GLuint program, GLuint desired_index,
162                      GLsizei maxLength, GLsizei * length, GLint * size,
163                      GLenum * type, GLchar * name)
164{
165   GET_CURRENT_CONTEXT(ctx);
166   struct gl_shader_program *shProg;
167
168   if (maxLength < 0) {
169      _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(maxLength < 0)");
170      return;
171   }
172
173   shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveAttrib");
174   if (!shProg)
175      return;
176
177   if (!shProg->data->LinkStatus) {
178      _mesa_error(ctx, GL_INVALID_VALUE,
179                  "glGetActiveAttrib(program not linked)");
180      return;
181   }
182
183   if (shProg->_LinkedShaders[MESA_SHADER_VERTEX] == NULL) {
184      _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(no vertex shader)");
185      return;
186   }
187
188   struct gl_program_resource *res =
189      _mesa_program_resource_find_index(shProg, GL_PROGRAM_INPUT,
190                                        desired_index);
191
192   /* User asked for index that does not exist. */
193   if (!res) {
194      _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(index)");
195      return;
196   }
197
198   const gl_shader_variable *const var = RESOURCE_VAR(res);
199
200   const char *var_name = var->name.string;
201
202   _mesa_copy_string(name, maxLength, length, var_name);
203
204   if (size)
205      _mesa_program_resource_prop(shProg, res, desired_index, GL_ARRAY_SIZE,
206                                  size, false, "glGetActiveAttrib");
207
208   if (type)
209      _mesa_program_resource_prop(shProg, res, desired_index, GL_TYPE,
210                                  (GLint *) type, false, "glGetActiveAttrib");
211}
212
213GLint GLAPIENTRY
214_mesa_GetAttribLocation(GLuint program, const GLchar * name)
215{
216   GET_CURRENT_CONTEXT(ctx);
217   struct gl_shader_program *const shProg =
218      _mesa_lookup_shader_program_err(ctx, program, "glGetAttribLocation");
219
220   if (!shProg) {
221      return -1;
222   }
223
224   if (!shProg->data->LinkStatus) {
225      _mesa_error(ctx, GL_INVALID_OPERATION,
226                  "glGetAttribLocation(program not linked)");
227      return -1;
228   }
229
230   if (!name)
231      return -1;
232
233   /* Not having a vertex shader is not an error.
234    */
235   if (shProg->_LinkedShaders[MESA_SHADER_VERTEX] == NULL)
236      return -1;
237
238   unsigned array_index = 0;
239   struct gl_program_resource *res =
240      _mesa_program_resource_find_name(shProg, GL_PROGRAM_INPUT, name,
241                                       &array_index);
242
243   if (!res)
244      return -1;
245
246   return program_resource_location(res, array_index);
247}
248
249unsigned
250_mesa_count_active_attribs(struct gl_shader_program *shProg)
251{
252   if (!shProg->data->LinkStatus
253       || shProg->_LinkedShaders[MESA_SHADER_VERTEX] == NULL) {
254      return 0;
255   }
256
257   struct gl_program_resource *res = shProg->data->ProgramResourceList;
258   unsigned count = 0;
259   for (unsigned j = 0; j < shProg->data->NumProgramResourceList;
260        j++, res++) {
261      if (res->Type == GL_PROGRAM_INPUT &&
262          res->StageReferences & (1 << MESA_SHADER_VERTEX))
263         count++;
264   }
265   return count;
266}
267
268
269size_t
270_mesa_longest_attribute_name_length(struct gl_shader_program *shProg)
271{
272   if (!shProg->data->LinkStatus
273       || shProg->_LinkedShaders[MESA_SHADER_VERTEX] == NULL) {
274      return 0;
275   }
276
277   struct gl_program_resource *res = shProg->data->ProgramResourceList;
278   size_t longest = 0;
279   for (unsigned j = 0; j < shProg->data->NumProgramResourceList;
280        j++, res++) {
281      if (res->Type == GL_PROGRAM_INPUT &&
282          res->StageReferences & (1 << MESA_SHADER_VERTEX)) {
283
284         /* From the ARB_gl_spirv spec:
285          *
286          *   "If pname is ACTIVE_ATTRIBUTE_MAX_LENGTH, the length of the
287          *    longest active attribute name, including a null terminator, is
288          *    returned.  If no active attributes exist, zero is returned. If
289          *    no name reflection information is available, one is returned."
290          */
291         const size_t length = RESOURCE_VAR(res)->name.length;
292
293         if (length >= longest)
294            longest = length + 1;
295      }
296   }
297
298   return longest;
299}
300
301void static
302bind_frag_data_location(struct gl_shader_program *const shProg,
303                        const char *name, unsigned colorNumber,
304                        unsigned index)
305{
306   /* Replace the current value if it's already in the list.  Add
307    * FRAG_RESULT_DATA0 because that's how the linker differentiates
308    * between built-in attributes and user-defined attributes.
309    */
310   shProg->FragDataBindings->put(colorNumber + FRAG_RESULT_DATA0, name);
311   shProg->FragDataIndexBindings->put(index, name);
312
313   /*
314    * Note that this binding won't go into effect until
315    * glLinkProgram is called again.
316    */
317}
318
319void GLAPIENTRY
320_mesa_BindFragDataLocation(GLuint program, GLuint colorNumber,
321			   const GLchar *name)
322{
323   _mesa_BindFragDataLocationIndexed(program, colorNumber, 0, name);
324}
325
326void GLAPIENTRY
327_mesa_BindFragDataLocation_no_error(GLuint program, GLuint colorNumber,
328                                    const GLchar *name)
329{
330   GET_CURRENT_CONTEXT(ctx);
331
332   if (!name)
333      return;
334
335   struct gl_shader_program *const shProg =
336      _mesa_lookup_shader_program(ctx, program);
337
338   bind_frag_data_location(shProg, name, colorNumber, 0);
339}
340
341void GLAPIENTRY
342_mesa_BindFragDataLocationIndexed(GLuint program, GLuint colorNumber,
343                                  GLuint index, const GLchar *name)
344{
345   GET_CURRENT_CONTEXT(ctx);
346
347   struct gl_shader_program *const shProg =
348      _mesa_lookup_shader_program_err(ctx, program, "glBindFragDataLocationIndexed");
349   if (!shProg)
350      return;
351
352   if (!name)
353      return;
354
355   if (strncmp(name, "gl_", 3) == 0) {
356      _mesa_error(ctx, GL_INVALID_OPERATION, "glBindFragDataLocationIndexed(illegal name)");
357      return;
358   }
359
360   if (index > 1) {
361      _mesa_error(ctx, GL_INVALID_VALUE, "glBindFragDataLocationIndexed(index)");
362      return;
363   }
364
365   if (index == 0 && colorNumber >= ctx->Const.MaxDrawBuffers) {
366      _mesa_error(ctx, GL_INVALID_VALUE, "glBindFragDataLocationIndexed(colorNumber)");
367      return;
368   }
369
370   if (index == 1 && colorNumber >= ctx->Const.MaxDualSourceDrawBuffers) {
371      _mesa_error(ctx, GL_INVALID_VALUE, "glBindFragDataLocationIndexed(colorNumber)");
372      return;
373   }
374
375   bind_frag_data_location(shProg, name, colorNumber, index);
376}
377
378void GLAPIENTRY
379_mesa_BindFragDataLocationIndexed_no_error(GLuint program, GLuint colorNumber,
380                                           GLuint index, const GLchar *name)
381{
382   GET_CURRENT_CONTEXT(ctx);
383
384   if (!name)
385      return;
386
387   struct gl_shader_program *const shProg =
388      _mesa_lookup_shader_program(ctx, program);
389
390   bind_frag_data_location(shProg, name, colorNumber, index);
391}
392
393GLint GLAPIENTRY
394_mesa_GetFragDataIndex(GLuint program, const GLchar *name)
395{
396   GET_CURRENT_CONTEXT(ctx);
397   struct gl_shader_program *const shProg =
398      _mesa_lookup_shader_program_err(ctx, program, "glGetFragDataIndex");
399
400   if (!shProg) {
401      return -1;
402   }
403
404   if (!shProg->data->LinkStatus) {
405      _mesa_error(ctx, GL_INVALID_OPERATION,
406                  "glGetFragDataIndex(program not linked)");
407      return -1;
408   }
409
410   if (!name)
411      return -1;
412
413   /* Not having a fragment shader is not an error.
414    */
415   if (shProg->_LinkedShaders[MESA_SHADER_FRAGMENT] == NULL)
416      return -1;
417
418   return _mesa_program_resource_location_index(shProg, GL_PROGRAM_OUTPUT,
419                                                name);
420}
421
422GLint GLAPIENTRY
423_mesa_GetFragDataLocation(GLuint program, const GLchar *name)
424{
425   GET_CURRENT_CONTEXT(ctx);
426   struct gl_shader_program *const shProg =
427      _mesa_lookup_shader_program_err(ctx, program, "glGetFragDataLocation");
428
429   if (!shProg) {
430      return -1;
431   }
432
433   if (!shProg->data->LinkStatus) {
434      _mesa_error(ctx, GL_INVALID_OPERATION,
435                  "glGetFragDataLocation(program not linked)");
436      return -1;
437   }
438
439   if (!name)
440      return -1;
441
442   /* Not having a fragment shader is not an error.
443    */
444   if (shProg->_LinkedShaders[MESA_SHADER_FRAGMENT] == NULL)
445      return -1;
446
447   unsigned array_index = 0;
448   struct gl_program_resource *res =
449      _mesa_program_resource_find_name(shProg, GL_PROGRAM_OUTPUT, name,
450                                       &array_index);
451
452   if (!res)
453      return -1;
454
455   return program_resource_location(res, array_index);
456}
457
458const char*
459_mesa_program_resource_name(struct gl_program_resource *res)
460{
461   switch (res->Type) {
462   case GL_UNIFORM_BLOCK:
463   case GL_SHADER_STORAGE_BLOCK:
464      return RESOURCE_UBO(res)->name.string;
465   case GL_TRANSFORM_FEEDBACK_VARYING:
466      return RESOURCE_XFV(res)->name.string;
467   case GL_PROGRAM_INPUT:
468   case GL_PROGRAM_OUTPUT:
469      return RESOURCE_VAR(res)->name.string;
470   case GL_UNIFORM:
471   case GL_BUFFER_VARIABLE:
472      return RESOURCE_UNI(res)->name.string;
473   case GL_VERTEX_SUBROUTINE_UNIFORM:
474   case GL_GEOMETRY_SUBROUTINE_UNIFORM:
475   case GL_FRAGMENT_SUBROUTINE_UNIFORM:
476   case GL_COMPUTE_SUBROUTINE_UNIFORM:
477   case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
478   case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
479      return RESOURCE_UNI(res)->name.string + MESA_SUBROUTINE_PREFIX_LEN;
480   case GL_VERTEX_SUBROUTINE:
481   case GL_GEOMETRY_SUBROUTINE:
482   case GL_FRAGMENT_SUBROUTINE:
483   case GL_COMPUTE_SUBROUTINE:
484   case GL_TESS_CONTROL_SUBROUTINE:
485   case GL_TESS_EVALUATION_SUBROUTINE:
486      return RESOURCE_SUB(res)->name.string;
487   default:
488      break;
489   }
490   return NULL;
491}
492
493int
494_mesa_program_resource_name_length(struct gl_program_resource *res)
495{
496   switch (res->Type) {
497   case GL_UNIFORM_BLOCK:
498   case GL_SHADER_STORAGE_BLOCK:
499      return RESOURCE_UBO(res)->name.length;
500   case GL_TRANSFORM_FEEDBACK_VARYING:
501      return RESOURCE_XFV(res)->name.length;
502   case GL_PROGRAM_INPUT:
503   case GL_PROGRAM_OUTPUT:
504      return RESOURCE_VAR(res)->name.length;
505   case GL_UNIFORM:
506   case GL_BUFFER_VARIABLE:
507      return RESOURCE_UNI(res)->name.length;
508   case GL_VERTEX_SUBROUTINE_UNIFORM:
509   case GL_GEOMETRY_SUBROUTINE_UNIFORM:
510   case GL_FRAGMENT_SUBROUTINE_UNIFORM:
511   case GL_COMPUTE_SUBROUTINE_UNIFORM:
512   case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
513   case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
514      return RESOURCE_UNI(res)->name.length - MESA_SUBROUTINE_PREFIX_LEN;
515   case GL_VERTEX_SUBROUTINE:
516   case GL_GEOMETRY_SUBROUTINE:
517   case GL_FRAGMENT_SUBROUTINE:
518   case GL_COMPUTE_SUBROUTINE:
519   case GL_TESS_CONTROL_SUBROUTINE:
520   case GL_TESS_EVALUATION_SUBROUTINE:
521      return RESOURCE_SUB(res)->name.length;
522   default:
523      break;
524   }
525   return 0;
526}
527
528bool
529_mesa_program_get_resource_name(struct gl_program_resource *res,
530                                struct gl_resource_name *out)
531{
532   switch (res->Type) {
533   case GL_UNIFORM_BLOCK:
534   case GL_SHADER_STORAGE_BLOCK:
535      *out = RESOURCE_UBO(res)->name;
536      return out->string != NULL;
537   case GL_TRANSFORM_FEEDBACK_VARYING:
538      *out = RESOURCE_XFV(res)->name;
539      return out->string != NULL;
540   case GL_PROGRAM_INPUT:
541   case GL_PROGRAM_OUTPUT:
542      *out = RESOURCE_VAR(res)->name;
543      return out->string != NULL;
544   case GL_UNIFORM:
545   case GL_BUFFER_VARIABLE:
546      *out = RESOURCE_UNI(res)->name;
547      return out->string != NULL;
548   case GL_VERTEX_SUBROUTINE_UNIFORM:
549   case GL_GEOMETRY_SUBROUTINE_UNIFORM:
550   case GL_FRAGMENT_SUBROUTINE_UNIFORM:
551   case GL_COMPUTE_SUBROUTINE_UNIFORM:
552   case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
553   case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
554      *out = RESOURCE_UNI(res)->name;
555      out->string += MESA_SUBROUTINE_PREFIX_LEN;
556      out->length -= MESA_SUBROUTINE_PREFIX_LEN;
557      assert(out->string); /* always non-NULL */
558      return true;
559   case GL_VERTEX_SUBROUTINE:
560   case GL_GEOMETRY_SUBROUTINE:
561   case GL_FRAGMENT_SUBROUTINE:
562   case GL_COMPUTE_SUBROUTINE:
563   case GL_TESS_CONTROL_SUBROUTINE:
564   case GL_TESS_EVALUATION_SUBROUTINE:
565      *out = RESOURCE_SUB(res)->name;
566      return out->string != NULL;
567   default:
568      return false;
569   }
570}
571
572unsigned
573_mesa_program_resource_array_size(struct gl_program_resource *res)
574{
575   switch (res->Type) {
576   case GL_TRANSFORM_FEEDBACK_VARYING:
577      return RESOURCE_XFV(res)->Size > 1 ?
578             RESOURCE_XFV(res)->Size : 0;
579   case GL_PROGRAM_INPUT:
580   case GL_PROGRAM_OUTPUT:
581      return RESOURCE_VAR(res)->type->length;
582   case GL_UNIFORM:
583   case GL_VERTEX_SUBROUTINE_UNIFORM:
584   case GL_GEOMETRY_SUBROUTINE_UNIFORM:
585   case GL_FRAGMENT_SUBROUTINE_UNIFORM:
586   case GL_COMPUTE_SUBROUTINE_UNIFORM:
587   case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
588   case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
589      return RESOURCE_UNI(res)->array_elements;
590   case GL_BUFFER_VARIABLE:
591      /* Unsized arrays */
592      if (RESOURCE_UNI(res)->array_stride > 0 &&
593          RESOURCE_UNI(res)->array_elements == 0)
594         return 1;
595      else
596         return RESOURCE_UNI(res)->array_elements;
597   case GL_VERTEX_SUBROUTINE:
598   case GL_GEOMETRY_SUBROUTINE:
599   case GL_FRAGMENT_SUBROUTINE:
600   case GL_COMPUTE_SUBROUTINE:
601   case GL_TESS_CONTROL_SUBROUTINE:
602   case GL_TESS_EVALUATION_SUBROUTINE:
603   case GL_ATOMIC_COUNTER_BUFFER:
604   case GL_UNIFORM_BLOCK:
605   case GL_SHADER_STORAGE_BLOCK:
606      return 0;
607   default:
608      assert(!"support for resource type not implemented");
609   }
610   return 0;
611}
612
613/**
614 * Checks if array subscript is valid and if so sets array_index.
615 */
616static bool
617valid_array_index(const GLchar *name, int len, unsigned *array_index)
618{
619   long idx = 0;
620   const GLchar *out_base_name_end;
621
622   idx = link_util_parse_program_resource_name(name, len, &out_base_name_end);
623   if (idx < 0)
624      return false;
625
626   if (array_index)
627      *array_index = idx;
628
629   return true;
630}
631
632static struct gl_program_resource *
633search_resource_hash(struct gl_shader_program *shProg,
634                     GLenum programInterface, const char *name, int len,
635                     unsigned *array_index)
636{
637   unsigned type = GET_PROGRAM_RESOURCE_TYPE_FROM_GLENUM(programInterface);
638   assert(type < ARRAY_SIZE(shProg->data->ProgramResourceHash));
639
640   if (!shProg->data->ProgramResourceHash[type])
641      return NULL;
642
643   const char *base_name_end;
644   long index = link_util_parse_program_resource_name(name, len, &base_name_end);
645   char *name_copy;
646
647   /* If dealing with array, we need to get the basename. */
648   if (index >= 0) {
649      name_copy = (char *) alloca(base_name_end - name + 1);
650      memcpy(name_copy, name, base_name_end - name);
651      name_copy[base_name_end - name] = '\0';
652      len = base_name_end - name;
653   } else {
654      name_copy = (char*) name;
655   }
656
657   uint32_t hash = _mesa_hash_string_with_length(name_copy, len);
658   struct hash_entry *entry =
659      _mesa_hash_table_search_pre_hashed(shProg->data->ProgramResourceHash[type],
660                                         hash, name_copy);
661   if (!entry)
662      return NULL;
663
664   if (array_index)
665      *array_index = index >= 0 ? index : 0;
666
667   return (struct gl_program_resource *)entry->data;
668}
669
670/* Find a program resource with specific name in given interface.
671 */
672struct gl_program_resource *
673_mesa_program_resource_find_name(struct gl_shader_program *shProg,
674                                 GLenum programInterface, const char *name,
675                                 unsigned *array_index)
676{
677   if (name == NULL)
678      return NULL;
679
680   int len = strlen(name);
681
682   /* If we have a name, try the ProgramResourceHash first. */
683   struct gl_program_resource *res =
684      search_resource_hash(shProg, programInterface, name, len, array_index);
685
686   if (res)
687      return res;
688
689   res = shProg->data->ProgramResourceList;
690   for (unsigned i = 0; i < shProg->data->NumProgramResourceList; i++, res++) {
691      if (res->Type != programInterface)
692         continue;
693
694      struct gl_resource_name rname;
695
696      /* Since ARB_gl_spirv lack of name reflections is a possibility */
697      if (!_mesa_program_get_resource_name(res, &rname))
698         continue;
699
700      bool found = false;
701
702      /* From ARB_program_interface_query spec:
703       *
704       * "uint GetProgramResourceIndex(uint program, enum programInterface,
705       *                               const char *name);
706       *  [...]
707       *  If <name> exactly matches the name string of one of the active
708       *  resources for <programInterface>, the index of the matched resource is
709       *  returned. Additionally, if <name> would exactly match the name string
710       *  of an active resource if "[0]" were appended to <name>, the index of
711       *  the matched resource is returned. [...]"
712       *
713       * "A string provided to GetProgramResourceLocation or
714       * GetProgramResourceLocationIndex is considered to match an active variable
715       * if:
716       *
717       *  * the string exactly matches the name of the active variable;
718       *
719       *  * if the string identifies the base name of an active array, where the
720       *    string would exactly match the name of the variable if the suffix
721       *    "[0]" were appended to the string; [...]"
722       */
723      /* Remove array's index from interface block name comparison only if
724       * array's index is zero and the resulting string length is the same
725       * than the provided name's length.
726       */
727      int length_without_array_index =
728         rname.last_square_bracket >= 0 ? rname.last_square_bracket : rname.length;
729      bool rname_has_array_index_zero = rname.suffix_is_zero_square_bracketed &&
730                                        rname.last_square_bracket == len;
731
732      if (len >= rname.length && strncmp(rname.string, name, rname.length) == 0)
733         found = true;
734      else if (rname_has_array_index_zero &&
735               strncmp(rname.string, name, length_without_array_index) == 0)
736         found = true;
737
738      if (found) {
739         switch (programInterface) {
740         case GL_UNIFORM_BLOCK:
741         case GL_SHADER_STORAGE_BLOCK:
742            /* Basename match, check if array or struct. */
743            if (rname_has_array_index_zero ||
744                name[rname.length] == '\0' ||
745                name[rname.length] == '[' ||
746                name[rname.length] == '.') {
747               return res;
748            }
749            break;
750         case GL_TRANSFORM_FEEDBACK_VARYING:
751         case GL_BUFFER_VARIABLE:
752         case GL_UNIFORM:
753         case GL_VERTEX_SUBROUTINE_UNIFORM:
754         case GL_GEOMETRY_SUBROUTINE_UNIFORM:
755         case GL_FRAGMENT_SUBROUTINE_UNIFORM:
756         case GL_COMPUTE_SUBROUTINE_UNIFORM:
757         case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
758         case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
759         case GL_VERTEX_SUBROUTINE:
760         case GL_GEOMETRY_SUBROUTINE:
761         case GL_FRAGMENT_SUBROUTINE:
762         case GL_COMPUTE_SUBROUTINE:
763         case GL_TESS_CONTROL_SUBROUTINE:
764         case GL_TESS_EVALUATION_SUBROUTINE:
765            if (name[rname.length] == '.') {
766               return res;
767            }
768            FALLTHROUGH;
769         case GL_PROGRAM_INPUT:
770         case GL_PROGRAM_OUTPUT:
771            if (name[rname.length] == '\0') {
772               return res;
773            } else if (name[rname.length] == '[' &&
774                valid_array_index(name, len, array_index)) {
775               return res;
776            }
777            break;
778         default:
779            assert(!"not implemented for given interface");
780         }
781      }
782   }
783   return NULL;
784}
785
786/* Find an uniform or buffer variable program resource with an specific offset
787 * inside a block with an specific binding.
788 *
789 * Valid interfaces are GL_BUFFER_VARIABLE and GL_UNIFORM.
790 */
791static struct gl_program_resource *
792program_resource_find_binding_offset(struct gl_shader_program *shProg,
793                                     GLenum programInterface,
794                                     const GLuint binding,
795                                     const GLint offset)
796{
797
798   /* First we need to get the BLOCK_INDEX from the BUFFER_BINDING */
799   GLenum blockInterface;
800
801   switch (programInterface) {
802   case GL_BUFFER_VARIABLE:
803      blockInterface = GL_SHADER_STORAGE_BLOCK;
804      break;
805   case GL_UNIFORM:
806      blockInterface = GL_UNIFORM_BLOCK;
807      break;
808   default:
809      assert("Invalid program interface");
810      return NULL;
811   }
812
813   int block_index = -1;
814   int starting_index = -1;
815   struct gl_program_resource *res = shProg->data->ProgramResourceList;
816
817   /* Blocks are added to the resource list in the same order that they are
818    * added to UniformBlocks/ShaderStorageBlocks. Furthermore, all the blocks
819    * of each type (UBO/SSBO) are contiguous, so we can infer block_index from
820    * the resource list.
821    */
822   for (unsigned i = 0; i < shProg->data->NumProgramResourceList; i++, res++) {
823      if (res->Type != blockInterface)
824         continue;
825
826      /* Store the first index where a resource of the specific interface is. */
827      if (starting_index == -1)
828         starting_index = i;
829
830      const struct gl_uniform_block *block = RESOURCE_UBO(res);
831
832      if (block->Binding == binding) {
833         /* For arrays, or arrays of arrays of blocks, we want the resource
834          * for the block with base index. Most properties for members of each
835          * block are inherited from the block with the base index, including
836          * a uniform being active or not.
837          */
838         block_index = i - starting_index - block->linearized_array_index;
839         break;
840      }
841   }
842
843   if (block_index == -1)
844      return NULL;
845
846   /* We now look for the resource corresponding to the uniform or buffer
847    * variable using the BLOCK_INDEX and OFFSET.
848    */
849   res = shProg->data->ProgramResourceList;
850   for (unsigned i = 0; i < shProg->data->NumProgramResourceList; i++, res++) {
851      if (res->Type != programInterface)
852         continue;
853
854      const struct gl_uniform_storage *uniform = RESOURCE_UNI(res);
855
856      if (uniform->block_index == block_index && uniform->offset == offset) {
857         return res;
858      }
859   }
860
861   return NULL;
862}
863
864/* Checks if an uniform or buffer variable is in the active program resource
865 * list.
866 *
867 * It takes into accout that for variables coming from SPIR-V binaries their
868 * names could not be available (ARB_gl_spirv). In that case, it will use the
869 * the offset and the block binding to locate the resource.
870 *
871 * Valid interfaces are GL_BUFFER_VARIABLE and GL_UNIFORM.
872 */
873struct gl_program_resource *
874_mesa_program_resource_find_active_variable(struct gl_shader_program *shProg,
875                                            GLenum programInterface,
876                                            const gl_uniform_block *block,
877                                            unsigned index)
878{
879   struct gl_program_resource *res;
880   struct gl_uniform_buffer_variable uni = block->Uniforms[index];
881
882   assert(programInterface == GL_UNIFORM ||
883          programInterface == GL_BUFFER_VARIABLE);
884
885   if (uni.IndexName) {
886      res = _mesa_program_resource_find_name(shProg, programInterface, uni.IndexName,
887                                             NULL);
888   } else {
889      /* As the resource has no associated name (ARB_gl_spirv),
890       * we can use the UBO/SSBO binding and offset to find it.
891       */
892      res = program_resource_find_binding_offset(shProg, programInterface,
893                                                 block->Binding, uni.Offset);
894   }
895
896   return res;
897}
898
899static GLuint
900calc_resource_index(struct gl_shader_program *shProg,
901                    struct gl_program_resource *res)
902{
903   unsigned i;
904   GLuint index = 0;
905   for (i = 0; i < shProg->data->NumProgramResourceList; i++) {
906      if (&shProg->data->ProgramResourceList[i] == res)
907         return index;
908      if (shProg->data->ProgramResourceList[i].Type == res->Type)
909         index++;
910   }
911   return GL_INVALID_INDEX;
912}
913
914/**
915 * Calculate index for the given resource.
916 */
917GLuint
918_mesa_program_resource_index(struct gl_shader_program *shProg,
919                             struct gl_program_resource *res)
920{
921   if (!res)
922      return GL_INVALID_INDEX;
923
924   switch (res->Type) {
925   case GL_ATOMIC_COUNTER_BUFFER:
926      return RESOURCE_ATC(res) - shProg->data->AtomicBuffers;
927   case GL_VERTEX_SUBROUTINE:
928   case GL_GEOMETRY_SUBROUTINE:
929   case GL_FRAGMENT_SUBROUTINE:
930   case GL_COMPUTE_SUBROUTINE:
931   case GL_TESS_CONTROL_SUBROUTINE:
932   case GL_TESS_EVALUATION_SUBROUTINE:
933      return RESOURCE_SUB(res)->index;
934   case GL_UNIFORM_BLOCK:
935   case GL_SHADER_STORAGE_BLOCK:
936   case GL_TRANSFORM_FEEDBACK_BUFFER:
937   case GL_TRANSFORM_FEEDBACK_VARYING:
938   default:
939      return calc_resource_index(shProg, res);
940   }
941}
942
943/**
944 * Find a program resource that points to given data.
945 */
946static struct gl_program_resource*
947program_resource_find_data(struct gl_shader_program *shProg, void *data)
948{
949   struct gl_program_resource *res = shProg->data->ProgramResourceList;
950   for (unsigned i = 0; i < shProg->data->NumProgramResourceList;
951        i++, res++) {
952      if (res->Data == data)
953         return res;
954   }
955   return NULL;
956}
957
958/* Find a program resource with specific index in given interface.
959 */
960struct gl_program_resource *
961_mesa_program_resource_find_index(struct gl_shader_program *shProg,
962                                  GLenum programInterface, GLuint index)
963{
964   struct gl_program_resource *res = shProg->data->ProgramResourceList;
965   int idx = -1;
966
967   for (unsigned i = 0; i < shProg->data->NumProgramResourceList;
968        i++, res++) {
969      if (res->Type != programInterface)
970         continue;
971
972      switch (res->Type) {
973      case GL_UNIFORM_BLOCK:
974      case GL_ATOMIC_COUNTER_BUFFER:
975      case GL_SHADER_STORAGE_BLOCK:
976      case GL_TRANSFORM_FEEDBACK_BUFFER:
977         if (_mesa_program_resource_index(shProg, res) == index)
978            return res;
979         break;
980      case GL_TRANSFORM_FEEDBACK_VARYING:
981      case GL_PROGRAM_INPUT:
982      case GL_PROGRAM_OUTPUT:
983      case GL_UNIFORM:
984      case GL_VERTEX_SUBROUTINE_UNIFORM:
985      case GL_GEOMETRY_SUBROUTINE_UNIFORM:
986      case GL_FRAGMENT_SUBROUTINE_UNIFORM:
987      case GL_COMPUTE_SUBROUTINE_UNIFORM:
988      case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
989      case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
990      case GL_VERTEX_SUBROUTINE:
991      case GL_GEOMETRY_SUBROUTINE:
992      case GL_FRAGMENT_SUBROUTINE:
993      case GL_COMPUTE_SUBROUTINE:
994      case GL_TESS_CONTROL_SUBROUTINE:
995      case GL_TESS_EVALUATION_SUBROUTINE:
996      case GL_BUFFER_VARIABLE:
997         if (++idx == (int) index)
998            return res;
999         break;
1000      default:
1001         assert(!"not implemented for given interface");
1002      }
1003   }
1004   return NULL;
1005}
1006
1007/* Function returns if resource name is expected to have index
1008 * appended into it.
1009 *
1010 *
1011 * Page 61 (page 73 of the PDF) in section 2.11 of the OpenGL ES 3.0
1012 * spec says:
1013 *
1014 *     "If the active uniform is an array, the uniform name returned in
1015 *     name will always be the name of the uniform array appended with
1016 *     "[0]"."
1017 *
1018 * The same text also appears in the OpenGL 4.2 spec.  It does not,
1019 * however, appear in any previous spec.  Previous specifications are
1020 * ambiguous in this regard.  However, either name can later be passed
1021 * to glGetUniformLocation (and related APIs), so there shouldn't be any
1022 * harm in always appending "[0]" to uniform array names.
1023 */
1024static bool
1025add_index_to_name(struct gl_program_resource *res)
1026{
1027   /* Transform feedback varyings have array index already appended
1028    * in their names.
1029    */
1030   return res->Type != GL_TRANSFORM_FEEDBACK_VARYING;
1031}
1032
1033/* Get name length of a program resource. This consists of
1034 * base name + 3 for '[0]' if resource is an array.
1035 */
1036extern unsigned
1037_mesa_program_resource_name_length_array(struct gl_program_resource *res)
1038{
1039   int length = _mesa_program_resource_name_length(res);
1040
1041   /* For shaders constructed from SPIR-V binaries, variables may not
1042    * have names associated with them.
1043    */
1044   if (!length)
1045      return 0;
1046
1047   if (_mesa_program_resource_array_size(res) && add_index_to_name(res))
1048      length += 3;
1049   return length;
1050}
1051
1052/* Get full name of a program resource.
1053 */
1054bool
1055_mesa_get_program_resource_name(struct gl_shader_program *shProg,
1056                                GLenum programInterface, GLuint index,
1057                                GLsizei bufSize, GLsizei *length,
1058                                GLchar *name, bool glthread,
1059                                const char *caller)
1060{
1061   GET_CURRENT_CONTEXT(ctx);
1062
1063   /* Find resource with given interface and index. */
1064   struct gl_program_resource *res =
1065      _mesa_program_resource_find_index(shProg, programInterface, index);
1066
1067   /* The error INVALID_VALUE is generated if <index> is greater than
1068   * or equal to the number of entries in the active resource list for
1069   * <programInterface>.
1070   */
1071   if (!res) {
1072      _mesa_error_glthread_safe(ctx, GL_INVALID_VALUE, glthread,
1073                                "%s(index %u)", caller, index);
1074      return false;
1075   }
1076
1077   if (bufSize < 0) {
1078      _mesa_error_glthread_safe(ctx, GL_INVALID_VALUE, glthread,
1079                                "%s(bufSize %d)", caller, bufSize);
1080      return false;
1081   }
1082
1083   GLsizei localLength;
1084
1085   if (length == NULL)
1086      length = &localLength;
1087
1088   _mesa_copy_string(name, bufSize, length, _mesa_program_resource_name(res));
1089
1090   /* The resource name can be NULL for shaders constructed from SPIR-V
1091    * binaries. In that case, we do not add the '[0]'.
1092    */
1093   if (name && name[0] != '\0' &&
1094       _mesa_program_resource_array_size(res) && add_index_to_name(res)) {
1095      int i;
1096
1097      /* The comparison is strange because *length does *NOT* include the
1098       * terminating NUL, but maxLength does.
1099       */
1100      for (i = 0; i < 3 && (*length + i + 1) < bufSize; i++)
1101         name[*length + i] = "[0]"[i];
1102
1103      name[*length + i] = '\0';
1104      *length += i;
1105   }
1106   return true;
1107}
1108
1109static GLint
1110program_resource_location(struct gl_program_resource *res, unsigned array_index)
1111{
1112   switch (res->Type) {
1113   case GL_PROGRAM_INPUT: {
1114      const gl_shader_variable *var = RESOURCE_VAR(res);
1115
1116      if (var->location == -1)
1117         return -1;
1118
1119      /* If the input is an array, fail if the index is out of bounds. */
1120      if (array_index > 0
1121          && array_index >= var->type->length) {
1122         return -1;
1123      }
1124      return var->location +
1125	     (array_index * var->type->without_array()->matrix_columns);
1126   }
1127   case GL_PROGRAM_OUTPUT:
1128      if (RESOURCE_VAR(res)->location == -1)
1129         return -1;
1130
1131      /* If the output is an array, fail if the index is out of bounds. */
1132      if (array_index > 0
1133          && array_index >= RESOURCE_VAR(res)->type->length) {
1134         return -1;
1135      }
1136      return RESOURCE_VAR(res)->location + array_index;
1137   case GL_UNIFORM:
1138      /* If the uniform is built-in, fail. */
1139      if (RESOURCE_UNI(res)->builtin)
1140         return -1;
1141
1142     /* From page 79 of the OpenGL 4.2 spec:
1143      *
1144      *     "A valid name cannot be a structure, an array of structures, or any
1145      *     portion of a single vector or a matrix."
1146      */
1147      if (RESOURCE_UNI(res)->type->without_array()->is_struct())
1148         return -1;
1149
1150      /* From the GL_ARB_uniform_buffer_object spec:
1151       *
1152       *     "The value -1 will be returned if <name> does not correspond to an
1153       *     active uniform variable name in <program>, if <name> is associated
1154       *     with a named uniform block, or if <name> starts with the reserved
1155       *     prefix "gl_"."
1156       */
1157      if (RESOURCE_UNI(res)->block_index != -1 ||
1158          RESOURCE_UNI(res)->atomic_buffer_index != -1)
1159         return -1;
1160
1161      FALLTHROUGH;
1162   case GL_VERTEX_SUBROUTINE_UNIFORM:
1163   case GL_GEOMETRY_SUBROUTINE_UNIFORM:
1164   case GL_FRAGMENT_SUBROUTINE_UNIFORM:
1165   case GL_COMPUTE_SUBROUTINE_UNIFORM:
1166   case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
1167   case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
1168      /* If the uniform is an array, fail if the index is out of bounds. */
1169      if (array_index > 0
1170          && array_index >= RESOURCE_UNI(res)->array_elements) {
1171         return -1;
1172      }
1173
1174      /* location in remap table + array element offset */
1175      return RESOURCE_UNI(res)->remap_location + array_index;
1176   default:
1177      return -1;
1178   }
1179}
1180
1181/**
1182 * Function implements following location queries:
1183 *    glGetUniformLocation
1184 */
1185GLint
1186_mesa_program_resource_location(struct gl_shader_program *shProg,
1187                                GLenum programInterface, const char *name)
1188{
1189   unsigned array_index = 0;
1190   struct gl_program_resource *res =
1191      _mesa_program_resource_find_name(shProg, programInterface, name,
1192                                       &array_index);
1193
1194   /* Resource not found. */
1195   if (!res)
1196      return -1;
1197
1198   return program_resource_location(res, array_index);
1199}
1200
1201static GLint
1202_get_resource_location_index(struct gl_program_resource *res)
1203{
1204   /* Non-existent variable or resource is not referenced by fragment stage. */
1205   if (!res || !(res->StageReferences & (1 << MESA_SHADER_FRAGMENT)))
1206      return -1;
1207
1208   /* From OpenGL 4.5 spec, 7.3 Program Objects
1209    * "The value -1 will be returned by either command...
1210    *  ... or if name identifies an active variable that does not have a
1211    * valid location assigned.
1212    */
1213   if (RESOURCE_VAR(res)->location == -1)
1214      return -1;
1215   return RESOURCE_VAR(res)->index;
1216}
1217
1218/**
1219 * Function implements following index queries:
1220 *    glGetFragDataIndex
1221 */
1222GLint
1223_mesa_program_resource_location_index(struct gl_shader_program *shProg,
1224                                      GLenum programInterface, const char *name)
1225{
1226   struct gl_program_resource *res =
1227      _mesa_program_resource_find_name(shProg, programInterface, name, NULL);
1228
1229   return _get_resource_location_index(res);
1230}
1231
1232static uint8_t
1233stage_from_enum(GLenum ref)
1234{
1235   switch (ref) {
1236   case GL_REFERENCED_BY_VERTEX_SHADER:
1237      return MESA_SHADER_VERTEX;
1238   case GL_REFERENCED_BY_TESS_CONTROL_SHADER:
1239      return MESA_SHADER_TESS_CTRL;
1240   case GL_REFERENCED_BY_TESS_EVALUATION_SHADER:
1241      return MESA_SHADER_TESS_EVAL;
1242   case GL_REFERENCED_BY_GEOMETRY_SHADER:
1243      return MESA_SHADER_GEOMETRY;
1244   case GL_REFERENCED_BY_FRAGMENT_SHADER:
1245      return MESA_SHADER_FRAGMENT;
1246   case GL_REFERENCED_BY_COMPUTE_SHADER:
1247      return MESA_SHADER_COMPUTE;
1248   default:
1249      assert(!"shader stage not supported");
1250      return MESA_SHADER_STAGES;
1251   }
1252}
1253
1254/**
1255 * Check if resource is referenced by given 'referenced by' stage enum.
1256 * ATC and UBO resources hold stage references of their own.
1257 */
1258static bool
1259is_resource_referenced(struct gl_shader_program *shProg,
1260                       struct gl_program_resource *res,
1261                       GLuint index, uint8_t stage)
1262{
1263   /* First, check if we even have such a stage active. */
1264   if (!shProg->_LinkedShaders[stage])
1265      return false;
1266
1267   if (res->Type == GL_ATOMIC_COUNTER_BUFFER)
1268      return RESOURCE_ATC(res)->StageReferences[stage];
1269
1270   if (res->Type == GL_UNIFORM_BLOCK)
1271      return shProg->data->UniformBlocks[index].stageref & (1 << stage);
1272
1273   if (res->Type == GL_SHADER_STORAGE_BLOCK)
1274      return shProg->data->ShaderStorageBlocks[index].stageref & (1 << stage);
1275
1276   return res->StageReferences & (1 << stage);
1277}
1278
1279static unsigned
1280get_buffer_property(struct gl_shader_program *shProg,
1281                    struct gl_program_resource *res, const GLenum prop,
1282                    GLint *val, bool glthread, const char *caller)
1283{
1284   GET_CURRENT_CONTEXT(ctx);
1285   if (res->Type != GL_UNIFORM_BLOCK &&
1286       res->Type != GL_ATOMIC_COUNTER_BUFFER &&
1287       res->Type != GL_SHADER_STORAGE_BLOCK &&
1288       res->Type != GL_TRANSFORM_FEEDBACK_BUFFER)
1289      goto invalid_operation;
1290
1291   if (res->Type == GL_UNIFORM_BLOCK) {
1292      switch (prop) {
1293      case GL_BUFFER_BINDING:
1294         *val = RESOURCE_UBO(res)->Binding;
1295         return 1;
1296      case GL_BUFFER_DATA_SIZE:
1297         *val = RESOURCE_UBO(res)->UniformBufferSize;
1298         return 1;
1299      case GL_NUM_ACTIVE_VARIABLES:
1300         *val = 0;
1301         for (unsigned i = 0; i < RESOURCE_UBO(res)->NumUniforms; i++) {
1302            struct gl_program_resource *uni =
1303               _mesa_program_resource_find_active_variable(
1304                  shProg,
1305                  GL_UNIFORM,
1306                  RESOURCE_UBO(res),
1307                  i);
1308
1309            if (!uni)
1310               continue;
1311            (*val)++;
1312         }
1313         return 1;
1314      case GL_ACTIVE_VARIABLES: {
1315         unsigned num_values = 0;
1316         for (unsigned i = 0; i < RESOURCE_UBO(res)->NumUniforms; i++) {
1317            struct gl_program_resource *uni =
1318               _mesa_program_resource_find_active_variable(
1319                  shProg,
1320                  GL_UNIFORM,
1321                  RESOURCE_UBO(res),
1322                  i);
1323
1324            if (!uni)
1325               continue;
1326            *val++ =
1327               _mesa_program_resource_index(shProg, uni);
1328            num_values++;
1329         }
1330         return num_values;
1331      }
1332      }
1333   } else if (res->Type == GL_SHADER_STORAGE_BLOCK) {
1334      switch (prop) {
1335      case GL_BUFFER_BINDING:
1336         *val = RESOURCE_UBO(res)->Binding;
1337         return 1;
1338      case GL_BUFFER_DATA_SIZE:
1339         *val = RESOURCE_UBO(res)->UniformBufferSize;
1340         return 1;
1341      case GL_NUM_ACTIVE_VARIABLES:
1342         *val = 0;
1343         for (unsigned i = 0; i < RESOURCE_UBO(res)->NumUniforms; i++) {
1344            struct gl_program_resource *uni =
1345               _mesa_program_resource_find_active_variable(
1346                  shProg,
1347                  GL_BUFFER_VARIABLE,
1348                  RESOURCE_UBO(res),
1349                  i);
1350
1351            if (!uni)
1352               continue;
1353            (*val)++;
1354         }
1355         return 1;
1356      case GL_ACTIVE_VARIABLES: {
1357         unsigned num_values = 0;
1358         for (unsigned i = 0; i < RESOURCE_UBO(res)->NumUniforms; i++) {
1359            struct gl_program_resource *uni =
1360               _mesa_program_resource_find_active_variable(
1361                  shProg,
1362                  GL_BUFFER_VARIABLE,
1363                  RESOURCE_UBO(res),
1364                  i);
1365
1366            if (!uni)
1367               continue;
1368            *val++ =
1369               _mesa_program_resource_index(shProg, uni);
1370            num_values++;
1371         }
1372         return num_values;
1373      }
1374      }
1375   } else if (res->Type == GL_ATOMIC_COUNTER_BUFFER) {
1376      switch (prop) {
1377      case GL_BUFFER_BINDING:
1378         *val = RESOURCE_ATC(res)->Binding;
1379         return 1;
1380      case GL_BUFFER_DATA_SIZE:
1381         *val = RESOURCE_ATC(res)->MinimumSize;
1382         return 1;
1383      case GL_NUM_ACTIVE_VARIABLES:
1384         *val = RESOURCE_ATC(res)->NumUniforms;
1385         return 1;
1386      case GL_ACTIVE_VARIABLES:
1387         for (unsigned i = 0; i < RESOURCE_ATC(res)->NumUniforms; i++) {
1388            /* Active atomic buffer contains index to UniformStorage. Find
1389             * out gl_program_resource via data pointer and then calculate
1390             * index of that uniform.
1391             */
1392            unsigned idx = RESOURCE_ATC(res)->Uniforms[i];
1393            struct gl_program_resource *uni =
1394               program_resource_find_data(shProg,
1395                                          &shProg->data->UniformStorage[idx]);
1396            assert(uni);
1397            *val++ = _mesa_program_resource_index(shProg, uni);
1398         }
1399         return RESOURCE_ATC(res)->NumUniforms;
1400      }
1401   } else if (res->Type == GL_TRANSFORM_FEEDBACK_BUFFER) {
1402      switch (prop) {
1403      case GL_BUFFER_BINDING:
1404         *val = RESOURCE_XFB(res)->Binding;
1405         return 1;
1406      case GL_NUM_ACTIVE_VARIABLES:
1407         *val = RESOURCE_XFB(res)->NumVaryings;
1408         return 1;
1409      case GL_ACTIVE_VARIABLES:
1410         struct gl_transform_feedback_info *linked_xfb =
1411            shProg->last_vert_prog->sh.LinkedTransformFeedback;
1412         for (int i = 0; i < linked_xfb->NumVarying; i++) {
1413            unsigned index = linked_xfb->Varyings[i].BufferIndex;
1414            struct gl_program_resource *buf_res =
1415               _mesa_program_resource_find_index(shProg,
1416                                                 GL_TRANSFORM_FEEDBACK_BUFFER,
1417                                                 index);
1418            assert(buf_res);
1419            if (res == buf_res) {
1420               *val++ = i;
1421            }
1422         }
1423         return RESOURCE_XFB(res)->NumVaryings;
1424      }
1425   }
1426   assert(!"support for property type not implemented");
1427
1428invalid_operation:
1429   _mesa_error_glthread_safe(ctx, GL_INVALID_OPERATION, glthread,
1430                             "%s(%s prop %s)", caller,
1431                             _mesa_enum_to_string(res->Type),
1432                             _mesa_enum_to_string(prop));
1433
1434   return 0;
1435}
1436
1437unsigned
1438_mesa_program_resource_prop(struct gl_shader_program *shProg,
1439                            struct gl_program_resource *res, GLuint index,
1440                            const GLenum prop, GLint *val, bool glthread,
1441                            const char *caller)
1442{
1443   GET_CURRENT_CONTEXT(ctx);
1444
1445#define VALIDATE_TYPE(type)\
1446   if (res->Type != type)\
1447      goto invalid_operation;
1448
1449#define VALIDATE_TYPE_2(type1, type2)\
1450   if (res->Type != type1 && res->Type != type2)\
1451      goto invalid_operation;
1452
1453   switch(prop) {
1454   case GL_NAME_LENGTH:
1455      switch (res->Type) {
1456      case GL_ATOMIC_COUNTER_BUFFER:
1457      case GL_TRANSFORM_FEEDBACK_BUFFER:
1458         goto invalid_operation;
1459      default:
1460         /* Resource name length + terminator. */
1461         *val = _mesa_program_resource_name_length_array(res) + 1;
1462      }
1463      return 1;
1464   case GL_TYPE:
1465      switch (res->Type) {
1466      case GL_UNIFORM:
1467      case GL_BUFFER_VARIABLE:
1468         *val = RESOURCE_UNI(res)->type->gl_type;
1469         *val = mediump_to_highp_type(*val);
1470         return 1;
1471      case GL_PROGRAM_INPUT:
1472      case GL_PROGRAM_OUTPUT:
1473         *val = RESOURCE_VAR(res)->type->gl_type;
1474         *val = mediump_to_highp_type(*val);
1475         return 1;
1476      case GL_TRANSFORM_FEEDBACK_VARYING:
1477         *val = RESOURCE_XFV(res)->Type;
1478         *val = mediump_to_highp_type(*val);
1479         return 1;
1480      default:
1481         goto invalid_operation;
1482      }
1483   case GL_ARRAY_SIZE:
1484      switch (res->Type) {
1485      case GL_UNIFORM:
1486      case GL_BUFFER_VARIABLE:
1487      case GL_VERTEX_SUBROUTINE_UNIFORM:
1488      case GL_GEOMETRY_SUBROUTINE_UNIFORM:
1489      case GL_FRAGMENT_SUBROUTINE_UNIFORM:
1490      case GL_COMPUTE_SUBROUTINE_UNIFORM:
1491      case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
1492      case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
1493
1494         /* Test if a buffer variable is an array or an unsized array.
1495          * Unsized arrays return zero as array size.
1496          */
1497         if (RESOURCE_UNI(res)->is_shader_storage &&
1498             RESOURCE_UNI(res)->array_stride > 0)
1499            *val = RESOURCE_UNI(res)->array_elements;
1500         else
1501            *val = MAX2(RESOURCE_UNI(res)->array_elements, 1);
1502         return 1;
1503      case GL_PROGRAM_INPUT:
1504      case GL_PROGRAM_OUTPUT:
1505         *val = MAX2(_mesa_program_resource_array_size(res), 1);
1506         return 1;
1507      case GL_TRANSFORM_FEEDBACK_VARYING:
1508         *val = RESOURCE_XFV(res)->Size;
1509         return 1;
1510      default:
1511         goto invalid_operation;
1512      }
1513   case GL_OFFSET:
1514      switch (res->Type) {
1515      case GL_UNIFORM:
1516      case GL_BUFFER_VARIABLE:
1517         *val = RESOURCE_UNI(res)->offset;
1518         return 1;
1519      case GL_TRANSFORM_FEEDBACK_VARYING:
1520         *val = RESOURCE_XFV(res)->Offset;
1521         return 1;
1522      default:
1523         goto invalid_operation;
1524      }
1525   case GL_BLOCK_INDEX:
1526      VALIDATE_TYPE_2(GL_UNIFORM, GL_BUFFER_VARIABLE);
1527      *val = RESOURCE_UNI(res)->block_index;
1528      return 1;
1529   case GL_ARRAY_STRIDE:
1530      VALIDATE_TYPE_2(GL_UNIFORM, GL_BUFFER_VARIABLE);
1531      *val = RESOURCE_UNI(res)->array_stride;
1532      return 1;
1533   case GL_MATRIX_STRIDE:
1534      VALIDATE_TYPE_2(GL_UNIFORM, GL_BUFFER_VARIABLE);
1535      *val = RESOURCE_UNI(res)->matrix_stride;
1536      return 1;
1537   case GL_IS_ROW_MAJOR:
1538      VALIDATE_TYPE_2(GL_UNIFORM, GL_BUFFER_VARIABLE);
1539      *val = RESOURCE_UNI(res)->row_major;
1540      return 1;
1541   case GL_ATOMIC_COUNTER_BUFFER_INDEX:
1542      VALIDATE_TYPE(GL_UNIFORM);
1543      *val = RESOURCE_UNI(res)->atomic_buffer_index;
1544      return 1;
1545   case GL_BUFFER_BINDING:
1546   case GL_BUFFER_DATA_SIZE:
1547   case GL_NUM_ACTIVE_VARIABLES:
1548   case GL_ACTIVE_VARIABLES:
1549      return get_buffer_property(shProg, res, prop, val, glthread, caller);
1550   case GL_REFERENCED_BY_COMPUTE_SHADER:
1551      if (!_mesa_has_compute_shaders(ctx))
1552         goto invalid_enum;
1553      FALLTHROUGH;
1554   case GL_REFERENCED_BY_VERTEX_SHADER:
1555   case GL_REFERENCED_BY_TESS_CONTROL_SHADER:
1556   case GL_REFERENCED_BY_TESS_EVALUATION_SHADER:
1557   case GL_REFERENCED_BY_GEOMETRY_SHADER:
1558   case GL_REFERENCED_BY_FRAGMENT_SHADER:
1559      switch (res->Type) {
1560      case GL_UNIFORM:
1561      case GL_PROGRAM_INPUT:
1562      case GL_PROGRAM_OUTPUT:
1563      case GL_UNIFORM_BLOCK:
1564      case GL_BUFFER_VARIABLE:
1565      case GL_SHADER_STORAGE_BLOCK:
1566      case GL_ATOMIC_COUNTER_BUFFER:
1567         *val = is_resource_referenced(shProg, res, index,
1568                                       stage_from_enum(prop));
1569         return 1;
1570      default:
1571         goto invalid_operation;
1572      }
1573   case GL_LOCATION:
1574      switch (res->Type) {
1575      case GL_UNIFORM:
1576      case GL_VERTEX_SUBROUTINE_UNIFORM:
1577      case GL_GEOMETRY_SUBROUTINE_UNIFORM:
1578      case GL_FRAGMENT_SUBROUTINE_UNIFORM:
1579      case GL_COMPUTE_SUBROUTINE_UNIFORM:
1580      case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
1581      case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
1582      case GL_PROGRAM_INPUT:
1583      case GL_PROGRAM_OUTPUT:
1584         *val = program_resource_location(res, 0);
1585         return 1;
1586      default:
1587         goto invalid_operation;
1588      }
1589   case GL_LOCATION_COMPONENT:
1590      switch (res->Type) {
1591      case GL_PROGRAM_INPUT:
1592      case GL_PROGRAM_OUTPUT:
1593         *val = RESOURCE_VAR(res)->component;
1594         return 1;
1595      default:
1596         goto invalid_operation;
1597      }
1598   case GL_LOCATION_INDEX: {
1599      int tmp;
1600      if (res->Type != GL_PROGRAM_OUTPUT)
1601         goto invalid_operation;
1602      tmp = program_resource_location(res, 0);
1603      if (tmp == -1)
1604         *val = -1;
1605      else
1606         *val = _get_resource_location_index(res);
1607      return 1;
1608   }
1609   case GL_NUM_COMPATIBLE_SUBROUTINES:
1610      if (res->Type != GL_VERTEX_SUBROUTINE_UNIFORM &&
1611          res->Type != GL_FRAGMENT_SUBROUTINE_UNIFORM &&
1612          res->Type != GL_GEOMETRY_SUBROUTINE_UNIFORM &&
1613          res->Type != GL_COMPUTE_SUBROUTINE_UNIFORM &&
1614          res->Type != GL_TESS_CONTROL_SUBROUTINE_UNIFORM &&
1615          res->Type != GL_TESS_EVALUATION_SUBROUTINE_UNIFORM)
1616         goto invalid_operation;
1617      *val = RESOURCE_UNI(res)->num_compatible_subroutines;
1618      return 1;
1619   case GL_COMPATIBLE_SUBROUTINES: {
1620      const struct gl_uniform_storage *uni;
1621      struct gl_program *p;
1622      unsigned count, i;
1623      int j;
1624
1625      if (res->Type != GL_VERTEX_SUBROUTINE_UNIFORM &&
1626          res->Type != GL_FRAGMENT_SUBROUTINE_UNIFORM &&
1627          res->Type != GL_GEOMETRY_SUBROUTINE_UNIFORM &&
1628          res->Type != GL_COMPUTE_SUBROUTINE_UNIFORM &&
1629          res->Type != GL_TESS_CONTROL_SUBROUTINE_UNIFORM &&
1630          res->Type != GL_TESS_EVALUATION_SUBROUTINE_UNIFORM)
1631         goto invalid_operation;
1632      uni = RESOURCE_UNI(res);
1633
1634      p = shProg->_LinkedShaders[_mesa_shader_stage_from_subroutine_uniform(res->Type)]->Program;
1635      count = 0;
1636      for (i = 0; i < p->sh.NumSubroutineFunctions; i++) {
1637         struct gl_subroutine_function *fn = &p->sh.SubroutineFunctions[i];
1638         for (j = 0; j < fn->num_compat_types; j++) {
1639            if (fn->types[j] == uni->type) {
1640               val[count++] = i;
1641               break;
1642            }
1643         }
1644      }
1645      return count;
1646   }
1647
1648   case GL_TOP_LEVEL_ARRAY_SIZE:
1649      VALIDATE_TYPE(GL_BUFFER_VARIABLE);
1650      *val = RESOURCE_UNI(res)->top_level_array_size;
1651      return 1;
1652
1653   case GL_TOP_LEVEL_ARRAY_STRIDE:
1654      VALIDATE_TYPE(GL_BUFFER_VARIABLE);
1655      *val = RESOURCE_UNI(res)->top_level_array_stride;
1656      return 1;
1657
1658   /* GL_ARB_tessellation_shader */
1659   case GL_IS_PER_PATCH:
1660      switch (res->Type) {
1661      case GL_PROGRAM_INPUT:
1662      case GL_PROGRAM_OUTPUT:
1663         *val = RESOURCE_VAR(res)->patch;
1664         return 1;
1665      default:
1666         goto invalid_operation;
1667      }
1668
1669   case GL_TRANSFORM_FEEDBACK_BUFFER_INDEX:
1670      VALIDATE_TYPE(GL_TRANSFORM_FEEDBACK_VARYING);
1671      *val = RESOURCE_XFV(res)->BufferIndex;
1672      return 1;
1673   case GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE:
1674      VALIDATE_TYPE(GL_TRANSFORM_FEEDBACK_BUFFER);
1675      *val = RESOURCE_XFB(res)->Stride * 4;
1676      return 1;
1677
1678   default:
1679      goto invalid_enum;
1680   }
1681
1682#undef VALIDATE_TYPE
1683#undef VALIDATE_TYPE_2
1684
1685invalid_enum:
1686   _mesa_error_glthread_safe(ctx, GL_INVALID_ENUM, glthread,
1687                             "%s(%s prop %s)", caller,
1688                             _mesa_enum_to_string(res->Type),
1689                             _mesa_enum_to_string(prop));
1690   return 0;
1691
1692invalid_operation:
1693   _mesa_error_glthread_safe(ctx, GL_INVALID_OPERATION, glthread,
1694                             "%s(%s prop %s)", caller,
1695                             _mesa_enum_to_string(res->Type),
1696                             _mesa_enum_to_string(prop));
1697   return 0;
1698}
1699
1700extern void
1701_mesa_get_program_resourceiv(struct gl_shader_program *shProg,
1702                             GLenum programInterface, GLuint index, GLsizei propCount,
1703                             const GLenum *props, GLsizei bufSize,
1704                             GLsizei *length, GLint *params)
1705{
1706   GET_CURRENT_CONTEXT(ctx);
1707   GLint *val = (GLint *) params;
1708   const GLenum *prop = props;
1709   GLsizei amount = 0;
1710
1711   struct gl_program_resource *res =
1712      _mesa_program_resource_find_index(shProg, programInterface, index);
1713
1714   /* No such resource found or bufSize negative. */
1715   if (!res || bufSize < 0) {
1716      _mesa_error(ctx, GL_INVALID_VALUE,
1717                  "glGetProgramResourceiv(%s index %d bufSize %d)",
1718                  _mesa_enum_to_string(programInterface), index, bufSize);
1719      return;
1720   }
1721
1722   /* Write propCount values until error occurs or bufSize reached. */
1723   for (int i = 0; i < propCount && i < bufSize; i++, val++, prop++) {
1724      int props_written =
1725         _mesa_program_resource_prop(shProg, res, index, *prop, val,
1726                                     false, "glGetProgramResourceiv");
1727
1728      /* Error happened. */
1729      if (props_written == 0)
1730         return;
1731
1732      amount += props_written;
1733   }
1734
1735   /* If <length> is not NULL, the actual number of integer values
1736    * written to <params> will be written to <length>.
1737    */
1738   if (length)
1739      *length = amount;
1740}
1741
1742extern void
1743_mesa_get_program_interfaceiv(struct gl_shader_program *shProg,
1744                              GLenum programInterface, GLenum pname,
1745                              GLint *params)
1746{
1747   GET_CURRENT_CONTEXT(ctx);
1748   unsigned i;
1749
1750   /* Validate pname against interface. */
1751   switch(pname) {
1752   case GL_ACTIVE_RESOURCES:
1753      for (i = 0, *params = 0; i < shProg->data->NumProgramResourceList; i++)
1754         if (shProg->data->ProgramResourceList[i].Type == programInterface)
1755            (*params)++;
1756      break;
1757   case GL_MAX_NAME_LENGTH:
1758      if (programInterface == GL_ATOMIC_COUNTER_BUFFER ||
1759          programInterface == GL_TRANSFORM_FEEDBACK_BUFFER) {
1760         _mesa_error(ctx, GL_INVALID_OPERATION,
1761                     "glGetProgramInterfaceiv(%s pname %s)",
1762                     _mesa_enum_to_string(programInterface),
1763                     _mesa_enum_to_string(pname));
1764         return;
1765      }
1766      /* Name length consists of base name, 3 additional chars '[0]' if
1767       * resource is an array and finally 1 char for string terminator.
1768       */
1769      for (i = 0, *params = 0; i < shProg->data->NumProgramResourceList; i++) {
1770         if (shProg->data->ProgramResourceList[i].Type != programInterface)
1771            continue;
1772         unsigned len =
1773            _mesa_program_resource_name_length_array(&shProg->data->ProgramResourceList[i]);
1774         *params = MAX2((unsigned)*params, len + 1);
1775      }
1776      break;
1777   case GL_MAX_NUM_ACTIVE_VARIABLES:
1778      switch (programInterface) {
1779      case GL_UNIFORM_BLOCK:
1780         for (i = 0, *params = 0; i < shProg->data->NumProgramResourceList; i++) {
1781            if (shProg->data->ProgramResourceList[i].Type == programInterface) {
1782               struct gl_uniform_block *block =
1783                  (struct gl_uniform_block *)
1784                  shProg->data->ProgramResourceList[i].Data;
1785               *params = MAX2((unsigned)*params, block->NumUniforms);
1786            }
1787         }
1788         break;
1789      case GL_SHADER_STORAGE_BLOCK:
1790         for (i = 0, *params = 0; i < shProg->data->NumProgramResourceList; i++) {
1791            if (shProg->data->ProgramResourceList[i].Type == programInterface) {
1792               struct gl_uniform_block *block =
1793                  (struct gl_uniform_block *)
1794                  shProg->data->ProgramResourceList[i].Data;
1795               GLint block_params = 0;
1796               for (unsigned j = 0; j < block->NumUniforms; j++) {
1797                  struct gl_program_resource *uni =
1798                     _mesa_program_resource_find_active_variable(
1799                        shProg,
1800                        GL_BUFFER_VARIABLE,
1801                        block,
1802                        j);
1803                  if (!uni)
1804                     continue;
1805                  block_params++;
1806               }
1807               *params = MAX2(*params, block_params);
1808            }
1809         }
1810         break;
1811      case GL_ATOMIC_COUNTER_BUFFER:
1812         for (i = 0, *params = 0; i < shProg->data->NumProgramResourceList; i++) {
1813            if (shProg->data->ProgramResourceList[i].Type == programInterface) {
1814               struct gl_active_atomic_buffer *buffer =
1815                  (struct gl_active_atomic_buffer *)
1816                  shProg->data->ProgramResourceList[i].Data;
1817               *params = MAX2((unsigned)*params, buffer->NumUniforms);
1818            }
1819         }
1820         break;
1821      case GL_TRANSFORM_FEEDBACK_BUFFER:
1822         for (i = 0, *params = 0; i < shProg->data->NumProgramResourceList; i++) {
1823            if (shProg->data->ProgramResourceList[i].Type == programInterface) {
1824               struct gl_transform_feedback_buffer *buffer =
1825                  (struct gl_transform_feedback_buffer *)
1826                  shProg->data->ProgramResourceList[i].Data;
1827               *params = MAX2((unsigned)*params, buffer->NumVaryings);
1828            }
1829         }
1830         break;
1831      default:
1832        _mesa_error(ctx, GL_INVALID_OPERATION,
1833                    "glGetProgramInterfaceiv(%s pname %s)",
1834                    _mesa_enum_to_string(programInterface),
1835                    _mesa_enum_to_string(pname));
1836      }
1837      break;
1838   case GL_MAX_NUM_COMPATIBLE_SUBROUTINES:
1839      switch (programInterface) {
1840      case GL_VERTEX_SUBROUTINE_UNIFORM:
1841      case GL_FRAGMENT_SUBROUTINE_UNIFORM:
1842      case GL_GEOMETRY_SUBROUTINE_UNIFORM:
1843      case GL_COMPUTE_SUBROUTINE_UNIFORM:
1844      case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
1845      case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM: {
1846         for (i = 0, *params = 0; i < shProg->data->NumProgramResourceList; i++) {
1847            if (shProg->data->ProgramResourceList[i].Type == programInterface) {
1848               struct gl_uniform_storage *uni =
1849                  (struct gl_uniform_storage *)
1850                  shProg->data->ProgramResourceList[i].Data;
1851               *params = MAX2((unsigned)*params, uni->num_compatible_subroutines);
1852            }
1853         }
1854         break;
1855      }
1856
1857      default:
1858         _mesa_error(ctx, GL_INVALID_OPERATION,
1859                     "glGetProgramInterfaceiv(%s pname %s)",
1860                     _mesa_enum_to_string(programInterface),
1861                     _mesa_enum_to_string(pname));
1862      }
1863      break;
1864   default:
1865      _mesa_error(ctx, GL_INVALID_OPERATION,
1866                  "glGetProgramInterfaceiv(pname %s)",
1867                  _mesa_enum_to_string(pname));
1868   }
1869}
1870
1871static bool
1872validate_io(struct gl_program *producer, struct gl_program *consumer)
1873{
1874   if (producer->sh.data->linked_stages == consumer->sh.data->linked_stages)
1875      return true;
1876
1877   const bool producer_is_array_stage =
1878      producer->info.stage == MESA_SHADER_TESS_CTRL;
1879   const bool consumer_is_array_stage =
1880      consumer->info.stage == MESA_SHADER_GEOMETRY ||
1881      consumer->info.stage == MESA_SHADER_TESS_CTRL ||
1882      consumer->info.stage == MESA_SHADER_TESS_EVAL;
1883
1884   bool valid = true;
1885
1886   gl_shader_variable const **outputs =
1887      (gl_shader_variable const **) calloc(producer->sh.data->NumProgramResourceList,
1888                                           sizeof(gl_shader_variable *));
1889   if (outputs == NULL)
1890      return false;
1891
1892   /* Section 7.4.1 (Shader Interface Matching) of the OpenGL ES 3.1 spec
1893    * says:
1894    *
1895    *    At an interface between program objects, the set of inputs and
1896    *    outputs are considered to match exactly if and only if:
1897    *
1898    *    - Every declared input variable has a matching output, as described
1899    *      above.
1900    *    - There are no user-defined output variables declared without a
1901    *      matching input variable declaration.
1902    *
1903    * Every input has an output, and every output has an input.  Scan the list
1904    * of producer resources once, and generate the list of outputs.  As inputs
1905    * and outputs are matched, remove the matched outputs from the set.  At
1906    * the end, the set must be empty.  If the set is not empty, then there is
1907    * some output that did not have an input.
1908    */
1909   unsigned num_outputs = 0;
1910   for (unsigned i = 0; i < producer->sh.data->NumProgramResourceList; i++) {
1911      struct gl_program_resource *res =
1912         &producer->sh.data->ProgramResourceList[i];
1913
1914      if (res->Type != GL_PROGRAM_OUTPUT)
1915         continue;
1916
1917      gl_shader_variable const *const var = RESOURCE_VAR(res);
1918
1919      /* Section 7.4.1 (Shader Interface Matching) of the OpenGL ES 3.1 spec
1920       * says:
1921       *
1922       *    Built-in inputs or outputs do not affect interface matching.
1923       */
1924      if (is_gl_identifier(var->name.string))
1925         continue;
1926
1927      outputs[num_outputs++] = var;
1928   }
1929
1930   unsigned match_index = 0;
1931   for (unsigned i = 0; i < consumer->sh.data->NumProgramResourceList; i++) {
1932      struct gl_program_resource *res =
1933         &consumer->sh.data->ProgramResourceList[i];
1934
1935      if (res->Type != GL_PROGRAM_INPUT)
1936         continue;
1937
1938      gl_shader_variable const *const consumer_var = RESOURCE_VAR(res);
1939      gl_shader_variable const *producer_var = NULL;
1940
1941      if (is_gl_identifier(consumer_var->name.string))
1942         continue;
1943
1944      /* Inputs with explicit locations match other outputs with explicit
1945       * locations by location instead of by name.
1946       */
1947      if (consumer_var->explicit_location) {
1948         for (unsigned j = 0; j < num_outputs; j++) {
1949            const gl_shader_variable *const var = outputs[j];
1950
1951            if (var->explicit_location &&
1952                consumer_var->location == var->location) {
1953               producer_var = var;
1954               match_index = j;
1955               break;
1956            }
1957         }
1958      } else {
1959         for (unsigned j = 0; j < num_outputs; j++) {
1960            const gl_shader_variable *const var = outputs[j];
1961
1962            if (!var->explicit_location &&
1963                strcmp(consumer_var->name.string, var->name.string) == 0) {
1964               producer_var = var;
1965               match_index = j;
1966               break;
1967            }
1968         }
1969      }
1970
1971      /* Section 7.4.1 (Shader Interface Matching) of the OpenGL ES 3.1 spec
1972       * says:
1973       *
1974       *    - An output variable is considered to match an input variable in
1975       *      the subsequent shader if:
1976       *
1977       *      - the two variables match in name, type, and qualification; or
1978       *
1979       *      - the two variables are declared with the same location
1980       *        qualifier and match in type and qualification.
1981       */
1982      if (producer_var == NULL) {
1983         valid = false;
1984         goto out;
1985      }
1986
1987      /* An output cannot match more than one input, so remove the output from
1988       * the set of possible outputs.
1989       */
1990      outputs[match_index] = NULL;
1991      num_outputs--;
1992      if (match_index < num_outputs)
1993         outputs[match_index] = outputs[num_outputs];
1994
1995      /* Section 7.4.1 (Shader Interface Matching) of the ES 3.2 spec says:
1996       *
1997       *    "Tessellation control shader per-vertex output variables and
1998       *     blocks and tessellation control, tessellation evaluation, and
1999       *     geometry shader per-vertex input variables and blocks are
2000       *     required to be declared as arrays, with each element representing
2001       *     input or output values for a single vertex of a multi-vertex
2002       *     primitive. For the purposes of interface matching, such variables
2003       *     and blocks are treated as though they were not declared as
2004       *     arrays."
2005       *
2006       * So we unwrap those types before matching.
2007       */
2008      const glsl_type *consumer_type = consumer_var->type;
2009      const glsl_type *consumer_interface_type = consumer_var->interface_type;
2010      const glsl_type *producer_type = producer_var->type;
2011      const glsl_type *producer_interface_type = producer_var->interface_type;
2012
2013      if (consumer_is_array_stage) {
2014         if (consumer_interface_type) {
2015            /* the interface is the array; the underlying types should match */
2016            if (consumer_interface_type->is_array() && !consumer_var->patch)
2017               consumer_interface_type = consumer_interface_type->fields.array;
2018         } else {
2019            if (consumer_type->is_array() && !consumer_var->patch)
2020               consumer_type = consumer_type->fields.array;
2021         }
2022      }
2023
2024      if (producer_is_array_stage) {
2025         if (producer_interface_type) {
2026            /* the interface is the array; the underlying types should match */
2027            if (producer_interface_type->is_array() && !producer_var->patch)
2028               producer_interface_type = producer_interface_type->fields.array;
2029         } else {
2030            if (producer_type->is_array() && !producer_var->patch)
2031               producer_type = producer_type->fields.array;
2032         }
2033      }
2034
2035      if (producer_type != consumer_type) {
2036         valid = false;
2037         goto out;
2038      }
2039
2040      if (producer_interface_type != consumer_interface_type) {
2041         valid = false;
2042         goto out;
2043      }
2044
2045      /* Section 9.2.2 (Separable Programs) of the GLSL ES spec says:
2046       *
2047       *    Qualifier Class|  Qualifier  |in/out
2048       *    ---------------+-------------+------
2049       *    Storage        |     in      |
2050       *                   |     out     |  N/A
2051       *                   |   uniform   |
2052       *    ---------------+-------------+------
2053       *    Auxiliary      |   centroid  |   No
2054       *    ---------------+-------------+------
2055       *                   |   location  |  Yes
2056       *                   | Block layout|  N/A
2057       *                   |   binding   |  N/A
2058       *                   |   offset    |  N/A
2059       *                   |   format    |  N/A
2060       *    ---------------+-------------+------
2061       *    Interpolation  |   smooth    |
2062       *                   |    flat     |  Yes
2063       *    ---------------+-------------+------
2064       *                   |    lowp     |
2065       *    Precision      |   mediump   |  Yes
2066       *                   |    highp    |
2067       *    ---------------+-------------+------
2068       *    Variance       |  invariant  |   No
2069       *    ---------------+-------------+------
2070       *    Memory         |     all     |  N/A
2071       *
2072       * Note that location mismatches are detected by the loops above that
2073       * find the producer variable that goes with the consumer variable.
2074       */
2075      unsigned producer_interpolation = producer_var->interpolation;
2076      unsigned consumer_interpolation = consumer_var->interpolation;
2077      if (producer_interpolation == INTERP_MODE_NONE)
2078         producer_interpolation = INTERP_MODE_SMOOTH;
2079      if (consumer_interpolation == INTERP_MODE_NONE)
2080         consumer_interpolation = INTERP_MODE_SMOOTH;
2081      if (producer_interpolation != consumer_interpolation) {
2082         valid = false;
2083         goto out;
2084      }
2085
2086      if (producer_var->precision != consumer_var->precision) {
2087         valid = false;
2088         goto out;
2089      }
2090
2091      if (producer_var->outermost_struct_type != consumer_var->outermost_struct_type) {
2092         valid = false;
2093         goto out;
2094      }
2095   }
2096
2097 out:
2098   free(outputs);
2099   return valid && num_outputs == 0;
2100}
2101
2102/**
2103 * Validate inputs against outputs in a program pipeline.
2104 */
2105extern "C" bool
2106_mesa_validate_pipeline_io(struct gl_pipeline_object *pipeline)
2107{
2108   struct gl_program **prog = (struct gl_program **) pipeline->CurrentProgram;
2109
2110   /* Find first active stage in pipeline. */
2111   unsigned idx, prev = 0;
2112   for (idx = 0; idx < ARRAY_SIZE(pipeline->CurrentProgram); idx++) {
2113      if (prog[idx]) {
2114         prev = idx;
2115         break;
2116      }
2117   }
2118
2119   for (idx = prev + 1; idx < ARRAY_SIZE(pipeline->CurrentProgram); idx++) {
2120      if (prog[idx]) {
2121         /* Pipeline might include both non-compute and a compute program, do
2122          * not attempt to validate varyings between non-compute and compute
2123          * stage.
2124          */
2125         if (prog[idx]->info.stage == MESA_SHADER_COMPUTE)
2126            break;
2127
2128         if (!validate_io(prog[prev], prog[idx]))
2129            return false;
2130
2131         prev = idx;
2132      }
2133   }
2134   return true;
2135}
2136
2137extern "C" void
2138_mesa_program_resource_hash_destroy(struct gl_shader_program *shProg)
2139{
2140   for (unsigned i = 0; i < ARRAY_SIZE(shProg->data->ProgramResourceHash); i++) {
2141      if (shProg->data->ProgramResourceHash[i]) {
2142         _mesa_hash_table_destroy(shProg->data->ProgramResourceHash[i], NULL);
2143         shProg->data->ProgramResourceHash[i] = NULL;
2144      }
2145   }
2146}
2147
2148extern "C" void
2149_mesa_create_program_resource_hash(struct gl_shader_program *shProg)
2150{
2151   /* Rebuild resource hash. */
2152   _mesa_program_resource_hash_destroy(shProg);
2153
2154   struct gl_program_resource *res = shProg->data->ProgramResourceList;
2155   for (unsigned i = 0; i < shProg->data->NumProgramResourceList; i++, res++) {
2156      struct gl_resource_name name;
2157      if (_mesa_program_get_resource_name(res, &name)) {
2158         unsigned type = GET_PROGRAM_RESOURCE_TYPE_FROM_GLENUM(res->Type);
2159         assert(type < ARRAY_SIZE(shProg->data->ProgramResourceHash));
2160
2161         if (!shProg->data->ProgramResourceHash[type]) {
2162            shProg->data->ProgramResourceHash[type] =
2163               _mesa_hash_table_create(shProg, _mesa_hash_string,
2164                                       _mesa_key_string_equal);
2165         }
2166
2167         _mesa_hash_table_insert(shProg->data->ProgramResourceHash[type],
2168                                 name.string, res);
2169      }
2170   }
2171}
2172