More GLSL code:
[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 "imports.h"
35 #include "hash.h"
36 #include "macros.h"
37 #include "shaderobjects.h"
38 #include "shaderobjects_3dlabs.h"
39
40 #if USE_3DLABS_FRONTEND
41 #include "slang_mesa.h"
42 #include "Public/ShaderLang.h"
43 #else
44 #include "slang_link.h"
45 #endif
46
47 struct gl2_unknown_obj
48 {
49 GLuint reference_count;
50 void (* _destructor) (struct gl2_unknown_intf **);
51 };
52
53 struct gl2_unknown_impl
54 {
55 struct gl2_unknown_intf *_vftbl;
56 struct gl2_unknown_obj _obj;
57 };
58
59 static void
60 _unknown_destructor (struct gl2_unknown_intf **intf)
61 {
62 }
63
64 static void
65 _unknown_AddRef (struct gl2_unknown_intf **intf)
66 {
67 struct gl2_unknown_impl *impl = (struct gl2_unknown_impl *) intf;
68
69 impl->_obj.reference_count++;
70 }
71
72 static void
73 _unknown_Release (struct gl2_unknown_intf **intf)
74 {
75 struct gl2_unknown_impl *impl = (struct gl2_unknown_impl *) intf;
76
77 impl->_obj.reference_count--;
78 if (impl->_obj.reference_count == 0)
79 {
80 impl->_obj._destructor (intf);
81 _mesa_free ((void *) intf);
82 }
83 }
84
85 static struct gl2_unknown_intf **
86 _unknown_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
87 {
88 if (uiid == UIID_UNKNOWN)
89 {
90 (**intf).AddRef (intf);
91 return intf;
92 }
93 return NULL;
94 }
95
96 static struct gl2_unknown_intf _unknown_vftbl = {
97 _unknown_AddRef,
98 _unknown_Release,
99 _unknown_QueryInterface
100 };
101
102 static void
103 _unknown_constructor (struct gl2_unknown_impl *impl)
104 {
105 impl->_vftbl = &_unknown_vftbl;
106 impl->_obj.reference_count = 1;
107 impl->_obj._destructor = _unknown_destructor;
108 }
109
110 struct gl2_unkinner_obj
111 {
112 struct gl2_unknown_intf **unkouter;
113 };
114
115 struct gl2_unkinner_impl
116 {
117 struct gl2_unknown_intf *_vftbl;
118 struct gl2_unkinner_obj _obj;
119 };
120
121 static void
122 _unkinner_destructor (struct gl2_unknown_intf **intf)
123 {
124 }
125
126 static void
127 _unkinner_AddRef (struct gl2_unknown_intf **intf)
128 {
129 struct gl2_unkinner_impl *impl = (struct gl2_unkinner_impl *) intf;
130
131 (**impl->_obj.unkouter).AddRef (impl->_obj.unkouter);
132 }
133
134 static void
135 _unkinner_Release (struct gl2_unknown_intf **intf)
136 {
137 struct gl2_unkinner_impl *impl = (struct gl2_unkinner_impl *) intf;
138
139 (**impl->_obj.unkouter).Release (impl->_obj.unkouter);
140 }
141
142 static struct gl2_unknown_intf **
143 _unkinner_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
144 {
145 struct gl2_unkinner_impl *impl = (struct gl2_unkinner_impl *) intf;
146
147 return (**impl->_obj.unkouter).QueryInterface (impl->_obj.unkouter, uiid);
148 }
149
150 static struct gl2_unknown_intf _unkinner_vftbl = {
151 _unkinner_AddRef,
152 _unkinner_Release,
153 _unkinner_QueryInterface
154 };
155
156 static void
157 _unkinner_constructor (struct gl2_unkinner_impl *impl, struct gl2_unknown_intf **outer)
158 {
159 impl->_vftbl = &_unkinner_vftbl;
160 impl->_obj.unkouter = outer;
161 }
162
163 struct gl2_generic_obj
164 {
165 struct gl2_unknown_obj _unknown;
166 GLhandleARB name;
167 GLboolean delete_status;
168 GLcharARB *info_log;
169 };
170
171 struct gl2_generic_impl
172 {
173 struct gl2_generic_intf *_vftbl;
174 struct gl2_generic_obj _obj;
175 };
176
177 static void
178 _generic_destructor (struct gl2_unknown_intf **intf)
179 {
180 GET_CURRENT_CONTEXT(ctx);
181 struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf;
182
183 _mesa_free ((void *) impl->_obj.info_log);
184
185 _glthread_LOCK_MUTEX (ctx->Shared->Mutex);
186 _mesa_HashRemove (ctx->Shared->GL2Objects, impl->_obj.name);
187 _glthread_UNLOCK_MUTEX (ctx->Shared->Mutex);
188
189 _unknown_destructor (intf);
190 }
191
192 static struct gl2_unknown_intf **
193 _generic_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
194 {
195 if (uiid == UIID_GENERIC)
196 {
197 (**intf).AddRef (intf);
198 return intf;
199 }
200 return _unknown_QueryInterface (intf, uiid);
201 }
202
203 static void
204 _generic_Delete (struct gl2_generic_intf **intf)
205 {
206 struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf;
207
208 if (impl->_obj.delete_status == GL_FALSE)
209 {
210 impl->_obj.delete_status = GL_TRUE;
211 (**intf)._unknown.Release ((struct gl2_unknown_intf **) intf);
212 }
213 }
214
215 static GLhandleARB
216 _generic_GetName (struct gl2_generic_intf **intf)
217 {
218 struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf;
219
220 return impl->_obj.name;
221 }
222
223 static GLboolean
224 _generic_GetDeleteStatus (struct gl2_generic_intf **intf)
225 {
226 struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf;
227
228 return impl->_obj.delete_status;
229 }
230
231 static const GLcharARB *
232 _generic_GetInfoLog (struct gl2_generic_intf **intf)
233 {
234 struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf;
235
236 return impl->_obj.info_log;
237 }
238
239 static struct gl2_generic_intf _generic_vftbl = {
240 {
241 _unknown_AddRef,
242 _unknown_Release,
243 _generic_QueryInterface
244 },
245 _generic_Delete,
246 NULL, /* abstract GetType */
247 _generic_GetName,
248 _generic_GetDeleteStatus,
249 _generic_GetInfoLog
250 };
251
252 static void
253 _generic_constructor (struct gl2_generic_impl *impl)
254 {
255 GET_CURRENT_CONTEXT(ctx);
256
257 _unknown_constructor ((struct gl2_unknown_impl *) impl);
258 impl->_vftbl = &_generic_vftbl;
259 impl->_obj._unknown._destructor = _generic_destructor;
260 impl->_obj.delete_status = GL_FALSE;
261 impl->_obj.info_log = NULL;
262
263 _glthread_LOCK_MUTEX (ctx->Shared->Mutex);
264 impl->_obj.name = _mesa_HashFindFreeKeyBlock (ctx->Shared->GL2Objects, 1);
265 _mesa_HashInsert (ctx->Shared->GL2Objects, impl->_obj.name, (void *) impl);
266 _glthread_UNLOCK_MUTEX (ctx->Shared->Mutex);
267 }
268
269 struct gl2_container_obj
270 {
271 struct gl2_generic_obj _generic;
272 struct gl2_generic_intf ***attached;
273 GLuint attached_count;
274 };
275
276 struct gl2_container_impl
277 {
278 struct gl2_container_intf *_vftbl;
279 struct gl2_container_obj _obj;
280 };
281
282 static void
283 _container_destructor (struct gl2_unknown_intf **intf)
284 {
285 struct gl2_container_impl *impl = (struct gl2_container_impl *) intf;
286 GLuint i;
287
288 for (i = 0; i < impl->_obj.attached_count; i++)
289 {
290 struct gl2_generic_intf **x = impl->_obj.attached[i];
291 (**x)._unknown.Release ((struct gl2_unknown_intf **) x);
292 }
293
294 _generic_destructor (intf);
295 }
296
297 static struct gl2_unknown_intf **
298 _container_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
299 {
300 if (uiid == UIID_CONTAINER)
301 {
302 (**intf).AddRef (intf);
303 return intf;
304 }
305 return _generic_QueryInterface (intf, uiid);
306 }
307
308 static GLboolean
309 _container_Attach (struct gl2_container_intf **intf, struct gl2_generic_intf **att)
310 {
311 GET_CURRENT_CONTEXT(ctx);
312 struct gl2_container_impl *impl = (struct gl2_container_impl *) intf;
313 GLuint i;
314
315 for (i = 0; i < impl->_obj.attached_count; i++)
316 if (impl->_obj.attached[i] == att)
317 {
318 _mesa_error (ctx, GL_INVALID_OPERATION, "_container_Attach");
319 return GL_FALSE;
320 }
321
322 impl->_obj.attached = (struct gl2_generic_intf ***) _mesa_realloc (impl->_obj.attached,
323 impl->_obj.attached_count * sizeof (*impl->_obj.attached), (impl->_obj.attached_count + 1) *
324 sizeof (*impl->_obj.attached));
325 if (impl->_obj.attached == NULL)
326 return GL_FALSE;
327
328 impl->_obj.attached[impl->_obj.attached_count] = att;
329 impl->_obj.attached_count++;
330 (**att)._unknown.AddRef ((struct gl2_unknown_intf **) att);
331 return GL_TRUE;
332 }
333
334 static GLboolean
335 _container_Detach (struct gl2_container_intf **intf, struct gl2_generic_intf **att)
336 {
337 GET_CURRENT_CONTEXT(ctx);
338 struct gl2_container_impl *impl = (struct gl2_container_impl *) intf;
339 GLuint i, j;
340
341 for (i = 0; i < impl->_obj.attached_count; i++)
342 if (impl->_obj.attached[i] == att)
343 {
344 for (j = i; j < impl->_obj.attached_count - 1; j++)
345 impl->_obj.attached[j] = impl->_obj.attached[j + 1];
346 impl->_obj.attached = (struct gl2_generic_intf ***) _mesa_realloc (impl->_obj.attached,
347 impl->_obj.attached_count * sizeof (*impl->_obj.attached),
348 (impl->_obj.attached_count - 1) * sizeof (*impl->_obj.attached));
349 impl->_obj.attached_count--;
350 (**att)._unknown.Release ((struct gl2_unknown_intf **) att);
351 return GL_TRUE;
352 }
353
354 _mesa_error (ctx, GL_INVALID_OPERATION, "_container_Detach");
355 return GL_FALSE;
356 }
357
358 static GLsizei
359 _container_GetAttachedCount (struct gl2_container_intf **intf)
360 {
361 struct gl2_container_impl *impl = (struct gl2_container_impl *) intf;
362
363 return impl->_obj.attached_count;
364 }
365
366 static struct gl2_generic_intf **
367 _container_GetAttached (struct gl2_container_intf **intf, GLuint index)
368 {
369 struct gl2_container_impl *impl = (struct gl2_container_impl *) intf;
370
371 (**impl->_obj.attached[index])._unknown.AddRef (
372 (struct gl2_unknown_intf **)impl->_obj.attached[index]);
373 return impl->_obj.attached[index];
374 }
375
376 static struct gl2_container_intf _container_vftbl = {
377 {
378 {
379 _unknown_AddRef,
380 _unknown_Release,
381 _container_QueryInterface
382 },
383 _generic_Delete,
384 NULL, /* abstract GetType */
385 _generic_GetName,
386 _generic_GetDeleteStatus,
387 _generic_GetInfoLog
388 },
389 _container_Attach,
390 _container_Detach,
391 _container_GetAttachedCount,
392 _container_GetAttached
393 };
394
395 static void
396 _container_constructor (struct gl2_container_impl *impl)
397 {
398 _generic_constructor ((struct gl2_generic_impl *) impl);
399 impl->_vftbl = &_container_vftbl;
400 impl->_obj._generic._unknown._destructor = _container_destructor;
401 impl->_obj.attached = NULL;
402 impl->_obj.attached_count = 0;
403 }
404
405 struct gl2_3dlabs_shhandle_obj
406 {
407 struct gl2_unkinner_obj _unknown;
408 #if USE_3DLABS_FRONTEND
409 ShHandle handle;
410 #endif
411 };
412
413 struct gl2_3dlabs_shhandle_impl
414 {
415 struct gl2_3dlabs_shhandle_intf *_vftbl;
416 struct gl2_3dlabs_shhandle_obj _obj;
417 };
418
419 static void
420 _3dlabs_shhandle_destructor (struct gl2_unknown_intf **intf)
421 {
422 #if USE_3DLABS_FRONTEND
423 struct gl2_3dlabs_shhandle_impl *impl = (struct gl2_3dlabs_shhandle_impl *) intf;
424 ShDestruct (impl->_obj.handle);
425 #endif
426 _unkinner_destructor (intf);
427 }
428
429 static GLvoid *
430 _3dlabs_shhandle_GetShHandle (struct gl2_3dlabs_shhandle_intf **intf)
431 {
432 #if USE_3DLABS_FRONTEND
433 struct gl2_3dlabs_shhandle_impl *impl = (struct gl2_3dlabs_shhandle_impl *) intf;
434 return impl->_obj.handle;
435 #else
436 return NULL;
437 #endif
438 }
439
440 static struct gl2_3dlabs_shhandle_intf _3dlabs_shhandle_vftbl = {
441 {
442 _unkinner_AddRef,
443 _unkinner_Release,
444 _unkinner_QueryInterface
445 },
446 _3dlabs_shhandle_GetShHandle
447 };
448
449 static void
450 _3dlabs_shhandle_constructor (struct gl2_3dlabs_shhandle_impl *impl, struct gl2_unknown_intf **outer)
451 {
452 _unkinner_constructor ((struct gl2_unkinner_impl *) impl, outer);
453 impl->_vftbl = &_3dlabs_shhandle_vftbl;
454 #if USE_3DLABS_FRONTEND
455 impl->_obj.handle = NULL;
456 #endif
457 }
458
459 struct gl2_shader_obj
460 {
461 struct gl2_generic_obj _generic;
462 struct gl2_3dlabs_shhandle_impl _3dlabs_shhandle;
463 GLboolean compile_status;
464 GLcharARB *source;
465 GLint *offsets;
466 GLsizei offset_count;
467 slang_translation_unit unit;
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_unit_type type;
552 slang_info_log info_log;
553 #endif
554
555 impl->_obj.compile_status = GL_FALSE;
556 _mesa_free ((void *) impl->_obj._generic.info_log);
557 impl->_obj._generic.info_log = NULL;
558
559 #if USE_3DLABS_FRONTEND
560 /* 3dlabs compiler expects us to feed it with null-terminated string array,
561 we've got only one big string with offsets, so we must split it; but when
562 there's only one string to deal with, we pass its address directly */
563
564 if (impl->_obj.offset_count <= 1)
565 strings = &impl->_obj.source;
566 else
567 {
568 GLsizei i, offset = 0;
569
570 strings = (char **) _mesa_malloc (impl->_obj.offset_count * sizeof (char *));
571 if (strings == NULL)
572 return;
573
574 for (i = 0; i < impl->_obj.offset_count; i++)
575 {
576 GLsizei size = impl->_obj.offsets[i] - offset;
577
578 strings[i] = (char *) _mesa_malloc ((size + 1) * sizeof (char));
579 if (strings[i] == NULL)
580 {
581 GLsizei j;
582
583 for (j = 0; j < i; j++)
584 _mesa_free (strings[j]);
585 _mesa_free (strings);
586 return;
587 }
588
589 _mesa_memcpy (strings[i], impl->_obj.source + offset, size * sizeof (char));
590 strings[i][size] = '\0';
591 offset = impl->_obj.offsets[i];
592 }
593 }
594
595 /* TODO set these fields to some REAL numbers */
596 res.maxLights = 8;
597 res.maxClipPlanes = 6;
598 res.maxTextureUnits = 2;
599 res.maxTextureCoords = 2;
600 res.maxVertexAttribs = 8;
601 res.maxVertexUniformComponents = 64;
602 res.maxVaryingFloats = 8;
603 res.maxVertexTextureImageUnits = 2;
604 res.maxCombinedTextureImageUnits = 2;
605 res.maxTextureImageUnits = 2;
606 res.maxFragmentUniformComponents = 64;
607 res.maxDrawBuffers = 1;
608
609 if (ShCompile (impl->_obj._3dlabs_shhandle._obj.handle, strings, impl->_obj.offset_count,
610 EShOptFull, &res, 0))
611 impl->_obj.compile_status = GL_TRUE;
612 if (impl->_obj.offset_count > 1)
613 {
614 GLsizei i;
615
616 for (i = 0; i < impl->_obj.offset_count; i++)
617 _mesa_free (strings[i]);
618 _mesa_free (strings);
619 }
620
621 impl->_obj._generic.info_log = _mesa_strdup (ShGetInfoLog (
622 impl->_obj._3dlabs_shhandle._obj.handle));
623 #else
624 if (impl->_vftbl->GetSubType (intf) == GL_FRAGMENT_SHADER)
625 type = slang_unit_fragment_shader;
626 else
627 type = slang_unit_vertex_shader;
628 slang_info_log_construct (&info_log);
629 if (_slang_compile (impl->_obj.source, &impl->_obj.unit, type, &info_log))
630 {
631 impl->_obj.compile_status = GL_TRUE;
632 }
633 if (info_log.text != NULL)
634 impl->_obj._generic.info_log = _mesa_strdup (info_log.text);
635 else
636 impl->_obj._generic.info_log = _mesa_strdup ("");
637 slang_info_log_destruct (&info_log);
638 #endif
639 }
640
641 static struct gl2_shader_intf _shader_vftbl = {
642 {
643 {
644 _unknown_AddRef,
645 _unknown_Release,
646 _shader_QueryInterface
647 },
648 _generic_Delete,
649 _shader_GetType,
650 _generic_GetName,
651 _generic_GetDeleteStatus,
652 _generic_GetInfoLog
653 },
654 NULL, /* abstract GetSubType */
655 _shader_GetCompileStatus,
656 _shader_SetSource,
657 _shader_GetSource,
658 _shader_Compile
659 };
660
661 static void
662 _shader_constructor (struct gl2_shader_impl *impl)
663 {
664 _generic_constructor ((struct gl2_generic_impl *) impl);
665 _3dlabs_shhandle_constructor (&impl->_obj._3dlabs_shhandle, (struct gl2_unknown_intf **)
666 &impl->_vftbl);
667 impl->_vftbl = &_shader_vftbl;
668 impl->_obj._generic._unknown._destructor = _shader_destructor;
669 impl->_obj.compile_status = GL_FALSE;
670 impl->_obj.source = NULL;
671 impl->_obj.offsets = NULL;
672 impl->_obj.offset_count = 0;
673 }
674
675 struct gl2_program_obj
676 {
677 struct gl2_container_obj _container;
678 GLboolean link_status;
679 GLboolean validate_status;
680 #if USE_3DLABS_FRONTEND
681 ShHandle linker;
682 ShHandle uniforms;
683 #endif
684 slang_program prog;
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 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
697 #if USE_3DLABS_FRONTEND
698 ShDestruct (impl->_obj.linker);
699 ShDestruct (impl->_obj.uniforms);
700 #endif
701 _container_destructor (intf);
702 slang_program_dtr (&impl->_obj.prog);
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 #endif
762 GLuint i, count;
763 slang_translation_unit *units[2];
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 slang_program_dtr (&impl->_obj.prog);
769 slang_program_ctr (&impl->_obj.prog);
770
771 #if USE_3DLABS_FRONTEND
772 handles = (ShHandle *) _mesa_malloc (impl->_obj._container.attached_count * sizeof (ShHandle));
773 if (handles == NULL)
774 return;
775
776 for (i = 0; i < impl->_obj._container.attached_count; i++)
777 {
778 struct gl2_generic_intf **gen = impl->_obj._container.attached[i];
779 struct gl2_3dlabs_shhandle_intf **sh;
780
781 sh = (struct gl2_3dlabs_shhandle_intf **) (**gen)._unknown.QueryInterface (
782 (struct gl2_unknown_intf **) gen, UIID_3DLABS_SHHANDLE);
783 if (sh != NULL)
784 {
785 handles[i] = (**sh).GetShHandle (sh);
786 (**sh)._unknown.Release ((struct gl2_unknown_intf **) sh);
787 }
788 else
789 {
790 _mesa_free (handles);
791 return;
792 }
793 }
794
795 if (ShLink (impl->_obj.linker, handles, impl->_obj._container.attached_count,
796 impl->_obj.uniforms, NULL, NULL))
797 impl->_obj.link_status = GL_TRUE;
798
799 impl->_obj._container._generic.info_log = _mesa_strdup (ShGetInfoLog (impl->_obj.linker));
800 #else
801 count = impl->_obj._container.attached_count;
802 if (count == 0 || count > 2)
803 return;
804 for (i = 0; i < count; i++)
805 {
806 struct gl2_generic_intf **obj;
807 struct gl2_unknown_intf **unk;
808 struct gl2_shader_impl *sha;
809
810 obj = impl->_obj._container.attached[i];
811 unk = (**obj)._unknown.QueryInterface ((struct gl2_unknown_intf **) obj, UIID_SHADER);
812 (**obj)._unknown.Release ((struct gl2_unknown_intf **) obj);
813 if (unk == NULL)
814 return;
815 sha = (struct gl2_shader_impl *) unk;
816 units[i] = &sha->_obj.unit;
817 (**unk).Release (unk);
818 }
819
820 impl->_obj.link_status = _slang_link (&impl->_obj.prog, units, count);
821 if (impl->_obj.link_status)
822 impl->_obj._container._generic.info_log = _mesa_strdup ("Link OK.\n");
823 else
824 impl->_obj._container._generic.info_log = _mesa_strdup ("Link failed.\n");
825 #endif
826 }
827
828 static GLvoid
829 _program_Validate (struct gl2_program_intf **intf)
830 {
831 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
832
833 impl->_obj.validate_status = GL_FALSE;
834 _mesa_free ((void *) impl->_obj._container._generic.info_log);
835 impl->_obj._container._generic.info_log = NULL;
836
837 /* TODO validate */
838 }
839
840 static GLvoid
841 write_common_fixed (slang_program *pro, GLuint index, const GLvoid *src, GLuint off, GLuint size)
842 {
843 GLuint i;
844
845 for (i = 0; i < SLANG_SHADER_MAX; i++)
846 {
847 GLuint addr;
848
849 addr = pro->common_fixed_entries[i][index];
850 if (addr != ~0)
851 {
852 GLubyte *dst;
853
854 dst = (GLubyte *) pro->machines[i]->mem + addr + off * size;
855 _mesa_memcpy (dst, src, size);
856 }
857 }
858 }
859
860 static GLvoid
861 write_common_fixed_mat4 (slang_program *pro, GLmatrix *matrix, GLuint off, GLuint i, GLuint ii,
862 GLuint it, GLuint iit)
863 {
864 GLfloat mat[16];
865
866 /* we want inverse matrix */
867 if (!matrix->inv)
868 {
869 /* allocate inverse matrix and make it dirty */
870 _math_matrix_alloc_inv (matrix);
871 _math_matrix_loadf (matrix, matrix->m);
872 }
873 _math_matrix_analyse (matrix);
874
875 write_common_fixed (pro, i, matrix->m, off, 16 * sizeof (GLfloat));
876
877 /* inverse */
878 write_common_fixed (pro, ii, matrix->inv, off, 16 * sizeof (GLfloat));
879
880 /* transpose */
881 _math_transposef (mat, matrix->m);
882 write_common_fixed (pro, it, mat, off, 16 * sizeof (GLfloat));
883
884 /* inverse transpose */
885 _math_transposef (mat, matrix->inv);
886 write_common_fixed (pro, iit, mat, off, 16 * sizeof (GLfloat));
887 }
888
889 static GLvoid
890 write_common_fixed_material (GLcontext *ctx, slang_program *pro, GLuint i, GLuint e, GLuint a,
891 GLuint d, GLuint sp, GLuint sh)
892 {
893 GLfloat v[17];
894
895 COPY_4FV(v, ctx->Light.Material.Attrib[e]);
896 COPY_4FV((v + 4), ctx->Light.Material.Attrib[a]);
897 COPY_4FV((v + 8), ctx->Light.Material.Attrib[d]);
898 COPY_4FV((v + 12), ctx->Light.Material.Attrib[sp]);
899 v[16] = ctx->Light.Material.Attrib[sh][0];
900 write_common_fixed (pro, i, v, 0, 17 * sizeof (GLfloat));
901 }
902
903 static GLvoid
904 write_common_fixed_light_model_product (GLcontext *ctx, slang_program *pro, GLuint i, GLuint e,
905 GLuint a)
906 {
907 GLfloat v[4];
908
909 SCALE_4V(v, ctx->Light.Material.Attrib[a], ctx->Light.Model.Ambient);
910 ACC_4V(v, ctx->Light.Material.Attrib[e]);
911 write_common_fixed (pro, i, v, 0, 4 * sizeof (GLfloat));
912 }
913
914 static GLvoid
915 write_common_fixed_light_product (GLcontext *ctx, slang_program *pro, GLuint off, GLuint i, GLuint a,
916 GLuint d, GLuint s)
917 {
918 GLfloat v[12];
919
920 SCALE_4V(v, ctx->Light.Light[off].Ambient, ctx->Light.Material.Attrib[a]);
921 SCALE_4V((v + 4), ctx->Light.Light[off].Diffuse, ctx->Light.Material.Attrib[d]);
922 SCALE_4V((v + 8), ctx->Light.Light[off].Specular, ctx->Light.Material.Attrib[s]);
923 write_common_fixed (pro, i, v, off, 12 * sizeof (GLfloat));
924 }
925
926 static GLvoid
927 _program_UpdateFixedUniforms (struct gl2_program_intf **intf)
928 {
929 GET_CURRENT_CONTEXT(ctx);
930 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
931 slang_program *pro = &impl->_obj.prog;
932 GLuint i;
933 GLfloat v[29];
934 GLfloat *p;
935
936 /* MODELVIEW matrix */
937 write_common_fixed_mat4 (pro, ctx->ModelviewMatrixStack.Top, 0,
938 SLANG_COMMON_FIXED_MODELVIEWMATRIX,
939 SLANG_COMMON_FIXED_MODELVIEWMATRIXINVERSE,
940 SLANG_COMMON_FIXED_MODELVIEWMATRIXTRANSPOSE,
941 SLANG_COMMON_FIXED_MODELVIEWMATRIXINVERSETRANSPOSE);
942
943 /* PROJECTION matrix */
944 write_common_fixed_mat4 (pro, ctx->ProjectionMatrixStack.Top, 0,
945 SLANG_COMMON_FIXED_PROJECTIONMATRIX,
946 SLANG_COMMON_FIXED_PROJECTIONMATRIXINVERSE,
947 SLANG_COMMON_FIXED_PROJECTIONMATRIXTRANSPOSE,
948 SLANG_COMMON_FIXED_PROJECTIONMATRIXINVERSETRANSPOSE);
949
950 /* MVP matrix */
951 write_common_fixed_mat4 (pro, &ctx->_ModelProjectMatrix, 0,
952 SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIX,
953 SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIXINVERSE,
954 SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIXTRANSPOSE,
955 SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIXINVERSETRANSPOSE);
956
957 for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++)
958 {
959 /* TEXTURE matrix */
960 write_common_fixed_mat4 (pro, ctx->TextureMatrixStack[i].Top, i,
961 SLANG_COMMON_FIXED_TEXTUREMATRIX,
962 SLANG_COMMON_FIXED_TEXTUREMATRIXINVERSE,
963 SLANG_COMMON_FIXED_TEXTUREMATRIXTRANSPOSE,
964 SLANG_COMMON_FIXED_TEXTUREMATRIXINVERSETRANSPOSE);
965
966 /* EYE_PLANE texture-coordinate generation */
967 write_common_fixed (pro, SLANG_COMMON_FIXED_EYEPLANES, ctx->Texture.Unit[i].EyePlaneS,
968 i, 4 * sizeof (GLfloat));
969 write_common_fixed (pro, SLANG_COMMON_FIXED_EYEPLANET, ctx->Texture.Unit[i].EyePlaneT,
970 i, 4 * sizeof (GLfloat));
971 write_common_fixed (pro, SLANG_COMMON_FIXED_EYEPLANER, ctx->Texture.Unit[i].EyePlaneR,
972 i, 4 * sizeof (GLfloat));
973 write_common_fixed (pro, SLANG_COMMON_FIXED_EYEPLANEQ, ctx->Texture.Unit[i].EyePlaneQ,
974 i, 4 * sizeof (GLfloat));
975
976 /* OBJECT_PLANE texture-coordinate generation */
977 write_common_fixed (pro, SLANG_COMMON_FIXED_OBJECTPLANES, ctx->Texture.Unit[i].ObjectPlaneS,
978 i, 4 * sizeof (GLfloat));
979 write_common_fixed (pro, SLANG_COMMON_FIXED_OBJECTPLANET, ctx->Texture.Unit[i].ObjectPlaneT,
980 i, 4 * sizeof (GLfloat));
981 write_common_fixed (pro, SLANG_COMMON_FIXED_OBJECTPLANER, ctx->Texture.Unit[i].ObjectPlaneR,
982 i, 4 * sizeof (GLfloat));
983 write_common_fixed (pro, SLANG_COMMON_FIXED_OBJECTPLANEQ, ctx->Texture.Unit[i].ObjectPlaneQ,
984 i, 4 * sizeof (GLfloat));
985 }
986
987 /* NORMAL matrix - upper 3x3 inverse transpose of MODELVIEW matrix */
988 p = ctx->ModelviewMatrixStack.Top->inv;
989 v[0] = p[0];
990 v[1] = p[4];
991 v[2] = p[8];
992 v[3] = p[1];
993 v[4] = p[5];
994 v[5] = p[9];
995 v[6] = p[2];
996 v[7] = p[6];
997 v[8] = p[10];
998 write_common_fixed (pro, SLANG_COMMON_FIXED_NORMALMATRIX, v, 0, 9 * sizeof (GLfloat));
999
1000 /* normal scale */
1001 write_common_fixed (pro, SLANG_COMMON_FIXED_NORMALSCALE, &ctx->_ModelViewInvScale, 0, sizeof (GLfloat));
1002
1003 /* depth range parameters */
1004 v[0] = ctx->Viewport.Near;
1005 v[1] = ctx->Viewport.Far;
1006 v[2] = ctx->Viewport.Far - ctx->Viewport.Near;
1007 write_common_fixed (pro, SLANG_COMMON_FIXED_DEPTHRANGE, v, 0, 3 * sizeof (GLfloat));
1008
1009 /* CLIP_PLANEi */
1010 for (i = 0; i < ctx->Const.MaxClipPlanes; i++)
1011 {
1012 write_common_fixed (pro, SLANG_COMMON_FIXED_CLIPPLANE, ctx->Transform.EyeUserPlane[i], i,
1013 4 * sizeof (GLfloat));
1014 }
1015
1016 /* point parameters */
1017 v[0] = ctx->Point.Size;
1018 v[1] = ctx->Point.MinSize;
1019 v[2] = ctx->Point.MaxSize;
1020 v[3] = ctx->Point.Threshold;
1021 COPY_3FV((v + 4), ctx->Point.Params);
1022 write_common_fixed (pro, SLANG_COMMON_FIXED_POINT, v, 0, 7 * sizeof (GLfloat));
1023
1024 /* material parameters */
1025 write_common_fixed_material (ctx, pro, SLANG_COMMON_FIXED_FRONTMATERIAL,
1026 MAT_ATTRIB_FRONT_EMISSION,
1027 MAT_ATTRIB_FRONT_AMBIENT,
1028 MAT_ATTRIB_FRONT_DIFFUSE,
1029 MAT_ATTRIB_FRONT_SPECULAR,
1030 MAT_ATTRIB_FRONT_SHININESS);
1031 write_common_fixed_material (ctx, pro, SLANG_COMMON_FIXED_BACKMATERIAL,
1032 MAT_ATTRIB_BACK_EMISSION,
1033 MAT_ATTRIB_BACK_AMBIENT,
1034 MAT_ATTRIB_BACK_DIFFUSE,
1035 MAT_ATTRIB_BACK_SPECULAR,
1036 MAT_ATTRIB_BACK_SHININESS);
1037
1038 for (i = 0; i < ctx->Const.MaxLights; i++)
1039 {
1040 /* light source parameters */
1041 COPY_4FV(v, ctx->Light.Light[i].Ambient);
1042 COPY_4FV((v + 4), ctx->Light.Light[i].Diffuse);
1043 COPY_4FV((v + 8), ctx->Light.Light[i].Specular);
1044 COPY_4FV((v + 12), ctx->Light.Light[i].EyePosition);
1045 COPY_2FV((v + 16), ctx->Light.Light[i].EyePosition);
1046 v[18] = ctx->Light.Light[i].EyePosition[2] + 1.0f;
1047 NORMALIZE_3FV((v + 16));
1048 v[19] = 0.0f;
1049 COPY_3V((v + 20), ctx->Light.Light[i].EyeDirection);
1050 v[23] = ctx->Light.Light[i].SpotExponent;
1051 v[24] = ctx->Light.Light[i].SpotCutoff;
1052 v[25] = ctx->Light.Light[i]._CosCutoffNeg;
1053 v[26] = ctx->Light.Light[i].ConstantAttenuation;
1054 v[27] = ctx->Light.Light[i].LinearAttenuation;
1055 v[28] = ctx->Light.Light[i].QuadraticAttenuation;
1056 write_common_fixed (pro, SLANG_COMMON_FIXED_LIGHTSOURCE, v, i, 29 * sizeof (GLfloat));
1057
1058 /* light product */
1059 write_common_fixed_light_product (ctx, pro, i, SLANG_COMMON_FIXED_FRONTLIGHTPRODUCT,
1060 MAT_ATTRIB_FRONT_AMBIENT,
1061 MAT_ATTRIB_FRONT_DIFFUSE,
1062 MAT_ATTRIB_FRONT_SPECULAR);
1063 write_common_fixed_light_product (ctx, pro, i, SLANG_COMMON_FIXED_BACKLIGHTPRODUCT,
1064 MAT_ATTRIB_BACK_AMBIENT,
1065 MAT_ATTRIB_BACK_DIFFUSE,
1066 MAT_ATTRIB_BACK_SPECULAR);
1067 }
1068
1069 /* light model parameters */
1070 write_common_fixed (pro, SLANG_COMMON_FIXED_LIGHTMODEL, ctx->Light.Model.Ambient, 0, 4 * sizeof (GLfloat));
1071
1072 /* light model product */
1073 write_common_fixed_light_model_product (ctx, pro, SLANG_COMMON_FIXED_FRONTLIGHTMODELPRODUCT,
1074 MAT_ATTRIB_FRONT_EMISSION,
1075 MAT_ATTRIB_FRONT_AMBIENT);
1076 write_common_fixed_light_model_product (ctx, pro, SLANG_COMMON_FIXED_BACKLIGHTMODELPRODUCT,
1077 MAT_ATTRIB_BACK_EMISSION,
1078 MAT_ATTRIB_BACK_AMBIENT);
1079
1080 /* TEXTURE_ENV_COLOR */
1081 for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++)
1082 {
1083 write_common_fixed (pro, SLANG_COMMON_FIXED_TEXTUREENVCOLOR, ctx->Texture.Unit[i].EnvColor,
1084 i, 4 * sizeof (GLfloat));
1085 }
1086
1087 /* fog parameters */
1088 COPY_4FV(v, ctx->Fog.Color);
1089 v[4] = ctx->Fog.Density;
1090 v[5] = ctx->Fog.Start;
1091 v[6] = ctx->Fog.End;
1092 v[7] = ctx->Fog._Scale;
1093 write_common_fixed (pro, SLANG_COMMON_FIXED_FOG, v, 0, 8 * sizeof (GLfloat));
1094 }
1095
1096 static GLvoid
1097 _program_UpdateFixedAttribute (struct gl2_program_intf **intf, GLuint index, GLvoid *data,
1098 GLuint offset, GLuint size, GLboolean write)
1099 {
1100 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
1101 slang_program *pro = &impl->_obj.prog;
1102 GLuint addr;
1103
1104 addr = pro->vertex_fixed_entries[index];
1105 if (addr != ~0)
1106 {
1107 GLubyte *mem;
1108
1109 mem = (GLubyte *) pro->machines[SLANG_SHADER_VERTEX]->mem + addr + offset * size;
1110 if (write)
1111 _mesa_memcpy (mem, data, size);
1112 else
1113 _mesa_memcpy (data, mem, size);
1114 }
1115 }
1116
1117 static GLvoid
1118 _program_UpdateFixedVarying (struct gl2_program_intf **intf, GLuint index, GLvoid *data,
1119 GLuint offset, GLuint size, GLboolean write)
1120 {
1121 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
1122 slang_program *pro = &impl->_obj.prog;
1123 GLuint addr;
1124
1125 addr = pro->fragment_fixed_entries[index];
1126 if (addr != ~0)
1127 {
1128 GLubyte *mem;
1129
1130 mem = (GLubyte *) pro->machines[SLANG_SHADER_FRAGMENT]->mem + addr + offset * size;
1131 if (write)
1132 _mesa_memcpy (mem, data, size);
1133 else
1134 _mesa_memcpy (data, mem, size);
1135 }
1136 }
1137
1138 static GLvoid
1139 _program_GetTextureImageUsage (struct gl2_program_intf **intf, GLbitfield *teximageusage)
1140 {
1141 GET_CURRENT_CONTEXT(ctx);
1142 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
1143 slang_program *pro = &impl->_obj.prog;
1144 GLuint i;
1145
1146 for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++)
1147 teximageusage[i] = 0;
1148
1149 for (i = 0; i < pro->texture_usage.count; i++)
1150 {
1151 GLuint n, addr, j;
1152
1153 n = slang_export_data_quant_elements (pro->texture_usage.table[i].quant);
1154 addr = pro->texture_usage.table[i].frag_address;
1155 for (j = 0; j < n; j++)
1156 {
1157 GLubyte *mem;
1158 GLuint image;
1159
1160 mem = (GLubyte *) pro->machines[SLANG_SHADER_FRAGMENT]->mem + addr + j * 4;
1161 image = (GLuint) *((GLfloat *) mem);
1162 if (image >= 0 && image < ctx->Const.MaxTextureImageUnits)
1163 {
1164 switch (slang_export_data_quant_type (pro->texture_usage.table[i].quant))
1165 {
1166 case GL_SAMPLER_1D_ARB:
1167 case GL_SAMPLER_1D_SHADOW_ARB:
1168 teximageusage[image] |= TEXTURE_1D_BIT;
1169 break;
1170 case GL_SAMPLER_2D_ARB:
1171 case GL_SAMPLER_2D_SHADOW_ARB:
1172 teximageusage[image] |= TEXTURE_2D_BIT;
1173 break;
1174 case GL_SAMPLER_3D_ARB:
1175 teximageusage[image] |= TEXTURE_3D_BIT;
1176 break;
1177 case GL_SAMPLER_CUBE_ARB:
1178 teximageusage[image] |= TEXTURE_CUBE_BIT;
1179 break;
1180 }
1181 }
1182 }
1183 }
1184
1185 /* TODO: make sure that for 0<=i<=MaxTextureImageUint bitcount(teximageuint[i])<=0 */
1186 }
1187
1188 static GLboolean
1189 _program_IsShaderPresent (struct gl2_program_intf **intf, GLenum subtype)
1190 {
1191 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
1192 slang_program *pro = &impl->_obj.prog;
1193
1194 switch (subtype)
1195 {
1196 case GL_VERTEX_SHADER_ARB:
1197 return pro->machines[SLANG_SHADER_VERTEX] != NULL;
1198 case GL_FRAGMENT_SHADER_ARB:
1199 return pro->machines[SLANG_SHADER_FRAGMENT] != NULL;
1200 default:
1201 return GL_FALSE;
1202 }
1203 }
1204
1205 static GLvoid
1206 _program_UpdateVarying (struct gl2_program_intf **intf, GLuint index, GLfloat *value,
1207 GLboolean vert)
1208 {
1209 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
1210 slang_program *pro = &impl->_obj.prog;
1211 GLuint addr;
1212
1213 if (index >= pro->varyings.total)
1214 return;
1215 if (vert)
1216 addr = pro->varyings.slots[index].vert_addr / 4;
1217 else
1218 addr = pro->varyings.slots[index].frag_addr / 4;
1219 if (addr != ~0)
1220 {
1221 if (vert)
1222 *value = pro->machines[SLANG_SHADER_VERTEX]->mem[addr]._float;
1223 else
1224 pro->machines[SLANG_SHADER_FRAGMENT]->mem[addr]._float = *value;
1225 }
1226 }
1227
1228 static struct gl2_program_intf _program_vftbl = {
1229 {
1230 {
1231 {
1232 _unknown_AddRef,
1233 _unknown_Release,
1234 _program_QueryInterface
1235 },
1236 _generic_Delete,
1237 _program_GetType,
1238 _generic_GetName,
1239 _generic_GetDeleteStatus,
1240 _generic_GetInfoLog
1241 },
1242 _program_Attach,
1243 _container_Detach,
1244 _container_GetAttachedCount,
1245 _container_GetAttached
1246 },
1247 _program_GetLinkStatus,
1248 _program_GetValidateStatus,
1249 _program_Link,
1250 _program_Validate,
1251 _program_UpdateFixedUniforms,
1252 _program_UpdateFixedAttribute,
1253 _program_UpdateFixedVarying,
1254 _program_GetTextureImageUsage,
1255 _program_IsShaderPresent,
1256 _program_UpdateVarying
1257 };
1258
1259 static void
1260 _program_constructor (struct gl2_program_impl *impl)
1261 {
1262 _container_constructor ((struct gl2_container_impl *) impl);
1263 impl->_vftbl = &_program_vftbl;
1264 impl->_obj._container._generic._unknown._destructor = _program_destructor;
1265 impl->_obj.link_status = GL_FALSE;
1266 impl->_obj.validate_status = GL_FALSE;
1267 #if USE_3DLABS_FRONTEND
1268 impl->_obj.linker = ShConstructLinker (EShExVertexFragment, 0);
1269 impl->_obj.uniforms = ShConstructUniformMap ();
1270 #endif
1271 slang_program_ctr (&impl->_obj.prog);
1272 }
1273
1274 struct gl2_fragment_shader_obj
1275 {
1276 struct gl2_shader_obj _shader;
1277 };
1278
1279 struct gl2_fragment_shader_impl
1280 {
1281 struct gl2_fragment_shader_intf *_vftbl;
1282 struct gl2_fragment_shader_obj _obj;
1283 };
1284
1285 static void
1286 _fragment_shader_destructor (struct gl2_unknown_intf **intf)
1287 {
1288 struct gl2_fragment_shader_impl *impl = (struct gl2_fragment_shader_impl *) intf;
1289
1290 (void) impl;
1291 /* TODO free fragment shader data */
1292
1293 _shader_destructor (intf);
1294 }
1295
1296 static struct gl2_unknown_intf **
1297 _fragment_shader_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
1298 {
1299 if (uiid == UIID_FRAGMENT_SHADER)
1300 {
1301 (**intf).AddRef (intf);
1302 return intf;
1303 }
1304 return _shader_QueryInterface (intf, uiid);
1305 }
1306
1307 static GLenum
1308 _fragment_shader_GetSubType (struct gl2_shader_intf **intf)
1309 {
1310 return GL_FRAGMENT_SHADER_ARB;
1311 }
1312
1313 static struct gl2_fragment_shader_intf _fragment_shader_vftbl = {
1314 {
1315 {
1316 {
1317 _unknown_AddRef,
1318 _unknown_Release,
1319 _fragment_shader_QueryInterface
1320 },
1321 _generic_Delete,
1322 _shader_GetType,
1323 _generic_GetName,
1324 _generic_GetDeleteStatus,
1325 _generic_GetInfoLog
1326 },
1327 _fragment_shader_GetSubType,
1328 _shader_GetCompileStatus,
1329 _shader_SetSource,
1330 _shader_GetSource,
1331 _shader_Compile
1332 }
1333 };
1334
1335 static void
1336 _fragment_shader_constructor (struct gl2_fragment_shader_impl *impl)
1337 {
1338 _shader_constructor ((struct gl2_shader_impl *) impl);
1339 impl->_vftbl = &_fragment_shader_vftbl;
1340 impl->_obj._shader._generic._unknown._destructor = _fragment_shader_destructor;
1341 #if USE_3DLABS_FRONTEND
1342 impl->_obj._shader._3dlabs_shhandle._obj.handle = ShConstructCompiler (EShLangFragment, 0);
1343 #endif
1344 }
1345
1346 struct gl2_vertex_shader_obj
1347 {
1348 struct gl2_shader_obj _shader;
1349 };
1350
1351 struct gl2_vertex_shader_impl
1352 {
1353 struct gl2_vertex_shader_intf *_vftbl;
1354 struct gl2_vertex_shader_obj _obj;
1355 };
1356
1357 static void
1358 _vertex_shader_destructor (struct gl2_unknown_intf **intf)
1359 {
1360 struct gl2_vertex_shader_impl *impl = (struct gl2_vertex_shader_impl *) intf;
1361
1362 (void) impl;
1363 /* TODO free vertex shader data */
1364
1365 _shader_destructor (intf);
1366 }
1367
1368 static struct gl2_unknown_intf **
1369 _vertex_shader_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
1370 {
1371 if (uiid == UIID_VERTEX_SHADER)
1372 {
1373 (**intf).AddRef (intf);
1374 return intf;
1375 }
1376 return _shader_QueryInterface (intf, uiid);
1377 }
1378
1379 static GLenum
1380 _vertex_shader_GetSubType (struct gl2_shader_intf **intf)
1381 {
1382 return GL_VERTEX_SHADER_ARB;
1383 }
1384
1385 static struct gl2_vertex_shader_intf _vertex_shader_vftbl = {
1386 {
1387 {
1388 {
1389 _unknown_AddRef,
1390 _unknown_Release,
1391 _vertex_shader_QueryInterface
1392 },
1393 _generic_Delete,
1394 _shader_GetType,
1395 _generic_GetName,
1396 _generic_GetDeleteStatus,
1397 _generic_GetInfoLog
1398 },
1399 _vertex_shader_GetSubType,
1400 _shader_GetCompileStatus,
1401 _shader_SetSource,
1402 _shader_GetSource,
1403 _shader_Compile
1404 }
1405 };
1406
1407 static void
1408 _vertex_shader_constructor (struct gl2_vertex_shader_impl *impl)
1409 {
1410 _shader_constructor ((struct gl2_shader_impl *) impl);
1411 impl->_vftbl = &_vertex_shader_vftbl;
1412 impl->_obj._shader._generic._unknown._destructor = _vertex_shader_destructor;
1413 #if USE_3DLABS_FRONTEND
1414 impl->_obj._shader._3dlabs_shhandle._obj.handle = ShConstructCompiler (EShLangVertex, 0);
1415 #endif
1416 }
1417
1418 GLhandleARB
1419 _mesa_3dlabs_create_shader_object (GLenum shaderType)
1420 {
1421 switch (shaderType)
1422 {
1423 case GL_FRAGMENT_SHADER_ARB:
1424 {
1425 struct gl2_fragment_shader_impl *x = (struct gl2_fragment_shader_impl *)
1426 _mesa_malloc (sizeof (struct gl2_fragment_shader_impl));
1427
1428 if (x != NULL)
1429 {
1430 _fragment_shader_constructor (x);
1431 return x->_obj._shader._generic.name;
1432 }
1433 }
1434 break;
1435 case GL_VERTEX_SHADER_ARB:
1436 {
1437 struct gl2_vertex_shader_impl *x = (struct gl2_vertex_shader_impl *)
1438 _mesa_malloc (sizeof (struct gl2_vertex_shader_impl));
1439
1440 if (x != NULL)
1441 {
1442 _vertex_shader_constructor (x);
1443 return x->_obj._shader._generic.name;
1444 }
1445 }
1446 break;
1447 }
1448
1449 return 0;
1450 }
1451
1452 GLhandleARB
1453 _mesa_3dlabs_create_program_object (void)
1454 {
1455 struct gl2_program_impl *x = (struct gl2_program_impl *)
1456 _mesa_malloc (sizeof (struct gl2_program_impl));
1457
1458 if (x != NULL)
1459 {
1460 _program_constructor (x);
1461 return x->_obj._container._generic.name;
1462 }
1463
1464 return 0;
1465 }
1466
1467 #include "slang_assemble.h"
1468 #include "slang_execute.h"
1469
1470 int _slang_fetch_discard (struct gl2_program_intf **pro, GLboolean *val)
1471 {
1472 struct gl2_program_impl *impl;
1473
1474 impl = (struct gl2_program_impl *) pro;
1475 *val = impl->_obj.prog.machines[SLANG_SHADER_FRAGMENT]->kill ? GL_TRUE : GL_FALSE;
1476 return 1;
1477 }
1478
1479 static GLvoid exec_shader (struct gl2_program_intf **pro, GLuint i)
1480 {
1481 struct gl2_program_impl *impl;
1482 slang_program *p;
1483
1484 impl = (struct gl2_program_impl *) pro;
1485 p = &impl->_obj.prog;
1486
1487 slang_machine_init (p->machines[i]);
1488 p->machines[i]->ip = p->code[i][SLANG_COMMON_CODE_MAIN];
1489
1490 _slang_execute2 (p->assemblies[i], p->machines[i]);
1491 }
1492
1493 GLvoid _slang_exec_fragment_shader (struct gl2_program_intf **pro)
1494 {
1495 exec_shader (pro, SLANG_SHADER_FRAGMENT);
1496 }
1497
1498 GLvoid _slang_exec_vertex_shader (struct gl2_program_intf **pro)
1499 {
1500 exec_shader (pro, SLANG_SHADER_VERTEX);
1501 }
1502
1503 GLint _slang_get_uniform_location (struct gl2_program_intf **pro, const char *name)
1504 {
1505 struct gl2_program_impl *impl;
1506 slang_uniform_bindings *bind;
1507 GLuint i;
1508
1509 impl = (struct gl2_program_impl *) pro;
1510 bind = &impl->_obj.prog.uniforms;
1511 for (i = 0; i < bind->count; i++)
1512 if (_mesa_strcmp (bind->table[i].name, name) == 0)
1513 return i;
1514 return -1;
1515 }
1516
1517 GLboolean _slang_write_uniform (struct gl2_program_intf **pro, GLint loc, GLsizei count,
1518 const GLvoid *data, GLenum type)
1519 {
1520 struct gl2_program_impl *impl;
1521 slang_uniform_bindings *bind;
1522 slang_uniform_binding *b;
1523 GLuint i;
1524 GLboolean convert_float_to_bool = GL_FALSE;
1525 GLboolean convert_int_to_bool = GL_FALSE;
1526 GLboolean convert_int_to_float = GL_FALSE;
1527 GLboolean types_match = GL_FALSE;
1528
1529 if (loc == -1)
1530 return GL_TRUE;
1531
1532 impl = (struct gl2_program_impl *) pro;
1533 bind = &impl->_obj.prog.uniforms;
1534 if (loc >= bind->count)
1535 return GL_FALSE;
1536
1537 b = &bind->table[loc];
1538 /* TODO: check sizes */
1539 if (slang_export_data_quant_struct (b->quant))
1540 return GL_FALSE;
1541
1542 switch (slang_export_data_quant_type (b->quant))
1543 {
1544 case GL_BOOL_ARB:
1545 types_match = (type == GL_FLOAT) || (type == GL_INT);
1546 if (type == GL_FLOAT)
1547 convert_float_to_bool = GL_TRUE;
1548 else
1549 convert_int_to_bool = GL_TRUE;
1550 break;
1551 case GL_BOOL_VEC2_ARB:
1552 types_match = (type == GL_FLOAT_VEC2_ARB) || (type == GL_INT_VEC2_ARB);
1553 if (type == GL_FLOAT_VEC2_ARB)
1554 convert_float_to_bool = GL_TRUE;
1555 else
1556 convert_int_to_bool = GL_TRUE;
1557 break;
1558 case GL_BOOL_VEC3_ARB:
1559 types_match = (type == GL_FLOAT_VEC3_ARB) || (type == GL_INT_VEC3_ARB);
1560 if (type == GL_FLOAT_VEC3_ARB)
1561 convert_float_to_bool = GL_TRUE;
1562 else
1563 convert_int_to_bool = GL_TRUE;
1564 break;
1565 case GL_BOOL_VEC4_ARB:
1566 types_match = (type == GL_FLOAT_VEC4_ARB) || (type == GL_INT_VEC4_ARB);
1567 if (type == GL_FLOAT_VEC4_ARB)
1568 convert_float_to_bool = GL_TRUE;
1569 else
1570 convert_int_to_bool = GL_TRUE;
1571 break;
1572 case GL_SAMPLER_1D_ARB:
1573 case GL_SAMPLER_2D_ARB:
1574 case GL_SAMPLER_3D_ARB:
1575 case GL_SAMPLER_CUBE_ARB:
1576 case GL_SAMPLER_1D_SHADOW_ARB:
1577 case GL_SAMPLER_2D_SHADOW_ARB:
1578 types_match = (type == GL_INT);
1579 break;
1580 default:
1581 types_match = (type == slang_export_data_quant_type (b->quant));
1582 break;
1583 }
1584
1585 if (!types_match)
1586 return GL_FALSE;
1587
1588 switch (type)
1589 {
1590 case GL_INT:
1591 case GL_INT_VEC2_ARB:
1592 case GL_INT_VEC3_ARB:
1593 case GL_INT_VEC4_ARB:
1594 convert_int_to_float = GL_TRUE;
1595 break;
1596 }
1597
1598 if (convert_float_to_bool)
1599 {
1600 for (i = 0; i < SLANG_SHADER_MAX; i++)
1601 if (b->address[i] != ~0)
1602 {
1603 const GLfloat *src = (GLfloat *) (data);
1604 GLfloat *dst = (GLfloat *) (&impl->_obj.prog.machines[i]->mem[b->address[i] / 4]);
1605 GLuint j;
1606 GLuint total = count * slang_export_data_quant_components (b->quant);
1607
1608 for (j = 0; j < total; j++)
1609 dst[j] = src[j] != 0.0f ? 1.0f : 0.0f;
1610 }
1611 }
1612 else if (convert_int_to_bool)
1613 {
1614 for (i = 0; i < SLANG_SHADER_MAX; i++)
1615 if (b->address[i] != ~0)
1616 {
1617 const GLuint *src = (GLuint *) (data);
1618 GLfloat *dst = (GLfloat *) (&impl->_obj.prog.machines[i]->mem[b->address[i] / 4]);
1619 GLuint j;
1620 GLuint total = count * slang_export_data_quant_components (b->quant);
1621
1622 for (j = 0; j < total; j++)
1623 dst[j] = src[j] ? 1.0f : 0.0f;
1624 }
1625 }
1626 else if (convert_int_to_float)
1627 {
1628 for (i = 0; i < SLANG_SHADER_MAX; i++)
1629 if (b->address[i] != ~0)
1630 {
1631 const GLuint *src = (GLuint *) (data);
1632 GLfloat *dst = (GLfloat *) (&impl->_obj.prog.machines[i]->mem[b->address[i] / 4]);
1633 GLuint j;
1634 GLuint total = count * slang_export_data_quant_components (b->quant);
1635
1636 for (j = 0; j < total; j++)
1637 dst[j] = (GLfloat) src[j];
1638 }
1639 }
1640 else
1641 {
1642 for (i = 0; i < SLANG_SHADER_MAX; i++)
1643 if (b->address[i] != ~0)
1644 {
1645 _mesa_memcpy (&impl->_obj.prog.machines[i]->mem[b->address[i] / 4], data,
1646 count * slang_export_data_quant_size (b->quant));
1647 }
1648 }
1649 return GL_TRUE;
1650 }
1651
1652 GLuint _slang_get_active_uniform_count (struct gl2_program_intf **pro)
1653 {
1654 struct gl2_program_impl *impl;
1655
1656 impl = (struct gl2_program_impl *) pro;
1657 return impl->_obj.prog.active_uniforms.count;
1658 }
1659
1660 GLuint _slang_get_active_uniform_max_length (struct gl2_program_intf **pro)
1661 {
1662 struct gl2_program_impl *impl;
1663 GLuint i, len = 0;
1664
1665 impl = (struct gl2_program_impl *) pro;
1666 for (i = 0; i < impl->_obj.prog.active_uniforms.count; i++)
1667 {
1668 GLuint n = _mesa_strlen (impl->_obj.prog.active_uniforms.table[i].name);
1669 if (n > len)
1670 len = n;
1671 }
1672 return len;
1673 }
1674
1675 GLvoid _slang_get_active_uniform (struct gl2_program_intf **pro, GLuint index, GLsizei maxLength,
1676 GLsizei *length, GLint *size, GLenum *type, char *name)
1677 {
1678 struct gl2_program_impl *impl;
1679 slang_active_uniform *u;
1680 GLsizei len;
1681
1682 impl = (struct gl2_program_impl *) pro;
1683 u = &impl->_obj.prog.active_uniforms.table[index];
1684
1685 len = _mesa_strlen (u->name);
1686 if (len >= maxLength)
1687 len = maxLength - 1;
1688 _mesa_memcpy (name, u->name, len);
1689 name[len] = '\0';
1690 if (length != NULL)
1691 *length = len;
1692 *type = slang_export_data_quant_type (u->quant);
1693 *size = slang_export_data_quant_elements (u->quant);
1694 }
1695
1696 void
1697 _mesa_init_shaderobjects_3dlabs (GLcontext *ctx)
1698 {
1699 #if USE_3DLABS_FRONTEND
1700 _glslang_3dlabs_InitProcess ();
1701 _glslang_3dlabs_ShInitialize ();
1702 #endif
1703 }
1704