diff options
author | marha <marha@users.sourceforge.net> | 2010-12-28 16:10:20 +0000 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2010-12-28 16:10:20 +0000 |
commit | 807c6931fe683fd844ceec1b023232181e6aae03 (patch) | |
tree | 1a131ed95fe2200d0ad33da8f7755a7ed2364adc /mesalib/src/mesa/main/shaderobj.c | |
parent | 973099dda7e49e5abe29819a7124b3b1e7bd8b92 (diff) | |
download | vcxsrv-807c6931fe683fd844ceec1b023232181e6aae03.tar.gz vcxsrv-807c6931fe683fd844ceec1b023232181e6aae03.tar.bz2 vcxsrv-807c6931fe683fd844ceec1b023232181e6aae03.zip |
xserver and mesa git update 28-12-2010
Diffstat (limited to 'mesalib/src/mesa/main/shaderobj.c')
-rw-r--r-- | mesalib/src/mesa/main/shaderobj.c | 819 |
1 files changed, 411 insertions, 408 deletions
diff --git a/mesalib/src/mesa/main/shaderobj.c b/mesalib/src/mesa/main/shaderobj.c index 2de8f2798..60f133691 100644 --- a/mesalib/src/mesa/main/shaderobj.c +++ b/mesalib/src/mesa/main/shaderobj.c @@ -1,408 +1,411 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 2004-2008 Brian Paul All Rights Reserved. - * Copyright (C) 2009-2010 VMware, Inc. 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 shaderobj.c - * \author Brian Paul - * - */ - - -#include "main/glheader.h" -#include "main/context.h" -#include "main/hash.h" -#include "main/shaderobj.h" -#include "program/program.h" -#include "program/prog_parameter.h" -#include "program/prog_uniform.h" -#include "talloc.h" - -/**********************************************************************/ -/*** Shader object functions ***/ -/**********************************************************************/ - - -/** - * Set ptr to point to sh. - * If ptr is pointing to another shader, decrement its refcount (and delete - * if refcount hits zero). - * Then set ptr to point to sh, incrementing its refcount. - */ -void -_mesa_reference_shader(GLcontext *ctx, struct gl_shader **ptr, - struct gl_shader *sh) -{ - assert(ptr); - if (*ptr == sh) { - /* no-op */ - return; - } - if (*ptr) { - /* Unreference the old shader */ - GLboolean deleteFlag = GL_FALSE; - struct gl_shader *old = *ptr; - - ASSERT(old->RefCount > 0); - old->RefCount--; - /*printf("SHADER DECR %p (%d) to %d\n", - (void*) old, old->Name, old->RefCount);*/ - deleteFlag = (old->RefCount == 0); - - if (deleteFlag) { - _mesa_HashRemove(ctx->Shared->ShaderObjects, old->Name); - ctx->Driver.DeleteShader(ctx, old); - } - - *ptr = NULL; - } - assert(!*ptr); - - if (sh) { - /* reference new */ - sh->RefCount++; - /*printf("SHADER INCR %p (%d) to %d\n", - (void*) sh, sh->Name, sh->RefCount);*/ - *ptr = sh; - } -} - -void -_mesa_init_shader(GLcontext *ctx, struct gl_shader *shader) -{ - shader->RefCount = 1; -} - -/** - * Allocate a new gl_shader object, initialize it. - * Called via ctx->Driver.NewShader() - */ -struct gl_shader * -_mesa_new_shader(GLcontext *ctx, GLuint name, GLenum type) -{ - struct gl_shader *shader; - assert(type == GL_FRAGMENT_SHADER || type == GL_VERTEX_SHADER || - type == GL_GEOMETRY_SHADER_ARB); - shader = talloc_zero(NULL, struct gl_shader); - if (shader) { - shader->Type = type; - shader->Name = name; - _mesa_init_shader(ctx, shader); - } - return shader; -} - - -/** - * Delete a shader object. - * Called via ctx->Driver.DeleteShader(). - */ -static void -_mesa_delete_shader(GLcontext *ctx, struct gl_shader *sh) -{ - if (sh->Source) - free((void *) sh->Source); - _mesa_reference_program(ctx, &sh->Program, NULL); - talloc_free(sh); -} - - -/** - * Lookup a GLSL shader object. - */ -struct gl_shader * -_mesa_lookup_shader(GLcontext *ctx, GLuint name) -{ - if (name) { - struct gl_shader *sh = (struct gl_shader *) - _mesa_HashLookup(ctx->Shared->ShaderObjects, name); - /* Note that both gl_shader and gl_shader_program objects are kept - * in the same hash table. Check the object's type to be sure it's - * what we're expecting. - */ - if (sh && sh->Type == GL_SHADER_PROGRAM_MESA) { - return NULL; - } - return sh; - } - return NULL; -} - - -/** - * As above, but record an error if shader is not found. - */ -struct gl_shader * -_mesa_lookup_shader_err(GLcontext *ctx, GLuint name, const char *caller) -{ - if (!name) { - _mesa_error(ctx, GL_INVALID_VALUE, "%s", caller); - return NULL; - } - else { - struct gl_shader *sh = (struct gl_shader *) - _mesa_HashLookup(ctx->Shared->ShaderObjects, name); - if (!sh) { - _mesa_error(ctx, GL_INVALID_VALUE, "%s", caller); - return NULL; - } - if (sh->Type == GL_SHADER_PROGRAM_MESA) { - _mesa_error(ctx, GL_INVALID_OPERATION, "%s", caller); - return NULL; - } - return sh; - } -} - - - -/**********************************************************************/ -/*** Shader Program object functions ***/ -/**********************************************************************/ - - -/** - * Set ptr to point to shProg. - * If ptr is pointing to another object, decrement its refcount (and delete - * if refcount hits zero). - * Then set ptr to point to shProg, incrementing its refcount. - */ -void -_mesa_reference_shader_program(GLcontext *ctx, - struct gl_shader_program **ptr, - struct gl_shader_program *shProg) -{ - assert(ptr); - if (*ptr == shProg) { - /* no-op */ - return; - } - if (*ptr) { - /* Unreference the old shader program */ - GLboolean deleteFlag = GL_FALSE; - struct gl_shader_program *old = *ptr; - - ASSERT(old->RefCount > 0); - old->RefCount--; -#if 0 - printf("ShaderProgram %p ID=%u RefCount-- to %d\n", - (void *) old, old->Name, old->RefCount); -#endif - deleteFlag = (old->RefCount == 0); - - if (deleteFlag) { - _mesa_HashRemove(ctx->Shared->ShaderObjects, old->Name); - ctx->Driver.DeleteShaderProgram(ctx, old); - } - - *ptr = NULL; - } - assert(!*ptr); - - if (shProg) { - shProg->RefCount++; -#if 0 - printf("ShaderProgram %p ID=%u RefCount++ to %d\n", - (void *) shProg, shProg->Name, shProg->RefCount); -#endif - *ptr = shProg; - } -} - -void -_mesa_init_shader_program(GLcontext *ctx, struct gl_shader_program *prog) -{ - prog->Type = GL_SHADER_PROGRAM_MESA; - prog->RefCount = 1; - prog->Attributes = _mesa_new_parameter_list(); -#if FEATURE_ARB_geometry_shader4 - prog->Geom.VerticesOut = 0; - prog->Geom.InputType = GL_TRIANGLES; - prog->Geom.OutputType = GL_TRIANGLE_STRIP; -#endif -} - -/** - * Allocate a new gl_shader_program object, initialize it. - * Called via ctx->Driver.NewShaderProgram() - */ -static struct gl_shader_program * -_mesa_new_shader_program(GLcontext *ctx, GLuint name) -{ - struct gl_shader_program *shProg; - shProg = talloc_zero(NULL, struct gl_shader_program); - if (shProg) { - shProg->Name = name; - _mesa_init_shader_program(ctx, shProg); - } - return shProg; -} - - -/** - * Clear (free) the shader program state that gets produced by linking. - */ -void -_mesa_clear_shader_program_data(GLcontext *ctx, - struct gl_shader_program *shProg) -{ - _mesa_reference_vertprog(ctx, &shProg->VertexProgram, NULL); - _mesa_reference_fragprog(ctx, &shProg->FragmentProgram, NULL); - _mesa_reference_geomprog(ctx, &shProg->GeometryProgram, NULL); - - if (shProg->Uniforms) { - _mesa_free_uniform_list(shProg->Uniforms); - shProg->Uniforms = NULL; - } - - if (shProg->Varying) { - _mesa_free_parameter_list(shProg->Varying); - shProg->Varying = NULL; - } -} - - -/** - * Free all the data that hangs off a shader program object, but not the - * object itself. - */ -void -_mesa_free_shader_program_data(GLcontext *ctx, - struct gl_shader_program *shProg) -{ - GLuint i; - - assert(shProg->Type == GL_SHADER_PROGRAM_MESA); - - _mesa_clear_shader_program_data(ctx, shProg); - - if (shProg->Attributes) { - _mesa_free_parameter_list(shProg->Attributes); - shProg->Attributes = NULL; - } - - /* detach shaders */ - for (i = 0; i < shProg->NumShaders; i++) { - _mesa_reference_shader(ctx, &shProg->Shaders[i], NULL); - } - shProg->NumShaders = 0; - - if (shProg->Shaders) { - free(shProg->Shaders); - shProg->Shaders = NULL; - } - - if (shProg->InfoLog) { - talloc_free(shProg->InfoLog); - shProg->InfoLog = NULL; - } - - /* Transform feedback varying vars */ - for (i = 0; i < shProg->TransformFeedback.NumVarying; i++) { - free(shProg->TransformFeedback.VaryingNames[i]); - } - free(shProg->TransformFeedback.VaryingNames); - shProg->TransformFeedback.VaryingNames = NULL; - shProg->TransformFeedback.NumVarying = 0; - - - for (i = 0; i < shProg->_NumLinkedShaders; i++) { - ctx->Driver.DeleteShader(ctx, shProg->_LinkedShaders[i]); - } - shProg->_NumLinkedShaders = 0; -} - - -/** - * Free/delete a shader program object. - * Called via ctx->Driver.DeleteShaderProgram(). - */ -static void -_mesa_delete_shader_program(GLcontext *ctx, struct gl_shader_program *shProg) -{ - _mesa_free_shader_program_data(ctx, shProg); - - talloc_free(shProg); -} - - -/** - * Lookup a GLSL program object. - */ -struct gl_shader_program * -_mesa_lookup_shader_program(GLcontext *ctx, GLuint name) -{ - struct gl_shader_program *shProg; - if (name) { - shProg = (struct gl_shader_program *) - _mesa_HashLookup(ctx->Shared->ShaderObjects, name); - /* Note that both gl_shader and gl_shader_program objects are kept - * in the same hash table. Check the object's type to be sure it's - * what we're expecting. - */ - if (shProg && shProg->Type != GL_SHADER_PROGRAM_MESA) { - return NULL; - } - return shProg; - } - return NULL; -} - - -/** - * As above, but record an error if program is not found. - */ -struct gl_shader_program * -_mesa_lookup_shader_program_err(GLcontext *ctx, GLuint name, - const char *caller) -{ - if (!name) { - _mesa_error(ctx, GL_INVALID_VALUE, "%s", caller); - return NULL; - } - else { - struct gl_shader_program *shProg = (struct gl_shader_program *) - _mesa_HashLookup(ctx->Shared->ShaderObjects, name); - if (!shProg) { - _mesa_error(ctx, GL_INVALID_VALUE, "%s", caller); - return NULL; - } - if (shProg->Type != GL_SHADER_PROGRAM_MESA) { - _mesa_error(ctx, GL_INVALID_OPERATION, "%s", caller); - return NULL; - } - return shProg; - } -} - - -void -_mesa_init_shader_object_functions(struct dd_function_table *driver) -{ - driver->NewShader = _mesa_new_shader; - driver->DeleteShader = _mesa_delete_shader; - driver->NewShaderProgram = _mesa_new_shader_program; - driver->DeleteShaderProgram = _mesa_delete_shader_program; - driver->CompileShader = _mesa_ir_compile_shader; - driver->LinkShader = _mesa_ir_link_shader; -} +/*
+ * Mesa 3-D graphics library
+ *
+ * Copyright (C) 2004-2008 Brian Paul All Rights Reserved.
+ * Copyright (C) 2009-2010 VMware, Inc. 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 shaderobj.c
+ * \author Brian Paul
+ *
+ */
+
+
+#include "main/glheader.h"
+#include "main/context.h"
+#include "main/hash.h"
+#include "main/shaderobj.h"
+#include "program/program.h"
+#include "program/prog_parameter.h"
+#include "program/prog_uniform.h"
+#include "talloc.h"
+
+/**********************************************************************/
+/*** Shader object functions ***/
+/**********************************************************************/
+
+
+/**
+ * Set ptr to point to sh.
+ * If ptr is pointing to another shader, decrement its refcount (and delete
+ * if refcount hits zero).
+ * Then set ptr to point to sh, incrementing its refcount.
+ */
+void
+_mesa_reference_shader(struct gl_context *ctx, struct gl_shader **ptr,
+ struct gl_shader *sh)
+{
+ assert(ptr);
+ if (*ptr == sh) {
+ /* no-op */
+ return;
+ }
+ if (*ptr) {
+ /* Unreference the old shader */
+ GLboolean deleteFlag = GL_FALSE;
+ struct gl_shader *old = *ptr;
+
+ ASSERT(old->RefCount > 0);
+ old->RefCount--;
+ /*printf("SHADER DECR %p (%d) to %d\n",
+ (void*) old, old->Name, old->RefCount);*/
+ deleteFlag = (old->RefCount == 0);
+
+ if (deleteFlag) {
+ _mesa_HashRemove(ctx->Shared->ShaderObjects, old->Name);
+ ctx->Driver.DeleteShader(ctx, old);
+ }
+
+ *ptr = NULL;
+ }
+ assert(!*ptr);
+
+ if (sh) {
+ /* reference new */
+ sh->RefCount++;
+ /*printf("SHADER INCR %p (%d) to %d\n",
+ (void*) sh, sh->Name, sh->RefCount);*/
+ *ptr = sh;
+ }
+}
+
+void
+_mesa_init_shader(struct gl_context *ctx, struct gl_shader *shader)
+{
+ shader->RefCount = 1;
+}
+
+/**
+ * Allocate a new gl_shader object, initialize it.
+ * Called via ctx->Driver.NewShader()
+ */
+struct gl_shader *
+_mesa_new_shader(struct gl_context *ctx, GLuint name, GLenum type)
+{
+ struct gl_shader *shader;
+ assert(type == GL_FRAGMENT_SHADER || type == GL_VERTEX_SHADER ||
+ type == GL_GEOMETRY_SHADER_ARB);
+ shader = talloc_zero(NULL, struct gl_shader);
+ if (shader) {
+ shader->Type = type;
+ shader->Name = name;
+ _mesa_init_shader(ctx, shader);
+ }
+ return shader;
+}
+
+
+/**
+ * Delete a shader object.
+ * Called via ctx->Driver.DeleteShader().
+ */
+static void
+_mesa_delete_shader(struct gl_context *ctx, struct gl_shader *sh)
+{
+ if (sh->Source)
+ free((void *) sh->Source);
+ _mesa_reference_program(ctx, &sh->Program, NULL);
+ talloc_free(sh);
+}
+
+
+/**
+ * Lookup a GLSL shader object.
+ */
+struct gl_shader *
+_mesa_lookup_shader(struct gl_context *ctx, GLuint name)
+{
+ if (name) {
+ struct gl_shader *sh = (struct gl_shader *)
+ _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
+ /* Note that both gl_shader and gl_shader_program objects are kept
+ * in the same hash table. Check the object's type to be sure it's
+ * what we're expecting.
+ */
+ if (sh && sh->Type == GL_SHADER_PROGRAM_MESA) {
+ return NULL;
+ }
+ return sh;
+ }
+ return NULL;
+}
+
+
+/**
+ * As above, but record an error if shader is not found.
+ */
+struct gl_shader *
+_mesa_lookup_shader_err(struct gl_context *ctx, GLuint name, const char *caller)
+{
+ if (!name) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s", caller);
+ return NULL;
+ }
+ else {
+ struct gl_shader *sh = (struct gl_shader *)
+ _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
+ if (!sh) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s", caller);
+ return NULL;
+ }
+ if (sh->Type == GL_SHADER_PROGRAM_MESA) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s", caller);
+ return NULL;
+ }
+ return sh;
+ }
+}
+
+
+
+/**********************************************************************/
+/*** Shader Program object functions ***/
+/**********************************************************************/
+
+
+/**
+ * Set ptr to point to shProg.
+ * If ptr is pointing to another object, decrement its refcount (and delete
+ * if refcount hits zero).
+ * Then set ptr to point to shProg, incrementing its refcount.
+ */
+void
+_mesa_reference_shader_program(struct gl_context *ctx,
+ struct gl_shader_program **ptr,
+ struct gl_shader_program *shProg)
+{
+ assert(ptr);
+ if (*ptr == shProg) {
+ /* no-op */
+ return;
+ }
+ if (*ptr) {
+ /* Unreference the old shader program */
+ GLboolean deleteFlag = GL_FALSE;
+ struct gl_shader_program *old = *ptr;
+
+ ASSERT(old->RefCount > 0);
+ old->RefCount--;
+#if 0
+ printf("ShaderProgram %p ID=%u RefCount-- to %d\n",
+ (void *) old, old->Name, old->RefCount);
+#endif
+ deleteFlag = (old->RefCount == 0);
+
+ if (deleteFlag) {
+ _mesa_HashRemove(ctx->Shared->ShaderObjects, old->Name);
+ ctx->Driver.DeleteShaderProgram(ctx, old);
+ }
+
+ *ptr = NULL;
+ }
+ assert(!*ptr);
+
+ if (shProg) {
+ shProg->RefCount++;
+#if 0
+ printf("ShaderProgram %p ID=%u RefCount++ to %d\n",
+ (void *) shProg, shProg->Name, shProg->RefCount);
+#endif
+ *ptr = shProg;
+ }
+}
+
+void
+_mesa_init_shader_program(struct gl_context *ctx, struct gl_shader_program *prog)
+{
+ prog->Type = GL_SHADER_PROGRAM_MESA;
+ prog->RefCount = 1;
+ prog->Attributes = _mesa_new_parameter_list();
+#if FEATURE_ARB_geometry_shader4
+ prog->Geom.VerticesOut = 0;
+ prog->Geom.InputType = GL_TRIANGLES;
+ prog->Geom.OutputType = GL_TRIANGLE_STRIP;
+#endif
+}
+
+/**
+ * Allocate a new gl_shader_program object, initialize it.
+ * Called via ctx->Driver.NewShaderProgram()
+ */
+static struct gl_shader_program *
+_mesa_new_shader_program(struct gl_context *ctx, GLuint name)
+{
+ struct gl_shader_program *shProg;
+ shProg = talloc_zero(NULL, struct gl_shader_program);
+ if (shProg) {
+ shProg->Name = name;
+ _mesa_init_shader_program(ctx, shProg);
+ }
+ return shProg;
+}
+
+
+/**
+ * Clear (free) the shader program state that gets produced by linking.
+ */
+void
+_mesa_clear_shader_program_data(struct gl_context *ctx,
+ struct gl_shader_program *shProg)
+{
+ _mesa_reference_vertprog(ctx, &shProg->VertexProgram, NULL);
+ _mesa_reference_fragprog(ctx, &shProg->FragmentProgram, NULL);
+ _mesa_reference_geomprog(ctx, &shProg->GeometryProgram, NULL);
+
+ if (shProg->Uniforms) {
+ _mesa_free_uniform_list(shProg->Uniforms);
+ shProg->Uniforms = NULL;
+ }
+
+ if (shProg->Varying) {
+ _mesa_free_parameter_list(shProg->Varying);
+ shProg->Varying = NULL;
+ }
+}
+
+
+/**
+ * Free all the data that hangs off a shader program object, but not the
+ * object itself.
+ */
+void
+_mesa_free_shader_program_data(struct gl_context *ctx,
+ struct gl_shader_program *shProg)
+{
+ GLuint i;
+ gl_shader_type sh;
+
+ assert(shProg->Type == GL_SHADER_PROGRAM_MESA);
+
+ _mesa_clear_shader_program_data(ctx, shProg);
+
+ if (shProg->Attributes) {
+ _mesa_free_parameter_list(shProg->Attributes);
+ shProg->Attributes = NULL;
+ }
+
+ /* detach shaders */
+ for (i = 0; i < shProg->NumShaders; i++) {
+ _mesa_reference_shader(ctx, &shProg->Shaders[i], NULL);
+ }
+ shProg->NumShaders = 0;
+
+ if (shProg->Shaders) {
+ free(shProg->Shaders);
+ shProg->Shaders = NULL;
+ }
+
+ if (shProg->InfoLog) {
+ talloc_free(shProg->InfoLog);
+ shProg->InfoLog = NULL;
+ }
+
+ /* Transform feedback varying vars */
+ for (i = 0; i < shProg->TransformFeedback.NumVarying; i++) {
+ free(shProg->TransformFeedback.VaryingNames[i]);
+ }
+ free(shProg->TransformFeedback.VaryingNames);
+ shProg->TransformFeedback.VaryingNames = NULL;
+ shProg->TransformFeedback.NumVarying = 0;
+
+
+ for (sh = 0; sh < MESA_SHADER_TYPES; sh++) {
+ if (shProg->_LinkedShaders[sh] != NULL) {
+ ctx->Driver.DeleteShader(ctx, shProg->_LinkedShaders[sh]);
+ shProg->_LinkedShaders[sh] = NULL;
+ }
+ }
+}
+
+
+/**
+ * Free/delete a shader program object.
+ * Called via ctx->Driver.DeleteShaderProgram().
+ */
+static void
+_mesa_delete_shader_program(struct gl_context *ctx, struct gl_shader_program *shProg)
+{
+ _mesa_free_shader_program_data(ctx, shProg);
+
+ talloc_free(shProg);
+}
+
+
+/**
+ * Lookup a GLSL program object.
+ */
+struct gl_shader_program *
+_mesa_lookup_shader_program(struct gl_context *ctx, GLuint name)
+{
+ struct gl_shader_program *shProg;
+ if (name) {
+ shProg = (struct gl_shader_program *)
+ _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
+ /* Note that both gl_shader and gl_shader_program objects are kept
+ * in the same hash table. Check the object's type to be sure it's
+ * what we're expecting.
+ */
+ if (shProg && shProg->Type != GL_SHADER_PROGRAM_MESA) {
+ return NULL;
+ }
+ return shProg;
+ }
+ return NULL;
+}
+
+
+/**
+ * As above, but record an error if program is not found.
+ */
+struct gl_shader_program *
+_mesa_lookup_shader_program_err(struct gl_context *ctx, GLuint name,
+ const char *caller)
+{
+ if (!name) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s", caller);
+ return NULL;
+ }
+ else {
+ struct gl_shader_program *shProg = (struct gl_shader_program *)
+ _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
+ if (!shProg) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s", caller);
+ return NULL;
+ }
+ if (shProg->Type != GL_SHADER_PROGRAM_MESA) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s", caller);
+ return NULL;
+ }
+ return shProg;
+ }
+}
+
+
+void
+_mesa_init_shader_object_functions(struct dd_function_table *driver)
+{
+ driver->NewShader = _mesa_new_shader;
+ driver->DeleteShader = _mesa_delete_shader;
+ driver->NewShaderProgram = _mesa_new_shader_program;
+ driver->DeleteShaderProgram = _mesa_delete_shader_program;
+ driver->CompileShader = _mesa_ir_compile_shader;
+ driver->LinkShader = _mesa_ir_link_shader;
+}
|