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