Add GetInfoLogLength and WriteAttrib functions.
[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 GLvoid
232 _generic_GetInfoLog (struct gl2_generic_intf **intf, GLsizei maxlen, GLcharARB *infolog)
233 {
234 struct gl2_generic_impl *impl = (struct gl2_generic_impl *) (intf);
235
236 if (maxlen > 0) {
237 _mesa_strncpy (infolog, impl->_obj.info_log, maxlen - 1);
238 infolog[maxlen - 1] = '\0';
239 }
240 }
241
242 static GLsizei
243 _generic_GetInfoLogLength (struct gl2_generic_intf **intf)
244 {
245 struct gl2_generic_impl *impl = (struct gl2_generic_impl *) (intf);
246
247 if (impl->_obj.info_log == NULL)
248 return 1;
249 return _mesa_strlen (impl->_obj.info_log) + 1;
250 }
251
252 static struct gl2_generic_intf _generic_vftbl = {
253 {
254 _unknown_AddRef,
255 _unknown_Release,
256 _generic_QueryInterface
257 },
258 _generic_Delete,
259 NULL, /* abstract GetType */
260 _generic_GetName,
261 _generic_GetDeleteStatus,
262 _generic_GetInfoLog,
263 _generic_GetInfoLogLength
264 };
265
266 static void
267 _generic_constructor (struct gl2_generic_impl *impl)
268 {
269 GET_CURRENT_CONTEXT(ctx);
270
271 _unknown_constructor ((struct gl2_unknown_impl *) impl);
272 impl->_vftbl = &_generic_vftbl;
273 impl->_obj._unknown._destructor = _generic_destructor;
274 impl->_obj.delete_status = GL_FALSE;
275 impl->_obj.info_log = NULL;
276
277 _glthread_LOCK_MUTEX (ctx->Shared->Mutex);
278 impl->_obj.name = _mesa_HashFindFreeKeyBlock (ctx->Shared->GL2Objects, 1);
279 _mesa_HashInsert (ctx->Shared->GL2Objects, impl->_obj.name, (void *) impl);
280 _glthread_UNLOCK_MUTEX (ctx->Shared->Mutex);
281 }
282
283 struct gl2_container_obj
284 {
285 struct gl2_generic_obj _generic;
286 struct gl2_generic_intf ***attached;
287 GLuint attached_count;
288 };
289
290 struct gl2_container_impl
291 {
292 struct gl2_container_intf *_vftbl;
293 struct gl2_container_obj _obj;
294 };
295
296 static void
297 _container_destructor (struct gl2_unknown_intf **intf)
298 {
299 struct gl2_container_impl *impl = (struct gl2_container_impl *) intf;
300 GLuint i;
301
302 for (i = 0; i < impl->_obj.attached_count; i++)
303 {
304 struct gl2_generic_intf **x = impl->_obj.attached[i];
305 (**x)._unknown.Release ((struct gl2_unknown_intf **) x);
306 }
307
308 _generic_destructor (intf);
309 }
310
311 static struct gl2_unknown_intf **
312 _container_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
313 {
314 if (uiid == UIID_CONTAINER)
315 {
316 (**intf).AddRef (intf);
317 return intf;
318 }
319 return _generic_QueryInterface (intf, uiid);
320 }
321
322 static GLboolean
323 _container_Attach (struct gl2_container_intf **intf, struct gl2_generic_intf **att)
324 {
325 GET_CURRENT_CONTEXT(ctx);
326 struct gl2_container_impl *impl = (struct gl2_container_impl *) intf;
327 GLuint i;
328
329 for (i = 0; i < impl->_obj.attached_count; i++)
330 if (impl->_obj.attached[i] == att)
331 {
332 _mesa_error (ctx, GL_INVALID_OPERATION, "_container_Attach");
333 return GL_FALSE;
334 }
335
336 impl->_obj.attached = (struct gl2_generic_intf ***) _mesa_realloc (impl->_obj.attached,
337 impl->_obj.attached_count * sizeof (*impl->_obj.attached), (impl->_obj.attached_count + 1) *
338 sizeof (*impl->_obj.attached));
339 if (impl->_obj.attached == NULL)
340 return GL_FALSE;
341
342 impl->_obj.attached[impl->_obj.attached_count] = att;
343 impl->_obj.attached_count++;
344 (**att)._unknown.AddRef ((struct gl2_unknown_intf **) att);
345 return GL_TRUE;
346 }
347
348 static GLboolean
349 _container_Detach (struct gl2_container_intf **intf, struct gl2_generic_intf **att)
350 {
351 GET_CURRENT_CONTEXT(ctx);
352 struct gl2_container_impl *impl = (struct gl2_container_impl *) intf;
353 GLuint i, j;
354
355 for (i = 0; i < impl->_obj.attached_count; i++)
356 if (impl->_obj.attached[i] == att)
357 {
358 for (j = i; j < impl->_obj.attached_count - 1; j++)
359 impl->_obj.attached[j] = impl->_obj.attached[j + 1];
360 impl->_obj.attached = (struct gl2_generic_intf ***) _mesa_realloc (impl->_obj.attached,
361 impl->_obj.attached_count * sizeof (*impl->_obj.attached),
362 (impl->_obj.attached_count - 1) * sizeof (*impl->_obj.attached));
363 impl->_obj.attached_count--;
364 (**att)._unknown.Release ((struct gl2_unknown_intf **) att);
365 return GL_TRUE;
366 }
367
368 _mesa_error (ctx, GL_INVALID_OPERATION, "_container_Detach");
369 return GL_FALSE;
370 }
371
372 static GLsizei
373 _container_GetAttachedCount (struct gl2_container_intf **intf)
374 {
375 struct gl2_container_impl *impl = (struct gl2_container_impl *) intf;
376
377 return impl->_obj.attached_count;
378 }
379
380 static struct gl2_generic_intf **
381 _container_GetAttached (struct gl2_container_intf **intf, GLuint index)
382 {
383 struct gl2_container_impl *impl = (struct gl2_container_impl *) intf;
384
385 (**impl->_obj.attached[index])._unknown.AddRef (
386 (struct gl2_unknown_intf **)impl->_obj.attached[index]);
387 return impl->_obj.attached[index];
388 }
389
390 static struct gl2_container_intf _container_vftbl = {
391 {
392 {
393 _unknown_AddRef,
394 _unknown_Release,
395 _container_QueryInterface
396 },
397 _generic_Delete,
398 NULL, /* abstract GetType */
399 _generic_GetName,
400 _generic_GetDeleteStatus,
401 _generic_GetInfoLog,
402 _generic_GetInfoLogLength
403 },
404 _container_Attach,
405 _container_Detach,
406 _container_GetAttachedCount,
407 _container_GetAttached
408 };
409
410 static void
411 _container_constructor (struct gl2_container_impl *impl)
412 {
413 _generic_constructor ((struct gl2_generic_impl *) impl);
414 impl->_vftbl = &_container_vftbl;
415 impl->_obj._generic._unknown._destructor = _container_destructor;
416 impl->_obj.attached = NULL;
417 impl->_obj.attached_count = 0;
418 }
419
420 struct gl2_3dlabs_shhandle_obj
421 {
422 struct gl2_unkinner_obj _unknown;
423 #if USE_3DLABS_FRONTEND
424 ShHandle handle;
425 #endif
426 };
427
428 struct gl2_3dlabs_shhandle_impl
429 {
430 struct gl2_3dlabs_shhandle_intf *_vftbl;
431 struct gl2_3dlabs_shhandle_obj _obj;
432 };
433
434 static void
435 _3dlabs_shhandle_destructor (struct gl2_unknown_intf **intf)
436 {
437 #if USE_3DLABS_FRONTEND
438 struct gl2_3dlabs_shhandle_impl *impl = (struct gl2_3dlabs_shhandle_impl *) intf;
439 ShDestruct (impl->_obj.handle);
440 #endif
441 _unkinner_destructor (intf);
442 }
443
444 static GLvoid *
445 _3dlabs_shhandle_GetShHandle (struct gl2_3dlabs_shhandle_intf **intf)
446 {
447 #if USE_3DLABS_FRONTEND
448 struct gl2_3dlabs_shhandle_impl *impl = (struct gl2_3dlabs_shhandle_impl *) intf;
449 return impl->_obj.handle;
450 #else
451 return NULL;
452 #endif
453 }
454
455 static struct gl2_3dlabs_shhandle_intf _3dlabs_shhandle_vftbl = {
456 {
457 _unkinner_AddRef,
458 _unkinner_Release,
459 _unkinner_QueryInterface
460 },
461 _3dlabs_shhandle_GetShHandle
462 };
463
464 static void
465 _3dlabs_shhandle_constructor (struct gl2_3dlabs_shhandle_impl *impl, struct gl2_unknown_intf **outer)
466 {
467 _unkinner_constructor ((struct gl2_unkinner_impl *) impl, outer);
468 impl->_vftbl = &_3dlabs_shhandle_vftbl;
469 #if USE_3DLABS_FRONTEND
470 impl->_obj.handle = NULL;
471 #endif
472 }
473
474 struct gl2_shader_obj
475 {
476 struct gl2_generic_obj _generic;
477 struct gl2_3dlabs_shhandle_impl _3dlabs_shhandle;
478 GLboolean compile_status;
479 GLcharARB *source;
480 GLint *offsets;
481 GLsizei offset_count;
482 slang_code_object code;
483 };
484
485 struct gl2_shader_impl
486 {
487 struct gl2_shader_intf *_vftbl;
488 struct gl2_shader_obj _obj;
489 };
490
491 static void
492 _shader_destructor (struct gl2_unknown_intf **intf)
493 {
494 struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
495
496 _mesa_free ((void *) impl->_obj.source);
497 _mesa_free ((void *) impl->_obj.offsets);
498 _slang_code_object_dtr (&impl->_obj.code);
499 _3dlabs_shhandle_destructor ((struct gl2_unknown_intf **) &impl->_obj._3dlabs_shhandle._vftbl);
500 _generic_destructor (intf);
501 }
502
503 static struct gl2_unknown_intf **
504 _shader_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
505 {
506 #if USE_3DLABS_FRONTEND
507 struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
508 #endif
509
510 if (uiid == UIID_SHADER)
511 {
512 (**intf).AddRef (intf);
513 return intf;
514 }
515 #if USE_3DLABS_FRONTEND
516 if (uiid == UIID_3DLABS_SHHANDLE)
517 {
518 (**intf).AddRef (intf);
519 return (struct gl2_unknown_intf **) &impl->_obj._3dlabs_shhandle._vftbl;
520 }
521 #endif
522 return _generic_QueryInterface (intf, uiid);
523 }
524
525 static GLenum
526 _shader_GetType (struct gl2_generic_intf **intf)
527 {
528 return GL_SHADER_OBJECT_ARB;
529 }
530
531 static GLvoid
532 _shader_GetInfoLog (struct gl2_generic_intf **intf, GLsizei maxlen, GLcharARB *infolog)
533 {
534 struct gl2_shader_impl *impl = (struct gl2_shader_impl *) (intf);
535
536 if (maxlen > 0) {
537 if (impl->_obj._generic.info_log != NULL) {
538 GLsizei len = _mesa_strlen (impl->_obj._generic.info_log);
539 if (len > maxlen - 1)
540 len = maxlen - 1;
541 _mesa_memcpy (infolog, impl->_obj._generic.info_log, len);
542 infolog += len;
543 maxlen -= len;
544 }
545 if (impl->_obj.code.machine.infolog != NULL &&
546 impl->_obj.code.machine.infolog->text != NULL) {
547 GLsizei len = _mesa_strlen (impl->_obj.code.machine.infolog->text);
548 if (len > maxlen - 1)
549 len = maxlen - 1;
550 _mesa_memcpy (infolog, impl->_obj.code.machine.infolog->text, len);
551 }
552 infolog[maxlen - 1] = '\0';
553 }
554 }
555
556 static GLsizei
557 _shader_GetInfoLogLength (struct gl2_generic_intf **intf)
558 {
559 struct gl2_shader_impl *impl = (struct gl2_shader_impl *) (intf);
560 GLsizei length = 1;
561
562 if (impl->_obj._generic.info_log != NULL)
563 length += _mesa_strlen (impl->_obj._generic.info_log);
564 if (impl->_obj.code.machine.infolog != NULL &&
565 impl->_obj.code.machine.infolog->text != NULL)
566 length += _mesa_strlen (impl->_obj.code.machine.infolog->text);
567 return length;
568 }
569
570 static GLboolean
571 _shader_GetCompileStatus (struct gl2_shader_intf **intf)
572 {
573 struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
574
575 return impl->_obj.compile_status;
576 }
577
578 static GLvoid
579 _shader_SetSource (struct gl2_shader_intf **intf, GLcharARB *src, GLint *off, GLsizei cnt)
580 {
581 struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
582
583 _mesa_free ((void *) impl->_obj.source);
584 impl->_obj.source = src;
585 _mesa_free ((void *) impl->_obj.offsets);
586 impl->_obj.offsets = off;
587 impl->_obj.offset_count = cnt;
588 }
589
590 static const GLcharARB *
591 _shader_GetSource (struct gl2_shader_intf **intf)
592 {
593 struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
594
595 return impl->_obj.source;
596 }
597
598 static GLvoid
599 _shader_Compile (struct gl2_shader_intf **intf)
600 {
601 struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
602 #if USE_3DLABS_FRONTEND
603 char **strings;
604 TBuiltInResource res;
605 #else
606 slang_unit_type type;
607 slang_info_log info_log;
608 #endif
609
610 impl->_obj.compile_status = GL_FALSE;
611 _mesa_free ((void *) impl->_obj._generic.info_log);
612 impl->_obj._generic.info_log = NULL;
613
614 #if USE_3DLABS_FRONTEND
615 /* 3dlabs compiler expects us to feed it with null-terminated string array,
616 we've got only one big string with offsets, so we must split it; but when
617 there's only one string to deal with, we pass its address directly */
618
619 if (impl->_obj.offset_count <= 1)
620 strings = &impl->_obj.source;
621 else
622 {
623 GLsizei i, offset = 0;
624
625 strings = (char **) _mesa_malloc (impl->_obj.offset_count * sizeof (char *));
626 if (strings == NULL)
627 return;
628
629 for (i = 0; i < impl->_obj.offset_count; i++)
630 {
631 GLsizei size = impl->_obj.offsets[i] - offset;
632
633 strings[i] = (char *) _mesa_malloc ((size + 1) * sizeof (char));
634 if (strings[i] == NULL)
635 {
636 GLsizei j;
637
638 for (j = 0; j < i; j++)
639 _mesa_free (strings[j]);
640 _mesa_free (strings);
641 return;
642 }
643
644 _mesa_memcpy (strings[i], impl->_obj.source + offset, size * sizeof (char));
645 strings[i][size] = '\0';
646 offset = impl->_obj.offsets[i];
647 }
648 }
649
650 /* TODO set these fields to some REAL numbers */
651 res.maxLights = 8;
652 res.maxClipPlanes = 6;
653 res.maxTextureUnits = 2;
654 res.maxTextureCoords = 2;
655 res.maxVertexAttribs = 8;
656 res.maxVertexUniformComponents = 64;
657 res.maxVaryingFloats = 8;
658 res.maxVertexTextureImageUnits = 2;
659 res.maxCombinedTextureImageUnits = 2;
660 res.maxTextureImageUnits = 2;
661 res.maxFragmentUniformComponents = 64;
662 res.maxDrawBuffers = 1;
663
664 if (ShCompile (impl->_obj._3dlabs_shhandle._obj.handle, strings, impl->_obj.offset_count,
665 EShOptFull, &res, 0))
666 impl->_obj.compile_status = GL_TRUE;
667 if (impl->_obj.offset_count > 1)
668 {
669 GLsizei i;
670
671 for (i = 0; i < impl->_obj.offset_count; i++)
672 _mesa_free (strings[i]);
673 _mesa_free (strings);
674 }
675
676 impl->_obj._generic.info_log = _mesa_strdup (ShGetInfoLog (
677 impl->_obj._3dlabs_shhandle._obj.handle));
678 #else
679 if (impl->_vftbl->GetSubType (intf) == GL_FRAGMENT_SHADER)
680 type = slang_unit_fragment_shader;
681 else
682 type = slang_unit_vertex_shader;
683 slang_info_log_construct (&info_log);
684 if (_slang_compile (impl->_obj.source, &impl->_obj.code, type, &info_log))
685 impl->_obj.compile_status = GL_TRUE;
686 if (info_log.text != NULL)
687 impl->_obj._generic.info_log = _mesa_strdup (info_log.text);
688 else if (impl->_obj.compile_status)
689 impl->_obj._generic.info_log = _mesa_strdup ("Compile OK.\n");
690 else
691 impl->_obj._generic.info_log = _mesa_strdup ("Compile failed.\n");
692 slang_info_log_destruct (&info_log);
693 #endif
694 }
695
696 static struct gl2_shader_intf _shader_vftbl = {
697 {
698 {
699 _unknown_AddRef,
700 _unknown_Release,
701 _shader_QueryInterface
702 },
703 _generic_Delete,
704 _shader_GetType,
705 _generic_GetName,
706 _generic_GetDeleteStatus,
707 _shader_GetInfoLog,
708 _shader_GetInfoLogLength
709 },
710 NULL, /* abstract GetSubType */
711 _shader_GetCompileStatus,
712 _shader_SetSource,
713 _shader_GetSource,
714 _shader_Compile
715 };
716
717 static void
718 _shader_constructor (struct gl2_shader_impl *impl)
719 {
720 _generic_constructor ((struct gl2_generic_impl *) impl);
721 _3dlabs_shhandle_constructor (&impl->_obj._3dlabs_shhandle, (struct gl2_unknown_intf **)
722 &impl->_vftbl);
723 impl->_vftbl = &_shader_vftbl;
724 impl->_obj._generic._unknown._destructor = _shader_destructor;
725 impl->_obj.compile_status = GL_FALSE;
726 impl->_obj.source = NULL;
727 impl->_obj.offsets = NULL;
728 impl->_obj.offset_count = 0;
729 _slang_code_object_ctr (&impl->_obj.code);
730 }
731
732 struct gl2_program_obj
733 {
734 struct gl2_container_obj _container;
735 GLboolean link_status;
736 GLboolean validate_status;
737 #if USE_3DLABS_FRONTEND
738 ShHandle linker;
739 ShHandle uniforms;
740 #endif
741 slang_program prog;
742 };
743
744 struct gl2_program_impl
745 {
746 struct gl2_program_intf *_vftbl;
747 struct gl2_program_obj _obj;
748 };
749
750 static void
751 _program_destructor (struct gl2_unknown_intf **intf)
752 {
753 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
754 #if USE_3DLABS_FRONTEND
755 ShDestruct (impl->_obj.linker);
756 ShDestruct (impl->_obj.uniforms);
757 #endif
758 _container_destructor (intf);
759 slang_program_dtr (&impl->_obj.prog);
760 }
761
762 static struct gl2_unknown_intf **
763 _program_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
764 {
765 if (uiid == UIID_PROGRAM)
766 {
767 (**intf).AddRef (intf);
768 return intf;
769 }
770 return _container_QueryInterface (intf, uiid);
771 }
772
773 static GLenum
774 _program_GetType (struct gl2_generic_intf **intf)
775 {
776 return GL_PROGRAM_OBJECT_ARB;
777 }
778
779 static GLboolean
780 _program_Attach (struct gl2_container_intf **intf, struct gl2_generic_intf **att)
781 {
782 GET_CURRENT_CONTEXT(ctx);
783 struct gl2_unknown_intf **sha;
784
785 sha = (**att)._unknown.QueryInterface ((struct gl2_unknown_intf **) att, UIID_SHADER);
786 if (sha == NULL)
787 {
788 _mesa_error (ctx, GL_INVALID_OPERATION, "_program_Attach");
789 return GL_FALSE;
790 }
791
792 (**sha).Release (sha);
793 return _container_Attach (intf, att);
794 }
795
796 static GLboolean
797 _program_GetLinkStatus (struct gl2_program_intf **intf)
798 {
799 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
800
801 return impl->_obj.link_status;
802 }
803
804 static GLboolean
805 _program_GetValidateStatus (struct gl2_program_intf **intf)
806 {
807 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
808
809 return impl->_obj.validate_status;
810 }
811
812 static GLvoid
813 _program_Link (struct gl2_program_intf **intf)
814 {
815 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
816 #if USE_3DLABS_FRONTEND
817 ShHandle *handles;
818 #endif
819 GLuint i, count;
820 slang_code_object *code[2];
821 GLboolean all_compiled = GL_TRUE;
822
823 impl->_obj.link_status = GL_FALSE;
824 _mesa_free ((void *) impl->_obj._container._generic.info_log);
825 impl->_obj._container._generic.info_log = NULL;
826 slang_program_rst (&impl->_obj.prog);
827
828 #if USE_3DLABS_FRONTEND
829 handles = (ShHandle *) _mesa_malloc (impl->_obj._container.attached_count * sizeof (ShHandle));
830 if (handles == NULL)
831 return;
832
833 for (i = 0; i < impl->_obj._container.attached_count; i++)
834 {
835 struct gl2_generic_intf **gen = impl->_obj._container.attached[i];
836 struct gl2_3dlabs_shhandle_intf **sh;
837
838 sh = (struct gl2_3dlabs_shhandle_intf **) (**gen)._unknown.QueryInterface (
839 (struct gl2_unknown_intf **) gen, UIID_3DLABS_SHHANDLE);
840 if (sh != NULL)
841 {
842 handles[i] = (**sh).GetShHandle (sh);
843 (**sh)._unknown.Release ((struct gl2_unknown_intf **) sh);
844 }
845 else
846 {
847 _mesa_free (handles);
848 return;
849 }
850 }
851
852 if (ShLink (impl->_obj.linker, handles, impl->_obj._container.attached_count,
853 impl->_obj.uniforms, NULL, NULL))
854 impl->_obj.link_status = GL_TRUE;
855
856 impl->_obj._container._generic.info_log = _mesa_strdup (ShGetInfoLog (impl->_obj.linker));
857 #else
858 count = impl->_obj._container.attached_count;
859 if (count > 2)
860 return;
861 for (i = 0; i < count; i++)
862 {
863 struct gl2_generic_intf **obj;
864 struct gl2_unknown_intf **unk;
865 struct gl2_shader_impl *sha;
866
867 obj = impl->_obj._container.attached[i];
868 unk = (**obj)._unknown.QueryInterface ((struct gl2_unknown_intf **) obj, UIID_SHADER);
869 if (unk == NULL)
870 return;
871 sha = (struct gl2_shader_impl *) unk;
872 code[i] = &sha->_obj.code;
873 all_compiled = all_compiled && sha->_obj.compile_status;
874 (**unk).Release (unk);
875 }
876
877 impl->_obj.link_status = all_compiled;
878 if (!impl->_obj.link_status)
879 {
880 impl->_obj._container._generic.info_log = _mesa_strdup (
881 "Error: One or more shaders has not successfully compiled.\n");
882 return;
883 }
884
885 impl->_obj.link_status = _slang_link (&impl->_obj.prog, code, count);
886 if (!impl->_obj.link_status)
887 {
888 impl->_obj._container._generic.info_log = _mesa_strdup ("Link failed.\n");
889 return;
890 }
891
892 impl->_obj._container._generic.info_log = _mesa_strdup ("Link OK.\n");
893 #endif
894 }
895
896 static GLvoid
897 _program_Validate (struct gl2_program_intf **intf)
898 {
899 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
900
901 impl->_obj.validate_status = GL_FALSE;
902 _mesa_free ((void *) impl->_obj._container._generic.info_log);
903 impl->_obj._container._generic.info_log = NULL;
904
905 /* TODO validate */
906 }
907
908 static GLvoid
909 write_common_fixed (slang_program *pro, GLuint index, const GLvoid *src, GLuint off, GLuint size)
910 {
911 GLuint i;
912
913 for (i = 0; i < SLANG_SHADER_MAX; i++)
914 {
915 GLuint addr;
916
917 addr = pro->common_fixed_entries[i][index];
918 if (addr != ~0)
919 {
920 GLubyte *dst;
921
922 dst = (GLubyte *) pro->machines[i]->mem + addr + off * size;
923 _mesa_memcpy (dst, src, size);
924 }
925 }
926 }
927
928 static GLvoid
929 write_common_fixed_mat4 (slang_program *pro, GLmatrix *matrix, GLuint off, GLuint i, GLuint ii,
930 GLuint it, GLuint iit)
931 {
932 GLfloat mat[16];
933
934 /* we want inverse matrix */
935 if (!matrix->inv)
936 {
937 /* allocate inverse matrix and make it dirty */
938 _math_matrix_alloc_inv (matrix);
939 _math_matrix_loadf (matrix, matrix->m);
940 }
941 _math_matrix_analyse (matrix);
942
943 write_common_fixed (pro, i, matrix->m, off, 16 * sizeof (GLfloat));
944
945 /* inverse */
946 write_common_fixed (pro, ii, matrix->inv, off, 16 * sizeof (GLfloat));
947
948 /* transpose */
949 _math_transposef (mat, matrix->m);
950 write_common_fixed (pro, it, mat, off, 16 * sizeof (GLfloat));
951
952 /* inverse transpose */
953 _math_transposef (mat, matrix->inv);
954 write_common_fixed (pro, iit, mat, off, 16 * sizeof (GLfloat));
955 }
956
957 static GLvoid
958 write_common_fixed_material (GLcontext *ctx, slang_program *pro, GLuint i, GLuint e, GLuint a,
959 GLuint d, GLuint sp, GLuint sh)
960 {
961 GLfloat v[17];
962
963 COPY_4FV(v, ctx->Light.Material.Attrib[e]);
964 COPY_4FV((v + 4), ctx->Light.Material.Attrib[a]);
965 COPY_4FV((v + 8), ctx->Light.Material.Attrib[d]);
966 COPY_4FV((v + 12), ctx->Light.Material.Attrib[sp]);
967 v[16] = ctx->Light.Material.Attrib[sh][0];
968 write_common_fixed (pro, i, v, 0, 17 * sizeof (GLfloat));
969 }
970
971 static GLvoid
972 write_common_fixed_light_model_product (GLcontext *ctx, slang_program *pro, GLuint i, GLuint e,
973 GLuint a)
974 {
975 GLfloat v[4];
976
977 SCALE_4V(v, ctx->Light.Material.Attrib[a], ctx->Light.Model.Ambient);
978 ACC_4V(v, ctx->Light.Material.Attrib[e]);
979 write_common_fixed (pro, i, v, 0, 4 * sizeof (GLfloat));
980 }
981
982 static GLvoid
983 write_common_fixed_light_product (GLcontext *ctx, slang_program *pro, GLuint off, GLuint i, GLuint a,
984 GLuint d, GLuint s)
985 {
986 GLfloat v[12];
987
988 SCALE_4V(v, ctx->Light.Light[off].Ambient, ctx->Light.Material.Attrib[a]);
989 SCALE_4V((v + 4), ctx->Light.Light[off].Diffuse, ctx->Light.Material.Attrib[d]);
990 SCALE_4V((v + 8), ctx->Light.Light[off].Specular, ctx->Light.Material.Attrib[s]);
991 write_common_fixed (pro, i, v, off, 12 * sizeof (GLfloat));
992 }
993
994 static GLvoid
995 _program_UpdateFixedUniforms (struct gl2_program_intf **intf)
996 {
997 GET_CURRENT_CONTEXT(ctx);
998 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
999 slang_program *pro = &impl->_obj.prog;
1000 GLuint i;
1001 GLfloat v[29];
1002 GLfloat *p;
1003
1004 /* MODELVIEW matrix */
1005 write_common_fixed_mat4 (pro, ctx->ModelviewMatrixStack.Top, 0,
1006 SLANG_COMMON_FIXED_MODELVIEWMATRIX,
1007 SLANG_COMMON_FIXED_MODELVIEWMATRIXINVERSE,
1008 SLANG_COMMON_FIXED_MODELVIEWMATRIXTRANSPOSE,
1009 SLANG_COMMON_FIXED_MODELVIEWMATRIXINVERSETRANSPOSE);
1010
1011 /* PROJECTION matrix */
1012 write_common_fixed_mat4 (pro, ctx->ProjectionMatrixStack.Top, 0,
1013 SLANG_COMMON_FIXED_PROJECTIONMATRIX,
1014 SLANG_COMMON_FIXED_PROJECTIONMATRIXINVERSE,
1015 SLANG_COMMON_FIXED_PROJECTIONMATRIXTRANSPOSE,
1016 SLANG_COMMON_FIXED_PROJECTIONMATRIXINVERSETRANSPOSE);
1017
1018 /* MVP matrix */
1019 write_common_fixed_mat4 (pro, &ctx->_ModelProjectMatrix, 0,
1020 SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIX,
1021 SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIXINVERSE,
1022 SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIXTRANSPOSE,
1023 SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIXINVERSETRANSPOSE);
1024
1025 for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++)
1026 {
1027 /* TEXTURE matrix */
1028 write_common_fixed_mat4 (pro, ctx->TextureMatrixStack[i].Top, i,
1029 SLANG_COMMON_FIXED_TEXTUREMATRIX,
1030 SLANG_COMMON_FIXED_TEXTUREMATRIXINVERSE,
1031 SLANG_COMMON_FIXED_TEXTUREMATRIXTRANSPOSE,
1032 SLANG_COMMON_FIXED_TEXTUREMATRIXINVERSETRANSPOSE);
1033
1034 /* EYE_PLANE texture-coordinate generation */
1035 write_common_fixed (pro, SLANG_COMMON_FIXED_EYEPLANES, ctx->Texture.Unit[i].EyePlaneS,
1036 i, 4 * sizeof (GLfloat));
1037 write_common_fixed (pro, SLANG_COMMON_FIXED_EYEPLANET, ctx->Texture.Unit[i].EyePlaneT,
1038 i, 4 * sizeof (GLfloat));
1039 write_common_fixed (pro, SLANG_COMMON_FIXED_EYEPLANER, ctx->Texture.Unit[i].EyePlaneR,
1040 i, 4 * sizeof (GLfloat));
1041 write_common_fixed (pro, SLANG_COMMON_FIXED_EYEPLANEQ, ctx->Texture.Unit[i].EyePlaneQ,
1042 i, 4 * sizeof (GLfloat));
1043
1044 /* OBJECT_PLANE texture-coordinate generation */
1045 write_common_fixed (pro, SLANG_COMMON_FIXED_OBJECTPLANES, ctx->Texture.Unit[i].ObjectPlaneS,
1046 i, 4 * sizeof (GLfloat));
1047 write_common_fixed (pro, SLANG_COMMON_FIXED_OBJECTPLANET, ctx->Texture.Unit[i].ObjectPlaneT,
1048 i, 4 * sizeof (GLfloat));
1049 write_common_fixed (pro, SLANG_COMMON_FIXED_OBJECTPLANER, ctx->Texture.Unit[i].ObjectPlaneR,
1050 i, 4 * sizeof (GLfloat));
1051 write_common_fixed (pro, SLANG_COMMON_FIXED_OBJECTPLANEQ, ctx->Texture.Unit[i].ObjectPlaneQ,
1052 i, 4 * sizeof (GLfloat));
1053 }
1054
1055 /* NORMAL matrix - upper 3x3 inverse transpose of MODELVIEW matrix */
1056 p = ctx->ModelviewMatrixStack.Top->inv;
1057 v[0] = p[0];
1058 v[1] = p[4];
1059 v[2] = p[8];
1060 v[3] = p[1];
1061 v[4] = p[5];
1062 v[5] = p[9];
1063 v[6] = p[2];
1064 v[7] = p[6];
1065 v[8] = p[10];
1066 write_common_fixed (pro, SLANG_COMMON_FIXED_NORMALMATRIX, v, 0, 9 * sizeof (GLfloat));
1067
1068 /* normal scale */
1069 write_common_fixed (pro, SLANG_COMMON_FIXED_NORMALSCALE, &ctx->_ModelViewInvScale, 0, sizeof (GLfloat));
1070
1071 /* depth range parameters */
1072 v[0] = ctx->Viewport.Near;
1073 v[1] = ctx->Viewport.Far;
1074 v[2] = ctx->Viewport.Far - ctx->Viewport.Near;
1075 write_common_fixed (pro, SLANG_COMMON_FIXED_DEPTHRANGE, v, 0, 3 * sizeof (GLfloat));
1076
1077 /* CLIP_PLANEi */
1078 for (i = 0; i < ctx->Const.MaxClipPlanes; i++)
1079 {
1080 write_common_fixed (pro, SLANG_COMMON_FIXED_CLIPPLANE, ctx->Transform.EyeUserPlane[i], i,
1081 4 * sizeof (GLfloat));
1082 }
1083
1084 /* point parameters */
1085 v[0] = ctx->Point.Size;
1086 v[1] = ctx->Point.MinSize;
1087 v[2] = ctx->Point.MaxSize;
1088 v[3] = ctx->Point.Threshold;
1089 COPY_3FV((v + 4), ctx->Point.Params);
1090 write_common_fixed (pro, SLANG_COMMON_FIXED_POINT, v, 0, 7 * sizeof (GLfloat));
1091
1092 /* material parameters */
1093 write_common_fixed_material (ctx, pro, SLANG_COMMON_FIXED_FRONTMATERIAL,
1094 MAT_ATTRIB_FRONT_EMISSION,
1095 MAT_ATTRIB_FRONT_AMBIENT,
1096 MAT_ATTRIB_FRONT_DIFFUSE,
1097 MAT_ATTRIB_FRONT_SPECULAR,
1098 MAT_ATTRIB_FRONT_SHININESS);
1099 write_common_fixed_material (ctx, pro, SLANG_COMMON_FIXED_BACKMATERIAL,
1100 MAT_ATTRIB_BACK_EMISSION,
1101 MAT_ATTRIB_BACK_AMBIENT,
1102 MAT_ATTRIB_BACK_DIFFUSE,
1103 MAT_ATTRIB_BACK_SPECULAR,
1104 MAT_ATTRIB_BACK_SHININESS);
1105
1106 for (i = 0; i < ctx->Const.MaxLights; i++)
1107 {
1108 /* light source parameters */
1109 COPY_4FV(v, ctx->Light.Light[i].Ambient);
1110 COPY_4FV((v + 4), ctx->Light.Light[i].Diffuse);
1111 COPY_4FV((v + 8), ctx->Light.Light[i].Specular);
1112 COPY_4FV((v + 12), ctx->Light.Light[i].EyePosition);
1113 COPY_2FV((v + 16), ctx->Light.Light[i].EyePosition);
1114 v[18] = ctx->Light.Light[i].EyePosition[2] + 1.0f;
1115 NORMALIZE_3FV((v + 16));
1116 v[19] = 0.0f;
1117 COPY_3V((v + 20), ctx->Light.Light[i].EyeDirection);
1118 v[23] = ctx->Light.Light[i].SpotExponent;
1119 v[24] = ctx->Light.Light[i].SpotCutoff;
1120 v[25] = ctx->Light.Light[i]._CosCutoffNeg;
1121 v[26] = ctx->Light.Light[i].ConstantAttenuation;
1122 v[27] = ctx->Light.Light[i].LinearAttenuation;
1123 v[28] = ctx->Light.Light[i].QuadraticAttenuation;
1124 write_common_fixed (pro, SLANG_COMMON_FIXED_LIGHTSOURCE, v, i, 29 * sizeof (GLfloat));
1125
1126 /* light product */
1127 write_common_fixed_light_product (ctx, pro, i, SLANG_COMMON_FIXED_FRONTLIGHTPRODUCT,
1128 MAT_ATTRIB_FRONT_AMBIENT,
1129 MAT_ATTRIB_FRONT_DIFFUSE,
1130 MAT_ATTRIB_FRONT_SPECULAR);
1131 write_common_fixed_light_product (ctx, pro, i, SLANG_COMMON_FIXED_BACKLIGHTPRODUCT,
1132 MAT_ATTRIB_BACK_AMBIENT,
1133 MAT_ATTRIB_BACK_DIFFUSE,
1134 MAT_ATTRIB_BACK_SPECULAR);
1135 }
1136
1137 /* light model parameters */
1138 write_common_fixed (pro, SLANG_COMMON_FIXED_LIGHTMODEL, ctx->Light.Model.Ambient, 0, 4 * sizeof (GLfloat));
1139
1140 /* light model product */
1141 write_common_fixed_light_model_product (ctx, pro, SLANG_COMMON_FIXED_FRONTLIGHTMODELPRODUCT,
1142 MAT_ATTRIB_FRONT_EMISSION,
1143 MAT_ATTRIB_FRONT_AMBIENT);
1144 write_common_fixed_light_model_product (ctx, pro, SLANG_COMMON_FIXED_BACKLIGHTMODELPRODUCT,
1145 MAT_ATTRIB_BACK_EMISSION,
1146 MAT_ATTRIB_BACK_AMBIENT);
1147
1148 /* TEXTURE_ENV_COLOR */
1149 for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++)
1150 {
1151 write_common_fixed (pro, SLANG_COMMON_FIXED_TEXTUREENVCOLOR, ctx->Texture.Unit[i].EnvColor,
1152 i, 4 * sizeof (GLfloat));
1153 }
1154
1155 /* fog parameters */
1156 COPY_4FV(v, ctx->Fog.Color);
1157 v[4] = ctx->Fog.Density;
1158 v[5] = ctx->Fog.Start;
1159 v[6] = ctx->Fog.End;
1160 v[7] = ctx->Fog._Scale;
1161 write_common_fixed (pro, SLANG_COMMON_FIXED_FOG, v, 0, 8 * sizeof (GLfloat));
1162 }
1163
1164 static GLvoid
1165 _program_UpdateFixedAttrib (struct gl2_program_intf **intf, GLuint index, GLvoid *data,
1166 GLuint offset, GLuint size, GLboolean write)
1167 {
1168 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
1169 slang_program *pro = &impl->_obj.prog;
1170 GLuint addr;
1171
1172 addr = pro->vertex_fixed_entries[index];
1173 if (addr != ~0)
1174 {
1175 GLubyte *mem;
1176
1177 mem = (GLubyte *) pro->machines[SLANG_SHADER_VERTEX]->mem + addr + offset * size;
1178 if (write)
1179 _mesa_memcpy (mem, data, size);
1180 else
1181 _mesa_memcpy (data, mem, size);
1182 }
1183 }
1184
1185 static GLvoid
1186 _program_UpdateFixedVarying (struct gl2_program_intf **intf, GLuint index, GLvoid *data,
1187 GLuint offset, GLuint size, GLboolean write)
1188 {
1189 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
1190 slang_program *pro = &impl->_obj.prog;
1191 GLuint addr;
1192
1193 addr = pro->fragment_fixed_entries[index];
1194 if (addr != ~0)
1195 {
1196 GLubyte *mem;
1197
1198 mem = (GLubyte *) pro->machines[SLANG_SHADER_FRAGMENT]->mem + addr + offset * size;
1199 if (write)
1200 _mesa_memcpy (mem, data, size);
1201 else
1202 _mesa_memcpy (data, mem, size);
1203 }
1204 }
1205
1206 static GLvoid
1207 _program_GetTextureImageUsage (struct gl2_program_intf **intf, GLbitfield *teximageusage)
1208 {
1209 GET_CURRENT_CONTEXT(ctx);
1210 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
1211 slang_program *pro = &impl->_obj.prog;
1212 GLuint i;
1213
1214 for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++)
1215 teximageusage[i] = 0;
1216
1217 for (i = 0; i < pro->texture_usage.count; i++)
1218 {
1219 GLuint n, addr, j;
1220
1221 n = slang_export_data_quant_elements (pro->texture_usage.table[i].quant);
1222 addr = pro->texture_usage.table[i].frag_address;
1223 for (j = 0; j < n; j++)
1224 {
1225 GLubyte *mem;
1226 GLuint image;
1227
1228 mem = (GLubyte *) pro->machines[SLANG_SHADER_FRAGMENT]->mem + addr + j * 4;
1229 image = (GLuint) *((GLfloat *) mem);
1230 if (image >= 0 && image < ctx->Const.MaxTextureImageUnits)
1231 {
1232 switch (slang_export_data_quant_type (pro->texture_usage.table[i].quant))
1233 {
1234 case GL_SAMPLER_1D_ARB:
1235 case GL_SAMPLER_1D_SHADOW_ARB:
1236 teximageusage[image] |= TEXTURE_1D_BIT;
1237 break;
1238 case GL_SAMPLER_2D_ARB:
1239 case GL_SAMPLER_2D_SHADOW_ARB:
1240 teximageusage[image] |= TEXTURE_2D_BIT;
1241 break;
1242 case GL_SAMPLER_3D_ARB:
1243 teximageusage[image] |= TEXTURE_3D_BIT;
1244 break;
1245 case GL_SAMPLER_CUBE_ARB:
1246 teximageusage[image] |= TEXTURE_CUBE_BIT;
1247 break;
1248 }
1249 }
1250 }
1251 }
1252
1253 /* TODO: make sure that for 0<=i<=MaxTextureImageUint bitcount(teximageuint[i])<=0 */
1254 }
1255
1256 static GLboolean
1257 _program_IsShaderPresent (struct gl2_program_intf **intf, GLenum subtype)
1258 {
1259 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
1260 slang_program *pro = &impl->_obj.prog;
1261
1262 switch (subtype)
1263 {
1264 case GL_VERTEX_SHADER_ARB:
1265 return pro->machines[SLANG_SHADER_VERTEX] != NULL;
1266 case GL_FRAGMENT_SHADER_ARB:
1267 return pro->machines[SLANG_SHADER_FRAGMENT] != NULL;
1268 default:
1269 return GL_FALSE;
1270 }
1271 }
1272
1273 static GLvoid
1274 get_active_variable (slang_active_variable *var, GLsizei maxLength, GLsizei *length, GLint *size,
1275 GLenum *type, GLchar *name)
1276 {
1277 GLsizei len;
1278
1279 len = _mesa_strlen (var->name);
1280 if (len >= maxLength)
1281 len = maxLength - 1;
1282 if (length != NULL)
1283 *length = len;
1284 *size = slang_export_data_quant_elements (var->quant);
1285 *type = slang_export_data_quant_type (var->quant);
1286 _mesa_memcpy (name, var->name, len);
1287 name[len] = '\0';
1288 }
1289
1290 static GLuint
1291 get_active_variable_max_length (slang_active_variables *vars)
1292 {
1293 GLuint i, len = 0;
1294
1295 for (i = 0; i < vars->count; i++)
1296 {
1297 GLuint n = _mesa_strlen (vars->table[i].name);
1298 if (n > len)
1299 len = n;
1300 }
1301 return len;
1302 }
1303
1304 static GLvoid
1305 _program_GetActiveUniform (struct gl2_program_intf **intf, GLuint index, GLsizei maxLength,
1306 GLsizei *length, GLint *size, GLenum *type, GLchar *name)
1307 {
1308 struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf);
1309 slang_active_variable *u = &impl->_obj.prog.active_uniforms.table[index];
1310
1311 get_active_variable (u, maxLength, length, size, type, name);
1312 }
1313
1314 static GLuint
1315 _program_GetActiveUniformMaxLength (struct gl2_program_intf **intf)
1316 {
1317 struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf);
1318
1319 return get_active_variable_max_length (&impl->_obj.prog.active_uniforms);
1320 }
1321
1322 static GLuint
1323 _program_GetActiveUniformCount (struct gl2_program_intf **intf)
1324 {
1325 struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf);
1326
1327 return impl->_obj.prog.active_uniforms.count;
1328 }
1329
1330 static GLint
1331 _program_GetUniformLocation (struct gl2_program_intf **intf, const GLchar *name)
1332 {
1333 struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf);
1334 slang_uniform_bindings *bind = &impl->_obj.prog.uniforms;
1335 GLuint i;
1336
1337 for (i = 0; i < bind->count; i++)
1338 if (_mesa_strcmp (bind->table[i].name, name) == 0)
1339 return i;
1340 return -1;
1341 }
1342
1343 static GLboolean
1344 _program_WriteUniform (struct gl2_program_intf **intf, GLint loc, GLsizei count, const GLvoid *data,
1345 GLenum type)
1346 {
1347 struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf);
1348 slang_uniform_bindings *uniforms = &impl->_obj.prog.uniforms;
1349 slang_uniform_binding *uniform;
1350 GLuint i;
1351 GLboolean convert_float_to_bool = GL_FALSE;
1352 GLboolean convert_int_to_bool = GL_FALSE;
1353 GLboolean convert_int_to_float = GL_FALSE;
1354 GLboolean types_match = GL_FALSE;
1355
1356 if (loc == -1)
1357 return GL_TRUE;
1358 if (loc >= uniforms->count)
1359 return GL_FALSE;
1360
1361 uniform = &uniforms->table[loc];
1362 /* TODO: check sizes */
1363 if (slang_export_data_quant_struct (uniform->quant))
1364 return GL_FALSE;
1365
1366 switch (slang_export_data_quant_type (uniform->quant))
1367 {
1368 case GL_BOOL_ARB:
1369 types_match = (type == GL_FLOAT) || (type == GL_INT);
1370 if (type == GL_FLOAT)
1371 convert_float_to_bool = GL_TRUE;
1372 else
1373 convert_int_to_bool = GL_TRUE;
1374 break;
1375 case GL_BOOL_VEC2_ARB:
1376 types_match = (type == GL_FLOAT_VEC2_ARB) || (type == GL_INT_VEC2_ARB);
1377 if (type == GL_FLOAT_VEC2_ARB)
1378 convert_float_to_bool = GL_TRUE;
1379 else
1380 convert_int_to_bool = GL_TRUE;
1381 break;
1382 case GL_BOOL_VEC3_ARB:
1383 types_match = (type == GL_FLOAT_VEC3_ARB) || (type == GL_INT_VEC3_ARB);
1384 if (type == GL_FLOAT_VEC3_ARB)
1385 convert_float_to_bool = GL_TRUE;
1386 else
1387 convert_int_to_bool = GL_TRUE;
1388 break;
1389 case GL_BOOL_VEC4_ARB:
1390 types_match = (type == GL_FLOAT_VEC4_ARB) || (type == GL_INT_VEC4_ARB);
1391 if (type == GL_FLOAT_VEC4_ARB)
1392 convert_float_to_bool = GL_TRUE;
1393 else
1394 convert_int_to_bool = GL_TRUE;
1395 break;
1396 case GL_SAMPLER_1D_ARB:
1397 case GL_SAMPLER_2D_ARB:
1398 case GL_SAMPLER_3D_ARB:
1399 case GL_SAMPLER_CUBE_ARB:
1400 case GL_SAMPLER_1D_SHADOW_ARB:
1401 case GL_SAMPLER_2D_SHADOW_ARB:
1402 types_match = (type == GL_INT);
1403 break;
1404 default:
1405 types_match = (type == slang_export_data_quant_type (uniform->quant));
1406 break;
1407 }
1408
1409 if (!types_match)
1410 return GL_FALSE;
1411
1412 switch (type)
1413 {
1414 case GL_INT:
1415 case GL_INT_VEC2_ARB:
1416 case GL_INT_VEC3_ARB:
1417 case GL_INT_VEC4_ARB:
1418 convert_int_to_float = GL_TRUE;
1419 break;
1420 }
1421
1422 if (convert_float_to_bool)
1423 {
1424 for (i = 0; i < SLANG_SHADER_MAX; i++)
1425 if (uniform->address[i] != ~0)
1426 {
1427 const GLfloat *src = (GLfloat *) (data);
1428 GLfloat *dst = (GLfloat *)
1429 (&impl->_obj.prog.machines[i]->mem[uniform->address[i] / 4]);
1430 GLuint j;
1431 GLuint total = count * slang_export_data_quant_components (uniform->quant);
1432
1433 for (j = 0; j < total; j++)
1434 dst[j] = src[j] != 0.0f ? 1.0f : 0.0f;
1435 }
1436 }
1437 else if (convert_int_to_bool)
1438 {
1439 for (i = 0; i < SLANG_SHADER_MAX; i++)
1440 if (uniform->address[i] != ~0)
1441 {
1442 const GLuint *src = (GLuint *) (data);
1443 GLfloat *dst = (GLfloat *)
1444 (&impl->_obj.prog.machines[i]->mem[uniform->address[i] / 4]);
1445 GLuint j;
1446 GLuint total = count * slang_export_data_quant_components (uniform->quant);
1447
1448 for (j = 0; j < total; j++)
1449 dst[j] = src[j] ? 1.0f : 0.0f;
1450 }
1451 }
1452 else if (convert_int_to_float)
1453 {
1454 for (i = 0; i < SLANG_SHADER_MAX; i++)
1455 if (uniform->address[i] != ~0)
1456 {
1457 const GLuint *src = (GLuint *) (data);
1458 GLfloat *dst = (GLfloat *)
1459 (&impl->_obj.prog.machines[i]->mem[uniform->address[i] / 4]);
1460 GLuint j;
1461 GLuint total = count * slang_export_data_quant_components (uniform->quant);
1462
1463 for (j = 0; j < total; j++)
1464 dst[j] = (GLfloat) src[j];
1465 }
1466 }
1467 else
1468 {
1469 for (i = 0; i < SLANG_SHADER_MAX; i++)
1470 if (uniform->address[i] != ~0)
1471 {
1472 _mesa_memcpy (&impl->_obj.prog.machines[i]->mem[uniform->address[i] / 4], data,
1473 count * slang_export_data_quant_size (uniform->quant));
1474 }
1475 }
1476 return GL_TRUE;
1477 }
1478
1479 static GLvoid
1480 _program_GetActiveAttrib (struct gl2_program_intf **intf, GLuint index, GLsizei maxLength,
1481 GLsizei *length, GLint *size, GLenum *type, GLchar *name)
1482 {
1483 struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf);
1484 slang_active_variable *a = &impl->_obj.prog.active_attribs.table[index];
1485
1486 get_active_variable (a, maxLength, length, size, type, name);
1487 }
1488
1489 static GLuint
1490 _program_GetActiveAttribMaxLength (struct gl2_program_intf **intf)
1491 {
1492 struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf);
1493
1494 return get_active_variable_max_length (&impl->_obj.prog.active_attribs);
1495 }
1496
1497 static GLuint
1498 _program_GetActiveAttribCount (struct gl2_program_intf **intf)
1499 {
1500 struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf);
1501
1502 return impl->_obj.prog.active_attribs.count;
1503 }
1504
1505 static GLint
1506 _program_GetAttribLocation (struct gl2_program_intf **intf, const GLchar *name)
1507 {
1508 struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf);
1509 slang_attrib_bindings *attribs = &impl->_obj.prog.attribs;
1510 GLuint i;
1511
1512 for (i = 0; i < attribs->binding_count; i++)
1513 if (_mesa_strcmp (attribs->bindings[i].name, name) == 0)
1514 return attribs->bindings[i].first_slot_index;
1515 return -1;
1516 }
1517
1518 static GLvoid
1519 _program_OverrideAttribBinding (struct gl2_program_intf **intf, GLuint index, const GLchar *name)
1520 {
1521 GET_CURRENT_CONTEXT(ctx);
1522 struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf);
1523 slang_program *pro = &impl->_obj.prog;
1524
1525 if (!slang_attrib_overrides_add (&pro->attrib_overrides, index, name))
1526 _mesa_error (ctx, GL_OUT_OF_MEMORY, "_program_OverrideAttribBinding");
1527 }
1528
1529 static GLvoid
1530 _program_WriteAttrib (struct gl2_program_intf **intf, GLuint index, const GLfloat *value)
1531 {
1532 struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf);
1533 slang_program *pro = &impl->_obj.prog;
1534 slang_attrib_slot *slot = &pro->attribs.slots[index];
1535
1536 /*
1537 * Generic attributes can be allocated in a shader with scalar, vec or mat type.
1538 * For scalar and vec types (specifically float, vec2 and vec3) this is simple - just
1539 * ignore the extra components. For mat type this is more complicated - the vertex_shader
1540 * spec requires to store every column of a matrix in a separate attrib slot.
1541 * To prvent from overwriting data from neighbouring matrix columns, the "fill" information
1542 * is kept to know how many components to copy.
1543 */
1544
1545 if (slot->addr != ~0)
1546 _mesa_memcpy (&pro->machines[SLANG_SHADER_VERTEX]->mem[slot->addr / 4]._float, value,
1547 slot->fill * sizeof (GLfloat));
1548 }
1549
1550 static GLvoid
1551 _program_UpdateVarying (struct gl2_program_intf **intf, GLuint index, GLfloat *value,
1552 GLboolean vert)
1553 {
1554 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
1555 slang_program *pro = &impl->_obj.prog;
1556 GLuint addr;
1557
1558 if (index >= pro->varyings.slot_count)
1559 return;
1560 if (vert)
1561 addr = pro->varyings.slots[index].vert_addr / 4;
1562 else
1563 addr = pro->varyings.slots[index].frag_addr / 4;
1564 if (addr != ~0)
1565 {
1566 if (vert)
1567 *value = pro->machines[SLANG_SHADER_VERTEX]->mem[addr]._float;
1568 else
1569 pro->machines[SLANG_SHADER_FRAGMENT]->mem[addr]._float = *value;
1570 }
1571 }
1572
1573 static struct gl2_program_intf _program_vftbl = {
1574 {
1575 {
1576 {
1577 _unknown_AddRef,
1578 _unknown_Release,
1579 _program_QueryInterface
1580 },
1581 _generic_Delete,
1582 _program_GetType,
1583 _generic_GetName,
1584 _generic_GetDeleteStatus,
1585 _generic_GetInfoLog,
1586 _generic_GetInfoLogLength
1587 },
1588 _program_Attach,
1589 _container_Detach,
1590 _container_GetAttachedCount,
1591 _container_GetAttached
1592 },
1593 _program_GetLinkStatus,
1594 _program_GetValidateStatus,
1595 _program_Link,
1596 _program_Validate,
1597 _program_UpdateFixedUniforms,
1598 _program_UpdateFixedAttrib,
1599 _program_UpdateFixedVarying,
1600 _program_GetTextureImageUsage,
1601 _program_IsShaderPresent,
1602 _program_GetActiveUniform,
1603 _program_GetActiveUniformMaxLength,
1604 _program_GetActiveUniformCount,
1605 _program_GetUniformLocation,
1606 _program_WriteUniform,
1607 _program_GetActiveAttrib,
1608 _program_GetActiveAttribMaxLength,
1609 _program_GetActiveAttribCount,
1610 _program_GetAttribLocation,
1611 _program_OverrideAttribBinding,
1612 _program_WriteAttrib,
1613 _program_UpdateVarying
1614 };
1615
1616 static void
1617 _program_constructor (struct gl2_program_impl *impl)
1618 {
1619 _container_constructor ((struct gl2_container_impl *) impl);
1620 impl->_vftbl = &_program_vftbl;
1621 impl->_obj._container._generic._unknown._destructor = _program_destructor;
1622 impl->_obj.link_status = GL_FALSE;
1623 impl->_obj.validate_status = GL_FALSE;
1624 #if USE_3DLABS_FRONTEND
1625 impl->_obj.linker = ShConstructLinker (EShExVertexFragment, 0);
1626 impl->_obj.uniforms = ShConstructUniformMap ();
1627 #endif
1628 slang_program_ctr (&impl->_obj.prog);
1629 }
1630
1631 struct gl2_fragment_shader_obj
1632 {
1633 struct gl2_shader_obj _shader;
1634 };
1635
1636 struct gl2_fragment_shader_impl
1637 {
1638 struct gl2_fragment_shader_intf *_vftbl;
1639 struct gl2_fragment_shader_obj _obj;
1640 };
1641
1642 static void
1643 _fragment_shader_destructor (struct gl2_unknown_intf **intf)
1644 {
1645 struct gl2_fragment_shader_impl *impl = (struct gl2_fragment_shader_impl *) intf;
1646
1647 (void) impl;
1648 /* TODO free fragment shader data */
1649
1650 _shader_destructor (intf);
1651 }
1652
1653 static struct gl2_unknown_intf **
1654 _fragment_shader_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
1655 {
1656 if (uiid == UIID_FRAGMENT_SHADER)
1657 {
1658 (**intf).AddRef (intf);
1659 return intf;
1660 }
1661 return _shader_QueryInterface (intf, uiid);
1662 }
1663
1664 static GLenum
1665 _fragment_shader_GetSubType (struct gl2_shader_intf **intf)
1666 {
1667 return GL_FRAGMENT_SHADER_ARB;
1668 }
1669
1670 static struct gl2_fragment_shader_intf _fragment_shader_vftbl = {
1671 {
1672 {
1673 {
1674 _unknown_AddRef,
1675 _unknown_Release,
1676 _fragment_shader_QueryInterface
1677 },
1678 _generic_Delete,
1679 _shader_GetType,
1680 _generic_GetName,
1681 _generic_GetDeleteStatus,
1682 _shader_GetInfoLog,
1683 _shader_GetInfoLogLength
1684 },
1685 _fragment_shader_GetSubType,
1686 _shader_GetCompileStatus,
1687 _shader_SetSource,
1688 _shader_GetSource,
1689 _shader_Compile
1690 }
1691 };
1692
1693 static void
1694 _fragment_shader_constructor (struct gl2_fragment_shader_impl *impl)
1695 {
1696 _shader_constructor ((struct gl2_shader_impl *) impl);
1697 impl->_vftbl = &_fragment_shader_vftbl;
1698 impl->_obj._shader._generic._unknown._destructor = _fragment_shader_destructor;
1699 #if USE_3DLABS_FRONTEND
1700 impl->_obj._shader._3dlabs_shhandle._obj.handle = ShConstructCompiler (EShLangFragment, 0);
1701 #endif
1702 }
1703
1704 struct gl2_vertex_shader_obj
1705 {
1706 struct gl2_shader_obj _shader;
1707 };
1708
1709 struct gl2_vertex_shader_impl
1710 {
1711 struct gl2_vertex_shader_intf *_vftbl;
1712 struct gl2_vertex_shader_obj _obj;
1713 };
1714
1715 static void
1716 _vertex_shader_destructor (struct gl2_unknown_intf **intf)
1717 {
1718 struct gl2_vertex_shader_impl *impl = (struct gl2_vertex_shader_impl *) intf;
1719
1720 (void) impl;
1721 /* TODO free vertex shader data */
1722
1723 _shader_destructor (intf);
1724 }
1725
1726 static struct gl2_unknown_intf **
1727 _vertex_shader_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
1728 {
1729 if (uiid == UIID_VERTEX_SHADER)
1730 {
1731 (**intf).AddRef (intf);
1732 return intf;
1733 }
1734 return _shader_QueryInterface (intf, uiid);
1735 }
1736
1737 static GLenum
1738 _vertex_shader_GetSubType (struct gl2_shader_intf **intf)
1739 {
1740 return GL_VERTEX_SHADER_ARB;
1741 }
1742
1743 static struct gl2_vertex_shader_intf _vertex_shader_vftbl = {
1744 {
1745 {
1746 {
1747 _unknown_AddRef,
1748 _unknown_Release,
1749 _vertex_shader_QueryInterface
1750 },
1751 _generic_Delete,
1752 _shader_GetType,
1753 _generic_GetName,
1754 _generic_GetDeleteStatus,
1755 _shader_GetInfoLog,
1756 _shader_GetInfoLogLength
1757 },
1758 _vertex_shader_GetSubType,
1759 _shader_GetCompileStatus,
1760 _shader_SetSource,
1761 _shader_GetSource,
1762 _shader_Compile
1763 }
1764 };
1765
1766 static void
1767 _vertex_shader_constructor (struct gl2_vertex_shader_impl *impl)
1768 {
1769 _shader_constructor ((struct gl2_shader_impl *) impl);
1770 impl->_vftbl = &_vertex_shader_vftbl;
1771 impl->_obj._shader._generic._unknown._destructor = _vertex_shader_destructor;
1772 #if USE_3DLABS_FRONTEND
1773 impl->_obj._shader._3dlabs_shhandle._obj.handle = ShConstructCompiler (EShLangVertex, 0);
1774 #endif
1775 }
1776
1777 GLhandleARB
1778 _mesa_3dlabs_create_shader_object (GLenum shaderType)
1779 {
1780 switch (shaderType)
1781 {
1782 case GL_FRAGMENT_SHADER_ARB:
1783 {
1784 struct gl2_fragment_shader_impl *x = (struct gl2_fragment_shader_impl *)
1785 _mesa_malloc (sizeof (struct gl2_fragment_shader_impl));
1786
1787 if (x != NULL)
1788 {
1789 _fragment_shader_constructor (x);
1790 return x->_obj._shader._generic.name;
1791 }
1792 }
1793 break;
1794 case GL_VERTEX_SHADER_ARB:
1795 {
1796 struct gl2_vertex_shader_impl *x = (struct gl2_vertex_shader_impl *)
1797 _mesa_malloc (sizeof (struct gl2_vertex_shader_impl));
1798
1799 if (x != NULL)
1800 {
1801 _vertex_shader_constructor (x);
1802 return x->_obj._shader._generic.name;
1803 }
1804 }
1805 break;
1806 }
1807
1808 return 0;
1809 }
1810
1811 GLhandleARB
1812 _mesa_3dlabs_create_program_object (void)
1813 {
1814 struct gl2_program_impl *x = (struct gl2_program_impl *)
1815 _mesa_malloc (sizeof (struct gl2_program_impl));
1816
1817 if (x != NULL)
1818 {
1819 _program_constructor (x);
1820 return x->_obj._container._generic.name;
1821 }
1822
1823 return 0;
1824 }
1825
1826 #include "slang_assemble.h"
1827 #include "slang_execute.h"
1828
1829 int _slang_fetch_discard (struct gl2_program_intf **pro, GLboolean *val)
1830 {
1831 struct gl2_program_impl *impl;
1832
1833 impl = (struct gl2_program_impl *) pro;
1834 *val = impl->_obj.prog.machines[SLANG_SHADER_FRAGMENT]->kill ? GL_TRUE : GL_FALSE;
1835 return 1;
1836 }
1837
1838 static GLvoid exec_shader (struct gl2_program_intf **pro, GLuint i)
1839 {
1840 struct gl2_program_impl *impl;
1841 slang_program *p;
1842
1843 impl = (struct gl2_program_impl *) pro;
1844 p = &impl->_obj.prog;
1845
1846 slang_machine_init (p->machines[i]);
1847 p->machines[i]->ip = p->code[i][SLANG_COMMON_CODE_MAIN];
1848
1849 _slang_execute2 (p->assemblies[i], p->machines[i]);
1850 }
1851
1852 GLvoid _slang_exec_fragment_shader (struct gl2_program_intf **pro)
1853 {
1854 exec_shader (pro, SLANG_SHADER_FRAGMENT);
1855 }
1856
1857 GLvoid _slang_exec_vertex_shader (struct gl2_program_intf **pro)
1858 {
1859 exec_shader (pro, SLANG_SHADER_VERTEX);
1860 }
1861
1862 void
1863 _mesa_init_shaderobjects_3dlabs (GLcontext *ctx)
1864 {
1865 #if USE_3DLABS_FRONTEND
1866 _glslang_3dlabs_InitProcess ();
1867 _glslang_3dlabs_ShInitialize ();
1868 #endif
1869 }
1870