2 * Mesa 3-D graphics library
5 * Copyright (C) 2005 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
33 #include "shaderobjects.h"
34 #include "shaderobjects_3dlabs.h"
40 struct gl2_unknown_obj
42 GLuint reference_count
;
43 void (* _destructor
) (struct gl2_unknown_intf
**);
46 struct gl2_unknown_impl
48 struct gl2_unknown_intf
*_vftbl
;
49 struct gl2_unknown_obj _obj
;
53 _unknown_destructor (struct gl2_unknown_intf
**intf
)
58 _unknown_AddRef (struct gl2_unknown_intf
**intf
)
60 struct gl2_unknown_impl
*impl
= (struct gl2_unknown_impl
*) intf
;
62 impl
->_obj
.reference_count
++;
66 _unknown_Release (struct gl2_unknown_intf
**intf
)
68 struct gl2_unknown_impl
*impl
= (struct gl2_unknown_impl
*) intf
;
70 impl
->_obj
.reference_count
--;
71 if (impl
->_obj
.reference_count
== 0)
73 impl
->_obj
._destructor (intf
);
74 _mesa_free ((void *) intf
);
78 static struct gl2_unknown_intf
**
79 _unknown_QueryInterface (struct gl2_unknown_intf
**intf
, enum gl2_uiid uiid
)
81 if (uiid
== UIID_UNKNOWN
)
83 (**intf
).AddRef (intf
);
89 static struct gl2_unknown_intf _unknown_vftbl
= {
92 _unknown_QueryInterface
96 _unknown_constructor (struct gl2_unknown_impl
*impl
)
98 impl
->_vftbl
= &_unknown_vftbl
;
99 impl
->_obj
.reference_count
= 1;
100 impl
->_obj
._destructor
= _unknown_destructor
;
103 struct gl2_generic_obj
105 struct gl2_unknown_obj _unknown
;
107 GLboolean delete_status
;
111 struct gl2_generic_impl
113 struct gl2_generic_intf
*_vftbl
;
114 struct gl2_generic_obj _obj
;
118 _generic_destructor (struct gl2_unknown_intf
**intf
)
120 GET_CURRENT_CONTEXT(ctx
);
121 struct gl2_generic_impl
*impl
= (struct gl2_generic_impl
*) intf
;
123 _mesa_free ((void *) impl
->_obj
.info_log
);
125 _glthread_LOCK_MUTEX (ctx
->Shared
->Mutex
);
126 _mesa_HashRemove (ctx
->Shared
->GL2Objects
, impl
->_obj
.name
);
127 _glthread_UNLOCK_MUTEX (ctx
->Shared
->Mutex
);
129 _unknown_destructor (intf
);
132 static struct gl2_unknown_intf
**
133 _generic_QueryInterface (struct gl2_unknown_intf
**intf
, enum gl2_uiid uiid
)
135 if (uiid
== UIID_GENERIC
)
137 (**intf
).AddRef (intf
);
140 return _unknown_QueryInterface (intf
, uiid
);
144 _generic_Delete (struct gl2_generic_intf
**intf
)
146 struct gl2_generic_impl
*impl
= (struct gl2_generic_impl
*) intf
;
148 if (impl
->_obj
.delete_status
== GL_FALSE
)
150 impl
->_obj
.delete_status
= GL_TRUE
;
151 (**intf
)._unknown
.Release ((struct gl2_unknown_intf
**) intf
);
156 _generic_GetName (struct gl2_generic_intf
**intf
)
158 struct gl2_generic_impl
*impl
= (struct gl2_generic_impl
*) intf
;
160 return impl
->_obj
.name
;
164 _generic_GetDeleteStatus (struct gl2_generic_intf
**intf
)
166 struct gl2_generic_impl
*impl
= (struct gl2_generic_impl
*) intf
;
168 return impl
->_obj
.delete_status
;
171 static const GLcharARB
*
172 _generic_GetInfoLog (struct gl2_generic_intf
**intf
)
174 struct gl2_generic_impl
*impl
= (struct gl2_generic_impl
*) intf
;
176 return impl
->_obj
.info_log
;
179 static struct gl2_generic_intf _generic_vftbl
= {
183 _generic_QueryInterface
188 _generic_GetDeleteStatus
,
193 _generic_constructor (struct gl2_generic_impl
*impl
)
195 GET_CURRENT_CONTEXT(ctx
);
197 _unknown_constructor ((struct gl2_unknown_impl
*) impl
);
198 impl
->_vftbl
= &_generic_vftbl
;
199 impl
->_obj
._unknown
._destructor
= _generic_destructor
;
200 impl
->_obj
.delete_status
= GL_FALSE
;
201 impl
->_obj
.info_log
= NULL
;
203 _glthread_LOCK_MUTEX (ctx
->Shared
->Mutex
);
204 impl
->_obj
.name
= _mesa_HashFindFreeKeyBlock (ctx
->Shared
->GL2Objects
, 1);
205 _mesa_HashInsert (ctx
->Shared
->GL2Objects
, impl
->_obj
.name
, (void *) impl
);
206 _glthread_UNLOCK_MUTEX (ctx
->Shared
->Mutex
);
209 struct gl2_container_obj
211 struct gl2_generic_obj _generic
;
212 struct gl2_generic_intf
***attached
;
213 GLuint attached_count
;
216 struct gl2_container_impl
218 struct gl2_container_intf
*_vftbl
;
219 struct gl2_container_obj _obj
;
223 _container_destructor (struct gl2_unknown_intf
**intf
)
225 struct gl2_container_impl
*impl
= (struct gl2_container_impl
*) intf
;
228 for (i
= 0; i
< impl
->_obj
.attached_count
; i
++)
230 struct gl2_generic_intf
**x
= impl
->_obj
.attached
[i
];
231 (**x
)._unknown
.Release ((struct gl2_unknown_intf
**) x
);
234 _generic_destructor (intf
);
237 static struct gl2_unknown_intf
**
238 _container_QueryInterface (struct gl2_unknown_intf
**intf
, enum gl2_uiid uiid
)
240 if (uiid
== UIID_CONTAINER
)
242 (**intf
).AddRef (intf
);
245 return _generic_QueryInterface (intf
, uiid
);
249 _container_Attach (struct gl2_container_intf
**intf
, struct gl2_generic_intf
**att
)
251 GET_CURRENT_CONTEXT(ctx
);
252 struct gl2_container_impl
*impl
= (struct gl2_container_impl
*) intf
;
255 for (i
= 0; i
< impl
->_obj
.attached_count
; i
++)
256 if (impl
->_obj
.attached
[i
] == att
)
258 _mesa_error (ctx
, GL_INVALID_OPERATION
, "_container_Attach");
262 impl
->_obj
.attached
= (struct gl2_generic_intf
***) _mesa_realloc (impl
->_obj
.attached
,
263 impl
->_obj
.attached_count
* sizeof (*impl
->_obj
.attached
), (impl
->_obj
.attached_count
+ 1) *
264 sizeof (*impl
->_obj
.attached
));
265 if (impl
->_obj
.attached
== NULL
)
268 impl
->_obj
.attached
[impl
->_obj
.attached_count
] = att
;
269 impl
->_obj
.attached_count
++;
270 (**att
)._unknown
.AddRef ((struct gl2_unknown_intf
**) att
);
275 _container_Detach (struct gl2_container_intf
**intf
, struct gl2_generic_intf
**att
)
277 GET_CURRENT_CONTEXT(ctx
);
278 struct gl2_container_impl
*impl
= (struct gl2_container_impl
*) intf
;
281 for (i
= 0; i
< impl
->_obj
.attached_count
; i
++)
282 if (impl
->_obj
.attached
[i
] == att
)
284 for (j
= i
; j
< impl
->_obj
.attached_count
- 1; j
++)
285 impl
->_obj
.attached
[j
] = impl
->_obj
.attached
[j
+ 1];
286 impl
->_obj
.attached
= (struct gl2_generic_intf
***) _mesa_realloc (impl
->_obj
.attached
,
287 impl
->_obj
.attached_count
* sizeof (*impl
->_obj
.attached
),
288 (impl
->_obj
.attached_count
- 1) * sizeof (*impl
->_obj
.attached
));
289 impl
->_obj
.attached_count
--;
290 (**att
)._unknown
.Release ((struct gl2_unknown_intf
**) att
);
294 _mesa_error (ctx
, GL_INVALID_OPERATION
, "_container_Detach");
299 _container_GetAttachedCount (struct gl2_container_intf
**intf
)
301 struct gl2_container_impl
*impl
= (struct gl2_container_impl
*) intf
;
303 return impl
->_obj
.attached_count
;
306 static struct gl2_generic_intf
**
307 _container_GetAttached (struct gl2_container_intf
**intf
, GLuint index
)
309 struct gl2_container_impl
*impl
= (struct gl2_container_impl
*) intf
;
311 (**impl
->_obj
.attached
[index
])._unknown
.AddRef (
312 (struct gl2_unknown_intf
**)impl
->_obj
.attached
[index
]);
313 return impl
->_obj
.attached
[index
];
316 static struct gl2_container_intf _container_vftbl
= {
321 _container_QueryInterface
,
326 _generic_GetDeleteStatus
,
331 _container_GetAttachedCount
,
332 _container_GetAttached
336 _container_constructor (struct gl2_container_impl
*impl
)
338 _generic_constructor ((struct gl2_generic_impl
*) impl
);
339 impl
->_vftbl
= &_container_vftbl
;
340 impl
->_obj
._generic
._unknown
._destructor
= _container_destructor
;
341 impl
->_obj
.attached
= NULL
;
342 impl
->_obj
.attached_count
= 0;
345 struct gl2_shader_obj
347 struct gl2_generic_obj _generic
;
348 GLboolean compile_status
;
351 GLsizei offset_count
;
354 struct gl2_shader_impl
356 struct gl2_shader_intf
*_vftbl
;
357 struct gl2_shader_obj _obj
;
361 _shader_destructor (struct gl2_unknown_intf
**intf
)
363 struct gl2_shader_impl
*impl
= (struct gl2_shader_impl
*) intf
;
365 _mesa_free ((void *) impl
->_obj
.source
);
366 _mesa_free ((void *) impl
->_obj
.offsets
);
367 _generic_destructor (intf
);
370 static struct gl2_unknown_intf
**
371 _shader_QueryInterface (struct gl2_unknown_intf
**intf
, enum gl2_uiid uiid
)
373 if (uiid
== UIID_SHADER
)
375 (**intf
).AddRef (intf
);
378 return _generic_QueryInterface (intf
, uiid
);
382 _shader_GetType (struct gl2_generic_intf
**intf
)
384 return GL_SHADER_OBJECT_ARB
;
388 _shader_GetCompileStatus (struct gl2_shader_intf
**intf
)
390 struct gl2_shader_impl
*impl
= (struct gl2_shader_impl
*) intf
;
392 return impl
->_obj
.compile_status
;
396 _shader_SetSource (struct gl2_shader_intf
**intf
, GLcharARB
*src
, GLint
*off
, GLsizei cnt
)
398 struct gl2_shader_impl
*impl
= (struct gl2_shader_impl
*) intf
;
400 _mesa_free ((void *) impl
->_obj
.source
);
401 impl
->_obj
.source
= src
;
402 _mesa_free ((void *) impl
->_obj
.offsets
);
403 impl
->_obj
.offsets
= off
;
404 impl
->_obj
.offset_count
= cnt
;
407 static const GLcharARB
*
408 _shader_GetSource (struct gl2_shader_intf
**intf
)
410 struct gl2_shader_impl
*impl
= (struct gl2_shader_impl
*) intf
;
412 return impl
->_obj
.source
;
416 _shader_Compile (struct gl2_shader_intf
**intf
)
418 struct gl2_shader_impl
*impl
= (struct gl2_shader_impl
*) intf
;
420 impl
->_obj
.compile_status
= GL_FALSE
;
421 _mesa_free ((void *) impl
->_obj
._generic
.info_log
);
422 impl
->_obj
._generic
.info_log
= NULL
;
427 static struct gl2_shader_intf _shader_vftbl
= {
432 _shader_QueryInterface
,
437 _generic_GetDeleteStatus
,
441 _shader_GetCompileStatus
,
448 _shader_constructor (struct gl2_shader_impl
*impl
)
450 _generic_constructor ((struct gl2_generic_impl
*) impl
);
451 impl
->_vftbl
= &_shader_vftbl
;
452 impl
->_obj
._generic
._unknown
._destructor
= _shader_destructor
;
453 impl
->_obj
.compile_status
= GL_FALSE
;
454 impl
->_obj
.source
= NULL
;
455 impl
->_obj
.offsets
= NULL
;
456 impl
->_obj
.offset_count
= 0;
459 struct gl2_program_obj
461 struct gl2_container_obj _container
;
462 GLboolean link_status
;
463 GLboolean validate_status
;
466 struct gl2_program_impl
468 struct gl2_program_intf
*_vftbl
;
469 struct gl2_program_obj _obj
;
473 _program_destructor (struct gl2_unknown_intf
**intf
)
475 struct gl2_program_impl
*impl
= (struct gl2_program_impl
*) intf
;
477 _container_destructor (intf
);
480 static struct gl2_unknown_intf
**
481 _program_QueryInterface (struct gl2_unknown_intf
**intf
, enum gl2_uiid uiid
)
483 if (uiid
== UIID_PROGRAM
)
485 (**intf
).AddRef (intf
);
488 return _container_QueryInterface (intf
, uiid
);
492 _program_GetType (struct gl2_generic_intf
**intf
)
494 return GL_PROGRAM_OBJECT_ARB
;
498 _program_Attach (struct gl2_container_intf
**intf
, struct gl2_generic_intf
**att
)
500 GET_CURRENT_CONTEXT(ctx
);
501 struct gl2_unknown_intf
**sha
;
503 sha
= (**att
)._unknown
.QueryInterface ((struct gl2_unknown_intf
**) att
, UIID_SHADER
);
506 _mesa_error (ctx
, GL_INVALID_OPERATION
, "_program_Attach");
510 (**sha
).Release (sha
);
511 return _container_Attach (intf
, att
);
515 _program_GetLinkStatus (struct gl2_program_intf
**intf
)
517 struct gl2_program_impl
*impl
= (struct gl2_program_impl
*) intf
;
519 return impl
->_obj
.link_status
;
523 _program_GetValidateStatus (struct gl2_program_intf
**intf
)
525 struct gl2_program_impl
*impl
= (struct gl2_program_impl
*) intf
;
527 return impl
->_obj
.validate_status
;
531 _program_Link (struct gl2_program_intf
**intf
)
533 struct gl2_program_impl
*impl
= (struct gl2_program_impl
*) intf
;
535 impl
->_obj
.link_status
= GL_FALSE
;
536 _mesa_free ((void *) impl
->_obj
._container
._generic
.info_log
);
537 impl
->_obj
._container
._generic
.info_log
= NULL
;
543 _program_Validate (struct gl2_program_intf
**intf
)
545 struct gl2_program_impl
*impl
= (struct gl2_program_impl
*) intf
;
547 impl
->_obj
.validate_status
= GL_FALSE
;
552 static struct gl2_program_intf _program_vftbl
= {
558 _program_QueryInterface
,
563 _generic_GetDeleteStatus
,
568 _container_GetAttachedCount
,
569 _container_GetAttached
,
571 _program_GetLinkStatus
,
572 _program_GetValidateStatus
,
578 _program_constructor (struct gl2_program_impl
*impl
)
580 _container_constructor ((struct gl2_container_impl
*) impl
);
581 impl
->_vftbl
= &_program_vftbl
;
582 impl
->_obj
._container
._generic
._unknown
._destructor
= _program_destructor
;
583 impl
->_obj
.link_status
= GL_FALSE
;
584 impl
->_obj
.validate_status
= GL_FALSE
;
587 struct gl2_fragment_shader_obj
589 struct gl2_shader_obj _shader
;
592 struct gl2_fragment_shader_impl
594 struct gl2_fragment_shader_intf
*_vftbl
;
595 struct gl2_fragment_shader_obj _obj
;
599 _fragment_shader_destructor (struct gl2_unknown_intf
**intf
)
601 struct gl2_fragment_shader_impl
*impl
= (struct gl2_fragment_shader_impl
*) intf
;
603 /* TODO free fragment shader data */
605 _shader_destructor (intf
);
608 static struct gl2_unknown_intf
**
609 _fragment_shader_QueryInterface (struct gl2_unknown_intf
**intf
, enum gl2_uiid uiid
)
611 if (uiid
== UIID_FRAGMENT_SHADER
)
613 (**intf
).AddRef (intf
);
616 return _shader_QueryInterface (intf
, uiid
);
620 _fragment_shader_GetSubType (struct gl2_shader_intf
**intf
)
622 return GL_FRAGMENT_SHADER_ARB
;
625 static struct gl2_fragment_shader_intf _fragment_shader_vftbl
= {
631 _fragment_shader_QueryInterface
,
636 _generic_GetDeleteStatus
,
639 _fragment_shader_GetSubType
,
640 _shader_GetCompileStatus
,
648 _fragment_shader_constructor (struct gl2_fragment_shader_impl
*impl
)
650 _shader_constructor ((struct gl2_shader_impl
*) impl
);
651 impl
->_vftbl
= &_fragment_shader_vftbl
;
652 impl
->_obj
._shader
._generic
._unknown
._destructor
= _fragment_shader_destructor
;
655 struct gl2_vertex_shader_obj
657 struct gl2_shader_obj _shader
;
660 struct gl2_vertex_shader_impl
662 struct gl2_vertex_shader_intf
*_vftbl
;
663 struct gl2_vertex_shader_obj _obj
;
667 _vertex_shader_destructor (struct gl2_unknown_intf
**intf
)
669 struct gl2_vertex_shader_impl
*impl
= (struct gl2_vertex_shader_impl
*) intf
;
671 /* TODO free vertex shader data */
673 _shader_destructor (intf
);
676 static struct gl2_unknown_intf
**
677 _vertex_shader_QueryInterface (struct gl2_unknown_intf
**intf
, enum gl2_uiid uiid
)
679 if (uiid
== UIID_VERTEX_SHADER
)
681 (**intf
).AddRef (intf
);
684 return _shader_QueryInterface (intf
, uiid
);
688 _vertex_shader_GetSubType (struct gl2_shader_intf
**intf
)
690 return GL_VERTEX_SHADER_ARB
;
693 static struct gl2_vertex_shader_intf _vertex_shader_vftbl
= {
699 _vertex_shader_QueryInterface
,
704 _generic_GetDeleteStatus
,
707 _vertex_shader_GetSubType
,
708 _shader_GetCompileStatus
,
716 _vertex_shader_constructor (struct gl2_vertex_shader_impl
*impl
)
718 _shader_constructor ((struct gl2_shader_impl
*) impl
);
719 impl
->_vftbl
= &_vertex_shader_vftbl
;
720 impl
->_obj
._shader
._generic
._unknown
._destructor
= _vertex_shader_destructor
;
724 _mesa_3dlabs_create_shader_object (GLenum shaderType
)
726 GET_CURRENT_CONTEXT(ctx
);
730 case GL_FRAGMENT_SHADER_ARB
:
732 struct gl2_fragment_shader_impl
*x
= (struct gl2_fragment_shader_impl
*) _mesa_malloc (
733 sizeof (struct gl2_fragment_shader_impl
));
737 _fragment_shader_constructor (x
);
738 return x
->_obj
._shader
._generic
.name
;
742 case GL_VERTEX_SHADER_ARB
:
744 struct gl2_vertex_shader_impl
*x
= (struct gl2_vertex_shader_impl
*) _mesa_malloc (
745 sizeof (struct gl2_vertex_shader_impl
));
749 _vertex_shader_constructor (x
);
750 return x
->_obj
._shader
._generic
.name
;
760 _mesa_3dlabs_create_program_object (void)
762 GET_CURRENT_CONTEXT(ctx
);
763 struct gl2_program_impl
*x
= (struct gl2_program_impl
*)
764 _mesa_malloc (sizeof (struct gl2_program_impl
));
769 _program_constructor (x
);
770 return x
->_obj
._container
._generic
.name
;