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 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26 /**
27 * \file uniforms.c
28 * Functions related to GLSL uniform variables.
29 * \author Brian Paul
30 */
31
32 /**
33 * XXX things to do:
34 * 1. Check that the right error code is generated for all _mesa_error() calls.
35 * 2. Insert FLUSH_VERTICES calls in various places
36 */
37
38 #include "main/glheader.h"
39 #include "main/context.h"
40 #include "main/dispatch.h"
41 #include "main/shaderapi.h"
42 #include "main/shaderobj.h"
43 #include "main/uniforms.h"
44 #include "main/enums.h"
45 #include "ir_uniform.h"
46 #include "glsl_types.h"
47
48 /**
49 * Update the vertex/fragment program's TexturesUsed array.
50 *
51 * This needs to be called after glUniform(set sampler var) is called.
52 * A call to glUniform(samplerVar, value) causes a sampler to point to a
53 * particular texture unit. We know the sampler's texture target
54 * (1D/2D/3D/etc) from compile time but the sampler's texture unit is
55 * set by glUniform() calls.
56 *
57 * So, scan the program->SamplerUnits[] and program->SamplerTargets[]
58 * information to update the prog->TexturesUsed[] values.
59 * Each value of TexturesUsed[unit] is one of zero, TEXTURE_1D_INDEX,
60 * TEXTURE_2D_INDEX, TEXTURE_3D_INDEX, etc.
61 * We'll use that info for state validation before rendering.
62 */
63 void
_mesa_update_shader_textures_used(struct gl_shader_program * shProg,struct gl_program * prog)64 _mesa_update_shader_textures_used(struct gl_shader_program *shProg,
65 struct gl_program *prog)
66 {
67 GLuint s;
68
69 memcpy(prog->SamplerUnits, shProg->SamplerUnits, sizeof(prog->SamplerUnits));
70 memset(prog->TexturesUsed, 0, sizeof(prog->TexturesUsed));
71
72 for (s = 0; s < MAX_SAMPLERS; s++) {
73 if (prog->SamplersUsed & (1 << s)) {
74 GLuint unit = shProg->SamplerUnits[s];
75 GLuint tgt = shProg->SamplerTargets[s];
76 assert(unit < Elements(prog->TexturesUsed));
77 assert(tgt < NUM_TEXTURE_TARGETS);
78 prog->TexturesUsed[unit] |= (1 << tgt);
79 }
80 }
81 }
82
83 /**
84 * Connect a piece of driver storage with a part of a uniform
85 *
86 * \param uni The uniform with which the storage will be associated
87 * \param element_stride Byte-stride between array elements.
88 * \sa gl_uniform_driver_storage::element_stride.
89 * \param vector_stride Byte-stride between vectors (in a matrix).
90 * \sa gl_uniform_driver_storage::vector_stride.
91 * \param format Conversion from native format to driver format
92 * required by the driver.
93 * \param data Location to dump the data.
94 */
95 void
_mesa_uniform_attach_driver_storage(struct gl_uniform_storage * uni,unsigned element_stride,unsigned vector_stride,enum gl_uniform_driver_format format,void * data)96 _mesa_uniform_attach_driver_storage(struct gl_uniform_storage *uni,
97 unsigned element_stride,
98 unsigned vector_stride,
99 enum gl_uniform_driver_format format,
100 void *data)
101 {
102 uni->driver_storage = (struct gl_uniform_driver_storage*)
103 realloc(uni->driver_storage,
104 sizeof(struct gl_uniform_driver_storage)
105 * (uni->num_driver_storage + 1));
106
107 uni->driver_storage[uni->num_driver_storage].element_stride = element_stride;
108 uni->driver_storage[uni->num_driver_storage].vector_stride = vector_stride;
109 uni->driver_storage[uni->num_driver_storage].format = (uint8_t) format;
110 uni->driver_storage[uni->num_driver_storage].data = data;
111
112 uni->num_driver_storage++;
113 }
114
115 /**
116 * Sever all connections with all pieces of driver storage for all uniforms
117 *
118 * \warning
119 * This function does \b not release any of the \c data pointers
120 * previously passed in to \c _mesa_uniform_attach_driver_stoarge.
121 */
122 void
_mesa_uniform_detach_all_driver_storage(struct gl_uniform_storage * uni)123 _mesa_uniform_detach_all_driver_storage(struct gl_uniform_storage *uni)
124 {
125 free(uni->driver_storage);
126 uni->driver_storage = NULL;
127 uni->num_driver_storage = 0;
128 }
129
130 void GLAPIENTRY
_mesa_Uniform1fARB(GLint location,GLfloat v0)131 _mesa_Uniform1fARB(GLint location, GLfloat v0)
132 {
133 GET_CURRENT_CONTEXT(ctx);
134 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, &v0, GL_FLOAT);
135 }
136
137 void GLAPIENTRY
_mesa_Uniform2fARB(GLint location,GLfloat v0,GLfloat v1)138 _mesa_Uniform2fARB(GLint location, GLfloat v0, GLfloat v1)
139 {
140 GET_CURRENT_CONTEXT(ctx);
141 GLfloat v[2];
142 v[0] = v0;
143 v[1] = v1;
144 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_FLOAT_VEC2);
145 }
146
147 void GLAPIENTRY
_mesa_Uniform3fARB(GLint location,GLfloat v0,GLfloat v1,GLfloat v2)148 _mesa_Uniform3fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
149 {
150 GET_CURRENT_CONTEXT(ctx);
151 GLfloat v[3];
152 v[0] = v0;
153 v[1] = v1;
154 v[2] = v2;
155 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_FLOAT_VEC3);
156 }
157
158 void GLAPIENTRY
_mesa_Uniform4fARB(GLint location,GLfloat v0,GLfloat v1,GLfloat v2,GLfloat v3)159 _mesa_Uniform4fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2,
160 GLfloat v3)
161 {
162 GET_CURRENT_CONTEXT(ctx);
163 GLfloat v[4];
164 v[0] = v0;
165 v[1] = v1;
166 v[2] = v2;
167 v[3] = v3;
168 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_FLOAT_VEC4);
169 }
170
171 void GLAPIENTRY
_mesa_Uniform1iARB(GLint location,GLint v0)172 _mesa_Uniform1iARB(GLint location, GLint v0)
173 {
174 GET_CURRENT_CONTEXT(ctx);
175 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, &v0, GL_INT);
176 }
177
178 void GLAPIENTRY
_mesa_Uniform2iARB(GLint location,GLint v0,GLint v1)179 _mesa_Uniform2iARB(GLint location, GLint v0, GLint v1)
180 {
181 GET_CURRENT_CONTEXT(ctx);
182 GLint v[2];
183 v[0] = v0;
184 v[1] = v1;
185 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_INT_VEC2);
186 }
187
188 void GLAPIENTRY
_mesa_Uniform3iARB(GLint location,GLint v0,GLint v1,GLint v2)189 _mesa_Uniform3iARB(GLint location, GLint v0, GLint v1, GLint v2)
190 {
191 GET_CURRENT_CONTEXT(ctx);
192 GLint v[3];
193 v[0] = v0;
194 v[1] = v1;
195 v[2] = v2;
196 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_INT_VEC3);
197 }
198
199 void GLAPIENTRY
_mesa_Uniform4iARB(GLint location,GLint v0,GLint v1,GLint v2,GLint v3)200 _mesa_Uniform4iARB(GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
201 {
202 GET_CURRENT_CONTEXT(ctx);
203 GLint v[4];
204 v[0] = v0;
205 v[1] = v1;
206 v[2] = v2;
207 v[3] = v3;
208 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_INT_VEC4);
209 }
210
211 void GLAPIENTRY
_mesa_Uniform1fvARB(GLint location,GLsizei count,const GLfloat * value)212 _mesa_Uniform1fvARB(GLint location, GLsizei count, const GLfloat * value)
213 {
214 GET_CURRENT_CONTEXT(ctx);
215 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_FLOAT);
216 }
217
218 void GLAPIENTRY
_mesa_Uniform2fvARB(GLint location,GLsizei count,const GLfloat * value)219 _mesa_Uniform2fvARB(GLint location, GLsizei count, const GLfloat * value)
220 {
221 GET_CURRENT_CONTEXT(ctx);
222 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_FLOAT_VEC2);
223 }
224
225 void GLAPIENTRY
_mesa_Uniform3fvARB(GLint location,GLsizei count,const GLfloat * value)226 _mesa_Uniform3fvARB(GLint location, GLsizei count, const GLfloat * value)
227 {
228 GET_CURRENT_CONTEXT(ctx);
229 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_FLOAT_VEC3);
230 }
231
232 void GLAPIENTRY
_mesa_Uniform4fvARB(GLint location,GLsizei count,const GLfloat * value)233 _mesa_Uniform4fvARB(GLint location, GLsizei count, const GLfloat * value)
234 {
235 GET_CURRENT_CONTEXT(ctx);
236 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_FLOAT_VEC4);
237 }
238
239 void GLAPIENTRY
_mesa_Uniform1ivARB(GLint location,GLsizei count,const GLint * value)240 _mesa_Uniform1ivARB(GLint location, GLsizei count, const GLint * value)
241 {
242 GET_CURRENT_CONTEXT(ctx);
243 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_INT);
244 }
245
246 void GLAPIENTRY
_mesa_Uniform2ivARB(GLint location,GLsizei count,const GLint * value)247 _mesa_Uniform2ivARB(GLint location, GLsizei count, const GLint * value)
248 {
249 GET_CURRENT_CONTEXT(ctx);
250 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_INT_VEC2);
251 }
252
253 void GLAPIENTRY
_mesa_Uniform3ivARB(GLint location,GLsizei count,const GLint * value)254 _mesa_Uniform3ivARB(GLint location, GLsizei count, const GLint * value)
255 {
256 GET_CURRENT_CONTEXT(ctx);
257 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_INT_VEC3);
258 }
259
260 void GLAPIENTRY
_mesa_Uniform4ivARB(GLint location,GLsizei count,const GLint * value)261 _mesa_Uniform4ivARB(GLint location, GLsizei count, const GLint * value)
262 {
263 GET_CURRENT_CONTEXT(ctx);
264 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_INT_VEC4);
265 }
266
267
268 /** OpenGL 3.0 GLuint-valued functions **/
269 void GLAPIENTRY
_mesa_Uniform1ui(GLint location,GLuint v0)270 _mesa_Uniform1ui(GLint location, GLuint v0)
271 {
272 GET_CURRENT_CONTEXT(ctx);
273 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, &v0, GL_UNSIGNED_INT);
274 }
275
276 void GLAPIENTRY
_mesa_Uniform2ui(GLint location,GLuint v0,GLuint v1)277 _mesa_Uniform2ui(GLint location, GLuint v0, GLuint v1)
278 {
279 GET_CURRENT_CONTEXT(ctx);
280 GLuint v[2];
281 v[0] = v0;
282 v[1] = v1;
283 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_UNSIGNED_INT_VEC2);
284 }
285
286 void GLAPIENTRY
_mesa_Uniform3ui(GLint location,GLuint v0,GLuint v1,GLuint v2)287 _mesa_Uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)
288 {
289 GET_CURRENT_CONTEXT(ctx);
290 GLuint v[3];
291 v[0] = v0;
292 v[1] = v1;
293 v[2] = v2;
294 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_UNSIGNED_INT_VEC3);
295 }
296
297 void GLAPIENTRY
_mesa_Uniform4ui(GLint location,GLuint v0,GLuint v1,GLuint v2,GLuint v3)298 _mesa_Uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
299 {
300 GET_CURRENT_CONTEXT(ctx);
301 GLuint v[4];
302 v[0] = v0;
303 v[1] = v1;
304 v[2] = v2;
305 v[3] = v3;
306 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_UNSIGNED_INT_VEC4);
307 }
308
309 void GLAPIENTRY
_mesa_Uniform1uiv(GLint location,GLsizei count,const GLuint * value)310 _mesa_Uniform1uiv(GLint location, GLsizei count, const GLuint *value)
311 {
312 GET_CURRENT_CONTEXT(ctx);
313 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_UNSIGNED_INT);
314 }
315
316 void GLAPIENTRY
_mesa_Uniform2uiv(GLint location,GLsizei count,const GLuint * value)317 _mesa_Uniform2uiv(GLint location, GLsizei count, const GLuint *value)
318 {
319 GET_CURRENT_CONTEXT(ctx);
320 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_UNSIGNED_INT_VEC2);
321 }
322
323 void GLAPIENTRY
_mesa_Uniform3uiv(GLint location,GLsizei count,const GLuint * value)324 _mesa_Uniform3uiv(GLint location, GLsizei count, const GLuint *value)
325 {
326 GET_CURRENT_CONTEXT(ctx);
327 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_UNSIGNED_INT_VEC3);
328 }
329
330 void GLAPIENTRY
_mesa_Uniform4uiv(GLint location,GLsizei count,const GLuint * value)331 _mesa_Uniform4uiv(GLint location, GLsizei count, const GLuint *value)
332 {
333 GET_CURRENT_CONTEXT(ctx);
334 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_UNSIGNED_INT_VEC4);
335 }
336
337
338
339 void GLAPIENTRY
_mesa_UniformMatrix2fvARB(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)340 _mesa_UniformMatrix2fvARB(GLint location, GLsizei count, GLboolean transpose,
341 const GLfloat * value)
342 {
343 GET_CURRENT_CONTEXT(ctx);
344 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
345 2, 2, location, count, transpose, value);
346 }
347
348 void GLAPIENTRY
_mesa_UniformMatrix3fvARB(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)349 _mesa_UniformMatrix3fvARB(GLint location, GLsizei count, GLboolean transpose,
350 const GLfloat * value)
351 {
352 GET_CURRENT_CONTEXT(ctx);
353 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
354 3, 3, location, count, transpose, value);
355 }
356
357 void GLAPIENTRY
_mesa_UniformMatrix4fvARB(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)358 _mesa_UniformMatrix4fvARB(GLint location, GLsizei count, GLboolean transpose,
359 const GLfloat * value)
360 {
361 GET_CURRENT_CONTEXT(ctx);
362 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
363 4, 4, location, count, transpose, value);
364 }
365
366
367 /**
368 * Non-square UniformMatrix are OpenGL 2.1
369 */
370 void GLAPIENTRY
_mesa_UniformMatrix2x3fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)371 _mesa_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose,
372 const GLfloat *value)
373 {
374 GET_CURRENT_CONTEXT(ctx);
375 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
376 2, 3, location, count, transpose, value);
377 }
378
379 void GLAPIENTRY
_mesa_UniformMatrix3x2fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)380 _mesa_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose,
381 const GLfloat *value)
382 {
383 GET_CURRENT_CONTEXT(ctx);
384 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
385 3, 2, location, count, transpose, value);
386 }
387
388 void GLAPIENTRY
_mesa_UniformMatrix2x4fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)389 _mesa_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose,
390 const GLfloat *value)
391 {
392 GET_CURRENT_CONTEXT(ctx);
393 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
394 2, 4, location, count, transpose, value);
395 }
396
397 void GLAPIENTRY
_mesa_UniformMatrix4x2fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)398 _mesa_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose,
399 const GLfloat *value)
400 {
401 GET_CURRENT_CONTEXT(ctx);
402 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
403 4, 2, location, count, transpose, value);
404 }
405
406 void GLAPIENTRY
_mesa_UniformMatrix3x4fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)407 _mesa_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose,
408 const GLfloat *value)
409 {
410 GET_CURRENT_CONTEXT(ctx);
411 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
412 3, 4, location, count, transpose, value);
413 }
414
415 void GLAPIENTRY
_mesa_UniformMatrix4x3fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)416 _mesa_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose,
417 const GLfloat *value)
418 {
419 GET_CURRENT_CONTEXT(ctx);
420 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
421 4, 3, location, count, transpose, value);
422 }
423
424
425 void GLAPIENTRY
_mesa_GetnUniformfvARB(GLhandleARB program,GLint location,GLsizei bufSize,GLfloat * params)426 _mesa_GetnUniformfvARB(GLhandleARB program, GLint location,
427 GLsizei bufSize, GLfloat *params)
428 {
429 GET_CURRENT_CONTEXT(ctx);
430 _mesa_get_uniform(ctx, program, location, bufSize, GLSL_TYPE_FLOAT, params);
431 }
432
433 void GLAPIENTRY
_mesa_GetUniformfvARB(GLhandleARB program,GLint location,GLfloat * params)434 _mesa_GetUniformfvARB(GLhandleARB program, GLint location, GLfloat *params)
435 {
436 _mesa_GetnUniformfvARB(program, location, INT_MAX, params);
437 }
438
439
440 void GLAPIENTRY
_mesa_GetnUniformivARB(GLhandleARB program,GLint location,GLsizei bufSize,GLint * params)441 _mesa_GetnUniformivARB(GLhandleARB program, GLint location,
442 GLsizei bufSize, GLint *params)
443 {
444 GET_CURRENT_CONTEXT(ctx);
445 _mesa_get_uniform(ctx, program, location, bufSize, GLSL_TYPE_INT, params);
446 }
447
448 void GLAPIENTRY
_mesa_GetUniformivARB(GLhandleARB program,GLint location,GLint * params)449 _mesa_GetUniformivARB(GLhandleARB program, GLint location, GLint *params)
450 {
451 _mesa_GetnUniformivARB(program, location, INT_MAX, params);
452 }
453
454
455 /* GL3 */
456 void GLAPIENTRY
_mesa_GetnUniformuivARB(GLhandleARB program,GLint location,GLsizei bufSize,GLuint * params)457 _mesa_GetnUniformuivARB(GLhandleARB program, GLint location,
458 GLsizei bufSize, GLuint *params)
459 {
460 GET_CURRENT_CONTEXT(ctx);
461 _mesa_get_uniform(ctx, program, location, bufSize, GLSL_TYPE_UINT, params);
462 }
463
464 void GLAPIENTRY
_mesa_GetUniformuiv(GLhandleARB program,GLint location,GLuint * params)465 _mesa_GetUniformuiv(GLhandleARB program, GLint location, GLuint *params)
466 {
467 _mesa_GetnUniformuivARB(program, location, INT_MAX, params);
468 }
469
470
471 /* GL4 */
472 void GLAPIENTRY
_mesa_GetnUniformdvARB(GLhandleARB program,GLint location,GLsizei bufSize,GLdouble * params)473 _mesa_GetnUniformdvARB(GLhandleARB program, GLint location,
474 GLsizei bufSize, GLdouble *params)
475 {
476 GET_CURRENT_CONTEXT(ctx);
477
478 (void) program;
479 (void) location;
480 (void) bufSize;
481 (void) params;
482
483 /*
484 _mesa_get_uniform(ctx, program, location, bufSize, GLSL_TYPE_DOUBLE, params);
485 */
486 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformdvARB"
487 "(GL_ARB_gpu_shader_fp64 not implemented)");
488 }
489
490 void GLAPIENTRY
_mesa_GetUniformdv(GLhandleARB program,GLint location,GLdouble * params)491 _mesa_GetUniformdv(GLhandleARB program, GLint location, GLdouble *params)
492 {
493 _mesa_GetnUniformdvARB(program, location, INT_MAX, params);
494 }
495
496
497 GLint GLAPIENTRY
_mesa_GetUniformLocationARB(GLhandleARB programObj,const GLcharARB * name)498 _mesa_GetUniformLocationARB(GLhandleARB programObj, const GLcharARB *name)
499 {
500 struct gl_shader_program *shProg;
501 GLuint index, offset;
502
503 GET_CURRENT_CONTEXT(ctx);
504
505 shProg = _mesa_lookup_shader_program_err(ctx, programObj,
506 "glGetUniformLocation");
507 if (!shProg)
508 return -1;
509
510 /* Page 80 (page 94 of the PDF) of the OpenGL 2.1 spec says:
511 *
512 * "If program has not been successfully linked, the error
513 * INVALID_OPERATION is generated."
514 */
515 if (shProg->LinkStatus == GL_FALSE) {
516 _mesa_error(ctx, GL_INVALID_OPERATION,
517 "glGetUniformLocation(program not linked)");
518 return -1;
519 }
520
521 index = _mesa_get_uniform_location(ctx, shProg, name, &offset);
522 if (index == GL_INVALID_INDEX)
523 return -1;
524
525 /* From the GL_ARB_uniform_buffer_object spec:
526 *
527 * "The value -1 will be returned if <name> does not correspond to an
528 * active uniform variable name in <program>, if <name> is associated
529 * with a named uniform block, or if <name> starts with the reserved
530 * prefix "gl_"."
531 */
532 if (shProg->UniformStorage[index].block_index != -1)
533 return -1;
534
535 return _mesa_uniform_merge_location_offset(index, offset);
536 }
537
538 static GLuint GLAPIENTRY
_mesa_GetUniformBlockIndex(GLuint program,const GLchar * uniformBlockName)539 _mesa_GetUniformBlockIndex(GLuint program,
540 const GLchar *uniformBlockName)
541 {
542 GET_CURRENT_CONTEXT(ctx);
543 GLuint i;
544 struct gl_shader_program *shProg;
545
546 if (!ctx->Extensions.ARB_uniform_buffer_object) {
547 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformBlockIndex");
548 return GL_INVALID_INDEX;
549 }
550
551 shProg = _mesa_lookup_shader_program_err(ctx, program,
552 "glGetUniformBlockIndex");
553 if (!shProg)
554 return GL_INVALID_INDEX;
555
556 for (i = 0; i < shProg->NumUniformBlocks; i++) {
557 if (!strcmp(shProg->UniformBlocks[i].Name, uniformBlockName))
558 return i;
559 }
560
561 return GL_INVALID_INDEX;
562 }
563
564 static void GLAPIENTRY
_mesa_GetUniformIndices(GLuint program,GLsizei uniformCount,const GLchar * const * uniformNames,GLuint * uniformIndices)565 _mesa_GetUniformIndices(GLuint program,
566 GLsizei uniformCount,
567 const GLchar * const *uniformNames,
568 GLuint *uniformIndices)
569 {
570 GET_CURRENT_CONTEXT(ctx);
571 GLsizei i;
572 struct gl_shader_program *shProg;
573
574 if (!ctx->Extensions.ARB_uniform_buffer_object) {
575 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformIndices");
576 return;
577 }
578
579 shProg = _mesa_lookup_shader_program_err(ctx, program,
580 "glGetUniformIndices");
581 if (!shProg)
582 return;
583
584 if (uniformCount < 0) {
585 _mesa_error(ctx, GL_INVALID_VALUE,
586 "glGetUniformIndices(uniformCount < 0)");
587 return;
588 }
589
590 for (i = 0; i < uniformCount; i++) {
591 unsigned offset;
592 uniformIndices[i] = _mesa_get_uniform_location(ctx, shProg,
593 uniformNames[i], &offset);
594 }
595 }
596
597 static void GLAPIENTRY
_mesa_UniformBlockBinding(GLuint program,GLuint uniformBlockIndex,GLuint uniformBlockBinding)598 _mesa_UniformBlockBinding(GLuint program,
599 GLuint uniformBlockIndex,
600 GLuint uniformBlockBinding)
601 {
602 GET_CURRENT_CONTEXT(ctx);
603 struct gl_shader_program *shProg;
604
605 if (!ctx->Extensions.ARB_uniform_buffer_object) {
606 _mesa_error(ctx, GL_INVALID_OPERATION, "glUniformBlockBinding");
607 return;
608 }
609
610 shProg = _mesa_lookup_shader_program_err(ctx, program,
611 "glUniformBlockBinding");
612 if (!shProg)
613 return;
614
615 if (uniformBlockIndex >= shProg->NumUniformBlocks) {
616 _mesa_error(ctx, GL_INVALID_VALUE,
617 "glUniformBlockBinding(block index %d >= %d)",
618 uniformBlockIndex, shProg->NumUniformBlocks);
619 return;
620 }
621
622 if (uniformBlockBinding >= ctx->Const.MaxUniformBufferBindings) {
623 _mesa_error(ctx, GL_INVALID_VALUE,
624 "glUniformBlockBinding(block binding %d >= %d)",
625 uniformBlockBinding, ctx->Const.MaxUniformBufferBindings);
626 return;
627 }
628
629 if (shProg->UniformBlocks[uniformBlockIndex].Binding !=
630 uniformBlockBinding) {
631 int i;
632
633 FLUSH_VERTICES(ctx, _NEW_BUFFER_OBJECT);
634 shProg->UniformBlocks[uniformBlockIndex].Binding = uniformBlockBinding;
635
636 for (i = 0; i < MESA_SHADER_TYPES; i++) {
637 int stage_index = shProg->UniformBlockStageIndex[i][uniformBlockIndex];
638
639 if (stage_index != -1) {
640 struct gl_shader *sh = shProg->_LinkedShaders[i];
641 sh->UniformBlocks[stage_index].Binding = uniformBlockBinding;
642 }
643 }
644 }
645 }
646
647 static void GLAPIENTRY
_mesa_GetActiveUniformBlockiv(GLuint program,GLuint uniformBlockIndex,GLenum pname,GLint * params)648 _mesa_GetActiveUniformBlockiv(GLuint program,
649 GLuint uniformBlockIndex,
650 GLenum pname,
651 GLint *params)
652 {
653 GET_CURRENT_CONTEXT(ctx);
654 struct gl_shader_program *shProg;
655 struct gl_uniform_block *block;
656 unsigned i;
657
658 if (!ctx->Extensions.ARB_uniform_buffer_object) {
659 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetActiveUniformBlockiv");
660 return;
661 }
662
663 shProg = _mesa_lookup_shader_program_err(ctx, program,
664 "glGetActiveUniformBlockiv");
665 if (!shProg)
666 return;
667
668 if (uniformBlockIndex >= shProg->NumUniformBlocks) {
669 _mesa_error(ctx, GL_INVALID_VALUE,
670 "glGetActiveUniformBlockiv(block index %d >= %d)",
671 uniformBlockIndex, shProg->NumUniformBlocks);
672 return;
673 }
674
675 block = &shProg->UniformBlocks[uniformBlockIndex];
676
677 switch (pname) {
678 case GL_UNIFORM_BLOCK_BINDING:
679 params[0] = block->Binding;
680 return;
681
682 case GL_UNIFORM_BLOCK_DATA_SIZE:
683 params[0] = block->UniformBufferSize;
684 return;
685
686 case GL_UNIFORM_BLOCK_NAME_LENGTH:
687 params[0] = strlen(block->Name) + 1;
688 return;
689
690 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
691 params[0] = block->NumUniforms;
692 return;
693
694 case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
695 for (i = 0; i < block->NumUniforms; i++) {
696 unsigned offset;
697 params[i] = _mesa_get_uniform_location(ctx, shProg,
698 block->Uniforms[i].Name,
699 &offset);
700 }
701 return;
702
703 case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
704 params[0] = shProg->UniformBlockStageIndex[MESA_SHADER_VERTEX][uniformBlockIndex] != -1;
705 return;
706
707 case GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER:
708 params[0] = shProg->UniformBlockStageIndex[MESA_SHADER_GEOMETRY][uniformBlockIndex] != -1;
709 return;
710
711 case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
712 params[0] = shProg->UniformBlockStageIndex[MESA_SHADER_FRAGMENT][uniformBlockIndex] != -1;
713 return;
714
715 default:
716 _mesa_error(ctx, GL_INVALID_ENUM,
717 "glGetActiveUniformBlockiv(pname 0x%x (%s))",
718 pname, _mesa_lookup_enum_by_nr(pname));
719 return;
720 }
721 }
722
723 static void GLAPIENTRY
_mesa_GetActiveUniformBlockName(GLuint program,GLuint uniformBlockIndex,GLsizei bufSize,GLsizei * length,GLchar * uniformBlockName)724 _mesa_GetActiveUniformBlockName(GLuint program,
725 GLuint uniformBlockIndex,
726 GLsizei bufSize,
727 GLsizei *length,
728 GLchar *uniformBlockName)
729 {
730 GET_CURRENT_CONTEXT(ctx);
731 struct gl_shader_program *shProg;
732 struct gl_uniform_block *block;
733
734 if (!ctx->Extensions.ARB_uniform_buffer_object) {
735 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetActiveUniformBlockiv");
736 return;
737 }
738
739 if (bufSize < 0) {
740 _mesa_error(ctx, GL_INVALID_VALUE,
741 "glGetActiveUniformBlockName(bufSize %d < 0)",
742 bufSize);
743 return;
744 }
745
746 shProg = _mesa_lookup_shader_program_err(ctx, program,
747 "glGetActiveUniformBlockiv");
748 if (!shProg)
749 return;
750
751 if (uniformBlockIndex >= shProg->NumUniformBlocks) {
752 _mesa_error(ctx, GL_INVALID_VALUE,
753 "glGetActiveUniformBlockiv(block index %d >= %d)",
754 uniformBlockIndex, shProg->NumUniformBlocks);
755 return;
756 }
757
758 block = &shProg->UniformBlocks[uniformBlockIndex];
759
760 if (uniformBlockName) {
761 _mesa_copy_string(uniformBlockName, bufSize, length, block->Name);
762 }
763 }
764
765 static void GLAPIENTRY
_mesa_GetActiveUniformName(GLuint program,GLuint uniformIndex,GLsizei bufSize,GLsizei * length,GLchar * uniformName)766 _mesa_GetActiveUniformName(GLuint program, GLuint uniformIndex,
767 GLsizei bufSize, GLsizei *length,
768 GLchar *uniformName)
769 {
770 GET_CURRENT_CONTEXT(ctx);
771 struct gl_shader_program *shProg;
772
773 if (!ctx->Extensions.ARB_uniform_buffer_object) {
774 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetActiveUniformBlockiv");
775 return;
776 }
777
778 if (bufSize < 0) {
779 _mesa_error(ctx, GL_INVALID_VALUE,
780 "glGetActiveUniformName(bufSize %d < 0)",
781 bufSize);
782 return;
783 }
784
785 ASSERT_OUTSIDE_BEGIN_END(ctx);
786
787 shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniformName");
788
789 if (!shProg)
790 return;
791
792 if (uniformIndex >= shProg->NumUserUniformStorage) {
793 _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(index)");
794 return;
795 }
796
797 if (uniformName) {
798 _mesa_copy_string(uniformName, bufSize, length,
799 shProg->UniformStorage[uniformIndex].name);
800 }
801 }
802
803 /**
804 * Plug in shader uniform-related functions into API dispatch table.
805 */
806 void
_mesa_init_shader_uniform_dispatch(const struct gl_context * ctx,struct _glapi_table * exec)807 _mesa_init_shader_uniform_dispatch(const struct gl_context *ctx,
808 struct _glapi_table *exec)
809 {
810 #if FEATURE_GL
811 SET_Uniform1fARB(exec, _mesa_Uniform1fARB);
812 SET_Uniform2fARB(exec, _mesa_Uniform2fARB);
813 SET_Uniform3fARB(exec, _mesa_Uniform3fARB);
814 SET_Uniform4fARB(exec, _mesa_Uniform4fARB);
815 SET_Uniform1iARB(exec, _mesa_Uniform1iARB);
816 SET_Uniform2iARB(exec, _mesa_Uniform2iARB);
817 SET_Uniform3iARB(exec, _mesa_Uniform3iARB);
818 SET_Uniform4iARB(exec, _mesa_Uniform4iARB);
819 SET_Uniform1fvARB(exec, _mesa_Uniform1fvARB);
820 SET_Uniform2fvARB(exec, _mesa_Uniform2fvARB);
821 SET_Uniform3fvARB(exec, _mesa_Uniform3fvARB);
822 SET_Uniform4fvARB(exec, _mesa_Uniform4fvARB);
823 SET_Uniform1ivARB(exec, _mesa_Uniform1ivARB);
824 SET_Uniform2ivARB(exec, _mesa_Uniform2ivARB);
825 SET_Uniform3ivARB(exec, _mesa_Uniform3ivARB);
826 SET_Uniform4ivARB(exec, _mesa_Uniform4ivARB);
827 SET_UniformMatrix2fvARB(exec, _mesa_UniformMatrix2fvARB);
828 SET_UniformMatrix3fvARB(exec, _mesa_UniformMatrix3fvARB);
829 SET_UniformMatrix4fvARB(exec, _mesa_UniformMatrix4fvARB);
830
831 SET_GetActiveUniformARB(exec, _mesa_GetActiveUniformARB);
832 SET_GetUniformLocationARB(exec, _mesa_GetUniformLocationARB);
833 SET_GetUniformfvARB(exec, _mesa_GetUniformfvARB);
834 SET_GetUniformivARB(exec, _mesa_GetUniformivARB);
835
836 /* OpenGL 2.1 */
837 if (ctx->API != API_OPENGLES2 || _mesa_is_gles3(ctx)) {
838 SET_UniformMatrix2x3fv(exec, _mesa_UniformMatrix2x3fv);
839 SET_UniformMatrix3x2fv(exec, _mesa_UniformMatrix3x2fv);
840 SET_UniformMatrix2x4fv(exec, _mesa_UniformMatrix2x4fv);
841 SET_UniformMatrix4x2fv(exec, _mesa_UniformMatrix4x2fv);
842 SET_UniformMatrix3x4fv(exec, _mesa_UniformMatrix3x4fv);
843 SET_UniformMatrix4x3fv(exec, _mesa_UniformMatrix4x3fv);
844
845 /* OpenGL 3.0 */
846 SET_Uniform1uiEXT(exec, _mesa_Uniform1ui);
847 SET_Uniform2uiEXT(exec, _mesa_Uniform2ui);
848 SET_Uniform3uiEXT(exec, _mesa_Uniform3ui);
849 SET_Uniform4uiEXT(exec, _mesa_Uniform4ui);
850 SET_Uniform1uivEXT(exec, _mesa_Uniform1uiv);
851 SET_Uniform2uivEXT(exec, _mesa_Uniform2uiv);
852 SET_Uniform3uivEXT(exec, _mesa_Uniform3uiv);
853 SET_Uniform4uivEXT(exec, _mesa_Uniform4uiv);
854 SET_GetUniformuivEXT(exec, _mesa_GetUniformuiv);
855
856 /* GL_ARB_robustness */
857 SET_GetnUniformfvARB(exec, _mesa_GetnUniformfvARB);
858 SET_GetnUniformivARB(exec, _mesa_GetnUniformivARB);
859 SET_GetnUniformuivARB(exec, _mesa_GetnUniformuivARB);
860 SET_GetnUniformdvARB(exec, _mesa_GetnUniformdvARB); /* GL 4.0 */
861
862 /* GL_ARB_uniform_buffer_object / GL 3.1 */
863 SET_GetUniformBlockIndex(exec, _mesa_GetUniformBlockIndex);
864 SET_GetUniformIndices(exec, _mesa_GetUniformIndices);
865 SET_GetActiveUniformsiv(exec, _mesa_GetActiveUniformsiv);
866 SET_GetActiveUniformBlockiv(exec, _mesa_GetActiveUniformBlockiv);
867 SET_GetActiveUniformBlockName(exec, _mesa_GetActiveUniformBlockName);
868 SET_GetActiveUniformName(exec, _mesa_GetActiveUniformName);
869 SET_UniformBlockBinding(exec, _mesa_UniformBlockBinding);
870 }
871 #endif /* FEATURE_GL */
872 }
873