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