shaderobj.c revision ce220540744c0dde30e5670441bbc7eab915cf89
147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/*
247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Mesa 3-D graphics library
347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *
447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Copyright (C) 2004-2008  Brian Paul   All Rights Reserved.
547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Copyright (C) 2009-2010  VMware, Inc.  All Rights Reserved.
647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *
747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Permission is hereby granted, free of charge, to any person obtaining a
847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * copy of this software and associated documentation files (the "Software"),
947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * to deal in the Software without restriction, including without limitation
1047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * the rights to use, copy, modify, merge, publish, distribute, sublicense,
1147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * and/or sell copies of the Software, and to permit persons to whom the
1247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Software is furnished to do so, subject to the following conditions:
1347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *
1447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * The above copyright notice and this permission notice shall be included
1547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * in all copies or substantial portions of the Software.
1647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *
1747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
1847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
2047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
2147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
2247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */
2447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
2547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/**
2647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * \file shaderobj.c
2747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * \author Brian Paul
2847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt *
2947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */
3047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
3147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
3247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#include "main/glheader.h"
3347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#include "main/context.h"
3447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#include "main/hash.h"
3547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#include "main/mfeatures.h"
3647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#include "main/mtypes.h"
3747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#include "main/shaderobj.h"
3847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#include "main/uniforms.h"
3947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#include "program/program.h"
4047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#include "program/prog_parameter.h"
4147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#include "program/hash_table.h"
4247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#include "ralloc.h"
4347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
4447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/**********************************************************************/
4547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/*** Shader object functions                                        ***/
4647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/**********************************************************************/
4747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
4847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
4947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/**
5047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Set ptr to point to sh.
5147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * If ptr is pointing to another shader, decrement its refcount (and delete
5247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * if refcount hits zero).
5347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Then set ptr to point to sh, incrementing its refcount.
5447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */
5547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltvoid
5647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt_mesa_reference_shader(struct gl_context *ctx, struct gl_shader **ptr,
5747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt                       struct gl_shader *sh)
5847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{
5947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   assert(ptr);
6047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   if (*ptr == sh) {
6147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      /* no-op */
6247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      return;
6347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   }
6447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   if (*ptr) {
6547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      /* Unreference the old shader */
6647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      GLboolean deleteFlag = GL_FALSE;
6747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      struct gl_shader *old = *ptr;
6847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
6947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      ASSERT(old->RefCount > 0);
7047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      old->RefCount--;
7147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      /*printf("SHADER DECR %p (%d) to %d\n",
7247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt        (void*) old, old->Name, old->RefCount);*/
7347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      deleteFlag = (old->RefCount == 0);
7447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
7547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      if (deleteFlag) {
7647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	 if (old->Name != 0)
7747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	    _mesa_HashRemove(ctx->Shared->ShaderObjects, old->Name);
7847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt         ctx->Driver.DeleteShader(ctx, old);
7947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      }
8047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
8147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      *ptr = NULL;
8247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   }
8347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   assert(!*ptr);
8447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
8547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   if (sh) {
8647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      /* reference new */
8747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      sh->RefCount++;
8847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      /*printf("SHADER INCR %p (%d) to %d\n",
8947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt        (void*) sh, sh->Name, sh->RefCount);*/
9047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      *ptr = sh;
9147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   }
9247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt}
9347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
9447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltvoid
9547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt_mesa_init_shader(struct gl_context *ctx, struct gl_shader *shader)
9647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{
9747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   shader->RefCount = 1;
9847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt}
9947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
10047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/**
10147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Allocate a new gl_shader object, initialize it.
10247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Called via ctx->Driver.NewShader()
10347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */
10447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstruct gl_shader *
10547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt_mesa_new_shader(struct gl_context *ctx, GLuint name, GLenum type)
10647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{
10747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   struct gl_shader *shader;
10847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   assert(type == GL_FRAGMENT_SHADER || type == GL_VERTEX_SHADER ||
10947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt          type == GL_GEOMETRY_SHADER_ARB);
11047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   shader = rzalloc(NULL, struct gl_shader);
11147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   if (shader) {
11247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      shader->Type = type;
11347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      shader->Name = name;
11447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      _mesa_init_shader(ctx, shader);
11547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   }
11647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   return shader;
11747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt}
11847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
11947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
12047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/**
12147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Delete a shader object.
12247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Called via ctx->Driver.DeleteShader().
12347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */
12447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic void
12547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt_mesa_delete_shader(struct gl_context *ctx, struct gl_shader *sh)
12647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{
12747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   if (sh->Source)
12847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      free((void *) sh->Source);
12947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   _mesa_reference_program(ctx, &sh->Program, NULL);
13047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   ralloc_free(sh);
13147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt}
13247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
13347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
13447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/**
13547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Lookup a GLSL shader object.
13647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */
13747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstruct gl_shader *
13847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt_mesa_lookup_shader(struct gl_context *ctx, GLuint name)
13947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{
14047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   if (name) {
14147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      struct gl_shader *sh = (struct gl_shader *)
14247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt         _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
14347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      /* Note that both gl_shader and gl_shader_program objects are kept
14447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt       * in the same hash table.  Check the object's type to be sure it's
14547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt       * what we're expecting.
14647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt       */
14747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      if (sh && sh->Type == GL_SHADER_PROGRAM_MESA) {
14847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt         return NULL;
14947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      }
15047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      return sh;
15147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   }
15247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   return NULL;
15347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt}
15447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
15547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
15647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/**
15747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * As above, but record an error if shader is not found.
15847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */
15947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstruct gl_shader *
16047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt_mesa_lookup_shader_err(struct gl_context *ctx, GLuint name, const char *caller)
16147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{
16247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   if (!name) {
16347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      _mesa_error(ctx, GL_INVALID_VALUE, "%s", caller);
16447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      return NULL;
16547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   }
16647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   else {
16747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      struct gl_shader *sh = (struct gl_shader *)
16847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt         _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
16947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      if (!sh) {
17047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt         _mesa_error(ctx, GL_INVALID_VALUE, "%s", caller);
17147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt         return NULL;
17247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      }
17347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      if (sh->Type == GL_SHADER_PROGRAM_MESA) {
17447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt         _mesa_error(ctx, GL_INVALID_OPERATION, "%s", caller);
17547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt         return NULL;
17647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      }
17747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      return sh;
17847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   }
17947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt}
18047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
18147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
18247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
18347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/**********************************************************************/
18447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/*** Shader Program object functions                                ***/
18547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/**********************************************************************/
18647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
18747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
18847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/**
18947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Set ptr to point to shProg.
19047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * If ptr is pointing to another object, decrement its refcount (and delete
19147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * if refcount hits zero).
19247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Then set ptr to point to shProg, incrementing its refcount.
19347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */
19447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltvoid
19547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt_mesa_reference_shader_program(struct gl_context *ctx,
19647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt                               struct gl_shader_program **ptr,
19747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt                               struct gl_shader_program *shProg)
19847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{
19947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   assert(ptr);
20047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   if (*ptr == shProg) {
20147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      /* no-op */
20247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      return;
20347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   }
20447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   if (*ptr) {
20547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      /* Unreference the old shader program */
20647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      GLboolean deleteFlag = GL_FALSE;
20747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      struct gl_shader_program *old = *ptr;
20847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
20947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      ASSERT(old->RefCount > 0);
21047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      old->RefCount--;
21147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#if 0
21247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      printf("ShaderProgram %p ID=%u  RefCount-- to %d\n",
21347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt             (void *) old, old->Name, old->RefCount);
21447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
21547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      deleteFlag = (old->RefCount == 0);
21647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
21747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      if (deleteFlag) {
21847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	 if (old->Name != 0)
21947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	    _mesa_HashRemove(ctx->Shared->ShaderObjects, old->Name);
22047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt         ctx->Driver.DeleteShaderProgram(ctx, old);
22147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      }
22247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
22347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      *ptr = NULL;
22447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   }
22547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   assert(!*ptr);
22647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
22747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   if (shProg) {
22847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      shProg->RefCount++;
22947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#if 0
23047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      printf("ShaderProgram %p ID=%u  RefCount++ to %d\n",
23147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt             (void *) shProg, shProg->Name, shProg->RefCount);
23247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
23347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      *ptr = shProg;
23447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   }
23547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt}
23647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
23747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltvoid
23847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt_mesa_init_shader_program(struct gl_context *ctx, struct gl_shader_program *prog)
23947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{
24047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   prog->Type = GL_SHADER_PROGRAM_MESA;
24147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   prog->RefCount = 1;
24247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
24347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   prog->AttributeBindings = string_to_uint_map_ctor();
24447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   prog->FragDataBindings = string_to_uint_map_ctor();
24547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   prog->FragDataIndexBindings = string_to_uint_map_ctor();
24647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
24747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#if FEATURE_ARB_geometry_shader4
24847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   prog->Geom.VerticesOut = 0;
24947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   prog->Geom.InputType = GL_TRIANGLES;
25047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   prog->Geom.OutputType = GL_TRIANGLE_STRIP;
25147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt#endif
25247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
25347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   prog->TransformFeedback.BufferMode = GL_INTERLEAVED_ATTRIBS;
25447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
25547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   prog->InfoLog = ralloc_strdup(prog, "");
25647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt}
25747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
25847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/**
25947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Allocate a new gl_shader_program object, initialize it.
26047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Called via ctx->Driver.NewShaderProgram()
26147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */
26247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic struct gl_shader_program *
26347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt_mesa_new_shader_program(struct gl_context *ctx, GLuint name)
26447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{
26547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   struct gl_shader_program *shProg;
26647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   shProg = rzalloc(NULL, struct gl_shader_program);
26747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   if (shProg) {
26847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      shProg->Name = name;
26947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      _mesa_init_shader_program(ctx, shProg);
27047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   }
27147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   return shProg;
27247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt}
27347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
27447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
27547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/**
27647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Clear (free) the shader program state that gets produced by linking.
27747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */
27847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltvoid
27947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt_mesa_clear_shader_program_data(struct gl_context *ctx,
28047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt                                struct gl_shader_program *shProg)
28147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{
28247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   if (shProg->UniformStorage) {
28347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      unsigned i;
28447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      for (i = 0; i < shProg->NumUserUniformStorage; ++i)
28547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt         _mesa_uniform_detach_all_driver_storage(&shProg->UniformStorage[i]);
28647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      ralloc_free(shProg->UniformStorage);
28747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      shProg->NumUserUniformStorage = 0;
28847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      shProg->UniformStorage = NULL;
28947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   }
29047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
29147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   if (shProg->UniformHash) {
29247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      string_to_uint_map_dtor(shProg->UniformHash);
29347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      shProg->UniformHash = NULL;
29447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   }
29547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
29647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   assert(shProg->InfoLog != NULL);
29747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   ralloc_free(shProg->InfoLog);
29847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   shProg->InfoLog = ralloc_strdup(shProg, "");
29947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt}
30047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
30147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
30247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/**
30347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Free all the data that hangs off a shader program object, but not the
30447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * object itself.
30547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */
30647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltvoid
30747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt_mesa_free_shader_program_data(struct gl_context *ctx,
30847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt                               struct gl_shader_program *shProg)
30947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{
31047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   GLuint i;
31147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   gl_shader_type sh;
31247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
31347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   assert(shProg->Type == GL_SHADER_PROGRAM_MESA);
31447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
31547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   _mesa_clear_shader_program_data(ctx, shProg);
31647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
31747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   if (shProg->AttributeBindings) {
31847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      string_to_uint_map_dtor(shProg->AttributeBindings);
31947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      shProg->AttributeBindings = NULL;
32047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   }
32147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
32247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   if (shProg->FragDataBindings) {
32347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      string_to_uint_map_dtor(shProg->FragDataBindings);
32447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      shProg->FragDataBindings = NULL;
32547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   }
32647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
32747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   if (shProg->FragDataIndexBindings) {
32847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      string_to_uint_map_dtor(shProg->FragDataIndexBindings);
32947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      shProg->FragDataIndexBindings = NULL;
33047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   }
33147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
33247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   /* detach shaders */
33347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   for (i = 0; i < shProg->NumShaders; i++) {
33447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      _mesa_reference_shader(ctx, &shProg->Shaders[i], NULL);
33547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   }
33647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   shProg->NumShaders = 0;
33747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
33847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   if (shProg->Shaders) {
33947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      free(shProg->Shaders);
34047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      shProg->Shaders = NULL;
34147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   }
34247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
34347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   /* Transform feedback varying vars */
34447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   for (i = 0; i < shProg->TransformFeedback.NumVarying; i++) {
34547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      free(shProg->TransformFeedback.VaryingNames[i]);
34647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   }
34747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   free(shProg->TransformFeedback.VaryingNames);
34847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   shProg->TransformFeedback.VaryingNames = NULL;
34947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   shProg->TransformFeedback.NumVarying = 0;
35047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
35147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
35247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   for (sh = 0; sh < MESA_SHADER_TYPES; sh++) {
35347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      if (shProg->_LinkedShaders[sh] != NULL) {
35447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	 ctx->Driver.DeleteShader(ctx, shProg->_LinkedShaders[sh]);
35547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt	 shProg->_LinkedShaders[sh] = NULL;
35647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      }
35747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   }
35847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt}
35947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
36047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
36147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/**
36247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Free/delete a shader program object.
36347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Called via ctx->Driver.DeleteShaderProgram().
36447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */
36547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstatic void
36647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt_mesa_delete_shader_program(struct gl_context *ctx, struct gl_shader_program *shProg)
36747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{
36847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   _mesa_free_shader_program_data(ctx, shProg);
36947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
37047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   ralloc_free(shProg);
37147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt}
37247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
37347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
37447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/**
37547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * Lookup a GLSL program object.
37647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */
37747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstruct gl_shader_program *
37847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt_mesa_lookup_shader_program(struct gl_context *ctx, GLuint name)
37947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{
38047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   struct gl_shader_program *shProg;
38147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   if (name) {
38247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      shProg = (struct gl_shader_program *)
38347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt         _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
38447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      /* Note that both gl_shader and gl_shader_program objects are kept
38547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt       * in the same hash table.  Check the object's type to be sure it's
38647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt       * what we're expecting.
38747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt       */
38847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      if (shProg && shProg->Type != GL_SHADER_PROGRAM_MESA) {
38947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt         return NULL;
39047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      }
39147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      return shProg;
39247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   }
39347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   return NULL;
39447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt}
39547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
39647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
39747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt/**
39847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt * As above, but record an error if program is not found.
39947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt */
40047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltstruct gl_shader_program *
40147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt_mesa_lookup_shader_program_err(struct gl_context *ctx, GLuint name,
40247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt                                const char *caller)
40347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{
40447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   if (!name) {
40547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      _mesa_error(ctx, GL_INVALID_VALUE, "%s", caller);
40647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      return NULL;
40747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   }
40847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   else {
40947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      struct gl_shader_program *shProg = (struct gl_shader_program *)
41047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt         _mesa_HashLookup(ctx->Shared->ShaderObjects, name);
41147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      if (!shProg) {
41247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt         _mesa_error(ctx, GL_INVALID_VALUE, "%s", caller);
41347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt         return NULL;
41447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      }
41547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      if (shProg->Type != GL_SHADER_PROGRAM_MESA) {
41647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt         _mesa_error(ctx, GL_INVALID_OPERATION, "%s", caller);
41747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt         return NULL;
41847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      }
41947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt      return shProg;
42047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   }
42147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt}
42247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
42347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt
42447e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwaltvoid
42547e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt_mesa_init_shader_object_functions(struct dd_function_table *driver)
42647e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt{
42747e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   driver->NewShader = _mesa_new_shader;
42847e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   driver->DeleteShader = _mesa_delete_shader;
42947e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   driver->NewShaderProgram = _mesa_new_shader_program;
43047e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   driver->DeleteShaderProgram = _mesa_delete_shader_program;
43147e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt   driver->LinkShader = _mesa_ir_link_shader;
43247e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt}
43347e4cebad7397422144bb03a21f3f7682c062c4aRobert Greenwalt