summaryrefslogtreecommitdiffstats
path: root/src/mesa/main
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesa/main')
-rw-r--r--src/mesa/main/config.h12
-rw-r--r--src/mesa/main/context.c128
-rw-r--r--src/mesa/main/dd.h58
-rw-r--r--src/mesa/main/get.c6
-rw-r--r--src/mesa/main/get_gen.py2
-rw-r--r--src/mesa/main/getstring.c4
-rw-r--r--src/mesa/main/imports.c20
-rw-r--r--src/mesa/main/matrix.c12
-rw-r--r--src/mesa/main/mtypes.h237
-rw-r--r--src/mesa/main/shaders.c669
-rw-r--r--src/mesa/main/shaders.h236
-rw-r--r--src/mesa/main/state.c81
-rw-r--r--src/mesa/main/texenvprogram.c98
-rw-r--r--src/mesa/main/texstate.c63
14 files changed, 1373 insertions, 253 deletions
diff --git a/src/mesa/main/config.h b/src/mesa/main/config.h
index 13c6281f077..00df084fc88 100644
--- a/src/mesa/main/config.h
+++ b/src/mesa/main/config.h
@@ -196,21 +196,19 @@
/** For any program target/extension */
/*@{*/
#define MAX_PROGRAM_LOCAL_PARAMS 128 /* KW: power of two */
+#define MAX_PROGRAM_ENV_PARAMS 128
#define MAX_PROGRAM_MATRICES 8
#define MAX_PROGRAM_MATRIX_STACK_DEPTH 4
#define MAX_PROGRAM_CALL_DEPTH 8
-/*@}*/
-
-/** For GL_ARB_fragment_shader */
-/*@{*/
-#define MAX_FRAGMENT_UNIFORM_COMPONENTS 64
+#define MAX_PROGRAM_TEMPS 128
+#define MAX_PROGRAM_ADDRESS_REGS 2
+#define MAX_UNIFORMS 128
+#define MAX_VARYING 8
/*@}*/
/** For GL_ARB_vertex_shader */
/*@{*/
#define MAX_VERTEX_ATTRIBS 16
-#define MAX_VERTEX_UNIFORM_COMPONENTS 512
-#define MAX_VARYING_FLOATS 32
#define MAX_VERTEX_TEXTURE_IMAGE_UNITS 0
#define MAX_COMBINED_TEXTURE_IMAGE_UNITS (MAX_TEXTURE_IMAGE_UNITS + MAX_VERTEX_TEXTURE_IMAGE_UNITS)
/*@}*/
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index 135c814c0a6..0cff90c77a6 100644
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -132,7 +132,7 @@
#include "math/m_xform.h"
#include "math/mathmod.h"
#endif
-#include "shaderobjects.h"
+#include "shader_api.h"
#ifdef USE_SPARC_ASM
#include "sparc/sparc.h"
@@ -701,7 +701,7 @@ alloc_shared_state( GLcontext *ctx )
ss->ArrayObjects = _mesa_NewHashTable();
#if FEATURE_ARB_shader_objects
- ss->GL2Objects = _mesa_NewHashTable ();
+ ss->ShaderObjects = _mesa_NewHashTable();
#endif
ss->Default1D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_1D);
@@ -778,8 +778,8 @@ alloc_shared_state( GLcontext *ctx )
_mesa_DeleteHashTable (ss->ArrayObjects);
#if FEATURE_ARB_shader_objects
- if (ss->GL2Objects)
- _mesa_DeleteHashTable (ss->GL2Objects);
+ if (ss->ShaderObjects)
+ _mesa_DeleteHashTable (ss->ShaderObjects);
#endif
#if FEATURE_EXT_framebuffer_object
@@ -873,13 +873,22 @@ delete_arrayobj_cb(GLuint id, void *data, void *userData)
}
/**
- * Callback for deleting an shader object. Called by _mesa_HashDeleteAll().
+ * Callback for deleting shader and shader programs objects.
+ * Called by _mesa_HashDeleteAll().
*/
static void
-delete_shaderobj_cb(GLuint id, void *data, void *userData)
+delete_shader_cb(GLuint id, void *data, void *userData)
{
- /* XXX probably need to fix this */
- _mesa_free(data);
+ GLcontext *ctx = (GLcontext *) userData;
+ struct gl_shader *sh = (struct gl_shader *) data;
+ if (sh->Type == GL_FRAGMENT_SHADER || sh->Type == GL_VERTEX_SHADER) {
+ _mesa_free_shader(ctx, sh);
+ }
+ else {
+ struct gl_shader_program *shProg = (struct gl_shader_program *) data;
+ ASSERT(shProg->Type == GL_SHADER_PROGRAM);
+ _mesa_free_shader_program(ctx, shProg);
+ }
}
@@ -944,8 +953,8 @@ free_shared_state( GLcontext *ctx, struct gl_shared_state *ss )
_mesa_DeleteHashTable(ss->ArrayObjects);
#if FEATURE_ARB_shader_objects
- _mesa_HashDeleteAll(ss->GL2Objects, delete_shaderobj_cb, ctx);
- _mesa_DeleteHashTable(ss->GL2Objects);
+ _mesa_HashDeleteAll(ss->ShaderObjects, delete_shader_cb, ctx);
+ _mesa_DeleteHashTable(ss->ShaderObjects);
#endif
#if FEATURE_EXT_framebuffer_object
@@ -963,7 +972,7 @@ free_shared_state( GLcontext *ctx, struct gl_shared_state *ss )
* Initialize fields of gl_current_attrib (aka ctx->Current.*)
*/
static void
-_mesa_init_current( GLcontext *ctx )
+_mesa_init_current(GLcontext *ctx)
{
GLuint i;
@@ -1005,7 +1014,7 @@ init_natives(struct gl_program_constants *prog)
* some of these values (such as number of texture units).
*/
static void
-_mesa_init_constants( GLcontext *ctx )
+_mesa_init_constants(GLcontext *ctx)
{
assert(ctx);
@@ -1058,9 +1067,10 @@ _mesa_init_constants( GLcontext *ctx )
ctx->Const.VertexProgram.MaxLocalParams = MAX_PROGRAM_LOCAL_PARAMS;
ctx->Const.VertexProgram.MaxEnvParams = MAX_NV_VERTEX_PROGRAM_PARAMS;
ctx->Const.VertexProgram.MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS;
- ctx->Const.VertexProgram.MaxUniformComponents = MAX_VERTEX_UNIFORM_COMPONENTS;
+ ctx->Const.VertexProgram.MaxUniformComponents = 4 * MAX_UNIFORMS;
init_natives(&ctx->Const.VertexProgram);
#endif
+
#if FEATURE_ARB_fragment_program
ctx->Const.FragmentProgram.MaxInstructions = MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS;
ctx->Const.FragmentProgram.MaxAluInstructions = MAX_FRAGMENT_PROGRAM_ALU_INSTRUCTIONS;
@@ -1072,7 +1082,7 @@ _mesa_init_constants( GLcontext *ctx )
ctx->Const.FragmentProgram.MaxLocalParams = MAX_PROGRAM_LOCAL_PARAMS;
ctx->Const.FragmentProgram.MaxEnvParams = MAX_NV_FRAGMENT_PROGRAM_PARAMS;
ctx->Const.FragmentProgram.MaxAddressRegs = MAX_FRAGMENT_PROGRAM_ADDRESS_REGS;
- ctx->Const.FragmentProgram.MaxUniformComponents = MAX_FRAGMENT_UNIFORM_COMPONENTS;
+ ctx->Const.FragmentProgram.MaxUniformComponents = 4 * MAX_UNIFORMS;
init_natives(&ctx->Const.FragmentProgram);
#endif
ctx->Const.MaxProgramMatrices = MAX_PROGRAM_MATRICES;
@@ -1095,7 +1105,7 @@ _mesa_init_constants( GLcontext *ctx )
#if FEATURE_ARB_vertex_shader
ctx->Const.MaxVertexTextureImageUnits = MAX_VERTEX_TEXTURE_IMAGE_UNITS;
- ctx->Const.MaxVaryingFloats = MAX_VARYING_FLOATS;
+ ctx->Const.MaxVarying = MAX_VARYING;
#endif
/* sanity checks */
@@ -1103,6 +1113,11 @@ _mesa_init_constants( GLcontext *ctx )
ctx->Const.MaxTextureCoordUnits));
ASSERT(ctx->Const.FragmentProgram.MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS);
ASSERT(ctx->Const.VertexProgram.MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS);
+
+ ASSERT(MAX_NV_FRAGMENT_PROGRAM_TEMPS <= MAX_PROGRAM_TEMPS);
+ ASSERT(MAX_NV_VERTEX_PROGRAM_TEMPS <= MAX_PROGRAM_TEMPS);
+ ASSERT(MAX_NV_VERTEX_PROGRAM_INPUTS <= VERT_ATTRIB_MAX);
+ ASSERT(MAX_NV_VERTEX_PROGRAM_OUTPUTS <= VERT_RESULT_MAX);
}
@@ -1144,7 +1159,7 @@ check_context_limits(GLcontext *ctx)
* functions for the more complex data structures.
*/
static GLboolean
-init_attrib_groups( GLcontext *ctx )
+init_attrib_groups(GLcontext *ctx)
{
assert(ctx);
@@ -1180,7 +1195,7 @@ init_attrib_groups( GLcontext *ctx )
_mesa_init_query( ctx );
_mesa_init_rastpos( ctx );
_mesa_init_scissor( ctx );
- _mesa_init_shaderobjects (ctx);
+ _mesa_init_shader_state( ctx );
_mesa_init_stencil( ctx );
_mesa_init_transform( ctx );
_mesa_init_varray( ctx );
@@ -1267,11 +1282,11 @@ alloc_dispatch_table(void)
* \param driverContext pointer to driver-specific context data
*/
GLboolean
-_mesa_initialize_context( GLcontext *ctx,
- const GLvisual *visual,
- GLcontext *share_list,
- const struct dd_function_table *driverFunctions,
- void *driverContext )
+_mesa_initialize_context(GLcontext *ctx,
+ const GLvisual *visual,
+ GLcontext *share_list,
+ const struct dd_function_table *driverFunctions,
+ void *driverContext)
{
ASSERT(driverContext);
assert(driverFunctions->NewTextureObject);
@@ -1340,12 +1355,14 @@ _mesa_initialize_context( GLcontext *ctx,
ctx->TnlModule.SwapCount = 0;
#endif
- ctx->_MaintainTexEnvProgram = (_mesa_getenv("MESA_TEX_PROG") != NULL);
- ctx->_UseTexEnvProgram = ctx->_MaintainTexEnvProgram;
-
- ctx->_MaintainTnlProgram = (_mesa_getenv("MESA_TNL_PROG") != NULL);
- if (ctx->_MaintainTnlProgram)
- ctx->_MaintainTexEnvProgram = 1; /* this is required... */
+ ctx->VertexProgram._MaintainTnlProgram
+ = (_mesa_getenv("MESA_TNL_PROG") != NULL);
+ if (ctx->VertexProgram._MaintainTnlProgram)
+ /* this is required... */
+ ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
+ else
+ ctx->FragmentProgram._MaintainTexEnvProgram
+ = (_mesa_getenv("MESA_TEX_PROG") != NULL);
ctx->FirstTimeCurrent = GL_TRUE;
@@ -1368,11 +1385,10 @@ _mesa_initialize_context( GLcontext *ctx,
* \return pointer to a new __GLcontextRec or NULL if error.
*/
GLcontext *
-_mesa_create_context( const GLvisual *visual,
- GLcontext *share_list,
- const struct dd_function_table *driverFunctions,
- void *driverContext )
-
+_mesa_create_context(const GLvisual *visual,
+ GLcontext *share_list,
+ const struct dd_function_table *driverFunctions,
+ void *driverContext)
{
GLcontext *ctx;
@@ -1696,6 +1712,30 @@ _mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer,
}
}
+#if 0 /** XXX enable this someday */
+ if (oldCtx && oldCtx != newCtx) {
+ /* unbind old context's draw/read buffers */
+ if (oldCtx->DrawBuffer && oldCtx->DrawBuffer->Name == 0) {
+ oldCtx->DrawBuffer->RefCount--;
+ oldCtx->DrawBuffer = NULL;
+ }
+ if (oldCtx->ReadBuffer && oldCtx->ReadBuffer->Name == 0) {
+ oldCtx->ReadBuffer->RefCount--;
+ oldCtx->ReadBuffer = NULL;
+ }
+ if (oldCtx->WinSysDrawBuffer) {
+ ASSERT(oldCtx->WinSysDrawBuffer->Name == 0);
+ oldCtx->WinSysDrawBuffer->RefCount--;
+ oldCtx->WinSysDrawBuffer = NULL;
+ }
+ if (oldCtx->WinSysReadBuffer) {
+ ASSERT(oldCtx->WinSysReadBuffer->Name == 0);
+ oldCtx->WinSysReadBuffer->RefCount--;
+ oldCtx->WinSysReadBuffer = NULL;
+ }
+ }
+#endif
+
/* We used to call _glapi_check_multithread() here. Now do it in drivers */
_glapi_set_context((void *) newCtx);
ASSERT(_mesa_get_current_context() == newCtx);
@@ -1813,12 +1853,11 @@ _mesa_share_state(GLcontext *ctx, GLcontext *ctxToShare)
/**
- * Get current context for the calling thread.
- *
- * \return pointer to the current GL context.
+ * \return pointer to the current GL context for this thread.
*
* Calls _glapi_get_context(). This isn't the fastest way to get the current
- * context. If you need speed, see the #GET_CURRENT_CONTEXT macro in context.h.
+ * context. If you need speed, see the #GET_CURRENT_CONTEXT macro in
+ * context.h.
*/
GLcontext *
_mesa_get_current_context( void )
@@ -1826,6 +1865,7 @@ _mesa_get_current_context( void )
return (GLcontext *) _glapi_get_context();
}
+
/**
* Get context's current API dispatch table.
*
@@ -1865,7 +1905,7 @@ _mesa_get_dispatch(GLcontext *ctx)
* This is called via _mesa_error().
*/
void
-_mesa_record_error( GLcontext *ctx, GLenum error )
+_mesa_record_error(GLcontext *ctx, GLenum error)
{
if (!ctx)
return;
@@ -1876,10 +1916,11 @@ _mesa_record_error( GLcontext *ctx, GLenum error )
/* Call device driver's error handler, if any. This is used on the Mac. */
if (ctx->Driver.Error) {
- (*ctx->Driver.Error)( ctx );
+ ctx->Driver.Error(ctx);
}
}
+
/**
* Execute glFinish().
*
@@ -1887,15 +1928,16 @@ _mesa_record_error( GLcontext *ctx, GLenum error )
* dd_function_table::Finish driver callback, if not NULL.
*/
void GLAPIENTRY
-_mesa_Finish( void )
+_mesa_Finish(void)
{
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
if (ctx->Driver.Finish) {
- (*ctx->Driver.Finish)( ctx );
+ ctx->Driver.Finish(ctx);
}
}
+
/**
* Execute glFlush().
*
@@ -1903,12 +1945,12 @@ _mesa_Finish( void )
* dd_function_table::Flush driver callback, if not NULL.
*/
void GLAPIENTRY
-_mesa_Flush( void )
+_mesa_Flush(void)
{
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
if (ctx->Driver.Flush) {
- (*ctx->Driver.Flush)( ctx );
+ ctx->Driver.Flush(ctx);
}
}
diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h
index 1de2542bee2..88f33943b31 100644
--- a/src/mesa/main/dd.h
+++ b/src/mesa/main/dd.h
@@ -570,9 +570,9 @@ struct dd_function_table {
/** Notify driver that a program string has been specified. */
void (*ProgramStringNotify)(GLcontext *ctx, GLenum target,
struct gl_program *prog);
- /** Get value of a fragment program register during program execution. */
- void (*GetFragmentProgramRegister)(GLcontext *ctx, enum register_file file,
- GLuint index, GLfloat val[4]);
+ /** Get value of a program register during program execution. */
+ void (*GetProgramRegister)(GLcontext *ctx, enum register_file file,
+ GLuint index, GLfloat val[4]);
/** Query if program can be loaded onto hardware */
GLboolean (*IsProgramNative)(GLcontext *ctx, GLenum target,
@@ -821,6 +821,58 @@ struct dd_function_table {
void (*BindArrayObject)(GLcontext *ctx, struct gl_array_object *obj);
/*@}*/
+ /**
+ * \name GLSL-related functions (ARB extensions and OpenGL 2.x)
+ */
+ /*@{*/
+ void (*AttachShader)(GLcontext *ctx, GLuint program, GLuint shader);
+ void (*BindAttribLocation)(GLcontext *ctx, GLuint program, GLuint index,
+ const GLcharARB *name);
+ void (*CompileShader)(GLcontext *ctx, GLuint shader);
+ GLuint (*CreateShader)(GLcontext *ctx, GLenum type);
+ GLuint (*CreateProgram)(GLcontext *ctx);
+ void (*DeleteProgram2)(GLcontext *ctx, GLuint program);
+ void (*DeleteShader)(GLcontext *ctx, GLuint shader);
+ void (*DetachShader)(GLcontext *ctx, GLuint program, GLuint shader);
+ void (*GetActiveAttrib)(GLcontext *ctx, GLuint program, GLuint index,
+ GLsizei maxLength, GLsizei * length, GLint * size,
+ GLenum * type, GLcharARB * name);
+ void (*GetActiveUniform)(GLcontext *ctx, GLuint program, GLuint index,
+ GLsizei maxLength, GLsizei *length, GLint *size,
+ GLenum *type, GLcharARB *name);
+ void (*GetAttachedShaders)(GLcontext *ctx, GLuint program, GLsizei maxCount,
+ GLsizei *count, GLuint *obj);
+ GLint (*GetAttribLocation)(GLcontext *ctx, GLuint program,
+ const GLcharARB *name);
+ GLuint (*GetHandle)(GLcontext *ctx, GLenum pname);
+ void (*GetProgramiv)(GLcontext *ctx, GLuint program,
+ GLenum pname, GLint *params);
+ void (*GetProgramInfoLog)(GLcontext *ctx, GLuint program, GLsizei bufSize,
+ GLsizei *length, GLchar *infoLog);
+ void (*GetShaderiv)(GLcontext *ctx, GLuint shader,
+ GLenum pname, GLint *params);
+ void (*GetShaderInfoLog)(GLcontext *ctx, GLuint shader, GLsizei bufSize,
+ GLsizei *length, GLchar *infoLog);
+ void (*GetShaderSource)(GLcontext *ctx, GLuint shader, GLsizei maxLength,
+ GLsizei *length, GLcharARB *sourceOut);
+ void (*GetUniformfv)(GLcontext *ctx, GLuint program, GLint location,
+ GLfloat *params);
+ GLint (*GetUniformLocation)(GLcontext *ctx, GLuint program,
+ const GLcharARB *name);
+ GLboolean (*IsProgram)(GLcontext *ctx, GLuint name);
+ GLboolean (*IsShader)(GLcontext *ctx, GLuint name);
+ void (*LinkProgram)(GLcontext *ctx, GLuint program);
+ void (*ShaderSource)(GLcontext *ctx, GLuint shader, const GLchar *source);
+ void (*Uniform)(GLcontext *ctx, GLint location, GLsizei count,
+ const GLvoid *values, GLenum type);
+ void (*UniformMatrix)(GLcontext *ctx, GLint cols, GLint rows,
+ GLenum matrixType, GLint location, GLsizei count,
+ GLboolean transpose, const GLfloat *values);
+ void (*UseProgram)(GLcontext *ctx, GLuint program);
+ void (*ValidateProgram)(GLcontext *ctx, GLuint program);
+ /* XXX many more to come */
+ /*@}*/
+
/**
* \name Support for multiple T&L engines
diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c
index 9b2a42f7c1a..4cd07cb7b11 100644
--- a/src/mesa/main/get.c
+++ b/src/mesa/main/get.c
@@ -1878,7 +1878,7 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params )
break;
case GL_MAX_VARYING_FLOATS_ARB:
CHECK_EXT1(ARB_vertex_shader, "GetBooleanv");
- params[0] = INT_TO_BOOLEAN(ctx->Const.MaxVaryingFloats);
+ params[0] = INT_TO_BOOLEAN(ctx->Const.MaxVarying * 4);
break;
case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB:
CHECK_EXT1(ARB_vertex_shader, "GetBooleanv");
@@ -3705,7 +3705,7 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params )
break;
case GL_MAX_VARYING_FLOATS_ARB:
CHECK_EXT1(ARB_vertex_shader, "GetFloatv");
- params[0] = (GLfloat)(ctx->Const.MaxVaryingFloats);
+ params[0] = (GLfloat)(ctx->Const.MaxVarying * 4);
break;
case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB:
CHECK_EXT1(ARB_vertex_shader, "GetFloatv");
@@ -5532,7 +5532,7 @@ _mesa_GetIntegerv( GLenum pname, GLint *params )
break;
case GL_MAX_VARYING_FLOATS_ARB:
CHECK_EXT1(ARB_vertex_shader, "GetIntegerv");
- params[0] = ctx->Const.MaxVaryingFloats;
+ params[0] = ctx->Const.MaxVarying * 4;
break;
case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB:
CHECK_EXT1(ARB_vertex_shader, "GetIntegerv");
diff --git a/src/mesa/main/get_gen.py b/src/mesa/main/get_gen.py
index c18216d4a8f..2f07cc51926 100644
--- a/src/mesa/main/get_gen.py
+++ b/src/mesa/main/get_gen.py
@@ -989,7 +989,7 @@ StateVars = [
["ctx->Const.VertexProgram.MaxUniformComponents"], "",
["ARB_vertex_shader"] ),
( "GL_MAX_VARYING_FLOATS_ARB", GLint,
- ["ctx->Const.MaxVaryingFloats"], "", ["ARB_vertex_shader"] ),
+ ["ctx->Const.MaxVarying * 4"], "", ["ARB_vertex_shader"] ),
( "GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB", GLint,
["ctx->Const.MaxVertexTextureImageUnits"], "", ["ARB_vertex_shader"] ),
( "GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB", GLint,
diff --git a/src/mesa/main/getstring.c b/src/mesa/main/getstring.c
index f033ddc8954..e41e9899ef6 100644
--- a/src/mesa/main/getstring.c
+++ b/src/mesa/main/getstring.c
@@ -54,8 +54,8 @@ _mesa_GetString( GLenum name )
static const char *version_1_3 = "1.3 Mesa " MESA_VERSION_STRING;
static const char *version_1_4 = "1.4 Mesa " MESA_VERSION_STRING;
static const char *version_1_5 = "1.5 Mesa " MESA_VERSION_STRING;
- static const char *version_2_0 = "1.5 Mesa " MESA_VERSION_STRING;
- static const char *version_2_1 = "1.5 Mesa " MESA_VERSION_STRING;
+ static const char *version_2_0 = "2.0 Mesa " MESA_VERSION_STRING;
+ static const char *version_2_1 = "2.1 Mesa " MESA_VERSION_STRING;
#if FEATURE_ARB_shading_language_100
static const char *sl_version_110 = "1.10 Mesa " MESA_VERSION_STRING;
diff --git a/src/mesa/main/imports.c b/src/mesa/main/imports.c
index 890d1a4e32e..e2d44fa07c4 100644
--- a/src/mesa/main/imports.c
+++ b/src/mesa/main/imports.c
@@ -849,15 +849,23 @@ _mesa_strncmp( const char *s1, const char *s2, size_t n )
return strncmp(s1, s2, n);
}
-/** Implemented using _mesa_malloc() and _mesa_strcpy */
+/**
+ * Implemented using _mesa_malloc() and _mesa_strcpy.
+ * Note that NULL is handled accordingly.
+ */
char *
_mesa_strdup( const char *s )
{
- size_t l = _mesa_strlen(s);
- char *s2 = (char *) _mesa_malloc(l + 1);
- if (s2)
- _mesa_strcpy(s2, s);
- return s2;
+ if (s) {
+ size_t l = _mesa_strlen(s);
+ char *s2 = (char *) _mesa_malloc(l + 1);
+ if (s2)
+ _mesa_strcpy(s2, s);
+ return s2;
+ }
+ else {
+ return NULL;
+ }
}
/** Wrapper around atoi() */
diff --git a/src/mesa/main/matrix.c b/src/mesa/main/matrix.c
index b2aa83e1890..0f96f949096 100644
--- a/src/mesa/main/matrix.c
+++ b/src/mesa/main/matrix.c
@@ -1,8 +1,8 @@
/*
* Mesa 3-D graphics library
- * Version: 6.3
+ * Version: 6.5.3
*
- * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2007 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"),
@@ -230,7 +230,7 @@ void GLAPIENTRY
_mesa_PushMatrix( void )
{
GET_CURRENT_CONTEXT(ctx);
- struct matrix_stack *stack = ctx->CurrentStack;
+ struct gl_matrix_stack *stack = ctx->CurrentStack;
ASSERT_OUTSIDE_BEGIN_END(ctx);
if (MESA_VERBOSE&VERBOSE_API)
@@ -270,7 +270,7 @@ void GLAPIENTRY
_mesa_PopMatrix( void )
{
GET_CURRENT_CONTEXT(ctx);
- struct matrix_stack *stack = ctx->CurrentStack;
+ struct gl_matrix_stack *stack = ctx->CurrentStack;
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
if (MESA_VERBOSE&VERBOSE_API)
@@ -766,7 +766,7 @@ void _mesa_update_modelview_project( GLcontext *ctx, GLuint new_state )
* initialize it.
*/
static void
-init_matrix_stack( struct matrix_stack *stack,
+init_matrix_stack( struct gl_matrix_stack *stack,
GLuint maxDepth, GLuint dirtyFlag )
{
GLuint i;
@@ -792,7 +792,7 @@ init_matrix_stack( struct matrix_stack *stack,
* frees the array.
*/
static void
-free_matrix_stack( struct matrix_stack *stack )
+free_matrix_stack( struct gl_matrix_stack *stack )
{
GLuint i;
for (i = 0; i < stack->MaxDepth; i++) {
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 7caa1f8d7ff..b08e77ea880 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -7,9 +7,9 @@
/*
* Mesa 3-D graphics library
- * Version: 6.5
+ * Version: 6.5.3
*
- * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ * Copyright (C) 1999-2007 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"),
@@ -45,6 +45,12 @@
/**
+ * Special, internal token
+ */
+#define GL_SHADER_PROGRAM 0x9999
+
+
+/**
* Color channel data type.
*/
#if CHAN_BITS == 8
@@ -213,22 +219,6 @@ enum
#define VERT_BIT_GENERIC(g) (1 << (VERT_ATTRIB_GENERIC0 + (g)))
/*@}*/
-/**
- * GLSL allows shader writers to allocate vertex result attributes (varyings) in
- * single float component granularity. This is in contrast to vertex / fragment
- * programs, where result attributes (actually texcoords) were allocated
- * in 4-component vectors of floats granularity.
- * For performance reasons, it would be optimal to stick with this scheme on a scalar
- * processor. Varyings will likely be allocated as 3-component vectors, so statistically
- * we win 2 floats.
- * The constant VARYINGS_PER_VECTOR tells us how much of float components we pack into
- * one result vector. For scalar processor it would be 1, for vector processor - 4.
- *
- * NOTE: Currently we pack varyings into vertex attributes.
- */
-#define VARYINGS_PER_VECTOR 2
-#define VARYING_EMIT_STYLE EMIT_2F
-#define MAX_VARYING_VECTORS ((MAX_VARYING_FLOATS + VARYINGS_PER_VECTOR - 1) / VARYINGS_PER_VECTOR)
/**
* Indexes for vertex program result attributes
@@ -250,7 +240,8 @@ enum
#define VERT_RESULT_BFC0 13
#define VERT_RESULT_BFC1 14
#define VERT_RESULT_EDGE 15
-#define VERT_RESULT_MAX 16
+#define VERT_RESULT_VAR0 16 /**< shader varying */
+#define VERT_RESULT_MAX (VERT_RESULT_VAR0 + MAX_VARYING)
/*@}*/
@@ -271,7 +262,8 @@ enum
FRAG_ATTRIB_TEX5 = 9,
FRAG_ATTRIB_TEX6 = 10,
FRAG_ATTRIB_TEX7 = 11,
- FRAG_ATTRIB_MAX = 12
+ FRAG_ATTRIB_VAR0 = 12, /**< shader varying */
+ FRAG_ATTRIB_MAX = (FRAG_ATTRIB_VAR0 + MAX_VARYING)
};
/**
@@ -290,6 +282,10 @@ enum
#define FRAG_BIT_TEX5 (1 << FRAG_ATTRIB_TEX5)
#define FRAG_BIT_TEX6 (1 << FRAG_ATTRIB_TEX6)
#define FRAG_BIT_TEX7 (1 << FRAG_ATTRIB_TEX7)
+#define FRAG_BIT_VAR0 (1 << FRAG_ATTRIB_VAR0)
+
+#define FRAG_BIT_TEX(U) (FRAG_BIT_TEX0 << (U))
+#define FRAG_BIT_VAR(V) (FRAG_BIT_VAR0 << (V))
#define FRAG_BITS_TEX_ANY (FRAG_BIT_TEX0| \
FRAG_BIT_TEX1| \
@@ -305,12 +301,13 @@ enum
/**
* Fragment program results
*/
-/*@{*/
-#define FRAG_RESULT_COLR 0
-#define FRAG_RESULT_COLH 1
-#define FRAG_RESULT_DEPR 2
-#define FRAG_RESULT_MAX 3
-/*@}*/
+enum
+{
+ FRAG_RESULT_COLR = 0,
+ FRAG_RESULT_COLH = 1,
+ FRAG_RESULT_DEPR = 2,
+ FRAG_RESULT_MAX = 3
+};
/**
@@ -1807,22 +1804,31 @@ struct gl_evaluators
/**
* Names of the various vertex/fragment program register files, etc.
+ *
* NOTE: first four tokens must fit into 2 bits (see t_vb_arbprogram.c)
* All values should fit in a 4-bit field.
+ *
+ * NOTE: PROGRAM_ENV_PARAM, PROGRAM_STATE_VAR, PROGRAM_NAMED_PARAM,
+ * PROGRAM_CONSTANT, and PROGRAM_UNIFORM can all be considered to
+ * be "uniform" variables since they can only be set outside glBegin/End.
+ * They're also all stored in the same Parameters array.
*/
enum register_file
{
- PROGRAM_TEMPORARY = 0,
- PROGRAM_LOCAL_PARAM = 1,
- PROGRAM_ENV_PARAM = 2,
- PROGRAM_STATE_VAR = 3,
- PROGRAM_INPUT = 4,
- PROGRAM_OUTPUT = 5,
- PROGRAM_NAMED_PARAM = 6,
- PROGRAM_CONSTANT = 7,
- PROGRAM_WRITE_ONLY = 8,
- PROGRAM_ADDRESS = 9,
- PROGRAM_UNDEFINED = 10, /* invalid value */
+ PROGRAM_TEMPORARY = 0, /**< machine->Temporary[] */
+ PROGRAM_LOCAL_PARAM = 1, /**< gl_program->LocalParams[] */
+ PROGRAM_ENV_PARAM = 2, /**< gl_program->Parameters[] */
+ PROGRAM_STATE_VAR = 3, /**< gl_program->Parameters[] */
+ PROGRAM_INPUT = 4, /**< machine->Inputs[] */
+ PROGRAM_OUTPUT = 5, /**< machine->Outputs[] */
+ PROGRAM_NAMED_PARAM = 6, /**< gl_program->Parameters[] */
+ PROGRAM_CONSTANT = 7, /**< gl_program->Parameters[] */
+ PROGRAM_UNIFORM = 8, /**< gl_program->Parameters[] */
+ PROGRAM_VARYING = 9, /**< machine->Inputs[]/Outputs[] */
+ PROGRAM_WRITE_ONLY = 10, /**< A dummy, write-only register */
+ PROGRAM_ADDRESS = 11, /**< machine->AddressReg */
+ PROGRAM_SAMPLER = 12, /**< for shader samplers, compile-time only */
+ PROGRAM_UNDEFINED = 13, /**< Invalid value */
PROGRAM_FILE_MAX
};
@@ -1838,22 +1844,28 @@ struct gl_program_parameter_list;
struct gl_program
{
GLuint Id;
- GLubyte *String; /**< Null-terminated program text */
+ GLubyte *String; /**< Null-terminated program text */
GLint RefCount;
- GLenum Target;
- GLenum Format; /**< String encoding format */
+ GLenum Target; /**< GL_VERTEX/FRAGMENT_PROGRAM_ARB, GL_FRAGMENT_PROGRAM_NV */
+ GLenum Format; /**< String encoding format */
GLboolean Resident;
struct prog_instruction *Instructions;
- GLbitfield InputsRead; /* Bitmask of which input regs are read */
- GLbitfield OutputsWritten; /* Bitmask of which output regs are written to */
+ GLbitfield InputsRead; /**< Bitmask of which input regs are read */
+ GLbitfield OutputsWritten; /**< Bitmask of which output regs are written to */
+ GLbitfield TexturesUsed[MAX_TEXTURE_IMAGE_UNITS]; /**< TEXTURE_x_BIT bitmask */
/** Named parameters, constants, etc. from program text */
struct gl_program_parameter_list *Parameters;
/** Numbered local parameters */
GLfloat LocalParams[MAX_PROGRAM_LOCAL_PARAMS][4];
+ /** Vertex/fragment shader varying vars */
+ struct gl_program_parameter_list *Varying;
+ /** Vertex program user-defined attributes */
+ struct gl_program_parameter_list *Attributes;
+
/** Logical counts */
/*@{*/
GLuint NumInstructions;
@@ -1861,6 +1873,9 @@ struct gl_program
GLuint NumParameters;
GLuint NumAttributes;
GLuint NumAddressRegs;
+ GLuint NumAluInstructions;
+ GLuint NumTexInstructions;
+ GLuint NumTexIndirections;
/*@}*/
/** Native, actual h/w counts */
/*@{*/
@@ -1869,6 +1884,9 @@ struct gl_program
GLuint NumNativeParameters;
GLuint NumNativeAttributes;
GLuint NumNativeAddressRegs;
+ GLuint NumNativeAluInstructions;
+ GLuint NumNativeTexInstructions;
+ GLuint NumNativeTexIndirections;
/*@}*/
};
@@ -1887,13 +1905,6 @@ struct gl_vertex_program
struct gl_fragment_program
{
struct gl_program Base; /**< base class */
- GLbitfield TexturesUsed[MAX_TEXTURE_IMAGE_UNITS]; /**< TEXTURE_x_BIT bitmask */
- GLuint NumAluInstructions; /**< GL_ARB_fragment_program */
- GLuint NumTexInstructions;
- GLuint NumTexIndirections;
- GLuint NumNativeAluInstructions; /**< GL_ARB_fragment_program */
- GLuint NumNativeTexInstructions;
- GLuint NumNativeTexIndirections;
GLenum FogOption;
GLboolean UsesKill;
};
@@ -1918,16 +1929,24 @@ struct gl_vertex_program_state
GLboolean _Enabled; /**< Enabled and valid program? */
GLboolean PointSizeEnabled; /**< GL_VERTEX_PROGRAM_POINT_SIZE_ARB/NV */
GLboolean TwoSideEnabled; /**< GL_VERTEX_PROGRAM_TWO_SIDE_ARB/NV */
- struct gl_vertex_program *Current; /**< ptr to currently bound program */
- const struct gl_vertex_program *_Current; /**< ptr to currently bound
- program, including internal
- (t_vp_build.c) programs */
+ struct gl_vertex_program *Current; /**< user-bound vertex program */
- GLfloat Parameters[MAX_NV_VERTEX_PROGRAM_PARAMS][4]; /**< Env params */
+ /** Currently enabled and valid program (including internal programs
+ * and compiled shader programs).
+ */
+ struct gl_vertex_program *_Current;
+
+ GLfloat Parameters[MAX_PROGRAM_ENV_PARAMS][4]; /**< Env params */
/* For GL_NV_vertex_program only: */
- GLenum TrackMatrix[MAX_NV_VERTEX_PROGRAM_PARAMS / 4];
- GLenum TrackMatrixTransform[MAX_NV_VERTEX_PROGRAM_PARAMS / 4];
+ GLenum TrackMatrix[MAX_PROGRAM_ENV_PARAMS / 4];
+ GLenum TrackMatrixTransform[MAX_PROGRAM_ENV_PARAMS / 4];
+
+ /** Should fixed-function T&L be implemented with a vertex prog? */
+ GLboolean _MaintainTnlProgram;
+
+ /** Program to emulate fixed-function T&L (see above) */
+ struct gl_vertex_program *_TnlProgram;
#if FEATURE_MESA_program_debug
GLprogramcallbackMESA Callback;
@@ -1945,11 +1964,20 @@ struct gl_fragment_program_state
{
GLboolean Enabled; /**< User-set fragment program enable flag */
GLboolean _Enabled; /**< Fragment program enabled and valid? */
- GLboolean _Active; /**< Is a user program or internal program active? */
- struct gl_fragment_program *Current; /**< User-bound program */
- const struct gl_fragment_program *_Current; /**< currently active program
- (including internal programs) */
- GLfloat Parameters[MAX_NV_FRAGMENT_PROGRAM_PARAMS][4]; /**< Env params */
+ struct gl_fragment_program *Current; /**< User-bound fragment program */
+
+ /** Currently enabled and valid program (including internal programs
+ * and compiled shader programs).
+ */
+ struct gl_fragment_program *_Current;
+
+ GLfloat Parameters[MAX_PROGRAM_ENV_PARAMS][4]; /**< Env params */
+
+ /** Should fixed-function texturing be implemented with a fragment prog? */
+ GLboolean _MaintainTexEnvProgram;
+
+ /** Program to emulate fixed-function texture env/combine (see above) */
+ struct gl_fragment_program *_TexEnvProgram;
#if FEATURE_MESA_program_debug
GLprogramcallbackMESA Callback;
@@ -2026,14 +2054,58 @@ struct gl_query_state
};
+
/**
- * Context state for vertex/fragment shaders.
+ * A GLSL shader object.
*/
-struct gl_shader_objects_state
+struct gl_shader
{
- struct gl2_program_intf **CurrentProgram;
- GLboolean _VertexShaderPresent;
- GLboolean _FragmentShaderPresent;
+ GLenum Type; /**< GL_FRAGMENT_SHADER || GL_VERTEX_SHADER (first field!) */
+ GLuint Name; /**< AKA the handle */
+ GLint RefCount; /**< Reference count */
+ GLboolean DeletePending;
+
+ const GLchar *Source; /**< Source code string */
+ GLboolean CompileStatus;
+ GLuint NumPrograms; /**< size of Programs[] array */
+ struct gl_program **Programs; /**< Post-compile assembly code */
+ GLchar *InfoLog;
+};
+
+
+/**
+ * A GLSL program object. Basically a linked collection of "shaders".
+ */
+struct gl_shader_program
+{
+ GLenum Type; /**< Always GL_SHADER_PROGRAM (internal token) */
+ GLuint Name; /**< aka handle or ID */
+ GLint RefCount; /**< Reference count */
+ GLboolean DeletePending;
+
+ GLuint NumShaders; /**< number of attached shaders */
+ struct gl_shader **Shaders; /**< List of attached the shaders */
+
+ /* post-link info: */
+ struct gl_vertex_program *VertexProgram; /**< Linked vertex program */
+ struct gl_fragment_program *FragmentProgram; /**< Linked fragment prog */
+ struct gl_program_parameter_list *Uniforms; /**< Plus constants, etc */
+ struct gl_program_parameter_list *Varying;
+ struct gl_program_parameter_list *Attributes; /**< Vertex attributes */
+ GLboolean LinkStatus; /**< GL_LINK_STATUS */
+ GLboolean Validated;
+ GLchar *InfoLog;
+};
+
+
+/**
+ * Context state for GLSL vertex/fragment shaders.
+ */
+struct gl_shader_state
+{
+ struct gl_shader_program *CurrentProgram; /**< The user-bound program */
+ GLboolean EmitHighLevelInstructions; /**< Driver-selectable */
+ GLboolean EmitComments; /**< Driver-selectable */
};
@@ -2094,7 +2166,8 @@ struct gl_shared_state
#endif
#if FEATURE_ARB_shader_objects
- struct _mesa_HashTable *GL2Objects;
+ /** Table of both gl_shader and gl_shader_program objects */
+ struct _mesa_HashTable *ShaderObjects;
#endif
#if FEATURE_EXT_framebuffer_object
@@ -2374,7 +2447,7 @@ struct gl_constants
GLuint MaxRenderbufferSize;
/* GL_ARB_vertex_shader */
GLuint MaxVertexTextureImageUnits;
- GLuint MaxVaryingFloats;
+ GLuint MaxVarying;
};
@@ -2512,7 +2585,7 @@ struct gl_extensions
/**
* A stack of matrices (projection, modelview, color, texture, etc).
*/
-struct matrix_stack
+struct gl_matrix_stack
{
GLmatrix *Top; /**< points into Stack */
GLmatrix *Stack; /**< array [MaxDepth] of GLmatrix */
@@ -2744,7 +2817,7 @@ struct mesa_display_list
/**
* State used during display list compilation and execution.
*/
-struct mesa_list_state
+struct gl_dlist_state
{
struct mesa_display_list *CallStack[MAX_LIST_NESTING];
GLuint CallDepth; /**< Current recursion calling depth */
@@ -2816,26 +2889,25 @@ struct __GLcontextRec
struct dd_function_table Driver;
void *DriverCtx; /**< Points to device driver context/state */
- void *DriverMgrCtx; /**< Points to device driver manager (optional)*/
/** Core/Driver constants */
struct gl_constants Const;
/** \name The various 4x4 matrix stacks */
/*@{*/
- struct matrix_stack ModelviewMatrixStack;
- struct matrix_stack ProjectionMatrixStack;
- struct matrix_stack ColorMatrixStack;
- struct matrix_stack TextureMatrixStack[MAX_TEXTURE_COORD_UNITS];
- struct matrix_stack ProgramMatrixStack[MAX_PROGRAM_MATRICES];
- struct matrix_stack *CurrentStack; /**< Points to one of the above stacks */
+ struct gl_matrix_stack ModelviewMatrixStack;
+ struct gl_matrix_stack ProjectionMatrixStack;
+ struct gl_matrix_stack ColorMatrixStack;
+ struct gl_matrix_stack TextureMatrixStack[MAX_TEXTURE_COORD_UNITS];
+ struct gl_matrix_stack ProgramMatrixStack[MAX_PROGRAM_MATRICES];
+ struct gl_matrix_stack *CurrentStack; /**< Points to one of the above stacks */
/*@}*/
/** Combined modelview and projection matrix */
GLmatrix _ModelProjectMatrix;
/** \name Display lists */
- struct mesa_list_state ListState;
+ struct gl_dlist_state ListState;
GLboolean ExecuteFlag; /**< Execute GL commands? */
GLboolean CompileFlag; /**< Compile GL commands into display list? */
@@ -2915,16 +2987,9 @@ struct __GLcontextRec
struct gl_fragment_program_state FragmentProgram; /**< GL_ARB/NV_vertex_program */
struct gl_ati_fragment_shader_state ATIFragmentShader; /**< GL_ATI_fragment_shader */
- struct gl_fragment_program *_TexEnvProgram; /**< Texture state as fragment program */
- struct gl_vertex_program *_TnlProgram; /**< Fixed func TNL state as vertex program */
-
- GLboolean _MaintainTnlProgram;
- GLboolean _MaintainTexEnvProgram;
- GLboolean _UseTexEnvProgram;
-
struct gl_query_state Query; /**< GL_ARB_occlusion_query */
- struct gl_shader_objects_state ShaderObjects; /* GL_ARB_shader_objects */
+ struct gl_shader_state Shader; /**< GLSL shader object state */
/*@}*/
#if FEATURE_EXT_framebuffer_object
diff --git a/src/mesa/main/shaders.c b/src/mesa/main/shaders.c
new file mode 100644
index 00000000000..5bd4a3f5ff5
--- /dev/null
+++ b/src/mesa/main/shaders.c
@@ -0,0 +1,669 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5.3
+ *
+ * Copyright (C) 2004-2007 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.
+ */
+
+
+#include "glheader.h"
+#include "context.h"
+#include "shaders.h"
+
+
+/**
+ * These are basically just wrappers/adaptors for calling the
+ * ctx->Driver.foobar() GLSL-related functions.
+ *
+ * Things are biased toward the OpenGL 2.0 functions rather than the
+ * ARB extensions (i.e. the ARB functions are layered on the 2.0 functions).
+ *
+ * The general idea here is to allow enough modularity such that a
+ * completely different GLSL implemenation can be plugged in and co-exist
+ * with Mesa's native GLSL code.
+ */
+
+
+
+void GLAPIENTRY
+_mesa_AttachObjectARB(GLhandleARB program, GLhandleARB shader)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ctx->Driver.AttachShader(ctx, program, shader);
+}
+
+
+void GLAPIENTRY
+_mesa_AttachShader(GLuint program, GLuint shader)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ctx->Driver.AttachShader(ctx, program, shader);
+}
+
+
+void GLAPIENTRY
+_mesa_BindAttribLocationARB(GLhandleARB program, GLuint index,
+ const GLcharARB *name)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ctx->Driver.BindAttribLocation(ctx, program, index, name);
+}
+
+
+void GLAPIENTRY
+_mesa_CompileShaderARB(GLhandleARB shaderObj)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ctx->Driver.CompileShader(ctx, shaderObj);
+}
+
+
+GLuint GLAPIENTRY
+_mesa_CreateShader(GLenum type)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ return ctx->Driver.CreateShader(ctx, type);
+}
+
+
+GLhandleARB APIENTRY
+_mesa_CreateShaderObjectARB(GLenum type)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ return ctx->Driver.CreateShader(ctx, type);
+}
+
+
+GLuint GLAPIENTRY
+_mesa_CreateProgram(void)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ return ctx->Driver.CreateProgram(ctx);
+}
+
+
+GLhandleARB APIENTRY
+_mesa_CreateProgramObjectARB(void)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ return ctx->Driver.CreateProgram(ctx);
+}
+
+
+void GLAPIENTRY
+_mesa_DeleteObjectARB(GLhandleARB obj)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ if (ctx->Driver.IsProgram(ctx, obj)) {
+ ctx->Driver.DeleteProgram2(ctx, obj);
+ }
+ else if (ctx->Driver.IsShader(ctx, obj)) {
+ ctx->Driver.DeleteShader(ctx, obj);
+ }
+ else {
+ /* error? */
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_DeleteProgram(GLuint name)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ctx->Driver.DeleteProgram2(ctx, name);
+}
+
+
+void GLAPIENTRY
+_mesa_DeleteShader(GLuint name)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ctx->Driver.DeleteShader(ctx, name);
+}
+
+
+void GLAPIENTRY
+_mesa_DetachObjectARB(GLhandleARB program, GLhandleARB shader)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ctx->Driver.DetachShader(ctx, program, shader);
+}
+
+
+void GLAPIENTRY
+_mesa_DetachShader(GLuint program, GLuint shader)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ctx->Driver.DetachShader(ctx, program, shader);
+}
+
+
+void GLAPIENTRY
+_mesa_GetActiveAttribARB(GLhandleARB program, GLuint index,
+ GLsizei maxLength, GLsizei * length, GLint * size,
+ GLenum * type, GLcharARB * name)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ctx->Driver.GetActiveAttrib(ctx, program, index, maxLength, length, size,
+ type, name);
+}
+
+
+void GLAPIENTRY
+_mesa_GetActiveUniformARB(GLhandleARB program, GLuint index,
+ GLsizei maxLength, GLsizei * length, GLint * size,
+ GLenum * type, GLcharARB * name)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ctx->Driver.GetActiveUniform(ctx, program, index, maxLength, length, size,
+ type, name);
+}
+
+
+void GLAPIENTRY
+_mesa_GetAttachedObjectsARB(GLhandleARB container, GLsizei maxCount,
+ GLsizei * count, GLhandleARB * obj)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ctx->Driver.GetAttachedShaders(ctx, container, maxCount, count, obj);
+}
+
+
+void GLAPIENTRY
+_mesa_GetAttachedShaders(GLuint program, GLsizei maxCount,
+ GLsizei *count, GLuint *obj)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ctx->Driver.GetAttachedShaders(ctx, program, maxCount, count, obj);
+}
+
+
+GLint GLAPIENTRY
+_mesa_GetAttribLocationARB(GLhandleARB program, const GLcharARB * name)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ return ctx->Driver.GetAttribLocation(ctx, program, name);
+}
+
+
+void GLAPIENTRY
+_mesa_GetInfoLogARB(GLhandleARB object, GLsizei maxLength, GLsizei * length,
+ GLcharARB * infoLog)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ /* Implement in terms of GetProgramInfoLog, GetShaderInfoLog */
+ if (ctx->Driver.IsProgram(ctx, object)) {
+ ctx->Driver.GetProgramInfoLog(ctx, object, maxLength, length, infoLog);
+ }
+ else if (ctx->Driver.IsShader(ctx, object)) {
+ ctx->Driver.GetShaderInfoLog(ctx, object, maxLength, length, infoLog);
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetInfoLogARB");
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_GetObjectParameterivARB(GLhandleARB object, GLenum pname, GLint *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ /* Implement in terms of GetProgramiv, GetShaderiv */
+ if (ctx->Driver.IsProgram(ctx, object)) {
+ ctx->Driver.GetProgramiv(ctx, object, pname, params);
+ }
+ else if (ctx->Driver.IsShader(ctx, object)) {
+ ctx->Driver.GetShaderiv(ctx, object, pname, params);
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetObjectParameterivARB");
+ }
+}
+
+
+void GLAPIENTRY
+_mesa_GetObjectParameterfvARB(GLhandleARB object, GLenum pname,
+ GLfloat *params)
+{
+ GLint iparams[1]; /* XXX is one element enough? */
+ _mesa_GetObjectParameterivARB(object, pname, iparams);
+ params[0] = (GLfloat) iparams[0];
+}
+
+
+void GLAPIENTRY
+_mesa_GetProgramiv(GLuint program, GLenum pname, GLint *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ctx->Driver.GetProgramiv(ctx, program, pname, params);
+}
+
+
+void GLAPIENTRY
+_mesa_GetShaderiv(GLuint shader, GLenum pname, GLint *params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ctx->Driver.GetShaderiv(ctx, shader, pname, params);
+}
+
+
+void GLAPIENTRY
+_mesa_GetProgramInfoLog(GLuint program, GLsizei bufSize,
+ GLsizei *length, GLchar *infoLog)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ctx->Driver.GetProgramInfoLog(ctx, program, bufSize, length, infoLog);
+}
+
+
+void GLAPIENTRY
+_mesa_GetShaderInfoLog(GLuint shader, GLsizei bufSize,
+ GLsizei *length, GLchar *infoLog)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ctx->Driver.GetShaderInfoLog(ctx, shader, bufSize, length, infoLog);
+}
+
+
+void GLAPIENTRY
+_mesa_GetShaderSourceARB(GLhandleARB shader, GLsizei maxLength,
+ GLsizei *length, GLcharARB *sourceOut)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ctx->Driver.GetShaderSource(ctx, shader, maxLength, length, sourceOut);
+}
+
+
+void GLAPIENTRY
+_mesa_GetUniformfvARB(GLhandleARB program, GLint location, GLfloat * params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ctx->Driver.GetUniformfv(ctx, program, location, params);
+}
+
+
+void GLAPIENTRY
+_mesa_GetUniformivARB(GLhandleARB program, GLint location, GLint * params)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLfloat fparams[16]; /* XXX is 16 enough? */
+ GLuint i;
+ ctx->Driver.GetUniformfv(ctx, program, location, fparams);
+ for (i = 0; i < 16; i++)
+ params[i] = (GLint) fparams[i]; /* XXX correct? */
+}
+
+
+
+#if 0
+GLint APIENTRY
+_mesa_GetUniformLocation(GLuint program, const GLcharARB *name)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ return ctx->Driver.GetUniformLocation(ctx, program, name);
+}
+#endif
+
+
+GLhandleARB GLAPIENTRY
+_mesa_GetHandleARB(GLenum pname)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ return ctx->Driver.GetHandle(ctx, pname);
+}
+
+
+GLint APIENTRY
+_mesa_GetUniformLocationARB(GLhandleARB programObj, const GLcharARB *name)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ return ctx->Driver.GetUniformLocation(ctx, programObj, name);
+}
+
+
+GLboolean GLAPIENTRY
+_mesa_IsProgram(GLuint name)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ return ctx->Driver.IsProgram(ctx, name);
+}
+
+
+GLboolean GLAPIENTRY
+_mesa_IsShader(GLuint name)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ return ctx->Driver.IsShader(ctx, name);
+}
+
+
+void GLAPIENTRY
+_mesa_LinkProgramARB(GLhandleARB programObj)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ctx->Driver.LinkProgram(ctx, programObj);
+}
+
+
+/**
+ * Called via glShaderSource() and glShaderSourceARB() API functions.
+ * Basically, concatenate the source code strings into one long string
+ * and pass it to ctx->Driver.ShaderSource().
+ */
+void GLAPIENTRY
+_mesa_ShaderSourceARB(GLhandleARB shaderObj, GLsizei count,
+ const GLcharARB ** string, const GLint * length)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLint *offsets;
+ GLsizei i;
+ GLcharARB *source;
+
+ if (string == NULL) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glShaderSourceARB");
+ return;
+ }
+
+ /*
+ * This array holds offsets of where the appropriate string ends, thus the
+ * last element will be set to the total length of the source code.
+ */
+ offsets = (GLint *) _mesa_malloc(count * sizeof(GLint));
+ if (offsets == NULL) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB");
+ return;
+ }
+
+ for (i = 0; i < count; i++) {
+ if (string[i] == NULL) {
+ _mesa_free((GLvoid *) offsets);
+ _mesa_error(ctx, GL_INVALID_VALUE, "glShaderSourceARB(null string)");
+ return;
+ }
+ if (length == NULL || length[i] < 0)
+ offsets[i] = _mesa_strlen(string[i]);
+ else
+ offsets[i] = length[i];
+ /* accumulate string lengths */
+ if (i > 0)
+ offsets[i] += offsets[i - 1];
+ }
+
+ source = (GLcharARB *) _mesa_malloc((offsets[count - 1] + 1) *
+ sizeof(GLcharARB));
+ if (source == NULL) {
+ _mesa_free((GLvoid *) offsets);
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB");
+ return;
+ }
+
+ for (i = 0; i < count; i++) {
+ GLint start = (i > 0) ? offsets[i - 1] : 0;
+ _mesa_memcpy(source + start, string[i],
+ (offsets[i] - start) * sizeof(GLcharARB));
+ }
+ source[offsets[count - 1]] = '\0';
+
+ ctx->Driver.ShaderSource(ctx, shaderObj, source);
+
+ _mesa_free(offsets);
+}
+
+
+void GLAPIENTRY
+_mesa_Uniform1fARB(GLint location, GLfloat v0)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ctx->Driver.Uniform(ctx, location, 1, &v0, GL_FLOAT);
+}
+
+void GLAPIENTRY
+_mesa_Uniform2fARB(GLint location, GLfloat v0, GLfloat v1)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLfloat v[2];
+ v[0] = v0;
+ v[1] = v1;
+ ctx->Driver.Uniform(ctx, location, 1, v, GL_FLOAT_VEC2);
+}
+
+void GLAPIENTRY
+_mesa_Uniform3fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLfloat v[3];
+ v[0] = v0;
+ v[1] = v1;
+ v[2] = v2;
+ ctx->Driver.Uniform(ctx, location, 1, v, GL_FLOAT_VEC3);
+}
+
+void GLAPIENTRY
+_mesa_Uniform4fARB(GLint location, GLfloat v0, GLfloat v1, GLfloat v2,
+ GLfloat v3)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLfloat v[4];
+ v[0] = v0;
+ v[1] = v1;
+ v[2] = v2;
+ v[3] = v3;
+ ctx->Driver.Uniform(ctx, location, 1, v, GL_FLOAT_VEC4);
+}
+
+void GLAPIENTRY
+_mesa_Uniform1iARB(GLint location, GLint v0)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ctx->Driver.Uniform(ctx, location, 1, &v0, GL_INT);
+}
+
+void GLAPIENTRY
+_mesa_Uniform2iARB(GLint location, GLint v0, GLint v1)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLint v[2];
+ v[0] = v0;
+ v[1] = v1;
+ ctx->Driver.Uniform(ctx, location, 1, v, GL_INT_VEC2);
+}
+
+void GLAPIENTRY
+_mesa_Uniform3iARB(GLint location, GLint v0, GLint v1, GLint v2)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLint v[3];
+ v[0] = v0;
+ v[1] = v1;
+ v[2] = v2;
+ ctx->Driver.Uniform(ctx, location, 1, v, GL_INT_VEC3);
+}
+
+void GLAPIENTRY
+_mesa_Uniform4iARB(GLint location, GLint v0, GLint v1, GLint v2, GLint v3)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLint v[4];
+ v[0] = v0;
+ v[1] = v1;
+ v[2] = v2;
+ v[3] = v3;
+ ctx->Driver.Uniform(ctx, location, 1, v, GL_INT_VEC4);
+}
+
+void GLAPIENTRY
+_mesa_Uniform1fvARB(GLint location, GLsizei count, const GLfloat * value)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ctx->Driver.Uniform(ctx, location, count, value, GL_FLOAT);
+}
+
+void GLAPIENTRY
+_mesa_Uniform2fvARB(GLint location, GLsizei count, const GLfloat * value)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ctx->Driver.Uniform(ctx, location, count, value, GL_FLOAT_VEC2);
+}
+
+void GLAPIENTRY
+_mesa_Uniform3fvARB(GLint location, GLsizei count, const GLfloat * value)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ctx->Driver.Uniform(ctx, location, count, value, GL_FLOAT_VEC3);
+}
+
+void GLAPIENTRY
+_mesa_Uniform4fvARB(GLint location, GLsizei count, const GLfloat * value)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ctx->Driver.Uniform(ctx, location, count, value, GL_FLOAT_VEC4);
+}
+
+void GLAPIENTRY
+_mesa_Uniform1ivARB(GLint location, GLsizei count, const GLint * value)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ctx->Driver.Uniform(ctx, location, count, value, GL_INT);
+}
+
+void GLAPIENTRY
+_mesa_Uniform2ivARB(GLint location, GLsizei count, const GLint * value)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ctx->Driver.Uniform(ctx, location, count, value, GL_INT_VEC2);
+}
+
+void GLAPIENTRY
+_mesa_Uniform3ivARB(GLint location, GLsizei count, const GLint * value)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ctx->Driver.Uniform(ctx, location, count, value, GL_INT_VEC3);
+}
+
+void GLAPIENTRY
+_mesa_Uniform4ivARB(GLint location, GLsizei count, const GLint * value)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ctx->Driver.Uniform(ctx, location, count, value, GL_INT_VEC4);
+}
+
+
+void GLAPIENTRY
+_mesa_UniformMatrix2fvARB(GLint location, GLsizei count, GLboolean transpose,
+ const GLfloat * value)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ctx->Driver.UniformMatrix(ctx, 2, 2, GL_FLOAT_MAT2,
+ location, count, transpose, value);
+}
+
+void GLAPIENTRY
+_mesa_UniformMatrix3fvARB(GLint location, GLsizei count, GLboolean transpose,
+ const GLfloat * value)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ctx->Driver.UniformMatrix(ctx, 3, 3, GL_FLOAT_MAT3,
+ location, count, transpose, value);
+}
+
+void GLAPIENTRY
+_mesa_UniformMatrix4fvARB(GLint location, GLsizei count, GLboolean transpose,
+ const GLfloat * value)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ctx->Driver.UniformMatrix(ctx, 4, 4, GL_FLOAT_MAT4,
+ location, count, transpose, value);
+}
+
+
+/**
+ * Non-square UniformMatrix are OpenGL 2.1
+ */
+void GLAPIENTRY
+_mesa_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose,
+ const GLfloat *value)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ctx->Driver.UniformMatrix(ctx, 2, 3, GL_FLOAT_MAT2x3,
+ location, count, transpose, value);
+}
+
+void GLAPIENTRY
+_mesa_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose,
+ const GLfloat *value)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ctx->Driver.UniformMatrix(ctx, 3, 2, GL_FLOAT_MAT3x2,
+ location, count, transpose, value);
+}
+
+void GLAPIENTRY
+_mesa_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose,
+ const GLfloat *value)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ctx->Driver.UniformMatrix(ctx, 2, 4, GL_FLOAT_MAT2x4,
+ location, count, transpose, value);
+}
+
+void GLAPIENTRY
+_mesa_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose,
+ const GLfloat *value)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ctx->Driver.UniformMatrix(ctx, 4, 2, GL_FLOAT_MAT4x2,
+ location, count, transpose, value);
+}
+
+void GLAPIENTRY
+_mesa_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose,
+ const GLfloat *value)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ctx->Driver.UniformMatrix(ctx, 3, 4, GL_FLOAT_MAT3x4,
+ location, count, transpose, value);
+}
+
+void GLAPIENTRY
+_mesa_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose,
+ const GLfloat *value)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ctx->Driver.UniformMatrix(ctx, 4, 3, GL_FLOAT_MAT4x3,
+ location, count, transpose, value);
+}
+
+
+void GLAPIENTRY
+_mesa_UseProgramObjectARB(GLhandleARB program)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ FLUSH_VERTICES(ctx, _NEW_PROGRAM);
+ ctx->Driver.UseProgram(ctx, program);
+}
+
+
+void GLAPIENTRY
+_mesa_ValidateProgramARB(GLhandleARB program)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ctx->Driver.ValidateProgram(ctx, program);
+}
+
diff --git a/src/mesa/main/shaders.h b/src/mesa/main/shaders.h
new file mode 100644
index 00000000000..17339ccf623
--- /dev/null
+++ b/src/mesa/main/shaders.h
@@ -0,0 +1,236 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5.3
+ *
+ * Copyright (C) 2004-2007 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.
+ */
+
+
+#ifndef SHADERS_H
+#define SHADERS_H
+
+
+#include "glheader.h"
+#include "mtypes.h"
+
+
+extern void GLAPIENTRY
+_mesa_DeleteObjectARB(GLhandleARB obj);
+
+extern GLhandleARB GLAPIENTRY
+_mesa_GetHandleARB(GLenum pname);
+
+extern void GLAPIENTRY
+_mesa_DetachObjectARB (GLhandleARB, GLhandleARB);
+
+extern GLhandleARB GLAPIENTRY
+_mesa_CreateShaderObjectARB (GLenum);
+
+extern void GLAPIENTRY
+_mesa_ShaderSourceARB (GLhandleARB, GLsizei, const GLcharARB* *, const GLint *);
+
+extern void GLAPIENTRY
+_mesa_CompileShaderARB (GLhandleARB);
+
+extern GLhandleARB GLAPIENTRY
+_mesa_CreateProgramObjectARB (void);
+
+extern void GLAPIENTRY
+_mesa_AttachObjectARB (GLhandleARB, GLhandleARB);
+
+extern void GLAPIENTRY
+_mesa_LinkProgramARB (GLhandleARB);
+
+extern void GLAPIENTRY
+_mesa_UseProgramObjectARB (GLhandleARB);
+
+extern void GLAPIENTRY
+_mesa_ValidateProgramARB (GLhandleARB);
+
+extern void GLAPIENTRY
+_mesa_Uniform1fARB (GLint, GLfloat);
+
+extern void GLAPIENTRY
+_mesa_Uniform2fARB (GLint, GLfloat, GLfloat);
+
+extern void GLAPIENTRY
+_mesa_Uniform3fARB (GLint, GLfloat, GLfloat, GLfloat);
+
+extern void GLAPIENTRY
+_mesa_Uniform4fARB (GLint, GLfloat, GLfloat, GLfloat, GLfloat);
+
+extern void GLAPIENTRY
+_mesa_Uniform1iARB (GLint, GLint);
+
+extern void GLAPIENTRY
+_mesa_Uniform2iARB (GLint, GLint, GLint);
+
+extern void GLAPIENTRY
+_mesa_Uniform3iARB (GLint, GLint, GLint, GLint);
+
+extern void GLAPIENTRY
+_mesa_Uniform4iARB (GLint, GLint, GLint, GLint, GLint);
+
+extern void GLAPIENTRY
+_mesa_Uniform1fvARB (GLint, GLsizei, const GLfloat *);
+
+extern void GLAPIENTRY
+_mesa_Uniform2fvARB (GLint, GLsizei, const GLfloat *);
+
+extern void GLAPIENTRY
+_mesa_Uniform3fvARB (GLint, GLsizei, const GLfloat *);
+
+extern void GLAPIENTRY
+_mesa_Uniform4fvARB (GLint, GLsizei, const GLfloat *);
+
+extern void GLAPIENTRY
+_mesa_Uniform1ivARB (GLint, GLsizei, const GLint *);
+
+extern void GLAPIENTRY
+_mesa_Uniform2ivARB (GLint, GLsizei, const GLint *);
+
+extern void GLAPIENTRY
+_mesa_Uniform3ivARB (GLint, GLsizei, const GLint *);
+
+extern void GLAPIENTRY
+_mesa_Uniform4ivARB (GLint, GLsizei, const GLint *);
+
+extern void GLAPIENTRY
+_mesa_UniformMatrix2fvARB (GLint, GLsizei, GLboolean, const GLfloat *);
+
+extern void GLAPIENTRY
+_mesa_UniformMatrix3fvARB (GLint, GLsizei, GLboolean, const GLfloat *);
+
+extern void GLAPIENTRY
+_mesa_UniformMatrix4fvARB (GLint, GLsizei, GLboolean, const GLfloat *);
+
+extern void GLAPIENTRY
+_mesa_GetObjectParameterfvARB (GLhandleARB, GLenum, GLfloat *);
+
+extern void GLAPIENTRY
+_mesa_GetObjectParameterivARB (GLhandleARB, GLenum, GLint *);
+
+extern void GLAPIENTRY
+_mesa_GetInfoLogARB (GLhandleARB, GLsizei, GLsizei *, GLcharARB *);
+
+extern void GLAPIENTRY
+_mesa_GetAttachedObjectsARB (GLhandleARB, GLsizei, GLsizei *, GLhandleARB *);
+
+extern GLint GLAPIENTRY
+_mesa_GetUniformLocationARB (GLhandleARB, const GLcharARB *);
+
+extern void GLAPIENTRY
+_mesa_GetActiveUniformARB (GLhandleARB, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLcharARB *);
+
+extern void GLAPIENTRY
+_mesa_GetUniformfvARB (GLhandleARB, GLint, GLfloat *);
+
+extern void GLAPIENTRY
+_mesa_GetUniformivARB (GLhandleARB, GLint, GLint *);
+
+extern void GLAPIENTRY
+_mesa_GetShaderSourceARB (GLhandleARB, GLsizei, GLsizei *, GLcharARB *);
+
+#if FEATURE_ARB_vertex_shader
+
+extern void GLAPIENTRY
+_mesa_BindAttribLocationARB (GLhandleARB, GLuint, const GLcharARB *);
+
+extern void GLAPIENTRY
+_mesa_GetActiveAttribARB (GLhandleARB, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLcharARB *);
+
+extern GLint GLAPIENTRY
+_mesa_GetAttribLocationARB (GLhandleARB, const GLcharARB *);
+
+#endif /* FEATURE_ARB_vertex_shader */
+
+
+/* 2.0 */
+extern void GLAPIENTRY
+_mesa_AttachShader(GLuint program, GLuint shader);
+
+extern GLuint GLAPIENTRY
+_mesa_CreateShader(GLenum);
+
+extern GLuint GLAPIENTRY
+_mesa_CreateProgram(void);
+
+extern void GLAPIENTRY
+_mesa_DeleteProgram(GLuint program);
+
+extern void GLAPIENTRY
+_mesa_DeleteShader(GLuint shader);
+
+extern void GLAPIENTRY
+_mesa_DetachShader(GLuint program, GLuint shader);
+
+extern void GLAPIENTRY
+_mesa_GetAttachedShaders(GLuint program, GLsizei maxCount,
+ GLsizei *count, GLuint *obj);
+
+extern void GLAPIENTRY
+_mesa_GetProgramiv(GLuint program, GLenum pname, GLint *params);
+
+extern void GLAPIENTRY
+_mesa_GetProgramInfoLog(GLuint program, GLsizei bufSize,
+ GLsizei *length, GLchar *infoLog);
+
+extern void GLAPIENTRY
+_mesa_GetShaderiv(GLuint shader, GLenum pname, GLint *params);
+
+extern void GLAPIENTRY
+_mesa_GetShaderInfoLog(GLuint shader, GLsizei bufSize,
+ GLsizei *length, GLchar *infoLog);
+
+extern GLboolean GLAPIENTRY
+_mesa_IsProgram(GLuint program);
+
+extern GLboolean GLAPIENTRY
+_mesa_IsShader(GLuint shader);
+
+
+
+/* 2.1 */
+extern void GLAPIENTRY
+_mesa_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose,
+ const GLfloat *value);
+
+extern void GLAPIENTRY
+_mesa_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose,
+ const GLfloat *value);
+
+extern void GLAPIENTRY
+_mesa_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose,
+ const GLfloat *value);
+
+extern void GLAPIENTRY
+_mesa_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose,
+ const GLfloat *value);
+
+extern void GLAPIENTRY
+_mesa_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose,
+ const GLfloat *value);
+
+extern void GLAPIENTRY
+_mesa_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose,
+ const GLfloat *value);
+
+
+#endif /* SHADERS_H */
diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c
index f4f73a5089f..6ed7ae6c7dd 100644
--- a/src/mesa/main/state.c
+++ b/src/mesa/main/state.c
@@ -93,7 +93,7 @@
#include "texenvprogram.h"
#endif
#if FEATURE_ARB_shader_objects
-#include "shaderobjects.h"
+#include "shaders.h"
#endif
#include "debug.h"
#include "dispatch.h"
@@ -832,11 +832,7 @@ update_arrays( GLcontext *ctx )
/* find min of _MaxElement values for all enabled arrays */
/* 0 */
- if (ctx->ShaderObjects._VertexShaderPresent
- && ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_GENERIC0].Enabled) {
- min = ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_GENERIC0]._MaxElement;
- }
- else if (ctx->VertexProgram._Enabled
+ if (ctx->VertexProgram._Current
&& ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_POS].Enabled) {
min = ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_POS]._MaxElement;
}
@@ -920,7 +916,7 @@ update_arrays( GLcontext *ctx )
}
/* 16..31 */
- if (ctx->ShaderObjects._VertexShaderPresent) {
+ if (ctx->VertexProgram._Current) {
for (i = VERT_ATTRIB_GENERIC0; i < VERT_ATTRIB_MAX; i++) {
if (ctx->Array.ArrayObj->VertexAttrib[i].Enabled) {
min = MIN2(min, ctx->Array.ArrayObj->VertexAttrib[i]._MaxElement);
@@ -943,30 +939,66 @@ update_arrays( GLcontext *ctx )
static void
update_program(GLcontext *ctx)
{
- /* For now, just set the _Enabled (really enabled) flags.
- * In the future we may have to check other state to be sure we really
- * have a runable program or shader.
- */
+ const struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
+
+ /* These _Enabled flags indicate if the program is enabled AND valid. */
ctx->VertexProgram._Enabled = ctx->VertexProgram.Enabled
&& ctx->VertexProgram.Current->Base.Instructions;
ctx->FragmentProgram._Enabled = ctx->FragmentProgram.Enabled
&& ctx->FragmentProgram.Current->Base.Instructions;
ctx->ATIFragmentShader._Enabled = ctx->ATIFragmentShader.Enabled
&& ctx->ATIFragmentShader.Current->Instructions;
-
- ctx->FragmentProgram._Current = ctx->FragmentProgram.Current;
- ctx->FragmentProgram._Active = ctx->FragmentProgram._Enabled;
- if (ctx->_MaintainTexEnvProgram && !ctx->FragmentProgram._Enabled) {
-#if 0
- if (!ctx->_TexEnvProgram)
- ctx->_TexEnvProgram = (struct gl_fragment_program *)
- ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
- ctx->FragmentProgram._Current = ctx->_TexEnvProgram;
-#endif
+ /*
+ * Set the ctx->VertexProgram._Current and ctx->FragmentProgram._Current
+ * pointers to the programs that should be enabled/used.
+ *
+ * These programs may come from several sources. The priority is as
+ * follows:
+ * 1. OpenGL 2.0/ARB vertex/fragment shaders
+ * 2. ARB/NV vertex/fragment programs
+ * 3. Programs derived from fixed-function state.
+ */
- if (ctx->_UseTexEnvProgram)
- ctx->FragmentProgram._Active = GL_TRUE;
+ ctx->FragmentProgram._Current = NULL;
+
+ if (shProg && shProg->LinkStatus) {
+ /* Use shader programs */
+ ctx->VertexProgram._Current = shProg->VertexProgram;
+ ctx->FragmentProgram._Current = shProg->FragmentProgram;
+ }
+ else {
+ if (ctx->VertexProgram._Enabled) {
+ /* use user-defined vertex program */
+ ctx->VertexProgram._Current = ctx->VertexProgram.Current;
+ }
+ else if (ctx->VertexProgram._MaintainTnlProgram) {
+ /* Use vertex program generated from fixed-function state.
+ * The _Current pointer will get set in
+ * _tnl_UpdateFixedFunctionProgram() later if appropriate.
+ */
+ ctx->VertexProgram._Current = NULL;
+ }
+ else {
+ /* no vertex program */
+ ctx->VertexProgram._Current = NULL;
+ }
+
+ if (ctx->FragmentProgram._Enabled) {
+ /* use user-defined vertex program */
+ ctx->FragmentProgram._Current = ctx->FragmentProgram.Current;
+ }
+ else if (ctx->FragmentProgram._MaintainTexEnvProgram) {
+ /* Use fragment program generated from fixed-function state.
+ * The _Current pointer will get set in _mesa_UpdateTexEnvProgram()
+ * later if appropriate.
+ */
+ ctx->FragmentProgram._Current = NULL;
+ }
+ else {
+ /* no fragment program */
+ ctx->FragmentProgram._Current = NULL;
+ }
}
}
@@ -1003,6 +1035,7 @@ update_color(GLcontext *ctx)
}
+
/**
* Update the ctx->_TriangleCaps bitfield.
* XXX that bitfield should really go away someday!
@@ -1133,7 +1166,7 @@ _mesa_update_state_locked( GLcontext *ctx )
| _NEW_STENCIL | _DD_NEW_SEPARATE_SPECULAR))
update_tricaps( ctx, new_state );
- if (ctx->_MaintainTexEnvProgram) {
+ if (ctx->FragmentProgram._MaintainTexEnvProgram) {
if (new_state & (_NEW_TEXTURE | _DD_NEW_SEPARATE_SPECULAR | _NEW_FOG))
_mesa_UpdateTexEnvProgram(ctx);
}
diff --git a/src/mesa/main/texenvprogram.c b/src/mesa/main/texenvprogram.c
index 5038b9b0c36..54ae7ce0a13 100644
--- a/src/mesa/main/texenvprogram.c
+++ b/src/mesa/main/texenvprogram.c
@@ -28,11 +28,12 @@
#include "glheader.h"
#include "macros.h"
#include "enums.h"
+#include "prog_parameter.h"
+#include "prog_instruction.h"
+#include "prog_print.h"
+#include "prog_statevars.h"
#include "texenvprogram.h"
-#include "shader/program.h"
-#include "shader/program_instruction.h"
-
/**
* According to Glean's texCombine test, no more than 21 instructions
* are needed. Allow a few extra just in case.
@@ -410,31 +411,29 @@ static void release_temps( struct texenv_fragment_program *p )
}
-static struct ureg register_param6( struct texenv_fragment_program *p,
+static struct ureg register_param5( struct texenv_fragment_program *p,
GLint s0,
GLint s1,
GLint s2,
GLint s3,
- GLint s4,
- GLint s5)
+ GLint s4)
{
- GLint tokens[6];
+ gl_state_index tokens[STATE_LENGTH];
GLuint idx;
tokens[0] = s0;
tokens[1] = s1;
tokens[2] = s2;
tokens[3] = s3;
tokens[4] = s4;
- tokens[5] = s5;
idx = _mesa_add_state_reference( p->program->Base.Parameters, tokens );
return make_ureg(PROGRAM_STATE_VAR, idx);
}
-#define register_param1(p,s0) register_param6(p,s0,0,0,0,0,0)
-#define register_param2(p,s0,s1) register_param6(p,s0,s1,0,0,0,0)
-#define register_param3(p,s0,s1,s2) register_param6(p,s0,s1,s2,0,0,0)
-#define register_param4(p,s0,s1,s2,s3) register_param6(p,s0,s1,s2,s3,0,0)
+#define register_param1(p,s0) register_param5(p,s0,0,0,0,0)
+#define register_param2(p,s0,s1) register_param5(p,s0,s1,0,0,0)
+#define register_param3(p,s0,s1,s2) register_param5(p,s0,s1,s2,0,0)
+#define register_param4(p,s0,s1,s2,s3) register_param5(p,s0,s1,s2,s3,0)
static struct ureg register_input( struct texenv_fragment_program *p, GLuint input )
@@ -523,7 +522,7 @@ static struct ureg emit_arith( struct texenv_fragment_program *p,
if (dest.file == PROGRAM_TEMPORARY)
p->alu_temps |= 1 << dest.idx;
- p->program->NumAluInstructions++;
+ p->program->Base.NumAluInstructions++;
return dest;
}
@@ -545,7 +544,7 @@ static struct ureg emit_texld( struct texenv_fragment_program *p,
inst->TexSrcTarget = tex_idx;
inst->TexSrcUnit = tex_unit;
- p->program->NumTexInstructions++;
+ p->program->Base.NumTexInstructions++;
/* Is this a texture indirection?
*/
@@ -553,7 +552,7 @@ static struct ureg emit_texld( struct texenv_fragment_program *p,
(p->temps_output & (1<<coord.idx))) ||
(dest.file == PROGRAM_TEMPORARY &&
(p->alu_temps & (1<<dest.idx)))) {
- p->program->NumTexIndirections++;
+ p->program->Base.NumTexIndirections++;
p->temps_output = 1<<coord.idx;
p->alu_temps = 0;
assert(0); /* KW: texture env crossbar */
@@ -570,12 +569,14 @@ static struct ureg register_const4f( struct texenv_fragment_program *p,
GLfloat s3)
{
GLfloat values[4];
- GLuint idx;
+ GLuint idx, swizzle;
values[0] = s0;
values[1] = s1;
values[2] = s2;
values[3] = s3;
- idx = _mesa_add_unnamed_constant( p->program->Base.Parameters, values, 4 );
+ idx = _mesa_add_unnamed_constant( p->program->Base.Parameters, values, 4,
+ &swizzle );
+ ASSERT(swizzle == SWIZZLE_NOOP);
return make_ureg(PROGRAM_STATE_VAR, idx);
}
@@ -1010,9 +1011,9 @@ create_new_program(GLcontext *ctx, struct state_key *key,
*/
p.program->Base.Instructions = instBuffer;
p.program->Base.Target = GL_FRAGMENT_PROGRAM_ARB;
- p.program->NumTexIndirections = 1; /* correct? */
- p.program->NumTexInstructions = 0;
- p.program->NumAluInstructions = 0;
+ p.program->Base.NumTexIndirections = 1; /* correct? */
+ p.program->Base.NumTexInstructions = 0;
+ p.program->Base.NumAluInstructions = 0;
p.program->Base.String = 0;
p.program->Base.NumInstructions =
p.program->Base.NumTemporaries =
@@ -1083,13 +1084,13 @@ create_new_program(GLcontext *ctx, struct state_key *key,
} else
p.program->FogOption = GL_NONE;
- if (p.program->NumTexIndirections > ctx->Const.FragmentProgram.MaxTexIndirections)
+ if (p.program->Base.NumTexIndirections > ctx->Const.FragmentProgram.MaxTexIndirections)
program_error(&p, "Exceeded max nr indirect texture lookups");
- if (p.program->NumTexInstructions > ctx->Const.FragmentProgram.MaxTexInstructions)
+ if (p.program->Base.NumTexInstructions > ctx->Const.FragmentProgram.MaxTexInstructions)
program_error(&p, "Exceeded max TEX instructions");
- if (p.program->NumAluInstructions > ctx->Const.FragmentProgram.MaxAluInstructions)
+ if (p.program->Base.NumAluInstructions > ctx->Const.FragmentProgram.MaxAluInstructions)
program_error(&p, "Exceeded max ALU instructions");
ASSERT(p.program->Base.NumInstructions <= MAX_INSTRUCTIONS);
@@ -1222,32 +1223,49 @@ static GLuint hash_key( const struct state_key *key )
return hash;
}
-void _mesa_UpdateTexEnvProgram( GLcontext *ctx )
+
+/**
+ * If _MaintainTexEnvProgram is set we'll generate a fragment program that
+ * implements the current texture env/combine mode.
+ * This function generates that program and puts it into effect.
+ */
+void
+_mesa_UpdateTexEnvProgram( GLcontext *ctx )
{
struct state_key key;
GLuint hash;
const struct gl_fragment_program *prev = ctx->FragmentProgram._Current;
- if (!ctx->FragmentProgram._Enabled) {
+ ASSERT(ctx->FragmentProgram._MaintainTexEnvProgram);
+
+ /* If a conventional fragment program/shader isn't in effect... */
+ if (!ctx->FragmentProgram._Enabled &&
+ !ctx->Shader.CurrentProgram) {
make_state_key(ctx, &key);
hash = hash_key(&key);
ctx->FragmentProgram._Current =
- ctx->_TexEnvProgram =
- search_cache(&ctx->Texture.env_fp_cache, hash, &key, sizeof(key));
-
- if (!ctx->_TexEnvProgram) {
- if (0) _mesa_printf("Building new texenv proggy for key %x\n", hash);
-
- ctx->FragmentProgram._Current = ctx->_TexEnvProgram =
- (struct gl_fragment_program *)
- ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
-
- create_new_program(ctx, &key, ctx->_TexEnvProgram);
+ ctx->FragmentProgram._TexEnvProgram =
+ search_cache(&ctx->Texture.env_fp_cache, hash, &key, sizeof(key));
+
+ if (!ctx->FragmentProgram._TexEnvProgram) {
+ if (0)
+ _mesa_printf("Building new texenv proggy for key %x\n", hash);
+
+ /* create new tex env program */
+ ctx->FragmentProgram._Current =
+ ctx->FragmentProgram._TexEnvProgram =
+ (struct gl_fragment_program *)
+ ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
- cache_item(&ctx->Texture.env_fp_cache, hash, &key, ctx->_TexEnvProgram);
- } else {
- if (0) _mesa_printf("Found existing texenv program for key %x\n", hash);
+ create_new_program(ctx, &key, ctx->FragmentProgram._TexEnvProgram);
+
+ cache_item(&ctx->Texture.env_fp_cache, hash, &key,
+ ctx->FragmentProgram._TexEnvProgram);
+ }
+ else {
+ if (0)
+ _mesa_printf("Found existing texenv program for key %x\n", hash);
}
}
else {
@@ -1259,7 +1277,7 @@ void _mesa_UpdateTexEnvProgram( GLcontext *ctx )
*/
if (ctx->FragmentProgram._Current != prev && ctx->Driver.BindProgram) {
ctx->Driver.BindProgram(ctx, GL_FRAGMENT_PROGRAM_ARB,
- (struct gl_program *) ctx->FragmentProgram._Current);
+ (struct gl_program *) ctx->FragmentProgram._Current);
}
}
diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c
index bcedcafe19e..7be3a44d59f 100644
--- a/src/mesa/main/texstate.c
+++ b/src/mesa/main/texstate.c
@@ -41,7 +41,7 @@
#include "texenvprogram.h"
#include "mtypes.h"
#include "math/m_xform.h"
-#include "shaderobjects.h"
+/*#include "shaderobjects.h"*/
@@ -2919,11 +2919,18 @@ static void
update_texture_state( GLcontext *ctx )
{
GLuint unit;
+ struct gl_fragment_program *fprog;
-#if FEATURE_ARB_fragment_shader
- struct gl2_program_intf **prog = ctx->ShaderObjects.CurrentProgram;
- GLbitfield progteximageusage[MAX_TEXTURE_IMAGE_UNITS];
-#endif
+ if (ctx->Shader.CurrentProgram &&
+ ctx->Shader.CurrentProgram->LinkStatus) {
+ fprog = ctx->Shader.CurrentProgram->FragmentProgram;
+ }
+ else if (ctx->FragmentProgram._Enabled) {
+ fprog = ctx->FragmentProgram.Current;
+ }
+ else {
+ fprog = NULL;
+ }
ctx->NewState |= _NEW_TEXTURE; /* TODO: only set this if there are
* actual changes.
@@ -2934,17 +2941,6 @@ update_texture_state( GLcontext *ctx )
ctx->Texture._TexMatEnabled = 0;
ctx->Texture._TexGenEnabled = 0;
-#if FEATURE_ARB_fragment_shader
- /*
- * Grab texture image usage state from shader program. It must be
- * grabbed every time uniform sampler changes, so maybe there is a
- * better place to perform these rather expensive computations.
- */
- if (ctx->ShaderObjects._FragmentShaderPresent) {
- (**prog).GetTextureImageUsage (prog, progteximageusage);
- }
-#endif /* FEATURE_ARB_fragment_shader */
-
/*
* Update texture unit state.
*/
@@ -2956,15 +2952,14 @@ update_texture_state( GLcontext *ctx )
texUnit->_ReallyEnabled = 0;
texUnit->_GenFlags = 0;
- /* Get the bitmask of texture enables */
-#if FEATURE_ARB_fragment_shader
- if (ctx->ShaderObjects._FragmentShaderPresent) {
- enableBits = progteximageusage[unit];
- }
- else
-#endif
- if (ctx->FragmentProgram._Enabled) {
- enableBits = ctx->FragmentProgram.Current->TexturesUsed[unit];
+ /* Get the bitmask of texture enables.
+ * enableBits will be a mask of the TEXTURE_*_BIT flags indicating
+ * which texture targets are enabled (fixed function) or referenced
+ * by a fragment shader/program. When multiple flags are set, we'll
+ * settle on the one with highest priority (see texture_override below).
+ */
+ if (fprog) {
+ enableBits = fprog->Base.TexturesUsed[unit];
}
else {
if (!texUnit->Enabled)
@@ -3081,21 +3076,25 @@ update_texture_state( GLcontext *ctx )
ctx->Texture._TexMatEnabled |= ENABLE_TEXMAT(unit);
}
+ /* XXX maybe move this below as an else-clause */
ctx->Texture._EnabledCoordUnits = ctx->Texture._EnabledUnits;
+
/* Fragment programs may need texture coordinates but not the
* corresponding texture images.
*/
- if (ctx->ShaderObjects.CurrentProgram != NULL) {
- ctx->Texture._EnabledCoordUnits |= (1 << ctx->Const.MaxTextureCoordUnits) - 1;
- }
- else if (ctx->FragmentProgram._Enabled) {
- ctx->Texture._EnabledCoordUnits |=
- (ctx->FragmentProgram.Current->Base.InputsRead >> FRAG_ATTRIB_TEX0);
+ if (fprog) {
+ const GLuint coordMask = (1 << MAX_TEXTURE_UNITS) - 1;
+ ctx->Texture._EnabledCoordUnits
+ |= (fprog->Base.InputsRead >> FRAG_ATTRIB_TEX0) & coordMask;
}
}
-void _mesa_update_texture( GLcontext *ctx, GLuint new_state )
+/**
+ * Update texture-related derived state.
+ */
+void
+_mesa_update_texture( GLcontext *ctx, GLuint new_state )
{
if (new_state & _NEW_TEXTURE_MATRIX)
update_texture_matrices( ctx );