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