2 * Mesa 3-D graphics library
4 * Copyright (C) 2015 Intel Corporation. All Rights Reserved.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
26 #include "main/enums.h"
27 #include "main/macros.h"
28 #include "main/mtypes.h"
29 #include "main/shaderapi.h"
30 #include "main/shaderobj.h"
31 #include "program_resource.h"
34 supported_interface_enum(GLenum iface
)
38 case GL_UNIFORM_BLOCK
:
39 case GL_PROGRAM_INPUT
:
40 case GL_PROGRAM_OUTPUT
:
41 case GL_TRANSFORM_FEEDBACK_VARYING
:
42 case GL_ATOMIC_COUNTER_BUFFER
:
44 case GL_VERTEX_SUBROUTINE
:
45 case GL_TESS_CONTROL_SUBROUTINE
:
46 case GL_TESS_EVALUATION_SUBROUTINE
:
47 case GL_GEOMETRY_SUBROUTINE
:
48 case GL_FRAGMENT_SUBROUTINE
:
49 case GL_COMPUTE_SUBROUTINE
:
50 case GL_VERTEX_SUBROUTINE_UNIFORM
:
51 case GL_TESS_CONTROL_SUBROUTINE_UNIFORM
:
52 case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM
:
53 case GL_GEOMETRY_SUBROUTINE_UNIFORM
:
54 case GL_FRAGMENT_SUBROUTINE_UNIFORM
:
55 case GL_COMPUTE_SUBROUTINE_UNIFORM
:
56 case GL_BUFFER_VARIABLE
:
57 case GL_SHADER_STORAGE_BLOCK
:
64 _mesa_GetProgramInterfaceiv(GLuint program
, GLenum programInterface
,
65 GLenum pname
, GLint
*params
)
67 GET_CURRENT_CONTEXT(ctx
);
69 struct gl_shader_program
*shProg
=
70 _mesa_lookup_shader_program_err(ctx
, program
,
71 "glGetProgramInterfaceiv");
76 _mesa_error(ctx
, GL_INVALID_OPERATION
,
77 "glGetProgramInterfaceiv(params NULL)");
81 /* Validate interface. */
82 if (!supported_interface_enum(programInterface
)) {
83 _mesa_error(ctx
, GL_INVALID_OPERATION
, "glGetProgramInterfaceiv(%s)",
84 _mesa_lookup_enum_by_nr(programInterface
));
88 /* Validate pname against interface. */
90 case GL_ACTIVE_RESOURCES
:
91 for (i
= 0, *params
= 0; i
< shProg
->NumProgramResourceList
; i
++)
92 if (shProg
->ProgramResourceList
[i
].Type
== programInterface
)
95 case GL_MAX_NAME_LENGTH
:
96 if (programInterface
== GL_ATOMIC_COUNTER_BUFFER
) {
97 _mesa_error(ctx
, GL_INVALID_OPERATION
,
98 "glGetProgramInterfaceiv(%s pname %s)",
99 _mesa_lookup_enum_by_nr(programInterface
),
100 _mesa_lookup_enum_by_nr(pname
));
103 /* Name length consists of base name, 3 additional chars '[0]' if
104 * resource is an array and finally 1 char for string terminator.
106 for (i
= 0, *params
= 0; i
< shProg
->NumProgramResourceList
; i
++) {
107 if (shProg
->ProgramResourceList
[i
].Type
!= programInterface
)
110 _mesa_program_resource_name(&shProg
->ProgramResourceList
[i
]);
111 unsigned array_size
=
112 _mesa_program_resource_array_size(&shProg
->ProgramResourceList
[i
]);
113 *params
= MAX2(*params
, strlen(name
) + (array_size
? 3 : 0) + 1);
116 case GL_MAX_NUM_ACTIVE_VARIABLES
:
117 switch (programInterface
) {
118 case GL_UNIFORM_BLOCK
:
119 for (i
= 0, *params
= 0; i
< shProg
->NumProgramResourceList
; i
++) {
120 if (shProg
->ProgramResourceList
[i
].Type
== programInterface
) {
121 struct gl_uniform_block
*block
=
122 (struct gl_uniform_block
*)
123 shProg
->ProgramResourceList
[i
].Data
;
124 *params
= MAX2(*params
, block
->NumUniforms
);
128 case GL_ATOMIC_COUNTER_BUFFER
:
129 for (i
= 0, *params
= 0; i
< shProg
->NumProgramResourceList
; i
++) {
130 if (shProg
->ProgramResourceList
[i
].Type
== programInterface
) {
131 struct gl_active_atomic_buffer
*buffer
=
132 (struct gl_active_atomic_buffer
*)
133 shProg
->ProgramResourceList
[i
].Data
;
134 *params
= MAX2(*params
, buffer
->NumUniforms
);
139 _mesa_error(ctx
, GL_INVALID_OPERATION
,
140 "glGetProgramInterfaceiv(%s pname %s)",
141 _mesa_lookup_enum_by_nr(programInterface
),
142 _mesa_lookup_enum_by_nr(pname
));
145 case GL_MAX_NUM_COMPATIBLE_SUBROUTINES
:
147 _mesa_error(ctx
, GL_INVALID_OPERATION
,
148 "glGetProgramInterfaceiv(pname %s)",
149 _mesa_lookup_enum_by_nr(pname
));
154 is_xfb_marker(const char *str
)
156 static const char *markers
[] = {
158 "gl_SkipComponents1",
159 "gl_SkipComponents2",
160 "gl_SkipComponents3",
161 "gl_SkipComponents4",
164 const char **m
= markers
;
166 if (strncmp(str
, "gl_", 3) != 0)
170 if (strcmp(*m
, str
) == 0)
177 * Checks if given name index is legal for GetProgramResourceIndex,
178 * check is written to be compatible with GL_ARB_array_of_arrays.
181 valid_program_resource_index_name(const GLchar
*name
)
183 const char *array
= strstr(name
, "[");
184 const char *close
= strrchr(name
, ']');
186 /* Not array, no need for the check. */
190 /* Last array index has to be zero. */
191 if (!close
|| *--close
!= '0')
198 _mesa_GetProgramResourceIndex(GLuint program
, GLenum programInterface
,
201 GET_CURRENT_CONTEXT(ctx
);
202 struct gl_program_resource
*res
;
203 struct gl_shader_program
*shProg
=
204 _mesa_lookup_shader_program_err(ctx
, program
,
205 "glGetProgramResourceIndex");
206 if (!shProg
|| !name
)
207 return GL_INVALID_INDEX
;
210 * For the interface TRANSFORM_FEEDBACK_VARYING, the value INVALID_INDEX
211 * should be returned when querying the index assigned to the special names
212 * "gl_NextBuffer", "gl_SkipComponents1", "gl_SkipComponents2",
213 * "gl_SkipComponents3", and "gl_SkipComponents4".
215 if (programInterface
== GL_TRANSFORM_FEEDBACK_VARYING
&&
217 return GL_INVALID_INDEX
;
219 switch (programInterface
) {
220 case GL_PROGRAM_INPUT
:
221 case GL_PROGRAM_OUTPUT
:
223 case GL_UNIFORM_BLOCK
:
224 case GL_TRANSFORM_FEEDBACK_VARYING
:
225 /* Validate name syntax for arrays. */
226 if (!valid_program_resource_index_name(name
))
227 return GL_INVALID_INDEX
;
229 res
= _mesa_program_resource_find_name(shProg
, programInterface
, name
);
231 return GL_INVALID_INDEX
;
233 return _mesa_program_resource_index(shProg
, res
);
234 case GL_ATOMIC_COUNTER_BUFFER
:
236 _mesa_error(ctx
, GL_INVALID_ENUM
, "glGetProgramResourceIndex(%s)",
237 _mesa_lookup_enum_by_nr(programInterface
));
240 return GL_INVALID_INDEX
;
244 _mesa_GetProgramResourceName(GLuint program
, GLenum programInterface
,
245 GLuint index
, GLsizei bufSize
, GLsizei
*length
,
251 _mesa_GetProgramResourceiv(GLuint program
, GLenum programInterface
,
252 GLuint index
, GLsizei propCount
,
253 const GLenum
*props
, GLsizei bufSize
,
254 GLsizei
*length
, GLint
*params
)
259 _mesa_GetProgramResourceLocation(GLuint program
, GLenum programInterface
,
266 _mesa_GetProgramResourceLocationIndex(GLuint program
, GLenum programInterface
,