More GLSL code:
[mesa.git] / src / mesa / shader / shaderobjects_3dlabs.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 6.5
4 *
5 * Copyright (C) 2005-2006 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 /**
26 * \file shaderobjects_3dlabs.c
27 * shader objects definitions for 3dlabs compiler
28 * \author Michal Krol
29 */
30
31 /* Set this to 1 when we are ready to use 3dlabs' front-end */
32 #define USE_3DLABS_FRONTEND 0
33
34 #include "imports.h"
35 #include "hash.h"
36 #include "shaderobjects.h"
37
38 #if USE_3DLABS_FRONTEND
39 #include "slang_mesa.h"
40 #include "Public/ShaderLang.h"
41 #else
42 #include "slang_link.h"
43 #endif
44
45 struct gl2_unknown_obj
46 {
47 GLuint reference_count;
48 void (* _destructor) (struct gl2_unknown_intf **);
49 };
50
51 struct gl2_unknown_impl
52 {
53 struct gl2_unknown_intf *_vftbl;
54 struct gl2_unknown_obj _obj;
55 };
56
57 static void
58 _unknown_destructor (struct gl2_unknown_intf **intf)
59 {
60 }
61
62 static void
63 _unknown_AddRef (struct gl2_unknown_intf **intf)
64 {
65 struct gl2_unknown_impl *impl = (struct gl2_unknown_impl *) intf;
66
67 impl->_obj.reference_count++;
68 }
69
70 static void
71 _unknown_Release (struct gl2_unknown_intf **intf)
72 {
73 struct gl2_unknown_impl *impl = (struct gl2_unknown_impl *) intf;
74
75 impl->_obj.reference_count--;
76 if (impl->_obj.reference_count == 0)
77 {
78 impl->_obj._destructor (intf);
79 _mesa_free ((void *) intf);
80 }
81 }
82
83 static struct gl2_unknown_intf **
84 _unknown_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
85 {
86 if (uiid == UIID_UNKNOWN)
87 {
88 (**intf).AddRef (intf);
89 return intf;
90 }
91 return NULL;
92 }
93
94 static struct gl2_unknown_intf _unknown_vftbl = {
95 _unknown_AddRef,
96 _unknown_Release,
97 _unknown_QueryInterface
98 };
99
100 static void
101 _unknown_constructor (struct gl2_unknown_impl *impl)
102 {
103 impl->_vftbl = &_unknown_vftbl;
104 impl->_obj.reference_count = 1;
105 impl->_obj._destructor = _unknown_destructor;
106 }
107
108 struct gl2_unkinner_obj
109 {
110 struct gl2_unknown_intf **unkouter;
111 };
112
113 struct gl2_unkinner_impl
114 {
115 struct gl2_unknown_intf *_vftbl;
116 struct gl2_unkinner_obj _obj;
117 };
118
119 static void
120 _unkinner_destructor (struct gl2_unknown_intf **intf)
121 {
122 }
123
124 static void
125 _unkinner_AddRef (struct gl2_unknown_intf **intf)
126 {
127 struct gl2_unkinner_impl *impl = (struct gl2_unkinner_impl *) intf;
128
129 (**impl->_obj.unkouter).AddRef (impl->_obj.unkouter);
130 }
131
132 static void
133 _unkinner_Release (struct gl2_unknown_intf **intf)
134 {
135 struct gl2_unkinner_impl *impl = (struct gl2_unkinner_impl *) intf;
136
137 (**impl->_obj.unkouter).Release (impl->_obj.unkouter);
138 }
139
140 static struct gl2_unknown_intf **
141 _unkinner_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
142 {
143 struct gl2_unkinner_impl *impl = (struct gl2_unkinner_impl *) intf;
144
145 return (**impl->_obj.unkouter).QueryInterface (impl->_obj.unkouter, uiid);
146 }
147
148 static struct gl2_unknown_intf _unkinner_vftbl = {
149 _unkinner_AddRef,
150 _unkinner_Release,
151 _unkinner_QueryInterface
152 };
153
154 static void
155 _unkinner_constructor (struct gl2_unkinner_impl *impl, struct gl2_unknown_intf **outer)
156 {
157 impl->_vftbl = &_unkinner_vftbl;
158 impl->_obj.unkouter = outer;
159 }
160
161 struct gl2_generic_obj
162 {
163 struct gl2_unknown_obj _unknown;
164 GLhandleARB name;
165 GLboolean delete_status;
166 GLcharARB *info_log;
167 };
168
169 struct gl2_generic_impl
170 {
171 struct gl2_generic_intf *_vftbl;
172 struct gl2_generic_obj _obj;
173 };
174
175 static void
176 _generic_destructor (struct gl2_unknown_intf **intf)
177 {
178 GET_CURRENT_CONTEXT(ctx);
179 struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf;
180
181 _mesa_free ((void *) impl->_obj.info_log);
182
183 _glthread_LOCK_MUTEX (ctx->Shared->Mutex);
184 _mesa_HashRemove (ctx->Shared->GL2Objects, impl->_obj.name);
185 _glthread_UNLOCK_MUTEX (ctx->Shared->Mutex);
186
187 _unknown_destructor (intf);
188 }
189
190 static struct gl2_unknown_intf **
191 _generic_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
192 {
193 if (uiid == UIID_GENERIC)
194 {
195 (**intf).AddRef (intf);
196 return intf;
197 }
198 return _unknown_QueryInterface (intf, uiid);
199 }
200
201 static void
202 _generic_Delete (struct gl2_generic_intf **intf)
203 {
204 struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf;
205
206 if (impl->_obj.delete_status == GL_FALSE)
207 {
208 impl->_obj.delete_status = GL_TRUE;
209 (**intf)._unknown.Release ((struct gl2_unknown_intf **) intf);
210 }
211 }
212
213 static GLhandleARB
214 _generic_GetName (struct gl2_generic_intf **intf)
215 {
216 struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf;
217
218 return impl->_obj.name;
219 }
220
221 static GLboolean
222 _generic_GetDeleteStatus (struct gl2_generic_intf **intf)
223 {
224 struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf;
225
226 return impl->_obj.delete_status;
227 }
228
229 static const GLcharARB *
230 _generic_GetInfoLog (struct gl2_generic_intf **intf)
231 {
232 struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf;
233
234 return impl->_obj.info_log;
235 }
236
237 static struct gl2_generic_intf _generic_vftbl = {
238 {
239 _unknown_AddRef,
240 _unknown_Release,
241 _generic_QueryInterface
242 },
243 _generic_Delete,
244 NULL, /* abstract GetType */
245 _generic_GetName,
246 _generic_GetDeleteStatus,
247 _generic_GetInfoLog
248 };
249
250 static void
251 _generic_constructor (struct gl2_generic_impl *impl)
252 {
253 GET_CURRENT_CONTEXT(ctx);
254
255 _unknown_constructor ((struct gl2_unknown_impl *) impl);
256 impl->_vftbl = &_generic_vftbl;
257 impl->_obj._unknown._destructor = _generic_destructor;
258 impl->_obj.delete_status = GL_FALSE;
259 impl->_obj.info_log = NULL;
260
261 _glthread_LOCK_MUTEX (ctx->Shared->Mutex);
262 impl->_obj.name = _mesa_HashFindFreeKeyBlock (ctx->Shared->GL2Objects, 1);
263 _mesa_HashInsert (ctx->Shared->GL2Objects, impl->_obj.name, (void *) impl);
264 _glthread_UNLOCK_MUTEX (ctx->Shared->Mutex);
265 }
266
267 struct gl2_container_obj
268 {
269 struct gl2_generic_obj _generic;
270 struct gl2_generic_intf ***attached;
271 GLuint attached_count;
272 };
273
274 struct gl2_container_impl
275 {
276 struct gl2_container_intf *_vftbl;
277 struct gl2_container_obj _obj;
278 };
279
280 static void
281 _container_destructor (struct gl2_unknown_intf **intf)
282 {
283 struct gl2_container_impl *impl = (struct gl2_container_impl *) intf;
284 GLuint i;
285
286 for (i = 0; i < impl->_obj.attached_count; i++)
287 {
288 struct gl2_generic_intf **x = impl->_obj.attached[i];
289 (**x)._unknown.Release ((struct gl2_unknown_intf **) x);
290 }
291
292 _generic_destructor (intf);
293 }
294
295 static struct gl2_unknown_intf **
296 _container_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
297 {
298 if (uiid == UIID_CONTAINER)
299 {
300 (**intf).AddRef (intf);
301 return intf;
302 }
303 return _generic_QueryInterface (intf, uiid);
304 }
305
306 static GLboolean
307 _container_Attach (struct gl2_container_intf **intf, struct gl2_generic_intf **att)
308 {
309 GET_CURRENT_CONTEXT(ctx);
310 struct gl2_container_impl *impl = (struct gl2_container_impl *) intf;
311 GLuint i;
312
313 for (i = 0; i < impl->_obj.attached_count; i++)
314 if (impl->_obj.attached[i] == att)
315 {
316 _mesa_error (ctx, GL_INVALID_OPERATION, "_container_Attach");
317 return GL_FALSE;
318 }
319
320 impl->_obj.attached = (struct gl2_generic_intf ***) _mesa_realloc (impl->_obj.attached,
321 impl->_obj.attached_count * sizeof (*impl->_obj.attached), (impl->_obj.attached_count + 1) *
322 sizeof (*impl->_obj.attached));
323 if (impl->_obj.attached == NULL)
324 return GL_FALSE;
325
326 impl->_obj.attached[impl->_obj.attached_count] = att;
327 impl->_obj.attached_count++;
328 (**att)._unknown.AddRef ((struct gl2_unknown_intf **) att);
329 return GL_TRUE;
330 }
331
332 static GLboolean
333 _container_Detach (struct gl2_container_intf **intf, struct gl2_generic_intf **att)
334 {
335 GET_CURRENT_CONTEXT(ctx);
336 struct gl2_container_impl *impl = (struct gl2_container_impl *) intf;
337 GLuint i, j;
338
339 for (i = 0; i < impl->_obj.attached_count; i++)
340 if (impl->_obj.attached[i] == att)
341 {
342 for (j = i; j < impl->_obj.attached_count - 1; j++)
343 impl->_obj.attached[j] = impl->_obj.attached[j + 1];
344 impl->_obj.attached = (struct gl2_generic_intf ***) _mesa_realloc (impl->_obj.attached,
345 impl->_obj.attached_count * sizeof (*impl->_obj.attached),
346 (impl->_obj.attached_count - 1) * sizeof (*impl->_obj.attached));
347 impl->_obj.attached_count--;
348 (**att)._unknown.Release ((struct gl2_unknown_intf **) att);
349 return GL_TRUE;
350 }
351
352 _mesa_error (ctx, GL_INVALID_OPERATION, "_container_Detach");
353 return GL_FALSE;
354 }
355
356 static GLsizei
357 _container_GetAttachedCount (struct gl2_container_intf **intf)
358 {
359 struct gl2_container_impl *impl = (struct gl2_container_impl *) intf;
360
361 return impl->_obj.attached_count;
362 }
363
364 static struct gl2_generic_intf **
365 _container_GetAttached (struct gl2_container_intf **intf, GLuint index)
366 {
367 struct gl2_container_impl *impl = (struct gl2_container_impl *) intf;
368
369 (**impl->_obj.attached[index])._unknown.AddRef (
370 (struct gl2_unknown_intf **)impl->_obj.attached[index]);
371 return impl->_obj.attached[index];
372 }
373
374 static struct gl2_container_intf _container_vftbl = {
375 {
376 {
377 _unknown_AddRef,
378 _unknown_Release,
379 _container_QueryInterface
380 },
381 _generic_Delete,
382 NULL, /* abstract GetType */
383 _generic_GetName,
384 _generic_GetDeleteStatus,
385 _generic_GetInfoLog
386 },
387 _container_Attach,
388 _container_Detach,
389 _container_GetAttachedCount,
390 _container_GetAttached
391 };
392
393 static void
394 _container_constructor (struct gl2_container_impl *impl)
395 {
396 _generic_constructor ((struct gl2_generic_impl *) impl);
397 impl->_vftbl = &_container_vftbl;
398 impl->_obj._generic._unknown._destructor = _container_destructor;
399 impl->_obj.attached = NULL;
400 impl->_obj.attached_count = 0;
401 }
402
403 struct gl2_3dlabs_shhandle_obj
404 {
405 struct gl2_unkinner_obj _unknown;
406 #if USE_3DLABS_FRONTEND
407 ShHandle handle;
408 #endif
409 };
410
411 struct gl2_3dlabs_shhandle_impl
412 {
413 struct gl2_3dlabs_shhandle_intf *_vftbl;
414 struct gl2_3dlabs_shhandle_obj _obj;
415 };
416
417 static void
418 _3dlabs_shhandle_destructor (struct gl2_unknown_intf **intf)
419 {
420 #if USE_3DLABS_FRONTEND
421 struct gl2_3dlabs_shhandle_impl *impl = (struct gl2_3dlabs_shhandle_impl *) intf;
422 ShDestruct (impl->_obj.handle);
423 #endif
424 _unkinner_destructor (intf);
425 }
426
427 static GLvoid *
428 _3dlabs_shhandle_GetShHandle (struct gl2_3dlabs_shhandle_intf **intf)
429 {
430 #if USE_3DLABS_FRONTEND
431 struct gl2_3dlabs_shhandle_impl *impl = (struct gl2_3dlabs_shhandle_impl *) intf;
432 return impl->_obj.handle;
433 #else
434 return NULL;
435 #endif
436 }
437
438 static struct gl2_3dlabs_shhandle_intf _3dlabs_shhandle_vftbl = {
439 {
440 _unkinner_AddRef,
441 _unkinner_Release,
442 _unkinner_QueryInterface
443 },
444 _3dlabs_shhandle_GetShHandle
445 };
446
447 static void
448 _3dlabs_shhandle_constructor (struct gl2_3dlabs_shhandle_impl *impl, struct gl2_unknown_intf **outer)
449 {
450 _unkinner_constructor ((struct gl2_unkinner_impl *) impl, outer);
451 impl->_vftbl = &_3dlabs_shhandle_vftbl;
452 #if USE_3DLABS_FRONTEND
453 impl->_obj.handle = NULL;
454 #endif
455 }
456
457 struct gl2_shader_obj
458 {
459 struct gl2_generic_obj _generic;
460 struct gl2_3dlabs_shhandle_impl _3dlabs_shhandle;
461 GLboolean compile_status;
462 GLcharARB *source;
463 GLint *offsets;
464 GLsizei offset_count;
465 slang_translation_unit unit;
466 };
467
468 struct gl2_shader_impl
469 {
470 struct gl2_shader_intf *_vftbl;
471 struct gl2_shader_obj _obj;
472 };
473
474 static void
475 _shader_destructor (struct gl2_unknown_intf **intf)
476 {
477 struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
478
479 _mesa_free ((void *) impl->_obj.source);
480 _mesa_free ((void *) impl->_obj.offsets);
481 _3dlabs_shhandle_destructor ((struct gl2_unknown_intf **) &impl->_obj._3dlabs_shhandle._vftbl);
482 _generic_destructor (intf);
483 }
484
485 static struct gl2_unknown_intf **
486 _shader_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
487 {
488 #if USE_3DLABS_FRONTEND
489 struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
490 #endif
491
492 if (uiid == UIID_SHADER)
493 {
494 (**intf).AddRef (intf);
495 return intf;
496 }
497 #if USE_3DLABS_FRONTEND
498 if (uiid == UIID_3DLABS_SHHANDLE)
499 {
500 (**intf).AddRef (intf);
501 return (struct gl2_unknown_intf **) &impl->_obj._3dlabs_shhandle._vftbl;
502 }
503 #endif
504 return _generic_QueryInterface (intf, uiid);
505 }
506
507 static GLenum
508 _shader_GetType (struct gl2_generic_intf **intf)
509 {
510 return GL_SHADER_OBJECT_ARB;
511 }
512
513 static GLboolean
514 _shader_GetCompileStatus (struct gl2_shader_intf **intf)
515 {
516 struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
517
518 return impl->_obj.compile_status;
519 }
520
521 static GLvoid
522 _shader_SetSource (struct gl2_shader_intf **intf, GLcharARB *src, GLint *off, GLsizei cnt)
523 {
524 struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
525
526 _mesa_free ((void *) impl->_obj.source);
527 impl->_obj.source = src;
528 _mesa_free ((void *) impl->_obj.offsets);
529 impl->_obj.offsets = off;
530 impl->_obj.offset_count = cnt;
531 }
532
533 static const GLcharARB *
534 _shader_GetSource (struct gl2_shader_intf **intf)
535 {
536 struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
537
538 return impl->_obj.source;
539 }
540
541 static GLvoid
542 _shader_Compile (struct gl2_shader_intf **intf)
543 {
544 struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf;
545 #if USE_3DLABS_FRONTEND
546 char **strings;
547 TBuiltInResource res;
548 #else
549 slang_unit_type type;
550 slang_info_log info_log;
551 #endif
552
553 impl->_obj.compile_status = GL_FALSE;
554 _mesa_free ((void *) impl->_obj._generic.info_log);
555 impl->_obj._generic.info_log = NULL;
556
557 #if USE_3DLABS_FRONTEND
558 /* 3dlabs compiler expects us to feed it with null-terminated string array,
559 we've got only one big string with offsets, so we must split it; but when
560 there's only one string to deal with, we pass its address directly */
561
562 if (impl->_obj.offset_count <= 1)
563 strings = &impl->_obj.source;
564 else
565 {
566 GLsizei i, offset = 0;
567
568 strings = (char **) _mesa_malloc (impl->_obj.offset_count * sizeof (char *));
569 if (strings == NULL)
570 return;
571
572 for (i = 0; i < impl->_obj.offset_count; i++)
573 {
574 GLsizei size = impl->_obj.offsets[i] - offset;
575
576 strings[i] = (char *) _mesa_malloc ((size + 1) * sizeof (char));
577 if (strings[i] == NULL)
578 {
579 GLsizei j;
580
581 for (j = 0; j < i; j++)
582 _mesa_free (strings[j]);
583 _mesa_free (strings);
584 return;
585 }
586
587 _mesa_memcpy (strings[i], impl->_obj.source + offset, size * sizeof (char));
588 strings[i][size] = '\0';
589 offset = impl->_obj.offsets[i];
590 }
591 }
592
593 /* TODO set these fields to some REAL numbers */
594 res.maxLights = 8;
595 res.maxClipPlanes = 6;
596 res.maxTextureUnits = 2;
597 res.maxTextureCoords = 2;
598 res.maxVertexAttribs = 8;
599 res.maxVertexUniformComponents = 64;
600 res.maxVaryingFloats = 8;
601 res.maxVertexTextureImageUnits = 2;
602 res.maxCombinedTextureImageUnits = 2;
603 res.maxTextureImageUnits = 2;
604 res.maxFragmentUniformComponents = 64;
605 res.maxDrawBuffers = 1;
606
607 if (ShCompile (impl->_obj._3dlabs_shhandle._obj.handle, strings, impl->_obj.offset_count,
608 EShOptFull, &res, 0))
609 impl->_obj.compile_status = GL_TRUE;
610 if (impl->_obj.offset_count > 1)
611 {
612 GLsizei i;
613
614 for (i = 0; i < impl->_obj.offset_count; i++)
615 _mesa_free (strings[i]);
616 _mesa_free (strings);
617 }
618
619 impl->_obj._generic.info_log = _mesa_strdup (ShGetInfoLog (
620 impl->_obj._3dlabs_shhandle._obj.handle));
621 #else
622 if (impl->_vftbl->GetSubType (intf) == GL_FRAGMENT_SHADER)
623 type = slang_unit_fragment_shader;
624 else
625 type = slang_unit_vertex_shader;
626 slang_info_log_construct (&info_log);
627 if (_slang_compile (impl->_obj.source, &impl->_obj.unit, type, &info_log))
628 {
629 impl->_obj.compile_status = GL_TRUE;
630 }
631 if (info_log.text != NULL)
632 impl->_obj._generic.info_log = _mesa_strdup (info_log.text);
633 else
634 impl->_obj._generic.info_log = _mesa_strdup ("");
635 slang_info_log_destruct (&info_log);
636 #endif
637 }
638
639 static struct gl2_shader_intf _shader_vftbl = {
640 {
641 {
642 _unknown_AddRef,
643 _unknown_Release,
644 _shader_QueryInterface
645 },
646 _generic_Delete,
647 _shader_GetType,
648 _generic_GetName,
649 _generic_GetDeleteStatus,
650 _generic_GetInfoLog
651 },
652 NULL, /* abstract GetSubType */
653 _shader_GetCompileStatus,
654 _shader_SetSource,
655 _shader_GetSource,
656 _shader_Compile
657 };
658
659 static void
660 _shader_constructor (struct gl2_shader_impl *impl)
661 {
662 _generic_constructor ((struct gl2_generic_impl *) impl);
663 _3dlabs_shhandle_constructor (&impl->_obj._3dlabs_shhandle, (struct gl2_unknown_intf **)
664 &impl->_vftbl);
665 impl->_vftbl = &_shader_vftbl;
666 impl->_obj._generic._unknown._destructor = _shader_destructor;
667 impl->_obj.compile_status = GL_FALSE;
668 impl->_obj.source = NULL;
669 impl->_obj.offsets = NULL;
670 impl->_obj.offset_count = 0;
671 }
672
673 struct gl2_program_obj
674 {
675 struct gl2_container_obj _container;
676 GLboolean link_status;
677 GLboolean validate_status;
678 #if USE_3DLABS_FRONTEND
679 ShHandle linker;
680 ShHandle uniforms;
681 #endif
682 slang_program prog;
683 };
684
685 struct gl2_program_impl
686 {
687 struct gl2_program_intf *_vftbl;
688 struct gl2_program_obj _obj;
689 };
690
691 static void
692 _program_destructor (struct gl2_unknown_intf **intf)
693 {
694 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
695 #if USE_3DLABS_FRONTEND
696 ShDestruct (impl->_obj.linker);
697 ShDestruct (impl->_obj.uniforms);
698 #endif
699 _container_destructor (intf);
700 slang_program_dtr (&impl->_obj.prog);
701 }
702
703 static struct gl2_unknown_intf **
704 _program_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
705 {
706 if (uiid == UIID_PROGRAM)
707 {
708 (**intf).AddRef (intf);
709 return intf;
710 }
711 return _container_QueryInterface (intf, uiid);
712 }
713
714 static GLenum
715 _program_GetType (struct gl2_generic_intf **intf)
716 {
717 return GL_PROGRAM_OBJECT_ARB;
718 }
719
720 static GLboolean
721 _program_Attach (struct gl2_container_intf **intf, struct gl2_generic_intf **att)
722 {
723 GET_CURRENT_CONTEXT(ctx);
724 struct gl2_unknown_intf **sha;
725
726 sha = (**att)._unknown.QueryInterface ((struct gl2_unknown_intf **) att, UIID_SHADER);
727 if (sha == NULL)
728 {
729 _mesa_error (ctx, GL_INVALID_OPERATION, "_program_Attach");
730 return GL_FALSE;
731 }
732
733 (**sha).Release (sha);
734 return _container_Attach (intf, att);
735 }
736
737 static GLboolean
738 _program_GetLinkStatus (struct gl2_program_intf **intf)
739 {
740 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
741
742 return impl->_obj.link_status;
743 }
744
745 static GLboolean
746 _program_GetValidateStatus (struct gl2_program_intf **intf)
747 {
748 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
749
750 return impl->_obj.validate_status;
751 }
752
753 static GLvoid
754 _program_Link (struct gl2_program_intf **intf)
755 {
756 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
757 #if USE_3DLABS_FRONTEND
758 ShHandle *handles;
759 #endif
760 GLuint i, count;
761 slang_translation_unit *units[2];
762
763 impl->_obj.link_status = GL_FALSE;
764 _mesa_free ((void *) impl->_obj._container._generic.info_log);
765 impl->_obj._container._generic.info_log = NULL;
766 slang_program_dtr (&impl->_obj.prog);
767 slang_program_ctr (&impl->_obj.prog);
768
769 #if USE_3DLABS_FRONTEND
770 handles = (ShHandle *) _mesa_malloc (impl->_obj._container.attached_count * sizeof (ShHandle));
771 if (handles == NULL)
772 return;
773
774 for (i = 0; i < impl->_obj._container.attached_count; i++)
775 {
776 struct gl2_generic_intf **gen = impl->_obj._container.attached[i];
777 struct gl2_3dlabs_shhandle_intf **sh;
778
779 sh = (struct gl2_3dlabs_shhandle_intf **) (**gen)._unknown.QueryInterface (
780 (struct gl2_unknown_intf **) gen, UIID_3DLABS_SHHANDLE);
781 if (sh != NULL)
782 {
783 handles[i] = (**sh).GetShHandle (sh);
784 (**sh)._unknown.Release ((struct gl2_unknown_intf **) sh);
785 }
786 else
787 {
788 _mesa_free (handles);
789 return;
790 }
791 }
792
793 if (ShLink (impl->_obj.linker, handles, impl->_obj._container.attached_count,
794 impl->_obj.uniforms, NULL, NULL))
795 impl->_obj.link_status = GL_TRUE;
796
797 impl->_obj._container._generic.info_log = _mesa_strdup (ShGetInfoLog (impl->_obj.linker));
798 #else
799 count = impl->_obj._container.attached_count;
800 if (count == 0 || count > 2)
801 return;
802 for (i = 0; i < count; i++)
803 {
804 struct gl2_generic_intf **obj;
805 struct gl2_unknown_intf **unk;
806 struct gl2_shader_impl *sha;
807
808 obj = impl->_obj._container.attached[i];
809 unk = (**obj)._unknown.QueryInterface ((struct gl2_unknown_intf **) obj, UIID_SHADER);
810 (**obj)._unknown.Release ((struct gl2_unknown_intf **) obj);
811 if (unk == NULL)
812 return;
813 sha = (struct gl2_shader_impl *) unk;
814 units[i] = &sha->_obj.unit;
815 (**unk).Release (unk);
816 }
817
818 impl->_obj.link_status = _slang_link (&impl->_obj.prog, units, count);
819 if (impl->_obj.link_status)
820 impl->_obj._container._generic.info_log = _mesa_strdup ("Link OK.\n");
821 else
822 impl->_obj._container._generic.info_log = _mesa_strdup ("Link failed.\n");
823 #endif
824 }
825
826 static GLvoid
827 _program_Validate (struct gl2_program_intf **intf)
828 {
829 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
830
831 impl->_obj.validate_status = GL_FALSE;
832 _mesa_free ((void *) impl->_obj._container._generic.info_log);
833 impl->_obj._container._generic.info_log = NULL;
834
835 /* TODO validate */
836 }
837
838 static GLvoid
839 write_common_fixed (slang_program *pro, GLuint index, const GLvoid *src, GLuint off, GLuint size)
840 {
841 GLuint i;
842
843 for (i = 0; i < SLANG_UNIFORM_BINDING_MAX; i++)
844 {
845 GLuint addr;
846
847 addr = pro->common_fixed_entries[i][index];
848 if (addr != ~0)
849 {
850 GLubyte *dst;
851
852 dst = (GLubyte *) pro->machines[i]->mem + addr + off * size;
853 _mesa_memcpy (dst, src, size);
854 }
855 }
856 }
857
858 static GLvoid
859 write_common_fixed_mat4 (slang_program *pro, GLmatrix *matrix, GLuint off, GLuint i, GLuint ii,
860 GLuint it, GLuint iit)
861 {
862 GLfloat mat[16];
863
864 /* we want inverse matrix */
865 if (!matrix->inv)
866 {
867 /* allocate inverse matrix and make it dirty */
868 _math_matrix_alloc_inv (matrix);
869 _math_matrix_loadf (matrix, matrix->m);
870 }
871 _math_matrix_analyse (matrix);
872
873 write_common_fixed (pro, i, matrix->m, off, 16 * sizeof (GLfloat));
874
875 /* inverse */
876 write_common_fixed (pro, ii, matrix->inv, off, 16 * sizeof (GLfloat));
877
878 /* transpose */
879 _math_transposef (mat, matrix->m);
880 write_common_fixed (pro, it, mat, off, 16 * sizeof (GLfloat));
881
882 /* inverse transpose */
883 _math_transposef (mat, matrix->inv);
884 write_common_fixed (pro, iit, mat, off, 16 * sizeof (GLfloat));
885 }
886
887 static GLvoid
888 _program_UpdateFixedUniforms (struct gl2_program_intf **intf)
889 {
890 GET_CURRENT_CONTEXT(ctx);
891 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
892 slang_program *pro = &impl->_obj.prog;
893 GLuint i;
894 GLfloat v[9];
895 GLfloat *p;
896
897 /* MODELVIEW matrix */
898 write_common_fixed_mat4 (pro, ctx->ModelviewMatrixStack.Top, 0,
899 SLANG_COMMON_FIXED_MODELVIEWMATRIX,
900 SLANG_COMMON_FIXED_MODELVIEWMATRIXINVERSE,
901 SLANG_COMMON_FIXED_MODELVIEWMATRIXTRANSPOSE,
902 SLANG_COMMON_FIXED_MODELVIEWMATRIXINVERSETRANSPOSE);
903
904 /* PROJECTION matrix */
905 write_common_fixed_mat4 (pro, ctx->ProjectionMatrixStack.Top, 0,
906 SLANG_COMMON_FIXED_PROJECTIONMATRIX,
907 SLANG_COMMON_FIXED_PROJECTIONMATRIXINVERSE,
908 SLANG_COMMON_FIXED_PROJECTIONMATRIXTRANSPOSE,
909 SLANG_COMMON_FIXED_PROJECTIONMATRIXINVERSETRANSPOSE);
910
911 /* MVP matrix */
912 write_common_fixed_mat4 (pro, &ctx->_ModelProjectMatrix, 0,
913 SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIX,
914 SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIXINVERSE,
915 SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIXTRANSPOSE,
916 SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIXINVERSETRANSPOSE);
917
918 /* TEXTURE matrix */
919 for (i = 0; i < 8; i++)
920 {
921 write_common_fixed_mat4 (pro, ctx->TextureMatrixStack[i].Top, i,
922 SLANG_COMMON_FIXED_TEXTUREMATRIX,
923 SLANG_COMMON_FIXED_TEXTUREMATRIXINVERSE,
924 SLANG_COMMON_FIXED_TEXTUREMATRIXTRANSPOSE,
925 SLANG_COMMON_FIXED_TEXTUREMATRIXINVERSETRANSPOSE);
926 }
927
928 /* NORMAL matrix - upper 3x3 inverse transpose of MODELVIEW matrix */
929 p = ctx->ModelviewMatrixStack.Top->inv;
930 v[0] = p[0];
931 v[1] = p[4];
932 v[2] = p[8];
933 v[3] = p[1];
934 v[4] = p[5];
935 v[5] = p[9];
936 v[6] = p[2];
937 v[7] = p[6];
938 v[8] = p[10];
939 write_common_fixed (pro, SLANG_COMMON_FIXED_NORMALMATRIX, v, 0, 9 * sizeof (GLfloat));
940
941 /* XXX: fetch uniform float gl_NormalScale */
942 /* XXX: fetch uniform mat4 gl_ClipPlane */
943 /* XXX: fetch uniform mat4 gl_TextureEnvColor */
944 /* XXX: fetch uniform mat4 gl_EyePlaneS */
945 /* XXX: fetch uniform mat4 gl_EyePlaneT */
946 /* XXX: fetch uniform mat4 gl_EyePlaneR */
947 /* XXX: fetch uniform mat4 gl_EyePlaneQ */
948 /* XXX: fetch uniform mat4 gl_ObjectPlaneS */
949 /* XXX: fetch uniform mat4 gl_ObjectPlaneT */
950 /* XXX: fetch uniform mat4 gl_ObjectPlaneR */
951 /* XXX: fetch uniform mat4 gl_ObjectPlaneQ */
952 }
953
954 static GLvoid
955 _program_UpdateFixedAttribute (struct gl2_program_intf **intf, GLuint index, GLvoid *data,
956 GLuint offset, GLuint size, GLboolean write)
957 {
958 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
959 slang_program *pro = &impl->_obj.prog;
960 GLuint addr;
961
962 addr = pro->vertex_fixed_entries[index];
963 if (addr != ~0)
964 {
965 GLubyte *mem;
966
967 mem = (GLubyte *) pro->machines[SLANG_UNIFORM_BINDING_VERTEX]->mem + addr + offset * size;
968 if (write)
969 _mesa_memcpy (mem, data, size);
970 else
971 _mesa_memcpy (data, mem, size);
972 }
973 }
974
975 static GLvoid
976 _program_UpdateFixedVarying (struct gl2_program_intf **intf, GLuint index, GLvoid *data,
977 GLuint offset, GLuint size, GLboolean write)
978 {
979 struct gl2_program_impl *impl = (struct gl2_program_impl *) intf;
980 slang_program *pro = &impl->_obj.prog;
981 GLuint addr;
982
983 addr = pro->fragment_fixed_entries[index];
984 if (addr != ~0)
985 {
986 GLubyte *mem;
987
988 mem = (GLubyte *) pro->machines[SLANG_UNIFORM_BINDING_FRAGMENT]->mem + addr + offset * size;
989 if (write)
990 _mesa_memcpy (mem, data, size);
991 else
992 _mesa_memcpy (data, mem, size);
993 }
994 }
995
996 static struct gl2_program_intf _program_vftbl = {
997 {
998 {
999 {
1000 _unknown_AddRef,
1001 _unknown_Release,
1002 _program_QueryInterface
1003 },
1004 _generic_Delete,
1005 _program_GetType,
1006 _generic_GetName,
1007 _generic_GetDeleteStatus,
1008 _generic_GetInfoLog
1009 },
1010 _program_Attach,
1011 _container_Detach,
1012 _container_GetAttachedCount,
1013 _container_GetAttached
1014 },
1015 _program_GetLinkStatus,
1016 _program_GetValidateStatus,
1017 _program_Link,
1018 _program_Validate,
1019 _program_UpdateFixedUniforms,
1020 _program_UpdateFixedAttribute,
1021 _program_UpdateFixedVarying
1022 };
1023
1024 static void
1025 _program_constructor (struct gl2_program_impl *impl)
1026 {
1027 _container_constructor ((struct gl2_container_impl *) impl);
1028 impl->_vftbl = &_program_vftbl;
1029 impl->_obj._container._generic._unknown._destructor = _program_destructor;
1030 impl->_obj.link_status = GL_FALSE;
1031 impl->_obj.validate_status = GL_FALSE;
1032 #if USE_3DLABS_FRONTEND
1033 impl->_obj.linker = ShConstructLinker (EShExVertexFragment, 0);
1034 impl->_obj.uniforms = ShConstructUniformMap ();
1035 #endif
1036 slang_program_ctr (&impl->_obj.prog);
1037 }
1038
1039 struct gl2_fragment_shader_obj
1040 {
1041 struct gl2_shader_obj _shader;
1042 };
1043
1044 struct gl2_fragment_shader_impl
1045 {
1046 struct gl2_fragment_shader_intf *_vftbl;
1047 struct gl2_fragment_shader_obj _obj;
1048 };
1049
1050 static void
1051 _fragment_shader_destructor (struct gl2_unknown_intf **intf)
1052 {
1053 struct gl2_fragment_shader_impl *impl = (struct gl2_fragment_shader_impl *) intf;
1054
1055 (void) impl;
1056 /* TODO free fragment shader data */
1057
1058 _shader_destructor (intf);
1059 }
1060
1061 static struct gl2_unknown_intf **
1062 _fragment_shader_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
1063 {
1064 if (uiid == UIID_FRAGMENT_SHADER)
1065 {
1066 (**intf).AddRef (intf);
1067 return intf;
1068 }
1069 return _shader_QueryInterface (intf, uiid);
1070 }
1071
1072 static GLenum
1073 _fragment_shader_GetSubType (struct gl2_shader_intf **intf)
1074 {
1075 return GL_FRAGMENT_SHADER_ARB;
1076 }
1077
1078 static struct gl2_fragment_shader_intf _fragment_shader_vftbl = {
1079 {
1080 {
1081 {
1082 _unknown_AddRef,
1083 _unknown_Release,
1084 _fragment_shader_QueryInterface
1085 },
1086 _generic_Delete,
1087 _shader_GetType,
1088 _generic_GetName,
1089 _generic_GetDeleteStatus,
1090 _generic_GetInfoLog
1091 },
1092 _fragment_shader_GetSubType,
1093 _shader_GetCompileStatus,
1094 _shader_SetSource,
1095 _shader_GetSource,
1096 _shader_Compile
1097 }
1098 };
1099
1100 static void
1101 _fragment_shader_constructor (struct gl2_fragment_shader_impl *impl)
1102 {
1103 _shader_constructor ((struct gl2_shader_impl *) impl);
1104 impl->_vftbl = &_fragment_shader_vftbl;
1105 impl->_obj._shader._generic._unknown._destructor = _fragment_shader_destructor;
1106 #if USE_3DLABS_FRONTEND
1107 impl->_obj._shader._3dlabs_shhandle._obj.handle = ShConstructCompiler (EShLangFragment, 0);
1108 #endif
1109 }
1110
1111 struct gl2_vertex_shader_obj
1112 {
1113 struct gl2_shader_obj _shader;
1114 };
1115
1116 struct gl2_vertex_shader_impl
1117 {
1118 struct gl2_vertex_shader_intf *_vftbl;
1119 struct gl2_vertex_shader_obj _obj;
1120 };
1121
1122 static void
1123 _vertex_shader_destructor (struct gl2_unknown_intf **intf)
1124 {
1125 struct gl2_vertex_shader_impl *impl = (struct gl2_vertex_shader_impl *) intf;
1126
1127 (void) impl;
1128 /* TODO free vertex shader data */
1129
1130 _shader_destructor (intf);
1131 }
1132
1133 static struct gl2_unknown_intf **
1134 _vertex_shader_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid)
1135 {
1136 if (uiid == UIID_VERTEX_SHADER)
1137 {
1138 (**intf).AddRef (intf);
1139 return intf;
1140 }
1141 return _shader_QueryInterface (intf, uiid);
1142 }
1143
1144 static GLenum
1145 _vertex_shader_GetSubType (struct gl2_shader_intf **intf)
1146 {
1147 return GL_VERTEX_SHADER_ARB;
1148 }
1149
1150 static struct gl2_vertex_shader_intf _vertex_shader_vftbl = {
1151 {
1152 {
1153 {
1154 _unknown_AddRef,
1155 _unknown_Release,
1156 _vertex_shader_QueryInterface
1157 },
1158 _generic_Delete,
1159 _shader_GetType,
1160 _generic_GetName,
1161 _generic_GetDeleteStatus,
1162 _generic_GetInfoLog
1163 },
1164 _vertex_shader_GetSubType,
1165 _shader_GetCompileStatus,
1166 _shader_SetSource,
1167 _shader_GetSource,
1168 _shader_Compile
1169 }
1170 };
1171
1172 static void
1173 _vertex_shader_constructor (struct gl2_vertex_shader_impl *impl)
1174 {
1175 _shader_constructor ((struct gl2_shader_impl *) impl);
1176 impl->_vftbl = &_vertex_shader_vftbl;
1177 impl->_obj._shader._generic._unknown._destructor = _vertex_shader_destructor;
1178 #if USE_3DLABS_FRONTEND
1179 impl->_obj._shader._3dlabs_shhandle._obj.handle = ShConstructCompiler (EShLangVertex, 0);
1180 #endif
1181 }
1182
1183 GLhandleARB
1184 _mesa_3dlabs_create_shader_object (GLenum shaderType)
1185 {
1186 switch (shaderType)
1187 {
1188 case GL_FRAGMENT_SHADER_ARB:
1189 {
1190 struct gl2_fragment_shader_impl *x = (struct gl2_fragment_shader_impl *)
1191 _mesa_malloc (sizeof (struct gl2_fragment_shader_impl));
1192
1193 if (x != NULL)
1194 {
1195 _fragment_shader_constructor (x);
1196 return x->_obj._shader._generic.name;
1197 }
1198 }
1199 break;
1200 case GL_VERTEX_SHADER_ARB:
1201 {
1202 struct gl2_vertex_shader_impl *x = (struct gl2_vertex_shader_impl *)
1203 _mesa_malloc (sizeof (struct gl2_vertex_shader_impl));
1204
1205 if (x != NULL)
1206 {
1207 _vertex_shader_constructor (x);
1208 return x->_obj._shader._generic.name;
1209 }
1210 }
1211 break;
1212 }
1213
1214 return 0;
1215 }
1216
1217 GLhandleARB
1218 _mesa_3dlabs_create_program_object (void)
1219 {
1220 struct gl2_program_impl *x = (struct gl2_program_impl *)
1221 _mesa_malloc (sizeof (struct gl2_program_impl));
1222
1223 if (x != NULL)
1224 {
1225 _program_constructor (x);
1226 return x->_obj._container._generic.name;
1227 }
1228
1229 return 0;
1230 }
1231
1232 #include "slang_assemble.h"
1233 #include "slang_execute.h"
1234
1235 int _slang_fetch_discard (struct gl2_program_intf **pro, GLboolean *val)
1236 {
1237 struct gl2_program_impl *impl;
1238
1239 impl = (struct gl2_program_impl *) pro;
1240 *val = impl->_obj.prog.machines[SLANG_UNIFORM_BINDING_FRAGMENT]->kill ? GL_TRUE : GL_FALSE;
1241 return 1;
1242 }
1243
1244 static GLvoid exec_shader (struct gl2_program_intf **pro, GLuint i)
1245 {
1246 struct gl2_program_impl *impl;
1247 slang_program *p;
1248
1249 impl = (struct gl2_program_impl *) pro;
1250 p = &impl->_obj.prog;
1251
1252 slang_machine_init (p->machines[i]);
1253 p->machines[i]->ip = p->code[i];
1254
1255 _slang_execute2 (p->assemblies[i], p->machines[i]);
1256 }
1257
1258 GLvoid _slang_exec_fragment_shader (struct gl2_program_intf **pro)
1259 {
1260 exec_shader (pro, SLANG_UNIFORM_BINDING_FRAGMENT);
1261 }
1262
1263 GLvoid _slang_exec_vertex_shader (struct gl2_program_intf **pro)
1264 {
1265 exec_shader (pro, SLANG_UNIFORM_BINDING_VERTEX);
1266 }
1267
1268 GLint _slang_get_uniform_location (struct gl2_program_intf **pro, const char *name)
1269 {
1270 struct gl2_program_impl *impl;
1271 slang_uniform_bindings *bind;
1272 GLuint i;
1273
1274 impl = (struct gl2_program_impl *) pro;
1275 bind = &impl->_obj.prog.uniforms;
1276 for (i = 0; i < bind->count; i++)
1277 if (_mesa_strcmp (bind->table[i].name, name) == 0)
1278 return i;
1279 return -1;
1280 }
1281
1282 GLboolean _slang_write_uniform (struct gl2_program_intf **pro, GLint loc, GLsizei count,
1283 const GLvoid *data, GLenum type)
1284 {
1285 struct gl2_program_impl *impl;
1286 slang_uniform_bindings *bind;
1287 slang_uniform_binding *b;
1288 GLuint i;
1289
1290 if (loc == -1)
1291 return GL_TRUE;
1292
1293 impl = (struct gl2_program_impl *) pro;
1294 bind = &impl->_obj.prog.uniforms;
1295 if (loc >= bind->count)
1296 return GL_FALSE;
1297
1298 b = &bind->table[loc];
1299 /* TODO: check sizes */
1300 /* TODO: check if not structure */
1301 if (b->quant->u.basic_type != type)
1302 return GL_FALSE;
1303
1304 for (i = 0; i < SLANG_UNIFORM_BINDING_MAX; i++)
1305 if (b->address[i] != ~0)
1306 {
1307 _mesa_memcpy (&impl->_obj.prog.machines[i]->mem[b->address[i] / 4], data,
1308 count * b->quant->size);
1309 }
1310 return GL_TRUE;
1311 }
1312
1313 GLuint _slang_get_active_uniform_count (struct gl2_program_intf **pro)
1314 {
1315 struct gl2_program_impl *impl;
1316
1317 impl = (struct gl2_program_impl *) pro;
1318 return impl->_obj.prog.active_uniforms.count;
1319 }
1320
1321 GLuint _slang_get_active_uniform_max_length (struct gl2_program_intf **pro)
1322 {
1323 struct gl2_program_impl *impl;
1324 GLuint i, len = 0;
1325
1326 impl = (struct gl2_program_impl *) pro;
1327 for (i = 0; i < impl->_obj.prog.active_uniforms.count; i++)
1328 {
1329 GLuint n = _mesa_strlen (impl->_obj.prog.active_uniforms.table[i].name);
1330 if (n > len)
1331 len = n;
1332 }
1333 return len;
1334 }
1335
1336 GLvoid _slang_get_active_uniform (struct gl2_program_intf **pro, GLuint index, GLsizei maxLength,
1337 GLsizei *length, GLint *size, GLenum *type, char *name)
1338 {
1339 struct gl2_program_impl *impl;
1340 slang_active_uniform *u;
1341 GLsizei len;
1342
1343 impl = (struct gl2_program_impl *) pro;
1344 u = &impl->_obj.prog.active_uniforms.table[index];
1345
1346 len = _mesa_strlen (u->name);
1347 if (len >= maxLength)
1348 len = maxLength - 1;
1349 _mesa_memcpy (name, u->name, len);
1350 name[len] = '\0';
1351 if (length != NULL)
1352 *length = len;
1353 *type = u->quant->u.basic_type;
1354 if (u->quant->array_len == 0)
1355 *size = 1;
1356 else
1357 *size = u->quant->array_len;
1358 }
1359
1360 void
1361 _mesa_init_shaderobjects_3dlabs (GLcontext *ctx)
1362 {
1363 #if USE_3DLABS_FRONTEND
1364 _glslang_3dlabs_InitProcess ();
1365 _glslang_3dlabs_ShInitialize ();
1366 #endif
1367 }
1368