Home | History | Annotate | Download | only in main
      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 (at) intel.com>
     29  */
     30 
     31 #include "main/context.h"
     32 #include "main/core.h"
     33 #include "main/enums.h"
     34 #include "main/shaderapi.h"
     35 #include "main/shaderobj.h"
     36 #include "main/uniforms.h"
     37 #include "compiler/glsl/glsl_symbol_table.h"
     38 #include "compiler/glsl/ir.h"
     39 #include "compiler/glsl/program.h"
     40 #include "util/string_to_uint_map.h"
     41 #include "util/strndup.h"
     42 
     43 
     44 static GLint
     45 program_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) \
     53 const type * RESOURCE_ ## name (gl_program_resource *res) { \
     54    assert(res->Data); \
     55    return (type *) res->Data; \
     56 }
     57 
     58 DECL_RESOURCE_FUNC(VAR, gl_shader_variable);
     59 DECL_RESOURCE_FUNC(UBO, gl_uniform_block);
     60 DECL_RESOURCE_FUNC(UNI, gl_uniform_storage);
     61 DECL_RESOURCE_FUNC(ATC, gl_active_atomic_buffer);
     62 DECL_RESOURCE_FUNC(XFV, gl_transform_feedback_varying_info);
     63 DECL_RESOURCE_FUNC(XFB, gl_transform_feedback_buffer);
     64 DECL_RESOURCE_FUNC(SUB, gl_subroutine_function);
     65 
     66 void GLAPIENTRY
     67 _mesa_BindAttribLocation(GLuint program, GLuint index,
     68                          const GLchar *name)
     69 {
     70    GET_CURRENT_CONTEXT(ctx);
     71 
     72    struct gl_shader_program *const shProg =
     73       _mesa_lookup_shader_program_err(ctx, program, "glBindAttribLocation");
     74    if (!shProg)
     75       return;
     76 
     77    if (!name)
     78       return;
     79 
     80    if (strncmp(name, "gl_", 3) == 0) {
     81       _mesa_error(ctx, GL_INVALID_OPERATION,
     82                   "glBindAttribLocation(illegal name)");
     83       return;
     84    }
     85 
     86    if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) {
     87       _mesa_error(ctx, GL_INVALID_VALUE, "glBindAttribLocation(%u >= %u)",
     88                   index, ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs);
     89       return;
     90    }
     91 
     92    /* Replace the current value if it's already in the list.  Add
     93     * VERT_ATTRIB_GENERIC0 because that's how the linker differentiates
     94     * between built-in attributes and user-defined attributes.
     95     */
     96    shProg->AttributeBindings->put(index + VERT_ATTRIB_GENERIC0, name);
     97 
     98    /*
     99     * Note that this attribute binding won't go into effect until
    100     * glLinkProgram is called again.
    101     */
    102 }
    103 
    104 void GLAPIENTRY
    105 _mesa_GetActiveAttrib(GLuint program, GLuint desired_index,
    106                       GLsizei maxLength, GLsizei * length, GLint * size,
    107                       GLenum * type, GLchar * name)
    108 {
    109    GET_CURRENT_CONTEXT(ctx);
    110    struct gl_shader_program *shProg;
    111 
    112    if (maxLength < 0) {
    113       _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(maxLength < 0)");
    114       return;
    115    }
    116 
    117    shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveAttrib");
    118    if (!shProg)
    119       return;
    120 
    121    if (!shProg->data->LinkStatus) {
    122       _mesa_error(ctx, GL_INVALID_VALUE,
    123                   "glGetActiveAttrib(program not linked)");
    124       return;
    125    }
    126 
    127    if (shProg->_LinkedShaders[MESA_SHADER_VERTEX] == NULL) {
    128       _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(no vertex shader)");
    129       return;
    130    }
    131 
    132    struct gl_program_resource *res =
    133       _mesa_program_resource_find_index(shProg, GL_PROGRAM_INPUT,
    134                                         desired_index);
    135 
    136    /* User asked for index that does not exist. */
    137    if (!res) {
    138       _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(index)");
    139       return;
    140    }
    141 
    142    const gl_shader_variable *const var = RESOURCE_VAR(res);
    143 
    144    const char *var_name = var->name;
    145 
    146    _mesa_copy_string(name, maxLength, length, var_name);
    147 
    148    if (size)
    149       _mesa_program_resource_prop(shProg, res, desired_index, GL_ARRAY_SIZE,
    150                                   size, "glGetActiveAttrib");
    151 
    152    if (type)
    153       _mesa_program_resource_prop(shProg, res, desired_index, GL_TYPE,
    154                                   (GLint *) type, "glGetActiveAttrib");
    155 }
    156 
    157 GLint GLAPIENTRY
    158 _mesa_GetAttribLocation(GLuint program, const GLchar * name)
    159 {
    160    GET_CURRENT_CONTEXT(ctx);
    161    struct gl_shader_program *const shProg =
    162       _mesa_lookup_shader_program_err(ctx, program, "glGetAttribLocation");
    163 
    164    if (!shProg) {
    165       return -1;
    166    }
    167 
    168    if (!shProg->data->LinkStatus) {
    169       _mesa_error(ctx, GL_INVALID_OPERATION,
    170                   "glGetAttribLocation(program not linked)");
    171       return -1;
    172    }
    173 
    174    if (!name)
    175       return -1;
    176 
    177    /* Not having a vertex shader is not an error.
    178     */
    179    if (shProg->_LinkedShaders[MESA_SHADER_VERTEX] == NULL)
    180       return -1;
    181 
    182    unsigned array_index = 0;
    183    struct gl_program_resource *res =
    184       _mesa_program_resource_find_name(shProg, GL_PROGRAM_INPUT, name,
    185                                        &array_index);
    186 
    187    if (!res)
    188       return -1;
    189 
    190    return program_resource_location(res, array_index);
    191 }
    192 
    193 unsigned
    194 _mesa_count_active_attribs(struct gl_shader_program *shProg)
    195 {
    196    if (!shProg->data->LinkStatus
    197        || shProg->_LinkedShaders[MESA_SHADER_VERTEX] == NULL) {
    198       return 0;
    199    }
    200 
    201    struct gl_program_resource *res = shProg->ProgramResourceList;
    202    unsigned count = 0;
    203    for (unsigned j = 0; j < shProg->NumProgramResourceList; j++, res++) {
    204       if (res->Type == GL_PROGRAM_INPUT &&
    205           res->StageReferences & (1 << MESA_SHADER_VERTEX))
    206          count++;
    207    }
    208    return count;
    209 }
    210 
    211 
    212 size_t
    213 _mesa_longest_attribute_name_length(struct gl_shader_program *shProg)
    214 {
    215    if (!shProg->data->LinkStatus
    216        || shProg->_LinkedShaders[MESA_SHADER_VERTEX] == NULL) {
    217       return 0;
    218    }
    219 
    220    struct gl_program_resource *res = shProg->ProgramResourceList;
    221    size_t longest = 0;
    222    for (unsigned j = 0; j < shProg->NumProgramResourceList; j++, res++) {
    223       if (res->Type == GL_PROGRAM_INPUT &&
    224           res->StageReferences & (1 << MESA_SHADER_VERTEX)) {
    225 
    226           const size_t length = strlen(RESOURCE_VAR(res)->name);
    227           if (length >= longest)
    228              longest = length + 1;
    229       }
    230    }
    231 
    232    return longest;
    233 }
    234 
    235 void GLAPIENTRY
    236 _mesa_BindFragDataLocation(GLuint program, GLuint colorNumber,
    237 			   const GLchar *name)
    238 {
    239    _mesa_BindFragDataLocationIndexed(program, colorNumber, 0, name);
    240 }
    241 
    242 void GLAPIENTRY
    243 _mesa_BindFragDataLocationIndexed(GLuint program, GLuint colorNumber,
    244                                   GLuint index, const GLchar *name)
    245 {
    246    GET_CURRENT_CONTEXT(ctx);
    247 
    248    struct gl_shader_program *const shProg =
    249       _mesa_lookup_shader_program_err(ctx, program, "glBindFragDataLocationIndexed");
    250    if (!shProg)
    251       return;
    252 
    253    if (!name)
    254       return;
    255 
    256    if (strncmp(name, "gl_", 3) == 0) {
    257       _mesa_error(ctx, GL_INVALID_OPERATION, "glBindFragDataLocationIndexed(illegal name)");
    258       return;
    259    }
    260 
    261    if (index > 1) {
    262       _mesa_error(ctx, GL_INVALID_VALUE, "glBindFragDataLocationIndexed(index)");
    263       return;
    264    }
    265 
    266    if (index == 0 && colorNumber >= ctx->Const.MaxDrawBuffers) {
    267       _mesa_error(ctx, GL_INVALID_VALUE, "glBindFragDataLocationIndexed(colorNumber)");
    268       return;
    269    }
    270 
    271    if (index == 1 && colorNumber >= ctx->Const.MaxDualSourceDrawBuffers) {
    272       _mesa_error(ctx, GL_INVALID_VALUE, "glBindFragDataLocationIndexed(colorNumber)");
    273       return;
    274    }
    275 
    276    /* Replace the current value if it's already in the list.  Add
    277     * FRAG_RESULT_DATA0 because that's how the linker differentiates
    278     * between built-in attributes and user-defined attributes.
    279     */
    280    shProg->FragDataBindings->put(colorNumber + FRAG_RESULT_DATA0, name);
    281    shProg->FragDataIndexBindings->put(index, name);
    282    /*
    283     * Note that this binding won't go into effect until
    284     * glLinkProgram is called again.
    285     */
    286 
    287 }
    288 
    289 GLint GLAPIENTRY
    290 _mesa_GetFragDataIndex(GLuint program, const GLchar *name)
    291 {
    292    GET_CURRENT_CONTEXT(ctx);
    293    struct gl_shader_program *const shProg =
    294       _mesa_lookup_shader_program_err(ctx, program, "glGetFragDataIndex");
    295 
    296    if (!shProg) {
    297       return -1;
    298    }
    299 
    300    if (!shProg->data->LinkStatus) {
    301       _mesa_error(ctx, GL_INVALID_OPERATION,
    302                   "glGetFragDataIndex(program not linked)");
    303       return -1;
    304    }
    305 
    306    if (!name)
    307       return -1;
    308 
    309    if (strncmp(name, "gl_", 3) == 0) {
    310       _mesa_error(ctx, GL_INVALID_OPERATION,
    311                   "glGetFragDataIndex(illegal name)");
    312       return -1;
    313    }
    314 
    315    /* Not having a fragment shader is not an error.
    316     */
    317    if (shProg->_LinkedShaders[MESA_SHADER_FRAGMENT] == NULL)
    318       return -1;
    319 
    320    return _mesa_program_resource_location_index(shProg, GL_PROGRAM_OUTPUT,
    321                                                 name);
    322 }
    323 
    324 GLint GLAPIENTRY
    325 _mesa_GetFragDataLocation(GLuint program, const GLchar *name)
    326 {
    327    GET_CURRENT_CONTEXT(ctx);
    328    struct gl_shader_program *const shProg =
    329       _mesa_lookup_shader_program_err(ctx, program, "glGetFragDataLocation");
    330 
    331    if (!shProg) {
    332       return -1;
    333    }
    334 
    335    if (!shProg->data->LinkStatus) {
    336       _mesa_error(ctx, GL_INVALID_OPERATION,
    337                   "glGetFragDataLocation(program not linked)");
    338       return -1;
    339    }
    340 
    341    if (!name)
    342       return -1;
    343 
    344    if (strncmp(name, "gl_", 3) == 0) {
    345       _mesa_error(ctx, GL_INVALID_OPERATION,
    346                   "glGetFragDataLocation(illegal name)");
    347       return -1;
    348    }
    349 
    350    /* Not having a fragment shader is not an error.
    351     */
    352    if (shProg->_LinkedShaders[MESA_SHADER_FRAGMENT] == NULL)
    353       return -1;
    354 
    355    unsigned array_index = 0;
    356    struct gl_program_resource *res =
    357       _mesa_program_resource_find_name(shProg, GL_PROGRAM_OUTPUT, name,
    358                                        &array_index);
    359 
    360    if (!res)
    361       return -1;
    362 
    363    return program_resource_location(res, array_index);
    364 }
    365 
    366 const char*
    367 _mesa_program_resource_name(struct gl_program_resource *res)
    368 {
    369    switch (res->Type) {
    370    case GL_UNIFORM_BLOCK:
    371    case GL_SHADER_STORAGE_BLOCK:
    372       return RESOURCE_UBO(res)->Name;
    373    case GL_TRANSFORM_FEEDBACK_VARYING:
    374       return RESOURCE_XFV(res)->Name;
    375    case GL_PROGRAM_INPUT:
    376    case GL_PROGRAM_OUTPUT:
    377       return RESOURCE_VAR(res)->name;
    378    case GL_UNIFORM:
    379    case GL_BUFFER_VARIABLE:
    380       return RESOURCE_UNI(res)->name;
    381    case GL_VERTEX_SUBROUTINE_UNIFORM:
    382    case GL_GEOMETRY_SUBROUTINE_UNIFORM:
    383    case GL_FRAGMENT_SUBROUTINE_UNIFORM:
    384    case GL_COMPUTE_SUBROUTINE_UNIFORM:
    385    case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
    386    case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
    387       return RESOURCE_UNI(res)->name + MESA_SUBROUTINE_PREFIX_LEN;
    388    case GL_VERTEX_SUBROUTINE:
    389    case GL_GEOMETRY_SUBROUTINE:
    390    case GL_FRAGMENT_SUBROUTINE:
    391    case GL_COMPUTE_SUBROUTINE:
    392    case GL_TESS_CONTROL_SUBROUTINE:
    393    case GL_TESS_EVALUATION_SUBROUTINE:
    394       return RESOURCE_SUB(res)->name;
    395    default:
    396       assert(!"support for resource type not implemented");
    397    }
    398    return NULL;
    399 }
    400 
    401 
    402 unsigned
    403 _mesa_program_resource_array_size(struct gl_program_resource *res)
    404 {
    405    switch (res->Type) {
    406    case GL_TRANSFORM_FEEDBACK_VARYING:
    407       return RESOURCE_XFV(res)->Size > 1 ?
    408              RESOURCE_XFV(res)->Size : 0;
    409    case GL_PROGRAM_INPUT:
    410    case GL_PROGRAM_OUTPUT:
    411       return RESOURCE_VAR(res)->type->length;
    412    case GL_UNIFORM:
    413    case GL_VERTEX_SUBROUTINE_UNIFORM:
    414    case GL_GEOMETRY_SUBROUTINE_UNIFORM:
    415    case GL_FRAGMENT_SUBROUTINE_UNIFORM:
    416    case GL_COMPUTE_SUBROUTINE_UNIFORM:
    417    case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
    418    case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
    419       return RESOURCE_UNI(res)->array_elements;
    420    case GL_BUFFER_VARIABLE:
    421       /* Unsized arrays */
    422       if (RESOURCE_UNI(res)->array_stride > 0 &&
    423           RESOURCE_UNI(res)->array_elements == 0)
    424          return 1;
    425       else
    426          return RESOURCE_UNI(res)->array_elements;
    427    case GL_VERTEX_SUBROUTINE:
    428    case GL_GEOMETRY_SUBROUTINE:
    429    case GL_FRAGMENT_SUBROUTINE:
    430    case GL_COMPUTE_SUBROUTINE:
    431    case GL_TESS_CONTROL_SUBROUTINE:
    432    case GL_TESS_EVALUATION_SUBROUTINE:
    433    case GL_ATOMIC_COUNTER_BUFFER:
    434    case GL_UNIFORM_BLOCK:
    435    case GL_SHADER_STORAGE_BLOCK:
    436       return 0;
    437    default:
    438       assert(!"support for resource type not implemented");
    439    }
    440    return 0;
    441 }
    442 
    443 /**
    444  * Checks if array subscript is valid and if so sets array_index.
    445  */
    446 static bool
    447 valid_array_index(const GLchar *name, unsigned *array_index)
    448 {
    449    long idx = 0;
    450    const GLchar *out_base_name_end;
    451 
    452    idx = parse_program_resource_name(name, &out_base_name_end);
    453    if (idx < 0)
    454       return false;
    455 
    456    if (array_index)
    457       *array_index = idx;
    458 
    459    return true;
    460 }
    461 
    462 /* Find a program resource with specific name in given interface.
    463  */
    464 struct gl_program_resource *
    465 _mesa_program_resource_find_name(struct gl_shader_program *shProg,
    466                                  GLenum programInterface, const char *name,
    467                                  unsigned *array_index)
    468 {
    469    struct gl_program_resource *res = shProg->ProgramResourceList;
    470    for (unsigned i = 0; i < shProg->NumProgramResourceList; i++, res++) {
    471       if (res->Type != programInterface)
    472          continue;
    473 
    474       /* Resource basename. */
    475       const char *rname = _mesa_program_resource_name(res);
    476       unsigned baselen = strlen(rname);
    477       unsigned baselen_without_array_index = baselen;
    478       const char *rname_last_square_bracket = strrchr(rname, '[');
    479       bool found = false;
    480       bool rname_has_array_index_zero = false;
    481       /* From ARB_program_interface_query spec:
    482        *
    483        * "uint GetProgramResourceIndex(uint program, enum programInterface,
    484        *                               const char *name);
    485        *  [...]
    486        *  If <name> exactly matches the name string of one of the active
    487        *  resources for <programInterface>, the index of the matched resource is
    488        *  returned. Additionally, if <name> would exactly match the name string
    489        *  of an active resource if "[0]" were appended to <name>, the index of
    490        *  the matched resource is returned. [...]"
    491        *
    492        * "A string provided to GetProgramResourceLocation or
    493        * GetProgramResourceLocationIndex is considered to match an active variable
    494        * if:
    495        *
    496        *  * the string exactly matches the name of the active variable;
    497        *
    498        *  * if the string identifies the base name of an active array, where the
    499        *    string would exactly match the name of the variable if the suffix
    500        *    "[0]" were appended to the string; [...]"
    501        */
    502       /* Remove array's index from interface block name comparison only if
    503        * array's index is zero and the resulting string length is the same
    504        * than the provided name's length.
    505        */
    506       if (rname_last_square_bracket) {
    507          baselen_without_array_index -= strlen(rname_last_square_bracket);
    508          rname_has_array_index_zero =
    509             (strcmp(rname_last_square_bracket, "[0]") == 0) &&
    510             (baselen_without_array_index == strlen(name));
    511       }
    512 
    513       if (strncmp(rname, name, baselen) == 0)
    514          found = true;
    515       else if (rname_has_array_index_zero &&
    516                strncmp(rname, name, baselen_without_array_index) == 0)
    517          found = true;
    518 
    519       if (found) {
    520          switch (programInterface) {
    521          case GL_UNIFORM_BLOCK:
    522          case GL_SHADER_STORAGE_BLOCK:
    523             /* Basename match, check if array or struct. */
    524             if (rname_has_array_index_zero ||
    525                 name[baselen] == '\0' ||
    526                 name[baselen] == '[' ||
    527                 name[baselen] == '.') {
    528                return res;
    529             }
    530             break;
    531          case GL_TRANSFORM_FEEDBACK_VARYING:
    532          case GL_BUFFER_VARIABLE:
    533          case GL_UNIFORM:
    534          case GL_VERTEX_SUBROUTINE_UNIFORM:
    535          case GL_GEOMETRY_SUBROUTINE_UNIFORM:
    536          case GL_FRAGMENT_SUBROUTINE_UNIFORM:
    537          case GL_COMPUTE_SUBROUTINE_UNIFORM:
    538          case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
    539          case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
    540          case GL_VERTEX_SUBROUTINE:
    541          case GL_GEOMETRY_SUBROUTINE:
    542          case GL_FRAGMENT_SUBROUTINE:
    543          case GL_COMPUTE_SUBROUTINE:
    544          case GL_TESS_CONTROL_SUBROUTINE:
    545          case GL_TESS_EVALUATION_SUBROUTINE:
    546             if (name[baselen] == '.') {
    547                return res;
    548             }
    549             /* fall-through */
    550          case GL_PROGRAM_INPUT:
    551          case GL_PROGRAM_OUTPUT:
    552             if (name[baselen] == '\0') {
    553                return res;
    554             } else if (name[baselen] == '[' &&
    555                 valid_array_index(name, array_index)) {
    556                return res;
    557             }
    558             break;
    559          default:
    560             assert(!"not implemented for given interface");
    561          }
    562       }
    563    }
    564    return NULL;
    565 }
    566 
    567 static GLuint
    568 calc_resource_index(struct gl_shader_program *shProg,
    569                     struct gl_program_resource *res)
    570 {
    571    unsigned i;
    572    GLuint index = 0;
    573    for (i = 0; i < shProg->NumProgramResourceList; i++) {
    574       if (&shProg->ProgramResourceList[i] == res)
    575          return index;
    576       if (shProg->ProgramResourceList[i].Type == res->Type)
    577          index++;
    578    }
    579    return GL_INVALID_INDEX;
    580 }
    581 
    582 /**
    583  * Calculate index for the given resource.
    584  */
    585 GLuint
    586 _mesa_program_resource_index(struct gl_shader_program *shProg,
    587                              struct gl_program_resource *res)
    588 {
    589    if (!res)
    590       return GL_INVALID_INDEX;
    591 
    592    switch (res->Type) {
    593    case GL_ATOMIC_COUNTER_BUFFER:
    594       return RESOURCE_ATC(res) - shProg->data->AtomicBuffers;
    595    case GL_VERTEX_SUBROUTINE:
    596    case GL_GEOMETRY_SUBROUTINE:
    597    case GL_FRAGMENT_SUBROUTINE:
    598    case GL_COMPUTE_SUBROUTINE:
    599    case GL_TESS_CONTROL_SUBROUTINE:
    600    case GL_TESS_EVALUATION_SUBROUTINE:
    601       return RESOURCE_SUB(res)->index;
    602    case GL_UNIFORM_BLOCK:
    603    case GL_SHADER_STORAGE_BLOCK:
    604    case GL_TRANSFORM_FEEDBACK_BUFFER:
    605    case GL_TRANSFORM_FEEDBACK_VARYING:
    606    default:
    607       return calc_resource_index(shProg, res);
    608    }
    609 }
    610 
    611 /**
    612  * Find a program resource that points to given data.
    613  */
    614 static struct gl_program_resource*
    615 program_resource_find_data(struct gl_shader_program *shProg, void *data)
    616 {
    617    struct gl_program_resource *res = shProg->ProgramResourceList;
    618    for (unsigned i = 0; i < shProg->NumProgramResourceList; i++, res++) {
    619       if (res->Data == data)
    620          return res;
    621    }
    622    return NULL;
    623 }
    624 
    625 /* Find a program resource with specific index in given interface.
    626  */
    627 struct gl_program_resource *
    628 _mesa_program_resource_find_index(struct gl_shader_program *shProg,
    629                                   GLenum programInterface, GLuint index)
    630 {
    631    struct gl_program_resource *res = shProg->ProgramResourceList;
    632    int idx = -1;
    633 
    634    for (unsigned i = 0; i < shProg->NumProgramResourceList; i++, res++) {
    635       if (res->Type != programInterface)
    636          continue;
    637 
    638       switch (res->Type) {
    639       case GL_UNIFORM_BLOCK:
    640       case GL_ATOMIC_COUNTER_BUFFER:
    641       case GL_SHADER_STORAGE_BLOCK:
    642       case GL_TRANSFORM_FEEDBACK_BUFFER:
    643          if (_mesa_program_resource_index(shProg, res) == index)
    644             return res;
    645          break;
    646       case GL_TRANSFORM_FEEDBACK_VARYING:
    647       case GL_PROGRAM_INPUT:
    648       case GL_PROGRAM_OUTPUT:
    649       case GL_UNIFORM:
    650       case GL_VERTEX_SUBROUTINE_UNIFORM:
    651       case GL_GEOMETRY_SUBROUTINE_UNIFORM:
    652       case GL_FRAGMENT_SUBROUTINE_UNIFORM:
    653       case GL_COMPUTE_SUBROUTINE_UNIFORM:
    654       case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
    655       case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
    656       case GL_VERTEX_SUBROUTINE:
    657       case GL_GEOMETRY_SUBROUTINE:
    658       case GL_FRAGMENT_SUBROUTINE:
    659       case GL_COMPUTE_SUBROUTINE:
    660       case GL_TESS_CONTROL_SUBROUTINE:
    661       case GL_TESS_EVALUATION_SUBROUTINE:
    662       case GL_BUFFER_VARIABLE:
    663          if (++idx == (int) index)
    664             return res;
    665          break;
    666       default:
    667          assert(!"not implemented for given interface");
    668       }
    669    }
    670    return NULL;
    671 }
    672 
    673 /* Function returns if resource name is expected to have index
    674  * appended into it.
    675  *
    676  *
    677  * Page 61 (page 73 of the PDF) in section 2.11 of the OpenGL ES 3.0
    678  * spec says:
    679  *
    680  *     "If the active uniform is an array, the uniform name returned in
    681  *     name will always be the name of the uniform array appended with
    682  *     "[0]"."
    683  *
    684  * The same text also appears in the OpenGL 4.2 spec.  It does not,
    685  * however, appear in any previous spec.  Previous specifications are
    686  * ambiguous in this regard.  However, either name can later be passed
    687  * to glGetUniformLocation (and related APIs), so there shouldn't be any
    688  * harm in always appending "[0]" to uniform array names.
    689  */
    690 static bool
    691 add_index_to_name(struct gl_program_resource *res)
    692 {
    693    /* Transform feedback varyings have array index already appended
    694     * in their names.
    695     */
    696    return res->Type != GL_TRANSFORM_FEEDBACK_VARYING;
    697 }
    698 
    699 /* Get name length of a program resource. This consists of
    700  * base name + 3 for '[0]' if resource is an array.
    701  */
    702 extern unsigned
    703 _mesa_program_resource_name_len(struct gl_program_resource *res)
    704 {
    705    unsigned length = strlen(_mesa_program_resource_name(res));
    706    if (_mesa_program_resource_array_size(res) && add_index_to_name(res))
    707       length += 3;
    708    return length;
    709 }
    710 
    711 /* Get full name of a program resource.
    712  */
    713 bool
    714 _mesa_get_program_resource_name(struct gl_shader_program *shProg,
    715                                 GLenum programInterface, GLuint index,
    716                                 GLsizei bufSize, GLsizei *length,
    717                                 GLchar *name, const char *caller)
    718 {
    719    GET_CURRENT_CONTEXT(ctx);
    720 
    721    /* Find resource with given interface and index. */
    722    struct gl_program_resource *res =
    723       _mesa_program_resource_find_index(shProg, programInterface, index);
    724 
    725    /* The error INVALID_VALUE is generated if <index> is greater than
    726    * or equal to the number of entries in the active resource list for
    727    * <programInterface>.
    728    */
    729    if (!res) {
    730       _mesa_error(ctx, GL_INVALID_VALUE, "%s(index %u)", caller, index);
    731       return false;
    732    }
    733 
    734    if (bufSize < 0) {
    735       _mesa_error(ctx, GL_INVALID_VALUE, "%s(bufSize %d)", caller, bufSize);
    736       return false;
    737    }
    738 
    739    GLsizei localLength;
    740 
    741    if (length == NULL)
    742       length = &localLength;
    743 
    744    _mesa_copy_string(name, bufSize, length, _mesa_program_resource_name(res));
    745 
    746    if (_mesa_program_resource_array_size(res) && add_index_to_name(res)) {
    747       int i;
    748 
    749       /* The comparison is strange because *length does *NOT* include the
    750        * terminating NUL, but maxLength does.
    751        */
    752       for (i = 0; i < 3 && (*length + i + 1) < bufSize; i++)
    753          name[*length + i] = "[0]"[i];
    754 
    755       name[*length + i] = '\0';
    756       *length += i;
    757    }
    758    return true;
    759 }
    760 
    761 static GLint
    762 program_resource_location(struct gl_program_resource *res, unsigned array_index)
    763 {
    764    switch (res->Type) {
    765    case GL_PROGRAM_INPUT: {
    766       const gl_shader_variable *var = RESOURCE_VAR(res);
    767 
    768       if (var->location == -1)
    769          return -1;
    770 
    771       /* If the input is an array, fail if the index is out of bounds. */
    772       if (array_index > 0
    773           && array_index >= var->type->length) {
    774          return -1;
    775       }
    776       return var->location +
    777 	     (array_index * var->type->without_array()->matrix_columns);
    778    }
    779    case GL_PROGRAM_OUTPUT:
    780       if (RESOURCE_VAR(res)->location == -1)
    781          return -1;
    782 
    783       /* If the output is an array, fail if the index is out of bounds. */
    784       if (array_index > 0
    785           && array_index >= RESOURCE_VAR(res)->type->length) {
    786          return -1;
    787       }
    788       return RESOURCE_VAR(res)->location + array_index;
    789    case GL_UNIFORM:
    790       /* If the uniform is built-in, fail. */
    791       if (RESOURCE_UNI(res)->builtin)
    792          return -1;
    793 
    794      /* From page 79 of the OpenGL 4.2 spec:
    795       *
    796       *     "A valid name cannot be a structure, an array of structures, or any
    797       *     portion of a single vector or a matrix."
    798       */
    799       if (RESOURCE_UNI(res)->type->without_array()->is_record())
    800          return -1;
    801 
    802       /* From the GL_ARB_uniform_buffer_object spec:
    803        *
    804        *     "The value -1 will be returned if <name> does not correspond to an
    805        *     active uniform variable name in <program>, if <name> is associated
    806        *     with a named uniform block, or if <name> starts with the reserved
    807        *     prefix "gl_"."
    808        */
    809       if (RESOURCE_UNI(res)->block_index != -1 ||
    810           RESOURCE_UNI(res)->atomic_buffer_index != -1)
    811          return -1;
    812 
    813       /* fallthrough */
    814    case GL_VERTEX_SUBROUTINE_UNIFORM:
    815    case GL_GEOMETRY_SUBROUTINE_UNIFORM:
    816    case GL_FRAGMENT_SUBROUTINE_UNIFORM:
    817    case GL_COMPUTE_SUBROUTINE_UNIFORM:
    818    case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
    819    case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
    820       /* If the uniform is an array, fail if the index is out of bounds. */
    821       if (array_index > 0
    822           && array_index >= RESOURCE_UNI(res)->array_elements) {
    823          return -1;
    824       }
    825 
    826       /* location in remap table + array element offset */
    827       return RESOURCE_UNI(res)->remap_location + array_index;
    828    default:
    829       return -1;
    830    }
    831 }
    832 
    833 /**
    834  * Function implements following location queries:
    835  *    glGetUniformLocation
    836  */
    837 GLint
    838 _mesa_program_resource_location(struct gl_shader_program *shProg,
    839                                 GLenum programInterface, const char *name)
    840 {
    841    unsigned array_index = 0;
    842    struct gl_program_resource *res =
    843       _mesa_program_resource_find_name(shProg, programInterface, name,
    844                                        &array_index);
    845 
    846    /* Resource not found. */
    847    if (!res)
    848       return -1;
    849 
    850    return program_resource_location(res, array_index);
    851 }
    852 
    853 /**
    854  * Function implements following index queries:
    855  *    glGetFragDataIndex
    856  */
    857 GLint
    858 _mesa_program_resource_location_index(struct gl_shader_program *shProg,
    859                                       GLenum programInterface, const char *name)
    860 {
    861    struct gl_program_resource *res =
    862       _mesa_program_resource_find_name(shProg, programInterface, name, NULL);
    863 
    864    /* Non-existent variable or resource is not referenced by fragment stage. */
    865    if (!res || !(res->StageReferences & (1 << MESA_SHADER_FRAGMENT)))
    866       return -1;
    867 
    868    /* From OpenGL 4.5 spec, 7.3 Program Objects
    869     * "The value -1 will be returned by either command...
    870     *  ... or if name identifies an active variable that does not have a
    871     * valid location assigned.
    872     */
    873    if (RESOURCE_VAR(res)->location == -1)
    874       return -1;
    875    return RESOURCE_VAR(res)->index;
    876 }
    877 
    878 static uint8_t
    879 stage_from_enum(GLenum ref)
    880 {
    881    switch (ref) {
    882    case GL_REFERENCED_BY_VERTEX_SHADER:
    883       return MESA_SHADER_VERTEX;
    884    case GL_REFERENCED_BY_TESS_CONTROL_SHADER:
    885       return MESA_SHADER_TESS_CTRL;
    886    case GL_REFERENCED_BY_TESS_EVALUATION_SHADER:
    887       return MESA_SHADER_TESS_EVAL;
    888    case GL_REFERENCED_BY_GEOMETRY_SHADER:
    889       return MESA_SHADER_GEOMETRY;
    890    case GL_REFERENCED_BY_FRAGMENT_SHADER:
    891       return MESA_SHADER_FRAGMENT;
    892    case GL_REFERENCED_BY_COMPUTE_SHADER:
    893       return MESA_SHADER_COMPUTE;
    894    default:
    895       assert(!"shader stage not supported");
    896       return MESA_SHADER_STAGES;
    897    }
    898 }
    899 
    900 /**
    901  * Check if resource is referenced by given 'referenced by' stage enum.
    902  * ATC and UBO resources hold stage references of their own.
    903  */
    904 static bool
    905 is_resource_referenced(struct gl_shader_program *shProg,
    906                        struct gl_program_resource *res,
    907                        GLuint index, uint8_t stage)
    908 {
    909    /* First, check if we even have such a stage active. */
    910    if (!shProg->_LinkedShaders[stage])
    911       return false;
    912 
    913    if (res->Type == GL_ATOMIC_COUNTER_BUFFER)
    914       return RESOURCE_ATC(res)->StageReferences[stage];
    915 
    916    if (res->Type == GL_UNIFORM_BLOCK)
    917       return shProg->data->UniformBlocks[index].stageref & (1 << stage);
    918 
    919    if (res->Type == GL_SHADER_STORAGE_BLOCK)
    920       return shProg->data->ShaderStorageBlocks[index].stageref & (1 << stage);
    921 
    922    return res->StageReferences & (1 << stage);
    923 }
    924 
    925 static unsigned
    926 get_buffer_property(struct gl_shader_program *shProg,
    927                     struct gl_program_resource *res, const GLenum prop,
    928                     GLint *val, const char *caller)
    929 {
    930    GET_CURRENT_CONTEXT(ctx);
    931    if (res->Type != GL_UNIFORM_BLOCK &&
    932        res->Type != GL_ATOMIC_COUNTER_BUFFER &&
    933        res->Type != GL_SHADER_STORAGE_BLOCK &&
    934        res->Type != GL_TRANSFORM_FEEDBACK_BUFFER)
    935       goto invalid_operation;
    936 
    937    if (res->Type == GL_UNIFORM_BLOCK) {
    938       switch (prop) {
    939       case GL_BUFFER_BINDING:
    940          *val = RESOURCE_UBO(res)->Binding;
    941          return 1;
    942       case GL_BUFFER_DATA_SIZE:
    943          *val = RESOURCE_UBO(res)->UniformBufferSize;
    944          return 1;
    945       case GL_NUM_ACTIVE_VARIABLES:
    946          *val = 0;
    947          for (unsigned i = 0; i < RESOURCE_UBO(res)->NumUniforms; i++) {
    948             const char *iname = RESOURCE_UBO(res)->Uniforms[i].IndexName;
    949             struct gl_program_resource *uni =
    950                _mesa_program_resource_find_name(shProg, GL_UNIFORM, iname,
    951                                                 NULL);
    952             if (!uni)
    953                continue;
    954             (*val)++;
    955          }
    956          return 1;
    957       case GL_ACTIVE_VARIABLES: {
    958          unsigned num_values = 0;
    959          for (unsigned i = 0; i < RESOURCE_UBO(res)->NumUniforms; i++) {
    960             const char *iname = RESOURCE_UBO(res)->Uniforms[i].IndexName;
    961             struct gl_program_resource *uni =
    962                _mesa_program_resource_find_name(shProg, GL_UNIFORM, iname,
    963                                                 NULL);
    964             if (!uni)
    965                continue;
    966             *val++ =
    967                _mesa_program_resource_index(shProg, uni);
    968             num_values++;
    969          }
    970          return num_values;
    971       }
    972       }
    973    } else if (res->Type == GL_SHADER_STORAGE_BLOCK) {
    974       switch (prop) {
    975       case GL_BUFFER_BINDING:
    976          *val = RESOURCE_UBO(res)->Binding;
    977          return 1;
    978       case GL_BUFFER_DATA_SIZE:
    979          *val = RESOURCE_UBO(res)->UniformBufferSize;
    980          return 1;
    981       case GL_NUM_ACTIVE_VARIABLES:
    982          *val = 0;
    983          for (unsigned i = 0; i < RESOURCE_UBO(res)->NumUniforms; i++) {
    984             const char *iname = RESOURCE_UBO(res)->Uniforms[i].IndexName;
    985             struct gl_program_resource *uni =
    986                _mesa_program_resource_find_name(shProg, GL_BUFFER_VARIABLE,
    987                                                 iname, NULL);
    988             if (!uni)
    989                continue;
    990             (*val)++;
    991          }
    992          return 1;
    993       case GL_ACTIVE_VARIABLES: {
    994          unsigned num_values = 0;
    995          for (unsigned i = 0; i < RESOURCE_UBO(res)->NumUniforms; i++) {
    996             const char *iname = RESOURCE_UBO(res)->Uniforms[i].IndexName;
    997             struct gl_program_resource *uni =
    998                _mesa_program_resource_find_name(shProg, GL_BUFFER_VARIABLE,
    999                                                 iname, NULL);
   1000             if (!uni)
   1001                continue;
   1002             *val++ =
   1003                _mesa_program_resource_index(shProg, uni);
   1004             num_values++;
   1005          }
   1006          return num_values;
   1007       }
   1008       }
   1009    } else if (res->Type == GL_ATOMIC_COUNTER_BUFFER) {
   1010       switch (prop) {
   1011       case GL_BUFFER_BINDING:
   1012          *val = RESOURCE_ATC(res)->Binding;
   1013          return 1;
   1014       case GL_BUFFER_DATA_SIZE:
   1015          *val = RESOURCE_ATC(res)->MinimumSize;
   1016          return 1;
   1017       case GL_NUM_ACTIVE_VARIABLES:
   1018          *val = RESOURCE_ATC(res)->NumUniforms;
   1019          return 1;
   1020       case GL_ACTIVE_VARIABLES:
   1021          for (unsigned i = 0; i < RESOURCE_ATC(res)->NumUniforms; i++) {
   1022             /* Active atomic buffer contains index to UniformStorage. Find
   1023              * out gl_program_resource via data pointer and then calculate
   1024              * index of that uniform.
   1025              */
   1026             unsigned idx = RESOURCE_ATC(res)->Uniforms[i];
   1027             struct gl_program_resource *uni =
   1028                program_resource_find_data(shProg,
   1029                                           &shProg->data->UniformStorage[idx]);
   1030             assert(uni);
   1031             *val++ = _mesa_program_resource_index(shProg, uni);
   1032          }
   1033          return RESOURCE_ATC(res)->NumUniforms;
   1034       }
   1035    } else if (res->Type == GL_TRANSFORM_FEEDBACK_BUFFER) {
   1036       switch (prop) {
   1037       case GL_BUFFER_BINDING:
   1038          *val = RESOURCE_XFB(res)->Binding;
   1039          return 1;
   1040       case GL_NUM_ACTIVE_VARIABLES:
   1041          *val = RESOURCE_XFB(res)->NumVaryings;
   1042          return 1;
   1043       case GL_ACTIVE_VARIABLES:
   1044          struct gl_transform_feedback_info *linked_xfb =
   1045             shProg->xfb_program->sh.LinkedTransformFeedback;
   1046          for (int i = 0; i < linked_xfb->NumVarying; i++) {
   1047             unsigned index = linked_xfb->Varyings[i].BufferIndex;
   1048             struct gl_program_resource *buf_res =
   1049                _mesa_program_resource_find_index(shProg,
   1050                                                  GL_TRANSFORM_FEEDBACK_BUFFER,
   1051                                                  index);
   1052             assert(buf_res);
   1053             if (res == buf_res) {
   1054                *val++ = i;
   1055             }
   1056          }
   1057          return RESOURCE_XFB(res)->NumVaryings;
   1058       }
   1059    }
   1060    assert(!"support for property type not implemented");
   1061 
   1062 invalid_operation:
   1063    _mesa_error(ctx, GL_INVALID_OPERATION, "%s(%s prop %s)", caller,
   1064                _mesa_enum_to_string(res->Type),
   1065                _mesa_enum_to_string(prop));
   1066 
   1067    return 0;
   1068 }
   1069 
   1070 unsigned
   1071 _mesa_program_resource_prop(struct gl_shader_program *shProg,
   1072                             struct gl_program_resource *res, GLuint index,
   1073                             const GLenum prop, GLint *val, const char *caller)
   1074 {
   1075    GET_CURRENT_CONTEXT(ctx);
   1076 
   1077 #define VALIDATE_TYPE(type)\
   1078    if (res->Type != type)\
   1079       goto invalid_operation;
   1080 
   1081 #define VALIDATE_TYPE_2(type1, type2)\
   1082    if (res->Type != type1 && res->Type != type2)\
   1083       goto invalid_operation;
   1084 
   1085    switch(prop) {
   1086    case GL_NAME_LENGTH:
   1087       switch (res->Type) {
   1088       case GL_ATOMIC_COUNTER_BUFFER:
   1089       case GL_TRANSFORM_FEEDBACK_BUFFER:
   1090          goto invalid_operation;
   1091       default:
   1092          /* Resource name length + terminator. */
   1093          *val = _mesa_program_resource_name_len(res) + 1;
   1094       }
   1095       return 1;
   1096    case GL_TYPE:
   1097       switch (res->Type) {
   1098       case GL_UNIFORM:
   1099       case GL_BUFFER_VARIABLE:
   1100          *val = RESOURCE_UNI(res)->type->gl_type;
   1101          return 1;
   1102       case GL_PROGRAM_INPUT:
   1103       case GL_PROGRAM_OUTPUT:
   1104          *val = RESOURCE_VAR(res)->type->gl_type;
   1105          return 1;
   1106       case GL_TRANSFORM_FEEDBACK_VARYING:
   1107          *val = RESOURCE_XFV(res)->Type;
   1108          return 1;
   1109       default:
   1110          goto invalid_operation;
   1111       }
   1112    case GL_ARRAY_SIZE:
   1113       switch (res->Type) {
   1114       case GL_UNIFORM:
   1115       case GL_BUFFER_VARIABLE:
   1116       case GL_VERTEX_SUBROUTINE_UNIFORM:
   1117       case GL_GEOMETRY_SUBROUTINE_UNIFORM:
   1118       case GL_FRAGMENT_SUBROUTINE_UNIFORM:
   1119       case GL_COMPUTE_SUBROUTINE_UNIFORM:
   1120       case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
   1121       case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
   1122 
   1123          /* Test if a buffer variable is an array or an unsized array.
   1124           * Unsized arrays return zero as array size.
   1125           */
   1126          if (RESOURCE_UNI(res)->is_shader_storage &&
   1127              RESOURCE_UNI(res)->array_stride > 0)
   1128             *val = RESOURCE_UNI(res)->array_elements;
   1129          else
   1130             *val = MAX2(RESOURCE_UNI(res)->array_elements, 1);
   1131          return 1;
   1132       case GL_PROGRAM_INPUT:
   1133       case GL_PROGRAM_OUTPUT:
   1134          *val = MAX2(_mesa_program_resource_array_size(res), 1);
   1135          return 1;
   1136       case GL_TRANSFORM_FEEDBACK_VARYING:
   1137          *val = RESOURCE_XFV(res)->Size;
   1138          return 1;
   1139       default:
   1140          goto invalid_operation;
   1141       }
   1142    case GL_OFFSET:
   1143       switch (res->Type) {
   1144       case GL_UNIFORM:
   1145       case GL_BUFFER_VARIABLE:
   1146          *val = RESOURCE_UNI(res)->offset;
   1147          return 1;
   1148       case GL_TRANSFORM_FEEDBACK_VARYING:
   1149          *val = RESOURCE_XFV(res)->Offset;
   1150          return 1;
   1151       default:
   1152          goto invalid_operation;
   1153       }
   1154    case GL_BLOCK_INDEX:
   1155       VALIDATE_TYPE_2(GL_UNIFORM, GL_BUFFER_VARIABLE);
   1156       *val = RESOURCE_UNI(res)->block_index;
   1157       return 1;
   1158    case GL_ARRAY_STRIDE:
   1159       VALIDATE_TYPE_2(GL_UNIFORM, GL_BUFFER_VARIABLE);
   1160       *val = RESOURCE_UNI(res)->array_stride;
   1161       return 1;
   1162    case GL_MATRIX_STRIDE:
   1163       VALIDATE_TYPE_2(GL_UNIFORM, GL_BUFFER_VARIABLE);
   1164       *val = RESOURCE_UNI(res)->matrix_stride;
   1165       return 1;
   1166    case GL_IS_ROW_MAJOR:
   1167       VALIDATE_TYPE_2(GL_UNIFORM, GL_BUFFER_VARIABLE);
   1168       *val = RESOURCE_UNI(res)->row_major;
   1169       return 1;
   1170    case GL_ATOMIC_COUNTER_BUFFER_INDEX:
   1171       VALIDATE_TYPE(GL_UNIFORM);
   1172       *val = RESOURCE_UNI(res)->atomic_buffer_index;
   1173       return 1;
   1174    case GL_BUFFER_BINDING:
   1175    case GL_BUFFER_DATA_SIZE:
   1176    case GL_NUM_ACTIVE_VARIABLES:
   1177    case GL_ACTIVE_VARIABLES:
   1178       return get_buffer_property(shProg, res, prop, val, caller);
   1179    case GL_REFERENCED_BY_COMPUTE_SHADER:
   1180       if (!_mesa_has_compute_shaders(ctx))
   1181          goto invalid_enum;
   1182       /* fallthrough */
   1183    case GL_REFERENCED_BY_VERTEX_SHADER:
   1184    case GL_REFERENCED_BY_TESS_CONTROL_SHADER:
   1185    case GL_REFERENCED_BY_TESS_EVALUATION_SHADER:
   1186    case GL_REFERENCED_BY_GEOMETRY_SHADER:
   1187    case GL_REFERENCED_BY_FRAGMENT_SHADER:
   1188       switch (res->Type) {
   1189       case GL_UNIFORM:
   1190       case GL_PROGRAM_INPUT:
   1191       case GL_PROGRAM_OUTPUT:
   1192       case GL_UNIFORM_BLOCK:
   1193       case GL_BUFFER_VARIABLE:
   1194       case GL_SHADER_STORAGE_BLOCK:
   1195       case GL_ATOMIC_COUNTER_BUFFER:
   1196          *val = is_resource_referenced(shProg, res, index,
   1197                                        stage_from_enum(prop));
   1198          return 1;
   1199       default:
   1200          goto invalid_operation;
   1201       }
   1202    case GL_LOCATION:
   1203       switch (res->Type) {
   1204       case GL_UNIFORM:
   1205       case GL_VERTEX_SUBROUTINE_UNIFORM:
   1206       case GL_GEOMETRY_SUBROUTINE_UNIFORM:
   1207       case GL_FRAGMENT_SUBROUTINE_UNIFORM:
   1208       case GL_COMPUTE_SUBROUTINE_UNIFORM:
   1209       case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
   1210       case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
   1211       case GL_PROGRAM_INPUT:
   1212       case GL_PROGRAM_OUTPUT:
   1213          *val = program_resource_location(res, 0);
   1214          return 1;
   1215       default:
   1216          goto invalid_operation;
   1217       }
   1218    case GL_LOCATION_COMPONENT:
   1219       switch (res->Type) {
   1220       case GL_PROGRAM_INPUT:
   1221       case GL_PROGRAM_OUTPUT:
   1222          *val = RESOURCE_VAR(res)->component;
   1223          return 1;
   1224       default:
   1225          goto invalid_operation;
   1226       }
   1227    case GL_LOCATION_INDEX: {
   1228       int tmp;
   1229       if (res->Type != GL_PROGRAM_OUTPUT)
   1230          goto invalid_operation;
   1231       tmp = program_resource_location(res, 0);
   1232       if (tmp == -1)
   1233          *val = -1;
   1234       else
   1235          *val = _mesa_program_resource_location_index(shProg, res->Type,
   1236                                                       RESOURCE_VAR(res)->name);
   1237       return 1;
   1238    }
   1239    case GL_NUM_COMPATIBLE_SUBROUTINES:
   1240       if (res->Type != GL_VERTEX_SUBROUTINE_UNIFORM &&
   1241           res->Type != GL_FRAGMENT_SUBROUTINE_UNIFORM &&
   1242           res->Type != GL_GEOMETRY_SUBROUTINE_UNIFORM &&
   1243           res->Type != GL_COMPUTE_SUBROUTINE_UNIFORM &&
   1244           res->Type != GL_TESS_CONTROL_SUBROUTINE_UNIFORM &&
   1245           res->Type != GL_TESS_EVALUATION_SUBROUTINE_UNIFORM)
   1246          goto invalid_operation;
   1247       *val = RESOURCE_UNI(res)->num_compatible_subroutines;
   1248       return 1;
   1249    case GL_COMPATIBLE_SUBROUTINES: {
   1250       const struct gl_uniform_storage *uni;
   1251       struct gl_program *p;
   1252       unsigned count, i;
   1253       int j;
   1254 
   1255       if (res->Type != GL_VERTEX_SUBROUTINE_UNIFORM &&
   1256           res->Type != GL_FRAGMENT_SUBROUTINE_UNIFORM &&
   1257           res->Type != GL_GEOMETRY_SUBROUTINE_UNIFORM &&
   1258           res->Type != GL_COMPUTE_SUBROUTINE_UNIFORM &&
   1259           res->Type != GL_TESS_CONTROL_SUBROUTINE_UNIFORM &&
   1260           res->Type != GL_TESS_EVALUATION_SUBROUTINE_UNIFORM)
   1261          goto invalid_operation;
   1262       uni = RESOURCE_UNI(res);
   1263 
   1264       p = shProg->_LinkedShaders[_mesa_shader_stage_from_subroutine_uniform(res->Type)]->Program;
   1265       count = 0;
   1266       for (i = 0; i < p->sh.NumSubroutineFunctions; i++) {
   1267          struct gl_subroutine_function *fn = &p->sh.SubroutineFunctions[i];
   1268          for (j = 0; j < fn->num_compat_types; j++) {
   1269             if (fn->types[j] == uni->type) {
   1270                val[count++] = i;
   1271                break;
   1272             }
   1273          }
   1274       }
   1275       return count;
   1276    }
   1277 
   1278    case GL_TOP_LEVEL_ARRAY_SIZE:
   1279       VALIDATE_TYPE(GL_BUFFER_VARIABLE);
   1280       *val = RESOURCE_UNI(res)->top_level_array_size;
   1281       return 1;
   1282 
   1283    case GL_TOP_LEVEL_ARRAY_STRIDE:
   1284       VALIDATE_TYPE(GL_BUFFER_VARIABLE);
   1285       *val = RESOURCE_UNI(res)->top_level_array_stride;
   1286       return 1;
   1287 
   1288    /* GL_ARB_tessellation_shader */
   1289    case GL_IS_PER_PATCH:
   1290       switch (res->Type) {
   1291       case GL_PROGRAM_INPUT:
   1292       case GL_PROGRAM_OUTPUT:
   1293          *val = RESOURCE_VAR(res)->patch;
   1294          return 1;
   1295       default:
   1296          goto invalid_operation;
   1297       }
   1298 
   1299    case GL_TRANSFORM_FEEDBACK_BUFFER_INDEX:
   1300       VALIDATE_TYPE(GL_TRANSFORM_FEEDBACK_VARYING);
   1301       *val = RESOURCE_XFV(res)->BufferIndex;
   1302       return 1;
   1303    case GL_TRANSFORM_FEEDBACK_BUFFER_STRIDE:
   1304       VALIDATE_TYPE(GL_TRANSFORM_FEEDBACK_BUFFER);
   1305       *val = RESOURCE_XFB(res)->Stride * 4;
   1306       return 1;
   1307 
   1308    default:
   1309       goto invalid_enum;
   1310    }
   1311 
   1312 #undef VALIDATE_TYPE
   1313 #undef VALIDATE_TYPE_2
   1314 
   1315 invalid_enum:
   1316    _mesa_error(ctx, GL_INVALID_ENUM, "%s(%s prop %s)", caller,
   1317                _mesa_enum_to_string(res->Type),
   1318                _mesa_enum_to_string(prop));
   1319    return 0;
   1320 
   1321 invalid_operation:
   1322    _mesa_error(ctx, GL_INVALID_OPERATION, "%s(%s prop %s)", caller,
   1323                _mesa_enum_to_string(res->Type),
   1324                _mesa_enum_to_string(prop));
   1325    return 0;
   1326 }
   1327 
   1328 extern void
   1329 _mesa_get_program_resourceiv(struct gl_shader_program *shProg,
   1330                              GLenum programInterface, GLuint index, GLsizei propCount,
   1331                              const GLenum *props, GLsizei bufSize,
   1332                              GLsizei *length, GLint *params)
   1333 {
   1334    GET_CURRENT_CONTEXT(ctx);
   1335    GLint *val = (GLint *) params;
   1336    const GLenum *prop = props;
   1337    GLsizei amount = 0;
   1338 
   1339    struct gl_program_resource *res =
   1340       _mesa_program_resource_find_index(shProg, programInterface, index);
   1341 
   1342    /* No such resource found or bufSize negative. */
   1343    if (!res || bufSize < 0) {
   1344       _mesa_error(ctx, GL_INVALID_VALUE,
   1345                   "glGetProgramResourceiv(%s index %d bufSize %d)",
   1346                   _mesa_enum_to_string(programInterface), index, bufSize);
   1347       return;
   1348    }
   1349 
   1350    /* Write propCount values until error occurs or bufSize reached. */
   1351    for (int i = 0; i < propCount && i < bufSize; i++, val++, prop++) {
   1352       int props_written =
   1353          _mesa_program_resource_prop(shProg, res, index, *prop, val,
   1354                                      "glGetProgramResourceiv");
   1355 
   1356       /* Error happened. */
   1357       if (props_written == 0)
   1358          return;
   1359 
   1360       amount += props_written;
   1361    }
   1362 
   1363    /* If <length> is not NULL, the actual number of integer values
   1364     * written to <params> will be written to <length>.
   1365     */
   1366    if (length)
   1367       *length = amount;
   1368 }
   1369 
   1370 static bool
   1371 validate_io(struct gl_shader_program *producer,
   1372             struct gl_shader_program *consumer,
   1373             gl_shader_stage producer_stage,
   1374             gl_shader_stage consumer_stage)
   1375 {
   1376    if (producer == consumer)
   1377       return true;
   1378 
   1379    const bool nonarray_stage_to_array_stage =
   1380       producer_stage != MESA_SHADER_TESS_CTRL &&
   1381       (consumer_stage == MESA_SHADER_GEOMETRY ||
   1382        consumer_stage == MESA_SHADER_TESS_CTRL ||
   1383        consumer_stage == MESA_SHADER_TESS_EVAL);
   1384 
   1385    bool valid = true;
   1386 
   1387    gl_shader_variable const **outputs =
   1388       (gl_shader_variable const **) calloc(producer->NumProgramResourceList,
   1389                                            sizeof(gl_shader_variable *));
   1390    if (outputs == NULL)
   1391       return false;
   1392 
   1393    /* Section 7.4.1 (Shader Interface Matching) of the OpenGL ES 3.1 spec
   1394     * says:
   1395     *
   1396     *    At an interface between program objects, the set of inputs and
   1397     *    outputs are considered to match exactly if and only if:
   1398     *
   1399     *    - Every declared input variable has a matching output, as described
   1400     *      above.
   1401     *    - There are no user-defined output variables declared without a
   1402     *      matching input variable declaration.
   1403     *
   1404     * Every input has an output, and every output has an input.  Scan the list
   1405     * of producer resources once, and generate the list of outputs.  As inputs
   1406     * and outputs are matched, remove the matched outputs from the set.  At
   1407     * the end, the set must be empty.  If the set is not empty, then there is
   1408     * some output that did not have an input.
   1409     */
   1410    unsigned num_outputs = 0;
   1411    for (unsigned i = 0; i < producer->NumProgramResourceList; i++) {
   1412       struct gl_program_resource *res = &producer->ProgramResourceList[i];
   1413 
   1414       if (res->Type != GL_PROGRAM_OUTPUT)
   1415          continue;
   1416 
   1417       gl_shader_variable const *const var = RESOURCE_VAR(res);
   1418 
   1419       /* Section 7.4.1 (Shader Interface Matching) of the OpenGL ES 3.1 spec
   1420        * says:
   1421        *
   1422        *    Built-in inputs or outputs do not affect interface matching.
   1423        */
   1424       if (is_gl_identifier(var->name))
   1425          continue;
   1426 
   1427       outputs[num_outputs++] = var;
   1428    }
   1429 
   1430    unsigned match_index = 0;
   1431    for (unsigned i = 0; i < consumer->NumProgramResourceList; i++) {
   1432       struct gl_program_resource *res = &consumer->ProgramResourceList[i];
   1433 
   1434       if (res->Type != GL_PROGRAM_INPUT)
   1435          continue;
   1436 
   1437       gl_shader_variable const *const consumer_var = RESOURCE_VAR(res);
   1438       gl_shader_variable const *producer_var = NULL;
   1439 
   1440       if (is_gl_identifier(consumer_var->name))
   1441          continue;
   1442 
   1443       /* Inputs with explicit locations match other outputs with explicit
   1444        * locations by location instead of by name.
   1445        */
   1446       if (consumer_var->explicit_location) {
   1447          for (unsigned j = 0; j < num_outputs; j++) {
   1448             const gl_shader_variable *const var = outputs[j];
   1449 
   1450             if (var->explicit_location &&
   1451                 consumer_var->location == var->location) {
   1452                producer_var = var;
   1453                match_index = j;
   1454                break;
   1455             }
   1456          }
   1457       } else {
   1458          for (unsigned j = 0; j < num_outputs; j++) {
   1459             const gl_shader_variable *const var = outputs[j];
   1460 
   1461             if (!var->explicit_location &&
   1462                 strcmp(consumer_var->name, var->name) == 0) {
   1463                producer_var = var;
   1464                match_index = j;
   1465                break;
   1466             }
   1467          }
   1468       }
   1469 
   1470       /* Section 7.4.1 (Shader Interface Matching) of the OpenGL ES 3.1 spec
   1471        * says:
   1472        *
   1473        *    - An output variable is considered to match an input variable in
   1474        *      the subsequent shader if:
   1475        *
   1476        *      - the two variables match in name, type, and qualification; or
   1477        *
   1478        *      - the two variables are declared with the same location
   1479        *        qualifier and match in type and qualification.
   1480        */
   1481       if (producer_var == NULL) {
   1482          valid = false;
   1483          goto out;
   1484       }
   1485 
   1486       /* An output cannot match more than one input, so remove the output from
   1487        * the set of possible outputs.
   1488        */
   1489       outputs[match_index] = NULL;
   1490       num_outputs--;
   1491       if (match_index < num_outputs)
   1492          outputs[match_index] = outputs[num_outputs];
   1493 
   1494       /* Section 9.2.2 (Separable Programs) of the GLSL ES spec says:
   1495        *
   1496        *    Qualifier Class|  Qualifier  |in/out
   1497        *    ---------------+-------------+------
   1498        *    Storage        |     in      |
   1499        *                   |     out     |  N/A
   1500        *                   |   uniform   |
   1501        *    ---------------+-------------+------
   1502        *    Auxiliary      |   centroid  |   No
   1503        *    ---------------+-------------+------
   1504        *                   |   location  |  Yes
   1505        *                   | Block layout|  N/A
   1506        *                   |   binding   |  N/A
   1507        *                   |   offset    |  N/A
   1508        *                   |   format    |  N/A
   1509        *    ---------------+-------------+------
   1510        *    Interpolation  |   smooth    |
   1511        *                   |    flat     |  Yes
   1512        *    ---------------+-------------+------
   1513        *                   |    lowp     |
   1514        *    Precision      |   mediump   |  Yes
   1515        *                   |    highp    |
   1516        *    ---------------+-------------+------
   1517        *    Variance       |  invariant  |   No
   1518        *    ---------------+-------------+------
   1519        *    Memory         |     all     |  N/A
   1520        *
   1521        * Note that location mismatches are detected by the loops above that
   1522        * find the producer variable that goes with the consumer variable.
   1523        */
   1524       if (nonarray_stage_to_array_stage) {
   1525          if (consumer_var->interface_type != NULL) {
   1526             /* the interface is the array; underlying types should match */
   1527             if (producer_var->type != consumer_var->type) {
   1528                valid = false;
   1529                goto out;
   1530             }
   1531 
   1532             if (!consumer_var->interface_type->is_array() ||
   1533                 consumer_var->interface_type->fields.array != producer_var->interface_type) {
   1534                valid = false;
   1535                goto out;
   1536             }
   1537          } else {
   1538             if (producer_var->interface_type != NULL) {
   1539                valid = false;
   1540                goto out;
   1541             }
   1542 
   1543             if (!consumer_var->type->is_array() ||
   1544                 consumer_var->type->fields.array != producer_var->type) {
   1545                valid = false;
   1546                goto out;
   1547             }
   1548          }
   1549       } else {
   1550          if (producer_var->type != consumer_var->type) {
   1551             valid = false;
   1552             goto out;
   1553          }
   1554 
   1555          if (producer_var->interface_type != consumer_var->interface_type) {
   1556             valid = false;
   1557             goto out;
   1558          }
   1559       }
   1560 
   1561       if (producer_var->interpolation != consumer_var->interpolation) {
   1562          valid = false;
   1563          goto out;
   1564       }
   1565 
   1566       if (producer_var->precision != consumer_var->precision) {
   1567          valid = false;
   1568          goto out;
   1569       }
   1570 
   1571       if (producer_var->outermost_struct_type != consumer_var->outermost_struct_type) {
   1572          valid = false;
   1573          goto out;
   1574       }
   1575    }
   1576 
   1577  out:
   1578    free(outputs);
   1579    return valid && num_outputs == 0;
   1580 }
   1581 
   1582 /**
   1583  * Validate inputs against outputs in a program pipeline.
   1584  */
   1585 extern "C" bool
   1586 _mesa_validate_pipeline_io(struct gl_pipeline_object *pipeline)
   1587 {
   1588    struct gl_shader_program **shProg =
   1589       (struct gl_shader_program **) pipeline->CurrentProgram;
   1590 
   1591    /* Find first active stage in pipeline. */
   1592    unsigned idx, prev = 0;
   1593    for (idx = 0; idx < ARRAY_SIZE(pipeline->CurrentProgram); idx++) {
   1594       if (shProg[idx]) {
   1595          prev = idx;
   1596          break;
   1597       }
   1598    }
   1599 
   1600    for (idx = prev + 1; idx < ARRAY_SIZE(pipeline->CurrentProgram); idx++) {
   1601       if (shProg[idx]) {
   1602          /* Pipeline might include both non-compute and a compute program, do
   1603           * not attempt to validate varyings between non-compute and compute
   1604           * stage.
   1605           */
   1606          if (shProg[idx]->_LinkedShaders[idx]->Stage == MESA_SHADER_COMPUTE)
   1607             break;
   1608 
   1609          if (!validate_io(shProg[prev], shProg[idx],
   1610                           shProg[prev]->_LinkedShaders[prev]->Stage,
   1611                           shProg[idx]->_LinkedShaders[idx]->Stage))
   1612             return false;
   1613 
   1614          prev = idx;
   1615       }
   1616    }
   1617    return true;
   1618 }
   1619