New datatypes, constants, variables.
#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_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)
/*@}*/
#if FEATURE_ARB_shader_objects
ss->GL2Objects = _mesa_NewHashTable ();
+ ss->ShaderObjects = _mesa_NewHashTable();
+ ss->ProgramObjects = _mesa_NewHashTable();
#endif
ss->Default1D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_1D);
_mesa_DeleteHashTable (ss->ArrayObjects);
#if FEATURE_ARB_shader_objects
- if (ss->GL2Objects)
+ if (ss->GL2Objects) {
_mesa_DeleteHashTable (ss->GL2Objects);
+ _mesa_DeleteHashTable (ss->ShaderObjects);
+ _mesa_DeleteHashTable (ss->ProgramObjects);
+ }
#endif
#if FEATURE_EXT_framebuffer_object
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;
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;
#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 */
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);
}
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;
_mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer,
GLframebuffer *readBuffer )
{
+#if 0
+ GET_CURRENT_CONTEXT(oldCtx);
+#endif
+
if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(newCtx, "_mesa_make_current()\n");
}
}
+#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);
#if FEATURE_EXT_texture_sRGB
ctx->Extensions.EXT_texture_sRGB = GL_TRUE;
#endif
- /* plus: shading language extensions, non-square uniform matrices */
+#ifdef FEATURE_ARB_shading_language_120
+ ctx->Extensions.ARB_shading_language_120 = GL_TRUE;
+#endif
}
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");
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");
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");
["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,
#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
#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)
/*@}*/
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)
};
/**
/**
* 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
+};
/**
/**
* 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_UNDEFINED = 12, /**< Invalid value */
PROGRAM_FILE_MAX
};
/** Numbered local parameters */
GLfloat LocalParams[MAX_PROGRAM_LOCAL_PARAMS][4];
+ /** Vertex/fragment shader varying vars */
+ struct gl_program_parameter_list *Varying;
+
/** Logical counts */
/*@{*/
GLuint NumInstructions;
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 */
+
+ /** Currently enabled and valid program (including internal programs) */
+ struct gl_vertex_program *_Current;
GLfloat Parameters[MAX_NV_VERTEX_PROGRAM_PARAMS][4]; /**< Env params */
GLenum TrackMatrix[MAX_NV_VERTEX_PROGRAM_PARAMS / 4];
GLenum TrackMatrixTransform[MAX_NV_VERTEX_PROGRAM_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;
GLvoid *CallbackData;
{
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) */
+
+ /** Currently enabled and valid program (including internal programs) */
+ struct gl_fragment_program *_Current;
+
GLfloat Parameters[MAX_NV_FRAGMENT_PROGRAM_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;
GLvoid *CallbackData;
};
+
+/**
+ * A GLSL shader object
+ * A collection of one or more gl_programs...
+ */
+struct gl_shader
+{
+ GLenum Type; /**< GL_FRAGMENT_SHADER || GL_VERTEX_SHADER */
+ GLuint Name; /**< AKA the handle */
+ GLchar *Source; /**< Source code string */
+ GLboolean CompileStatus;
+ GLuint NumPrograms; /**< size of Programs[] array */
+ struct gl_program **Programs; /**< Post-compile assembly code */
+};
+
+
+/**
+ * This corresponds to a GLSL "program" and is basically a linked collection
+ * of "shaders" (which are Mesa gl_programs).
+ * Yes, the terminology is a bit confusing.
+ */
+struct gl_linked_program
+{
+ GLenum Type;
+ GLuint Name; /**< aka handle or ID */
+ GLuint NumShaders; /**< total number of shaders in this program */
+ struct gl_program **Shaders; /**< List of the shaders */
+ struct gl_vertex_program *VertexProgram; /**< Linked vertex program */
+ struct gl_fragment_program *FragmentProgram; /**< Linked fragment prog */
+ GLboolean LinkStatus; /**< GL_LINK_STATUS */
+ struct gl_program_parameter_list *Uniforms; /**< Plus constants, etc */
+ struct gl_program_parameter_list *Varying;
+};
+
+
/**
* Context state for vertex/fragment shaders.
*/
struct gl2_program_intf **CurrentProgram;
GLboolean _VertexShaderPresent;
GLboolean _FragmentShaderPresent;
+ struct gl_linked_program *Linked; /* XXX temporary here */
};
#if FEATURE_ARB_shader_objects
struct _mesa_HashTable *GL2Objects;
+ struct _mesa_HashTable *ShaderObjects;
+ struct _mesa_HashTable *ProgramObjects;
#endif
#if FEATURE_EXT_framebuffer_object
GLuint MaxRenderbufferSize;
/* GL_ARB_vertex_shader */
GLuint MaxVertexTextureImageUnits;
- GLuint MaxVaryingFloats;
+ GLuint MaxVarying;
};
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 */
/* 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;
}
}
/* 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);
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_linked_program *linked = ctx->ShaderObjects.Linked;
+
+
+ /* 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.
+ */
+
+ ctx->FragmentProgram._Current = NULL;
+
+ if (linked && linked->LinkStatus) {
+ /* Use shader programs */
+ ctx->VertexProgram._Current = linked->VertexProgram;
+ ctx->FragmentProgram._Current = linked->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->_UseTexEnvProgram)
- ctx->FragmentProgram._Active = GL_TRUE;
+ 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;
+ }
}
}
}
+
/**
- * If __GLcontextRec::NewState is non-zero then this function \b must be called
- * before rendering any primitive. Basically, function pointers and
- * miscellaneous flags are updated to reflect the current state of the state
- * machine.
+ * Compute derived GL state.
+ * If __GLcontextRec::NewState is non-zero then this function \b must
+ * be called before rendering anything.
*
* Calls dd_function_table::UpdateState to perform any internal state
* management necessary.
if (new_state & _NEW_COLOR)
update_color( ctx );
- if (ctx->_MaintainTexEnvProgram) {
+ if (ctx->FragmentProgram._MaintainTexEnvProgram) {
if (new_state & (_NEW_TEXTURE | _DD_NEW_SEPARATE_SPECULAR | _NEW_FOG))
_mesa_UpdateTexEnvProgram(ctx);
}
/*@}*/
+
+
#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.
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);
}
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._Current) {
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._TexEnvProgram = (struct gl_fragment_program *)
+ ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0);
+
+ create_new_program(ctx, &key, ctx->FragmentProgram._TexEnvProgram);
- 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);
+ 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);
+ }
+ ctx->FragmentProgram._Current = ctx->FragmentProgram._TexEnvProgram;
}
- else {
- ctx->FragmentProgram._Current = ctx->FragmentProgram.Current;
- }
/* Tell the driver about the change. Could define a new target for
* this?
*/
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);
}
}
{
GLuint unit;
+#if 0 /** XXX NEW_SLANG */
#if FEATURE_ARB_fragment_shader
struct gl2_program_intf **prog = ctx->ShaderObjects.CurrentProgram;
GLbitfield progteximageusage[MAX_TEXTURE_IMAGE_UNITS];
+#endif
#endif
ctx->NewState |= _NEW_TEXTURE; /* TODO: only set this if there are
ctx->Texture._TexMatEnabled = 0;
ctx->Texture._TexGenEnabled = 0;
+#if 00 /* XXX NEW_SLANG */
#if FEATURE_ARB_fragment_shader
/*
* Grab texture image usage state from shader program. It must be
(**prog).GetTextureImageUsage (prog, progteximageusage);
}
#endif /* FEATURE_ARB_fragment_shader */
+#endif
/*
* Update texture unit state.
texUnit->_GenFlags = 0;
/* Get the bitmask of texture enables */
+#if 000 /* XXX NEW_SLANG */
#if FEATURE_ARB_fragment_shader
if (ctx->ShaderObjects._FragmentShaderPresent) {
enableBits = progteximageusage[unit];
}
else
+#endif
#endif
if (ctx->FragmentProgram._Enabled) {
enableBits = ctx->FragmentProgram.Current->TexturesUsed[unit];
/* Fragment programs may need texture coordinates but not the
* corresponding texture images.
*/
+#if 0 /* XXX NEW_SLANG */
if (ctx->ShaderObjects.CurrentProgram != NULL) {
ctx->Texture._EnabledCoordUnits |= (1 << ctx->Const.MaxTextureCoordUnits) - 1;
}
- else if (ctx->FragmentProgram._Enabled) {
+ else
+#endif
+ if (ctx->FragmentProgram._Enabled) {
ctx->Texture._EnabledCoordUnits |=
- (ctx->FragmentProgram.Current->Base.InputsRead >> FRAG_ATTRIB_TEX0);
+ (ctx->FragmentProgram._Current->Base.InputsRead >> FRAG_ATTRIB_TEX0);
}
}