2 * Mesa 3-D graphics library
5 * Copyright (C) 2005-2006 Brian Paul All Rights Reserved.
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:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
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.
26 * \file shaderobjects_3dlabs.c
27 * shader objects definitions for 3dlabs compiler
31 /* Set this to 1 when we are ready to use 3dlabs' front-end */
32 #define USE_3DLABS_FRONTEND 0
36 #include "shaderobjects.h"
38 #if USE_3DLABS_FRONTEND
39 #include "slang_mesa.h"
40 #include "Public/ShaderLang.h"
42 #include "slang_link.h"
45 struct gl2_unknown_obj
47 GLuint reference_count
;
48 void (* _destructor
) (struct gl2_unknown_intf
**);
51 struct gl2_unknown_impl
53 struct gl2_unknown_intf
*_vftbl
;
54 struct gl2_unknown_obj _obj
;
58 _unknown_destructor (struct gl2_unknown_intf
**intf
)
63 _unknown_AddRef (struct gl2_unknown_intf
**intf
)
65 struct gl2_unknown_impl
*impl
= (struct gl2_unknown_impl
*) intf
;
67 impl
->_obj
.reference_count
++;
71 _unknown_Release (struct gl2_unknown_intf
**intf
)
73 struct gl2_unknown_impl
*impl
= (struct gl2_unknown_impl
*) intf
;
75 impl
->_obj
.reference_count
--;
76 if (impl
->_obj
.reference_count
== 0)
78 impl
->_obj
._destructor (intf
);
79 _mesa_free ((void *) intf
);
83 static struct gl2_unknown_intf
**
84 _unknown_QueryInterface (struct gl2_unknown_intf
**intf
, enum gl2_uiid uiid
)
86 if (uiid
== UIID_UNKNOWN
)
88 (**intf
).AddRef (intf
);
94 static struct gl2_unknown_intf _unknown_vftbl
= {
97 _unknown_QueryInterface
101 _unknown_constructor (struct gl2_unknown_impl
*impl
)
103 impl
->_vftbl
= &_unknown_vftbl
;
104 impl
->_obj
.reference_count
= 1;
105 impl
->_obj
._destructor
= _unknown_destructor
;
108 struct gl2_unkinner_obj
110 struct gl2_unknown_intf
**unkouter
;
113 struct gl2_unkinner_impl
115 struct gl2_unknown_intf
*_vftbl
;
116 struct gl2_unkinner_obj _obj
;
120 _unkinner_destructor (struct gl2_unknown_intf
**intf
)
125 _unkinner_AddRef (struct gl2_unknown_intf
**intf
)
127 struct gl2_unkinner_impl
*impl
= (struct gl2_unkinner_impl
*) intf
;
129 (**impl
->_obj
.unkouter
).AddRef (impl
->_obj
.unkouter
);
133 _unkinner_Release (struct gl2_unknown_intf
**intf
)
135 struct gl2_unkinner_impl
*impl
= (struct gl2_unkinner_impl
*) intf
;
137 (**impl
->_obj
.unkouter
).Release (impl
->_obj
.unkouter
);
140 static struct gl2_unknown_intf
**
141 _unkinner_QueryInterface (struct gl2_unknown_intf
**intf
, enum gl2_uiid uiid
)
143 struct gl2_unkinner_impl
*impl
= (struct gl2_unkinner_impl
*) intf
;
145 return (**impl
->_obj
.unkouter
).QueryInterface (impl
->_obj
.unkouter
, uiid
);
148 static struct gl2_unknown_intf _unkinner_vftbl
= {
151 _unkinner_QueryInterface
155 _unkinner_constructor (struct gl2_unkinner_impl
*impl
, struct gl2_unknown_intf
**outer
)
157 impl
->_vftbl
= &_unkinner_vftbl
;
158 impl
->_obj
.unkouter
= outer
;
161 struct gl2_generic_obj
163 struct gl2_unknown_obj _unknown
;
165 GLboolean delete_status
;
169 struct gl2_generic_impl
171 struct gl2_generic_intf
*_vftbl
;
172 struct gl2_generic_obj _obj
;
176 _generic_destructor (struct gl2_unknown_intf
**intf
)
178 GET_CURRENT_CONTEXT(ctx
);
179 struct gl2_generic_impl
*impl
= (struct gl2_generic_impl
*) intf
;
181 _mesa_free ((void *) impl
->_obj
.info_log
);
183 _glthread_LOCK_MUTEX (ctx
->Shared
->Mutex
);
184 _mesa_HashRemove (ctx
->Shared
->GL2Objects
, impl
->_obj
.name
);
185 _glthread_UNLOCK_MUTEX (ctx
->Shared
->Mutex
);
187 _unknown_destructor (intf
);
190 static struct gl2_unknown_intf
**
191 _generic_QueryInterface (struct gl2_unknown_intf
**intf
, enum gl2_uiid uiid
)
193 if (uiid
== UIID_GENERIC
)
195 (**intf
).AddRef (intf
);
198 return _unknown_QueryInterface (intf
, uiid
);
202 _generic_Delete (struct gl2_generic_intf
**intf
)
204 struct gl2_generic_impl
*impl
= (struct gl2_generic_impl
*) intf
;
206 if (impl
->_obj
.delete_status
== GL_FALSE
)
208 impl
->_obj
.delete_status
= GL_TRUE
;
209 (**intf
)._unknown
.Release ((struct gl2_unknown_intf
**) intf
);
214 _generic_GetName (struct gl2_generic_intf
**intf
)
216 struct gl2_generic_impl
*impl
= (struct gl2_generic_impl
*) intf
;
218 return impl
->_obj
.name
;
222 _generic_GetDeleteStatus (struct gl2_generic_intf
**intf
)
224 struct gl2_generic_impl
*impl
= (struct gl2_generic_impl
*) intf
;
226 return impl
->_obj
.delete_status
;
229 static const GLcharARB
*
230 _generic_GetInfoLog (struct gl2_generic_intf
**intf
)
232 struct gl2_generic_impl
*impl
= (struct gl2_generic_impl
*) intf
;
234 return impl
->_obj
.info_log
;
237 static struct gl2_generic_intf _generic_vftbl
= {
241 _generic_QueryInterface
244 NULL
, /* abstract GetType */
246 _generic_GetDeleteStatus
,
251 _generic_constructor (struct gl2_generic_impl
*impl
)
253 GET_CURRENT_CONTEXT(ctx
);
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
;
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
);
267 struct gl2_container_obj
269 struct gl2_generic_obj _generic
;
270 struct gl2_generic_intf
***attached
;
271 GLuint attached_count
;
274 struct gl2_container_impl
276 struct gl2_container_intf
*_vftbl
;
277 struct gl2_container_obj _obj
;
281 _container_destructor (struct gl2_unknown_intf
**intf
)
283 struct gl2_container_impl
*impl
= (struct gl2_container_impl
*) intf
;
286 for (i
= 0; i
< impl
->_obj
.attached_count
; i
++)
288 struct gl2_generic_intf
**x
= impl
->_obj
.attached
[i
];
289 (**x
)._unknown
.Release ((struct gl2_unknown_intf
**) x
);
292 _generic_destructor (intf
);
295 static struct gl2_unknown_intf
**
296 _container_QueryInterface (struct gl2_unknown_intf
**intf
, enum gl2_uiid uiid
)
298 if (uiid
== UIID_CONTAINER
)
300 (**intf
).AddRef (intf
);
303 return _generic_QueryInterface (intf
, uiid
);
307 _container_Attach (struct gl2_container_intf
**intf
, struct gl2_generic_intf
**att
)
309 GET_CURRENT_CONTEXT(ctx
);
310 struct gl2_container_impl
*impl
= (struct gl2_container_impl
*) intf
;
313 for (i
= 0; i
< impl
->_obj
.attached_count
; i
++)
314 if (impl
->_obj
.attached
[i
] == att
)
316 _mesa_error (ctx
, GL_INVALID_OPERATION
, "_container_Attach");
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
)
326 impl
->_obj
.attached
[impl
->_obj
.attached_count
] = att
;
327 impl
->_obj
.attached_count
++;
328 (**att
)._unknown
.AddRef ((struct gl2_unknown_intf
**) att
);
333 _container_Detach (struct gl2_container_intf
**intf
, struct gl2_generic_intf
**att
)
335 GET_CURRENT_CONTEXT(ctx
);
336 struct gl2_container_impl
*impl
= (struct gl2_container_impl
*) intf
;
339 for (i
= 0; i
< impl
->_obj
.attached_count
; i
++)
340 if (impl
->_obj
.attached
[i
] == att
)
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
);
352 _mesa_error (ctx
, GL_INVALID_OPERATION
, "_container_Detach");
357 _container_GetAttachedCount (struct gl2_container_intf
**intf
)
359 struct gl2_container_impl
*impl
= (struct gl2_container_impl
*) intf
;
361 return impl
->_obj
.attached_count
;
364 static struct gl2_generic_intf
**
365 _container_GetAttached (struct gl2_container_intf
**intf
, GLuint index
)
367 struct gl2_container_impl
*impl
= (struct gl2_container_impl
*) intf
;
369 (**impl
->_obj
.attached
[index
])._unknown
.AddRef (
370 (struct gl2_unknown_intf
**)impl
->_obj
.attached
[index
]);
371 return impl
->_obj
.attached
[index
];
374 static struct gl2_container_intf _container_vftbl
= {
379 _container_QueryInterface
382 NULL
, /* abstract GetType */
384 _generic_GetDeleteStatus
,
389 _container_GetAttachedCount
,
390 _container_GetAttached
394 _container_constructor (struct gl2_container_impl
*impl
)
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;
403 struct gl2_3dlabs_shhandle_obj
405 struct gl2_unkinner_obj _unknown
;
406 #if USE_3DLABS_FRONTEND
411 struct gl2_3dlabs_shhandle_impl
413 struct gl2_3dlabs_shhandle_intf
*_vftbl
;
414 struct gl2_3dlabs_shhandle_obj _obj
;
418 _3dlabs_shhandle_destructor (struct gl2_unknown_intf
**intf
)
420 #if USE_3DLABS_FRONTEND
421 struct gl2_3dlabs_shhandle_impl
*impl
= (struct gl2_3dlabs_shhandle_impl
*) intf
;
422 ShDestruct (impl
->_obj
.handle
);
424 _unkinner_destructor (intf
);
428 _3dlabs_shhandle_GetShHandle (struct gl2_3dlabs_shhandle_intf
**intf
)
430 #if USE_3DLABS_FRONTEND
431 struct gl2_3dlabs_shhandle_impl
*impl
= (struct gl2_3dlabs_shhandle_impl
*) intf
;
432 return impl
->_obj
.handle
;
438 static struct gl2_3dlabs_shhandle_intf _3dlabs_shhandle_vftbl
= {
442 _unkinner_QueryInterface
444 _3dlabs_shhandle_GetShHandle
448 _3dlabs_shhandle_constructor (struct gl2_3dlabs_shhandle_impl
*impl
, struct gl2_unknown_intf
**outer
)
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
;
457 struct gl2_shader_obj
459 struct gl2_generic_obj _generic
;
460 struct gl2_3dlabs_shhandle_impl _3dlabs_shhandle
;
461 GLboolean compile_status
;
464 GLsizei offset_count
;
465 slang_translation_unit unit
;
468 struct gl2_shader_impl
470 struct gl2_shader_intf
*_vftbl
;
471 struct gl2_shader_obj _obj
;
475 _shader_destructor (struct gl2_unknown_intf
**intf
)
477 struct gl2_shader_impl
*impl
= (struct gl2_shader_impl
*) intf
;
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
);
485 static struct gl2_unknown_intf
**
486 _shader_QueryInterface (struct gl2_unknown_intf
**intf
, enum gl2_uiid uiid
)
488 #if USE_3DLABS_FRONTEND
489 struct gl2_shader_impl
*impl
= (struct gl2_shader_impl
*) intf
;
492 if (uiid
== UIID_SHADER
)
494 (**intf
).AddRef (intf
);
497 #if USE_3DLABS_FRONTEND
498 if (uiid
== UIID_3DLABS_SHHANDLE
)
500 (**intf
).AddRef (intf
);
501 return (struct gl2_unknown_intf
**) &impl
->_obj
._3dlabs_shhandle
._vftbl
;
504 return _generic_QueryInterface (intf
, uiid
);
508 _shader_GetType (struct gl2_generic_intf
**intf
)
510 return GL_SHADER_OBJECT_ARB
;
514 _shader_GetCompileStatus (struct gl2_shader_intf
**intf
)
516 struct gl2_shader_impl
*impl
= (struct gl2_shader_impl
*) intf
;
518 return impl
->_obj
.compile_status
;
522 _shader_SetSource (struct gl2_shader_intf
**intf
, GLcharARB
*src
, GLint
*off
, GLsizei cnt
)
524 struct gl2_shader_impl
*impl
= (struct gl2_shader_impl
*) intf
;
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
;
533 static const GLcharARB
*
534 _shader_GetSource (struct gl2_shader_intf
**intf
)
536 struct gl2_shader_impl
*impl
= (struct gl2_shader_impl
*) intf
;
538 return impl
->_obj
.source
;
542 _shader_Compile (struct gl2_shader_intf
**intf
)
544 struct gl2_shader_impl
*impl
= (struct gl2_shader_impl
*) intf
;
545 #if USE_3DLABS_FRONTEND
547 TBuiltInResource res
;
549 slang_unit_type type
;
550 slang_info_log info_log
;
553 impl
->_obj
.compile_status
= GL_FALSE
;
554 _mesa_free ((void *) impl
->_obj
._generic
.info_log
);
555 impl
->_obj
._generic
.info_log
= NULL
;
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 */
562 if (impl
->_obj
.offset_count
<= 1)
563 strings
= &impl
->_obj
.source
;
566 GLsizei i
, offset
= 0;
568 strings
= (char **) _mesa_malloc (impl
->_obj
.offset_count
* sizeof (char *));
572 for (i
= 0; i
< impl
->_obj
.offset_count
; i
++)
574 GLsizei size
= impl
->_obj
.offsets
[i
] - offset
;
576 strings
[i
] = (char *) _mesa_malloc ((size
+ 1) * sizeof (char));
577 if (strings
[i
] == NULL
)
581 for (j
= 0; j
< i
; j
++)
582 _mesa_free (strings
[j
]);
583 _mesa_free (strings
);
587 _mesa_memcpy (strings
[i
], impl
->_obj
.source
+ offset
, size
* sizeof (char));
588 strings
[i
][size
] = '\0';
589 offset
= impl
->_obj
.offsets
[i
];
593 /* TODO set these fields to some REAL numbers */
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;
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)
614 for (i
= 0; i
< impl
->_obj
.offset_count
; i
++)
615 _mesa_free (strings
[i
]);
616 _mesa_free (strings
);
619 impl
->_obj
._generic
.info_log
= _mesa_strdup (ShGetInfoLog (
620 impl
->_obj
._3dlabs_shhandle
._obj
.handle
));
622 if (impl
->_vftbl
->GetSubType (intf
) == GL_FRAGMENT_SHADER
)
623 type
= slang_unit_fragment_shader
;
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
))
629 impl
->_obj
.compile_status
= GL_TRUE
;
631 if (info_log
.text
!= NULL
)
632 impl
->_obj
._generic
.info_log
= _mesa_strdup (info_log
.text
);
634 impl
->_obj
._generic
.info_log
= _mesa_strdup ("");
635 slang_info_log_destruct (&info_log
);
639 static struct gl2_shader_intf _shader_vftbl
= {
644 _shader_QueryInterface
649 _generic_GetDeleteStatus
,
652 NULL
, /* abstract GetSubType */
653 _shader_GetCompileStatus
,
660 _shader_constructor (struct gl2_shader_impl
*impl
)
662 _generic_constructor ((struct gl2_generic_impl
*) impl
);
663 _3dlabs_shhandle_constructor (&impl
->_obj
._3dlabs_shhandle
, (struct gl2_unknown_intf
**)
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;
673 struct gl2_program_obj
675 struct gl2_container_obj _container
;
676 GLboolean link_status
;
677 GLboolean validate_status
;
678 #if USE_3DLABS_FRONTEND
685 struct gl2_program_impl
687 struct gl2_program_intf
*_vftbl
;
688 struct gl2_program_obj _obj
;
692 _program_destructor (struct gl2_unknown_intf
**intf
)
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
);
699 _container_destructor (intf
);
700 slang_program_dtr (&impl
->_obj
.prog
);
703 static struct gl2_unknown_intf
**
704 _program_QueryInterface (struct gl2_unknown_intf
**intf
, enum gl2_uiid uiid
)
706 if (uiid
== UIID_PROGRAM
)
708 (**intf
).AddRef (intf
);
711 return _container_QueryInterface (intf
, uiid
);
715 _program_GetType (struct gl2_generic_intf
**intf
)
717 return GL_PROGRAM_OBJECT_ARB
;
721 _program_Attach (struct gl2_container_intf
**intf
, struct gl2_generic_intf
**att
)
723 GET_CURRENT_CONTEXT(ctx
);
724 struct gl2_unknown_intf
**sha
;
726 sha
= (**att
)._unknown
.QueryInterface ((struct gl2_unknown_intf
**) att
, UIID_SHADER
);
729 _mesa_error (ctx
, GL_INVALID_OPERATION
, "_program_Attach");
733 (**sha
).Release (sha
);
734 return _container_Attach (intf
, att
);
738 _program_GetLinkStatus (struct gl2_program_intf
**intf
)
740 struct gl2_program_impl
*impl
= (struct gl2_program_impl
*) intf
;
742 return impl
->_obj
.link_status
;
746 _program_GetValidateStatus (struct gl2_program_intf
**intf
)
748 struct gl2_program_impl
*impl
= (struct gl2_program_impl
*) intf
;
750 return impl
->_obj
.validate_status
;
754 _program_Link (struct gl2_program_intf
**intf
)
756 struct gl2_program_impl
*impl
= (struct gl2_program_impl
*) intf
;
757 #if USE_3DLABS_FRONTEND
761 slang_translation_unit
*units
[2];
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
);
769 #if USE_3DLABS_FRONTEND
770 handles
= (ShHandle
*) _mesa_malloc (impl
->_obj
._container
.attached_count
* sizeof (ShHandle
));
774 for (i
= 0; i
< impl
->_obj
._container
.attached_count
; i
++)
776 struct gl2_generic_intf
**gen
= impl
->_obj
._container
.attached
[i
];
777 struct gl2_3dlabs_shhandle_intf
**sh
;
779 sh
= (struct gl2_3dlabs_shhandle_intf
**) (**gen
)._unknown
.QueryInterface (
780 (struct gl2_unknown_intf
**) gen
, UIID_3DLABS_SHHANDLE
);
783 handles
[i
] = (**sh
).GetShHandle (sh
);
784 (**sh
)._unknown
.Release ((struct gl2_unknown_intf
**) sh
);
788 _mesa_free (handles
);
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
;
797 impl
->_obj
._container
._generic
.info_log
= _mesa_strdup (ShGetInfoLog (impl
->_obj
.linker
));
799 count
= impl
->_obj
._container
.attached_count
;
800 if (count
== 0 || count
> 2)
802 for (i
= 0; i
< count
; i
++)
804 struct gl2_generic_intf
**obj
;
805 struct gl2_unknown_intf
**unk
;
806 struct gl2_shader_impl
*sha
;
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
);
813 sha
= (struct gl2_shader_impl
*) unk
;
814 units
[i
] = &sha
->_obj
.unit
;
815 (**unk
).Release (unk
);
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");
822 impl
->_obj
._container
._generic
.info_log
= _mesa_strdup ("Link failed.\n");
827 _program_Validate (struct gl2_program_intf
**intf
)
829 struct gl2_program_impl
*impl
= (struct gl2_program_impl
*) intf
;
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
;
839 write_common_fixed (slang_program
*pro
, GLuint index
, const GLvoid
*src
, GLuint off
, GLuint size
)
843 for (i
= 0; i
< SLANG_UNIFORM_BINDING_MAX
; i
++)
847 addr
= pro
->common_fixed_entries
[i
][index
];
852 dst
= (GLubyte
*) pro
->machines
[i
]->mem
+ addr
+ off
* size
;
853 _mesa_memcpy (dst
, src
, size
);
859 write_common_fixed_mat4 (slang_program
*pro
, GLmatrix
*matrix
, GLuint off
, GLuint i
, GLuint ii
,
860 GLuint it
, GLuint iit
)
864 /* we want inverse matrix */
867 /* allocate inverse matrix and make it dirty */
868 _math_matrix_alloc_inv (matrix
);
869 _math_matrix_loadf (matrix
, matrix
->m
);
871 _math_matrix_analyse (matrix
);
873 write_common_fixed (pro
, i
, matrix
->m
, off
, 16 * sizeof (GLfloat
));
876 write_common_fixed (pro
, ii
, matrix
->inv
, off
, 16 * sizeof (GLfloat
));
879 _math_transposef (mat
, matrix
->m
);
880 write_common_fixed (pro
, it
, mat
, off
, 16 * sizeof (GLfloat
));
882 /* inverse transpose */
883 _math_transposef (mat
, matrix
->inv
);
884 write_common_fixed (pro
, iit
, mat
, off
, 16 * sizeof (GLfloat
));
888 _program_UpdateFixedUniforms (struct gl2_program_intf
**intf
)
890 GET_CURRENT_CONTEXT(ctx
);
891 struct gl2_program_impl
*impl
= (struct gl2_program_impl
*) intf
;
892 slang_program
*pro
= &impl
->_obj
.prog
;
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
);
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
);
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
);
919 for (i
= 0; i
< 8; i
++)
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
);
928 /* NORMAL matrix - upper 3x3 inverse transpose of MODELVIEW matrix */
929 p
= ctx
->ModelviewMatrixStack
.Top
->inv
;
939 write_common_fixed (pro
, SLANG_COMMON_FIXED_NORMALMATRIX
, v
, 0, 9 * sizeof (GLfloat
));
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 */
955 _program_UpdateFixedAttribute (struct gl2_program_intf
**intf
, GLuint index
, GLvoid
*data
,
956 GLuint offset
, GLuint size
, GLboolean write
)
958 struct gl2_program_impl
*impl
= (struct gl2_program_impl
*) intf
;
959 slang_program
*pro
= &impl
->_obj
.prog
;
962 addr
= pro
->vertex_fixed_entries
[index
];
967 mem
= (GLubyte
*) pro
->machines
[SLANG_UNIFORM_BINDING_VERTEX
]->mem
+ addr
+ offset
* size
;
969 _mesa_memcpy (mem
, data
, size
);
971 _mesa_memcpy (data
, mem
, size
);
976 _program_UpdateFixedVarying (struct gl2_program_intf
**intf
, GLuint index
, GLvoid
*data
,
977 GLuint offset
, GLuint size
, GLboolean write
)
979 struct gl2_program_impl
*impl
= (struct gl2_program_impl
*) intf
;
980 slang_program
*pro
= &impl
->_obj
.prog
;
983 addr
= pro
->fragment_fixed_entries
[index
];
988 mem
= (GLubyte
*) pro
->machines
[SLANG_UNIFORM_BINDING_FRAGMENT
]->mem
+ addr
+ offset
* size
;
990 _mesa_memcpy (mem
, data
, size
);
992 _mesa_memcpy (data
, mem
, size
);
996 static struct gl2_program_intf _program_vftbl
= {
1002 _program_QueryInterface
1007 _generic_GetDeleteStatus
,
1012 _container_GetAttachedCount
,
1013 _container_GetAttached
1015 _program_GetLinkStatus
,
1016 _program_GetValidateStatus
,
1019 _program_UpdateFixedUniforms
,
1020 _program_UpdateFixedAttribute
,
1021 _program_UpdateFixedVarying
1025 _program_constructor (struct gl2_program_impl
*impl
)
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 ();
1036 slang_program_ctr (&impl
->_obj
.prog
);
1039 struct gl2_fragment_shader_obj
1041 struct gl2_shader_obj _shader
;
1044 struct gl2_fragment_shader_impl
1046 struct gl2_fragment_shader_intf
*_vftbl
;
1047 struct gl2_fragment_shader_obj _obj
;
1051 _fragment_shader_destructor (struct gl2_unknown_intf
**intf
)
1053 struct gl2_fragment_shader_impl
*impl
= (struct gl2_fragment_shader_impl
*) intf
;
1056 /* TODO free fragment shader data */
1058 _shader_destructor (intf
);
1061 static struct gl2_unknown_intf
**
1062 _fragment_shader_QueryInterface (struct gl2_unknown_intf
**intf
, enum gl2_uiid uiid
)
1064 if (uiid
== UIID_FRAGMENT_SHADER
)
1066 (**intf
).AddRef (intf
);
1069 return _shader_QueryInterface (intf
, uiid
);
1073 _fragment_shader_GetSubType (struct gl2_shader_intf
**intf
)
1075 return GL_FRAGMENT_SHADER_ARB
;
1078 static struct gl2_fragment_shader_intf _fragment_shader_vftbl
= {
1084 _fragment_shader_QueryInterface
1089 _generic_GetDeleteStatus
,
1092 _fragment_shader_GetSubType
,
1093 _shader_GetCompileStatus
,
1101 _fragment_shader_constructor (struct gl2_fragment_shader_impl
*impl
)
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);
1111 struct gl2_vertex_shader_obj
1113 struct gl2_shader_obj _shader
;
1116 struct gl2_vertex_shader_impl
1118 struct gl2_vertex_shader_intf
*_vftbl
;
1119 struct gl2_vertex_shader_obj _obj
;
1123 _vertex_shader_destructor (struct gl2_unknown_intf
**intf
)
1125 struct gl2_vertex_shader_impl
*impl
= (struct gl2_vertex_shader_impl
*) intf
;
1128 /* TODO free vertex shader data */
1130 _shader_destructor (intf
);
1133 static struct gl2_unknown_intf
**
1134 _vertex_shader_QueryInterface (struct gl2_unknown_intf
**intf
, enum gl2_uiid uiid
)
1136 if (uiid
== UIID_VERTEX_SHADER
)
1138 (**intf
).AddRef (intf
);
1141 return _shader_QueryInterface (intf
, uiid
);
1145 _vertex_shader_GetSubType (struct gl2_shader_intf
**intf
)
1147 return GL_VERTEX_SHADER_ARB
;
1150 static struct gl2_vertex_shader_intf _vertex_shader_vftbl
= {
1156 _vertex_shader_QueryInterface
1161 _generic_GetDeleteStatus
,
1164 _vertex_shader_GetSubType
,
1165 _shader_GetCompileStatus
,
1173 _vertex_shader_constructor (struct gl2_vertex_shader_impl
*impl
)
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);
1184 _mesa_3dlabs_create_shader_object (GLenum shaderType
)
1188 case GL_FRAGMENT_SHADER_ARB
:
1190 struct gl2_fragment_shader_impl
*x
= (struct gl2_fragment_shader_impl
*)
1191 _mesa_malloc (sizeof (struct gl2_fragment_shader_impl
));
1195 _fragment_shader_constructor (x
);
1196 return x
->_obj
._shader
._generic
.name
;
1200 case GL_VERTEX_SHADER_ARB
:
1202 struct gl2_vertex_shader_impl
*x
= (struct gl2_vertex_shader_impl
*)
1203 _mesa_malloc (sizeof (struct gl2_vertex_shader_impl
));
1207 _vertex_shader_constructor (x
);
1208 return x
->_obj
._shader
._generic
.name
;
1218 _mesa_3dlabs_create_program_object (void)
1220 struct gl2_program_impl
*x
= (struct gl2_program_impl
*)
1221 _mesa_malloc (sizeof (struct gl2_program_impl
));
1225 _program_constructor (x
);
1226 return x
->_obj
._container
._generic
.name
;
1232 #include "slang_assemble.h"
1233 #include "slang_execute.h"
1235 int _slang_fetch_discard (struct gl2_program_intf
**pro
, GLboolean
*val
)
1237 struct gl2_program_impl
*impl
;
1239 impl
= (struct gl2_program_impl
*) pro
;
1240 *val
= impl
->_obj
.prog
.machines
[SLANG_UNIFORM_BINDING_FRAGMENT
]->kill
? GL_TRUE
: GL_FALSE
;
1244 static GLvoid
exec_shader (struct gl2_program_intf
**pro
, GLuint i
)
1246 struct gl2_program_impl
*impl
;
1249 impl
= (struct gl2_program_impl
*) pro
;
1250 p
= &impl
->_obj
.prog
;
1252 slang_machine_init (p
->machines
[i
]);
1253 p
->machines
[i
]->ip
= p
->code
[i
];
1255 _slang_execute2 (p
->assemblies
[i
], p
->machines
[i
]);
1258 GLvoid
_slang_exec_fragment_shader (struct gl2_program_intf
**pro
)
1260 exec_shader (pro
, SLANG_UNIFORM_BINDING_FRAGMENT
);
1263 GLvoid
_slang_exec_vertex_shader (struct gl2_program_intf
**pro
)
1265 exec_shader (pro
, SLANG_UNIFORM_BINDING_VERTEX
);
1268 GLint
_slang_get_uniform_location (struct gl2_program_intf
**pro
, const char *name
)
1270 struct gl2_program_impl
*impl
;
1271 slang_uniform_bindings
*bind
;
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)
1282 GLboolean
_slang_write_uniform (struct gl2_program_intf
**pro
, GLint loc
, GLsizei count
,
1283 const GLvoid
*data
, GLenum type
)
1285 struct gl2_program_impl
*impl
;
1286 slang_uniform_bindings
*bind
;
1287 slang_uniform_binding
*b
;
1293 impl
= (struct gl2_program_impl
*) pro
;
1294 bind
= &impl
->_obj
.prog
.uniforms
;
1295 if (loc
>= bind
->count
)
1298 b
= &bind
->table
[loc
];
1299 /* TODO: check sizes */
1300 /* TODO: check if not structure */
1301 if (b
->quant
->u
.basic_type
!= type
)
1304 for (i
= 0; i
< SLANG_UNIFORM_BINDING_MAX
; i
++)
1305 if (b
->address
[i
] != ~0)
1307 _mesa_memcpy (&impl
->_obj
.prog
.machines
[i
]->mem
[b
->address
[i
] / 4], data
,
1308 count
* b
->quant
->size
);
1313 GLuint
_slang_get_active_uniform_count (struct gl2_program_intf
**pro
)
1315 struct gl2_program_impl
*impl
;
1317 impl
= (struct gl2_program_impl
*) pro
;
1318 return impl
->_obj
.prog
.active_uniforms
.count
;
1321 GLuint
_slang_get_active_uniform_max_length (struct gl2_program_intf
**pro
)
1323 struct gl2_program_impl
*impl
;
1326 impl
= (struct gl2_program_impl
*) pro
;
1327 for (i
= 0; i
< impl
->_obj
.prog
.active_uniforms
.count
; i
++)
1329 GLuint n
= _mesa_strlen (impl
->_obj
.prog
.active_uniforms
.table
[i
].name
);
1336 GLvoid
_slang_get_active_uniform (struct gl2_program_intf
**pro
, GLuint index
, GLsizei maxLength
,
1337 GLsizei
*length
, GLint
*size
, GLenum
*type
, char *name
)
1339 struct gl2_program_impl
*impl
;
1340 slang_active_uniform
*u
;
1343 impl
= (struct gl2_program_impl
*) pro
;
1344 u
= &impl
->_obj
.prog
.active_uniforms
.table
[index
];
1346 len
= _mesa_strlen (u
->name
);
1347 if (len
>= maxLength
)
1348 len
= maxLength
- 1;
1349 _mesa_memcpy (name
, u
->name
, len
);
1353 *type
= u
->quant
->u
.basic_type
;
1354 if (u
->quant
->array_len
== 0)
1357 *size
= u
->quant
->array_len
;
1361 _mesa_init_shaderobjects_3dlabs (GLcontext
*ctx
)
1363 #if USE_3DLABS_FRONTEND
1364 _glslang_3dlabs_InitProcess ();
1365 _glslang_3dlabs_ShInitialize ();