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