xref: /aosp_15_r20/external/mesa3d/src/mesa/main/program_resource.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Mesa 3-D graphics library
3*61046927SAndroid Build Coastguard Worker  *
4*61046927SAndroid Build Coastguard Worker  * Copyright (C) 2015 Intel Corporation.  All Rights Reserved.
5*61046927SAndroid Build Coastguard Worker  *
6*61046927SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
7*61046927SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
8*61046927SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
9*61046927SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10*61046927SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
11*61046927SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
12*61046927SAndroid Build Coastguard Worker  *
13*61046927SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice shall be included
14*61046927SAndroid Build Coastguard Worker  * in all copies or substantial portions of the Software.
15*61046927SAndroid Build Coastguard Worker  *
16*61046927SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17*61046927SAndroid Build Coastguard Worker  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18*61046927SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19*61046927SAndroid Build Coastguard Worker  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20*61046927SAndroid Build Coastguard Worker  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21*61046927SAndroid Build Coastguard Worker  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22*61046927SAndroid Build Coastguard Worker  * OTHER DEALINGS IN THE SOFTWARE.
23*61046927SAndroid Build Coastguard Worker  *
24*61046927SAndroid Build Coastguard Worker  */
25*61046927SAndroid Build Coastguard Worker 
26*61046927SAndroid Build Coastguard Worker #include "main/enums.h"
27*61046927SAndroid Build Coastguard Worker #include "main/macros.h"
28*61046927SAndroid Build Coastguard Worker #include "main/mtypes.h"
29*61046927SAndroid Build Coastguard Worker #include "main/shaderapi.h"
30*61046927SAndroid Build Coastguard Worker #include "main/shaderobj.h"
31*61046927SAndroid Build Coastguard Worker #include "main/context.h"
32*61046927SAndroid Build Coastguard Worker #include "compiler/glsl/ir_uniform.h"
33*61046927SAndroid Build Coastguard Worker #include "api_exec_decl.h"
34*61046927SAndroid Build Coastguard Worker 
35*61046927SAndroid Build Coastguard Worker static bool
supported_interface_enum(struct gl_context * ctx,GLenum iface)36*61046927SAndroid Build Coastguard Worker supported_interface_enum(struct gl_context *ctx, GLenum iface)
37*61046927SAndroid Build Coastguard Worker {
38*61046927SAndroid Build Coastguard Worker    switch (iface) {
39*61046927SAndroid Build Coastguard Worker    case GL_UNIFORM:
40*61046927SAndroid Build Coastguard Worker    case GL_UNIFORM_BLOCK:
41*61046927SAndroid Build Coastguard Worker    case GL_PROGRAM_INPUT:
42*61046927SAndroid Build Coastguard Worker    case GL_PROGRAM_OUTPUT:
43*61046927SAndroid Build Coastguard Worker    case GL_TRANSFORM_FEEDBACK_BUFFER:
44*61046927SAndroid Build Coastguard Worker    case GL_TRANSFORM_FEEDBACK_VARYING:
45*61046927SAndroid Build Coastguard Worker    case GL_ATOMIC_COUNTER_BUFFER:
46*61046927SAndroid Build Coastguard Worker    case GL_BUFFER_VARIABLE:
47*61046927SAndroid Build Coastguard Worker    case GL_SHADER_STORAGE_BLOCK:
48*61046927SAndroid Build Coastguard Worker       return true;
49*61046927SAndroid Build Coastguard Worker    case GL_VERTEX_SUBROUTINE:
50*61046927SAndroid Build Coastguard Worker    case GL_FRAGMENT_SUBROUTINE:
51*61046927SAndroid Build Coastguard Worker    case GL_VERTEX_SUBROUTINE_UNIFORM:
52*61046927SAndroid Build Coastguard Worker    case GL_FRAGMENT_SUBROUTINE_UNIFORM:
53*61046927SAndroid Build Coastguard Worker       return _mesa_has_ARB_shader_subroutine(ctx);
54*61046927SAndroid Build Coastguard Worker    case GL_GEOMETRY_SUBROUTINE:
55*61046927SAndroid Build Coastguard Worker    case GL_GEOMETRY_SUBROUTINE_UNIFORM:
56*61046927SAndroid Build Coastguard Worker       return _mesa_has_geometry_shaders(ctx) && _mesa_has_ARB_shader_subroutine(ctx);
57*61046927SAndroid Build Coastguard Worker    case GL_COMPUTE_SUBROUTINE:
58*61046927SAndroid Build Coastguard Worker    case GL_COMPUTE_SUBROUTINE_UNIFORM:
59*61046927SAndroid Build Coastguard Worker       return _mesa_has_compute_shaders(ctx) && _mesa_has_ARB_shader_subroutine(ctx);
60*61046927SAndroid Build Coastguard Worker    case GL_TESS_CONTROL_SUBROUTINE:
61*61046927SAndroid Build Coastguard Worker    case GL_TESS_EVALUATION_SUBROUTINE:
62*61046927SAndroid Build Coastguard Worker    case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
63*61046927SAndroid Build Coastguard Worker    case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
64*61046927SAndroid Build Coastguard Worker       return _mesa_has_tessellation(ctx) && _mesa_has_ARB_shader_subroutine(ctx);
65*61046927SAndroid Build Coastguard Worker    default:
66*61046927SAndroid Build Coastguard Worker       return false;
67*61046927SAndroid Build Coastguard Worker    }
68*61046927SAndroid Build Coastguard Worker }
69*61046927SAndroid Build Coastguard Worker 
70*61046927SAndroid Build Coastguard Worker static struct gl_shader_program *
lookup_linked_program(GLuint program,const char * caller)71*61046927SAndroid Build Coastguard Worker lookup_linked_program(GLuint program, const char *caller)
72*61046927SAndroid Build Coastguard Worker {
73*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
74*61046927SAndroid Build Coastguard Worker    struct gl_shader_program *prog =
75*61046927SAndroid Build Coastguard Worker       _mesa_lookup_shader_program_err(ctx, program, caller);
76*61046927SAndroid Build Coastguard Worker 
77*61046927SAndroid Build Coastguard Worker    if (!prog)
78*61046927SAndroid Build Coastguard Worker       return NULL;
79*61046927SAndroid Build Coastguard Worker 
80*61046927SAndroid Build Coastguard Worker    if (prog->data->LinkStatus == LINKING_FAILURE) {
81*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_OPERATION, "%s(program not linked)",
82*61046927SAndroid Build Coastguard Worker                   caller);
83*61046927SAndroid Build Coastguard Worker       return NULL;
84*61046927SAndroid Build Coastguard Worker    }
85*61046927SAndroid Build Coastguard Worker    return prog;
86*61046927SAndroid Build Coastguard Worker }
87*61046927SAndroid Build Coastguard Worker 
88*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_GetProgramInterfaceiv(GLuint program,GLenum programInterface,GLenum pname,GLint * params)89*61046927SAndroid Build Coastguard Worker _mesa_GetProgramInterfaceiv(GLuint program, GLenum programInterface,
90*61046927SAndroid Build Coastguard Worker                             GLenum pname, GLint *params)
91*61046927SAndroid Build Coastguard Worker {
92*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
93*61046927SAndroid Build Coastguard Worker 
94*61046927SAndroid Build Coastguard Worker    if (MESA_VERBOSE & VERBOSE_API) {
95*61046927SAndroid Build Coastguard Worker       _mesa_debug(ctx, "glGetProgramInterfaceiv(%u, %s, %s, %p)\n",
96*61046927SAndroid Build Coastguard Worker                   program, _mesa_enum_to_string(programInterface),
97*61046927SAndroid Build Coastguard Worker                   _mesa_enum_to_string(pname), params);
98*61046927SAndroid Build Coastguard Worker    }
99*61046927SAndroid Build Coastguard Worker 
100*61046927SAndroid Build Coastguard Worker    struct gl_shader_program *shProg =
101*61046927SAndroid Build Coastguard Worker       _mesa_lookup_shader_program_err(ctx, program,
102*61046927SAndroid Build Coastguard Worker                                       "glGetProgramInterfaceiv");
103*61046927SAndroid Build Coastguard Worker    if (!shProg)
104*61046927SAndroid Build Coastguard Worker       return;
105*61046927SAndroid Build Coastguard Worker 
106*61046927SAndroid Build Coastguard Worker    if (!params) {
107*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_OPERATION,
108*61046927SAndroid Build Coastguard Worker                   "glGetProgramInterfaceiv(params NULL)");
109*61046927SAndroid Build Coastguard Worker       return;
110*61046927SAndroid Build Coastguard Worker    }
111*61046927SAndroid Build Coastguard Worker 
112*61046927SAndroid Build Coastguard Worker    /* Validate interface. */
113*61046927SAndroid Build Coastguard Worker    if (!supported_interface_enum(ctx, programInterface)) {
114*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramInterfaceiv(%s)",
115*61046927SAndroid Build Coastguard Worker                   _mesa_enum_to_string(programInterface));
116*61046927SAndroid Build Coastguard Worker       return;
117*61046927SAndroid Build Coastguard Worker    }
118*61046927SAndroid Build Coastguard Worker 
119*61046927SAndroid Build Coastguard Worker    _mesa_get_program_interfaceiv(shProg, programInterface, pname, params);
120*61046927SAndroid Build Coastguard Worker }
121*61046927SAndroid Build Coastguard Worker 
122*61046927SAndroid Build Coastguard Worker static bool
is_xfb_marker(const char * str)123*61046927SAndroid Build Coastguard Worker is_xfb_marker(const char *str)
124*61046927SAndroid Build Coastguard Worker {
125*61046927SAndroid Build Coastguard Worker    static const char *markers[] = {
126*61046927SAndroid Build Coastguard Worker       "gl_NextBuffer",
127*61046927SAndroid Build Coastguard Worker       "gl_SkipComponents1",
128*61046927SAndroid Build Coastguard Worker       "gl_SkipComponents2",
129*61046927SAndroid Build Coastguard Worker       "gl_SkipComponents3",
130*61046927SAndroid Build Coastguard Worker       "gl_SkipComponents4",
131*61046927SAndroid Build Coastguard Worker       NULL
132*61046927SAndroid Build Coastguard Worker    };
133*61046927SAndroid Build Coastguard Worker    const char **m = markers;
134*61046927SAndroid Build Coastguard Worker 
135*61046927SAndroid Build Coastguard Worker    if (strncmp(str, "gl_", 3) != 0)
136*61046927SAndroid Build Coastguard Worker       return false;
137*61046927SAndroid Build Coastguard Worker 
138*61046927SAndroid Build Coastguard Worker    for (; *m; m++)
139*61046927SAndroid Build Coastguard Worker       if (strcmp(*m, str) == 0)
140*61046927SAndroid Build Coastguard Worker          return true;
141*61046927SAndroid Build Coastguard Worker 
142*61046927SAndroid Build Coastguard Worker    return false;
143*61046927SAndroid Build Coastguard Worker }
144*61046927SAndroid Build Coastguard Worker 
145*61046927SAndroid Build Coastguard Worker GLuint GLAPIENTRY
_mesa_GetProgramResourceIndex(GLuint program,GLenum programInterface,const GLchar * name)146*61046927SAndroid Build Coastguard Worker _mesa_GetProgramResourceIndex(GLuint program, GLenum programInterface,
147*61046927SAndroid Build Coastguard Worker                               const GLchar *name)
148*61046927SAndroid Build Coastguard Worker {
149*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
150*61046927SAndroid Build Coastguard Worker 
151*61046927SAndroid Build Coastguard Worker    if (MESA_VERBOSE & VERBOSE_API) {
152*61046927SAndroid Build Coastguard Worker       _mesa_debug(ctx, "glGetProgramResourceIndex(%u, %s, %s)\n",
153*61046927SAndroid Build Coastguard Worker                   program, _mesa_enum_to_string(programInterface), name);
154*61046927SAndroid Build Coastguard Worker    }
155*61046927SAndroid Build Coastguard Worker 
156*61046927SAndroid Build Coastguard Worker    unsigned array_index = 0;
157*61046927SAndroid Build Coastguard Worker    struct gl_program_resource *res;
158*61046927SAndroid Build Coastguard Worker    struct gl_shader_program *shProg =
159*61046927SAndroid Build Coastguard Worker       _mesa_lookup_shader_program_err(ctx, program,
160*61046927SAndroid Build Coastguard Worker                                       "glGetProgramResourceIndex");
161*61046927SAndroid Build Coastguard Worker    if (!shProg || !name)
162*61046927SAndroid Build Coastguard Worker       return GL_INVALID_INDEX;
163*61046927SAndroid Build Coastguard Worker 
164*61046927SAndroid Build Coastguard Worker    if (!supported_interface_enum(ctx, programInterface)) {
165*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramResourceIndex(%s)",
166*61046927SAndroid Build Coastguard Worker                   _mesa_enum_to_string(programInterface));
167*61046927SAndroid Build Coastguard Worker       return GL_INVALID_INDEX;
168*61046927SAndroid Build Coastguard Worker    }
169*61046927SAndroid Build Coastguard Worker    /*
170*61046927SAndroid Build Coastguard Worker     * For the interface TRANSFORM_FEEDBACK_VARYING, the value INVALID_INDEX
171*61046927SAndroid Build Coastguard Worker     * should be returned when querying the index assigned to the special names
172*61046927SAndroid Build Coastguard Worker     * "gl_NextBuffer", "gl_SkipComponents1", "gl_SkipComponents2",
173*61046927SAndroid Build Coastguard Worker     * "gl_SkipComponents3", and "gl_SkipComponents4".
174*61046927SAndroid Build Coastguard Worker     */
175*61046927SAndroid Build Coastguard Worker    if (programInterface == GL_TRANSFORM_FEEDBACK_VARYING &&
176*61046927SAndroid Build Coastguard Worker        is_xfb_marker(name))
177*61046927SAndroid Build Coastguard Worker       return GL_INVALID_INDEX;
178*61046927SAndroid Build Coastguard Worker 
179*61046927SAndroid Build Coastguard Worker    switch (programInterface) {
180*61046927SAndroid Build Coastguard Worker    case GL_TESS_CONTROL_SUBROUTINE:
181*61046927SAndroid Build Coastguard Worker    case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
182*61046927SAndroid Build Coastguard Worker    case GL_TESS_EVALUATION_SUBROUTINE:
183*61046927SAndroid Build Coastguard Worker    case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
184*61046927SAndroid Build Coastguard Worker    case GL_COMPUTE_SUBROUTINE:
185*61046927SAndroid Build Coastguard Worker    case GL_COMPUTE_SUBROUTINE_UNIFORM:
186*61046927SAndroid Build Coastguard Worker    case GL_GEOMETRY_SUBROUTINE:
187*61046927SAndroid Build Coastguard Worker    case GL_GEOMETRY_SUBROUTINE_UNIFORM:
188*61046927SAndroid Build Coastguard Worker    case GL_VERTEX_SUBROUTINE:
189*61046927SAndroid Build Coastguard Worker    case GL_FRAGMENT_SUBROUTINE:
190*61046927SAndroid Build Coastguard Worker    case GL_VERTEX_SUBROUTINE_UNIFORM:
191*61046927SAndroid Build Coastguard Worker    case GL_FRAGMENT_SUBROUTINE_UNIFORM:
192*61046927SAndroid Build Coastguard Worker    case GL_PROGRAM_INPUT:
193*61046927SAndroid Build Coastguard Worker    case GL_PROGRAM_OUTPUT:
194*61046927SAndroid Build Coastguard Worker    case GL_UNIFORM:
195*61046927SAndroid Build Coastguard Worker    case GL_BUFFER_VARIABLE:
196*61046927SAndroid Build Coastguard Worker    case GL_TRANSFORM_FEEDBACK_VARYING:
197*61046927SAndroid Build Coastguard Worker    case GL_UNIFORM_BLOCK:
198*61046927SAndroid Build Coastguard Worker    case GL_SHADER_STORAGE_BLOCK:
199*61046927SAndroid Build Coastguard Worker       res = _mesa_program_resource_find_name(shProg, programInterface, name,
200*61046927SAndroid Build Coastguard Worker                                              &array_index);
201*61046927SAndroid Build Coastguard Worker       if (!res || array_index > 0)
202*61046927SAndroid Build Coastguard Worker          return GL_INVALID_INDEX;
203*61046927SAndroid Build Coastguard Worker 
204*61046927SAndroid Build Coastguard Worker       return _mesa_program_resource_index(shProg, res);
205*61046927SAndroid Build Coastguard Worker    case GL_ATOMIC_COUNTER_BUFFER:
206*61046927SAndroid Build Coastguard Worker    case GL_TRANSFORM_FEEDBACK_BUFFER:
207*61046927SAndroid Build Coastguard Worker    default:
208*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramResourceIndex(%s)",
209*61046927SAndroid Build Coastguard Worker                   _mesa_enum_to_string(programInterface));
210*61046927SAndroid Build Coastguard Worker    }
211*61046927SAndroid Build Coastguard Worker 
212*61046927SAndroid Build Coastguard Worker    return GL_INVALID_INDEX;
213*61046927SAndroid Build Coastguard Worker }
214*61046927SAndroid Build Coastguard Worker 
215*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_GetProgramResourceName(GLuint program,GLenum programInterface,GLuint index,GLsizei bufSize,GLsizei * length,GLchar * name)216*61046927SAndroid Build Coastguard Worker _mesa_GetProgramResourceName(GLuint program, GLenum programInterface,
217*61046927SAndroid Build Coastguard Worker                              GLuint index, GLsizei bufSize, GLsizei *length,
218*61046927SAndroid Build Coastguard Worker                              GLchar *name)
219*61046927SAndroid Build Coastguard Worker {
220*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
221*61046927SAndroid Build Coastguard Worker 
222*61046927SAndroid Build Coastguard Worker    if (MESA_VERBOSE & VERBOSE_API) {
223*61046927SAndroid Build Coastguard Worker       _mesa_debug(ctx, "glGetProgramResourceName(%u, %s, %u, %d, %p, %p)\n",
224*61046927SAndroid Build Coastguard Worker                   program, _mesa_enum_to_string(programInterface), index,
225*61046927SAndroid Build Coastguard Worker                   bufSize, length, name);
226*61046927SAndroid Build Coastguard Worker    }
227*61046927SAndroid Build Coastguard Worker 
228*61046927SAndroid Build Coastguard Worker    struct gl_shader_program *shProg =
229*61046927SAndroid Build Coastguard Worker       _mesa_lookup_shader_program_err(ctx, program,
230*61046927SAndroid Build Coastguard Worker                                       "glGetProgramResourceName");
231*61046927SAndroid Build Coastguard Worker 
232*61046927SAndroid Build Coastguard Worker    if (!shProg || !name)
233*61046927SAndroid Build Coastguard Worker       return;
234*61046927SAndroid Build Coastguard Worker 
235*61046927SAndroid Build Coastguard Worker    if (programInterface == GL_ATOMIC_COUNTER_BUFFER ||
236*61046927SAndroid Build Coastguard Worker        programInterface == GL_TRANSFORM_FEEDBACK_BUFFER ||
237*61046927SAndroid Build Coastguard Worker        !supported_interface_enum(ctx, programInterface)) {
238*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramResourceName(%s)",
239*61046927SAndroid Build Coastguard Worker                   _mesa_enum_to_string(programInterface));
240*61046927SAndroid Build Coastguard Worker       return;
241*61046927SAndroid Build Coastguard Worker    }
242*61046927SAndroid Build Coastguard Worker 
243*61046927SAndroid Build Coastguard Worker    _mesa_get_program_resource_name(shProg, programInterface, index, bufSize,
244*61046927SAndroid Build Coastguard Worker                                    length, name, false,
245*61046927SAndroid Build Coastguard Worker                                    "glGetProgramResourceName");
246*61046927SAndroid Build Coastguard Worker }
247*61046927SAndroid Build Coastguard Worker 
248*61046927SAndroid Build Coastguard Worker void GLAPIENTRY
_mesa_GetProgramResourceiv(GLuint program,GLenum programInterface,GLuint index,GLsizei propCount,const GLenum * props,GLsizei bufSize,GLsizei * length,GLint * params)249*61046927SAndroid Build Coastguard Worker _mesa_GetProgramResourceiv(GLuint program, GLenum programInterface,
250*61046927SAndroid Build Coastguard Worker                            GLuint index, GLsizei propCount,
251*61046927SAndroid Build Coastguard Worker                            const GLenum *props, GLsizei bufSize,
252*61046927SAndroid Build Coastguard Worker                            GLsizei *length, GLint *params)
253*61046927SAndroid Build Coastguard Worker {
254*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
255*61046927SAndroid Build Coastguard Worker 
256*61046927SAndroid Build Coastguard Worker    if (MESA_VERBOSE & VERBOSE_API) {
257*61046927SAndroid Build Coastguard Worker       _mesa_debug(ctx, "glGetProgramResourceiv(%u, %s, %u, %d, %p, %d, %p, %p)\n",
258*61046927SAndroid Build Coastguard Worker                   program, _mesa_enum_to_string(programInterface), index,
259*61046927SAndroid Build Coastguard Worker                   propCount, props, bufSize, length, params);
260*61046927SAndroid Build Coastguard Worker    }
261*61046927SAndroid Build Coastguard Worker 
262*61046927SAndroid Build Coastguard Worker    struct gl_shader_program *shProg =
263*61046927SAndroid Build Coastguard Worker       _mesa_lookup_shader_program_err(ctx, program, "glGetProgramResourceiv");
264*61046927SAndroid Build Coastguard Worker 
265*61046927SAndroid Build Coastguard Worker    if (!shProg || !params)
266*61046927SAndroid Build Coastguard Worker       return;
267*61046927SAndroid Build Coastguard Worker 
268*61046927SAndroid Build Coastguard Worker    /* The error INVALID_VALUE is generated if <propCount> is zero.
269*61046927SAndroid Build Coastguard Worker     * Note that we check < 0 here because it makes sense to bail early.
270*61046927SAndroid Build Coastguard Worker     */
271*61046927SAndroid Build Coastguard Worker    if (propCount <= 0) {
272*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_VALUE,
273*61046927SAndroid Build Coastguard Worker                   "glGetProgramResourceiv(propCount <= 0)");
274*61046927SAndroid Build Coastguard Worker       return;
275*61046927SAndroid Build Coastguard Worker    }
276*61046927SAndroid Build Coastguard Worker 
277*61046927SAndroid Build Coastguard Worker    _mesa_get_program_resourceiv(shProg, programInterface, index,
278*61046927SAndroid Build Coastguard Worker                                 propCount, props, bufSize, length, params);
279*61046927SAndroid Build Coastguard Worker }
280*61046927SAndroid Build Coastguard Worker 
281*61046927SAndroid Build Coastguard Worker GLint GLAPIENTRY
_mesa_GetProgramResourceLocation(GLuint program,GLenum programInterface,const GLchar * name)282*61046927SAndroid Build Coastguard Worker _mesa_GetProgramResourceLocation(GLuint program, GLenum programInterface,
283*61046927SAndroid Build Coastguard Worker                                  const GLchar *name)
284*61046927SAndroid Build Coastguard Worker {
285*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
286*61046927SAndroid Build Coastguard Worker 
287*61046927SAndroid Build Coastguard Worker    if (MESA_VERBOSE & VERBOSE_API) {
288*61046927SAndroid Build Coastguard Worker       _mesa_debug(ctx, "glGetProgramResourceLocation(%u, %s, %s)\n",
289*61046927SAndroid Build Coastguard Worker                   program, _mesa_enum_to_string(programInterface), name);
290*61046927SAndroid Build Coastguard Worker    }
291*61046927SAndroid Build Coastguard Worker 
292*61046927SAndroid Build Coastguard Worker    struct gl_shader_program *shProg =
293*61046927SAndroid Build Coastguard Worker       lookup_linked_program(program, "glGetProgramResourceLocation");
294*61046927SAndroid Build Coastguard Worker 
295*61046927SAndroid Build Coastguard Worker    if (!shProg || !name)
296*61046927SAndroid Build Coastguard Worker       return -1;
297*61046927SAndroid Build Coastguard Worker 
298*61046927SAndroid Build Coastguard Worker    /* Validate programInterface. */
299*61046927SAndroid Build Coastguard Worker    switch (programInterface) {
300*61046927SAndroid Build Coastguard Worker    case GL_UNIFORM:
301*61046927SAndroid Build Coastguard Worker    case GL_PROGRAM_INPUT:
302*61046927SAndroid Build Coastguard Worker    case GL_PROGRAM_OUTPUT:
303*61046927SAndroid Build Coastguard Worker       break;
304*61046927SAndroid Build Coastguard Worker 
305*61046927SAndroid Build Coastguard Worker    case GL_VERTEX_SUBROUTINE_UNIFORM:
306*61046927SAndroid Build Coastguard Worker    case GL_FRAGMENT_SUBROUTINE_UNIFORM:
307*61046927SAndroid Build Coastguard Worker       if (!_mesa_has_ARB_shader_subroutine(ctx))
308*61046927SAndroid Build Coastguard Worker          goto fail;
309*61046927SAndroid Build Coastguard Worker       break;
310*61046927SAndroid Build Coastguard Worker    case GL_GEOMETRY_SUBROUTINE_UNIFORM:
311*61046927SAndroid Build Coastguard Worker       if (!_mesa_has_geometry_shaders(ctx) || !_mesa_has_ARB_shader_subroutine(ctx))
312*61046927SAndroid Build Coastguard Worker          goto fail;
313*61046927SAndroid Build Coastguard Worker       break;
314*61046927SAndroid Build Coastguard Worker    case GL_COMPUTE_SUBROUTINE_UNIFORM:
315*61046927SAndroid Build Coastguard Worker       if (!_mesa_has_compute_shaders(ctx) || !_mesa_has_ARB_shader_subroutine(ctx))
316*61046927SAndroid Build Coastguard Worker          goto fail;
317*61046927SAndroid Build Coastguard Worker       break;
318*61046927SAndroid Build Coastguard Worker    case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
319*61046927SAndroid Build Coastguard Worker    case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
320*61046927SAndroid Build Coastguard Worker       if (!_mesa_has_tessellation(ctx) || !_mesa_has_ARB_shader_subroutine(ctx))
321*61046927SAndroid Build Coastguard Worker          goto fail;
322*61046927SAndroid Build Coastguard Worker       break;
323*61046927SAndroid Build Coastguard Worker    default:
324*61046927SAndroid Build Coastguard Worker          goto fail;
325*61046927SAndroid Build Coastguard Worker    }
326*61046927SAndroid Build Coastguard Worker 
327*61046927SAndroid Build Coastguard Worker    return _mesa_program_resource_location(shProg, programInterface, name);
328*61046927SAndroid Build Coastguard Worker fail:
329*61046927SAndroid Build Coastguard Worker    _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramResourceLocation(%s %s)",
330*61046927SAndroid Build Coastguard Worker                _mesa_enum_to_string(programInterface), name);
331*61046927SAndroid Build Coastguard Worker    return -1;
332*61046927SAndroid Build Coastguard Worker }
333*61046927SAndroid Build Coastguard Worker 
334*61046927SAndroid Build Coastguard Worker /**
335*61046927SAndroid Build Coastguard Worker  * Returns output index for dual source blending.
336*61046927SAndroid Build Coastguard Worker  */
337*61046927SAndroid Build Coastguard Worker GLint GLAPIENTRY
_mesa_GetProgramResourceLocationIndex(GLuint program,GLenum programInterface,const GLchar * name)338*61046927SAndroid Build Coastguard Worker _mesa_GetProgramResourceLocationIndex(GLuint program, GLenum programInterface,
339*61046927SAndroid Build Coastguard Worker                                       const GLchar *name)
340*61046927SAndroid Build Coastguard Worker {
341*61046927SAndroid Build Coastguard Worker    GET_CURRENT_CONTEXT(ctx);
342*61046927SAndroid Build Coastguard Worker 
343*61046927SAndroid Build Coastguard Worker    if (MESA_VERBOSE & VERBOSE_API) {
344*61046927SAndroid Build Coastguard Worker       _mesa_debug(ctx, "glGetProgramResourceLocationIndex(%u, %s, %s)\n",
345*61046927SAndroid Build Coastguard Worker                   program, _mesa_enum_to_string(programInterface), name);
346*61046927SAndroid Build Coastguard Worker    }
347*61046927SAndroid Build Coastguard Worker 
348*61046927SAndroid Build Coastguard Worker    struct gl_shader_program *shProg =
349*61046927SAndroid Build Coastguard Worker       lookup_linked_program(program, "glGetProgramResourceLocationIndex");
350*61046927SAndroid Build Coastguard Worker 
351*61046927SAndroid Build Coastguard Worker    if (!shProg || !name)
352*61046927SAndroid Build Coastguard Worker       return -1;
353*61046927SAndroid Build Coastguard Worker 
354*61046927SAndroid Build Coastguard Worker    /* From the GL_ARB_program_interface_query spec:
355*61046927SAndroid Build Coastguard Worker     *
356*61046927SAndroid Build Coastguard Worker     * "For GetProgramResourceLocationIndex, <programInterface> must be
357*61046927SAndroid Build Coastguard Worker     * PROGRAM_OUTPUT."
358*61046927SAndroid Build Coastguard Worker     */
359*61046927SAndroid Build Coastguard Worker    if (programInterface != GL_PROGRAM_OUTPUT) {
360*61046927SAndroid Build Coastguard Worker       _mesa_error(ctx, GL_INVALID_ENUM,
361*61046927SAndroid Build Coastguard Worker                   "glGetProgramResourceLocationIndex(%s)",
362*61046927SAndroid Build Coastguard Worker                   _mesa_enum_to_string(programInterface));
363*61046927SAndroid Build Coastguard Worker       return -1;
364*61046927SAndroid Build Coastguard Worker    }
365*61046927SAndroid Build Coastguard Worker 
366*61046927SAndroid Build Coastguard Worker    return _mesa_program_resource_location_index(shProg, GL_PROGRAM_OUTPUT,
367*61046927SAndroid Build Coastguard Worker                                                 name);
368*61046927SAndroid Build Coastguard Worker }
369