/* * Mesa 3-D graphics library * Version: 6.3 * * Copyright (C) 2005 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /** * \file shaderobjects_3dlabs.c * shader objects definitions for 3dlabs compiler * \author Michal Krol */ /* Set this to 1 when we are ready to use 3dlabs' front-end */ #define USE_3DLABS_FRONTEND 0 #include "glheader.h" #include "shaderobjects.h" #include "shaderobjects_3dlabs.h" #include "context.h" #include "macros.h" #include "hash.h" #if USE_3DLABS_FRONTEND #include "slang_mesa.h" #include "Public/ShaderLang.h" #else #include "slang_compile.h" #endif struct gl2_unknown_obj { GLuint reference_count; void (* _destructor) (struct gl2_unknown_intf **); }; struct gl2_unknown_impl { struct gl2_unknown_intf *_vftbl; struct gl2_unknown_obj _obj; }; static void _unknown_destructor (struct gl2_unknown_intf **intf) { } static void _unknown_AddRef (struct gl2_unknown_intf **intf) { struct gl2_unknown_impl *impl = (struct gl2_unknown_impl *) intf; impl->_obj.reference_count++; } static void _unknown_Release (struct gl2_unknown_intf **intf) { struct gl2_unknown_impl *impl = (struct gl2_unknown_impl *) intf; impl->_obj.reference_count--; if (impl->_obj.reference_count == 0) { impl->_obj._destructor (intf); _mesa_free ((void *) intf); } } static struct gl2_unknown_intf ** _unknown_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid) { if (uiid == UIID_UNKNOWN) { (**intf).AddRef (intf); return intf; } return NULL; } static struct gl2_unknown_intf _unknown_vftbl = { _unknown_AddRef, _unknown_Release, _unknown_QueryInterface }; static void _unknown_constructor (struct gl2_unknown_impl *impl) { impl->_vftbl = &_unknown_vftbl; impl->_obj.reference_count = 1; impl->_obj._destructor = _unknown_destructor; } struct gl2_unkinner_obj { struct gl2_unknown_intf **unkouter; }; struct gl2_unkinner_impl { struct gl2_unknown_intf *_vftbl; struct gl2_unkinner_obj _obj; }; static void _unkinner_destructor (struct gl2_unknown_intf **intf) { } static void _unkinner_AddRef (struct gl2_unknown_intf **intf) { struct gl2_unkinner_impl *impl = (struct gl2_unkinner_impl *) intf; (**impl->_obj.unkouter).AddRef (impl->_obj.unkouter); } static void _unkinner_Release (struct gl2_unknown_intf **intf) { struct gl2_unkinner_impl *impl = (struct gl2_unkinner_impl *) intf; (**impl->_obj.unkouter).Release (impl->_obj.unkouter); } static struct gl2_unknown_intf ** _unkinner_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid) { struct gl2_unkinner_impl *impl = (struct gl2_unkinner_impl *) intf; return (**impl->_obj.unkouter).QueryInterface (impl->_obj.unkouter, uiid); } static struct gl2_unknown_intf _unkinner_vftbl = { _unkinner_AddRef, _unkinner_Release, _unkinner_QueryInterface }; static void _unkinner_constructor (struct gl2_unkinner_impl *impl, struct gl2_unknown_intf **outer) { impl->_vftbl = &_unkinner_vftbl; impl->_obj.unkouter = outer; } struct gl2_generic_obj { struct gl2_unknown_obj _unknown; GLhandleARB name; GLboolean delete_status; GLcharARB *info_log; }; struct gl2_generic_impl { struct gl2_generic_intf *_vftbl; struct gl2_generic_obj _obj; }; static void _generic_destructor (struct gl2_unknown_intf **intf) { GET_CURRENT_CONTEXT(ctx); struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf; _mesa_free ((void *) impl->_obj.info_log); _glthread_LOCK_MUTEX (ctx->Shared->Mutex); _mesa_HashRemove (ctx->Shared->GL2Objects, impl->_obj.name); _glthread_UNLOCK_MUTEX (ctx->Shared->Mutex); _unknown_destructor (intf); } static struct gl2_unknown_intf ** _generic_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid) { if (uiid == UIID_GENERIC) { (**intf).AddRef (intf); return intf; } return _unknown_QueryInterface (intf, uiid); } static void _generic_Delete (struct gl2_generic_intf **intf) { struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf; if (impl->_obj.delete_status == GL_FALSE) { impl->_obj.delete_status = GL_TRUE; (**intf)._unknown.Release ((struct gl2_unknown_intf **) intf); } } static GLhandleARB _generic_GetName (struct gl2_generic_intf **intf) { struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf; return impl->_obj.name; } static GLboolean _generic_GetDeleteStatus (struct gl2_generic_intf **intf) { struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf; return impl->_obj.delete_status; } static const GLcharARB * _generic_GetInfoLog (struct gl2_generic_intf **intf) { struct gl2_generic_impl *impl = (struct gl2_generic_impl *) intf; return impl->_obj.info_log; } static struct gl2_generic_intf _generic_vftbl = { { _unknown_AddRef, _unknown_Release, _generic_QueryInterface }, _generic_Delete, NULL, /* abstract GetType */ _generic_GetName, _generic_GetDeleteStatus, _generic_GetInfoLog }; static void _generic_constructor (struct gl2_generic_impl *impl) { GET_CURRENT_CONTEXT(ctx); _unknown_constructor ((struct gl2_unknown_impl *) impl); impl->_vftbl = &_generic_vftbl; impl->_obj._unknown._destructor = _generic_destructor; impl->_obj.delete_status = GL_FALSE; impl->_obj.info_log = NULL; _glthread_LOCK_MUTEX (ctx->Shared->Mutex); impl->_obj.name = _mesa_HashFindFreeKeyBlock (ctx->Shared->GL2Objects, 1); _mesa_HashInsert (ctx->Shared->GL2Objects, impl->_obj.name, (void *) impl); _glthread_UNLOCK_MUTEX (ctx->Shared->Mutex); } struct gl2_container_obj { struct gl2_generic_obj _generic; struct gl2_generic_intf ***attached; GLuint attached_count; }; struct gl2_container_impl { struct gl2_container_intf *_vftbl; struct gl2_container_obj _obj; }; static void _container_destructor (struct gl2_unknown_intf **intf) { struct gl2_container_impl *impl = (struct gl2_container_impl *) intf; GLuint i; for (i = 0; i < impl->_obj.attached_count; i++) { struct gl2_generic_intf **x = impl->_obj.attached[i]; (**x)._unknown.Release ((struct gl2_unknown_intf **) x); } _generic_destructor (intf); } static struct gl2_unknown_intf ** _container_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid) { if (uiid == UIID_CONTAINER) { (**intf).AddRef (intf); return intf; } return _generic_QueryInterface (intf, uiid); } static GLboolean _container_Attach (struct gl2_container_intf **intf, struct gl2_generic_intf **att) { GET_CURRENT_CONTEXT(ctx); struct gl2_container_impl *impl = (struct gl2_container_impl *) intf; GLuint i; for (i = 0; i < impl->_obj.attached_count; i++) if (impl->_obj.attached[i] == att) { _mesa_error (ctx, GL_INVALID_OPERATION, "_container_Attach"); return GL_FALSE; } impl->_obj.attached = (struct gl2_generic_intf ***) _mesa_realloc (impl->_obj.attached, impl->_obj.attached_count * sizeof (*impl->_obj.attached), (impl->_obj.attached_count + 1) * sizeof (*impl->_obj.attached)); if (impl->_obj.attached == NULL) return GL_FALSE; impl->_obj.attached[impl->_obj.attached_count] = att; impl->_obj.attached_count++; (**att)._unknown.AddRef ((struct gl2_unknown_intf **) att); return GL_TRUE; } static GLboolean _container_Detach (struct gl2_container_intf **intf, struct gl2_generic_intf **att) { GET_CURRENT_CONTEXT(ctx); struct gl2_container_impl *impl = (struct gl2_container_impl *) intf; GLuint i, j; for (i = 0; i < impl->_obj.attached_count; i++) if (impl->_obj.attached[i] == att) { for (j = i; j < impl->_obj.attached_count - 1; j++) impl->_obj.attached[j] = impl->_obj.attached[j + 1]; impl->_obj.attached = (struct gl2_generic_intf ***) _mesa_realloc (impl->_obj.attached, impl->_obj.attached_count * sizeof (*impl->_obj.attached), (impl->_obj.attached_count - 1) * sizeof (*impl->_obj.attached)); impl->_obj.attached_count--; (**att)._unknown.Release ((struct gl2_unknown_intf **) att); return GL_TRUE; } _mesa_error (ctx, GL_INVALID_OPERATION, "_container_Detach"); return GL_FALSE; } static GLsizei _container_GetAttachedCount (struct gl2_container_intf **intf) { struct gl2_container_impl *impl = (struct gl2_container_impl *) intf; return impl->_obj.attached_count; } static struct gl2_generic_intf ** _container_GetAttached (struct gl2_container_intf **intf, GLuint index) { struct gl2_container_impl *impl = (struct gl2_container_impl *) intf; (**impl->_obj.attached[index])._unknown.AddRef ( (struct gl2_unknown_intf **)impl->_obj.attached[index]); return impl->_obj.attached[index]; } static struct gl2_container_intf _container_vftbl = { { { _unknown_AddRef, _unknown_Release, _container_QueryInterface }, _generic_Delete, NULL, /* abstract GetType */ _generic_GetName, _generic_GetDeleteStatus, _generic_GetInfoLog }, _container_Attach, _container_Detach, _container_GetAttachedCount, _container_GetAttached }; static void _container_constructor (struct gl2_container_impl *impl) { _generic_constructor ((struct gl2_generic_impl *) impl); impl->_vftbl = &_container_vftbl; impl->_obj._generic._unknown._destructor = _container_destructor; impl->_obj.attached = NULL; impl->_obj.attached_count = 0; } struct gl2_3dlabs_shhandle_obj { struct gl2_unkinner_obj _unknown; #if USE_3DLABS_FRONTEND ShHandle handle; #endif }; struct gl2_3dlabs_shhandle_impl { struct gl2_3dlabs_shhandle_intf *_vftbl; struct gl2_3dlabs_shhandle_obj _obj; }; static void _3dlabs_shhandle_destructor (struct gl2_unknown_intf **intf) { #if USE_3DLABS_FRONTEND struct gl2_3dlabs_shhandle_impl *impl = (struct gl2_3dlabs_shhandle_impl *) intf; ShDestruct (impl->_obj.handle); #endif _unkinner_destructor (intf); } static GLvoid * _3dlabs_shhandle_GetShHandle (struct gl2_3dlabs_shhandle_intf **intf) { #if USE_3DLABS_FRONTEND struct gl2_3dlabs_shhandle_impl *impl = (struct gl2_3dlabs_shhandle_impl *) intf; return impl->_obj.handle; #else return NULL; #endif } static struct gl2_3dlabs_shhandle_intf _3dlabs_shhandle_vftbl = { { _unkinner_AddRef, _unkinner_Release, _unkinner_QueryInterface }, _3dlabs_shhandle_GetShHandle }; static void _3dlabs_shhandle_constructor (struct gl2_3dlabs_shhandle_impl *impl, struct gl2_unknown_intf **outer) { _unkinner_constructor ((struct gl2_unkinner_impl *) impl, outer); impl->_vftbl = &_3dlabs_shhandle_vftbl; #if USE_3DLABS_FRONTEND impl->_obj.handle = NULL; #endif } struct gl2_shader_obj { struct gl2_generic_obj _generic; struct gl2_3dlabs_shhandle_impl _3dlabs_shhandle; GLboolean compile_status; GLcharARB *source; GLint *offsets; GLsizei offset_count; }; struct gl2_shader_impl { struct gl2_shader_intf *_vftbl; struct gl2_shader_obj _obj; }; static void _shader_destructor (struct gl2_unknown_intf **intf) { struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf; _mesa_free ((void *) impl->_obj.source); _mesa_free ((void *) impl->_obj.offsets); _3dlabs_shhandle_destructor ((struct gl2_unknown_intf **) &impl->_obj._3dlabs_shhandle._vftbl); _generic_destructor (intf); } static struct gl2_unknown_intf ** _shader_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid) { #if USE_3DLABS_FRONTEND struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf; #endif if (uiid == UIID_SHADER) { (**intf).AddRef (intf); return intf; } #if USE_3DLABS_FRONTEND if (uiid == UIID_3DLABS_SHHANDLE) { (**intf).AddRef (intf); return (struct gl2_unknown_intf **) &impl->_obj._3dlabs_shhandle._vftbl; } #endif return _generic_QueryInterface (intf, uiid); } static GLenum _shader_GetType (struct gl2_generic_intf **intf) { return GL_SHADER_OBJECT_ARB; } static GLboolean _shader_GetCompileStatus (struct gl2_shader_intf **intf) { struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf; return impl->_obj.compile_status; } static GLvoid _shader_SetSource (struct gl2_shader_intf **intf, GLcharARB *src, GLint *off, GLsizei cnt) { struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf; _mesa_free ((void *) impl->_obj.source); impl->_obj.source = src; _mesa_free ((void *) impl->_obj.offsets); impl->_obj.offsets = off; impl->_obj.offset_count = cnt; } static const GLcharARB * _shader_GetSource (struct gl2_shader_intf **intf) { struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf; return impl->_obj.source; } static GLvoid _shader_Compile (struct gl2_shader_intf **intf) { struct gl2_shader_impl *impl = (struct gl2_shader_impl *) intf; #if USE_3DLABS_FRONTEND char **strings; TBuiltInResource res; #else slang_translation_unit unit; slang_unit_type type; slang_info_log info_log; #endif impl->_obj.compile_status = GL_FALSE; _mesa_free ((void *) impl->_obj._generic.info_log); impl->_obj._generic.info_log = NULL; #if USE_3DLABS_FRONTEND /* 3dlabs compiler expects us to feed it with null-terminated string array, we've got only one big string with offsets, so we must split it; but when there's only one string to deal with, we pass its address directly */ if (impl->_obj.offset_count <= 1) strings = &impl->_obj.source; else { GLsizei i, offset = 0; strings = (char **) _mesa_malloc (impl->_obj.offset_count * sizeof (char *)); if (strings == NULL) return; for (i = 0; i < impl->_obj.offset_count; i++) { GLsizei size = impl->_obj.offsets[i] - offset; strings[i] = (char *) _mesa_malloc ((size + 1) * sizeof (char)); if (strings[i] == NULL) { GLsizei j; for (j = 0; j < i; j++) _mesa_free (strings[j]); _mesa_free (strings); return; } _mesa_memcpy (strings[i], impl->_obj.source + offset, size * sizeof (char)); strings[i][size] = '\0'; offset = impl->_obj.offsets[i]; } } /* TODO set these fields to some REAL numbers */ res.maxLights = 8; res.maxClipPlanes = 6; res.maxTextureUnits = 2; res.maxTextureCoords = 2; res.maxVertexAttribs = 8; res.maxVertexUniformComponents = 64; res.maxVaryingFloats = 8; res.maxVertexTextureImageUnits = 2; res.maxCombinedTextureImageUnits = 2; res.maxTextureImageUnits = 2; res.maxFragmentUniformComponents = 64; res.maxDrawBuffers = 1; if (ShCompile (impl->_obj._3dlabs_shhandle._obj.handle, strings, impl->_obj.offset_count, EShOptFull, &res, 0)) impl->_obj.compile_status = GL_TRUE; if (impl->_obj.offset_count > 1) { GLsizei i; for (i = 0; i < impl->_obj.offset_count; i++) _mesa_free (strings[i]); _mesa_free (strings); } impl->_obj._generic.info_log = _mesa_strdup (ShGetInfoLog ( impl->_obj._3dlabs_shhandle._obj.handle)); #else if (impl->_vftbl->GetSubType (intf) == GL_FRAGMENT_SHADER) type = slang_unit_fragment_shader; else type = slang_unit_vertex_shader; slang_info_log_construct (&info_log); if (_slang_compile (impl->_obj.source, &unit, type, &info_log)) { impl->_obj.compile_status = GL_TRUE; } if (info_log.text != NULL) impl->_obj._generic.info_log = _mesa_strdup (info_log.text); else impl->_obj._generic.info_log = _mesa_strdup (""); slang_info_log_destruct (&info_log); #endif } static struct gl2_shader_intf _shader_vftbl = { { { _unknown_AddRef, _unknown_Release, _shader_QueryInterface }, _generic_Delete, _shader_GetType, _generic_GetName, _generic_GetDeleteStatus, _generic_GetInfoLog }, NULL, /* abstract GetSubType */ _shader_GetCompileStatus, _shader_SetSource, _shader_GetSource, _shader_Compile }; static void _shader_constructor (struct gl2_shader_impl *impl) { _generic_constructor ((struct gl2_generic_impl *) impl); _3dlabs_shhandle_constructor (&impl->_obj._3dlabs_shhandle, (struct gl2_unknown_intf **) &impl->_vftbl); impl->_vftbl = &_shader_vftbl; impl->_obj._generic._unknown._destructor = _shader_destructor; impl->_obj.compile_status = GL_FALSE; impl->_obj.source = NULL; impl->_obj.offsets = NULL; impl->_obj.offset_count = 0; } struct gl2_program_obj { struct gl2_container_obj _container; GLboolean link_status; GLboolean validate_status; #if USE_3DLABS_FRONTEND ShHandle linker; ShHandle uniforms; #endif }; struct gl2_program_impl { struct gl2_program_intf *_vftbl; struct gl2_program_obj _obj; }; static void _program_destructor (struct gl2_unknown_intf **intf) { #if USE_3DLABS_FRONTEND struct gl2_program_impl *impl = (struct gl2_program_impl *) intf; ShDestruct (impl->_obj.linker); ShDestruct (impl->_obj.uniforms); #endif _container_destructor (intf); } static struct gl2_unknown_intf ** _program_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid) { if (uiid == UIID_PROGRAM) { (**intf).AddRef (intf); return intf; } return _container_QueryInterface (intf, uiid); } static GLenum _program_GetType (struct gl2_generic_intf **intf) { return GL_PROGRAM_OBJECT_ARB; } static GLboolean _program_Attach (struct gl2_container_intf **intf, struct gl2_generic_intf **att) { GET_CURRENT_CONTEXT(ctx); struct gl2_unknown_intf **sha; sha = (**att)._unknown.QueryInterface ((struct gl2_unknown_intf **) att, UIID_SHADER); if (sha == NULL) { _mesa_error (ctx, GL_INVALID_OPERATION, "_program_Attach"); return GL_FALSE; } (**sha).Release (sha); return _container_Attach (intf, att); } static GLboolean _program_GetLinkStatus (struct gl2_program_intf **intf) { struct gl2_program_impl *impl = (struct gl2_program_impl *) intf; return impl->_obj.link_status; } static GLboolean _program_GetValidateStatus (struct gl2_program_intf **intf) { struct gl2_program_impl *impl = (struct gl2_program_impl *) intf; return impl->_obj.validate_status; } static GLvoid _program_Link (struct gl2_program_intf **intf) { struct gl2_program_impl *impl = (struct gl2_program_impl *) intf; #if USE_3DLABS_FRONTEND ShHandle *handles; GLuint i; #endif impl->_obj.link_status = GL_FALSE; _mesa_free ((void *) impl->_obj._container._generic.info_log); impl->_obj._container._generic.info_log = NULL; #if USE_3DLABS_FRONTEND handles = (ShHandle *) _mesa_malloc (impl->_obj._container.attached_count * sizeof (ShHandle)); if (handles == NULL) return; for (i = 0; i < impl->_obj._container.attached_count; i++) { struct gl2_generic_intf **gen = impl->_obj._container.attached[i]; struct gl2_3dlabs_shhandle_intf **sh; sh = (struct gl2_3dlabs_shhandle_intf **) (**gen)._unknown.QueryInterface ( (struct gl2_unknown_intf **) gen, UIID_3DLABS_SHHANDLE); if (sh != NULL) { handles[i] = (**sh).GetShHandle (sh); (**sh)._unknown.Release ((struct gl2_unknown_intf **) sh); } else { _mesa_free (handles); return; } } if (ShLink (impl->_obj.linker, handles, impl->_obj._container.attached_count, impl->_obj.uniforms, NULL, NULL)) impl->_obj.link_status = GL_TRUE; impl->_obj._container._generic.info_log = _mesa_strdup (ShGetInfoLog (impl->_obj.linker)); #endif } static GLvoid _program_Validate (struct gl2_program_intf **intf) { struct gl2_program_impl *impl = (struct gl2_program_impl *) intf; impl->_obj.validate_status = GL_FALSE; _mesa_free ((void *) impl->_obj._container._generic.info_log); impl->_obj._container._generic.info_log = NULL; /* TODO validate */ } static struct gl2_program_intf _program_vftbl = { { { { _unknown_AddRef, _unknown_Release, _program_QueryInterface }, _generic_Delete, _program_GetType, _generic_GetName, _generic_GetDeleteStatus, _generic_GetInfoLog }, _program_Attach, _container_Detach, _container_GetAttachedCount, _container_GetAttached }, _program_GetLinkStatus, _program_GetValidateStatus, _program_Link, _program_Validate }; static void _program_constructor (struct gl2_program_impl *impl) { _container_constructor ((struct gl2_container_impl *) impl); impl->_vftbl = &_program_vftbl; impl->_obj._container._generic._unknown._destructor = _program_destructor; impl->_obj.link_status = GL_FALSE; impl->_obj.validate_status = GL_FALSE; #if USE_3DLABS_FRONTEND impl->_obj.linker = ShConstructLinker (EShExVertexFragment, 0); impl->_obj.uniforms = ShConstructUniformMap (); #endif } struct gl2_fragment_shader_obj { struct gl2_shader_obj _shader; }; struct gl2_fragment_shader_impl { struct gl2_fragment_shader_intf *_vftbl; struct gl2_fragment_shader_obj _obj; }; static void _fragment_shader_destructor (struct gl2_unknown_intf **intf) { struct gl2_fragment_shader_impl *impl = (struct gl2_fragment_shader_impl *) intf; (void) impl; /* TODO free fragment shader data */ _shader_destructor (intf); } static struct gl2_unknown_intf ** _fragment_shader_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid) { if (uiid == UIID_FRAGMENT_SHADER) { (**intf).AddRef (intf); return intf; } return _shader_QueryInterface (intf, uiid); } static GLenum _fragment_shader_GetSubType (struct gl2_shader_intf **intf) { return GL_FRAGMENT_SHADER_ARB; } static struct gl2_fragment_shader_intf _fragment_shader_vftbl = { { { { _unknown_AddRef, _unknown_Release, _fragment_shader_QueryInterface }, _generic_Delete, _shader_GetType, _generic_GetName, _generic_GetDeleteStatus, _generic_GetInfoLog }, _fragment_shader_GetSubType, _shader_GetCompileStatus, _shader_SetSource, _shader_GetSource, _shader_Compile } }; static void _fragment_shader_constructor (struct gl2_fragment_shader_impl *impl) { _shader_constructor ((struct gl2_shader_impl *) impl); impl->_vftbl = &_fragment_shader_vftbl; impl->_obj._shader._generic._unknown._destructor = _fragment_shader_destructor; #if USE_3DLABS_FRONTEND impl->_obj._shader._3dlabs_shhandle._obj.handle = ShConstructCompiler (EShLangFragment, 0); #endif } struct gl2_vertex_shader_obj { struct gl2_shader_obj _shader; }; struct gl2_vertex_shader_impl { struct gl2_vertex_shader_intf *_vftbl; struct gl2_vertex_shader_obj _obj; }; static void _vertex_shader_destructor (struct gl2_unknown_intf **intf) { struct gl2_vertex_shader_impl *impl = (struct gl2_vertex_shader_impl *) intf; (void) impl; /* TODO free vertex shader data */ _shader_destructor (intf); } static struct gl2_unknown_intf ** _vertex_shader_QueryInterface (struct gl2_unknown_intf **intf, enum gl2_uiid uiid) { if (uiid == UIID_VERTEX_SHADER) { (**intf).AddRef (intf); return intf; } return _shader_QueryInterface (intf, uiid); } static GLenum _vertex_shader_GetSubType (struct gl2_shader_intf **intf) { return GL_VERTEX_SHADER_ARB; } static struct gl2_vertex_shader_intf _vertex_shader_vftbl = { { { { _unknown_AddRef, _unknown_Release, _vertex_shader_QueryInterface }, _generic_Delete, _shader_GetType, _generic_GetName, _generic_GetDeleteStatus, _generic_GetInfoLog }, _vertex_shader_GetSubType, _shader_GetCompileStatus, _shader_SetSource, _shader_GetSource, _shader_Compile } }; static void _vertex_shader_constructor (struct gl2_vertex_shader_impl *impl) { _shader_constructor ((struct gl2_shader_impl *) impl); impl->_vftbl = &_vertex_shader_vftbl; impl->_obj._shader._generic._unknown._destructor = _vertex_shader_destructor; #if USE_3DLABS_FRONTEND impl->_obj._shader._3dlabs_shhandle._obj.handle = ShConstructCompiler (EShLangVertex, 0); #endif } GLhandleARB _mesa_3dlabs_create_shader_object (GLenum shaderType) { switch (shaderType) { case GL_FRAGMENT_SHADER_ARB: { struct gl2_fragment_shader_impl *x = (struct gl2_fragment_shader_impl *) _mesa_malloc (sizeof (struct gl2_fragment_shader_impl)); if (x != NULL) { _fragment_shader_constructor (x); return x->_obj._shader._generic.name; } } break; case GL_VERTEX_SHADER_ARB: { struct gl2_vertex_shader_impl *x = (struct gl2_vertex_shader_impl *) _mesa_malloc (sizeof (struct gl2_vertex_shader_impl)); if (x != NULL) { _vertex_shader_constructor (x); return x->_obj._shader._generic.name; } } break; } return 0; } GLhandleARB _mesa_3dlabs_create_program_object (void) { struct gl2_program_impl *x = (struct gl2_program_impl *) _mesa_malloc (sizeof (struct gl2_program_impl)); if (x != NULL) { _program_constructor (x); return x->_obj._container._generic.name; } return 0; } void _mesa_init_shaderobjects_3dlabs (GLcontext *ctx) { #if USE_3DLABS_FRONTEND _glslang_3dlabs_InitProcess (); _glslang_3dlabs_ShInitialize (); #endif }