GLSL fixes:
[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
39 #if USE_3DLABS_FRONTEND
40 #include "slang_mesa.h"
41 #include "Public/ShaderLang.h"
42 #else
43 #include "slang_link.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 slang_translation_unit unit;
467 };
468
469 struct gl2_shader_impl
470 {
471 struct gl2_shader_intf *_vftbl;
472 struct gl2_shader_obj _obj;
473 };
474
475 static void
476 _shader_destructor (struct gl2_unknown_intf **intf)
477 {
478 struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
479
480 _mesa_free ((void *) impl->_obj.source);
481 _mesa_free ((void *) impl->_obj.offsets);
482 _3dlabs_shhandle_destructor ((struct gl2_unknown_intf **) &impl->_obj._3dlabs_shhandle._vftbl);
483 _generic_destructor (intf);
484 }
485
486 static struct gl2_unknown_intf **
487 _shader_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
488 {
489 #if USE_3DLABS_FRONTEND
490 struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
491 #endif
492
493 if (uiid == UIID_SHADER)
494 {
495 (**intf).AddRef (intf);
496 return intf;
497 }
498 #if USE_3DLABS_FRONTEND
499 if (uiid == UIID_3DLABS_SHHANDLE)
500 {
501 (**intf).AddRef (intf);
502 return (struct gl2_unknown_intf **) &impl->_obj._3dlabs_shhandle._vftbl;
503 }
504 #endif
505 return _generic_QueryInterface (intf, uiid);
506 }
507
508 static GLenum
509 _shader_GetType (struct gl2_generic_intf **intf)
510 {
511 return GL_SHADER_OBJECT_ARB;
512 }
513
514 static GLboolean
515 _shader_GetCompileStatus (struct gl2_shader_intf **intf)
516 {
517 struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
518
519 return impl->_obj.compile_status;
520 }
521
522 static GLvoid
523 _shader_SetSource (struct gl2_shader_intf **intf, GLcharARB *src, GLint *off, GLsizei cnt)
524 {
525 struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
526
527 _mesa_free ((void *) impl->_obj.source);
528 impl->_obj.source = src;
529 _mesa_free ((void *) impl->_obj.offsets);
530 impl->_obj.offsets = off;
531 impl->_obj.offset_count = cnt;
532 }
533
534 static const GLcharARB *
535 _shader_GetSource (struct gl2_shader_intf **intf)
536 {
537 struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
538
539 return impl->_obj.source;
540 }
541
542 static GLvoid
543 _shader_Compile (struct gl2_shader_intf **intf)
544 {
545 struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
546 #if USE_3DLABS_FRONTEND
547 char **strings;
548 TBuiltInResource res;
549 #else
550 slang_unit_type type;
551 slang_info_log info_log;
552 #endif
553
554 impl->_obj.compile_status = GL_FALSE;
555 _mesa_free ((void *) impl->_obj._generic.info_log);
556 impl->_obj._generic.info_log = NULL;
557
558 #if USE_3DLABS_FRONTEND
559 /* 3dlabs compiler expects us to feed it with null-terminated string array,
560 we've got only one big string with offsets, so we must split it; but when
561 there's only one string to deal with, we pass its address directly */
562
563 if (impl->_obj.offset_count <= 1)
564 strings = &impl->_obj.source;
565 else
566 {
567 GLsizei i, offset = 0;
568
569 strings = (char **) _mesa_malloc (impl->_obj.offset_count * sizeof (char *));
570 if (strings == NULL)
571 return;
572
573 for (i = 0; i < impl->_obj.offset_count; i++)
574 {
575 GLsizei size = impl->_obj.offsets[i] - offset;
576
577 strings[i] = (char *) _mesa_malloc ((size + 1) * sizeof (char));
578 if (strings[i] == NULL)
579 {
580 GLsizei j;
581
582 for (j = 0; j < i; j++)
583 _mesa_free (strings[j]);
584 _mesa_free (strings);
585 return;
586 }
587
588 _mesa_memcpy (strings[i], impl->_obj.source + offset, size * sizeof (char));
589 strings[i][size] = '\0';
590 offset = impl->_obj.offsets[i];
591 }
592 }
593
594 /* TODO set these fields to some REAL numbers */
595 res.maxLights = 8;
596 res.maxClipPlanes = 6;
597 res.maxTextureUnits = 2;
598 res.maxTextureCoords = 2;
599 res.maxVertexAttribs = 8;
600 res.maxVertexUniformComponents = 64;
601 res.maxVaryingFloats = 8;
602 res.maxVertexTextureImageUnits = 2;
603 res.maxCombinedTextureImageUnits = 2;
604 res.maxTextureImageUnits = 2;
605 res.maxFragmentUniformComponents = 64;
606 res.maxDrawBuffers = 1;
607
608 if (ShCompile (impl->_obj._3dlabs_shhandle._obj.handle, strings, impl->_obj.offset_count,
609 EShOptFull, &res, 0))
610 impl->_obj.compile_status = GL_TRUE;
611 if (impl->_obj.offset_count > 1)
612 {
613 GLsizei i;
614
615 for (i = 0; i < impl->_obj.offset_count; i++)
616 _mesa_free (strings[i]);
617 _mesa_free (strings);
618 }
619
620 impl->_obj._generic.info_log = _mesa_strdup (ShGetInfoLog (
621 impl->_obj._3dlabs_shhandle._obj.handle));
622 #else
623 if (impl->_vftbl->GetSubType (intf) == GL_FRAGMENT_SHADER)
624 type = slang_unit_fragment_shader;
625 else
626 type = slang_unit_vertex_shader;
627 slang_info_log_construct (&info_log);
628 if (_slang_compile (impl->_obj.source, &impl->_obj.unit, type, &info_log))
629 {
630 impl->_obj.compile_status = GL_TRUE;
631 }
632 if (info_log.text != NULL)
633 impl->_obj._generic.info_log = _mesa_strdup (info_log.text);
634 else
635 impl->_obj._generic.info_log = _mesa_strdup ("");
636 slang_info_log_destruct (&info_log);
637 #endif
638 }
639
640 static struct gl2_shader_intf _shader_vftbl = {
641 {
642 {
643 _unknown_AddRef,
644 _unknown_Release,
645 _shader_QueryInterface
646 },
647 _generic_Delete,
648 _shader_GetType,
649 _generic_GetName,
650 _generic_GetDeleteStatus,
651 _generic_GetInfoLog
652 },
653 NULL, /* abstract GetSubType */
654 _shader_GetCompileStatus,
655 _shader_SetSource,
656 _shader_GetSource,
657 _shader_Compile
658 };
659
660 static void
661 _shader_constructor (struct gl2_shader_impl *impl)
662 {
663 _generic_constructor ((struct gl2_generic_impl *) impl);
664 _3dlabs_shhandle_constructor (&impl->_obj._3dlabs_shhandle, (struct gl2_unknown_intf **)
665 &impl->_vftbl);
666 impl->_vftbl = &_shader_vftbl;
667 impl->_obj._generic._unknown._destructor = _shader_destructor;
668 impl->_obj.compile_status = GL_FALSE;
669 impl->_obj.source = NULL;
670 impl->_obj.offsets = NULL;
671 impl->_obj.offset_count = 0;
672 }
673
674 struct gl2_program_obj
675 {
676 struct gl2_container_obj _container;
677 GLboolean link_status;
678 GLboolean validate_status;
679 #if USE_3DLABS_FRONTEND
680 ShHandle linker;
681 ShHandle uniforms;
682 #endif
683 slang_program prog;
684 };
685
686 struct gl2_program_impl
687 {
688 struct gl2_program_intf *_vftbl;
689 struct gl2_program_obj _obj;
690 };
691
692 static void
693 _program_destructor (struct gl2_unknown_intf **intf)
694 {
695 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
696 #if USE_3DLABS_FRONTEND
697 ShDestruct (impl->_obj.linker);
698 ShDestruct (impl->_obj.uniforms);
699 #endif
700 _container_destructor (intf);
701 slang_program_dtr (&impl->_obj.prog);
702 }
703
704 static struct gl2_unknown_intf **
705 _program_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
706 {
707 if (uiid == UIID_PROGRAM)
708 {
709 (**intf).AddRef (intf);
710 return intf;
711 }
712 return _container_QueryInterface (intf, uiid);
713 }
714
715 static GLenum
716 _program_GetType (struct gl2_generic_intf **intf)
717 {
718 return GL_PROGRAM_OBJECT_ARB;
719 }
720
721 static GLboolean
722 _program_Attach (struct gl2_container_intf **intf, struct gl2_generic_intf **att)
723 {
724 GET_CURRENT_CONTEXT(ctx);
725 struct gl2_unknown_intf **sha;
726
727 sha = (**att)._unknown.QueryInterface ((struct gl2_unknown_intf **) att, UIID_SHADER);
728 if (sha == NULL)
729 {
730 _mesa_error (ctx, GL_INVALID_OPERATION, "_program_Attach");
731 return GL_FALSE;
732 }
733
734 (**sha).Release (sha);
735 return _container_Attach (intf, att);
736 }
737
738 static GLboolean
739 _program_GetLinkStatus (struct gl2_program_intf **intf)
740 {
741 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
742
743 return impl->_obj.link_status;
744 }
745
746 static GLboolean
747 _program_GetValidateStatus (struct gl2_program_intf **intf)
748 {
749 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
750
751 return impl->_obj.validate_status;
752 }
753
754 static GLvoid
755 _program_Link (struct gl2_program_intf **intf)
756 {
757 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
758 #if USE_3DLABS_FRONTEND
759 ShHandle *handles;
760 #endif
761 GLuint i, count;
762 slang_translation_unit *units[2];
763
764 impl->_obj.link_status = GL_FALSE;
765 _mesa_free ((void *) impl->_obj._container._generic.info_log);
766 impl->_obj._container._generic.info_log = NULL;
767 slang_program_dtr (&impl->_obj.prog);
768 slang_program_ctr (&impl->_obj.prog);
769
770 #if USE_3DLABS_FRONTEND
771 handles = (ShHandle *) _mesa_malloc (impl->_obj._container.attached_count * sizeof (ShHandle));
772 if (handles == NULL)
773 return;
774
775 for (i = 0; i < impl->_obj._container.attached_count; i++)
776 {
777 struct gl2_generic_intf **gen = impl->_obj._container.attached[i];
778 struct gl2_3dlabs_shhandle_intf **sh;
779
780 sh = (struct gl2_3dlabs_shhandle_intf **) (**gen)._unknown.QueryInterface (
781 (struct gl2_unknown_intf **) gen, UIID_3DLABS_SHHANDLE);
782 if (sh != NULL)
783 {
784 handles[i] = (**sh).GetShHandle (sh);
785 (**sh)._unknown.Release ((struct gl2_unknown_intf **) sh);
786 }
787 else
788 {
789 _mesa_free (handles);
790 return;
791 }
792 }
793
794 if (ShLink (impl->_obj.linker, handles, impl->_obj._container.attached_count,
795 impl->_obj.uniforms, NULL, NULL))
796 impl->_obj.link_status = GL_TRUE;
797
798 impl->_obj._container._generic.info_log = _mesa_strdup (ShGetInfoLog (impl->_obj.linker));
799 #else
800 count = impl->_obj._container.attached_count;
801 if (count == 0 || count > 2)
802 return;
803 for (i = 0; i < count; i++)
804 {
805 struct gl2_generic_intf **obj;
806 struct gl2_unknown_intf **unk;
807 struct gl2_shader_impl *sha;
808
809 obj = impl->_obj._container.attached[i];
810 unk = (**obj)._unknown.QueryInterface ((struct gl2_unknown_intf **) obj, UIID_SHADER);
811 (**obj)._unknown.Release ((struct gl2_unknown_intf **) obj);
812 if (unk == NULL)
813 return;
814 sha = (struct gl2_shader_impl *) unk;
815 units[i] = &sha->_obj.unit;
816 (**unk).Release (unk);
817 }
818
819 impl->_obj.link_status = _slang_link (&impl->_obj.prog, units, count);
820 if (impl->_obj.link_status)
821 impl->_obj._container._generic.info_log = _mesa_strdup ("Link OK.\n");
822 else
823 impl->_obj._container._generic.info_log = _mesa_strdup ("Link failed.\n");
824 #endif
825 }
826
827 static GLvoid
828 _program_Validate (struct gl2_program_intf **intf)
829 {
830 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
831
832 impl->_obj.validate_status = GL_FALSE;
833 _mesa_free ((void *) impl->_obj._container._generic.info_log);
834 impl->_obj._container._generic.info_log = NULL;
835
836 /* TODO validate */
837 }
838
839 static GLvoid
840 write_common_fixed (slang_program *pro, GLuint index, const GLvoid *src, GLuint off, GLuint size)
841 {
842 GLuint i;
843
844 for (i = 0; i < SLANG_SHADER_MAX; i++)
845 {
846 GLuint addr;
847
848 addr = pro->common_fixed_entries[i][index];
849 if (addr != ~0)
850 {
851 GLubyte *dst;
852
853 dst = (GLubyte *) pro->machines[i]->mem + addr + off * size;
854 _mesa_memcpy (dst, src, size);
855 }
856 }
857 }
858
859 static GLvoid
860 write_common_fixed_mat4 (slang_program *pro, GLmatrix *matrix, GLuint off, GLuint i, GLuint ii,
861 GLuint it, GLuint iit)
862 {
863 GLfloat mat[16];
864
865 /* we want inverse matrix */
866 if (!matrix->inv)
867 {
868 /* allocate inverse matrix and make it dirty */
869 _math_matrix_alloc_inv (matrix);
870 _math_matrix_loadf (matrix, matrix->m);
871 }
872 _math_matrix_analyse (matrix);
873
874 write_common_fixed (pro, i, matrix->m, off, 16 * sizeof (GLfloat));
875
876 /* inverse */
877 write_common_fixed (pro, ii, matrix->inv, off, 16 * sizeof (GLfloat));
878
879 /* transpose */
880 _math_transposef (mat, matrix->m);
881 write_common_fixed (pro, it, mat, off, 16 * sizeof (GLfloat));
882
883 /* inverse transpose */
884 _math_transposef (mat, matrix->inv);
885 write_common_fixed (pro, iit, mat, off, 16 * sizeof (GLfloat));
886 }
887
888 static GLvoid
889 write_common_fixed_material (GLcontext *ctx, slang_program *pro, GLuint i, GLuint e, GLuint a,
890 GLuint d, GLuint sp, GLuint sh)
891 {
892 GLfloat v[17];
893
894 COPY_4FV(v, ctx->Light.Material.Attrib[e]);
895 COPY_4FV((v + 4), ctx->Light.Material.Attrib[a]);
896 COPY_4FV((v + 8), ctx->Light.Material.Attrib[d]);
897 COPY_4FV((v + 12), ctx->Light.Material.Attrib[sp]);
898 v[16] = ctx->Light.Material.Attrib[sh][0];
899 write_common_fixed (pro, i, v, 0, 17 * sizeof (GLfloat));
900 }
901
902 static GLvoid
903 write_common_fixed_light_model_product (GLcontext *ctx, slang_program *pro, GLuint i, GLuint e,
904 GLuint a)
905 {
906 GLfloat v[4];
907
908 SCALE_4V(v, ctx->Light.Material.Attrib[a], ctx->Light.Model.Ambient);
909 ACC_4V(v, ctx->Light.Material.Attrib[e]);
910 write_common_fixed (pro, i, v, 0, 4 * sizeof (GLfloat));
911 }
912
913 static GLvoid
914 write_common_fixed_light_product (GLcontext *ctx, slang_program *pro, GLuint off, GLuint i, GLuint a,
915 GLuint d, GLuint s)
916 {
917 GLfloat v[12];
918
919 SCALE_4V(v, ctx->Light.Light[off].Ambient, ctx->Light.Material.Attrib[a]);
920 SCALE_4V((v + 4), ctx->Light.Light[off].Diffuse, ctx->Light.Material.Attrib[d]);
921 SCALE_4V((v + 8), ctx->Light.Light[off].Specular, ctx->Light.Material.Attrib[s]);
922 write_common_fixed (pro, i, v, off, 12 * sizeof (GLfloat));
923 }
924
925 static GLvoid
926 _program_UpdateFixedUniforms (struct gl2_program_intf **intf)
927 {
928 GET_CURRENT_CONTEXT(ctx);
929 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
930 slang_program *pro = &impl->_obj.prog;
931 GLuint i;
932 GLfloat v[29];
933 GLfloat *p;
934
935 /* MODELVIEW matrix */
936 write_common_fixed_mat4 (pro, ctx->ModelviewMatrixStack.Top, 0,
937 SLANG_COMMON_FIXED_MODELVIEWMATRIX,
938 SLANG_COMMON_FIXED_MODELVIEWMATRIXINVERSE,
939 SLANG_COMMON_FIXED_MODELVIEWMATRIXTRANSPOSE,
940 SLANG_COMMON_FIXED_MODELVIEWMATRIXINVERSETRANSPOSE);
941
942 /* PROJECTION matrix */
943 write_common_fixed_mat4 (pro, ctx->ProjectionMatrixStack.Top, 0,
944 SLANG_COMMON_FIXED_PROJECTIONMATRIX,
945 SLANG_COMMON_FIXED_PROJECTIONMATRIXINVERSE,
946 SLANG_COMMON_FIXED_PROJECTIONMATRIXTRANSPOSE,
947 SLANG_COMMON_FIXED_PROJECTIONMATRIXINVERSETRANSPOSE);
948
949 /* MVP matrix */
950 write_common_fixed_mat4 (pro, &ctx->_ModelProjectMatrix, 0,
951 SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIX,
952 SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIXINVERSE,
953 SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIXTRANSPOSE,
954 SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIXINVERSETRANSPOSE);
955
956 for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++)
957 {
958 /* TEXTURE matrix */
959 write_common_fixed_mat4 (pro, ctx->TextureMatrixStack[i].Top, i,
960 SLANG_COMMON_FIXED_TEXTUREMATRIX,
961 SLANG_COMMON_FIXED_TEXTUREMATRIXINVERSE,
962 SLANG_COMMON_FIXED_TEXTUREMATRIXTRANSPOSE,
963 SLANG_COMMON_FIXED_TEXTUREMATRIXINVERSETRANSPOSE);
964
965 /* EYE_PLANE texture-coordinate generation */
966 write_common_fixed (pro, SLANG_COMMON_FIXED_EYEPLANES, ctx->Texture.Unit[i].EyePlaneS,
967 i, 4 * sizeof (GLfloat));
968 write_common_fixed (pro, SLANG_COMMON_FIXED_EYEPLANET, ctx->Texture.Unit[i].EyePlaneT,
969 i, 4 * sizeof (GLfloat));
970 write_common_fixed (pro, SLANG_COMMON_FIXED_EYEPLANER, ctx->Texture.Unit[i].EyePlaneR,
971 i, 4 * sizeof (GLfloat));
972 write_common_fixed (pro, SLANG_COMMON_FIXED_EYEPLANEQ, ctx->Texture.Unit[i].EyePlaneQ,
973 i, 4 * sizeof (GLfloat));
974
975 /* OBJECT_PLANE texture-coordinate generation */
976 write_common_fixed (pro, SLANG_COMMON_FIXED_OBJECTPLANES, ctx->Texture.Unit[i].ObjectPlaneS,
977 i, 4 * sizeof (GLfloat));
978 write_common_fixed (pro, SLANG_COMMON_FIXED_OBJECTPLANET, ctx->Texture.Unit[i].ObjectPlaneT,
979 i, 4 * sizeof (GLfloat));
980 write_common_fixed (pro, SLANG_COMMON_FIXED_OBJECTPLANER, ctx->Texture.Unit[i].ObjectPlaneR,
981 i, 4 * sizeof (GLfloat));
982 write_common_fixed (pro, SLANG_COMMON_FIXED_OBJECTPLANEQ, ctx->Texture.Unit[i].ObjectPlaneQ,
983 i, 4 * sizeof (GLfloat));
984 }
985
986 /* NORMAL matrix - upper 3x3 inverse transpose of MODELVIEW matrix */
987 p = ctx->ModelviewMatrixStack.Top->inv;
988 v[0] = p[0];
989 v[1] = p[4];
990 v[2] = p[8];
991 v[3] = p[1];
992 v[4] = p[5];
993 v[5] = p[9];
994 v[6] = p[2];
995 v[7] = p[6];
996 v[8] = p[10];
997 write_common_fixed (pro, SLANG_COMMON_FIXED_NORMALMATRIX, v, 0, 9 * sizeof (GLfloat));
998
999 /* normal scale */
1000 write_common_fixed (pro, SLANG_COMMON_FIXED_NORMALSCALE, &ctx->_ModelViewInvScale, 0, sizeof (GLfloat));
1001
1002 /* depth range parameters */
1003 v[0] = ctx->Viewport.Near;
1004 v[1] = ctx->Viewport.Far;
1005 v[2] = ctx->Viewport.Far - ctx->Viewport.Near;
1006 write_common_fixed (pro, SLANG_COMMON_FIXED_DEPTHRANGE, v, 0, 3 * sizeof (GLfloat));
1007
1008 /* CLIP_PLANEi */
1009 for (i = 0; i < ctx->Const.MaxClipPlanes; i++)
1010 {
1011 write_common_fixed (pro, SLANG_COMMON_FIXED_CLIPPLANE, ctx->Transform.EyeUserPlane[i], i,
1012 4 * sizeof (GLfloat));
1013 }
1014
1015 /* point parameters */
1016 v[0] = ctx->Point.Size;
1017 v[1] = ctx->Point.MinSize;
1018 v[2] = ctx->Point.MaxSize;
1019 v[3] = ctx->Point.Threshold;
1020 COPY_3FV((v + 4), ctx->Point.Params);
1021 write_common_fixed (pro, SLANG_COMMON_FIXED_POINT, v, 0, 7 * sizeof (GLfloat));
1022
1023 /* material parameters */
1024 write_common_fixed_material (ctx, pro, SLANG_COMMON_FIXED_FRONTMATERIAL,
1025 MAT_ATTRIB_FRONT_EMISSION,
1026 MAT_ATTRIB_FRONT_AMBIENT,
1027 MAT_ATTRIB_FRONT_DIFFUSE,
1028 MAT_ATTRIB_FRONT_SPECULAR,
1029 MAT_ATTRIB_FRONT_SHININESS);
1030 write_common_fixed_material (ctx, pro, SLANG_COMMON_FIXED_BACKMATERIAL,
1031 MAT_ATTRIB_BACK_EMISSION,
1032 MAT_ATTRIB_BACK_AMBIENT,
1033 MAT_ATTRIB_BACK_DIFFUSE,
1034 MAT_ATTRIB_BACK_SPECULAR,
1035 MAT_ATTRIB_BACK_SHININESS);
1036
1037 for (i = 0; i < ctx->Const.MaxLights; i++)
1038 {
1039 /* light source parameters */
1040 COPY_4FV(v, ctx->Light.Light[i].Ambient);
1041 COPY_4FV((v + 4), ctx->Light.Light[i].Diffuse);
1042 COPY_4FV((v + 8), ctx->Light.Light[i].Specular);
1043 COPY_4FV((v + 12), ctx->Light.Light[i].EyePosition);
1044 COPY_2FV((v + 16), ctx->Light.Light[i].EyePosition);
1045 v[18] = ctx->Light.Light[i].EyePosition[2] + 1.0f;
1046 NORMALIZE_3FV((v + 16));
1047 v[19] = 0.0f;
1048 COPY_3V((v + 20), ctx->Light.Light[i].EyeDirection);
1049 v[23] = ctx->Light.Light[i].SpotExponent;
1050 v[24] = ctx->Light.Light[i].SpotCutoff;
1051 v[25] = ctx->Light.Light[i]._CosCutoffNeg;
1052 v[26] = ctx->Light.Light[i].ConstantAttenuation;
1053 v[27] = ctx->Light.Light[i].LinearAttenuation;
1054 v[28] = ctx->Light.Light[i].QuadraticAttenuation;
1055 write_common_fixed (pro, SLANG_COMMON_FIXED_LIGHTSOURCE, v, i, 29 * sizeof (GLfloat));
1056
1057 /* light product */
1058 write_common_fixed_light_product (ctx, pro, i, SLANG_COMMON_FIXED_FRONTLIGHTPRODUCT,
1059 MAT_ATTRIB_FRONT_AMBIENT,
1060 MAT_ATTRIB_FRONT_DIFFUSE,
1061 MAT_ATTRIB_FRONT_SPECULAR);
1062 write_common_fixed_light_product (ctx, pro, i, SLANG_COMMON_FIXED_BACKLIGHTPRODUCT,
1063 MAT_ATTRIB_BACK_AMBIENT,
1064 MAT_ATTRIB_BACK_DIFFUSE,
1065 MAT_ATTRIB_BACK_SPECULAR);
1066 }
1067
1068 /* light model parameters */
1069 write_common_fixed (pro, SLANG_COMMON_FIXED_LIGHTMODEL, ctx->Light.Model.Ambient, 0, 4 * sizeof (GLfloat));
1070
1071 /* light model product */
1072 write_common_fixed_light_model_product (ctx, pro, SLANG_COMMON_FIXED_FRONTLIGHTMODELPRODUCT,
1073 MAT_ATTRIB_FRONT_EMISSION,
1074 MAT_ATTRIB_FRONT_AMBIENT);
1075 write_common_fixed_light_model_product (ctx, pro, SLANG_COMMON_FIXED_BACKLIGHTMODELPRODUCT,
1076 MAT_ATTRIB_BACK_EMISSION,
1077 MAT_ATTRIB_BACK_AMBIENT);
1078
1079 /* TEXTURE_ENV_COLOR */
1080 for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++)
1081 {
1082 write_common_fixed (pro, SLANG_COMMON_FIXED_TEXTUREENVCOLOR, ctx->Texture.Unit[i].EnvColor,
1083 i, 4 * sizeof (GLfloat));
1084 }
1085
1086 /* fog parameters */
1087 COPY_4FV(v, ctx->Fog.Color);
1088 v[4] = ctx->Fog.Density;
1089 v[5] = ctx->Fog.Start;
1090 v[6] = ctx->Fog.End;
1091 v[7] = ctx->Fog._Scale;
1092 write_common_fixed (pro, SLANG_COMMON_FIXED_FOG, v, 0, 8 * sizeof (GLfloat));
1093 }
1094
1095 static GLvoid
1096 _program_UpdateFixedAttribute (struct gl2_program_intf **intf, GLuint index, GLvoid *data,
1097 GLuint offset, GLuint size, GLboolean write)
1098 {
1099 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
1100 slang_program *pro = &impl->_obj.prog;
1101 GLuint addr;
1102
1103 addr = pro->vertex_fixed_entries[index];
1104 if (addr != ~0)
1105 {
1106 GLubyte *mem;
1107
1108 mem = (GLubyte *) pro->machines[SLANG_SHADER_VERTEX]->mem + addr + offset * size;
1109 if (write)
1110 _mesa_memcpy (mem, data, size);
1111 else
1112 _mesa_memcpy (data, mem, size);
1113 }
1114 }
1115
1116 static GLvoid
1117 _program_UpdateFixedVarying (struct gl2_program_intf **intf, GLuint index, GLvoid *data,
1118 GLuint offset, GLuint size, GLboolean write)
1119 {
1120 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
1121 slang_program *pro = &impl->_obj.prog;
1122 GLuint addr;
1123
1124 addr = pro->fragment_fixed_entries[index];
1125 if (addr != ~0)
1126 {
1127 GLubyte *mem;
1128
1129 mem = (GLubyte *) pro->machines[SLANG_SHADER_FRAGMENT]->mem + addr + offset * size;
1130 if (write)
1131 _mesa_memcpy (mem, data, size);
1132 else
1133 _mesa_memcpy (data, mem, size);
1134 }
1135 }
1136
1137 static GLvoid
1138 _program_GetTextureImageUsage (struct gl2_program_intf **intf, GLbitfield *teximageusage)
1139 {
1140 GET_CURRENT_CONTEXT(ctx);
1141 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
1142 slang_program *pro = &impl->_obj.prog;
1143 GLuint i;
1144
1145 for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++)
1146 teximageusage[i] = 0;
1147
1148 for (i = 0; i < pro->texture_usage.count; i++)
1149 {
1150 GLuint n, addr, j;
1151
1152 n = pro->texture_usage.table[i].quant->array_len;
1153 if (n == 0)
1154 n = 1;
1155 addr = pro->texture_usage.table[i].frag_address;
1156 for (j = 0; j < n; j++)
1157 {
1158 GLubyte *mem;
1159 GLuint image;
1160
1161 mem = (GLubyte *) pro->machines[SLANG_SHADER_FRAGMENT]->mem + addr + j * 4;
1162 image = (GLuint) *((GLfloat *) mem);
1163 if (image >= 0 && image < ctx->Const.MaxTextureImageUnits)
1164 {
1165 switch (pro->texture_usage.table[i].quant->u.basic_type)
1166 {
1167 case GL_SAMPLER_1D_ARB:
1168 case GL_SAMPLER_1D_SHADOW_ARB:
1169 teximageusage[image] |= TEXTURE_1D_BIT;
1170 break;
1171 case GL_SAMPLER_2D_ARB:
1172 case GL_SAMPLER_2D_SHADOW_ARB:
1173 teximageusage[image] |= TEXTURE_2D_BIT;
1174 break;
1175 case GL_SAMPLER_3D_ARB:
1176 teximageusage[image] |= TEXTURE_3D_BIT;
1177 break;
1178 case GL_SAMPLER_CUBE_ARB:
1179 teximageusage[image] |= TEXTURE_CUBE_BIT;
1180 break;
1181 }
1182 }
1183 }
1184 }
1185
1186 /* TODO: make sure that for 0<=i<=MaxTextureImageUint bitcount(teximageuint[i])<=0 */
1187 }
1188
1189 static GLboolean
1190 _program_IsShaderPresent (struct gl2_program_intf **intf, GLenum subtype)
1191 {
1192 GET_CURRENT_CONTEXT(ctx);
1193 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
1194 slang_program *pro = &impl->_obj.prog;
1195
1196 switch (subtype)
1197 {
1198 case GL_VERTEX_SHADER_ARB:
1199 return pro->machines[SLANG_SHADER_VERTEX] != NULL;
1200 case GL_FRAGMENT_SHADER_ARB:
1201 return pro->machines[SLANG_SHADER_FRAGMENT] != NULL;
1202 default:
1203 return GL_FALSE;
1204 }
1205 }
1206
1207 static struct gl2_program_intf _program_vftbl = {
1208 {
1209 {
1210 {
1211 _unknown_AddRef,
1212 _unknown_Release,
1213 _program_QueryInterface
1214 },
1215 _generic_Delete,
1216 _program_GetType,
1217 _generic_GetName,
1218 _generic_GetDeleteStatus,
1219 _generic_GetInfoLog
1220 },
1221 _program_Attach,
1222 _container_Detach,
1223 _container_GetAttachedCount,
1224 _container_GetAttached
1225 },
1226 _program_GetLinkStatus,
1227 _program_GetValidateStatus,
1228 _program_Link,
1229 _program_Validate,
1230 _program_UpdateFixedUniforms,
1231 _program_UpdateFixedAttribute,
1232 _program_UpdateFixedVarying,
1233 _program_GetTextureImageUsage,
1234 _program_IsShaderPresent
1235 };
1236
1237 static void
1238 _program_constructor (struct gl2_program_impl *impl)
1239 {
1240 _container_constructor ((struct gl2_container_impl *) impl);
1241 impl->_vftbl = &_program_vftbl;
1242 impl->_obj._container._generic._unknown._destructor = _program_destructor;
1243 impl->_obj.link_status = GL_FALSE;
1244 impl->_obj.validate_status = GL_FALSE;
1245 #if USE_3DLABS_FRONTEND
1246 impl->_obj.linker = ShConstructLinker (EShExVertexFragment, 0);
1247 impl->_obj.uniforms = ShConstructUniformMap ();
1248 #endif
1249 slang_program_ctr (&impl->_obj.prog);
1250 }
1251
1252 struct gl2_fragment_shader_obj
1253 {
1254 struct gl2_shader_obj _shader;
1255 };
1256
1257 struct gl2_fragment_shader_impl
1258 {
1259 struct gl2_fragment_shader_intf *_vftbl;
1260 struct gl2_fragment_shader_obj _obj;
1261 };
1262
1263 static void
1264 _fragment_shader_destructor (struct gl2_unknown_intf **intf)
1265 {
1266 struct gl2_fragment_shader_impl *impl = (struct gl2_fragment_shader_impl *) intf;
1267
1268 (void) impl;
1269 /* TODO free fragment shader data */
1270
1271 _shader_destructor (intf);
1272 }
1273
1274 static struct gl2_unknown_intf **
1275 _fragment_shader_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
1276 {
1277 if (uiid == UIID_FRAGMENT_SHADER)
1278 {
1279 (**intf).AddRef (intf);
1280 return intf;
1281 }
1282 return _shader_QueryInterface (intf, uiid);
1283 }
1284
1285 static GLenum
1286 _fragment_shader_GetSubType (struct gl2_shader_intf **intf)
1287 {
1288 return GL_FRAGMENT_SHADER_ARB;
1289 }
1290
1291 static struct gl2_fragment_shader_intf _fragment_shader_vftbl = {
1292 {
1293 {
1294 {
1295 _unknown_AddRef,
1296 _unknown_Release,
1297 _fragment_shader_QueryInterface
1298 },
1299 _generic_Delete,
1300 _shader_GetType,
1301 _generic_GetName,
1302 _generic_GetDeleteStatus,
1303 _generic_GetInfoLog
1304 },
1305 _fragment_shader_GetSubType,
1306 _shader_GetCompileStatus,
1307 _shader_SetSource,
1308 _shader_GetSource,
1309 _shader_Compile
1310 }
1311 };
1312
1313 static void
1314 _fragment_shader_constructor (struct gl2_fragment_shader_impl *impl)
1315 {
1316 _shader_constructor ((struct gl2_shader_impl *) impl);
1317 impl->_vftbl = &_fragment_shader_vftbl;
1318 impl->_obj._shader._generic._unknown._destructor = _fragment_shader_destructor;
1319 #if USE_3DLABS_FRONTEND
1320 impl->_obj._shader._3dlabs_shhandle._obj.handle = ShConstructCompiler (EShLangFragment, 0);
1321 #endif
1322 }
1323
1324 struct gl2_vertex_shader_obj
1325 {
1326 struct gl2_shader_obj _shader;
1327 };
1328
1329 struct gl2_vertex_shader_impl
1330 {
1331 struct gl2_vertex_shader_intf *_vftbl;
1332 struct gl2_vertex_shader_obj _obj;
1333 };
1334
1335 static void
1336 _vertex_shader_destructor (struct gl2_unknown_intf **intf)
1337 {
1338 struct gl2_vertex_shader_impl *impl = (struct gl2_vertex_shader_impl *) intf;
1339
1340 (void) impl;
1341 /* TODO free vertex shader data */
1342
1343 _shader_destructor (intf);
1344 }
1345
1346 static struct gl2_unknown_intf **
1347 _vertex_shader_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
1348 {
1349 if (uiid == UIID_VERTEX_SHADER)
1350 {
1351 (**intf).AddRef (intf);
1352 return intf;
1353 }
1354 return _shader_QueryInterface (intf, uiid);
1355 }
1356
1357 static GLenum
1358 _vertex_shader_GetSubType (struct gl2_shader_intf **intf)
1359 {
1360 return GL_VERTEX_SHADER_ARB;
1361 }
1362
1363 static struct gl2_vertex_shader_intf _vertex_shader_vftbl = {
1364 {
1365 {
1366 {
1367 _unknown_AddRef,
1368 _unknown_Release,
1369 _vertex_shader_QueryInterface
1370 },
1371 _generic_Delete,
1372 _shader_GetType,
1373 _generic_GetName,
1374 _generic_GetDeleteStatus,
1375 _generic_GetInfoLog
1376 },
1377 _vertex_shader_GetSubType,
1378 _shader_GetCompileStatus,
1379 _shader_SetSource,
1380 _shader_GetSource,
1381 _shader_Compile
1382 }
1383 };
1384
1385 static void
1386 _vertex_shader_constructor (struct gl2_vertex_shader_impl *impl)
1387 {
1388 _shader_constructor ((struct gl2_shader_impl *) impl);
1389 impl->_vftbl = &_vertex_shader_vftbl;
1390 impl->_obj._shader._generic._unknown._destructor = _vertex_shader_destructor;
1391 #if USE_3DLABS_FRONTEND
1392 impl->_obj._shader._3dlabs_shhandle._obj.handle = ShConstructCompiler (EShLangVertex, 0);
1393 #endif
1394 }
1395
1396 GLhandleARB
1397 _mesa_3dlabs_create_shader_object (GLenum shaderType)
1398 {
1399 switch (shaderType)
1400 {
1401 case GL_FRAGMENT_SHADER_ARB:
1402 {
1403 struct gl2_fragment_shader_impl *x = (struct gl2_fragment_shader_impl *)
1404 _mesa_malloc (sizeof (struct gl2_fragment_shader_impl));
1405
1406 if (x != NULL)
1407 {
1408 _fragment_shader_constructor (x);
1409 return x->_obj._shader._generic.name;
1410 }
1411 }
1412 break;
1413 case GL_VERTEX_SHADER_ARB:
1414 {
1415 struct gl2_vertex_shader_impl *x = (struct gl2_vertex_shader_impl *)
1416 _mesa_malloc (sizeof (struct gl2_vertex_shader_impl));
1417
1418 if (x != NULL)
1419 {
1420 _vertex_shader_constructor (x);
1421 return x->_obj._shader._generic.name;
1422 }
1423 }
1424 break;
1425 }
1426
1427 return 0;
1428 }
1429
1430 GLhandleARB
1431 _mesa_3dlabs_create_program_object (void)
1432 {
1433 struct gl2_program_impl *x = (struct gl2_program_impl *)
1434 _mesa_malloc (sizeof (struct gl2_program_impl));
1435
1436 if (x != NULL)
1437 {
1438 _program_constructor (x);
1439 return x->_obj._container._generic.name;
1440 }
1441
1442 return 0;
1443 }
1444
1445 #include "slang_assemble.h"
1446 #include "slang_execute.h"
1447
1448 int _slang_fetch_discard (struct gl2_program_intf **pro, GLboolean *val)
1449 {
1450 struct gl2_program_impl *impl;
1451
1452 impl = (struct gl2_program_impl *) pro;
1453 *val = impl->_obj.prog.machines[SLANG_SHADER_FRAGMENT]->kill ? GL_TRUE : GL_FALSE;
1454 return 1;
1455 }
1456
1457 static GLvoid exec_shader (struct gl2_program_intf **pro, GLuint i)
1458 {
1459 struct gl2_program_impl *impl;
1460 slang_program *p;
1461
1462 impl = (struct gl2_program_impl *) pro;
1463 p = &impl->_obj.prog;
1464
1465 slang_machine_init (p->machines[i]);
1466 p->machines[i]->ip = p->code[i][SLANG_COMMON_CODE_MAIN];
1467
1468 _slang_execute2 (p->assemblies[i], p->machines[i]);
1469 }
1470
1471 GLvoid _slang_exec_fragment_shader (struct gl2_program_intf **pro)
1472 {
1473 exec_shader (pro, SLANG_SHADER_FRAGMENT);
1474 }
1475
1476 GLvoid _slang_exec_vertex_shader (struct gl2_program_intf **pro)
1477 {
1478 exec_shader (pro, SLANG_SHADER_VERTEX);
1479 }
1480
1481 GLint _slang_get_uniform_location (struct gl2_program_intf **pro, const char *name)
1482 {
1483 struct gl2_program_impl *impl;
1484 slang_uniform_bindings *bind;
1485 GLuint i;
1486
1487 impl = (struct gl2_program_impl *) pro;
1488 bind = &impl->_obj.prog.uniforms;
1489 for (i = 0; i < bind->count; i++)
1490 if (_mesa_strcmp (bind->table[i].name, name) == 0)
1491 return i;
1492 return -1;
1493 }
1494
1495 GLboolean _slang_write_uniform (struct gl2_program_intf **pro, GLint loc, GLsizei count,
1496 const GLvoid *data, GLenum type)
1497 {
1498 struct gl2_program_impl *impl;
1499 slang_uniform_bindings *bind;
1500 slang_uniform_binding *b;
1501 GLuint i;
1502 GLboolean convert_float_to_bool = GL_FALSE;
1503 GLboolean convert_int_to_bool = GL_FALSE;
1504 GLboolean convert_int_to_float = GL_FALSE;
1505 GLboolean types_match = GL_FALSE;
1506
1507 if (loc == -1)
1508 return GL_TRUE;
1509
1510 impl = (struct gl2_program_impl *) pro;
1511 bind = &impl->_obj.prog.uniforms;
1512 if (loc >= bind->count)
1513 return GL_FALSE;
1514
1515 b = &bind->table[loc];
1516 /* TODO: check sizes */
1517 if (b->quant->structure != NULL)
1518 return GL_FALSE;
1519
1520 switch (b->quant->u.basic_type)
1521 {
1522 case GL_BOOL_ARB:
1523 types_match = (type == GL_FLOAT) || (type == GL_INT);
1524 if (type == GL_FLOAT)
1525 convert_float_to_bool = GL_TRUE;
1526 else
1527 convert_int_to_bool = GL_TRUE;
1528 break;
1529 case GL_BOOL_VEC2_ARB:
1530 types_match = (type == GL_FLOAT_VEC2_ARB) || (type == GL_INT_VEC2_ARB);
1531 if (type == GL_FLOAT_VEC2_ARB)
1532 convert_float_to_bool = GL_TRUE;
1533 else
1534 convert_int_to_bool = GL_TRUE;
1535 break;
1536 case GL_BOOL_VEC3_ARB:
1537 types_match = (type == GL_FLOAT_VEC3_ARB) || (type == GL_INT_VEC3_ARB);
1538 if (type == GL_FLOAT_VEC3_ARB)
1539 convert_float_to_bool = GL_TRUE;
1540 else
1541 convert_int_to_bool = GL_TRUE;
1542 break;
1543 case GL_BOOL_VEC4_ARB:
1544 types_match = (type == GL_FLOAT_VEC4_ARB) || (type == GL_INT_VEC4_ARB);
1545 if (type == GL_FLOAT_VEC4_ARB)
1546 convert_float_to_bool = GL_TRUE;
1547 else
1548 convert_int_to_bool = GL_TRUE;
1549 break;
1550 case GL_SAMPLER_1D_ARB:
1551 case GL_SAMPLER_2D_ARB:
1552 case GL_SAMPLER_3D_ARB:
1553 case GL_SAMPLER_CUBE_ARB:
1554 case GL_SAMPLER_1D_SHADOW_ARB:
1555 case GL_SAMPLER_2D_SHADOW_ARB:
1556 types_match = (type == GL_INT);
1557 break;
1558 default:
1559 types_match = (type == b->quant->u.basic_type);
1560 break;
1561 }
1562
1563 if (!types_match)
1564 return GL_FALSE;
1565
1566 switch (type)
1567 {
1568 case GL_INT:
1569 case GL_INT_VEC2_ARB:
1570 case GL_INT_VEC3_ARB:
1571 case GL_INT_VEC4_ARB:
1572 convert_int_to_float = GL_TRUE;
1573 break;
1574 }
1575
1576 if (convert_float_to_bool)
1577 {
1578 for (i = 0; i < SLANG_SHADER_MAX; i++)
1579 if (b->address[i] != ~0)
1580 {
1581 const GLfloat *src = (GLfloat *) (data);
1582 GLfloat *dst = (GLfloat *) (&impl->_obj.prog.machines[i]->mem[b->address[i] / 4]);
1583 GLuint j;
1584
1585 for (j = 0; j < count * b->quant->size / 4; j++)
1586 dst[j] = src[j] != 0.0f ? 1.0f : 0.0f;
1587 }
1588 }
1589 else if (convert_int_to_bool)
1590 {
1591 for (i = 0; i < SLANG_SHADER_MAX; i++)
1592 if (b->address[i] != ~0)
1593 {
1594 const GLuint *src = (GLuint *) (data);
1595 GLfloat *dst = (GLfloat *) (&impl->_obj.prog.machines[i]->mem[b->address[i] / 4]);
1596 GLuint j;
1597
1598 for (j = 0; j < count * b->quant->size / 4; j++)
1599 dst[j] = src[j] ? 1.0f : 0.0f;
1600 }
1601 }
1602 else if (convert_int_to_float)
1603 {
1604 for (i = 0; i < SLANG_SHADER_MAX; i++)
1605 if (b->address[i] != ~0)
1606 {
1607 const GLuint *src = (GLuint *) (data);
1608 GLfloat *dst = (GLfloat *) (&impl->_obj.prog.machines[i]->mem[b->address[i] / 4]);
1609 GLuint j;
1610
1611 for (j = 0; j < count * b->quant->size / 4; j++)
1612 dst[j] = (GLfloat) src[j];
1613 }
1614 }
1615 else
1616 {
1617 for (i = 0; i < SLANG_SHADER_MAX; i++)
1618 if (b->address[i] != ~0)
1619 {
1620 _mesa_memcpy (&impl->_obj.prog.machines[i]->mem[b->address[i] / 4], data,
1621 count * b->quant->size);
1622 }
1623 }
1624 return GL_TRUE;
1625 }
1626
1627 GLuint _slang_get_active_uniform_count (struct gl2_program_intf **pro)
1628 {
1629 struct gl2_program_impl *impl;
1630
1631 impl = (struct gl2_program_impl *) pro;
1632 return impl->_obj.prog.active_uniforms.count;
1633 }
1634
1635 GLuint _slang_get_active_uniform_max_length (struct gl2_program_intf **pro)
1636 {
1637 struct gl2_program_impl *impl;
1638 GLuint i, len = 0;
1639
1640 impl = (struct gl2_program_impl *) pro;
1641 for (i = 0; i < impl->_obj.prog.active_uniforms.count; i++)
1642 {
1643 GLuint n = _mesa_strlen (impl->_obj.prog.active_uniforms.table[i].name);
1644 if (n > len)
1645 len = n;
1646 }
1647 return len;
1648 }
1649
1650 GLvoid _slang_get_active_uniform (struct gl2_program_intf **pro, GLuint index, GLsizei maxLength,
1651 GLsizei *length, GLint *size, GLenum *type, char *name)
1652 {
1653 struct gl2_program_impl *impl;
1654 slang_active_uniform *u;
1655 GLsizei len;
1656
1657 impl = (struct gl2_program_impl *) pro;
1658 u = &impl->_obj.prog.active_uniforms.table[index];
1659
1660 len = _mesa_strlen (u->name);
1661 if (len >= maxLength)
1662 len = maxLength - 1;
1663 _mesa_memcpy (name, u->name, len);
1664 name[len] = '\0';
1665 if (length != NULL)
1666 *length = len;
1667 *type = u->quant->u.basic_type;
1668 if (u->quant->array_len == 0)
1669 *size = 1;
1670 else
1671 *size = u->quant->array_len;
1672 }
1673
1674 void
1675 _mesa_init_shaderobjects_3dlabs (GLcontext *ctx)
1676 {
1677 #if USE_3DLABS_FRONTEND
1678 _glslang_3dlabs_InitProcess ();
1679 _glslang_3dlabs_ShInitialize ();
1680 #endif
1681 }
1682