ad55b7448c54e55167fdcb72129ee7b310a5c3ed
[mesa.git] / src / mesa / shader / shaderobjects.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 6.3
4 *
5 * Copyright (C) 2004-2005 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)\
103 if ((**x).GetLinkStatus (x) == GL_FALSE) {\
104 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);\
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);\
129 } while (0)
130
131
132 GLvoid GLAPIENTRY
133 _mesa_DeleteObjectARB (GLhandleARB obj)
134 {
135 GET_CURRENT_CONTEXT(ctx);
136 GET_GENERIC(gen, obj, "glDeleteObjectARB");
137
138 if (gen != NULL)
139 {
140 (**gen).Delete (gen);
141 RELEASE_GENERIC(gen);
142 }
143 }
144
145 GLhandleARB GLAPIENTRY
146 _mesa_GetHandleARB (GLenum pname)
147 {
148 GET_CURRENT_CONTEXT(ctx);
149
150 switch (pname)
151 {
152 case GL_PROGRAM_OBJECT_ARB:
153 {
154 I_PROGRAM pro = ctx->ShaderObjects.CurrentProgram;
155
156 if (pro != NULL)
157 return (**pro)._container._generic.GetName ((I_GENERIC) pro);
158 }
159 break;
160 default:
161 _mesa_error (ctx, GL_INVALID_ENUM, "glGetHandleARB");
162 }
163
164 return 0;
165 }
166
167 GLvoid GLAPIENTRY
168 _mesa_DetachObjectARB (GLhandleARB containerObj, GLhandleARB attachedObj)
169 {
170 GET_CURRENT_CONTEXT(ctx);
171 GET_CONTAINER(con, containerObj, "glDetachObjectARB");
172
173 if (con != NULL)
174 {
175 GET_GENERIC(att, attachedObj, "glDetachObjectARB");
176
177 if (att != NULL)
178 {
179 (**con).Detach (con, att);
180 RELEASE_GENERIC(att);
181 }
182 RELEASE_CONTAINER(con);
183 }
184 }
185
186 GLhandleARB GLAPIENTRY
187 _mesa_CreateShaderObjectARB (GLenum shaderType)
188 {
189 return _mesa_3dlabs_create_shader_object (shaderType);
190 }
191
192 GLvoid GLAPIENTRY
193 _mesa_ShaderSourceARB (GLhandleARB shaderObj, GLsizei count, const GLcharARB **string,
194 const GLint *length)
195 {
196 GET_CURRENT_CONTEXT(ctx);
197 GLint *offsets;
198 GLsizei i;
199 GLcharARB *source;
200 GET_SHADER(sha, shaderObj, "glShaderSourceARB");
201
202 if (sha == NULL)
203 return;
204
205 /*
206 * This array holds offsets of where the appropriate string ends, thus the last
207 * element will be set to the total length of the source code.
208 */
209 offsets = (GLint *) _mesa_malloc (count * sizeof (GLint));
210 if (offsets == NULL)
211 {
212 RELEASE_SHADER(sha);
213 _mesa_error (ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB");
214 return;
215 }
216
217 for (i = 0; i < count; i++)
218 {
219 if (length == NULL || length[i] < 0)
220 offsets[i] = _mesa_strlen (string[i]);
221 else
222 offsets[i] = length[i];
223 /* accumulate string lengths */
224 if (i > 0)
225 offsets[i] += offsets[i - 1];
226 }
227
228 source = (GLcharARB *) _mesa_malloc ((offsets[count - 1] + 1) * sizeof (GLcharARB));
229 if (source == NULL)
230 {
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 {
239 GLint start = (i > 0) ? offsets[i - 1] : 0;
240 _mesa_memcpy (source + start, string[i], (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 {
256 (**sha).Compile (sha);
257 RELEASE_SHADER(sha);
258 }
259 }
260
261 GLhandleARB GLAPIENTRY
262 _mesa_CreateProgramObjectARB (GLvoid)
263 {
264 return _mesa_3dlabs_create_program_object ();
265 }
266
267 GLvoid GLAPIENTRY
268 _mesa_AttachObjectARB (GLhandleARB containerObj, GLhandleARB obj)
269 {
270 GET_CURRENT_CONTEXT(ctx);
271 GET_CONTAINER(con, containerObj, "glAttachObjectARB");
272
273 if (con != NULL)
274 {
275 GET_GENERIC(att, obj, "glAttachObjectARB");
276
277 if (att != NULL)
278 {
279 (**con).Attach (con, att);
280 RELEASE_GENERIC(att);
281 }
282 RELEASE_CONTAINER(con);
283 }
284 }
285
286 GLvoid GLAPIENTRY
287 _mesa_LinkProgramARB (GLhandleARB programObj)
288 {
289 GET_CURRENT_CONTEXT(ctx);
290 GET_PROGRAM(pro, programObj, "glLinkProgramARB");
291
292 if (pro != NULL)
293 {
294 if (pro == ctx->ShaderObjects.CurrentProgram)
295 {
296 /* TODO re-install executable program */
297 }
298 (**pro).Link (pro);
299 RELEASE_PROGRAM(pro);
300 }
301 }
302
303 GLvoid GLAPIENTRY
304 _mesa_UseProgramObjectARB (GLhandleARB programObj)
305 {
306 GET_CURRENT_CONTEXT(ctx);
307 I_PROGRAM program = NULL;
308
309 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
310
311 if (programObj != 0)
312 {
313 GET_PROGRAM(pro, programObj, "glUseProgramObjectARB");
314
315 if (pro == NULL)
316 return;
317
318 if ((**pro).GetLinkStatus (pro) == GL_FALSE)
319 {
320 RELEASE_PROGRAM(pro);
321 _mesa_error (ctx, GL_INVALID_OPERATION, "glUseProgramObjectARB");
322 return;
323 }
324
325 program = pro;
326 }
327
328 if (ctx->ShaderObjects.CurrentProgram != NULL)
329 RELEASE_PROGRAM(ctx->ShaderObjects.CurrentProgram);
330 ctx->ShaderObjects.CurrentProgram = program;
331 }
332
333 GLvoid GLAPIENTRY
334 _mesa_ValidateProgramARB (GLhandleARB programObj)
335 {
336 GET_CURRENT_CONTEXT(ctx);
337 GET_PROGRAM(pro, programObj, "glValidateProgramARB");
338
339 if (pro != NULL)
340 {
341 (**pro).Validate (pro);
342 RELEASE_PROGRAM(pro);
343 }
344 }
345
346 GLvoid GLAPIENTRY
347 _mesa_Uniform1fARB (GLint location, GLfloat v0)
348 {
349 GET_CURRENT_CONTEXT(ctx);
350 GET_CURRENT_LINKED_PROGRAM(pro, "glUniform1fARB");
351
352 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
353
354 if (pro != NULL)
355 {
356 if (!_slang_write_uniform (pro, location, 1, &v0, GL_FLOAT))
357 _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform1fARB");
358 }
359 }
360
361 GLvoid GLAPIENTRY
362 _mesa_Uniform2fARB (GLint location, GLfloat v0, GLfloat v1)
363 {
364 GET_CURRENT_CONTEXT(ctx);
365 GET_CURRENT_LINKED_PROGRAM(pro, "glUniform2fARB");
366
367 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
368
369 if (pro != NULL)
370 {
371 GLfloat v[2] = { v0, v1 };
372
373 if (!_slang_write_uniform (pro, location, 1, v, GL_FLOAT_VEC2))
374 _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform2fARB");
375 }
376 }
377
378 GLvoid GLAPIENTRY
379 _mesa_Uniform3fARB (GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
380 {
381 GET_CURRENT_CONTEXT(ctx);
382 GET_CURRENT_LINKED_PROGRAM(pro, "glUniform3fARB");
383
384 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
385
386 if (pro != NULL)
387 {
388 GLfloat v[3] = { v0, v1, v2 };
389
390 if (!_slang_write_uniform (pro, location, 1, v, GL_FLOAT_VEC3))
391 _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform3fARB");
392 }
393 }
394
395 GLvoid GLAPIENTRY
396 _mesa_Uniform4fARB (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
397 {
398 GET_CURRENT_CONTEXT(ctx);
399 GET_CURRENT_LINKED_PROGRAM(pro, "glUniform4fARB");
400
401 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
402
403 if (pro != NULL)
404 {
405 GLfloat v[4] = { v0, v1, v2, v3 };
406
407 if (!_slang_write_uniform (pro, location, 1, v, GL_FLOAT_VEC4))
408 _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform4fARB");
409 }
410 }
411
412 GLvoid GLAPIENTRY
413 _mesa_Uniform1iARB (GLint location, GLint v0)
414 {
415 GET_CURRENT_CONTEXT(ctx);
416 GET_CURRENT_LINKED_PROGRAM(pro, "glUniform1iARB");
417
418 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
419
420 if (pro != NULL)
421 {
422 if (!_slang_write_uniform (pro, location, 1, &v0, GL_INT))
423 _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform1iARB");
424 }
425 }
426
427 GLvoid GLAPIENTRY
428 _mesa_Uniform2iARB (GLint location, GLint v0, GLint v1)
429 {
430 GET_CURRENT_CONTEXT(ctx);
431 GET_CURRENT_LINKED_PROGRAM(pro, "glUniform2iARB");
432
433 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
434
435 if (pro != NULL)
436 {
437 GLint v[2] = { v0, v1 };
438
439 if (!_slang_write_uniform (pro, location, 1, v, GL_INT_VEC2))
440 _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform2iARB");
441 }
442 }
443
444 GLvoid GLAPIENTRY
445 _mesa_Uniform3iARB (GLint location, GLint v0, GLint v1, GLint v2)
446 {
447 GET_CURRENT_CONTEXT(ctx);
448 GET_CURRENT_LINKED_PROGRAM(pro, "glUniform3iARB");
449
450 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
451
452 if (pro != NULL)
453 {
454 GLint v[3] = { v0, v1, v2 };
455
456 if (!_slang_write_uniform (pro, location, 1, v, GL_INT_VEC3))
457 _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform3iARB");
458 }
459 }
460
461 GLvoid GLAPIENTRY
462 _mesa_Uniform4iARB (GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
463 {
464 GET_CURRENT_CONTEXT(ctx);
465 GET_CURRENT_LINKED_PROGRAM(pro, "glUniform4iARB");
466
467 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
468
469 if (pro != NULL)
470 {
471 GLint v[4] = { v0, v1, v2, v3 };
472
473 if (!_slang_write_uniform (pro, location, 1, v, GL_INT_VEC4))
474 _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform4iARB");
475 }
476 }
477
478 GLvoid GLAPIENTRY
479 _mesa_Uniform1fvARB (GLint location, GLsizei count, const GLfloat *value)
480 {
481 GET_CURRENT_CONTEXT(ctx);
482 GET_CURRENT_LINKED_PROGRAM(pro, "glUniform1fvARB");
483
484 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
485
486 if (pro != NULL)
487 {
488 if (!_slang_write_uniform (pro, location, count, value, GL_FLOAT))
489 _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform1fvARB");
490 }
491 }
492
493 GLvoid GLAPIENTRY
494 _mesa_Uniform2fvARB (GLint location, GLsizei count, const GLfloat *value)
495 {
496 GET_CURRENT_CONTEXT(ctx);
497 GET_CURRENT_LINKED_PROGRAM(pro, "glUniform2fvARB");
498
499 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
500
501 if (pro != NULL)
502 {
503 if (!_slang_write_uniform (pro, location, count, value, GL_FLOAT_VEC2))
504 _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform2fvARB");
505 }
506 }
507
508 GLvoid GLAPIENTRY
509 _mesa_Uniform3fvARB (GLint location, GLsizei count, const GLfloat *value)
510 {
511 GET_CURRENT_CONTEXT(ctx);
512 GET_CURRENT_LINKED_PROGRAM(pro, "glUniform3fvARB");
513
514 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
515
516 if (pro != NULL)
517 {
518 if (!_slang_write_uniform (pro, location, count, value, GL_FLOAT_VEC3))
519 _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform3fvARB");
520 }
521 }
522
523 GLvoid GLAPIENTRY
524 _mesa_Uniform4fvARB (GLint location, GLsizei count, const GLfloat *value)
525 {
526 GET_CURRENT_CONTEXT(ctx);
527 GET_CURRENT_LINKED_PROGRAM(pro, "glUniform4fvARB");
528
529 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
530
531 if (pro != NULL)
532 {
533 if (!_slang_write_uniform (pro, location, count, value, GL_FLOAT_VEC4))
534 _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform4fvARB");
535 }
536 }
537
538 GLvoid GLAPIENTRY
539 _mesa_Uniform1ivARB (GLint location, GLsizei count, const GLint *value)
540 {
541 GET_CURRENT_CONTEXT(ctx);
542 GET_CURRENT_LINKED_PROGRAM(pro, "glUniform1ivARB");
543
544 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
545
546 if (pro != NULL)
547 {
548 if (!_slang_write_uniform (pro, location, count, value, GL_INT))
549 _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform1ivARB");
550 }
551 }
552
553 GLvoid GLAPIENTRY
554 _mesa_Uniform2ivARB (GLint location, GLsizei count, const GLint *value)
555 {
556 GET_CURRENT_CONTEXT(ctx);
557 GET_CURRENT_LINKED_PROGRAM(pro, "glUniform2ivARB");
558
559 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
560
561 if (pro != NULL)
562 {
563 if (!_slang_write_uniform (pro, location, count, value, GL_INT_VEC2))
564 _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform2ivARB");
565 }
566 }
567
568 GLvoid GLAPIENTRY
569 _mesa_Uniform3ivARB (GLint location, GLsizei count, const GLint *value)
570 {
571 GET_CURRENT_CONTEXT(ctx);
572 GET_CURRENT_LINKED_PROGRAM(pro, "glUniform3ivARB");
573
574 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
575
576 if (pro != NULL)
577 {
578 if (!_slang_write_uniform (pro, location, count, value, GL_INT_VEC3))
579 _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform3ivARB");
580 }
581 }
582
583 GLvoid GLAPIENTRY
584 _mesa_Uniform4ivARB (GLint location, GLsizei count, const GLint *value)
585 {
586 GET_CURRENT_CONTEXT(ctx);
587 GET_CURRENT_LINKED_PROGRAM(pro, "glUniform4ivARB");
588
589 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
590
591 if (pro != NULL)
592 {
593 if (!_slang_write_uniform (pro, location, count, value, GL_INT_VEC4))
594 _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform4ivARB");
595 }
596 }
597
598 GLvoid GLAPIENTRY
599 _mesa_UniformMatrix2fvARB (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
600 {
601 GET_CURRENT_CONTEXT(ctx);
602 GET_CURRENT_LINKED_PROGRAM(pro, "glUniformMatrix2fvARB");
603
604 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
605
606 if (pro != NULL)
607 {
608 if (transpose)
609 {
610 GLfloat *trans, *pt;
611 const GLfloat *pv;
612
613 trans = (GLfloat *) _mesa_malloc (count * 4 * sizeof (GLfloat));
614 if (trans == NULL)
615 {
616 _mesa_error (ctx, GL_OUT_OF_MEMORY, "glUniformMatrix2fvARB");
617 return;
618 }
619 for (pt = trans, pv = value; pt != trans + count * 4; pt += 4, pv += 4)
620 {
621 pt[0] = pv[0];
622 pt[1] = pv[2];
623 pt[2] = pv[1];
624 pt[3] = pv[3];
625 }
626 if (!_slang_write_uniform (pro, location, count, trans, GL_FLOAT_MAT2))
627 _mesa_error (ctx, GL_INVALID_OPERATION, "glUniformMatrix2fvARB");
628 _mesa_free (trans);
629 }
630 else
631 {
632 if (!_slang_write_uniform (pro, location, count, value, GL_FLOAT_MAT2))
633 _mesa_error (ctx, GL_INVALID_OPERATION, "glUniformMatrix2fvARB");
634 }
635 }
636 }
637
638 GLvoid GLAPIENTRY
639 _mesa_UniformMatrix3fvARB (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
640 {
641 GET_CURRENT_CONTEXT(ctx);
642 GET_CURRENT_LINKED_PROGRAM(pro, "glUniformMatrix3fvARB");
643
644 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
645
646 if (pro != NULL)
647 {
648 if (transpose)
649 {
650 GLfloat *trans, *pt;
651 const GLfloat *pv;
652
653 trans = (GLfloat *) _mesa_malloc (count * 9 * sizeof (GLfloat));
654 if (trans == NULL)
655 {
656 _mesa_error (ctx, GL_OUT_OF_MEMORY, "glUniformMatrix3fvARB");
657 return;
658 }
659 for (pt = trans, pv = value; pt != trans + count * 9; pt += 9, pv += 9)
660 {
661 pt[0] = pv[0];
662 pt[1] = pv[3];
663 pt[2] = pv[6];
664 pt[3] = pv[1];
665 pt[4] = pv[4];
666 pt[5] = pv[7];
667 pt[6] = pv[2];
668 pt[7] = pv[5];
669 pt[8] = pv[8];
670 }
671 if (!_slang_write_uniform (pro, location, count, trans, GL_FLOAT_MAT3))
672 _mesa_error (ctx, GL_INVALID_OPERATION, "glUniformMatrix3fvARB");
673 _mesa_free (trans);
674 }
675 else
676 {
677 if (!_slang_write_uniform (pro, location, count, value, GL_FLOAT_MAT3))
678 _mesa_error (ctx, GL_INVALID_OPERATION, "glUniformMatrix3fvARB");
679 }
680 }
681 }
682
683 GLvoid GLAPIENTRY
684 _mesa_UniformMatrix4fvARB (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
685 {
686 GET_CURRENT_CONTEXT(ctx);
687 GET_CURRENT_LINKED_PROGRAM(pro, "glUniformMatrix4fvARB");
688
689 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
690
691 if (pro != NULL)
692 {
693 if (transpose)
694 {
695 GLfloat *trans, *pt;
696 const GLfloat *pv;
697
698 trans = (GLfloat *) _mesa_malloc (count * 16 * sizeof (GLfloat));
699 if (trans == NULL)
700 {
701 _mesa_error (ctx, GL_OUT_OF_MEMORY, "glUniformMatrix4fvARB");
702 return;
703 }
704 for (pt = trans, pv = value; pt != trans + count * 16; pt += 16, pv += 16)
705 {
706 _math_transposef (pt, pv);
707 }
708 if (!_slang_write_uniform (pro, location, count, trans, GL_FLOAT_MAT4))
709 _mesa_error (ctx, GL_INVALID_OPERATION, "glUniformMatrix4fvARB");
710 _mesa_free (trans);
711 }
712 else
713 {
714 if (!_slang_write_uniform (pro, location, count, value, GL_FLOAT_MAT4))
715 _mesa_error (ctx, GL_INVALID_OPERATION, "glUniformMatrix4fvARB");
716 }
717 }
718 }
719
720 static GLboolean
721 _mesa_get_object_parameter (GLhandleARB obj, GLenum pname, GLvoid *params, GLboolean *integral,
722 GLint *size)
723 {
724 GET_CURRENT_CONTEXT(ctx);
725 GLint *ipar = (GLint *) params;
726
727 /* set default values */
728 *integral = GL_TRUE; /* indicates param type, TRUE: GLint, FALSE: GLfloat */
729 *size = 1; /* param array size */
730
731 switch (pname)
732 {
733 case GL_OBJECT_TYPE_ARB:
734 case GL_OBJECT_DELETE_STATUS_ARB:
735 case GL_OBJECT_INFO_LOG_LENGTH_ARB:
736 {
737 GET_GENERIC(gen, obj, "glGetObjectParameterivARB");
738
739 if (gen == NULL)
740 return GL_FALSE;
741
742 switch (pname)
743 {
744 case GL_OBJECT_TYPE_ARB:
745 *ipar = (**gen).GetType (gen);
746 break;
747 case GL_OBJECT_DELETE_STATUS_ARB:
748 *ipar = (**gen).GetDeleteStatus (gen);
749 break;
750 case GL_OBJECT_INFO_LOG_LENGTH_ARB:
751 {
752 const GLcharARB *info = (**gen).GetInfoLog (gen);
753
754 if (info == NULL)
755 *ipar = 0;
756 else
757 *ipar = _mesa_strlen (info) + 1;
758 }
759 break;
760 }
761
762 RELEASE_GENERIC(gen);
763 }
764 break;
765 case GL_OBJECT_SUBTYPE_ARB:
766 case GL_OBJECT_COMPILE_STATUS_ARB:
767 case GL_OBJECT_SHADER_SOURCE_LENGTH_ARB:
768 {
769 GET_SHADER(sha, obj, "glGetObjectParameterivARB");
770
771 if (sha == NULL)
772 return GL_FALSE;
773
774 switch (pname)
775 {
776 case GL_OBJECT_SUBTYPE_ARB:
777 *ipar = (**sha).GetSubType (sha);
778 break;
779 case GL_OBJECT_COMPILE_STATUS_ARB:
780 *ipar = (**sha).GetCompileStatus (sha);
781 break;
782 case GL_OBJECT_SHADER_SOURCE_LENGTH_ARB:
783 {
784 const GLcharARB *src = (**sha).GetSource (sha);
785
786 if (src == NULL)
787 *ipar = 0;
788 else
789 *ipar = _mesa_strlen (src) + 1;
790 }
791 break;
792 }
793
794 RELEASE_SHADER(sha);
795 }
796 break;
797 case GL_OBJECT_LINK_STATUS_ARB:
798 case GL_OBJECT_VALIDATE_STATUS_ARB:
799 case GL_OBJECT_ATTACHED_OBJECTS_ARB:
800 case GL_OBJECT_ACTIVE_UNIFORMS_ARB:
801 case GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB:
802 {
803 GET_PROGRAM(pro, obj, "glGetObjectParameterivARB");
804
805 if (pro == NULL)
806 return GL_FALSE;
807
808 switch (pname)
809 {
810 case GL_OBJECT_LINK_STATUS_ARB:
811 *ipar = (**pro).GetLinkStatus (pro);
812 break;
813 case GL_OBJECT_VALIDATE_STATUS_ARB:
814 *ipar = (**pro).GetValidateStatus (pro);
815 break;
816 case GL_OBJECT_ATTACHED_OBJECTS_ARB:
817 *ipar = (**pro)._container.GetAttachedCount ((I_CONTAINER) pro);
818 break;
819 case GL_OBJECT_ACTIVE_UNIFORMS_ARB:
820 *ipar = _slang_get_active_uniform_count (pro);
821 break;
822 case GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB:
823 *ipar = _slang_get_active_uniform_max_length (pro);
824 break;
825 }
826
827 RELEASE_PROGRAM(pro);
828 }
829 break;
830 default:
831 _mesa_error (ctx, GL_INVALID_ENUM, "glGetObjectParameterivARB");
832 return GL_FALSE;
833 }
834
835 return GL_TRUE;
836 }
837
838 GLvoid GLAPIENTRY
839 _mesa_GetObjectParameterfvARB (GLhandleARB obj, GLenum pname, GLfloat *params)
840 {
841 GLboolean integral;
842 GLint size;
843
844 assert (sizeof (GLfloat) == sizeof (GLint));
845
846 if (_mesa_get_object_parameter (obj, pname, (GLvoid *) params, &integral, &size))
847 if (integral)
848 {
849 GLint i;
850
851 for (i = 0; i < size; i++)
852 params[i] = (GLfloat) ((GLint *) params)[i];
853 }
854 }
855
856 GLvoid GLAPIENTRY
857 _mesa_GetObjectParameterivARB (GLhandleARB obj, GLenum pname, GLint *params)
858 {
859 GLboolean integral;
860 GLint size;
861
862 assert (sizeof (GLfloat) == sizeof (GLint));
863
864 if (_mesa_get_object_parameter (obj, pname, (GLvoid *) params, &integral, &size))
865 if (!integral)
866 {
867 GLint i;
868
869 for (i = 0; i < size; i++)
870 params[i] = (GLint) ((GLfloat *) params)[i];
871 }
872 }
873
874 static GLvoid
875 _mesa_get_string (const GLcharARB *src, GLsizei maxLength, GLsizei *length, GLcharARB *str)
876 {
877 GLsizei len;
878
879 if (maxLength == 0)
880 {
881 if (length != NULL)
882 *length = 0;
883 return;
884 }
885
886 if (src == NULL)
887 src = "";
888
889 len = _mesa_strlen (src);
890 if (len >= maxLength)
891 len = maxLength - 1;
892
893 _mesa_memcpy (str, src, len * sizeof (GLcharARB));
894 str[len] = '\0';
895 if (length != NULL)
896 *length = len;
897 }
898
899 GLvoid GLAPIENTRY
900 _mesa_GetInfoLogARB (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog)
901 {
902 GET_CURRENT_CONTEXT(ctx);
903 GET_GENERIC(gen, obj, "glGetInfoLogARB");
904
905 if (gen != NULL)
906 {
907 _mesa_get_string ((**gen).GetInfoLog (gen), maxLength, length, infoLog);
908 RELEASE_GENERIC(gen);
909 }
910 }
911
912 GLvoid GLAPIENTRY
913 _mesa_GetAttachedObjectsARB (GLhandleARB containerObj, GLsizei maxCount, GLsizei *count,
914 GLhandleARB *obj)
915 {
916 GET_CURRENT_CONTEXT(ctx);
917 GLsizei cnt, i;
918 GET_CONTAINER(con, containerObj, "glGetAttachedObjectsARB");
919
920 if (con != NULL)
921 {
922 cnt = (**con).GetAttachedCount (con);
923 if (cnt > maxCount)
924 cnt = maxCount;
925 if (count != NULL)
926 *count = cnt;
927
928 for (i = 0; i < cnt; i++)
929 {
930 I_GENERIC x = (**con).GetAttached (con, i);
931 obj[i] = (**x).GetName (x);
932 RELEASE_GENERIC(x);
933 }
934 RELEASE_CONTAINER(con);
935 }
936 }
937
938 GLint GLAPIENTRY
939 _mesa_GetUniformLocationARB (GLhandleARB programObj, const GLcharARB *name)
940 {
941 GET_CURRENT_CONTEXT(ctx);
942 GLint loc = -1;
943 GET_LINKED_PROGRAM(pro, programObj, "glGetUniformLocationARB");
944
945 if (pro != NULL)
946 {
947 if (name != NULL && (name[0] != 'g' || name[1] != 'l' || name[2] != '_'))
948 loc = _slang_get_uniform_location (pro, name);
949 RELEASE_PROGRAM(pro);
950 }
951 return loc;
952 }
953
954 GLvoid GLAPIENTRY
955 _mesa_GetActiveUniformARB (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length,
956 GLint *size, GLenum *type, GLcharARB *name)
957 {
958 GET_CURRENT_CONTEXT(ctx);
959 GET_PROGRAM(pro, programObj, "glGetActiveUniformARB");
960
961 if (pro != NULL)
962 {
963 if (index < _slang_get_active_uniform_count (pro))
964 _slang_get_active_uniform (pro, index, maxLength, length, size, type, name);
965 else
966 _mesa_error (ctx, GL_INVALID_VALUE, "glGetActiveUniformARB");
967 RELEASE_PROGRAM(pro);
968 }
969 }
970
971 GLvoid GLAPIENTRY
972 _mesa_GetUniformfvARB (GLhandleARB programObj, GLint location, GLfloat *params)
973 {
974 GET_CURRENT_CONTEXT(ctx);
975 GET_LINKED_PROGRAM(pro, programObj, "glGetUniformfvARB");
976
977 if (pro != NULL)
978 {
979 /* TODO */
980 RELEASE_PROGRAM(pro);
981 }
982 }
983
984 GLvoid GLAPIENTRY
985 _mesa_GetUniformivARB (GLhandleARB programObj, GLint location, GLint *params)
986 {
987 GET_CURRENT_CONTEXT(ctx);
988 GET_LINKED_PROGRAM(pro, programObj, "glGetUniformivARB");
989
990 if (pro != NULL)
991 {
992 /* TODO */
993 RELEASE_PROGRAM(pro);
994 }
995 }
996
997 GLvoid GLAPIENTRY
998 _mesa_GetShaderSourceARB (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *source)
999 {
1000 GET_CURRENT_CONTEXT(ctx);
1001 GET_SHADER(sha, obj, "glGetShaderSourceARB");
1002
1003 if (sha != NULL)
1004 {
1005 _mesa_get_string ((**sha).GetSource (sha), maxLength, length, source);
1006 RELEASE_SHADER(sha);
1007 }
1008 }
1009
1010 /* GL_ARB_vertex_shader */
1011
1012 GLvoid GLAPIENTRY
1013 _mesa_BindAttribLocationARB (GLhandleARB programObj, GLuint index, const GLcharARB *name)
1014 {
1015 GET_CURRENT_CONTEXT(ctx);
1016 GET_PROGRAM(pro, programObj, "glBindAttribLocationARB");
1017
1018 if (pro != NULL)
1019 {
1020 if (name != NULL && (name[0] != 'g' || name[1] != 'l' || name[2] != '_'))
1021 {
1022 /* TODO */
1023 }
1024 RELEASE_PROGRAM(pro);
1025 }
1026 }
1027
1028 GLvoid GLAPIENTRY
1029 _mesa_GetActiveAttribARB (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length,
1030 GLint *size, GLenum *type, GLcharARB *name)
1031 {
1032 GET_CURRENT_CONTEXT(ctx);
1033 GET_PROGRAM(pro, programObj, "glGetActiveAttribARB");
1034
1035 if (pro != NULL)
1036 {
1037 /* TODO */
1038 RELEASE_PROGRAM(pro);
1039 }
1040 }
1041
1042 GLint GLAPIENTRY
1043 _mesa_GetAttribLocationARB (GLhandleARB programObj, const GLcharARB *name)
1044 {
1045 GET_CURRENT_CONTEXT(ctx);
1046 GLint loc = -1;
1047 GET_PROGRAM(pro, programObj, "glGetAttribLocationARB");
1048
1049 if (pro != NULL)
1050 {
1051 if (name != NULL && (name[0] != 'g' || name[1] != 'l' || name[2] != '_'))
1052 {
1053 /* TODO */
1054 }
1055 RELEASE_PROGRAM(pro);
1056 }
1057 return loc;
1058 }
1059
1060 GLvoid
1061 _mesa_init_shaderobjects (GLcontext *ctx)
1062 {
1063 ctx->ShaderObjects.CurrentProgram = NULL;
1064
1065 _mesa_init_shaderobjects_3dlabs (ctx);
1066 }
1067