New functions for cloning programs and parameter lists.
[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 "program.h"
38 #include "shaderobjects.h"
39 #include "shaderobjects_3dlabs.h"
40
41 #if USE_3DLABS_FRONTEND
42 #include "slang_mesa.h"
43 #include "Public/ShaderLang.h"
44 #else
45 #include "slang_link.h"
46 #endif
47
48 #if FEATURE_ARB_shader_objects
49
50 struct gl2_unknown_obj
51 {
52 GLuint reference_count;
53 void (*_destructor) (struct gl2_unknown_intf **);
54 };
55
56 struct gl2_unknown_impl
57 {
58 struct gl2_unknown_intf *_vftbl;
59 struct gl2_unknown_obj _obj;
60 };
61
62 static void
63 _unknown_destructor(struct gl2_unknown_intf **intf)
64 {
65 }
66
67 static void
68 _unknown_AddRef(struct gl2_unknown_intf **intf)
69 {
70 struct gl2_unknown_impl *impl = (struct gl2_unknown_impl *) intf;
71
72 impl->_obj.reference_count++;
73 }
74
75 static void
76 _unknown_Release(struct gl2_unknown_intf **intf)
77 {
78 struct gl2_unknown_impl *impl = (struct gl2_unknown_impl *) intf;
79
80 impl->_obj.reference_count--;
81 if (impl->_obj.reference_count == 0) {
82 impl->_obj._destructor(intf);
83 _mesa_free((void *) intf);
84 }
85 }
86
87 static struct gl2_unknown_intf **
88 _unknown_QueryInterface(struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
89 {
90 if (uiid == UIID_UNKNOWN) {
91 (**intf).AddRef(intf);
92 return intf;
93 }
94 return NULL;
95 }
96
97 static struct gl2_unknown_intf _unknown_vftbl = {
98 _unknown_AddRef,
99 _unknown_Release,
100 _unknown_QueryInterface
101 };
102
103 static void
104 _unknown_constructor(struct gl2_unknown_impl *impl)
105 {
106 impl->_vftbl = &_unknown_vftbl;
107 impl->_obj.reference_count = 1;
108 impl->_obj._destructor = _unknown_destructor;
109 }
110
111 struct gl2_unkinner_obj
112 {
113 struct gl2_unknown_intf **unkouter;
114 };
115
116 struct gl2_unkinner_impl
117 {
118 struct gl2_unknown_intf *_vftbl;
119 struct gl2_unkinner_obj _obj;
120 };
121
122 static void
123 _unkinner_destructor(struct gl2_unknown_intf **intf)
124 {
125 }
126
127 static void
128 _unkinner_AddRef(struct gl2_unknown_intf **intf)
129 {
130 struct gl2_unkinner_impl *impl = (struct gl2_unkinner_impl *) intf;
131
132 (**impl->_obj.unkouter).AddRef(impl->_obj.unkouter);
133 }
134
135 static void
136 _unkinner_Release(struct gl2_unknown_intf **intf)
137 {
138 struct gl2_unkinner_impl *impl = (struct gl2_unkinner_impl *) intf;
139
140 (**impl->_obj.unkouter).Release(impl->_obj.unkouter);
141 }
142
143 static struct gl2_unknown_intf **
144 _unkinner_QueryInterface(struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
145 {
146 struct gl2_unkinner_impl *impl = (struct gl2_unkinner_impl *) intf;
147
148 return (**impl->_obj.unkouter).QueryInterface(impl->_obj.unkouter, uiid);
149 }
150
151 static struct gl2_unknown_intf _unkinner_vftbl = {
152 _unkinner_AddRef,
153 _unkinner_Release,
154 _unkinner_QueryInterface
155 };
156
157 static void
158 _unkinner_constructor(struct gl2_unkinner_impl *impl,
159 struct gl2_unknown_intf **outer)
160 {
161 impl->_vftbl = &_unkinner_vftbl;
162 impl->_obj.unkouter = outer;
163 }
164
165 struct gl2_generic_obj
166 {
167 struct gl2_unknown_obj _unknown;
168 GLhandleARB name;
169 GLboolean delete_status;
170 GLcharARB *info_log;
171 };
172
173 struct gl2_generic_impl
174 {
175 struct gl2_generic_intf *_vftbl;
176 struct gl2_generic_obj _obj;
177 };
178
179 static void
180 _generic_destructor(struct gl2_unknown_intf **intf)
181 {
182 GET_CURRENT_CONTEXT(ctx);
183 struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf;
184
185 _mesa_free((void *) impl->_obj.info_log);
186
187 _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
188 _mesa_HashRemove(ctx->Shared->GL2Objects, impl->_obj.name);
189 _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
190
191 _unknown_destructor(intf);
192 }
193
194 static struct gl2_unknown_intf **
195 _generic_QueryInterface(struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
196 {
197 if (uiid == UIID_GENERIC) {
198 (**intf).AddRef(intf);
199 return intf;
200 }
201 return _unknown_QueryInterface(intf, uiid);
202 }
203
204 static void
205 _generic_Delete(struct gl2_generic_intf **intf)
206 {
207 struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf;
208
209 if (impl->_obj.delete_status == GL_FALSE) {
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,
233 GLcharARB * infolog)
234 {
235 struct gl2_generic_impl *impl = (struct gl2_generic_impl *) (intf);
236
237 if (maxlen > 0) {
238 _mesa_strncpy(infolog, impl->_obj.info_log, maxlen - 1);
239 infolog[maxlen - 1] = '\0';
240 }
241 }
242
243 static GLsizei
244 _generic_GetInfoLogLength(struct gl2_generic_intf **intf)
245 {
246 struct gl2_generic_impl *impl = (struct gl2_generic_impl *) (intf);
247
248 if (impl->_obj.info_log == NULL)
249 return 1;
250 return _mesa_strlen(impl->_obj.info_log) + 1;
251 }
252
253 static struct gl2_generic_intf _generic_vftbl = {
254 {
255 _unknown_AddRef,
256 _unknown_Release,
257 _generic_QueryInterface},
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 struct gl2_generic_intf **x = impl->_obj.attached[i];
304 (**x)._unknown.Release((struct gl2_unknown_intf **) x);
305 }
306
307 _generic_destructor(intf);
308 }
309
310 static struct gl2_unknown_intf **
311 _container_QueryInterface(struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
312 {
313 if (uiid == UIID_CONTAINER) {
314 (**intf).AddRef(intf);
315 return intf;
316 }
317 return _generic_QueryInterface(intf, uiid);
318 }
319
320 static GLboolean
321 _container_Attach(struct gl2_container_intf **intf,
322 struct gl2_generic_intf **att)
323 {
324 GET_CURRENT_CONTEXT(ctx);
325 struct gl2_container_impl *impl = (struct gl2_container_impl *) intf;
326 GLuint i;
327
328 for (i = 0; i < impl->_obj.attached_count; i++)
329 if (impl->_obj.attached[i] == att) {
330 _mesa_error(ctx, GL_INVALID_OPERATION, "_container_Attach");
331 return GL_FALSE;
332 }
333
334 impl->_obj.attached = (struct gl2_generic_intf ***)
335 _mesa_realloc(impl->_obj.attached,
336 impl->_obj.attached_count * sizeof(*impl->_obj.attached),
337 (impl->_obj.attached_count + 1) * sizeof(*impl->_obj.attached));
338 if (impl->_obj.attached == NULL)
339 return GL_FALSE;
340
341 impl->_obj.attached[impl->_obj.attached_count] = att;
342 impl->_obj.attached_count++;
343 (**att)._unknown.AddRef((struct gl2_unknown_intf **) att);
344 return GL_TRUE;
345 }
346
347 static GLboolean
348 _container_Detach(struct gl2_container_intf **intf,
349 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 for (j = i; j < impl->_obj.attached_count - 1; j++)
358 impl->_obj.attached[j] = impl->_obj.attached[j + 1];
359 impl->_obj.attached = (struct gl2_generic_intf ***)
360 _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((struct gl2_unknown_intf **)
386 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 =
439 (struct gl2_3dlabs_shhandle_impl *) intf;
440 ShDestruct(impl->_obj.handle);
441 #endif
442 _unkinner_destructor(intf);
443 }
444
445 static GLvoid *
446 _3dlabs_shhandle_GetShHandle(struct gl2_3dlabs_shhandle_intf **intf)
447 {
448 #if USE_3DLABS_FRONTEND
449 struct gl2_3dlabs_shhandle_impl *impl =
450 (struct gl2_3dlabs_shhandle_impl *) intf;
451 return impl->_obj.handle;
452 #else
453 return NULL;
454 #endif
455 }
456
457 static struct gl2_3dlabs_shhandle_intf _3dlabs_shhandle_vftbl = {
458 {
459 _unkinner_AddRef,
460 _unkinner_Release,
461 _unkinner_QueryInterface},
462 _3dlabs_shhandle_GetShHandle
463 };
464
465 static void
466 _3dlabs_shhandle_constructor(struct gl2_3dlabs_shhandle_impl *impl,
467 struct gl2_unknown_intf **outer)
468 {
469 _unkinner_constructor((struct gl2_unkinner_impl *) impl, outer);
470 impl->_vftbl = &_3dlabs_shhandle_vftbl;
471 #if USE_3DLABS_FRONTEND
472 impl->_obj.handle = NULL;
473 #endif
474 }
475
476 struct gl2_shader_obj
477 {
478 struct gl2_generic_obj _generic;
479 struct gl2_3dlabs_shhandle_impl _3dlabs_shhandle;
480 GLboolean compile_status;
481 GLcharARB *source;
482 GLint *offsets;
483 GLsizei offset_count;
484 slang_code_object code;
485 };
486
487 struct gl2_shader_impl
488 {
489 struct gl2_shader_intf *_vftbl;
490 struct gl2_shader_obj _obj;
491 };
492
493 static void
494 _shader_destructor(struct gl2_unknown_intf **intf)
495 {
496 struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
497
498 _mesa_free((void *) impl->_obj.source);
499 _mesa_free((void *) impl->_obj.offsets);
500 _slang_code_object_dtr(&impl->_obj.code);
501 _3dlabs_shhandle_destructor((struct gl2_unknown_intf **) &impl->_obj.
502 _3dlabs_shhandle._vftbl);
503 _generic_destructor(intf);
504 }
505
506 static struct gl2_unknown_intf **
507 _shader_QueryInterface(struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
508 {
509 #if USE_3DLABS_FRONTEND
510 struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
511 #endif
512
513 if (uiid == UIID_SHADER) {
514 (**intf).AddRef(intf);
515 return intf;
516 }
517 #if USE_3DLABS_FRONTEND
518 if (uiid == UIID_3DLABS_SHHANDLE) {
519 (**intf).AddRef(intf);
520 return (struct gl2_unknown_intf **) &impl->_obj._3dlabs_shhandle._vftbl;
521 }
522 #endif
523 return _generic_QueryInterface(intf, uiid);
524 }
525
526 static GLenum
527 _shader_GetType(struct gl2_generic_intf **intf)
528 {
529 return GL_SHADER_OBJECT_ARB;
530 }
531
532 static GLvoid
533 _shader_GetInfoLog(struct gl2_generic_intf **intf, GLsizei maxlen,
534 GLcharARB * infolog)
535 {
536 struct gl2_shader_impl *impl = (struct gl2_shader_impl *) (intf);
537
538 if (maxlen > 0) {
539 if (impl->_obj._generic.info_log != NULL) {
540 GLsizei len = _mesa_strlen(impl->_obj._generic.info_log);
541 if (len > maxlen - 1)
542 len = maxlen - 1;
543 _mesa_memcpy(infolog, impl->_obj._generic.info_log, len);
544 infolog += len;
545 maxlen -= len;
546 }
547 if (impl->_obj.code.machine.infolog != NULL &&
548 impl->_obj.code.machine.infolog->text != NULL) {
549 GLsizei len = _mesa_strlen(impl->_obj.code.machine.infolog->text);
550 if (len > maxlen - 1)
551 len = maxlen - 1;
552 _mesa_memcpy(infolog, impl->_obj.code.machine.infolog->text, len);
553 }
554 infolog[maxlen - 1] = '\0';
555 }
556 }
557
558 static GLsizei
559 _shader_GetInfoLogLength(struct gl2_generic_intf **intf)
560 {
561 struct gl2_shader_impl *impl = (struct gl2_shader_impl *) (intf);
562 GLsizei length = 1;
563
564 if (impl->_obj._generic.info_log != NULL)
565 length += _mesa_strlen(impl->_obj._generic.info_log);
566 if (impl->_obj.code.machine.infolog != NULL &&
567 impl->_obj.code.machine.infolog->text != NULL)
568 length += _mesa_strlen(impl->_obj.code.machine.infolog->text);
569 return length;
570 }
571
572 static GLboolean
573 _shader_GetCompileStatus(struct gl2_shader_intf **intf)
574 {
575 struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
576
577 return impl->_obj.compile_status;
578 }
579
580 static GLvoid
581 _shader_SetSource(struct gl2_shader_intf **intf, GLcharARB * src, GLint * off,
582 GLsizei cnt)
583 {
584 struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
585
586 _mesa_free((void *) impl->_obj.source);
587 impl->_obj.source = src;
588 _mesa_free((void *) impl->_obj.offsets);
589 impl->_obj.offsets = off;
590 impl->_obj.offset_count = cnt;
591 }
592
593 static const GLcharARB *
594 _shader_GetSource(struct gl2_shader_intf **intf)
595 {
596 struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
597
598 return impl->_obj.source;
599 }
600
601 static GLvoid
602 _shader_Compile(struct gl2_shader_intf **intf)
603 {
604 GET_CURRENT_CONTEXT(ctx);
605 struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
606 #if USE_3DLABS_FRONTEND
607 char **strings;
608 TBuiltInResource res;
609 #else
610 slang_unit_type type;
611 slang_info_log info_log;
612 #endif
613
614 impl->_obj.compile_status = GL_FALSE;
615 _mesa_free((void *) impl->_obj._generic.info_log);
616 impl->_obj._generic.info_log = NULL;
617
618 #if USE_3DLABS_FRONTEND
619 /* 3dlabs compiler expects us to feed it with null-terminated string array,
620 we've got only one big string with offsets, so we must split it; but when
621 there's only one string to deal with, we pass its address directly */
622
623 if (impl->_obj.offset_count <= 1)
624 strings = &impl->_obj.source;
625 else {
626 GLsizei i, offset = 0;
627
628 strings =
629 (char **) _mesa_malloc(impl->_obj.offset_count * sizeof(char *));
630 if (strings == NULL)
631 return;
632
633 for (i = 0; i < impl->_obj.offset_count; i++) {
634 GLsizei size = impl->_obj.offsets[i] - offset;
635
636 strings[i] = (char *) _mesa_malloc((size + 1) * sizeof(char));
637 if (strings[i] == NULL) {
638 GLsizei j;
639
640 for (j = 0; j < i; j++)
641 _mesa_free(strings[j]);
642 _mesa_free(strings);
643 return;
644 }
645
646 _mesa_memcpy(strings[i], impl->_obj.source + offset,
647 size * sizeof(char));
648 strings[i][size] = '\0';
649 offset = impl->_obj.offsets[i];
650 }
651 }
652
653 /* TODO set these fields to some REAL numbers */
654 res.maxLights = 8;
655 res.maxClipPlanes = 6;
656 res.maxTextureUnits = 2;
657 res.maxTextureCoords = 2;
658 res.maxVertexAttribs = 8;
659 res.maxVertexUniformComponents = 64;
660 res.maxVaryingFloats = 8;
661 res.maxVertexTextureImageUnits = 2;
662 res.maxCombinedTextureImageUnits = 2;
663 res.maxTextureImageUnits = 2;
664 res.maxFragmentUniformComponents = 64;
665 res.maxDrawBuffers = 1;
666
667 if (ShCompile
668 (impl->_obj._3dlabs_shhandle._obj.handle, strings,
669 impl->_obj.offset_count, EShOptFull, &res, 0))
670 impl->_obj.compile_status = GL_TRUE;
671 if (impl->_obj.offset_count > 1) {
672 GLsizei i;
673
674 for (i = 0; i < impl->_obj.offset_count; i++)
675 _mesa_free(strings[i]);
676 _mesa_free(strings);
677 }
678
679 impl->_obj._generic.info_log =
680 _mesa_strdup(ShGetInfoLog(impl->_obj._3dlabs_shhandle._obj.handle));
681 #else
682 /* NEW_SLANG */
683 if (impl->_vftbl->GetSubType(intf) == GL_FRAGMENT_SHADER) {
684 type = slang_unit_fragment_shader;
685 (*intf)->Program = _mesa_new_program(ctx, GL_FRAGMENT_PROGRAM_ARB, 1);
686 }
687 else {
688 type = slang_unit_vertex_shader;
689 (*intf)->Program = _mesa_new_program(ctx, GL_VERTEX_PROGRAM_ARB, 1);
690 }
691 slang_info_log_construct(&info_log);
692 if (_slang_compile(impl->_obj.source, &impl->_obj.code, type, &info_log,
693 (*intf)->Program))
694 impl->_obj.compile_status = GL_TRUE;
695 if (info_log.text != NULL)
696 impl->_obj._generic.info_log = _mesa_strdup(info_log.text);
697 else if (impl->_obj.compile_status)
698 impl->_obj._generic.info_log = _mesa_strdup("Compile OK.\n");
699 else
700 impl->_obj._generic.info_log = _mesa_strdup("Compile failed.\n");
701 slang_info_log_destruct(&info_log);
702 #endif
703 }
704
705 static struct gl2_shader_intf _shader_vftbl = {
706 {
707 {
708 _unknown_AddRef,
709 _unknown_Release,
710 _shader_QueryInterface
711 },
712 _generic_Delete,
713 _shader_GetType,
714 _generic_GetName,
715 _generic_GetDeleteStatus,
716 _shader_GetInfoLog,
717 _shader_GetInfoLogLength
718 },
719 NULL, /* abstract GetSubType */
720 _shader_GetCompileStatus,
721 _shader_SetSource,
722 _shader_GetSource,
723 _shader_Compile
724 };
725
726 static void
727 _shader_constructor(struct gl2_shader_impl *impl)
728 {
729 _generic_constructor((struct gl2_generic_impl *) impl);
730 _3dlabs_shhandle_constructor(&impl->_obj._3dlabs_shhandle,
731 (struct gl2_unknown_intf **)
732 &impl->_vftbl);
733 impl->_vftbl = &_shader_vftbl;
734 impl->_obj._generic._unknown._destructor = _shader_destructor;
735 impl->_obj.compile_status = GL_FALSE;
736 impl->_obj.source = NULL;
737 impl->_obj.offsets = NULL;
738 impl->_obj.offset_count = 0;
739 _slang_code_object_ctr(&impl->_obj.code);
740 }
741
742 struct gl2_program_obj
743 {
744 struct gl2_container_obj _container;
745 GLboolean link_status;
746 GLboolean validate_status;
747 #if USE_3DLABS_FRONTEND
748 ShHandle linker;
749 ShHandle uniforms;
750 #endif
751 slang_program prog;
752 };
753
754 struct gl2_program_impl
755 {
756 struct gl2_program_intf *_vftbl;
757 struct gl2_program_obj _obj;
758 };
759
760 static void
761 _program_destructor(struct gl2_unknown_intf **intf)
762 {
763 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
764 #if USE_3DLABS_FRONTEND
765 ShDestruct(impl->_obj.linker);
766 ShDestruct(impl->_obj.uniforms);
767 #endif
768 _container_destructor(intf);
769 _slang_program_dtr(&impl->_obj.prog);
770 }
771
772 static struct gl2_unknown_intf **
773 _program_QueryInterface(struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
774 {
775 if (uiid == UIID_PROGRAM) {
776 (**intf).AddRef(intf);
777 return intf;
778 }
779 return _container_QueryInterface(intf, uiid);
780 }
781
782 static GLenum
783 _program_GetType(struct gl2_generic_intf **intf)
784 {
785 return GL_PROGRAM_OBJECT_ARB;
786 }
787
788 static GLboolean
789 _program_Attach(struct gl2_container_intf **intf,
790 struct gl2_generic_intf **att)
791 {
792 GET_CURRENT_CONTEXT(ctx);
793 struct gl2_unknown_intf **sha;
794
795 sha =
796 (**att)._unknown.QueryInterface((struct gl2_unknown_intf **) att,
797 UIID_SHADER);
798 if (sha == NULL) {
799 _mesa_error(ctx, GL_INVALID_OPERATION, "_program_Attach");
800 return GL_FALSE;
801 }
802
803 (**sha).Release(sha);
804 return _container_Attach(intf, att);
805 }
806
807 static GLboolean
808 _program_GetLinkStatus(struct gl2_program_intf **intf)
809 {
810 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
811
812 return impl->_obj.link_status;
813 }
814
815 static GLboolean
816 _program_GetValidateStatus(struct gl2_program_intf **intf)
817 {
818 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
819
820 return impl->_obj.validate_status;
821 }
822
823 static GLvoid
824 _program_Link(struct gl2_program_intf **intf)
825 {
826 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
827 #if USE_3DLABS_FRONTEND
828 ShHandle *handles;
829 #endif
830 GLuint i, count;
831 slang_code_object *code[2];
832 GLboolean all_compiled = GL_TRUE;
833
834 impl->_obj.link_status = GL_FALSE;
835 _mesa_free((void *) impl->_obj._container._generic.info_log);
836 impl->_obj._container._generic.info_log = NULL;
837 _slang_program_rst(&impl->_obj.prog);
838
839 #if USE_3DLABS_FRONTEND
840 handles =
841 (ShHandle *) _mesa_malloc(impl->_obj._container.attached_count *
842 sizeof(ShHandle));
843 if (handles == NULL)
844 return;
845
846 for (i = 0; i < impl->_obj._container.attached_count; i++) {
847 struct gl2_generic_intf **gen = impl->_obj._container.attached[i];
848 struct gl2_3dlabs_shhandle_intf **sh;
849
850 sh =
851 (struct gl2_3dlabs_shhandle_intf **) (**gen)._unknown.
852 QueryInterface((struct gl2_unknown_intf **) gen,
853 UIID_3DLABS_SHHANDLE);
854 if (sh != NULL) {
855 handles[i] = (**sh).GetShHandle(sh);
856 (**sh)._unknown.Release((struct gl2_unknown_intf **) sh);
857 }
858 else {
859 _mesa_free(handles);
860 return;
861 }
862 }
863
864 if (ShLink(impl->_obj.linker, handles, impl->_obj._container.attached_count,
865 impl->_obj.uniforms, NULL, NULL))
866 impl->_obj.link_status = GL_TRUE;
867
868 impl->_obj._container._generic.info_log =
869 _mesa_strdup(ShGetInfoLog(impl->_obj.linker));
870 #else
871 count = impl->_obj._container.attached_count;
872 if (count > 2)
873 return;
874
875 for (i = 0; i < count; i++) {
876 struct gl2_generic_intf **obj;
877 struct gl2_unknown_intf **unk;
878 struct gl2_shader_impl *sha;
879
880 obj = impl->_obj._container.attached[i];
881 unk =
882 (**obj)._unknown.QueryInterface((struct gl2_unknown_intf **) obj,
883 UIID_SHADER);
884 if (unk == NULL)
885 return;
886 sha = (struct gl2_shader_impl *) unk;
887 code[i] = &sha->_obj.code;
888 all_compiled = all_compiled && sha->_obj.compile_status;
889 (**unk).Release(unk);
890 }
891
892 impl->_obj.link_status = all_compiled;
893 if (!impl->_obj.link_status) {
894 impl->_obj._container._generic.info_log =
895 _mesa_strdup
896 ("Error: One or more shaders has not successfully compiled.\n");
897 return;
898 }
899
900 impl->_obj.link_status = _slang_link(&impl->_obj.prog, code, count);
901 if (!impl->_obj.link_status) {
902 impl->_obj._container._generic.info_log =
903 _mesa_strdup("Link failed.\n");
904 return;
905 }
906
907 impl->_obj._container._generic.info_log = _mesa_strdup("Link OK.\n");
908 #endif
909 }
910
911 static GLvoid
912 _program_Validate(struct gl2_program_intf **intf)
913 {
914 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
915
916 impl->_obj.validate_status = GL_FALSE;
917 _mesa_free((void *) impl->_obj._container._generic.info_log);
918 impl->_obj._container._generic.info_log = NULL;
919
920 /* TODO validate */
921 }
922
923 static GLvoid
924 write_common_fixed(slang_program * pro, GLuint index, const GLvoid * src,
925 GLuint off, GLuint size)
926 {
927 GLuint i;
928
929 for (i = 0; i < SLANG_SHADER_MAX; i++) {
930 GLuint addr;
931
932 addr = pro->common_fixed_entries[i][index];
933 if (addr != ~0) {
934 GLubyte *dst;
935
936 dst = (GLubyte *) pro->machines[i]->mem + addr + off * size;
937 _mesa_memcpy(dst, src, size);
938 }
939 }
940 }
941
942 static GLvoid
943 write_common_fixed_mat4(slang_program * pro, GLmatrix * matrix, GLuint off,
944 GLuint i, GLuint ii, GLuint it, GLuint iit)
945 {
946 GLfloat mat[16];
947
948 /* we want inverse matrix */
949 if (!matrix->inv) {
950 /* allocate inverse matrix and make it dirty */
951 _math_matrix_alloc_inv(matrix);
952 _math_matrix_loadf(matrix, matrix->m);
953 }
954 _math_matrix_analyse(matrix);
955
956 write_common_fixed(pro, i, matrix->m, off, 16 * sizeof(GLfloat));
957
958 /* inverse */
959 write_common_fixed(pro, ii, matrix->inv, off, 16 * sizeof(GLfloat));
960
961 /* transpose */
962 _math_transposef(mat, matrix->m);
963 write_common_fixed(pro, it, mat, off, 16 * sizeof(GLfloat));
964
965 /* inverse transpose */
966 _math_transposef(mat, matrix->inv);
967 write_common_fixed(pro, iit, mat, off, 16 * sizeof(GLfloat));
968 }
969
970 static GLvoid
971 write_common_fixed_material(GLcontext * ctx, slang_program * pro, GLuint i,
972 GLuint e, GLuint a, GLuint d, GLuint sp,
973 GLuint sh)
974 {
975 GLfloat v[17];
976
977 COPY_4FV(v, ctx->Light.Material.Attrib[e]);
978 COPY_4FV((v + 4), ctx->Light.Material.Attrib[a]);
979 COPY_4FV((v + 8), ctx->Light.Material.Attrib[d]);
980 COPY_4FV((v + 12), ctx->Light.Material.Attrib[sp]);
981 v[16] = ctx->Light.Material.Attrib[sh][0];
982 write_common_fixed(pro, i, v, 0, 17 * sizeof(GLfloat));
983 }
984
985 static GLvoid
986 write_common_fixed_light_model_product(GLcontext * ctx, slang_program * pro,
987 GLuint i, GLuint e, GLuint a)
988 {
989 GLfloat v[4];
990
991 SCALE_4V(v, ctx->Light.Material.Attrib[a], ctx->Light.Model.Ambient);
992 ACC_4V(v, ctx->Light.Material.Attrib[e]);
993 write_common_fixed(pro, i, v, 0, 4 * sizeof(GLfloat));
994 }
995
996 static GLvoid
997 write_common_fixed_light_product(GLcontext * ctx, slang_program * pro,
998 GLuint off, GLuint i, GLuint a, GLuint d,
999 GLuint s)
1000 {
1001 GLfloat v[12];
1002
1003 SCALE_4V(v, ctx->Light.Light[off].Ambient, ctx->Light.Material.Attrib[a]);
1004 SCALE_4V((v + 4), ctx->Light.Light[off].Diffuse,
1005 ctx->Light.Material.Attrib[d]);
1006 SCALE_4V((v + 8), ctx->Light.Light[off].Specular,
1007 ctx->Light.Material.Attrib[s]);
1008 write_common_fixed(pro, i, v, off, 12 * sizeof(GLfloat));
1009 }
1010
1011 static GLvoid
1012 _program_UpdateFixedUniforms(struct gl2_program_intf **intf)
1013 {
1014 GET_CURRENT_CONTEXT(ctx);
1015 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
1016 slang_program *pro = &impl->_obj.prog;
1017 GLuint i;
1018 GLfloat v[29];
1019 GLfloat *p;
1020
1021 /* MODELVIEW matrix */
1022 write_common_fixed_mat4(pro, ctx->ModelviewMatrixStack.Top, 0,
1023 SLANG_COMMON_FIXED_MODELVIEWMATRIX,
1024 SLANG_COMMON_FIXED_MODELVIEWMATRIXINVERSE,
1025 SLANG_COMMON_FIXED_MODELVIEWMATRIXTRANSPOSE,
1026 SLANG_COMMON_FIXED_MODELVIEWMATRIXINVERSETRANSPOSE);
1027
1028 /* PROJECTION matrix */
1029 write_common_fixed_mat4(pro, ctx->ProjectionMatrixStack.Top, 0,
1030 SLANG_COMMON_FIXED_PROJECTIONMATRIX,
1031 SLANG_COMMON_FIXED_PROJECTIONMATRIXINVERSE,
1032 SLANG_COMMON_FIXED_PROJECTIONMATRIXTRANSPOSE,
1033 SLANG_COMMON_FIXED_PROJECTIONMATRIXINVERSETRANSPOSE);
1034
1035 /* MVP matrix */
1036 write_common_fixed_mat4(pro, &ctx->_ModelProjectMatrix, 0,
1037 SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIX,
1038 SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIXINVERSE,
1039 SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIXTRANSPOSE,
1040 SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIXINVERSETRANSPOSE);
1041
1042 for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) {
1043 /* TEXTURE matrix */
1044 write_common_fixed_mat4(pro, ctx->TextureMatrixStack[i].Top, i,
1045 SLANG_COMMON_FIXED_TEXTUREMATRIX,
1046 SLANG_COMMON_FIXED_TEXTUREMATRIXINVERSE,
1047 SLANG_COMMON_FIXED_TEXTUREMATRIXTRANSPOSE,
1048 SLANG_COMMON_FIXED_TEXTUREMATRIXINVERSETRANSPOSE);
1049
1050 /* EYE_PLANE texture-coordinate generation */
1051 write_common_fixed(pro, SLANG_COMMON_FIXED_EYEPLANES,
1052 ctx->Texture.Unit[i].EyePlaneS, i,
1053 4 * sizeof(GLfloat));
1054 write_common_fixed(pro, SLANG_COMMON_FIXED_EYEPLANET,
1055 ctx->Texture.Unit[i].EyePlaneT, i,
1056 4 * sizeof(GLfloat));
1057 write_common_fixed(pro, SLANG_COMMON_FIXED_EYEPLANER,
1058 ctx->Texture.Unit[i].EyePlaneR, i,
1059 4 * sizeof(GLfloat));
1060 write_common_fixed(pro, SLANG_COMMON_FIXED_EYEPLANEQ,
1061 ctx->Texture.Unit[i].EyePlaneQ, i,
1062 4 * sizeof(GLfloat));
1063
1064 /* OBJECT_PLANE texture-coordinate generation */
1065 write_common_fixed(pro, SLANG_COMMON_FIXED_OBJECTPLANES,
1066 ctx->Texture.Unit[i].ObjectPlaneS, i,
1067 4 * sizeof(GLfloat));
1068 write_common_fixed(pro, SLANG_COMMON_FIXED_OBJECTPLANET,
1069 ctx->Texture.Unit[i].ObjectPlaneT, i,
1070 4 * sizeof(GLfloat));
1071 write_common_fixed(pro, SLANG_COMMON_FIXED_OBJECTPLANER,
1072 ctx->Texture.Unit[i].ObjectPlaneR, i,
1073 4 * sizeof(GLfloat));
1074 write_common_fixed(pro, SLANG_COMMON_FIXED_OBJECTPLANEQ,
1075 ctx->Texture.Unit[i].ObjectPlaneQ, i,
1076 4 * sizeof(GLfloat));
1077 }
1078
1079 /* NORMAL matrix - upper 3x3 inverse transpose of MODELVIEW matrix */
1080 p = ctx->ModelviewMatrixStack.Top->inv;
1081 v[0] = p[0];
1082 v[1] = p[4];
1083 v[2] = p[8];
1084 v[3] = p[1];
1085 v[4] = p[5];
1086 v[5] = p[9];
1087 v[6] = p[2];
1088 v[7] = p[6];
1089 v[8] = p[10];
1090 write_common_fixed(pro, SLANG_COMMON_FIXED_NORMALMATRIX, v, 0,
1091 9 * sizeof(GLfloat));
1092
1093 /* normal scale */
1094 write_common_fixed(pro, SLANG_COMMON_FIXED_NORMALSCALE,
1095 &ctx->_ModelViewInvScale, 0, sizeof(GLfloat));
1096
1097 /* depth range parameters */
1098 v[0] = ctx->Viewport.Near;
1099 v[1] = ctx->Viewport.Far;
1100 v[2] = ctx->Viewport.Far - ctx->Viewport.Near;
1101 write_common_fixed(pro, SLANG_COMMON_FIXED_DEPTHRANGE, v, 0,
1102 3 * sizeof(GLfloat));
1103
1104 /* CLIP_PLANEi */
1105 for (i = 0; i < ctx->Const.MaxClipPlanes; i++) {
1106 write_common_fixed(pro, SLANG_COMMON_FIXED_CLIPPLANE,
1107 ctx->Transform.EyeUserPlane[i], i,
1108 4 * sizeof(GLfloat));
1109 }
1110
1111 /* point parameters */
1112 v[0] = ctx->Point.Size;
1113 v[1] = ctx->Point.MinSize;
1114 v[2] = ctx->Point.MaxSize;
1115 v[3] = ctx->Point.Threshold;
1116 COPY_3FV((v + 4), ctx->Point.Params);
1117 write_common_fixed(pro, SLANG_COMMON_FIXED_POINT, v, 0,
1118 7 * sizeof(GLfloat));
1119
1120 /* material parameters */
1121 write_common_fixed_material(ctx, pro, SLANG_COMMON_FIXED_FRONTMATERIAL,
1122 MAT_ATTRIB_FRONT_EMISSION,
1123 MAT_ATTRIB_FRONT_AMBIENT,
1124 MAT_ATTRIB_FRONT_DIFFUSE,
1125 MAT_ATTRIB_FRONT_SPECULAR,
1126 MAT_ATTRIB_FRONT_SHININESS);
1127 write_common_fixed_material(ctx, pro, SLANG_COMMON_FIXED_BACKMATERIAL,
1128 MAT_ATTRIB_BACK_EMISSION,
1129 MAT_ATTRIB_BACK_AMBIENT,
1130 MAT_ATTRIB_BACK_DIFFUSE,
1131 MAT_ATTRIB_BACK_SPECULAR,
1132 MAT_ATTRIB_BACK_SHININESS);
1133
1134 for (i = 0; i < ctx->Const.MaxLights; i++) {
1135 /* light source parameters */
1136 COPY_4FV(v, ctx->Light.Light[i].Ambient);
1137 COPY_4FV((v + 4), ctx->Light.Light[i].Diffuse);
1138 COPY_4FV((v + 8), ctx->Light.Light[i].Specular);
1139 COPY_4FV((v + 12), ctx->Light.Light[i].EyePosition);
1140 COPY_2FV((v + 16), ctx->Light.Light[i].EyePosition);
1141 v[18] = ctx->Light.Light[i].EyePosition[2] + 1.0f;
1142 NORMALIZE_3FV((v + 16));
1143 v[19] = 0.0f;
1144 COPY_3V((v + 20), ctx->Light.Light[i].EyeDirection);
1145 v[23] = ctx->Light.Light[i].SpotExponent;
1146 v[24] = ctx->Light.Light[i].SpotCutoff;
1147 v[25] = ctx->Light.Light[i]._CosCutoffNeg;
1148 v[26] = ctx->Light.Light[i].ConstantAttenuation;
1149 v[27] = ctx->Light.Light[i].LinearAttenuation;
1150 v[28] = ctx->Light.Light[i].QuadraticAttenuation;
1151 write_common_fixed(pro, SLANG_COMMON_FIXED_LIGHTSOURCE, v, i,
1152 29 * sizeof(GLfloat));
1153
1154 /* light product */
1155 write_common_fixed_light_product(ctx, pro, i,
1156 SLANG_COMMON_FIXED_FRONTLIGHTPRODUCT,
1157 MAT_ATTRIB_FRONT_AMBIENT,
1158 MAT_ATTRIB_FRONT_DIFFUSE,
1159 MAT_ATTRIB_FRONT_SPECULAR);
1160 write_common_fixed_light_product(ctx, pro, i,
1161 SLANG_COMMON_FIXED_BACKLIGHTPRODUCT,
1162 MAT_ATTRIB_BACK_AMBIENT,
1163 MAT_ATTRIB_BACK_DIFFUSE,
1164 MAT_ATTRIB_BACK_SPECULAR);
1165 }
1166
1167 /* light model parameters */
1168 write_common_fixed(pro, SLANG_COMMON_FIXED_LIGHTMODEL,
1169 ctx->Light.Model.Ambient, 0, 4 * sizeof(GLfloat));
1170
1171 /* light model product */
1172 write_common_fixed_light_model_product(ctx, pro,
1173 SLANG_COMMON_FIXED_FRONTLIGHTMODELPRODUCT,
1174 MAT_ATTRIB_FRONT_EMISSION,
1175 MAT_ATTRIB_FRONT_AMBIENT);
1176 write_common_fixed_light_model_product(ctx, pro,
1177 SLANG_COMMON_FIXED_BACKLIGHTMODELPRODUCT,
1178 MAT_ATTRIB_BACK_EMISSION,
1179 MAT_ATTRIB_BACK_AMBIENT);
1180
1181 /* TEXTURE_ENV_COLOR */
1182 for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
1183 write_common_fixed(pro, SLANG_COMMON_FIXED_TEXTUREENVCOLOR,
1184 ctx->Texture.Unit[i].EnvColor, i,
1185 4 * sizeof(GLfloat));
1186 }
1187
1188 /* fog parameters */
1189 COPY_4FV(v, ctx->Fog.Color);
1190 v[4] = ctx->Fog.Density;
1191 v[5] = ctx->Fog.Start;
1192 v[6] = ctx->Fog.End;
1193 v[7] = ctx->Fog._Scale;
1194 write_common_fixed(pro, SLANG_COMMON_FIXED_FOG, v, 0, 8 * sizeof(GLfloat));
1195 }
1196
1197 static GLvoid
1198 _program_UpdateFixedAttrib(struct gl2_program_intf **intf, GLuint index,
1199 GLvoid * data, GLuint offset, GLuint size,
1200 GLboolean write)
1201 {
1202 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
1203 slang_program *pro = &impl->_obj.prog;
1204 GLuint addr;
1205
1206 addr = pro->vertex_fixed_entries[index];
1207 if (addr != ~0) {
1208 GLubyte *mem;
1209
1210 mem =
1211 (GLubyte *) pro->machines[SLANG_SHADER_VERTEX]->mem + addr +
1212 offset * size;
1213 if (write)
1214 _mesa_memcpy(mem, data, size);
1215 else
1216 _mesa_memcpy(data, mem, size);
1217 }
1218 }
1219
1220
1221 /**
1222 * Called during fragment shader execution to either load a varying
1223 * register with values, or fetch values from a varying register.
1224 * \param intf the internal program?
1225 * \param index which varying register, one of the SLANG_FRAGMENT_FIXED_*
1226 * values for example.
1227 * \param data source values to load (or dest to write to)
1228 * \param offset indicates a texture unit or generic varying attribute
1229 * \param size number of bytes to copy
1230 * \param write if true, write to the varying register, else store values
1231 * in 'data'
1232 */
1233 static GLvoid
1234 _program_UpdateFixedVarying(struct gl2_program_intf **intf, GLuint index,
1235 GLvoid * data,
1236 GLuint offset, GLuint size, GLboolean write)
1237 {
1238 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
1239 slang_program *pro = &impl->_obj.prog;
1240 GLuint addr;
1241
1242 addr = pro->fragment_fixed_entries[index];
1243 if (addr != ~0) {
1244 GLubyte *mem;
1245
1246 mem =
1247 (GLubyte *) pro->machines[SLANG_SHADER_FRAGMENT]->mem + addr +
1248 offset * size;
1249 if (write)
1250 _mesa_memcpy(mem, data, size);
1251 else
1252 _mesa_memcpy(data, mem, size);
1253 }
1254 }
1255
1256 static GLvoid
1257 _program_GetTextureImageUsage(struct gl2_program_intf **intf,
1258 GLbitfield * teximageusage)
1259 {
1260 GET_CURRENT_CONTEXT(ctx);
1261 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
1262 slang_program *pro = &impl->_obj.prog;
1263 GLuint i;
1264
1265 for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++)
1266 teximageusage[i] = 0;
1267
1268 for (i = 0; i < pro->texture_usage.count; i++) {
1269 GLuint n, addr, j;
1270
1271 n = slang_export_data_quant_elements(pro->texture_usage.table[i].quant);
1272 addr = pro->texture_usage.table[i].frag_address;
1273 for (j = 0; j < n; j++) {
1274 GLubyte *mem;
1275 GLuint image;
1276
1277 mem =
1278 (GLubyte *) pro->machines[SLANG_SHADER_FRAGMENT]->mem + addr +
1279 j * 4;
1280 image = (GLuint) * ((GLfloat *) mem);
1281 if (image >= 0 && image < ctx->Const.MaxTextureImageUnits) {
1282 switch (slang_export_data_quant_type
1283 (pro->texture_usage.table[i].quant)) {
1284 case GL_SAMPLER_1D_ARB:
1285 case GL_SAMPLER_1D_SHADOW_ARB:
1286 teximageusage[image] |= TEXTURE_1D_BIT;
1287 break;
1288 case GL_SAMPLER_2D_ARB:
1289 case GL_SAMPLER_2D_SHADOW_ARB:
1290 teximageusage[image] |= TEXTURE_2D_BIT;
1291 break;
1292 case GL_SAMPLER_3D_ARB:
1293 teximageusage[image] |= TEXTURE_3D_BIT;
1294 break;
1295 case GL_SAMPLER_CUBE_ARB:
1296 teximageusage[image] |= TEXTURE_CUBE_BIT;
1297 break;
1298 }
1299 }
1300 }
1301 }
1302
1303 /* TODO: make sure that for 0<=i<=MaxTextureImageUint bitcount(teximageuint[i])<=0 */
1304 }
1305
1306 static GLboolean
1307 _program_IsShaderPresent(struct gl2_program_intf **intf, GLenum subtype)
1308 {
1309 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
1310 slang_program *pro = &impl->_obj.prog;
1311
1312 switch (subtype) {
1313 case GL_VERTEX_SHADER_ARB:
1314 return pro->machines[SLANG_SHADER_VERTEX] != NULL;
1315 case GL_FRAGMENT_SHADER_ARB:
1316 return pro->machines[SLANG_SHADER_FRAGMENT] != NULL;
1317 default:
1318 return GL_FALSE;
1319 }
1320 }
1321
1322 static GLvoid
1323 get_active_variable(slang_active_variable * var, GLsizei maxLength,
1324 GLsizei * length, GLint * size, GLenum * type,
1325 GLchar * name)
1326 {
1327 GLsizei len;
1328
1329 len = _mesa_strlen(var->name);
1330 if (len >= maxLength)
1331 len = maxLength - 1;
1332 if (length != NULL)
1333 *length = len;
1334 *size = slang_export_data_quant_elements(var->quant);
1335 *type = slang_export_data_quant_type(var->quant);
1336 _mesa_memcpy(name, var->name, len);
1337 name[len] = '\0';
1338 }
1339
1340 static GLuint
1341 get_active_variable_max_length(slang_active_variables * vars)
1342 {
1343 GLuint i, len = 0;
1344
1345 for (i = 0; i < vars->count; i++) {
1346 GLuint n = _mesa_strlen(vars->table[i].name);
1347 if (n > len)
1348 len = n;
1349 }
1350 return len;
1351 }
1352
1353 static GLvoid
1354 _program_GetActiveUniform(struct gl2_program_intf **intf, GLuint index,
1355 GLsizei maxLength, GLsizei * length, GLint * size,
1356 GLenum * type, GLchar * name)
1357 {
1358 struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf);
1359 slang_active_variable *u = &impl->_obj.prog.active_uniforms.table[index];
1360
1361 get_active_variable(u, maxLength, length, size, type, name);
1362 }
1363
1364 static GLuint
1365 _program_GetActiveUniformMaxLength(struct gl2_program_intf **intf)
1366 {
1367 struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf);
1368
1369 return get_active_variable_max_length(&impl->_obj.prog.active_uniforms);
1370 }
1371
1372 static GLuint
1373 _program_GetActiveUniformCount(struct gl2_program_intf **intf)
1374 {
1375 struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf);
1376
1377 return impl->_obj.prog.active_uniforms.count;
1378 }
1379
1380 static GLint
1381 _program_GetUniformLocation(struct gl2_program_intf **intf,
1382 const GLchar * name)
1383 {
1384 struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf);
1385 slang_uniform_bindings *bind = &impl->_obj.prog.uniforms;
1386 GLuint i;
1387
1388 for (i = 0; i < bind->count; i++)
1389 if (_mesa_strcmp(bind->table[i].name, name) == 0)
1390 return i;
1391 return -1;
1392 }
1393
1394 /**
1395 * Write a uniform variable into program's memory.
1396 * \return GL_TRUE for success, GL_FALSE if error
1397 */
1398 static GLboolean
1399 _program_WriteUniform(struct gl2_program_intf **intf, GLint loc,
1400 GLsizei count, const GLvoid * data, GLenum type)
1401 {
1402 struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf);
1403 slang_uniform_bindings *uniforms = &impl->_obj.prog.uniforms;
1404 slang_uniform_binding *uniform;
1405 GLuint i;
1406 GLboolean convert_float_to_bool = GL_FALSE;
1407 GLboolean convert_int_to_bool = GL_FALSE;
1408 GLboolean convert_int_to_float = GL_FALSE;
1409 GLboolean types_match = GL_FALSE;
1410
1411 if (loc < 0 || loc >= uniforms->count)
1412 return GL_FALSE;
1413
1414 uniform = &uniforms->table[loc];
1415 /* TODO: check sizes */
1416 if (slang_export_data_quant_struct(uniform->quant))
1417 return GL_FALSE;
1418
1419 switch (slang_export_data_quant_type(uniform->quant)) {
1420 case GL_BOOL_ARB:
1421 types_match = (type == GL_FLOAT) || (type == GL_INT);
1422 if (type == GL_FLOAT)
1423 convert_float_to_bool = GL_TRUE;
1424 else
1425 convert_int_to_bool = GL_TRUE;
1426 break;
1427 case GL_BOOL_VEC2_ARB:
1428 types_match = (type == GL_FLOAT_VEC2_ARB) || (type == GL_INT_VEC2_ARB);
1429 if (type == GL_FLOAT_VEC2_ARB)
1430 convert_float_to_bool = GL_TRUE;
1431 else
1432 convert_int_to_bool = GL_TRUE;
1433 break;
1434 case GL_BOOL_VEC3_ARB:
1435 types_match = (type == GL_FLOAT_VEC3_ARB) || (type == GL_INT_VEC3_ARB);
1436 if (type == GL_FLOAT_VEC3_ARB)
1437 convert_float_to_bool = GL_TRUE;
1438 else
1439 convert_int_to_bool = GL_TRUE;
1440 break;
1441 case GL_BOOL_VEC4_ARB:
1442 types_match = (type == GL_FLOAT_VEC4_ARB) || (type == GL_INT_VEC4_ARB);
1443 if (type == GL_FLOAT_VEC4_ARB)
1444 convert_float_to_bool = GL_TRUE;
1445 else
1446 convert_int_to_bool = GL_TRUE;
1447 break;
1448 case GL_SAMPLER_1D_ARB:
1449 case GL_SAMPLER_2D_ARB:
1450 case GL_SAMPLER_3D_ARB:
1451 case GL_SAMPLER_CUBE_ARB:
1452 case GL_SAMPLER_1D_SHADOW_ARB:
1453 case GL_SAMPLER_2D_SHADOW_ARB:
1454 types_match = (type == GL_INT);
1455 break;
1456 default:
1457 types_match = (type == slang_export_data_quant_type(uniform->quant));
1458 break;
1459 }
1460
1461 if (!types_match)
1462 return GL_FALSE;
1463
1464 switch (type) {
1465 case GL_INT:
1466 case GL_INT_VEC2_ARB:
1467 case GL_INT_VEC3_ARB:
1468 case GL_INT_VEC4_ARB:
1469 convert_int_to_float = GL_TRUE;
1470 break;
1471 }
1472
1473 for (i = 0; i < SLANG_SHADER_MAX; i++) {
1474 if (uniform->address[i] != ~0) {
1475 void *dest
1476 = &impl->_obj.prog.machines[i]->mem[uniform->address[i] / 4];
1477 /* total number of values to copy */
1478 GLuint total
1479 = count * slang_export_data_quant_components(uniform->quant);
1480 GLuint j;
1481 if (convert_float_to_bool) {
1482 const GLfloat *src = (GLfloat *) (data);
1483 GLfloat *dst = (GLfloat *) dest;
1484 for (j = 0; j < total; j++)
1485 dst[j] = src[j] != 0.0f ? 1.0f : 0.0f;
1486 break;
1487 }
1488 else if (convert_int_to_bool) {
1489 const GLint *src = (GLint *) (data);
1490 GLfloat *dst = (GLfloat *) dest;
1491 for (j = 0; j < total; j++)
1492 dst[j] = src[j] ? 1.0f : 0.0f;
1493 break;
1494 }
1495 else if (convert_int_to_float) {
1496 const GLint *src = (GLint *) (data);
1497 GLfloat *dst = (GLfloat *) dest;
1498 for (j = 0; j < total; j++)
1499 dst[j] = (GLfloat) src[j];
1500 break;
1501 }
1502 else {
1503 _mesa_memcpy(dest, data, total * sizeof(GLfloat));
1504 break;
1505 }
1506 break;
1507 }
1508 }
1509 return GL_TRUE;
1510 }
1511
1512 /**
1513 * Read a uniform variable from program's memory.
1514 * \return GL_TRUE for success, GL_FALSE if error
1515 */
1516 static GLboolean
1517 _program_ReadUniform(struct gl2_program_intf **intf, GLint loc,
1518 GLsizei count, GLvoid *data, GLenum type)
1519 {
1520 struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf);
1521 const slang_uniform_bindings *uniforms = &impl->_obj.prog.uniforms;
1522 const slang_uniform_binding *uniform;
1523 GLuint i;
1524 GLboolean convert_bool_to_float = GL_FALSE;
1525 GLboolean convert_bool_to_int = GL_FALSE;
1526 GLboolean convert_float_to_int = GL_FALSE;
1527 GLboolean types_match = GL_FALSE;
1528
1529 if (loc < 0 || loc >= uniforms->count)
1530 return GL_FALSE;
1531
1532 uniform = &uniforms->table[loc];
1533
1534 if (slang_export_data_quant_struct(uniform->quant))
1535 return GL_FALSE;
1536
1537 switch (slang_export_data_quant_type(uniform->quant)) {
1538 case GL_BOOL_ARB:
1539 types_match = (type == GL_FLOAT) || (type == GL_INT);
1540 if (type == GL_FLOAT)
1541 convert_bool_to_float = GL_TRUE;
1542 else
1543 convert_bool_to_int = GL_TRUE;
1544 break;
1545 case GL_BOOL_VEC2_ARB:
1546 types_match = (type == GL_FLOAT_VEC2_ARB) || (type == GL_INT_VEC2_ARB);
1547 if (type == GL_FLOAT_VEC2_ARB)
1548 convert_bool_to_float = GL_TRUE;
1549 else
1550 convert_bool_to_int = GL_TRUE;
1551 break;
1552 case GL_BOOL_VEC3_ARB:
1553 types_match = (type == GL_FLOAT_VEC3_ARB) || (type == GL_INT_VEC3_ARB);
1554 if (type == GL_FLOAT_VEC3_ARB)
1555 convert_bool_to_float = GL_TRUE;
1556 else
1557 convert_bool_to_int = GL_TRUE;
1558 break;
1559 case GL_BOOL_VEC4_ARB:
1560 types_match = (type == GL_FLOAT_VEC4_ARB) || (type == GL_INT_VEC4_ARB);
1561 if (type == GL_FLOAT_VEC4_ARB)
1562 convert_bool_to_float = GL_TRUE;
1563 else
1564 convert_bool_to_int = GL_TRUE;
1565 break;
1566 case GL_SAMPLER_1D_ARB:
1567 case GL_SAMPLER_2D_ARB:
1568 case GL_SAMPLER_3D_ARB:
1569 case GL_SAMPLER_CUBE_ARB:
1570 case GL_SAMPLER_1D_SHADOW_ARB:
1571 case GL_SAMPLER_2D_SHADOW_ARB:
1572 types_match = (type == GL_INT);
1573 break;
1574 default:
1575 /* uniform is a float type */
1576 types_match = (type == GL_FLOAT);
1577 break;
1578 }
1579
1580 if (!types_match)
1581 return GL_FALSE;
1582
1583 switch (type) {
1584 case GL_INT:
1585 case GL_INT_VEC2_ARB:
1586 case GL_INT_VEC3_ARB:
1587 case GL_INT_VEC4_ARB:
1588 convert_float_to_int = GL_TRUE;
1589 break;
1590 }
1591
1592 for (i = 0; i < SLANG_SHADER_MAX; i++) {
1593 if (uniform->address[i] != ~0) {
1594 /* XXX if bools are really implemented as floats, some of this
1595 * could probably be culled out.
1596 */
1597 const void *source
1598 = &impl->_obj.prog.machines[i]->mem[uniform->address[i] / 4];
1599 /* total number of values to copy */
1600 const GLuint total
1601 = count * slang_export_data_quant_components(uniform->quant);
1602 GLuint j;
1603 if (convert_bool_to_float) {
1604 GLfloat *dst = (GLfloat *) (data);
1605 const GLfloat *src = (GLfloat *) source;
1606 for (j = 0; j < total; j++)
1607 dst[j] = src[j] == 0.0 ? 0.0 : 1.0;
1608 }
1609 else if (convert_bool_to_int) {
1610 GLint *dst = (GLint *) (data);
1611 const GLfloat *src = (GLfloat *) source;
1612 for (j = 0; j < total; j++)
1613 dst[j] = src[j] == 0.0 ? 0 : 1;
1614 }
1615 else if (convert_float_to_int) {
1616 GLint *dst = (GLint *) (data);
1617 const GLfloat *src = (GLfloat *) source;
1618 for (j = 0; j < total; j++)
1619 dst[j] = (GLint) src[j];
1620 }
1621 else {
1622 /* no type conversion needed */
1623 _mesa_memcpy(data, source, total * sizeof(GLfloat));
1624 }
1625 break;
1626 } /* if */
1627 } /* for */
1628
1629 return GL_TRUE;
1630 }
1631
1632
1633 static GLvoid
1634 _program_GetActiveAttrib(struct gl2_program_intf **intf, GLuint index,
1635 GLsizei maxLength, GLsizei * length, GLint * size,
1636 GLenum * type, GLchar * name)
1637 {
1638 struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf);
1639 slang_active_variable *a = &impl->_obj.prog.active_attribs.table[index];
1640
1641 get_active_variable(a, maxLength, length, size, type, name);
1642 }
1643
1644 static GLuint
1645 _program_GetActiveAttribMaxLength(struct gl2_program_intf **intf)
1646 {
1647 struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf);
1648
1649 return get_active_variable_max_length(&impl->_obj.prog.active_attribs);
1650 }
1651
1652 static GLuint
1653 _program_GetActiveAttribCount(struct gl2_program_intf **intf)
1654 {
1655 struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf);
1656
1657 return impl->_obj.prog.active_attribs.count;
1658 }
1659
1660 static GLint
1661 _program_GetAttribLocation(struct gl2_program_intf **intf,
1662 const GLchar * name)
1663 {
1664 struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf);
1665 slang_attrib_bindings *attribs = &impl->_obj.prog.attribs;
1666 GLuint i;
1667
1668 for (i = 0; i < attribs->binding_count; i++)
1669 if (_mesa_strcmp(attribs->bindings[i].name, name) == 0)
1670 return attribs->bindings[i].first_slot_index;
1671 return -1;
1672 }
1673
1674 static GLvoid
1675 _program_OverrideAttribBinding(struct gl2_program_intf **intf, GLuint index,
1676 const GLchar * name)
1677 {
1678 GET_CURRENT_CONTEXT(ctx);
1679 struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf);
1680 slang_program *pro = &impl->_obj.prog;
1681
1682 if (!_slang_attrib_overrides_add(&pro->attrib_overrides, index, name))
1683 _mesa_error(ctx, GL_OUT_OF_MEMORY, "_program_OverrideAttribBinding");
1684 }
1685
1686 static GLvoid
1687 _program_WriteAttrib(struct gl2_program_intf **intf, GLuint index,
1688 const GLfloat * value)
1689 {
1690 struct gl2_program_impl *impl = (struct gl2_program_impl *) (intf);
1691 slang_program *pro = &impl->_obj.prog;
1692 slang_attrib_slot *slot = &pro->attribs.slots[index];
1693
1694 /*
1695 * Generic attributes can be allocated in a shader with scalar, vec
1696 * or mat type. For scalar and vec types (specifically float, vec2
1697 * and vec3) this is simple - just ignore the extra components. For
1698 * mat type this is more complicated - the vertex_shader spec
1699 * requires to store every column of a matrix in a separate attrib
1700 * slot. To prvent from overwriting data from neighbouring matrix
1701 * columns, the "fill" information is kept to know how many
1702 * components to copy.
1703 */
1704
1705 if (slot->addr != ~0)
1706 _mesa_memcpy(&pro->machines[SLANG_SHADER_VERTEX]->mem[slot->addr / 4].
1707 _float, value, slot->fill * sizeof(GLfloat));
1708 }
1709
1710 static GLvoid
1711 _program_UpdateVarying(struct gl2_program_intf **intf, GLuint index,
1712 GLfloat * value, GLboolean vert)
1713 {
1714 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
1715 slang_program *pro = &impl->_obj.prog;
1716 GLuint addr;
1717
1718 if (index >= pro->varyings.slot_count)
1719 return;
1720 if (vert)
1721 addr = pro->varyings.slots[index].vert_addr / 4;
1722 else
1723 addr = pro->varyings.slots[index].frag_addr / 4;
1724 if (addr != ~0) {
1725 if (vert)
1726 *value = pro->machines[SLANG_SHADER_VERTEX]->mem[addr]._float;
1727 else
1728 pro->machines[SLANG_SHADER_FRAGMENT]->mem[addr]._float = *value;
1729 }
1730 }
1731
1732 static struct gl2_program_intf _program_vftbl = {
1733 {
1734 {
1735 {
1736 _unknown_AddRef,
1737 _unknown_Release,
1738 _program_QueryInterface
1739 },
1740 _generic_Delete,
1741 _program_GetType,
1742 _generic_GetName,
1743 _generic_GetDeleteStatus,
1744 _generic_GetInfoLog,
1745 _generic_GetInfoLogLength
1746 },
1747 _program_Attach,
1748 _container_Detach,
1749 _container_GetAttachedCount,
1750 _container_GetAttached
1751 },
1752 _program_GetLinkStatus,
1753 _program_GetValidateStatus,
1754 _program_Link,
1755 _program_Validate,
1756 _program_UpdateFixedUniforms,
1757 _program_UpdateFixedAttrib,
1758 _program_UpdateFixedVarying,
1759 _program_GetTextureImageUsage,
1760 _program_IsShaderPresent,
1761 _program_GetActiveUniform,
1762 _program_GetActiveUniformMaxLength,
1763 _program_GetActiveUniformCount,
1764 _program_GetUniformLocation,
1765 _program_WriteUniform,
1766 _program_ReadUniform,
1767 _program_GetActiveAttrib,
1768 _program_GetActiveAttribMaxLength,
1769 _program_GetActiveAttribCount,
1770 _program_GetAttribLocation,
1771 _program_OverrideAttribBinding,
1772 _program_WriteAttrib,
1773 _program_UpdateVarying
1774 };
1775
1776 static void
1777 _program_constructor(struct gl2_program_impl *impl)
1778 {
1779 _container_constructor((struct gl2_container_impl *) impl);
1780 impl->_vftbl = &_program_vftbl;
1781 impl->_obj._container._generic._unknown._destructor = _program_destructor;
1782 impl->_obj.link_status = GL_FALSE;
1783 impl->_obj.validate_status = GL_FALSE;
1784 #if USE_3DLABS_FRONTEND
1785 impl->_obj.linker = ShConstructLinker(EShExVertexFragment, 0);
1786 impl->_obj.uniforms = ShConstructUniformMap();
1787 #endif
1788 _slang_program_ctr(&impl->_obj.prog);
1789 }
1790
1791 struct gl2_fragment_shader_obj
1792 {
1793 struct gl2_shader_obj _shader;
1794 };
1795
1796 struct gl2_fragment_shader_impl
1797 {
1798 struct gl2_fragment_shader_intf *_vftbl;
1799 struct gl2_fragment_shader_obj _obj;
1800 };
1801
1802 static void
1803 _fragment_shader_destructor(struct gl2_unknown_intf **intf)
1804 {
1805 struct gl2_fragment_shader_impl *impl =
1806 (struct gl2_fragment_shader_impl *) intf;
1807
1808 (void) impl;
1809 /* TODO free fragment shader data */
1810
1811 _shader_destructor(intf);
1812 }
1813
1814 static struct gl2_unknown_intf **
1815 _fragment_shader_QueryInterface(struct gl2_unknown_intf **intf,
1816 enum gl2_uiid uiid)
1817 {
1818 if (uiid == UIID_FRAGMENT_SHADER) {
1819 (**intf).AddRef(intf);
1820 return intf;
1821 }
1822 return _shader_QueryInterface(intf, uiid);
1823 }
1824
1825 static GLenum
1826 _fragment_shader_GetSubType(struct gl2_shader_intf **intf)
1827 {
1828 return GL_FRAGMENT_SHADER_ARB;
1829 }
1830
1831 static struct gl2_fragment_shader_intf _fragment_shader_vftbl = {
1832 {
1833 {
1834 {
1835 _unknown_AddRef,
1836 _unknown_Release,
1837 _fragment_shader_QueryInterface
1838 },
1839 _generic_Delete,
1840 _shader_GetType,
1841 _generic_GetName,
1842 _generic_GetDeleteStatus,
1843 _shader_GetInfoLog,
1844 _shader_GetInfoLogLength
1845 },
1846 _fragment_shader_GetSubType,
1847 _shader_GetCompileStatus,
1848 _shader_SetSource,
1849 _shader_GetSource,
1850 _shader_Compile
1851 }
1852 };
1853
1854 static void
1855 _fragment_shader_constructor(struct gl2_fragment_shader_impl *impl)
1856 {
1857 _shader_constructor((struct gl2_shader_impl *) impl);
1858 impl->_vftbl = &_fragment_shader_vftbl;
1859 impl->_obj._shader._generic._unknown._destructor =
1860 _fragment_shader_destructor;
1861 #if USE_3DLABS_FRONTEND
1862 impl->_obj._shader._3dlabs_shhandle._obj.handle =
1863 ShConstructCompiler(EShLangFragment, 0);
1864 #endif
1865 }
1866
1867 struct gl2_vertex_shader_obj
1868 {
1869 struct gl2_shader_obj _shader;
1870 };
1871
1872 struct gl2_vertex_shader_impl
1873 {
1874 struct gl2_vertex_shader_intf *_vftbl;
1875 struct gl2_vertex_shader_obj _obj;
1876 };
1877
1878 static void
1879 _vertex_shader_destructor(struct gl2_unknown_intf **intf)
1880 {
1881 struct gl2_vertex_shader_impl *impl =
1882 (struct gl2_vertex_shader_impl *) intf;
1883
1884 (void) impl;
1885 /* TODO free vertex shader data */
1886
1887 _shader_destructor(intf);
1888 }
1889
1890 static struct gl2_unknown_intf **
1891 _vertex_shader_QueryInterface(struct gl2_unknown_intf **intf,
1892 enum gl2_uiid uiid)
1893 {
1894 if (uiid == UIID_VERTEX_SHADER) {
1895 (**intf).AddRef(intf);
1896 return intf;
1897 }
1898 return _shader_QueryInterface(intf, uiid);
1899 }
1900
1901 static GLenum
1902 _vertex_shader_GetSubType(struct gl2_shader_intf **intf)
1903 {
1904 return GL_VERTEX_SHADER_ARB;
1905 }
1906
1907 static struct gl2_vertex_shader_intf _vertex_shader_vftbl = {
1908 {
1909 {
1910 {
1911 _unknown_AddRef,
1912 _unknown_Release,
1913 _vertex_shader_QueryInterface
1914 },
1915 _generic_Delete,
1916 _shader_GetType,
1917 _generic_GetName,
1918 _generic_GetDeleteStatus,
1919 _shader_GetInfoLog,
1920 _shader_GetInfoLogLength
1921 },
1922 _vertex_shader_GetSubType,
1923 _shader_GetCompileStatus,
1924 _shader_SetSource,
1925 _shader_GetSource,
1926 _shader_Compile
1927 }
1928 };
1929
1930 static void
1931 _vertex_shader_constructor(struct gl2_vertex_shader_impl *impl)
1932 {
1933 _shader_constructor((struct gl2_shader_impl *) impl);
1934 impl->_vftbl = &_vertex_shader_vftbl;
1935 impl->_obj._shader._generic._unknown._destructor =
1936 _vertex_shader_destructor;
1937 #if USE_3DLABS_FRONTEND
1938 impl->_obj._shader._3dlabs_shhandle._obj.handle =
1939 ShConstructCompiler(EShLangVertex, 0);
1940 #endif
1941 }
1942
1943 struct gl2_debug_obj
1944 {
1945 struct gl2_generic_obj _generic;
1946 };
1947
1948 struct gl2_debug_impl
1949 {
1950 struct gl2_debug_intf *_vftbl;
1951 struct gl2_debug_obj _obj;
1952 };
1953
1954 static GLvoid
1955 _debug_destructor(struct gl2_unknown_intf **intf)
1956 {
1957 struct gl2_debug_impl *impl = (struct gl2_debug_impl *) (intf);
1958
1959 (void) (impl);
1960 /* TODO */
1961
1962 _generic_destructor(intf);
1963 }
1964
1965 static struct gl2_unknown_intf **
1966 _debug_QueryInterface(struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
1967 {
1968 if (uiid == UIID_DEBUG) {
1969 (**intf).AddRef(intf);
1970 return intf;
1971 }
1972 return _generic_QueryInterface(intf, uiid);
1973 }
1974
1975 static GLenum
1976 _debug_GetType(struct gl2_generic_intf **intf)
1977 {
1978 return /*GL_DEBUG_OBJECT_MESA */ 0;
1979 }
1980
1981 static GLvoid
1982 _debug_ClearDebugLog(struct gl2_debug_intf **intf, GLenum logType,
1983 GLenum shaderType)
1984 {
1985 struct gl2_debug_impl *impl = (struct gl2_debug_impl *) (intf);
1986
1987 (void) (impl);
1988 /* TODO */
1989 }
1990
1991 static GLvoid
1992 _debug_GetDebugLog(struct gl2_debug_intf **intf, GLenum logType,
1993 GLenum shaderType, GLsizei maxLength, GLsizei * length,
1994 GLcharARB * infoLog)
1995 {
1996 struct gl2_debug_impl *impl = (struct gl2_debug_impl *) (intf);
1997
1998 (void) (impl);
1999 /* TODO */
2000 }
2001
2002 static GLsizei
2003 _debug_GetDebugLogLength(struct gl2_debug_intf **intf, GLenum logType,
2004 GLenum shaderType)
2005 {
2006 struct gl2_debug_impl *impl = (struct gl2_debug_impl *) (intf);
2007
2008 (void) (impl);
2009 /* TODO */
2010
2011 return 0;
2012 }
2013
2014 static struct gl2_debug_intf _debug_vftbl = {
2015 {
2016 {
2017 _unknown_AddRef,
2018 _unknown_Release,
2019 _debug_QueryInterface
2020 },
2021 _generic_Delete,
2022 _debug_GetType,
2023 _generic_GetName,
2024 _generic_GetDeleteStatus,
2025 _generic_GetInfoLog,
2026 _generic_GetInfoLogLength
2027 },
2028 _debug_ClearDebugLog,
2029 _debug_GetDebugLog,
2030 _debug_GetDebugLogLength
2031 };
2032
2033 static GLvoid
2034 _debug_constructor(struct gl2_debug_impl *impl)
2035 {
2036 _generic_constructor((struct gl2_generic_impl *) (impl));
2037 impl->_vftbl = &_debug_vftbl;
2038 impl->_obj._generic._unknown._destructor = _debug_destructor;
2039 }
2040
2041 GLhandleARB
2042 _mesa_3dlabs_create_shader_object(GLenum shaderType)
2043 {
2044 switch (shaderType) {
2045 case GL_FRAGMENT_SHADER_ARB:
2046 {
2047 struct gl2_fragment_shader_impl *x =
2048 (struct gl2_fragment_shader_impl *)
2049 _mesa_malloc(sizeof(struct gl2_fragment_shader_impl));
2050
2051 if (x != NULL) {
2052 _fragment_shader_constructor(x);
2053 return x->_obj._shader._generic.name;
2054 }
2055 }
2056 break;
2057 case GL_VERTEX_SHADER_ARB:
2058 {
2059 struct gl2_vertex_shader_impl *x = (struct gl2_vertex_shader_impl *)
2060 _mesa_malloc(sizeof(struct gl2_vertex_shader_impl));
2061
2062 if (x != NULL) {
2063 _vertex_shader_constructor(x);
2064 return x->_obj._shader._generic.name;
2065 }
2066 }
2067 break;
2068 }
2069
2070 return 0;
2071 }
2072
2073 GLhandleARB
2074 _mesa_3dlabs_create_program_object(void)
2075 {
2076 struct gl2_program_impl *x = (struct gl2_program_impl *)
2077 _mesa_malloc(sizeof(struct gl2_program_impl));
2078
2079 if (x != NULL) {
2080 _program_constructor(x);
2081 return x->_obj._container._generic.name;
2082 }
2083
2084 return 0;
2085 }
2086
2087 GLhandleARB
2088 _mesa_3dlabs_create_debug_object(GLvoid)
2089 {
2090 struct gl2_debug_impl *obj;
2091
2092 obj =
2093 (struct gl2_debug_impl *) (_mesa_malloc(sizeof(struct gl2_debug_impl)));
2094 if (obj != NULL) {
2095 _debug_constructor(obj);
2096 return obj->_obj._generic.name;
2097 }
2098 return 0;
2099 }
2100
2101 #include "slang_assemble.h"
2102 #include "slang_execute.h"
2103
2104 int
2105 _slang_fetch_discard(struct gl2_program_intf **pro, GLboolean * val)
2106 {
2107 struct gl2_program_impl *impl;
2108
2109 impl = (struct gl2_program_impl *) pro;
2110 *val =
2111 impl->_obj.prog.machines[SLANG_SHADER_FRAGMENT]->
2112 kill ? GL_TRUE : GL_FALSE;
2113 return 1;
2114 }
2115
2116 static GLvoid
2117 exec_shader(struct gl2_program_intf **pro, GLuint i)
2118 {
2119 struct gl2_program_impl *impl;
2120 slang_program *p;
2121
2122 impl = (struct gl2_program_impl *) pro;
2123 p = &impl->_obj.prog;
2124
2125 slang_machine_init(p->machines[i]);
2126 p->machines[i]->ip = p->code[i][SLANG_COMMON_CODE_MAIN];
2127
2128 _slang_execute2(p->assemblies[i], p->machines[i]);
2129 }
2130
2131 GLvoid
2132 _slang_exec_fragment_shader(struct gl2_program_intf **pro)
2133 {
2134 exec_shader(pro, SLANG_SHADER_FRAGMENT);
2135 }
2136
2137 GLvoid
2138 _slang_exec_vertex_shader(struct gl2_program_intf **pro)
2139 {
2140 exec_shader(pro, SLANG_SHADER_VERTEX);
2141 }
2142
2143 #endif
2144
2145 void
2146 _mesa_init_shaderobjects_3dlabs(GLcontext * ctx)
2147 {
2148 #if USE_3DLABS_FRONTEND
2149 _glslang_3dlabs_InitProcess();
2150 _glslang_3dlabs_ShInitialize();
2151 #endif
2152 }