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