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