#define LONGSTRING __extension__ in imports.h and use it to silence gcc
[mesa.git] / src / mesa / shader / shaderobjects.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 6.5
4 *
5 * Copyright (C) 2004-2006 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 /**
26 * \file shaderobjects.c
27 * ARB_shader_objects state management functions
28 * \author Michal Krol
29 */
30
31
32 #include "glheader.h"
33 #include "context.h"
34 #include "hash.h"
35 #include "shaderobjects.h"
36 #include "shaderobjects_3dlabs.h"
37
38
39 #if FEATURE_ARB_shader_objects
40
41 #define RELEASE_GENERIC(x)\
42 (**x)._unknown.Release ((struct gl2_unknown_intf **) (x))
43
44 #define RELEASE_CONTAINER(x)\
45 (**x)._generic._unknown.Release ((struct gl2_unknown_intf **) (x))
46
47 #define RELEASE_PROGRAM(x)\
48 (**x)._container._generic._unknown.Release ((struct gl2_unknown_intf **) (x))
49
50 #define RELEASE_SHADER(x)\
51 (**x)._generic._unknown.Release ((struct gl2_unknown_intf **) (x))
52
53
54
55 static struct gl2_unknown_intf **
56 lookup_handle(GLcontext * ctx, GLhandleARB handle, enum gl2_uiid uiid,
57 const char *function)
58 {
59 struct gl2_unknown_intf **unk;
60
61 /*
62 * Note: _mesa_HashLookup() requires non-zero input values, so the
63 * passed-in handle value must be checked beforehand.
64 */
65 if (handle == 0) {
66 _mesa_error(ctx, GL_INVALID_VALUE, function);
67 return NULL;
68 }
69 _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
70 unk = (struct gl2_unknown_intf **) _mesa_HashLookup(ctx->Shared->GL2Objects,
71 handle);
72 _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
73
74 if (unk == NULL) {
75 _mesa_error(ctx, GL_INVALID_VALUE, function);
76 }
77 else {
78 unk = (**unk).QueryInterface(unk, uiid);
79 if (unk == NULL)
80 _mesa_error(ctx, GL_INVALID_OPERATION, function);
81 }
82 return unk;
83 }
84
85 #define GET_GENERIC(x, handle, function)\
86 struct gl2_generic_intf **x = (struct gl2_generic_intf **)\
87 lookup_handle (ctx, handle, UIID_GENERIC, function);
88
89 #define GET_CONTAINER(x, handle, function)\
90 struct gl2_container_intf **x = (struct gl2_container_intf **)\
91 lookup_handle (ctx, handle, UIID_CONTAINER, function);
92
93 #define GET_PROGRAM(x, handle, function)\
94 struct gl2_program_intf **x = (struct gl2_program_intf **)\
95 lookup_handle (ctx, handle, UIID_PROGRAM, function);
96
97 #define GET_SHADER(x, handle, function)\
98 struct gl2_shader_intf **x = (struct gl2_shader_intf **)\
99 lookup_handle (ctx, handle, UIID_SHADER, function);
100
101
102 #define GET_LINKED_PROGRAM(x, handle, function) \
103 GET_PROGRAM(x, handle, function); \
104 if (x && (**x).GetLinkStatus(x) == GL_FALSE) { \
105 RELEASE_PROGRAM(x); \
106 _mesa_error(ctx, GL_INVALID_OPERATION, function); \
107 x = NULL; \
108 }
109
110 #define GET_CURRENT_LINKED_PROGRAM(x, function) \
111 struct gl2_program_intf **x = ctx->ShaderObjects.CurrentProgram; \
112 if (!x || (**x).GetLinkStatus(x) == GL_FALSE) { \
113 _mesa_error(ctx, GL_INVALID_OPERATION, function); \
114 return; \
115 }
116
117
118
119 #define IS_NAME_WITH_GL_PREFIX(x) ((x)[0] == 'g' && (x)[1] == 'l' && (x)[2] == '_')
120
121
122 GLvoid GLAPIENTRY
123 _mesa_DeleteObjectARB(GLhandleARB obj)
124 {
125 if (obj != 0) {
126 GET_CURRENT_CONTEXT(ctx);
127 GET_GENERIC(gen, obj, "glDeleteObjectARB");
128
129 if (gen != NULL) {
130 (**gen).Delete(gen);
131 RELEASE_GENERIC(gen);
132 }
133 }
134 }
135
136 GLhandleARB GLAPIENTRY
137 _mesa_GetHandleARB(GLenum pname)
138 {
139 GET_CURRENT_CONTEXT(ctx);
140
141 switch (pname) {
142 case GL_PROGRAM_OBJECT_ARB:
143 {
144 struct gl2_program_intf **pro = ctx->ShaderObjects.CurrentProgram;
145
146 if (pro != NULL)
147 return (**pro)._container._generic.
148 GetName((struct gl2_generic_intf **) (pro));
149 }
150 break;
151 default:
152 _mesa_error(ctx, GL_INVALID_ENUM, "glGetHandleARB");
153 }
154
155 return 0;
156 }
157
158 GLvoid GLAPIENTRY
159 _mesa_DetachObjectARB(GLhandleARB containerObj, GLhandleARB attachedObj)
160 {
161 GET_CURRENT_CONTEXT(ctx);
162 GET_CONTAINER(con, containerObj, "glDetachObjectARB");
163
164 if (con != NULL) {
165 GET_GENERIC(att, attachedObj, "glDetachObjectARB");
166
167 if (att != NULL) {
168 (**con).Detach(con, att);
169 RELEASE_GENERIC(att);
170 }
171 RELEASE_CONTAINER(con);
172 }
173 }
174
175 GLhandleARB GLAPIENTRY
176 _mesa_CreateShaderObjectARB(GLenum shaderType)
177 {
178 return _mesa_3dlabs_create_shader_object(shaderType);
179 }
180
181 GLvoid GLAPIENTRY
182 _mesa_ShaderSourceARB(GLhandleARB shaderObj, GLsizei count,
183 const GLcharARB ** string, const GLint * length)
184 {
185 GET_CURRENT_CONTEXT(ctx);
186 GLint *offsets;
187 GLsizei i;
188 GLcharARB *source;
189 GET_SHADER(sha, shaderObj, "glShaderSourceARB");
190
191 if (sha == NULL)
192 return;
193
194 if (string == NULL) {
195 RELEASE_SHADER(sha);
196 _mesa_error(ctx, GL_INVALID_VALUE, "glShaderSourceARB");
197 return;
198 }
199
200 /*
201 * This array holds offsets of where the appropriate string ends, thus the last
202 * element will be set to the total length of the source code.
203 */
204 offsets = (GLint *) _mesa_malloc(count * sizeof(GLint));
205 if (offsets == NULL) {
206 RELEASE_SHADER(sha);
207 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB");
208 return;
209 }
210
211 for (i = 0; i < count; i++) {
212 if (string[i] == NULL) {
213 _mesa_free((GLvoid *) offsets);
214 RELEASE_SHADER(sha);
215 _mesa_error(ctx, GL_INVALID_VALUE, "glShaderSourceARB");
216 return;
217 }
218 if (length == NULL || length[i] < 0)
219 offsets[i] = _mesa_strlen(string[i]);
220 else
221 offsets[i] = length[i];
222 /* accumulate string lengths */
223 if (i > 0)
224 offsets[i] += offsets[i - 1];
225 }
226
227 source =
228 (GLcharARB *) _mesa_malloc((offsets[count - 1] + 1) *
229 sizeof(GLcharARB));
230 if (source == NULL) {
231 _mesa_free((GLvoid *) offsets);
232 RELEASE_SHADER(sha);
233 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB");
234 return;
235 }
236
237 for (i = 0; i < count; i++) {
238 GLint start = (i > 0) ? offsets[i - 1] : 0;
239 _mesa_memcpy(source + start, string[i],
240 (offsets[i] - start) * sizeof(GLcharARB));
241 }
242 source[offsets[count - 1]] = '\0';
243
244 (**sha).SetSource(sha, source, offsets, count);
245 RELEASE_SHADER(sha);
246 }
247
248 GLvoid GLAPIENTRY
249 _mesa_CompileShaderARB(GLhandleARB shaderObj)
250 {
251 GET_CURRENT_CONTEXT(ctx);
252 GET_SHADER(sha, shaderObj, "glCompileShaderARB");
253
254 if (sha != NULL) {
255 (**sha).Compile(sha);
256 RELEASE_SHADER(sha);
257 }
258 }
259
260 GLhandleARB GLAPIENTRY
261 _mesa_CreateProgramObjectARB(GLvoid)
262 {
263 return _mesa_3dlabs_create_program_object();
264 }
265
266 GLvoid GLAPIENTRY
267 _mesa_AttachObjectARB(GLhandleARB containerObj, GLhandleARB obj)
268 {
269 GET_CURRENT_CONTEXT(ctx);
270 GET_CONTAINER(con, containerObj, "glAttachObjectARB");
271
272 if (con != NULL) {
273 GET_GENERIC(att, obj, "glAttachObjectARB");
274
275 if (att != NULL) {
276 (**con).Attach(con, att);
277 RELEASE_GENERIC(att);
278 }
279 RELEASE_CONTAINER(con);
280 }
281 }
282
283 GLvoid GLAPIENTRY
284 _mesa_LinkProgramARB(GLhandleARB programObj)
285 {
286 GET_CURRENT_CONTEXT(ctx);
287 GET_PROGRAM(pro, programObj, "glLinkProgramARB");
288
289 if (pro != NULL) {
290 (**pro).Link(pro);
291 if (pro == ctx->ShaderObjects.CurrentProgram) {
292 if ((**pro).GetLinkStatus(pro))
293 _mesa_UseProgramObjectARB(programObj);
294 else
295 _mesa_UseProgramObjectARB(0);
296 }
297 RELEASE_PROGRAM(pro);
298 }
299 }
300
301 GLvoid GLAPIENTRY
302 _mesa_UseProgramObjectARB(GLhandleARB programObj)
303 {
304 GET_CURRENT_CONTEXT(ctx);
305 struct gl2_program_intf **program = NULL;
306
307 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
308
309 if (programObj != 0) {
310 GET_PROGRAM(pro, programObj, "glUseProgramObjectARB");
311
312 if (pro == NULL)
313 return;
314
315 if ((**pro).GetLinkStatus(pro) == GL_FALSE) {
316 RELEASE_PROGRAM(pro);
317 _mesa_error(ctx, GL_INVALID_OPERATION, "glUseProgramObjectARB");
318 return;
319 }
320
321 program = pro;
322
323 ctx->ShaderObjects._VertexShaderPresent =
324 (**pro).IsShaderPresent(pro, GL_VERTEX_SHADER_ARB);
325 ctx->ShaderObjects._FragmentShaderPresent =
326 (**pro).IsShaderPresent(pro, GL_FRAGMENT_SHADER_ARB);
327 }
328 else {
329 ctx->ShaderObjects._VertexShaderPresent = GL_FALSE;
330 ctx->ShaderObjects._FragmentShaderPresent = GL_FALSE;
331 }
332
333 if (ctx->ShaderObjects.CurrentProgram != NULL)
334 RELEASE_PROGRAM(ctx->ShaderObjects.CurrentProgram);
335 ctx->ShaderObjects.CurrentProgram = program;
336 }
337
338 GLvoid GLAPIENTRY
339 _mesa_ValidateProgramARB(GLhandleARB programObj)
340 {
341 GET_CURRENT_CONTEXT(ctx);
342 GET_PROGRAM(pro, programObj, "glValidateProgramARB");
343
344 if (pro != NULL) {
345 (**pro).Validate(pro);
346 RELEASE_PROGRAM(pro);
347 }
348 }
349
350
351 /**
352 * Helper function for all the _mesa_Uniform*() functions below.
353 */
354 static INLINE void
355 uniform(GLint location, GLsizei count, const GLvoid *values, GLenum type,
356 const char *caller)
357 {
358 GET_CURRENT_CONTEXT(ctx);
359 GET_CURRENT_LINKED_PROGRAM(pro, caller);
360
361 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
362
363 if (!(**pro).WriteUniform(pro, location, count, values, type))
364 _mesa_error(ctx, GL_INVALID_OPERATION, caller);
365 }
366
367
368 GLvoid GLAPIENTRY
369 _mesa_Uniform1fARB(GLint location, GLfloat v0)
370 {
371 uniform(location, 1, &v0, GL_FLOAT, "glUniform1fARB");
372 }
373
374 GLvoid GLAPIENTRY
375 _mesa_Uniform2fARB(GLint location, GLfloat v0, GLfloat v1)
376 {
377 GLfloat v[2];
378 v[0] = v0;
379 v[1] = v1;
380 uniform(location, 1, v, GL_FLOAT_VEC2, "glUniform2fARB");
381 }
382
383 GLvoid GLAPIENTRY
384 _mesa_Uniform3fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
385 {
386 GLfloat v[3];
387 v[0] = v0;
388 v[1] = v1;
389 v[2] = v2;
390 uniform(location, 1, v, GL_FLOAT_VEC3, "glUniform3fARB");
391 }
392
393 GLvoid GLAPIENTRY
394 _mesa_Uniform4fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2,
395 GLfloat v3)
396 {
397 GLfloat v[4];
398 v[0] = v0;
399 v[1] = v1;
400 v[2] = v2;
401 v[3] = v3;
402 uniform(location, 1, v, GL_FLOAT_VEC4, "glUniform4fARB");
403 }
404
405 GLvoid GLAPIENTRY
406 _mesa_Uniform1iARB(GLint location, GLint v0)
407 {
408 uniform(location, 1, &v0, GL_INT, "glUniform1iARB");
409 }
410
411 GLvoid GLAPIENTRY
412 _mesa_Uniform2iARB(GLint location, GLint v0, GLint v1)
413 {
414 GLint v[2];
415 v[0] = v0;
416 v[1] = v1;
417 uniform(location, 1, v, GL_INT_VEC2, "glUniform2iARB");
418 }
419
420 GLvoid GLAPIENTRY
421 _mesa_Uniform3iARB(GLint location, GLint v0, GLint v1, GLint v2)
422 {
423 GLint v[3];
424 v[0] = v0;
425 v[1] = v1;
426 v[2] = v2;
427 uniform(location, 1, v, GL_INT_VEC3, "glUniform3iARB");
428 }
429
430 GLvoid GLAPIENTRY
431 _mesa_Uniform4iARB(GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
432 {
433 GLint v[4];
434 v[0] = v0;
435 v[1] = v1;
436 v[2] = v2;
437 v[3] = v3;
438 uniform(location, 1, v, GL_INT_VEC4, "glUniform4iARB");
439 }
440
441 GLvoid GLAPIENTRY
442 _mesa_Uniform1fvARB(GLint location, GLsizei count, const GLfloat * value)
443 {
444 uniform(location, count, value, GL_FLOAT, "glUniform1fvARB");
445 }
446
447 GLvoid GLAPIENTRY
448 _mesa_Uniform2fvARB(GLint location, GLsizei count, const GLfloat * value)
449 {
450 uniform(location, count, value, GL_FLOAT_VEC2, "glUniform2fvARB");
451 }
452
453 GLvoid GLAPIENTRY
454 _mesa_Uniform3fvARB(GLint location, GLsizei count, const GLfloat * value)
455 {
456 uniform(location, count, value, GL_FLOAT_VEC3, "glUniform3fvARB");
457 }
458
459 GLvoid GLAPIENTRY
460 _mesa_Uniform4fvARB(GLint location, GLsizei count, const GLfloat * value)
461 {
462 uniform(location, count, value, GL_FLOAT_VEC4, "glUniform4fvARB");
463 }
464
465 GLvoid GLAPIENTRY
466 _mesa_Uniform1ivARB(GLint location, GLsizei count, const GLint * value)
467 {
468 uniform(location, count, value, GL_INT, "glUniform1ivARB");
469 }
470
471 GLvoid GLAPIENTRY
472 _mesa_Uniform2ivARB(GLint location, GLsizei count, const GLint * value)
473 {
474 uniform(location, count, value, GL_INT_VEC2, "glUniform2ivARB");
475 }
476
477 GLvoid GLAPIENTRY
478 _mesa_Uniform3ivARB(GLint location, GLsizei count, const GLint * value)
479 {
480 uniform(location, count, value, GL_INT_VEC3, "glUniform3ivARB");
481 }
482
483 GLvoid GLAPIENTRY
484 _mesa_Uniform4ivARB(GLint location, GLsizei count, const GLint * value)
485 {
486 uniform(location, count, value, GL_INT_VEC4, "glUniform4ivARB");
487 }
488
489
490 /**
491 * Helper function used by UniformMatrix**vARB() functions below.
492 */
493 static void
494 uniform_matrix(GLint cols, GLint rows, const char *caller,
495 GLenum matrixType,
496 GLint location, GLsizei count, GLboolean transpose,
497 const GLfloat *values)
498 {
499 const GLint matElements = rows * cols;
500 GET_CURRENT_CONTEXT(ctx);
501 GET_CURRENT_LINKED_PROGRAM(pro, caller);
502
503 if (values == NULL) {
504 _mesa_error(ctx, GL_INVALID_VALUE, caller);
505 return;
506 }
507
508 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
509
510 if (transpose) {
511 GLfloat *trans, *pt;
512 const GLfloat *pv;
513 GLint i, j, k;
514
515 trans = (GLfloat *) _mesa_malloc(count * matElements * sizeof(GLfloat));
516 if (!trans) {
517 _mesa_error(ctx, GL_OUT_OF_MEMORY, caller);
518 return;
519 }
520
521 pt = trans;
522 pv = values;
523 for (i = 0; i < count; i++) {
524 /* transpose from pv matrix into pt matrix */
525 for (j = 0; j < cols; j++) {
526 for (k = 0; k < rows; k++) {
527 /* XXX verify this */
528 pt[j * rows + k] = pv[k * cols + j];
529 }
530 }
531 pt += matElements;
532 pv += matElements;
533 }
534
535 if (!(**pro).WriteUniform(pro, location, count, trans, matrixType))
536 _mesa_error(ctx, GL_INVALID_OPERATION, caller);
537 _mesa_free(trans);
538 }
539 else {
540 if (!(**pro).WriteUniform(pro, location, count, values, matrixType))
541 _mesa_error(ctx, GL_INVALID_OPERATION, caller);
542 }
543 }
544
545
546 GLvoid GLAPIENTRY
547 _mesa_UniformMatrix2fvARB(GLint location, GLsizei count, GLboolean transpose,
548 const GLfloat * value)
549 {
550 uniform_matrix(2, 2, "glUniformMatrix2fvARB", GL_FLOAT_MAT2,
551 location, count, transpose, value);
552 }
553
554 GLvoid GLAPIENTRY
555 _mesa_UniformMatrix3fvARB(GLint location, GLsizei count, GLboolean transpose,
556 const GLfloat * value)
557 {
558 uniform_matrix(3, 3, "glUniformMatrix3fvARB", GL_FLOAT_MAT3,
559 location, count, transpose, value);
560 }
561
562 GLvoid GLAPIENTRY
563 _mesa_UniformMatrix4fvARB(GLint location, GLsizei count, GLboolean transpose,
564 const GLfloat * value)
565 {
566 uniform_matrix(4, 4, "glUniformMatrix4fvARB", GL_FLOAT_MAT4,
567 location, count, transpose, value);
568 }
569
570 static GLboolean
571 _mesa_get_object_parameter(GLhandleARB obj, GLenum pname, GLvoid * params,
572 GLboolean * integral, GLint * size)
573 {
574 GET_CURRENT_CONTEXT(ctx);
575 GLint *ipar = (GLint *) params;
576
577 /* set default values */
578 *integral = GL_TRUE; /* indicates param type, TRUE: GLint, FALSE: GLfloat */
579 *size = 1; /* param array size */
580
581 switch (pname) {
582 case GL_OBJECT_TYPE_ARB:
583 case GL_OBJECT_DELETE_STATUS_ARB:
584 case GL_OBJECT_INFO_LOG_LENGTH_ARB:
585 {
586 GET_GENERIC(gen, obj, "glGetObjectParameterivARB");
587
588 if (gen == NULL)
589 return GL_FALSE;
590
591 switch (pname) {
592 case GL_OBJECT_TYPE_ARB:
593 *ipar = (**gen).GetType(gen);
594 break;
595 case GL_OBJECT_DELETE_STATUS_ARB:
596 *ipar = (**gen).GetDeleteStatus(gen);
597 break;
598 case GL_OBJECT_INFO_LOG_LENGTH_ARB:
599 *ipar = (**gen).GetInfoLogLength(gen);
600 break;
601 }
602
603 RELEASE_GENERIC(gen);
604 }
605 break;
606 case GL_OBJECT_SUBTYPE_ARB:
607 case GL_OBJECT_COMPILE_STATUS_ARB:
608 case GL_OBJECT_SHADER_SOURCE_LENGTH_ARB:
609 {
610 GET_SHADER(sha, obj, "glGetObjectParameterivARB");
611
612 if (sha == NULL)
613 return GL_FALSE;
614
615 switch (pname) {
616 case GL_OBJECT_SUBTYPE_ARB:
617 *ipar = (**sha).GetSubType(sha);
618 break;
619 case GL_OBJECT_COMPILE_STATUS_ARB:
620 *ipar = (**sha).GetCompileStatus(sha);
621 break;
622 case GL_OBJECT_SHADER_SOURCE_LENGTH_ARB:
623 {
624 const GLcharARB *src = (**sha).GetSource(sha);
625 if (src == NULL)
626 *ipar = 0;
627 else
628 *ipar = _mesa_strlen(src) + 1;
629 }
630 break;
631 }
632
633 RELEASE_SHADER(sha);
634 }
635 break;
636 case GL_OBJECT_LINK_STATUS_ARB:
637 case GL_OBJECT_VALIDATE_STATUS_ARB:
638 case GL_OBJECT_ATTACHED_OBJECTS_ARB:
639 case GL_OBJECT_ACTIVE_UNIFORMS_ARB:
640 case GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB:
641 {
642 GET_PROGRAM(pro, obj, "glGetObjectParameterivARB");
643
644 if (pro == NULL)
645 return GL_FALSE;
646
647 switch (pname) {
648 case GL_OBJECT_LINK_STATUS_ARB:
649 *ipar = (**pro).GetLinkStatus(pro);
650 break;
651 case GL_OBJECT_VALIDATE_STATUS_ARB:
652 *ipar = (**pro).GetValidateStatus(pro);
653 break;
654 case GL_OBJECT_ATTACHED_OBJECTS_ARB:
655 *ipar =
656 (**pro)._container.
657 GetAttachedCount((struct gl2_container_intf **) (pro));
658 break;
659 case GL_OBJECT_ACTIVE_UNIFORMS_ARB:
660 *ipar = (**pro).GetActiveUniformCount(pro);
661 break;
662 case GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB:
663 *ipar = (**pro).GetActiveUniformMaxLength(pro);
664 break;
665 case GL_OBJECT_ACTIVE_ATTRIBUTES_ARB:
666 *ipar = (**pro).GetActiveAttribCount(pro);
667 break;
668 case GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB:
669 *ipar = (**pro).GetActiveAttribMaxLength(pro);
670 break;
671 }
672
673 RELEASE_PROGRAM(pro);
674 }
675 break;
676 default:
677 _mesa_error(ctx, GL_INVALID_ENUM, "glGetObjectParameterivARB");
678 return GL_FALSE;
679 }
680
681 return GL_TRUE;
682 }
683
684 GLvoid GLAPIENTRY
685 _mesa_GetObjectParameterfvARB(GLhandleARB obj, GLenum pname, GLfloat * params)
686 {
687 GET_CURRENT_CONTEXT(ctx);
688 GLboolean integral;
689 GLint size;
690
691 if (params == NULL) {
692 _mesa_error(ctx, GL_INVALID_VALUE, "glGetObjectParameterfvARB");
693 return;
694 }
695
696 assert(sizeof(GLfloat) == sizeof(GLint));
697
698 if (_mesa_get_object_parameter(obj, pname, (GLvoid *) params,
699 &integral, &size)) {
700 if (integral) {
701 GLint i;
702 for (i = 0; i < size; i++)
703 params[i] = (GLfloat) ((GLint *) params)[i];
704 }
705 }
706 }
707
708 GLvoid GLAPIENTRY
709 _mesa_GetObjectParameterivARB(GLhandleARB obj, GLenum pname, GLint * params)
710 {
711 GET_CURRENT_CONTEXT(ctx);
712 GLboolean integral;
713 GLint size;
714
715 if (params == NULL) {
716 _mesa_error(ctx, GL_INVALID_VALUE, "glGetObjectParameterivARB");
717 return;
718 }
719
720 assert(sizeof(GLfloat) == sizeof(GLint));
721
722 if (_mesa_get_object_parameter(obj, pname, (GLvoid *) params,
723 &integral, &size)) {
724 if (!integral) {
725 GLint i;
726 for (i = 0; i < size; i++)
727 params[i] = (GLint) ((GLfloat *) params)[i];
728 }
729 }
730 }
731
732
733 /**
734 * Copy string from <src> to <dst>, up to maxLength characters, returning
735 * length of <dst> in <length>.
736 * \param src the strings source
737 * \param maxLength max chars to copy
738 * \param length returns numberof chars copied
739 * \param dst the string destination
740 */
741 static GLvoid
742 copy_string(const GLcharARB * src, GLsizei maxLength, GLsizei * length,
743 GLcharARB * dst)
744 {
745 GLsizei len;
746 for (len = 0; len < maxLength - 1 && src && src[len]; len++)
747 dst[len] = src[len];
748 if (maxLength > 0)
749 dst[len] = 0;
750 if (length)
751 *length = len;
752 }
753
754
755 GLvoid GLAPIENTRY
756 _mesa_GetInfoLogARB(GLhandleARB obj, GLsizei maxLength, GLsizei * length,
757 GLcharARB * infoLog)
758 {
759 GET_CURRENT_CONTEXT(ctx);
760 GET_GENERIC(gen, obj, "glGetInfoLogARB");
761
762 if (gen == NULL)
763 return;
764
765 if (infoLog == NULL)
766 _mesa_error(ctx, GL_INVALID_VALUE, "glGetInfoLogARB");
767 else {
768 GLsizei actualsize = (**gen).GetInfoLogLength(gen);
769 if (actualsize > maxLength)
770 actualsize = maxLength;
771 (**gen).GetInfoLog(gen, actualsize, infoLog);
772 if (length != NULL)
773 *length = (actualsize > 0) ? actualsize - 1 : 0;
774 }
775 RELEASE_GENERIC(gen);
776 }
777
778 GLvoid GLAPIENTRY
779 _mesa_GetAttachedObjectsARB(GLhandleARB containerObj, GLsizei maxCount,
780 GLsizei * count, GLhandleARB * obj)
781 {
782 GET_CURRENT_CONTEXT(ctx);
783 GET_CONTAINER(con, containerObj, "glGetAttachedObjectsARB");
784
785 if (con == NULL)
786 return;
787
788 if (obj == NULL)
789 _mesa_error(ctx, GL_INVALID_VALUE, "glGetAttachedObjectsARB");
790 else {
791 GLsizei cnt, i;
792
793 cnt = (**con).GetAttachedCount(con);
794 if (cnt > maxCount)
795 cnt = maxCount;
796 if (count != NULL)
797 *count = cnt;
798
799 for (i = 0; i < cnt; i++) {
800 struct gl2_generic_intf **x = (**con).GetAttached(con, i);
801 obj[i] = (**x).GetName(x);
802 RELEASE_GENERIC(x);
803 }
804 }
805 RELEASE_CONTAINER(con);
806 }
807
808 GLint GLAPIENTRY
809 _mesa_GetUniformLocationARB(GLhandleARB programObj, const GLcharARB * name)
810 {
811 GET_CURRENT_CONTEXT(ctx);
812 GLint loc = -1;
813 GET_LINKED_PROGRAM(pro, programObj, "glGetUniformLocationARB");
814
815 if (!pro)
816 return -1;
817
818 if (name == NULL)
819 _mesa_error(ctx, GL_INVALID_VALUE, "glGetUniformLocationARB");
820 else {
821 if (!IS_NAME_WITH_GL_PREFIX(name))
822 loc = (**pro).GetUniformLocation(pro, name);
823 }
824 RELEASE_PROGRAM(pro);
825 return loc;
826 }
827
828 GLvoid GLAPIENTRY
829 _mesa_GetActiveUniformARB(GLhandleARB programObj, GLuint index,
830 GLsizei maxLength, GLsizei * length, GLint * size,
831 GLenum * type, GLcharARB * name)
832 {
833 GET_CURRENT_CONTEXT(ctx);
834 GET_PROGRAM(pro, programObj, "glGetActiveUniformARB");
835
836 if (pro == NULL)
837 return;
838
839 if (size == NULL || type == NULL || name == NULL)
840 _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniformARB");
841 else {
842 if (index < (**pro).GetActiveUniformCount(pro))
843 (**pro).GetActiveUniform(pro, index, maxLength, length, size, type,
844 name);
845 else
846 _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveUniformARB");
847 }
848 RELEASE_PROGRAM(pro);
849 }
850
851 GLvoid GLAPIENTRY
852 _mesa_GetUniformfvARB(GLhandleARB programObj, GLint location, GLfloat * params)
853 {
854 GET_CURRENT_CONTEXT(ctx);
855 GET_LINKED_PROGRAM(pro, programObj, "glGetUniformfvARB");
856
857 if (!pro)
858 return;
859
860 if (!(**pro).ReadUniform(pro, location, 1, params, GL_FLOAT))
861 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformfvARB");
862
863 RELEASE_PROGRAM(pro);
864 }
865
866 GLvoid GLAPIENTRY
867 _mesa_GetUniformivARB(GLhandleARB programObj, GLint location, GLint * params)
868 {
869 GET_CURRENT_CONTEXT(ctx);
870 GET_LINKED_PROGRAM(pro, programObj, "glGetUniformivARB");
871
872 if (!pro)
873 return;
874
875 if (!(**pro).ReadUniform(pro, location, 1, params, GL_INT))
876 _mesa_error(ctx, GL_INVALID_OPERATION, "glGetUniformivARB");
877 RELEASE_PROGRAM(pro);
878 }
879
880 GLvoid GLAPIENTRY
881 _mesa_GetShaderSourceARB(GLhandleARB obj, GLsizei maxLength, GLsizei * length,
882 GLcharARB * source)
883 {
884 GET_CURRENT_CONTEXT(ctx);
885 GET_SHADER(sha, obj, "glGetShaderSourceARB");
886
887 if (sha == NULL)
888 return;
889
890 if (source == NULL)
891 _mesa_error(ctx, GL_INVALID_VALUE, "glGetShaderSourceARB");
892 else
893 copy_string((**sha).GetSource(sha), maxLength, length, source);
894 RELEASE_SHADER(sha);
895 }
896
897 /* GL_ARB_vertex_shader */
898
899 GLvoid GLAPIENTRY
900 _mesa_BindAttribLocationARB(GLhandleARB programObj, GLuint index,
901 const GLcharARB * name)
902 {
903 GET_CURRENT_CONTEXT(ctx);
904 GET_PROGRAM(pro, programObj, "glBindAttribLocationARB");
905
906 if (pro == NULL)
907 return;
908
909 if (name == NULL || index >= MAX_VERTEX_ATTRIBS)
910 _mesa_error(ctx, GL_INVALID_VALUE, "glBindAttribLocationARB");
911 else if (IS_NAME_WITH_GL_PREFIX(name))
912 _mesa_error(ctx, GL_INVALID_OPERATION, "glBindAttribLocationARB");
913 else
914 (**pro).OverrideAttribBinding(pro, index, name);
915 RELEASE_PROGRAM(pro);
916 }
917
918 GLvoid GLAPIENTRY
919 _mesa_GetActiveAttribARB(GLhandleARB programObj, GLuint index,
920 GLsizei maxLength, GLsizei * length, GLint * size,
921 GLenum * type, GLcharARB * name)
922 {
923 GET_CURRENT_CONTEXT(ctx);
924 GET_PROGRAM(pro, programObj, "glGetActiveAttribARB");
925
926 if (pro == NULL)
927 return;
928
929 if (name == NULL || index >= (**pro).GetActiveAttribCount(pro))
930 _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttribARB");
931 else
932 (**pro).GetActiveAttrib(pro, index, maxLength, length, size, type,
933 name);
934 RELEASE_PROGRAM(pro);
935 }
936
937 GLint GLAPIENTRY
938 _mesa_GetAttribLocationARB(GLhandleARB programObj, const GLcharARB * name)
939 {
940 GET_CURRENT_CONTEXT(ctx);
941 GLint loc = -1;
942 GET_LINKED_PROGRAM(pro, programObj, "glGetAttribLocationARB");
943
944 if (!pro)
945 return -1;
946
947 if (name == NULL)
948 _mesa_error(ctx, GL_INVALID_VALUE, "glGetAttribLocationARB");
949 else if (!IS_NAME_WITH_GL_PREFIX(name))
950 loc = (**pro).GetAttribLocation(pro, name);
951 RELEASE_PROGRAM(pro);
952 return loc;
953 }
954
955
956 /**
957 ** OpenGL 2.0 functions which basically wrap the ARB_shader functions
958 **/
959
960 void GLAPIENTRY
961 _mesa_AttachShader(GLuint program, GLuint shader)
962 {
963 _mesa_AttachObjectARB(program, shader);
964 }
965
966
967 GLuint GLAPIENTRY
968 _mesa_CreateShader(GLenum type)
969 {
970 return (GLuint) _mesa_CreateShaderObjectARB(type);
971 }
972
973 GLuint GLAPIENTRY
974 _mesa_CreateProgram(void)
975 {
976 return (GLuint) _mesa_CreateProgramObjectARB();
977 }
978
979 void GLAPIENTRY
980 _mesa_DeleteProgram(GLuint program)
981 {
982 _mesa_DeleteObjectARB(program);
983 }
984
985
986 void GLAPIENTRY
987 _mesa_DeleteShader(GLuint shader)
988 {
989 _mesa_DeleteObjectARB(shader);
990 }
991
992 void GLAPIENTRY
993 _mesa_DetachShader(GLuint program, GLuint shader)
994 {
995 _mesa_DetachObjectARB(program, shader);
996 }
997
998 void GLAPIENTRY
999 _mesa_GetAttachedShaders(GLuint program, GLsizei maxCount,
1000 GLsizei *count, GLuint *obj)
1001 {
1002 _mesa_GetAttachedObjectsARB(program, maxCount, count, obj);
1003 }
1004
1005 void GLAPIENTRY
1006 _mesa_GetProgramiv(GLuint program, GLenum pname, GLint *params)
1007 {
1008 GET_CURRENT_CONTEXT(ctx);
1009 GET_PROGRAM(pro, program, "glGetProgramiv");
1010
1011 if (!pro)
1012 return;
1013
1014 switch (pname) {
1015 case GL_DELETE_STATUS:
1016 *params = (**pro)._container._generic.GetDeleteStatus((struct gl2_generic_inf **) pro);
1017 break;
1018 case GL_LINK_STATUS:
1019 *params = (**pro).GetLinkStatus(pro);
1020 break;
1021 case GL_VALIDATE_STATUS:
1022 *params = (**pro).GetValidateStatus(pro);
1023 break;
1024 case GL_INFO_LOG_LENGTH:
1025 *params = (**pro)._container._generic.GetInfoLogLength( (struct gl2_unknown_inf **) pro );
1026 break;
1027 case GL_ATTACHED_SHADERS:
1028 *params = (**pro)._container.GetAttachedCount( (struct gl2_unknown_inf **) pro );
1029 break;
1030 case GL_ACTIVE_ATTRIBUTES:
1031 *params = (**pro).GetActiveAttribCount(pro);
1032 break;
1033 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
1034 *params = (**pro).GetActiveAttribMaxLength(pro);
1035 break;
1036 case GL_ACTIVE_UNIFORMS:
1037 *params = (**pro).GetActiveUniformCount(pro);
1038 break;
1039 case GL_ACTIVE_UNIFORM_MAX_LENGTH:
1040 *params = (**pro).GetActiveUniformMaxLength(pro);
1041 break;
1042 default:
1043 _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramiv(pname)");
1044 return;
1045 }
1046 }
1047
1048 void GLAPIENTRY
1049 _mesa_GetProgramInfoLog(GLuint program, GLsizei bufSize,
1050 GLsizei *length, GLchar *infoLog)
1051 {
1052 _mesa_GetInfoLogARB(program, bufSize, length, infoLog);
1053 }
1054
1055 void GLAPIENTRY
1056 _mesa_GetShaderiv(GLuint shader, GLenum pname, GLint *params)
1057 {
1058 GET_CURRENT_CONTEXT(ctx);
1059 GET_SHADER(sh, shader, "glGetShaderiv");
1060
1061 if (!sh)
1062 return;
1063
1064 switch (pname) {
1065 case GL_SHADER_TYPE:
1066 *params = (**sh).GetSubType(sh);
1067 break;
1068 case GL_DELETE_STATUS:
1069 *params = (**sh)._generic.GetDeleteStatus((struct gl2_generic_inf **) sh);
1070 break;
1071 case GL_COMPILE_STATUS:
1072 *params = (**sh).GetCompileStatus(sh);
1073 break;
1074 case GL_INFO_LOG_LENGTH:
1075 *params = (**sh)._generic.GetInfoLogLength((struct gl2_generic_inf **)sh);
1076 break;
1077 case GL_SHADER_SOURCE_LENGTH:
1078 {
1079 const GLchar *src = (**sh).GetSource(sh);
1080 *params = src ? (_mesa_strlen(src) + 1) : 0;
1081 }
1082 break;
1083 default:
1084 _mesa_error(ctx, GL_INVALID_ENUM, "glGetShaderiv(pname)");
1085 return;
1086 }
1087 }
1088
1089 void GLAPIENTRY
1090 _mesa_GetShaderInfoLog(GLuint shader, GLsizei bufSize,
1091 GLsizei *length, GLchar *infoLog)
1092 {
1093 _mesa_GetInfoLogARB(shader, bufSize, length, infoLog);
1094 }
1095
1096 GLboolean GLAPIENTRY
1097 _mesa_IsProgram(GLuint program)
1098 {
1099 GET_CURRENT_CONTEXT(ctx);
1100 GET_PROGRAM(pro, program, "glIsProgram");
1101 if (pro) {
1102 RELEASE_PROGRAM(pro);
1103 return GL_TRUE;
1104 }
1105 else {
1106 return GL_FALSE;
1107 }
1108 }
1109
1110 GLboolean GLAPIENTRY
1111 _mesa_IsShader(GLuint shader)
1112 {
1113 GET_CURRENT_CONTEXT(ctx);
1114 GET_SHADER(sh, shader, "glIsProgram");
1115 if (sh) {
1116 RELEASE_SHADER(sh);
1117 return GL_TRUE;
1118 }
1119 else {
1120 return GL_FALSE;
1121 }
1122 }
1123
1124
1125 /**
1126 ** 2.1 functions
1127 **/
1128
1129 void GLAPIENTRY
1130 _mesa_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose,
1131 const GLfloat *value)
1132 {
1133 uniform_matrix(2, 3, "glUniformMatrix2x3fv", GL_FLOAT_MAT2x3,
1134 location, count, transpose, value);
1135 }
1136
1137 void GLAPIENTRY
1138 _mesa_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose,
1139 const GLfloat *value)
1140 {
1141 uniform_matrix(3, 2, "glUniformMatrix3x2fv", GL_FLOAT_MAT3x2,
1142 location, count, transpose, value);
1143 }
1144
1145 void GLAPIENTRY
1146 _mesa_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose,
1147 const GLfloat *value)
1148 {
1149 uniform_matrix(2, 4, "glUniformMatrix2x4fv", GL_FLOAT_MAT2x4,
1150 location, count, transpose, value);
1151 }
1152
1153 void GLAPIENTRY
1154 _mesa_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose,
1155 const GLfloat *value)
1156 {
1157 uniform_matrix(4, 2, "glUniformMatrix4x2fv", GL_FLOAT_MAT4x2,
1158 location, count, transpose, value);
1159 }
1160
1161 void GLAPIENTRY
1162 _mesa_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose,
1163 const GLfloat *value)
1164 {
1165 uniform_matrix(3, 4, "glUniformMatrix3x4fv", GL_FLOAT_MAT3x4,
1166 location, count, transpose, value);
1167 }
1168
1169 void GLAPIENTRY
1170 _mesa_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose,
1171 const GLfloat *value)
1172 {
1173 uniform_matrix(4, 3, "glUniformMatrix4x3fv", GL_FLOAT_MAT4x3,
1174 location, count, transpose, value);
1175 }
1176
1177
1178
1179
1180
1181 #endif
1182
1183 GLvoid
1184 _mesa_init_shaderobjects(GLcontext * ctx)
1185 {
1186 ctx->ShaderObjects.CurrentProgram = NULL;
1187 ctx->ShaderObjects._FragmentShaderPresent = GL_FALSE;
1188 ctx->ShaderObjects._VertexShaderPresent = GL_FALSE;
1189
1190 _mesa_init_shaderobjects_3dlabs(ctx);
1191 }