Lots of assorted changes for new GLSL compiler backend.
New datatypes, constants, variables.
This commit is contained in:
@@ -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)
|
||||
/*@}*/
|
||||
|
@@ -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);
|
||||
|
@@ -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
|
||||
}
|
||||
|
||||
|
||||
|
@@ -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");
|
||||
|
@@ -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,
|
||||
|
@@ -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 */
|
||||
|
@@ -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 )
|
||||
|
||||
|
||||
/*@}*/
|
||||
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user