From a90046f1097ad95de2aa95ca65741dff5cddced9 Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 15 Dec 2006 10:07:26 -0700 Subject: Lots of assorted changes for new GLSL compiler backend. New datatypes, constants, variables. --- src/mesa/main/config.h | 10 +-- src/mesa/main/context.c | 61 +++++++++++++++--- src/mesa/main/extensions.c | 4 +- src/mesa/main/get.c | 6 +- src/mesa/main/get_gen.py | 2 +- src/mesa/main/mtypes.h | 140 +++++++++++++++++++++++++++--------------- src/mesa/main/state.c | 89 +++++++++++++++++++-------- src/mesa/main/texenvprogram.c | 66 ++++++++++++-------- src/mesa/main/texstate.c | 13 +++- 9 files changed, 265 insertions(+), 126 deletions(-) (limited to 'src') diff --git a/src/mesa/main/config.h b/src/mesa/main/config.h index 13c6281f07..d779860f11 100644 --- a/src/mesa/main/config.h +++ b/src/mesa/main/config.h @@ -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) /*@}*/ diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 7ff45cffe8..4986b29ef0 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -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); diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c index 135323f9c1..7845ea018e 100644 --- a/src/mesa/main/extensions.c +++ b/src/mesa/main/extensions.c @@ -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 } diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c index 858c822659..335443ef4f 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 0f2ca00b83..5a9ca0720e 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/mtypes.h b/src/mesa/main/mtypes.h index 0ed73beb3c..5ed95ccf65 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -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 */ diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index e62fbe47d1..e121f59258 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -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,30 +949,67 @@ 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 && 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; + } } } @@ -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 ) /*@}*/ + + diff --git a/src/mesa/main/texenvprogram.c b/src/mesa/main/texenvprogram.c index 5329719cbb..d318a43ebe 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. @@ -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,44 +1224,55 @@ 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 = - 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); } } diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c index bcedcafe19..e379933a66 100644 --- a/src/mesa/main/texstate.c +++ b/src/mesa/main/texstate.c @@ -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); } } -- cgit v1.2.3