mesa/sso: rename Shader to the pointer _Shader
[mesa.git] / src / mesa / main / uniforms.c
1 /*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 2004-2008 Brian Paul All Rights Reserved.
5 * Copyright (C) 2009-2010 VMware, Inc. All Rights Reserved.
6 * Copyright © 2010 Intel Corporation
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
22 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 * OTHER DEALINGS IN THE SOFTWARE.
25 */
26
27 /**
28 * \file uniforms.c
29 * Functions related to GLSL uniform variables.
30 * \author Brian Paul
31 */
32
33 /**
34 * XXX things to do:
35 * 1. Check that the right error code is generated for all _mesa_error() calls.
36 * 2. Insert FLUSH_VERTICES calls in various places
37 */
38
39 #include "main/glheader.h"
40 #include "main/context.h"
41 #include "main/dispatch.h"
42 #include "main/shaderapi.h"
43 #include "main/shaderobj.h"
44 #include "main/uniforms.h"
45 #include "main/enums.h"
46 #include "ir_uniform.h"
47 #include "glsl_types.h"
48 #include "program/program.h"
49
50 /**
51 * Update the vertex/fragment program's TexturesUsed array.
52 *
53 * This needs to be called after glUniform(set sampler var) is called.
54 * A call to glUniform(samplerVar, value) causes a sampler to point to a
55 * particular texture unit. We know the sampler's texture target
56 * (1D/2D/3D/etc) from compile time but the sampler's texture unit is
57 * set by glUniform() calls.
58 *
59 * So, scan the program->SamplerUnits[] and program->SamplerTargets[]
60 * information to update the prog->TexturesUsed[] values.
61 * Each value of TexturesUsed[unit] is one of zero, TEXTURE_1D_INDEX,
62 * TEXTURE_2D_INDEX, TEXTURE_3D_INDEX, etc.
63 * We'll use that info for state validation before rendering.
64 */
65 void
66 _mesa_update_shader_textures_used(struct gl_shader_program *shProg,
67 struct gl_program *prog)
68 {
69 GLuint s;
70 struct gl_shader *shader =
71 shProg->_LinkedShaders[_mesa_program_enum_to_shader_stage(prog->Target)];
72
73 assert(shader);
74
75 memcpy(prog->SamplerUnits, shader->SamplerUnits, sizeof(prog->SamplerUnits));
76 memset(prog->TexturesUsed, 0, sizeof(prog->TexturesUsed));
77
78 for (s = 0; s < MAX_SAMPLERS; s++) {
79 if (prog->SamplersUsed & (1 << s)) {
80 GLuint unit = shader->SamplerUnits[s];
81 GLuint tgt = shader->SamplerTargets[s];
82 assert(unit < Elements(prog->TexturesUsed));
83 assert(tgt < NUM_TEXTURE_TARGETS);
84 prog->TexturesUsed[unit] |= (1 << tgt);
85 }
86 }
87 }
88
89 /**
90 * Connect a piece of driver storage with a part of a uniform
91 *
92 * \param uni The uniform with which the storage will be associated
93 * \param element_stride Byte-stride between array elements.
94 * \sa gl_uniform_driver_storage::element_stride.
95 * \param vector_stride Byte-stride between vectors (in a matrix).
96 * \sa gl_uniform_driver_storage::vector_stride.
97 * \param format Conversion from native format to driver format
98 * required by the driver.
99 * \param data Location to dump the data.
100 */
101 void
102 _mesa_uniform_attach_driver_storage(struct gl_uniform_storage *uni,
103 unsigned element_stride,
104 unsigned vector_stride,
105 enum gl_uniform_driver_format format,
106 void *data)
107 {
108 uni->driver_storage =
109 realloc(uni->driver_storage,
110 sizeof(struct gl_uniform_driver_storage)
111 * (uni->num_driver_storage + 1));
112
113 uni->driver_storage[uni->num_driver_storage].element_stride = element_stride;
114 uni->driver_storage[uni->num_driver_storage].vector_stride = vector_stride;
115 uni->driver_storage[uni->num_driver_storage].format = (uint8_t) format;
116 uni->driver_storage[uni->num_driver_storage].data = data;
117
118 uni->num_driver_storage++;
119 }
120
121 /**
122 * Sever all connections with all pieces of driver storage for all uniforms
123 *
124 * \warning
125 * This function does \b not release any of the \c data pointers
126 * previously passed in to \c _mesa_uniform_attach_driver_stoarge.
127 */
128 void
129 _mesa_uniform_detach_all_driver_storage(struct gl_uniform_storage *uni)
130 {
131 free(uni->driver_storage);
132 uni->driver_storage = NULL;
133 uni->num_driver_storage = 0;
134 }
135
136 void GLAPIENTRY
137 _mesa_Uniform1f(GLint location, GLfloat v0)
138 {
139 GET_CURRENT_CONTEXT(ctx);
140 _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, 1, &v0, GL_FLOAT);
141 }
142
143 void GLAPIENTRY
144 _mesa_Uniform2f(GLint location, GLfloat v0, GLfloat v1)
145 {
146 GET_CURRENT_CONTEXT(ctx);
147 GLfloat v[2];
148 v[0] = v0;
149 v[1] = v1;
150 _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, 1, v, GL_FLOAT_VEC2);
151 }
152
153 void GLAPIENTRY
154 _mesa_Uniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
155 {
156 GET_CURRENT_CONTEXT(ctx);
157 GLfloat v[3];
158 v[0] = v0;
159 v[1] = v1;
160 v[2] = v2;
161 _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, 1, v, GL_FLOAT_VEC3);
162 }
163
164 void GLAPIENTRY
165 _mesa_Uniform4f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2,
166 GLfloat v3)
167 {
168 GET_CURRENT_CONTEXT(ctx);
169 GLfloat v[4];
170 v[0] = v0;
171 v[1] = v1;
172 v[2] = v2;
173 v[3] = v3;
174 _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, 1, v, GL_FLOAT_VEC4);
175 }
176
177 void GLAPIENTRY
178 _mesa_Uniform1i(GLint location, GLint v0)
179 {
180 GET_CURRENT_CONTEXT(ctx);
181 _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, 1, &v0, GL_INT);
182 }
183
184 void GLAPIENTRY
185 _mesa_Uniform2i(GLint location, GLint v0, GLint v1)
186 {
187 GET_CURRENT_CONTEXT(ctx);
188 GLint v[2];
189 v[0] = v0;
190 v[1] = v1;
191 _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, 1, v, GL_INT_VEC2);
192 }
193
194 void GLAPIENTRY
195 _mesa_Uniform3i(GLint location, GLint v0, GLint v1, GLint v2)
196 {
197 GET_CURRENT_CONTEXT(ctx);
198 GLint v[3];
199 v[0] = v0;
200 v[1] = v1;
201 v[2] = v2;
202 _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, 1, v, GL_INT_VEC3);
203 }
204
205 void GLAPIENTRY
206 _mesa_Uniform4i(GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
207 {
208 GET_CURRENT_CONTEXT(ctx);
209 GLint v[4];
210 v[0] = v0;
211 v[1] = v1;
212 v[2] = v2;
213 v[3] = v3;
214 _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, 1, v, GL_INT_VEC4);
215 }
216
217 void GLAPIENTRY
218 _mesa_Uniform1fv(GLint location, GLsizei count, const GLfloat * value)
219 {
220 GET_CURRENT_CONTEXT(ctx);
221 _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, count, value, GL_FLOAT);
222 }
223
224 void GLAPIENTRY
225 _mesa_Uniform2fv(GLint location, GLsizei count, const GLfloat * value)
226 {
227 GET_CURRENT_CONTEXT(ctx);
228 _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, count, value, GL_FLOAT_VEC2);
229 }
230
231 void GLAPIENTRY
232 _mesa_Uniform3fv(GLint location, GLsizei count, const GLfloat * value)
233 {
234 GET_CURRENT_CONTEXT(ctx);
235 _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, count, value, GL_FLOAT_VEC3);
236 }
237
238 void GLAPIENTRY
239 _mesa_Uniform4fv(GLint location, GLsizei count, const GLfloat * value)
240 {
241 GET_CURRENT_CONTEXT(ctx);
242 _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, count, value, GL_FLOAT_VEC4);
243 }
244
245 void GLAPIENTRY
246 _mesa_Uniform1iv(GLint location, GLsizei count, const GLint * value)
247 {
248 GET_CURRENT_CONTEXT(ctx);
249 _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, count, value, GL_INT);
250 }
251
252 void GLAPIENTRY
253 _mesa_Uniform2iv(GLint location, GLsizei count, const GLint * value)
254 {
255 GET_CURRENT_CONTEXT(ctx);
256 _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, count, value, GL_INT_VEC2);
257 }
258
259 void GLAPIENTRY
260 _mesa_Uniform3iv(GLint location, GLsizei count, const GLint * value)
261 {
262 GET_CURRENT_CONTEXT(ctx);
263 _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, count, value, GL_INT_VEC3);
264 }
265
266 void GLAPIENTRY
267 _mesa_Uniform4iv(GLint location, GLsizei count, const GLint * value)
268 {
269 GET_CURRENT_CONTEXT(ctx);
270 _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, count, value, GL_INT_VEC4);
271 }
272
273 /** Same as above with direct state access **/
274 void GLAPIENTRY
275 _mesa_ProgramUniform1f(GLuint program, GLint location, GLfloat v0)
276 {
277 GET_CURRENT_CONTEXT(ctx);
278 struct gl_shader_program *shProg =
279 _mesa_lookup_shader_program_err(ctx, program,
280 "glProgramUniform1f");
281 _mesa_uniform(ctx, shProg, location, 1, &v0, GL_FLOAT);
282 }
283
284 void GLAPIENTRY
285 _mesa_ProgramUniform2f(GLuint program, GLint location, GLfloat v0, GLfloat v1)
286 {
287 GET_CURRENT_CONTEXT(ctx);
288 GLfloat v[2];
289 struct gl_shader_program *shProg;
290 v[0] = v0;
291 v[1] = v1;
292 shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramUniform2f");
293 _mesa_uniform(ctx, shProg, location, 1, v, GL_FLOAT_VEC2);
294 }
295
296 void GLAPIENTRY
297 _mesa_ProgramUniform3f(GLuint program, GLint location, GLfloat v0, GLfloat v1,
298 GLfloat v2)
299 {
300 GET_CURRENT_CONTEXT(ctx);
301 GLfloat v[3];
302 struct gl_shader_program *shProg;
303 v[0] = v0;
304 v[1] = v1;
305 v[2] = v2;
306 shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramUniform3f");
307 _mesa_uniform(ctx, shProg, location, 1, v, GL_FLOAT_VEC3);
308 }
309
310 void GLAPIENTRY
311 _mesa_ProgramUniform4f(GLuint program, GLint location, GLfloat v0, GLfloat v1,
312 GLfloat v2, GLfloat v3)
313 {
314 GET_CURRENT_CONTEXT(ctx);
315 GLfloat v[4];
316 struct gl_shader_program *shProg;
317 v[0] = v0;
318 v[1] = v1;
319 v[2] = v2;
320 v[3] = v3;
321 shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramUniform4f");
322 _mesa_uniform(ctx, shProg, location, 1, v, GL_FLOAT_VEC4);
323 }
324
325 void GLAPIENTRY
326 _mesa_ProgramUniform1i(GLuint program, GLint location, GLint v0)
327 {
328 GET_CURRENT_CONTEXT(ctx);
329 struct gl_shader_program *shProg =
330 _mesa_lookup_shader_program_err(ctx, program,
331 "glProgramUniform1i");
332 _mesa_uniform(ctx, shProg, location, 1, &v0, GL_INT);
333 }
334
335 void GLAPIENTRY
336 _mesa_ProgramUniform2i(GLuint program, GLint location, GLint v0, GLint v1)
337 {
338 GET_CURRENT_CONTEXT(ctx);
339 GLint v[2];
340 struct gl_shader_program *shProg;
341 v[0] = v0;
342 v[1] = v1;
343 shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramUniform2i");
344 _mesa_uniform(ctx, shProg, location, 1, v, GL_INT_VEC2);
345 }
346
347 void GLAPIENTRY
348 _mesa_ProgramUniform3i(GLuint program, GLint location, GLint v0, GLint v1,
349 GLint v2)
350 {
351 GET_CURRENT_CONTEXT(ctx);
352 GLint v[3];
353 struct gl_shader_program *shProg;
354 v[0] = v0;
355 v[1] = v1;
356 v[2] = v2;
357 shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramUniform3i");
358 _mesa_uniform(ctx, shProg, location, 1, v, GL_INT_VEC3);
359 }
360
361 void GLAPIENTRY
362 _mesa_ProgramUniform4i(GLuint program, GLint location, GLint v0, GLint v1,
363 GLint v2, GLint v3)
364 {
365 GET_CURRENT_CONTEXT(ctx);
366 GLint v[4];
367 struct gl_shader_program *shProg;
368 v[0] = v0;
369 v[1] = v1;
370 v[2] = v2;
371 v[3] = v3;
372 shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramUniform4i");
373 _mesa_uniform(ctx, shProg, location, 1, v, GL_INT_VEC4);
374 }
375
376 void GLAPIENTRY
377 _mesa_ProgramUniform1fv(GLuint program, GLint location, GLsizei count,
378 const GLfloat * value)
379 {
380 GET_CURRENT_CONTEXT(ctx);
381 struct gl_shader_program *shProg =
382 _mesa_lookup_shader_program_err(ctx, program,
383 "glProgramUniform1fv");
384 _mesa_uniform(ctx, shProg, location, count, value, GL_FLOAT);
385 }
386
387 void GLAPIENTRY
388 _mesa_ProgramUniform2fv(GLuint program, GLint location, GLsizei count,
389 const GLfloat * value)
390 {
391 GET_CURRENT_CONTEXT(ctx);
392 struct gl_shader_program *shProg =
393 _mesa_lookup_shader_program_err(ctx, program,
394 "glProgramUniform2fv");
395 _mesa_uniform(ctx, shProg, location, count, value, GL_FLOAT_VEC2);
396 }
397
398 void GLAPIENTRY
399 _mesa_ProgramUniform3fv(GLuint program, GLint location, GLsizei count,
400 const GLfloat * value)
401 {
402 GET_CURRENT_CONTEXT(ctx);
403 struct gl_shader_program *shProg =
404 _mesa_lookup_shader_program_err(ctx, program,
405 "glProgramUniform3fv");
406 _mesa_uniform(ctx, shProg, location, count, value, GL_FLOAT_VEC3);
407 }
408
409 void GLAPIENTRY
410 _mesa_ProgramUniform4fv(GLuint program, GLint location, GLsizei count,
411 const GLfloat * value)
412 {
413 GET_CURRENT_CONTEXT(ctx);
414 struct gl_shader_program *shProg =
415 _mesa_lookup_shader_program_err(ctx, program,
416 "glProgramUniform4fv");
417 _mesa_uniform(ctx, shProg, location, count, value, GL_FLOAT_VEC4);
418 }
419
420 void GLAPIENTRY
421 _mesa_ProgramUniform1iv(GLuint program, GLint location, GLsizei count,
422 const GLint * value)
423 {
424 GET_CURRENT_CONTEXT(ctx);
425 struct gl_shader_program *shProg =
426 _mesa_lookup_shader_program_err(ctx, program,
427 "glProgramUniform1iv");
428 _mesa_uniform(ctx, shProg, location, count, value, GL_INT);
429 }
430
431 void GLAPIENTRY
432 _mesa_ProgramUniform2iv(GLuint program, GLint location, GLsizei count,
433 const GLint * value)
434 {
435 GET_CURRENT_CONTEXT(ctx);
436 struct gl_shader_program *shProg =
437 _mesa_lookup_shader_program_err(ctx, program,
438 "glProgramUniform2iv");
439 _mesa_uniform(ctx, shProg, location, count, value, GL_INT_VEC2);
440 }
441
442 void GLAPIENTRY
443 _mesa_ProgramUniform3iv(GLuint program, GLint location, GLsizei count,
444 const GLint * value)
445 {
446 GET_CURRENT_CONTEXT(ctx);
447 struct gl_shader_program *shProg =
448 _mesa_lookup_shader_program_err(ctx, program,
449 "glProgramUniform3iv");
450 _mesa_uniform(ctx, shProg, location, count, value, GL_INT_VEC3);
451 }
452
453 void GLAPIENTRY
454 _mesa_ProgramUniform4iv(GLuint program, GLint location, GLsizei count,
455 const GLint * value)
456 {
457 GET_CURRENT_CONTEXT(ctx);
458 struct gl_shader_program *shProg =
459 _mesa_lookup_shader_program_err(ctx, program,
460 "glProgramUniform4iv");
461 _mesa_uniform(ctx, shProg, location, count, value, GL_INT_VEC4);
462 }
463
464
465 /** OpenGL 3.0 GLuint-valued functions **/
466 void GLAPIENTRY
467 _mesa_Uniform1ui(GLint location, GLuint v0)
468 {
469 GET_CURRENT_CONTEXT(ctx);
470 _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, 1, &v0, GL_UNSIGNED_INT);
471 }
472
473 void GLAPIENTRY
474 _mesa_Uniform2ui(GLint location, GLuint v0, GLuint v1)
475 {
476 GET_CURRENT_CONTEXT(ctx);
477 GLuint v[2];
478 v[0] = v0;
479 v[1] = v1;
480 _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, 1, v, GL_UNSIGNED_INT_VEC2);
481 }
482
483 void GLAPIENTRY
484 _mesa_Uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)
485 {
486 GET_CURRENT_CONTEXT(ctx);
487 GLuint v[3];
488 v[0] = v0;
489 v[1] = v1;
490 v[2] = v2;
491 _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, 1, v, GL_UNSIGNED_INT_VEC3);
492 }
493
494 void GLAPIENTRY
495 _mesa_Uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
496 {
497 GET_CURRENT_CONTEXT(ctx);
498 GLuint v[4];
499 v[0] = v0;
500 v[1] = v1;
501 v[2] = v2;
502 v[3] = v3;
503 _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, 1, v, GL_UNSIGNED_INT_VEC4);
504 }
505
506 void GLAPIENTRY
507 _mesa_Uniform1uiv(GLint location, GLsizei count, const GLuint *value)
508 {
509 GET_CURRENT_CONTEXT(ctx);
510 _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, count, value, GL_UNSIGNED_INT);
511 }
512
513 void GLAPIENTRY
514 _mesa_Uniform2uiv(GLint location, GLsizei count, const GLuint *value)
515 {
516 GET_CURRENT_CONTEXT(ctx);
517 _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, count, value, GL_UNSIGNED_INT_VEC2);
518 }
519
520 void GLAPIENTRY
521 _mesa_Uniform3uiv(GLint location, GLsizei count, const GLuint *value)
522 {
523 GET_CURRENT_CONTEXT(ctx);
524 _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, count, value, GL_UNSIGNED_INT_VEC3);
525 }
526
527 void GLAPIENTRY
528 _mesa_Uniform4uiv(GLint location, GLsizei count, const GLuint *value)
529 {
530 GET_CURRENT_CONTEXT(ctx);
531 _mesa_uniform(ctx, ctx->_Shader->ActiveProgram, location, count, value, GL_UNSIGNED_INT_VEC4);
532 }
533
534
535
536 void GLAPIENTRY
537 _mesa_UniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose,
538 const GLfloat * value)
539 {
540 GET_CURRENT_CONTEXT(ctx);
541 _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
542 2, 2, location, count, transpose, value);
543 }
544
545 void GLAPIENTRY
546 _mesa_UniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose,
547 const GLfloat * value)
548 {
549 GET_CURRENT_CONTEXT(ctx);
550 _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
551 3, 3, location, count, transpose, value);
552 }
553
554 void GLAPIENTRY
555 _mesa_UniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose,
556 const GLfloat * value)
557 {
558 GET_CURRENT_CONTEXT(ctx);
559 _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
560 4, 4, location, count, transpose, value);
561 }
562
563 /** Same as above with direct state access **/
564
565 void GLAPIENTRY
566 _mesa_ProgramUniform1ui(GLuint program, GLint location, GLuint v0)
567 {
568 GET_CURRENT_CONTEXT(ctx);
569 struct gl_shader_program *shProg =
570 _mesa_lookup_shader_program_err(ctx, program,
571 "glProgramUniform1ui");
572 _mesa_uniform(ctx, shProg, location, 1, &v0, GL_UNSIGNED_INT);
573 }
574
575 void GLAPIENTRY
576 _mesa_ProgramUniform2ui(GLuint program, GLint location, GLuint v0, GLuint v1)
577 {
578 GET_CURRENT_CONTEXT(ctx);
579 GLuint v[2];
580 struct gl_shader_program *shProg;
581 v[0] = v0;
582 v[1] = v1;
583 shProg = _mesa_lookup_shader_program_err(ctx, program,
584 "glProgramUniform2ui");
585 _mesa_uniform(ctx, shProg, location, 1, v, GL_UNSIGNED_INT_VEC2);
586 }
587
588 void GLAPIENTRY
589 _mesa_ProgramUniform3ui(GLuint program, GLint location, GLuint v0, GLuint v1,
590 GLuint v2)
591 {
592 GET_CURRENT_CONTEXT(ctx);
593 GLuint v[3];
594 struct gl_shader_program *shProg;
595 v[0] = v0;
596 v[1] = v1;
597 v[2] = v2;
598 shProg = _mesa_lookup_shader_program_err(ctx, program,
599 "glProgramUniform3ui");
600 _mesa_uniform(ctx, shProg, location, 1, v, GL_UNSIGNED_INT_VEC3);
601 }
602
603 void GLAPIENTRY
604 _mesa_ProgramUniform4ui(GLuint program, GLint location, GLuint v0, GLuint v1,
605 GLuint v2, GLuint v3)
606 {
607 GET_CURRENT_CONTEXT(ctx);
608 GLuint v[4];
609 struct gl_shader_program *shProg;
610 v[0] = v0;
611 v[1] = v1;
612 v[2] = v2;
613 v[3] = v3;
614 shProg = _mesa_lookup_shader_program_err(ctx, program, "glProgramUniform4ui");
615 _mesa_uniform(ctx, shProg, location, 1, v, GL_UNSIGNED_INT_VEC4);
616 }
617
618 void GLAPIENTRY
619 _mesa_ProgramUniform1uiv(GLuint program, GLint location, GLsizei count,
620 const GLuint *value)
621 {
622 GET_CURRENT_CONTEXT(ctx);
623 struct gl_shader_program *shProg =
624 _mesa_lookup_shader_program_err(ctx, program,
625 "glProgramUniform1uiv");
626 _mesa_uniform(ctx, shProg, location, count, value, GL_UNSIGNED_INT);
627 }
628
629 void GLAPIENTRY
630 _mesa_ProgramUniform2uiv(GLuint program, GLint location, GLsizei count,
631 const GLuint *value)
632 {
633 GET_CURRENT_CONTEXT(ctx);
634 struct gl_shader_program *shProg =
635 _mesa_lookup_shader_program_err(ctx, program,
636 "glProgramUniform2uiv");
637 _mesa_uniform(ctx, shProg, location, count, value, GL_UNSIGNED_INT_VEC2);
638 }
639
640 void GLAPIENTRY
641 _mesa_ProgramUniform3uiv(GLuint program, GLint location, GLsizei count,
642 const GLuint *value)
643 {
644 GET_CURRENT_CONTEXT(ctx);
645 struct gl_shader_program *shProg =
646 _mesa_lookup_shader_program_err(ctx, program,
647 "glProgramUniform3uiv");
648 _mesa_uniform(ctx, shProg, location, count, value, GL_UNSIGNED_INT_VEC3);
649 }
650
651 void GLAPIENTRY
652 _mesa_ProgramUniform4uiv(GLuint program, GLint location, GLsizei count,
653 const GLuint *value)
654 {
655 GET_CURRENT_CONTEXT(ctx);
656 struct gl_shader_program *shProg =
657 _mesa_lookup_shader_program_err(ctx, program,
658 "glProgramUniform4uiv");
659 _mesa_uniform(ctx, shProg, location, count, value, GL_UNSIGNED_INT_VEC4);
660 }
661
662
663
664 void GLAPIENTRY
665 _mesa_ProgramUniformMatrix2fv(GLuint program, GLint location, GLsizei count,
666 GLboolean transpose, const GLfloat * value)
667 {
668 GET_CURRENT_CONTEXT(ctx);
669 struct gl_shader_program *shProg =
670 _mesa_lookup_shader_program_err(ctx, program,
671 "glProgramUniformMatrix2fv");
672 _mesa_uniform_matrix(ctx, shProg, 2, 2, location, count, transpose, value);
673 }
674
675 void GLAPIENTRY
676 _mesa_ProgramUniformMatrix3fv(GLuint program, GLint location, GLsizei count,
677 GLboolean transpose, const GLfloat * value)
678 {
679 GET_CURRENT_CONTEXT(ctx);
680 struct gl_shader_program *shProg =
681 _mesa_lookup_shader_program_err(ctx, program,
682 "glProgramUniformMatrix3fv");
683 _mesa_uniform_matrix(ctx, shProg, 3, 3, location, count, transpose, value);
684 }
685
686 void GLAPIENTRY
687 _mesa_ProgramUniformMatrix4fv(GLuint program, GLint location, GLsizei count,
688 GLboolean transpose, const GLfloat * value)
689 {
690 GET_CURRENT_CONTEXT(ctx);
691 struct gl_shader_program *shProg =
692 _mesa_lookup_shader_program_err(ctx, program,
693 "glProgramUniformMatrix4fv");
694 _mesa_uniform_matrix(ctx, shProg, 4, 4, location, count, transpose, value);
695 }
696
697
698 /**
699 * Non-square UniformMatrix are OpenGL 2.1
700 */
701 void GLAPIENTRY
702 _mesa_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose,
703 const GLfloat *value)
704 {
705 GET_CURRENT_CONTEXT(ctx);
706 _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
707 2, 3, location, count, transpose, value);
708 }
709
710 void GLAPIENTRY
711 _mesa_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose,
712 const GLfloat *value)
713 {
714 GET_CURRENT_CONTEXT(ctx);
715 _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
716 3, 2, location, count, transpose, value);
717 }
718
719 void GLAPIENTRY
720 _mesa_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose,
721 const GLfloat *value)
722 {
723 GET_CURRENT_CONTEXT(ctx);
724 _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
725 2, 4, location, count, transpose, value);
726 }
727
728 void GLAPIENTRY
729 _mesa_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose,
730 const GLfloat *value)
731 {
732 GET_CURRENT_CONTEXT(ctx);
733 _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
734 4, 2, location, count, transpose, value);
735 }
736
737 void GLAPIENTRY
738 _mesa_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose,
739 const GLfloat *value)
740 {
741 GET_CURRENT_CONTEXT(ctx);
742 _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
743 3, 4, location, count, transpose, value);
744 }
745
746 void GLAPIENTRY
747 _mesa_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose,
748 const GLfloat *value)
749 {
750 GET_CURRENT_CONTEXT(ctx);
751 _mesa_uniform_matrix(ctx, ctx->_Shader->ActiveProgram,
752 4, 3, location, count, transpose, value);
753 }
754
755 /** Same as above with direct state access **/
756
757 void GLAPIENTRY
758 _mesa_ProgramUniformMatrix2x3fv(GLuint program, GLint location, GLsizei count,
759 GLboolean transpose, const GLfloat * value)
760 {
761 GET_CURRENT_CONTEXT(ctx);
762 struct gl_shader_program *shProg =
763 _mesa_lookup_shader_program_err(ctx, program,
764 "glProgramUniformMatrix2x3fv");
765 _mesa_uniform_matrix(ctx, shProg, 2, 3, location, count, transpose, value);
766 }
767
768 void GLAPIENTRY
769 _mesa_ProgramUniformMatrix3x2fv(GLuint program, GLint location, GLsizei count,
770 GLboolean transpose, const GLfloat * value)
771 {
772 GET_CURRENT_CONTEXT(ctx);
773 struct gl_shader_program *shProg =
774 _mesa_lookup_shader_program_err(ctx, program,
775 "glProgramUniformMatrix3x2fv");
776 _mesa_uniform_matrix(ctx, shProg, 3, 2, location, count, transpose, value);
777 }
778
779 void GLAPIENTRY
780 _mesa_ProgramUniformMatrix2x4fv(GLuint program, GLint location, GLsizei count,
781 GLboolean transpose, const GLfloat * value)
782 {
783 GET_CURRENT_CONTEXT(ctx);
784 struct gl_shader_program *shProg =
785 _mesa_lookup_shader_program_err(ctx, program,
786 "glProgramUniformMatrix2x4fv");
787 _mesa_uniform_matrix(ctx, shProg, 2, 4, location, count, transpose, value);
788 }
789
790 void GLAPIENTRY
791 _mesa_ProgramUniformMatrix4x2fv(GLuint program, GLint location, GLsizei count,
792 GLboolean transpose, const GLfloat * value)
793 {
794 GET_CURRENT_CONTEXT(ctx);
795 struct gl_shader_program *shProg =
796 _mesa_lookup_shader_program_err(ctx, program,
797 "glProgramUniformMatrix4x2fv");
798 _mesa_uniform_matrix(ctx, shProg, 4, 2, location, count, transpose, value);
799 }
800
801 void GLAPIENTRY
802 _mesa_ProgramUniformMatrix3x4fv(GLuint program, GLint location, GLsizei count,
803 GLboolean transpose, const GLfloat * value)
804 {
805 GET_CURRENT_CONTEXT(ctx);
806 struct gl_shader_program *shProg =
807 _mesa_lookup_shader_program_err(ctx, program,
808 "glProgramUniformMatrix3x4fv");
809 _mesa_uniform_matrix(ctx, shProg, 3, 4, location, count, transpose, value);
810 }
811
812 void GLAPIENTRY
813 _mesa_ProgramUniformMatrix4x3fv(GLuint program, GLint location, GLsizei count,
814 GLboolean transpose, const GLfloat * value)
815 {
816 GET_CURRENT_CONTEXT(ctx);
817 struct gl_shader_program *shProg =
818 _mesa_lookup_shader_program_err(ctx, program,
819 "glProgramUniformMatrix4x3fv");
820 _mesa_uniform_matrix(ctx, shProg, 4, 3, location, count, transpose, value);
821 }
822
823
824 void GLAPIENTRY
825 _mesa_GetnUniformfvARB(GLuint program, GLint location,
826 GLsizei bufSize, GLfloat *params)
827 {
828 GET_CURRENT_CONTEXT(ctx);
829 _mesa_get_uniform(ctx, program, location, bufSize, GLSL_TYPE_FLOAT, params);
830 }
831
832 void GLAPIENTRY
833 _mesa_GetUniformfv(GLuint program, GLint location, GLfloat *params)
834 {
835 _mesa_GetnUniformfvARB(program, location, INT_MAX, params);
836 }
837
838
839 void GLAPIENTRY
840 _mesa_GetnUniformivARB(GLuint program, GLint location,
841 GLsizei bufSize, GLint *params)
842 {
843 GET_CURRENT_CONTEXT(ctx);
844 _mesa_get_uniform(ctx, program, location, bufSize, GLSL_TYPE_INT, params);
845 }
846
847 void GLAPIENTRY
848 _mesa_GetUniformiv(GLuint program, GLint location, GLint *params)
849 {
850 _mesa_GetnUniformivARB(program, location, INT_MAX, params);
851 }
852
853
854 /* GL3 */
855 void GLAPIENTRY
856 _mesa_GetnUniformuivARB(GLuint program, GLint location,
857 GLsizei bufSize, GLuint *params)
858 {
859 GET_CURRENT_CONTEXT(ctx);
860 _mesa_get_uniform(ctx, program, location, bufSize, GLSL_TYPE_UINT, params);
861 }
862
863 void GLAPIENTRY
864 _mesa_GetUniformuiv(GLuint program, GLint location, GLuint *params)
865 {
866 _mesa_GetnUniformuivARB(program, location, INT_MAX, params);
867 }
868
869
870 /* GL4 */
871 void GLAPIENTRY
872 _mesa_GetnUniformdvARB(GLuint program, GLint location,
873 GLsizei bufSize, GLdouble *params)
874 {
875 GET_CURRENT_CONTEXT(ctx);
876
877 (void) program;
878 (void) location;
879 (void) bufSize;
880 (void) params;
881
882 /*
883 _mesa_get_uniform(ctx, program, location, bufSize, GLSL_TYPE_DOUBLE, params);
884 */
885 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformdvARB"
886 "(GL_ARB_gpu_shader_fp64 not implemented)");
887 }
888
889 void GLAPIENTRY
890 _mesa_GetUniformdv(GLuint program, GLint location, GLdouble *params)
891 {
892 _mesa_GetnUniformdvARB(program, location, INT_MAX, params);
893 }
894
895
896 GLint GLAPIENTRY
897 _mesa_GetUniformLocation(GLuint programObj, const GLcharARB *name)
898 {
899 struct gl_shader_program *shProg;
900 GLuint index, offset;
901
902 GET_CURRENT_CONTEXT(ctx);
903
904 shProg = _mesa_lookup_shader_program_err(ctx, programObj,
905 "glGetUniformLocation");
906 if (!shProg)
907 return -1;
908
909 /* Page 80 (page 94 of the PDF) of the OpenGL 2.1 spec says:
910 *
911 * "If program has not been successfully linked, the error
912 * INVALID_OPERATION is generated."
913 */
914 if (shProg->LinkStatus == GL_FALSE) {
915 _mesa_error(ctx, GL_INVALID_OPERATION,
916 "glGetUniformLocation(program not linked)");
917 return -1;
918 }
919
920 index = _mesa_get_uniform_location(ctx, shProg, name, &offset);
921 if (index == GL_INVALID_INDEX)
922 return -1;
923
924 /* From the GL_ARB_uniform_buffer_object spec:
925 *
926 * "The value -1 will be returned if <name> does not correspond to an
927 * active uniform variable name in <program>, if <name> is associated
928 * with a named uniform block, or if <name> starts with the reserved
929 * prefix "gl_"."
930 */
931 if (shProg->UniformStorage[index].block_index != -1 ||
932 shProg->UniformStorage[index].atomic_buffer_index != -1)
933 return -1;
934
935 return _mesa_uniform_merge_location_offset(shProg, index, offset);
936 }
937
938 GLuint GLAPIENTRY
939 _mesa_GetUniformBlockIndex(GLuint program,
940 const GLchar *uniformBlockName)
941 {
942 GET_CURRENT_CONTEXT(ctx);
943 GLuint i;
944 struct gl_shader_program *shProg;
945
946 if (!ctx->Extensions.ARB_uniform_buffer_object) {
947 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformBlockIndex");
948 return GL_INVALID_INDEX;
949 }
950
951 shProg = _mesa_lookup_shader_program_err(ctx, program,
952 "glGetUniformBlockIndex");
953 if (!shProg)
954 return GL_INVALID_INDEX;
955
956 for (i = 0; i < shProg->NumUniformBlocks; i++) {
957 if (!strcmp(shProg->UniformBlocks[i].Name, uniformBlockName))
958 return i;
959 }
960
961 return GL_INVALID_INDEX;
962 }
963
964 void GLAPIENTRY
965 _mesa_GetUniformIndices(GLuint program,
966 GLsizei uniformCount,
967 const GLchar * const *uniformNames,
968 GLuint *uniformIndices)
969 {
970 GET_CURRENT_CONTEXT(ctx);
971 GLsizei i;
972 struct gl_shader_program *shProg;
973
974 if (!ctx->Extensions.ARB_uniform_buffer_object) {
975 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformIndices");
976 return;
977 }
978
979 shProg = _mesa_lookup_shader_program_err(ctx, program,
980 "glGetUniformIndices");
981 if (!shProg)
982 return;
983
984 if (uniformCount < 0) {
985 _mesa_error(ctx, GL_INVALID_VALUE,
986 "glGetUniformIndices(uniformCount < 0)");
987 return;
988 }
989
990 for (i = 0; i < uniformCount; i++) {
991 unsigned offset;
992 uniformIndices[i] = _mesa_get_uniform_location(ctx, shProg,
993 uniformNames[i], &offset);
994 }
995 }
996
997 void GLAPIENTRY
998 _mesa_UniformBlockBinding(GLuint program,
999 GLuint uniformBlockIndex,
1000 GLuint uniformBlockBinding)
1001 {
1002 GET_CURRENT_CONTEXT(ctx);
1003 struct gl_shader_program *shProg;
1004
1005 if (!ctx->Extensions.ARB_uniform_buffer_object) {
1006 _mesa_error(ctx, GL_INVALID_OPERATION, "glUniformBlockBinding");
1007 return;
1008 }
1009
1010 shProg = _mesa_lookup_shader_program_err(ctx, program,
1011 "glUniformBlockBinding");
1012 if (!shProg)
1013 return;
1014
1015 if (uniformBlockIndex >= shProg->NumUniformBlocks) {
1016 _mesa_error(ctx, GL_INVALID_VALUE,
1017 "glUniformBlockBinding(block index %u >= %u)",
1018 uniformBlockIndex, shProg->NumUniformBlocks);
1019 return;
1020 }
1021
1022 if (uniformBlockBinding >= ctx->Const.MaxUniformBufferBindings) {
1023 _mesa_error(ctx, GL_INVALID_VALUE,
1024 "glUniformBlockBinding(block binding %u >= %u)",
1025 uniformBlockBinding, ctx->Const.MaxUniformBufferBindings);
1026 return;
1027 }
1028
1029 if (shProg->UniformBlocks[uniformBlockIndex].Binding !=
1030 uniformBlockBinding) {
1031 int i;
1032
1033 FLUSH_VERTICES(ctx, 0);
1034 ctx->NewDriverState |= ctx->DriverFlags.NewUniformBuffer;
1035
1036 shProg->UniformBlocks[uniformBlockIndex].Binding = uniformBlockBinding;
1037
1038 for (i = 0; i < MESA_SHADER_STAGES; i++) {
1039 int stage_index = shProg->UniformBlockStageIndex[i][uniformBlockIndex];
1040
1041 if (stage_index != -1) {
1042 struct gl_shader *sh = shProg->_LinkedShaders[i];
1043 sh->UniformBlocks[stage_index].Binding = uniformBlockBinding;
1044 }
1045 }
1046 }
1047 }
1048
1049 void GLAPIENTRY
1050 _mesa_GetActiveUniformBlockiv(GLuint program,
1051 GLuint uniformBlockIndex,
1052 GLenum pname,
1053 GLint *params)
1054 {
1055 GET_CURRENT_CONTEXT(ctx);
1056 struct gl_shader_program *shProg;
1057 struct gl_uniform_block *block;
1058 unsigned i;
1059
1060 if (!ctx->Extensions.ARB_uniform_buffer_object) {
1061 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetActiveUniformBlockiv");
1062 return;
1063 }
1064
1065 shProg = _mesa_lookup_shader_program_err(ctx, program,
1066 "glGetActiveUniformBlockiv");
1067 if (!shProg)
1068 return;
1069
1070 if (uniformBlockIndex >= shProg->NumUniformBlocks) {
1071 _mesa_error(ctx, GL_INVALID_VALUE,
1072 "glGetActiveUniformBlockiv(block index %u >= %u)",
1073 uniformBlockIndex, shProg->NumUniformBlocks);
1074 return;
1075 }
1076
1077 block = &shProg->UniformBlocks[uniformBlockIndex];
1078
1079 switch (pname) {
1080 case GL_UNIFORM_BLOCK_BINDING:
1081 params[0] = block->Binding;
1082 return;
1083
1084 case GL_UNIFORM_BLOCK_DATA_SIZE:
1085 params[0] = block->UniformBufferSize;
1086 return;
1087
1088 case GL_UNIFORM_BLOCK_NAME_LENGTH:
1089 params[0] = strlen(block->Name) + 1;
1090 return;
1091
1092 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
1093 params[0] = block->NumUniforms;
1094 return;
1095
1096 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
1097 for (i = 0; i < block->NumUniforms; i++) {
1098 unsigned offset;
1099 params[i] = _mesa_get_uniform_location(ctx, shProg,
1100 block->Uniforms[i].IndexName,
1101 &offset);
1102 }
1103 return;
1104
1105 case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
1106 params[0] = shProg->UniformBlockStageIndex[MESA_SHADER_VERTEX][uniformBlockIndex] != -1;
1107 return;
1108
1109 case GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER:
1110 params[0] = shProg->UniformBlockStageIndex[MESA_SHADER_GEOMETRY][uniformBlockIndex] != -1;
1111 return;
1112
1113 case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
1114 params[0] = shProg->UniformBlockStageIndex[MESA_SHADER_FRAGMENT][uniformBlockIndex] != -1;
1115 return;
1116
1117 default:
1118 _mesa_error(ctx, GL_INVALID_ENUM,
1119 "glGetActiveUniformBlockiv(pname 0x%x (%s))",
1120 pname, _mesa_lookup_enum_by_nr(pname));
1121 return;
1122 }
1123 }
1124
1125 void GLAPIENTRY
1126 _mesa_GetActiveUniformBlockName(GLuint program,
1127 GLuint uniformBlockIndex,
1128 GLsizei bufSize,
1129 GLsizei *length,
1130 GLchar *uniformBlockName)
1131 {
1132 GET_CURRENT_CONTEXT(ctx);
1133 struct gl_shader_program *shProg;
1134 struct gl_uniform_block *block;
1135
1136 if (!ctx->Extensions.ARB_uniform_buffer_object) {
1137 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetActiveUniformBlockiv");
1138 return;
1139 }
1140
1141 if (bufSize < 0) {
1142 _mesa_error(ctx, GL_INVALID_VALUE,
1143 "glGetActiveUniformBlockName(bufSize %d < 0)",
1144 bufSize);
1145 return;
1146 }
1147
1148 shProg = _mesa_lookup_shader_program_err(ctx, program,
1149 "glGetActiveUniformBlockiv");
1150 if (!shProg)
1151 return;
1152
1153 if (uniformBlockIndex >= shProg->NumUniformBlocks) {
1154 _mesa_error(ctx, GL_INVALID_VALUE,
1155 "glGetActiveUniformBlockiv(block index %u >= %u)",
1156 uniformBlockIndex, shProg->NumUniformBlocks);
1157 return;
1158 }
1159
1160 block = &shProg->UniformBlocks[uniformBlockIndex];
1161
1162 if (uniformBlockName) {
1163 _mesa_copy_string(uniformBlockName, bufSize, length, block->Name);
1164 }
1165 }
1166
1167 void GLAPIENTRY
1168 _mesa_GetActiveUniformName(GLuint program, GLuint uniformIndex,
1169 GLsizei bufSize, GLsizei *length,
1170 GLchar *uniformName)
1171 {
1172 GET_CURRENT_CONTEXT(ctx);
1173 struct gl_shader_program *shProg;
1174
1175 if (!ctx->Extensions.ARB_uniform_buffer_object) {
1176 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetActiveUniformBlockiv");
1177 return;
1178 }
1179
1180 if (bufSize < 0) {
1181 _mesa_error(ctx, GL_INVALID_VALUE,
1182 "glGetActiveUniformName(bufSize %d < 0)",
1183 bufSize);
1184 return;
1185 }
1186
1187 shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniformName");
1188
1189 if (!shProg)
1190 return;
1191
1192 if (uniformIndex >= shProg->NumUserUniformStorage) {
1193 _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(index)");
1194 return;
1195 }
1196
1197 if (uniformName) {
1198 _mesa_get_uniform_name(& shProg->UniformStorage[uniformIndex],
1199 bufSize, length, uniformName);
1200 }
1201 }
1202
1203 void
1204 _mesa_get_uniform_name(const struct gl_uniform_storage *uni,
1205 GLsizei maxLength, GLsizei *length,
1206 GLchar *nameOut)
1207 {
1208 GLsizei localLength;
1209
1210 if (length == NULL)
1211 length = &localLength;
1212
1213 _mesa_copy_string(nameOut, maxLength, length, uni->name);
1214
1215 /* Page 61 (page 73 of the PDF) in section 2.11 of the OpenGL ES 3.0
1216 * spec says:
1217 *
1218 * "If the active uniform is an array, the uniform name returned in
1219 * name will always be the name of the uniform array appended with
1220 * "[0]"."
1221 *
1222 * The same text also appears in the OpenGL 4.2 spec. It does not,
1223 * however, appear in any previous spec. Previous specifications are
1224 * ambiguous in this regard. However, either name can later be passed
1225 * to glGetUniformLocation (and related APIs), so there shouldn't be any
1226 * harm in always appending "[0]" to uniform array names.
1227 */
1228 if (uni->array_elements != 0) {
1229 int i;
1230
1231 /* The comparison is strange because *length does *NOT* include the
1232 * terminating NUL, but maxLength does.
1233 */
1234 for (i = 0; i < 3 && (*length + i + 1) < maxLength; i++)
1235 nameOut[*length + i] = "[0]"[i];
1236
1237 nameOut[*length + i] = '\0';
1238 *length += i;
1239 }
1240 }
1241
1242 void GLAPIENTRY
1243 _mesa_GetActiveAtomicCounterBufferiv(GLuint program, GLuint bufferIndex,
1244 GLenum pname, GLint *params)
1245 {
1246 GET_CURRENT_CONTEXT(ctx);
1247 struct gl_shader_program *shProg;
1248 struct gl_active_atomic_buffer *ab;
1249 GLuint i;
1250
1251 if (!ctx->Extensions.ARB_shader_atomic_counters) {
1252 _mesa_error(ctx, GL_INVALID_OPERATION,
1253 "glGetActiveAtomicCounterBufferiv");
1254 return;
1255 }
1256
1257 shProg = _mesa_lookup_shader_program_err(ctx, program,
1258 "glGetActiveAtomicCounterBufferiv");
1259 if (!shProg)
1260 return;
1261
1262 if (bufferIndex >= shProg->NumAtomicBuffers) {
1263 _mesa_error(ctx, GL_INVALID_VALUE,
1264 "glGetActiveAtomicCounterBufferiv(bufferIndex)");
1265 return;
1266 }
1267
1268 ab = &shProg->AtomicBuffers[bufferIndex];
1269
1270 switch (pname) {
1271 case GL_ATOMIC_COUNTER_BUFFER_BINDING:
1272 params[0] = ab->Binding;
1273 return;
1274 case GL_ATOMIC_COUNTER_BUFFER_DATA_SIZE:
1275 params[0] = ab->MinimumSize;
1276 return;
1277 case GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTERS:
1278 params[0] = ab->NumUniforms;
1279 return;
1280 case GL_ATOMIC_COUNTER_BUFFER_ACTIVE_ATOMIC_COUNTER_INDICES:
1281 for (i = 0; i < ab->NumUniforms; ++i)
1282 params[i] = ab->Uniforms[i];
1283 return;
1284 case GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_VERTEX_SHADER:
1285 params[0] = ab->StageReferences[MESA_SHADER_VERTEX];
1286 return;
1287 case GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_GEOMETRY_SHADER:
1288 params[0] = ab->StageReferences[MESA_SHADER_GEOMETRY];
1289 return;
1290 case GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_FRAGMENT_SHADER:
1291 params[0] = ab->StageReferences[MESA_SHADER_FRAGMENT];
1292 return;
1293 case GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_CONTROL_SHADER:
1294 params[0] = GL_FALSE;
1295 return;
1296 case GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_TESS_EVALUATION_SHADER:
1297 params[0] = GL_FALSE;
1298 return;
1299 default:
1300 _mesa_error(ctx, GL_INVALID_ENUM,
1301 "glGetActiveAtomicCounterBufferiv(pname 0x%x (%s))",
1302 pname, _mesa_lookup_enum_by_nr(pname));
1303 return;
1304 }
1305 }