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