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