Disable _mesa_3dlabs_create_{program,shader}_object references.
[mesa.git] / src / mesa / shader / shaderobjects_3dlabs.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 6.3
4 *
5 * Copyright (C) 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_3dlabs.c
27 * shader objects definitions for 3dlabs compiler
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 #include "slang_mesa.h"
39 #include "Public/ShaderLang.h"
40
41 struct gl2_unknown_obj
42 {
43 GLuint reference_count;
44 void (* _destructor) (struct gl2_unknown_intf **);
45 };
46
47 struct gl2_unknown_impl
48 {
49 struct gl2_unknown_intf *_vftbl;
50 struct gl2_unknown_obj _obj;
51 };
52
53 static void
54 _unknown_destructor (struct gl2_unknown_intf **intf)
55 {
56 }
57
58 static void
59 _unknown_AddRef (struct gl2_unknown_intf **intf)
60 {
61 struct gl2_unknown_impl *impl = (struct gl2_unknown_impl *) intf;
62
63 impl->_obj.reference_count++;
64 }
65
66 static void
67 _unknown_Release (struct gl2_unknown_intf **intf)
68 {
69 struct gl2_unknown_impl *impl = (struct gl2_unknown_impl *) intf;
70
71 impl->_obj.reference_count--;
72 if (impl->_obj.reference_count == 0)
73 {
74 impl->_obj._destructor (intf);
75 _mesa_free ((void *) intf);
76 }
77 }
78
79 static struct gl2_unknown_intf **
80 _unknown_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
81 {
82 if (uiid == UIID_UNKNOWN)
83 {
84 (**intf).AddRef (intf);
85 return intf;
86 }
87 return NULL;
88 }
89
90 static struct gl2_unknown_intf _unknown_vftbl = {
91 _unknown_AddRef,
92 _unknown_Release,
93 _unknown_QueryInterface
94 };
95
96 static void
97 _unknown_constructor (struct gl2_unknown_impl *impl)
98 {
99 impl->_vftbl = &_unknown_vftbl;
100 impl->_obj.reference_count = 1;
101 impl->_obj._destructor = _unknown_destructor;
102 }
103
104 struct gl2_unkinner_obj
105 {
106 struct gl2_unknown_intf **unkouter;
107 };
108
109 struct gl2_unkinner_impl
110 {
111 struct gl2_unknown_intf *_vftbl;
112 struct gl2_unkinner_obj _obj;
113 };
114
115 static void
116 _unkinner_destructor (struct gl2_unknown_intf **intf)
117 {
118 }
119
120 static void
121 _unkinner_AddRef (struct gl2_unknown_intf **intf)
122 {
123 struct gl2_unkinner_impl *impl = (struct gl2_unkinner_impl *) intf;
124
125 (**impl->_obj.unkouter).AddRef (impl->_obj.unkouter);
126 }
127
128 static void
129 _unkinner_Release (struct gl2_unknown_intf **intf)
130 {
131 struct gl2_unkinner_impl *impl = (struct gl2_unkinner_impl *) intf;
132
133 (**impl->_obj.unkouter).Release (impl->_obj.unkouter);
134 }
135
136 static struct gl2_unknown_intf **
137 _unkinner_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
138 {
139 struct gl2_unkinner_impl *impl = (struct gl2_unkinner_impl *) intf;
140
141 return (**impl->_obj.unkouter).QueryInterface (impl->_obj.unkouter, uiid);
142 }
143
144 static struct gl2_unknown_intf _unkinner_vftbl = {
145 _unkinner_AddRef,
146 _unkinner_Release,
147 _unkinner_QueryInterface
148 };
149
150 static void
151 _unkinner_constructor (struct gl2_unkinner_impl *impl, struct gl2_unknown_intf **outer)
152 {
153 impl->_vftbl = &_unkinner_vftbl;
154 impl->_obj.unkouter = outer;
155 }
156
157 struct gl2_generic_obj
158 {
159 struct gl2_unknown_obj _unknown;
160 GLhandleARB name;
161 GLboolean delete_status;
162 GLcharARB *info_log;
163 };
164
165 struct gl2_generic_impl
166 {
167 struct gl2_generic_intf *_vftbl;
168 struct gl2_generic_obj _obj;
169 };
170
171 static void
172 _generic_destructor (struct gl2_unknown_intf **intf)
173 {
174 GET_CURRENT_CONTEXT(ctx);
175 struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf;
176
177 _mesa_free ((void *) impl->_obj.info_log);
178
179 _glthread_LOCK_MUTEX (ctx->Shared->Mutex);
180 _mesa_HashRemove (ctx->Shared->GL2Objects, impl->_obj.name);
181 _glthread_UNLOCK_MUTEX (ctx->Shared->Mutex);
182
183 _unknown_destructor (intf);
184 }
185
186 static struct gl2_unknown_intf **
187 _generic_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
188 {
189 if (uiid == UIID_GENERIC)
190 {
191 (**intf).AddRef (intf);
192 return intf;
193 }
194 return _unknown_QueryInterface (intf, uiid);
195 }
196
197 static void
198 _generic_Delete (struct gl2_generic_intf **intf)
199 {
200 struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf;
201
202 if (impl->_obj.delete_status == GL_FALSE)
203 {
204 impl->_obj.delete_status = GL_TRUE;
205 (**intf)._unknown.Release ((struct gl2_unknown_intf **) intf);
206 }
207 }
208
209 static GLhandleARB
210 _generic_GetName (struct gl2_generic_intf **intf)
211 {
212 struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf;
213
214 return impl->_obj.name;
215 }
216
217 static GLboolean
218 _generic_GetDeleteStatus (struct gl2_generic_intf **intf)
219 {
220 struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf;
221
222 return impl->_obj.delete_status;
223 }
224
225 static const GLcharARB *
226 _generic_GetInfoLog (struct gl2_generic_intf **intf)
227 {
228 struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf;
229
230 return impl->_obj.info_log;
231 }
232
233 static struct gl2_generic_intf _generic_vftbl = {
234 {
235 _unknown_AddRef,
236 _unknown_Release,
237 _generic_QueryInterface
238 },
239 _generic_Delete,
240 NULL, /* abstract GetType */
241 _generic_GetName,
242 _generic_GetDeleteStatus,
243 _generic_GetInfoLog
244 };
245
246 static void
247 _generic_constructor (struct gl2_generic_impl *impl)
248 {
249 GET_CURRENT_CONTEXT(ctx);
250
251 _unknown_constructor ((struct gl2_unknown_impl *) impl);
252 impl->_vftbl = &_generic_vftbl;
253 impl->_obj._unknown._destructor = _generic_destructor;
254 impl->_obj.delete_status = GL_FALSE;
255 impl->_obj.info_log = NULL;
256
257 _glthread_LOCK_MUTEX (ctx->Shared->Mutex);
258 impl->_obj.name = _mesa_HashFindFreeKeyBlock (ctx->Shared->GL2Objects, 1);
259 _mesa_HashInsert (ctx->Shared->GL2Objects, impl->_obj.name, (void *) impl);
260 _glthread_UNLOCK_MUTEX (ctx->Shared->Mutex);
261 }
262
263 struct gl2_container_obj
264 {
265 struct gl2_generic_obj _generic;
266 struct gl2_generic_intf ***attached;
267 GLuint attached_count;
268 };
269
270 struct gl2_container_impl
271 {
272 struct gl2_container_intf *_vftbl;
273 struct gl2_container_obj _obj;
274 };
275
276 static void
277 _container_destructor (struct gl2_unknown_intf **intf)
278 {
279 struct gl2_container_impl *impl = (struct gl2_container_impl *) intf;
280 GLuint i;
281
282 for (i = 0; i < impl->_obj.attached_count; i++)
283 {
284 struct gl2_generic_intf **x = impl->_obj.attached[i];
285 (**x)._unknown.Release ((struct gl2_unknown_intf **) x);
286 }
287
288 _generic_destructor (intf);
289 }
290
291 static struct gl2_unknown_intf **
292 _container_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
293 {
294 if (uiid == UIID_CONTAINER)
295 {
296 (**intf).AddRef (intf);
297 return intf;
298 }
299 return _generic_QueryInterface (intf, uiid);
300 }
301
302 static GLboolean
303 _container_Attach (struct gl2_container_intf **intf, struct gl2_generic_intf **att)
304 {
305 GET_CURRENT_CONTEXT(ctx);
306 struct gl2_container_impl *impl = (struct gl2_container_impl *) intf;
307 GLuint i;
308
309 for (i = 0; i < impl->_obj.attached_count; i++)
310 if (impl->_obj.attached[i] == att)
311 {
312 _mesa_error (ctx, GL_INVALID_OPERATION, "_container_Attach");
313 return GL_FALSE;
314 }
315
316 impl->_obj.attached = (struct gl2_generic_intf ***) _mesa_realloc (impl->_obj.attached,
317 impl->_obj.attached_count * sizeof (*impl->_obj.attached), (impl->_obj.attached_count + 1) *
318 sizeof (*impl->_obj.attached));
319 if (impl->_obj.attached == NULL)
320 return GL_FALSE;
321
322 impl->_obj.attached[impl->_obj.attached_count] = att;
323 impl->_obj.attached_count++;
324 (**att)._unknown.AddRef ((struct gl2_unknown_intf **) att);
325 return GL_TRUE;
326 }
327
328 static GLboolean
329 _container_Detach (struct gl2_container_intf **intf, struct gl2_generic_intf **att)
330 {
331 GET_CURRENT_CONTEXT(ctx);
332 struct gl2_container_impl *impl = (struct gl2_container_impl *) intf;
333 GLuint i, j;
334
335 for (i = 0; i < impl->_obj.attached_count; i++)
336 if (impl->_obj.attached[i] == att)
337 {
338 for (j = i; j < impl->_obj.attached_count - 1; j++)
339 impl->_obj.attached[j] = impl->_obj.attached[j + 1];
340 impl->_obj.attached = (struct gl2_generic_intf ***) _mesa_realloc (impl->_obj.attached,
341 impl->_obj.attached_count * sizeof (*impl->_obj.attached),
342 (impl->_obj.attached_count - 1) * sizeof (*impl->_obj.attached));
343 impl->_obj.attached_count--;
344 (**att)._unknown.Release ((struct gl2_unknown_intf **) att);
345 return GL_TRUE;
346 }
347
348 _mesa_error (ctx, GL_INVALID_OPERATION, "_container_Detach");
349 return GL_FALSE;
350 }
351
352 static GLsizei
353 _container_GetAttachedCount (struct gl2_container_intf **intf)
354 {
355 struct gl2_container_impl *impl = (struct gl2_container_impl *) intf;
356
357 return impl->_obj.attached_count;
358 }
359
360 static struct gl2_generic_intf **
361 _container_GetAttached (struct gl2_container_intf **intf, GLuint index)
362 {
363 struct gl2_container_impl *impl = (struct gl2_container_impl *) intf;
364
365 (**impl->_obj.attached[index])._unknown.AddRef (
366 (struct gl2_unknown_intf **)impl->_obj.attached[index]);
367 return impl->_obj.attached[index];
368 }
369
370 static struct gl2_container_intf _container_vftbl = {
371 {
372 {
373 _unknown_AddRef,
374 _unknown_Release,
375 _container_QueryInterface
376 },
377 _generic_Delete,
378 NULL, /* abstract GetType */
379 _generic_GetName,
380 _generic_GetDeleteStatus,
381 _generic_GetInfoLog
382 },
383 _container_Attach,
384 _container_Detach,
385 _container_GetAttachedCount,
386 _container_GetAttached
387 };
388
389 static void
390 _container_constructor (struct gl2_container_impl *impl)
391 {
392 _generic_constructor ((struct gl2_generic_impl *) impl);
393 impl->_vftbl = &_container_vftbl;
394 impl->_obj._generic._unknown._destructor = _container_destructor;
395 impl->_obj.attached = NULL;
396 impl->_obj.attached_count = 0;
397 }
398
399 struct gl2_3dlabs_shhandle_obj
400 {
401 struct gl2_unkinner_obj _unknown;
402 ShHandle handle;
403 };
404
405 struct gl2_3dlabs_shhandle_impl
406 {
407 struct gl2_3dlabs_shhandle_intf *_vftbl;
408 struct gl2_3dlabs_shhandle_obj _obj;
409 };
410
411 static void
412 _3dlabs_shhandle_destructor (struct gl2_unknown_intf **intf)
413 {
414 struct gl2_3dlabs_shhandle_impl *impl = (struct gl2_3dlabs_shhandle_impl *) intf;
415
416 ShDestruct (impl->_obj.handle);
417 _unkinner_destructor (intf);
418 }
419
420 static GLvoid *
421 _3dlabs_shhandle_GetShHandle (struct gl2_3dlabs_shhandle_intf **intf)
422 {
423 struct gl2_3dlabs_shhandle_impl *impl = (struct gl2_3dlabs_shhandle_impl *) intf;
424
425 return impl->_obj.handle;
426 }
427
428 static struct gl2_3dlabs_shhandle_intf _3dlabs_shhandle_vftbl = {
429 {
430 _unkinner_AddRef,
431 _unkinner_Release,
432 _unkinner_QueryInterface
433 },
434 _3dlabs_shhandle_GetShHandle
435 };
436
437 static void
438 _3dlabs_shhandle_constructor (struct gl2_3dlabs_shhandle_impl *impl, struct gl2_unknown_intf **outer)
439 {
440 _unkinner_constructor ((struct gl2_unkinner_impl *) impl, outer);
441 impl->_vftbl = &_3dlabs_shhandle_vftbl;
442 impl->_obj.handle = NULL;
443 }
444
445 struct gl2_shader_obj
446 {
447 struct gl2_generic_obj _generic;
448 struct gl2_3dlabs_shhandle_impl _3dlabs_shhandle;
449 GLboolean compile_status;
450 GLcharARB *source;
451 GLint *offsets;
452 GLsizei offset_count;
453 };
454
455 struct gl2_shader_impl
456 {
457 struct gl2_shader_intf *_vftbl;
458 struct gl2_shader_obj _obj;
459 };
460
461 static void
462 _shader_destructor (struct gl2_unknown_intf **intf)
463 {
464 struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
465
466 _mesa_free ((void *) impl->_obj.source);
467 _mesa_free ((void *) impl->_obj.offsets);
468 _3dlabs_shhandle_destructor ((struct gl2_unknown_intf **) &impl->_obj._3dlabs_shhandle._vftbl);
469 _generic_destructor (intf);
470 }
471
472 static struct gl2_unknown_intf **
473 _shader_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
474 {
475 struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
476
477 if (uiid == UIID_SHADER)
478 {
479 (**intf).AddRef (intf);
480 return intf;
481 }
482 if (uiid == UIID_3DLABS_SHHANDLE)
483 {
484 (**intf).AddRef (intf);
485 return (struct gl2_unknown_intf **) &impl->_obj._3dlabs_shhandle._vftbl;
486 }
487 return _generic_QueryInterface (intf, uiid);
488 }
489
490 static GLenum
491 _shader_GetType (struct gl2_generic_intf **intf)
492 {
493 return GL_SHADER_OBJECT_ARB;
494 }
495
496 static GLboolean
497 _shader_GetCompileStatus (struct gl2_shader_intf **intf)
498 {
499 struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
500
501 return impl->_obj.compile_status;
502 }
503
504 static GLvoid
505 _shader_SetSource (struct gl2_shader_intf **intf, GLcharARB *src, GLint *off, GLsizei cnt)
506 {
507 struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
508
509 _mesa_free ((void *) impl->_obj.source);
510 impl->_obj.source = src;
511 _mesa_free ((void *) impl->_obj.offsets);
512 impl->_obj.offsets = off;
513 impl->_obj.offset_count = cnt;
514 }
515
516 static const GLcharARB *
517 _shader_GetSource (struct gl2_shader_intf **intf)
518 {
519 struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
520
521 return impl->_obj.source;
522 }
523
524 static GLvoid
525 _shader_Compile (struct gl2_shader_intf **intf)
526 {
527 struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
528 char **strings;
529 TBuiltInResource res;
530
531 impl->_obj.compile_status = GL_FALSE;
532 _mesa_free ((void *) impl->_obj._generic.info_log);
533 impl->_obj._generic.info_log = NULL;
534
535 /* 3dlabs compiler expects us to feed it with null-terminated string array,
536 we've got only one big string with offsets, so we must split it; but when
537 there's only one string to deal with, we pass its address directly */
538
539 if (impl->_obj.offset_count <= 1)
540 strings = &impl->_obj.source;
541 else
542 {
543 GLsizei i, offset = 0;
544
545 strings = (char **) _mesa_malloc (impl->_obj.offset_count * sizeof (char *));
546 if (strings == NULL)
547 return;
548
549 for (i = 0; i < impl->_obj.offset_count; i++)
550 {
551 GLsizei size = impl->_obj.offsets[i] - offset;
552
553 strings[i] = (char *) _mesa_malloc ((size + 1) * sizeof (char));
554 if (strings[i] == NULL)
555 {
556 GLsizei j;
557
558 for (j = 0; j < i; j++)
559 _mesa_free (strings[j]);
560 _mesa_free (strings);
561 return;
562 }
563
564 _mesa_memcpy (strings[i], impl->_obj.source + offset, size * sizeof (char));
565 strings[i][size] = '\0';
566 offset = impl->_obj.offsets[i];
567 }
568 }
569
570 /* TODO set these fields to some REAL numbers */
571 res.maxLights = 8;
572 res.maxClipPlanes = 6;
573 res.maxTextureUnits = 2;
574 res.maxTextureCoords = 2;
575 res.maxVertexAttribs = 8;
576 res.maxVertexUniformComponents = 64;
577 res.maxVaryingFloats = 8;
578 res.maxVertexTextureImageUnits = 2;
579 res.maxCombinedTextureImageUnits = 2;
580 res.maxTextureImageUnits = 2;
581 res.maxFragmentUniformComponents = 64;
582 res.maxDrawBuffers = 1;
583
584 if (ShCompile (impl->_obj._3dlabs_shhandle._obj.handle, strings, impl->_obj.offset_count,
585 EShOptFull, &res, 0))
586 impl->_obj.compile_status = GL_TRUE;
587
588 if (impl->_obj.offset_count > 1)
589 {
590 GLsizei i;
591
592 for (i = 0; i < impl->_obj.offset_count; i++)
593 _mesa_free (strings[i]);
594 _mesa_free (strings);
595 }
596
597 impl->_obj._generic.info_log = _mesa_strdup (ShGetInfoLog (
598 impl->_obj._3dlabs_shhandle._obj.handle));
599 }
600
601 static struct gl2_shader_intf _shader_vftbl = {
602 {
603 {
604 _unknown_AddRef,
605 _unknown_Release,
606 _shader_QueryInterface
607 },
608 _generic_Delete,
609 _shader_GetType,
610 _generic_GetName,
611 _generic_GetDeleteStatus,
612 _generic_GetInfoLog
613 },
614 NULL, /* abstract GetSubType */
615 _shader_GetCompileStatus,
616 _shader_SetSource,
617 _shader_GetSource,
618 _shader_Compile
619 };
620
621 static void
622 _shader_constructor (struct gl2_shader_impl *impl)
623 {
624 _generic_constructor ((struct gl2_generic_impl *) impl);
625 _3dlabs_shhandle_constructor (&impl->_obj._3dlabs_shhandle, (struct gl2_unknown_intf **)
626 &impl->_vftbl);
627 impl->_vftbl = &_shader_vftbl;
628 impl->_obj._generic._unknown._destructor = _shader_destructor;
629 impl->_obj.compile_status = GL_FALSE;
630 impl->_obj.source = NULL;
631 impl->_obj.offsets = NULL;
632 impl->_obj.offset_count = 0;
633 }
634
635 struct gl2_program_obj
636 {
637 struct gl2_container_obj _container;
638 GLboolean link_status;
639 GLboolean validate_status;
640 ShHandle linker;
641 ShHandle uniforms;
642 };
643
644 struct gl2_program_impl
645 {
646 struct gl2_program_intf *_vftbl;
647 struct gl2_program_obj _obj;
648 };
649
650 static void
651 _program_destructor (struct gl2_unknown_intf **intf)
652 {
653 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
654
655 ShDestruct (impl->_obj.linker);
656 ShDestruct (impl->_obj.uniforms);
657 _container_destructor (intf);
658 }
659
660 static struct gl2_unknown_intf **
661 _program_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
662 {
663 if (uiid == UIID_PROGRAM)
664 {
665 (**intf).AddRef (intf);
666 return intf;
667 }
668 return _container_QueryInterface (intf, uiid);
669 }
670
671 static GLenum
672 _program_GetType (struct gl2_generic_intf **intf)
673 {
674 return GL_PROGRAM_OBJECT_ARB;
675 }
676
677 static GLboolean
678 _program_Attach (struct gl2_container_intf **intf, struct gl2_generic_intf **att)
679 {
680 GET_CURRENT_CONTEXT(ctx);
681 struct gl2_unknown_intf **sha;
682
683 sha = (**att)._unknown.QueryInterface ((struct gl2_unknown_intf **) att, UIID_SHADER);
684 if (sha == NULL)
685 {
686 _mesa_error (ctx, GL_INVALID_OPERATION, "_program_Attach");
687 return GL_FALSE;
688 }
689
690 (**sha).Release (sha);
691 return _container_Attach (intf, att);
692 }
693
694 static GLboolean
695 _program_GetLinkStatus (struct gl2_program_intf **intf)
696 {
697 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
698
699 return impl->_obj.link_status;
700 }
701
702 static GLboolean
703 _program_GetValidateStatus (struct gl2_program_intf **intf)
704 {
705 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
706
707 return impl->_obj.validate_status;
708 }
709
710 static GLvoid
711 _program_Link (struct gl2_program_intf **intf)
712 {
713 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
714 ShHandle *handles;
715 GLuint i;
716
717 impl->_obj.link_status = GL_FALSE;
718 _mesa_free ((void *) impl->_obj._container._generic.info_log);
719 impl->_obj._container._generic.info_log = NULL;
720
721 handles = (ShHandle *) _mesa_malloc (impl->_obj._container.attached_count * sizeof (ShHandle));
722 if (handles == NULL)
723 return;
724
725 for (i = 0; i < impl->_obj._container.attached_count; i++)
726 {
727 struct gl2_generic_intf **gen = impl->_obj._container.attached[i];
728 struct gl2_3dlabs_shhandle_intf **sh;
729
730 sh = (struct gl2_3dlabs_shhandle_intf **) (**gen)._unknown.QueryInterface (
731 (struct gl2_unknown_intf **) gen, UIID_3DLABS_SHHANDLE);
732 if (sh != NULL)
733 {
734 handles[i] = (**sh).GetShHandle (sh);
735 (**sh)._unknown.Release ((struct gl2_unknown_intf **) sh);
736 }
737 else
738 {
739 _mesa_free (handles);
740 return;
741 }
742 }
743
744 if (ShLink (impl->_obj.linker, handles, impl->_obj._container.attached_count,
745 impl->_obj.uniforms, NULL, NULL))
746 impl->_obj.link_status = GL_TRUE;
747
748 impl->_obj._container._generic.info_log = _mesa_strdup (ShGetInfoLog (impl->_obj.linker));
749 }
750
751 static GLvoid
752 _program_Validate (struct gl2_program_intf **intf)
753 {
754 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
755
756 impl->_obj.validate_status = GL_FALSE;
757 _mesa_free ((void *) impl->_obj._container._generic.info_log);
758 impl->_obj._container._generic.info_log = NULL;
759
760 /* TODO validate */
761 }
762
763 static struct gl2_program_intf _program_vftbl = {
764 {
765 {
766 {
767 _unknown_AddRef,
768 _unknown_Release,
769 _program_QueryInterface
770 },
771 _generic_Delete,
772 _program_GetType,
773 _generic_GetName,
774 _generic_GetDeleteStatus,
775 _generic_GetInfoLog
776 },
777 _program_Attach,
778 _container_Detach,
779 _container_GetAttachedCount,
780 _container_GetAttached
781 },
782 _program_GetLinkStatus,
783 _program_GetValidateStatus,
784 _program_Link,
785 _program_Validate
786 };
787
788 static void
789 _program_constructor (struct gl2_program_impl *impl)
790 {
791 _container_constructor ((struct gl2_container_impl *) impl);
792 impl->_vftbl = &_program_vftbl;
793 impl->_obj._container._generic._unknown._destructor = _program_destructor;
794 impl->_obj.link_status = GL_FALSE;
795 impl->_obj.validate_status = GL_FALSE;
796 impl->_obj.linker = ShConstructLinker (EShExVertexFragment, 0);
797 impl->_obj.uniforms = ShConstructUniformMap ();
798 }
799
800 struct gl2_fragment_shader_obj
801 {
802 struct gl2_shader_obj _shader;
803 };
804
805 struct gl2_fragment_shader_impl
806 {
807 struct gl2_fragment_shader_intf *_vftbl;
808 struct gl2_fragment_shader_obj _obj;
809 };
810
811 static void
812 _fragment_shader_destructor (struct gl2_unknown_intf **intf)
813 {
814 struct gl2_fragment_shader_impl *impl = (struct gl2_fragment_shader_impl *) intf;
815
816 (void) impl;
817 /* TODO free fragment shader data */
818
819 _shader_destructor (intf);
820 }
821
822 static struct gl2_unknown_intf **
823 _fragment_shader_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
824 {
825 if (uiid == UIID_FRAGMENT_SHADER)
826 {
827 (**intf).AddRef (intf);
828 return intf;
829 }
830 return _shader_QueryInterface (intf, uiid);
831 }
832
833 static GLenum
834 _fragment_shader_GetSubType (struct gl2_shader_intf **intf)
835 {
836 return GL_FRAGMENT_SHADER_ARB;
837 }
838
839 static struct gl2_fragment_shader_intf _fragment_shader_vftbl = {
840 {
841 {
842 {
843 _unknown_AddRef,
844 _unknown_Release,
845 _fragment_shader_QueryInterface
846 },
847 _generic_Delete,
848 _shader_GetType,
849 _generic_GetName,
850 _generic_GetDeleteStatus,
851 _generic_GetInfoLog
852 },
853 _fragment_shader_GetSubType,
854 _shader_GetCompileStatus,
855 _shader_SetSource,
856 _shader_GetSource,
857 _shader_Compile
858 }
859 };
860
861 static void
862 _fragment_shader_constructor (struct gl2_fragment_shader_impl *impl)
863 {
864 _shader_constructor ((struct gl2_shader_impl *) impl);
865 impl->_vftbl = &_fragment_shader_vftbl;
866 impl->_obj._shader._generic._unknown._destructor = _fragment_shader_destructor;
867 impl->_obj._shader._3dlabs_shhandle._obj.handle = ShConstructCompiler (EShLangFragment, 0);
868 }
869
870 struct gl2_vertex_shader_obj
871 {
872 struct gl2_shader_obj _shader;
873 };
874
875 struct gl2_vertex_shader_impl
876 {
877 struct gl2_vertex_shader_intf *_vftbl;
878 struct gl2_vertex_shader_obj _obj;
879 };
880
881 static void
882 _vertex_shader_destructor (struct gl2_unknown_intf **intf)
883 {
884 struct gl2_vertex_shader_impl *impl = (struct gl2_vertex_shader_impl *) intf;
885
886 (void) impl;
887 /* TODO free vertex shader data */
888
889 _shader_destructor (intf);
890 }
891
892 static struct gl2_unknown_intf **
893 _vertex_shader_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
894 {
895 if (uiid == UIID_VERTEX_SHADER)
896 {
897 (**intf).AddRef (intf);
898 return intf;
899 }
900 return _shader_QueryInterface (intf, uiid);
901 }
902
903 static GLenum
904 _vertex_shader_GetSubType (struct gl2_shader_intf **intf)
905 {
906 return GL_VERTEX_SHADER_ARB;
907 }
908
909 static struct gl2_vertex_shader_intf _vertex_shader_vftbl = {
910 {
911 {
912 {
913 _unknown_AddRef,
914 _unknown_Release,
915 _vertex_shader_QueryInterface
916 },
917 _generic_Delete,
918 _shader_GetType,
919 _generic_GetName,
920 _generic_GetDeleteStatus,
921 _generic_GetInfoLog
922 },
923 _vertex_shader_GetSubType,
924 _shader_GetCompileStatus,
925 _shader_SetSource,
926 _shader_GetSource,
927 _shader_Compile
928 }
929 };
930
931 static void
932 _vertex_shader_constructor (struct gl2_vertex_shader_impl *impl)
933 {
934 _shader_constructor ((struct gl2_shader_impl *) impl);
935 impl->_vftbl = &_vertex_shader_vftbl;
936 impl->_obj._shader._generic._unknown._destructor = _vertex_shader_destructor;
937 impl->_obj._shader._3dlabs_shhandle._obj.handle = ShConstructCompiler (EShLangVertex, 0);
938 }
939
940 GLhandleARB
941 _mesa_3dlabs_create_shader_object (GLenum shaderType)
942 {
943 switch (shaderType)
944 {
945 case GL_FRAGMENT_SHADER_ARB:
946 {
947 struct gl2_fragment_shader_impl *x = (struct gl2_fragment_shader_impl *)
948 _mesa_malloc (sizeof (struct gl2_fragment_shader_impl));
949
950 if (x != NULL)
951 {
952 _fragment_shader_constructor (x);
953 return x->_obj._shader._generic.name;
954 }
955 }
956 break;
957 case GL_VERTEX_SHADER_ARB:
958 {
959 struct gl2_vertex_shader_impl *x = (struct gl2_vertex_shader_impl *)
960 _mesa_malloc (sizeof (struct gl2_vertex_shader_impl));
961
962 if (x != NULL)
963 {
964 _vertex_shader_constructor (x);
965 return x->_obj._shader._generic.name;
966 }
967 }
968 break;
969 }
970
971 return 0;
972 }
973
974 GLhandleARB
975 _mesa_3dlabs_create_program_object (void)
976 {
977 struct gl2_program_impl *x = (struct gl2_program_impl *)
978 _mesa_malloc (sizeof (struct gl2_program_impl));
979
980 if (x != NULL)
981 {
982 _program_constructor (x);
983 return x->_obj._container._generic.name;
984 }
985
986 return 0;
987 }
988
989 void
990 _mesa_init_shaderobjects_3dlabs (GLcontext *ctx)
991 {
992 _glslang_3dlabs_InitProcess ();
993 _glslang_3dlabs_ShInitialize ();
994 }
995