Lots of assorted changes for new GLSL compiler backend.

New datatypes, constants, variables.
This commit is contained in:
Brian
2006-12-15 10:07:26 -07:00
parent becb393d42
commit a90046f109
9 changed files with 265 additions and 126 deletions

View File

@@ -199,18 +199,14 @@
#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)
/*@}*/

View File

@@ -706,6 +706,8 @@ alloc_shared_state( GLcontext *ctx )
#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);
@@ -782,8 +784,11 @@ alloc_shared_state( GLcontext *ctx )
_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
@@ -1063,9 +1068,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;
@@ -1077,7 +1083,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;
@@ -1106,7 +1112,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 */
@@ -1114,6 +1120,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);
}
@@ -1351,12 +1362,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;
@@ -1678,6 +1691,10 @@ void
_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");
@@ -1698,6 +1715,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);

View File

@@ -409,7 +409,9 @@ _mesa_enable_2_1_extensions(GLcontext *ctx)
#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
}

View File

@@ -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");

View File

@@ -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,

View File

@@ -213,22 +213,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 +234,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 +256,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)
};
/**
@@ -305,12 +291,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
};
/**
@@ -1811,22 +1798,30 @@ 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_UNDEFINED = 12, /**< Invalid value */
PROGRAM_FILE_MAX
};
@@ -1858,6 +1853,9 @@ struct gl_program
/** 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;
@@ -1923,9 +1921,9 @@ struct gl_vertex_program_state
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 */
@@ -1933,6 +1931,12 @@ struct gl_vertex_program_state
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;
@@ -1949,12 +1953,19 @@ 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) */
/** 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;
@@ -2030,6 +2041,41 @@ struct gl_query_state
};
/**
* 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.
*/
@@ -2038,6 +2084,7 @@ struct gl_shader_objects_state
struct gl2_program_intf **CurrentProgram;
GLboolean _VertexShaderPresent;
GLboolean _FragmentShaderPresent;
struct gl_linked_program *Linked; /* XXX temporary here */
};
@@ -2099,6 +2146,8 @@ struct gl_shared_state
#if FEATURE_ARB_shader_objects
struct _mesa_HashTable *GL2Objects;
struct _mesa_HashTable *ShaderObjects;
struct _mesa_HashTable *ProgramObjects;
#endif
#if FEATURE_EXT_framebuffer_object
@@ -2377,7 +2426,7 @@ struct gl_constants
GLuint MaxRenderbufferSize;
/* GL_ARB_vertex_shader */
GLuint MaxVertexTextureImageUnits;
GLuint MaxVaryingFloats;
GLuint MaxVarying;
};
@@ -2915,13 +2964,6 @@ 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 */

View File

@@ -842,11 +842,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;
}
@@ -930,7 +926,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);
@@ -953,10 +949,10 @@ 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_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
@@ -964,19 +960,56 @@ update_program(GLcontext *ctx)
ctx->ATIFragmentShader._Enabled = ctx->ATIFragmentShader.Enabled
&& ctx->ATIFragmentShader.Current->Instructions;
/*
* 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->FragmentProgram._Enabled) {
/* use user-defined vertex program */
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
if (ctx->_UseTexEnvProgram)
ctx->FragmentProgram._Active = GL_TRUE;
}
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;
}
}
}
@@ -1013,11 +1046,11 @@ update_color(GLcontext *ctx)
}
/**
* 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.
@@ -1076,7 +1109,7 @@ _mesa_update_state_locked( GLcontext *ctx )
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);
}
@@ -1122,3 +1155,5 @@ _mesa_update_state( GLcontext *ctx )
/*@}*/

View File

@@ -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.
@@ -570,12 +571,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);
}
@@ -1221,36 +1224,47 @@ 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._Current) {
make_state_key(ctx, &key);
hash = hash_key(&key);
ctx->FragmentProgram._Current =
ctx->_TexEnvProgram =
ctx->FragmentProgram._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);
if (!ctx->FragmentProgram._TexEnvProgram) {
if (0)
_mesa_printf("Building new texenv proggy for key %x\n", hash);
ctx->FragmentProgram._Current = ctx->_TexEnvProgram =
(struct gl_fragment_program *)
/* 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->_TexEnvProgram);
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 {
ctx->FragmentProgram._Current = ctx->FragmentProgram.Current;
if (0)
_mesa_printf("Found existing texenv program for key %x\n", hash);
}
ctx->FragmentProgram._Current = ctx->FragmentProgram._TexEnvProgram;
}
/* Tell the driver about the change. Could define a new target for

View File

@@ -2920,9 +2920,11 @@ update_texture_state( GLcontext *ctx )
{
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
@@ -2934,6 +2936,7 @@ update_texture_state( GLcontext *ctx )
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
@@ -2944,6 +2947,7 @@ update_texture_state( GLcontext *ctx )
(**prog).GetTextureImageUsage (prog, progteximageusage);
}
#endif /* FEATURE_ARB_fragment_shader */
#endif
/*
* Update texture unit state.
@@ -2957,11 +2961,13 @@ update_texture_state( GLcontext *ctx )
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];
@@ -3085,12 +3091,15 @@ update_texture_state( GLcontext *ctx )
/* 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);
}
}