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
35 #include "shaderobjects.h"
36 #include "shaderobjects_3dlabs.h"
41 #if USE_3DLABS_FRONTEND
42 #include "slang_mesa.h"
43 #include "Public/ShaderLang.h"
45 #include "slang_utility.h"
46 #include "slang_compile.h"
47 #include "slang_link.h"
50 struct gl2_unknown_obj
52 GLuint reference_count
;
53 void (* _destructor
) (struct gl2_unknown_intf
**);
56 struct gl2_unknown_impl
58 struct gl2_unknown_intf
*_vftbl
;
59 struct gl2_unknown_obj _obj
;
63 _unknown_destructor (struct gl2_unknown_intf
**intf
)
68 _unknown_AddRef (struct gl2_unknown_intf
**intf
)
70 struct gl2_unknown_impl
*impl
= (struct gl2_unknown_impl
*) intf
;
72 impl
->_obj
.reference_count
++;
76 _unknown_Release (struct gl2_unknown_intf
**intf
)
78 struct gl2_unknown_impl
*impl
= (struct gl2_unknown_impl
*) intf
;
80 impl
->_obj
.reference_count
--;
81 if (impl
->_obj
.reference_count
== 0)
83 impl
->_obj
._destructor (intf
);
84 _mesa_free ((void *) intf
);
88 static struct gl2_unknown_intf
**
89 _unknown_QueryInterface (struct gl2_unknown_intf
**intf
, enum gl2_uiid uiid
)
91 if (uiid
== UIID_UNKNOWN
)
93 (**intf
).AddRef (intf
);
99 static struct gl2_unknown_intf _unknown_vftbl
= {
102 _unknown_QueryInterface
106 _unknown_constructor (struct gl2_unknown_impl
*impl
)
108 impl
->_vftbl
= &_unknown_vftbl
;
109 impl
->_obj
.reference_count
= 1;
110 impl
->_obj
._destructor
= _unknown_destructor
;
113 struct gl2_unkinner_obj
115 struct gl2_unknown_intf
**unkouter
;
118 struct gl2_unkinner_impl
120 struct gl2_unknown_intf
*_vftbl
;
121 struct gl2_unkinner_obj _obj
;
125 _unkinner_destructor (struct gl2_unknown_intf
**intf
)
130 _unkinner_AddRef (struct gl2_unknown_intf
**intf
)
132 struct gl2_unkinner_impl
*impl
= (struct gl2_unkinner_impl
*) intf
;
134 (**impl
->_obj
.unkouter
).AddRef (impl
->_obj
.unkouter
);
138 _unkinner_Release (struct gl2_unknown_intf
**intf
)
140 struct gl2_unkinner_impl
*impl
= (struct gl2_unkinner_impl
*) intf
;
142 (**impl
->_obj
.unkouter
).Release (impl
->_obj
.unkouter
);
145 static struct gl2_unknown_intf
**
146 _unkinner_QueryInterface (struct gl2_unknown_intf
**intf
, enum gl2_uiid uiid
)
148 struct gl2_unkinner_impl
*impl
= (struct gl2_unkinner_impl
*) intf
;
150 return (**impl
->_obj
.unkouter
).QueryInterface (impl
->_obj
.unkouter
, uiid
);
153 static struct gl2_unknown_intf _unkinner_vftbl
= {
156 _unkinner_QueryInterface
160 _unkinner_constructor (struct gl2_unkinner_impl
*impl
, struct gl2_unknown_intf
**outer
)
162 impl
->_vftbl
= &_unkinner_vftbl
;
163 impl
->_obj
.unkouter
= outer
;
166 struct gl2_generic_obj
168 struct gl2_unknown_obj _unknown
;
170 GLboolean delete_status
;
174 struct gl2_generic_impl
176 struct gl2_generic_intf
*_vftbl
;
177 struct gl2_generic_obj _obj
;
181 _generic_destructor (struct gl2_unknown_intf
**intf
)
183 GET_CURRENT_CONTEXT(ctx
);
184 struct gl2_generic_impl
*impl
= (struct gl2_generic_impl
*) intf
;
186 _mesa_free ((void *) impl
->_obj
.info_log
);
188 _glthread_LOCK_MUTEX (ctx
->Shared
->Mutex
);
189 _mesa_HashRemove (ctx
->Shared
->GL2Objects
, impl
->_obj
.name
);
190 _glthread_UNLOCK_MUTEX (ctx
->Shared
->Mutex
);
192 _unknown_destructor (intf
);
195 static struct gl2_unknown_intf
**
196 _generic_QueryInterface (struct gl2_unknown_intf
**intf
, enum gl2_uiid uiid
)
198 if (uiid
== UIID_GENERIC
)
200 (**intf
).AddRef (intf
);
203 return _unknown_QueryInterface (intf
, uiid
);
207 _generic_Delete (struct gl2_generic_intf
**intf
)
209 struct gl2_generic_impl
*impl
= (struct gl2_generic_impl
*) intf
;
211 if (impl
->_obj
.delete_status
== GL_FALSE
)
213 impl
->_obj
.delete_status
= GL_TRUE
;
214 (**intf
)._unknown
.Release ((struct gl2_unknown_intf
**) intf
);
219 _generic_GetName (struct gl2_generic_intf
**intf
)
221 struct gl2_generic_impl
*impl
= (struct gl2_generic_impl
*) intf
;
223 return impl
->_obj
.name
;
227 _generic_GetDeleteStatus (struct gl2_generic_intf
**intf
)
229 struct gl2_generic_impl
*impl
= (struct gl2_generic_impl
*) intf
;
231 return impl
->_obj
.delete_status
;
234 static const GLcharARB
*
235 _generic_GetInfoLog (struct gl2_generic_intf
**intf
)
237 struct gl2_generic_impl
*impl
= (struct gl2_generic_impl
*) intf
;
239 return impl
->_obj
.info_log
;
242 static struct gl2_generic_intf _generic_vftbl
= {
246 _generic_QueryInterface
249 NULL
, /* abstract GetType */
251 _generic_GetDeleteStatus
,
256 _generic_constructor (struct gl2_generic_impl
*impl
)
258 GET_CURRENT_CONTEXT(ctx
);
260 _unknown_constructor ((struct gl2_unknown_impl
*) impl
);
261 impl
->_vftbl
= &_generic_vftbl
;
262 impl
->_obj
._unknown
._destructor
= _generic_destructor
;
263 impl
->_obj
.delete_status
= GL_FALSE
;
264 impl
->_obj
.info_log
= NULL
;
266 _glthread_LOCK_MUTEX (ctx
->Shared
->Mutex
);
267 impl
->_obj
.name
= _mesa_HashFindFreeKeyBlock (ctx
->Shared
->GL2Objects
, 1);
268 _mesa_HashInsert (ctx
->Shared
->GL2Objects
, impl
->_obj
.name
, (void *) impl
);
269 _glthread_UNLOCK_MUTEX (ctx
->Shared
->Mutex
);
272 struct gl2_container_obj
274 struct gl2_generic_obj _generic
;
275 struct gl2_generic_intf
***attached
;
276 GLuint attached_count
;
279 struct gl2_container_impl
281 struct gl2_container_intf
*_vftbl
;
282 struct gl2_container_obj _obj
;
286 _container_destructor (struct gl2_unknown_intf
**intf
)
288 struct gl2_container_impl
*impl
= (struct gl2_container_impl
*) intf
;
291 for (i
= 0; i
< impl
->_obj
.attached_count
; i
++)
293 struct gl2_generic_intf
**x
= impl
->_obj
.attached
[i
];
294 (**x
)._unknown
.Release ((struct gl2_unknown_intf
**) x
);
297 _generic_destructor (intf
);
300 static struct gl2_unknown_intf
**
301 _container_QueryInterface (struct gl2_unknown_intf
**intf
, enum gl2_uiid uiid
)
303 if (uiid
== UIID_CONTAINER
)
305 (**intf
).AddRef (intf
);
308 return _generic_QueryInterface (intf
, uiid
);
312 _container_Attach (struct gl2_container_intf
**intf
, struct gl2_generic_intf
**att
)
314 GET_CURRENT_CONTEXT(ctx
);
315 struct gl2_container_impl
*impl
= (struct gl2_container_impl
*) intf
;
318 for (i
= 0; i
< impl
->_obj
.attached_count
; i
++)
319 if (impl
->_obj
.attached
[i
] == att
)
321 _mesa_error (ctx
, GL_INVALID_OPERATION
, "_container_Attach");
325 impl
->_obj
.attached
= (struct gl2_generic_intf
***) _mesa_realloc (impl
->_obj
.attached
,
326 impl
->_obj
.attached_count
* sizeof (*impl
->_obj
.attached
), (impl
->_obj
.attached_count
+ 1) *
327 sizeof (*impl
->_obj
.attached
));
328 if (impl
->_obj
.attached
== NULL
)
331 impl
->_obj
.attached
[impl
->_obj
.attached_count
] = att
;
332 impl
->_obj
.attached_count
++;
333 (**att
)._unknown
.AddRef ((struct gl2_unknown_intf
**) att
);
338 _container_Detach (struct gl2_container_intf
**intf
, struct gl2_generic_intf
**att
)
340 GET_CURRENT_CONTEXT(ctx
);
341 struct gl2_container_impl
*impl
= (struct gl2_container_impl
*) intf
;
344 for (i
= 0; i
< impl
->_obj
.attached_count
; i
++)
345 if (impl
->_obj
.attached
[i
] == att
)
347 for (j
= i
; j
< impl
->_obj
.attached_count
- 1; j
++)
348 impl
->_obj
.attached
[j
] = impl
->_obj
.attached
[j
+ 1];
349 impl
->_obj
.attached
= (struct gl2_generic_intf
***) _mesa_realloc (impl
->_obj
.attached
,
350 impl
->_obj
.attached_count
* sizeof (*impl
->_obj
.attached
),
351 (impl
->_obj
.attached_count
- 1) * sizeof (*impl
->_obj
.attached
));
352 impl
->_obj
.attached_count
--;
353 (**att
)._unknown
.Release ((struct gl2_unknown_intf
**) att
);
357 _mesa_error (ctx
, GL_INVALID_OPERATION
, "_container_Detach");
362 _container_GetAttachedCount (struct gl2_container_intf
**intf
)
364 struct gl2_container_impl
*impl
= (struct gl2_container_impl
*) intf
;
366 return impl
->_obj
.attached_count
;
369 static struct gl2_generic_intf
**
370 _container_GetAttached (struct gl2_container_intf
**intf
, GLuint index
)
372 struct gl2_container_impl
*impl
= (struct gl2_container_impl
*) intf
;
374 (**impl
->_obj
.attached
[index
])._unknown
.AddRef (
375 (struct gl2_unknown_intf
**)impl
->_obj
.attached
[index
]);
376 return impl
->_obj
.attached
[index
];
379 static struct gl2_container_intf _container_vftbl
= {
384 _container_QueryInterface
387 NULL
, /* abstract GetType */
389 _generic_GetDeleteStatus
,
394 _container_GetAttachedCount
,
395 _container_GetAttached
399 _container_constructor (struct gl2_container_impl
*impl
)
401 _generic_constructor ((struct gl2_generic_impl
*) impl
);
402 impl
->_vftbl
= &_container_vftbl
;
403 impl
->_obj
._generic
._unknown
._destructor
= _container_destructor
;
404 impl
->_obj
.attached
= NULL
;
405 impl
->_obj
.attached_count
= 0;
408 struct gl2_3dlabs_shhandle_obj
410 struct gl2_unkinner_obj _unknown
;
411 #if USE_3DLABS_FRONTEND
416 struct gl2_3dlabs_shhandle_impl
418 struct gl2_3dlabs_shhandle_intf
*_vftbl
;
419 struct gl2_3dlabs_shhandle_obj _obj
;
423 _3dlabs_shhandle_destructor (struct gl2_unknown_intf
**intf
)
425 #if USE_3DLABS_FRONTEND
426 struct gl2_3dlabs_shhandle_impl
*impl
= (struct gl2_3dlabs_shhandle_impl
*) intf
;
427 ShDestruct (impl
->_obj
.handle
);
429 _unkinner_destructor (intf
);
433 _3dlabs_shhandle_GetShHandle (struct gl2_3dlabs_shhandle_intf
**intf
)
435 #if USE_3DLABS_FRONTEND
436 struct gl2_3dlabs_shhandle_impl
*impl
= (struct gl2_3dlabs_shhandle_impl
*) intf
;
437 return impl
->_obj
.handle
;
443 static struct gl2_3dlabs_shhandle_intf _3dlabs_shhandle_vftbl
= {
447 _unkinner_QueryInterface
449 _3dlabs_shhandle_GetShHandle
453 _3dlabs_shhandle_constructor (struct gl2_3dlabs_shhandle_impl
*impl
, struct gl2_unknown_intf
**outer
)
455 _unkinner_constructor ((struct gl2_unkinner_impl
*) impl
, outer
);
456 impl
->_vftbl
= &_3dlabs_shhandle_vftbl
;
457 #if USE_3DLABS_FRONTEND
458 impl
->_obj
.handle
= NULL
;
462 struct gl2_shader_obj
464 struct gl2_generic_obj _generic
;
465 struct gl2_3dlabs_shhandle_impl _3dlabs_shhandle
;
466 GLboolean compile_status
;
469 GLsizei offset_count
;
470 slang_translation_unit unit
;
473 struct gl2_shader_impl
475 struct gl2_shader_intf
*_vftbl
;
476 struct gl2_shader_obj _obj
;
480 _shader_destructor (struct gl2_unknown_intf
**intf
)
482 struct gl2_shader_impl
*impl
= (struct gl2_shader_impl
*) intf
;
484 _mesa_free ((void *) impl
->_obj
.source
);
485 _mesa_free ((void *) impl
->_obj
.offsets
);
486 _3dlabs_shhandle_destructor ((struct gl2_unknown_intf
**) &impl
->_obj
._3dlabs_shhandle
._vftbl
);
487 _generic_destructor (intf
);
490 static struct gl2_unknown_intf
**
491 _shader_QueryInterface (struct gl2_unknown_intf
**intf
, enum gl2_uiid uiid
)
493 #if USE_3DLABS_FRONTEND
494 struct gl2_shader_impl
*impl
= (struct gl2_shader_impl
*) intf
;
497 if (uiid
== UIID_SHADER
)
499 (**intf
).AddRef (intf
);
502 #if USE_3DLABS_FRONTEND
503 if (uiid
== UIID_3DLABS_SHHANDLE
)
505 (**intf
).AddRef (intf
);
506 return (struct gl2_unknown_intf
**) &impl
->_obj
._3dlabs_shhandle
._vftbl
;
509 return _generic_QueryInterface (intf
, uiid
);
513 _shader_GetType (struct gl2_generic_intf
**intf
)
515 return GL_SHADER_OBJECT_ARB
;
519 _shader_GetCompileStatus (struct gl2_shader_intf
**intf
)
521 struct gl2_shader_impl
*impl
= (struct gl2_shader_impl
*) intf
;
523 return impl
->_obj
.compile_status
;
527 _shader_SetSource (struct gl2_shader_intf
**intf
, GLcharARB
*src
, GLint
*off
, GLsizei cnt
)
529 struct gl2_shader_impl
*impl
= (struct gl2_shader_impl
*) intf
;
531 _mesa_free ((void *) impl
->_obj
.source
);
532 impl
->_obj
.source
= src
;
533 _mesa_free ((void *) impl
->_obj
.offsets
);
534 impl
->_obj
.offsets
= off
;
535 impl
->_obj
.offset_count
= cnt
;
538 static const GLcharARB
*
539 _shader_GetSource (struct gl2_shader_intf
**intf
)
541 struct gl2_shader_impl
*impl
= (struct gl2_shader_impl
*) intf
;
543 return impl
->_obj
.source
;
547 _shader_Compile (struct gl2_shader_intf
**intf
)
549 struct gl2_shader_impl
*impl
= (struct gl2_shader_impl
*) intf
;
550 #if USE_3DLABS_FRONTEND
552 TBuiltInResource res
;
554 slang_unit_type type
;
555 slang_info_log info_log
;
558 impl
->_obj
.compile_status
= GL_FALSE
;
559 _mesa_free ((void *) impl
->_obj
._generic
.info_log
);
560 impl
->_obj
._generic
.info_log
= NULL
;
562 #if USE_3DLABS_FRONTEND
563 /* 3dlabs compiler expects us to feed it with null-terminated string array,
564 we've got only one big string with offsets, so we must split it; but when
565 there's only one string to deal with, we pass its address directly */
567 if (impl
->_obj
.offset_count
<= 1)
568 strings
= &impl
->_obj
.source
;
571 GLsizei i
, offset
= 0;
573 strings
= (char **) _mesa_malloc (impl
->_obj
.offset_count
* sizeof (char *));
577 for (i
= 0; i
< impl
->_obj
.offset_count
; i
++)
579 GLsizei size
= impl
->_obj
.offsets
[i
] - offset
;
581 strings
[i
] = (char *) _mesa_malloc ((size
+ 1) * sizeof (char));
582 if (strings
[i
] == NULL
)
586 for (j
= 0; j
< i
; j
++)
587 _mesa_free (strings
[j
]);
588 _mesa_free (strings
);
592 _mesa_memcpy (strings
[i
], impl
->_obj
.source
+ offset
, size
* sizeof (char));
593 strings
[i
][size
] = '\0';
594 offset
= impl
->_obj
.offsets
[i
];
598 /* TODO set these fields to some REAL numbers */
600 res
.maxClipPlanes
= 6;
601 res
.maxTextureUnits
= 2;
602 res
.maxTextureCoords
= 2;
603 res
.maxVertexAttribs
= 8;
604 res
.maxVertexUniformComponents
= 64;
605 res
.maxVaryingFloats
= 8;
606 res
.maxVertexTextureImageUnits
= 2;
607 res
.maxCombinedTextureImageUnits
= 2;
608 res
.maxTextureImageUnits
= 2;
609 res
.maxFragmentUniformComponents
= 64;
610 res
.maxDrawBuffers
= 1;
612 if (ShCompile (impl
->_obj
._3dlabs_shhandle
._obj
.handle
, strings
, impl
->_obj
.offset_count
,
613 EShOptFull
, &res
, 0))
614 impl
->_obj
.compile_status
= GL_TRUE
;
615 if (impl
->_obj
.offset_count
> 1)
619 for (i
= 0; i
< impl
->_obj
.offset_count
; i
++)
620 _mesa_free (strings
[i
]);
621 _mesa_free (strings
);
624 impl
->_obj
._generic
.info_log
= _mesa_strdup (ShGetInfoLog (
625 impl
->_obj
._3dlabs_shhandle
._obj
.handle
));
627 if (impl
->_vftbl
->GetSubType (intf
) == GL_FRAGMENT_SHADER
)
628 type
= slang_unit_fragment_shader
;
630 type
= slang_unit_vertex_shader
;
631 slang_info_log_construct (&info_log
);
632 if (_slang_compile (impl
->_obj
.source
, &impl
->_obj
.unit
, type
, &info_log
))
634 impl
->_obj
.compile_status
= GL_TRUE
;
636 if (info_log
.text
!= NULL
)
637 impl
->_obj
._generic
.info_log
= _mesa_strdup (info_log
.text
);
639 impl
->_obj
._generic
.info_log
= _mesa_strdup ("");
640 slang_info_log_destruct (&info_log
);
644 static struct gl2_shader_intf _shader_vftbl
= {
649 _shader_QueryInterface
654 _generic_GetDeleteStatus
,
657 NULL
, /* abstract GetSubType */
658 _shader_GetCompileStatus
,
665 _shader_constructor (struct gl2_shader_impl
*impl
)
667 _generic_constructor ((struct gl2_generic_impl
*) impl
);
668 _3dlabs_shhandle_constructor (&impl
->_obj
._3dlabs_shhandle
, (struct gl2_unknown_intf
**)
670 impl
->_vftbl
= &_shader_vftbl
;
671 impl
->_obj
._generic
._unknown
._destructor
= _shader_destructor
;
672 impl
->_obj
.compile_status
= GL_FALSE
;
673 impl
->_obj
.source
= NULL
;
674 impl
->_obj
.offsets
= NULL
;
675 impl
->_obj
.offset_count
= 0;
678 struct gl2_program_obj
680 struct gl2_container_obj _container
;
681 GLboolean link_status
;
682 GLboolean validate_status
;
683 #if USE_3DLABS_FRONTEND
690 struct gl2_program_impl
692 struct gl2_program_intf
*_vftbl
;
693 struct gl2_program_obj _obj
;
697 _program_destructor (struct gl2_unknown_intf
**intf
)
699 struct gl2_program_impl
*impl
= (struct gl2_program_impl
*) intf
;
700 #if USE_3DLABS_FRONTEND
701 ShDestruct (impl
->_obj
.linker
);
702 ShDestruct (impl
->_obj
.uniforms
);
704 _container_destructor (intf
);
705 slang_program_dtr (&impl
->_obj
.prog
);
708 static struct gl2_unknown_intf
**
709 _program_QueryInterface (struct gl2_unknown_intf
**intf
, enum gl2_uiid uiid
)
711 if (uiid
== UIID_PROGRAM
)
713 (**intf
).AddRef (intf
);
716 return _container_QueryInterface (intf
, uiid
);
720 _program_GetType (struct gl2_generic_intf
**intf
)
722 return GL_PROGRAM_OBJECT_ARB
;
726 _program_Attach (struct gl2_container_intf
**intf
, struct gl2_generic_intf
**att
)
728 GET_CURRENT_CONTEXT(ctx
);
729 struct gl2_unknown_intf
**sha
;
731 sha
= (**att
)._unknown
.QueryInterface ((struct gl2_unknown_intf
**) att
, UIID_SHADER
);
734 _mesa_error (ctx
, GL_INVALID_OPERATION
, "_program_Attach");
738 (**sha
).Release (sha
);
739 return _container_Attach (intf
, att
);
743 _program_GetLinkStatus (struct gl2_program_intf
**intf
)
745 struct gl2_program_impl
*impl
= (struct gl2_program_impl
*) intf
;
747 return impl
->_obj
.link_status
;
751 _program_GetValidateStatus (struct gl2_program_intf
**intf
)
753 struct gl2_program_impl
*impl
= (struct gl2_program_impl
*) intf
;
755 return impl
->_obj
.validate_status
;
759 _program_Link (struct gl2_program_intf
**intf
)
761 struct gl2_program_impl
*impl
= (struct gl2_program_impl
*) intf
;
762 #if USE_3DLABS_FRONTEND
766 slang_translation_unit
*units
[2];
768 impl
->_obj
.link_status
= GL_FALSE
;
769 _mesa_free ((void *) impl
->_obj
._container
._generic
.info_log
);
770 impl
->_obj
._container
._generic
.info_log
= NULL
;
771 slang_program_dtr (&impl
->_obj
.prog
);
772 slang_program_ctr (&impl
->_obj
.prog
);
774 #if USE_3DLABS_FRONTEND
775 handles
= (ShHandle
*) _mesa_malloc (impl
->_obj
._container
.attached_count
* sizeof (ShHandle
));
779 for (i
= 0; i
< impl
->_obj
._container
.attached_count
; i
++)
781 struct gl2_generic_intf
**gen
= impl
->_obj
._container
.attached
[i
];
782 struct gl2_3dlabs_shhandle_intf
**sh
;
784 sh
= (struct gl2_3dlabs_shhandle_intf
**) (**gen
)._unknown
.QueryInterface (
785 (struct gl2_unknown_intf
**) gen
, UIID_3DLABS_SHHANDLE
);
788 handles
[i
] = (**sh
).GetShHandle (sh
);
789 (**sh
)._unknown
.Release ((struct gl2_unknown_intf
**) sh
);
793 _mesa_free (handles
);
798 if (ShLink (impl
->_obj
.linker
, handles
, impl
->_obj
._container
.attached_count
,
799 impl
->_obj
.uniforms
, NULL
, NULL
))
800 impl
->_obj
.link_status
= GL_TRUE
;
802 impl
->_obj
._container
._generic
.info_log
= _mesa_strdup (ShGetInfoLog (impl
->_obj
.linker
));
804 count
= impl
->_obj
._container
.attached_count
;
805 if (count
== 0 || count
> 2)
807 for (i
= 0; i
< count
; i
++)
809 struct gl2_generic_intf
**obj
;
810 struct gl2_unknown_intf
**unk
;
811 struct gl2_shader_impl
*sha
;
813 obj
= impl
->_obj
._container
.attached
[i
];
814 unk
= (**obj
)._unknown
.QueryInterface ((struct gl2_unknown_intf
**) obj
, UIID_SHADER
);
815 (**obj
)._unknown
.Release ((struct gl2_unknown_intf
**) obj
);
818 sha
= (struct gl2_shader_impl
*) unk
;
819 units
[i
] = &sha
->_obj
.unit
;
820 (**unk
).Release (unk
);
823 impl
->_obj
.link_status
= _slang_link (&impl
->_obj
.prog
, units
, count
);
824 if (impl
->_obj
.link_status
)
825 impl
->_obj
._container
._generic
.info_log
= _mesa_strdup ("Link OK.\n");
827 impl
->_obj
._container
._generic
.info_log
= _mesa_strdup ("Link failed.\n");
832 _program_Validate (struct gl2_program_intf
**intf
)
834 struct gl2_program_impl
*impl
= (struct gl2_program_impl
*) intf
;
836 impl
->_obj
.validate_status
= GL_FALSE
;
837 _mesa_free ((void *) impl
->_obj
._container
._generic
.info_log
);
838 impl
->_obj
._container
._generic
.info_log
= NULL
;
843 static struct gl2_program_intf _program_vftbl
= {
849 _program_QueryInterface
854 _generic_GetDeleteStatus
,
859 _container_GetAttachedCount
,
860 _container_GetAttached
862 _program_GetLinkStatus
,
863 _program_GetValidateStatus
,
869 _program_constructor (struct gl2_program_impl
*impl
)
871 _container_constructor ((struct gl2_container_impl
*) impl
);
872 impl
->_vftbl
= &_program_vftbl
;
873 impl
->_obj
._container
._generic
._unknown
._destructor
= _program_destructor
;
874 impl
->_obj
.link_status
= GL_FALSE
;
875 impl
->_obj
.validate_status
= GL_FALSE
;
876 #if USE_3DLABS_FRONTEND
877 impl
->_obj
.linker
= ShConstructLinker (EShExVertexFragment
, 0);
878 impl
->_obj
.uniforms
= ShConstructUniformMap ();
880 slang_program_ctr (&impl
->_obj
.prog
);
883 struct gl2_fragment_shader_obj
885 struct gl2_shader_obj _shader
;
888 struct gl2_fragment_shader_impl
890 struct gl2_fragment_shader_intf
*_vftbl
;
891 struct gl2_fragment_shader_obj _obj
;
895 _fragment_shader_destructor (struct gl2_unknown_intf
**intf
)
897 struct gl2_fragment_shader_impl
*impl
= (struct gl2_fragment_shader_impl
*) intf
;
900 /* TODO free fragment shader data */
902 _shader_destructor (intf
);
905 static struct gl2_unknown_intf
**
906 _fragment_shader_QueryInterface (struct gl2_unknown_intf
**intf
, enum gl2_uiid uiid
)
908 if (uiid
== UIID_FRAGMENT_SHADER
)
910 (**intf
).AddRef (intf
);
913 return _shader_QueryInterface (intf
, uiid
);
917 _fragment_shader_GetSubType (struct gl2_shader_intf
**intf
)
919 return GL_FRAGMENT_SHADER_ARB
;
922 static struct gl2_fragment_shader_intf _fragment_shader_vftbl
= {
928 _fragment_shader_QueryInterface
933 _generic_GetDeleteStatus
,
936 _fragment_shader_GetSubType
,
937 _shader_GetCompileStatus
,
945 _fragment_shader_constructor (struct gl2_fragment_shader_impl
*impl
)
947 _shader_constructor ((struct gl2_shader_impl
*) impl
);
948 impl
->_vftbl
= &_fragment_shader_vftbl
;
949 impl
->_obj
._shader
._generic
._unknown
._destructor
= _fragment_shader_destructor
;
950 #if USE_3DLABS_FRONTEND
951 impl
->_obj
._shader
._3dlabs_shhandle
._obj
.handle
= ShConstructCompiler (EShLangFragment
, 0);
955 struct gl2_vertex_shader_obj
957 struct gl2_shader_obj _shader
;
960 struct gl2_vertex_shader_impl
962 struct gl2_vertex_shader_intf
*_vftbl
;
963 struct gl2_vertex_shader_obj _obj
;
967 _vertex_shader_destructor (struct gl2_unknown_intf
**intf
)
969 struct gl2_vertex_shader_impl
*impl
= (struct gl2_vertex_shader_impl
*) intf
;
972 /* TODO free vertex shader data */
974 _shader_destructor (intf
);
977 static struct gl2_unknown_intf
**
978 _vertex_shader_QueryInterface (struct gl2_unknown_intf
**intf
, enum gl2_uiid uiid
)
980 if (uiid
== UIID_VERTEX_SHADER
)
982 (**intf
).AddRef (intf
);
985 return _shader_QueryInterface (intf
, uiid
);
989 _vertex_shader_GetSubType (struct gl2_shader_intf
**intf
)
991 return GL_VERTEX_SHADER_ARB
;
994 static struct gl2_vertex_shader_intf _vertex_shader_vftbl
= {
1000 _vertex_shader_QueryInterface
1005 _generic_GetDeleteStatus
,
1008 _vertex_shader_GetSubType
,
1009 _shader_GetCompileStatus
,
1017 _vertex_shader_constructor (struct gl2_vertex_shader_impl
*impl
)
1019 _shader_constructor ((struct gl2_shader_impl
*) impl
);
1020 impl
->_vftbl
= &_vertex_shader_vftbl
;
1021 impl
->_obj
._shader
._generic
._unknown
._destructor
= _vertex_shader_destructor
;
1022 #if USE_3DLABS_FRONTEND
1023 impl
->_obj
._shader
._3dlabs_shhandle
._obj
.handle
= ShConstructCompiler (EShLangVertex
, 0);
1028 _mesa_3dlabs_create_shader_object (GLenum shaderType
)
1032 case GL_FRAGMENT_SHADER_ARB
:
1034 struct gl2_fragment_shader_impl
*x
= (struct gl2_fragment_shader_impl
*)
1035 _mesa_malloc (sizeof (struct gl2_fragment_shader_impl
));
1039 _fragment_shader_constructor (x
);
1040 return x
->_obj
._shader
._generic
.name
;
1044 case GL_VERTEX_SHADER_ARB
:
1046 struct gl2_vertex_shader_impl
*x
= (struct gl2_vertex_shader_impl
*)
1047 _mesa_malloc (sizeof (struct gl2_vertex_shader_impl
));
1051 _vertex_shader_constructor (x
);
1052 return x
->_obj
._shader
._generic
.name
;
1062 _mesa_3dlabs_create_program_object (void)
1064 struct gl2_program_impl
*x
= (struct gl2_program_impl
*)
1065 _mesa_malloc (sizeof (struct gl2_program_impl
));
1069 _program_constructor (x
);
1070 return x
->_obj
._container
._generic
.name
;
1076 #include "slang_assemble.h"
1077 #include "slang_execute.h"
1079 static GLubyte
*get_address_of (struct gl2_vertex_shader_intf
**vs
, const char *name
)
1081 struct gl2_vertex_shader_impl
*impl
;
1082 slang_translation_unit
*unit
;
1084 slang_variable
*var
;
1086 impl
= (struct gl2_vertex_shader_impl
*) vs
;
1087 unit
= &impl
->_obj
._shader
.unit
;
1088 atom
= slang_atom_pool_atom (unit
->atom_pool
, name
);
1089 var
= _slang_locate_variable (&unit
->globals
, atom
, 1);
1090 if (var
== NULL
|| var
->address
== ~0)
1092 return (GLubyte
*) unit
->machine
->mem
+ var
->address
;
1095 static GLubyte
*get_address_of_f (struct gl2_fragment_shader_intf
**fs
, const char *name
)
1097 struct gl2_fragment_shader_impl
*impl
;
1098 slang_translation_unit
*unit
;
1100 slang_variable
*var
;
1102 impl
= (struct gl2_fragment_shader_impl
*) fs
;
1103 unit
= &impl
->_obj
._shader
.unit
;
1104 atom
= slang_atom_pool_atom (unit
->atom_pool
, name
);
1105 var
= _slang_locate_variable (&unit
->globals
, atom
, 1);
1106 if (var
== NULL
|| var
->address
== ~0)
1108 return (GLubyte
*) unit
->machine
->mem
+ var
->address
;
1111 static int fetch_mem (struct gl2_vertex_shader_intf
**vs
, const char *name
, GLvoid
*val
,
1112 GLuint size
, GLuint index
, int write
)
1116 data
= get_address_of (vs
, name
);
1120 _mesa_memcpy (data
+ index
* size
, val
, size
);
1122 _mesa_memcpy (val
, data
+ index
* size
, size
);
1126 static int fetch_mem_f (struct gl2_fragment_shader_intf
**fs
, const char *name
, GLvoid
*val
,
1127 GLuint size
, GLuint index
, int write
)
1131 data
= get_address_of_f (fs
, name
);
1135 _mesa_memcpy (data
+ index
* size
, val
, size
);
1137 _mesa_memcpy (val
, data
+ index
* size
, size
);
1141 int _slang_fetch_float (struct gl2_vertex_shader_intf
**vs
, const char *name
, GLfloat
*val
, int write
)
1143 return fetch_mem (vs
, name
, val
, 4, 0, write
);
1146 int _slang_fetch_vec3 (struct gl2_vertex_shader_intf
**vs
, const char *name
, GLfloat
*val
, int write
)
1148 return fetch_mem (vs
, name
, val
, 12, 0, write
);
1151 int _slang_fetch_vec4 (struct gl2_vertex_shader_intf
**vs
, const char *name
, GLfloat
*val
,
1152 GLuint index
, int write
)
1154 return fetch_mem (vs
, name
, val
, 16, index
, write
);
1157 int _slang_fetch_vec4_f (struct gl2_fragment_shader_intf
**fs
, const char *name
, GLfloat
*val
,
1158 GLuint index
, int write
)
1160 return fetch_mem_f (fs
, name
, val
, 16, index
, write
);
1163 int _slang_fetch_mat3 (struct gl2_vertex_shader_intf
**vs
, const char *name
, GLfloat
*val
,
1164 GLuint index
, int write
)
1166 return fetch_mem (vs
, name
, val
, 36, index
, write
);
1169 int _slang_fetch_mat4 (struct gl2_vertex_shader_intf
**vs
, const char *name
, GLfloat
*val
,
1170 GLuint index
, int write
)
1172 return fetch_mem (vs
, name
, val
, 64, index
, write
);
1175 int _slang_fetch_discard (struct gl2_fragment_shader_intf
**fs
, GLboolean
*val
)
1177 struct gl2_fragment_shader_impl
*impl
;
1178 slang_translation_unit
*unit
;
1180 impl
= (struct gl2_fragment_shader_impl
*) fs
;
1181 unit
= &impl
->_obj
._shader
.unit
;
1182 *val
= unit
->machine
->kill
? GL_TRUE
: GL_FALSE
;
1186 void _slang_exec_vertex_shader (struct gl2_vertex_shader_intf
**vs
)
1188 struct gl2_vertex_shader_impl
*impl
;
1189 slang_translation_unit
*unit
;
1193 impl
= (struct gl2_vertex_shader_impl
*) vs
;
1194 unit
= &impl
->_obj
._shader
.unit
;
1195 atom
= slang_atom_pool_atom (unit
->atom_pool
, "main");
1196 for (i
= 0; i
< unit
->functions
.num_functions
; i
++)
1197 if (atom
== unit
->functions
.functions
[i
].header
.a_name
)
1199 if (i
< unit
->functions
.num_functions
)
1202 slang_assembly_file_restore_point point
;
1203 slang_assemble_ctx A
;
1205 f
= &unit
->functions
.functions
[i
];
1206 slang_assembly_file_restore_point_save (unit
->assembly
, &point
);
1208 slang_machine_init (unit
->machine
);
1209 unit
->machine
->ip
= unit
->assembly
->count
;
1211 A
.file
= unit
->assembly
;
1212 A
.mach
= unit
->machine
;
1213 A
.atoms
= unit
->atom_pool
;
1214 A
.space
.funcs
= &unit
->functions
;
1215 A
.space
.structs
= &unit
->structs
;
1216 A
.space
.vars
= &unit
->globals
;
1217 slang_assembly_file_push_label (unit
->assembly
, slang_asm_local_alloc
, 20);
1218 slang_assembly_file_push_label (unit
->assembly
, slang_asm_enter
, 20);
1219 _slang_assemble_function_call (&A
, f
, NULL
, 0, GL_FALSE
);
1220 slang_assembly_file_push (unit
->assembly
, slang_asm_exit
);
1222 _slang_execute2 (unit
->assembly
, unit
->machine
);
1224 slang_assembly_file_restore_point_load (unit
->assembly
, &point
);
1228 void _slang_exec_fragment_shader (struct gl2_fragment_shader_intf
**fs
)
1230 struct gl2_fragment_shader_impl
*impl
;
1231 slang_translation_unit
*unit
;
1235 impl
= (struct gl2_fragment_shader_impl
*) fs
;
1236 unit
= &impl
->_obj
._shader
.unit
;
1237 atom
= slang_atom_pool_atom (unit
->atom_pool
, "main");
1238 for (i
= 0; i
< unit
->functions
.num_functions
; i
++)
1239 if (atom
== unit
->functions
.functions
[i
].header
.a_name
)
1241 if (i
< unit
->functions
.num_functions
)
1244 slang_assembly_file_restore_point point
;
1245 slang_assemble_ctx A
;
1247 f
= &unit
->functions
.functions
[i
];
1248 slang_assembly_file_restore_point_save (unit
->assembly
, &point
);
1250 slang_machine_init (unit
->machine
);
1251 unit
->machine
->ip
= unit
->assembly
->count
;
1253 A
.file
= unit
->assembly
;
1254 A
.mach
= unit
->machine
;
1255 A
.atoms
= unit
->atom_pool
;
1256 A
.space
.funcs
= &unit
->functions
;
1257 A
.space
.structs
= &unit
->structs
;
1258 A
.space
.vars
= &unit
->globals
;
1259 slang_assembly_file_push_label (unit
->assembly
, slang_asm_local_alloc
, 20);
1260 slang_assembly_file_push_label (unit
->assembly
, slang_asm_enter
, 20);
1261 _slang_assemble_function_call (&A
, f
, NULL
, 0, GL_FALSE
);
1262 slang_assembly_file_push (unit
->assembly
, slang_asm_exit
);
1264 _slang_execute2 (unit
->assembly
, unit
->machine
);
1266 slang_assembly_file_restore_point_load (unit
->assembly
, &point
);
1270 GLint
_slang_get_uniform_location (struct gl2_program_intf
**pro
, const char *name
)
1272 struct gl2_program_impl
*impl
;
1273 slang_uniform_bindings
*bind
;
1276 impl
= (struct gl2_program_impl
*) pro
;
1277 bind
= &impl
->_obj
.prog
.uniforms
;
1278 for (i
= 0; i
< bind
->count
; i
++)
1279 if (_mesa_strcmp (bind
->table
[i
].name
, name
) == 0)
1284 GLboolean
_slang_write_uniform (struct gl2_program_intf
**pro
, GLint loc
, GLsizei count
,
1285 const GLvoid
*data
, GLenum type
)
1287 struct gl2_program_impl
*impl
;
1288 slang_uniform_bindings
*bind
;
1289 slang_uniform_binding
*b
;
1295 impl
= (struct gl2_program_impl
*) pro
;
1296 bind
= &impl
->_obj
.prog
.uniforms
;
1297 if (loc
>= bind
->count
)
1300 b
= &bind
->table
[loc
];
1301 /* TODO: check sizes */
1302 /* TODO: check if not structure */
1303 if (b
->quant
->u
.basic_type
!= type
)
1306 for (i
= 0; i
< SLANG_UNIFORM_BINDING_MAX
; i
++)
1307 if (b
->address
[i
] != ~0)
1309 _mesa_memcpy (&impl
->_obj
.prog
.machines
[i
]->mem
[b
->address
[i
] / 4], data
,
1310 count
* b
->quant
->size
);
1316 _mesa_init_shaderobjects_3dlabs (GLcontext
*ctx
)
1318 #if USE_3DLABS_FRONTEND
1319 _glslang_3dlabs_InitProcess ();
1320 _glslang_3dlabs_ShInitialize ();