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_MATRICES 8
#define MAX_PROGRAM_MATRIX_STACK_DEPTH 4 #define MAX_PROGRAM_MATRIX_STACK_DEPTH 4
#define MAX_PROGRAM_CALL_DEPTH 8 #define MAX_PROGRAM_CALL_DEPTH 8
/*@}*/ #define MAX_PROGRAM_TEMPS 128
#define MAX_UNIFORMS 128
/** For GL_ARB_fragment_shader */ #define MAX_VARYING 8
/*@{*/
#define MAX_FRAGMENT_UNIFORM_COMPONENTS 64
/*@}*/ /*@}*/
/** For GL_ARB_vertex_shader */ /** For GL_ARB_vertex_shader */
/*@{*/ /*@{*/
#define MAX_VERTEX_ATTRIBS 16 #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_VERTEX_TEXTURE_IMAGE_UNITS 0
#define MAX_COMBINED_TEXTURE_IMAGE_UNITS (MAX_TEXTURE_IMAGE_UNITS + MAX_VERTEX_TEXTURE_IMAGE_UNITS) #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 #if FEATURE_ARB_shader_objects
ss->GL2Objects = _mesa_NewHashTable (); ss->GL2Objects = _mesa_NewHashTable ();
ss->ShaderObjects = _mesa_NewHashTable();
ss->ProgramObjects = _mesa_NewHashTable();
#endif #endif
ss->Default1D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_1D); ss->Default1D = (*ctx->Driver.NewTextureObject)(ctx, 0, GL_TEXTURE_1D);
@@ -782,8 +784,11 @@ alloc_shared_state( GLcontext *ctx )
_mesa_DeleteHashTable (ss->ArrayObjects); _mesa_DeleteHashTable (ss->ArrayObjects);
#if FEATURE_ARB_shader_objects #if FEATURE_ARB_shader_objects
if (ss->GL2Objects) if (ss->GL2Objects) {
_mesa_DeleteHashTable (ss->GL2Objects); _mesa_DeleteHashTable (ss->GL2Objects);
_mesa_DeleteHashTable (ss->ShaderObjects);
_mesa_DeleteHashTable (ss->ProgramObjects);
}
#endif #endif
#if FEATURE_EXT_framebuffer_object #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.MaxLocalParams = MAX_PROGRAM_LOCAL_PARAMS;
ctx->Const.VertexProgram.MaxEnvParams = MAX_NV_VERTEX_PROGRAM_PARAMS; ctx->Const.VertexProgram.MaxEnvParams = MAX_NV_VERTEX_PROGRAM_PARAMS;
ctx->Const.VertexProgram.MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS; 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); init_natives(&ctx->Const.VertexProgram);
#endif #endif
#if FEATURE_ARB_fragment_program #if FEATURE_ARB_fragment_program
ctx->Const.FragmentProgram.MaxInstructions = MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS; ctx->Const.FragmentProgram.MaxInstructions = MAX_NV_FRAGMENT_PROGRAM_INSTRUCTIONS;
ctx->Const.FragmentProgram.MaxAluInstructions = MAX_FRAGMENT_PROGRAM_ALU_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.MaxLocalParams = MAX_PROGRAM_LOCAL_PARAMS;
ctx->Const.FragmentProgram.MaxEnvParams = MAX_NV_FRAGMENT_PROGRAM_PARAMS; ctx->Const.FragmentProgram.MaxEnvParams = MAX_NV_FRAGMENT_PROGRAM_PARAMS;
ctx->Const.FragmentProgram.MaxAddressRegs = MAX_FRAGMENT_PROGRAM_ADDRESS_REGS; 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); init_natives(&ctx->Const.FragmentProgram);
#endif #endif
ctx->Const.MaxProgramMatrices = MAX_PROGRAM_MATRICES; ctx->Const.MaxProgramMatrices = MAX_PROGRAM_MATRICES;
@@ -1106,7 +1112,7 @@ _mesa_init_constants( GLcontext *ctx )
#if FEATURE_ARB_vertex_shader #if FEATURE_ARB_vertex_shader
ctx->Const.MaxVertexTextureImageUnits = MAX_VERTEX_TEXTURE_IMAGE_UNITS; ctx->Const.MaxVertexTextureImageUnits = MAX_VERTEX_TEXTURE_IMAGE_UNITS;
ctx->Const.MaxVaryingFloats = MAX_VARYING_FLOATS; ctx->Const.MaxVarying = MAX_VARYING;
#endif #endif
/* sanity checks */ /* sanity checks */
@@ -1114,6 +1120,11 @@ _mesa_init_constants( GLcontext *ctx )
ctx->Const.MaxTextureCoordUnits)); ctx->Const.MaxTextureCoordUnits));
ASSERT(ctx->Const.FragmentProgram.MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS); ASSERT(ctx->Const.FragmentProgram.MaxLocalParams <= MAX_PROGRAM_LOCAL_PARAMS);
ASSERT(ctx->Const.VertexProgram.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; ctx->TnlModule.SwapCount = 0;
#endif #endif
ctx->_MaintainTexEnvProgram = (_mesa_getenv("MESA_TEX_PROG") != NULL); ctx->VertexProgram._MaintainTnlProgram
ctx->_UseTexEnvProgram = ctx->_MaintainTexEnvProgram; = (_mesa_getenv("MESA_TNL_PROG") != NULL);
if (ctx->VertexProgram._MaintainTnlProgram)
ctx->_MaintainTnlProgram = (_mesa_getenv("MESA_TNL_PROG") != NULL); /* this is required... */
if (ctx->_MaintainTnlProgram) ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
ctx->_MaintainTexEnvProgram = 1; /* this is required... */ else
ctx->FragmentProgram._MaintainTexEnvProgram
= (_mesa_getenv("MESA_TEX_PROG") != NULL);
ctx->FirstTimeCurrent = GL_TRUE; ctx->FirstTimeCurrent = GL_TRUE;
@@ -1678,6 +1691,10 @@ void
_mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer, _mesa_make_current( GLcontext *newCtx, GLframebuffer *drawBuffer,
GLframebuffer *readBuffer ) GLframebuffer *readBuffer )
{ {
#if 0
GET_CURRENT_CONTEXT(oldCtx);
#endif
if (MESA_VERBOSE & VERBOSE_API) if (MESA_VERBOSE & VERBOSE_API)
_mesa_debug(newCtx, "_mesa_make_current()\n"); _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 */ /* We used to call _glapi_check_multithread() here. Now do it in drivers */
_glapi_set_context((void *) newCtx); _glapi_set_context((void *) newCtx);
ASSERT(_mesa_get_current_context() == 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 #if FEATURE_EXT_texture_sRGB
ctx->Extensions.EXT_texture_sRGB = GL_TRUE; ctx->Extensions.EXT_texture_sRGB = GL_TRUE;
#endif #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; break;
case GL_MAX_VARYING_FLOATS_ARB: case GL_MAX_VARYING_FLOATS_ARB:
CHECK_EXT1(ARB_vertex_shader, "GetBooleanv"); CHECK_EXT1(ARB_vertex_shader, "GetBooleanv");
params[0] = INT_TO_BOOLEAN(ctx->Const.MaxVaryingFloats); params[0] = INT_TO_BOOLEAN(ctx->Const.MaxVarying * 4);
break; break;
case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB: case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB:
CHECK_EXT1(ARB_vertex_shader, "GetBooleanv"); CHECK_EXT1(ARB_vertex_shader, "GetBooleanv");
@@ -3705,7 +3705,7 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params )
break; break;
case GL_MAX_VARYING_FLOATS_ARB: case GL_MAX_VARYING_FLOATS_ARB:
CHECK_EXT1(ARB_vertex_shader, "GetFloatv"); CHECK_EXT1(ARB_vertex_shader, "GetFloatv");
params[0] = (GLfloat)(ctx->Const.MaxVaryingFloats); params[0] = (GLfloat)(ctx->Const.MaxVarying * 4);
break; break;
case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB: case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB:
CHECK_EXT1(ARB_vertex_shader, "GetFloatv"); CHECK_EXT1(ARB_vertex_shader, "GetFloatv");
@@ -5532,7 +5532,7 @@ _mesa_GetIntegerv( GLenum pname, GLint *params )
break; break;
case GL_MAX_VARYING_FLOATS_ARB: case GL_MAX_VARYING_FLOATS_ARB:
CHECK_EXT1(ARB_vertex_shader, "GetIntegerv"); CHECK_EXT1(ARB_vertex_shader, "GetIntegerv");
params[0] = ctx->Const.MaxVaryingFloats; params[0] = ctx->Const.MaxVarying * 4;
break; break;
case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB: case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB:
CHECK_EXT1(ARB_vertex_shader, "GetIntegerv"); CHECK_EXT1(ARB_vertex_shader, "GetIntegerv");

View File

@@ -989,7 +989,7 @@ StateVars = [
["ctx->Const.VertexProgram.MaxUniformComponents"], "", ["ctx->Const.VertexProgram.MaxUniformComponents"], "",
["ARB_vertex_shader"] ), ["ARB_vertex_shader"] ),
( "GL_MAX_VARYING_FLOATS_ARB", GLint, ( "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, ( "GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB", GLint,
["ctx->Const.MaxVertexTextureImageUnits"], "", ["ARB_vertex_shader"] ), ["ctx->Const.MaxVertexTextureImageUnits"], "", ["ARB_vertex_shader"] ),
( "GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB", GLint, ( "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))) #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 * Indexes for vertex program result attributes
@@ -250,7 +234,8 @@ enum
#define VERT_RESULT_BFC0 13 #define VERT_RESULT_BFC0 13
#define VERT_RESULT_BFC1 14 #define VERT_RESULT_BFC1 14
#define VERT_RESULT_EDGE 15 #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_TEX5 = 9,
FRAG_ATTRIB_TEX6 = 10, FRAG_ATTRIB_TEX6 = 10,
FRAG_ATTRIB_TEX7 = 11, 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 * Fragment program results
*/ */
/*@{*/ enum
#define FRAG_RESULT_COLR 0 {
#define FRAG_RESULT_COLH 1 FRAG_RESULT_COLR = 0,
#define FRAG_RESULT_DEPR 2 FRAG_RESULT_COLH = 1,
#define FRAG_RESULT_MAX 3 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. * Names of the various vertex/fragment program register files, etc.
*
* NOTE: first four tokens must fit into 2 bits (see t_vb_arbprogram.c) * NOTE: first four tokens must fit into 2 bits (see t_vb_arbprogram.c)
* All values should fit in a 4-bit field. * 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 enum register_file
{ {
PROGRAM_TEMPORARY = 0, PROGRAM_TEMPORARY = 0, /**< machine->Temporary[] */
PROGRAM_LOCAL_PARAM = 1, PROGRAM_LOCAL_PARAM = 1, /**< gl_program->LocalParams[] */
PROGRAM_ENV_PARAM = 2, PROGRAM_ENV_PARAM = 2, /**< gl_program->Parameters[] */
PROGRAM_STATE_VAR = 3, PROGRAM_STATE_VAR = 3, /**< gl_program->Parameters[] */
PROGRAM_INPUT = 4, PROGRAM_INPUT = 4, /**< machine->Inputs[] */
PROGRAM_OUTPUT = 5, PROGRAM_OUTPUT = 5, /**< machine->Outputs[] */
PROGRAM_NAMED_PARAM = 6, PROGRAM_NAMED_PARAM = 6, /**< gl_program->Parameters[] */
PROGRAM_CONSTANT = 7, PROGRAM_CONSTANT = 7, /**< gl_program->Parameters[] */
PROGRAM_WRITE_ONLY = 8, PROGRAM_UNIFORM = 8, /**< gl_program->Parameters[] */
PROGRAM_ADDRESS = 9, PROGRAM_VARYING = 9, /**< machine->Inputs[]/Outputs[] */
PROGRAM_UNDEFINED = 10, /* invalid value */ PROGRAM_WRITE_ONLY = 10, /**< A dummy, write-only register */
PROGRAM_ADDRESS = 11, /**< machine->AddressReg */
PROGRAM_UNDEFINED = 12, /**< Invalid value */
PROGRAM_FILE_MAX PROGRAM_FILE_MAX
}; };
@@ -1858,6 +1853,9 @@ struct gl_program
/** Numbered local parameters */ /** Numbered local parameters */
GLfloat LocalParams[MAX_PROGRAM_LOCAL_PARAMS][4]; GLfloat LocalParams[MAX_PROGRAM_LOCAL_PARAMS][4];
/** Vertex/fragment shader varying vars */
struct gl_program_parameter_list *Varying;
/** Logical counts */ /** Logical counts */
/*@{*/ /*@{*/
GLuint NumInstructions; GLuint NumInstructions;
@@ -1923,9 +1921,9 @@ struct gl_vertex_program_state
GLboolean PointSizeEnabled; /**< GL_VERTEX_PROGRAM_POINT_SIZE_ARB/NV */ GLboolean PointSizeEnabled; /**< GL_VERTEX_PROGRAM_POINT_SIZE_ARB/NV */
GLboolean TwoSideEnabled; /**< GL_VERTEX_PROGRAM_TWO_SIDE_ARB/NV */ GLboolean TwoSideEnabled; /**< GL_VERTEX_PROGRAM_TWO_SIDE_ARB/NV */
struct gl_vertex_program *Current; /**< ptr to currently bound program */ struct gl_vertex_program *Current; /**< ptr to currently bound program */
const struct gl_vertex_program *_Current; /**< ptr to currently bound
program, including internal /** Currently enabled and valid program (including internal programs) */
(t_vp_build.c) programs */ struct gl_vertex_program *_Current;
GLfloat Parameters[MAX_NV_VERTEX_PROGRAM_PARAMS][4]; /**< Env params */ 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 TrackMatrix[MAX_NV_VERTEX_PROGRAM_PARAMS / 4];
GLenum TrackMatrixTransform[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 #if FEATURE_MESA_program_debug
GLprogramcallbackMESA Callback; GLprogramcallbackMESA Callback;
GLvoid *CallbackData; GLvoid *CallbackData;
@@ -1949,12 +1953,19 @@ struct gl_fragment_program_state
{ {
GLboolean Enabled; /**< User-set fragment program enable flag */ GLboolean Enabled; /**< User-set fragment program enable flag */
GLboolean _Enabled; /**< Fragment program enabled and valid? */ 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 */ 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 */ 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 #if FEATURE_MESA_program_debug
GLprogramcallbackMESA Callback; GLprogramcallbackMESA Callback;
GLvoid *CallbackData; 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. * Context state for vertex/fragment shaders.
*/ */
@@ -2038,6 +2084,7 @@ struct gl_shader_objects_state
struct gl2_program_intf **CurrentProgram; struct gl2_program_intf **CurrentProgram;
GLboolean _VertexShaderPresent; GLboolean _VertexShaderPresent;
GLboolean _FragmentShaderPresent; GLboolean _FragmentShaderPresent;
struct gl_linked_program *Linked; /* XXX temporary here */
}; };
@@ -2099,6 +2146,8 @@ struct gl_shared_state
#if FEATURE_ARB_shader_objects #if FEATURE_ARB_shader_objects
struct _mesa_HashTable *GL2Objects; struct _mesa_HashTable *GL2Objects;
struct _mesa_HashTable *ShaderObjects;
struct _mesa_HashTable *ProgramObjects;
#endif #endif
#if FEATURE_EXT_framebuffer_object #if FEATURE_EXT_framebuffer_object
@@ -2377,7 +2426,7 @@ struct gl_constants
GLuint MaxRenderbufferSize; GLuint MaxRenderbufferSize;
/* GL_ARB_vertex_shader */ /* GL_ARB_vertex_shader */
GLuint MaxVertexTextureImageUnits; 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_fragment_program_state FragmentProgram; /**< GL_ARB/NV_vertex_program */
struct gl_ati_fragment_shader_state ATIFragmentShader; /**< GL_ATI_fragment_shader */ 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_query_state Query; /**< GL_ARB_occlusion_query */
struct gl_shader_objects_state ShaderObjects; /* GL_ARB_shader_objects */ 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 */ /* find min of _MaxElement values for all enabled arrays */
/* 0 */ /* 0 */
if (ctx->ShaderObjects._VertexShaderPresent if (ctx->VertexProgram._Current
&& ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_GENERIC0].Enabled) {
min = ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_GENERIC0]._MaxElement;
}
else if (ctx->VertexProgram._Enabled
&& ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_POS].Enabled) { && ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_POS].Enabled) {
min = ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_POS]._MaxElement; min = ctx->Array.ArrayObj->VertexAttrib[VERT_ATTRIB_POS]._MaxElement;
} }
@@ -930,7 +926,7 @@ update_arrays( GLcontext *ctx )
} }
/* 16..31 */ /* 16..31 */
if (ctx->ShaderObjects._VertexShaderPresent) { if (ctx->VertexProgram._Current) {
for (i = VERT_ATTRIB_GENERIC0; i < VERT_ATTRIB_MAX; i++) { for (i = VERT_ATTRIB_GENERIC0; i < VERT_ATTRIB_MAX; i++) {
if (ctx->Array.ArrayObj->VertexAttrib[i].Enabled) { if (ctx->Array.ArrayObj->VertexAttrib[i].Enabled) {
min = MIN2(min, ctx->Array.ArrayObj->VertexAttrib[i]._MaxElement); min = MIN2(min, ctx->Array.ArrayObj->VertexAttrib[i]._MaxElement);
@@ -953,10 +949,10 @@ update_arrays( GLcontext *ctx )
static void static void
update_program(GLcontext *ctx) update_program(GLcontext *ctx)
{ {
/* For now, just set the _Enabled (really enabled) flags. const struct gl_linked_program *linked = ctx->ShaderObjects.Linked;
* In the future we may have to check other state to be sure we really
* have a runable program or shader.
*/ /* These _Enabled flags indicate if the program is enabled AND valid. */
ctx->VertexProgram._Enabled = ctx->VertexProgram.Enabled ctx->VertexProgram._Enabled = ctx->VertexProgram.Enabled
&& ctx->VertexProgram.Current->Base.Instructions; && ctx->VertexProgram.Current->Base.Instructions;
ctx->FragmentProgram._Enabled = ctx->FragmentProgram.Enabled ctx->FragmentProgram._Enabled = ctx->FragmentProgram.Enabled
@@ -964,19 +960,56 @@ update_program(GLcontext *ctx)
ctx->ATIFragmentShader._Enabled = ctx->ATIFragmentShader.Enabled ctx->ATIFragmentShader._Enabled = ctx->ATIFragmentShader.Enabled
&& ctx->ATIFragmentShader.Current->Instructions; && 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._Current = ctx->FragmentProgram.Current;
ctx->FragmentProgram._Active = ctx->FragmentProgram._Enabled; }
else if (ctx->FragmentProgram._MaintainTexEnvProgram) {
if (ctx->_MaintainTexEnvProgram && !ctx->FragmentProgram._Enabled) { /* Use fragment program generated from fixed-function state.
#if 0 * The _Current pointer will get set in _mesa_UpdateTexEnvProgram()
if (!ctx->_TexEnvProgram) * later if appropriate.
ctx->_TexEnvProgram = (struct gl_fragment_program *) */
ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0); ctx->FragmentProgram._Current = NULL;
ctx->FragmentProgram._Current = ctx->_TexEnvProgram; }
#endif else {
/* no fragment program */
if (ctx->_UseTexEnvProgram) ctx->FragmentProgram._Current = NULL;
ctx->FragmentProgram._Active = GL_TRUE; }
} }
} }
@@ -1013,11 +1046,11 @@ update_color(GLcontext *ctx)
} }
/** /**
* If __GLcontextRec::NewState is non-zero then this function \b must be called * Compute derived GL state.
* before rendering any primitive. Basically, function pointers and * If __GLcontextRec::NewState is non-zero then this function \b must
* miscellaneous flags are updated to reflect the current state of the state * be called before rendering anything.
* machine.
* *
* Calls dd_function_table::UpdateState to perform any internal state * Calls dd_function_table::UpdateState to perform any internal state
* management necessary. * management necessary.
@@ -1076,7 +1109,7 @@ _mesa_update_state_locked( GLcontext *ctx )
if (new_state & _NEW_COLOR) if (new_state & _NEW_COLOR)
update_color( ctx ); update_color( ctx );
if (ctx->_MaintainTexEnvProgram) { if (ctx->FragmentProgram._MaintainTexEnvProgram) {
if (new_state & (_NEW_TEXTURE | _DD_NEW_SEPARATE_SPECULAR | _NEW_FOG)) if (new_state & (_NEW_TEXTURE | _DD_NEW_SEPARATE_SPECULAR | _NEW_FOG))
_mesa_UpdateTexEnvProgram(ctx); _mesa_UpdateTexEnvProgram(ctx);
} }
@@ -1122,3 +1155,5 @@ _mesa_update_state( GLcontext *ctx )
/*@}*/ /*@}*/

View File

@@ -28,11 +28,12 @@
#include "glheader.h" #include "glheader.h"
#include "macros.h" #include "macros.h"
#include "enums.h" #include "enums.h"
#include "prog_parameter.h"
#include "prog_instruction.h"
#include "prog_print.h"
#include "prog_statevars.h"
#include "texenvprogram.h" #include "texenvprogram.h"
#include "shader/program.h"
#include "shader/program_instruction.h"
/** /**
* According to Glean's texCombine test, no more than 21 instructions * According to Glean's texCombine test, no more than 21 instructions
* are needed. Allow a few extra just in case. * 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 s3)
{ {
GLfloat values[4]; GLfloat values[4];
GLuint idx; GLuint idx, swizzle;
values[0] = s0; values[0] = s0;
values[1] = s1; values[1] = s1;
values[2] = s2; values[2] = s2;
values[3] = s3; 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 make_ureg(PROGRAM_STATE_VAR, idx);
} }
@@ -1221,36 +1224,47 @@ static GLuint hash_key( const struct state_key *key )
return hash; 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; struct state_key key;
GLuint hash; GLuint hash;
const struct gl_fragment_program *prev = ctx->FragmentProgram._Current; 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); make_state_key(ctx, &key);
hash = hash_key(&key); hash = hash_key(&key);
ctx->FragmentProgram._Current = ctx->FragmentProgram._TexEnvProgram =
ctx->_TexEnvProgram =
search_cache(&ctx->Texture.env_fp_cache, hash, &key, sizeof(key)); search_cache(&ctx->Texture.env_fp_cache, hash, &key, sizeof(key));
if (!ctx->_TexEnvProgram) { if (!ctx->FragmentProgram._TexEnvProgram) {
if (0) _mesa_printf("Building new texenv proggy for key %x\n", hash); if (0)
_mesa_printf("Building new texenv proggy for key %x\n", hash);
ctx->FragmentProgram._Current = ctx->_TexEnvProgram = /* create new tex env program */
(struct gl_fragment_program *) ctx->FragmentProgram._TexEnvProgram = (struct gl_fragment_program *)
ctx->Driver.NewProgram(ctx, GL_FRAGMENT_PROGRAM_ARB, 0); 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); cache_item(&ctx->Texture.env_fp_cache, hash, &key,
} else { ctx->FragmentProgram._TexEnvProgram);
if (0) _mesa_printf("Found existing texenv program for key %x\n", hash);
}
} }
else { 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 /* 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; GLuint unit;
#if 0 /** XXX NEW_SLANG */
#if FEATURE_ARB_fragment_shader #if FEATURE_ARB_fragment_shader
struct gl2_program_intf **prog = ctx->ShaderObjects.CurrentProgram; struct gl2_program_intf **prog = ctx->ShaderObjects.CurrentProgram;
GLbitfield progteximageusage[MAX_TEXTURE_IMAGE_UNITS]; GLbitfield progteximageusage[MAX_TEXTURE_IMAGE_UNITS];
#endif
#endif #endif
ctx->NewState |= _NEW_TEXTURE; /* TODO: only set this if there are 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._TexMatEnabled = 0;
ctx->Texture._TexGenEnabled = 0; ctx->Texture._TexGenEnabled = 0;
#if 00 /* XXX NEW_SLANG */
#if FEATURE_ARB_fragment_shader #if FEATURE_ARB_fragment_shader
/* /*
* Grab texture image usage state from shader program. It must be * Grab texture image usage state from shader program. It must be
@@ -2944,6 +2947,7 @@ update_texture_state( GLcontext *ctx )
(**prog).GetTextureImageUsage (prog, progteximageusage); (**prog).GetTextureImageUsage (prog, progteximageusage);
} }
#endif /* FEATURE_ARB_fragment_shader */ #endif /* FEATURE_ARB_fragment_shader */
#endif
/* /*
* Update texture unit state. * Update texture unit state.
@@ -2957,11 +2961,13 @@ update_texture_state( GLcontext *ctx )
texUnit->_GenFlags = 0; texUnit->_GenFlags = 0;
/* Get the bitmask of texture enables */ /* Get the bitmask of texture enables */
#if 000 /* XXX NEW_SLANG */
#if FEATURE_ARB_fragment_shader #if FEATURE_ARB_fragment_shader
if (ctx->ShaderObjects._FragmentShaderPresent) { if (ctx->ShaderObjects._FragmentShaderPresent) {
enableBits = progteximageusage[unit]; enableBits = progteximageusage[unit];
} }
else else
#endif
#endif #endif
if (ctx->FragmentProgram._Enabled) { if (ctx->FragmentProgram._Enabled) {
enableBits = ctx->FragmentProgram.Current->TexturesUsed[unit]; enableBits = ctx->FragmentProgram.Current->TexturesUsed[unit];
@@ -3085,12 +3091,15 @@ update_texture_state( GLcontext *ctx )
/* Fragment programs may need texture coordinates but not the /* Fragment programs may need texture coordinates but not the
* corresponding texture images. * corresponding texture images.
*/ */
#if 0 /* XXX NEW_SLANG */
if (ctx->ShaderObjects.CurrentProgram != NULL) { if (ctx->ShaderObjects.CurrentProgram != NULL) {
ctx->Texture._EnabledCoordUnits |= (1 << ctx->Const.MaxTextureCoordUnits) - 1; ctx->Texture._EnabledCoordUnits |= (1 << ctx->Const.MaxTextureCoordUnits) - 1;
} }
else if (ctx->FragmentProgram._Enabled) { else
#endif
if (ctx->FragmentProgram._Enabled) {
ctx->Texture._EnabledCoordUnits |= ctx->Texture._EnabledCoordUnits |=
(ctx->FragmentProgram.Current->Base.InputsRead >> FRAG_ATTRIB_TEX0); (ctx->FragmentProgram._Current->Base.InputsRead >> FRAG_ATTRIB_TEX0);
} }
} }