remove some test code;
[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 static GLboolean
645 _mesa_get_object_parameter (GLhandleARB obj, GLenum pname, GLvoid *params, GLboolean *integral,
646 GLint *size)
647 {
648 GET_CURRENT_CONTEXT(ctx);
649 struct gl2_unknown_intf **unk;
650 struct gl2_generic_intf **gen;
651 struct gl2_shader_intf **sha;
652 struct gl2_program_intf **pro;
653 GLint *ipar = (GLint *) params;
654 /*GLfloat *fpar = (GLfloat *) params;*/
655 GLboolean success = GL_TRUE;
656
657 _glthread_LOCK_MUTEX (ctx->Shared->Mutex);
658 unk = (struct gl2_unknown_intf **) _mesa_HashLookup (ctx->Shared->GL2Objects, obj);
659 _glthread_UNLOCK_MUTEX (ctx->Shared->Mutex);
660
661 if (unk == NULL)
662 {
663 _mesa_error (ctx, GL_INVALID_VALUE, "glGetObjectParameterivARB");
664 return GL_FALSE;
665 }
666
667 gen = (struct gl2_generic_intf **) (**unk).QueryInterface (unk, UIID_GENERIC);
668 if (gen == NULL)
669 {
670 _mesa_error (ctx, GL_INVALID_OPERATION, "glGetObjectParameterivARB");
671 return GL_FALSE;
672 }
673
674 sha = (struct gl2_shader_intf **) (**unk).QueryInterface (unk, UIID_SHADER);
675 pro = (struct gl2_program_intf **) (**unk).QueryInterface (unk, UIID_PROGRAM);
676
677 /* set default values */
678 *integral = GL_TRUE; /* indicates param type, TRUE: GLint, FALSE: GLfloat */
679 *size = 1; /* param array size */
680
681 switch (pname)
682 {
683 case GL_OBJECT_TYPE_ARB:
684 *ipar = (**gen).GetType (gen);
685 break;
686 case GL_OBJECT_SUBTYPE_ARB:
687 if (sha != NULL)
688 *ipar = (**sha).GetSubType (sha);
689 else {
690 _mesa_error (ctx, GL_INVALID_OPERATION, "glGetObjectParameterivARB");
691 success = GL_FALSE;
692 }
693 break;
694 case GL_OBJECT_DELETE_STATUS_ARB:
695 *ipar = (**gen).GetDeleteStatus (gen);
696 break;
697 case GL_OBJECT_COMPILE_STATUS_ARB:
698 if (sha != NULL)
699 *ipar = (**sha).GetCompileStatus (sha);
700 else {
701 _mesa_error (ctx, GL_INVALID_OPERATION, "glGetObjectParameterivARB");
702 success = GL_FALSE;
703 }
704 break;
705 case GL_OBJECT_LINK_STATUS_ARB:
706 if (pro != NULL)
707 *ipar = (**pro).GetLinkStatus (pro);
708 else {
709 _mesa_error (ctx, GL_INVALID_OPERATION, "glGetObjectParameterivARB");
710 success = GL_FALSE;
711 }
712 break;
713 case GL_OBJECT_VALIDATE_STATUS_ARB:
714 if (pro != NULL)
715 *ipar = (**pro).GetValidateStatus (pro);
716 else {
717 _mesa_error (ctx, GL_INVALID_OPERATION, "glGetObjectParameterivARB");
718 success = GL_FALSE;
719 }
720 break;
721 case GL_OBJECT_INFO_LOG_LENGTH_ARB:
722 {
723 const GLcharARB *info = (**gen).GetInfoLog (gen);
724 if (info == NULL)
725 *ipar = 0;
726 else
727 *ipar = _mesa_strlen (info) + 1;
728 }
729 break;
730 case GL_OBJECT_ATTACHED_OBJECTS_ARB:
731 if (pro != NULL)
732 *ipar = (**pro)._container.GetAttachedCount ((struct gl2_container_intf **) pro);
733 else {
734 _mesa_error (ctx, GL_INVALID_OPERATION, "glGetObjectParameterivARB");
735 success = GL_FALSE;
736 }
737 break;
738 case GL_OBJECT_ACTIVE_UNIFORMS_ARB:
739 if (pro != NULL)
740 *ipar = 0; /* TODO */
741 else {
742 _mesa_error (ctx, GL_INVALID_OPERATION, "glGetObjectParameterivARB");
743 success = GL_FALSE;
744 }
745 break;
746 case GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB:
747 if (pro != NULL)
748 *ipar = 0; /* TODO */
749 else {
750 _mesa_error (ctx, GL_INVALID_OPERATION, "glGetObjectParameterivARB");
751 success = GL_FALSE;
752 }
753 break;
754 case GL_OBJECT_SHADER_SOURCE_LENGTH_ARB:
755 if (sha != NULL) {
756 const GLcharARB *src = (**sha).GetSource (sha);
757 if (src == NULL)
758 *ipar = 0;
759 else
760 *ipar = _mesa_strlen (src) + 1;
761 } else {
762 _mesa_error (ctx, GL_INVALID_OPERATION, "glGetObjectParameterivARB");
763 success = GL_FALSE;
764 }
765 break;
766 default:
767 _mesa_error (ctx, GL_INVALID_ENUM, "glGetObjectParameterivARB");
768 success = GL_FALSE;
769 break;
770 }
771
772 (**gen)._unknown.Release ((struct gl2_unknown_intf **) gen);
773 if (sha != NULL)
774 (**sha)._generic._unknown.Release ((struct gl2_unknown_intf **) sha);
775 if (pro != NULL)
776 (**pro)._container._generic._unknown.Release ((struct gl2_unknown_intf **) pro);
777
778 return success;
779 }
780
781 void GLAPIENTRY
782 _mesa_GetObjectParameterfvARB (GLhandleARB obj, GLenum pname, GLfloat *params)
783 {
784 GLboolean integral;
785 GLint size, i;
786
787 assert (sizeof (GLfloat) == sizeof (GLint));
788
789 if (_mesa_get_object_parameter (obj, pname, (GLvoid *) params, &integral, &size) != GL_FALSE)
790 if (integral != GL_FALSE)
791 for (i = 0; i < size; i++)
792 params[i] = (GLfloat) ((GLint *) params)[i];
793 }
794
795 void GLAPIENTRY
796 _mesa_GetObjectParameterivARB (GLhandleARB obj, GLenum pname, GLint *params)
797 {
798 GLboolean integral;
799 GLint size, i;
800
801 assert (sizeof (GLfloat) == sizeof (GLint));
802
803 if (_mesa_get_object_parameter (obj, pname, (GLvoid *) params, &integral, &size) != GL_FALSE)
804 if (integral == GL_FALSE)
805 for (i = 0; i < size; i++)
806 params[i] = (GLint) ((GLfloat *) params)[i];
807 }
808
809 static void
810 _mesa_get_string (const GLcharARB *src, GLsizei maxLength, GLsizei *length, GLcharARB *str)
811 {
812 GLsizei len;
813
814 if (src == NULL)
815 src = "";
816
817 len = _mesa_strlen (src);
818 if (len > maxLength)
819 {
820 len = maxLength;
821 /* allocate space for null termination */
822 if (len > 0)
823 len--;
824 }
825
826 _mesa_memcpy (str, src, len * sizeof (GLcharARB));
827 if (maxLength > 0)
828 str[len] = '\0';
829
830 if (length != NULL)
831 *length = len;
832 }
833
834 void GLAPIENTRY
835 _mesa_GetInfoLogARB (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog)
836 {
837 GET_CURRENT_CONTEXT(ctx);
838 struct gl2_unknown_intf **unk;
839 struct gl2_generic_intf **gen;
840
841 _glthread_LOCK_MUTEX (ctx->Shared->Mutex);
842 unk = (struct gl2_unknown_intf **) _mesa_HashLookup (ctx->Shared->GL2Objects, obj);
843 _glthread_UNLOCK_MUTEX (ctx->Shared->Mutex);
844
845 if (unk == NULL)
846 {
847 _mesa_error (ctx, GL_INVALID_VALUE, "glGetInfoLogARB");
848 return;
849 }
850
851 gen = (struct gl2_generic_intf **) (**unk).QueryInterface (unk, UIID_GENERIC);
852 if (gen == NULL)
853 {
854 _mesa_error (ctx, GL_INVALID_OPERATION, "glGetInfoLogARB");
855 return;
856 }
857
858 _mesa_get_string ((**gen).GetInfoLog (gen), maxLength, length, infoLog);
859
860 (**gen)._unknown.Release ((struct gl2_unknown_intf **) gen);
861 }
862
863 void GLAPIENTRY
864 _mesa_GetAttachedObjectsARB (GLhandleARB containerObj, GLsizei maxCount, GLsizei *count, GLhandleARB *obj)
865 {
866 GET_CURRENT_CONTEXT(ctx);
867 struct gl2_unknown_intf **unk;
868 struct gl2_container_intf **con;
869 GLsizei cnt, i;
870
871 _glthread_LOCK_MUTEX (ctx->Shared->Mutex);
872 unk = (struct gl2_unknown_intf **) _mesa_HashLookup (ctx->Shared->GL2Objects, containerObj);
873 _glthread_UNLOCK_MUTEX (ctx->Shared->Mutex);
874
875 if (unk == NULL)
876 {
877 _mesa_error (ctx, GL_INVALID_VALUE, "glGetAttachedObjectsARB");
878 return;
879 }
880
881 con = (struct gl2_container_intf **) (**unk).QueryInterface (unk, UIID_CONTAINER);
882 if (con == NULL)
883 {
884 _mesa_error (ctx, GL_INVALID_OPERATION, "glGetAttachedObjectsARB");
885 return;
886 }
887
888 cnt = (**con).GetAttachedCount (con);
889 if (cnt > maxCount)
890 cnt = maxCount;
891
892 for (i = 0; i < cnt; i++)
893 {
894 struct gl2_generic_intf **x = (**con).GetAttached (con, i);
895 obj[i] = (**x).GetName (x);
896 (**x)._unknown.Release ((struct gl2_unknown_intf **) x);
897 }
898
899 (**con)._generic._unknown.Release ((struct gl2_unknown_intf **) con);
900
901 if (count != NULL)
902 *count = cnt;
903 }
904
905 GLint GLAPIENTRY
906 _mesa_GetUniformLocationARB (GLhandleARB programObj, const GLcharARB *name)
907 {
908 GET_CURRENT_CONTEXT(ctx);
909 struct gl2_unknown_intf **unk;
910 struct gl2_program_intf **pro;
911 GLint loc = -1;
912
913 _glthread_LOCK_MUTEX (ctx->Shared->Mutex);
914 unk = (struct gl2_unknown_intf **) _mesa_HashLookup (ctx->Shared->GL2Objects, programObj);
915 _glthread_UNLOCK_MUTEX (ctx->Shared->Mutex);
916
917 if (unk == NULL)
918 {
919 _mesa_error (ctx, GL_INVALID_VALUE, "glGetUniformLocationARB");
920 return -1;
921 }
922
923 pro = (struct gl2_program_intf **) (**unk).QueryInterface (unk, UIID_PROGRAM);
924 if (pro == NULL)
925 {
926 _mesa_error (ctx, GL_INVALID_OPERATION, "glGetUniformLocationARB");
927 return -1;
928 }
929
930 if ((**pro).GetLinkStatus (pro) == GL_FALSE)
931 {
932 _mesa_error (ctx, GL_INVALID_OPERATION, "glGetUniformLocationARB");
933 (**pro)._container._generic._unknown.Release ((struct gl2_unknown_intf **) pro);
934 return -1;
935 }
936
937 /* TODO */
938
939 (**pro)._container._generic._unknown.Release ((struct gl2_unknown_intf **) pro);
940 return loc;
941 }
942
943 void GLAPIENTRY
944 _mesa_GetActiveUniformARB (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name)
945 {
946 GET_CURRENT_CONTEXT(ctx);
947 struct gl2_unknown_intf **unk;
948 struct gl2_program_intf **pro;
949
950 _glthread_LOCK_MUTEX (ctx->Shared->Mutex);
951 unk = (struct gl2_unknown_intf **) _mesa_HashLookup (ctx->Shared->GL2Objects, programObj);
952 _glthread_UNLOCK_MUTEX (ctx->Shared->Mutex);
953
954 if (unk == NULL)
955 {
956 _mesa_error (ctx, GL_INVALID_VALUE, "glGetActiveUniformARB");
957 return;
958 }
959
960 pro = (struct gl2_program_intf **) (**unk).QueryInterface (unk, UIID_PROGRAM);
961 if (pro == NULL)
962 {
963 _mesa_error (ctx, GL_INVALID_OPERATION, "glGetActiveUniformARB");
964 return;
965 }
966
967 /* if (index >= val (OBJECT_ACTIVE_ATTRIBUTES_ARB))
968 {
969 _mesa_error (ctx, GL_INVALID_VALUE, "glGetActiveUniformARB");
970 (**pro)._container._generic._unknown.Release ((struct gl2_unknown_intf **) pro);
971 return;
972 }*/
973
974 /* TODO */
975
976 (**pro)._container._generic._unknown.Release ((struct gl2_unknown_intf **) pro);
977 }
978
979 void GLAPIENTRY
980 _mesa_GetUniformfvARB (GLhandleARB programObj, GLint location, GLfloat *params)
981 {
982 GET_CURRENT_CONTEXT(ctx);
983 struct gl2_unknown_intf **unk;
984 struct gl2_program_intf **pro;
985
986 _glthread_LOCK_MUTEX (ctx->Shared->Mutex);
987 unk = (struct gl2_unknown_intf **) _mesa_HashLookup (ctx->Shared->GL2Objects, programObj);
988 _glthread_UNLOCK_MUTEX (ctx->Shared->Mutex);
989
990 if (unk == NULL)
991 {
992 _mesa_error (ctx, GL_INVALID_VALUE, "glGetUniformfvARB");
993 return;
994 }
995
996 pro = (struct gl2_program_intf **) (**unk).QueryInterface (unk, UIID_PROGRAM);
997 if (pro == NULL)
998 {
999 _mesa_error (ctx, GL_INVALID_OPERATION, "glGetUniformfvARB");
1000 return;
1001 }
1002
1003 if ((**pro).GetLinkStatus (pro) == GL_FALSE)
1004 {
1005 _mesa_error (ctx, GL_INVALID_OPERATION, "glGetUniformfvARB");
1006 (**pro)._container._generic._unknown.Release ((struct gl2_unknown_intf **) pro);
1007 return;
1008 }
1009
1010 /* TODO validate location (OPERATION) */
1011
1012 /* TODO */
1013
1014 (**pro)._container._generic._unknown.Release ((struct gl2_unknown_intf **) pro);
1015 }
1016
1017 void GLAPIENTRY
1018 _mesa_GetUniformivARB (GLhandleARB programObj, GLint location, GLint *params)
1019 {
1020 GET_CURRENT_CONTEXT(ctx);
1021 struct gl2_unknown_intf **unk;
1022 struct gl2_program_intf **pro;
1023
1024 _glthread_LOCK_MUTEX (ctx->Shared->Mutex);
1025 unk = (struct gl2_unknown_intf **) _mesa_HashLookup (ctx->Shared->GL2Objects, programObj);
1026 _glthread_UNLOCK_MUTEX (ctx->Shared->Mutex);
1027
1028 if (unk == NULL)
1029 {
1030 _mesa_error (ctx, GL_INVALID_VALUE, "glGetUniformivARB");
1031 return;
1032 }
1033
1034 pro = (struct gl2_program_intf **) (**unk).QueryInterface (unk, UIID_PROGRAM);
1035 if (pro == NULL)
1036 {
1037 _mesa_error (ctx, GL_INVALID_OPERATION, "glGetUniformivARB");
1038 return;
1039 }
1040
1041 if ((**pro).GetLinkStatus (pro) == GL_FALSE)
1042 {
1043 _mesa_error (ctx, GL_INVALID_OPERATION, "glGetUniformivARB");
1044 (**pro)._container._generic._unknown.Release ((struct gl2_unknown_intf **) pro);
1045 return;
1046 }
1047
1048 /* TODO validate location (GL_INVALID_OPERATION) */
1049
1050 /* TODO */
1051
1052 (**pro)._container._generic._unknown.Release ((struct gl2_unknown_intf **) pro);
1053 }
1054
1055 void GLAPIENTRY
1056 _mesa_GetShaderSourceARB (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *source)
1057 {
1058 GET_CURRENT_CONTEXT(ctx);
1059 struct gl2_unknown_intf **unk;
1060 struct gl2_shader_intf **sha;
1061
1062 _glthread_LOCK_MUTEX (ctx->Shared->Mutex);
1063 unk = (struct gl2_unknown_intf **) _mesa_HashLookup (ctx->Shared->GL2Objects, obj);
1064 _glthread_UNLOCK_MUTEX (ctx->Shared->Mutex);
1065
1066 if (unk == NULL)
1067 {
1068 _mesa_error (ctx, GL_INVALID_VALUE, "glGetShaderSourceARB");
1069 return;
1070 }
1071
1072 sha = (struct gl2_shader_intf **) (**unk).QueryInterface (unk, UIID_SHADER);
1073 if (sha == NULL)
1074 {
1075 _mesa_error (ctx, GL_INVALID_OPERATION, "glGetShaderSourceARB");
1076 return;
1077 }
1078
1079 _mesa_get_string ((**sha).GetSource (sha), maxLength, length, source);
1080
1081 (**sha)._generic._unknown.Release ((struct gl2_unknown_intf **) sha);
1082 }
1083
1084 /* GL_ARB_vertex_shader */
1085
1086 void GLAPIENTRY
1087 _mesa_BindAttribLocationARB (GLhandleARB programObj, GLuint index, const GLcharARB *name)
1088 {
1089 GET_CURRENT_CONTEXT(ctx);
1090 struct gl2_unknown_intf **unk;
1091 struct gl2_program_intf **pro;
1092
1093 _glthread_LOCK_MUTEX (ctx->Shared->Mutex);
1094 unk = (struct gl2_unknown_intf **) _mesa_HashLookup (ctx->Shared->GL2Objects, programObj);
1095 _glthread_UNLOCK_MUTEX (ctx->Shared->Mutex);
1096
1097 if (unk == NULL)
1098 {
1099 _mesa_error (ctx, GL_INVALID_VALUE, "glBindAttribLocationARB");
1100 return;
1101 }
1102
1103 pro = (struct gl2_program_intf **) (**unk).QueryInterface (unk, UIID_PROGRAM);
1104 if (pro == NULL)
1105 {
1106 _mesa_error (ctx, GL_INVALID_VALUE, "glBindAttribLocationARB");
1107 return;
1108 }
1109
1110 /* TODO */
1111
1112 (**pro)._container._generic._unknown.Release ((struct gl2_unknown_intf **) pro);
1113 }
1114
1115 void GLAPIENTRY
1116 _mesa_GetActiveAttribARB (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name)
1117 {
1118 GET_CURRENT_CONTEXT(ctx);
1119 struct gl2_unknown_intf **unk;
1120 struct gl2_program_intf **pro;
1121
1122 _glthread_LOCK_MUTEX (ctx->Shared->Mutex);
1123 unk = (struct gl2_unknown_intf **) _mesa_HashLookup (ctx->Shared->GL2Objects, programObj);
1124 _glthread_UNLOCK_MUTEX (ctx->Shared->Mutex);
1125
1126 if (unk == NULL)
1127 {
1128 _mesa_error (ctx, GL_INVALID_VALUE, "glGetActiveAttribARB");
1129 return;
1130 }
1131
1132 pro = (struct gl2_program_intf **) (**unk).QueryInterface (unk, UIID_PROGRAM);
1133 if (pro == NULL)
1134 {
1135 _mesa_error (ctx, GL_INVALID_VALUE, "glGetActiveAttribARB");
1136 return;
1137 }
1138
1139 /* TODO */
1140
1141 (**pro)._container._generic._unknown.Release ((struct gl2_unknown_intf **) pro);
1142 }
1143
1144 GLint GLAPIENTRY
1145 _mesa_GetAttribLocationARB (GLhandleARB programObj, const GLcharARB *name)
1146 {
1147 GET_CURRENT_CONTEXT(ctx);
1148 struct gl2_unknown_intf **unk;
1149 struct gl2_program_intf **pro;
1150 GLint loc = 0;
1151
1152 _glthread_LOCK_MUTEX (ctx->Shared->Mutex);
1153 unk = (struct gl2_unknown_intf **) _mesa_HashLookup (ctx->Shared->GL2Objects, programObj);
1154 _glthread_UNLOCK_MUTEX (ctx->Shared->Mutex);
1155
1156 if (unk == NULL)
1157 {
1158 _mesa_error (ctx, GL_INVALID_VALUE, "glGetAttribLocationARB");
1159 return 0;
1160 }
1161
1162 pro = (struct gl2_program_intf **) (**unk).QueryInterface (unk, UIID_PROGRAM);
1163 if (pro == NULL)
1164 {
1165 _mesa_error (ctx, GL_INVALID_VALUE, "glGetAttribLocationARB");
1166 return 0;
1167 }
1168
1169 /* TODO */
1170
1171 (**pro)._container._generic._unknown.Release ((struct gl2_unknown_intf **) pro);
1172 return loc;
1173 }
1174
1175 void
1176 _mesa_init_shaderobjects (GLcontext *ctx)
1177 {
1178 ctx->ShaderObjects.current_program = NULL;
1179
1180 _mesa_init_shaderobjects_3dlabs (ctx);
1181 }
1182