mesa: Include mtypes.h in files that use gl_context struct.
[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 * 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
39 #include "main/glheader.h"
40 #include "main/context.h"
41 #include "main/dispatch.h"
42 #include "main/mtypes.h"
43 #include "main/shaderapi.h"
44 #include "main/shaderobj.h"
45 #include "main/uniforms.h"
46 #include "program/prog_parameter.h"
47 #include "program/prog_statevars.h"
48 #include "program/prog_uniform.h"
49 #include "program/prog_instruction.h"
50
51
52 static GLenum
53 base_uniform_type(GLenum type)
54 {
55 switch (type) {
56 #if 0 /* not needed, for now */
57 case GL_BOOL:
58 case GL_BOOL_VEC2:
59 case GL_BOOL_VEC3:
60 case GL_BOOL_VEC4:
61 return GL_BOOL;
62 #endif
63 case GL_FLOAT:
64 case GL_FLOAT_VEC2:
65 case GL_FLOAT_VEC3:
66 case GL_FLOAT_VEC4:
67 return GL_FLOAT;
68 case GL_UNSIGNED_INT:
69 case GL_UNSIGNED_INT_VEC2:
70 case GL_UNSIGNED_INT_VEC3:
71 case GL_UNSIGNED_INT_VEC4:
72 return GL_UNSIGNED_INT;
73 case GL_INT:
74 case GL_INT_VEC2:
75 case GL_INT_VEC3:
76 case GL_INT_VEC4:
77 return GL_INT;
78 default:
79 _mesa_problem(NULL, "Invalid type in base_uniform_type()");
80 return GL_FLOAT;
81 }
82 }
83
84 static struct gl_builtin_uniform_element gl_DepthRange_elements[] = {
85 {"near", {STATE_DEPTH_RANGE, 0, 0}, SWIZZLE_XXXX},
86 {"far", {STATE_DEPTH_RANGE, 0, 0}, SWIZZLE_YYYY},
87 {"diff", {STATE_DEPTH_RANGE, 0, 0}, SWIZZLE_ZZZZ},
88 };
89
90 static struct gl_builtin_uniform_element gl_ClipPlane_elements[] = {
91 {NULL, {STATE_CLIPPLANE, 0, 0}, SWIZZLE_XYZW}
92 };
93
94 static struct gl_builtin_uniform_element gl_Point_elements[] = {
95 {"size", {STATE_POINT_SIZE}, SWIZZLE_XXXX},
96 {"sizeMin", {STATE_POINT_SIZE}, SWIZZLE_YYYY},
97 {"sizeMax", {STATE_POINT_SIZE}, SWIZZLE_ZZZZ},
98 {"fadeThresholdSize", {STATE_POINT_SIZE}, SWIZZLE_WWWW},
99 {"distanceConstantAttenuation", {STATE_POINT_ATTENUATION}, SWIZZLE_XXXX},
100 {"distanceLinearAttenuation", {STATE_POINT_ATTENUATION}, SWIZZLE_YYYY},
101 {"distanceQuadraticAttenuation", {STATE_POINT_ATTENUATION}, SWIZZLE_ZZZZ},
102 };
103
104 static struct gl_builtin_uniform_element gl_FrontMaterial_elements[] = {
105 {"emission", {STATE_MATERIAL, 0, STATE_EMISSION}, SWIZZLE_XYZW},
106 {"ambient", {STATE_MATERIAL, 0, STATE_AMBIENT}, SWIZZLE_XYZW},
107 {"diffuse", {STATE_MATERIAL, 0, STATE_DIFFUSE}, SWIZZLE_XYZW},
108 {"specular", {STATE_MATERIAL, 0, STATE_SPECULAR}, SWIZZLE_XYZW},
109 {"shininess", {STATE_MATERIAL, 0, STATE_SHININESS}, SWIZZLE_XXXX},
110 };
111
112 static struct gl_builtin_uniform_element gl_BackMaterial_elements[] = {
113 {"emission", {STATE_MATERIAL, 1, STATE_EMISSION}, SWIZZLE_XYZW},
114 {"ambient", {STATE_MATERIAL, 1, STATE_AMBIENT}, SWIZZLE_XYZW},
115 {"diffuse", {STATE_MATERIAL, 1, STATE_DIFFUSE}, SWIZZLE_XYZW},
116 {"specular", {STATE_MATERIAL, 1, STATE_SPECULAR}, SWIZZLE_XYZW},
117 {"shininess", {STATE_MATERIAL, 1, STATE_SHININESS}, SWIZZLE_XXXX},
118 };
119
120 static struct gl_builtin_uniform_element gl_LightSource_elements[] = {
121 {"ambient", {STATE_LIGHT, 0, STATE_AMBIENT}, SWIZZLE_XYZW},
122 {"diffuse", {STATE_LIGHT, 0, STATE_DIFFUSE}, SWIZZLE_XYZW},
123 {"specular", {STATE_LIGHT, 0, STATE_SPECULAR}, SWIZZLE_XYZW},
124 {"position", {STATE_LIGHT, 0, STATE_POSITION}, SWIZZLE_XYZW},
125 {"halfVector", {STATE_LIGHT, 0, STATE_HALF_VECTOR}, SWIZZLE_XYZW},
126 {"spotDirection", {STATE_LIGHT, 0, STATE_SPOT_DIRECTION},
127 MAKE_SWIZZLE4(SWIZZLE_X,
128 SWIZZLE_Y,
129 SWIZZLE_Z,
130 SWIZZLE_Z)},
131 {"spotCosCutoff", {STATE_LIGHT, 0, STATE_SPOT_DIRECTION}, SWIZZLE_WWWW},
132 {"spotCutoff", {STATE_LIGHT, 0, STATE_SPOT_CUTOFF}, SWIZZLE_XXXX},
133 {"spotExponent", {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_WWWW},
134 {"constantAttenuation", {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_XXXX},
135 {"linearAttenuation", {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_YYYY},
136 {"quadraticAttenuation", {STATE_LIGHT, 0, STATE_ATTENUATION}, SWIZZLE_ZZZZ},
137 };
138
139 static struct gl_builtin_uniform_element gl_LightModel_elements[] = {
140 {"ambient", {STATE_LIGHTMODEL_AMBIENT, 0}, SWIZZLE_XYZW},
141 };
142
143 static struct gl_builtin_uniform_element gl_FrontLightModelProduct_elements[] = {
144 {"sceneColor", {STATE_LIGHTMODEL_SCENECOLOR, 0}, SWIZZLE_XYZW},
145 };
146
147 static struct gl_builtin_uniform_element gl_BackLightModelProduct_elements[] = {
148 {"sceneColor", {STATE_LIGHTMODEL_SCENECOLOR, 1}, SWIZZLE_XYZW},
149 };
150
151 static struct gl_builtin_uniform_element gl_FrontLightProduct_elements[] = {
152 {"ambient", {STATE_LIGHTPROD, 0, 0, STATE_AMBIENT}, SWIZZLE_XYZW},
153 {"diffuse", {STATE_LIGHTPROD, 0, 0, STATE_DIFFUSE}, SWIZZLE_XYZW},
154 {"specular", {STATE_LIGHTPROD, 0, 0, STATE_SPECULAR}, SWIZZLE_XYZW},
155 };
156
157 static struct gl_builtin_uniform_element gl_BackLightProduct_elements[] = {
158 {"ambient", {STATE_LIGHTPROD, 0, 1, STATE_AMBIENT}, SWIZZLE_XYZW},
159 {"diffuse", {STATE_LIGHTPROD, 0, 1, STATE_DIFFUSE}, SWIZZLE_XYZW},
160 {"specular", {STATE_LIGHTPROD, 0, 1, STATE_SPECULAR}, SWIZZLE_XYZW},
161 };
162
163 static struct gl_builtin_uniform_element gl_TextureEnvColor_elements[] = {
164 {NULL, {STATE_TEXENV_COLOR, 0}, SWIZZLE_XYZW},
165 };
166
167 static struct gl_builtin_uniform_element gl_EyePlaneS_elements[] = {
168 {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_S}, SWIZZLE_XYZW},
169 };
170
171 static struct gl_builtin_uniform_element gl_EyePlaneT_elements[] = {
172 {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_T}, SWIZZLE_XYZW},
173 };
174
175 static struct gl_builtin_uniform_element gl_EyePlaneR_elements[] = {
176 {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_R}, SWIZZLE_XYZW},
177 };
178
179 static struct gl_builtin_uniform_element gl_EyePlaneQ_elements[] = {
180 {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_EYE_Q}, SWIZZLE_XYZW},
181 };
182
183 static struct gl_builtin_uniform_element gl_ObjectPlaneS_elements[] = {
184 {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_S}, SWIZZLE_XYZW},
185 };
186
187 static struct gl_builtin_uniform_element gl_ObjectPlaneT_elements[] = {
188 {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_T}, SWIZZLE_XYZW},
189 };
190
191 static struct gl_builtin_uniform_element gl_ObjectPlaneR_elements[] = {
192 {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_R}, SWIZZLE_XYZW},
193 };
194
195 static struct gl_builtin_uniform_element gl_ObjectPlaneQ_elements[] = {
196 {NULL, {STATE_TEXGEN, 0, STATE_TEXGEN_OBJECT_Q}, SWIZZLE_XYZW},
197 };
198
199 static struct gl_builtin_uniform_element gl_Fog_elements[] = {
200 {"color", {STATE_FOG_COLOR}, SWIZZLE_XYZW},
201 {"density", {STATE_FOG_PARAMS}, SWIZZLE_XXXX},
202 {"start", {STATE_FOG_PARAMS}, SWIZZLE_YYYY},
203 {"end", {STATE_FOG_PARAMS}, SWIZZLE_ZZZZ},
204 {"scale", {STATE_FOG_PARAMS}, SWIZZLE_WWWW},
205 };
206
207 static struct gl_builtin_uniform_element gl_NormalScale_elements[] = {
208 {NULL, {STATE_NORMAL_SCALE}, SWIZZLE_XXXX},
209 };
210
211 #define MATRIX(name, statevar, modifier) \
212 static struct gl_builtin_uniform_element name ## _elements[] = { \
213 { NULL, { statevar, 0, 0, 0, modifier}, SWIZZLE_XYZW }, \
214 { NULL, { statevar, 0, 1, 1, modifier}, SWIZZLE_XYZW }, \
215 { NULL, { statevar, 0, 2, 2, modifier}, SWIZZLE_XYZW }, \
216 { NULL, { statevar, 0, 3, 3, modifier}, SWIZZLE_XYZW }, \
217 }
218
219 MATRIX(gl_ModelViewMatrix,
220 STATE_MODELVIEW_MATRIX, STATE_MATRIX_TRANSPOSE);
221 MATRIX(gl_ModelViewMatrixInverse,
222 STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVTRANS);
223 MATRIX(gl_ModelViewMatrixTranspose,
224 STATE_MODELVIEW_MATRIX, 0);
225 MATRIX(gl_ModelViewMatrixInverseTranspose,
226 STATE_MODELVIEW_MATRIX, STATE_MATRIX_INVERSE);
227
228 MATRIX(gl_ProjectionMatrix,
229 STATE_PROJECTION_MATRIX, STATE_MATRIX_TRANSPOSE);
230 MATRIX(gl_ProjectionMatrixInverse,
231 STATE_PROJECTION_MATRIX, STATE_MATRIX_INVTRANS);
232 MATRIX(gl_ProjectionMatrixTranspose,
233 STATE_PROJECTION_MATRIX, 0);
234 MATRIX(gl_ProjectionMatrixInverseTranspose,
235 STATE_PROJECTION_MATRIX, STATE_MATRIX_INVERSE);
236
237 MATRIX(gl_ModelViewProjectionMatrix,
238 STATE_MVP_MATRIX, STATE_MATRIX_TRANSPOSE);
239 MATRIX(gl_ModelViewProjectionMatrixInverse,
240 STATE_MVP_MATRIX, STATE_MATRIX_INVTRANS);
241 MATRIX(gl_ModelViewProjectionMatrixTranspose,
242 STATE_MVP_MATRIX, 0);
243 MATRIX(gl_ModelViewProjectionMatrixInverseTranspose,
244 STATE_MVP_MATRIX, STATE_MATRIX_INVERSE);
245
246 MATRIX(gl_TextureMatrix,
247 STATE_TEXTURE_MATRIX, STATE_MATRIX_TRANSPOSE);
248 MATRIX(gl_TextureMatrixInverse,
249 STATE_TEXTURE_MATRIX, STATE_MATRIX_INVTRANS);
250 MATRIX(gl_TextureMatrixTranspose,
251 STATE_TEXTURE_MATRIX, 0);
252 MATRIX(gl_TextureMatrixInverseTranspose,
253 STATE_TEXTURE_MATRIX, STATE_MATRIX_INVERSE);
254
255 static struct gl_builtin_uniform_element gl_NormalMatrix_elements[] = {
256 { NULL, { STATE_MODELVIEW_MATRIX, 0, 0, 0, STATE_MATRIX_INVERSE},
257 SWIZZLE_XYZW },
258 { NULL, { STATE_MODELVIEW_MATRIX, 0, 1, 1, STATE_MATRIX_INVERSE},
259 SWIZZLE_XYZW },
260 { NULL, { STATE_MODELVIEW_MATRIX, 0, 2, 2, STATE_MATRIX_INVERSE},
261 SWIZZLE_XYZW },
262 };
263
264 #undef MATRIX
265
266 #define STATEVAR(name) {#name, name ## _elements, Elements(name ## _elements)}
267
268 const struct gl_builtin_uniform_desc _mesa_builtin_uniform_desc[] = {
269 STATEVAR(gl_DepthRange),
270 STATEVAR(gl_ClipPlane),
271 STATEVAR(gl_Point),
272 STATEVAR(gl_FrontMaterial),
273 STATEVAR(gl_BackMaterial),
274 STATEVAR(gl_LightSource),
275 STATEVAR(gl_LightModel),
276 STATEVAR(gl_FrontLightModelProduct),
277 STATEVAR(gl_BackLightModelProduct),
278 STATEVAR(gl_FrontLightProduct),
279 STATEVAR(gl_BackLightProduct),
280 STATEVAR(gl_TextureEnvColor),
281 STATEVAR(gl_EyePlaneS),
282 STATEVAR(gl_EyePlaneT),
283 STATEVAR(gl_EyePlaneR),
284 STATEVAR(gl_EyePlaneQ),
285 STATEVAR(gl_ObjectPlaneS),
286 STATEVAR(gl_ObjectPlaneT),
287 STATEVAR(gl_ObjectPlaneR),
288 STATEVAR(gl_ObjectPlaneQ),
289 STATEVAR(gl_Fog),
290
291 STATEVAR(gl_ModelViewMatrix),
292 STATEVAR(gl_ModelViewMatrixInverse),
293 STATEVAR(gl_ModelViewMatrixTranspose),
294 STATEVAR(gl_ModelViewMatrixInverseTranspose),
295
296 STATEVAR(gl_ProjectionMatrix),
297 STATEVAR(gl_ProjectionMatrixInverse),
298 STATEVAR(gl_ProjectionMatrixTranspose),
299 STATEVAR(gl_ProjectionMatrixInverseTranspose),
300
301 STATEVAR(gl_ModelViewProjectionMatrix),
302 STATEVAR(gl_ModelViewProjectionMatrixInverse),
303 STATEVAR(gl_ModelViewProjectionMatrixTranspose),
304 STATEVAR(gl_ModelViewProjectionMatrixInverseTranspose),
305
306 STATEVAR(gl_TextureMatrix),
307 STATEVAR(gl_TextureMatrixInverse),
308 STATEVAR(gl_TextureMatrixTranspose),
309 STATEVAR(gl_TextureMatrixInverseTranspose),
310
311 STATEVAR(gl_NormalMatrix),
312 STATEVAR(gl_NormalScale),
313
314 {NULL, NULL, 0}
315 };
316
317 static GLboolean
318 is_boolean_type(GLenum type)
319 {
320 switch (type) {
321 case GL_BOOL:
322 case GL_BOOL_VEC2:
323 case GL_BOOL_VEC3:
324 case GL_BOOL_VEC4:
325 return GL_TRUE;
326 default:
327 return GL_FALSE;
328 }
329 }
330
331
332 static GLboolean
333 is_sampler_type(GLenum type)
334 {
335 switch (type) {
336 case GL_SAMPLER_1D:
337 case GL_SAMPLER_2D:
338 case GL_SAMPLER_3D:
339 case GL_SAMPLER_CUBE:
340 case GL_SAMPLER_1D_SHADOW:
341 case GL_SAMPLER_2D_SHADOW:
342 case GL_SAMPLER_2D_RECT_ARB:
343 case GL_SAMPLER_2D_RECT_SHADOW_ARB:
344 case GL_SAMPLER_1D_ARRAY_EXT:
345 case GL_SAMPLER_2D_ARRAY_EXT:
346 case GL_SAMPLER_1D_ARRAY_SHADOW_EXT:
347 case GL_SAMPLER_2D_ARRAY_SHADOW_EXT:
348 return GL_TRUE;
349 default:
350 return GL_FALSE;
351 }
352 }
353
354
355 static struct gl_program_parameter *
356 get_uniform_parameter(const struct gl_shader_program *shProg, GLuint index)
357 {
358 const struct gl_program *prog = NULL;
359 GLint progPos;
360
361 progPos = shProg->Uniforms->Uniforms[index].VertPos;
362 if (progPos >= 0) {
363 prog = &shProg->VertexProgram->Base;
364 }
365 else {
366 progPos = shProg->Uniforms->Uniforms[index].FragPos;
367 if (progPos >= 0) {
368 prog = &shProg->FragmentProgram->Base;
369 } else {
370 progPos = shProg->Uniforms->Uniforms[index].GeomPos;
371 if (progPos >= 0) {
372 prog = &shProg->GeometryProgram->Base;
373 }
374 }
375 }
376
377 if (!prog || progPos < 0)
378 return NULL; /* should never happen */
379
380 return &prog->Parameters->Parameters[progPos];
381 }
382
383
384 /**
385 * Called by glGetActiveUniform().
386 */
387 static void
388 _mesa_get_active_uniform(struct gl_context *ctx, GLuint program, GLuint index,
389 GLsizei maxLength, GLsizei *length, GLint *size,
390 GLenum *type, GLchar *nameOut)
391 {
392 const struct gl_shader_program *shProg;
393 const struct gl_program *prog = NULL;
394 const struct gl_program_parameter *param;
395 GLint progPos;
396
397 shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveUniform");
398 if (!shProg)
399 return;
400
401 if (!shProg->Uniforms || index >= shProg->Uniforms->NumUniforms) {
402 _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniform(index)");
403 return;
404 }
405
406 progPos = shProg->Uniforms->Uniforms[index].VertPos;
407 if (progPos >= 0) {
408 prog = &shProg->VertexProgram->Base;
409 }
410 else {
411 progPos = shProg->Uniforms->Uniforms[index].FragPos;
412 if (progPos >= 0) {
413 prog = &shProg->FragmentProgram->Base;
414 } else {
415 progPos = shProg->Uniforms->Uniforms[index].GeomPos;
416 if (progPos >= 0) {
417 prog = &shProg->GeometryProgram->Base;
418 }
419 }
420 }
421
422 if (!prog || progPos < 0)
423 return; /* should never happen */
424
425 ASSERT(progPos < prog->Parameters->NumParameters);
426 param = &prog->Parameters->Parameters[progPos];
427
428 if (nameOut) {
429 _mesa_copy_string(nameOut, maxLength, length, param->Name);
430 }
431
432 if (size) {
433 GLint typeSize = _mesa_sizeof_glsl_type(param->DataType);
434 if ((GLint) param->Size > typeSize) {
435 /* This is an array.
436 * Array elements are placed on vector[4] boundaries so they're
437 * a multiple of four floats. We round typeSize up to next multiple
438 * of four to get the right size below.
439 */
440 typeSize = (typeSize + 3) & ~3;
441 }
442 /* Note that the returned size is in units of the <type>, not bytes */
443 *size = param->Size / typeSize;
444 }
445
446 if (type) {
447 *type = param->DataType;
448 }
449 }
450
451
452
453 static void
454 get_matrix_dims(GLenum type, GLint *rows, GLint *cols)
455 {
456 switch (type) {
457 case GL_FLOAT_MAT2:
458 *rows = *cols = 2;
459 break;
460 case GL_FLOAT_MAT2x3:
461 *rows = 3;
462 *cols = 2;
463 break;
464 case GL_FLOAT_MAT2x4:
465 *rows = 4;
466 *cols = 2;
467 break;
468 case GL_FLOAT_MAT3:
469 *rows = 3;
470 *cols = 3;
471 break;
472 case GL_FLOAT_MAT3x2:
473 *rows = 2;
474 *cols = 3;
475 break;
476 case GL_FLOAT_MAT3x4:
477 *rows = 4;
478 *cols = 3;
479 break;
480 case GL_FLOAT_MAT4:
481 *rows = 4;
482 *cols = 4;
483 break;
484 case GL_FLOAT_MAT4x2:
485 *rows = 2;
486 *cols = 4;
487 break;
488 case GL_FLOAT_MAT4x3:
489 *rows = 3;
490 *cols = 4;
491 break;
492 default:
493 *rows = *cols = 0;
494 }
495 }
496
497
498 /**
499 * Determine the number of rows and columns occupied by a uniform
500 * according to its datatype. For non-matrix types (such as GL_FLOAT_VEC4),
501 * the number of rows = 1 and cols = number of elements in the vector.
502 */
503 static void
504 get_uniform_rows_cols(const struct gl_program_parameter *p,
505 GLint *rows, GLint *cols)
506 {
507 get_matrix_dims(p->DataType, rows, cols);
508 if (*rows == 0 && *cols == 0) {
509 /* not a matrix type, probably a float or vector */
510 if (p->Size <= 4) {
511 *rows = 1;
512 *cols = p->Size;
513 }
514 else {
515 *rows = p->Size / 4 + 1;
516 if (p->Size % 4 == 0)
517 *cols = 4;
518 else
519 *cols = p->Size % 4;
520 }
521 }
522 }
523
524
525 /**
526 * Helper for get_uniform[fi]v() functions.
527 * Given a shader program name and uniform location, return a pointer
528 * to the shader program and return the program parameter position.
529 */
530 static void
531 lookup_uniform_parameter(struct gl_context *ctx, GLuint program, GLint location,
532 struct gl_program **progOut, GLint *paramPosOut)
533 {
534 struct gl_shader_program *shProg
535 = _mesa_lookup_shader_program_err(ctx, program, "glGetUniform[if]v");
536 struct gl_program *prog = NULL;
537 GLint progPos = -1;
538
539 /* if shProg is NULL, we'll have already recorded an error */
540
541 if (shProg) {
542 if (!shProg->Uniforms ||
543 location < 0 ||
544 location >= (GLint) shProg->Uniforms->NumUniforms) {
545 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfv(location)");
546 }
547 else {
548 /* OK, find the gl_program and program parameter location */
549 progPos = shProg->Uniforms->Uniforms[location].VertPos;
550 if (progPos >= 0) {
551 prog = &shProg->VertexProgram->Base;
552 }
553 else {
554 progPos = shProg->Uniforms->Uniforms[location].FragPos;
555 if (progPos >= 0) {
556 prog = &shProg->FragmentProgram->Base;
557 } else {
558 progPos = shProg->Uniforms->Uniforms[location].GeomPos;
559 if (progPos >= 0) {
560 prog = &shProg->GeometryProgram->Base;
561 }
562 }
563 }
564 }
565 }
566
567 *progOut = prog;
568 *paramPosOut = progPos;
569 }
570
571
572 /**
573 * GLGL uniform arrays and structs require special handling.
574 *
575 * The GL_ARB_shader_objects spec says that if you use
576 * glGetUniformLocation to get the location of an array, you CANNOT
577 * access other elements of the array by adding an offset to the
578 * returned location. For example, you must call
579 * glGetUniformLocation("foo[16]") if you want to set the 16th element
580 * of the array with glUniform().
581 *
582 * HOWEVER, some other OpenGL drivers allow accessing array elements
583 * by adding an offset to the returned array location. And some apps
584 * seem to depend on that behaviour.
585 *
586 * Mesa's gl_uniform_list doesn't directly support this since each
587 * entry in the list describes one uniform variable, not one uniform
588 * element. We could insert dummy entries in the list for each array
589 * element after [0] but that causes complications elsewhere.
590 *
591 * We solve this problem by encoding two values in the location that's
592 * returned by glGetUniformLocation():
593 * a) index into gl_uniform_list::Uniforms[] for the uniform
594 * b) an array/field offset (0 for simple types)
595 *
596 * These two values are encoded in the high and low halves of a GLint.
597 * By putting the uniform number in the high part and the offset in the
598 * low part, we can support the unofficial ability to index into arrays
599 * by adding offsets to the location value.
600 */
601 static void
602 merge_location_offset(GLint *location, GLint offset)
603 {
604 *location = (*location << 16) | offset;
605 }
606
607
608 /**
609 * Separate the uniform location and parameter offset. See above.
610 */
611 static void
612 split_location_offset(GLint *location, GLint *offset)
613 {
614 *offset = *location & 0xffff;
615 *location = *location >> 16;
616 }
617
618
619
620 /**
621 * Called via glGetUniformfv().
622 */
623 static void
624 _mesa_get_uniformfv(struct gl_context *ctx, GLuint program, GLint location,
625 GLfloat *params)
626 {
627 struct gl_program *prog;
628 GLint paramPos;
629 GLint offset;
630
631 split_location_offset(&location, &offset);
632
633 lookup_uniform_parameter(ctx, program, location, &prog, &paramPos);
634
635 if (prog) {
636 const struct gl_program_parameter *p =
637 &prog->Parameters->Parameters[paramPos];
638 GLint rows, cols, i, j, k;
639
640 get_uniform_rows_cols(p, &rows, &cols);
641
642 k = 0;
643 for (i = 0; i < rows; i++) {
644 for (j = 0; j < cols; j++ ) {
645 params[k++] = prog->Parameters->ParameterValues[paramPos+i][j];
646 }
647 }
648 }
649 }
650
651
652 /**
653 * Called via glGetUniformiv().
654 * \sa _mesa_get_uniformfv, only difference is a cast.
655 */
656 static void
657 _mesa_get_uniformiv(struct gl_context *ctx, GLuint program, GLint location,
658 GLint *params)
659 {
660 struct gl_program *prog;
661 GLint paramPos;
662 GLint offset;
663
664 split_location_offset(&location, &offset);
665
666 lookup_uniform_parameter(ctx, program, location, &prog, &paramPos);
667
668 if (prog) {
669 const struct gl_program_parameter *p =
670 &prog->Parameters->Parameters[paramPos];
671 GLint rows, cols, i, j, k;
672
673 get_uniform_rows_cols(p, &rows, &cols);
674
675 k = 0;
676 for (i = 0; i < rows; i++) {
677 for (j = 0; j < cols; j++ ) {
678 params[k++] = (GLint) prog->Parameters->ParameterValues[paramPos+i][j];
679 }
680 }
681 }
682 }
683
684
685 /**
686 * Called via glGetUniformuiv().
687 * New in GL_EXT_gpu_shader4, OpenGL 3.0
688 * \sa _mesa_get_uniformfv, only difference is a cast.
689 */
690 static void
691 _mesa_get_uniformuiv(struct gl_context *ctx, GLuint program, GLint location,
692 GLuint *params)
693 {
694 struct gl_program *prog;
695 GLint paramPos;
696 GLint offset;
697
698 split_location_offset(&location, &offset);
699
700 lookup_uniform_parameter(ctx, program, location, &prog, &paramPos);
701
702 if (prog) {
703 const struct gl_program_parameter *p =
704 &prog->Parameters->Parameters[paramPos];
705 GLint rows, cols, i, j, k;
706
707 get_uniform_rows_cols(p, &rows, &cols);
708
709 k = 0;
710 for (i = 0; i < rows; i++) {
711 for (j = 0; j < cols; j++ ) {
712 params[k++] = (GLuint) prog->Parameters->ParameterValues[paramPos+i][j];
713 }
714 }
715 }
716 }
717
718
719 /**
720 * Called via glGetUniformLocation().
721 *
722 * The return value will encode two values, the uniform location and an
723 * offset (used for arrays, structs).
724 */
725 GLint
726 _mesa_get_uniform_location(struct gl_context *ctx, struct gl_shader_program *shProg,
727 const GLchar *name)
728 {
729 GLint offset = 0, location = -1;
730
731 if (shProg->LinkStatus == GL_FALSE) {
732 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfv(program)");
733 return -1;
734 }
735
736 /* XXX we should return -1 if the uniform was declared, but not
737 * actually used.
738 */
739
740 /* XXX we need to be able to parse uniform names for structs and arrays
741 * such as:
742 * mymatrix[1]
743 * mystruct.field1
744 */
745
746 {
747 /* handle 1-dimension arrays here... */
748 char *c = strchr(name, '[');
749 if (c) {
750 /* truncate name at [ */
751 const GLint len = c - name;
752 GLchar *newName = malloc(len + 1);
753 if (!newName)
754 return -1; /* out of mem */
755 memcpy(newName, name, len);
756 newName[len] = 0;
757
758 location = _mesa_lookup_uniform(shProg->Uniforms, newName);
759 if (location >= 0) {
760 const GLint element = atoi(c + 1);
761 if (element > 0) {
762 /* get type of the uniform array element */
763 struct gl_program_parameter *p;
764 p = get_uniform_parameter(shProg, location);
765 if (p) {
766 GLint rows, cols;
767 get_matrix_dims(p->DataType, &rows, &cols);
768 if (rows < 1)
769 rows = 1;
770 offset = element * rows;
771 }
772 }
773 }
774
775 free(newName);
776 }
777 }
778
779 if (location < 0) {
780 location = _mesa_lookup_uniform(shProg->Uniforms, name);
781 }
782
783 if (location >= 0) {
784 merge_location_offset(&location, offset);
785 }
786
787 return location;
788 }
789
790
791
792 /**
793 * Update the vertex/fragment program's TexturesUsed array.
794 *
795 * This needs to be called after glUniform(set sampler var) is called.
796 * A call to glUniform(samplerVar, value) causes a sampler to point to a
797 * particular texture unit. We know the sampler's texture target
798 * (1D/2D/3D/etc) from compile time but the sampler's texture unit is
799 * set by glUniform() calls.
800 *
801 * So, scan the program->SamplerUnits[] and program->SamplerTargets[]
802 * information to update the prog->TexturesUsed[] values.
803 * Each value of TexturesUsed[unit] is one of zero, TEXTURE_1D_INDEX,
804 * TEXTURE_2D_INDEX, TEXTURE_3D_INDEX, etc.
805 * We'll use that info for state validation before rendering.
806 */
807 void
808 _mesa_update_shader_textures_used(struct gl_program *prog)
809 {
810 GLuint s;
811
812 memset(prog->TexturesUsed, 0, sizeof(prog->TexturesUsed));
813
814 for (s = 0; s < MAX_SAMPLERS; s++) {
815 if (prog->SamplersUsed & (1 << s)) {
816 GLuint unit = prog->SamplerUnits[s];
817 GLuint tgt = prog->SamplerTargets[s];
818 assert(unit < MAX_TEXTURE_IMAGE_UNITS);
819 assert(tgt < NUM_TEXTURE_TARGETS);
820 prog->TexturesUsed[unit] |= (1 << tgt);
821 }
822 }
823 }
824
825
826 /**
827 * Check if the type given by userType is allowed to set a uniform of the
828 * target type. Generally, equivalence is required, but setting Boolean
829 * uniforms can be done with glUniformiv or glUniformfv.
830 */
831 static GLboolean
832 compatible_types(GLenum userType, GLenum targetType)
833 {
834 if (userType == targetType)
835 return GL_TRUE;
836
837 if (targetType == GL_BOOL && (userType == GL_FLOAT ||
838 userType == GL_UNSIGNED_INT ||
839 userType == GL_INT))
840 return GL_TRUE;
841
842 if (targetType == GL_BOOL_VEC2 && (userType == GL_FLOAT_VEC2 ||
843 userType == GL_UNSIGNED_INT_VEC2 ||
844 userType == GL_INT_VEC2))
845 return GL_TRUE;
846
847 if (targetType == GL_BOOL_VEC3 && (userType == GL_FLOAT_VEC3 ||
848 userType == GL_UNSIGNED_INT_VEC3 ||
849 userType == GL_INT_VEC3))
850 return GL_TRUE;
851
852 if (targetType == GL_BOOL_VEC4 && (userType == GL_FLOAT_VEC4 ||
853 userType == GL_UNSIGNED_INT_VEC4 ||
854 userType == GL_INT_VEC4))
855 return GL_TRUE;
856
857 if (is_sampler_type(targetType) && userType == GL_INT)
858 return GL_TRUE;
859
860 return GL_FALSE;
861 }
862
863
864 /**
865 * Set the value of a program's uniform variable.
866 * \param program the program whose uniform to update
867 * \param index the index of the program parameter for the uniform
868 * \param offset additional parameter slot offset (for arrays)
869 * \param type the incoming datatype of 'values'
870 * \param count the number of uniforms to set
871 * \param elems number of elements per uniform (1, 2, 3 or 4)
872 * \param values the new values, of datatype 'type'
873 */
874 static void
875 set_program_uniform(struct gl_context *ctx, struct gl_program *program,
876 GLint index, GLint offset,
877 GLenum type, GLsizei count, GLint elems,
878 const void *values)
879 {
880 const struct gl_program_parameter *param =
881 &program->Parameters->Parameters[index];
882
883 assert(offset >= 0);
884 assert(elems >= 1);
885 assert(elems <= 4);
886
887 if (!compatible_types(type, param->DataType)) {
888 _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(type mismatch)");
889 return;
890 }
891
892 if (index + offset > (GLint) program->Parameters->Size) {
893 /* out of bounds! */
894 return;
895 }
896
897 if (param->Type == PROGRAM_SAMPLER) {
898 /* This controls which texture unit which is used by a sampler */
899 GLboolean changed = GL_FALSE;
900 GLint i;
901
902 /* this should have been caught by the compatible_types() check */
903 ASSERT(type == GL_INT);
904
905 /* loop over number of samplers to change */
906 for (i = 0; i < count; i++) {
907 GLuint sampler =
908 (GLuint) program->Parameters->ParameterValues[index + offset + i][0];
909 GLuint texUnit = ((GLuint *) values)[i];
910
911 /* check that the sampler (tex unit index) is legal */
912 if (texUnit >= ctx->Const.MaxTextureImageUnits) {
913 _mesa_error(ctx, GL_INVALID_VALUE,
914 "glUniform1(invalid sampler/tex unit index for '%s')",
915 param->Name);
916 return;
917 }
918
919 /* This maps a sampler to a texture unit: */
920 if (sampler < MAX_SAMPLERS) {
921 #if 0
922 printf("Set program %p sampler %d '%s' to unit %u\n",
923 program, sampler, param->Name, texUnit);
924 #endif
925 if (program->SamplerUnits[sampler] != texUnit) {
926 program->SamplerUnits[sampler] = texUnit;
927 changed = GL_TRUE;
928 }
929 }
930 }
931
932 if (changed) {
933 /* When a sampler's value changes it usually requires rewriting
934 * a GPU program's TEX instructions since there may not be a
935 * sampler->texture lookup table. We signal this with the
936 * ProgramStringNotify() callback.
937 */
938 FLUSH_VERTICES(ctx, _NEW_TEXTURE | _NEW_PROGRAM);
939 _mesa_update_shader_textures_used(program);
940 /* Do we need to care about the return value here?
941 * This should not be the first time the driver was notified of
942 * this program.
943 */
944 (void) ctx->Driver.ProgramStringNotify(ctx, program->Target, program);
945 }
946 }
947 else {
948 /* ordinary uniform variable */
949 const GLboolean isUniformBool = is_boolean_type(param->DataType);
950 const GLenum basicType = base_uniform_type(type);
951 const GLint slots = (param->Size + 3) / 4;
952 const GLint typeSize = _mesa_sizeof_glsl_type(param->DataType);
953 GLsizei k, i;
954
955 if ((GLint) param->Size > typeSize) {
956 /* an array */
957 /* we'll ignore extra data below */
958 }
959 else {
960 /* non-array: count must be at most one; count == 0 is handled by the loop below */
961 if (count > 1) {
962 _mesa_error(ctx, GL_INVALID_OPERATION,
963 "glUniform(uniform '%s' is not an array)",
964 param->Name);
965 return;
966 }
967 }
968
969 /* loop over number of array elements */
970 for (k = 0; k < count; k++) {
971 GLfloat *uniformVal;
972
973 if (offset + k >= slots) {
974 /* Extra array data is ignored */
975 break;
976 }
977
978 /* uniformVal (the destination) is always float[4] */
979 uniformVal = program->Parameters->ParameterValues[index + offset + k];
980
981 if (basicType == GL_INT) {
982 /* convert user's ints to floats */
983 const GLint *iValues = ((const GLint *) values) + k * elems;
984 for (i = 0; i < elems; i++) {
985 uniformVal[i] = (GLfloat) iValues[i];
986 }
987 }
988 else if (basicType == GL_UNSIGNED_INT) {
989 /* convert user's uints to floats */
990 const GLuint *iValues = ((const GLuint *) values) + k * elems;
991 for (i = 0; i < elems; i++) {
992 uniformVal[i] = (GLfloat) iValues[i];
993 }
994 }
995 else {
996 const GLfloat *fValues = ((const GLfloat *) values) + k * elems;
997 assert(basicType == GL_FLOAT);
998 for (i = 0; i < elems; i++) {
999 uniformVal[i] = fValues[i];
1000 }
1001 }
1002
1003 /* if the uniform is bool-valued, convert to 1.0 or 0.0 */
1004 if (isUniformBool) {
1005 for (i = 0; i < elems; i++) {
1006 uniformVal[i] = uniformVal[i] ? 1.0f : 0.0f;
1007 }
1008 }
1009 }
1010 }
1011 }
1012
1013
1014 /**
1015 * Called via glUniform*() functions.
1016 */
1017 void
1018 _mesa_uniform(struct gl_context *ctx, struct gl_shader_program *shProg,
1019 GLint location, GLsizei count,
1020 const GLvoid *values, GLenum type)
1021 {
1022 struct gl_uniform *uniform;
1023 GLint elems, offset;
1024
1025 if (!shProg || !shProg->LinkStatus) {
1026 _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(program not linked)");
1027 return;
1028 }
1029
1030 if (location == -1)
1031 return; /* The standard specifies this as a no-op */
1032
1033 if (location < -1) {
1034 _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(location=%d)",
1035 location);
1036 return;
1037 }
1038
1039 split_location_offset(&location, &offset);
1040
1041 if (location < 0 || location >= (GLint) shProg->Uniforms->NumUniforms) {
1042 _mesa_error(ctx, GL_INVALID_VALUE, "glUniform(location=%d)", location);
1043 return;
1044 }
1045
1046 if (count < 0) {
1047 _mesa_error(ctx, GL_INVALID_VALUE, "glUniform(count < 0)");
1048 return;
1049 }
1050
1051 elems = _mesa_sizeof_glsl_type(type);
1052
1053 FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
1054
1055 uniform = &shProg->Uniforms->Uniforms[location];
1056
1057 if (ctx->Shader.Flags & GLSL_UNIFORMS) {
1058 const GLenum basicType = base_uniform_type(type);
1059 GLint i;
1060 printf("Mesa: set program %u uniform %s (loc %d) to: ",
1061 shProg->Name, uniform->Name, location);
1062 if (basicType == GL_INT) {
1063 const GLint *v = (const GLint *) values;
1064 for (i = 0; i < count * elems; i++) {
1065 printf("%d ", v[i]);
1066 }
1067 }
1068 else if (basicType == GL_UNSIGNED_INT) {
1069 const GLuint *v = (const GLuint *) values;
1070 for (i = 0; i < count * elems; i++) {
1071 printf("%u ", v[i]);
1072 }
1073 }
1074 else {
1075 const GLfloat *v = (const GLfloat *) values;
1076 assert(basicType == GL_FLOAT);
1077 for (i = 0; i < count * elems; i++) {
1078 printf("%g ", v[i]);
1079 }
1080 }
1081 printf("\n");
1082 }
1083
1084 /* A uniform var may be used by both a vertex shader and a fragment
1085 * shader. We may need to update one or both shader's uniform here:
1086 */
1087 if (shProg->VertexProgram) {
1088 /* convert uniform location to program parameter index */
1089 GLint index = uniform->VertPos;
1090 if (index >= 0) {
1091 set_program_uniform(ctx, &shProg->VertexProgram->Base,
1092 index, offset, type, count, elems, values);
1093 }
1094 }
1095
1096 if (shProg->FragmentProgram) {
1097 /* convert uniform location to program parameter index */
1098 GLint index = uniform->FragPos;
1099 if (index >= 0) {
1100 set_program_uniform(ctx, &shProg->FragmentProgram->Base,
1101 index, offset, type, count, elems, values);
1102 }
1103 }
1104
1105 if (shProg->GeometryProgram) {
1106 /* convert uniform location to program parameter index */
1107 GLint index = uniform->GeomPos;
1108 if (index >= 0) {
1109 set_program_uniform(ctx, &shProg->GeometryProgram->Base,
1110 index, offset, type, count, elems, values);
1111 }
1112 }
1113
1114 uniform->Initialized = GL_TRUE;
1115 }
1116
1117
1118 /**
1119 * Set a matrix-valued program parameter.
1120 */
1121 static void
1122 set_program_uniform_matrix(struct gl_context *ctx, struct gl_program *program,
1123 GLuint index, GLuint offset,
1124 GLuint count, GLuint rows, GLuint cols,
1125 GLboolean transpose, const GLfloat *values)
1126 {
1127 GLuint mat, row, col;
1128 GLuint src = 0;
1129 const struct gl_program_parameter * param = &program->Parameters->Parameters[index];
1130 const GLuint slots = (param->Size + 3) / 4;
1131 const GLint typeSize = _mesa_sizeof_glsl_type(param->DataType);
1132 GLint nr, nc;
1133
1134 /* check that the number of rows, columns is correct */
1135 get_matrix_dims(param->DataType, &nr, &nc);
1136 if (rows != nr || cols != nc) {
1137 _mesa_error(ctx, GL_INVALID_OPERATION,
1138 "glUniformMatrix(matrix size mismatch)");
1139 return;
1140 }
1141
1142 if ((GLint) param->Size <= typeSize) {
1143 /* non-array: count must be at most one; count == 0 is handled by the loop below */
1144 if (count > 1) {
1145 _mesa_error(ctx, GL_INVALID_OPERATION,
1146 "glUniformMatrix(uniform is not an array)");
1147 return;
1148 }
1149 }
1150
1151 /*
1152 * Note: the _columns_ of a matrix are stored in program registers, not
1153 * the rows. So, the loops below look a little funny.
1154 * XXX could optimize this a bit...
1155 */
1156
1157 /* loop over matrices */
1158 for (mat = 0; mat < count; mat++) {
1159
1160 /* each matrix: */
1161 for (col = 0; col < cols; col++) {
1162 GLfloat *v;
1163 if (offset >= slots) {
1164 /* Ignore writes beyond the end of (the used part of) an array */
1165 return;
1166 }
1167 v = program->Parameters->ParameterValues[index + offset];
1168 for (row = 0; row < rows; row++) {
1169 if (transpose) {
1170 v[row] = values[src + row * cols + col];
1171 }
1172 else {
1173 v[row] = values[src + col * rows + row];
1174 }
1175 }
1176
1177 offset++;
1178 }
1179
1180 src += rows * cols; /* next matrix */
1181 }
1182 }
1183
1184
1185 /**
1186 * Called by glUniformMatrix*() functions.
1187 * Note: cols=2, rows=4 ==> array[2] of vec4
1188 */
1189 void
1190 _mesa_uniform_matrix(struct gl_context *ctx, struct gl_shader_program *shProg,
1191 GLint cols, GLint rows,
1192 GLint location, GLsizei count,
1193 GLboolean transpose, const GLfloat *values)
1194 {
1195 struct gl_uniform *uniform;
1196 GLint offset;
1197
1198 if (!shProg || !shProg->LinkStatus) {
1199 _mesa_error(ctx, GL_INVALID_OPERATION,
1200 "glUniformMatrix(program not linked)");
1201 return;
1202 }
1203
1204 if (location == -1)
1205 return; /* The standard specifies this as a no-op */
1206
1207 if (location < -1) {
1208 _mesa_error(ctx, GL_INVALID_OPERATION, "glUniformMatrix(location)");
1209 return;
1210 }
1211
1212 split_location_offset(&location, &offset);
1213
1214 if (location < 0 || location >= (GLint) shProg->Uniforms->NumUniforms) {
1215 _mesa_error(ctx, GL_INVALID_VALUE, "glUniformMatrix(location)");
1216 return;
1217 }
1218 if (values == NULL) {
1219 _mesa_error(ctx, GL_INVALID_VALUE, "glUniformMatrix");
1220 return;
1221 }
1222
1223 FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
1224
1225 uniform = &shProg->Uniforms->Uniforms[location];
1226
1227 if (shProg->VertexProgram) {
1228 /* convert uniform location to program parameter index */
1229 GLint index = uniform->VertPos;
1230 if (index >= 0) {
1231 set_program_uniform_matrix(ctx, &shProg->VertexProgram->Base,
1232 index, offset,
1233 count, rows, cols, transpose, values);
1234 }
1235 }
1236
1237 if (shProg->FragmentProgram) {
1238 /* convert uniform location to program parameter index */
1239 GLint index = uniform->FragPos;
1240 if (index >= 0) {
1241 set_program_uniform_matrix(ctx, &shProg->FragmentProgram->Base,
1242 index, offset,
1243 count, rows, cols, transpose, values);
1244 }
1245 }
1246
1247 if (shProg->GeometryProgram) {
1248 /* convert uniform location to program parameter index */
1249 GLint index = uniform->GeomPos;
1250 if (index >= 0) {
1251 set_program_uniform_matrix(ctx, &shProg->GeometryProgram->Base,
1252 index, offset,
1253 count, rows, cols, transpose, values);
1254 }
1255 }
1256
1257 uniform->Initialized = GL_TRUE;
1258 }
1259
1260
1261 void GLAPIENTRY
1262 _mesa_Uniform1fARB(GLint location, GLfloat v0)
1263 {
1264 GET_CURRENT_CONTEXT(ctx);
1265 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, &v0, GL_FLOAT);
1266 }
1267
1268 void GLAPIENTRY
1269 _mesa_Uniform2fARB(GLint location, GLfloat v0, GLfloat v1)
1270 {
1271 GET_CURRENT_CONTEXT(ctx);
1272 GLfloat v[2];
1273 v[0] = v0;
1274 v[1] = v1;
1275 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_FLOAT_VEC2);
1276 }
1277
1278 void GLAPIENTRY
1279 _mesa_Uniform3fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
1280 {
1281 GET_CURRENT_CONTEXT(ctx);
1282 GLfloat v[3];
1283 v[0] = v0;
1284 v[1] = v1;
1285 v[2] = v2;
1286 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_FLOAT_VEC3);
1287 }
1288
1289 void GLAPIENTRY
1290 _mesa_Uniform4fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2,
1291 GLfloat v3)
1292 {
1293 GET_CURRENT_CONTEXT(ctx);
1294 GLfloat v[4];
1295 v[0] = v0;
1296 v[1] = v1;
1297 v[2] = v2;
1298 v[3] = v3;
1299 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_FLOAT_VEC4);
1300 }
1301
1302 void GLAPIENTRY
1303 _mesa_Uniform1iARB(GLint location, GLint v0)
1304 {
1305 GET_CURRENT_CONTEXT(ctx);
1306 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, &v0, GL_INT);
1307 }
1308
1309 void GLAPIENTRY
1310 _mesa_Uniform2iARB(GLint location, GLint v0, GLint v1)
1311 {
1312 GET_CURRENT_CONTEXT(ctx);
1313 GLint v[2];
1314 v[0] = v0;
1315 v[1] = v1;
1316 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_INT_VEC2);
1317 }
1318
1319 void GLAPIENTRY
1320 _mesa_Uniform3iARB(GLint location, GLint v0, GLint v1, GLint v2)
1321 {
1322 GET_CURRENT_CONTEXT(ctx);
1323 GLint v[3];
1324 v[0] = v0;
1325 v[1] = v1;
1326 v[2] = v2;
1327 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_INT_VEC3);
1328 }
1329
1330 void GLAPIENTRY
1331 _mesa_Uniform4iARB(GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
1332 {
1333 GET_CURRENT_CONTEXT(ctx);
1334 GLint v[4];
1335 v[0] = v0;
1336 v[1] = v1;
1337 v[2] = v2;
1338 v[3] = v3;
1339 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_INT_VEC4);
1340 }
1341
1342 void GLAPIENTRY
1343 _mesa_Uniform1fvARB(GLint location, GLsizei count, const GLfloat * value)
1344 {
1345 GET_CURRENT_CONTEXT(ctx);
1346 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_FLOAT);
1347 }
1348
1349 void GLAPIENTRY
1350 _mesa_Uniform2fvARB(GLint location, GLsizei count, const GLfloat * value)
1351 {
1352 GET_CURRENT_CONTEXT(ctx);
1353 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_FLOAT_VEC2);
1354 }
1355
1356 void GLAPIENTRY
1357 _mesa_Uniform3fvARB(GLint location, GLsizei count, const GLfloat * value)
1358 {
1359 GET_CURRENT_CONTEXT(ctx);
1360 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_FLOAT_VEC3);
1361 }
1362
1363 void GLAPIENTRY
1364 _mesa_Uniform4fvARB(GLint location, GLsizei count, const GLfloat * value)
1365 {
1366 GET_CURRENT_CONTEXT(ctx);
1367 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_FLOAT_VEC4);
1368 }
1369
1370 void GLAPIENTRY
1371 _mesa_Uniform1ivARB(GLint location, GLsizei count, const GLint * value)
1372 {
1373 GET_CURRENT_CONTEXT(ctx);
1374 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_INT);
1375 }
1376
1377 void GLAPIENTRY
1378 _mesa_Uniform2ivARB(GLint location, GLsizei count, const GLint * value)
1379 {
1380 GET_CURRENT_CONTEXT(ctx);
1381 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_INT_VEC2);
1382 }
1383
1384 void GLAPIENTRY
1385 _mesa_Uniform3ivARB(GLint location, GLsizei count, const GLint * value)
1386 {
1387 GET_CURRENT_CONTEXT(ctx);
1388 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_INT_VEC3);
1389 }
1390
1391 void GLAPIENTRY
1392 _mesa_Uniform4ivARB(GLint location, GLsizei count, const GLint * value)
1393 {
1394 GET_CURRENT_CONTEXT(ctx);
1395 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_INT_VEC4);
1396 }
1397
1398
1399 /** OpenGL 3.0 GLuint-valued functions **/
1400 void GLAPIENTRY
1401 _mesa_Uniform1ui(GLint location, GLuint v0)
1402 {
1403 GET_CURRENT_CONTEXT(ctx);
1404 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, &v0, GL_UNSIGNED_INT);
1405 }
1406
1407 void GLAPIENTRY
1408 _mesa_Uniform2ui(GLint location, GLuint v0, GLuint v1)
1409 {
1410 GET_CURRENT_CONTEXT(ctx);
1411 GLuint v[2];
1412 v[0] = v0;
1413 v[1] = v1;
1414 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_UNSIGNED_INT_VEC2);
1415 }
1416
1417 void GLAPIENTRY
1418 _mesa_Uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2)
1419 {
1420 GET_CURRENT_CONTEXT(ctx);
1421 GLuint v[3];
1422 v[0] = v0;
1423 v[1] = v1;
1424 v[2] = v2;
1425 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_UNSIGNED_INT_VEC3);
1426 }
1427
1428 void GLAPIENTRY
1429 _mesa_Uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3)
1430 {
1431 GET_CURRENT_CONTEXT(ctx);
1432 GLuint v[4];
1433 v[0] = v0;
1434 v[1] = v1;
1435 v[2] = v2;
1436 v[3] = v3;
1437 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, 1, v, GL_UNSIGNED_INT_VEC4);
1438 }
1439
1440 void GLAPIENTRY
1441 _mesa_Uniform1uiv(GLint location, GLsizei count, const GLuint *value)
1442 {
1443 GET_CURRENT_CONTEXT(ctx);
1444 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_UNSIGNED_INT);
1445 }
1446
1447 void GLAPIENTRY
1448 _mesa_Uniform2uiv(GLint location, GLsizei count, const GLuint *value)
1449 {
1450 GET_CURRENT_CONTEXT(ctx);
1451 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_UNSIGNED_INT_VEC2);
1452 }
1453
1454 void GLAPIENTRY
1455 _mesa_Uniform3uiv(GLint location, GLsizei count, const GLuint *value)
1456 {
1457 GET_CURRENT_CONTEXT(ctx);
1458 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_UNSIGNED_INT_VEC3);
1459 }
1460
1461 void GLAPIENTRY
1462 _mesa_Uniform4uiv(GLint location, GLsizei count, const GLuint *value)
1463 {
1464 GET_CURRENT_CONTEXT(ctx);
1465 _mesa_uniform(ctx, ctx->Shader.ActiveProgram, location, count, value, GL_UNSIGNED_INT_VEC4);
1466 }
1467
1468
1469
1470 void GLAPIENTRY
1471 _mesa_UniformMatrix2fvARB(GLint location, GLsizei count, GLboolean transpose,
1472 const GLfloat * value)
1473 {
1474 GET_CURRENT_CONTEXT(ctx);
1475 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
1476 2, 2, location, count, transpose, value);
1477 }
1478
1479 void GLAPIENTRY
1480 _mesa_UniformMatrix3fvARB(GLint location, GLsizei count, GLboolean transpose,
1481 const GLfloat * value)
1482 {
1483 GET_CURRENT_CONTEXT(ctx);
1484 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
1485 3, 3, location, count, transpose, value);
1486 }
1487
1488 void GLAPIENTRY
1489 _mesa_UniformMatrix4fvARB(GLint location, GLsizei count, GLboolean transpose,
1490 const GLfloat * value)
1491 {
1492 GET_CURRENT_CONTEXT(ctx);
1493 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
1494 4, 4, location, count, transpose, value);
1495 }
1496
1497
1498 /**
1499 * Non-square UniformMatrix are OpenGL 2.1
1500 */
1501 void GLAPIENTRY
1502 _mesa_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose,
1503 const GLfloat *value)
1504 {
1505 GET_CURRENT_CONTEXT(ctx);
1506 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
1507 2, 3, location, count, transpose, value);
1508 }
1509
1510 void GLAPIENTRY
1511 _mesa_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose,
1512 const GLfloat *value)
1513 {
1514 GET_CURRENT_CONTEXT(ctx);
1515 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
1516 3, 2, location, count, transpose, value);
1517 }
1518
1519 void GLAPIENTRY
1520 _mesa_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose,
1521 const GLfloat *value)
1522 {
1523 GET_CURRENT_CONTEXT(ctx);
1524 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
1525 2, 4, location, count, transpose, value);
1526 }
1527
1528 void GLAPIENTRY
1529 _mesa_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose,
1530 const GLfloat *value)
1531 {
1532 GET_CURRENT_CONTEXT(ctx);
1533 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
1534 4, 2, location, count, transpose, value);
1535 }
1536
1537 void GLAPIENTRY
1538 _mesa_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose,
1539 const GLfloat *value)
1540 {
1541 GET_CURRENT_CONTEXT(ctx);
1542 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
1543 3, 4, location, count, transpose, value);
1544 }
1545
1546 void GLAPIENTRY
1547 _mesa_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose,
1548 const GLfloat *value)
1549 {
1550 GET_CURRENT_CONTEXT(ctx);
1551 _mesa_uniform_matrix(ctx, ctx->Shader.ActiveProgram,
1552 4, 3, location, count, transpose, value);
1553 }
1554
1555
1556 void GLAPIENTRY
1557 _mesa_GetUniformfvARB(GLhandleARB program, GLint location, GLfloat *params)
1558 {
1559 GET_CURRENT_CONTEXT(ctx);
1560 _mesa_get_uniformfv(ctx, program, location, params);
1561 }
1562
1563
1564 void GLAPIENTRY
1565 _mesa_GetUniformivARB(GLhandleARB program, GLint location, GLint *params)
1566 {
1567 GET_CURRENT_CONTEXT(ctx);
1568 _mesa_get_uniformiv(ctx, program, location, params);
1569 }
1570
1571
1572 /* GL3 */
1573 void GLAPIENTRY
1574 _mesa_GetUniformuiv(GLhandleARB program, GLint location, GLuint *params)
1575 {
1576 GET_CURRENT_CONTEXT(ctx);
1577 _mesa_get_uniformuiv(ctx, program, location, params);
1578 }
1579
1580
1581
1582 GLint GLAPIENTRY
1583 _mesa_GetUniformLocationARB(GLhandleARB programObj, const GLcharARB *name)
1584 {
1585 struct gl_shader_program *shProg;
1586
1587 GET_CURRENT_CONTEXT(ctx);
1588
1589 shProg = _mesa_lookup_shader_program_err(ctx, programObj,
1590 "glGetUniformLocation");
1591 if (!shProg)
1592 return -1;
1593
1594 return _mesa_get_uniform_location(ctx, shProg, name);
1595 }
1596
1597
1598 void GLAPIENTRY
1599 _mesa_GetActiveUniformARB(GLhandleARB program, GLuint index,
1600 GLsizei maxLength, GLsizei * length, GLint * size,
1601 GLenum * type, GLcharARB * name)
1602 {
1603 GET_CURRENT_CONTEXT(ctx);
1604 _mesa_get_active_uniform(ctx, program, index, maxLength, length, size,
1605 type, name);
1606 }
1607
1608
1609 /**
1610 * Plug in shader uniform-related functions into API dispatch table.
1611 */
1612 void
1613 _mesa_init_shader_uniform_dispatch(struct _glapi_table *exec)
1614 {
1615 #if FEATURE_GL
1616 SET_Uniform1fARB(exec, _mesa_Uniform1fARB);
1617 SET_Uniform2fARB(exec, _mesa_Uniform2fARB);
1618 SET_Uniform3fARB(exec, _mesa_Uniform3fARB);
1619 SET_Uniform4fARB(exec, _mesa_Uniform4fARB);
1620 SET_Uniform1iARB(exec, _mesa_Uniform1iARB);
1621 SET_Uniform2iARB(exec, _mesa_Uniform2iARB);
1622 SET_Uniform3iARB(exec, _mesa_Uniform3iARB);
1623 SET_Uniform4iARB(exec, _mesa_Uniform4iARB);
1624 SET_Uniform1fvARB(exec, _mesa_Uniform1fvARB);
1625 SET_Uniform2fvARB(exec, _mesa_Uniform2fvARB);
1626 SET_Uniform3fvARB(exec, _mesa_Uniform3fvARB);
1627 SET_Uniform4fvARB(exec, _mesa_Uniform4fvARB);
1628 SET_Uniform1ivARB(exec, _mesa_Uniform1ivARB);
1629 SET_Uniform2ivARB(exec, _mesa_Uniform2ivARB);
1630 SET_Uniform3ivARB(exec, _mesa_Uniform3ivARB);
1631 SET_Uniform4ivARB(exec, _mesa_Uniform4ivARB);
1632 SET_UniformMatrix2fvARB(exec, _mesa_UniformMatrix2fvARB);
1633 SET_UniformMatrix3fvARB(exec, _mesa_UniformMatrix3fvARB);
1634 SET_UniformMatrix4fvARB(exec, _mesa_UniformMatrix4fvARB);
1635
1636 SET_GetActiveUniformARB(exec, _mesa_GetActiveUniformARB);
1637 SET_GetUniformLocationARB(exec, _mesa_GetUniformLocationARB);
1638 SET_GetUniformfvARB(exec, _mesa_GetUniformfvARB);
1639 SET_GetUniformivARB(exec, _mesa_GetUniformivARB);
1640
1641 /* OpenGL 2.1 */
1642 SET_UniformMatrix2x3fv(exec, _mesa_UniformMatrix2x3fv);
1643 SET_UniformMatrix3x2fv(exec, _mesa_UniformMatrix3x2fv);
1644 SET_UniformMatrix2x4fv(exec, _mesa_UniformMatrix2x4fv);
1645 SET_UniformMatrix4x2fv(exec, _mesa_UniformMatrix4x2fv);
1646 SET_UniformMatrix3x4fv(exec, _mesa_UniformMatrix3x4fv);
1647 SET_UniformMatrix4x3fv(exec, _mesa_UniformMatrix4x3fv);
1648
1649 /* OpenGL 3.0 */
1650 /* XXX finish dispatch */
1651 SET_Uniform1uiEXT(exec, _mesa_Uniform1ui);
1652 SET_Uniform2uiEXT(exec, _mesa_Uniform2ui);
1653 SET_Uniform3uiEXT(exec, _mesa_Uniform3ui);
1654 SET_Uniform4uiEXT(exec, _mesa_Uniform4ui);
1655 SET_Uniform1uivEXT(exec, _mesa_Uniform1uiv);
1656 SET_Uniform2uivEXT(exec, _mesa_Uniform2uiv);
1657 SET_Uniform3uivEXT(exec, _mesa_Uniform3uiv);
1658 SET_Uniform4uivEXT(exec, _mesa_Uniform4uiv);
1659 SET_GetUniformuivEXT(exec, _mesa_GetUniformuiv);
1660
1661
1662 #endif /* FEATURE_GL */
1663 }