From 0560d81ce94d27f2162d77d981468cea1b2bbd8a Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 14 Dec 2006 15:01:28 -0700 Subject: Move many functions into new files. --- src/mesa/shader/program.c | 1774 ++------------------------------------------- src/mesa/shader/program.h | 203 ------ 2 files changed, 63 insertions(+), 1914 deletions(-) (limited to 'src') diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c index 6245870722..c504c7c5c5 100644 --- a/src/mesa/shader/program.c +++ b/src/mesa/shader/program.c @@ -35,19 +35,15 @@ #include "imports.h" #include "macros.h" #include "mtypes.h" -#include "program.h" #include "nvfragparse.h" -#include "program_instruction.h" +#include "program.h" +#include "prog_parameter.h" +#include "prog_instruction.h" +#include "prog_statevars.h" #include "nvvertparse.h" #include "atifragshader.h" -static const char * -make_state_string(const GLint stateTokens[6]); - -static GLbitfield -make_state_flags(const GLint state[]); - /**********************************************************************/ /* Utility functions */ @@ -335,1725 +331,81 @@ _mesa_lookup_program(GLcontext *ctx, GLuint id) } -/**********************************************************************/ -/* Program parameter functions */ -/**********************************************************************/ - -struct gl_program_parameter_list * -_mesa_new_parameter_list(void) -{ - return (struct gl_program_parameter_list *) - _mesa_calloc(sizeof(struct gl_program_parameter_list)); -} - - -/** - * Free a parameter list and all its parameters - */ -void -_mesa_free_parameter_list(struct gl_program_parameter_list *paramList) -{ - GLuint i; - for (i = 0; i < paramList->NumParameters; i++) { - if (paramList->Parameters[i].Name) - _mesa_free((void *) paramList->Parameters[i].Name); - } - _mesa_free(paramList->Parameters); - if (paramList->ParameterValues) - _mesa_align_free(paramList->ParameterValues); - _mesa_free(paramList); -} - - - -/** - * Add a new parameter to a parameter list. - * \param paramList the list to add the parameter to - * \param name the parameter name, will be duplicated/copied! - * \param values initial parameter value, up to 4 GLfloats - * \param size number of elements in 'values' vector (1..4) - * \param type type of parameter, such as - * \return index of new parameter in the list, or -1 if error (out of mem) - */ -GLint -_mesa_add_parameter(struct gl_program_parameter_list *paramList, - const char *name, const GLfloat values[4], GLuint size, - enum register_file type) -{ - const GLuint n = paramList->NumParameters; - - if (n == paramList->Size) { - /* Need to grow the parameter list array */ - if (paramList->Size == 0) - paramList->Size = 8; - else - paramList->Size *= 2; - - /* realloc arrays */ - paramList->Parameters = (struct gl_program_parameter *) - _mesa_realloc(paramList->Parameters, - n * sizeof(struct gl_program_parameter), - paramList->Size * sizeof(struct gl_program_parameter)); - - paramList->ParameterValues = (GLfloat (*)[4]) - _mesa_align_realloc(paramList->ParameterValues, /* old buf */ - n * 4 * sizeof(GLfloat), /* old size */ - paramList->Size * 4 *sizeof(GLfloat), /* new sz */ - 16); - } - - if (!paramList->Parameters || - !paramList->ParameterValues) { - /* out of memory */ - paramList->NumParameters = 0; - paramList->Size = 0; - return -1; - } - else { - paramList->NumParameters = n + 1; - - _mesa_memset(¶mList->Parameters[n], 0, - sizeof(struct gl_program_parameter)); - - paramList->Parameters[n].Name = name ? _mesa_strdup(name) : NULL; - paramList->Parameters[n].Type = type; - paramList->Parameters[n].Size = size; - if (values) - COPY_4V(paramList->ParameterValues[n], values); - return (GLint) n; - } -} - - -/** - * Add a new named program parameter (Ex: NV_fragment_program DEFINE statement) - * \return index of the new entry in the parameter list - */ -GLint -_mesa_add_named_parameter(struct gl_program_parameter_list *paramList, - const char *name, const GLfloat values[4]) -{ - return _mesa_add_parameter(paramList, name, values, 4, PROGRAM_NAMED_PARAM); -} - - -/** - * Add a new named constant to the parameter list. - * This will be used when the program contains something like this: - * PARAM myVals = { 0, 1, 2, 3 }; - * - * \param paramList the parameter list - * \param name the name for the constant - * \param values four float values - * \return index/position of the new parameter in the parameter list - */ -GLint -_mesa_add_named_constant(struct gl_program_parameter_list *paramList, - const char *name, const GLfloat values[4], - GLuint size) -{ -#if 0 /* disable this for now -- we need to save the name! */ - GLint pos; - GLuint swizzle; - ASSERT(size == 4); /* XXX future feature */ - /* check if we already have this constant */ - if (_mesa_lookup_parameter_constant(paramList, values, 4, &pos, &swizzle)) { - return pos; - } -#endif - size = 4; /** XXX fix */ - return _mesa_add_parameter(paramList, name, values, size, PROGRAM_CONSTANT); -} - - -/** - * Add a new unnamed constant to the parameter list. - * This will be used when the program contains something like this: - * MOV r, { 0, 1, 2, 3 }; - * - * \param paramList the parameter list - * \param values four float values - * \param swizzleOut returns swizzle mask for accessing the constant - * \return index/position of the new parameter in the parameter list. - */ -GLint -_mesa_add_unnamed_constant(struct gl_program_parameter_list *paramList, - const GLfloat values[4], GLuint size, - GLuint *swizzleOut) -{ - GLint pos; - GLuint swizzle; - ASSERT(size >= 1); - ASSERT(size <= 4); - size = 4; /* XXX temporary */ - /* check if we already have this constant */ - if (_mesa_lookup_parameter_constant(paramList, values, - size, &pos, &swizzle)) { - return pos; - } - return _mesa_add_parameter(paramList, NULL, values, size, PROGRAM_CONSTANT); -} - - -GLint -_mesa_add_uniform(struct gl_program_parameter_list *paramList, - const char *name, GLuint size) -{ - GLint i = _mesa_lookup_parameter_index(paramList, -1, name); - if (i >= 0 && paramList->Parameters[i].Type == PROGRAM_UNIFORM) { - /* already in list */ - return i; - } - else { - assert(size == 4); - i = _mesa_add_parameter(paramList, name, NULL, size, PROGRAM_UNIFORM); - return i; - } -} - - -GLint -_mesa_add_varying(struct gl_program_parameter_list *paramList, - const char *name, GLuint size) -{ - GLint i = _mesa_lookup_parameter_index(paramList, -1, name); - if (i >= 0 && paramList->Parameters[i].Type == PROGRAM_VARYING) { - /* already in list */ - return i; - } - else { - assert(size == 4); - i = _mesa_add_parameter(paramList, name, NULL, size, PROGRAM_VARYING); - return i; - } -} - - - - -#if 0 /* not used yet */ -/** - * Returns the number of 4-component registers needed to store a piece - * of GL state. For matrices this may be as many as 4 registers, - * everything else needs - * just 1 register. - */ -static GLuint -sizeof_state_reference(const GLint *stateTokens) -{ - if (stateTokens[0] == STATE_MATRIX) { - GLuint rows = stateTokens[4] - stateTokens[3] + 1; - assert(rows >= 1); - assert(rows <= 4); - return rows; - } - else { - return 1; - } -} -#endif - - /** - * Add a new state reference to the parameter list. - * This will be used when the program contains something like this: - * PARAM ambient = state.material.front.ambient; - * - * \param paramList the parameter list - * \param state an array of 6 state tokens - * \return index of the new parameter. + * Return a copy of a program. + * XXX Problem here if the program object is actually OO-derivation + * made by a device driver. */ -GLint -_mesa_add_state_reference(struct gl_program_parameter_list *paramList, - const GLint *stateTokens) +struct gl_program * +_mesa_clone_program(GLcontext *ctx, const struct gl_program *prog) { - const GLuint size = 4; /* XXX fix */ - const char *name; - GLint index; - - /* Check if the state reference is already in the list */ - for (index = 0; index < paramList->NumParameters; index++) { - GLuint i, match = 0; - for (i = 0; i < 6; i++) { - if (paramList->Parameters[index].StateIndexes[i] == stateTokens[i]) { - match++; - } - else { - break; - } - } - if (match == 6) { - /* this state reference is already in the parameter list */ - return index; - } - } - - name = make_state_string(stateTokens); - index = _mesa_add_parameter(paramList, name, NULL, size, PROGRAM_STATE_VAR); - if (index >= 0) { - GLuint i; - for (i = 0; i < 6; i++) { - paramList->Parameters[index].StateIndexes[i] - = (gl_state_index) stateTokens[i]; - } - paramList->StateFlags |= make_state_flags(stateTokens); - } - - /* free name string here since we duplicated it in add_parameter() */ - _mesa_free((void *) name); - - return index; -} - + struct gl_program *clone; -/** - * Lookup a parameter value by name in the given parameter list. - * \return pointer to the float[4] values. - */ -GLfloat * -_mesa_lookup_parameter_value(const struct gl_program_parameter_list *paramList, - GLsizei nameLen, const char *name) -{ - GLuint i = _mesa_lookup_parameter_index(paramList, nameLen, name); - if (i < 0) + clone = _mesa_new_program(ctx, prog->Target, prog->Id); + if (!clone) return NULL; - else - return paramList->ParameterValues[i]; -} - - -/** - * Given a program parameter name, find its position in the list of parameters. - * \param paramList the parameter list to search - * \param nameLen length of name (in chars). - * If length is negative, assume that name is null-terminated. - * \param name the name to search for - * \return index of parameter in the list. - */ -GLint -_mesa_lookup_parameter_index(const struct gl_program_parameter_list *paramList, - GLsizei nameLen, const char *name) -{ - GLint i; - - if (!paramList) - return -1; - if (nameLen == -1) { - /* name is null-terminated */ - for (i = 0; i < (GLint) paramList->NumParameters; i++) { - if (paramList->Parameters[i].Name && - _mesa_strcmp(paramList->Parameters[i].Name, name) == 0) - return i; - } - } - else { - /* name is not null-terminated, use nameLen */ - for (i = 0; i < (GLint) paramList->NumParameters; i++) { - if (paramList->Parameters[i].Name && - _mesa_strncmp(paramList->Parameters[i].Name, name, nameLen) == 0 - && _mesa_strlen(paramList->Parameters[i].Name) == (size_t)nameLen) - return i; - } + assert(clone->Target == prog->Target); + clone->String = (GLubyte *) _mesa_strdup((char *) prog->String); + clone->RefCount = 1; + clone->Format = prog->Format; + clone->Instructions = _mesa_alloc_instructions(prog->NumInstructions); + if (!clone->Instructions) { + _mesa_delete_program(ctx, clone); + return NULL; } - return -1; -} - - -/** - * Look for a float vector in the given parameter list. The float vector - * may be of length 1, 2, 3 or 4. - * \param paramList the parameter list to search - * \param v the float vector to search for - * \param size number of element in v - * \param posOut returns the position of the constant, if found - * \param swizzleOut returns a swizzle mask describing location of the - * vector elements if found - * \return GL_TRUE if found, GL_FALSE if not found - */ -GLboolean -_mesa_lookup_parameter_constant(const struct gl_program_parameter_list *paramList, - const GLfloat v[], GLsizei vSize, - GLint *posOut, GLuint *swizzleOut) -{ - GLuint i; + memcpy(clone->Instructions, prog->Instructions, + prog->NumInstructions * sizeof(struct prog_instruction)); + clone->InputsRead = prog->InputsRead; + clone->OutputsWritten = prog->OutputsWritten; + clone->Parameters = _mesa_clone_parameter_list(prog->Parameters); + memcpy(clone->LocalParams, prog->LocalParams, sizeof(clone->LocalParams)); + clone->Varying = _mesa_clone_parameter_list(prog->Varying); + memcpy(clone->LocalParams, prog->LocalParams, sizeof(clone->LocalParams)); + clone->NumInstructions = prog->NumInstructions; + clone->NumTemporaries = prog->NumTemporaries; + clone->NumParameters = prog->NumParameters; + clone->NumAttributes = prog->NumAttributes; + clone->NumAddressRegs = prog->NumAddressRegs; + clone->NumNativeInstructions = prog->NumNativeInstructions; + clone->NumNativeTemporaries = prog->NumNativeTemporaries; + clone->NumNativeParameters = prog->NumNativeParameters; + clone->NumNativeAttributes = prog->NumNativeAttributes; + clone->NumNativeAddressRegs = prog->NumNativeAddressRegs; - assert(vSize >= 1); - assert(vSize <= 4); - - if (!paramList) - return -1; - - for (i = 0; i < paramList->NumParameters; i++) { - if (paramList->Parameters[i].Type == PROGRAM_CONSTANT) { - const GLint maxShift = 4 - vSize; - GLint shift, j; - for (shift = 0; shift <= maxShift; shift++) { - GLint matched = 0; - GLuint swizzle[4]; - swizzle[0] = swizzle[1] = swizzle[2] = swizzle[3] = 0; - /* XXX we could do out-of-order swizzle matches too, someday */ - for (j = 0; j < vSize; j++) { - assert(shift + j < 4); - if (paramList->ParameterValues[i][shift + j] == v[j]) { - matched++; - swizzle[j] = shift + j; - ASSERT(swizzle[j] >= SWIZZLE_X); - ASSERT(swizzle[j] <= SWIZZLE_W); - } - } - if (matched == vSize) { - /* found! */ - *posOut = i; - *swizzleOut = MAKE_SWIZZLE4(swizzle[0], swizzle[1], - swizzle[2], swizzle[3]); - return GL_TRUE; - } - } + switch (prog->Target) { + case GL_VERTEX_PROGRAM_ARB: + { + const struct gl_vertex_program *vp + = (const struct gl_vertex_program *) prog; + struct gl_vertex_program *vpc = (struct gl_vertex_program *) clone; + vpc->IsPositionInvariant = vp->IsPositionInvariant; } - } - - *posOut = -1; - return GL_FALSE; -} - - -struct gl_program_parameter_list * -_mesa_clone_parameter_list(const struct gl_program_parameter_list *list) -{ - struct gl_program_parameter_list *clone; - GLuint i; - - clone = _mesa_new_parameter_list(); - if (!clone) - return NULL; - - /** Not too efficient, but correct */ - for (i = 0; i < list->NumParameters; i++) { - struct gl_program_parameter *p = list->Parameters + i; - GLint j = _mesa_add_parameter(clone, p->Name, list->ParameterValues[i], - p->Size, p->Type); - ASSERT(j >= 0); - /* copy state indexes */ - if (p->Type == PROGRAM_STATE_VAR) { - GLint k; - struct gl_program_parameter *q = clone->Parameters + j; - for (k = 0; k < 6; k++) { - q->StateIndexes[k] = p->StateIndexes[k]; - } + break; + case GL_FRAGMENT_PROGRAM_ARB: + { + const struct gl_fragment_program *fp + = (const struct gl_fragment_program *) prog; + struct gl_fragment_program *fpc = (struct gl_fragment_program *) clone; + memcpy(fpc->TexturesUsed, fp->TexturesUsed, sizeof(fp->TexturesUsed)); + fpc->NumAluInstructions = fp->NumAluInstructions; + fpc->NumTexInstructions = fp->NumTexInstructions; + fpc->NumTexIndirections = fp->NumTexIndirections; + fpc->NumNativeAluInstructions = fp->NumNativeAluInstructions; + fpc->NumNativeTexInstructions = fp->NumNativeTexInstructions; + fpc->NumNativeTexIndirections = fp->NumNativeTexIndirections; + fpc->FogOption = fp->FogOption; + fpc->UsesKill = fp->UsesKill; } + break; + default: + _mesa_problem(NULL, "Unexpected target in _mesa_clone_program"); } return clone; } -/** - * Use the list of tokens in the state[] array to find global GL state - * and return it in . Usually, four values are returned in - * but matrix queries may return as many as 16 values. - * This function is used for ARB vertex/fragment programs. - * The program parser will produce the state[] values. - */ -static void -_mesa_fetch_state(GLcontext *ctx, const gl_state_index state[], - GLfloat *value) -{ - switch (state[0]) { - case STATE_MATERIAL: - { - /* state[1] is either 0=front or 1=back side */ - const GLuint face = (GLuint) state[1]; - const struct gl_material *mat = &ctx->Light.Material; - ASSERT(face == 0 || face == 1); - /* we rely on tokens numbered so that _BACK_ == _FRONT_+ 1 */ - ASSERT(MAT_ATTRIB_FRONT_AMBIENT + 1 == MAT_ATTRIB_BACK_AMBIENT); - /* XXX we could get rid of this switch entirely with a little - * work in arbprogparse.c's parse_state_single_item(). - */ - /* state[2] is the material attribute */ - switch (state[2]) { - case STATE_AMBIENT: - COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_AMBIENT + face]); - return; - case STATE_DIFFUSE: - COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_DIFFUSE + face]); - return; - case STATE_SPECULAR: - COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_SPECULAR + face]); - return; - case STATE_EMISSION: - COPY_4V(value, mat->Attrib[MAT_ATTRIB_FRONT_EMISSION + face]); - return; - case STATE_SHININESS: - value[0] = mat->Attrib[MAT_ATTRIB_FRONT_SHININESS + face][0]; - value[1] = 0.0F; - value[2] = 0.0F; - value[3] = 1.0F; - return; - default: - _mesa_problem(ctx, "Invalid material state in fetch_state"); - return; - } - } - case STATE_LIGHT: - { - /* state[1] is the light number */ - const GLuint ln = (GLuint) state[1]; - /* state[2] is the light attribute */ - switch (state[2]) { - case STATE_AMBIENT: - COPY_4V(value, ctx->Light.Light[ln].Ambient); - return; - case STATE_DIFFUSE: - COPY_4V(value, ctx->Light.Light[ln].Diffuse); - return; - case STATE_SPECULAR: - COPY_4V(value, ctx->Light.Light[ln].Specular); - return; - case STATE_POSITION: - COPY_4V(value, ctx->Light.Light[ln].EyePosition); - return; - case STATE_ATTENUATION: - value[0] = ctx->Light.Light[ln].ConstantAttenuation; - value[1] = ctx->Light.Light[ln].LinearAttenuation; - value[2] = ctx->Light.Light[ln].QuadraticAttenuation; - value[3] = ctx->Light.Light[ln].SpotExponent; - return; - case STATE_SPOT_DIRECTION: - COPY_3V(value, ctx->Light.Light[ln].EyeDirection); - value[3] = ctx->Light.Light[ln]._CosCutoff; - return; - case STATE_HALF: - { - GLfloat eye_z[] = {0, 0, 1}; - - /* Compute infinite half angle vector: - * half-vector = light_position + (0, 0, 1) - * and then normalize. w = 0 - * - * light.EyePosition.w should be 0 for infinite lights. - */ - ADD_3V(value, eye_z, ctx->Light.Light[ln].EyePosition); - NORMALIZE_3FV(value); - value[3] = 0; - } - return; - case STATE_POSITION_NORMALIZED: - COPY_4V(value, ctx->Light.Light[ln].EyePosition); - NORMALIZE_3FV( value ); - return; - default: - _mesa_problem(ctx, "Invalid light state in fetch_state"); - return; - } - } - case STATE_LIGHTMODEL_AMBIENT: - COPY_4V(value, ctx->Light.Model.Ambient); - return; - case STATE_LIGHTMODEL_SCENECOLOR: - if (state[1] == 0) { - /* front */ - GLint i; - for (i = 0; i < 3; i++) { - value[i] = ctx->Light.Model.Ambient[i] - * ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT][i] - + ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_EMISSION][i]; - } - value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE][3]; - } - else { - /* back */ - GLint i; - for (i = 0; i < 3; i++) { - value[i] = ctx->Light.Model.Ambient[i] - * ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_AMBIENT][i] - + ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_EMISSION][i]; - } - value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_DIFFUSE][3]; - } - return; - case STATE_LIGHTPROD: - { - const GLuint ln = (GLuint) state[1]; - const GLuint face = (GLuint) state[2]; - GLint i; - ASSERT(face == 0 || face == 1); - switch (state[3]) { - case STATE_AMBIENT: - for (i = 0; i < 3; i++) { - value[i] = ctx->Light.Light[ln].Ambient[i] * - ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_AMBIENT+face][i]; - } - /* [3] = material alpha */ - value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][3]; - return; - case STATE_DIFFUSE: - for (i = 0; i < 3; i++) { - value[i] = ctx->Light.Light[ln].Diffuse[i] * - ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][i]; - } - /* [3] = material alpha */ - value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][3]; - return; - case STATE_SPECULAR: - for (i = 0; i < 3; i++) { - value[i] = ctx->Light.Light[ln].Specular[i] * - ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_SPECULAR+face][i]; - } - /* [3] = material alpha */ - value[3] = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_DIFFUSE+face][3]; - return; - default: - _mesa_problem(ctx, "Invalid lightprod state in fetch_state"); - return; - } - } - case STATE_TEXGEN: - { - /* state[1] is the texture unit */ - const GLuint unit = (GLuint) state[1]; - /* state[2] is the texgen attribute */ - switch (state[2]) { - case STATE_TEXGEN_EYE_S: - COPY_4V(value, ctx->Texture.Unit[unit].EyePlaneS); - return; - case STATE_TEXGEN_EYE_T: - COPY_4V(value, ctx->Texture.Unit[unit].EyePlaneT); - return; - case STATE_TEXGEN_EYE_R: - COPY_4V(value, ctx->Texture.Unit[unit].EyePlaneR); - return; - case STATE_TEXGEN_EYE_Q: - COPY_4V(value, ctx->Texture.Unit[unit].EyePlaneQ); - return; - case STATE_TEXGEN_OBJECT_S: - COPY_4V(value, ctx->Texture.Unit[unit].ObjectPlaneS); - return; - case STATE_TEXGEN_OBJECT_T: - COPY_4V(value, ctx->Texture.Unit[unit].ObjectPlaneT); - return; - case STATE_TEXGEN_OBJECT_R: - COPY_4V(value, ctx->Texture.Unit[unit].ObjectPlaneR); - return; - case STATE_TEXGEN_OBJECT_Q: - COPY_4V(value, ctx->Texture.Unit[unit].ObjectPlaneQ); - return; - default: - _mesa_problem(ctx, "Invalid texgen state in fetch_state"); - return; - } - } - case STATE_TEXENV_COLOR: - { - /* state[1] is the texture unit */ - const GLuint unit = (GLuint) state[1]; - COPY_4V(value, ctx->Texture.Unit[unit].EnvColor); - } - return; - case STATE_FOG_COLOR: - COPY_4V(value, ctx->Fog.Color); - return; - case STATE_FOG_PARAMS: - value[0] = ctx->Fog.Density; - value[1] = ctx->Fog.Start; - value[2] = ctx->Fog.End; - value[3] = 1.0F / (ctx->Fog.End - ctx->Fog.Start); - return; - case STATE_CLIPPLANE: - { - const GLuint plane = (GLuint) state[1]; - COPY_4V(value, ctx->Transform.EyeUserPlane[plane]); - } - return; - case STATE_POINT_SIZE: - value[0] = ctx->Point.Size; - value[1] = ctx->Point.MinSize; - value[2] = ctx->Point.MaxSize; - value[3] = ctx->Point.Threshold; - return; - case STATE_POINT_ATTENUATION: - value[0] = ctx->Point.Params[0]; - value[1] = ctx->Point.Params[1]; - value[2] = ctx->Point.Params[2]; - value[3] = 1.0F; - return; - case STATE_MATRIX: - { - /* state[1] = modelview, projection, texture, etc. */ - /* state[2] = which texture matrix or program matrix */ - /* state[3] = first row to fetch */ - /* state[4] = last row to fetch */ - /* state[5] = transpose, inverse or invtrans */ - - const GLmatrix *matrix; - const gl_state_index mat = state[1]; - const GLuint index = (GLuint) state[2]; - const GLuint firstRow = (GLuint) state[3]; - const GLuint lastRow = (GLuint) state[4]; - const gl_state_index modifier = state[5]; - const GLfloat *m; - GLuint row, i; - if (mat == STATE_MODELVIEW) { - matrix = ctx->ModelviewMatrixStack.Top; - } - else if (mat == STATE_PROJECTION) { - matrix = ctx->ProjectionMatrixStack.Top; - } - else if (mat == STATE_MVP) { - matrix = &ctx->_ModelProjectMatrix; - } - else if (mat == STATE_TEXTURE) { - matrix = ctx->TextureMatrixStack[index].Top; - } - else if (mat == STATE_PROGRAM) { - matrix = ctx->ProgramMatrixStack[index].Top; - } - else { - _mesa_problem(ctx, "Bad matrix name in _mesa_fetch_state()"); - return; - } - if (modifier == STATE_MATRIX_INVERSE || - modifier == STATE_MATRIX_INVTRANS) { - /* Be sure inverse is up to date: - */ - _math_matrix_alloc_inv( (GLmatrix *) matrix ); - _math_matrix_analyse( (GLmatrix*) matrix ); - m = matrix->inv; - } - else { - m = matrix->m; - } - if (modifier == STATE_MATRIX_TRANSPOSE || - modifier == STATE_MATRIX_INVTRANS) { - for (i = 0, row = firstRow; row <= lastRow; row++) { - value[i++] = m[row * 4 + 0]; - value[i++] = m[row * 4 + 1]; - value[i++] = m[row * 4 + 2]; - value[i++] = m[row * 4 + 3]; - } - } - else { - for (i = 0, row = firstRow; row <= lastRow; row++) { - value[i++] = m[row + 0]; - value[i++] = m[row + 4]; - value[i++] = m[row + 8]; - value[i++] = m[row + 12]; - } - } - } - return; - case STATE_DEPTH_RANGE: - value[0] = ctx->Viewport.Near; /* near */ - value[1] = ctx->Viewport.Far; /* far */ - value[2] = ctx->Viewport.Far - ctx->Viewport.Near; /* far - near */ - value[3] = 0; - return; - case STATE_FRAGMENT_PROGRAM: - { - /* state[1] = {STATE_ENV, STATE_LOCAL} */ - /* state[2] = parameter index */ - const int idx = (int) state[2]; - switch (state[1]) { - case STATE_ENV: - COPY_4V(value, ctx->FragmentProgram.Parameters[idx]); - break; - case STATE_LOCAL: - COPY_4V(value, ctx->FragmentProgram.Current->Base.LocalParams[idx]); - break; - default: - _mesa_problem(ctx, "Bad state switch in _mesa_fetch_state()"); - return; - } - } - return; - - case STATE_VERTEX_PROGRAM: - { - /* state[1] = {STATE_ENV, STATE_LOCAL} */ - /* state[2] = parameter index */ - const int idx = (int) state[2]; - switch (state[1]) { - case STATE_ENV: - COPY_4V(value, ctx->VertexProgram.Parameters[idx]); - break; - case STATE_LOCAL: - COPY_4V(value, ctx->VertexProgram.Current->Base.LocalParams[idx]); - break; - default: - _mesa_problem(ctx, "Bad state switch in _mesa_fetch_state()"); - return; - } - } - return; - - case STATE_INTERNAL: - { - switch (state[1]) { - case STATE_NORMAL_SCALE: - ASSIGN_4V(value, ctx->_ModelViewInvScale, 0, 0, 1); - break; - case STATE_TEXRECT_SCALE: { - const int unit = (int) state[2]; - const struct gl_texture_object *texObj = ctx->Texture.Unit[unit]._Current; - if (texObj) { - struct gl_texture_image *texImage = texObj->Image[0][0]; - ASSIGN_4V(value, 1.0 / texImage->Width, 1.0 / texImage->Height, 0, 1); - } - break; - } - default: - /* unknown state indexes are silently ignored - * should be handled by the driver. - */ - return; - } - } - return; - - default: - _mesa_problem(ctx, "Invalid state in _mesa_fetch_state"); - return; - } -} - - -/** - * Return a bitmask of the Mesa state flags (_NEW_* values) which would - * indicate that the given context state may have changed. - * The bitmask is used during validation to determine if we need to update - * vertex/fragment program parameters (like "state.material.color") when - * some GL state has changed. - */ -static GLbitfield -make_state_flags(const GLint state[]) -{ - switch (state[0]) { - case STATE_MATERIAL: - case STATE_LIGHT: - case STATE_LIGHTMODEL_AMBIENT: - case STATE_LIGHTMODEL_SCENECOLOR: - case STATE_LIGHTPROD: - return _NEW_LIGHT; - - case STATE_TEXGEN: - case STATE_TEXENV_COLOR: - return _NEW_TEXTURE; - - case STATE_FOG_COLOR: - case STATE_FOG_PARAMS: - return _NEW_FOG; - - case STATE_CLIPPLANE: - return _NEW_TRANSFORM; - - case STATE_POINT_SIZE: - case STATE_POINT_ATTENUATION: - return _NEW_POINT; - - case STATE_MATRIX: - switch (state[1]) { - case STATE_MODELVIEW: - return _NEW_MODELVIEW; - case STATE_PROJECTION: - return _NEW_PROJECTION; - case STATE_MVP: - return _NEW_MODELVIEW | _NEW_PROJECTION; - case STATE_TEXTURE: - return _NEW_TEXTURE_MATRIX; - case STATE_PROGRAM: - return _NEW_TRACK_MATRIX; - default: - _mesa_problem(NULL, "unexpected matrix in make_state_flags()"); - return 0; - } - - case STATE_DEPTH_RANGE: - return _NEW_VIEWPORT; - - case STATE_FRAGMENT_PROGRAM: - case STATE_VERTEX_PROGRAM: - return _NEW_PROGRAM; - - case STATE_INTERNAL: - switch (state[1]) { - case STATE_NORMAL_SCALE: - return _NEW_MODELVIEW; - case STATE_TEXRECT_SCALE: - return _NEW_TEXTURE; - default: - /* unknown state indexes are silently ignored and - * no flag set, since it is handled by the driver. - */ - return 0; - } - - default: - _mesa_problem(NULL, "unexpected state[0] in make_state_flags()"); - return 0; - } -} - - -static void -append(char *dst, const char *src) -{ - while (*dst) - dst++; - while (*src) - *dst++ = *src++; - *dst = 0; -} - - -static void -append_token(char *dst, gl_state_index k) -{ - switch (k) { - case STATE_MATERIAL: - append(dst, "material."); - break; - case STATE_LIGHT: - append(dst, "light"); - break; - case STATE_LIGHTMODEL_AMBIENT: - append(dst, "lightmodel.ambient"); - break; - case STATE_LIGHTMODEL_SCENECOLOR: - break; - case STATE_LIGHTPROD: - append(dst, "lightprod"); - break; - case STATE_TEXGEN: - append(dst, "texgen"); - break; - case STATE_FOG_COLOR: - append(dst, "fog.color"); - break; - case STATE_FOG_PARAMS: - append(dst, "fog.params"); - break; - case STATE_CLIPPLANE: - append(dst, "clip"); - break; - case STATE_POINT_SIZE: - append(dst, "point.size"); - break; - case STATE_POINT_ATTENUATION: - append(dst, "point.attenuation"); - break; - case STATE_MATRIX: - append(dst, "matrix."); - break; - case STATE_MODELVIEW: - append(dst, "modelview"); - break; - case STATE_PROJECTION: - append(dst, "projection"); - break; - case STATE_MVP: - append(dst, "mvp"); - break; - case STATE_TEXTURE: - append(dst, "texture"); - break; - case STATE_PROGRAM: - append(dst, "program"); - break; - case STATE_MATRIX_INVERSE: - append(dst, ".inverse"); - break; - case STATE_MATRIX_TRANSPOSE: - append(dst, ".transpose"); - break; - case STATE_MATRIX_INVTRANS: - append(dst, ".invtrans"); - break; - case STATE_AMBIENT: - append(dst, "ambient"); - break; - case STATE_DIFFUSE: - append(dst, "diffuse"); - break; - case STATE_SPECULAR: - append(dst, "specular"); - break; - case STATE_EMISSION: - append(dst, "emission"); - break; - case STATE_SHININESS: - append(dst, "shininess"); - break; - case STATE_HALF: - append(dst, "half"); - break; - case STATE_POSITION: - append(dst, ".position"); - break; - case STATE_ATTENUATION: - append(dst, ".attenuation"); - break; - case STATE_SPOT_DIRECTION: - append(dst, ".spot.direction"); - break; - case STATE_TEXGEN_EYE_S: - append(dst, "eye.s"); - break; - case STATE_TEXGEN_EYE_T: - append(dst, "eye.t"); - break; - case STATE_TEXGEN_EYE_R: - append(dst, "eye.r"); - break; - case STATE_TEXGEN_EYE_Q: - append(dst, "eye.q"); - break; - case STATE_TEXGEN_OBJECT_S: - append(dst, "object.s"); - break; - case STATE_TEXGEN_OBJECT_T: - append(dst, "object.t"); - break; - case STATE_TEXGEN_OBJECT_R: - append(dst, "object.r"); - break; - case STATE_TEXGEN_OBJECT_Q: - append(dst, "object.q"); - break; - case STATE_TEXENV_COLOR: - append(dst, "texenv"); - break; - case STATE_DEPTH_RANGE: - append(dst, "depth.range"); - break; - case STATE_VERTEX_PROGRAM: - case STATE_FRAGMENT_PROGRAM: - break; - case STATE_ENV: - append(dst, "env"); - break; - case STATE_LOCAL: - append(dst, "local"); - break; - case STATE_INTERNAL: - case STATE_NORMAL_SCALE: - case STATE_POSITION_NORMALIZED: - append(dst, "(internal)"); - break; - default: - ; - } -} - -static void -append_face(char *dst, GLint face) -{ - if (face == 0) - append(dst, "front."); - else - append(dst, "back."); -} - -static void -append_index(char *dst, GLint index) -{ - char s[20]; - _mesa_sprintf(s, "[%d].", index); - append(dst, s); -} - -/** - * Make a string from the given state vector. - * For example, return "state.matrix.texture[2].inverse". - * Use _mesa_free() to deallocate the string. - */ -static const char * -make_state_string(const GLint state[6]) -{ - char str[1000] = ""; - char tmp[30]; - - append(str, "state."); - append_token(str, (gl_state_index) state[0]); - - switch (state[0]) { - case STATE_MATERIAL: - append_face(str, state[1]); - append_token(str, (gl_state_index) state[2]); - break; - case STATE_LIGHT: - append(str, "light"); - append_index(str, state[1]); /* light number [i]. */ - append_token(str, (gl_state_index) state[2]); /* coefficients */ - break; - case STATE_LIGHTMODEL_AMBIENT: - append(str, "lightmodel.ambient"); - break; - case STATE_LIGHTMODEL_SCENECOLOR: - if (state[1] == 0) { - append(str, "lightmodel.front.scenecolor"); - } - else { - append(str, "lightmodel.back.scenecolor"); - } - break; - case STATE_LIGHTPROD: - append_index(str, state[1]); /* light number [i]. */ - append_face(str, state[2]); - append_token(str, (gl_state_index) state[3]); - break; - case STATE_TEXGEN: - append_index(str, state[1]); /* tex unit [i] */ - append_token(str, (gl_state_index) state[2]); /* plane coef */ - break; - case STATE_TEXENV_COLOR: - append_index(str, state[1]); /* tex unit [i] */ - append(str, "color"); - break; - case STATE_FOG_COLOR: - case STATE_FOG_PARAMS: - break; - case STATE_CLIPPLANE: - append_index(str, state[1]); /* plane [i] */ - append(str, "plane"); - break; - case STATE_POINT_SIZE: - case STATE_POINT_ATTENUATION: - break; - case STATE_MATRIX: - { - /* state[1] = modelview, projection, texture, etc. */ - /* state[2] = which texture matrix or program matrix */ - /* state[3] = first row to fetch */ - /* state[4] = last row to fetch */ - /* state[5] = transpose, inverse or invtrans */ - const gl_state_index mat = (gl_state_index) state[1]; - const GLuint index = (GLuint) state[2]; - const GLuint firstRow = (GLuint) state[3]; - const GLuint lastRow = (GLuint) state[4]; - const gl_state_index modifier = (gl_state_index) state[5]; - append_token(str, mat); - if (index) - append_index(str, index); - if (modifier) - append_token(str, modifier); - if (firstRow == lastRow) - _mesa_sprintf(tmp, ".row[%d]", firstRow); - else - _mesa_sprintf(tmp, ".row[%d..%d]", firstRow, lastRow); - append(str, tmp); - } - break; - case STATE_DEPTH_RANGE: - break; - case STATE_FRAGMENT_PROGRAM: - case STATE_VERTEX_PROGRAM: - /* state[1] = {STATE_ENV, STATE_LOCAL} */ - /* state[2] = parameter index */ - append_token(str, (gl_state_index) state[1]); - append_index(str, state[2]); - break; - case STATE_INTERNAL: - break; - default: - _mesa_problem(NULL, "Invalid state in make_state_string"); - break; - } - - return _mesa_strdup(str); -} - - -/** - * Loop over all the parameters in a parameter list. If the parameter - * is a GL state reference, look up the current value of that state - * variable and put it into the parameter's Value[4] array. - * This would be called at glBegin time when using a fragment program. - */ -void -_mesa_load_state_parameters(GLcontext *ctx, - struct gl_program_parameter_list *paramList) -{ - GLuint i; - - if (!paramList) - return; - - for (i = 0; i < paramList->NumParameters; i++) { - if (paramList->Parameters[i].Type == PROGRAM_STATE_VAR) { - _mesa_fetch_state(ctx, - paramList->Parameters[i].StateIndexes, - paramList->ParameterValues[i]); - } - } -} - - -/** - * Initialize program instruction fields to defaults. - * \param inst first instruction to initialize - * \param count number of instructions to initialize - */ -void -_mesa_init_instructions(struct prog_instruction *inst, GLuint count) -{ - GLuint i; - - _mesa_bzero(inst, count * sizeof(struct prog_instruction)); - - for (i = 0; i < count; i++) { - inst[i].SrcReg[0].File = PROGRAM_UNDEFINED; - inst[i].SrcReg[0].Swizzle = SWIZZLE_NOOP; - inst[i].SrcReg[1].File = PROGRAM_UNDEFINED; - inst[i].SrcReg[1].Swizzle = SWIZZLE_NOOP; - inst[i].SrcReg[2].File = PROGRAM_UNDEFINED; - inst[i].SrcReg[2].Swizzle = SWIZZLE_NOOP; - - inst[i].DstReg.File = PROGRAM_UNDEFINED; - inst[i].DstReg.WriteMask = WRITEMASK_XYZW; - inst[i].DstReg.CondMask = COND_TR; - inst[i].DstReg.CondSwizzle = SWIZZLE_NOOP; - - inst[i].SaturateMode = SATURATE_OFF; - inst[i].Precision = FLOAT32; - } -} - - -/** - * Allocate an array of program instructions. - * \param numInst number of instructions - * \return pointer to instruction memory - */ -struct prog_instruction * -_mesa_alloc_instructions(GLuint numInst) -{ - return (struct prog_instruction *) - _mesa_calloc(numInst * sizeof(struct prog_instruction)); -} - - -/** - * Reallocate memory storing an array of program instructions. - * This is used when we need to append additional instructions onto an - * program. - * \param oldInst pointer to first of old/src instructions - * \param numOldInst number of instructions at - * \param numNewInst desired size of new instruction array. - * \return pointer to start of new instruction array. - */ -struct prog_instruction * -_mesa_realloc_instructions(struct prog_instruction *oldInst, - GLuint numOldInst, GLuint numNewInst) -{ - struct prog_instruction *newInst; - - newInst = (struct prog_instruction *) - _mesa_realloc(oldInst, - numOldInst * sizeof(struct prog_instruction), - numNewInst * sizeof(struct prog_instruction)); - - return newInst; -} - - -/** - * Return a copy of a program. - * XXX Problem here if the program object is actually OO-derivation - * made by a device driver. - */ -struct gl_program * -_mesa_clone_program(GLcontext *ctx, const struct gl_program *prog) -{ - struct gl_program *clone; - - clone = _mesa_new_program(ctx, prog->Target, prog->Id); - if (!clone) - return NULL; - - assert(clone->Target == prog->Target); - clone->String = (GLubyte *) _mesa_strdup((char *) prog->String); - clone->RefCount = 1; - clone->Format = prog->Format; - clone->Instructions = _mesa_alloc_instructions(prog->NumInstructions); - if (!clone->Instructions) { - _mesa_delete_program(ctx, clone); - return NULL; - } - memcpy(clone->Instructions, prog->Instructions, - prog->NumInstructions * sizeof(struct prog_instruction)); - clone->InputsRead = prog->InputsRead; - clone->OutputsWritten = prog->OutputsWritten; - clone->Parameters = _mesa_clone_parameter_list(prog->Parameters); - memcpy(clone->LocalParams, prog->LocalParams, sizeof(clone->LocalParams)); - clone->Varying = _mesa_clone_parameter_list(prog->Varying); - memcpy(clone->LocalParams, prog->LocalParams, sizeof(clone->LocalParams)); - clone->NumInstructions = prog->NumInstructions; - clone->NumTemporaries = prog->NumTemporaries; - clone->NumParameters = prog->NumParameters; - clone->NumAttributes = prog->NumAttributes; - clone->NumAddressRegs = prog->NumAddressRegs; - clone->NumNativeInstructions = prog->NumNativeInstructions; - clone->NumNativeTemporaries = prog->NumNativeTemporaries; - clone->NumNativeParameters = prog->NumNativeParameters; - clone->NumNativeAttributes = prog->NumNativeAttributes; - clone->NumNativeAddressRegs = prog->NumNativeAddressRegs; - - switch (prog->Target) { - case GL_VERTEX_PROGRAM_ARB: - { - const struct gl_vertex_program *vp - = (const struct gl_vertex_program *) prog; - struct gl_vertex_program *vpc = (struct gl_vertex_program *) clone; - vpc->IsPositionInvariant = vp->IsPositionInvariant; - } - break; - case GL_FRAGMENT_PROGRAM_ARB: - { - const struct gl_fragment_program *fp - = (const struct gl_fragment_program *) prog; - struct gl_fragment_program *fpc = (struct gl_fragment_program *) clone; - memcpy(fpc->TexturesUsed, fp->TexturesUsed, sizeof(fp->TexturesUsed)); - fpc->NumAluInstructions = fp->NumAluInstructions; - fpc->NumTexInstructions = fp->NumTexInstructions; - fpc->NumTexIndirections = fp->NumTexIndirections; - fpc->NumNativeAluInstructions = fp->NumNativeAluInstructions; - fpc->NumNativeTexInstructions = fp->NumNativeTexInstructions; - fpc->NumNativeTexIndirections = fp->NumNativeTexIndirections; - fpc->FogOption = fp->FogOption; - fpc->UsesKill = fp->UsesKill; - } - break; - default: - _mesa_problem(NULL, "Unexpected target in _mesa_clone_program"); - } - - return clone; -} - - - -/** - * Basic info about each instruction - */ -struct instruction_info -{ - gl_inst_opcode Opcode; - const char *Name; - GLuint NumSrcRegs; -}; - -/** - * Instruction info - * \note Opcode should equal array index! - */ -static const struct instruction_info InstInfo[MAX_OPCODE] = { - { OPCODE_NOP, "NOP", 0 }, - { OPCODE_ABS, "ABS", 1 }, - { OPCODE_ADD, "ADD", 2 }, - { OPCODE_ARA, "ARA", 1 }, - { OPCODE_ARL, "ARL", 1 }, - { OPCODE_ARL_NV, "ARL", 1 }, - { OPCODE_ARR, "ARL", 1 }, - { OPCODE_BRA, "BRA", 0 }, - { OPCODE_CAL, "CAL", 0 }, - { OPCODE_CMP, "CMP", 3 }, - { OPCODE_COS, "COS", 1 }, - { OPCODE_DDX, "DDX", 1 }, - { OPCODE_DDY, "DDY", 1 }, - { OPCODE_DP3, "DP3", 2 }, - { OPCODE_DP4, "DP4", 2 }, - { OPCODE_DPH, "DPH", 2 }, - { OPCODE_DST, "DST", 2 }, - { OPCODE_END, "END", 0 }, - { OPCODE_EX2, "EX2", 1 }, - { OPCODE_EXP, "EXP", 1 }, - { OPCODE_FLR, "FLR", 1 }, - { OPCODE_FRC, "FRC", 1 }, - { OPCODE_KIL, "KIL", 1 }, - { OPCODE_KIL_NV, "KIL", 0 }, - { OPCODE_LG2, "LG2", 1 }, - { OPCODE_LIT, "LIT", 1 }, - { OPCODE_LOG, "LOG", 1 }, - { OPCODE_LRP, "LRP", 3 }, - { OPCODE_MAD, "MAD", 3 }, - { OPCODE_MAX, "MAX", 2 }, - { OPCODE_MIN, "MIN", 2 }, - { OPCODE_MOV, "MOV", 1 }, - { OPCODE_MUL, "MUL", 2 }, - { OPCODE_PK2H, "PK2H", 1 }, - { OPCODE_PK2US, "PK2US", 1 }, - { OPCODE_PK4B, "PK4B", 1 }, - { OPCODE_PK4UB, "PK4UB", 1 }, - { OPCODE_POW, "POW", 2 }, - { OPCODE_POPA, "POPA", 0 }, - { OPCODE_PRINT, "PRINT", 1 }, - { OPCODE_PUSHA, "PUSHA", 0 }, - { OPCODE_RCC, "RCC", 1 }, - { OPCODE_RCP, "RCP", 1 }, - { OPCODE_RET, "RET", 0 }, - { OPCODE_RFL, "RFL", 1 }, - { OPCODE_RSQ, "RSQ", 1 }, - { OPCODE_SCS, "SCS", 1 }, - { OPCODE_SEQ, "SEQ", 2 }, - { OPCODE_SFL, "SFL", 0 }, - { OPCODE_SGE, "SGE", 2 }, - { OPCODE_SGT, "SGT", 2 }, - { OPCODE_SIN, "SIN", 1 }, - { OPCODE_SLE, "SLE", 2 }, - { OPCODE_SLT, "SLT", 2 }, - { OPCODE_SNE, "SNE", 2 }, - { OPCODE_SSG, "SSG", 1 }, - { OPCODE_STR, "STR", 0 }, - { OPCODE_SUB, "SUB", 2 }, - { OPCODE_SWZ, "SWZ", 1 }, - { OPCODE_TEX, "TEX", 1 }, - { OPCODE_TXB, "TXB", 1 }, - { OPCODE_TXD, "TXD", 3 }, - { OPCODE_TXL, "TXL", 1 }, - { OPCODE_TXP, "TXP", 1 }, - { OPCODE_TXP_NV, "TXP", 1 }, - { OPCODE_UP2H, "UP2H", 1 }, - { OPCODE_UP2US, "UP2US", 1 }, - { OPCODE_UP4B, "UP4B", 1 }, - { OPCODE_UP4UB, "UP4UB", 1 }, - { OPCODE_X2D, "X2D", 3 }, - { OPCODE_XPD, "XPD", 2 } -}; - - -/** - * Return the number of src registers for the given instruction/opcode. - */ -GLuint -_mesa_num_inst_src_regs(gl_inst_opcode opcode) -{ - ASSERT(opcode == InstInfo[opcode].Opcode); - ASSERT(OPCODE_XPD == InstInfo[OPCODE_XPD].Opcode); - return InstInfo[opcode].NumSrcRegs; -} - - -/** - * Return string name for given program opcode. - */ -const char * -_mesa_opcode_string(gl_inst_opcode opcode) -{ - ASSERT(opcode < MAX_OPCODE); - return InstInfo[opcode].Name; -} - -/** - * Return string name for given program/register file. - */ -static const char * -program_file_string(enum register_file f) -{ - switch (f) { - case PROGRAM_TEMPORARY: - return "TEMP"; - case PROGRAM_LOCAL_PARAM: - return "LOCAL"; - case PROGRAM_ENV_PARAM: - return "ENV"; - case PROGRAM_STATE_VAR: - return "STATE"; - case PROGRAM_INPUT: - return "INPUT"; - case PROGRAM_OUTPUT: - return "OUTPUT"; - case PROGRAM_NAMED_PARAM: - return "NAMED"; - case PROGRAM_CONSTANT: - return "CONST"; - case PROGRAM_UNIFORM: - return "UNIFORM"; - case PROGRAM_VARYING: - return "VARYING"; - case PROGRAM_WRITE_ONLY: - return "WRITE_ONLY"; - case PROGRAM_ADDRESS: - return "ADDR"; - default: - return "Unknown program file!"; - } -} - - -/** - * Return a string representation of the given swizzle word. - * If extended is true, use extended (comma-separated) format. - */ -static const char * -swizzle_string(GLuint swizzle, GLuint negateBase, GLboolean extended) -{ - static const char swz[] = "xyzw01"; - static char s[20]; - GLuint i = 0; - - if (!extended && swizzle == SWIZZLE_NOOP && negateBase == 0) - return ""; /* no swizzle/negation */ - - if (!extended) - s[i++] = '.'; - - if (negateBase & 0x1) - s[i++] = '-'; - s[i++] = swz[GET_SWZ(swizzle, 0)]; - - if (extended) { - s[i++] = ','; - } - - if (negateBase & 0x2) - s[i++] = '-'; - s[i++] = swz[GET_SWZ(swizzle, 1)]; - - if (extended) { - s[i++] = ','; - } - - if (negateBase & 0x4) - s[i++] = '-'; - s[i++] = swz[GET_SWZ(swizzle, 2)]; - - if (extended) { - s[i++] = ','; - } - - if (negateBase & 0x8) - s[i++] = '-'; - s[i++] = swz[GET_SWZ(swizzle, 3)]; - - s[i] = 0; - return s; -} - - -static const char * -writemask_string(GLuint writeMask) -{ - static char s[10]; - GLuint i = 0; - - if (writeMask == WRITEMASK_XYZW) - return ""; - - s[i++] = '.'; - if (writeMask & WRITEMASK_X) - s[i++] = 'x'; - if (writeMask & WRITEMASK_Y) - s[i++] = 'y'; - if (writeMask & WRITEMASK_Z) - s[i++] = 'z'; - if (writeMask & WRITEMASK_W) - s[i++] = 'w'; - - s[i] = 0; - return s; -} - -static void -print_dst_reg(const struct prog_dst_register *dstReg) -{ - _mesa_printf(" %s[%d]%s", - program_file_string((enum register_file) dstReg->File), - dstReg->Index, - writemask_string(dstReg->WriteMask)); -} - -static void -print_src_reg(const struct prog_src_register *srcReg) -{ - _mesa_printf("%s[%d]%s", - program_file_string((enum register_file) srcReg->File), - srcReg->Index, - swizzle_string(srcReg->Swizzle, - srcReg->NegateBase, GL_FALSE)); -} - -static void -print_comment(const struct prog_instruction *inst) -{ - if (inst->Comment) - _mesa_printf("; # %s\n", inst->Comment); - else - _mesa_printf(";\n"); -} - - -void -_mesa_print_alu_instruction(const struct prog_instruction *inst, - const char *opcode_string, - GLuint numRegs) -{ - GLuint j; - - _mesa_printf("%s", opcode_string); - - /* frag prog only */ - if (inst->SaturateMode == SATURATE_ZERO_ONE) - _mesa_printf("_SAT"); - - if (inst->DstReg.File != PROGRAM_UNDEFINED) { - _mesa_printf(" %s[%d]%s", - program_file_string((enum register_file) inst->DstReg.File), - inst->DstReg.Index, - writemask_string(inst->DstReg.WriteMask)); - } - else { - _mesa_printf(" ???"); - } - - if (numRegs > 0) - _mesa_printf(", "); - - for (j = 0; j < numRegs; j++) { - print_src_reg(inst->SrcReg + j); - if (j + 1 < numRegs) - _mesa_printf(", "); - } - - if (inst->Comment) - _mesa_printf(" # %s", inst->Comment); - - print_comment(inst); -} - - -/** - * Print a single vertex/fragment program instruction. - */ -void -_mesa_print_instruction(const struct prog_instruction *inst) -{ - switch (inst->Opcode) { - case OPCODE_PRINT: - _mesa_printf("PRINT '%s'", inst->Data); - if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) { - _mesa_printf(", "); - _mesa_printf("%s[%d]%s", - program_file_string((enum register_file) inst->SrcReg[0].File), - inst->SrcReg[0].Index, - swizzle_string(inst->SrcReg[0].Swizzle, - inst->SrcReg[0].NegateBase, GL_FALSE)); - } - if (inst->Comment) - _mesa_printf(" # %s", inst->Comment); - print_comment(inst); - break; - case OPCODE_SWZ: - _mesa_printf("SWZ"); - if (inst->SaturateMode == SATURATE_ZERO_ONE) - _mesa_printf("_SAT"); - print_dst_reg(&inst->DstReg); - _mesa_printf("%s[%d], %s", - program_file_string((enum register_file) inst->SrcReg[0].File), - inst->SrcReg[0].Index, - swizzle_string(inst->SrcReg[0].Swizzle, - inst->SrcReg[0].NegateBase, GL_TRUE)); - print_comment(inst); - break; - case OPCODE_TEX: - case OPCODE_TXP: - case OPCODE_TXB: - _mesa_printf("%s", _mesa_opcode_string(inst->Opcode)); - if (inst->SaturateMode == SATURATE_ZERO_ONE) - _mesa_printf("_SAT"); - _mesa_printf(" "); - print_dst_reg(&inst->DstReg); - _mesa_printf(", "); - print_src_reg(&inst->SrcReg[0]); - _mesa_printf(", texture[%d], ", inst->TexSrcUnit); - switch (inst->TexSrcTarget) { - case TEXTURE_1D_INDEX: _mesa_printf("1D"); break; - case TEXTURE_2D_INDEX: _mesa_printf("2D"); break; - case TEXTURE_3D_INDEX: _mesa_printf("3D"); break; - case TEXTURE_CUBE_INDEX: _mesa_printf("CUBE"); break; - case TEXTURE_RECT_INDEX: _mesa_printf("RECT"); break; - default: - ; - } - print_comment(inst); - break; - case OPCODE_ARL: - _mesa_printf("ARL addr.x, "); - print_src_reg(&inst->SrcReg[0]); - print_comment(inst); - break; - case OPCODE_BRA: - _mesa_printf("BRA %u", inst->BranchTarget); - print_comment(inst); - break; - case OPCODE_CAL: - _mesa_printf("CAL %u", inst->BranchTarget); - print_comment(inst); - break; - case OPCODE_END: - _mesa_printf("END"); - print_comment(inst); - break; - /* XXX may need other special-case instructions */ - default: - /* typical alu instruction */ - _mesa_print_alu_instruction(inst, - _mesa_opcode_string(inst->Opcode), - _mesa_num_inst_src_regs(inst->Opcode)); - break; - } -} - - -/** - * Print a vertx/fragment program to stdout. - * XXX this function could be greatly improved. - */ -void -_mesa_print_program(const struct gl_program *prog) -{ - GLuint i; - for (i = 0; i < prog->NumInstructions; i++) { - _mesa_printf("%3d: ", i); - _mesa_print_instruction(prog->Instructions + i); - } -} - - -/** - * Print all of a program's parameters. - */ -void -_mesa_print_program_parameters(GLcontext *ctx, const struct gl_program *prog) -{ - GLint i; - - _mesa_printf("NumInstructions=%d\n", prog->NumInstructions); - _mesa_printf("NumTemporaries=%d\n", prog->NumTemporaries); - _mesa_printf("NumParameters=%d\n", prog->NumParameters); - _mesa_printf("NumAttributes=%d\n", prog->NumAttributes); - _mesa_printf("NumAddressRegs=%d\n", prog->NumAddressRegs); - - _mesa_load_state_parameters(ctx, prog->Parameters); - -#if 0 - _mesa_printf("Local Params:\n"); - for (i = 0; i < MAX_PROGRAM_LOCAL_PARAMS; i++){ - const GLfloat *p = prog->LocalParams[i]; - _mesa_printf("%2d: %f, %f, %f, %f\n", i, p[0], p[1], p[2], p[3]); - } -#endif - - for (i = 0; i < prog->Parameters->NumParameters; i++){ - struct gl_program_parameter *param = prog->Parameters->Parameters + i; - const GLfloat *v = prog->Parameters->ParameterValues[i]; - _mesa_printf("param[%d] %s %s = {%.3f, %.3f, %.3f, %.3f};\n", - i, - program_file_string(prog->Parameters->Parameters[i].Type), - param->Name, v[0], v[1], v[2], v[3]); - } -} - /** * Mixing ARB and NV vertex/fragment programs can be tricky. diff --git a/src/mesa/shader/program.h b/src/mesa/shader/program.h index 98e2b53602..34485776e9 100644 --- a/src/mesa/shader/program.h +++ b/src/mesa/shader/program.h @@ -43,37 +43,6 @@ #include "mtypes.h" -/* for GL_ARB_v_p and GL_ARB_f_p SWZ instruction */ -#define SWIZZLE_X 0 -#define SWIZZLE_Y 1 -#define SWIZZLE_Z 2 -#define SWIZZLE_W 3 -#define SWIZZLE_ZERO 4 /* keep these values together: KW */ -#define SWIZZLE_ONE 5 /* keep these values together: KW */ - -#define MAKE_SWIZZLE4(a,b,c,d) (((a)<<0) | ((b)<<3) | ((c)<<6) | ((d)<<9)) -#define SWIZZLE_NOOP MAKE_SWIZZLE4(0,1,2,3) -#define GET_SWZ(swz, idx) (((swz) >> ((idx)*3)) & 0x7) -#define GET_BIT(msk, idx) (((msk) >> (idx)) & 0x1) - - -#define WRITEMASK_X 0x1 -#define WRITEMASK_Y 0x2 -#define WRITEMASK_XY 0x3 -#define WRITEMASK_Z 0x4 -#define WRITEMASK_XZ 0x5 -#define WRITEMASK_YZ 0x6 -#define WRITEMASK_XYZ 0x7 -#define WRITEMASK_W 0x8 -#define WRITEMASK_XW 0x9 -#define WRITEMASK_YW 0xa -#define WRITEMASK_XYW 0xb -#define WRITEMASK_ZW 0xc -#define WRITEMASK_XZW 0xd -#define WRITEMASK_YZW 0xe -#define WRITEMASK_XYZW 0xf - - extern struct gl_program _mesa_DummyProgram; @@ -125,179 +94,7 @@ extern struct gl_program * _mesa_clone_program(GLcontext *ctx, const struct gl_program *prog); -/** - * Used for describing GL state referenced from inside ARB vertex and - * fragment programs. - * A string such as "state.light[0].ambient" gets translated into a - * sequence of tokens such as [ STATE_LIGHT, 0, STATE_AMBIENT ]. - */ -typedef enum gl_state_index_ { - STATE_MATERIAL = 100, /* start at 100 so small ints are seen as ints */ - - STATE_LIGHT, - STATE_LIGHTMODEL_AMBIENT, - STATE_LIGHTMODEL_SCENECOLOR, - STATE_LIGHTPROD, - - STATE_TEXGEN, - - STATE_FOG_COLOR, - STATE_FOG_PARAMS, - - STATE_CLIPPLANE, - - STATE_POINT_SIZE, - STATE_POINT_ATTENUATION, - - STATE_MATRIX, - STATE_MODELVIEW, - STATE_PROJECTION, - STATE_MVP, - STATE_TEXTURE, - STATE_PROGRAM, - STATE_MATRIX_INVERSE, - STATE_MATRIX_TRANSPOSE, - STATE_MATRIX_INVTRANS, - - STATE_AMBIENT, - STATE_DIFFUSE, - STATE_SPECULAR, - STATE_EMISSION, - STATE_SHININESS, - STATE_HALF, - - STATE_POSITION, - STATE_ATTENUATION, - STATE_SPOT_DIRECTION, - - STATE_TEXGEN_EYE_S, - STATE_TEXGEN_EYE_T, - STATE_TEXGEN_EYE_R, - STATE_TEXGEN_EYE_Q, - STATE_TEXGEN_OBJECT_S, - STATE_TEXGEN_OBJECT_T, - STATE_TEXGEN_OBJECT_R, - STATE_TEXGEN_OBJECT_Q, - - STATE_TEXENV_COLOR, - - STATE_DEPTH_RANGE, - - STATE_VERTEX_PROGRAM, - STATE_FRAGMENT_PROGRAM, - - STATE_ENV, - STATE_LOCAL, - - STATE_INTERNAL, /* Mesa additions */ - STATE_NORMAL_SCALE, - STATE_TEXRECT_SCALE, - STATE_POSITION_NORMALIZED, /* normalized light position */ - STATE_INTERNAL_DRIVER /* first available state index for drivers (must be last) */ -} gl_state_index; - - - -/** - * Named program parameters - * Used for NV_fragment_program "DEFINE"d constants and "DECLARE"d parameters, - * and ARB_fragment_program global state references. For the later, Name - * might be "state.light[0].diffuse", for example. - */ -struct gl_program_parameter -{ - const char *Name; /**< Null-terminated string */ - enum register_file Type; /**< PROGRAM_NAMED_PARAM, CONSTANT or STATE_VAR */ - GLuint Size; /**< Number of components (1..4) */ - /** - * A sequence of STATE_* tokens and integers to identify GL state. - */ - gl_state_index StateIndexes[6]; -}; - - -/** - * A list of the above program_parameter instances. - */ -struct gl_program_parameter_list -{ - GLuint Size; /**< allocated size of Parameters, ParameterValues */ - GLuint NumParameters; /**< number of parameters in arrays */ - struct gl_program_parameter *Parameters; /**< Array [Size] */ - GLfloat (*ParameterValues)[4]; /**< Array [Size] of GLfloat[4] */ - GLbitfield StateFlags; /**< _NEW_* flags indicating which state changes - might invalidate ParameterValues[] */ -}; - - -/* - * Program parameter functions - */ - -extern struct gl_program_parameter_list * -_mesa_new_parameter_list(void); - -extern void -_mesa_free_parameter_list(struct gl_program_parameter_list *paramList); - -extern struct gl_program_parameter_list * -_mesa_clone_parameter_list(const struct gl_program_parameter_list *list); - -extern GLint -_mesa_add_parameter(struct gl_program_parameter_list *paramList, - const char *name, const GLfloat values[4], GLuint size, - enum register_file type); - -extern GLint -_mesa_add_named_parameter(struct gl_program_parameter_list *paramList, - const char *name, const GLfloat values[4]); - -extern GLint -_mesa_add_named_constant(struct gl_program_parameter_list *paramList, - const char *name, const GLfloat values[4], - GLuint size); - -extern GLint -_mesa_add_unnamed_constant(struct gl_program_parameter_list *paramList, - const GLfloat values[4], GLuint size, - GLuint *swizzleOut); - -extern GLint -_mesa_add_uniform(struct gl_program_parameter_list *paramList, - const char *name, GLuint size); - -extern GLint -_mesa_add_varying(struct gl_program_parameter_list *paramList, - const char *name, GLuint size); - -extern GLint -_mesa_add_state_reference(struct gl_program_parameter_list *paramList, - const GLint *stateTokens); - -extern GLfloat * -_mesa_lookup_parameter_value(const struct gl_program_parameter_list *paramList, - GLsizei nameLen, const char *name); - -extern GLint -_mesa_lookup_parameter_index(const struct gl_program_parameter_list *paramList, - GLsizei nameLen, const char *name); - -extern GLboolean -_mesa_lookup_parameter_constant(const struct gl_program_parameter_list *paramList, - const GLfloat v[], GLsizei vSize, - GLint *posOut, GLuint *swizzleOut); - -extern void -_mesa_load_state_parameters(GLcontext *ctx, - struct gl_program_parameter_list *paramList); - -extern void -_mesa_print_instruction(const struct prog_instruction *inst); -void -_mesa_print_alu_instruction(const struct prog_instruction *inst, - const char *opcode_string, - GLuint numRegs); extern void _mesa_print_program(const struct gl_program *prog); -- cgit v1.2.3