Silence a few -pedantic warnings.
[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];
398 v[0] = v0;
399 v[1] = v1;
400
401 if (!_slang_write_uniform (pro, location, 1, v, GL_FLOAT_VEC2))
402 _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform2fARB");
403 }
404 }
405
406 GLvoid GLAPIENTRY
407 _mesa_Uniform3fARB (GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
408 {
409 GET_CURRENT_CONTEXT(ctx);
410 GET_CURRENT_LINKED_PROGRAM(pro, "glUniform3fARB");
411
412 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
413
414 if (pro != NULL)
415 {
416 GLfloat v[3];
417 v[0] = v0;
418 v[1] = v1;
419 v[2] = v2;
420
421 if (!_slang_write_uniform (pro, location, 1, v, GL_FLOAT_VEC3))
422 _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform3fARB");
423 }
424 }
425
426 GLvoid GLAPIENTRY
427 _mesa_Uniform4fARB (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
428 {
429 GET_CURRENT_CONTEXT(ctx);
430 GET_CURRENT_LINKED_PROGRAM(pro, "glUniform4fARB");
431
432 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
433
434 if (pro != NULL)
435 {
436 GLfloat v[4];
437 v[0] = v0;
438 v[1] = v1;
439 v[2] = v2;
440 v[3] = v3;
441
442 if (!_slang_write_uniform (pro, location, 1, v, GL_FLOAT_VEC4))
443 _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform4fARB");
444 }
445 }
446
447 GLvoid GLAPIENTRY
448 _mesa_Uniform1iARB (GLint location, GLint v0)
449 {
450 GET_CURRENT_CONTEXT(ctx);
451 GET_CURRENT_LINKED_PROGRAM(pro, "glUniform1iARB");
452
453 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
454
455 if (pro != NULL)
456 {
457 if (!_slang_write_uniform (pro, location, 1, &v0, GL_INT))
458 _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform1iARB");
459 }
460 }
461
462 GLvoid GLAPIENTRY
463 _mesa_Uniform2iARB (GLint location, GLint v0, GLint v1)
464 {
465 GET_CURRENT_CONTEXT(ctx);
466 GET_CURRENT_LINKED_PROGRAM(pro, "glUniform2iARB");
467
468 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
469
470 if (pro != NULL)
471 {
472 GLint v[2];
473 v[0] = v0;
474 v[1] = v1;
475
476 if (!_slang_write_uniform (pro, location, 1, v, GL_INT_VEC2))
477 _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform2iARB");
478 }
479 }
480
481 GLvoid GLAPIENTRY
482 _mesa_Uniform3iARB (GLint location, GLint v0, GLint v1, GLint v2)
483 {
484 GET_CURRENT_CONTEXT(ctx);
485 GET_CURRENT_LINKED_PROGRAM(pro, "glUniform3iARB");
486
487 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
488
489 if (pro != NULL)
490 {
491 GLint v[3];
492 v[0] = v0;
493 v[1] = v1;
494 v[2] = v2;
495
496 if (!_slang_write_uniform (pro, location, 1, v, GL_INT_VEC3))
497 _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform3iARB");
498 }
499 }
500
501 GLvoid GLAPIENTRY
502 _mesa_Uniform4iARB (GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
503 {
504 GET_CURRENT_CONTEXT(ctx);
505 GET_CURRENT_LINKED_PROGRAM(pro, "glUniform4iARB");
506
507 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
508
509 if (pro != NULL)
510 {
511 GLint v[4];
512 v[0] = v0;
513 v[1] = v1;
514 v[2] = v2;
515 v[3] = v3;
516
517 if (!_slang_write_uniform (pro, location, 1, v, GL_INT_VEC4))
518 _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform4iARB");
519 }
520 }
521
522 GLvoid GLAPIENTRY
523 _mesa_Uniform1fvARB (GLint location, GLsizei count, const GLfloat *value)
524 {
525 GET_CURRENT_CONTEXT(ctx);
526 GET_CURRENT_LINKED_PROGRAM(pro, "glUniform1fvARB");
527
528 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
529
530 if (pro != NULL)
531 {
532 if (!_slang_write_uniform (pro, location, count, value, GL_FLOAT))
533 _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform1fvARB");
534 }
535 }
536
537 GLvoid GLAPIENTRY
538 _mesa_Uniform2fvARB (GLint location, GLsizei count, const GLfloat *value)
539 {
540 GET_CURRENT_CONTEXT(ctx);
541 GET_CURRENT_LINKED_PROGRAM(pro, "glUniform2fvARB");
542
543 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
544
545 if (pro != NULL)
546 {
547 if (!_slang_write_uniform (pro, location, count, value, GL_FLOAT_VEC2))
548 _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform2fvARB");
549 }
550 }
551
552 GLvoid GLAPIENTRY
553 _mesa_Uniform3fvARB (GLint location, GLsizei count, const GLfloat *value)
554 {
555 GET_CURRENT_CONTEXT(ctx);
556 GET_CURRENT_LINKED_PROGRAM(pro, "glUniform3fvARB");
557
558 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
559
560 if (pro != NULL)
561 {
562 if (!_slang_write_uniform (pro, location, count, value, GL_FLOAT_VEC3))
563 _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform3fvARB");
564 }
565 }
566
567 GLvoid GLAPIENTRY
568 _mesa_Uniform4fvARB (GLint location, GLsizei count, const GLfloat *value)
569 {
570 GET_CURRENT_CONTEXT(ctx);
571 GET_CURRENT_LINKED_PROGRAM(pro, "glUniform4fvARB");
572
573 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
574
575 if (pro != NULL)
576 {
577 if (!_slang_write_uniform (pro, location, count, value, GL_FLOAT_VEC4))
578 _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform4fvARB");
579 }
580 }
581
582 GLvoid GLAPIENTRY
583 _mesa_Uniform1ivARB (GLint location, GLsizei count, const GLint *value)
584 {
585 GET_CURRENT_CONTEXT(ctx);
586 GET_CURRENT_LINKED_PROGRAM(pro, "glUniform1ivARB");
587
588 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
589
590 if (pro != NULL)
591 {
592 if (!_slang_write_uniform (pro, location, count, value, GL_INT))
593 _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform1ivARB");
594 }
595 }
596
597 GLvoid GLAPIENTRY
598 _mesa_Uniform2ivARB (GLint location, GLsizei count, const GLint *value)
599 {
600 GET_CURRENT_CONTEXT(ctx);
601 GET_CURRENT_LINKED_PROGRAM(pro, "glUniform2ivARB");
602
603 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
604
605 if (pro != NULL)
606 {
607 if (!_slang_write_uniform (pro, location, count, value, GL_INT_VEC2))
608 _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform2ivARB");
609 }
610 }
611
612 GLvoid GLAPIENTRY
613 _mesa_Uniform3ivARB (GLint location, GLsizei count, const GLint *value)
614 {
615 GET_CURRENT_CONTEXT(ctx);
616 GET_CURRENT_LINKED_PROGRAM(pro, "glUniform3ivARB");
617
618 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
619
620 if (pro != NULL)
621 {
622 if (!_slang_write_uniform (pro, location, count, value, GL_INT_VEC3))
623 _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform3ivARB");
624 }
625 }
626
627 GLvoid GLAPIENTRY
628 _mesa_Uniform4ivARB (GLint location, GLsizei count, const GLint *value)
629 {
630 GET_CURRENT_CONTEXT(ctx);
631 GET_CURRENT_LINKED_PROGRAM(pro, "glUniform4ivARB");
632
633 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
634
635 if (pro != NULL)
636 {
637 if (!_slang_write_uniform (pro, location, count, value, GL_INT_VEC4))
638 _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform4ivARB");
639 }
640 }
641
642 GLvoid GLAPIENTRY
643 _mesa_UniformMatrix2fvARB (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
644 {
645 GET_CURRENT_CONTEXT(ctx);
646 GET_CURRENT_LINKED_PROGRAM(pro, "glUniformMatrix2fvARB");
647
648 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
649
650 if (pro != NULL)
651 {
652 if (transpose)
653 {
654 GLfloat *trans, *pt;
655 const GLfloat *pv;
656
657 trans = (GLfloat *) _mesa_malloc (count * 4 * sizeof (GLfloat));
658 if (trans == NULL)
659 {
660 _mesa_error (ctx, GL_OUT_OF_MEMORY, "glUniformMatrix2fvARB");
661 return;
662 }
663 for (pt = trans, pv = value; pt != trans + count * 4; pt += 4, pv += 4)
664 {
665 pt[0] = pv[0];
666 pt[1] = pv[2];
667 pt[2] = pv[1];
668 pt[3] = pv[3];
669 }
670 if (!_slang_write_uniform (pro, location, count, trans, GL_FLOAT_MAT2))
671 _mesa_error (ctx, GL_INVALID_OPERATION, "glUniformMatrix2fvARB");
672 _mesa_free (trans);
673 }
674 else
675 {
676 if (!_slang_write_uniform (pro, location, count, value, GL_FLOAT_MAT2))
677 _mesa_error (ctx, GL_INVALID_OPERATION, "glUniformMatrix2fvARB");
678 }
679 }
680 }
681
682 GLvoid GLAPIENTRY
683 _mesa_UniformMatrix3fvARB (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
684 {
685 GET_CURRENT_CONTEXT(ctx);
686 GET_CURRENT_LINKED_PROGRAM(pro, "glUniformMatrix3fvARB");
687
688 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
689
690 if (pro != NULL)
691 {
692 if (transpose)
693 {
694 GLfloat *trans, *pt;
695 const GLfloat *pv;
696
697 trans = (GLfloat *) _mesa_malloc (count * 9 * sizeof (GLfloat));
698 if (trans == NULL)
699 {
700 _mesa_error (ctx, GL_OUT_OF_MEMORY, "glUniformMatrix3fvARB");
701 return;
702 }
703 for (pt = trans, pv = value; pt != trans + count * 9; pt += 9, pv += 9)
704 {
705 pt[0] = pv[0];
706 pt[1] = pv[3];
707 pt[2] = pv[6];
708 pt[3] = pv[1];
709 pt[4] = pv[4];
710 pt[5] = pv[7];
711 pt[6] = pv[2];
712 pt[7] = pv[5];
713 pt[8] = pv[8];
714 }
715 if (!_slang_write_uniform (pro, location, count, trans, GL_FLOAT_MAT3))
716 _mesa_error (ctx, GL_INVALID_OPERATION, "glUniformMatrix3fvARB");
717 _mesa_free (trans);
718 }
719 else
720 {
721 if (!_slang_write_uniform (pro, location, count, value, GL_FLOAT_MAT3))
722 _mesa_error (ctx, GL_INVALID_OPERATION, "glUniformMatrix3fvARB");
723 }
724 }
725 }
726
727 GLvoid GLAPIENTRY
728 _mesa_UniformMatrix4fvARB (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
729 {
730 GET_CURRENT_CONTEXT(ctx);
731 GET_CURRENT_LINKED_PROGRAM(pro, "glUniformMatrix4fvARB");
732
733 FLUSH_VERTICES(ctx, _NEW_PROGRAM);
734
735 if (pro != NULL)
736 {
737 if (transpose)
738 {
739 GLfloat *trans, *pt;
740 const GLfloat *pv;
741
742 trans = (GLfloat *) _mesa_malloc (count * 16 * sizeof (GLfloat));
743 if (trans == NULL)
744 {
745 _mesa_error (ctx, GL_OUT_OF_MEMORY, "glUniformMatrix4fvARB");
746 return;
747 }
748 for (pt = trans, pv = value; pt != trans + count * 16; pt += 16, pv += 16)
749 {
750 _math_transposef (pt, pv);
751 }
752 if (!_slang_write_uniform (pro, location, count, trans, GL_FLOAT_MAT4))
753 _mesa_error (ctx, GL_INVALID_OPERATION, "glUniformMatrix4fvARB");
754 _mesa_free (trans);
755 }
756 else
757 {
758 if (!_slang_write_uniform (pro, location, count, value, GL_FLOAT_MAT4))
759 _mesa_error (ctx, GL_INVALID_OPERATION, "glUniformMatrix4fvARB");
760 }
761 }
762 }
763
764 static GLboolean
765 _mesa_get_object_parameter (GLhandleARB obj, GLenum pname, GLvoid *params, GLboolean *integral,
766 GLint *size)
767 {
768 GET_CURRENT_CONTEXT(ctx);
769 GLint *ipar = (GLint *) params;
770
771 /* set default values */
772 *integral = GL_TRUE; /* indicates param type, TRUE: GLint, FALSE: GLfloat */
773 *size = 1; /* param array size */
774
775 switch (pname)
776 {
777 case GL_OBJECT_TYPE_ARB:
778 case GL_OBJECT_DELETE_STATUS_ARB:
779 case GL_OBJECT_INFO_LOG_LENGTH_ARB:
780 {
781 GET_GENERIC(gen, obj, "glGetObjectParameterivARB");
782
783 if (gen == NULL)
784 return GL_FALSE;
785
786 switch (pname)
787 {
788 case GL_OBJECT_TYPE_ARB:
789 *ipar = (**gen).GetType (gen);
790 break;
791 case GL_OBJECT_DELETE_STATUS_ARB:
792 *ipar = (**gen).GetDeleteStatus (gen);
793 break;
794 case GL_OBJECT_INFO_LOG_LENGTH_ARB:
795 {
796 const GLcharARB *info = (**gen).GetInfoLog (gen);
797
798 if (info == NULL)
799 *ipar = 0;
800 else
801 *ipar = _mesa_strlen (info) + 1;
802 }
803 break;
804 }
805
806 RELEASE_GENERIC(gen);
807 }
808 break;
809 case GL_OBJECT_SUBTYPE_ARB:
810 case GL_OBJECT_COMPILE_STATUS_ARB:
811 case GL_OBJECT_SHADER_SOURCE_LENGTH_ARB:
812 {
813 GET_SHADER(sha, obj, "glGetObjectParameterivARB");
814
815 if (sha == NULL)
816 return GL_FALSE;
817
818 switch (pname)
819 {
820 case GL_OBJECT_SUBTYPE_ARB:
821 *ipar = (**sha).GetSubType (sha);
822 break;
823 case GL_OBJECT_COMPILE_STATUS_ARB:
824 *ipar = (**sha).GetCompileStatus (sha);
825 break;
826 case GL_OBJECT_SHADER_SOURCE_LENGTH_ARB:
827 {
828 const GLcharARB *src = (**sha).GetSource (sha);
829
830 if (src == NULL)
831 *ipar = 0;
832 else
833 *ipar = _mesa_strlen (src) + 1;
834 }
835 break;
836 }
837
838 RELEASE_SHADER(sha);
839 }
840 break;
841 case GL_OBJECT_LINK_STATUS_ARB:
842 case GL_OBJECT_VALIDATE_STATUS_ARB:
843 case GL_OBJECT_ATTACHED_OBJECTS_ARB:
844 case GL_OBJECT_ACTIVE_UNIFORMS_ARB:
845 case GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB:
846 {
847 GET_PROGRAM(pro, obj, "glGetObjectParameterivARB");
848
849 if (pro == NULL)
850 return GL_FALSE;
851
852 switch (pname)
853 {
854 case GL_OBJECT_LINK_STATUS_ARB:
855 *ipar = (**pro).GetLinkStatus (pro);
856 break;
857 case GL_OBJECT_VALIDATE_STATUS_ARB:
858 *ipar = (**pro).GetValidateStatus (pro);
859 break;
860 case GL_OBJECT_ATTACHED_OBJECTS_ARB:
861 *ipar = (**pro)._container.GetAttachedCount ((I_CONTAINER) pro);
862 break;
863 case GL_OBJECT_ACTIVE_UNIFORMS_ARB:
864 *ipar = _slang_get_active_uniform_count (pro);
865 break;
866 case GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB:
867 *ipar = _slang_get_active_uniform_max_length (pro);
868 break;
869 }
870
871 RELEASE_PROGRAM(pro);
872 }
873 break;
874 default:
875 _mesa_error (ctx, GL_INVALID_ENUM, "glGetObjectParameterivARB");
876 return GL_FALSE;
877 }
878
879 return GL_TRUE;
880 }
881
882 GLvoid GLAPIENTRY
883 _mesa_GetObjectParameterfvARB (GLhandleARB obj, GLenum pname, GLfloat *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] = (GLfloat) ((GLint *) params)[i];
897 }
898 }
899
900 GLvoid GLAPIENTRY
901 _mesa_GetObjectParameterivARB (GLhandleARB obj, GLenum pname, GLint *params)
902 {
903 GLboolean integral;
904 GLint size;
905
906 assert (sizeof (GLfloat) == sizeof (GLint));
907
908 if (_mesa_get_object_parameter (obj, pname, (GLvoid *) params, &integral, &size))
909 if (!integral)
910 {
911 GLint i;
912
913 for (i = 0; i < size; i++)
914 params[i] = (GLint) ((GLfloat *) params)[i];
915 }
916 }
917
918
919 /**
920 * Copy string from <src> to <dst>, up to maxLength characters, returning
921 * length of <dst> in <length>.
922 * \param src the strings source
923 * \param maxLength max chars to copy
924 * \param length returns numberof chars copied
925 * \param dst the string destination
926 */
927 static GLvoid
928 copy_string(const GLcharARB *src, GLsizei maxLength, GLsizei *length,
929 GLcharARB *dst)
930 {
931 GLsizei len;
932 for (len = 0; len < maxLength - 1 && src && src[len]; len++)
933 dst[len] = src[len];
934 if (maxLength > 0)
935 dst[len] = 0;
936 if (length)
937 *length = len;
938 }
939
940
941 GLvoid GLAPIENTRY
942 _mesa_GetInfoLogARB (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog)
943 {
944 GET_CURRENT_CONTEXT(ctx);
945 GET_GENERIC(gen, obj, "glGetInfoLogARB");
946
947 if (gen != NULL)
948 {
949 copy_string((**gen).GetInfoLog (gen), maxLength, length, infoLog);
950 RELEASE_GENERIC(gen);
951 }
952 }
953
954 GLvoid GLAPIENTRY
955 _mesa_GetAttachedObjectsARB (GLhandleARB containerObj, GLsizei maxCount, GLsizei *count,
956 GLhandleARB *obj)
957 {
958 GET_CURRENT_CONTEXT(ctx);
959 GLsizei cnt, i;
960 GET_CONTAINER(con, containerObj, "glGetAttachedObjectsARB");
961
962 if (con != NULL)
963 {
964 cnt = (**con).GetAttachedCount (con);
965 if (cnt > maxCount)
966 cnt = maxCount;
967 if (count != NULL)
968 *count = cnt;
969
970 for (i = 0; i < cnt; i++)
971 {
972 I_GENERIC x = (**con).GetAttached (con, i);
973 obj[i] = (**x).GetName (x);
974 RELEASE_GENERIC(x);
975 }
976 RELEASE_CONTAINER(con);
977 }
978 }
979
980 GLint GLAPIENTRY
981 _mesa_GetUniformLocationARB (GLhandleARB programObj, const GLcharARB *name)
982 {
983 GET_CURRENT_CONTEXT(ctx);
984 GLint loc = -1;
985 GET_LINKED_PROGRAM(pro, programObj, "glGetUniformLocationARB");
986
987 if (pro != NULL)
988 {
989 if (name != NULL && (name[0] != 'g' || name[1] != 'l' || name[2] != '_'))
990 loc = _slang_get_uniform_location (pro, name);
991 RELEASE_PROGRAM(pro);
992 }
993 return loc;
994 }
995
996 GLvoid GLAPIENTRY
997 _mesa_GetActiveUniformARB (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length,
998 GLint *size, GLenum *type, GLcharARB *name)
999 {
1000 GET_CURRENT_CONTEXT(ctx);
1001 GET_PROGRAM(pro, programObj, "glGetActiveUniformARB");
1002
1003 if (pro != NULL)
1004 {
1005 if (index < _slang_get_active_uniform_count (pro))
1006 _slang_get_active_uniform (pro, index, maxLength, length, size, type, name);
1007 else
1008 _mesa_error (ctx, GL_INVALID_VALUE, "glGetActiveUniformARB");
1009 RELEASE_PROGRAM(pro);
1010 }
1011 }
1012
1013 GLvoid GLAPIENTRY
1014 _mesa_GetUniformfvARB (GLhandleARB programObj, GLint location, GLfloat *params)
1015 {
1016 GET_CURRENT_CONTEXT(ctx);
1017 GET_LINKED_PROGRAM(pro, programObj, "glGetUniformfvARB");
1018
1019 if (pro != NULL)
1020 {
1021 /* TODO */
1022 RELEASE_PROGRAM(pro);
1023 }
1024 }
1025
1026 GLvoid GLAPIENTRY
1027 _mesa_GetUniformivARB (GLhandleARB programObj, GLint location, GLint *params)
1028 {
1029 GET_CURRENT_CONTEXT(ctx);
1030 GET_LINKED_PROGRAM(pro, programObj, "glGetUniformivARB");
1031
1032 if (pro != NULL)
1033 {
1034 /* TODO */
1035 RELEASE_PROGRAM(pro);
1036 }
1037 }
1038
1039 GLvoid GLAPIENTRY
1040 _mesa_GetShaderSourceARB (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *source)
1041 {
1042 GET_CURRENT_CONTEXT(ctx);
1043 GET_SHADER(sha, obj, "glGetShaderSourceARB");
1044
1045 if (sha != NULL)
1046 {
1047 copy_string((**sha).GetSource (sha), maxLength, length, source);
1048 RELEASE_SHADER(sha);
1049 }
1050 }
1051
1052 /* GL_ARB_vertex_shader */
1053
1054 GLvoid GLAPIENTRY
1055 _mesa_BindAttribLocationARB (GLhandleARB programObj, GLuint index, const GLcharARB *name)
1056 {
1057 GET_CURRENT_CONTEXT(ctx);
1058 GET_PROGRAM(pro, programObj, "glBindAttribLocationARB");
1059
1060 if (pro != NULL)
1061 {
1062 if (name != NULL && (name[0] != 'g' || name[1] != 'l' || name[2] != '_'))
1063 {
1064 /* TODO */
1065 }
1066 RELEASE_PROGRAM(pro);
1067 }
1068 }
1069
1070 GLvoid GLAPIENTRY
1071 _mesa_GetActiveAttribARB (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length,
1072 GLint *size, GLenum *type, GLcharARB *name)
1073 {
1074 GET_CURRENT_CONTEXT(ctx);
1075 GET_PROGRAM(pro, programObj, "glGetActiveAttribARB");
1076
1077 if (pro != NULL)
1078 {
1079 /* TODO */
1080 RELEASE_PROGRAM(pro);
1081 }
1082 }
1083
1084 GLint GLAPIENTRY
1085 _mesa_GetAttribLocationARB (GLhandleARB programObj, const GLcharARB *name)
1086 {
1087 GET_CURRENT_CONTEXT(ctx);
1088 GLint loc = -1;
1089 GET_PROGRAM(pro, programObj, "glGetAttribLocationARB");
1090
1091 if (pro != NULL)
1092 {
1093 if (name != NULL && (name[0] != 'g' || name[1] != 'l' || name[2] != '_'))
1094 {
1095 /* TODO */
1096 }
1097 RELEASE_PROGRAM(pro);
1098 }
1099 return loc;
1100 }
1101
1102 GLvoid
1103 _mesa_init_shaderobjects (GLcontext *ctx)
1104 {
1105 ctx->ShaderObjects.CurrentProgram = NULL;
1106 ctx->ShaderObjects._FragmentShaderPresent = GL_FALSE;
1107 ctx->ShaderObjects._VertexShaderPresent = GL_FALSE;
1108
1109 _mesa_init_shaderobjects_3dlabs (ctx);
1110 }
1111