From 12ef1fbefcee964b715783d3ade6b69b2c699ed8 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 13 Dec 2006 15:05:23 -0700 Subject: Checkpoint for GLSL compiler changes. In brief: Check for enabled fragment program by looking at ctx->FragmentProgram._Current. New code for varying variables. --- src/mesa/swrast/s_aalinetemp.h | 4 ++-- src/mesa/swrast/s_context.c | 27 +++++++++++------------- src/mesa/swrast/s_nvfragprog.c | 41 +++++++++++++++++++++++++++++------- src/mesa/swrast/s_pointtemp.h | 2 +- src/mesa/swrast/s_span.c | 48 ++++++++++++++++++------------------------ src/mesa/swrast/s_triangle.c | 15 +++++++------ 6 files changed, 76 insertions(+), 61 deletions(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/swrast/s_aalinetemp.h b/src/mesa/swrast/s_aalinetemp.h index 34c95fc34e..68291afeea 100644 --- a/src/mesa/swrast/s_aalinetemp.h +++ b/src/mesa/swrast/s_aalinetemp.h @@ -80,7 +80,7 @@ NAME(plot)(GLcontext *ctx, struct LineInfo *line, int ix, int iy) #ifdef DO_TEX { GLfloat invQ; - if (ctx->FragmentProgram._Active) { + if (ctx->FragmentProgram._Current) { invQ = 1.0F; } else { @@ -100,7 +100,7 @@ NAME(plot)(GLcontext *ctx, struct LineInfo *line, int ix, int iy) for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { if (ctx->Texture.Unit[unit]._ReallyEnabled) { GLfloat invQ; - if (ctx->FragmentProgram._Active) { + if (ctx->FragmentProgram._Current) { invQ = 1.0F; } else { diff --git a/src/mesa/swrast/s_context.c b/src/mesa/swrast/s_context.c index 52d560ffdb..e304789154 100644 --- a/src/mesa/swrast/s_context.c +++ b/src/mesa/swrast/s_context.c @@ -98,7 +98,7 @@ _swrast_update_rasterflags( GLcontext *ctx ) rasterMask |= MULTI_DRAW_BIT; /* all color index bits disabled */ } - if (ctx->FragmentProgram._Enabled) { + if (ctx->FragmentProgram._Current) { rasterMask |= FRAGPROG_BIT; } @@ -165,7 +165,7 @@ _swrast_update_fog_hint( GLcontext *ctx ) { SWcontext *swrast = SWRAST_CONTEXT(ctx); swrast->_PreferPixelFog = (!swrast->AllowVertexFog || - ctx->FragmentProgram._Enabled || /* not _Active! */ + ctx->FragmentProgram._Current || (ctx->Hint.Fog == GL_NICEST && swrast->AllowPixelFog)); } @@ -198,17 +198,14 @@ static void _swrast_update_fog_state( GLcontext *ctx ) { SWcontext *swrast = SWRAST_CONTEXT(ctx); + const struct gl_fragment_program *fp = ctx->FragmentProgram._Current; /* determine if fog is needed, and if so, which fog mode */ swrast->_FogEnabled = GL_FALSE; - if (ctx->FragmentProgram._Enabled) { - if (ctx->FragmentProgram._Current->Base.Target==GL_FRAGMENT_PROGRAM_ARB) { - const struct gl_fragment_program *fp - = ctx->FragmentProgram._Current; - if (fp->FogOption != GL_NONE) { - swrast->_FogEnabled = GL_TRUE; - swrast->_FogMode = fp->FogOption; - } + if (fp && fp->Base.Target == GL_FRAGMENT_PROGRAM_ARB) { + if (fp->FogOption != GL_NONE) { + swrast->_FogEnabled = GL_TRUE; + swrast->_FogMode = fp->FogOption; } } else if (ctx->Fog.Enabled) { @@ -225,8 +222,8 @@ _swrast_update_fog_state( GLcontext *ctx ) static void _swrast_update_fragment_program(GLcontext *ctx, GLbitfield newState) { - if (ctx->FragmentProgram._Enabled) { - const struct gl_fragment_program *fp = ctx->FragmentProgram._Current; + const struct gl_fragment_program *fp = ctx->FragmentProgram._Current; + if (fp) { #if 0 /* XXX Need a way to trigger the initial loading of parameters * even when there's no recent state changes. @@ -301,7 +298,7 @@ _swrast_validate_triangle( GLcontext *ctx, if (ctx->Texture._EnabledUnits == 0 && NEED_SECONDARY_COLOR(ctx) - && !ctx->FragmentProgram._Enabled) { + && !ctx->FragmentProgram._Current) { /* separate specular color, but no texture */ swrast->SpecTriangle = swrast->Triangle; swrast->Triangle = _swrast_add_spec_terms_triangle; @@ -325,7 +322,7 @@ _swrast_validate_line( GLcontext *ctx, const SWvertex *v0, const SWvertex *v1 ) if (ctx->Texture._EnabledUnits == 0 && NEED_SECONDARY_COLOR(ctx) - && !ctx->FragmentProgram._Enabled) { + && !ctx->FragmentProgram._Current) { swrast->SpecLine = swrast->Line; swrast->Line = _swrast_add_spec_terms_line; } @@ -348,7 +345,7 @@ _swrast_validate_point( GLcontext *ctx, const SWvertex *v0 ) if (ctx->Texture._EnabledUnits == 0 && NEED_SECONDARY_COLOR(ctx) - && !ctx->FragmentProgram._Enabled) { + && !ctx->FragmentProgram._Current) { swrast->SpecPoint = swrast->Point; swrast->Point = _swrast_add_spec_terms_point; } diff --git a/src/mesa/swrast/s_nvfragprog.c b/src/mesa/swrast/s_nvfragprog.c index 028ddc0090..df583bb29c 100644 --- a/src/mesa/swrast/s_nvfragprog.c +++ b/src/mesa/swrast/s_nvfragprog.c @@ -53,9 +53,9 @@ */ struct fp_machine { - GLfloat Temporaries[MAX_NV_FRAGMENT_PROGRAM_TEMPS][4]; - GLfloat Inputs[MAX_NV_FRAGMENT_PROGRAM_INPUTS][4]; - GLfloat Outputs[MAX_NV_FRAGMENT_PROGRAM_OUTPUTS][4]; + GLfloat Temporaries[MAX_PROGRAM_TEMPS][4]; + GLfloat Inputs[FRAG_ATTRIB_MAX][4]; + GLfloat Outputs[FRAG_RESULT_MAX][4]; GLuint CondCodes[4]; /**< COND_* value for x/y/z/w */ GLuint CallStack[MAX_PROGRAM_CALL_DEPTH]; /**< For CAL/RET instructions */ @@ -161,14 +161,14 @@ get_register_pointer( GLcontext *ctx, { switch (source->File) { case PROGRAM_TEMPORARY: - ASSERT(source->Index < MAX_NV_FRAGMENT_PROGRAM_TEMPS); + ASSERT(source->Index < MAX_PROGRAM_TEMPS); return machine->Temporaries[source->Index]; case PROGRAM_INPUT: - ASSERT(source->Index < MAX_NV_FRAGMENT_PROGRAM_INPUTS); + ASSERT(source->Index < FRAG_ATTRIB_MAX); return machine->Inputs[source->Index]; case PROGRAM_OUTPUT: /* This is only for PRINT */ - ASSERT(source->Index < MAX_NV_FRAGMENT_PROGRAM_OUTPUTS); + ASSERT(source->Index < FRAG_RESULT_MAX); return machine->Outputs[source->Index]; case PROGRAM_LOCAL_PARAM: ASSERT(source->Index < MAX_PROGRAM_LOCAL_PARAMS); @@ -180,6 +180,8 @@ get_register_pointer( GLcontext *ctx, /* Fallthrough */ case PROGRAM_CONSTANT: /* Fallthrough */ + case PROGRAM_UNIFORM: + /* Fallthrough */ case PROGRAM_NAMED_PARAM: ASSERT(source->Index < (GLint) program->Base.Parameters->NumParameters); return program->Base.Parameters->ParameterValues[source->Index]; @@ -539,7 +541,7 @@ init_machine_deriv( GLcontext *ctx, const SWspan *span, char xOrY, struct fp_machine *dMachine ) { - GLuint u; + GLuint u, v; ASSERT(xOrY == 'X' || xOrY == 'Y'); @@ -626,6 +628,17 @@ init_machine_deriv( GLcontext *ctx, } } + for (v = 0; v < ctx->Const.MaxVarying; v++) { + if (program->Base.InputsRead & (1 << (FRAG_ATTRIB_VAR0 + v))) { + GLfloat *var = (GLfloat*) machine->Inputs[FRAG_ATTRIB_VAR0 + v]; + /* XXXX finish this */ + var[0] += span->varStepX[v][0]; + var[1] += span->varStepX[v][1]; + var[2] += span->varStepX[v][2]; + var[3] += span->varStepX[v][3]; + } + } + /* init condition codes */ dMachine->CondCodes[0] = COND_EQ; dMachine->CondCodes[1] = COND_EQ; @@ -1531,7 +1544,7 @@ init_machine( GLcontext *ctx, struct fp_machine *machine, const SWspan *span, GLuint col ) { GLuint inputsRead = program->Base.InputsRead; - GLuint u; + GLuint u, v; if (ctx->FragmentProgram.CallbackEnabled) inputsRead = ~0; @@ -1583,6 +1596,18 @@ init_machine( GLcontext *ctx, struct fp_machine *machine, /*ASSERT(tex[0] != 0 || tex[1] != 0 || tex[2] != 0);*/ } } + for (v = 0; v < ctx->Const.MaxVarying; v++) { + if (inputsRead & (1 << (FRAG_ATTRIB_VAR0 + v))) { +#if 0 + printf("Frag Var %d: %f %f %f\n", col, + span->array->varying[col][v][0], + span->array->varying[col][v][1], + span->array->varying[col][v][2]); +#endif + COPY_4V(machine->Inputs[FRAG_ATTRIB_VAR0 + v], + span->array->varying[col][v]); + } + } /* init condition codes */ machine->CondCodes[0] = COND_EQ; diff --git a/src/mesa/swrast/s_pointtemp.h b/src/mesa/swrast/s_pointtemp.h index 6316833a68..b41776b017 100644 --- a/src/mesa/swrast/s_pointtemp.h +++ b/src/mesa/swrast/s_pointtemp.h @@ -120,7 +120,7 @@ NAME ( GLcontext *ctx, const SWvertex *vert ) #endif #if FLAGS & TEXTURE span->arrayMask |= (SPAN_TEXTURE | SPAN_LAMBDA); - if (ctx->FragmentProgram._Active) { + if (ctx->FragmentProgram._Current) { /* Don't divide texture s,t,r by q (use TXP to do that) */ for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { if (ctx->Texture._EnabledCoordUnits & (1 << u)) { diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c index c74b98facf..69ecfa9558 100644 --- a/src/mesa/swrast/s_span.c +++ b/src/mesa/swrast/s_span.c @@ -130,7 +130,7 @@ _swrast_span_default_texcoords( GLcontext *ctx, SWspan *span ) GLuint i; for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { const GLfloat *tc = ctx->Current.RasterTexCoords[i]; - if (ctx->FragmentProgram._Enabled || ctx->ATIFragmentShader._Enabled) { + if (ctx->FragmentProgram._Current || ctx->ATIFragmentShader._Enabled) { COPY_4V(span->tex[i], tc); } else if (tc[3] > 0.0F) { @@ -555,7 +555,7 @@ interpolate_texcoords(GLcontext *ctx, SWspan *span) if (obj) { const struct gl_texture_image *img = obj->Image[0][obj->BaseLevel]; needLambda = (obj->MinFilter != obj->MagFilter) - || ctx->FragmentProgram._Enabled; + || ctx->FragmentProgram._Current; texW = img->WidthScale; texH = img->HeightScale; } @@ -580,8 +580,8 @@ interpolate_texcoords(GLcontext *ctx, SWspan *span) GLfloat r = span->tex[u][2]; GLfloat q = span->tex[u][3]; GLuint i; - if (ctx->FragmentProgram._Enabled || ctx->ATIFragmentShader._Enabled || - ctx->ShaderObjects._FragmentShaderPresent) { + if (ctx->FragmentProgram._Current + || ctx->ATIFragmentShader._Enabled) { /* do perspective correction but don't divide s, t, r by q */ const GLfloat dwdx = span->dwdx; GLfloat w = span->w; @@ -632,8 +632,8 @@ interpolate_texcoords(GLcontext *ctx, SWspan *span) GLfloat r = span->tex[u][2]; GLfloat q = span->tex[u][3]; GLuint i; - if (ctx->FragmentProgram._Enabled || ctx->ATIFragmentShader._Enabled || - ctx->ShaderObjects._FragmentShaderPresent) { + if (ctx->FragmentProgram._Current || + ctx->ATIFragmentShader._Enabled) { /* do perspective correction but don't divide s, t, r by q */ const GLfloat dwdx = span->dwdx; GLfloat w = span->w; @@ -691,7 +691,7 @@ interpolate_texcoords(GLcontext *ctx, SWspan *span) if (obj) { const struct gl_texture_image *img = obj->Image[0][obj->BaseLevel]; needLambda = (obj->MinFilter != obj->MagFilter) - || ctx->FragmentProgram._Enabled; + || ctx->FragmentProgram._Current; texW = (GLfloat) img->WidthScale; texH = (GLfloat) img->HeightScale; } @@ -716,8 +716,8 @@ interpolate_texcoords(GLcontext *ctx, SWspan *span) GLfloat r = span->tex[0][2]; GLfloat q = span->tex[0][3]; GLuint i; - if (ctx->FragmentProgram._Enabled || ctx->ATIFragmentShader._Enabled || - ctx->ShaderObjects._FragmentShaderPresent) { + if (ctx->FragmentProgram._Current + || ctx->ATIFragmentShader._Enabled) { /* do perspective correction but don't divide s, t, r by q */ const GLfloat dwdx = span->dwdx; GLfloat w = span->w; @@ -768,8 +768,8 @@ interpolate_texcoords(GLcontext *ctx, SWspan *span) GLfloat r = span->tex[0][2]; GLfloat q = span->tex[0][3]; GLuint i; - if (ctx->FragmentProgram._Enabled || ctx->ATIFragmentShader._Enabled || - ctx->ShaderObjects._FragmentShaderPresent) { + if (ctx->FragmentProgram._Current + || ctx->ATIFragmentShader._Enabled) { /* do perspective correction but don't divide s, t, r by q */ const GLfloat dwdx = span->dwdx; GLfloat w = span->w; @@ -1340,8 +1340,7 @@ shade_texture_span(GLcontext *ctx, SWspan *span) if (ctx->Texture._EnabledCoordUnits && (span->interpMask & SPAN_TEXTURE)) interpolate_texcoords(ctx, span); - if (ctx->ShaderObjects._FragmentShaderPresent || - ctx->FragmentProgram._Enabled || + if (ctx->FragmentProgram._Current || ctx->ATIFragmentShader._Enabled) { /* use float colors if running a fragment program or shader */ @@ -1367,12 +1366,11 @@ shade_texture_span(GLcontext *ctx, SWspan *span) if (span->interpMask & SPAN_Z) _swrast_span_interpolate_z (ctx, span); - /* Run fragment program/shader now */ - if (ctx->ShaderObjects._FragmentShaderPresent) { + if (ctx->ShaderObjects.Linked && span->interpMask & SPAN_VARYING) interpolate_varying(ctx, span); - _swrast_exec_arbshader(ctx, span); - } - else if (ctx->FragmentProgram._Enabled) { + + /* Run fragment program/shader now */ + if (ctx->FragmentProgram._Current) { _swrast_exec_fragment_program(ctx, span); } else { @@ -1403,10 +1401,8 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span) const GLbitfield origInterpMask = span->interpMask; const GLbitfield origArrayMask = span->arrayMask; const GLenum chanType = span->array->ChanType; - const GLboolean shader - = ctx->FragmentProgram._Enabled - || ctx->ShaderObjects._FragmentShaderPresent - || ctx->ATIFragmentShader._Enabled; + const GLboolean shader = (ctx->FragmentProgram._Current + || ctx->ATIFragmentShader._Enabled); const GLboolean shaderOrTexture = shader || ctx->Texture._EnabledUnits; GLboolean deferredTexture; @@ -1429,20 +1425,16 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span) deferredTexture = GL_FALSE; } else if (shaderOrTexture) { - if (ctx->FragmentProgram._Enabled) { + if (ctx->FragmentProgram._Current) { if (ctx->FragmentProgram.Current->Base.OutputsWritten & (1 << FRAG_RESULT_DEPR)) { - /* Z comes from fragment program */ + /* Z comes from fragment program/shader */ deferredTexture = GL_FALSE; } else { deferredTexture = GL_TRUE; } } - else if (ctx->ShaderObjects._FragmentShaderPresent) { - /* XXX how do we test if Z is written by shader? */ - deferredTexture = GL_FALSE; /* never defer to be safe */ - } else { /* ATI frag shader or conventional texturing */ deferredTexture = GL_TRUE; diff --git a/src/mesa/swrast/s_triangle.c b/src/mesa/swrast/s_triangle.c index b17c435460..9b775928cd 100644 --- a/src/mesa/swrast/s_triangle.c +++ b/src/mesa/swrast/s_triangle.c @@ -883,8 +883,8 @@ fast_persp_span(GLcontext *ctx, SWspan *span, /* * This is the big one! - * Interpolate Z, RGB, Alpha, specular, fog, N sets of texture coordinates, and varying floats. - * Yup, it's slow. + * Interpolate Z, RGB, Alpha, specular, fog, N sets of texture coordinates, + * and varying floats. Yup, it's slow. */ #define NAME multitextured_triangle #define INTERP_Z 1 @@ -1073,8 +1073,9 @@ _swrast_choose_triangle( GLcontext *ctx ) } } - if (ctx->Texture._EnabledCoordUnits || ctx->FragmentProgram._Enabled || - ctx->ATIFragmentShader._Enabled || ctx->ShaderObjects._FragmentShaderPresent) { + if (ctx->Texture._EnabledCoordUnits || + ctx->FragmentProgram._Current || + ctx->ATIFragmentShader._Enabled) { /* Ugh, we do a _lot_ of tests to pick the best textured tri func */ const struct gl_texture_object *texObj2D; const struct gl_texture_image *texImg; @@ -1089,9 +1090,8 @@ _swrast_choose_triangle( GLcontext *ctx ) /* First see if we can use an optimized 2-D texture function */ if (ctx->Texture._EnabledCoordUnits == 0x1 - && !ctx->FragmentProgram._Enabled + && !ctx->FragmentProgram._Current && !ctx->ATIFragmentShader._Enabled - && !ctx->ShaderObjects._FragmentShaderPresent && ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT && texObj2D->WrapS == GL_REPEAT && texObj2D->WrapT == GL_REPEAT @@ -1137,7 +1137,8 @@ _swrast_choose_triangle( GLcontext *ctx ) } else { /* general case textured triangles */ - if (ctx->Texture._EnabledCoordUnits > 1) { + if (ctx->Texture._EnabledCoordUnits > 1 || + ctx->FragmentProgram._Current) { USE(multitextured_triangle); } else { -- cgit v1.2.3 From cefc983bec26b597a98a53932cd5ea05ded2b35a Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 13 Dec 2006 15:06:28 -0700 Subject: Retire old GLSL shader code. --- src/mesa/swrast/s_arbshader.c | 124 ------------------------------------------ src/mesa/swrast/s_arbshader.h | 38 ------------- 2 files changed, 162 deletions(-) delete mode 100644 src/mesa/swrast/s_arbshader.c delete mode 100644 src/mesa/swrast/s_arbshader.h (limited to 'src/mesa/swrast') diff --git a/src/mesa/swrast/s_arbshader.c b/src/mesa/swrast/s_arbshader.c deleted file mode 100644 index ee971a36ec..0000000000 --- a/src/mesa/swrast/s_arbshader.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.6 - * - * Copyright (C) 2006 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: - * Michal Krol - */ - -#include "glheader.h" -#include "context.h" -#include "colormac.h" -#include "s_arbshader.h" -#include "s_context.h" -#include "shaderobjects.h" -#include "shaderobjects_3dlabs.h" -#include "slang_utility.h" -#include "slang_link.h" - -#if FEATURE_ARB_fragment_shader - -void -_swrast_exec_arbshader(GLcontext *ctx, SWspan *span) -{ - struct gl2_program_intf **pro; - GLuint i; - - ASSERT(span->array->ChanType == GL_FLOAT); - - if (!ctx->ShaderObjects._FragmentShaderPresent) - return; - - pro = ctx->ShaderObjects.CurrentProgram; - if (!ctx->ShaderObjects._VertexShaderPresent) - (**pro).UpdateFixedUniforms(pro); - - for (i = span->start; i < span->end; i++) { - /* only run shader on active fragments */ - if (span->array->mask[i]) { - GLfloat vec[4]; - GLuint j; - GLboolean discard; - - /* - * Load input attributes - */ - vec[0] = (GLfloat) span->x + i; - vec[1] = (GLfloat) span->y; - vec[2] = (GLfloat) span->array->z[i] / ctx->DrawBuffer->_DepthMaxF; - vec[3] = span->w + span->dwdx * i; - (**pro).UpdateFixedVarying(pro, SLANG_FRAGMENT_FIXED_FRAGCOORD, vec, - 0, 4 * sizeof(GLfloat), GL_TRUE); - - (**pro).UpdateFixedVarying(pro, SLANG_FRAGMENT_FIXED_COLOR, - span->array->color.sz4.rgba[i], - 0, 4 * sizeof(GLfloat), GL_TRUE); - - (**pro).UpdateFixedVarying(pro, SLANG_FRAGMENT_FIXED_SECONDARYCOLOR, - span->array->color.sz4.spec[i], - 0, 4 * sizeof(GLfloat), GL_TRUE); - - for (j = 0; j < ctx->Const.MaxTextureCoordUnits; j++) { - (**pro).UpdateFixedVarying(pro, SLANG_FRAGMENT_FIXED_TEXCOORD, - span->array->texcoords[j][i], - j, 4 * sizeof(GLfloat), GL_TRUE); - } - - for (j = 0; j < MAX_VARYING_VECTORS; j++) { - GLuint k; - for (k = 0; k < VARYINGS_PER_VECTOR; k++) { - (**pro).UpdateVarying(pro, j * VARYINGS_PER_VECTOR + k, - &span->array->varying[i][j][k], - GL_FALSE); - } - } - - _slang_exec_fragment_shader(pro); - - /* - * Store results - */ - _slang_fetch_discard(pro, &discard); - if (discard) { - span->array->mask[i] = GL_FALSE; - span->writeAll = GL_FALSE; - } - else { - (**pro).UpdateFixedVarying(pro, SLANG_FRAGMENT_FIXED_FRAGCOLOR, - vec, 0, 4 * sizeof(GLfloat), GL_FALSE); - COPY_4V(span->array->color.sz4.rgba[i], vec); - - (**pro).UpdateFixedVarying(pro, SLANG_FRAGMENT_FIXED_FRAGDEPTH, vec, 0, - sizeof (GLfloat), GL_FALSE); - if (vec[0] <= 0.0f) - span->array->z[i] = 0; - else if (vec[0] >= 1.0f) - span->array->z[i] = ctx->DrawBuffer->_DepthMax; - else - span->array->z[i] = IROUND(vec[0] * ctx->DrawBuffer->_DepthMaxF); - } - } - } -} - -#endif /* FEATURE_ARB_fragment_shader */ - diff --git a/src/mesa/swrast/s_arbshader.h b/src/mesa/swrast/s_arbshader.h deleted file mode 100644 index 5df80c870b..0000000000 --- a/src/mesa/swrast/s_arbshader.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5 - * - * Copyright (C) 2006 David Airlie All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * DAVID AIRLIE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - - -#ifndef S_ARBSHADER_H -#define S_ARBSHADER_H - -#include "s_context.h" - -#if FEATURE_ARB_fragment_shader - -extern void _swrast_exec_arbshader (GLcontext *ctx, SWspan *span); - -#endif /* FEATURE_ARB_fragment_shader */ - -#endif - -- cgit v1.2.3 From e7e4181361cf2820761c654555f4751e49978a13 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 14 Dec 2006 09:51:54 -0700 Subject: Remove include of s_arbshader.h --- src/mesa/swrast/s_span.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c index 69ecfa9558..e4904e1dd2 100644 --- a/src/mesa/swrast/s_span.c +++ b/src/mesa/swrast/s_span.c @@ -39,7 +39,6 @@ #include "s_atifragshader.h" #include "s_alpha.h" -#include "s_arbshader.h" #include "s_blend.h" #include "s_context.h" #include "s_depth.h" -- cgit v1.2.3 From 49f82803cc6ceaf1ecc3928a5417ef300f73f37d Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 14 Dec 2006 15:13:06 -0700 Subject: Updated includes. --- src/mesa/swrast/s_context.c | 2 +- src/mesa/swrast/s_nvfragprog.c | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/swrast/s_context.c b/src/mesa/swrast/s_context.c index e304789154..46f99ef6e0 100644 --- a/src/mesa/swrast/s_context.c +++ b/src/mesa/swrast/s_context.c @@ -31,7 +31,7 @@ #include "context.h" #include "colormac.h" #include "mtypes.h" -#include "program.h" +#include "prog_statevars.h" #include "teximage.h" #include "swrast.h" #include "s_blend.h" diff --git a/src/mesa/swrast/s_nvfragprog.c b/src/mesa/swrast/s_nvfragprog.c index df583bb29c..ac2f5d93b6 100644 --- a/src/mesa/swrast/s_nvfragprog.c +++ b/src/mesa/swrast/s_nvfragprog.c @@ -34,7 +34,9 @@ #include "glheader.h" #include "colormac.h" #include "context.h" -#include "program_instruction.h" +#include "prog_instruction.h" +#include "prog_parameter.h" +#include "prog_print.h" #include "program.h" #include "s_nvfragprog.h" -- cgit v1.2.3 From 865f88afc0d59d886fb2ad50429e584ecf17fa81 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 14 Dec 2006 15:14:14 -0700 Subject: Renamed from s_nvfragprog.[ch] --- src/mesa/swrast/s_fragprog.c | 1692 ++++++++++++++++++++++++++++++++++++++++++ src/mesa/swrast/s_fragprog.h | 37 + 2 files changed, 1729 insertions(+) create mode 100644 src/mesa/swrast/s_fragprog.c create mode 100644 src/mesa/swrast/s_fragprog.h (limited to 'src/mesa/swrast') diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c new file mode 100644 index 0000000000..ac2f5d93b6 --- /dev/null +++ b/src/mesa/swrast/s_fragprog.c @@ -0,0 +1,1692 @@ +/* + * Mesa 3-D graphics library + * Version: 6.5.2 + * + * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * Regarding GL_NV_fragment_program: + * + * Portions of this software may use or implement intellectual + * property owned and licensed by NVIDIA Corporation. NVIDIA disclaims + * any and all warranties with respect to such intellectual property, + * including any use thereof or modifications thereto. + */ + +#include "glheader.h" +#include "colormac.h" +#include "context.h" +#include "prog_instruction.h" +#include "prog_parameter.h" +#include "prog_print.h" +#include "program.h" + +#include "s_nvfragprog.h" +#include "s_span.h" + + +/* See comments below for info about this */ +#define LAMBDA_ZERO 1 + +/* debug predicate */ +#define DEBUG_FRAG 0 + + +/** + * Virtual machine state used during execution of a fragment programs. + */ +struct fp_machine +{ + GLfloat Temporaries[MAX_PROGRAM_TEMPS][4]; + GLfloat Inputs[FRAG_ATTRIB_MAX][4]; + GLfloat Outputs[FRAG_RESULT_MAX][4]; + GLuint CondCodes[4]; /**< COND_* value for x/y/z/w */ + + GLuint CallStack[MAX_PROGRAM_CALL_DEPTH]; /**< For CAL/RET instructions */ + GLuint StackDepth; /**< Index/ptr to top of CallStack[] */ +}; + + +#if FEATURE_MESA_program_debug +static struct fp_machine *CurrentMachine = NULL; + +/** + * For GL_MESA_program_debug. + * Return current value (4*GLfloat) of a fragment program register. + * Called via ctx->Driver.GetFragmentProgramRegister(). + */ +void +_swrast_get_program_register(GLcontext *ctx, enum register_file file, + GLuint index, GLfloat val[4]) +{ + if (CurrentMachine) { + switch (file) { + case PROGRAM_INPUT: + COPY_4V(val, CurrentMachine->Inputs[index]); + break; + case PROGRAM_OUTPUT: + COPY_4V(val, CurrentMachine->Outputs[index]); + break; + case PROGRAM_TEMPORARY: + COPY_4V(val, CurrentMachine->Temporaries[index]); + break; + default: + _mesa_problem(NULL, + "bad register file in _swrast_get_program_register"); + } + } +} +#endif /* FEATURE_MESA_program_debug */ + + +/** + * Fetch a texel. + */ +static void +fetch_texel( GLcontext *ctx, const GLfloat texcoord[4], GLfloat lambda, + GLuint unit, GLfloat color[4] ) +{ + GLchan rgba[4]; + SWcontext *swrast = SWRAST_CONTEXT(ctx); + + /* XXX use a float-valued TextureSample routine here!!! */ + swrast->TextureSample[unit](ctx, ctx->Texture.Unit[unit]._Current, + 1, (const GLfloat (*)[4]) texcoord, + &lambda, &rgba); + color[0] = CHAN_TO_FLOAT(rgba[0]); + color[1] = CHAN_TO_FLOAT(rgba[1]); + color[2] = CHAN_TO_FLOAT(rgba[2]); + color[3] = CHAN_TO_FLOAT(rgba[3]); +} + + +/** + * Fetch a texel with the given partial derivatives to compute a level + * of detail in the mipmap. + */ +static void +fetch_texel_deriv( GLcontext *ctx, const GLfloat texcoord[4], + const GLfloat texdx[4], const GLfloat texdy[4], + GLuint unit, GLfloat color[4] ) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + const struct gl_texture_object *texObj = ctx->Texture.Unit[unit]._Current; + const struct gl_texture_image *texImg = texObj->Image[0][texObj->BaseLevel]; + const GLfloat texW = (GLfloat) texImg->WidthScale; + const GLfloat texH = (GLfloat) texImg->HeightScale; + GLchan rgba[4]; + + GLfloat lambda = _swrast_compute_lambda(texdx[0], texdy[0], /* ds/dx, ds/dy */ + texdx[1], texdy[1], /* dt/dx, dt/dy */ + texdx[3], texdy[2], /* dq/dx, dq/dy */ + texW, texH, + texcoord[0], texcoord[1], texcoord[3], + 1.0F / texcoord[3]); + + swrast->TextureSample[unit](ctx, ctx->Texture.Unit[unit]._Current, + 1, (const GLfloat (*)[4]) texcoord, + &lambda, &rgba); + color[0] = CHAN_TO_FLOAT(rgba[0]); + color[1] = CHAN_TO_FLOAT(rgba[1]); + color[2] = CHAN_TO_FLOAT(rgba[2]); + color[3] = CHAN_TO_FLOAT(rgba[3]); +} + + +/** + * Return a pointer to the 4-element float vector specified by the given + * source register. + */ +static INLINE const GLfloat * +get_register_pointer( GLcontext *ctx, + const struct prog_src_register *source, + const struct fp_machine *machine, + const struct gl_fragment_program *program ) +{ + switch (source->File) { + case PROGRAM_TEMPORARY: + ASSERT(source->Index < MAX_PROGRAM_TEMPS); + return machine->Temporaries[source->Index]; + case PROGRAM_INPUT: + ASSERT(source->Index < FRAG_ATTRIB_MAX); + return machine->Inputs[source->Index]; + case PROGRAM_OUTPUT: + /* This is only for PRINT */ + ASSERT(source->Index < FRAG_RESULT_MAX); + return machine->Outputs[source->Index]; + case PROGRAM_LOCAL_PARAM: + ASSERT(source->Index < MAX_PROGRAM_LOCAL_PARAMS); + return program->Base.LocalParams[source->Index]; + case PROGRAM_ENV_PARAM: + ASSERT(source->Index < MAX_NV_FRAGMENT_PROGRAM_PARAMS); + return ctx->FragmentProgram.Parameters[source->Index]; + case PROGRAM_STATE_VAR: + /* Fallthrough */ + case PROGRAM_CONSTANT: + /* Fallthrough */ + case PROGRAM_UNIFORM: + /* Fallthrough */ + case PROGRAM_NAMED_PARAM: + ASSERT(source->Index < (GLint) program->Base.Parameters->NumParameters); + return program->Base.Parameters->ParameterValues[source->Index]; + default: + _mesa_problem(ctx, "Invalid input register file %d in fp " + "get_register_pointer", source->File); + return NULL; + } +} + + +/** + * Fetch a 4-element float vector from the given source register. + * Apply swizzling and negating as needed. + */ +static void +fetch_vector4( GLcontext *ctx, + const struct prog_src_register *source, + const struct fp_machine *machine, + const struct gl_fragment_program *program, + GLfloat result[4] ) +{ + const GLfloat *src = get_register_pointer(ctx, source, machine, program); + ASSERT(src); + + if (source->Swizzle == MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, + SWIZZLE_Z, SWIZZLE_W)) { + /* no swizzling */ + COPY_4V(result, src); + } + else { + result[0] = src[GET_SWZ(source->Swizzle, 0)]; + result[1] = src[GET_SWZ(source->Swizzle, 1)]; + result[2] = src[GET_SWZ(source->Swizzle, 2)]; + result[3] = src[GET_SWZ(source->Swizzle, 3)]; + } + + if (source->NegateBase) { + result[0] = -result[0]; + result[1] = -result[1]; + result[2] = -result[2]; + result[3] = -result[3]; + } + if (source->Abs) { + result[0] = FABSF(result[0]); + result[1] = FABSF(result[1]); + result[2] = FABSF(result[2]); + result[3] = FABSF(result[3]); + } + if (source->NegateAbs) { + result[0] = -result[0]; + result[1] = -result[1]; + result[2] = -result[2]; + result[3] = -result[3]; + } +} + + +/** + * Fetch the derivative with respect to X for the given register. + * \return GL_TRUE if it was easily computed or GL_FALSE if we + * need to execute another instance of the program (ugh)! + */ +static GLboolean +fetch_vector4_deriv( GLcontext *ctx, + const struct prog_src_register *source, + const SWspan *span, + char xOrY, GLint column, GLfloat result[4] ) +{ + GLfloat src[4]; + + ASSERT(xOrY == 'X' || xOrY == 'Y'); + + switch (source->Index) { + case FRAG_ATTRIB_WPOS: + if (xOrY == 'X') { + src[0] = 1.0; + src[1] = 0.0; + src[2] = span->dzdx / ctx->DrawBuffer->_DepthMaxF; + src[3] = span->dwdx; + } + else { + src[0] = 0.0; + src[1] = 1.0; + src[2] = span->dzdy / ctx->DrawBuffer->_DepthMaxF; + src[3] = span->dwdy; + } + break; + case FRAG_ATTRIB_COL0: + if (xOrY == 'X') { + src[0] = span->drdx * (1.0F / CHAN_MAXF); + src[1] = span->dgdx * (1.0F / CHAN_MAXF); + src[2] = span->dbdx * (1.0F / CHAN_MAXF); + src[3] = span->dadx * (1.0F / CHAN_MAXF); + } + else { + src[0] = span->drdy * (1.0F / CHAN_MAXF); + src[1] = span->dgdy * (1.0F / CHAN_MAXF); + src[2] = span->dbdy * (1.0F / CHAN_MAXF); + src[3] = span->dady * (1.0F / CHAN_MAXF); + } + break; + case FRAG_ATTRIB_COL1: + if (xOrY == 'X') { + src[0] = span->dsrdx * (1.0F / CHAN_MAXF); + src[1] = span->dsgdx * (1.0F / CHAN_MAXF); + src[2] = span->dsbdx * (1.0F / CHAN_MAXF); + src[3] = 0.0; /* XXX need this */ + } + else { + src[0] = span->dsrdy * (1.0F / CHAN_MAXF); + src[1] = span->dsgdy * (1.0F / CHAN_MAXF); + src[2] = span->dsbdy * (1.0F / CHAN_MAXF); + src[3] = 0.0; /* XXX need this */ + } + break; + case FRAG_ATTRIB_FOGC: + if (xOrY == 'X') { + src[0] = span->dfogdx; + src[1] = 0.0; + src[2] = 0.0; + src[3] = 0.0; + } + else { + src[0] = span->dfogdy; + src[1] = 0.0; + src[2] = 0.0; + src[3] = 0.0; + } + break; + case FRAG_ATTRIB_TEX0: + case FRAG_ATTRIB_TEX1: + case FRAG_ATTRIB_TEX2: + case FRAG_ATTRIB_TEX3: + case FRAG_ATTRIB_TEX4: + case FRAG_ATTRIB_TEX5: + case FRAG_ATTRIB_TEX6: + case FRAG_ATTRIB_TEX7: + if (xOrY == 'X') { + const GLuint u = source->Index - FRAG_ATTRIB_TEX0; + /* this is a little tricky - I think I've got it right */ + const GLfloat invQ = 1.0f / (span->tex[u][3] + + span->texStepX[u][3] * column); + src[0] = span->texStepX[u][0] * invQ; + src[1] = span->texStepX[u][1] * invQ; + src[2] = span->texStepX[u][2] * invQ; + src[3] = span->texStepX[u][3] * invQ; + } + else { + const GLuint u = source->Index - FRAG_ATTRIB_TEX0; + /* Tricky, as above, but in Y direction */ + const GLfloat invQ = 1.0f / (span->tex[u][3] + span->texStepY[u][3]); + src[0] = span->texStepY[u][0] * invQ; + src[1] = span->texStepY[u][1] * invQ; + src[2] = span->texStepY[u][2] * invQ; + src[3] = span->texStepY[u][3] * invQ; + } + break; + default: + return GL_FALSE; + } + + result[0] = src[GET_SWZ(source->Swizzle, 0)]; + result[1] = src[GET_SWZ(source->Swizzle, 1)]; + result[2] = src[GET_SWZ(source->Swizzle, 2)]; + result[3] = src[GET_SWZ(source->Swizzle, 3)]; + + if (source->NegateBase) { + result[0] = -result[0]; + result[1] = -result[1]; + result[2] = -result[2]; + result[3] = -result[3]; + } + if (source->Abs) { + result[0] = FABSF(result[0]); + result[1] = FABSF(result[1]); + result[2] = FABSF(result[2]); + result[3] = FABSF(result[3]); + } + if (source->NegateAbs) { + result[0] = -result[0]; + result[1] = -result[1]; + result[2] = -result[2]; + result[3] = -result[3]; + } + return GL_TRUE; +} + + +/** + * As above, but only return result[0] element. + */ +static void +fetch_vector1( GLcontext *ctx, + const struct prog_src_register *source, + const struct fp_machine *machine, + const struct gl_fragment_program *program, + GLfloat result[4] ) +{ + const GLfloat *src = get_register_pointer(ctx, source, machine, program); + ASSERT(src); + + result[0] = src[GET_SWZ(source->Swizzle, 0)]; + + if (source->NegateBase) { + result[0] = -result[0]; + } + if (source->Abs) { + result[0] = FABSF(result[0]); + } + if (source->NegateAbs) { + result[0] = -result[0]; + } +} + + +/** + * Test value against zero and return GT, LT, EQ or UN if NaN. + */ +static INLINE GLuint +generate_cc( float value ) +{ + if (value != value) + return COND_UN; /* NaN */ + if (value > 0.0F) + return COND_GT; + if (value < 0.0F) + return COND_LT; + return COND_EQ; +} + + +/** + * Test if the ccMaskRule is satisfied by the given condition code. + * Used to mask destination writes according to the current condition code. + */ +static INLINE GLboolean +test_cc(GLuint condCode, GLuint ccMaskRule) +{ + switch (ccMaskRule) { + case COND_EQ: return (condCode == COND_EQ); + case COND_NE: return (condCode != COND_EQ); + case COND_LT: return (condCode == COND_LT); + case COND_GE: return (condCode == COND_GT || condCode == COND_EQ); + case COND_LE: return (condCode == COND_LT || condCode == COND_EQ); + case COND_GT: return (condCode == COND_GT); + case COND_TR: return GL_TRUE; + case COND_FL: return GL_FALSE; + default: return GL_TRUE; + } +} + + +/** + * Store 4 floats into a register. Observe the instructions saturate and + * set-condition-code flags. + */ +static void +store_vector4( const struct prog_instruction *inst, + struct fp_machine *machine, + const GLfloat value[4] ) +{ + const struct prog_dst_register *dest = &(inst->DstReg); + const GLboolean clamp = inst->SaturateMode == SATURATE_ZERO_ONE; + GLfloat *dstReg; + GLfloat dummyReg[4]; + GLfloat clampedValue[4]; + GLuint writeMask = dest->WriteMask; + + switch (dest->File) { + case PROGRAM_OUTPUT: + dstReg = machine->Outputs[dest->Index]; + break; + case PROGRAM_TEMPORARY: + dstReg = machine->Temporaries[dest->Index]; + break; + case PROGRAM_WRITE_ONLY: + dstReg = dummyReg; + return; + default: + _mesa_problem(NULL, "bad register file in store_vector4(fp)"); + return; + } + +#if 0 + if (value[0] > 1.0e10 || + IS_INF_OR_NAN(value[0]) || + IS_INF_OR_NAN(value[1]) || + IS_INF_OR_NAN(value[2]) || + IS_INF_OR_NAN(value[3]) ) + printf("store %g %g %g %g\n", value[0], value[1], value[2], value[3]); +#endif + + if (clamp) { + clampedValue[0] = CLAMP(value[0], 0.0F, 1.0F); + clampedValue[1] = CLAMP(value[1], 0.0F, 1.0F); + clampedValue[2] = CLAMP(value[2], 0.0F, 1.0F); + clampedValue[3] = CLAMP(value[3], 0.0F, 1.0F); + value = clampedValue; + } + + if (dest->CondMask != COND_TR) { + /* condition codes may turn off some writes */ + if (writeMask & WRITEMASK_X) { + if (!test_cc(machine->CondCodes[GET_SWZ(dest->CondSwizzle, 0)], + dest->CondMask)) + writeMask &= ~WRITEMASK_X; + } + if (writeMask & WRITEMASK_Y) { + if (!test_cc(machine->CondCodes[GET_SWZ(dest->CondSwizzle, 1)], + dest->CondMask)) + writeMask &= ~WRITEMASK_Y; + } + if (writeMask & WRITEMASK_Z) { + if (!test_cc(machine->CondCodes[GET_SWZ(dest->CondSwizzle, 2)], + dest->CondMask)) + writeMask &= ~WRITEMASK_Z; + } + if (writeMask & WRITEMASK_W) { + if (!test_cc(machine->CondCodes[GET_SWZ(dest->CondSwizzle, 3)], + dest->CondMask)) + writeMask &= ~WRITEMASK_W; + } + } + + if (writeMask & WRITEMASK_X) + dstReg[0] = value[0]; + if (writeMask & WRITEMASK_Y) + dstReg[1] = value[1]; + if (writeMask & WRITEMASK_Z) + dstReg[2] = value[2]; + if (writeMask & WRITEMASK_W) + dstReg[3] = value[3]; + + if (inst->CondUpdate) { + if (writeMask & WRITEMASK_X) + machine->CondCodes[0] = generate_cc(value[0]); + if (writeMask & WRITEMASK_Y) + machine->CondCodes[1] = generate_cc(value[1]); + if (writeMask & WRITEMASK_Z) + machine->CondCodes[2] = generate_cc(value[2]); + if (writeMask & WRITEMASK_W) + machine->CondCodes[3] = generate_cc(value[3]); + } +} + + +/** + * Initialize a new machine state instance from an existing one, adding + * the partial derivatives onto the input registers. + * Used to implement DDX and DDY instructions in non-trivial cases. + */ +static void +init_machine_deriv( GLcontext *ctx, + const struct fp_machine *machine, + const struct gl_fragment_program *program, + const SWspan *span, char xOrY, + struct fp_machine *dMachine ) +{ + GLuint u, v; + + ASSERT(xOrY == 'X' || xOrY == 'Y'); + + /* copy existing machine */ + _mesa_memcpy(dMachine, machine, sizeof(struct fp_machine)); + + if (program->Base.Target == GL_FRAGMENT_PROGRAM_NV) { + /* Clear temporary registers (undefined for ARB_f_p) */ + _mesa_bzero( (void*) machine->Temporaries, + MAX_NV_FRAGMENT_PROGRAM_TEMPS * 4 * sizeof(GLfloat)); + } + + /* Add derivatives */ + if (program->Base.InputsRead & (1 << FRAG_ATTRIB_WPOS)) { + GLfloat *wpos = (GLfloat*) machine->Inputs[FRAG_ATTRIB_WPOS]; + if (xOrY == 'X') { + wpos[0] += 1.0F; + wpos[1] += 0.0F; + wpos[2] += span->dzdx; + wpos[3] += span->dwdx; + } + else { + wpos[0] += 0.0F; + wpos[1] += 1.0F; + wpos[2] += span->dzdy; + wpos[3] += span->dwdy; + } + } + if (program->Base.InputsRead & (1 << FRAG_ATTRIB_COL0)) { + GLfloat *col0 = (GLfloat*) machine->Inputs[FRAG_ATTRIB_COL0]; + if (xOrY == 'X') { + col0[0] += span->drdx * (1.0F / CHAN_MAXF); + col0[1] += span->dgdx * (1.0F / CHAN_MAXF); + col0[2] += span->dbdx * (1.0F / CHAN_MAXF); + col0[3] += span->dadx * (1.0F / CHAN_MAXF); + } + else { + col0[0] += span->drdy * (1.0F / CHAN_MAXF); + col0[1] += span->dgdy * (1.0F / CHAN_MAXF); + col0[2] += span->dbdy * (1.0F / CHAN_MAXF); + col0[3] += span->dady * (1.0F / CHAN_MAXF); + } + } + if (program->Base.InputsRead & (1 << FRAG_ATTRIB_COL1)) { + GLfloat *col1 = (GLfloat*) machine->Inputs[FRAG_ATTRIB_COL1]; + if (xOrY == 'X') { + col1[0] += span->dsrdx * (1.0F / CHAN_MAXF); + col1[1] += span->dsgdx * (1.0F / CHAN_MAXF); + col1[2] += span->dsbdx * (1.0F / CHAN_MAXF); + col1[3] += 0.0; /*XXX fix */ + } + else { + col1[0] += span->dsrdy * (1.0F / CHAN_MAXF); + col1[1] += span->dsgdy * (1.0F / CHAN_MAXF); + col1[2] += span->dsbdy * (1.0F / CHAN_MAXF); + col1[3] += 0.0; /*XXX fix */ + } + } + if (program->Base.InputsRead & (1 << FRAG_ATTRIB_FOGC)) { + GLfloat *fogc = (GLfloat*) machine->Inputs[FRAG_ATTRIB_FOGC]; + if (xOrY == 'X') { + fogc[0] += span->dfogdx; + } + else { + fogc[0] += span->dfogdy; + } + } + for (u = 0; u < ctx->Const.MaxTextureCoordUnits; u++) { + if (program->Base.InputsRead & (1 << (FRAG_ATTRIB_TEX0 + u))) { + GLfloat *tex = (GLfloat*) machine->Inputs[FRAG_ATTRIB_TEX0 + u]; + /* XXX perspective-correct interpolation */ + if (xOrY == 'X') { + tex[0] += span->texStepX[u][0]; + tex[1] += span->texStepX[u][1]; + tex[2] += span->texStepX[u][2]; + tex[3] += span->texStepX[u][3]; + } + else { + tex[0] += span->texStepY[u][0]; + tex[1] += span->texStepY[u][1]; + tex[2] += span->texStepY[u][2]; + tex[3] += span->texStepY[u][3]; + } + } + } + + for (v = 0; v < ctx->Const.MaxVarying; v++) { + if (program->Base.InputsRead & (1 << (FRAG_ATTRIB_VAR0 + v))) { + GLfloat *var = (GLfloat*) machine->Inputs[FRAG_ATTRIB_VAR0 + v]; + /* XXXX finish this */ + var[0] += span->varStepX[v][0]; + var[1] += span->varStepX[v][1]; + var[2] += span->varStepX[v][2]; + var[3] += span->varStepX[v][3]; + } + } + + /* init condition codes */ + dMachine->CondCodes[0] = COND_EQ; + dMachine->CondCodes[1] = COND_EQ; + dMachine->CondCodes[2] = COND_EQ; + dMachine->CondCodes[3] = COND_EQ; +} + + +/** + * Execute the given vertex program. + * NOTE: we do everything in single-precision floating point; we don't + * currently observe the single/half/fixed-precision qualifiers. + * \param ctx - rendering context + * \param program - the fragment program to execute + * \param machine - machine state (register file) + * \param maxInst - max number of instructions to execute + * \return GL_TRUE if program completed or GL_FALSE if program executed KIL. + */ +static GLboolean +execute_program( GLcontext *ctx, + const struct gl_fragment_program *program, GLuint maxInst, + struct fp_machine *machine, const SWspan *span, + GLuint column ) +{ + GLuint pc; + + if (DEBUG_FRAG) { + printf("execute fragment program --------------------\n"); + } + + for (pc = 0; pc < maxInst; pc++) { + const struct prog_instruction *inst = program->Base.Instructions + pc; + + if (ctx->FragmentProgram.CallbackEnabled && + ctx->FragmentProgram.Callback) { + ctx->FragmentProgram.CurrentPosition = inst->StringPos; + ctx->FragmentProgram.Callback(program->Base.Target, + ctx->FragmentProgram.CallbackData); + } + + if (DEBUG_FRAG) { + _mesa_print_instruction(inst); + } + + switch (inst->Opcode) { + case OPCODE_ABS: + { + GLfloat a[4], result[4]; + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); + result[0] = FABSF(a[0]); + result[1] = FABSF(a[1]); + result[2] = FABSF(a[2]); + result[3] = FABSF(a[3]); + store_vector4( inst, machine, result ); + } + break; + case OPCODE_ADD: + { + GLfloat a[4], b[4], result[4]; + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); + fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); + result[0] = a[0] + b[0]; + result[1] = a[1] + b[1]; + result[2] = a[2] + b[2]; + result[3] = a[3] + b[3]; + store_vector4( inst, machine, result ); + if (DEBUG_FRAG) { + printf("ADD (%g %g %g %g) = (%g %g %g %g) + (%g %g %g %g)\n", + result[0], result[1], result[2], result[3], + a[0], a[1], a[2], a[3], + b[0], b[1], b[2], b[3]); + } + } + break; + case OPCODE_BRA: /* conditional branch */ + { + /* NOTE: The return is conditional! */ + const GLuint swizzle = inst->DstReg.CondSwizzle; + const GLuint condMask = inst->DstReg.CondMask; + if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) || + test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) || + test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) || + test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) { + /* take branch */ + pc = inst->BranchTarget; + } + } + break; + case OPCODE_CAL: /* Call subroutine */ + { + /* NOTE: The call is conditional! */ + const GLuint swizzle = inst->DstReg.CondSwizzle; + const GLuint condMask = inst->DstReg.CondMask; + if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) || + test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) || + test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) || + test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) { + if (machine->StackDepth >= MAX_PROGRAM_CALL_DEPTH) { + return GL_TRUE; /* Per GL_NV_vertex_program2 spec */ + } + machine->CallStack[machine->StackDepth++] = pc + 1; + pc = inst->BranchTarget; + } + } + break; + case OPCODE_CMP: + { + GLfloat a[4], b[4], c[4], result[4]; + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); + fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); + fetch_vector4( ctx, &inst->SrcReg[2], machine, program, c ); + result[0] = a[0] < 0.0F ? b[0] : c[0]; + result[1] = a[1] < 0.0F ? b[1] : c[1]; + result[2] = a[2] < 0.0F ? b[2] : c[2]; + result[3] = a[3] < 0.0F ? b[3] : c[3]; + store_vector4( inst, machine, result ); + } + break; + case OPCODE_COS: + { + GLfloat a[4], result[4]; + fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); + result[0] = result[1] = result[2] = result[3] + = (GLfloat) _mesa_cos(a[0]); + store_vector4( inst, machine, result ); + } + break; + case OPCODE_DDX: /* Partial derivative with respect to X */ + { + GLfloat a[4], aNext[4], result[4]; + struct fp_machine dMachine; + if (!fetch_vector4_deriv(ctx, &inst->SrcReg[0], span, 'X', + column, result)) { + /* This is tricky. Make a copy of the current machine state, + * increment the input registers by the dx or dy partial + * derivatives, then re-execute the program up to the + * preceeding instruction, then fetch the source register. + * Finally, find the difference in the register values for + * the original and derivative runs. + */ + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a); + init_machine_deriv(ctx, machine, program, span, + 'X', &dMachine); + execute_program(ctx, program, pc, &dMachine, span, column); + fetch_vector4( ctx, &inst->SrcReg[0], &dMachine, program, aNext ); + result[0] = aNext[0] - a[0]; + result[1] = aNext[1] - a[1]; + result[2] = aNext[2] - a[2]; + result[3] = aNext[3] - a[3]; + } + store_vector4( inst, machine, result ); + } + break; + case OPCODE_DDY: /* Partial derivative with respect to Y */ + { + GLfloat a[4], aNext[4], result[4]; + struct fp_machine dMachine; + if (!fetch_vector4_deriv(ctx, &inst->SrcReg[0], span, 'Y', + column, result)) { + init_machine_deriv(ctx, machine, program, span, + 'Y', &dMachine); + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a); + execute_program(ctx, program, pc, &dMachine, span, column); + fetch_vector4( ctx, &inst->SrcReg[0], &dMachine, program, aNext ); + result[0] = aNext[0] - a[0]; + result[1] = aNext[1] - a[1]; + result[2] = aNext[2] - a[2]; + result[3] = aNext[3] - a[3]; + } + store_vector4( inst, machine, result ); + } + break; + case OPCODE_DP3: + { + GLfloat a[4], b[4], result[4]; + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); + fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); + result[0] = result[1] = result[2] = result[3] = DOT3(a, b); + store_vector4( inst, machine, result ); + if (DEBUG_FRAG) { + printf("DP3 %g = (%g %g %g) . (%g %g %g)\n", + result[0], a[0], a[1], a[2], b[0], b[1], b[2]); + } + } + break; + case OPCODE_DP4: + { + GLfloat a[4], b[4], result[4]; + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); + fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); + result[0] = result[1] = result[2] = result[3] = DOT4(a,b); + store_vector4( inst, machine, result ); + if (DEBUG_FRAG) { + printf("DP4 %g = (%g, %g %g %g) . (%g, %g %g %g)\n", + result[0], a[0], a[1], a[2], a[3], + b[0], b[1], b[2], b[3]); + } + } + break; + case OPCODE_DPH: + { + GLfloat a[4], b[4], result[4]; + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); + fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); + result[0] = result[1] = result[2] = result[3] = + a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + b[3]; + store_vector4( inst, machine, result ); + } + break; + case OPCODE_DST: /* Distance vector */ + { + GLfloat a[4], b[4], result[4]; + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); + fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); + result[0] = 1.0F; + result[1] = a[1] * b[1]; + result[2] = a[2]; + result[3] = b[3]; + store_vector4( inst, machine, result ); + } + break; + case OPCODE_EX2: /* Exponential base 2 */ + { + GLfloat a[4], result[4]; + fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); + result[0] = result[1] = result[2] = result[3] = + (GLfloat) _mesa_pow(2.0, a[0]); + store_vector4( inst, machine, result ); + } + break; + case OPCODE_FLR: + { + GLfloat a[4], result[4]; + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); + result[0] = FLOORF(a[0]); + result[1] = FLOORF(a[1]); + result[2] = FLOORF(a[2]); + result[3] = FLOORF(a[3]); + store_vector4( inst, machine, result ); + } + break; + case OPCODE_FRC: + { + GLfloat a[4], result[4]; + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); + result[0] = a[0] - FLOORF(a[0]); + result[1] = a[1] - FLOORF(a[1]); + result[2] = a[2] - FLOORF(a[2]); + result[3] = a[3] - FLOORF(a[3]); + store_vector4( inst, machine, result ); + } + break; + case OPCODE_KIL_NV: /* NV_f_p only */ + { + const GLuint swizzle = inst->DstReg.CondSwizzle; + const GLuint condMask = inst->DstReg.CondMask; + if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) || + test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) || + test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) || + test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) { + return GL_FALSE; + } + } + break; + case OPCODE_KIL: /* ARB_f_p only */ + { + GLfloat a[4]; + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); + if (a[0] < 0.0F || a[1] < 0.0F || a[2] < 0.0F || a[3] < 0.0F) { + return GL_FALSE; + } + } + break; + case OPCODE_LG2: /* log base 2 */ + { + GLfloat a[4], result[4]; + fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); + result[0] = result[1] = result[2] = result[3] = LOG2(a[0]); + store_vector4( inst, machine, result ); + } + break; + case OPCODE_LIT: + { + const GLfloat epsilon = 1.0F / 256.0F; /* from NV VP spec */ + GLfloat a[4], result[4]; + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); + a[0] = MAX2(a[0], 0.0F); + a[1] = MAX2(a[1], 0.0F); + /* XXX ARB version clamps a[3], NV version doesn't */ + a[3] = CLAMP(a[3], -(128.0F - epsilon), (128.0F - epsilon)); + result[0] = 1.0F; + result[1] = a[0]; + /* XXX we could probably just use pow() here */ + if (a[0] > 0.0F) { + if (a[1] == 0.0 && a[3] == 0.0) + result[2] = 1.0; + else + result[2] = EXPF(a[3] * LOGF(a[1])); + } + else { + result[2] = 0.0; + } + result[3] = 1.0F; + store_vector4( inst, machine, result ); + if (DEBUG_FRAG) { + printf("LIT (%g %g %g %g) : (%g %g %g %g)\n", + result[0], result[1], result[2], result[3], + a[0], a[1], a[2], a[3]); + } + } + break; + case OPCODE_LRP: + { + GLfloat a[4], b[4], c[4], result[4]; + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); + fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); + fetch_vector4( ctx, &inst->SrcReg[2], machine, program, c ); + result[0] = a[0] * b[0] + (1.0F - a[0]) * c[0]; + result[1] = a[1] * b[1] + (1.0F - a[1]) * c[1]; + result[2] = a[2] * b[2] + (1.0F - a[2]) * c[2]; + result[3] = a[3] * b[3] + (1.0F - a[3]) * c[3]; + store_vector4( inst, machine, result ); + if (DEBUG_FRAG) { + printf("LRP (%g %g %g %g) = (%g %g %g %g), " + "(%g %g %g %g), (%g %g %g %g)\n", + result[0], result[1], result[2], result[3], + a[0], a[1], a[2], a[3], + b[0], b[1], b[2], b[3], + c[0], c[1], c[2], c[3]); + } + } + break; + case OPCODE_MAD: + { + GLfloat a[4], b[4], c[4], result[4]; + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); + fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); + fetch_vector4( ctx, &inst->SrcReg[2], machine, program, c ); + result[0] = a[0] * b[0] + c[0]; + result[1] = a[1] * b[1] + c[1]; + result[2] = a[2] * b[2] + c[2]; + result[3] = a[3] * b[3] + c[3]; + store_vector4( inst, machine, result ); + if (DEBUG_FRAG) { + printf("MAD (%g %g %g %g) = (%g %g %g %g) * " + "(%g %g %g %g) + (%g %g %g %g)\n", + result[0], result[1], result[2], result[3], + a[0], a[1], a[2], a[3], + b[0], b[1], b[2], b[3], + c[0], c[1], c[2], c[3]); + } + } + break; + case OPCODE_MAX: + { + GLfloat a[4], b[4], result[4]; + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); + fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); + result[0] = MAX2(a[0], b[0]); + result[1] = MAX2(a[1], b[1]); + result[2] = MAX2(a[2], b[2]); + result[3] = MAX2(a[3], b[3]); + store_vector4( inst, machine, result ); + if (DEBUG_FRAG) { + printf("MAX (%g %g %g %g) = (%g %g %g %g), (%g %g %g %g)\n", + result[0], result[1], result[2], result[3], + a[0], a[1], a[2], a[3], + b[0], b[1], b[2], b[3]); + } + } + break; + case OPCODE_MIN: + { + GLfloat a[4], b[4], result[4]; + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); + fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); + result[0] = MIN2(a[0], b[0]); + result[1] = MIN2(a[1], b[1]); + result[2] = MIN2(a[2], b[2]); + result[3] = MIN2(a[3], b[3]); + store_vector4( inst, machine, result ); + } + break; + case OPCODE_MOV: + { + GLfloat result[4]; + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, result ); + store_vector4( inst, machine, result ); + if (DEBUG_FRAG) { + printf("MOV (%g %g %g %g)\n", + result[0], result[1], result[2], result[3]); + } + } + break; + case OPCODE_MUL: + { + GLfloat a[4], b[4], result[4]; + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); + fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); + result[0] = a[0] * b[0]; + result[1] = a[1] * b[1]; + result[2] = a[2] * b[2]; + result[3] = a[3] * b[3]; + store_vector4( inst, machine, result ); + if (DEBUG_FRAG) { + printf("MUL (%g %g %g %g) = (%g %g %g %g) * (%g %g %g %g)\n", + result[0], result[1], result[2], result[3], + a[0], a[1], a[2], a[3], + b[0], b[1], b[2], b[3]); + } + } + break; + case OPCODE_PK2H: /* pack two 16-bit floats in one 32-bit float */ + { + GLfloat a[4], result[4]; + GLhalfNV hx, hy; + GLuint *rawResult = (GLuint *) result; + GLuint twoHalves; + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); + hx = _mesa_float_to_half(a[0]); + hy = _mesa_float_to_half(a[1]); + twoHalves = hx | (hy << 16); + rawResult[0] = rawResult[1] = rawResult[2] = rawResult[3] + = twoHalves; + store_vector4( inst, machine, result ); + } + break; + case OPCODE_PK2US: /* pack two GLushorts into one 32-bit float */ + { + GLfloat a[4], result[4]; + GLuint usx, usy, *rawResult = (GLuint *) result; + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); + a[0] = CLAMP(a[0], 0.0F, 1.0F); + a[1] = CLAMP(a[1], 0.0F, 1.0F); + usx = IROUND(a[0] * 65535.0F); + usy = IROUND(a[1] * 65535.0F); + rawResult[0] = rawResult[1] = rawResult[2] = rawResult[3] + = usx | (usy << 16); + store_vector4( inst, machine, result ); + } + break; + case OPCODE_PK4B: /* pack four GLbytes into one 32-bit float */ + { + GLfloat a[4], result[4]; + GLuint ubx, uby, ubz, ubw, *rawResult = (GLuint *) result; + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); + a[0] = CLAMP(a[0], -128.0F / 127.0F, 1.0F); + a[1] = CLAMP(a[1], -128.0F / 127.0F, 1.0F); + a[2] = CLAMP(a[2], -128.0F / 127.0F, 1.0F); + a[3] = CLAMP(a[3], -128.0F / 127.0F, 1.0F); + ubx = IROUND(127.0F * a[0] + 128.0F); + uby = IROUND(127.0F * a[1] + 128.0F); + ubz = IROUND(127.0F * a[2] + 128.0F); + ubw = IROUND(127.0F * a[3] + 128.0F); + rawResult[0] = rawResult[1] = rawResult[2] = rawResult[3] + = ubx | (uby << 8) | (ubz << 16) | (ubw << 24); + store_vector4( inst, machine, result ); + } + break; + case OPCODE_PK4UB: /* pack four GLubytes into one 32-bit float */ + { + GLfloat a[4], result[4]; + GLuint ubx, uby, ubz, ubw, *rawResult = (GLuint *) result; + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); + a[0] = CLAMP(a[0], 0.0F, 1.0F); + a[1] = CLAMP(a[1], 0.0F, 1.0F); + a[2] = CLAMP(a[2], 0.0F, 1.0F); + a[3] = CLAMP(a[3], 0.0F, 1.0F); + ubx = IROUND(255.0F * a[0]); + uby = IROUND(255.0F * a[1]); + ubz = IROUND(255.0F * a[2]); + ubw = IROUND(255.0F * a[3]); + rawResult[0] = rawResult[1] = rawResult[2] = rawResult[3] + = ubx | (uby << 8) | (ubz << 16) | (ubw << 24); + store_vector4( inst, machine, result ); + } + break; + case OPCODE_POW: + { + GLfloat a[4], b[4], result[4]; + fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); + fetch_vector1( ctx, &inst->SrcReg[1], machine, program, b ); + result[0] = result[1] = result[2] = result[3] + = (GLfloat)_mesa_pow(a[0], b[0]); + store_vector4( inst, machine, result ); + } + break; + case OPCODE_RCP: + { + GLfloat a[4], result[4]; + fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); + if (DEBUG_FRAG) { + if (a[0] == 0) + printf("RCP(0)\n"); + else if (IS_INF_OR_NAN(a[0])) + printf("RCP(inf)\n"); + } + result[0] = result[1] = result[2] = result[3] = 1.0F / a[0]; + store_vector4( inst, machine, result ); + } + break; + case OPCODE_RET: /* return from subroutine */ + { + /* NOTE: The return is conditional! */ + const GLuint swizzle = inst->DstReg.CondSwizzle; + const GLuint condMask = inst->DstReg.CondMask; + if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) || + test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) || + test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) || + test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) { + if (machine->StackDepth == 0) { + return GL_TRUE; /* Per GL_NV_vertex_program2 spec */ + } + pc = machine->CallStack[--machine->StackDepth]; + } + } + break; + case OPCODE_RFL: /* reflection vector */ + { + GLfloat axis[4], dir[4], result[4], tmpX, tmpW; + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, axis ); + fetch_vector4( ctx, &inst->SrcReg[1], machine, program, dir ); + tmpW = DOT3(axis, axis); + tmpX = (2.0F * DOT3(axis, dir)) / tmpW; + result[0] = tmpX * axis[0] - dir[0]; + result[1] = tmpX * axis[1] - dir[1]; + result[2] = tmpX * axis[2] - dir[2]; + /* result[3] is never written! XXX enforce in parser! */ + store_vector4( inst, machine, result ); + } + break; + case OPCODE_RSQ: /* 1 / sqrt() */ + { + GLfloat a[4], result[4]; + fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); + a[0] = FABSF(a[0]); + result[0] = result[1] = result[2] = result[3] = INV_SQRTF(a[0]); + store_vector4( inst, machine, result ); + if (DEBUG_FRAG) { + printf("RSQ %g = 1/sqrt(|%g|)\n", result[0], a[0]); + } + } + break; + case OPCODE_SCS: /* sine and cos */ + { + GLfloat a[4], result[4]; + fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); + result[0] = (GLfloat)_mesa_cos(a[0]); + result[1] = (GLfloat)_mesa_sin(a[0]); + result[2] = 0.0; /* undefined! */ + result[3] = 0.0; /* undefined! */ + store_vector4( inst, machine, result ); + } + break; + case OPCODE_SEQ: /* set on equal */ + { + GLfloat a[4], b[4], result[4]; + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); + fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); + result[0] = (a[0] == b[0]) ? 1.0F : 0.0F; + result[1] = (a[1] == b[1]) ? 1.0F : 0.0F; + result[2] = (a[2] == b[2]) ? 1.0F : 0.0F; + result[3] = (a[3] == b[3]) ? 1.0F : 0.0F; + store_vector4( inst, machine, result ); + } + break; + case OPCODE_SFL: /* set false, operands ignored */ + { + static const GLfloat result[4] = { 0.0F, 0.0F, 0.0F, 0.0F }; + store_vector4( inst, machine, result ); + } + break; + case OPCODE_SGE: /* set on greater or equal */ + { + GLfloat a[4], b[4], result[4]; + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); + fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); + result[0] = (a[0] >= b[0]) ? 1.0F : 0.0F; + result[1] = (a[1] >= b[1]) ? 1.0F : 0.0F; + result[2] = (a[2] >= b[2]) ? 1.0F : 0.0F; + result[3] = (a[3] >= b[3]) ? 1.0F : 0.0F; + store_vector4( inst, machine, result ); + } + break; + case OPCODE_SGT: /* set on greater */ + { + GLfloat a[4], b[4], result[4]; + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); + fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); + result[0] = (a[0] > b[0]) ? 1.0F : 0.0F; + result[1] = (a[1] > b[1]) ? 1.0F : 0.0F; + result[2] = (a[2] > b[2]) ? 1.0F : 0.0F; + result[3] = (a[3] > b[3]) ? 1.0F : 0.0F; + store_vector4( inst, machine, result ); + } + break; + case OPCODE_SIN: + { + GLfloat a[4], result[4]; + fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); + result[0] = result[1] = result[2] = result[3] + = (GLfloat) _mesa_sin(a[0]); + store_vector4( inst, machine, result ); + } + break; + case OPCODE_SLE: /* set on less or equal */ + { + GLfloat a[4], b[4], result[4]; + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); + fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); + result[0] = (a[0] <= b[0]) ? 1.0F : 0.0F; + result[1] = (a[1] <= b[1]) ? 1.0F : 0.0F; + result[2] = (a[2] <= b[2]) ? 1.0F : 0.0F; + result[3] = (a[3] <= b[3]) ? 1.0F : 0.0F; + store_vector4( inst, machine, result ); + } + break; + case OPCODE_SLT: /* set on less */ + { + GLfloat a[4], b[4], result[4]; + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); + fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); + result[0] = (a[0] < b[0]) ? 1.0F : 0.0F; + result[1] = (a[1] < b[1]) ? 1.0F : 0.0F; + result[2] = (a[2] < b[2]) ? 1.0F : 0.0F; + result[3] = (a[3] < b[3]) ? 1.0F : 0.0F; + store_vector4( inst, machine, result ); + } + break; + case OPCODE_SNE: /* set on not equal */ + { + GLfloat a[4], b[4], result[4]; + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); + fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); + result[0] = (a[0] != b[0]) ? 1.0F : 0.0F; + result[1] = (a[1] != b[1]) ? 1.0F : 0.0F; + result[2] = (a[2] != b[2]) ? 1.0F : 0.0F; + result[3] = (a[3] != b[3]) ? 1.0F : 0.0F; + store_vector4( inst, machine, result ); + } + break; + case OPCODE_STR: /* set true, operands ignored */ + { + static const GLfloat result[4] = { 1.0F, 1.0F, 1.0F, 1.0F }; + store_vector4( inst, machine, result ); + } + break; + case OPCODE_SUB: + { + GLfloat a[4], b[4], result[4]; + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); + fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); + result[0] = a[0] - b[0]; + result[1] = a[1] - b[1]; + result[2] = a[2] - b[2]; + result[3] = a[3] - b[3]; + store_vector4( inst, machine, result ); + if (DEBUG_FRAG) { + printf("SUB (%g %g %g %g) = (%g %g %g %g) - (%g %g %g %g)\n", + result[0], result[1], result[2], result[3], + a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3]); + } + } + break; + case OPCODE_SWZ: /* extended swizzle */ + { + const struct prog_src_register *source = &inst->SrcReg[0]; + const GLfloat *src = get_register_pointer(ctx, source, + machine, program); + GLfloat result[4]; + GLuint i; + for (i = 0; i < 4; i++) { + const GLuint swz = GET_SWZ(source->Swizzle, i); + if (swz == SWIZZLE_ZERO) + result[i] = 0.0; + else if (swz == SWIZZLE_ONE) + result[i] = 1.0; + else { + ASSERT(swz >= 0); + ASSERT(swz <= 3); + result[i] = src[swz]; + } + if (source->NegateBase & (1 << i)) + result[i] = -result[i]; + } + store_vector4( inst, machine, result ); + } + break; + case OPCODE_TEX: /* Both ARB and NV frag prog */ + /* Texel lookup */ + { + /* Note: only use the precomputed lambda value when we're + * sampling texture unit [K] with texcoord[K]. + * Otherwise, the lambda value may have no relation to the + * instruction's texcoord or texture image. Using the wrong + * lambda is usually bad news. + * The rest of the time, just use zero (until we get a more + * sophisticated way of computing lambda). + */ + GLfloat coord[4], color[4], lambda; + if (inst->SrcReg[0].File == PROGRAM_INPUT && + inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0+inst->TexSrcUnit) + lambda = span->array->lambda[inst->TexSrcUnit][column]; + else + lambda = 0.0; + fetch_vector4(ctx, &inst->SrcReg[0], machine, program, coord); + fetch_texel( ctx, coord, lambda, inst->TexSrcUnit, color ); + if (DEBUG_FRAG) { + printf("TEX (%g, %g, %g, %g) = texture[%d][%g, %g, %g, %g], " + "lod %f\n", + color[0], color[1], color[2], color[3], + inst->TexSrcUnit, + coord[0], coord[1], coord[2], coord[3], lambda); + } + store_vector4( inst, machine, color ); + } + break; + case OPCODE_TXB: /* GL_ARB_fragment_program only */ + /* Texel lookup with LOD bias */ + { + GLfloat coord[4], color[4], lambda, bias; + if (inst->SrcReg[0].File == PROGRAM_INPUT && + inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0+inst->TexSrcUnit) + lambda = span->array->lambda[inst->TexSrcUnit][column]; + else + lambda = 0.0; + fetch_vector4(ctx, &inst->SrcReg[0], machine, program, coord); + /* coord[3] is the bias to add to lambda */ + bias = ctx->Texture.Unit[inst->TexSrcUnit].LodBias + + ctx->Texture.Unit[inst->TexSrcUnit]._Current->LodBias + + coord[3]; + fetch_texel(ctx, coord, lambda + bias, inst->TexSrcUnit, color); + store_vector4( inst, machine, color ); + } + break; + case OPCODE_TXD: /* GL_NV_fragment_program only */ + /* Texture lookup w/ partial derivatives for LOD */ + { + GLfloat texcoord[4], dtdx[4], dtdy[4], color[4]; + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, texcoord ); + fetch_vector4( ctx, &inst->SrcReg[1], machine, program, dtdx ); + fetch_vector4( ctx, &inst->SrcReg[2], machine, program, dtdy ); + fetch_texel_deriv( ctx, texcoord, dtdx, dtdy, inst->TexSrcUnit, + color ); + store_vector4( inst, machine, color ); + } + break; + case OPCODE_TXP: /* GL_ARB_fragment_program only */ + /* Texture lookup w/ projective divide */ + { + GLfloat texcoord[4], color[4], lambda; + if (inst->SrcReg[0].File == PROGRAM_INPUT && + inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0+inst->TexSrcUnit) + lambda = span->array->lambda[inst->TexSrcUnit][column]; + else + lambda = 0.0; + fetch_vector4(ctx, &inst->SrcReg[0], machine, program,texcoord); + /* Not so sure about this test - if texcoord[3] is + * zero, we'd probably be fine except for an ASSERT in + * IROUND_POS() which gets triggered by the inf values created. + */ + if (texcoord[3] != 0.0) { + texcoord[0] /= texcoord[3]; + texcoord[1] /= texcoord[3]; + texcoord[2] /= texcoord[3]; + } + fetch_texel( ctx, texcoord, lambda, inst->TexSrcUnit, color ); + store_vector4( inst, machine, color ); + } + break; + case OPCODE_TXP_NV: /* GL_NV_fragment_program only */ + /* Texture lookup w/ projective divide */ + { + GLfloat texcoord[4], color[4], lambda; + if (inst->SrcReg[0].File == PROGRAM_INPUT && + inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0+inst->TexSrcUnit) + lambda = span->array->lambda[inst->TexSrcUnit][column]; + else + lambda = 0.0; + fetch_vector4(ctx, &inst->SrcReg[0], machine, program,texcoord); + if (inst->TexSrcTarget != TEXTURE_CUBE_INDEX && + texcoord[3] != 0.0) { + texcoord[0] /= texcoord[3]; + texcoord[1] /= texcoord[3]; + texcoord[2] /= texcoord[3]; + } + fetch_texel( ctx, texcoord, lambda, inst->TexSrcUnit, color ); + store_vector4( inst, machine, color ); + } + break; + case OPCODE_UP2H: /* unpack two 16-bit floats */ + { + GLfloat a[4], result[4]; + const GLuint *rawBits = (const GLuint *) a; + GLhalfNV hx, hy; + fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); + hx = rawBits[0] & 0xffff; + hy = rawBits[0] >> 16; + result[0] = result[2] = _mesa_half_to_float(hx); + result[1] = result[3] = _mesa_half_to_float(hy); + store_vector4( inst, machine, result ); + } + break; + case OPCODE_UP2US: /* unpack two GLushorts */ + { + GLfloat a[4], result[4]; + const GLuint *rawBits = (const GLuint *) a; + GLushort usx, usy; + fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); + usx = rawBits[0] & 0xffff; + usy = rawBits[0] >> 16; + result[0] = result[2] = usx * (1.0f / 65535.0f); + result[1] = result[3] = usy * (1.0f / 65535.0f); + store_vector4( inst, machine, result ); + } + break; + case OPCODE_UP4B: /* unpack four GLbytes */ + { + GLfloat a[4], result[4]; + const GLuint *rawBits = (const GLuint *) a; + fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); + result[0] = (((rawBits[0] >> 0) & 0xff) - 128) / 127.0F; + result[1] = (((rawBits[0] >> 8) & 0xff) - 128) / 127.0F; + result[2] = (((rawBits[0] >> 16) & 0xff) - 128) / 127.0F; + result[3] = (((rawBits[0] >> 24) & 0xff) - 128) / 127.0F; + store_vector4( inst, machine, result ); + } + break; + case OPCODE_UP4UB: /* unpack four GLubytes */ + { + GLfloat a[4], result[4]; + const GLuint *rawBits = (const GLuint *) a; + fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); + result[0] = ((rawBits[0] >> 0) & 0xff) / 255.0F; + result[1] = ((rawBits[0] >> 8) & 0xff) / 255.0F; + result[2] = ((rawBits[0] >> 16) & 0xff) / 255.0F; + result[3] = ((rawBits[0] >> 24) & 0xff) / 255.0F; + store_vector4( inst, machine, result ); + } + break; + case OPCODE_XPD: /* cross product */ + { + GLfloat a[4], b[4], result[4]; + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); + fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); + result[0] = a[1] * b[2] - a[2] * b[1]; + result[1] = a[2] * b[0] - a[0] * b[2]; + result[2] = a[0] * b[1] - a[1] * b[0]; + result[3] = 1.0; + store_vector4( inst, machine, result ); + } + break; + case OPCODE_X2D: /* 2-D matrix transform */ + { + GLfloat a[4], b[4], c[4], result[4]; + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); + fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); + fetch_vector4( ctx, &inst->SrcReg[2], machine, program, c ); + result[0] = a[0] + b[0] * c[0] + b[1] * c[1]; + result[1] = a[1] + b[0] * c[2] + b[1] * c[3]; + result[2] = a[2] + b[0] * c[0] + b[1] * c[1]; + result[3] = a[3] + b[0] * c[2] + b[1] * c[3]; + store_vector4( inst, machine, result ); + } + break; + case OPCODE_PRINT: + { + if (inst->SrcReg[0].File != -1) { + GLfloat a[4]; + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a); + _mesa_printf("%s%g, %g, %g, %g\n", (const char *) inst->Data, + a[0], a[1], a[2], a[3]); + } + else { + _mesa_printf("%s\n", (const char *) inst->Data); + } + } + break; + case OPCODE_END: + return GL_TRUE; + default: + _mesa_problem(ctx, "Bad opcode %d in _mesa_exec_fragment_program", + inst->Opcode); + return GL_TRUE; /* return value doesn't matter */ + } + } + return GL_TRUE; +} + + +/** + * Initialize the virtual fragment program machine state prior to running + * fragment program on a fragment. This involves initializing the input + * registers, condition codes, etc. + * \param machine the virtual machine state to init + * \param program the fragment program we're about to run + * \param span the span of pixels we'll operate on + * \param col which element (column) of the span we'll operate on + */ +static void +init_machine( GLcontext *ctx, struct fp_machine *machine, + const struct gl_fragment_program *program, + const SWspan *span, GLuint col ) +{ + GLuint inputsRead = program->Base.InputsRead; + GLuint u, v; + + if (ctx->FragmentProgram.CallbackEnabled) + inputsRead = ~0; + + if (program->Base.Target == GL_FRAGMENT_PROGRAM_NV) { + /* Clear temporary registers (undefined for ARB_f_p) */ + _mesa_bzero(machine->Temporaries, + MAX_NV_FRAGMENT_PROGRAM_TEMPS * 4 * sizeof(GLfloat)); + } + + /* Load input registers */ + if (inputsRead & (1 << FRAG_ATTRIB_WPOS)) { + GLfloat *wpos = machine->Inputs[FRAG_ATTRIB_WPOS]; + ASSERT(span->arrayMask & SPAN_Z); + if (span->arrayMask & SPAN_XY) { + wpos[0] = (GLfloat) span->array->x[col]; + wpos[1] = (GLfloat) span->array->y[col]; + } + else { + wpos[0] = (GLfloat) span->x + col; + wpos[1] = (GLfloat) span->y; + } + wpos[2] = (GLfloat) span->array->z[col] / ctx->DrawBuffer->_DepthMaxF; + wpos[3] = span->w + col * span->dwdx; + } + if (inputsRead & (1 << FRAG_ATTRIB_COL0)) { + ASSERT(span->arrayMask & SPAN_RGBA); + COPY_4V(machine->Inputs[FRAG_ATTRIB_COL0], + span->array->color.sz4.rgba[col]); + } + if (inputsRead & (1 << FRAG_ATTRIB_COL1)) { + ASSERT(span->arrayMask & SPAN_SPEC); + COPY_4V(machine->Inputs[FRAG_ATTRIB_COL1], + span->array->color.sz4.spec[col]); + } + if (inputsRead & (1 << FRAG_ATTRIB_FOGC)) { + GLfloat *fogc = machine->Inputs[FRAG_ATTRIB_FOGC]; + ASSERT(span->arrayMask & SPAN_FOG); + fogc[0] = span->array->fog[col]; + fogc[1] = 0.0F; + fogc[2] = 0.0F; + fogc[3] = 0.0F; + } + for (u = 0; u < ctx->Const.MaxTextureCoordUnits; u++) { + if (inputsRead & (1 << (FRAG_ATTRIB_TEX0 + u))) { + GLfloat *tex = machine->Inputs[FRAG_ATTRIB_TEX0 + u]; + /*ASSERT(ctx->Texture._EnabledCoordUnits & (1 << u));*/ + COPY_4V(tex, span->array->texcoords[u][col]); + /*ASSERT(tex[0] != 0 || tex[1] != 0 || tex[2] != 0);*/ + } + } + for (v = 0; v < ctx->Const.MaxVarying; v++) { + if (inputsRead & (1 << (FRAG_ATTRIB_VAR0 + v))) { +#if 0 + printf("Frag Var %d: %f %f %f\n", col, + span->array->varying[col][v][0], + span->array->varying[col][v][1], + span->array->varying[col][v][2]); +#endif + COPY_4V(machine->Inputs[FRAG_ATTRIB_VAR0 + v], + span->array->varying[col][v]); + } + } + + /* init condition codes */ + machine->CondCodes[0] = COND_EQ; + machine->CondCodes[1] = COND_EQ; + machine->CondCodes[2] = COND_EQ; + machine->CondCodes[3] = COND_EQ; + + /* init call stack */ + machine->StackDepth = 0; +} + + +/** + * Run fragment program on the pixels in span from 'start' to 'end' - 1. + */ +static void +run_program(GLcontext *ctx, SWspan *span, GLuint start, GLuint end) +{ + const struct gl_fragment_program *program = ctx->FragmentProgram._Current; + struct fp_machine machine; + GLuint i; + + CurrentMachine = &machine; + + for (i = start; i < end; i++) { + if (span->array->mask[i]) { + init_machine(ctx, &machine, program, span, i); + + if (execute_program(ctx, program, ~0, &machine, span, i)) { + /* Store result color */ + COPY_4V(span->array->color.sz4.rgba[i], + machine.Outputs[FRAG_RESULT_COLR]); + + /* Store result depth/z */ + if (program->Base.OutputsWritten & (1 << FRAG_RESULT_DEPR)) { + const GLfloat depth = machine.Outputs[FRAG_RESULT_DEPR][2]; + if (depth <= 0.0) + span->array->z[i] = 0; + else if (depth >= 1.0) + span->array->z[i] = ctx->DrawBuffer->_DepthMax; + else + span->array->z[i] = IROUND(depth * ctx->DrawBuffer->_DepthMaxF); + } + } + else { + /* killed fragment */ + span->array->mask[i] = GL_FALSE; + span->writeAll = GL_FALSE; + } + } + } + + CurrentMachine = NULL; +} + + +/** + * Execute the current fragment program for all the fragments + * in the given span. + */ +void +_swrast_exec_fragment_program( GLcontext *ctx, SWspan *span ) +{ + const struct gl_fragment_program *program = ctx->FragmentProgram._Current; + + /* incoming colors should be floats */ + ASSERT(span->array->ChanType == GL_FLOAT); + + ctx->_CurrentProgram = GL_FRAGMENT_PROGRAM_ARB; /* or NV, doesn't matter */ + + run_program(ctx, span, 0, span->end); + + if (program->Base.OutputsWritten & (1 << FRAG_RESULT_DEPR)) { + span->interpMask &= ~SPAN_Z; + span->arrayMask |= SPAN_Z; + } + + ctx->_CurrentProgram = 0; +} + diff --git a/src/mesa/swrast/s_fragprog.h b/src/mesa/swrast/s_fragprog.h new file mode 100644 index 0000000000..188bacc3d8 --- /dev/null +++ b/src/mesa/swrast/s_fragprog.h @@ -0,0 +1,37 @@ +/* + * Mesa 3-D graphics library + * Version: 6.1 + * + * Copyright (C) 1999-2003 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +#ifndef S_NVFRAGPROG_H +#define S_NVFRAGPROG_H + + +#include "s_context.h" + + +extern void +_swrast_exec_fragment_program( GLcontext *ctx, SWspan *span ); + + +#endif -- cgit v1.2.3 From b78fb7abaff4e1b1e55d7f2c137ac9a1d40137f2 Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 15 Dec 2006 08:49:27 -0700 Subject: Renamed s_nvfragprog.[ch] to s_fragprog.[ch], program_instruction.h to prog_instruction.h --- src/mesa/shader/program_instruction.h | 364 ------- src/mesa/swrast/s_nvfragprog.c | 1692 --------------------------------- src/mesa/swrast/s_nvfragprog.h | 37 - 3 files changed, 2093 deletions(-) delete mode 100644 src/mesa/shader/program_instruction.h delete mode 100644 src/mesa/swrast/s_nvfragprog.c delete mode 100644 src/mesa/swrast/s_nvfragprog.h (limited to 'src/mesa/swrast') diff --git a/src/mesa/shader/program_instruction.h b/src/mesa/shader/program_instruction.h deleted file mode 100644 index 2fcdfaa2be..0000000000 --- a/src/mesa/shader/program_instruction.h +++ /dev/null @@ -1,364 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5 - * - * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - - -/** - * \file prog_instruction.h - * - * Private vertex program types and constants only used by files - * related to vertex programs. - * - * \author Brian Paul - * \author Keith Whitwell - * \author Ian Romanick - */ - - -#ifndef PROG_INSTRUCTION_H -#define PROG_INSTRUCTION_H - -/** - * Condition codes for GL_NV_fragment_program - */ -/*@{*/ -#define COND_GT 1 /* greater than zero */ -#define COND_EQ 2 /* equal to zero */ -#define COND_LT 3 /* less than zero */ -#define COND_UN 4 /* unordered (NaN) */ -#define COND_GE 5 /* greater then or equal to zero */ -#define COND_LE 6 /* less then or equal to zero */ -#define COND_NE 7 /* not equal to zero */ -#define COND_TR 8 /* always true */ -#define COND_FL 9 /* always false */ -/*@}*/ - - -/** - * Instruction precision for GL_NV_fragment_program - */ -/*@{*/ -#define FLOAT32 0x1 -#define FLOAT16 0x2 -#define FIXED12 0x4 -/*@}*/ - - -/** - * Saturation modes when storing values. - */ -/*@{*/ -#define SATURATE_OFF 0 -#define SATURATE_ZERO_ONE 1 -#define SATURATE_PLUS_MINUS_ONE 2 -/*@}*/ - - -/** - * Per-component negation masks - */ -/*@{*/ -#define NEGATE_X 0x1 -#define NEGATE_Y 0x2 -#define NEGATE_Z 0x4 -#define NEGATE_W 0x8 -#define NEGATE_XYZW 0xf -#define NEGATE_NONE 0x0 -/*@}*/ - - -/** - * Program instruction opcodes, for both vertex and fragment programs. - * \note changes to this opcode list must be reflected in t_vb_arbprogram.c - */ -typedef enum prog_opcode { - /* ARB_vp ARB_fp NV_vp NV_fp */ - /*---------------------------------*/ - OPCODE_NOP = 0, - OPCODE_ABS, /* X X 1.1 */ - OPCODE_ADD, /* X X X X */ - OPCODE_ARA, /* 2 */ - OPCODE_ARL, /* X X */ - OPCODE_ARL_NV, /* 2 */ - OPCODE_ARR, /* 2 */ - OPCODE_BRA, /* 2 */ - OPCODE_CAL, /* 2 2 */ - OPCODE_CMP, /* X */ - OPCODE_COS, /* X 2 X */ - OPCODE_DDX, /* X */ - OPCODE_DDY, /* X */ - OPCODE_DP3, /* X X X X */ - OPCODE_DP4, /* X X X X */ - OPCODE_DPH, /* X X 1.1 */ - OPCODE_DST, /* X X X X */ - OPCODE_END, /* X X X X */ - OPCODE_EX2, /* X X 2 X */ - OPCODE_EXP, /* X X */ - OPCODE_FLR, /* X X 2 X */ - OPCODE_FRC, /* X X 2 X */ - OPCODE_KIL, /* X */ - OPCODE_KIL_NV, /* X */ - OPCODE_LG2, /* X X 2 X */ - OPCODE_LIT, /* X X X X */ - OPCODE_LOG, /* X X */ - OPCODE_LRP, /* X X */ - OPCODE_MAD, /* X X X X */ - OPCODE_MAX, /* X X X X */ - OPCODE_MIN, /* X X X X */ - OPCODE_MOV, /* X X X X */ - OPCODE_MUL, /* X X X X */ - OPCODE_PK2H, /* X */ - OPCODE_PK2US, /* X */ - OPCODE_PK4B, /* X */ - OPCODE_PK4UB, /* X */ - OPCODE_POW, /* X X X */ - OPCODE_POPA, /* 3 */ - OPCODE_PRINT, /* X X */ - OPCODE_PUSHA, /* 3 */ - OPCODE_RCC, /* 1.1 */ - OPCODE_RCP, /* X X X X */ - OPCODE_RET, /* 2 2 */ - OPCODE_RFL, /* X X */ - OPCODE_RSQ, /* X X X X */ - OPCODE_SCS, /* X */ - OPCODE_SEQ, /* 2 X */ - OPCODE_SFL, /* 2 X */ - OPCODE_SGE, /* X X X X */ - OPCODE_SGT, /* 2 X */ - OPCODE_SIN, /* X 2 X */ - OPCODE_SLE, /* 2 X */ - OPCODE_SLT, /* X X X X */ - OPCODE_SNE, /* 2 X */ - OPCODE_SSG, /* 2 */ - OPCODE_STR, /* 2 X */ - OPCODE_SUB, /* X X 1.1 X */ - OPCODE_SWZ, /* X X */ - OPCODE_TEX, /* X 3 X */ - OPCODE_TXB, /* X 3 */ - OPCODE_TXD, /* X */ - OPCODE_TXL, /* 3 2 */ - OPCODE_TXP, /* X */ - OPCODE_TXP_NV, /* 3 X */ - OPCODE_UP2H, /* X */ - OPCODE_UP2US, /* X */ - OPCODE_UP4B, /* X */ - OPCODE_UP4UB, /* X */ - OPCODE_X2D, /* X */ - OPCODE_XPD, /* X X */ - MAX_OPCODE -} gl_inst_opcode; - - -/** - * Instruction source register. - */ -struct prog_src_register -{ - GLuint File:4; /**< One of the PROGRAM_* register file values. */ - GLint Index:9; /**< May be negative for relative addressing. */ - GLuint Swizzle:12; - GLuint RelAddr:1; - - /** - * \name Source register "sign" control. - * - * The ARB and NV extensions allow varrying degrees of control over the - * sign of the source vector components. These values allow enough control - * for all flavors of the extensions. - */ - /*@{*/ - /** - * Per-component negation for the SWZ instruction. For non-SWZ - * instructions the only possible values are NEGATE_XYZW and NEGATE_NONE. - * - * \since - * ARB_vertex_program, ARB_fragment_program - */ - GLuint NegateBase:4; - - /** - * Take the component-wise absolute value. - * - * \since - * NV_fragment_program, NV_fragment_program_option, NV_vertex_program2, - * NV_vertex_program2_option. - */ - GLuint Abs:1; - - /** - * Post-absolute value negation (all components). - */ - GLuint NegateAbs:1; - /*@}*/ -}; - - -/** - * Instruction destination register. - */ -struct prog_dst_register -{ - /** - * One of the PROGRAM_* register file values. - */ - GLuint File:4; - - GLuint Index:8; - GLuint WriteMask:4; - - /** - * \name Conditional destination update control. - * - * \since - * NV_fragment_program, NV_fragment_program_option, NV_vertex_program2, - * NV_vertex_program2_option. - */ - /*@{*/ - /** - * Takes one of the 9 possible condition values (EQ, FL, GT, GE, LE, LT, - * NE, TR, or UN). Destination update is enabled if the matching - * (swizzled) condition code value passes. When a conditional update mask - * is not specified, this will be \c COND_TR. - */ - GLuint CondMask:4; - - /** - * Condition code swizzle value. - */ - GLuint CondSwizzle:12; - - /** - * Selects the condition code register to use for conditional destination - * update masking. In NV_fragmnet_program or NV_vertex_program2 mode, only - * condition code register 0 is available. In NV_vertex_program3 mode, - * condition code registers 0 and 1 are available. - */ - GLuint CondSrc:1; - /*@}*/ - - GLuint pad:31; -}; - - -/** - * Vertex/fragment program instruction. - */ -struct prog_instruction -{ - gl_inst_opcode Opcode; -#if FEATURE_MESA_program_debug - GLshort StringPos; -#endif - /** - * Arbitrary data. Used for the PRINT, CAL, and BRA instructions. - */ - void *Data; - - struct prog_src_register SrcReg[3]; - struct prog_dst_register DstReg; - - /** - * Indicates that the instruction should update the condition code - * register. - * - * \since - * NV_fragment_program, NV_fragment_program_option, NV_vertex_program2, - * NV_vertex_program2_option. - */ - GLuint CondUpdate:1; - - /** - * If prog_instruction::CondUpdate is \c GL_TRUE, this value selects the - * condition code register that is to be updated. - * - * In GL_NV_fragment_program or GL_NV_vertex_program2 mode, only condition - * code register 0 is available. In GL_NV_vertex_program3 mode, condition - * code registers 0 and 1 are available. - * - * \since - * NV_fragment_program, NV_fragment_program_option, NV_vertex_program2, - * NV_vertex_program2_option. - */ - GLuint CondDst:1; - - /** - * Saturate each value of the vectored result to the range [0,1] or the - * range [-1,1]. \c SSAT mode (i.e., saturation to the range [-1,1]) is - * only available in NV_fragment_program2 mode. - * Value is one of the SATURATE_* tokens. - * - * \since - * NV_fragment_program, NV_fragment_program_option, NV_vertex_program3. - */ - GLuint SaturateMode:2; - - /** - * Per-instruction selectable precision. - * - * \since - * NV_fragment_program, NV_fragment_program_option. - */ - GLuint Precision:3; - - /** - * \name Texture source controls. - * - * The texture source controls are only used with the \c TEX, \c TXD, - * \c TXL, and \c TXP instructions. - * - * \since - * ARB_fragment_program, NV_fragment_program, NV_vertex_program3. - */ - /*@{*/ - /** - * Source texture unit. OpenGL supports a maximum of 32 texture - * units. - */ - GLuint TexSrcUnit:5; - - /** - * Source texture target, one of TEXTURE_{1D,2D,3D,CUBE,RECT}_INDEX. - */ - GLuint TexSrcTarget:3; - /*@}*/ - - /** - * For BRA and CAL instructions, the location to jump to. - */ - GLuint BranchTarget; - - const char *Comment; -}; - - -extern void -_mesa_init_instructions(struct prog_instruction *inst, GLuint count); - -extern GLuint -_mesa_num_inst_src_regs(gl_inst_opcode opcode); - -extern const char * -_mesa_opcode_string(gl_inst_opcode opcode); - - -#endif /* PROG_INSTRUCTION_H */ diff --git a/src/mesa/swrast/s_nvfragprog.c b/src/mesa/swrast/s_nvfragprog.c deleted file mode 100644 index ac2f5d93b6..0000000000 --- a/src/mesa/swrast/s_nvfragprog.c +++ /dev/null @@ -1,1692 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.5.2 - * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * Regarding GL_NV_fragment_program: - * - * Portions of this software may use or implement intellectual - * property owned and licensed by NVIDIA Corporation. NVIDIA disclaims - * any and all warranties with respect to such intellectual property, - * including any use thereof or modifications thereto. - */ - -#include "glheader.h" -#include "colormac.h" -#include "context.h" -#include "prog_instruction.h" -#include "prog_parameter.h" -#include "prog_print.h" -#include "program.h" - -#include "s_nvfragprog.h" -#include "s_span.h" - - -/* See comments below for info about this */ -#define LAMBDA_ZERO 1 - -/* debug predicate */ -#define DEBUG_FRAG 0 - - -/** - * Virtual machine state used during execution of a fragment programs. - */ -struct fp_machine -{ - GLfloat Temporaries[MAX_PROGRAM_TEMPS][4]; - GLfloat Inputs[FRAG_ATTRIB_MAX][4]; - GLfloat Outputs[FRAG_RESULT_MAX][4]; - GLuint CondCodes[4]; /**< COND_* value for x/y/z/w */ - - GLuint CallStack[MAX_PROGRAM_CALL_DEPTH]; /**< For CAL/RET instructions */ - GLuint StackDepth; /**< Index/ptr to top of CallStack[] */ -}; - - -#if FEATURE_MESA_program_debug -static struct fp_machine *CurrentMachine = NULL; - -/** - * For GL_MESA_program_debug. - * Return current value (4*GLfloat) of a fragment program register. - * Called via ctx->Driver.GetFragmentProgramRegister(). - */ -void -_swrast_get_program_register(GLcontext *ctx, enum register_file file, - GLuint index, GLfloat val[4]) -{ - if (CurrentMachine) { - switch (file) { - case PROGRAM_INPUT: - COPY_4V(val, CurrentMachine->Inputs[index]); - break; - case PROGRAM_OUTPUT: - COPY_4V(val, CurrentMachine->Outputs[index]); - break; - case PROGRAM_TEMPORARY: - COPY_4V(val, CurrentMachine->Temporaries[index]); - break; - default: - _mesa_problem(NULL, - "bad register file in _swrast_get_program_register"); - } - } -} -#endif /* FEATURE_MESA_program_debug */ - - -/** - * Fetch a texel. - */ -static void -fetch_texel( GLcontext *ctx, const GLfloat texcoord[4], GLfloat lambda, - GLuint unit, GLfloat color[4] ) -{ - GLchan rgba[4]; - SWcontext *swrast = SWRAST_CONTEXT(ctx); - - /* XXX use a float-valued TextureSample routine here!!! */ - swrast->TextureSample[unit](ctx, ctx->Texture.Unit[unit]._Current, - 1, (const GLfloat (*)[4]) texcoord, - &lambda, &rgba); - color[0] = CHAN_TO_FLOAT(rgba[0]); - color[1] = CHAN_TO_FLOAT(rgba[1]); - color[2] = CHAN_TO_FLOAT(rgba[2]); - color[3] = CHAN_TO_FLOAT(rgba[3]); -} - - -/** - * Fetch a texel with the given partial derivatives to compute a level - * of detail in the mipmap. - */ -static void -fetch_texel_deriv( GLcontext *ctx, const GLfloat texcoord[4], - const GLfloat texdx[4], const GLfloat texdy[4], - GLuint unit, GLfloat color[4] ) -{ - SWcontext *swrast = SWRAST_CONTEXT(ctx); - const struct gl_texture_object *texObj = ctx->Texture.Unit[unit]._Current; - const struct gl_texture_image *texImg = texObj->Image[0][texObj->BaseLevel]; - const GLfloat texW = (GLfloat) texImg->WidthScale; - const GLfloat texH = (GLfloat) texImg->HeightScale; - GLchan rgba[4]; - - GLfloat lambda = _swrast_compute_lambda(texdx[0], texdy[0], /* ds/dx, ds/dy */ - texdx[1], texdy[1], /* dt/dx, dt/dy */ - texdx[3], texdy[2], /* dq/dx, dq/dy */ - texW, texH, - texcoord[0], texcoord[1], texcoord[3], - 1.0F / texcoord[3]); - - swrast->TextureSample[unit](ctx, ctx->Texture.Unit[unit]._Current, - 1, (const GLfloat (*)[4]) texcoord, - &lambda, &rgba); - color[0] = CHAN_TO_FLOAT(rgba[0]); - color[1] = CHAN_TO_FLOAT(rgba[1]); - color[2] = CHAN_TO_FLOAT(rgba[2]); - color[3] = CHAN_TO_FLOAT(rgba[3]); -} - - -/** - * Return a pointer to the 4-element float vector specified by the given - * source register. - */ -static INLINE const GLfloat * -get_register_pointer( GLcontext *ctx, - const struct prog_src_register *source, - const struct fp_machine *machine, - const struct gl_fragment_program *program ) -{ - switch (source->File) { - case PROGRAM_TEMPORARY: - ASSERT(source->Index < MAX_PROGRAM_TEMPS); - return machine->Temporaries[source->Index]; - case PROGRAM_INPUT: - ASSERT(source->Index < FRAG_ATTRIB_MAX); - return machine->Inputs[source->Index]; - case PROGRAM_OUTPUT: - /* This is only for PRINT */ - ASSERT(source->Index < FRAG_RESULT_MAX); - return machine->Outputs[source->Index]; - case PROGRAM_LOCAL_PARAM: - ASSERT(source->Index < MAX_PROGRAM_LOCAL_PARAMS); - return program->Base.LocalParams[source->Index]; - case PROGRAM_ENV_PARAM: - ASSERT(source->Index < MAX_NV_FRAGMENT_PROGRAM_PARAMS); - return ctx->FragmentProgram.Parameters[source->Index]; - case PROGRAM_STATE_VAR: - /* Fallthrough */ - case PROGRAM_CONSTANT: - /* Fallthrough */ - case PROGRAM_UNIFORM: - /* Fallthrough */ - case PROGRAM_NAMED_PARAM: - ASSERT(source->Index < (GLint) program->Base.Parameters->NumParameters); - return program->Base.Parameters->ParameterValues[source->Index]; - default: - _mesa_problem(ctx, "Invalid input register file %d in fp " - "get_register_pointer", source->File); - return NULL; - } -} - - -/** - * Fetch a 4-element float vector from the given source register. - * Apply swizzling and negating as needed. - */ -static void -fetch_vector4( GLcontext *ctx, - const struct prog_src_register *source, - const struct fp_machine *machine, - const struct gl_fragment_program *program, - GLfloat result[4] ) -{ - const GLfloat *src = get_register_pointer(ctx, source, machine, program); - ASSERT(src); - - if (source->Swizzle == MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, - SWIZZLE_Z, SWIZZLE_W)) { - /* no swizzling */ - COPY_4V(result, src); - } - else { - result[0] = src[GET_SWZ(source->Swizzle, 0)]; - result[1] = src[GET_SWZ(source->Swizzle, 1)]; - result[2] = src[GET_SWZ(source->Swizzle, 2)]; - result[3] = src[GET_SWZ(source->Swizzle, 3)]; - } - - if (source->NegateBase) { - result[0] = -result[0]; - result[1] = -result[1]; - result[2] = -result[2]; - result[3] = -result[3]; - } - if (source->Abs) { - result[0] = FABSF(result[0]); - result[1] = FABSF(result[1]); - result[2] = FABSF(result[2]); - result[3] = FABSF(result[3]); - } - if (source->NegateAbs) { - result[0] = -result[0]; - result[1] = -result[1]; - result[2] = -result[2]; - result[3] = -result[3]; - } -} - - -/** - * Fetch the derivative with respect to X for the given register. - * \return GL_TRUE if it was easily computed or GL_FALSE if we - * need to execute another instance of the program (ugh)! - */ -static GLboolean -fetch_vector4_deriv( GLcontext *ctx, - const struct prog_src_register *source, - const SWspan *span, - char xOrY, GLint column, GLfloat result[4] ) -{ - GLfloat src[4]; - - ASSERT(xOrY == 'X' || xOrY == 'Y'); - - switch (source->Index) { - case FRAG_ATTRIB_WPOS: - if (xOrY == 'X') { - src[0] = 1.0; - src[1] = 0.0; - src[2] = span->dzdx / ctx->DrawBuffer->_DepthMaxF; - src[3] = span->dwdx; - } - else { - src[0] = 0.0; - src[1] = 1.0; - src[2] = span->dzdy / ctx->DrawBuffer->_DepthMaxF; - src[3] = span->dwdy; - } - break; - case FRAG_ATTRIB_COL0: - if (xOrY == 'X') { - src[0] = span->drdx * (1.0F / CHAN_MAXF); - src[1] = span->dgdx * (1.0F / CHAN_MAXF); - src[2] = span->dbdx * (1.0F / CHAN_MAXF); - src[3] = span->dadx * (1.0F / CHAN_MAXF); - } - else { - src[0] = span->drdy * (1.0F / CHAN_MAXF); - src[1] = span->dgdy * (1.0F / CHAN_MAXF); - src[2] = span->dbdy * (1.0F / CHAN_MAXF); - src[3] = span->dady * (1.0F / CHAN_MAXF); - } - break; - case FRAG_ATTRIB_COL1: - if (xOrY == 'X') { - src[0] = span->dsrdx * (1.0F / CHAN_MAXF); - src[1] = span->dsgdx * (1.0F / CHAN_MAXF); - src[2] = span->dsbdx * (1.0F / CHAN_MAXF); - src[3] = 0.0; /* XXX need this */ - } - else { - src[0] = span->dsrdy * (1.0F / CHAN_MAXF); - src[1] = span->dsgdy * (1.0F / CHAN_MAXF); - src[2] = span->dsbdy * (1.0F / CHAN_MAXF); - src[3] = 0.0; /* XXX need this */ - } - break; - case FRAG_ATTRIB_FOGC: - if (xOrY == 'X') { - src[0] = span->dfogdx; - src[1] = 0.0; - src[2] = 0.0; - src[3] = 0.0; - } - else { - src[0] = span->dfogdy; - src[1] = 0.0; - src[2] = 0.0; - src[3] = 0.0; - } - break; - case FRAG_ATTRIB_TEX0: - case FRAG_ATTRIB_TEX1: - case FRAG_ATTRIB_TEX2: - case FRAG_ATTRIB_TEX3: - case FRAG_ATTRIB_TEX4: - case FRAG_ATTRIB_TEX5: - case FRAG_ATTRIB_TEX6: - case FRAG_ATTRIB_TEX7: - if (xOrY == 'X') { - const GLuint u = source->Index - FRAG_ATTRIB_TEX0; - /* this is a little tricky - I think I've got it right */ - const GLfloat invQ = 1.0f / (span->tex[u][3] - + span->texStepX[u][3] * column); - src[0] = span->texStepX[u][0] * invQ; - src[1] = span->texStepX[u][1] * invQ; - src[2] = span->texStepX[u][2] * invQ; - src[3] = span->texStepX[u][3] * invQ; - } - else { - const GLuint u = source->Index - FRAG_ATTRIB_TEX0; - /* Tricky, as above, but in Y direction */ - const GLfloat invQ = 1.0f / (span->tex[u][3] + span->texStepY[u][3]); - src[0] = span->texStepY[u][0] * invQ; - src[1] = span->texStepY[u][1] * invQ; - src[2] = span->texStepY[u][2] * invQ; - src[3] = span->texStepY[u][3] * invQ; - } - break; - default: - return GL_FALSE; - } - - result[0] = src[GET_SWZ(source->Swizzle, 0)]; - result[1] = src[GET_SWZ(source->Swizzle, 1)]; - result[2] = src[GET_SWZ(source->Swizzle, 2)]; - result[3] = src[GET_SWZ(source->Swizzle, 3)]; - - if (source->NegateBase) { - result[0] = -result[0]; - result[1] = -result[1]; - result[2] = -result[2]; - result[3] = -result[3]; - } - if (source->Abs) { - result[0] = FABSF(result[0]); - result[1] = FABSF(result[1]); - result[2] = FABSF(result[2]); - result[3] = FABSF(result[3]); - } - if (source->NegateAbs) { - result[0] = -result[0]; - result[1] = -result[1]; - result[2] = -result[2]; - result[3] = -result[3]; - } - return GL_TRUE; -} - - -/** - * As above, but only return result[0] element. - */ -static void -fetch_vector1( GLcontext *ctx, - const struct prog_src_register *source, - const struct fp_machine *machine, - const struct gl_fragment_program *program, - GLfloat result[4] ) -{ - const GLfloat *src = get_register_pointer(ctx, source, machine, program); - ASSERT(src); - - result[0] = src[GET_SWZ(source->Swizzle, 0)]; - - if (source->NegateBase) { - result[0] = -result[0]; - } - if (source->Abs) { - result[0] = FABSF(result[0]); - } - if (source->NegateAbs) { - result[0] = -result[0]; - } -} - - -/** - * Test value against zero and return GT, LT, EQ or UN if NaN. - */ -static INLINE GLuint -generate_cc( float value ) -{ - if (value != value) - return COND_UN; /* NaN */ - if (value > 0.0F) - return COND_GT; - if (value < 0.0F) - return COND_LT; - return COND_EQ; -} - - -/** - * Test if the ccMaskRule is satisfied by the given condition code. - * Used to mask destination writes according to the current condition code. - */ -static INLINE GLboolean -test_cc(GLuint condCode, GLuint ccMaskRule) -{ - switch (ccMaskRule) { - case COND_EQ: return (condCode == COND_EQ); - case COND_NE: return (condCode != COND_EQ); - case COND_LT: return (condCode == COND_LT); - case COND_GE: return (condCode == COND_GT || condCode == COND_EQ); - case COND_LE: return (condCode == COND_LT || condCode == COND_EQ); - case COND_GT: return (condCode == COND_GT); - case COND_TR: return GL_TRUE; - case COND_FL: return GL_FALSE; - default: return GL_TRUE; - } -} - - -/** - * Store 4 floats into a register. Observe the instructions saturate and - * set-condition-code flags. - */ -static void -store_vector4( const struct prog_instruction *inst, - struct fp_machine *machine, - const GLfloat value[4] ) -{ - const struct prog_dst_register *dest = &(inst->DstReg); - const GLboolean clamp = inst->SaturateMode == SATURATE_ZERO_ONE; - GLfloat *dstReg; - GLfloat dummyReg[4]; - GLfloat clampedValue[4]; - GLuint writeMask = dest->WriteMask; - - switch (dest->File) { - case PROGRAM_OUTPUT: - dstReg = machine->Outputs[dest->Index]; - break; - case PROGRAM_TEMPORARY: - dstReg = machine->Temporaries[dest->Index]; - break; - case PROGRAM_WRITE_ONLY: - dstReg = dummyReg; - return; - default: - _mesa_problem(NULL, "bad register file in store_vector4(fp)"); - return; - } - -#if 0 - if (value[0] > 1.0e10 || - IS_INF_OR_NAN(value[0]) || - IS_INF_OR_NAN(value[1]) || - IS_INF_OR_NAN(value[2]) || - IS_INF_OR_NAN(value[3]) ) - printf("store %g %g %g %g\n", value[0], value[1], value[2], value[3]); -#endif - - if (clamp) { - clampedValue[0] = CLAMP(value[0], 0.0F, 1.0F); - clampedValue[1] = CLAMP(value[1], 0.0F, 1.0F); - clampedValue[2] = CLAMP(value[2], 0.0F, 1.0F); - clampedValue[3] = CLAMP(value[3], 0.0F, 1.0F); - value = clampedValue; - } - - if (dest->CondMask != COND_TR) { - /* condition codes may turn off some writes */ - if (writeMask & WRITEMASK_X) { - if (!test_cc(machine->CondCodes[GET_SWZ(dest->CondSwizzle, 0)], - dest->CondMask)) - writeMask &= ~WRITEMASK_X; - } - if (writeMask & WRITEMASK_Y) { - if (!test_cc(machine->CondCodes[GET_SWZ(dest->CondSwizzle, 1)], - dest->CondMask)) - writeMask &= ~WRITEMASK_Y; - } - if (writeMask & WRITEMASK_Z) { - if (!test_cc(machine->CondCodes[GET_SWZ(dest->CondSwizzle, 2)], - dest->CondMask)) - writeMask &= ~WRITEMASK_Z; - } - if (writeMask & WRITEMASK_W) { - if (!test_cc(machine->CondCodes[GET_SWZ(dest->CondSwizzle, 3)], - dest->CondMask)) - writeMask &= ~WRITEMASK_W; - } - } - - if (writeMask & WRITEMASK_X) - dstReg[0] = value[0]; - if (writeMask & WRITEMASK_Y) - dstReg[1] = value[1]; - if (writeMask & WRITEMASK_Z) - dstReg[2] = value[2]; - if (writeMask & WRITEMASK_W) - dstReg[3] = value[3]; - - if (inst->CondUpdate) { - if (writeMask & WRITEMASK_X) - machine->CondCodes[0] = generate_cc(value[0]); - if (writeMask & WRITEMASK_Y) - machine->CondCodes[1] = generate_cc(value[1]); - if (writeMask & WRITEMASK_Z) - machine->CondCodes[2] = generate_cc(value[2]); - if (writeMask & WRITEMASK_W) - machine->CondCodes[3] = generate_cc(value[3]); - } -} - - -/** - * Initialize a new machine state instance from an existing one, adding - * the partial derivatives onto the input registers. - * Used to implement DDX and DDY instructions in non-trivial cases. - */ -static void -init_machine_deriv( GLcontext *ctx, - const struct fp_machine *machine, - const struct gl_fragment_program *program, - const SWspan *span, char xOrY, - struct fp_machine *dMachine ) -{ - GLuint u, v; - - ASSERT(xOrY == 'X' || xOrY == 'Y'); - - /* copy existing machine */ - _mesa_memcpy(dMachine, machine, sizeof(struct fp_machine)); - - if (program->Base.Target == GL_FRAGMENT_PROGRAM_NV) { - /* Clear temporary registers (undefined for ARB_f_p) */ - _mesa_bzero( (void*) machine->Temporaries, - MAX_NV_FRAGMENT_PROGRAM_TEMPS * 4 * sizeof(GLfloat)); - } - - /* Add derivatives */ - if (program->Base.InputsRead & (1 << FRAG_ATTRIB_WPOS)) { - GLfloat *wpos = (GLfloat*) machine->Inputs[FRAG_ATTRIB_WPOS]; - if (xOrY == 'X') { - wpos[0] += 1.0F; - wpos[1] += 0.0F; - wpos[2] += span->dzdx; - wpos[3] += span->dwdx; - } - else { - wpos[0] += 0.0F; - wpos[1] += 1.0F; - wpos[2] += span->dzdy; - wpos[3] += span->dwdy; - } - } - if (program->Base.InputsRead & (1 << FRAG_ATTRIB_COL0)) { - GLfloat *col0 = (GLfloat*) machine->Inputs[FRAG_ATTRIB_COL0]; - if (xOrY == 'X') { - col0[0] += span->drdx * (1.0F / CHAN_MAXF); - col0[1] += span->dgdx * (1.0F / CHAN_MAXF); - col0[2] += span->dbdx * (1.0F / CHAN_MAXF); - col0[3] += span->dadx * (1.0F / CHAN_MAXF); - } - else { - col0[0] += span->drdy * (1.0F / CHAN_MAXF); - col0[1] += span->dgdy * (1.0F / CHAN_MAXF); - col0[2] += span->dbdy * (1.0F / CHAN_MAXF); - col0[3] += span->dady * (1.0F / CHAN_MAXF); - } - } - if (program->Base.InputsRead & (1 << FRAG_ATTRIB_COL1)) { - GLfloat *col1 = (GLfloat*) machine->Inputs[FRAG_ATTRIB_COL1]; - if (xOrY == 'X') { - col1[0] += span->dsrdx * (1.0F / CHAN_MAXF); - col1[1] += span->dsgdx * (1.0F / CHAN_MAXF); - col1[2] += span->dsbdx * (1.0F / CHAN_MAXF); - col1[3] += 0.0; /*XXX fix */ - } - else { - col1[0] += span->dsrdy * (1.0F / CHAN_MAXF); - col1[1] += span->dsgdy * (1.0F / CHAN_MAXF); - col1[2] += span->dsbdy * (1.0F / CHAN_MAXF); - col1[3] += 0.0; /*XXX fix */ - } - } - if (program->Base.InputsRead & (1 << FRAG_ATTRIB_FOGC)) { - GLfloat *fogc = (GLfloat*) machine->Inputs[FRAG_ATTRIB_FOGC]; - if (xOrY == 'X') { - fogc[0] += span->dfogdx; - } - else { - fogc[0] += span->dfogdy; - } - } - for (u = 0; u < ctx->Const.MaxTextureCoordUnits; u++) { - if (program->Base.InputsRead & (1 << (FRAG_ATTRIB_TEX0 + u))) { - GLfloat *tex = (GLfloat*) machine->Inputs[FRAG_ATTRIB_TEX0 + u]; - /* XXX perspective-correct interpolation */ - if (xOrY == 'X') { - tex[0] += span->texStepX[u][0]; - tex[1] += span->texStepX[u][1]; - tex[2] += span->texStepX[u][2]; - tex[3] += span->texStepX[u][3]; - } - else { - tex[0] += span->texStepY[u][0]; - tex[1] += span->texStepY[u][1]; - tex[2] += span->texStepY[u][2]; - tex[3] += span->texStepY[u][3]; - } - } - } - - for (v = 0; v < ctx->Const.MaxVarying; v++) { - if (program->Base.InputsRead & (1 << (FRAG_ATTRIB_VAR0 + v))) { - GLfloat *var = (GLfloat*) machine->Inputs[FRAG_ATTRIB_VAR0 + v]; - /* XXXX finish this */ - var[0] += span->varStepX[v][0]; - var[1] += span->varStepX[v][1]; - var[2] += span->varStepX[v][2]; - var[3] += span->varStepX[v][3]; - } - } - - /* init condition codes */ - dMachine->CondCodes[0] = COND_EQ; - dMachine->CondCodes[1] = COND_EQ; - dMachine->CondCodes[2] = COND_EQ; - dMachine->CondCodes[3] = COND_EQ; -} - - -/** - * Execute the given vertex program. - * NOTE: we do everything in single-precision floating point; we don't - * currently observe the single/half/fixed-precision qualifiers. - * \param ctx - rendering context - * \param program - the fragment program to execute - * \param machine - machine state (register file) - * \param maxInst - max number of instructions to execute - * \return GL_TRUE if program completed or GL_FALSE if program executed KIL. - */ -static GLboolean -execute_program( GLcontext *ctx, - const struct gl_fragment_program *program, GLuint maxInst, - struct fp_machine *machine, const SWspan *span, - GLuint column ) -{ - GLuint pc; - - if (DEBUG_FRAG) { - printf("execute fragment program --------------------\n"); - } - - for (pc = 0; pc < maxInst; pc++) { - const struct prog_instruction *inst = program->Base.Instructions + pc; - - if (ctx->FragmentProgram.CallbackEnabled && - ctx->FragmentProgram.Callback) { - ctx->FragmentProgram.CurrentPosition = inst->StringPos; - ctx->FragmentProgram.Callback(program->Base.Target, - ctx->FragmentProgram.CallbackData); - } - - if (DEBUG_FRAG) { - _mesa_print_instruction(inst); - } - - switch (inst->Opcode) { - case OPCODE_ABS: - { - GLfloat a[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - result[0] = FABSF(a[0]); - result[1] = FABSF(a[1]); - result[2] = FABSF(a[2]); - result[3] = FABSF(a[3]); - store_vector4( inst, machine, result ); - } - break; - case OPCODE_ADD: - { - GLfloat a[4], b[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - result[0] = a[0] + b[0]; - result[1] = a[1] + b[1]; - result[2] = a[2] + b[2]; - result[3] = a[3] + b[3]; - store_vector4( inst, machine, result ); - if (DEBUG_FRAG) { - printf("ADD (%g %g %g %g) = (%g %g %g %g) + (%g %g %g %g)\n", - result[0], result[1], result[2], result[3], - a[0], a[1], a[2], a[3], - b[0], b[1], b[2], b[3]); - } - } - break; - case OPCODE_BRA: /* conditional branch */ - { - /* NOTE: The return is conditional! */ - const GLuint swizzle = inst->DstReg.CondSwizzle; - const GLuint condMask = inst->DstReg.CondMask; - if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) || - test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) || - test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) || - test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) { - /* take branch */ - pc = inst->BranchTarget; - } - } - break; - case OPCODE_CAL: /* Call subroutine */ - { - /* NOTE: The call is conditional! */ - const GLuint swizzle = inst->DstReg.CondSwizzle; - const GLuint condMask = inst->DstReg.CondMask; - if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) || - test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) || - test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) || - test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) { - if (machine->StackDepth >= MAX_PROGRAM_CALL_DEPTH) { - return GL_TRUE; /* Per GL_NV_vertex_program2 spec */ - } - machine->CallStack[machine->StackDepth++] = pc + 1; - pc = inst->BranchTarget; - } - } - break; - case OPCODE_CMP: - { - GLfloat a[4], b[4], c[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - fetch_vector4( ctx, &inst->SrcReg[2], machine, program, c ); - result[0] = a[0] < 0.0F ? b[0] : c[0]; - result[1] = a[1] < 0.0F ? b[1] : c[1]; - result[2] = a[2] < 0.0F ? b[2] : c[2]; - result[3] = a[3] < 0.0F ? b[3] : c[3]; - store_vector4( inst, machine, result ); - } - break; - case OPCODE_COS: - { - GLfloat a[4], result[4]; - fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); - result[0] = result[1] = result[2] = result[3] - = (GLfloat) _mesa_cos(a[0]); - store_vector4( inst, machine, result ); - } - break; - case OPCODE_DDX: /* Partial derivative with respect to X */ - { - GLfloat a[4], aNext[4], result[4]; - struct fp_machine dMachine; - if (!fetch_vector4_deriv(ctx, &inst->SrcReg[0], span, 'X', - column, result)) { - /* This is tricky. Make a copy of the current machine state, - * increment the input registers by the dx or dy partial - * derivatives, then re-execute the program up to the - * preceeding instruction, then fetch the source register. - * Finally, find the difference in the register values for - * the original and derivative runs. - */ - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a); - init_machine_deriv(ctx, machine, program, span, - 'X', &dMachine); - execute_program(ctx, program, pc, &dMachine, span, column); - fetch_vector4( ctx, &inst->SrcReg[0], &dMachine, program, aNext ); - result[0] = aNext[0] - a[0]; - result[1] = aNext[1] - a[1]; - result[2] = aNext[2] - a[2]; - result[3] = aNext[3] - a[3]; - } - store_vector4( inst, machine, result ); - } - break; - case OPCODE_DDY: /* Partial derivative with respect to Y */ - { - GLfloat a[4], aNext[4], result[4]; - struct fp_machine dMachine; - if (!fetch_vector4_deriv(ctx, &inst->SrcReg[0], span, 'Y', - column, result)) { - init_machine_deriv(ctx, machine, program, span, - 'Y', &dMachine); - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a); - execute_program(ctx, program, pc, &dMachine, span, column); - fetch_vector4( ctx, &inst->SrcReg[0], &dMachine, program, aNext ); - result[0] = aNext[0] - a[0]; - result[1] = aNext[1] - a[1]; - result[2] = aNext[2] - a[2]; - result[3] = aNext[3] - a[3]; - } - store_vector4( inst, machine, result ); - } - break; - case OPCODE_DP3: - { - GLfloat a[4], b[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - result[0] = result[1] = result[2] = result[3] = DOT3(a, b); - store_vector4( inst, machine, result ); - if (DEBUG_FRAG) { - printf("DP3 %g = (%g %g %g) . (%g %g %g)\n", - result[0], a[0], a[1], a[2], b[0], b[1], b[2]); - } - } - break; - case OPCODE_DP4: - { - GLfloat a[4], b[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - result[0] = result[1] = result[2] = result[3] = DOT4(a,b); - store_vector4( inst, machine, result ); - if (DEBUG_FRAG) { - printf("DP4 %g = (%g, %g %g %g) . (%g, %g %g %g)\n", - result[0], a[0], a[1], a[2], a[3], - b[0], b[1], b[2], b[3]); - } - } - break; - case OPCODE_DPH: - { - GLfloat a[4], b[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - result[0] = result[1] = result[2] = result[3] = - a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + b[3]; - store_vector4( inst, machine, result ); - } - break; - case OPCODE_DST: /* Distance vector */ - { - GLfloat a[4], b[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - result[0] = 1.0F; - result[1] = a[1] * b[1]; - result[2] = a[2]; - result[3] = b[3]; - store_vector4( inst, machine, result ); - } - break; - case OPCODE_EX2: /* Exponential base 2 */ - { - GLfloat a[4], result[4]; - fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); - result[0] = result[1] = result[2] = result[3] = - (GLfloat) _mesa_pow(2.0, a[0]); - store_vector4( inst, machine, result ); - } - break; - case OPCODE_FLR: - { - GLfloat a[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - result[0] = FLOORF(a[0]); - result[1] = FLOORF(a[1]); - result[2] = FLOORF(a[2]); - result[3] = FLOORF(a[3]); - store_vector4( inst, machine, result ); - } - break; - case OPCODE_FRC: - { - GLfloat a[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - result[0] = a[0] - FLOORF(a[0]); - result[1] = a[1] - FLOORF(a[1]); - result[2] = a[2] - FLOORF(a[2]); - result[3] = a[3] - FLOORF(a[3]); - store_vector4( inst, machine, result ); - } - break; - case OPCODE_KIL_NV: /* NV_f_p only */ - { - const GLuint swizzle = inst->DstReg.CondSwizzle; - const GLuint condMask = inst->DstReg.CondMask; - if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) || - test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) || - test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) || - test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) { - return GL_FALSE; - } - } - break; - case OPCODE_KIL: /* ARB_f_p only */ - { - GLfloat a[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - if (a[0] < 0.0F || a[1] < 0.0F || a[2] < 0.0F || a[3] < 0.0F) { - return GL_FALSE; - } - } - break; - case OPCODE_LG2: /* log base 2 */ - { - GLfloat a[4], result[4]; - fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); - result[0] = result[1] = result[2] = result[3] = LOG2(a[0]); - store_vector4( inst, machine, result ); - } - break; - case OPCODE_LIT: - { - const GLfloat epsilon = 1.0F / 256.0F; /* from NV VP spec */ - GLfloat a[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - a[0] = MAX2(a[0], 0.0F); - a[1] = MAX2(a[1], 0.0F); - /* XXX ARB version clamps a[3], NV version doesn't */ - a[3] = CLAMP(a[3], -(128.0F - epsilon), (128.0F - epsilon)); - result[0] = 1.0F; - result[1] = a[0]; - /* XXX we could probably just use pow() here */ - if (a[0] > 0.0F) { - if (a[1] == 0.0 && a[3] == 0.0) - result[2] = 1.0; - else - result[2] = EXPF(a[3] * LOGF(a[1])); - } - else { - result[2] = 0.0; - } - result[3] = 1.0F; - store_vector4( inst, machine, result ); - if (DEBUG_FRAG) { - printf("LIT (%g %g %g %g) : (%g %g %g %g)\n", - result[0], result[1], result[2], result[3], - a[0], a[1], a[2], a[3]); - } - } - break; - case OPCODE_LRP: - { - GLfloat a[4], b[4], c[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - fetch_vector4( ctx, &inst->SrcReg[2], machine, program, c ); - result[0] = a[0] * b[0] + (1.0F - a[0]) * c[0]; - result[1] = a[1] * b[1] + (1.0F - a[1]) * c[1]; - result[2] = a[2] * b[2] + (1.0F - a[2]) * c[2]; - result[3] = a[3] * b[3] + (1.0F - a[3]) * c[3]; - store_vector4( inst, machine, result ); - if (DEBUG_FRAG) { - printf("LRP (%g %g %g %g) = (%g %g %g %g), " - "(%g %g %g %g), (%g %g %g %g)\n", - result[0], result[1], result[2], result[3], - a[0], a[1], a[2], a[3], - b[0], b[1], b[2], b[3], - c[0], c[1], c[2], c[3]); - } - } - break; - case OPCODE_MAD: - { - GLfloat a[4], b[4], c[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - fetch_vector4( ctx, &inst->SrcReg[2], machine, program, c ); - result[0] = a[0] * b[0] + c[0]; - result[1] = a[1] * b[1] + c[1]; - result[2] = a[2] * b[2] + c[2]; - result[3] = a[3] * b[3] + c[3]; - store_vector4( inst, machine, result ); - if (DEBUG_FRAG) { - printf("MAD (%g %g %g %g) = (%g %g %g %g) * " - "(%g %g %g %g) + (%g %g %g %g)\n", - result[0], result[1], result[2], result[3], - a[0], a[1], a[2], a[3], - b[0], b[1], b[2], b[3], - c[0], c[1], c[2], c[3]); - } - } - break; - case OPCODE_MAX: - { - GLfloat a[4], b[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - result[0] = MAX2(a[0], b[0]); - result[1] = MAX2(a[1], b[1]); - result[2] = MAX2(a[2], b[2]); - result[3] = MAX2(a[3], b[3]); - store_vector4( inst, machine, result ); - if (DEBUG_FRAG) { - printf("MAX (%g %g %g %g) = (%g %g %g %g), (%g %g %g %g)\n", - result[0], result[1], result[2], result[3], - a[0], a[1], a[2], a[3], - b[0], b[1], b[2], b[3]); - } - } - break; - case OPCODE_MIN: - { - GLfloat a[4], b[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - result[0] = MIN2(a[0], b[0]); - result[1] = MIN2(a[1], b[1]); - result[2] = MIN2(a[2], b[2]); - result[3] = MIN2(a[3], b[3]); - store_vector4( inst, machine, result ); - } - break; - case OPCODE_MOV: - { - GLfloat result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, result ); - store_vector4( inst, machine, result ); - if (DEBUG_FRAG) { - printf("MOV (%g %g %g %g)\n", - result[0], result[1], result[2], result[3]); - } - } - break; - case OPCODE_MUL: - { - GLfloat a[4], b[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - result[0] = a[0] * b[0]; - result[1] = a[1] * b[1]; - result[2] = a[2] * b[2]; - result[3] = a[3] * b[3]; - store_vector4( inst, machine, result ); - if (DEBUG_FRAG) { - printf("MUL (%g %g %g %g) = (%g %g %g %g) * (%g %g %g %g)\n", - result[0], result[1], result[2], result[3], - a[0], a[1], a[2], a[3], - b[0], b[1], b[2], b[3]); - } - } - break; - case OPCODE_PK2H: /* pack two 16-bit floats in one 32-bit float */ - { - GLfloat a[4], result[4]; - GLhalfNV hx, hy; - GLuint *rawResult = (GLuint *) result; - GLuint twoHalves; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - hx = _mesa_float_to_half(a[0]); - hy = _mesa_float_to_half(a[1]); - twoHalves = hx | (hy << 16); - rawResult[0] = rawResult[1] = rawResult[2] = rawResult[3] - = twoHalves; - store_vector4( inst, machine, result ); - } - break; - case OPCODE_PK2US: /* pack two GLushorts into one 32-bit float */ - { - GLfloat a[4], result[4]; - GLuint usx, usy, *rawResult = (GLuint *) result; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - a[0] = CLAMP(a[0], 0.0F, 1.0F); - a[1] = CLAMP(a[1], 0.0F, 1.0F); - usx = IROUND(a[0] * 65535.0F); - usy = IROUND(a[1] * 65535.0F); - rawResult[0] = rawResult[1] = rawResult[2] = rawResult[3] - = usx | (usy << 16); - store_vector4( inst, machine, result ); - } - break; - case OPCODE_PK4B: /* pack four GLbytes into one 32-bit float */ - { - GLfloat a[4], result[4]; - GLuint ubx, uby, ubz, ubw, *rawResult = (GLuint *) result; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - a[0] = CLAMP(a[0], -128.0F / 127.0F, 1.0F); - a[1] = CLAMP(a[1], -128.0F / 127.0F, 1.0F); - a[2] = CLAMP(a[2], -128.0F / 127.0F, 1.0F); - a[3] = CLAMP(a[3], -128.0F / 127.0F, 1.0F); - ubx = IROUND(127.0F * a[0] + 128.0F); - uby = IROUND(127.0F * a[1] + 128.0F); - ubz = IROUND(127.0F * a[2] + 128.0F); - ubw = IROUND(127.0F * a[3] + 128.0F); - rawResult[0] = rawResult[1] = rawResult[2] = rawResult[3] - = ubx | (uby << 8) | (ubz << 16) | (ubw << 24); - store_vector4( inst, machine, result ); - } - break; - case OPCODE_PK4UB: /* pack four GLubytes into one 32-bit float */ - { - GLfloat a[4], result[4]; - GLuint ubx, uby, ubz, ubw, *rawResult = (GLuint *) result; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - a[0] = CLAMP(a[0], 0.0F, 1.0F); - a[1] = CLAMP(a[1], 0.0F, 1.0F); - a[2] = CLAMP(a[2], 0.0F, 1.0F); - a[3] = CLAMP(a[3], 0.0F, 1.0F); - ubx = IROUND(255.0F * a[0]); - uby = IROUND(255.0F * a[1]); - ubz = IROUND(255.0F * a[2]); - ubw = IROUND(255.0F * a[3]); - rawResult[0] = rawResult[1] = rawResult[2] = rawResult[3] - = ubx | (uby << 8) | (ubz << 16) | (ubw << 24); - store_vector4( inst, machine, result ); - } - break; - case OPCODE_POW: - { - GLfloat a[4], b[4], result[4]; - fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector1( ctx, &inst->SrcReg[1], machine, program, b ); - result[0] = result[1] = result[2] = result[3] - = (GLfloat)_mesa_pow(a[0], b[0]); - store_vector4( inst, machine, result ); - } - break; - case OPCODE_RCP: - { - GLfloat a[4], result[4]; - fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); - if (DEBUG_FRAG) { - if (a[0] == 0) - printf("RCP(0)\n"); - else if (IS_INF_OR_NAN(a[0])) - printf("RCP(inf)\n"); - } - result[0] = result[1] = result[2] = result[3] = 1.0F / a[0]; - store_vector4( inst, machine, result ); - } - break; - case OPCODE_RET: /* return from subroutine */ - { - /* NOTE: The return is conditional! */ - const GLuint swizzle = inst->DstReg.CondSwizzle; - const GLuint condMask = inst->DstReg.CondMask; - if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) || - test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) || - test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) || - test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) { - if (machine->StackDepth == 0) { - return GL_TRUE; /* Per GL_NV_vertex_program2 spec */ - } - pc = machine->CallStack[--machine->StackDepth]; - } - } - break; - case OPCODE_RFL: /* reflection vector */ - { - GLfloat axis[4], dir[4], result[4], tmpX, tmpW; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, axis ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, dir ); - tmpW = DOT3(axis, axis); - tmpX = (2.0F * DOT3(axis, dir)) / tmpW; - result[0] = tmpX * axis[0] - dir[0]; - result[1] = tmpX * axis[1] - dir[1]; - result[2] = tmpX * axis[2] - dir[2]; - /* result[3] is never written! XXX enforce in parser! */ - store_vector4( inst, machine, result ); - } - break; - case OPCODE_RSQ: /* 1 / sqrt() */ - { - GLfloat a[4], result[4]; - fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); - a[0] = FABSF(a[0]); - result[0] = result[1] = result[2] = result[3] = INV_SQRTF(a[0]); - store_vector4( inst, machine, result ); - if (DEBUG_FRAG) { - printf("RSQ %g = 1/sqrt(|%g|)\n", result[0], a[0]); - } - } - break; - case OPCODE_SCS: /* sine and cos */ - { - GLfloat a[4], result[4]; - fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); - result[0] = (GLfloat)_mesa_cos(a[0]); - result[1] = (GLfloat)_mesa_sin(a[0]); - result[2] = 0.0; /* undefined! */ - result[3] = 0.0; /* undefined! */ - store_vector4( inst, machine, result ); - } - break; - case OPCODE_SEQ: /* set on equal */ - { - GLfloat a[4], b[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - result[0] = (a[0] == b[0]) ? 1.0F : 0.0F; - result[1] = (a[1] == b[1]) ? 1.0F : 0.0F; - result[2] = (a[2] == b[2]) ? 1.0F : 0.0F; - result[3] = (a[3] == b[3]) ? 1.0F : 0.0F; - store_vector4( inst, machine, result ); - } - break; - case OPCODE_SFL: /* set false, operands ignored */ - { - static const GLfloat result[4] = { 0.0F, 0.0F, 0.0F, 0.0F }; - store_vector4( inst, machine, result ); - } - break; - case OPCODE_SGE: /* set on greater or equal */ - { - GLfloat a[4], b[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - result[0] = (a[0] >= b[0]) ? 1.0F : 0.0F; - result[1] = (a[1] >= b[1]) ? 1.0F : 0.0F; - result[2] = (a[2] >= b[2]) ? 1.0F : 0.0F; - result[3] = (a[3] >= b[3]) ? 1.0F : 0.0F; - store_vector4( inst, machine, result ); - } - break; - case OPCODE_SGT: /* set on greater */ - { - GLfloat a[4], b[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - result[0] = (a[0] > b[0]) ? 1.0F : 0.0F; - result[1] = (a[1] > b[1]) ? 1.0F : 0.0F; - result[2] = (a[2] > b[2]) ? 1.0F : 0.0F; - result[3] = (a[3] > b[3]) ? 1.0F : 0.0F; - store_vector4( inst, machine, result ); - } - break; - case OPCODE_SIN: - { - GLfloat a[4], result[4]; - fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); - result[0] = result[1] = result[2] = result[3] - = (GLfloat) _mesa_sin(a[0]); - store_vector4( inst, machine, result ); - } - break; - case OPCODE_SLE: /* set on less or equal */ - { - GLfloat a[4], b[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - result[0] = (a[0] <= b[0]) ? 1.0F : 0.0F; - result[1] = (a[1] <= b[1]) ? 1.0F : 0.0F; - result[2] = (a[2] <= b[2]) ? 1.0F : 0.0F; - result[3] = (a[3] <= b[3]) ? 1.0F : 0.0F; - store_vector4( inst, machine, result ); - } - break; - case OPCODE_SLT: /* set on less */ - { - GLfloat a[4], b[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - result[0] = (a[0] < b[0]) ? 1.0F : 0.0F; - result[1] = (a[1] < b[1]) ? 1.0F : 0.0F; - result[2] = (a[2] < b[2]) ? 1.0F : 0.0F; - result[3] = (a[3] < b[3]) ? 1.0F : 0.0F; - store_vector4( inst, machine, result ); - } - break; - case OPCODE_SNE: /* set on not equal */ - { - GLfloat a[4], b[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - result[0] = (a[0] != b[0]) ? 1.0F : 0.0F; - result[1] = (a[1] != b[1]) ? 1.0F : 0.0F; - result[2] = (a[2] != b[2]) ? 1.0F : 0.0F; - result[3] = (a[3] != b[3]) ? 1.0F : 0.0F; - store_vector4( inst, machine, result ); - } - break; - case OPCODE_STR: /* set true, operands ignored */ - { - static const GLfloat result[4] = { 1.0F, 1.0F, 1.0F, 1.0F }; - store_vector4( inst, machine, result ); - } - break; - case OPCODE_SUB: - { - GLfloat a[4], b[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - result[0] = a[0] - b[0]; - result[1] = a[1] - b[1]; - result[2] = a[2] - b[2]; - result[3] = a[3] - b[3]; - store_vector4( inst, machine, result ); - if (DEBUG_FRAG) { - printf("SUB (%g %g %g %g) = (%g %g %g %g) - (%g %g %g %g)\n", - result[0], result[1], result[2], result[3], - a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3]); - } - } - break; - case OPCODE_SWZ: /* extended swizzle */ - { - const struct prog_src_register *source = &inst->SrcReg[0]; - const GLfloat *src = get_register_pointer(ctx, source, - machine, program); - GLfloat result[4]; - GLuint i; - for (i = 0; i < 4; i++) { - const GLuint swz = GET_SWZ(source->Swizzle, i); - if (swz == SWIZZLE_ZERO) - result[i] = 0.0; - else if (swz == SWIZZLE_ONE) - result[i] = 1.0; - else { - ASSERT(swz >= 0); - ASSERT(swz <= 3); - result[i] = src[swz]; - } - if (source->NegateBase & (1 << i)) - result[i] = -result[i]; - } - store_vector4( inst, machine, result ); - } - break; - case OPCODE_TEX: /* Both ARB and NV frag prog */ - /* Texel lookup */ - { - /* Note: only use the precomputed lambda value when we're - * sampling texture unit [K] with texcoord[K]. - * Otherwise, the lambda value may have no relation to the - * instruction's texcoord or texture image. Using the wrong - * lambda is usually bad news. - * The rest of the time, just use zero (until we get a more - * sophisticated way of computing lambda). - */ - GLfloat coord[4], color[4], lambda; - if (inst->SrcReg[0].File == PROGRAM_INPUT && - inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0+inst->TexSrcUnit) - lambda = span->array->lambda[inst->TexSrcUnit][column]; - else - lambda = 0.0; - fetch_vector4(ctx, &inst->SrcReg[0], machine, program, coord); - fetch_texel( ctx, coord, lambda, inst->TexSrcUnit, color ); - if (DEBUG_FRAG) { - printf("TEX (%g, %g, %g, %g) = texture[%d][%g, %g, %g, %g], " - "lod %f\n", - color[0], color[1], color[2], color[3], - inst->TexSrcUnit, - coord[0], coord[1], coord[2], coord[3], lambda); - } - store_vector4( inst, machine, color ); - } - break; - case OPCODE_TXB: /* GL_ARB_fragment_program only */ - /* Texel lookup with LOD bias */ - { - GLfloat coord[4], color[4], lambda, bias; - if (inst->SrcReg[0].File == PROGRAM_INPUT && - inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0+inst->TexSrcUnit) - lambda = span->array->lambda[inst->TexSrcUnit][column]; - else - lambda = 0.0; - fetch_vector4(ctx, &inst->SrcReg[0], machine, program, coord); - /* coord[3] is the bias to add to lambda */ - bias = ctx->Texture.Unit[inst->TexSrcUnit].LodBias - + ctx->Texture.Unit[inst->TexSrcUnit]._Current->LodBias - + coord[3]; - fetch_texel(ctx, coord, lambda + bias, inst->TexSrcUnit, color); - store_vector4( inst, machine, color ); - } - break; - case OPCODE_TXD: /* GL_NV_fragment_program only */ - /* Texture lookup w/ partial derivatives for LOD */ - { - GLfloat texcoord[4], dtdx[4], dtdy[4], color[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, texcoord ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, dtdx ); - fetch_vector4( ctx, &inst->SrcReg[2], machine, program, dtdy ); - fetch_texel_deriv( ctx, texcoord, dtdx, dtdy, inst->TexSrcUnit, - color ); - store_vector4( inst, machine, color ); - } - break; - case OPCODE_TXP: /* GL_ARB_fragment_program only */ - /* Texture lookup w/ projective divide */ - { - GLfloat texcoord[4], color[4], lambda; - if (inst->SrcReg[0].File == PROGRAM_INPUT && - inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0+inst->TexSrcUnit) - lambda = span->array->lambda[inst->TexSrcUnit][column]; - else - lambda = 0.0; - fetch_vector4(ctx, &inst->SrcReg[0], machine, program,texcoord); - /* Not so sure about this test - if texcoord[3] is - * zero, we'd probably be fine except for an ASSERT in - * IROUND_POS() which gets triggered by the inf values created. - */ - if (texcoord[3] != 0.0) { - texcoord[0] /= texcoord[3]; - texcoord[1] /= texcoord[3]; - texcoord[2] /= texcoord[3]; - } - fetch_texel( ctx, texcoord, lambda, inst->TexSrcUnit, color ); - store_vector4( inst, machine, color ); - } - break; - case OPCODE_TXP_NV: /* GL_NV_fragment_program only */ - /* Texture lookup w/ projective divide */ - { - GLfloat texcoord[4], color[4], lambda; - if (inst->SrcReg[0].File == PROGRAM_INPUT && - inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0+inst->TexSrcUnit) - lambda = span->array->lambda[inst->TexSrcUnit][column]; - else - lambda = 0.0; - fetch_vector4(ctx, &inst->SrcReg[0], machine, program,texcoord); - if (inst->TexSrcTarget != TEXTURE_CUBE_INDEX && - texcoord[3] != 0.0) { - texcoord[0] /= texcoord[3]; - texcoord[1] /= texcoord[3]; - texcoord[2] /= texcoord[3]; - } - fetch_texel( ctx, texcoord, lambda, inst->TexSrcUnit, color ); - store_vector4( inst, machine, color ); - } - break; - case OPCODE_UP2H: /* unpack two 16-bit floats */ - { - GLfloat a[4], result[4]; - const GLuint *rawBits = (const GLuint *) a; - GLhalfNV hx, hy; - fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); - hx = rawBits[0] & 0xffff; - hy = rawBits[0] >> 16; - result[0] = result[2] = _mesa_half_to_float(hx); - result[1] = result[3] = _mesa_half_to_float(hy); - store_vector4( inst, machine, result ); - } - break; - case OPCODE_UP2US: /* unpack two GLushorts */ - { - GLfloat a[4], result[4]; - const GLuint *rawBits = (const GLuint *) a; - GLushort usx, usy; - fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); - usx = rawBits[0] & 0xffff; - usy = rawBits[0] >> 16; - result[0] = result[2] = usx * (1.0f / 65535.0f); - result[1] = result[3] = usy * (1.0f / 65535.0f); - store_vector4( inst, machine, result ); - } - break; - case OPCODE_UP4B: /* unpack four GLbytes */ - { - GLfloat a[4], result[4]; - const GLuint *rawBits = (const GLuint *) a; - fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); - result[0] = (((rawBits[0] >> 0) & 0xff) - 128) / 127.0F; - result[1] = (((rawBits[0] >> 8) & 0xff) - 128) / 127.0F; - result[2] = (((rawBits[0] >> 16) & 0xff) - 128) / 127.0F; - result[3] = (((rawBits[0] >> 24) & 0xff) - 128) / 127.0F; - store_vector4( inst, machine, result ); - } - break; - case OPCODE_UP4UB: /* unpack four GLubytes */ - { - GLfloat a[4], result[4]; - const GLuint *rawBits = (const GLuint *) a; - fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); - result[0] = ((rawBits[0] >> 0) & 0xff) / 255.0F; - result[1] = ((rawBits[0] >> 8) & 0xff) / 255.0F; - result[2] = ((rawBits[0] >> 16) & 0xff) / 255.0F; - result[3] = ((rawBits[0] >> 24) & 0xff) / 255.0F; - store_vector4( inst, machine, result ); - } - break; - case OPCODE_XPD: /* cross product */ - { - GLfloat a[4], b[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - result[0] = a[1] * b[2] - a[2] * b[1]; - result[1] = a[2] * b[0] - a[0] * b[2]; - result[2] = a[0] * b[1] - a[1] * b[0]; - result[3] = 1.0; - store_vector4( inst, machine, result ); - } - break; - case OPCODE_X2D: /* 2-D matrix transform */ - { - GLfloat a[4], b[4], c[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - fetch_vector4( ctx, &inst->SrcReg[2], machine, program, c ); - result[0] = a[0] + b[0] * c[0] + b[1] * c[1]; - result[1] = a[1] + b[0] * c[2] + b[1] * c[3]; - result[2] = a[2] + b[0] * c[0] + b[1] * c[1]; - result[3] = a[3] + b[0] * c[2] + b[1] * c[3]; - store_vector4( inst, machine, result ); - } - break; - case OPCODE_PRINT: - { - if (inst->SrcReg[0].File != -1) { - GLfloat a[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a); - _mesa_printf("%s%g, %g, %g, %g\n", (const char *) inst->Data, - a[0], a[1], a[2], a[3]); - } - else { - _mesa_printf("%s\n", (const char *) inst->Data); - } - } - break; - case OPCODE_END: - return GL_TRUE; - default: - _mesa_problem(ctx, "Bad opcode %d in _mesa_exec_fragment_program", - inst->Opcode); - return GL_TRUE; /* return value doesn't matter */ - } - } - return GL_TRUE; -} - - -/** - * Initialize the virtual fragment program machine state prior to running - * fragment program on a fragment. This involves initializing the input - * registers, condition codes, etc. - * \param machine the virtual machine state to init - * \param program the fragment program we're about to run - * \param span the span of pixels we'll operate on - * \param col which element (column) of the span we'll operate on - */ -static void -init_machine( GLcontext *ctx, struct fp_machine *machine, - const struct gl_fragment_program *program, - const SWspan *span, GLuint col ) -{ - GLuint inputsRead = program->Base.InputsRead; - GLuint u, v; - - if (ctx->FragmentProgram.CallbackEnabled) - inputsRead = ~0; - - if (program->Base.Target == GL_FRAGMENT_PROGRAM_NV) { - /* Clear temporary registers (undefined for ARB_f_p) */ - _mesa_bzero(machine->Temporaries, - MAX_NV_FRAGMENT_PROGRAM_TEMPS * 4 * sizeof(GLfloat)); - } - - /* Load input registers */ - if (inputsRead & (1 << FRAG_ATTRIB_WPOS)) { - GLfloat *wpos = machine->Inputs[FRAG_ATTRIB_WPOS]; - ASSERT(span->arrayMask & SPAN_Z); - if (span->arrayMask & SPAN_XY) { - wpos[0] = (GLfloat) span->array->x[col]; - wpos[1] = (GLfloat) span->array->y[col]; - } - else { - wpos[0] = (GLfloat) span->x + col; - wpos[1] = (GLfloat) span->y; - } - wpos[2] = (GLfloat) span->array->z[col] / ctx->DrawBuffer->_DepthMaxF; - wpos[3] = span->w + col * span->dwdx; - } - if (inputsRead & (1 << FRAG_ATTRIB_COL0)) { - ASSERT(span->arrayMask & SPAN_RGBA); - COPY_4V(machine->Inputs[FRAG_ATTRIB_COL0], - span->array->color.sz4.rgba[col]); - } - if (inputsRead & (1 << FRAG_ATTRIB_COL1)) { - ASSERT(span->arrayMask & SPAN_SPEC); - COPY_4V(machine->Inputs[FRAG_ATTRIB_COL1], - span->array->color.sz4.spec[col]); - } - if (inputsRead & (1 << FRAG_ATTRIB_FOGC)) { - GLfloat *fogc = machine->Inputs[FRAG_ATTRIB_FOGC]; - ASSERT(span->arrayMask & SPAN_FOG); - fogc[0] = span->array->fog[col]; - fogc[1] = 0.0F; - fogc[2] = 0.0F; - fogc[3] = 0.0F; - } - for (u = 0; u < ctx->Const.MaxTextureCoordUnits; u++) { - if (inputsRead & (1 << (FRAG_ATTRIB_TEX0 + u))) { - GLfloat *tex = machine->Inputs[FRAG_ATTRIB_TEX0 + u]; - /*ASSERT(ctx->Texture._EnabledCoordUnits & (1 << u));*/ - COPY_4V(tex, span->array->texcoords[u][col]); - /*ASSERT(tex[0] != 0 || tex[1] != 0 || tex[2] != 0);*/ - } - } - for (v = 0; v < ctx->Const.MaxVarying; v++) { - if (inputsRead & (1 << (FRAG_ATTRIB_VAR0 + v))) { -#if 0 - printf("Frag Var %d: %f %f %f\n", col, - span->array->varying[col][v][0], - span->array->varying[col][v][1], - span->array->varying[col][v][2]); -#endif - COPY_4V(machine->Inputs[FRAG_ATTRIB_VAR0 + v], - span->array->varying[col][v]); - } - } - - /* init condition codes */ - machine->CondCodes[0] = COND_EQ; - machine->CondCodes[1] = COND_EQ; - machine->CondCodes[2] = COND_EQ; - machine->CondCodes[3] = COND_EQ; - - /* init call stack */ - machine->StackDepth = 0; -} - - -/** - * Run fragment program on the pixels in span from 'start' to 'end' - 1. - */ -static void -run_program(GLcontext *ctx, SWspan *span, GLuint start, GLuint end) -{ - const struct gl_fragment_program *program = ctx->FragmentProgram._Current; - struct fp_machine machine; - GLuint i; - - CurrentMachine = &machine; - - for (i = start; i < end; i++) { - if (span->array->mask[i]) { - init_machine(ctx, &machine, program, span, i); - - if (execute_program(ctx, program, ~0, &machine, span, i)) { - /* Store result color */ - COPY_4V(span->array->color.sz4.rgba[i], - machine.Outputs[FRAG_RESULT_COLR]); - - /* Store result depth/z */ - if (program->Base.OutputsWritten & (1 << FRAG_RESULT_DEPR)) { - const GLfloat depth = machine.Outputs[FRAG_RESULT_DEPR][2]; - if (depth <= 0.0) - span->array->z[i] = 0; - else if (depth >= 1.0) - span->array->z[i] = ctx->DrawBuffer->_DepthMax; - else - span->array->z[i] = IROUND(depth * ctx->DrawBuffer->_DepthMaxF); - } - } - else { - /* killed fragment */ - span->array->mask[i] = GL_FALSE; - span->writeAll = GL_FALSE; - } - } - } - - CurrentMachine = NULL; -} - - -/** - * Execute the current fragment program for all the fragments - * in the given span. - */ -void -_swrast_exec_fragment_program( GLcontext *ctx, SWspan *span ) -{ - const struct gl_fragment_program *program = ctx->FragmentProgram._Current; - - /* incoming colors should be floats */ - ASSERT(span->array->ChanType == GL_FLOAT); - - ctx->_CurrentProgram = GL_FRAGMENT_PROGRAM_ARB; /* or NV, doesn't matter */ - - run_program(ctx, span, 0, span->end); - - if (program->Base.OutputsWritten & (1 << FRAG_RESULT_DEPR)) { - span->interpMask &= ~SPAN_Z; - span->arrayMask |= SPAN_Z; - } - - ctx->_CurrentProgram = 0; -} - diff --git a/src/mesa/swrast/s_nvfragprog.h b/src/mesa/swrast/s_nvfragprog.h deleted file mode 100644 index 188bacc3d8..0000000000 --- a/src/mesa/swrast/s_nvfragprog.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 6.1 - * - * Copyright (C) 1999-2003 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - - -#ifndef S_NVFRAGPROG_H -#define S_NVFRAGPROG_H - - -#include "s_context.h" - - -extern void -_swrast_exec_fragment_program( GLcontext *ctx, SWspan *span ); - - -#endif -- cgit v1.2.3 From c968d3d410a1897ecbb41d3557adaef69a4c627a Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 15 Dec 2006 08:50:02 -0700 Subject: Renamed s_nvfragprog.[ch] to s_fragprog.[ch] --- src/mesa/swrast/s_fragprog.c | 11 +---------- src/mesa/swrast/s_fragprog.h | 13 +++++++------ src/mesa/swrast/s_span.c | 2 +- 3 files changed, 9 insertions(+), 17 deletions(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c index ac2f5d93b6..d4985fa2d8 100644 --- a/src/mesa/swrast/s_fragprog.c +++ b/src/mesa/swrast/s_fragprog.c @@ -22,15 +22,6 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/* - * Regarding GL_NV_fragment_program: - * - * Portions of this software may use or implement intellectual - * property owned and licensed by NVIDIA Corporation. NVIDIA disclaims - * any and all warranties with respect to such intellectual property, - * including any use thereof or modifications thereto. - */ - #include "glheader.h" #include "colormac.h" #include "context.h" @@ -39,7 +30,7 @@ #include "prog_print.h" #include "program.h" -#include "s_nvfragprog.h" +#include "s_fragprog.h" #include "s_span.h" diff --git a/src/mesa/swrast/s_fragprog.h b/src/mesa/swrast/s_fragprog.h index 188bacc3d8..e1b7e67918 100644 --- a/src/mesa/swrast/s_fragprog.h +++ b/src/mesa/swrast/s_fragprog.h @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.1 + * Version: 6.5.3 * - * Copyright (C) 1999-2003 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -23,15 +23,16 @@ */ -#ifndef S_NVFRAGPROG_H -#define S_NVFRAGPROG_H +#ifndef S_FRAGPROG_H +#define S_FRAGPROG_H #include "s_context.h" extern void -_swrast_exec_fragment_program( GLcontext *ctx, SWspan *span ); +_swrast_exec_fragment_program(GLcontext *ctx, SWspan *span); -#endif +#endif /* S_FRAGPROG_H */ + diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c index e4904e1dd2..f091887838 100644 --- a/src/mesa/swrast/s_span.c +++ b/src/mesa/swrast/s_span.c @@ -45,7 +45,7 @@ #include "s_fog.h" #include "s_logic.h" #include "s_masking.h" -#include "s_nvfragprog.h" +#include "s_fragprog.h" #include "s_span.h" #include "s_stencil.h" #include "s_texcombine.h" -- cgit v1.2.3 From 464b9f4f6c6514a7cfcc873923b5c127c1c6f60b Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 15 Dec 2006 10:09:49 -0700 Subject: varying var changes --- src/mesa/swrast/s_context.h | 8 ++++---- src/mesa/swrast/s_span.c | 4 ++-- src/mesa/swrast/s_tritemp.h | 22 +++++++++++----------- 3 files changed, 17 insertions(+), 17 deletions(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/swrast/s_context.h b/src/mesa/swrast/s_context.h index 37d7081d4d..f784e18cd4 100644 --- a/src/mesa/swrast/s_context.h +++ b/src/mesa/swrast/s_context.h @@ -122,7 +122,7 @@ typedef struct sw_span_arrays { GLfloat texcoords[MAX_TEXTURE_COORD_UNITS][MAX_WIDTH][4]; GLfloat lambda[MAX_TEXTURE_COORD_UNITS][MAX_WIDTH]; GLfloat coverage[MAX_WIDTH]; - GLfloat varying[MAX_WIDTH][MAX_VARYING_VECTORS][VARYINGS_PER_VECTOR]; + GLfloat varying[MAX_WIDTH][MAX_VARYING][4]; /** This mask indicates which fragments are alive or culled */ GLubyte mask[MAX_WIDTH]; @@ -200,9 +200,9 @@ typedef struct sw_span { GLfloat texStepX[MAX_TEXTURE_COORD_UNITS][4]; GLfloat texStepY[MAX_TEXTURE_COORD_UNITS][4]; GLfixed intTex[2], intTexStep[2]; /* s, t only */ - GLfloat var[MAX_VARYING_VECTORS][VARYINGS_PER_VECTOR]; - GLfloat varStepX[MAX_VARYING_VECTORS][VARYINGS_PER_VECTOR]; - GLfloat varStepY[MAX_VARYING_VECTORS][VARYINGS_PER_VECTOR]; + GLfloat var[MAX_VARYING][4]; + GLfloat varStepX[MAX_VARYING][4]; + GLfloat varStepY[MAX_VARYING][4]; /* partial derivatives wrt X and Y. */ GLfloat dzdx, dzdy; diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c index f091887838..7bfb23f0f7 100644 --- a/src/mesa/swrast/s_span.c +++ b/src/mesa/swrast/s_span.c @@ -829,8 +829,8 @@ interpolate_varying(GLcontext *ctx, SWspan *span) span->arrayMask |= SPAN_VARYING; - for (i = 0; i < MAX_VARYING_VECTORS; i++) { - for (j = 0; j < VARYINGS_PER_VECTOR; j++) { + for (i = 0; i < MAX_VARYING; i++) { + for (j = 0; j < 4; j++) { const GLfloat dvdx = span->varStepX[i][j]; GLfloat v = span->var[i][j]; const GLfloat dwdx = span->dwdx; diff --git a/src/mesa/swrast/s_tritemp.h b/src/mesa/swrast/s_tritemp.h index 9e0a8a3d32..0ed1772a88 100644 --- a/src/mesa/swrast/s_tritemp.h +++ b/src/mesa/swrast/s_tritemp.h @@ -144,14 +144,14 @@ #ifdef INTERP_VARYING -#define VARYING_LOOP(CODE)\ - {\ - GLuint iv, ic;\ - for (iv = 0; iv < MAX_VARYING_VECTORS; iv++) {\ - for (ic = 0; ic < VARYINGS_PER_VECTOR; ic++) {\ - CODE\ - }\ - }\ +#define VARYING_LOOP(CODE) \ + { \ + GLuint iv, ic; \ + for (iv = 0; iv < MAX_VARYING; iv++) { \ + for (ic = 0; ic < 4; ic++) { \ + CODE \ + } \ + } \ } #endif @@ -780,9 +780,9 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, GLfloat dvOuter[MAX_TEXTURE_COORD_UNITS], dvInner[MAX_TEXTURE_COORD_UNITS]; #endif #ifdef INTERP_VARYING - GLfloat varLeft[MAX_VARYING_VECTORS][VARYINGS_PER_VECTOR]; - GLfloat dvarOuter[MAX_VARYING_VECTORS][VARYINGS_PER_VECTOR]; - GLfloat dvarInner[MAX_VARYING_VECTORS][VARYINGS_PER_VECTOR]; + GLfloat varLeft[MAX_VARYING][4]; + GLfloat dvarOuter[MAX_VARYING][4]; + GLfloat dvarInner[MAX_VARYING][4]; #endif for (subTriangle=0; subTriangle<=1; subTriangle++) { -- cgit v1.2.3 From 0031ea7d85ae8990872c2181d038fb97b566dc2b Mon Sep 17 00:00:00 2001 From: Brian Date: Sat, 16 Dec 2006 12:52:55 -0700 Subject: fix comment, handle NOP --- src/mesa/swrast/s_fragprog.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c index d4985fa2d8..180b86e7bb 100644 --- a/src/mesa/swrast/s_fragprog.c +++ b/src/mesa/swrast/s_fragprog.c @@ -708,7 +708,7 @@ execute_program( GLcontext *ctx, break; case OPCODE_BRA: /* conditional branch */ { - /* NOTE: The return is conditional! */ + /* NOTE: The branch is conditional! */ const GLuint swizzle = inst->DstReg.CondSwizzle; const GLuint condMask = inst->DstReg.CondMask; if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) || @@ -1044,6 +1044,8 @@ execute_program( GLcontext *ctx, } } break; + case OPCODE_NOP: + break; case OPCODE_PK2H: /* pack two 16-bit floats in one 32-bit float */ { GLfloat a[4], result[4]; -- cgit v1.2.3 From d22079217c5a1954a07afb1193d06eecb2decbb6 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 18 Dec 2006 16:22:27 -0700 Subject: Added instruction counter to catch infinite loops (temporary). --- src/mesa/swrast/s_fragprog.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c index 180b86e7bb..c59e24debe 100644 --- a/src/mesa/swrast/s_fragprog.c +++ b/src/mesa/swrast/s_fragprog.c @@ -656,7 +656,8 @@ execute_program( GLcontext *ctx, struct fp_machine *machine, const SWspan *span, GLuint column ) { - GLuint pc; + const GLuint MAX_EXEC = 5000; + GLuint pc, total = 0; if (DEBUG_FRAG) { printf("execute fragment program --------------------\n"); @@ -717,6 +718,9 @@ execute_program( GLcontext *ctx, test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) { /* take branch */ pc = inst->BranchTarget; + /* + printf("Take branch to %u\n", pc); + */ } } break; @@ -1518,6 +1522,12 @@ execute_program( GLcontext *ctx, _mesa_problem(ctx, "Bad opcode %d in _mesa_exec_fragment_program", inst->Opcode); return GL_TRUE; /* return value doesn't matter */ + + } + total++; + if (total > MAX_EXEC) { + _mesa_problem(ctx, "Infinite loop detected in fragment program"); + abort(); } } return GL_TRUE; -- cgit v1.2.3 From 0bf5dbe002a64e198f55724cc1542602c012490f Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 19 Dec 2006 18:02:41 -0700 Subject: Overhaul of GLSL API functions, dispatching, etc. --- src/mesa/drivers/common/driverfuncs.c | 46 +++++++++++++++++++++++++++++-- src/mesa/drivers/common/driverfuncs.h | 8 ++++-- src/mesa/main/context.c | 17 ++++++------ src/mesa/main/dd.h | 52 +++++++++++++++++++++++++++++++++++ src/mesa/main/mtypes.h | 22 +++++++++------ src/mesa/main/state.c | 4 +-- src/mesa/main/texstate.c | 2 +- src/mesa/sources | 5 +--- src/mesa/swrast/s_context.c | 2 +- src/mesa/swrast/s_span.c | 2 +- 10 files changed, 130 insertions(+), 30 deletions(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/drivers/common/driverfuncs.c b/src/mesa/drivers/common/driverfuncs.c index 1e44904b93..bc637a879e 100644 --- a/src/mesa/drivers/common/driverfuncs.c +++ b/src/mesa/drivers/common/driverfuncs.c @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * Version: 6.5.3 * - * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -43,6 +43,7 @@ #include "fbobject.h" #include "texrender.h" #endif +#include "shader_api.h" #include "arrayobj.h" #include "driverfuncs.h" @@ -248,4 +249,45 @@ _mesa_init_driver_functions(struct dd_function_table *driver) driver->EndList = NULL; driver->BeginCallList = NULL; driver->EndCallList = NULL; + + + /* XXX temporary here */ + _mesa_init_glsl_driver_functions(driver); +} + + +/** + * Plug in Mesa's GLSL functions. + */ +void +_mesa_init_glsl_driver_functions(struct dd_function_table *driver) +{ + driver->AttachShader = _mesa_attach_shader; + driver->BindAttribLocation = _mesa_bind_attrib_location; + driver->CompileShader = _mesa_compile_shader; + driver->CreateProgram = _mesa_create_program; + driver->CreateShader = _mesa_create_shader; + driver->DeleteProgram2 = _mesa_delete_program2; + driver->DeleteShader = _mesa_delete_shader; + driver->DetachShader = _mesa_detach_shader; + driver->GetActiveAttrib = _mesa_get_active_attrib; + driver->GetActiveUniform = _mesa_get_active_uniform; + driver->GetAttachedShaders = _mesa_get_attached_shaders; + driver->GetAttribLocation = _mesa_get_attrib_location; + driver->GetHandle = _mesa_get_handle; + driver->GetProgramiv = _mesa_get_programiv; + driver->GetProgramInfoLog = _mesa_get_program_info_log; + driver->GetShaderiv = _mesa_get_shaderiv; + driver->GetShaderInfoLog = _mesa_get_shader_info_log; + driver->GetShaderSource = _mesa_get_shader_source; + driver->GetUniformfv = _mesa_get_uniformfv; + driver->GetUniformLocation = _mesa_get_uniform_location; + driver->IsProgram = _mesa_is_program; + driver->IsShader = _mesa_is_shader; + driver->LinkProgram = _mesa_link_program; + driver->ShaderSource = _mesa_shader_source; + driver->Uniform = _mesa_uniform; + driver->UniformMatrix = _mesa_uniform_matrix; + driver->UseProgram = _mesa_use_program; + driver->ValidateProgram = _mesa_validate_program; } diff --git a/src/mesa/drivers/common/driverfuncs.h b/src/mesa/drivers/common/driverfuncs.h index 64f56d91f9..50f2b4271d 100644 --- a/src/mesa/drivers/common/driverfuncs.h +++ b/src/mesa/drivers/common/driverfuncs.h @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.1 + * Version: 6.5.3 * - * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -29,4 +29,8 @@ extern void _mesa_init_driver_functions(struct dd_function_table *driver); + +extern void +_mesa_init_glsl_driver_functions(struct dd_function_table *driver); + #endif diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index 4986b29ef0..c5220b5b2e 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -131,7 +131,7 @@ #include "math/m_xform.h" #include "math/mathmod.h" #endif -#include "shaderobjects.h" +#include "shaders.h" #ifdef USE_SPARC_ASM #include "sparc/sparc.h" @@ -705,7 +705,6 @@ alloc_shared_state( GLcontext *ctx ) ss->ArrayObjects = _mesa_NewHashTable(); #if FEATURE_ARB_shader_objects - ss->GL2Objects = _mesa_NewHashTable (); ss->ShaderObjects = _mesa_NewHashTable(); ss->ProgramObjects = _mesa_NewHashTable(); #endif @@ -784,11 +783,10 @@ alloc_shared_state( GLcontext *ctx ) _mesa_DeleteHashTable (ss->ArrayObjects); #if FEATURE_ARB_shader_objects - if (ss->GL2Objects) { - _mesa_DeleteHashTable (ss->GL2Objects); + if (ss->ShaderObjects) _mesa_DeleteHashTable (ss->ShaderObjects); + if (ss->ProgramObjects) _mesa_DeleteHashTable (ss->ProgramObjects); - } #endif #if FEATURE_EXT_framebuffer_object @@ -953,8 +951,11 @@ free_shared_state( GLcontext *ctx, struct gl_shared_state *ss ) _mesa_DeleteHashTable(ss->ArrayObjects); #if FEATURE_ARB_shader_objects - _mesa_HashDeleteAll(ss->GL2Objects, delete_shaderobj_cb, ctx); - _mesa_DeleteHashTable(ss->GL2Objects); + /* XXX SLANG TO-DO */ + /* + struct _mesa_HashTable *ShaderObjects; + struct _mesa_HashTable *ProgramObjects; + */ #endif #if FEATURE_EXT_framebuffer_object @@ -1202,7 +1203,7 @@ init_attrib_groups( GLcontext *ctx ) _mesa_init_query( ctx ); _mesa_init_rastpos( ctx ); _mesa_init_scissor( ctx ); - _mesa_init_shaderobjects (ctx); + _mesa_init_shader_state( ctx ); _mesa_init_stencil( ctx ); _mesa_init_transform( ctx ); _mesa_init_varray( ctx ); diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h index 1de2542bee..90c1f69c3d 100644 --- a/src/mesa/main/dd.h +++ b/src/mesa/main/dd.h @@ -821,6 +821,58 @@ struct dd_function_table { void (*BindArrayObject)(GLcontext *ctx, struct gl_array_object *obj); /*@}*/ + /** + * \name GLSL-related functions (ARB extensions and OpenGL 2.x) + */ + /*@{*/ + void (*AttachShader)(GLcontext *ctx, GLuint program, GLuint shader); + void (*BindAttribLocation)(GLcontext *ctx, GLuint program, GLuint index, + const GLcharARB *name); + void (*CompileShader)(GLcontext *ctx, GLuint shader); + GLuint (*CreateShader)(GLcontext *ctx, GLenum type); + GLuint (*CreateProgram)(GLcontext *ctx); + void (*DeleteProgram2)(GLcontext *ctx, GLuint program); + void (*DeleteShader)(GLcontext *ctx, GLuint shader); + void (*DetachShader)(GLcontext *ctx, GLuint program, GLuint shader); + void (*GetActiveAttrib)(GLcontext *ctx, GLuint program, GLuint index, + GLsizei maxLength, GLsizei * length, GLint * size, + GLenum * type, GLcharARB * name); + void (*GetActiveUniform)(GLcontext *ctx, GLuint program, GLuint index, + GLsizei maxLength, GLsizei *length, GLint *size, + GLenum *type, GLcharARB *name); + void (*GetAttachedShaders)(GLcontext *ctx, GLuint program, GLsizei maxCount, + GLsizei *count, GLuint *obj); + GLint (*GetAttribLocation)(GLcontext *ctx, GLuint program, + const GLcharARB *name); + GLuint (*GetHandle)(GLcontext *ctx, GLenum pname); + void (*GetProgramiv)(GLcontext *ctx, GLuint program, + GLenum pname, GLint *params); + void (*GetProgramInfoLog)(GLcontext *ctx, GLuint program, GLsizei bufSize, + GLsizei *length, GLchar *infoLog); + void (*GetShaderiv)(GLcontext *ctx, GLuint shader, + GLenum pname, GLint *params); + void (*GetShaderInfoLog)(GLcontext *ctx, GLuint shader, GLsizei bufSize, + GLsizei *length, GLchar *infoLog); + void (*GetShaderSource)(GLcontext *ctx, GLuint shader, GLsizei maxLength, + GLsizei *length, GLcharARB *sourceOut); + void (*GetUniformfv)(GLcontext *ctx, GLuint program, GLint location, + GLfloat *params); + GLint (*GetUniformLocation)(GLcontext *ctx, GLuint program, + const GLcharARB *name); + GLboolean (*IsProgram)(GLcontext *ctx, GLuint name); + GLboolean (*IsShader)(GLcontext *ctx, GLuint name); + void (*LinkProgram)(GLcontext *ctx, GLuint program); + void (*ShaderSource)(GLcontext *ctx, GLuint shader, const GLchar *source); + void (*Uniform)(GLcontext *ctx, GLint location, GLsizei count, + const GLvoid *values, GLenum type); + void (*UniformMatrix)(GLcontext *ctx, GLint cols, GLint rows, + GLenum matrixType, GLint location, GLsizei count, + GLboolean transpose, const GLfloat *values); + void (*UseProgram)(GLcontext *ctx, GLuint program); + void (*ValidateProgram)(GLcontext *ctx, GLuint program); + /* XXX many more to come */ + /*@}*/ + /** * \name Support for multiple T&L engines diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 5ed95ccf65..4a8f7d22e3 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -7,9 +7,9 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * Version: 6.5.3 * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -2052,8 +2052,10 @@ struct gl_shader GLuint Name; /**< AKA the handle */ GLchar *Source; /**< Source code string */ GLboolean CompileStatus; + GLboolean DeletePending; GLuint NumPrograms; /**< size of Programs[] array */ struct gl_program **Programs; /**< Post-compile assembly code */ + GLchar *InfoLog; }; @@ -2070,21 +2072,24 @@ struct gl_linked_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; + struct gl_program_parameter_list *Attributes; /**< Vertex attributes */ + GLboolean LinkStatus; /**< GL_LINK_STATUS */ + GLboolean Validated; + GLboolean DeletePending; + GLchar *InfoLog; }; /** - * Context state for vertex/fragment shaders. + * Context state for GLSL vertex/fragment shaders. */ -struct gl_shader_objects_state +struct gl_shader_state { - struct gl2_program_intf **CurrentProgram; GLboolean _VertexShaderPresent; GLboolean _FragmentShaderPresent; - struct gl_linked_program *Linked; /* XXX temporary here */ + struct gl_linked_program *CurrentProgram; }; @@ -2145,7 +2150,6 @@ struct gl_shared_state #endif #if FEATURE_ARB_shader_objects - struct _mesa_HashTable *GL2Objects; struct _mesa_HashTable *ShaderObjects; struct _mesa_HashTable *ProgramObjects; #endif @@ -2966,7 +2970,7 @@ struct __GLcontextRec struct gl_query_state Query; /**< GL_ARB_occlusion_query */ - struct gl_shader_objects_state ShaderObjects; /* GL_ARB_shader_objects */ + struct gl_shader_state Shader; /**< GLSL shader object state */ /*@}*/ #if FEATURE_EXT_framebuffer_object diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index e121f59258..1d8666888e 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -93,7 +93,7 @@ #include "texenvprogram.h" #endif #if FEATURE_ARB_shader_objects -#include "shaderobjects.h" +#include "shaders.h" #endif #include "debug.h" #include "dispatch.h" @@ -949,7 +949,7 @@ update_arrays( GLcontext *ctx ) static void update_program(GLcontext *ctx) { - const struct gl_linked_program *linked = ctx->ShaderObjects.Linked; + const struct gl_linked_program *linked = ctx->Shader.CurrentProgram; /* These _Enabled flags indicate if the program is enabled AND valid. */ diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c index e379933a66..e089de9310 100644 --- a/src/mesa/main/texstate.c +++ b/src/mesa/main/texstate.c @@ -41,7 +41,7 @@ #include "texenvprogram.h" #include "mtypes.h" #include "math/m_xform.h" -#include "shaderobjects.h" +/*#include "shaderobjects.h"*/ diff --git a/src/mesa/sources b/src/mesa/sources index eed6fb0a0e..19f43384ea 100644 --- a/src/mesa/sources +++ b/src/mesa/sources @@ -48,6 +48,7 @@ MAIN_SOURCES = \ main/rastpos.c \ main/rbadaptors.c \ main/renderbuffer.c \ + main/shaders.c \ main/state.c \ main/stencil.c \ main/texcompress.c \ @@ -164,10 +165,6 @@ SHADER_SOURCES = \ shader/programopt.c \ shader/shader_api.c \ - -## shader/shaderobjects.c \ -## shader/shaderobjects_3dlabs.c - SLANG_SOURCES = \ shader/slang/slang_analyse.c \ shader/slang/slang_assemble.c \ diff --git a/src/mesa/swrast/s_context.c b/src/mesa/swrast/s_context.c index 46f99ef6e0..749e278ffa 100644 --- a/src/mesa/swrast/s_context.c +++ b/src/mesa/swrast/s_context.c @@ -102,7 +102,7 @@ _swrast_update_rasterflags( GLcontext *ctx ) rasterMask |= FRAGPROG_BIT; } - if (ctx->ShaderObjects._FragmentShaderPresent) { + if (ctx->Shader._FragmentShaderPresent) { rasterMask |= FRAGPROG_BIT; } diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c index 7bfb23f0f7..536ac30033 100644 --- a/src/mesa/swrast/s_span.c +++ b/src/mesa/swrast/s_span.c @@ -1365,7 +1365,7 @@ shade_texture_span(GLcontext *ctx, SWspan *span) if (span->interpMask & SPAN_Z) _swrast_span_interpolate_z (ctx, span); - if (ctx->ShaderObjects.Linked && span->interpMask & SPAN_VARYING) + if (ctx->Shader.CurrentProgram && span->interpMask & SPAN_VARYING) interpolate_varying(ctx, span); /* Run fragment program/shader now */ -- cgit v1.2.3 From eb2a6d62f9353d90be757fc1617040c7ccddac39 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 21 Dec 2006 17:50:07 -0700 Subject: s/attribute/varying/ --- src/mesa/swrast/s_tritemp.h | 9 +++++---- src/mesa/swrast/swrast.h | 2 +- src/mesa/swrast_setup/ss_context.c | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/swrast/s_tritemp.h b/src/mesa/swrast/s_tritemp.h index 0ed1772a88..c85379b4b1 100644 --- a/src/mesa/swrast/s_tritemp.h +++ b/src/mesa/swrast/s_tritemp.h @@ -41,7 +41,7 @@ * INTERP_TEX - if defined, interpolate set 0 float STRQ texcoords * NOTE: OpenGL STRQ = Mesa STUV (R was taken for red) * INTERP_MULTITEX - if defined, interpolate N units of STRQ texcoords - * INTERP_VARYING - if defined, interpolate M floats of GLSL varyings + * INTERP_VARYING - if defined, interpolate M GLSL varyings * * When one can directly address pixels in the color buffer the following * macros can be defined and used to compute pixel addresses during @@ -144,6 +144,7 @@ #ifdef INTERP_VARYING +/* XXX need a varyingEnabled[] check */ #define VARYING_LOOP(CODE) \ { \ GLuint iv, ic; \ @@ -669,8 +670,8 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, /* win[3] is 1/W */ const GLfloat wMax = vMax->win[3], wMin = vMin->win[3], wMid = vMid->win[3]; VARYING_LOOP( - GLfloat eMaj_dvar = vMax->attribute[iv][ic] * wMax - vMin->attribute[iv][ic] * wMin; - GLfloat eBot_dvar = vMid->attribute[iv][ic] * wMid - vMin->attribute[iv][ic] * wMin; + GLfloat eMaj_dvar = vMax->varying[iv][ic] * wMax - vMin->varying[iv][ic] * wMin; + GLfloat eBot_dvar = vMid->varying[iv][ic] * wMid - vMin->varying[iv][ic] * wMin; span.varStepX[iv][ic] = oneOverArea * (eMaj_dvar * eBot.dy - eMaj.dy * eBot_dvar); span.varStepY[iv][ic] = oneOverArea * (eMaj.dx * eBot_dvar - eMaj_dvar * eBot.dx); ) @@ -1060,7 +1061,7 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, #ifdef INTERP_VARYING VARYING_LOOP( const GLfloat invW = vLower->win[3]; - const GLfloat var0 = vLower->attribute[iv][ic] * invW; + const GLfloat var0 = vLower->varying[iv][ic] * invW; varLeft[iv][ic] = var0 + (span.varStepX[iv][ic] * adjx + span.varStepY[iv][ic] * adjy) * (1.0f / FIXED_SCALE); dvarOuter[iv][ic] = span.varStepY[iv][ic] + dxOuter * span.varStepX[iv][ic]; diff --git a/src/mesa/swrast/swrast.h b/src/mesa/swrast/swrast.h index 09686c8380..2c1c0952af 100644 --- a/src/mesa/swrast/swrast.h +++ b/src/mesa/swrast/swrast.h @@ -73,7 +73,7 @@ typedef struct { GLfloat fog; GLfloat index; GLfloat pointSize; - GLfloat attribute[MAX_VERTEX_ATTRIBS][4]; + GLfloat varying[MAX_VERTEX_ATTRIBS][4]; } SWvertex; diff --git a/src/mesa/swrast_setup/ss_context.c b/src/mesa/swrast_setup/ss_context.c index 924b423e88..f17e69bfb2 100644 --- a/src/mesa/swrast_setup/ss_context.c +++ b/src/mesa/swrast_setup/ss_context.c @@ -156,7 +156,7 @@ _swsetup_RenderStart( GLcontext *ctx ) for (i = 0; i < ctx->Const.MaxVarying; i++) { if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_GENERIC(i) )) { EMIT_ATTR( _TNL_ATTRIB_GENERIC(i), VARYING_EMIT_STYLE, - attribute[i] ); + varying[i] ); } } } -- cgit v1.2.3 From 392d9701e30f4c7b4cbd25cb8714a42ba2512bd4 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 21 Dec 2006 17:50:22 -0700 Subject: added INTERP_VARYING code --- src/mesa/swrast/s_linetemp.h | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'src/mesa/swrast') diff --git a/src/mesa/swrast/s_linetemp.h b/src/mesa/swrast/s_linetemp.h index f5b2d95653..61c338ac69 100644 --- a/src/mesa/swrast/s_linetemp.h +++ b/src/mesa/swrast/s_linetemp.h @@ -37,6 +37,7 @@ * INTERP_INDEX - if defined, interpolate color index values * INTERP_TEX - if defined, interpolate unit 0 texcoords * INTERP_MULTITEX - if defined, interpolate multi-texcoords + * INTERP_VARYING - if defined, interpolate GLSL varyings * * When one can directly address pixels in the color buffer the following * macros can be defined and used to directly compute pixel addresses during @@ -333,6 +334,34 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 ) } } #endif +#ifdef INTERP_VARYING + interpFlags |= SPAN_VARYING; + { /* XXX review this */ + const GLfloat invLen = 1.0F / numPixels; + GLuint v; + for (v = 0; v < MAX_VARYING; v++) { + const GLfloat invw0 = vert0->win[3]; + const GLfloat invw1 = vert1->win[3]; + GLfloat ds, dt, dr, dq; + span.var[v][0] = invw0 * vert0->varying[v][0]; + span.var[v][1] = invw0 * vert0->varying[v][1]; + span.var[v][2] = invw0 * vert0->varying[v][2]; + span.var[v][3] = invw0 * vert0->varying[v][3]; + ds = (invw1 * vert1->varying[v][0]) - span.var[v][0]; + dt = (invw1 * vert1->varying[v][1]) - span.var[v][1]; + dr = (invw1 * vert1->varying[v][2]) - span.var[v][2]; + dq = (invw1 * vert1->varying[v][3]) - span.var[v][3]; + span.varStepX[v][0] = ds * invLen; + span.varStepX[v][1] = dt * invLen; + span.varStepX[v][2] = dr * invLen; + span.varStepX[v][3] = dq * invLen; + span.varStepY[v][0] = 0.0F; + span.varStepY[v][1] = 0.0F; + span.varStepY[v][2] = 0.0F; + span.varStepY[v][3] = 0.0F; + } + } +#endif INIT_SPAN(span, GL_LINE, numPixels, interpFlags, SPAN_XY); -- cgit v1.2.3 From 9a78ef980d89c0d18f859036d5a0cdf82acd303c Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 8 Jan 2007 16:10:34 -0700 Subject: Remove if (tObj) conditional so that texture units without a texture image return black (0,0,0,1) when sampled. --- src/mesa/swrast/s_context.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/swrast/s_context.c b/src/mesa/swrast/s_context.c index 749e278ffa..6e3475b130 100644 --- a/src/mesa/swrast/s_context.c +++ b/src/mesa/swrast/s_context.c @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.5.1 + * Version: 6.5.3 * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -499,9 +499,10 @@ _swrast_update_texture_samplers(GLcontext *ctx) for (u = 0; u < ctx->Const.MaxTextureImageUnits; u++) { const struct gl_texture_object *tObj = ctx->Texture.Unit[u]._Current; - if (tObj) - swrast->TextureSample[u] = - _swrast_choose_texture_sample_func(ctx, tObj); + /* Note: If tObj is NULL, the sample function will be a simple + * function that just returns opaque black (0,0,0,1). + */ + swrast->TextureSample[u] = _swrast_choose_texture_sample_func(ctx, tObj); } } -- cgit v1.2.3 From 41a4e828d9e06e42bba78166975cb283674c0d9f Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 8 Jan 2007 16:49:43 -0700 Subject: check if _Current == NULL for TXB --- src/mesa/swrast/s_fragprog.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c index c59e24debe..517b63c91b 100644 --- a/src/mesa/swrast/s_fragprog.c +++ b/src/mesa/swrast/s_fragprog.c @@ -1358,6 +1358,8 @@ execute_program( GLcontext *ctx, case OPCODE_TXB: /* GL_ARB_fragment_program only */ /* Texel lookup with LOD bias */ { + const struct gl_texture_unit *texUnit + = &ctx->Texture.Unit[inst->TexSrcUnit]; GLfloat coord[4], color[4], lambda, bias; if (inst->SrcReg[0].File == PROGRAM_INPUT && inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0+inst->TexSrcUnit) @@ -1366,9 +1368,9 @@ execute_program( GLcontext *ctx, lambda = 0.0; fetch_vector4(ctx, &inst->SrcReg[0], machine, program, coord); /* coord[3] is the bias to add to lambda */ - bias = ctx->Texture.Unit[inst->TexSrcUnit].LodBias - + ctx->Texture.Unit[inst->TexSrcUnit]._Current->LodBias - + coord[3]; + bias = texUnit->LodBias + coord[3]; + if (texUnit->_Current) + bias += texUnit->_Current->LodBias; fetch_texel(ctx, coord, lambda + bias, inst->TexSrcUnit, color); store_vector4( inst, machine, color ); } -- cgit v1.2.3 From 5e75db12d7b17f0295e8099bd357220df97d5013 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 9 Jan 2007 17:47:13 -0700 Subject: more debug code (disabled) --- src/mesa/swrast/s_fragprog.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c index 517b63c91b..83a50c7451 100644 --- a/src/mesa/swrast/s_fragprog.c +++ b/src/mesa/swrast/s_fragprog.c @@ -1601,12 +1601,16 @@ init_machine( GLcontext *ctx, struct fp_machine *machine, /*ASSERT(ctx->Texture._EnabledCoordUnits & (1 << u));*/ COPY_4V(tex, span->array->texcoords[u][col]); /*ASSERT(tex[0] != 0 || tex[1] != 0 || tex[2] != 0);*/ +#if 0 + printf("Texcoord %d: %g %g %g %g\n", u, + tex[0], tex[1], tex[2], tex[3]); +#endif } } for (v = 0; v < ctx->Const.MaxVarying; v++) { if (inputsRead & (1 << (FRAG_ATTRIB_VAR0 + v))) { #if 0 - printf("Frag Var %d: %f %f %f\n", col, + printf("Frag Var %d at y=%d: %f %f %f\n", v, col, span->array->varying[col][v][0], span->array->varying[col][v][1], span->array->varying[col][v][2]); -- cgit v1.2.3 From 0bad236cfbaabfc0ed4f20088e64fa89f81934ce Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 17 Jan 2007 15:54:14 -0700 Subject: Added OPCODE_INT to convert 4 floats to 4 ints. --- src/mesa/shader/prog_instruction.c | 1 + src/mesa/shader/prog_instruction.h | 1 + src/mesa/swrast/s_fragprog.c | 11 +++++++++++ src/mesa/tnl/t_vb_arbprogram.c | 17 +++++++++++++++++ 4 files changed, 30 insertions(+) (limited to 'src/mesa/swrast') diff --git a/src/mesa/shader/prog_instruction.c b/src/mesa/shader/prog_instruction.c index bebc3ecb69..1379018d4a 100644 --- a/src/mesa/shader/prog_instruction.c +++ b/src/mesa/shader/prog_instruction.c @@ -135,6 +135,7 @@ static const struct instruction_info InstInfo[MAX_OPCODE] = { { OPCODE_EXP, "EXP", 1 }, { OPCODE_FLR, "FLR", 1 }, { OPCODE_FRC, "FRC", 1 }, + { OPCODE_INT, "INT", 1 }, { OPCODE_KIL, "KIL", 1 }, { OPCODE_KIL_NV, "KIL", 0 }, { OPCODE_LG2, "LG2", 1 }, diff --git a/src/mesa/shader/prog_instruction.h b/src/mesa/shader/prog_instruction.h index d825e6e0a3..b659879651 100644 --- a/src/mesa/shader/prog_instruction.h +++ b/src/mesa/shader/prog_instruction.h @@ -148,6 +148,7 @@ typedef enum prog_opcode { OPCODE_EXP, /* X X */ OPCODE_FLR, /* X X 2 X */ OPCODE_FRC, /* X X 2 X */ + OPCODE_INT, /* */ OPCODE_KIL, /* X */ OPCODE_KIL_NV, /* X */ OPCODE_LG2, /* X X 2 X */ diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c index 83a50c7451..b842b49616 100644 --- a/src/mesa/swrast/s_fragprog.c +++ b/src/mesa/swrast/s_fragprog.c @@ -888,6 +888,17 @@ execute_program( GLcontext *ctx, store_vector4( inst, machine, result ); } break; + case OPCODE_INT: /* float to int */ + { + GLfloat a[4], result[4]; + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); + result[0] = (GLfloat) (GLint) a[0]; + result[1] = (GLfloat) (GLint) a[1]; + result[2] = (GLfloat) (GLint) a[2]; + result[3] = (GLfloat) (GLint) a[3]; + store_vector4( inst, machine, result ); + } + break; case OPCODE_KIL_NV: /* NV_f_p only */ { const GLuint swizzle = inst->DstReg.CondSwizzle; diff --git a/src/mesa/tnl/t_vb_arbprogram.c b/src/mesa/tnl/t_vb_arbprogram.c index 906fd3f1e8..5773f0f627 100644 --- a/src/mesa/tnl/t_vb_arbprogram.c +++ b/src/mesa/tnl/t_vb_arbprogram.c @@ -338,6 +338,17 @@ static void do_FRC( struct arb_vp_machine *m, union instruction op ) result[3] = arg0[3] - FLOORF(arg0[3]); } +static void do_INT( struct arb_vp_machine *m, union instruction op ) +{ + GLfloat *result = m->File[0][op.alu.dst]; + const GLfloat *arg0 = m->File[op.alu.file0][op.alu.idx0]; + + result[0] = (GLfloat) (GLint) arg0[0]; + result[1] = (GLfloat) (GLint) arg0[1]; + result[2] = (GLfloat) (GLint) arg0[2]; + result[3] = (GLfloat) (GLint) arg0[3]; +} + /* High precision log base 2: */ static void do_LG2( struct arb_vp_machine *m, union instruction op ) @@ -665,6 +676,7 @@ _tnl_disassem_vba_insn( union instruction op ) case OPCODE_EXP: case OPCODE_FLR: case OPCODE_FRC: + case OPCODE_INT: case OPCODE_LG2: case OPCODE_LIT: case OPCODE_LOG: @@ -739,6 +751,7 @@ static void (* const opcode_func[MAX_OPCODE+3])(struct arb_vp_machine *, union i do_EXP, do_FLR, do_FRC, + do_INT, do_NOP,/*KIL*/ do_NOP,/*KIL_NV*/ do_LG2, @@ -1458,6 +1471,10 @@ static GLboolean init_vertex_program( GLcontext *ctx, const GLuint size = VB->Size; GLuint i; + /* spot checks to be sure the opcode table is correct */ + assert(opcode_func[OPCODE_SGE] == do_SGE); + assert(opcode_func[OPCODE_XPD] == do_XPD); + stage->privatePtr = _mesa_calloc(sizeof(*m)); m = ARB_VP_MACHINE(stage); if (!m) -- cgit v1.2.3 From 5ae49cf3ed53fda6a904d7e90feef78495ae6903 Mon Sep 17 00:00:00 2001 From: Brian Date: Sat, 20 Jan 2007 09:27:40 -0700 Subject: Initial implementation of OPCODE_IF/ELSE/ENDIF instructions. --- src/mesa/shader/prog_instruction.c | 3 ++ src/mesa/shader/prog_instruction.h | 3 ++ src/mesa/shader/prog_print.c | 14 +++++++- src/mesa/shader/slang/slang_codegen.c | 53 ++++++++++++++++++++++++++- src/mesa/shader/slang/slang_emit.c | 37 +++++++++++++++++++ src/mesa/shader/slang/slang_ir.h | 3 ++ src/mesa/swrast/s_fragprog.c | 67 +++++++++++++++++++++++++++++++++++ src/mesa/tnl/t_vb_arbprogram.c | 5 ++- 8 files changed, 182 insertions(+), 3 deletions(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/shader/prog_instruction.c b/src/mesa/shader/prog_instruction.c index 1379018d4a..3de71b8b5d 100644 --- a/src/mesa/shader/prog_instruction.c +++ b/src/mesa/shader/prog_instruction.c @@ -130,11 +130,14 @@ static const struct instruction_info InstInfo[MAX_OPCODE] = { { OPCODE_DP4, "DP4", 2 }, { OPCODE_DPH, "DPH", 2 }, { OPCODE_DST, "DST", 2 }, + { OPCODE_ELSE, "ELSE", 0 }, { OPCODE_END, "END", 0 }, + { OPCODE_ENDIF, "ENDIF", 0 }, { OPCODE_EX2, "EX2", 1 }, { OPCODE_EXP, "EXP", 1 }, { OPCODE_FLR, "FLR", 1 }, { OPCODE_FRC, "FRC", 1 }, + { OPCODE_IF, "IF", 0 }, { OPCODE_INT, "INT", 1 }, { OPCODE_KIL, "KIL", 1 }, { OPCODE_KIL_NV, "KIL", 0 }, diff --git a/src/mesa/shader/prog_instruction.h b/src/mesa/shader/prog_instruction.h index b659879651..b1001885e0 100644 --- a/src/mesa/shader/prog_instruction.h +++ b/src/mesa/shader/prog_instruction.h @@ -143,11 +143,14 @@ typedef enum prog_opcode { OPCODE_DP4, /* X X X X */ OPCODE_DPH, /* X X 1.1 */ OPCODE_DST, /* X X X X */ + OPCODE_ELSE, OPCODE_END, /* X X X X */ + OPCODE_ENDIF, OPCODE_EX2, /* X X 2 X */ OPCODE_EXP, /* X X */ OPCODE_FLR, /* X X 2 X */ OPCODE_FRC, /* X X 2 X */ + OPCODE_IF, OPCODE_INT, /* */ OPCODE_KIL, /* X */ OPCODE_KIL_NV, /* X */ diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c index 04b7c7d22a..78ce752f2a 100644 --- a/src/mesa/shader/prog_print.c +++ b/src/mesa/shader/prog_print.c @@ -295,7 +295,7 @@ _mesa_print_instruction(const struct prog_instruction *inst) print_comment(inst); break; case OPCODE_BRA: - _mesa_printf("BRA %u (%s.%s)", + _mesa_printf("BRA %u (%s%s)", inst->BranchTarget, condcode_string(inst->DstReg.CondMask), swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE)); @@ -305,6 +305,18 @@ _mesa_print_instruction(const struct prog_instruction *inst) _mesa_printf("CAL %u", inst->BranchTarget); print_comment(inst); break; + case OPCODE_IF: + _mesa_printf(" IF (%s%s)", + condcode_string(inst->DstReg.CondMask), + swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE)); + print_comment(inst); + break; + case OPCODE_ELSE: + _mesa_printf(" ELSE;\n"); + break; + case OPCODE_ENDIF: + _mesa_printf(" ENDIF;\n"); + break; case OPCODE_END: _mesa_printf("END"); print_comment(inst); diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index 6923c00562..aba6813a8b 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -1560,6 +1560,51 @@ _slang_gen_if(slang_assemble_ctx * A, const slang_operation *oper) } +/** + * Use high-level IF/ELSE/ENDIF instructions + */ +static slang_ir_node * +_slang_gen_if2(slang_assemble_ctx * A, const slang_operation *oper) +{ + /* + * eval expr (child[0]), updating condcodes + * branch if false to _else or _endif + * "true" code block + * if haveElseClause clause: + * jump "__endif" + * label "__else" + * "false" code block + * label "__endif" + */ + const GLboolean haveElseClause = !_slang_is_noop(&oper->children[2]); + slang_ir_node *ifNode, *cond, *trueBody, *elseNode, *falseBody, *endifNode; + slang_ir_node *tree; + + cond = _slang_gen_operation(A, &oper->children[0]); + cond = _slang_gen_cond(cond); + /*assert(cond->Store);*/ + ifNode = new_node(IR_IF, cond, NULL); + + trueBody = _slang_gen_operation(A, &oper->children[1]); + tree = new_seq(ifNode, trueBody); + + if (haveElseClause) { + /* else clause */ + elseNode = new_node(IR_ELSE, NULL, NULL); + tree = new_seq(tree, elseNode); + + falseBody = _slang_gen_operation(A, &oper->children[2]); + tree = new_seq(tree, falseBody); + } + + endifNode = new_node(IR_ENDIF, NULL, NULL); + tree = new_seq(tree, endifNode); + + return tree; +} + + + /** * Generate IR node for storage of a temporary of given size. */ @@ -2314,7 +2359,13 @@ _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper) case slang_oper_identifier: return _slang_gen_variable(A, oper); case slang_oper_if: - return _slang_gen_if(A, oper); + if (A->program->Target == GL_FRAGMENT_PROGRAM_ARB) { + return _slang_gen_if(A, oper); + } + else { + /* XXX update tnl executor */ + return _slang_gen_if(A, oper); + } case slang_oper_field: return _slang_gen_field(A, oper); case slang_oper_subscript: diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c index 6c31bfc677..44fd3752e2 100644 --- a/src/mesa/shader/slang/slang_emit.c +++ b/src/mesa/shader/slang/slang_emit.c @@ -91,6 +91,9 @@ static slang_ir_info IrInfo[] = { { IR_JUMP, "IR_JUMP", 0, 0, 0 }, { IR_CJUMP0, "IR_CJUMP0", 0, 0, 0 }, { IR_CJUMP1, "IR_CJUMP1", 0, 0, 0 }, + { IR_IF, "IR_IF", 0, 0, 0 }, + { IR_ELSE, "IR_ELSE", 0, 0, 0 }, + { IR_ENDIF, "IR_ENDIF", 0, 0, 0 }, { IR_KILL, "IR_KILL", 0, 0, 0 }, { IR_COND, "IR_COND", 0, 0, 0 }, { IR_CALL, "IR_CALL", 0, 0, 0 }, @@ -271,6 +274,18 @@ slang_print_ir(const slang_ir_node *n, int indent) printf("CJUMP1 %s\n", n->Target); slang_print_ir(n->Children[0], indent+3); break; + + case IR_IF: + printf("IF \n"); + slang_print_ir(n->Children[0], indent+3); + break; + case IR_ELSE: + printf("ELSE\n"); + break; + case IR_ENDIF: + printf("ENDIF\n"); + break; + case IR_VAR: printf("VAR %s%s at %s store %p\n", (char *) n->Var->a_name, swizzle_string(n->Store->Swizzle), @@ -862,6 +877,28 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) case IR_KILL: return emit_kill(prog); + case IR_IF: + { + struct prog_instruction *inst; + emit(vt, n->Children[0], prog); /* the condition */ + inst = new_instruction(prog, OPCODE_IF); + inst->DstReg.CondMask = COND_NE; /* if cond is non-zero */ + inst->DstReg.CondSwizzle = SWIZZLE_X; + return inst; + } + case IR_ELSE: + { + struct prog_instruction *inst; + inst = new_instruction(prog, OPCODE_ELSE); + return inst; + } + case IR_ENDIF: + { + struct prog_instruction *inst; + inst = new_instruction(prog, OPCODE_ENDIF); + return inst; + } + default: _mesa_problem(NULL, "Unexpected IR opcode in emit()\n"); abort(); diff --git a/src/mesa/shader/slang/slang_ir.h b/src/mesa/shader/slang/slang_ir.h index 4072c70f90..e5a0fa8eb5 100644 --- a/src/mesa/shader/slang/slang_ir.h +++ b/src/mesa/shader/slang/slang_ir.h @@ -51,6 +51,9 @@ typedef enum IR_CJUMP0, /* conditional jump if zero */ IR_CJUMP1, /* conditional jump if one (or non-zero) */ IR_COND, /* conditional expression */ + IR_IF, /* high-level IF */ + IR_ELSE, /* high-level ELSE */ + IR_ENDIF, /* high-level ENDIF */ IR_CALL, /* call subroutine */ IR_MOVE, IR_ADD, diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c index b842b49616..813345f4cd 100644 --- a/src/mesa/swrast/s_fragprog.c +++ b/src/mesa/swrast/s_fragprog.c @@ -888,6 +888,73 @@ execute_program( GLcontext *ctx, store_vector4( inst, machine, result ); } break; + case OPCODE_IF: + { + const GLuint swizzle = inst->DstReg.CondSwizzle; + const GLuint condMask = inst->DstReg.CondMask; + if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) || + test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) || + test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) || + test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) { + /* do if-clause (just continue execution) */ + } + else { + /* do else-clause, or go to endif */ + GLint ifDepth = 1; + do { + pc++; + inst = program->Base.Instructions + pc; + if (inst->Opcode == OPCODE_END) { + /* mal-formed program! */ + abort(); + } + else if (inst->Opcode == OPCODE_IF) { + ifDepth++; + } + else if (inst->Opcode == OPCODE_ELSE) { + if (ifDepth == 0) { + /* ok, continue normal execution */ + break; + } + } + else if (inst->Opcode == OPCODE_ENDIF) { + ifDepth--; + if (ifDepth == 0) { + /* ok, continue normal execution */ + break; + } + } + assert(ifDepth >= 0); + } while (pc < maxInst); + } + } + break; + case OPCODE_ELSE: + { + /* find/goto ENDIF */ + GLint ifDepth = 1; + do { + pc++; + inst = program->Base.Instructions + pc; + if (inst->Opcode == OPCODE_END) { + /* mal-formed program! */ + abort(); + } + else if (inst->Opcode == OPCODE_IF) { + ifDepth++; + } + else if (inst->Opcode == OPCODE_ENDIF) { + ifDepth--; + if (ifDepth == 0) + break; + } + assert(ifDepth >= 0); + } while (pc < maxInst); + } + break; + case OPCODE_ENDIF: + /* nothing */ + break; case OPCODE_INT: /* float to int */ { GLfloat a[4], result[4]; diff --git a/src/mesa/tnl/t_vb_arbprogram.c b/src/mesa/tnl/t_vb_arbprogram.c index 5773f0f627..5726a66c90 100644 --- a/src/mesa/tnl/t_vb_arbprogram.c +++ b/src/mesa/tnl/t_vb_arbprogram.c @@ -746,11 +746,14 @@ static void (* const opcode_func[MAX_OPCODE+3])(struct arb_vp_machine *, union i do_DP4, do_DPH, do_DST, - do_NOP, + do_NOP,/*ELSE*/ + do_NOP,/*END*/ + do_NOP,/*ENDIF*/ do_EX2, do_EXP, do_FLR, do_FRC, + do_NOP,/*IF*/ do_INT, do_NOP,/*KIL*/ do_NOP,/*KIL_NV*/ -- cgit v1.2.3 From 223d7cb3c785ad58c869a3ee0fbf2f1d42c3310d Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 23 Jan 2007 16:37:51 -0700 Subject: fix g++ warnings/errors --- src/mesa/main/texenvprogram.c | 5 ++-- src/mesa/shader/arbprogram.c | 4 +-- src/mesa/shader/prog_parameter.c | 8 +++--- src/mesa/shader/prog_parameter.h | 4 +-- src/mesa/shader/prog_statevars.c | 2 +- src/mesa/shader/shader_api.c | 6 ++--- src/mesa/shader/slang/slang_codegen.c | 17 ++++++++----- src/mesa/shader/slang/slang_emit.c | 46 +++++++++++++++++------------------ src/mesa/shader/slang/slang_link2.c | 2 +- src/mesa/sources | 1 + src/mesa/swrast/s_fragprog.c | 7 +++--- 11 files changed, 54 insertions(+), 48 deletions(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/main/texenvprogram.c b/src/mesa/main/texenvprogram.c index 3cb2adbde2..b69e650159 100644 --- a/src/mesa/main/texenvprogram.c +++ b/src/mesa/main/texenvprogram.c @@ -1187,13 +1187,14 @@ static void cache_item( struct texenvprog_cache *cache, const struct state_key *key, void *data ) { - struct texenvprog_cache_item *c = MALLOC(sizeof(*c)); + struct texenvprog_cache_item *c + = (struct texenvprog_cache_item *) MALLOC(sizeof(*c)); c->hash = hash; c->key = _mesa_malloc(sizeof(*key)); memcpy(c->key, key, sizeof(*key)); - c->data = data; + c->data = (struct gl_fragment_program *) data; if (cache->n_items > cache->size * 1.5) { if (cache->size < 1000) diff --git a/src/mesa/shader/arbprogram.c b/src/mesa/shader/arbprogram.c index f3b25da394..5583f16ce8 100644 --- a/src/mesa/shader/arbprogram.c +++ b/src/mesa/shader/arbprogram.c @@ -312,7 +312,7 @@ _mesa_ProgramEnvParameters4fvEXT(GLenum target, GLuint index, GLsizei count, const GLfloat *params) { GET_CURRENT_CONTEXT(ctx); - unsigned i; + GLint i; GLfloat * dest; ASSERT_OUTSIDE_BEGIN_END(ctx); @@ -464,7 +464,7 @@ _mesa_ProgramLocalParameters4fvEXT(GLenum target, GLuint index, GLsizei count, { GET_CURRENT_CONTEXT(ctx); struct gl_program *prog; - unsigned i; + GLint i; ASSERT_OUTSIDE_BEGIN_END(ctx); FLUSH_VERTICES(ctx, _NEW_PROGRAM); diff --git a/src/mesa/shader/prog_parameter.c b/src/mesa/shader/prog_parameter.c index 90118b6294..a87dafc598 100644 --- a/src/mesa/shader/prog_parameter.c +++ b/src/mesa/shader/prog_parameter.c @@ -217,7 +217,7 @@ _mesa_add_unnamed_constant(struct gl_program_parameter_list *paramList, * constants because we rely on smearing (i.e. .yyyy or .zzzz). */ if (size == 1) { - for (pos = 0; pos < paramList->NumParameters; pos++) { + for (pos = 0; pos < (GLint) paramList->NumParameters; pos++) { struct gl_program_parameter *p = paramList->Parameters + pos; if (p->Type == PROGRAM_CONSTANT && p->Size + size <= 4) { /* ok, found room */ @@ -321,7 +321,7 @@ _mesa_add_attribute(struct gl_program_parameter_list *paramList, else { /* add */ gl_state_index state[STATE_LENGTH]; - state[0] = attrib; + state[0] = (gl_state_index) attrib; if (size < 0) size = 4; i = _mesa_add_parameter(paramList, PROGRAM_INPUT, name, @@ -373,7 +373,7 @@ _mesa_add_state_reference(struct gl_program_parameter_list *paramList, GLint index; /* Check if the state reference is already in the list */ - for (index = 0; index < paramList->NumParameters; index++) { + for (index = 0; index < (GLint) paramList->NumParameters; index++) { GLuint i, match = 0; for (i = 0; i < 6; i++) { if (paramList->Parameters[index].StateIndexes[i] == stateTokens[i]) { @@ -468,7 +468,7 @@ _mesa_lookup_parameter_index(const struct gl_program_parameter_list *paramList, */ GLboolean _mesa_lookup_parameter_constant(const struct gl_program_parameter_list *list, - const GLfloat v[], GLsizei vSize, + const GLfloat v[], GLuint vSize, GLint *posOut, GLuint *swizzleOut) { GLuint i; diff --git a/src/mesa/shader/prog_parameter.h b/src/mesa/shader/prog_parameter.h index bfae071be0..459643f425 100644 --- a/src/mesa/shader/prog_parameter.h +++ b/src/mesa/shader/prog_parameter.h @@ -50,7 +50,7 @@ struct gl_program_parameter /** * A sequence of STATE_* tokens and integers to identify GL state. */ - GLuint StateIndexes[STATE_LENGTH]; + GLint StateIndexes[STATE_LENGTH]; }; @@ -127,7 +127,7 @@ _mesa_lookup_parameter_index(const struct gl_program_parameter_list *paramList, extern GLboolean _mesa_lookup_parameter_constant(const struct gl_program_parameter_list *list, - const GLfloat v[], GLsizei vSize, + const GLfloat v[], GLuint vSize, GLint *posOut, GLuint *swizzleOut); extern GLuint diff --git a/src/mesa/shader/prog_statevars.c b/src/mesa/shader/prog_statevars.c index a0a00cfb95..3a54ab8c58 100644 --- a/src/mesa/shader/prog_statevars.c +++ b/src/mesa/shader/prog_statevars.c @@ -775,7 +775,7 @@ _mesa_load_state_parameters(GLcontext *ctx, for (i = 0; i < paramList->NumParameters; i++) { if (paramList->Parameters[i].Type == PROGRAM_STATE_VAR) { _mesa_fetch_state(ctx, - paramList->Parameters[i].StateIndexes, + (gl_state_index *) paramList->Parameters[i].StateIndexes, paramList->ParameterValues[i]); } } diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c index c18bbcec4b..6bae17a905 100644 --- a/src/mesa/shader/shader_api.c +++ b/src/mesa/shader/shader_api.c @@ -518,7 +518,7 @@ _mesa_get_attached_shaders(GLcontext *ctx, GLuint program, GLsizei maxCount, struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, program); if (shProg) { - GLuint i; + GLint i; for (i = 0; i < maxCount && i < shProg->NumShaders; i++) { obj[i] = shProg->Shaders[i]->Name; } @@ -719,7 +719,7 @@ _mesa_get_uniformfv(GLcontext *ctx, GLuint program, GLint location, struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, program); if (shProg) { - GLuint i; + GLint i; if (location >= 0 && location < shProg->Uniforms->NumParameters) { for (i = 0; i < shProg->Uniforms->Parameters[location].Size; i++) { params[i] = shProg->Uniforms->ParameterValues[location][i]; @@ -883,7 +883,7 @@ _mesa_uniform(GLcontext *ctx, GLint location, GLsizei count, return; } - if (location < 0 || location >= shProg->Uniforms->NumParameters) { + if (location < 0 || location >= (GLint) shProg->Uniforms->NumParameters) { _mesa_error(ctx, GL_INVALID_VALUE, "glUniform(location)"); return; } diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index aba6813a8b..ff42db9def 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -661,7 +661,7 @@ static slang_operation * slang_inline_asm_function(slang_assemble_ctx *A, slang_function *fun, slang_operation *oper) { - const int numArgs = oper->num_children; + const GLuint numArgs = oper->num_children; const slang_operation *args = oper->children; GLuint i; slang_operation *inlined = slang_operation_new(1); @@ -1052,7 +1052,8 @@ slang_inline_function_call(slang_assemble_ctx * A, slang_function *fun, &inlined->children, inlined->num_children); lab->type = slang_oper_label; - lab->a_id = slang_atom_pool_atom(A->atoms, A->CurFunction->end_label); + lab->a_id = slang_atom_pool_atom(A->atoms, + (char *) A->CurFunction->end_label); } for (i = 0; i < totalArgs; i++) { @@ -1281,7 +1282,7 @@ _slang_gen_cond(slang_ir_node *n) static void print_funcs(struct slang_function_scope_ *scope, const char *name) { - int i; + GLuint i; for (i = 0; i < scope->num_functions; i++) { slang_function *f = &scope->functions[i]; if (!name || strcmp(name, (char*) f->header.a_name) == 0) @@ -1301,7 +1302,7 @@ print_funcs(struct slang_function_scope_ *scope, const char *name) static slang_function * _slang_first_function(struct slang_function_scope_ *scope, const char *name) { - int i; + GLuint i; for (i = 0; i < scope->num_functions; i++) { slang_function *f = &scope->functions[i]; if (strcmp(name, (char*) f->header.a_name) == 0) @@ -1800,7 +1801,9 @@ _slang_gen_return(slang_assemble_ctx * A, slang_operation *oper) slang_operation gotoOp; slang_operation_construct(&gotoOp); gotoOp.type = slang_oper_goto; - gotoOp.a_id = slang_atom_pool_atom(A->atoms, A->CurFunction->end_label); + /* XXX don't call function? */ + gotoOp.a_id = slang_atom_pool_atom(A->atoms, + (char *) A->CurFunction->end_label); /* assemble the new code */ n = _slang_gen_operation(A, &gotoOp); /* destroy temp code */ @@ -1855,7 +1858,9 @@ _slang_gen_return(slang_assemble_ctx * A, slang_operation *oper) jump = &block->children[1]; jump->type = slang_oper_goto; assert(A->CurFunction->end_label); - jump->a_id = slang_atom_pool_atom(A->atoms, A->CurFunction->end_label); + /* XXX don't call function? */ + jump->a_id = slang_atom_pool_atom(A->atoms, + (char *) A->CurFunction->end_label); #if 0 /* debug */ printf("NEW RETURN:\n"); diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c index 036509c51c..82e8c0b158 100644 --- a/src/mesa/shader/slang/slang_emit.c +++ b/src/mesa/shader/slang/slang_emit.c @@ -83,35 +83,35 @@ static slang_ir_info IrInfo[] = { { IR_FLOOR, "IR_FLOOR", OPCODE_FLR, 4, 1 }, { IR_FRAC, "IR_FRAC", OPCODE_FRC, 4, 1 }, { IR_ABS, "IR_ABS", OPCODE_ABS, 4, 1 }, - { IR_NEG, "IR_NEG", 0/*spec case*/, 4, 1 }, + { IR_NEG, "IR_NEG", OPCODE_NOP/*spec case*/, 4, 1 }, { IR_DDX, "IR_DDX", OPCODE_DDX, 4, 1 }, { IR_DDX, "IR_DDY", OPCODE_DDX, 4, 1 }, { IR_SIN, "IR_SIN", OPCODE_SIN, 1, 1 }, { IR_COS, "IR_COS", OPCODE_COS, 1, 1 }, /* other */ - { IR_SEQ, "IR_SEQ", 0, 0, 0 }, - { IR_SCOPE, "IR_SCOPE", 0, 0, 0 }, - { IR_LABEL, "IR_LABEL", 0, 0, 0 }, - { IR_JUMP, "IR_JUMP", 0, 0, 0 }, - { IR_CJUMP0, "IR_CJUMP0", 0, 0, 0 }, - { IR_CJUMP1, "IR_CJUMP1", 0, 0, 0 }, - { IR_IF, "IR_IF", 0, 0, 0 }, - { IR_ELSE, "IR_ELSE", 0, 0, 0 }, - { IR_ENDIF, "IR_ENDIF", 0, 0, 0 }, - { IR_KILL, "IR_KILL", 0, 0, 0 }, - { IR_COND, "IR_COND", 0, 0, 0 }, - { IR_CALL, "IR_CALL", 0, 0, 0 }, - { IR_MOVE, "IR_MOVE", 0, 0, 1 }, - { IR_NOT, "IR_NOT", 0, 1, 1 }, - { IR_VAR, "IR_VAR", 0, 0, 0 }, - { IR_VAR_DECL, "IR_VAR_DECL", 0, 0, 0 }, + { IR_SEQ, "IR_SEQ", OPCODE_NOP, 0, 0 }, + { IR_SCOPE, "IR_SCOPE", OPCODE_NOP, 0, 0 }, + { IR_LABEL, "IR_LABEL", OPCODE_NOP, 0, 0 }, + { IR_JUMP, "IR_JUMP", OPCODE_NOP, 0, 0 }, + { IR_CJUMP0, "IR_CJUMP0", OPCODE_NOP, 0, 0 }, + { IR_CJUMP1, "IR_CJUMP1", OPCODE_NOP, 0, 0 }, + { IR_IF, "IR_IF", OPCODE_NOP, 0, 0 }, + { IR_ELSE, "IR_ELSE", OPCODE_NOP, 0, 0 }, + { IR_ENDIF, "IR_ENDIF", OPCODE_NOP, 0, 0 }, + { IR_KILL, "IR_KILL", OPCODE_NOP, 0, 0 }, + { IR_COND, "IR_COND", OPCODE_NOP, 0, 0 }, + { IR_CALL, "IR_CALL", OPCODE_NOP, 0, 0 }, + { IR_MOVE, "IR_MOVE", OPCODE_NOP, 0, 1 }, + { IR_NOT, "IR_NOT", OPCODE_NOP, 1, 1 }, + { IR_VAR, "IR_VAR", OPCODE_NOP, 0, 0 }, + { IR_VAR_DECL, "IR_VAR_DECL", OPCODE_NOP, 0, 0 }, { IR_TEX, "IR_TEX", OPCODE_TEX, 4, 1 }, { IR_TEXB, "IR_TEXB", OPCODE_TXB, 4, 1 }, { IR_TEXP, "IR_TEXP", OPCODE_TXP, 4, 1 }, - { IR_FLOAT, "IR_FLOAT", 0, 0, 0 }, - { IR_FIELD, "IR_FIELD", 0, 0, 0 }, - { IR_ELEMENT, "IR_ELEMENT", 0, 0, 0 }, - { IR_SWIZZLE, "IR_SWIZZLE", 0, 0, 0 }, + { IR_FLOAT, "IR_FLOAT", OPCODE_NOP, 0, 0 }, + { IR_FIELD, "IR_FIELD", OPCODE_NOP, 0, 0 }, + { IR_ELEMENT, "IR_ELEMENT", OPCODE_NOP, 0, 0 }, + { IR_SWIZZLE, "IR_SWIZZLE", OPCODE_NOP, 0, 0 }, { IR_NOP, NULL, OPCODE_NOP, 0, 0 } }; @@ -219,7 +219,7 @@ storage_string(const slang_ir_storage *st) sprintf(s, "%s[%d..%d]", files[st->File], st->Index, st->Index + st->Size - 1); #endif - assert(st->File < sizeof(files) / sizeof(files[0])); + assert(st->File < (GLint) (sizeof(files) / sizeof(files[0]))); sprintf(s, "%s[%d]", files[st->File], st->Index); return s; } @@ -966,7 +966,7 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) if (n->Children[1]->Opcode == IR_FLOAT) { /* OK, constant index */ const GLint arrayAddr = n->Children[0]->Store->Index; - const GLint index = n->Children[1]->Value[0]; + const GLint index = (GLint) n->Children[1]->Value[0]; n->Store->Index = arrayAddr + index; } else { diff --git a/src/mesa/shader/slang/slang_link2.c b/src/mesa/shader/slang/slang_link2.c index 0a517aecc5..9676aa5fa1 100644 --- a/src/mesa/shader/slang/slang_link2.c +++ b/src/mesa/shader/slang/slang_link2.c @@ -133,7 +133,7 @@ link_varying_vars(struct gl_shader_program *shProg, struct gl_program *prog) static GLboolean -is_uniform(enum register_file file) +is_uniform(GLuint file) { return (file == PROGRAM_ENV_PARAM || file == PROGRAM_STATE_VAR || diff --git a/src/mesa/sources b/src/mesa/sources index 1b0474c14b..d0b7246ed6 100644 --- a/src/mesa/sources +++ b/src/mesa/sources @@ -182,6 +182,7 @@ SLANG_SOURCES = \ shader/slang/slang_error.c \ shader/slang/slang_execute.c \ shader/slang/slang_export.c \ + shader/slang/slang_label.c \ shader/slang/slang_library_noise.c \ shader/slang/slang_library_texsample.c \ shader/slang/slang_link.c \ diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c index 813345f4cd..ed82460669 100644 --- a/src/mesa/swrast/s_fragprog.c +++ b/src/mesa/swrast/s_fragprog.c @@ -200,8 +200,7 @@ fetch_vector4( GLcontext *ctx, const GLfloat *src = get_register_pointer(ctx, source, machine, program); ASSERT(src); - if (source->Swizzle == MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, - SWIZZLE_Z, SWIZZLE_W)) { + if (source->Swizzle == SWIZZLE_NOOP) { /* no swizzling */ COPY_4V(result, src); } @@ -1263,8 +1262,8 @@ execute_program( GLcontext *ctx, { GLfloat a[4], result[4]; fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); - result[0] = (GLfloat)_mesa_cos(a[0]); - result[1] = (GLfloat)_mesa_sin(a[0]); + result[0] = (GLfloat) _mesa_cos(a[0]); + result[1] = (GLfloat) _mesa_sin(a[0]); result[2] = 0.0; /* undefined! */ result[3] = 0.0; /* undefined! */ store_vector4( inst, machine, result ); -- cgit v1.2.3 From 0552abce0ec54dbb3f8de2fb9665fd5e58451543 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 24 Jan 2007 14:13:02 -0700 Subject: only setup varying vars that will be used --- src/mesa/swrast/s_linetemp.h | 48 ++++++++++++++++++++++++-------------------- src/mesa/swrast/s_tritemp.h | 12 ++++++++--- 2 files changed, 35 insertions(+), 25 deletions(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/swrast/s_linetemp.h b/src/mesa/swrast/s_linetemp.h index 61c338ac69..b7b434771e 100644 --- a/src/mesa/swrast/s_linetemp.h +++ b/src/mesa/swrast/s_linetemp.h @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * Version: 6.5.3 * - * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -336,29 +336,33 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 ) #endif #ifdef INTERP_VARYING interpFlags |= SPAN_VARYING; - { /* XXX review this */ + { const GLfloat invLen = 1.0F / numPixels; + const GLbitfield inputsUsed = ctx->FragmentProgram._Current ? + ctx->FragmentProgram._Current->Base.InputsRead : 0x0; + const GLfloat invw0 = vert0->win[3]; + const GLfloat invw1 = vert1->win[3]; GLuint v; for (v = 0; v < MAX_VARYING; v++) { - const GLfloat invw0 = vert0->win[3]; - const GLfloat invw1 = vert1->win[3]; - GLfloat ds, dt, dr, dq; - span.var[v][0] = invw0 * vert0->varying[v][0]; - span.var[v][1] = invw0 * vert0->varying[v][1]; - span.var[v][2] = invw0 * vert0->varying[v][2]; - span.var[v][3] = invw0 * vert0->varying[v][3]; - ds = (invw1 * vert1->varying[v][0]) - span.var[v][0]; - dt = (invw1 * vert1->varying[v][1]) - span.var[v][1]; - dr = (invw1 * vert1->varying[v][2]) - span.var[v][2]; - dq = (invw1 * vert1->varying[v][3]) - span.var[v][3]; - span.varStepX[v][0] = ds * invLen; - span.varStepX[v][1] = dt * invLen; - span.varStepX[v][2] = dr * invLen; - span.varStepX[v][3] = dq * invLen; - span.varStepY[v][0] = 0.0F; - span.varStepY[v][1] = 0.0F; - span.varStepY[v][2] = 0.0F; - span.varStepY[v][3] = 0.0F; + if (inputsUsed & FRAG_BIT_VAR(v)) { + GLfloat ds, dt, dr, dq; + span.var[v][0] = invw0 * vert0->varying[v][0]; + span.var[v][1] = invw0 * vert0->varying[v][1]; + span.var[v][2] = invw0 * vert0->varying[v][2]; + span.var[v][3] = invw0 * vert0->varying[v][3]; + ds = (invw1 * vert1->varying[v][0]) - span.var[v][0]; + dt = (invw1 * vert1->varying[v][1]) - span.var[v][1]; + dr = (invw1 * vert1->varying[v][2]) - span.var[v][2]; + dq = (invw1 * vert1->varying[v][3]) - span.var[v][3]; + span.varStepX[v][0] = ds * invLen; + span.varStepX[v][1] = dt * invLen; + span.varStepX[v][2] = dr * invLen; + span.varStepX[v][3] = dq * invLen; + span.varStepY[v][0] = 0.0F; + span.varStepY[v][1] = 0.0F; + span.varStepY[v][2] = 0.0F; + span.varStepY[v][3] = 0.0F; + } } } #endif diff --git a/src/mesa/swrast/s_tritemp.h b/src/mesa/swrast/s_tritemp.h index c85379b4b1..6ff52b5e4a 100644 --- a/src/mesa/swrast/s_tritemp.h +++ b/src/mesa/swrast/s_tritemp.h @@ -144,13 +144,15 @@ #ifdef INTERP_VARYING -/* XXX need a varyingEnabled[] check */ + #define VARYING_LOOP(CODE) \ { \ GLuint iv, ic; \ for (iv = 0; iv < MAX_VARYING; iv++) { \ - for (ic = 0; ic < 4; ic++) { \ - CODE \ + if (inputsUsed & FRAG_BIT_VAR(iv)) { \ + for (ic = 0; ic < 4; ic++) { \ + CODE \ + } \ } \ } \ } @@ -216,6 +218,10 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, const GLint snapMask = ~((FIXED_ONE / (1 << SUB_PIXEL_BITS)) - 1); /* for x/y coord snapping */ #endif GLinterp vMin_fx, vMin_fy, vMid_fx, vMid_fy, vMax_fx, vMax_fy; +#ifdef INTERP_VARYING + const GLbitfield inputsUsed = ctx->FragmentProgram._Current ? + ctx->FragmentProgram._Current->Base.InputsRead : 0x0; +#endif SWspan span; -- cgit v1.2.3 From ccea3ff8a9eae16d2ca11b9cedef1318cffe3fb4 Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 24 Jan 2007 14:13:36 -0700 Subject: fix varying interpolation --- src/mesa/swrast/s_lines.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/swrast/s_lines.c b/src/mesa/swrast/s_lines.c index ff507249b0..7b2a52b4ff 100644 --- a/src/mesa/swrast/s_lines.c +++ b/src/mesa/swrast/s_lines.c @@ -198,6 +198,7 @@ draw_wide_line( GLcontext *ctx, SWspan *span, GLboolean xMajor ) #define INTERP_Z #define INTERP_FOG #define INTERP_MULTITEX +#define INTERP_VARYING #define RENDER_SPAN(span) \ if (ctx->Line.StippleFlag) { \ span.arrayMask |= SPAN_MASK; \ @@ -298,10 +299,12 @@ _swrast_choose_line( GLcontext *ctx ) _swrast_choose_aa_line_function(ctx); ASSERT(swrast->Line); } - else if (ctx->Texture._EnabledCoordUnits) { + else if (ctx->Texture._EnabledCoordUnits + || ctx->FragmentProgram._Current) { /* textured lines */ if (ctx->Texture._EnabledCoordUnits > 0x1 - || NEED_SECONDARY_COLOR(ctx)) { + || NEED_SECONDARY_COLOR(ctx) + || ctx->FragmentProgram._Current) { /* multi-texture and/or separate specular color */ USE(multitextured_line); } -- cgit v1.2.3 From 5ef553da9a0dc9f6d7f01b967082c24849ee4abf Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 25 Jan 2007 10:51:53 -0700 Subject: new comments, ideas --- src/mesa/swrast/s_context.h | 43 ++++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 21 deletions(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/swrast/s_context.h b/src/mesa/swrast/s_context.h index f784e18cd4..c9f6ec6bb8 100644 --- a/src/mesa/swrast/s_context.h +++ b/src/mesa/swrast/s_context.h @@ -86,11 +86,12 @@ struct arrays2 { #endif + /** * \sw_span_arrays * \brief Arrays of fragment values. * - * These will either be computed from the x/xStep values above or + * These will either be computed from the span x/xStep values or * filled in by glDraw/CopyPixels, etc. * These arrays are separated out of sw_span to conserve memory. */ @@ -114,15 +115,25 @@ typedef struct sw_span_arrays { GLchan (*rgba)[4]; GLchan (*spec)[4]; - GLuint index[MAX_WIDTH]; - GLint x[MAX_WIDTH]; /**< X/Y used for point/line rendering only */ - GLint y[MAX_WIDTH]; /**< X/Y used for point/line rendering only */ - GLuint z[MAX_WIDTH]; +#if 0 + /* XXX rearrange and unify these arrays to so that we can + * index all fragment inputs with the FRAG_ATTRIB_* values: + */ + GLfloat attribs[FRAG_ATTRIB_MAX][MAX_WIDTH][4]; + /*OR*/ + typedef GLfloat (*array4f)[4]; + array4f attribs[FRAG_ATTRIB_MAX]; +#endif + + GLint x[MAX_WIDTH]; /**< fragment X coords */ + GLint y[MAX_WIDTH]; /**< fragment Y coords */ + GLuint z[MAX_WIDTH]; /**< fragment Z coords */ + GLuint index[MAX_WIDTH]; /**< Color indexes */ GLfloat fog[MAX_WIDTH]; GLfloat texcoords[MAX_TEXTURE_COORD_UNITS][MAX_WIDTH][4]; GLfloat lambda[MAX_TEXTURE_COORD_UNITS][MAX_WIDTH]; - GLfloat coverage[MAX_WIDTH]; - GLfloat varying[MAX_WIDTH][MAX_VARYING][4]; + GLfloat coverage[MAX_WIDTH]; /**< Fragment coverage for AA/smoothing */ + GLfloat varying[MAX_VARYING][MAX_WIDTH][4]; /**< For shaders */ /** This mask indicates which fragments are alive or culled */ GLubyte mask[MAX_WIDTH]; @@ -130,21 +141,11 @@ typedef struct sw_span_arrays { /** - * \SWspan - * \brief Contains data for either a horizontal line or a set of - * pixels that are passed through a pipeline of functions before being - * drawn. - * - * The sw_span structure describes the colors, Z, fogcoord, texcoords, + * The SWspan structure describes the colors, Z, fogcoord, texcoords, * etc for either a horizontal run or an array of independent pixels. * We can either specify a base/step to indicate interpolated values, or - * fill in arrays of values. The interpMask and arrayMask bitfields - * indicate which are active. - * - * With this structure it's easy to hand-off span rasterization to - * subroutines instead of doing it all inline in the triangle functions - * like we used to do. - * It also cleans up the local variable namespace a great deal. + * fill in explicit arrays of values. The interpMask and arrayMask bitfields + * indicate which attributes are active interpolants or arrays, respectively. * * It would be interesting to experiment with multiprocessor rasterization * with this structure. The triangle rasterizer could simply emit a @@ -225,7 +226,7 @@ typedef struct sw_span { /** * We store the arrays of fragment values in a separate struct so * that we can allocate sw_span structs on the stack without using - * a lot of memory. The span_arrays struct is about 400KB while the + * a lot of memory. The span_arrays struct is about 1.4MB while the * sw_span struct is only about 512 bytes. */ SWspanarrays *array; -- cgit v1.2.3 From ff13f0ea4d5e88ac86bf5d97373ca419ad4226e5 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 25 Jan 2007 10:52:48 -0700 Subject: fixes, clean-ups, transpose span->varying array indexing --- src/mesa/swrast/s_fragprog.c | 50 +++++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 21 deletions(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c index ed82460669..74250b3592 100644 --- a/src/mesa/swrast/s_fragprog.c +++ b/src/mesa/swrast/s_fragprog.c @@ -152,6 +152,7 @@ get_register_pointer( GLcontext *ctx, const struct fp_machine *machine, const struct gl_fragment_program *program ) { + /* XXX relative addressing... */ switch (source->File) { case PROGRAM_TEMPORARY: ASSERT(source->Index < MAX_PROGRAM_TEMPS); @@ -547,7 +548,7 @@ init_machine_deriv( GLcontext *ctx, } /* Add derivatives */ - if (program->Base.InputsRead & (1 << FRAG_ATTRIB_WPOS)) { + if (program->Base.InputsRead & FRAG_BIT_WPOS) { GLfloat *wpos = (GLfloat*) machine->Inputs[FRAG_ATTRIB_WPOS]; if (xOrY == 'X') { wpos[0] += 1.0F; @@ -562,7 +563,7 @@ init_machine_deriv( GLcontext *ctx, wpos[3] += span->dwdy; } } - if (program->Base.InputsRead & (1 << FRAG_ATTRIB_COL0)) { + if (program->Base.InputsRead & FRAG_BIT_COL0) { GLfloat *col0 = (GLfloat*) machine->Inputs[FRAG_ATTRIB_COL0]; if (xOrY == 'X') { col0[0] += span->drdx * (1.0F / CHAN_MAXF); @@ -577,7 +578,7 @@ init_machine_deriv( GLcontext *ctx, col0[3] += span->dady * (1.0F / CHAN_MAXF); } } - if (program->Base.InputsRead & (1 << FRAG_ATTRIB_COL1)) { + if (program->Base.InputsRead & FRAG_BIT_COL1) { GLfloat *col1 = (GLfloat*) machine->Inputs[FRAG_ATTRIB_COL1]; if (xOrY == 'X') { col1[0] += span->dsrdx * (1.0F / CHAN_MAXF); @@ -592,7 +593,7 @@ init_machine_deriv( GLcontext *ctx, col1[3] += 0.0; /*XXX fix */ } } - if (program->Base.InputsRead & (1 << FRAG_ATTRIB_FOGC)) { + if (program->Base.InputsRead & FRAG_BIT_FOGC) { GLfloat *fogc = (GLfloat*) machine->Inputs[FRAG_ATTRIB_FOGC]; if (xOrY == 'X') { fogc[0] += span->dfogdx; @@ -602,7 +603,7 @@ init_machine_deriv( GLcontext *ctx, } } for (u = 0; u < ctx->Const.MaxTextureCoordUnits; u++) { - if (program->Base.InputsRead & (1 << (FRAG_ATTRIB_TEX0 + u))) { + if (program->Base.InputsRead & FRAG_BIT_TEX(u)) { GLfloat *tex = (GLfloat*) machine->Inputs[FRAG_ATTRIB_TEX0 + u]; /* XXX perspective-correct interpolation */ if (xOrY == 'X') { @@ -621,13 +622,20 @@ init_machine_deriv( GLcontext *ctx, } for (v = 0; v < ctx->Const.MaxVarying; v++) { - if (program->Base.InputsRead & (1 << (FRAG_ATTRIB_VAR0 + v))) { + if (program->Base.InputsRead & FRAG_BIT_VAR(v)) { GLfloat *var = (GLfloat*) machine->Inputs[FRAG_ATTRIB_VAR0 + v]; - /* XXXX finish this */ - var[0] += span->varStepX[v][0]; - var[1] += span->varStepX[v][1]; - var[2] += span->varStepX[v][2]; - var[3] += span->varStepX[v][3]; + if (xOrY == 'X') { + var[0] += span->varStepX[v][0]; + var[1] += span->varStepX[v][1]; + var[2] += span->varStepX[v][2]; + var[3] += span->varStepX[v][3]; + } + else { + var[0] += span->varStepY[v][0]; + var[1] += span->varStepY[v][1]; + var[2] += span->varStepY[v][2]; + var[3] += span->varStepY[v][3]; + } } } @@ -1640,7 +1648,7 @@ init_machine( GLcontext *ctx, struct fp_machine *machine, } /* Load input registers */ - if (inputsRead & (1 << FRAG_ATTRIB_WPOS)) { + if (inputsRead & FRAG_BIT_WPOS) { GLfloat *wpos = machine->Inputs[FRAG_ATTRIB_WPOS]; ASSERT(span->arrayMask & SPAN_Z); if (span->arrayMask & SPAN_XY) { @@ -1654,17 +1662,17 @@ init_machine( GLcontext *ctx, struct fp_machine *machine, wpos[2] = (GLfloat) span->array->z[col] / ctx->DrawBuffer->_DepthMaxF; wpos[3] = span->w + col * span->dwdx; } - if (inputsRead & (1 << FRAG_ATTRIB_COL0)) { + if (inputsRead & FRAG_BIT_COL0) { ASSERT(span->arrayMask & SPAN_RGBA); COPY_4V(machine->Inputs[FRAG_ATTRIB_COL0], span->array->color.sz4.rgba[col]); } - if (inputsRead & (1 << FRAG_ATTRIB_COL1)) { + if (inputsRead & FRAG_BIT_COL1) { ASSERT(span->arrayMask & SPAN_SPEC); COPY_4V(machine->Inputs[FRAG_ATTRIB_COL1], span->array->color.sz4.spec[col]); } - if (inputsRead & (1 << FRAG_ATTRIB_FOGC)) { + if (inputsRead & FRAG_BIT_FOGC) { GLfloat *fogc = machine->Inputs[FRAG_ATTRIB_FOGC]; ASSERT(span->arrayMask & SPAN_FOG); fogc[0] = span->array->fog[col]; @@ -1673,7 +1681,7 @@ init_machine( GLcontext *ctx, struct fp_machine *machine, fogc[3] = 0.0F; } for (u = 0; u < ctx->Const.MaxTextureCoordUnits; u++) { - if (inputsRead & (1 << (FRAG_ATTRIB_TEX0 + u))) { + if (inputsRead & FRAG_BIT_TEX(u)) { GLfloat *tex = machine->Inputs[FRAG_ATTRIB_TEX0 + u]; /*ASSERT(ctx->Texture._EnabledCoordUnits & (1 << u));*/ COPY_4V(tex, span->array->texcoords[u][col]); @@ -1685,15 +1693,15 @@ init_machine( GLcontext *ctx, struct fp_machine *machine, } } for (v = 0; v < ctx->Const.MaxVarying; v++) { - if (inputsRead & (1 << (FRAG_ATTRIB_VAR0 + v))) { + if (inputsRead & FRAG_BIT_VAR(v)) { #if 0 printf("Frag Var %d at y=%d: %f %f %f\n", v, col, - span->array->varying[col][v][0], - span->array->varying[col][v][1], - span->array->varying[col][v][2]); + span->array->varying[v][col][0], + span->array->varying[v][col][1], + span->array->varying[v][col][2]); #endif COPY_4V(machine->Inputs[FRAG_ATTRIB_VAR0 + v], - span->array->varying[col][v]); + span->array->varying[v][col]); } } -- cgit v1.2.3 From ea8b68e0f7e7a4025ce662d36380157273ce10a3 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 25 Jan 2007 10:54:52 -0700 Subject: asst fixes, tranpose span->varying array indexes --- src/mesa/swrast/s_span.c | 92 ++++++++++++++++++++++++++++-------------------- 1 file changed, 54 insertions(+), 38 deletions(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c index 536ac30033..d97c1672c2 100644 --- a/src/mesa/swrast/s_span.c +++ b/src/mesa/swrast/s_span.c @@ -822,26 +822,29 @@ interpolate_texcoords(GLcontext *ctx, SWspan *span) static INLINE void interpolate_varying(GLcontext *ctx, SWspan *span) { - GLuint i, j; + GLuint var; + const GLbitfield inputsUsed = ctx->FragmentProgram._Current->Base.InputsRead; ASSERT(span->interpMask & SPAN_VARYING); ASSERT(!(span->arrayMask & SPAN_VARYING)); span->arrayMask |= SPAN_VARYING; - for (i = 0; i < MAX_VARYING; i++) { - for (j = 0; j < 4; j++) { - const GLfloat dvdx = span->varStepX[i][j]; - GLfloat v = span->var[i][j]; - const GLfloat dwdx = span->dwdx; - GLfloat w = span->w; - GLuint k; - - for (k = 0; k < span->end; k++) { - GLfloat invW = 1.0f / w; - span->array->varying[k][i][j] = v * invW; - v += dvdx; - w += dwdx; + for (var = 0; var < MAX_VARYING; var++) { + if (inputsUsed & FRAG_BIT_VAR(var)) { + GLuint j; + for (j = 0; j < 4; j++) { + const GLfloat dvdx = span->varStepX[var][j]; + GLfloat v = span->var[var][j]; + const GLfloat dwdx = span->dwdx; + GLfloat w = span->w; + GLuint k; + for (k = 0; k < span->end; k++) { + GLfloat invW = 1.0f / w; + span->array->varying[var][k][j] = v * invW; + v += dvdx; + w += dwdx; + } } } } @@ -852,25 +855,37 @@ interpolate_varying(GLcontext *ctx, SWspan *span) * Apply the current polygon stipple pattern to a span of pixels. */ static INLINE void -stipple_polygon_span( GLcontext *ctx, SWspan *span ) +stipple_polygon_span(GLcontext *ctx, SWspan *span) { - const GLuint highbit = 0x80000000; - const GLuint stipple = ctx->PolygonStipple[span->y % 32]; GLubyte *mask = span->array->mask; - GLuint i, m; ASSERT(ctx->Polygon.StippleFlag); - ASSERT((span->arrayMask & SPAN_XY) == 0); - - m = highbit >> (GLuint) (span->x % 32); - for (i = 0; i < span->end; i++) { - if ((m & stipple) == 0) { - mask[i] = 0; + if (span->arrayMask & SPAN_XY) { + /* arrays of x/y pixel coords */ + GLuint i; + for (i = 0; i < span->end; i++) { + const GLint col = span->array->x[i] % 32; + const GLint row = span->array->y[i] % 32; + const GLuint stipple = ctx->PolygonStipple[row]; + if (((1 << col) & stipple) == 0) { + mask[i] = 0; + } } - m = m >> 1; - if (m == 0) { - m = highbit; + } + else { + /* horizontal span of pixels */ + const GLuint highBit = 1 << 31; + const GLuint stipple = ctx->PolygonStipple[span->y % 32]; + GLuint i, m = highBit >> (GLuint) (span->x % 32); + for (i = 0; i < span->end; i++) { + if ((m & stipple) == 0) { + mask[i] = 0; + } + m = m >> 1; + if (m == 0) { + m = highBit; + } } } span->writeAll = GL_FALSE; @@ -1295,7 +1310,7 @@ clamp_colors(SWspan *span) * Convert the span's color arrays to the given type. */ static INLINE void -convert_color_type(GLcontext *ctx, SWspan *span, GLenum newType) +convert_color_type(SWspan *span, GLenum newType) { GLvoid *src, *dst; if (span->array->ChanType == GL_UNSIGNED_BYTE) { @@ -1598,7 +1613,7 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span) if (numDrawBuffers > 0) { if (fb->_ColorDrawBuffers[output][0]->DataType != span->array->ChanType) { - convert_color_type(ctx, span, + convert_color_type(span, fb->_ColorDrawBuffers[output][0]->DataType); } } @@ -1656,9 +1671,9 @@ end: /** - * Read RGBA pixels from frame buffer. Clipping will be done to prevent + * Read RGBA pixels from a renderbuffer. Clipping will be done to prevent * reading ouside the buffer's boundaries. - * \param type datatype for returned colors + * \param dstType datatype for returned colors * \param rgba the returned colors */ void @@ -1723,7 +1738,7 @@ _swrast_read_rgba_span( GLcontext *ctx, struct gl_renderbuffer *rb, /** - * Read CI pixels from frame buffer. Clipping will be done to prevent + * Read CI pixels from a renderbuffer. Clipping will be done to prevent * reading ouside the buffer's boundaries. */ void @@ -1805,7 +1820,8 @@ _swrast_get_values(GLcontext *ctx, struct gl_renderbuffer *rb, GLuint i, inCount = 0, inStart = 0; for (i = 0; i < count; i++) { - if (x[i] >= 0 && y[i] >= 0 && x[i] < rb->Width && y[i] < rb->Height) { + if (x[i] >= 0 && y[i] >= 0 && + x[i] < (GLint) rb->Width && y[i] < (GLint) rb->Height) { /* inside */ if (inCount == 0) inStart = i; @@ -1839,13 +1855,13 @@ _swrast_put_row(GLcontext *ctx, struct gl_renderbuffer *rb, { GLint skip = 0; - if (y < 0 || y >= rb->Height) + if (y < 0 || y >= (GLint) rb->Height) return; /* above or below */ - if (x + (GLint) count <= 0 || x >= rb->Width) + if (x + (GLint) count <= 0 || x >= (GLint) rb->Width) return; /* entirely left or right */ - if (x + count > rb->Width) { + if ((GLint) (x + count) > (GLint) rb->Width) { /* right clip */ GLint clip = x + count - rb->Width; count -= clip; @@ -1874,10 +1890,10 @@ _swrast_get_row(GLcontext *ctx, struct gl_renderbuffer *rb, { GLint skip = 0; - if (y < 0 || y >= rb->Height) + if (y < 0 || y >= (GLint) rb->Height) return; /* above or below */ - if (x + (GLint) count <= 0 || x >= rb->Width) + if (x + (GLint) count <= 0 || x >= (GLint) rb->Width) return; /* entirely left or right */ if (x + count > rb->Width) { -- cgit v1.2.3 From 7aece10039ad4786d7f85d61ec8614b9f287ea23 Mon Sep 17 00:00:00 2001 From: Brian Date: Sun, 28 Jan 2007 19:01:35 -0700 Subject: noise functions --- src/mesa/shader/prog_instruction.c | 4 + src/mesa/shader/prog_instruction.h | 4 + .../shader/slang/library/slang_common_builtin.gc | 162 ++++++++++----------- .../shader/slang/library/slang_common_builtin_gc.h | 114 ++++++++------- src/mesa/shader/slang/slang_codegen.c | 7 + src/mesa/shader/slang/slang_emit.c | 9 ++ src/mesa/shader/slang/slang_ir.h | 4 + src/mesa/swrast/s_fragprog.c | 45 ++++++ src/mesa/tnl/t_vb_arbprogram.c | 4 + 9 files changed, 214 insertions(+), 139 deletions(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/shader/prog_instruction.c b/src/mesa/shader/prog_instruction.c index 3de71b8b5d..0523f42125 100644 --- a/src/mesa/shader/prog_instruction.c +++ b/src/mesa/shader/prog_instruction.c @@ -150,6 +150,10 @@ static const struct instruction_info InstInfo[MAX_OPCODE] = { { OPCODE_MIN, "MIN", 2 }, { OPCODE_MOV, "MOV", 1 }, { OPCODE_MUL, "MUL", 2 }, + { OPCODE_NOISE1, "NOISE1", 1 }, + { OPCODE_NOISE2, "NOISE2", 1 }, + { OPCODE_NOISE3, "NOISE3", 1 }, + { OPCODE_NOISE4, "NOISE4", 1 }, { OPCODE_PK2H, "PK2H", 1 }, { OPCODE_PK2US, "PK2US", 1 }, { OPCODE_PK4B, "PK4B", 1 }, diff --git a/src/mesa/shader/prog_instruction.h b/src/mesa/shader/prog_instruction.h index 83e8d7080b..3e88b4e627 100644 --- a/src/mesa/shader/prog_instruction.h +++ b/src/mesa/shader/prog_instruction.h @@ -172,6 +172,10 @@ typedef enum prog_opcode { OPCODE_MIN, /* X X X X X */ OPCODE_MOV, /* X X X X X */ OPCODE_MUL, /* X X X X X */ + OPCODE_NOISE1, /* X */ + OPCODE_NOISE2, /* X */ + OPCODE_NOISE3, /* X */ + OPCODE_NOISE4, /* X */ OPCODE_PK2H, /* X */ OPCODE_PK2US, /* X */ OPCODE_PK4B, /* X */ diff --git a/src/mesa/shader/slang/library/slang_common_builtin.gc b/src/mesa/shader/slang/library/slang_common_builtin.gc index 8812a73416..e4a55846b8 100644 --- a/src/mesa/shader/slang/library/slang_common_builtin.gc +++ b/src/mesa/shader/slang/library/slang_common_builtin.gc @@ -1699,123 +1699,107 @@ vec4 shadow2DProj (sampler2DShadow sampler, vec4 coord) { // AUTHOR: Stefan Gustavson (stegu@itn.liu.se), Nov 26, 2005 // -float noise1 (float x) { - float a; - __asm float_noise1 a, x; - return a; +float noise1(const float x) +{ + __asm float_noise1 __retVal, x; } -float noise1 (vec2 x) { - float a; - __asm float_noise2 a, x; - return a; -} -float noise1 (vec3 x) { - float a; - __asm float_noise3 a, x; - return a; +float noise1(const vec2 x) +{ + __asm float_noise2 __retVal, x; } -float noise1 (vec4 x) { - float a; - __asm float_noise4 a, x; - return a; +float noise1(const vec3 x) +{ + __asm float_noise3 __retVal, x; } -vec2 noise2 (float x) { - return vec2 ( - noise1 (x), - noise1 (x + 19.34) - ); +float noise1(const vec4 x) +{ + __asm float_noise4 __retVal, x; } -vec2 noise2 (vec2 x) { - return vec2 ( - noise1 (x), - noise1 (x + vec2 (19.34, 7.66)) - ); +vec2 noise2(const float x) +{ + __retVal.x = noise1(x); + __retVal.y = noise1(x + 19.34); } -vec2 noise2 (vec3 x) { - return vec2 ( - noise1 (x), - noise1 (x + vec3 (19.34, 7.66, 3.23)) - ); +vec2 noise2(const vec2 x) +{ + __retVal.x = noise1(x); + __retVal.y = noise1(x + vec2(19.34, 7.66)); } -vec2 noise2 (vec4 x) { - return vec2 ( - noise1 (x), - noise1 (x + vec4 (19.34, 7.66, 3.23, 2.77)) - ); +vec2 noise2(const vec3 x) +{ + __retVal.x = noise1(x); + __retVal.y = noise1(x + vec3(19.34, 7.66, 3.23)); } -vec3 noise3 (float x) { - return vec3 ( - noise1 (x), - noise1 (x + 19.34), - noise1 (x + 5.47) - ); +vec2 noise2(const vec4 x) +{ + __retVal.x = noise1(x); + __retVal.y = noise1(x + vec4(19.34, 7.66, 3.23, 2.77)); } -vec3 noise3 (vec2 x) { - return vec3 ( - noise1 (x), - noise1 (x + vec2 (19.34, 7.66)), - noise1 (x + vec2 (5.47, 17.85)) - ); +vec3 noise3(const float x) +{ + __retVal.x = noise1(x); + __retVal.y = noise1(x + 19.34); + __retVal.z = noise1(x + 5.47); } -vec3 noise3 (vec3 x) { - return vec3 ( - noise1 (x), - noise1 (x + vec3 (19.34, 7.66, 3.23)), - noise1 (x + vec3 (5.47, 17.85, 11.04)) - ); +vec3 noise3(const vec2 x) +{ + __retVal.x = noise1(x); + __retVal.y = noise1(x + vec2(19.34, 7.66)); + __retVal.z = noise1(x + vec2(5.47, 17.85)); } -vec3 noise3 (vec4 x) { - return vec3 ( - noise1 (x), - noise1 (x + vec4 (19.34, 7.66, 3.23, 2.77)), - noise1 (x + vec4 (5.47, 17.85, 11.04, 13.19)) - ); +vec3 noise3(const vec3 x) +{ + __retVal.x = noise1(x); + __retVal.y = noise1(x + vec3(19.34, 7.66, 3.23)); + __retVal.z = noise1(x + vec3(5.47, 17.85, 11.04)); } -vec4 noise4 (float x) { - return vec4 ( - noise1 (x), - noise1 (x + 19.34), - noise1 (x + 5.47), - noise1 (x + 23.54) - ); +vec3 noise3(const vec4 x) +{ + __retVal.x = noise1(x); + __retVal.y = noise1(x + vec4(19.34, 7.66, 3.23, 2.77)); + __retVal.z = noise1(x + vec4(5.47, 17.85, 11.04, 13.19)); } -vec4 noise4 (vec2 x) { - return vec4 ( - noise1 (x), - noise1 (x + vec2 (19.34, 7.66)), - noise1 (x + vec2 (5.47, 17.85)), - noise1 (x + vec2 (23.54, 29.11)) - ); +vec4 noise4(const float x) +{ + __retVal.x = noise1(x); + __retVal.y = noise1(x + 19.34); + __retVal.z = noise1(x + 5.47); + __retVal.w = noise1(x + 23.54); } -vec4 noise4 (vec3 x) { - return vec4 ( - noise1 (x), - noise1 (x + vec3 (19.34, 7.66, 3.23)), - noise1 (x + vec3 (5.47, 17.85, 11.04)), - noise1 (x + vec3 (23.54, 29.11, 31.91)) - ); +vec4 noise4(const vec2 x) +{ + __retVal.x = noise1(x); + __retVal.y = noise1(x + vec2 (19.34, 7.66)); + __retVal.z = noise1(x + vec2 (5.47, 17.85)); + __retVal.w = noise1(x + vec2 (23.54, 29.11)); } -vec4 noise4 (vec4 x) { - return vec4 ( - noise1 (x), - noise1 (x + vec4 (19.34, 7.66, 3.23, 2.77)), - noise1 (x + vec4 (5.47, 17.85, 11.04, 13.19)), - noise1 (x + vec4 (23.54, 29.11, 31.91, 37.48)) - ); +vec4 noise4(const vec3 x) +{ + __retVal.x = noise1(x); + __retVal.y = noise1(x + vec3(19.34, 7.66, 3.23)); + __retVal.z = noise1(x + vec3(5.47, 17.85, 11.04)); + __retVal.w = noise1(x + vec3(23.54, 29.11, 31.91)); } +vec4 noise4(const vec4 x) +{ + __retVal.x = noise1(x); + __retVal.y = noise1(x + vec4(19.34, 7.66, 3.23, 2.77)); + __retVal.z = noise1(x + vec4(5.47, 17.85, 11.04, 13.19)); + __retVal.w = noise1(x + vec4(23.54, 29.11, 31.91, 37.48)); +} diff --git a/src/mesa/shader/slang/library/slang_common_builtin_gc.h b/src/mesa/shader/slang/library/slang_common_builtin_gc.h index 655efdda16..e64f401115 100644 --- a/src/mesa/shader/slang/library/slang_common_builtin_gc.h +++ b/src/mesa/shader/slang/library/slang_common_builtin_gc.h @@ -717,54 +717,68 @@ 100,0,0,0,1,8,58,115,104,97,100,111,119,50,68,0,18,115,97,109,112,108,101,114,0,0,58,118,101,99,51, 0,18,99,111,111,114,100,0,59,115,0,18,99,111,111,114,100,0,59,113,0,49,0,18,99,111,111,114,100,0, 59,116,0,18,99,111,111,114,100,0,59,113,0,49,0,18,99,111,111,114,100,0,59,112,0,18,99,111,111,114, -100,0,59,113,0,49,0,0,0,0,0,0,1,0,9,0,110,111,105,115,101,49,0,1,0,0,9,120,0,0,0,1,3,2,0,9,1,97,0, -0,0,4,102,108,111,97,116,95,110,111,105,115,101,49,0,18,97,0,0,18,120,0,0,0,8,18,97,0,0,0,1,0,9,0, -110,111,105,115,101,49,0,1,0,0,10,120,0,0,0,1,3,2,0,9,1,97,0,0,0,4,102,108,111,97,116,95,110,111, -105,115,101,50,0,18,97,0,0,18,120,0,0,0,8,18,97,0,0,0,1,0,9,0,110,111,105,115,101,49,0,1,0,0,11, -120,0,0,0,1,3,2,0,9,1,97,0,0,0,4,102,108,111,97,116,95,110,111,105,115,101,51,0,18,97,0,0,18,120,0, -0,0,8,18,97,0,0,0,1,0,9,0,110,111,105,115,101,49,0,1,0,0,12,120,0,0,0,1,3,2,0,9,1,97,0,0,0,4,102, -108,111,97,116,95,110,111,105,115,101,52,0,18,97,0,0,18,120,0,0,0,8,18,97,0,0,0,1,0,10,0,110,111, -105,115,101,50,0,1,0,0,9,120,0,0,0,1,8,58,118,101,99,50,0,58,110,111,105,115,101,49,0,18,120,0,0,0, -0,58,110,111,105,115,101,49,0,18,120,0,17,49,57,0,51,52,0,0,46,0,0,0,0,0,0,1,0,10,0,110,111,105, -115,101,50,0,1,0,0,10,120,0,0,0,1,8,58,118,101,99,50,0,58,110,111,105,115,101,49,0,18,120,0,0,0,0, -58,110,111,105,115,101,49,0,18,120,0,58,118,101,99,50,0,17,49,57,0,51,52,0,0,0,17,55,0,54,54,0,0,0, -0,46,0,0,0,0,0,0,1,0,10,0,110,111,105,115,101,50,0,1,0,0,11,120,0,0,0,1,8,58,118,101,99,50,0,58, -110,111,105,115,101,49,0,18,120,0,0,0,0,58,110,111,105,115,101,49,0,18,120,0,58,118,101,99,51,0,17, -49,57,0,51,52,0,0,0,17,55,0,54,54,0,0,0,17,51,0,50,51,0,0,0,0,46,0,0,0,0,0,0,1,0,10,0,110,111,105, -115,101,50,0,1,0,0,12,120,0,0,0,1,8,58,118,101,99,50,0,58,110,111,105,115,101,49,0,18,120,0,0,0,0, -58,110,111,105,115,101,49,0,18,120,0,58,118,101,99,52,0,17,49,57,0,51,52,0,0,0,17,55,0,54,54,0,0,0, -17,51,0,50,51,0,0,0,17,50,0,55,55,0,0,0,0,46,0,0,0,0,0,0,1,0,11,0,110,111,105,115,101,51,0,1,0,0,9, -120,0,0,0,1,8,58,118,101,99,51,0,58,110,111,105,115,101,49,0,18,120,0,0,0,0,58,110,111,105,115,101, -49,0,18,120,0,17,49,57,0,51,52,0,0,46,0,0,0,58,110,111,105,115,101,49,0,18,120,0,17,53,0,52,55,0,0, -46,0,0,0,0,0,0,1,0,11,0,110,111,105,115,101,51,0,1,0,0,10,120,0,0,0,1,8,58,118,101,99,51,0,58,110, -111,105,115,101,49,0,18,120,0,0,0,0,58,110,111,105,115,101,49,0,18,120,0,58,118,101,99,50,0,17,49, -57,0,51,52,0,0,0,17,55,0,54,54,0,0,0,0,46,0,0,0,58,110,111,105,115,101,49,0,18,120,0,58,118,101,99, -50,0,17,53,0,52,55,0,0,0,17,49,55,0,56,53,0,0,0,0,46,0,0,0,0,0,0,1,0,11,0,110,111,105,115,101,51,0, -1,0,0,11,120,0,0,0,1,8,58,118,101,99,51,0,58,110,111,105,115,101,49,0,18,120,0,0,0,0,58,110,111, -105,115,101,49,0,18,120,0,58,118,101,99,51,0,17,49,57,0,51,52,0,0,0,17,55,0,54,54,0,0,0,17,51,0,50, -51,0,0,0,0,46,0,0,0,58,110,111,105,115,101,49,0,18,120,0,58,118,101,99,51,0,17,53,0,52,55,0,0,0,17, -49,55,0,56,53,0,0,0,17,49,49,0,48,52,0,0,0,0,46,0,0,0,0,0,0,1,0,11,0,110,111,105,115,101,51,0,1,0, -0,12,120,0,0,0,1,8,58,118,101,99,51,0,58,110,111,105,115,101,49,0,18,120,0,0,0,0,58,110,111,105, -115,101,49,0,18,120,0,58,118,101,99,52,0,17,49,57,0,51,52,0,0,0,17,55,0,54,54,0,0,0,17,51,0,50,51, -0,0,0,17,50,0,55,55,0,0,0,0,46,0,0,0,58,110,111,105,115,101,49,0,18,120,0,58,118,101,99,52,0,17,53, -0,52,55,0,0,0,17,49,55,0,56,53,0,0,0,17,49,49,0,48,52,0,0,0,17,49,51,0,49,57,0,0,0,0,46,0,0,0,0,0, -0,1,0,12,0,110,111,105,115,101,52,0,1,0,0,9,120,0,0,0,1,8,58,118,101,99,52,0,58,110,111,105,115, -101,49,0,18,120,0,0,0,0,58,110,111,105,115,101,49,0,18,120,0,17,49,57,0,51,52,0,0,46,0,0,0,58,110, -111,105,115,101,49,0,18,120,0,17,53,0,52,55,0,0,46,0,0,0,58,110,111,105,115,101,49,0,18,120,0,17, -50,51,0,53,52,0,0,46,0,0,0,0,0,0,1,0,12,0,110,111,105,115,101,52,0,1,0,0,10,120,0,0,0,1,8,58,118, -101,99,52,0,58,110,111,105,115,101,49,0,18,120,0,0,0,0,58,110,111,105,115,101,49,0,18,120,0,58,118, -101,99,50,0,17,49,57,0,51,52,0,0,0,17,55,0,54,54,0,0,0,0,46,0,0,0,58,110,111,105,115,101,49,0,18, -120,0,58,118,101,99,50,0,17,53,0,52,55,0,0,0,17,49,55,0,56,53,0,0,0,0,46,0,0,0,58,110,111,105,115, -101,49,0,18,120,0,58,118,101,99,50,0,17,50,51,0,53,52,0,0,0,17,50,57,0,49,49,0,0,0,0,46,0,0,0,0,0, -0,1,0,12,0,110,111,105,115,101,52,0,1,0,0,11,120,0,0,0,1,8,58,118,101,99,52,0,58,110,111,105,115, -101,49,0,18,120,0,0,0,0,58,110,111,105,115,101,49,0,18,120,0,58,118,101,99,51,0,17,49,57,0,51,52,0, -0,0,17,55,0,54,54,0,0,0,17,51,0,50,51,0,0,0,0,46,0,0,0,58,110,111,105,115,101,49,0,18,120,0,58,118, -101,99,51,0,17,53,0,52,55,0,0,0,17,49,55,0,56,53,0,0,0,17,49,49,0,48,52,0,0,0,0,46,0,0,0,58,110, -111,105,115,101,49,0,18,120,0,58,118,101,99,51,0,17,50,51,0,53,52,0,0,0,17,50,57,0,49,49,0,0,0,17, -51,49,0,57,49,0,0,0,0,46,0,0,0,0,0,0,1,0,12,0,110,111,105,115,101,52,0,1,0,0,12,120,0,0,0,1,8,58, -118,101,99,52,0,58,110,111,105,115,101,49,0,18,120,0,0,0,0,58,110,111,105,115,101,49,0,18,120,0,58, +100,0,59,113,0,49,0,0,0,0,0,0,1,0,9,0,110,111,105,115,101,49,0,1,1,0,9,120,0,0,0,1,4,102,108,111, +97,116,95,110,111,105,115,101,49,0,18,95,95,114,101,116,86,97,108,0,0,18,120,0,0,0,0,1,0,9,0,110, +111,105,115,101,49,0,1,1,0,10,120,0,0,0,1,4,102,108,111,97,116,95,110,111,105,115,101,50,0,18,95, +95,114,101,116,86,97,108,0,0,18,120,0,0,0,0,1,0,9,0,110,111,105,115,101,49,0,1,1,0,11,120,0,0,0,1, +4,102,108,111,97,116,95,110,111,105,115,101,51,0,18,95,95,114,101,116,86,97,108,0,0,18,120,0,0,0,0, +1,0,9,0,110,111,105,115,101,49,0,1,1,0,12,120,0,0,0,1,4,102,108,111,97,116,95,110,111,105,115,101, +52,0,18,95,95,114,101,116,86,97,108,0,0,18,120,0,0,0,0,1,0,10,0,110,111,105,115,101,50,0,1,1,0,9, +120,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,0,58,110,111,105,115,101,49,0,18,120,0,0,0, +20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,58,110,111,105,115,101,49,0,18,120,0,17,49,57,0, +51,52,0,0,46,0,0,20,0,0,1,0,10,0,110,111,105,115,101,50,0,1,1,0,10,120,0,0,0,1,9,18,95,95,114,101, +116,86,97,108,0,59,120,0,58,110,111,105,115,101,49,0,18,120,0,0,0,20,0,9,18,95,95,114,101,116,86, +97,108,0,59,121,0,58,110,111,105,115,101,49,0,18,120,0,58,118,101,99,50,0,17,49,57,0,51,52,0,0,0, +17,55,0,54,54,0,0,0,0,46,0,0,20,0,0,1,0,10,0,110,111,105,115,101,50,0,1,1,0,11,120,0,0,0,1,9,18,95, +95,114,101,116,86,97,108,0,59,120,0,58,110,111,105,115,101,49,0,18,120,0,0,0,20,0,9,18,95,95,114, +101,116,86,97,108,0,59,121,0,58,110,111,105,115,101,49,0,18,120,0,58,118,101,99,51,0,17,49,57,0,51, +52,0,0,0,17,55,0,54,54,0,0,0,17,51,0,50,51,0,0,0,0,46,0,0,20,0,0,1,0,10,0,110,111,105,115,101,50,0, +1,1,0,12,120,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,0,58,110,111,105,115,101,49,0,18, +120,0,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,58,110,111,105,115,101,49,0,18,120,0,58, 118,101,99,52,0,17,49,57,0,51,52,0,0,0,17,55,0,54,54,0,0,0,17,51,0,50,51,0,0,0,17,50,0,55,55,0,0,0, -0,46,0,0,0,58,110,111,105,115,101,49,0,18,120,0,58,118,101,99,52,0,17,53,0,52,55,0,0,0,17,49,55,0, -56,53,0,0,0,17,49,49,0,48,52,0,0,0,17,49,51,0,49,57,0,0,0,0,46,0,0,0,58,110,111,105,115,101,49,0, -18,120,0,58,118,101,99,52,0,17,50,51,0,53,52,0,0,0,17,50,57,0,49,49,0,0,0,17,51,49,0,57,49,0,0,0, -17,51,55,0,52,56,0,0,0,0,46,0,0,0,0,0,0,0 +0,46,0,0,20,0,0,1,0,11,0,110,111,105,115,101,51,0,1,1,0,9,120,0,0,0,1,9,18,95,95,114,101,116,86,97, +108,0,59,120,0,58,110,111,105,115,101,49,0,18,120,0,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59, +121,0,58,110,111,105,115,101,49,0,18,120,0,17,49,57,0,51,52,0,0,46,0,0,20,0,9,18,95,95,114,101,116, +86,97,108,0,59,122,0,58,110,111,105,115,101,49,0,18,120,0,17,53,0,52,55,0,0,46,0,0,20,0,0,1,0,11,0, +110,111,105,115,101,51,0,1,1,0,10,120,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,0,58,110, +111,105,115,101,49,0,18,120,0,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,58,110,111,105, +115,101,49,0,18,120,0,58,118,101,99,50,0,17,49,57,0,51,52,0,0,0,17,55,0,54,54,0,0,0,0,46,0,0,20,0, +9,18,95,95,114,101,116,86,97,108,0,59,122,0,58,110,111,105,115,101,49,0,18,120,0,58,118,101,99,50, +0,17,53,0,52,55,0,0,0,17,49,55,0,56,53,0,0,0,0,46,0,0,20,0,0,1,0,11,0,110,111,105,115,101,51,0,1,1, +0,11,120,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,0,58,110,111,105,115,101,49,0,18,120,0, +0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,58,110,111,105,115,101,49,0,18,120,0,58,118, +101,99,51,0,17,49,57,0,51,52,0,0,0,17,55,0,54,54,0,0,0,17,51,0,50,51,0,0,0,0,46,0,0,20,0,9,18,95, +95,114,101,116,86,97,108,0,59,122,0,58,110,111,105,115,101,49,0,18,120,0,58,118,101,99,51,0,17,53, +0,52,55,0,0,0,17,49,55,0,56,53,0,0,0,17,49,49,0,48,52,0,0,0,0,46,0,0,20,0,0,1,0,11,0,110,111,105, +115,101,51,0,1,1,0,12,120,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,0,58,110,111,105,115, +101,49,0,18,120,0,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,58,110,111,105,115,101,49,0, +18,120,0,58,118,101,99,52,0,17,49,57,0,51,52,0,0,0,17,55,0,54,54,0,0,0,17,51,0,50,51,0,0,0,17,50,0, +55,55,0,0,0,0,46,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,122,0,58,110,111,105,115,101,49,0, +18,120,0,58,118,101,99,52,0,17,53,0,52,55,0,0,0,17,49,55,0,56,53,0,0,0,17,49,49,0,48,52,0,0,0,17, +49,51,0,49,57,0,0,0,0,46,0,0,20,0,0,1,0,12,0,110,111,105,115,101,52,0,1,1,0,9,120,0,0,0,1,9,18,95, +95,114,101,116,86,97,108,0,59,120,0,58,110,111,105,115,101,49,0,18,120,0,0,0,20,0,9,18,95,95,114, +101,116,86,97,108,0,59,121,0,58,110,111,105,115,101,49,0,18,120,0,17,49,57,0,51,52,0,0,46,0,0,20,0, +9,18,95,95,114,101,116,86,97,108,0,59,122,0,58,110,111,105,115,101,49,0,18,120,0,17,53,0,52,55,0,0, +46,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,119,0,58,110,111,105,115,101,49,0,18,120,0,17,50, +51,0,53,52,0,0,46,0,0,20,0,0,1,0,12,0,110,111,105,115,101,52,0,1,1,0,10,120,0,0,0,1,9,18,95,95,114, +101,116,86,97,108,0,59,120,0,58,110,111,105,115,101,49,0,18,120,0,0,0,20,0,9,18,95,95,114,101,116, +86,97,108,0,59,121,0,58,110,111,105,115,101,49,0,18,120,0,58,118,101,99,50,0,17,49,57,0,51,52,0,0, +0,17,55,0,54,54,0,0,0,0,46,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,122,0,58,110,111,105,115, +101,49,0,18,120,0,58,118,101,99,50,0,17,53,0,52,55,0,0,0,17,49,55,0,56,53,0,0,0,0,46,0,0,20,0,9,18, +95,95,114,101,116,86,97,108,0,59,119,0,58,110,111,105,115,101,49,0,18,120,0,58,118,101,99,50,0,17, +50,51,0,53,52,0,0,0,17,50,57,0,49,49,0,0,0,0,46,0,0,20,0,0,1,0,12,0,110,111,105,115,101,52,0,1,1,0, +11,120,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,0,58,110,111,105,115,101,49,0,18,120,0,0, +0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,58,110,111,105,115,101,49,0,18,120,0,58,118,101, +99,51,0,17,49,57,0,51,52,0,0,0,17,55,0,54,54,0,0,0,17,51,0,50,51,0,0,0,0,46,0,0,20,0,9,18,95,95, +114,101,116,86,97,108,0,59,122,0,58,110,111,105,115,101,49,0,18,120,0,58,118,101,99,51,0,17,53,0, +52,55,0,0,0,17,49,55,0,56,53,0,0,0,17,49,49,0,48,52,0,0,0,0,46,0,0,20,0,9,18,95,95,114,101,116,86, +97,108,0,59,119,0,58,110,111,105,115,101,49,0,18,120,0,58,118,101,99,51,0,17,50,51,0,53,52,0,0,0, +17,50,57,0,49,49,0,0,0,17,51,49,0,57,49,0,0,0,0,46,0,0,20,0,0,1,0,12,0,110,111,105,115,101,52,0,1, +1,0,12,120,0,0,0,1,9,18,95,95,114,101,116,86,97,108,0,59,120,0,58,110,111,105,115,101,49,0,18,120, +0,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,121,0,58,110,111,105,115,101,49,0,18,120,0,58,118, +101,99,52,0,17,49,57,0,51,52,0,0,0,17,55,0,54,54,0,0,0,17,51,0,50,51,0,0,0,17,50,0,55,55,0,0,0,0, +46,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,122,0,58,110,111,105,115,101,49,0,18,120,0,58, +118,101,99,52,0,17,53,0,52,55,0,0,0,17,49,55,0,56,53,0,0,0,17,49,49,0,48,52,0,0,0,17,49,51,0,49,57, +0,0,0,0,46,0,0,20,0,9,18,95,95,114,101,116,86,97,108,0,59,119,0,58,110,111,105,115,101,49,0,18,120, +0,58,118,101,99,52,0,17,50,51,0,53,52,0,0,0,17,50,57,0,49,49,0,0,0,17,51,49,0,57,49,0,0,0,17,51,55, +0,52,56,0,0,0,0,46,0,0,20,0,0,0 diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index 6ae307d09a..9b932ca71b 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -494,6 +494,11 @@ static slang_asm_info AsmInfo[] = { { "float_rcp", IR_RCP, 1, 1 }, { "float_sine", IR_SIN, 1, 1 }, { "float_cosine", IR_COS, 1, 1 }, + { "float_noise1", IR_NOISE1, 1, 1}, + { "float_noise2", IR_NOISE2, 1, 1}, + { "float_noise3", IR_NOISE3, 1, 1}, + { "float_noise4", IR_NOISE4, 1, 1}, + { NULL, IR_NOP, 0, 0 } }; @@ -1657,6 +1662,8 @@ _slang_gen_var_decl(slang_assemble_ctx *A, slang_variable *var) /** * Generate code for a selection expression: b ? x : y + * XXX in some cases we could implement a selection expression + * with an LRP instruction (use the boolean as the interpolant). */ static slang_ir_node * _slang_gen_select(slang_assemble_ctx *A, slang_operation *oper) diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c index 092c53bda0..8e598bf660 100644 --- a/src/mesa/shader/slang/slang_emit.c +++ b/src/mesa/shader/slang/slang_emit.c @@ -89,6 +89,11 @@ static slang_ir_info IrInfo[] = { { IR_DDX, "IR_DDY", OPCODE_DDX, 4, 1 }, { IR_SIN, "IR_SIN", OPCODE_SIN, 1, 1 }, { IR_COS, "IR_COS", OPCODE_COS, 1, 1 }, + { IR_NOISE1, "IR_NOISE1", OPCODE_NOISE1, 1, 1 }, + { IR_NOISE2, "IR_NOISE2", OPCODE_NOISE2, 1, 1 }, + { IR_NOISE3, "IR_NOISE3", OPCODE_NOISE3, 1, 1 }, + { IR_NOISE4, "IR_NOISE4", OPCODE_NOISE4, 1, 1 }, + /* other */ { IR_SEQ, "IR_SEQ", OPCODE_NOP, 0, 0 }, { IR_SCOPE, "IR_SCOPE", OPCODE_NOP, 0, 0 }, @@ -994,6 +999,10 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) case IR_COS: case IR_DDX: case IR_DDY: + case IR_NOISE1: + case IR_NOISE2: + case IR_NOISE3: + case IR_NOISE4: /* binary */ case IR_ADD: case IR_SUB: diff --git a/src/mesa/shader/slang/slang_ir.h b/src/mesa/shader/slang/slang_ir.h index 5617c56d4b..39b4ab65b5 100644 --- a/src/mesa/shader/slang/slang_ir.h +++ b/src/mesa/shader/slang/slang_ir.h @@ -84,6 +84,10 @@ typedef enum IR_DDY, /* derivative w.r.t. Y */ IR_SIN, /* sine */ IR_COS, /* cosine */ + IR_NOISE1, /* noise(x) */ + IR_NOISE2, /* noise(x, y) */ + IR_NOISE3, /* noise(x, y, z) */ + IR_NOISE4, /* noise(x, y, z, w) */ IR_NOT, /* logical not */ IR_VAR, /* variable reference */ IR_VAR_DECL,/* var declaration */ diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c index 74250b3592..ab1e586f35 100644 --- a/src/mesa/swrast/s_fragprog.c +++ b/src/mesa/swrast/s_fragprog.c @@ -32,6 +32,7 @@ #include "s_fragprog.h" #include "s_span.h" +#include "slang_library_noise.h" /* See comments below for info about this */ @@ -1133,6 +1134,50 @@ execute_program( GLcontext *ctx, } } break; + case OPCODE_NOISE1: + { + GLfloat a[4], result[4]; + fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); + result[0] = + result[1] = + result[2] = + result[3] = _slang_library_noise1(a[0]); + store_vector4( inst, machine, result ); + } + break; + case OPCODE_NOISE2: + { + GLfloat a[4], result[4]; + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); + result[0] = + result[1] = + result[2] = + result[3] = _slang_library_noise2(a[0], a[1]); + store_vector4( inst, machine, result ); + } + break; + case OPCODE_NOISE3: + { + GLfloat a[4], result[4]; + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); + result[0] = + result[1] = + result[2] = + result[3] = _slang_library_noise3(a[0], a[1], a[2]); + store_vector4( inst, machine, result ); + } + break; + case OPCODE_NOISE4: + { + GLfloat a[4], result[4]; + fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); + result[0] = + result[1] = + result[2] = + result[3] = _slang_library_noise4(a[0], a[1], a[2], a[3]); + store_vector4( inst, machine, result ); + } + break; case OPCODE_NOP: break; case OPCODE_PK2H: /* pack two 16-bit floats in one 32-bit float */ diff --git a/src/mesa/tnl/t_vb_arbprogram.c b/src/mesa/tnl/t_vb_arbprogram.c index 5726a66c90..22b6089fc8 100644 --- a/src/mesa/tnl/t_vb_arbprogram.c +++ b/src/mesa/tnl/t_vb_arbprogram.c @@ -766,6 +766,10 @@ static void (* const opcode_func[MAX_OPCODE+3])(struct arb_vp_machine *, union i do_MIN, do_MOV, do_MUL, + do_NOP,/*NOISE1*/ + do_NOP,/*NOISE2*/ + do_NOP,/*NOISE3*/ + do_NOP,/*NOISE4*/ do_NOP,/*PK2H*/ do_NOP,/*PK2US*/ do_NOP,/*PK4B*/ -- cgit v1.2.3 From f673b24017b8b5e850a1be5c04bd28cefa811329 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 1 Feb 2007 08:18:03 -0700 Subject: additional assertions, bump up MAX_EXEC --- src/mesa/swrast/s_fragprog.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c index ab1e586f35..12afb5ea0e 100644 --- a/src/mesa/swrast/s_fragprog.c +++ b/src/mesa/swrast/s_fragprog.c @@ -207,6 +207,10 @@ fetch_vector4( GLcontext *ctx, COPY_4V(result, src); } else { + ASSERT(GET_SWZ(source->Swizzle, 0) <= 3); + ASSERT(GET_SWZ(source->Swizzle, 1) <= 3); + ASSERT(GET_SWZ(source->Swizzle, 2) <= 3); + ASSERT(GET_SWZ(source->Swizzle, 3) <= 3); result[0] = src[GET_SWZ(source->Swizzle, 0)]; result[1] = src[GET_SWZ(source->Swizzle, 1)]; result[2] = src[GET_SWZ(source->Swizzle, 2)]; @@ -664,7 +668,7 @@ execute_program( GLcontext *ctx, struct fp_machine *machine, const SWspan *span, GLuint column ) { - const GLuint MAX_EXEC = 5000; + const GLuint MAX_EXEC = 10000; GLuint pc, total = 0; if (DEBUG_FRAG) { @@ -1659,6 +1663,7 @@ execute_program( GLcontext *ctx, total++; if (total > MAX_EXEC) { _mesa_problem(ctx, "Infinite loop detected in fragment program"); + return GL_TRUE; abort(); } } -- cgit v1.2.3 From 3866558c9840f9c4fed6ac0bd2994ccc67f40f7f Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 1 Feb 2007 08:24:02 -0700 Subject: move span-related types/tokens into s_span.h --- src/mesa/swrast/s_context.h | 203 +------------------------------------------- src/mesa/swrast/s_span.h | 201 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 204 insertions(+), 200 deletions(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/swrast/s_context.h b/src/mesa/swrast/s_context.h index c9f6ec6bb8..b15a22dbf0 100644 --- a/src/mesa/swrast/s_context.h +++ b/src/mesa/swrast/s_context.h @@ -45,205 +45,7 @@ #include "mtypes.h" #include "swrast.h" - - -/** - * \defgroup SpanFlags SPAN_XXX-flags - * Bitmasks to indicate which sw_span_arrays need to be computed - * (sw_span::interpMask) or have already been filled in (sw_span::arrayMask) - */ -/*@{*/ -#define SPAN_RGBA 0x001 -#define SPAN_SPEC 0x002 -#define SPAN_INDEX 0x004 -#define SPAN_Z 0x008 -#define SPAN_W 0x010 -#define SPAN_FOG 0x020 -#define SPAN_TEXTURE 0x040 -#define SPAN_INT_TEXTURE 0x080 -#define SPAN_LAMBDA 0x100 -#define SPAN_COVERAGE 0x200 -#define SPAN_FLAT 0x400 /**< flat shading? */ -#define SPAN_XY 0x800 -#define SPAN_MASK 0x1000 -#define SPAN_VARYING 0x2000 -/*@}*/ - -#if 0 -/* alternate arrangement for code below */ -struct arrays2 { - union { - GLubyte sz1[MAX_WIDTH][4]; /* primary color */ - GLushort sz2[MAX_WIDTH][4]; - GLfloat sz4[MAX_WIDTH][4]; - } rgba; - union { - GLubyte sz1[MAX_WIDTH][4]; /* specular color and temp storage */ - GLushort sz2[MAX_WIDTH][4]; - GLfloat sz4[MAX_WIDTH][4]; - } spec; -}; -#endif - - - -/** - * \sw_span_arrays - * \brief Arrays of fragment values. - * - * These will either be computed from the span x/xStep values or - * filled in by glDraw/CopyPixels, etc. - * These arrays are separated out of sw_span to conserve memory. - */ -typedef struct sw_span_arrays { - GLenum ChanType; /**< Color channel type, GL_UNSIGNED_BYTE, GL_FLOAT */ - union { - struct { - GLubyte rgba[MAX_WIDTH][4]; /**< primary color */ - GLubyte spec[MAX_WIDTH][4]; /**< specular color and temp storage */ - } sz1; - struct { - GLushort rgba[MAX_WIDTH][4]; - GLushort spec[MAX_WIDTH][4]; - } sz2; - struct { - GLfloat rgba[MAX_WIDTH][4]; - GLfloat spec[MAX_WIDTH][4]; - } sz4; - } color; - /** XXX these are temporary fields, pointing into above color arrays */ - GLchan (*rgba)[4]; - GLchan (*spec)[4]; - -#if 0 - /* XXX rearrange and unify these arrays to so that we can - * index all fragment inputs with the FRAG_ATTRIB_* values: - */ - GLfloat attribs[FRAG_ATTRIB_MAX][MAX_WIDTH][4]; - /*OR*/ - typedef GLfloat (*array4f)[4]; - array4f attribs[FRAG_ATTRIB_MAX]; -#endif - - GLint x[MAX_WIDTH]; /**< fragment X coords */ - GLint y[MAX_WIDTH]; /**< fragment Y coords */ - GLuint z[MAX_WIDTH]; /**< fragment Z coords */ - GLuint index[MAX_WIDTH]; /**< Color indexes */ - GLfloat fog[MAX_WIDTH]; - GLfloat texcoords[MAX_TEXTURE_COORD_UNITS][MAX_WIDTH][4]; - GLfloat lambda[MAX_TEXTURE_COORD_UNITS][MAX_WIDTH]; - GLfloat coverage[MAX_WIDTH]; /**< Fragment coverage for AA/smoothing */ - GLfloat varying[MAX_VARYING][MAX_WIDTH][4]; /**< For shaders */ - - /** This mask indicates which fragments are alive or culled */ - GLubyte mask[MAX_WIDTH]; -} SWspanarrays; - - -/** - * The SWspan structure describes the colors, Z, fogcoord, texcoords, - * etc for either a horizontal run or an array of independent pixels. - * We can either specify a base/step to indicate interpolated values, or - * fill in explicit arrays of values. The interpMask and arrayMask bitfields - * indicate which attributes are active interpolants or arrays, respectively. - * - * It would be interesting to experiment with multiprocessor rasterization - * with this structure. The triangle rasterizer could simply emit a - * stream of these structures which would be consumed by one or more - * span-processing threads which could run in parallel. - */ -typedef struct sw_span { - GLint x, y; - - /** Only need to process pixels between start <= i < end */ - /** At this time, start is always zero. */ - GLuint start, end; - - /** This flag indicates that mask[] array is effectively filled with ones */ - GLboolean writeAll; - - /** either GL_POLYGON, GL_LINE, GL_POLYGON, GL_BITMAP */ - GLenum primitive; - - /** 0 = front-facing span, 1 = back-facing span (for two-sided stencil) */ - GLuint facing; - - /** - * This bitmask (of \link SpanFlags SPAN_* flags\endlink) indicates - * which of the x/xStep variables are relevant. - */ - GLbitfield interpMask; - - /* For horizontal spans, step is the partial derivative wrt X. - * For lines, step is the delta from one fragment to the next. - */ -#if CHAN_TYPE == GL_FLOAT - GLfloat red, redStep; - GLfloat green, greenStep; - GLfloat blue, blueStep; - GLfloat alpha, alphaStep; - GLfloat specRed, specRedStep; - GLfloat specGreen, specGreenStep; - GLfloat specBlue, specBlueStep; -#else /* CHAN_TYPE == GL_UNSIGNED_BYTE or GL_UNSIGNED_SHORT */ - GLfixed red, redStep; - GLfixed green, greenStep; - GLfixed blue, blueStep; - GLfixed alpha, alphaStep; - GLfixed specRed, specRedStep; - GLfixed specGreen, specGreenStep; - GLfixed specBlue, specBlueStep; -#endif - GLfixed index, indexStep; - GLfixed z, zStep; /* XXX z should probably be GLuint */ - GLfloat fog, fogStep; - GLfloat tex[MAX_TEXTURE_COORD_UNITS][4]; /* s, t, r, q */ - GLfloat texStepX[MAX_TEXTURE_COORD_UNITS][4]; - GLfloat texStepY[MAX_TEXTURE_COORD_UNITS][4]; - GLfixed intTex[2], intTexStep[2]; /* s, t only */ - GLfloat var[MAX_VARYING][4]; - GLfloat varStepX[MAX_VARYING][4]; - GLfloat varStepY[MAX_VARYING][4]; - - /* partial derivatives wrt X and Y. */ - GLfloat dzdx, dzdy; - GLfloat w, dwdx, dwdy; - GLfloat drdx, drdy; - GLfloat dgdx, dgdy; - GLfloat dbdx, dbdy; - GLfloat dadx, dady; - GLfloat dsrdx, dsrdy; - GLfloat dsgdx, dsgdy; - GLfloat dsbdx, dsbdy; - GLfloat dfogdx, dfogdy; - - /** - * This bitmask (of \link SpanFlags SPAN_* flags\endlink) indicates - * which of the fragment arrays in the span_arrays struct are relevant. - */ - GLbitfield arrayMask; - - /** - * We store the arrays of fragment values in a separate struct so - * that we can allocate sw_span structs on the stack without using - * a lot of memory. The span_arrays struct is about 1.4MB while the - * sw_span struct is only about 512 bytes. - */ - SWspanarrays *array; -} SWspan; - - - -#define INIT_SPAN(S, PRIMITIVE, END, INTERP_MASK, ARRAY_MASK) \ -do { \ - (S).primitive = (PRIMITIVE); \ - (S).interpMask = (INTERP_MASK); \ - (S).arrayMask = (ARRAY_MASK); \ - (S).start = 0; \ - (S).end = (END); \ - (S).facing = 0; \ - (S).array = SWRAST_CONTEXT(ctx)->SpanArrays; \ -} while (0) +#include "s_span.h" typedef void (*texture_sample_func)(GLcontext *ctx, @@ -270,7 +72,8 @@ typedef void (*validate_texture_image_func)(GLcontext *ctx, GLuint face, GLuint level); -/** \defgroup Bitmasks +/** + * \defgroup Bitmasks * Bitmasks to indicate which rasterization options are enabled * (RasterMask) */ diff --git a/src/mesa/swrast/s_span.h b/src/mesa/swrast/s_span.h index c441106aba..7c514afb0b 100644 --- a/src/mesa/swrast/s_span.h +++ b/src/mesa/swrast/s_span.h @@ -31,6 +31,207 @@ #include "swrast.h" +/** + * \defgroup SpanFlags SPAN_*-flags + * Bitflags used for interpMask and arrayMask fields below to indicate + * which interpolant values and fragment arrays are in use, respectively. + */ +/*@{*/ +#define SPAN_RGBA 0x001 +#define SPAN_SPEC 0x002 +#define SPAN_INDEX 0x004 +#define SPAN_Z 0x008 +#define SPAN_W 0x010 +#define SPAN_FOG 0x020 +#define SPAN_TEXTURE 0x040 +#define SPAN_INT_TEXTURE 0x080 +#define SPAN_LAMBDA 0x100 +#define SPAN_COVERAGE 0x200 +#define SPAN_FLAT 0x400 /**< flat shading? */ +#define SPAN_XY 0x800 +#define SPAN_MASK 0x1000 +#define SPAN_VARYING 0x2000 +/*@}*/ + + +#if 0 +/* alternate arrangement for code below */ +struct arrays2 { + union { + GLubyte sz1[MAX_WIDTH][4]; /* primary color */ + GLushort sz2[MAX_WIDTH][4]; + GLfloat sz4[MAX_WIDTH][4]; + } rgba; + union { + GLubyte sz1[MAX_WIDTH][4]; /* specular color and temp storage */ + GLushort sz2[MAX_WIDTH][4]; + GLfloat sz4[MAX_WIDTH][4]; + } spec; +}; +#endif + + + +/** + * \sw_span_arrays + * \brief Arrays of fragment values. + * + * These will either be computed from the span x/xStep values or + * filled in by glDraw/CopyPixels, etc. + * These arrays are separated out of sw_span to conserve memory. + */ +typedef struct sw_span_arrays { + GLenum ChanType; /**< Color channel type, GL_UNSIGNED_BYTE, GL_FLOAT */ + union { + struct { + GLubyte rgba[MAX_WIDTH][4]; /**< primary color */ + GLubyte spec[MAX_WIDTH][4]; /**< specular color and temp storage */ + } sz1; + struct { + GLushort rgba[MAX_WIDTH][4]; + GLushort spec[MAX_WIDTH][4]; + } sz2; + struct { + GLfloat rgba[MAX_WIDTH][4]; + GLfloat spec[MAX_WIDTH][4]; + } sz4; + } color; + /** XXX these are temporary fields, pointing into above color arrays */ + GLchan (*rgba)[4]; + GLchan (*spec)[4]; + +#if 0 + /* XXX rearrange and unify these arrays to so that we can + * index all fragment inputs with the FRAG_ATTRIB_* values: + */ + GLfloat attribs[FRAG_ATTRIB_MAX][MAX_WIDTH][4]; + /*OR*/ + typedef GLfloat (*array4f)[4]; + array4f attribs[FRAG_ATTRIB_MAX]; +#endif + + GLint x[MAX_WIDTH]; /**< fragment X coords */ + GLint y[MAX_WIDTH]; /**< fragment Y coords */ + GLuint z[MAX_WIDTH]; /**< fragment Z coords */ + GLuint index[MAX_WIDTH]; /**< Color indexes */ + GLfloat fog[MAX_WIDTH]; + GLfloat texcoords[MAX_TEXTURE_COORD_UNITS][MAX_WIDTH][4]; + GLfloat lambda[MAX_TEXTURE_COORD_UNITS][MAX_WIDTH]; + GLfloat coverage[MAX_WIDTH]; /**< Fragment coverage for AA/smoothing */ + GLfloat varying[MAX_VARYING][MAX_WIDTH][4]; /**< For shaders */ + + /** This mask indicates which fragments are alive or culled */ + GLubyte mask[MAX_WIDTH]; +} SWspanarrays; + + +/** + * The SWspan structure describes the colors, Z, fogcoord, texcoords, + * etc for either a horizontal run or an array of independent pixels. + * We can either specify a base/step to indicate interpolated values, or + * fill in explicit arrays of values. The interpMask and arrayMask bitfields + * indicate which attributes are active interpolants or arrays, respectively. + * + * It would be interesting to experiment with multiprocessor rasterization + * with this structure. The triangle rasterizer could simply emit a + * stream of these structures which would be consumed by one or more + * span-processing threads which could run in parallel. + */ +typedef struct sw_span { + GLint x, y; + + /** Only need to process pixels between start <= i < end */ + /** At this time, start is always zero. */ + GLuint start, end; + + /** This flag indicates that mask[] array is effectively filled with ones */ + GLboolean writeAll; + + /** either GL_POLYGON, GL_LINE, GL_POLYGON, GL_BITMAP */ + GLenum primitive; + + /** 0 = front-facing span, 1 = back-facing span (for two-sided stencil) */ + GLuint facing; + + /** + * This bitmask (of \link SpanFlags SPAN_* flags\endlink) indicates + * which of the x/xStep variables are relevant. + */ + GLbitfield interpMask; + + /* For horizontal spans, step is the partial derivative wrt X. + * For lines, step is the delta from one fragment to the next. + */ +#if CHAN_TYPE == GL_FLOAT + GLfloat red, redStep; + GLfloat green, greenStep; + GLfloat blue, blueStep; + GLfloat alpha, alphaStep; + GLfloat specRed, specRedStep; + GLfloat specGreen, specGreenStep; + GLfloat specBlue, specBlueStep; +#else /* CHAN_TYPE == GL_UNSIGNED_BYTE or GL_UNSIGNED_SHORT */ + GLfixed red, redStep; + GLfixed green, greenStep; + GLfixed blue, blueStep; + GLfixed alpha, alphaStep; + GLfixed specRed, specRedStep; + GLfixed specGreen, specGreenStep; + GLfixed specBlue, specBlueStep; +#endif + GLfixed index, indexStep; + GLfixed z, zStep; /* XXX z should probably be GLuint */ + GLfloat fog, fogStep; + GLfloat tex[MAX_TEXTURE_COORD_UNITS][4]; /* s, t, r, q */ + GLfloat texStepX[MAX_TEXTURE_COORD_UNITS][4]; + GLfloat texStepY[MAX_TEXTURE_COORD_UNITS][4]; + GLfixed intTex[2], intTexStep[2]; /* s, t only */ + GLfloat var[MAX_VARYING][4]; + GLfloat varStepX[MAX_VARYING][4]; + GLfloat varStepY[MAX_VARYING][4]; + + /* partial derivatives wrt X and Y. */ + GLfloat dzdx, dzdy; + GLfloat w, dwdx, dwdy; + GLfloat drdx, drdy; + GLfloat dgdx, dgdy; + GLfloat dbdx, dbdy; + GLfloat dadx, dady; + GLfloat dsrdx, dsrdy; + GLfloat dsgdx, dsgdy; + GLfloat dsbdx, dsbdy; + GLfloat dfogdx, dfogdy; + + /** + * This bitmask (of \link SpanFlags SPAN_* flags\endlink) indicates + * which of the fragment arrays in the span_arrays struct are relevant. + */ + GLbitfield arrayMask; + + /** + * We store the arrays of fragment values in a separate struct so + * that we can allocate sw_span structs on the stack without using + * a lot of memory. The span_arrays struct is about 1.4MB while the + * sw_span struct is only about 512 bytes. + */ + SWspanarrays *array; +} SWspan; + + + +#define INIT_SPAN(S, PRIMITIVE, END, INTERP_MASK, ARRAY_MASK) \ +do { \ + (S).primitive = (PRIMITIVE); \ + (S).interpMask = (INTERP_MASK); \ + (S).arrayMask = (ARRAY_MASK); \ + (S).start = 0; \ + (S).end = (END); \ + (S).facing = 0; \ + (S).array = SWRAST_CONTEXT(ctx)->SpanArrays; \ +} while (0) + + + extern void _swrast_span_default_z( GLcontext *ctx, SWspan *span ); -- cgit v1.2.3 From f3e507ef9f75dbfc58ccd07b5fe8cfca10d9a9e3 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 1 Feb 2007 09:51:48 -0700 Subject: New SWspanarrays attribs[] array. Replace texcoord[], varying[], etc. arrays with single attribs[] array, indexed by FRAG_ATTRIB_* values. Eliminates need to copy data into fragment program machine input registers. Will lead to future clean-ups. --- src/mesa/swrast/s_aalinetemp.h | 14 +++---- src/mesa/swrast/s_aatritemp.h | 39 +++++++++--------- src/mesa/swrast/s_alpha.c | 2 +- src/mesa/swrast/s_atifragshader.c | 11 ++--- src/mesa/swrast/s_copypix.c | 2 +- src/mesa/swrast/s_drawpix.c | 2 +- src/mesa/swrast/s_fog.c | 18 ++++----- src/mesa/swrast/s_fragprog.c | 84 ++++++++------------------------------- src/mesa/swrast/s_logic.c | 2 +- src/mesa/swrast/s_masking.c | 2 +- src/mesa/swrast/s_pointtemp.h | 14 +++---- src/mesa/swrast/s_readpix.c | 2 +- src/mesa/swrast/s_span.c | 65 ++++++++++++++++++++++-------- src/mesa/swrast/s_span.h | 38 ++++++------------ src/mesa/swrast/s_texcombine.c | 6 ++- src/mesa/swrast/s_zoom.c | 10 ++--- 16 files changed, 140 insertions(+), 171 deletions(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/swrast/s_aalinetemp.h b/src/mesa/swrast/s_aalinetemp.h index 68291afeea..b977ab8325 100644 --- a/src/mesa/swrast/s_aalinetemp.h +++ b/src/mesa/swrast/s_aalinetemp.h @@ -61,7 +61,7 @@ NAME(plot)(GLcontext *ctx, struct LineInfo *line, int ix, int iy) line->span.array->z[i] = (GLuint) solve_plane(fx, fy, line->zPlane); #endif #ifdef DO_FOG - line->span.array->fog[i] = solve_plane(fx, fy, line->fPlane); + line->span.array->attribs[FRAG_ATTRIB_FOGC][i][0] = solve_plane(fx, fy, line->fPlane); #endif #ifdef DO_RGBA line->span.array->rgba[i][RCOMP] = solve_plane_chan(fx, fy, line->rPlane); @@ -86,9 +86,9 @@ NAME(plot)(GLcontext *ctx, struct LineInfo *line, int ix, int iy) else { invQ = solve_plane_recip(fx, fy, line->vPlane[0]); } - line->span.array->texcoords[0][i][0] = solve_plane(fx, fy, line->sPlane[0]) * invQ; - line->span.array->texcoords[0][i][1] = solve_plane(fx, fy, line->tPlane[0]) * invQ; - line->span.array->texcoords[0][i][2] = solve_plane(fx, fy, line->uPlane[0]) * invQ; + line->span.array->attribs[FRAG_ATTRIB_TEX0][i][0] = solve_plane(fx, fy, line->sPlane[0]) * invQ; + line->span.array->attribs[FRAG_ATTRIB_TEX0][i][1] = solve_plane(fx, fy, line->tPlane[0]) * invQ; + line->span.array->attribs[FRAG_ATTRIB_TEX0][i][2] = solve_plane(fx, fy, line->uPlane[0]) * invQ; line->span.array->lambda[0][i] = compute_lambda(line->sPlane[0], line->tPlane[0], invQ, line->texWidth[0], @@ -106,9 +106,9 @@ NAME(plot)(GLcontext *ctx, struct LineInfo *line, int ix, int iy) else { invQ = solve_plane_recip(fx, fy, line->vPlane[unit]); } - line->span.array->texcoords[unit][i][0] = solve_plane(fx, fy, line->sPlane[unit]) * invQ; - line->span.array->texcoords[unit][i][1] = solve_plane(fx, fy, line->tPlane[unit]) * invQ; - line->span.array->texcoords[unit][i][2] = solve_plane(fx, fy, line->uPlane[unit]) * invQ; + line->span.array->attribs[FRAG_ATTRIB_TEX0 + unit][i][0] = solve_plane(fx, fy, line->sPlane[unit]) * invQ; + line->span.array->attribs[FRAG_ATTRIB_TEX0 + unit][i][1] = solve_plane(fx, fy, line->tPlane[unit]) * invQ; + line->span.array->attribs[FRAG_ATTRIB_TEX0 + unit][i][2] = solve_plane(fx, fy, line->uPlane[unit]) * invQ; line->span.array->lambda[unit][i] = compute_lambda(line->sPlane[unit], line->tPlane[unit], invQ, line->texWidth[unit], line->texHeight[unit]); diff --git a/src/mesa/swrast/s_aatritemp.h b/src/mesa/swrast/s_aatritemp.h index b5470a0298..3359a919e5 100644 --- a/src/mesa/swrast/s_aatritemp.h +++ b/src/mesa/swrast/s_aatritemp.h @@ -289,7 +289,7 @@ array->z[count] = (GLuint) solve_plane(cx, cy, zPlane); #endif #ifdef DO_FOG - array->fog[count] = solve_plane(cx, cy, fogPlane); + array->attribs[FRAG_ATTRIB_FOGC][count][0] = solve_plane(cx, cy, fogPlane); #endif #ifdef DO_RGBA array->rgba[count][RCOMP] = solve_plane_chan(cx, cy, rPlane); @@ -308,9 +308,9 @@ #ifdef DO_TEX { const GLfloat invQ = solve_plane_recip(cx, cy, vPlane); - array->texcoords[0][count][0] = solve_plane(cx, cy, sPlane) * invQ; - array->texcoords[0][count][1] = solve_plane(cx, cy, tPlane) * invQ; - array->texcoords[0][count][2] = solve_plane(cx, cy, uPlane) * invQ; + array->attribs[FRAG_ATTRIB_TEX0 + 0][count][0] = solve_plane(cx, cy, sPlane) * invQ; + array->attribs[FRAG_ATTRIB_TEX0 + 0][count][1] = solve_plane(cx, cy, tPlane) * invQ; + array->attribs[FRAG_ATTRIB_TEX0 + 0][count][2] = solve_plane(cx, cy, uPlane) * invQ; array->lambda[0][count] = compute_lambda(sPlane, tPlane, vPlane, cx, cy, invQ, texWidth, texHeight); @@ -321,9 +321,9 @@ for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { if (ctx->Texture.Unit[unit]._ReallyEnabled) { GLfloat invQ = solve_plane_recip(cx, cy, vPlane[unit]); - array->texcoords[unit][count][0] = solve_plane(cx, cy, sPlane[unit]) * invQ; - array->texcoords[unit][count][1] = solve_plane(cx, cy, tPlane[unit]) * invQ; - array->texcoords[unit][count][2] = solve_plane(cx, cy, uPlane[unit]) * invQ; + array->attribs[FRAG_ATTRIB_TEX0 + unit][count][0] = solve_plane(cx, cy, sPlane[unit]) * invQ; + array->attribs[FRAG_ATTRIB_TEX0 + unit][count][1] = solve_plane(cx, cy, tPlane[unit]) * invQ; + array->attribs[FRAG_ATTRIB_TEX0 + unit][count][2] = solve_plane(cx, cy, uPlane[unit]) * invQ; array->lambda[unit][count] = compute_lambda(sPlane[unit], tPlane[unit], vPlane[unit], cx, cy, invQ, texWidth[unit], texHeight[unit]); @@ -393,7 +393,7 @@ array->z[ix] = (GLuint) solve_plane(cx, cy, zPlane); #endif #ifdef DO_FOG - array->fog[ix] = solve_plane(cx, cy, fogPlane); + array->attribs[FRAG_ATTRIB_FOGC][ix][0] = solve_plane(cx, cy, fogPlane); #endif #ifdef DO_RGBA array->rgba[ix][RCOMP] = solve_plane_chan(cx, cy, rPlane); @@ -412,9 +412,9 @@ #ifdef DO_TEX { const GLfloat invQ = solve_plane_recip(cx, cy, vPlane); - array->texcoords[0][ix][0] = solve_plane(cx, cy, sPlane) * invQ; - array->texcoords[0][ix][1] = solve_plane(cx, cy, tPlane) * invQ; - array->texcoords[0][ix][2] = solve_plane(cx, cy, uPlane) * invQ; + array->attribs[FRAG_ATTRIB_TEX0][ix][0] = solve_plane(cx, cy, sPlane) * invQ; + array->attribs[FRAG_ATTRIB_TEX0][ix][1] = solve_plane(cx, cy, tPlane) * invQ; + array->attribs[FRAG_ATTRIB_TEX0][ix][2] = solve_plane(cx, cy, uPlane) * invQ; array->lambda[0][ix] = compute_lambda(sPlane, tPlane, vPlane, cx, cy, invQ, texWidth, texHeight); } @@ -424,9 +424,9 @@ for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { if (ctx->Texture.Unit[unit]._ReallyEnabled) { GLfloat invQ = solve_plane_recip(cx, cy, vPlane[unit]); - array->texcoords[unit][ix][0] = solve_plane(cx, cy, sPlane[unit]) * invQ; - array->texcoords[unit][ix][1] = solve_plane(cx, cy, tPlane[unit]) * invQ; - array->texcoords[unit][ix][2] = solve_plane(cx, cy, uPlane[unit]) * invQ; + array->attribs[FRAG_ATTRIB_TEX0 + unit][ix][0] = solve_plane(cx, cy, sPlane[unit]) * invQ; + array->attribs[FRAG_ATTRIB_TEX0 + unit][ix][1] = solve_plane(cx, cy, tPlane[unit]) * invQ; + array->attribs[FRAG_ATTRIB_TEX0 + unit][ix][2] = solve_plane(cx, cy, uPlane[unit]) * invQ; array->lambda[unit][ix] = compute_lambda(sPlane[unit], tPlane[unit], vPlane[unit], @@ -468,10 +468,11 @@ array->z[j] = array->z[j + left]; #endif #ifdef DO_FOG - array->fog[j] = array->fog[j + left]; + array->attribs[FRAG_ATTRIB_FOGC][j][0] + = array->attribs[FRAG_ATTRIB_FOGC][j + left][0]; #endif #ifdef DO_TEX - COPY_4V(array->texcoords[0][j], array->texcoords[0][j + left]); + COPY_4V(array->attribs[FRAG_ATTRIB_TEX0 + 0][j], array->attribs[FRAG_ATTRIB_TEX0 + 0][j + left]); #endif #if defined(DO_MULTITEX) || defined(DO_TEX) array->lambda[0][j] = array->lambda[0][j + left]; @@ -488,9 +489,9 @@ if (ctx->Texture.Unit[unit]._ReallyEnabled) { GLint j; for (j = 0; j < (GLint) n; j++) { - array->texcoords[unit][j][0] = array->texcoords[unit][j + left][0]; - array->texcoords[unit][j][1] = array->texcoords[unit][j + left][1]; - array->texcoords[unit][j][2] = array->texcoords[unit][j + left][2]; + array->attribs[FRAG_ATTRIB_TEX0 + unit][j][0] = array->attribs[FRAG_ATTRIB_TEX0 + unit][j + left][0]; + array->attribs[FRAG_ATTRIB_TEX0 + unit][j][1] = array->attribs[FRAG_ATTRIB_TEX0 + unit][j + left][1]; + array->attribs[FRAG_ATTRIB_TEX0 + unit][j][2] = array->attribs[FRAG_ATTRIB_TEX0 + unit][j + left][2]; array->lambda[unit][j] = array->lambda[unit][j + left]; } } diff --git a/src/mesa/swrast/s_alpha.c b/src/mesa/swrast/s_alpha.c index 87a016512c..af8a6baddc 100644 --- a/src/mesa/swrast/s_alpha.c +++ b/src/mesa/swrast/s_alpha.c @@ -123,7 +123,7 @@ _swrast_alpha_test(const GLcontext *ctx, SWspan *span) ALPHA_TEST(rgba[i][ACOMP], ;); } else { - GLfloat (*rgba)[4] = span->array->color.sz4.rgba; + GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; const GLfloat ref = ctx->Color.AlphaRef; ALPHA_TEST(rgba[i][ACOMP], ;); } diff --git a/src/mesa/swrast/s_atifragshader.c b/src/mesa/swrast/s_atifragshader.c index 75df50b0ba..1ac6528a91 100644 --- a/src/mesa/swrast/s_atifragshader.c +++ b/src/mesa/swrast/s_atifragshader.c @@ -268,7 +268,7 @@ handle_pass_op(struct atifs_machine *machine, struct atifs_setupinst *texinst, if (pass_tex >= GL_TEXTURE0_ARB && pass_tex <= GL_TEXTURE7_ARB) { pass_tex -= GL_TEXTURE0_ARB; COPY_4V(machine->Registers[idx], - span->array->texcoords[pass_tex][column]); + span->array->attribs[FRAG_ATTRIB_TEX0 + pass_tex][column]); } else if (pass_tex >= GL_REG_0_ATI && pass_tex <= GL_REG_5_ATI) { pass_tex -= GL_REG_0_ATI; @@ -290,7 +290,8 @@ handle_sample_op(GLcontext * ctx, struct atifs_machine *machine, if (coord_source >= GL_TEXTURE0_ARB && coord_source <= GL_TEXTURE7_ARB) { coord_source -= GL_TEXTURE0_ARB; - COPY_4V(tex_coords, span->array->texcoords[coord_source][column]); + COPY_4V(tex_coords, + span->array->attribs[FRAG_ATTRIB_TEX0 + coord_source][column]); } else if (coord_source >= GL_REG_0_ATI && coord_source <= GL_REG_5_ATI) { coord_source -= GL_REG_0_ATI; @@ -572,8 +573,8 @@ init_machine(GLcontext * ctx, struct atifs_machine *machine, machine->Registers[i][j] = 0.0; } - COPY_4V(inputs[ATI_FS_INPUT_PRIMARY], span->array->color.sz4.rgba[col]); - COPY_4V(inputs[ATI_FS_INPUT_SECONDARY], span->array->color.sz4.spec[col]); + COPY_4V(inputs[ATI_FS_INPUT_PRIMARY], span->array->attribs[FRAG_ATTRIB_COL0][col]); + COPY_4V(inputs[ATI_FS_INPUT_SECONDARY], span->array->attribs[FRAG_ATTRIB_COL1][col]); } @@ -604,7 +605,7 @@ _swrast_exec_fragment_shader(GLcontext * ctx, SWspan *span) const GLfloat *colOut = machine.Registers[0]; /*fprintf(stderr,"outputs %f %f %f %f\n", colOut[0], colOut[1], colOut[2], colOut[3]); */ - COPY_4V(span->array->color.sz4.rgba[i], colOut); + COPY_4V(span->array->attribs[FRAG_ATTRIB_COL0][i], colOut); } } } diff --git a/src/mesa/swrast/s_copypix.c b/src/mesa/swrast/s_copypix.c index 761ab724e9..a9bc6433de 100644 --- a/src/mesa/swrast/s_copypix.c +++ b/src/mesa/swrast/s_copypix.c @@ -263,7 +263,7 @@ copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy, ASSERT(width < MAX_WIDTH); for (row = 0; row < height; row++, sy += stepy, dy += stepy) { - GLvoid *rgba = span.array->color.sz4.rgba; + GLvoid *rgba = span.array->attribs[FRAG_ATTRIB_COL0]; /* Get row/span of source pixels */ if (overlapping) { diff --git a/src/mesa/swrast/s_drawpix.c b/src/mesa/swrast/s_drawpix.c index bdb2558351..dd2b57c7d3 100644 --- a/src/mesa/swrast/s_drawpix.c +++ b/src/mesa/swrast/s_drawpix.c @@ -635,7 +635,7 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y, = _mesa_image_row_stride(unpack, width, format, type); GLint skipPixels = 0; /* use span array for temp color storage */ - GLfloat *rgba = (GLfloat *) span.array->color.sz4.rgba; + GLfloat *rgba = (GLfloat *) span.array->attribs[FRAG_ATTRIB_COL0]; /* if the span is wider than MAX_WIDTH we have to do it in chunks */ while (skipPixels < width) { diff --git a/src/mesa/swrast/s_fog.c b/src/mesa/swrast/s_fog.c index f4c3fe4f2d..93d2ab469f 100644 --- a/src/mesa/swrast/s_fog.c +++ b/src/mesa/swrast/s_fog.c @@ -154,7 +154,7 @@ _swrast_fog_rgba_span( const GLcontext *ctx, SWspan *span ) FOG_LOOP(GLushort, COMPUTE_F); } else { - GLfloat (*rgba)[4] = span->array->color.sz4.rgba; + GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; ASSERT(span->array->ChanType == GL_FLOAT); FOG_LOOP(GLfloat, COMPUTE_F); } @@ -172,7 +172,7 @@ _swrast_fog_rgba_span( const GLcontext *ctx, SWspan *span ) FOG_LOOP(GLushort, COMPUTE_F); } else { - GLfloat (*rgba)[4] = span->array->color.sz4.rgba; + GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; ASSERT(span->array->ChanType == GL_FLOAT); FOG_LOOP(GLfloat, COMPUTE_F); } @@ -194,7 +194,7 @@ _swrast_fog_rgba_span( const GLcontext *ctx, SWspan *span ) FOG_LOOP(GLushort, COMPUTE_F); } else { - GLfloat (*rgba)[4] = span->array->color.sz4.rgba; + GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; ASSERT(span->array->ChanType == GL_FLOAT); FOG_LOOP(GLfloat, COMPUTE_F); } @@ -214,7 +214,7 @@ _swrast_fog_rgba_span( const GLcontext *ctx, SWspan *span ) if (span->array->ChanType == GL_UNSIGNED_BYTE) { GLubyte (*rgba)[4] = span->array->color.sz1.rgba; for (i = 0; i < span->end; i++) { - const GLfloat f = span->array->fog[i]; + const GLfloat f = span->array->attribs[FRAG_ATTRIB_FOGC][i][0]; const GLfloat oneMinusF = 1.0F - f; rgba[i][RCOMP] = (GLubyte) (f * rgba[i][RCOMP] + oneMinusF * rFog); rgba[i][GCOMP] = (GLubyte) (f * rgba[i][GCOMP] + oneMinusF * gFog); @@ -224,7 +224,7 @@ _swrast_fog_rgba_span( const GLcontext *ctx, SWspan *span ) else if (span->array->ChanType == GL_UNSIGNED_SHORT) { GLushort (*rgba)[4] = span->array->color.sz2.rgba; for (i = 0; i < span->end; i++) { - const GLfloat f = span->array->fog[i]; + const GLfloat f = span->array->attribs[FRAG_ATTRIB_FOGC][i][0]; const GLfloat oneMinusF = 1.0F - f; rgba[i][RCOMP] = (GLushort) (f * rgba[i][RCOMP] + oneMinusF * rFog); rgba[i][GCOMP] = (GLushort) (f * rgba[i][GCOMP] + oneMinusF * gFog); @@ -232,10 +232,10 @@ _swrast_fog_rgba_span( const GLcontext *ctx, SWspan *span ) } } else { - GLfloat (*rgba)[4] = span->array->color.sz4.rgba; + GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; ASSERT(span->array->ChanType == GL_FLOAT); for (i = 0; i < span->end; i++) { - const GLfloat f = span->array->fog[i]; + const GLfloat f = span->array->attribs[FRAG_ATTRIB_FOGC][i][0]; const GLfloat oneMinusF = 1.0F - f; rgba[i][RCOMP] = f * rgba[i][RCOMP] + oneMinusF * rFog; rgba[i][GCOMP] = f * rgba[i][GCOMP] + oneMinusF * gFog; @@ -258,7 +258,7 @@ _swrast_fog_rgba_span( const GLcontext *ctx, SWspan *span ) FOG_LOOP(GLushort, COMPUTE_F); } else { - GLfloat (*rgba)[4] = span->array->color.sz4.rgba; + GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; ASSERT(span->array->ChanType == GL_FLOAT); FOG_LOOP(GLfloat, COMPUTE_F); } @@ -360,7 +360,7 @@ _swrast_fog_ci_span( const GLcontext *ctx, SWspan *span ) */ GLuint i; for (i = 0; i < span->end; i++) { - const GLfloat f = span->array->fog[i]; + const GLfloat f = span->array->attribs[FRAG_ATTRIB_FOGC][i][0]; index[i] = (GLuint) ((GLfloat) index[i] + (1.0F - f) * fogIndex); } } diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c index 12afb5ea0e..9ae423dde9 100644 --- a/src/mesa/swrast/s_fragprog.c +++ b/src/mesa/swrast/s_fragprog.c @@ -47,8 +47,11 @@ */ struct fp_machine { + /** Fragment Input attributes */ + GLfloat (*Attribs)[MAX_WIDTH][4]; + GLuint CurFrag; /**< Index into Attribs arrays */ + GLfloat Temporaries[MAX_PROGRAM_TEMPS][4]; - GLfloat Inputs[FRAG_ATTRIB_MAX][4]; GLfloat Outputs[FRAG_RESULT_MAX][4]; GLuint CondCodes[4]; /**< COND_* value for x/y/z/w */ @@ -72,7 +75,7 @@ _swrast_get_program_register(GLcontext *ctx, enum register_file file, if (CurrentMachine) { switch (file) { case PROGRAM_INPUT: - COPY_4V(val, CurrentMachine->Inputs[index]); + COPY_4V(val, CurrentMachine->Attribs[index][CurrentMachine->CurFrag]); break; case PROGRAM_OUTPUT: COPY_4V(val, CurrentMachine->Outputs[index]); @@ -160,7 +163,7 @@ get_register_pointer( GLcontext *ctx, return machine->Temporaries[source->Index]; case PROGRAM_INPUT: ASSERT(source->Index < FRAG_ATTRIB_MAX); - return machine->Inputs[source->Index]; + return machine->Attribs[source->Index][machine->CurFrag]; case PROGRAM_OUTPUT: /* This is only for PRINT */ ASSERT(source->Index < FRAG_RESULT_MAX); @@ -554,7 +557,7 @@ init_machine_deriv( GLcontext *ctx, /* Add derivatives */ if (program->Base.InputsRead & FRAG_BIT_WPOS) { - GLfloat *wpos = (GLfloat*) machine->Inputs[FRAG_ATTRIB_WPOS]; + GLfloat *wpos = machine->Attribs[FRAG_ATTRIB_WPOS][machine->CurFrag]; if (xOrY == 'X') { wpos[0] += 1.0F; wpos[1] += 0.0F; @@ -569,7 +572,7 @@ init_machine_deriv( GLcontext *ctx, } } if (program->Base.InputsRead & FRAG_BIT_COL0) { - GLfloat *col0 = (GLfloat*) machine->Inputs[FRAG_ATTRIB_COL0]; + GLfloat *col0 = machine->Attribs[FRAG_ATTRIB_COL0][machine->CurFrag]; if (xOrY == 'X') { col0[0] += span->drdx * (1.0F / CHAN_MAXF); col0[1] += span->dgdx * (1.0F / CHAN_MAXF); @@ -584,7 +587,7 @@ init_machine_deriv( GLcontext *ctx, } } if (program->Base.InputsRead & FRAG_BIT_COL1) { - GLfloat *col1 = (GLfloat*) machine->Inputs[FRAG_ATTRIB_COL1]; + GLfloat *col1 = machine->Attribs[FRAG_ATTRIB_COL1][machine->CurFrag]; if (xOrY == 'X') { col1[0] += span->dsrdx * (1.0F / CHAN_MAXF); col1[1] += span->dsgdx * (1.0F / CHAN_MAXF); @@ -599,7 +602,7 @@ init_machine_deriv( GLcontext *ctx, } } if (program->Base.InputsRead & FRAG_BIT_FOGC) { - GLfloat *fogc = (GLfloat*) machine->Inputs[FRAG_ATTRIB_FOGC]; + GLfloat *fogc = machine->Attribs[FRAG_ATTRIB_FOGC][machine->CurFrag]; if (xOrY == 'X') { fogc[0] += span->dfogdx; } @@ -609,7 +612,7 @@ init_machine_deriv( GLcontext *ctx, } for (u = 0; u < ctx->Const.MaxTextureCoordUnits; u++) { if (program->Base.InputsRead & FRAG_BIT_TEX(u)) { - GLfloat *tex = (GLfloat*) machine->Inputs[FRAG_ATTRIB_TEX0 + u]; + GLfloat *tex = machine->Attribs[FRAG_ATTRIB_TEX0 + u][machine->CurFrag]; /* XXX perspective-correct interpolation */ if (xOrY == 'X') { tex[0] += span->texStepX[u][0]; @@ -628,7 +631,7 @@ init_machine_deriv( GLcontext *ctx, for (v = 0; v < ctx->Const.MaxVarying; v++) { if (program->Base.InputsRead & FRAG_BIT_VAR(v)) { - GLfloat *var = (GLfloat*) machine->Inputs[FRAG_ATTRIB_VAR0 + v]; + GLfloat *var = machine->Attribs[FRAG_ATTRIB_VAR0 + v][machine->CurFrag]; if (xOrY == 'X') { var[0] += span->varStepX[v][0]; var[1] += span->varStepX[v][1]; @@ -1686,7 +1689,6 @@ init_machine( GLcontext *ctx, struct fp_machine *machine, const SWspan *span, GLuint col ) { GLuint inputsRead = program->Base.InputsRead; - GLuint u, v; if (ctx->FragmentProgram.CallbackEnabled) inputsRead = ~0; @@ -1697,63 +1699,9 @@ init_machine( GLcontext *ctx, struct fp_machine *machine, MAX_NV_FRAGMENT_PROGRAM_TEMPS * 4 * sizeof(GLfloat)); } - /* Load input registers */ - if (inputsRead & FRAG_BIT_WPOS) { - GLfloat *wpos = machine->Inputs[FRAG_ATTRIB_WPOS]; - ASSERT(span->arrayMask & SPAN_Z); - if (span->arrayMask & SPAN_XY) { - wpos[0] = (GLfloat) span->array->x[col]; - wpos[1] = (GLfloat) span->array->y[col]; - } - else { - wpos[0] = (GLfloat) span->x + col; - wpos[1] = (GLfloat) span->y; - } - wpos[2] = (GLfloat) span->array->z[col] / ctx->DrawBuffer->_DepthMaxF; - wpos[3] = span->w + col * span->dwdx; - } - if (inputsRead & FRAG_BIT_COL0) { - ASSERT(span->arrayMask & SPAN_RGBA); - COPY_4V(machine->Inputs[FRAG_ATTRIB_COL0], - span->array->color.sz4.rgba[col]); - } - if (inputsRead & FRAG_BIT_COL1) { - ASSERT(span->arrayMask & SPAN_SPEC); - COPY_4V(machine->Inputs[FRAG_ATTRIB_COL1], - span->array->color.sz4.spec[col]); - } - if (inputsRead & FRAG_BIT_FOGC) { - GLfloat *fogc = machine->Inputs[FRAG_ATTRIB_FOGC]; - ASSERT(span->arrayMask & SPAN_FOG); - fogc[0] = span->array->fog[col]; - fogc[1] = 0.0F; - fogc[2] = 0.0F; - fogc[3] = 0.0F; - } - for (u = 0; u < ctx->Const.MaxTextureCoordUnits; u++) { - if (inputsRead & FRAG_BIT_TEX(u)) { - GLfloat *tex = machine->Inputs[FRAG_ATTRIB_TEX0 + u]; - /*ASSERT(ctx->Texture._EnabledCoordUnits & (1 << u));*/ - COPY_4V(tex, span->array->texcoords[u][col]); - /*ASSERT(tex[0] != 0 || tex[1] != 0 || tex[2] != 0);*/ -#if 0 - printf("Texcoord %d: %g %g %g %g\n", u, - tex[0], tex[1], tex[2], tex[3]); -#endif - } - } - for (v = 0; v < ctx->Const.MaxVarying; v++) { - if (inputsRead & FRAG_BIT_VAR(v)) { -#if 0 - printf("Frag Var %d at y=%d: %f %f %f\n", v, col, - span->array->varying[v][col][0], - span->array->varying[v][col][1], - span->array->varying[v][col][2]); -#endif - COPY_4V(machine->Inputs[FRAG_ATTRIB_VAR0 + v], - span->array->varying[v][col]); - } - } + /* Setup pointer to input attributes */ + machine->Attribs = span->array->attribs; + machine->CurFrag = col; /* init condition codes */ machine->CondCodes[0] = COND_EQ; @@ -1784,7 +1732,7 @@ run_program(GLcontext *ctx, SWspan *span, GLuint start, GLuint end) if (execute_program(ctx, program, ~0, &machine, span, i)) { /* Store result color */ - COPY_4V(span->array->color.sz4.rgba[i], + COPY_4V(span->array->attribs[FRAG_ATTRIB_COL0][i], machine.Outputs[FRAG_RESULT_COLR]); /* Store result depth/z */ diff --git a/src/mesa/swrast/s_logic.c b/src/mesa/swrast/s_logic.c index 719b17962d..e680732bee 100644 --- a/src/mesa/swrast/s_logic.c +++ b/src/mesa/swrast/s_logic.c @@ -240,7 +240,7 @@ _swrast_logicop_rgba_span(GLcontext *ctx, struct gl_renderbuffer *rb, } else { logicop_uint4(ctx, 4 * span->end, - (GLuint *) span->array->color.sz4.rgba, + (GLuint *) span->array->attribs[FRAG_ATTRIB_COL0], (const GLuint *) rbPixels, span->array->mask); } } diff --git a/src/mesa/swrast/s_masking.c b/src/mesa/swrast/s_masking.c index 65c984dd3e..8800f7d8e3 100644 --- a/src/mesa/swrast/s_masking.c +++ b/src/mesa/swrast/s_masking.c @@ -91,7 +91,7 @@ _swrast_mask_rgba_span(GLcontext *ctx, struct gl_renderbuffer *rb, const GLuint bMask = ctx->Color.ColorMask[BCOMP] ? ~0x0 : 0x0; const GLuint aMask = ctx->Color.ColorMask[ACOMP] ? ~0x0 : 0x0; const GLuint (*dst)[4] = (const GLuint (*)[4]) rbPixels; - GLuint (*src)[4] = (GLuint (*)[4]) span->array->color.sz4.rgba; + GLuint (*src)[4] = (GLuint (*)[4]) span->array->attribs[FRAG_ATTRIB_COL0]; GLuint i; for (i = 0; i < n; i++) { src[i][RCOMP] = (src[i][RCOMP] & rMask) | (dst[i][RCOMP] & ~rMask); diff --git a/src/mesa/swrast/s_pointtemp.h b/src/mesa/swrast/s_pointtemp.h index b41776b017..f68630af93 100644 --- a/src/mesa/swrast/s_pointtemp.h +++ b/src/mesa/swrast/s_pointtemp.h @@ -280,7 +280,7 @@ NAME ( GLcontext *ctx, const SWvertex *vert ) #if FLAGS & TEXTURE for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { if (ctx->Texture._EnabledCoordUnits & (1 << u)) { - COPY_4V(span->array->texcoords[u][count], texcoord[u]); + COPY_4V(span->array->attribs[FRAG_ATTRIB_TEX0 + u][count], texcoord[u]); span->array->lambda[u][count] = 0.0; } } @@ -342,14 +342,14 @@ NAME ( GLcontext *ctx, const SWvertex *vert ) r = vert->texcoord[u][0]; else /* GL_R */ r = vert->texcoord[u][2]; - span->array->texcoords[u][count][0] = s; - span->array->texcoords[u][count][1] = t; - span->array->texcoords[u][count][2] = r; - span->array->texcoords[u][count][3] = 1.0F; + span->array->attribs[FRAG_ATTRIB_TEX0 + u][count][0] = s; + span->array->attribs[FRAG_ATTRIB_TEX0 + u][count][1] = t; + span->array->attribs[FRAG_ATTRIB_TEX0 + u][count][2] = r; + span->array->attribs[FRAG_ATTRIB_TEX0 + u][count][3] = 1.0F; span->array->lambda[u][count] = 0.0; /* XXX fix? */ } else { - COPY_4V(span->array->texcoords[u][count], vert->texcoord[u]); + COPY_4V(span->array->attribs[FRAG_ATTRIB_TEX0 + u][count], vert->texcoord[u]); } } } @@ -402,7 +402,7 @@ NAME ( GLcontext *ctx, const SWvertex *vert ) #if FLAGS & TEXTURE for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { if (ctx->Texture.Unit[u]._ReallyEnabled) { - COPY_4V(span->array->texcoords[u][count], texcoord[u]); + COPY_4V(span->array->attribs[FRAG_ATTRIB_TEX0 + u][count], texcoord[u]); } } #endif diff --git a/src/mesa/swrast/s_readpix.c b/src/mesa/swrast/s_readpix.c index 128ce0afb3..75134ab462 100644 --- a/src/mesa/swrast/s_readpix.c +++ b/src/mesa/swrast/s_readpix.c @@ -394,7 +394,7 @@ read_rgba_pixels( GLcontext *ctx, /* no convolution */ const GLint dstStride = _mesa_image_row_stride(packing, width, format, type); - GLfloat (*rgba)[4] = swrast->SpanArrays->color.sz4.rgba; + GLfloat (*rgba)[4] = swrast->SpanArrays->attribs[FRAG_ATTRIB_COL0]; GLint row; GLubyte *dst = _mesa_image_address2d(packing, pixels, width, height, format, type, 0, 0); diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c index d97c1672c2..5c552e6288 100644 --- a/src/mesa/swrast/s_span.c +++ b/src/mesa/swrast/s_span.c @@ -239,7 +239,7 @@ interpolate_colors(SWspan *span) #endif case GL_FLOAT: { - GLfloat (*rgba)[4] = span->array->color.sz4.rgba; + GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; GLfloat r, g, b, a, dr, dg, db, da; r = span->red; g = span->green; @@ -351,7 +351,7 @@ interpolate_specular(SWspan *span) #endif case GL_FLOAT: { - GLfloat (*spec)[4] = span->array->color.sz4.spec; + GLfloat (*spec)[4] = span->array->attribs[FRAG_ATTRIB_COL1]; #if CHAN_BITS <= 16 GLfloat r = CHAN_TO_FLOAT(FixedToChan(span->specRed)); GLfloat g = CHAN_TO_FLOAT(FixedToChan(span->specGreen)); @@ -430,7 +430,7 @@ interpolate_indexes(GLcontext *ctx, SWspan *span) static INLINE void interpolate_fog(const GLcontext *ctx, SWspan *span) { - GLfloat *fog = span->array->fog; + GLfloat (*fog)[4] = span->array->attribs[FRAG_ATTRIB_FOGC]; const GLfloat fogStep = span->fogStep; GLfloat fogCoord = span->fog; const GLuint haveW = (span->interpMask & SPAN_W); @@ -438,7 +438,7 @@ interpolate_fog(const GLcontext *ctx, SWspan *span) GLfloat w = haveW ? span->w : 1.0F; GLuint i; for (i = 0; i < span->end; i++) { - fog[i] = fogCoord / w; + fog[i][0] = fogCoord / w; fogCoord += fogStep; w += wStep; } @@ -565,7 +565,7 @@ interpolate_texcoords(GLcontext *ctx, SWspan *span) needLambda = GL_FALSE; } if (needLambda) { - GLfloat (*texcoord)[4] = span->array->texcoords[u]; + GLfloat (*texcoord)[4] = span->array->attribs[FRAG_ATTRIB_TEX0 + u]; GLfloat *lambda = span->array->lambda[u]; const GLfloat dsdx = span->texStepX[u][0]; const GLfloat dsdy = span->texStepY[u][0]; @@ -620,7 +620,7 @@ interpolate_texcoords(GLcontext *ctx, SWspan *span) span->arrayMask |= SPAN_LAMBDA; } else { - GLfloat (*texcoord)[4] = span->array->texcoords[u]; + GLfloat (*texcoord)[4] = span->array->attribs[FRAG_ATTRIB_TEX0 + u]; GLfloat *lambda = span->array->lambda[u]; const GLfloat dsdx = span->texStepX[u][0]; const GLfloat dtdx = span->texStepX[u][1]; @@ -701,7 +701,7 @@ interpolate_texcoords(GLcontext *ctx, SWspan *span) span->arrayMask |= SPAN_TEXTURE; if (needLambda) { /* just texture unit 0, with lambda */ - GLfloat (*texcoord)[4] = span->array->texcoords[0]; + GLfloat (*texcoord)[4] = span->array->attribs[FRAG_ATTRIB_TEX0]; GLfloat *lambda = span->array->lambda[0]; const GLfloat dsdx = span->texStepX[0][0]; const GLfloat dsdy = span->texStepY[0][0]; @@ -757,7 +757,7 @@ interpolate_texcoords(GLcontext *ctx, SWspan *span) } else { /* just texture 0, without lambda */ - GLfloat (*texcoord)[4] = span->array->texcoords[0]; + GLfloat (*texcoord)[4] = span->array->attribs[FRAG_ATTRIB_TEX0]; const GLfloat dsdx = span->texStepX[0][0]; const GLfloat dtdx = span->texStepX[0][1]; const GLfloat drdx = span->texStepX[0][2]; @@ -841,7 +841,7 @@ interpolate_varying(GLcontext *ctx, SWspan *span) GLuint k; for (k = 0; k < span->end; k++) { GLfloat invW = 1.0f / w; - span->array->varying[var][k][j] = v * invW; + span->array->attribs[FRAG_ATTRIB_VAR0 + var][k][j] = v * invW; v += dvdx; w += dwdx; } @@ -851,6 +851,33 @@ interpolate_varying(GLcontext *ctx, SWspan *span) } +/** + * Fill in the arrays->attribs[FRAG_ATTRIB_WPOS] array. + */ +static INLINE void +interpolate_wpos(GLcontext *ctx, SWspan *span) +{ + GLfloat (*wpos)[4] = span->array->attribs[FRAG_ATTRIB_WPOS]; + GLuint i; + if (span->arrayMask & SPAN_XY) { + for (i = 0; i < span->end; i++) { + wpos[i][0] = (GLfloat) span->array->x[i]; + wpos[i][1] = (GLfloat) span->array->y[i]; + } + } + else { + for (i = 0; i < span->end; i++) { + wpos[i][0] = (GLfloat) span->x + i; + wpos[i][1] = (GLfloat) span->y; + } + } + for (i = 0; i < span->end; i++) { + wpos[i][2] = (GLfloat) span->array->z[i] / ctx->DrawBuffer->_DepthMaxF; + wpos[i][3] = span->w + i * span->dwdx; + } +} + + /** * Apply the current polygon stipple pattern to a span of pixels. */ @@ -1238,8 +1265,8 @@ add_specular(GLcontext *ctx, SWspan *span) break; case GL_FLOAT: { - GLfloat (*rgba)[4] = span->array->color.sz4.rgba; - GLfloat (*spec)[4] = span->array->color.sz4.spec; + GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; + GLfloat (*spec)[4] = span->array->attribs[FRAG_ATTRIB_COL1]; GLuint i; for (i = 0; i < span->end; i++) { rgba[i][RCOMP] += spec[i][RCOMP]; @@ -1280,7 +1307,7 @@ apply_aa_coverage(SWspan *span) } } else { - GLfloat (*rgba)[4] = span->array->color.sz4.rgba; + GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; for (i = 0; i < span->end; i++) { rgba[i][ACOMP] = rgba[i][ACOMP] * coverage[i]; } @@ -1294,7 +1321,7 @@ apply_aa_coverage(SWspan *span) static INLINE void clamp_colors(SWspan *span) { - GLfloat (*rgba)[4] = span->array->color.sz4.rgba; + GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; GLuint i; ASSERT(span->array->ChanType == GL_FLOAT); for (i = 0; i < span->end; i++) { @@ -1320,7 +1347,7 @@ convert_color_type(SWspan *span, GLenum newType) src = span->array->color.sz2.rgba; } else { - src = span->array->color.sz4.rgba; + src = span->array->attribs[FRAG_ATTRIB_COL0]; } if (newType == GL_UNSIGNED_BYTE) { dst = span->array->color.sz1.rgba; @@ -1329,7 +1356,7 @@ convert_color_type(SWspan *span, GLenum newType) dst = span->array->color.sz2.rgba; } else { - dst = span->array->color.sz4.rgba; + dst = span->array->attribs[FRAG_ATTRIB_COL0]; } _mesa_convert_colors(span->array->ChanType, src, @@ -1365,7 +1392,7 @@ shade_texture_span(GLcontext *ctx, SWspan *span) ? (GLvoid *) span->array->color.sz1.rgba : (GLvoid *) span->array->color.sz2.rgba; _mesa_convert_colors(oldType, src, - newType, span->array->color.sz4.rgba, + newType, span->array->attribs[FRAG_ATTRIB_COL0], span->end, span->array->mask); span->array->ChanType = newType; } @@ -1383,6 +1410,10 @@ shade_texture_span(GLcontext *ctx, SWspan *span) if (ctx->Shader.CurrentProgram && span->interpMask & SPAN_VARYING) interpolate_varying(ctx, span); + if (ctx->FragmentProgram._Current && + (ctx->FragmentProgram._Current->Base.InputsRead & FRAG_BIT_WPOS)) + interpolate_wpos(ctx, span); + /* Run fragment program/shader now */ if (ctx->FragmentProgram._Current) { _swrast_exec_fragment_program(ctx, span); @@ -1938,7 +1969,7 @@ _swrast_get_dest_rgba(GLcontext *ctx, struct gl_renderbuffer *rb, rbPixels = span->array->color.sz2.spec; } else { - rbPixels = span->array->color.sz4.spec; + rbPixels = span->array->attribs[FRAG_ATTRIB_COL1]; } /* Get destination values from renderbuffer */ diff --git a/src/mesa/swrast/s_span.h b/src/mesa/swrast/s_span.h index 7c514afb0b..292679bda1 100644 --- a/src/mesa/swrast/s_span.h +++ b/src/mesa/swrast/s_span.h @@ -32,7 +32,7 @@ /** - * \defgroup SpanFlags SPAN_*-flags + * \defgroup SpanFlags * Bitflags used for interpMask and arrayMask fields below to indicate * which interpolant values and fragment arrays are in use, respectively. */ @@ -60,12 +60,10 @@ struct arrays2 { union { GLubyte sz1[MAX_WIDTH][4]; /* primary color */ GLushort sz2[MAX_WIDTH][4]; - GLfloat sz4[MAX_WIDTH][4]; } rgba; union { GLubyte sz1[MAX_WIDTH][4]; /* specular color and temp storage */ GLushort sz2[MAX_WIDTH][4]; - GLfloat sz4[MAX_WIDTH][4]; } spec; }; #endif @@ -80,7 +78,14 @@ struct arrays2 { * filled in by glDraw/CopyPixels, etc. * These arrays are separated out of sw_span to conserve memory. */ -typedef struct sw_span_arrays { +typedef struct sw_span_arrays +{ + /** Per-fragment attributes (indexed by FRAG_ATTRIB_* tokens) */ + GLfloat attribs[FRAG_ATTRIB_MAX][MAX_WIDTH][4]; + + /** This mask indicates which fragments are alive or culled */ + GLubyte mask[MAX_WIDTH]; + GLenum ChanType; /**< Color channel type, GL_UNSIGNED_BYTE, GL_FLOAT */ union { struct { @@ -91,37 +96,17 @@ typedef struct sw_span_arrays { GLushort rgba[MAX_WIDTH][4]; GLushort spec[MAX_WIDTH][4]; } sz2; - struct { - GLfloat rgba[MAX_WIDTH][4]; - GLfloat spec[MAX_WIDTH][4]; - } sz4; } color; /** XXX these are temporary fields, pointing into above color arrays */ GLchan (*rgba)[4]; GLchan (*spec)[4]; -#if 0 - /* XXX rearrange and unify these arrays to so that we can - * index all fragment inputs with the FRAG_ATTRIB_* values: - */ - GLfloat attribs[FRAG_ATTRIB_MAX][MAX_WIDTH][4]; - /*OR*/ - typedef GLfloat (*array4f)[4]; - array4f attribs[FRAG_ATTRIB_MAX]; -#endif - GLint x[MAX_WIDTH]; /**< fragment X coords */ GLint y[MAX_WIDTH]; /**< fragment Y coords */ GLuint z[MAX_WIDTH]; /**< fragment Z coords */ GLuint index[MAX_WIDTH]; /**< Color indexes */ - GLfloat fog[MAX_WIDTH]; - GLfloat texcoords[MAX_TEXTURE_COORD_UNITS][MAX_WIDTH][4]; - GLfloat lambda[MAX_TEXTURE_COORD_UNITS][MAX_WIDTH]; + GLfloat lambda[MAX_TEXTURE_COORD_UNITS][MAX_WIDTH]; /**< Texture LOD */ GLfloat coverage[MAX_WIDTH]; /**< Fragment coverage for AA/smoothing */ - GLfloat varying[MAX_VARYING][MAX_WIDTH][4]; /**< For shaders */ - - /** This mask indicates which fragments are alive or culled */ - GLubyte mask[MAX_WIDTH]; } SWspanarrays; @@ -137,7 +122,8 @@ typedef struct sw_span_arrays { * stream of these structures which would be consumed by one or more * span-processing threads which could run in parallel. */ -typedef struct sw_span { +typedef struct sw_span +{ GLint x, y; /** Only need to process pixels between start <= i < end */ diff --git a/src/mesa/swrast/s_texcombine.c b/src/mesa/swrast/s_texcombine.c index 2a3455f35e..ebb4c0d936 100644 --- a/src/mesa/swrast/s_texcombine.c +++ b/src/mesa/swrast/s_texcombine.c @@ -1094,6 +1094,9 @@ _swrast_texture_span( GLcontext *ctx, SWspan *span ) */ for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { if (ctx->Texture.Unit[unit]._ReallyEnabled) { + const GLfloat (*texcoords)[4] + = (const GLfloat (*)[4]) + span->array->attribs[FRAG_ATTRIB_TEX0 + unit]; const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; const struct gl_texture_object *curObj = texUnit->_Current; GLfloat *lambda = span->array->lambda[unit]; @@ -1127,8 +1130,7 @@ _swrast_texture_span( GLcontext *ctx, SWspan *span ) /* Sample the texture (span->end = number of fragments) */ swrast->TextureSample[unit]( ctx, texUnit->_Current, span->end, - (const GLfloat (*)[4]) span->array->texcoords[unit], - lambda, texels ); + texcoords, lambda, texels ); /* GL_SGI_texture_color_table */ if (texUnit->ColorTableEnabled) { diff --git a/src/mesa/swrast/s_zoom.c b/src/mesa/swrast/s_zoom.c index 29b8df41b7..34732a67e6 100644 --- a/src/mesa/swrast/s_zoom.c +++ b/src/mesa/swrast/s_zoom.c @@ -230,7 +230,7 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span, GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x; ASSERT(j >= 0); ASSERT(j < span->end); - COPY_4V(zoomed.array->color.sz4.rgba[i], rgba[j]); + COPY_4V(zoomed.array->attribs[FRAG_ATTRIB_COL0][i], rgba[j]); } } } @@ -268,10 +268,10 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span, GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x; ASSERT(j >= 0); ASSERT(j < span->end); - zoomed.array->color.sz4.rgba[i][0] = rgb[j][0]; - zoomed.array->color.sz4.rgba[i][1] = rgb[j][1]; - zoomed.array->color.sz4.rgba[i][2] = rgb[j][2]; - zoomed.array->color.sz4.rgba[i][3] = 1.0F; + zoomed.array->attribs[FRAG_ATTRIB_COL0][i][0] = rgb[j][0]; + zoomed.array->attribs[FRAG_ATTRIB_COL0][i][1] = rgb[j][1]; + zoomed.array->attribs[FRAG_ATTRIB_COL0][i][2] = rgb[j][2]; + zoomed.array->attribs[FRAG_ATTRIB_COL0][i][3] = 1.0F; } } } -- cgit v1.2.3 From abeca8d17d0728e68ec0c7cb9d9ca91b06b560d0 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 1 Feb 2007 10:08:07 -0700 Subject: comments --- src/mesa/swrast/s_span.c | 6 ++++-- src/mesa/swrast/s_span.h | 3 +++ 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c index 5c552e6288..4a562752a8 100644 --- a/src/mesa/swrast/s_span.c +++ b/src/mesa/swrast/s_span.c @@ -599,7 +599,6 @@ interpolate_texcoords(GLcontext *ctx, SWspan *span) q += dqdx; w += dwdx; } - } else { for (i = 0; i < span->end; i++) { @@ -817,7 +816,10 @@ interpolate_texcoords(GLcontext *ctx, SWspan *span) /** - * Fill in the span.varying array from the interpolation values. + * Fill in the arrays->attribs[FRAG_ATTRIB_VARx] arrays from the + * interpolation values. + * XXX since interpolants/arrays are getting uniformed, we might merge + * this with interpolate_texcoords(), interpolate_Fog(), etc. someday. */ static INLINE void interpolate_varying(GLcontext *ctx, SWspan *span) diff --git a/src/mesa/swrast/s_span.h b/src/mesa/swrast/s_span.h index 292679bda1..ff91768001 100644 --- a/src/mesa/swrast/s_span.h +++ b/src/mesa/swrast/s_span.h @@ -81,6 +81,9 @@ struct arrays2 { typedef struct sw_span_arrays { /** Per-fragment attributes (indexed by FRAG_ATTRIB_* tokens) */ + /* XXX someday look at transposing first two indexes for better memory + * access pattern. + */ GLfloat attribs[FRAG_ATTRIB_MAX][MAX_WIDTH][4]; /** This mask indicates which fragments are alive or culled */ -- cgit v1.2.3 From 4e7fd7ad9604f6b9700a6011338c2bf1381b28da Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 2 Feb 2007 09:09:13 -0700 Subject: get rid of unused span->start field --- src/mesa/swrast/s_context.c | 1 - src/mesa/swrast/s_span.h | 6 ++---- 2 files changed, 2 insertions(+), 5 deletions(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/swrast/s_context.c b/src/mesa/swrast/s_context.c index 6e3475b130..ec2f3d68b8 100644 --- a/src/mesa/swrast/s_context.c +++ b/src/mesa/swrast/s_context.c @@ -704,7 +704,6 @@ _swrast_CreateContext( GLcontext *ctx ) /* init point span buffer */ swrast->PointSpan.primitive = GL_POINT; - swrast->PointSpan.start = 0; swrast->PointSpan.end = 0; swrast->PointSpan.facing = 0; swrast->PointSpan.array = swrast->SpanArrays; diff --git a/src/mesa/swrast/s_span.h b/src/mesa/swrast/s_span.h index ff91768001..c5f79871f1 100644 --- a/src/mesa/swrast/s_span.h +++ b/src/mesa/swrast/s_span.h @@ -129,9 +129,8 @@ typedef struct sw_span { GLint x, y; - /** Only need to process pixels between start <= i < end */ - /** At this time, start is always zero. */ - GLuint start, end; + /** Number of fragments in the span */ + GLuint end; /** This flag indicates that mask[] array is effectively filled with ones */ GLboolean writeAll; @@ -213,7 +212,6 @@ do { \ (S).primitive = (PRIMITIVE); \ (S).interpMask = (INTERP_MASK); \ (S).arrayMask = (ARRAY_MASK); \ - (S).start = 0; \ (S).end = (END); \ (S).facing = 0; \ (S).array = SWRAST_CONTEXT(ctx)->SpanArrays; \ -- cgit v1.2.3 From 462d8f5fafcc5ac69ea89cac1222abadded642e2 Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 2 Feb 2007 09:46:43 -0700 Subject: New span attrStart/attrStepX/attrStepY fields to replace fog, specular, etc. fields. More to come. --- src/mesa/swrast/s_fog.c | 20 +++++------ src/mesa/swrast/s_fragprog.c | 57 +++++++++++++++--------------- src/mesa/swrast/s_linetemp.h | 37 ++++++++++---------- src/mesa/swrast/s_pointtemp.h | 5 +-- src/mesa/swrast/s_span.c | 16 +++++---- src/mesa/swrast/s_span.h | 13 +++---- src/mesa/swrast/s_tritemp.h | 80 +++++++++++++++++++++---------------------- src/mesa/swrast/s_zoom.c | 5 +-- 8 files changed, 118 insertions(+), 115 deletions(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/swrast/s_fog.c b/src/mesa/swrast/s_fog.c index 93d2ab469f..a2bf4c620c 100644 --- a/src/mesa/swrast/s_fog.c +++ b/src/mesa/swrast/s_fog.c @@ -72,8 +72,8 @@ _swrast_z_to_fogfactor(GLcontext *ctx, GLfloat z) */ #define FOG_LOOP(TYPE, COMPUTE_F) \ do { \ - const GLfloat fogStep = span->fogStep; \ - GLfloat fogCoord = span->fog; \ + const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0]; \ + GLfloat fogCoord = span->attrStart[FRAG_ATTRIB_FOGC][0]; \ const GLfloat wStep = haveW ? span->dwdx : 0.0F; \ GLfloat w = haveW ? span->w : 1.0F; \ GLuint i; \ @@ -293,8 +293,8 @@ _swrast_fog_ci_span( const GLcontext *ctx, SWspan *span ) const GLfloat fogEnd = ctx->Fog.End; const GLfloat fogScale = (ctx->Fog.Start == ctx->Fog.End) ? 1.0F : 1.0F / (ctx->Fog.End - ctx->Fog.Start); - const GLfloat fogStep = span->fogStep; - GLfloat fogCoord = span->fog; + const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0]; + GLfloat fogCoord = span->attrStart[FRAG_ATTRIB_FOGC][0]; const GLfloat wStep = haveW ? span->dwdx : 0.0F; GLfloat w = haveW ? span->w : 1.0F; GLuint i; @@ -310,8 +310,8 @@ _swrast_fog_ci_span( const GLcontext *ctx, SWspan *span ) case GL_EXP: { const GLfloat density = -ctx->Fog.Density; - const GLfloat fogStep = span->fogStep; - GLfloat fogCoord = span->fog; + const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0]; + GLfloat fogCoord = span->attrStart[FRAG_ATTRIB_FOGC][0]; const GLfloat wStep = haveW ? span->dwdx : 0.0F; GLfloat w = haveW ? span->w : 1.0F; GLuint i; @@ -327,8 +327,8 @@ _swrast_fog_ci_span( const GLcontext *ctx, SWspan *span ) case GL_EXP2: { const GLfloat negDensitySquared = -ctx->Fog.Density * ctx->Fog.Density; - const GLfloat fogStep = span->fogStep; - GLfloat fogCoord = span->fog; + const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0]; + GLfloat fogCoord = span->attrStart[FRAG_ATTRIB_FOGC][0]; const GLfloat wStep = haveW ? span->dwdx : 0.0F; GLfloat w = haveW ? span->w : 1.0F; GLuint i; @@ -368,8 +368,8 @@ _swrast_fog_ci_span( const GLcontext *ctx, SWspan *span ) /* The span's fog start/step values are blend factors. * They were previously computed per-vertex. */ - const GLfloat fogStep = span->fogStep; - GLfloat fog = span->fog; + const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0]; + GLfloat fog = span->attrStart[FRAG_ATTRIB_FOGC][0]; const GLfloat wStep = haveW ? span->dwdx : 0.0F; GLfloat w = haveW ? span->w : 1.0F; GLuint i; diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c index 9ae423dde9..22483c56a6 100644 --- a/src/mesa/swrast/s_fragprog.c +++ b/src/mesa/swrast/s_fragprog.c @@ -287,27 +287,27 @@ fetch_vector4_deriv( GLcontext *ctx, break; case FRAG_ATTRIB_COL1: if (xOrY == 'X') { - src[0] = span->dsrdx * (1.0F / CHAN_MAXF); - src[1] = span->dsgdx * (1.0F / CHAN_MAXF); - src[2] = span->dsbdx * (1.0F / CHAN_MAXF); - src[3] = 0.0; /* XXX need this */ + src[0] = span->attrStepX[FRAG_ATTRIB_COL1][0] * (1.0F / CHAN_MAXF); + src[1] = span->attrStepX[FRAG_ATTRIB_COL1][1] * (1.0F / CHAN_MAXF); + src[2] = span->attrStepX[FRAG_ATTRIB_COL1][2] * (1.0F / CHAN_MAXF); + src[3] = span->attrStepX[FRAG_ATTRIB_COL1][3] * (1.0F / CHAN_MAXF); } else { - src[0] = span->dsrdy * (1.0F / CHAN_MAXF); - src[1] = span->dsgdy * (1.0F / CHAN_MAXF); - src[2] = span->dsbdy * (1.0F / CHAN_MAXF); - src[3] = 0.0; /* XXX need this */ + src[0] = span->attrStepY[FRAG_ATTRIB_COL1][0] * (1.0F / CHAN_MAXF); + src[1] = span->attrStepY[FRAG_ATTRIB_COL1][1] * (1.0F / CHAN_MAXF); + src[2] = span->attrStepY[FRAG_ATTRIB_COL1][2] * (1.0F / CHAN_MAXF); + src[3] = span->attrStepY[FRAG_ATTRIB_COL1][3] * (1.0F / CHAN_MAXF); } break; case FRAG_ATTRIB_FOGC: if (xOrY == 'X') { - src[0] = span->dfogdx; + src[0] = span->attrStepX[FRAG_ATTRIB_FOGC][0] * (1.0F / CHAN_MAXF); src[1] = 0.0; src[2] = 0.0; src[3] = 0.0; } else { - src[0] = span->dfogdy; + src[0] = span->attrStepY[FRAG_ATTRIB_FOGC][0] * (1.0F / CHAN_MAXF); src[1] = 0.0; src[2] = 0.0; src[3] = 0.0; @@ -589,25 +589,25 @@ init_machine_deriv( GLcontext *ctx, if (program->Base.InputsRead & FRAG_BIT_COL1) { GLfloat *col1 = machine->Attribs[FRAG_ATTRIB_COL1][machine->CurFrag]; if (xOrY == 'X') { - col1[0] += span->dsrdx * (1.0F / CHAN_MAXF); - col1[1] += span->dsgdx * (1.0F / CHAN_MAXF); - col1[2] += span->dsbdx * (1.0F / CHAN_MAXF); - col1[3] += 0.0; /*XXX fix */ + col1[0] += span->attrStepX[FRAG_ATTRIB_COL1][0] * (1.0F / CHAN_MAXF); + col1[1] += span->attrStepX[FRAG_ATTRIB_COL1][1] * (1.0F / CHAN_MAXF); + col1[2] += span->attrStepX[FRAG_ATTRIB_COL1][2] * (1.0F / CHAN_MAXF); + col1[3] += span->attrStepX[FRAG_ATTRIB_COL1][3] * (1.0F / CHAN_MAXF); } else { - col1[0] += span->dsrdy * (1.0F / CHAN_MAXF); - col1[1] += span->dsgdy * (1.0F / CHAN_MAXF); - col1[2] += span->dsbdy * (1.0F / CHAN_MAXF); - col1[3] += 0.0; /*XXX fix */ + col1[0] += span->attrStepY[FRAG_ATTRIB_COL1][0] * (1.0F / CHAN_MAXF); + col1[1] += span->attrStepY[FRAG_ATTRIB_COL1][1] * (1.0F / CHAN_MAXF); + col1[2] += span->attrStepY[FRAG_ATTRIB_COL1][2] * (1.0F / CHAN_MAXF); + col1[3] += span->attrStepY[FRAG_ATTRIB_COL1][3] * (1.0F / CHAN_MAXF); } } if (program->Base.InputsRead & FRAG_BIT_FOGC) { GLfloat *fogc = machine->Attribs[FRAG_ATTRIB_FOGC][machine->CurFrag]; if (xOrY == 'X') { - fogc[0] += span->dfogdx; + fogc[0] += span->attrStepX[FRAG_ATTRIB_FOGC][0]; } else { - fogc[0] += span->dfogdy; + fogc[0] += span->attrStepY[FRAG_ATTRIB_FOGC][0]; } } for (u = 0; u < ctx->Const.MaxTextureCoordUnits; u++) { @@ -632,17 +632,18 @@ init_machine_deriv( GLcontext *ctx, for (v = 0; v < ctx->Const.MaxVarying; v++) { if (program->Base.InputsRead & FRAG_BIT_VAR(v)) { GLfloat *var = machine->Attribs[FRAG_ATTRIB_VAR0 + v][machine->CurFrag]; + GLuint attr = FRAG_ATTRIB_VAR0 + v; if (xOrY == 'X') { - var[0] += span->varStepX[v][0]; - var[1] += span->varStepX[v][1]; - var[2] += span->varStepX[v][2]; - var[3] += span->varStepX[v][3]; + var[0] += span->attrStepX[attr][0]; + var[1] += span->attrStepX[attr][1]; + var[2] += span->attrStepX[attr][2]; + var[3] += span->attrStepX[attr][3]; } else { - var[0] += span->varStepY[v][0]; - var[1] += span->varStepY[v][1]; - var[2] += span->varStepY[v][2]; - var[3] += span->varStepY[v][3]; + var[0] += span->attrStepY[attr][0]; + var[1] += span->attrStepY[attr][1]; + var[2] += span->attrStepY[attr][2]; + var[3] += span->attrStepY[attr][3]; } } } diff --git a/src/mesa/swrast/s_linetemp.h b/src/mesa/swrast/s_linetemp.h index b7b434771e..d68868ded9 100644 --- a/src/mesa/swrast/s_linetemp.h +++ b/src/mesa/swrast/s_linetemp.h @@ -276,8 +276,8 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 ) #endif #ifdef INTERP_FOG interpFlags |= SPAN_FOG; - span.fog = vert0->fog; - span.fogStep = (vert1->fog - vert0->fog) / numPixels; + span.attrStart[FRAG_ATTRIB_FOGC][0] = vert0->fog; + span.attrStepX[FRAG_ATTRIB_FOGC][0] = (vert1->fog - vert0->fog) / numPixels; #endif #ifdef INTERP_TEX interpFlags |= SPAN_TEXTURE; @@ -345,23 +345,24 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 ) GLuint v; for (v = 0; v < MAX_VARYING; v++) { if (inputsUsed & FRAG_BIT_VAR(v)) { + GLuint attr = FRAG_ATTRIB_VAR0 + v; GLfloat ds, dt, dr, dq; - span.var[v][0] = invw0 * vert0->varying[v][0]; - span.var[v][1] = invw0 * vert0->varying[v][1]; - span.var[v][2] = invw0 * vert0->varying[v][2]; - span.var[v][3] = invw0 * vert0->varying[v][3]; - ds = (invw1 * vert1->varying[v][0]) - span.var[v][0]; - dt = (invw1 * vert1->varying[v][1]) - span.var[v][1]; - dr = (invw1 * vert1->varying[v][2]) - span.var[v][2]; - dq = (invw1 * vert1->varying[v][3]) - span.var[v][3]; - span.varStepX[v][0] = ds * invLen; - span.varStepX[v][1] = dt * invLen; - span.varStepX[v][2] = dr * invLen; - span.varStepX[v][3] = dq * invLen; - span.varStepY[v][0] = 0.0F; - span.varStepY[v][1] = 0.0F; - span.varStepY[v][2] = 0.0F; - span.varStepY[v][3] = 0.0F; + span.attrStart[attr][0] = invw0 * vert0->varying[v][0]; + span.attrStart[attr][1] = invw0 * vert0->varying[v][1]; + span.attrStart[attr][2] = invw0 * vert0->varying[v][2]; + span.attrStart[attr][3] = invw0 * vert0->varying[v][3]; + ds = (invw1 * vert1->varying[v][0]) - span.attrStart[attr][0]; + dt = (invw1 * vert1->varying[v][1]) - span.attrStart[attr][1]; + dr = (invw1 * vert1->varying[v][2]) - span.attrStart[attr][2]; + dq = (invw1 * vert1->varying[v][3]) - span.attrStart[attr][3]; + span.attrStepX[attr][0] = ds * invLen; + span.attrStepX[attr][1] = dt * invLen; + span.attrStepX[attr][2] = dr * invLen; + span.attrStepX[attr][3] = dq * invLen; + span.attrStepY[attr][0] = 0.0F; + span.attrStepY[attr][1] = 0.0F; + span.attrStepY[attr][2] = 0.0F; + span.attrStepY[attr][3] = 0.0F; } } } diff --git a/src/mesa/swrast/s_pointtemp.h b/src/mesa/swrast/s_pointtemp.h index f68630af93..f769f524a0 100644 --- a/src/mesa/swrast/s_pointtemp.h +++ b/src/mesa/swrast/s_pointtemp.h @@ -107,8 +107,9 @@ NAME ( GLcontext *ctx, const SWvertex *vert ) */ span->interpMask = SPAN_FOG; span->arrayMask = SPAN_XY | SPAN_Z; - span->fog = vert->fog; - span->fogStep = 0.0; + span->attrStart[FRAG_ATTRIB_FOGC][0] = vert->fog; + span->attrStepX[FRAG_ATTRIB_FOGC][0] = 0.0; + span->attrStepY[FRAG_ATTRIB_FOGC][0] = 0.0; #if FLAGS & RGBA span->arrayMask |= SPAN_RGBA; #endif diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c index 4a562752a8..52c7501df8 100644 --- a/src/mesa/swrast/s_span.c +++ b/src/mesa/swrast/s_span.c @@ -75,8 +75,9 @@ _swrast_span_default_z( GLcontext *ctx, SWspan *span ) void _swrast_span_default_fog( GLcontext *ctx, SWspan *span ) { - span->fog = _swrast_z_to_fogfactor(ctx, ctx->Current.RasterDistance); - span->fogStep = span->dfogdx = span->dfogdy = 0.0F; + span->attrStart[FRAG_ATTRIB_FOGC][0] = _swrast_z_to_fogfactor(ctx, ctx->Current.RasterDistance); + span->attrStepX[FRAG_ATTRIB_FOGC][0] = 0.0; + span->attrStepY[FRAG_ATTRIB_FOGC][0] = 0.0; span->interpMask |= SPAN_FOG; } @@ -431,8 +432,8 @@ static INLINE void interpolate_fog(const GLcontext *ctx, SWspan *span) { GLfloat (*fog)[4] = span->array->attribs[FRAG_ATTRIB_FOGC]; - const GLfloat fogStep = span->fogStep; - GLfloat fogCoord = span->fog; + const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0]; + GLfloat fogCoord = span->attrStart[FRAG_ATTRIB_FOGC][0]; const GLuint haveW = (span->interpMask & SPAN_W); const GLfloat wStep = haveW ? span->dwdx : 0.0F; GLfloat w = haveW ? span->w : 1.0F; @@ -834,16 +835,17 @@ interpolate_varying(GLcontext *ctx, SWspan *span) for (var = 0; var < MAX_VARYING; var++) { if (inputsUsed & FRAG_BIT_VAR(var)) { + const GLuint attr = FRAG_ATTRIB_VAR0 + var; GLuint j; for (j = 0; j < 4; j++) { - const GLfloat dvdx = span->varStepX[var][j]; - GLfloat v = span->var[var][j]; + const GLfloat dvdx = span->attrStepX[attr][j]; + GLfloat v = span->attrStart[attr][j]; const GLfloat dwdx = span->dwdx; GLfloat w = span->w; GLuint k; for (k = 0; k < span->end; k++) { GLfloat invW = 1.0f / w; - span->array->attribs[FRAG_ATTRIB_VAR0 + var][k][j] = v * invW; + span->array->attribs[attr][k][j] = v * invW; v += dvdx; w += dwdx; } diff --git a/src/mesa/swrast/s_span.h b/src/mesa/swrast/s_span.h index c5f79871f1..f60d4279e1 100644 --- a/src/mesa/swrast/s_span.h +++ b/src/mesa/swrast/s_span.h @@ -169,14 +169,15 @@ typedef struct sw_span #endif GLfixed index, indexStep; GLfixed z, zStep; /* XXX z should probably be GLuint */ - GLfloat fog, fogStep; GLfloat tex[MAX_TEXTURE_COORD_UNITS][4]; /* s, t, r, q */ GLfloat texStepX[MAX_TEXTURE_COORD_UNITS][4]; GLfloat texStepY[MAX_TEXTURE_COORD_UNITS][4]; GLfixed intTex[2], intTexStep[2]; /* s, t only */ - GLfloat var[MAX_VARYING][4]; - GLfloat varStepX[MAX_VARYING][4]; - GLfloat varStepY[MAX_VARYING][4]; + + /** Fragment attribute interpolants */ + GLfloat attrStart[FRAG_ATTRIB_MAX][4]; /**< initial value */ + GLfloat attrStepX[FRAG_ATTRIB_MAX][4]; /**< dvalue/dx */ + GLfloat attrStepY[FRAG_ATTRIB_MAX][4]; /**< dvalue/dy */ /* partial derivatives wrt X and Y. */ GLfloat dzdx, dzdy; @@ -185,10 +186,6 @@ typedef struct sw_span GLfloat dgdx, dgdy; GLfloat dbdx, dbdy; GLfloat dadx, dady; - GLfloat dsrdx, dsrdy; - GLfloat dsgdx, dsgdy; - GLfloat dsbdx, dsbdy; - GLfloat dfogdx, dfogdy; /** * This bitmask (of \link SpanFlags SPAN_* flags\endlink) indicates diff --git a/src/mesa/swrast/s_tritemp.h b/src/mesa/swrast/s_tritemp.h index 6ff52b5e4a..c8fe4b6e9e 100644 --- a/src/mesa/swrast/s_tritemp.h +++ b/src/mesa/swrast/s_tritemp.h @@ -150,6 +150,7 @@ GLuint iv, ic; \ for (iv = 0; iv < MAX_VARYING; iv++) { \ if (inputsUsed & FRAG_BIT_VAR(iv)) { \ + GLuint attr = FRAG_ATTRIB_VAR0 + iv; \ for (ic = 0; ic < 4; ic++) { \ CODE \ } \ @@ -507,9 +508,8 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, const GLfloat eMaj_dfog = vMax->fog - vMin->fog; const GLfloat eBot_dfog = vMid->fog - vMin->fog; # endif - span.dfogdx = oneOverArea * (eMaj_dfog * eBot.dy - eMaj.dy * eBot_dfog); - span.dfogdy = oneOverArea * (eMaj.dx * eBot_dfog - eMaj_dfog * eBot.dx); - span.fogStep = span.dfogdx; + span.attrStepX[FRAG_ATTRIB_FOGC][0] = oneOverArea * (eMaj_dfog * eBot.dy - eMaj.dy * eBot_dfog); + span.attrStepY[FRAG_ATTRIB_FOGC][0] = oneOverArea * (eMaj.dx * eBot_dfog - eMaj_dfog * eBot.dx); } #endif #ifdef INTERP_RGB @@ -584,26 +584,26 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, GLfloat eBot_dsg = (GLfloat) ((ColorTemp) vMid->specular[GCOMP] - (ColorTemp) vMin->specular[GCOMP]); GLfloat eMaj_dsb = (GLfloat) ((ColorTemp) vMax->specular[BCOMP] - (ColorTemp) vMin->specular[BCOMP]); GLfloat eBot_dsb = (GLfloat) ((ColorTemp) vMid->specular[BCOMP] - (ColorTemp) vMin->specular[BCOMP]); - span.dsrdx = oneOverArea * (eMaj_dsr * eBot.dy - eMaj.dy * eBot_dsr); - span.dsrdy = oneOverArea * (eMaj.dx * eBot_dsr - eMaj_dsr * eBot.dx); - span.dsgdx = oneOverArea * (eMaj_dsg * eBot.dy - eMaj.dy * eBot_dsg); - span.dsgdy = oneOverArea * (eMaj.dx * eBot_dsg - eMaj_dsg * eBot.dx); - span.dsbdx = oneOverArea * (eMaj_dsb * eBot.dy - eMaj.dy * eBot_dsb); - span.dsbdy = oneOverArea * (eMaj.dx * eBot_dsb - eMaj_dsb * eBot.dx); + span.attrStepX[FRAG_ATTRIB_COL1][0] = oneOverArea * (eMaj_dsr * eBot.dy - eMaj.dy * eBot_dsr); + span.attrStepY[FRAG_ATTRIB_COL1][0] = oneOverArea * (eMaj.dx * eBot_dsr - eMaj_dsr * eBot.dx); + span.attrStepX[FRAG_ATTRIB_COL1][1] = oneOverArea * (eMaj_dsg * eBot.dy - eMaj.dy * eBot_dsg); + span.attrStepY[FRAG_ATTRIB_COL1][1] = oneOverArea * (eMaj.dx * eBot_dsg - eMaj_dsg * eBot.dx); + span.attrStepX[FRAG_ATTRIB_COL1][2] = oneOverArea * (eMaj_dsb * eBot.dy - eMaj.dy * eBot_dsb); + span.attrStepY[FRAG_ATTRIB_COL1][2] = oneOverArea * (eMaj.dx * eBot_dsb - eMaj_dsb * eBot.dx); # if CHAN_TYPE == GL_FLOAT - span.specRedStep = span.dsrdx; + span.specRedStep = span.attrStep[FRAG_ATTRIB_COL1][0]; span.specGreenStep = span.dsgdx; span.specBlueStep = span.dsbdx; # else - span.specRedStep = SignedFloatToFixed(span.dsrdx); - span.specGreenStep = SignedFloatToFixed(span.dsgdx); - span.specBlueStep = SignedFloatToFixed(span.dsbdx); + span.specRedStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL1][0]); + span.specGreenStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL1][1]); + span.specBlueStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL1][2]); # endif } else { - span.dsrdx = span.dsrdy = 0.0F; - span.dsgdx = span.dsgdy = 0.0F; - span.dsbdx = span.dsbdy = 0.0F; + span.attrStepX[FRAG_ATTRIB_COL1][0] = span.attrStepY[FRAG_ATTRIB_COL1][0] = 0.0F; + span.attrStepX[FRAG_ATTRIB_COL1][1] = span.attrStepY[FRAG_ATTRIB_COL1][1] = 0.0F; + span.attrStepX[FRAG_ATTRIB_COL1][2] = span.attrStepY[FRAG_ATTRIB_COL1][2] = 0.0F; # if CHAN_TYPE == GL_FLOAT span.specRedStep = 0.0F; span.specGreenStep = 0.0F; @@ -678,8 +678,8 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, VARYING_LOOP( GLfloat eMaj_dvar = vMax->varying[iv][ic] * wMax - vMin->varying[iv][ic] * wMin; GLfloat eBot_dvar = vMid->varying[iv][ic] * wMid - vMin->varying[iv][ic] * wMin; - span.varStepX[iv][ic] = oneOverArea * (eMaj_dvar * eBot.dy - eMaj.dy * eBot_dvar); - span.varStepY[iv][ic] = oneOverArea * (eMaj.dx * eBot_dvar - eMaj_dvar * eBot.dx); + span.attrStepX[attr][ic] = oneOverArea * (eMaj_dvar * eBot.dy - eMaj.dy * eBot_dvar); + span.attrStepY[attr][ic] = oneOverArea * (eMaj.dx * eBot_dvar - eMaj_dvar * eBot.dx); ) } #endif @@ -928,11 +928,11 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, #endif #ifdef INTERP_FOG # ifdef INTERP_W - fogLeft = vLower->fog * vLower->win[3] + (span.dfogdx * adjx + span.dfogdy * adjy) * (1.0F/FIXED_SCALE); + fogLeft = vLower->fog * vLower->win[3] + (span.attrStepX[FRAG_ATTRIB_FOGC][0] * adjx + span.attrStepY[FRAG_ATTRIB_FOGC][0] * adjy) * (1.0F/FIXED_SCALE); # else - fogLeft = vLower->fog + (span.dfogdx * adjx + span.dfogdy * adjy) * (1.0F/FIXED_SCALE); + fogLeft = vLower->fog + (span.attrStepX[FRAG_ATTRIB_FOGC][0] * adjx + span.attrStepY[FRAG_ATTRIB_FOGC][0] * adjy) * (1.0F/FIXED_SCALE); # endif - dfogOuter = span.dfogdy + dxOuter * span.dfogdx; + dfogOuter = span.attrStepY[FRAG_ATTRIB_FOGC][0] + dxOuter * span.attrStepX[FRAG_ATTRIB_FOGC][0]; #endif #ifdef INTERP_RGB if (ctx->Light.ShadeModel == GL_SMOOTH) { @@ -990,19 +990,19 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, #ifdef INTERP_SPEC if (ctx->Light.ShadeModel == GL_SMOOTH) { # if CHAN_TYPE == GL_FLOAT - srLeft = vLower->specular[RCOMP] + (span.dsrdx * adjx + span.dsrdy * adjy) * (1.0F / FIXED_SCALE); - sgLeft = vLower->specular[GCOMP] + (span.dsgdx * adjx + span.dsgdy * adjy) * (1.0F / FIXED_SCALE); - sbLeft = vLower->specular[BCOMP] + (span.dsbdx * adjx + span.dsbdy * adjy) * (1.0F / FIXED_SCALE); - dsrOuter = span.dsrdy + dxOuter * span.dsrdx; - dsgOuter = span.dsgdy + dxOuter * span.dsgdx; - dsbOuter = span.dsbdy + dxOuter * span.dsbdx; + srLeft = vLower->specular[RCOMP] + (span.attrStepX[FRAG_ATTRIB_COL1][0] * adjx + span.attrStepY[FRAG_ATTRIB_COL1][0] * adjy) * (1.0F / FIXED_SCALE); + sgLeft = vLower->specular[GCOMP] + (span.attrStepX[FRAG_ATTRIB_COL1][1] * adjx + span.attrStepY[FRAG_ATTRIB_COL1][1] * adjy) * (1.0F / FIXED_SCALE); + sbLeft = vLower->specular[BCOMP] + (span.attrStepX[FRAG_ATTRIB_COL1][2] * adjx + span.attrStepY[FRAG_ATTRIB_COL1][2] * adjy) * (1.0F / FIXED_SCALE); + dsrOuter = span.attrStepY[FRAG_ATTRIB_COL1][0] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL1][0]; + dsgOuter = span.attrStepY[FRAG_ATTRIB_COL1][1] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL1][1]; + dsbOuter = span.attrStepY[FRAG_ATTRIB_COL1][2] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL1][2]; # else - srLeft = (GLfixed) (ChanToFixed(vLower->specular[RCOMP]) + span.dsrdx * adjx + span.dsrdy * adjy) + FIXED_HALF; - sgLeft = (GLfixed) (ChanToFixed(vLower->specular[GCOMP]) + span.dsgdx * adjx + span.dsgdy * adjy) + FIXED_HALF; - sbLeft = (GLfixed) (ChanToFixed(vLower->specular[BCOMP]) + span.dsbdx * adjx + span.dsbdy * adjy) + FIXED_HALF; - dsrOuter = SignedFloatToFixed(span.dsrdy + dxOuter * span.dsrdx); - dsgOuter = SignedFloatToFixed(span.dsgdy + dxOuter * span.dsgdx); - dsbOuter = SignedFloatToFixed(span.dsbdy + dxOuter * span.dsbdx); + srLeft = (GLfixed) (ChanToFixed(vLower->specular[RCOMP]) + span.attrStepX[FRAG_ATTRIB_COL1][0] * adjx + span.attrStepY[FRAG_ATTRIB_COL1][0] * adjy) + FIXED_HALF; + sgLeft = (GLfixed) (ChanToFixed(vLower->specular[GCOMP]) + span.attrStepX[FRAG_ATTRIB_COL1][1] * adjx + span.attrStepY[FRAG_ATTRIB_COL1][1] * adjy) + FIXED_HALF; + sbLeft = (GLfixed) (ChanToFixed(vLower->specular[BCOMP]) + span.attrStepX[FRAG_ATTRIB_COL1][2] * adjx + span.attrStepY[FRAG_ATTRIB_COL1][2] * adjy) + FIXED_HALF; + dsrOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL1][0] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL1][0]); + dsgOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL1][1] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL1][1]); + dsbOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL1][2] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL1][2]); # endif } else { @@ -1068,9 +1068,9 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, VARYING_LOOP( const GLfloat invW = vLower->win[3]; const GLfloat var0 = vLower->varying[iv][ic] * invW; - varLeft[iv][ic] = var0 + (span.varStepX[iv][ic] * adjx + - span.varStepY[iv][ic] * adjy) * (1.0f / FIXED_SCALE); - dvarOuter[iv][ic] = span.varStepY[iv][ic] + dxOuter * span.varStepX[iv][ic]; + varLeft[iv][ic] = var0 + (span.attrStepX[attr][ic] * adjx + + span.attrStepY[attr][ic] * adjy) * (1.0f / FIXED_SCALE); + dvarOuter[iv][ic] = span.attrStepY[attr][ic] + dxOuter * span.attrStepX[attr][ic]; ) #endif } /*if setupLeft*/ @@ -1105,7 +1105,7 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, dwInner = dwOuter + span.dwdx; #endif #ifdef INTERP_FOG - dfogInner = dfogOuter + span.dfogdx; + dfogInner = dfogOuter + span.attrStepX[FRAG_ATTRIB_FOGC][0]; #endif #ifdef INTERP_RGB fdrInner = fdrOuter + span.redStep; @@ -1137,7 +1137,7 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, #endif #ifdef INTERP_VARYING VARYING_LOOP( - dvarInner[iv][ic] = dvarOuter[iv][ic] + span.varStepX[iv][ic]; + dvarInner[iv][ic] = dvarOuter[iv][ic] + span.attrStepX[attr][ic]; ) #endif @@ -1158,7 +1158,7 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, span.w = wLeft; #endif #ifdef INTERP_FOG - span.fog = fogLeft; + span.attrStart[FRAG_ATTRIB_FOGC][0] = fogLeft; #endif #ifdef INTERP_RGB span.red = rLeft; @@ -1191,7 +1191,7 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, #endif #ifdef INTERP_VARYING VARYING_LOOP( - span.var[iv][ic] = varLeft[iv][ic]; + span.attrStart[attr][ic] = varLeft[iv][ic]; ) #endif diff --git a/src/mesa/swrast/s_zoom.c b/src/mesa/swrast/s_zoom.c index 34732a67e6..a4e8d9a36f 100644 --- a/src/mesa/swrast/s_zoom.c +++ b/src/mesa/swrast/s_zoom.c @@ -159,8 +159,9 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span, /* copy fog interp info */ - zoomed.fog = span->fog; - zoomed.fogStep = span->fogStep; + zoomed.attrStart[FRAG_ATTRIB_FOGC][0] = span->attrStart[FRAG_ATTRIB_FOGC][0]; + zoomed.attrStepX[FRAG_ATTRIB_FOGC][0] = span->attrStepX[FRAG_ATTRIB_FOGC][0]; + zoomed.attrStepY[FRAG_ATTRIB_FOGC][0] = span->attrStepY[FRAG_ATTRIB_FOGC][0]; /* XXX copy texcoord info? */ if (format == GL_RGBA || format == GL_RGB) { -- cgit v1.2.3 From 9ab512ad8cf3a12f4f7f8494fa99bc9389f217db Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 2 Feb 2007 11:01:01 -0700 Subject: Replace color, z, w, texture interpolants with new generic attrib interpolants. --- src/mesa/swrast/s_fog.c | 20 ++-- src/mesa/swrast/s_fragprog.c | 91 +++++++++--------- src/mesa/swrast/s_linetemp.h | 71 +++++++------- src/mesa/swrast/s_pointtemp.h | 6 +- src/mesa/swrast/s_span.c | 121 ++++++++++++------------ src/mesa/swrast/s_span.h | 26 ++---- src/mesa/swrast/s_triangle.c | 14 +-- src/mesa/swrast/s_tritemp.h | 208 ++++++++++++++++++++++-------------------- 8 files changed, 280 insertions(+), 277 deletions(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/swrast/s_fog.c b/src/mesa/swrast/s_fog.c index a2bf4c620c..433fc4a4d0 100644 --- a/src/mesa/swrast/s_fog.c +++ b/src/mesa/swrast/s_fog.c @@ -74,8 +74,8 @@ _swrast_z_to_fogfactor(GLcontext *ctx, GLfloat z) do { \ const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0]; \ GLfloat fogCoord = span->attrStart[FRAG_ATTRIB_FOGC][0]; \ - const GLfloat wStep = haveW ? span->dwdx : 0.0F; \ - GLfloat w = haveW ? span->w : 1.0F; \ + const GLfloat wStep = haveW ? span->attrStepX[FRAG_ATTRIB_WPOS][3] : 0.0F;\ + GLfloat w = haveW ? span->attrStart[FRAG_ATTRIB_WPOS][3] : 1.0F; \ GLuint i; \ for (i = 0; i < span->end; i++) { \ GLfloat f, oneMinusF; \ @@ -295,8 +295,8 @@ _swrast_fog_ci_span( const GLcontext *ctx, SWspan *span ) ? 1.0F : 1.0F / (ctx->Fog.End - ctx->Fog.Start); const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0]; GLfloat fogCoord = span->attrStart[FRAG_ATTRIB_FOGC][0]; - const GLfloat wStep = haveW ? span->dwdx : 0.0F; - GLfloat w = haveW ? span->w : 1.0F; + const GLfloat wStep = haveW ? span->attrStepX[FRAG_ATTRIB_WPOS][3] : 0.0F; + GLfloat w = haveW ? span->attrStart[FRAG_ATTRIB_WPOS][3] : 1.0F; GLuint i; for (i = 0; i < span->end; i++) { GLfloat f = (fogEnd - fogCoord / w) * fogScale; @@ -312,8 +312,8 @@ _swrast_fog_ci_span( const GLcontext *ctx, SWspan *span ) const GLfloat density = -ctx->Fog.Density; const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0]; GLfloat fogCoord = span->attrStart[FRAG_ATTRIB_FOGC][0]; - const GLfloat wStep = haveW ? span->dwdx : 0.0F; - GLfloat w = haveW ? span->w : 1.0F; + const GLfloat wStep = haveW ? span->attrStepX[FRAG_ATTRIB_WPOS][3] : 0.0F; + GLfloat w = haveW ? span->attrStart[FRAG_ATTRIB_WPOS][3] : 1.0F; GLuint i; for (i = 0; i < span->end; i++) { GLfloat f = EXPF(density * fogCoord / w); @@ -329,8 +329,8 @@ _swrast_fog_ci_span( const GLcontext *ctx, SWspan *span ) const GLfloat negDensitySquared = -ctx->Fog.Density * ctx->Fog.Density; const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0]; GLfloat fogCoord = span->attrStart[FRAG_ATTRIB_FOGC][0]; - const GLfloat wStep = haveW ? span->dwdx : 0.0F; - GLfloat w = haveW ? span->w : 1.0F; + const GLfloat wStep = haveW ? span->attrStepX[FRAG_ATTRIB_WPOS][3] : 0.0F; + GLfloat w = haveW ? span->attrStart[FRAG_ATTRIB_WPOS][3] : 1.0F; GLuint i; for (i = 0; i < span->end; i++) { const GLfloat coord = fogCoord / w; @@ -370,8 +370,8 @@ _swrast_fog_ci_span( const GLcontext *ctx, SWspan *span ) */ const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0]; GLfloat fog = span->attrStart[FRAG_ATTRIB_FOGC][0]; - const GLfloat wStep = haveW ? span->dwdx : 0.0F; - GLfloat w = haveW ? span->w : 1.0F; + const GLfloat wStep = haveW ? span->attrStepX[FRAG_ATTRIB_WPOS][3] : 0.0F; + GLfloat w = haveW ? span->attrStart[FRAG_ATTRIB_WPOS][3] : 1.0F; GLuint i; ASSERT(span->interpMask & SPAN_FOG); for (i = 0; i < span->end; i++) { diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c index 22483c56a6..090fd6dd97 100644 --- a/src/mesa/swrast/s_fragprog.c +++ b/src/mesa/swrast/s_fragprog.c @@ -261,28 +261,30 @@ fetch_vector4_deriv( GLcontext *ctx, if (xOrY == 'X') { src[0] = 1.0; src[1] = 0.0; - src[2] = span->dzdx / ctx->DrawBuffer->_DepthMaxF; - src[3] = span->dwdx; + src[2] = span->attrStepX[FRAG_ATTRIB_WPOS][2] + / ctx->DrawBuffer->_DepthMaxF; + src[3] = span->attrStepX[FRAG_ATTRIB_WPOS][3]; } else { src[0] = 0.0; src[1] = 1.0; - src[2] = span->dzdy / ctx->DrawBuffer->_DepthMaxF; - src[3] = span->dwdy; + src[2] = span->attrStepY[FRAG_ATTRIB_WPOS][2] + / ctx->DrawBuffer->_DepthMaxF; + src[3] = span->attrStepY[FRAG_ATTRIB_WPOS][3]; } break; case FRAG_ATTRIB_COL0: if (xOrY == 'X') { - src[0] = span->drdx * (1.0F / CHAN_MAXF); - src[1] = span->dgdx * (1.0F / CHAN_MAXF); - src[2] = span->dbdx * (1.0F / CHAN_MAXF); - src[3] = span->dadx * (1.0F / CHAN_MAXF); + src[0] = span->attrStepX[FRAG_ATTRIB_COL0][0] * (1.0F / CHAN_MAXF); + src[1] = span->attrStepX[FRAG_ATTRIB_COL0][1] * (1.0F / CHAN_MAXF); + src[2] = span->attrStepX[FRAG_ATTRIB_COL0][2] * (1.0F / CHAN_MAXF); + src[3] = span->attrStepX[FRAG_ATTRIB_COL0][3] * (1.0F / CHAN_MAXF); } else { - src[0] = span->drdy * (1.0F / CHAN_MAXF); - src[1] = span->dgdy * (1.0F / CHAN_MAXF); - src[2] = span->dbdy * (1.0F / CHAN_MAXF); - src[3] = span->dady * (1.0F / CHAN_MAXF); + src[0] = span->attrStepY[FRAG_ATTRIB_COL0][0] * (1.0F / CHAN_MAXF); + src[1] = span->attrStepY[FRAG_ATTRIB_COL0][1] * (1.0F / CHAN_MAXF); + src[2] = span->attrStepY[FRAG_ATTRIB_COL0][2] * (1.0F / CHAN_MAXF); + src[3] = span->attrStepY[FRAG_ATTRIB_COL0][3] * (1.0F / CHAN_MAXF); } break; case FRAG_ATTRIB_COL1: @@ -322,23 +324,22 @@ fetch_vector4_deriv( GLcontext *ctx, case FRAG_ATTRIB_TEX6: case FRAG_ATTRIB_TEX7: if (xOrY == 'X') { - const GLuint u = source->Index - FRAG_ATTRIB_TEX0; /* this is a little tricky - I think I've got it right */ - const GLfloat invQ = 1.0f / (span->tex[u][3] - + span->texStepX[u][3] * column); - src[0] = span->texStepX[u][0] * invQ; - src[1] = span->texStepX[u][1] * invQ; - src[2] = span->texStepX[u][2] * invQ; - src[3] = span->texStepX[u][3] * invQ; + const GLfloat invQ = 1.0f / (span->attrStart[source->Index][3] + + span->attrStepX[source->Index][3] * column); + src[0] = span->attrStepX[source->Index][0] * invQ; + src[1] = span->attrStepX[source->Index][1] * invQ; + src[2] = span->attrStepX[source->Index][2] * invQ; + src[3] = span->attrStepX[source->Index][3] * invQ; } else { - const GLuint u = source->Index - FRAG_ATTRIB_TEX0; /* Tricky, as above, but in Y direction */ - const GLfloat invQ = 1.0f / (span->tex[u][3] + span->texStepY[u][3]); - src[0] = span->texStepY[u][0] * invQ; - src[1] = span->texStepY[u][1] * invQ; - src[2] = span->texStepY[u][2] * invQ; - src[3] = span->texStepY[u][3] * invQ; + const GLfloat invQ = 1.0f / (span->attrStart[source->Index][3] + + span->attrStepY[source->Index][3]); + src[0] = span->attrStepY[source->Index][0] * invQ; + src[1] = span->attrStepY[source->Index][1] * invQ; + src[2] = span->attrStepY[source->Index][2] * invQ; + src[3] = span->attrStepY[source->Index][3] * invQ; } break; default: @@ -561,29 +562,29 @@ init_machine_deriv( GLcontext *ctx, if (xOrY == 'X') { wpos[0] += 1.0F; wpos[1] += 0.0F; - wpos[2] += span->dzdx; - wpos[3] += span->dwdx; + wpos[2] += span->attrStepX[FRAG_ATTRIB_WPOS][2]; + wpos[3] += span->attrStepX[FRAG_ATTRIB_WPOS][3]; } else { wpos[0] += 0.0F; wpos[1] += 1.0F; - wpos[2] += span->dzdy; - wpos[3] += span->dwdy; + wpos[2] += span->attrStepY[FRAG_ATTRIB_WPOS][2]; + wpos[3] += span->attrStepY[FRAG_ATTRIB_WPOS][3]; } } if (program->Base.InputsRead & FRAG_BIT_COL0) { GLfloat *col0 = machine->Attribs[FRAG_ATTRIB_COL0][machine->CurFrag]; if (xOrY == 'X') { - col0[0] += span->drdx * (1.0F / CHAN_MAXF); - col0[1] += span->dgdx * (1.0F / CHAN_MAXF); - col0[2] += span->dbdx * (1.0F / CHAN_MAXF); - col0[3] += span->dadx * (1.0F / CHAN_MAXF); + col0[0] += span->attrStepX[FRAG_ATTRIB_COL0][0] * (1.0F / CHAN_MAXF); + col0[1] += span->attrStepX[FRAG_ATTRIB_COL0][1] * (1.0F / CHAN_MAXF); + col0[2] += span->attrStepX[FRAG_ATTRIB_COL0][2] * (1.0F / CHAN_MAXF); + col0[3] += span->attrStepX[FRAG_ATTRIB_COL0][3] * (1.0F / CHAN_MAXF); } else { - col0[0] += span->drdy * (1.0F / CHAN_MAXF); - col0[1] += span->dgdy * (1.0F / CHAN_MAXF); - col0[2] += span->dbdy * (1.0F / CHAN_MAXF); - col0[3] += span->dady * (1.0F / CHAN_MAXF); + col0[0] += span->attrStepY[FRAG_ATTRIB_COL0][0] * (1.0F / CHAN_MAXF); + col0[1] += span->attrStepY[FRAG_ATTRIB_COL0][1] * (1.0F / CHAN_MAXF); + col0[2] += span->attrStepY[FRAG_ATTRIB_COL0][2] * (1.0F / CHAN_MAXF); + col0[3] += span->attrStepY[FRAG_ATTRIB_COL0][3] * (1.0F / CHAN_MAXF); } } if (program->Base.InputsRead & FRAG_BIT_COL1) { @@ -615,16 +616,16 @@ init_machine_deriv( GLcontext *ctx, GLfloat *tex = machine->Attribs[FRAG_ATTRIB_TEX0 + u][machine->CurFrag]; /* XXX perspective-correct interpolation */ if (xOrY == 'X') { - tex[0] += span->texStepX[u][0]; - tex[1] += span->texStepX[u][1]; - tex[2] += span->texStepX[u][2]; - tex[3] += span->texStepX[u][3]; + tex[0] += span->attrStepX[FRAG_ATTRIB_TEX0 + u][0]; + tex[1] += span->attrStepX[FRAG_ATTRIB_TEX0 + u][1]; + tex[2] += span->attrStepX[FRAG_ATTRIB_TEX0 + u][2]; + tex[3] += span->attrStepX[FRAG_ATTRIB_TEX0 + u][3]; } else { - tex[0] += span->texStepY[u][0]; - tex[1] += span->texStepY[u][1]; - tex[2] += span->texStepY[u][2]; - tex[3] += span->texStepY[u][3]; + tex[0] += span->attrStepY[FRAG_ATTRIB_TEX0 + u][0]; + tex[1] += span->attrStepY[FRAG_ATTRIB_TEX0 + u][1]; + tex[2] += span->attrStepY[FRAG_ATTRIB_TEX0 + u][2]; + tex[3] += span->attrStepY[FRAG_ATTRIB_TEX0 + u][3]; } } } diff --git a/src/mesa/swrast/s_linetemp.h b/src/mesa/swrast/s_linetemp.h index d68868ded9..e3ca4bd0ac 100644 --- a/src/mesa/swrast/s_linetemp.h +++ b/src/mesa/swrast/s_linetemp.h @@ -286,22 +286,22 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 ) const GLfloat invw1 = vert1->win[3]; const GLfloat invLen = 1.0F / numPixels; GLfloat ds, dt, dr, dq; - span.tex[0][0] = invw0 * vert0->texcoord[0][0]; - span.tex[0][1] = invw0 * vert0->texcoord[0][1]; - span.tex[0][2] = invw0 * vert0->texcoord[0][2]; - span.tex[0][3] = invw0 * vert0->texcoord[0][3]; - ds = (invw1 * vert1->texcoord[0][0]) - span.tex[0][0]; - dt = (invw1 * vert1->texcoord[0][1]) - span.tex[0][1]; - dr = (invw1 * vert1->texcoord[0][2]) - span.tex[0][2]; - dq = (invw1 * vert1->texcoord[0][3]) - span.tex[0][3]; - span.texStepX[0][0] = ds * invLen; - span.texStepX[0][1] = dt * invLen; - span.texStepX[0][2] = dr * invLen; - span.texStepX[0][3] = dq * invLen; - span.texStepY[0][0] = 0.0F; - span.texStepY[0][1] = 0.0F; - span.texStepY[0][2] = 0.0F; - span.texStepY[0][3] = 0.0F; + span.attrStart[FRAG_ATTRIB_TEX0][0] = invw0 * vert0->texcoord[0][0]; + span.attrStart[FRAG_ATTRIB_TEX0][1] = invw0 * vert0->texcoord[0][1]; + span.attrStart[FRAG_ATTRIB_TEX0][2] = invw0 * vert0->texcoord[0][2]; + span.attrStart[FRAG_ATTRIB_TEX0][3] = invw0 * vert0->texcoord[0][3]; + ds = (invw1 * vert1->texcoord[0][0]) - span.attrStart[FRAG_ATTRIB_TEX0][0]; + dt = (invw1 * vert1->texcoord[0][1]) - span.attrStart[FRAG_ATTRIB_TEX0][1]; + dr = (invw1 * vert1->texcoord[0][2]) - span.attrStart[FRAG_ATTRIB_TEX0][2]; + dq = (invw1 * vert1->texcoord[0][3]) - span.attrStart[FRAG_ATTRIB_TEX0][3]; + span.attrStepX[FRAG_ATTRIB_TEX0][0] = ds * invLen; + span.attrStepX[FRAG_ATTRIB_TEX0][1] = dt * invLen; + span.attrStepX[FRAG_ATTRIB_TEX0][2] = dr * invLen; + span.attrStepX[FRAG_ATTRIB_TEX0][3] = dq * invLen; + span.attrStepY[FRAG_ATTRIB_TEX0][0] = 0.0F; + span.attrStepY[FRAG_ATTRIB_TEX0][1] = 0.0F; + span.attrStepY[FRAG_ATTRIB_TEX0][2] = 0.0F; + span.attrStepY[FRAG_ATTRIB_TEX0][3] = 0.0F; } #endif #ifdef INTERP_MULTITEX @@ -311,25 +311,26 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 ) GLuint u; for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { if (ctx->Texture.Unit[u]._ReallyEnabled) { + const GLuint attr = FRAG_ATTRIB_TEX0 + u; const GLfloat invw0 = vert0->win[3]; const GLfloat invw1 = vert1->win[3]; GLfloat ds, dt, dr, dq; - span.tex[u][0] = invw0 * vert0->texcoord[u][0]; - span.tex[u][1] = invw0 * vert0->texcoord[u][1]; - span.tex[u][2] = invw0 * vert0->texcoord[u][2]; - span.tex[u][3] = invw0 * vert0->texcoord[u][3]; - ds = (invw1 * vert1->texcoord[u][0]) - span.tex[u][0]; - dt = (invw1 * vert1->texcoord[u][1]) - span.tex[u][1]; - dr = (invw1 * vert1->texcoord[u][2]) - span.tex[u][2]; - dq = (invw1 * vert1->texcoord[u][3]) - span.tex[u][3]; - span.texStepX[u][0] = ds * invLen; - span.texStepX[u][1] = dt * invLen; - span.texStepX[u][2] = dr * invLen; - span.texStepX[u][3] = dq * invLen; - span.texStepY[u][0] = 0.0F; - span.texStepY[u][1] = 0.0F; - span.texStepY[u][2] = 0.0F; - span.texStepY[u][3] = 0.0F; + span.attrStart[attr][0] = invw0 * vert0->texcoord[u][0]; + span.attrStart[attr][1] = invw0 * vert0->texcoord[u][1]; + span.attrStart[attr][2] = invw0 * vert0->texcoord[u][2]; + span.attrStart[attr][3] = invw0 * vert0->texcoord[u][3]; + ds = (invw1 * vert1->texcoord[u][0]) - span.attrStart[attr][0]; + dt = (invw1 * vert1->texcoord[u][1]) - span.attrStart[attr][1]; + dr = (invw1 * vert1->texcoord[u][2]) - span.attrStart[attr][2]; + dq = (invw1 * vert1->texcoord[u][3]) - span.attrStart[attr][3]; + span.attrStepX[attr][0] = ds * invLen; + span.attrStepX[attr][1] = dt * invLen; + span.attrStepX[attr][2] = dr * invLen; + span.attrStepX[attr][3] = dq * invLen; + span.attrStepY[attr][0] = 0.0F; + span.attrStepY[attr][1] = 0.0F; + span.attrStepY[attr][2] = 0.0F; + span.attrStepY[attr][3] = 0.0F; } } } @@ -371,9 +372,9 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 ) INIT_SPAN(span, GL_LINE, numPixels, interpFlags, SPAN_XY); /* Need these for fragment prog texcoord interpolation */ - span.w = 1.0F; - span.dwdx = 0.0F; - span.dwdy = 0.0F; + span.attrStart[FRAG_ATTRIB_WPOS][3] = 1.0F; + span.attrStepX[FRAG_ATTRIB_WPOS][3] = 0.0F; + span.attrStepY[FRAG_ATTRIB_WPOS][3] = 0.0F; /* * Draw diff --git a/src/mesa/swrast/s_pointtemp.h b/src/mesa/swrast/s_pointtemp.h index f769f524a0..d211a5a3a2 100644 --- a/src/mesa/swrast/s_pointtemp.h +++ b/src/mesa/swrast/s_pointtemp.h @@ -143,9 +143,9 @@ NAME ( GLcontext *ctx, const SWvertex *vert ) } } /* need these for fragment programs */ - span->w = 1.0F; - span->dwdx = 0.0F; - span->dwdy = 0.0F; + span->attrStart[FRAG_ATTRIB_WPOS][3] = 1.0F; + span->attrStepX[FRAG_ATTRIB_WPOS][3] = 0.0F; + span->attrStepY[FRAG_ATTRIB_WPOS][3] = 0.0F; #endif #if FLAGS & SMOOTH span->arrayMask |= SPAN_COVERAGE; diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c index 52c7501df8..ddc63594f2 100644 --- a/src/mesa/swrast/s_span.c +++ b/src/mesa/swrast/s_span.c @@ -129,22 +129,23 @@ _swrast_span_default_texcoords( GLcontext *ctx, SWspan *span ) { GLuint i; for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { + const GLuint attr = FRAG_ATTRIB_TEX0 + i; const GLfloat *tc = ctx->Current.RasterTexCoords[i]; if (ctx->FragmentProgram._Current || ctx->ATIFragmentShader._Enabled) { - COPY_4V(span->tex[i], tc); + COPY_4V(span->attrStart[attr], tc); } else if (tc[3] > 0.0F) { /* use (s/q, t/q, r/q, 1) */ - span->tex[i][0] = tc[0] / tc[3]; - span->tex[i][1] = tc[1] / tc[3]; - span->tex[i][2] = tc[2] / tc[3]; - span->tex[i][3] = 1.0; + span->attrStart[attr][0] = tc[0] / tc[3]; + span->attrStart[attr][1] = tc[1] / tc[3]; + span->attrStart[attr][2] = tc[2] / tc[3]; + span->attrStart[attr][3] = 1.0; } else { - ASSIGN_4V(span->tex[i], 0.0F, 0.0F, 0.0F, 1.0F); + ASSIGN_4V(span->attrStart[attr], 0.0F, 0.0F, 0.0F, 1.0F); } - ASSIGN_4V(span->texStepX[i], 0.0F, 0.0F, 0.0F, 0.0F); - ASSIGN_4V(span->texStepY[i], 0.0F, 0.0F, 0.0F, 0.0F); + ASSIGN_4V(span->attrStepX[attr], 0.0F, 0.0F, 0.0F, 0.0F); + ASSIGN_4V(span->attrStepY[attr], 0.0F, 0.0F, 0.0F, 0.0F); } span->interpMask |= SPAN_TEXTURE; } @@ -435,8 +436,8 @@ interpolate_fog(const GLcontext *ctx, SWspan *span) const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0]; GLfloat fogCoord = span->attrStart[FRAG_ATTRIB_FOGC][0]; const GLuint haveW = (span->interpMask & SPAN_W); - const GLfloat wStep = haveW ? span->dwdx : 0.0F; - GLfloat w = haveW ? span->w : 1.0F; + const GLfloat wStep = haveW ? span->attrStepX[FRAG_ATTRIB_WPOS][3] : 0.0F; + GLfloat w = haveW ? span->attrStart[FRAG_ATTRIB_WPOS][3] : 1.0F; GLuint i; for (i = 0; i < span->end; i++) { fog[i][0] = fogCoord / w; @@ -549,6 +550,7 @@ interpolate_texcoords(GLcontext *ctx, SWspan *span) /* XXX CoordUnits vs. ImageUnits */ for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { if (ctx->Texture._EnabledCoordUnits & (1 << u)) { + const GLuint attr = FRAG_ATTRIB_TEX0 + u; const struct gl_texture_object *obj =ctx->Texture.Unit[u]._Current; GLfloat texW, texH; GLboolean needLambda; @@ -568,23 +570,23 @@ interpolate_texcoords(GLcontext *ctx, SWspan *span) if (needLambda) { GLfloat (*texcoord)[4] = span->array->attribs[FRAG_ATTRIB_TEX0 + u]; GLfloat *lambda = span->array->lambda[u]; - const GLfloat dsdx = span->texStepX[u][0]; - const GLfloat dsdy = span->texStepY[u][0]; - const GLfloat dtdx = span->texStepX[u][1]; - const GLfloat dtdy = span->texStepY[u][1]; - const GLfloat drdx = span->texStepX[u][2]; - const GLfloat dqdx = span->texStepX[u][3]; - const GLfloat dqdy = span->texStepY[u][3]; - GLfloat s = span->tex[u][0]; - GLfloat t = span->tex[u][1]; - GLfloat r = span->tex[u][2]; - GLfloat q = span->tex[u][3]; + const GLfloat dsdx = span->attrStepX[attr][0]; + const GLfloat dsdy = span->attrStepY[attr][0]; + const GLfloat dtdx = span->attrStepX[attr][1]; + const GLfloat dtdy = span->attrStepY[attr][1]; + const GLfloat drdx = span->attrStepX[attr][2]; + const GLfloat dqdx = span->attrStepX[attr][3]; + const GLfloat dqdy = span->attrStepY[attr][3]; + GLfloat s = span->attrStart[attr][0]; + GLfloat t = span->attrStart[attr][1]; + GLfloat r = span->attrStart[attr][2]; + GLfloat q = span->attrStart[attr][3]; GLuint i; if (ctx->FragmentProgram._Current || ctx->ATIFragmentShader._Enabled) { /* do perspective correction but don't divide s, t, r by q */ - const GLfloat dwdx = span->dwdx; - GLfloat w = span->w; + const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3]; + GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3]; for (i = 0; i < span->end; i++) { const GLfloat invW = 1.0F / w; texcoord[i][0] = s * invW; @@ -622,20 +624,20 @@ interpolate_texcoords(GLcontext *ctx, SWspan *span) else { GLfloat (*texcoord)[4] = span->array->attribs[FRAG_ATTRIB_TEX0 + u]; GLfloat *lambda = span->array->lambda[u]; - const GLfloat dsdx = span->texStepX[u][0]; - const GLfloat dtdx = span->texStepX[u][1]; - const GLfloat drdx = span->texStepX[u][2]; - const GLfloat dqdx = span->texStepX[u][3]; - GLfloat s = span->tex[u][0]; - GLfloat t = span->tex[u][1]; - GLfloat r = span->tex[u][2]; - GLfloat q = span->tex[u][3]; + const GLfloat dsdx = span->attrStepX[attr][0]; + const GLfloat dtdx = span->attrStepX[attr][1]; + const GLfloat drdx = span->attrStepX[attr][2]; + const GLfloat dqdx = span->attrStepX[attr][3]; + GLfloat s = span->attrStart[attr][0]; + GLfloat t = span->attrStart[attr][1]; + GLfloat r = span->attrStart[attr][2]; + GLfloat q = span->attrStart[attr][3]; GLuint i; if (ctx->FragmentProgram._Current || ctx->ATIFragmentShader._Enabled) { /* do perspective correction but don't divide s, t, r by q */ - const GLfloat dwdx = span->dwdx; - GLfloat w = span->w; + const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3]; + GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3]; for (i = 0; i < span->end; i++) { const GLfloat invW = 1.0F / w; texcoord[i][0] = s * invW; @@ -703,23 +705,23 @@ interpolate_texcoords(GLcontext *ctx, SWspan *span) /* just texture unit 0, with lambda */ GLfloat (*texcoord)[4] = span->array->attribs[FRAG_ATTRIB_TEX0]; GLfloat *lambda = span->array->lambda[0]; - const GLfloat dsdx = span->texStepX[0][0]; - const GLfloat dsdy = span->texStepY[0][0]; - const GLfloat dtdx = span->texStepX[0][1]; - const GLfloat dtdy = span->texStepY[0][1]; - const GLfloat drdx = span->texStepX[0][2]; - const GLfloat dqdx = span->texStepX[0][3]; - const GLfloat dqdy = span->texStepY[0][3]; - GLfloat s = span->tex[0][0]; - GLfloat t = span->tex[0][1]; - GLfloat r = span->tex[0][2]; - GLfloat q = span->tex[0][3]; + const GLfloat dsdx = span->attrStepX[FRAG_ATTRIB_TEX0][0]; + const GLfloat dsdy = span->attrStepY[FRAG_ATTRIB_TEX0][0]; + const GLfloat dtdx = span->attrStepX[FRAG_ATTRIB_TEX0][1]; + const GLfloat dtdy = span->attrStepY[FRAG_ATTRIB_TEX0][1]; + const GLfloat drdx = span->attrStepX[FRAG_ATTRIB_TEX0][2]; + const GLfloat dqdx = span->attrStepX[FRAG_ATTRIB_TEX0][3]; + const GLfloat dqdy = span->attrStepY[FRAG_ATTRIB_TEX0][3]; + GLfloat s = span->attrStart[FRAG_ATTRIB_TEX0][0]; + GLfloat t = span->attrStart[FRAG_ATTRIB_TEX0][1]; + GLfloat r = span->attrStart[FRAG_ATTRIB_TEX0][2]; + GLfloat q = span->attrStart[FRAG_ATTRIB_TEX0][3]; GLuint i; if (ctx->FragmentProgram._Current || ctx->ATIFragmentShader._Enabled) { /* do perspective correction but don't divide s, t, r by q */ - const GLfloat dwdx = span->dwdx; - GLfloat w = span->w; + const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3]; + GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3]; for (i = 0; i < span->end; i++) { const GLfloat invW = 1.0F / w; texcoord[i][0] = s * invW; @@ -758,20 +760,20 @@ interpolate_texcoords(GLcontext *ctx, SWspan *span) else { /* just texture 0, without lambda */ GLfloat (*texcoord)[4] = span->array->attribs[FRAG_ATTRIB_TEX0]; - const GLfloat dsdx = span->texStepX[0][0]; - const GLfloat dtdx = span->texStepX[0][1]; - const GLfloat drdx = span->texStepX[0][2]; - const GLfloat dqdx = span->texStepX[0][3]; - GLfloat s = span->tex[0][0]; - GLfloat t = span->tex[0][1]; - GLfloat r = span->tex[0][2]; - GLfloat q = span->tex[0][3]; + const GLfloat dsdx = span->attrStepX[FRAG_ATTRIB_TEX0][0]; + const GLfloat dtdx = span->attrStepX[FRAG_ATTRIB_TEX0][1]; + const GLfloat drdx = span->attrStepX[FRAG_ATTRIB_TEX0][2]; + const GLfloat dqdx = span->attrStepX[FRAG_ATTRIB_TEX0][3]; + GLfloat s = span->attrStart[FRAG_ATTRIB_TEX0][0]; + GLfloat t = span->attrStart[FRAG_ATTRIB_TEX0][1]; + GLfloat r = span->attrStart[FRAG_ATTRIB_TEX0][2]; + GLfloat q = span->attrStart[FRAG_ATTRIB_TEX0][3]; GLuint i; if (ctx->FragmentProgram._Current || ctx->ATIFragmentShader._Enabled) { /* do perspective correction but don't divide s, t, r by q */ - const GLfloat dwdx = span->dwdx; - GLfloat w = span->w; + const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3]; + GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3]; for (i = 0; i < span->end; i++) { const GLfloat invW = 1.0F / w; texcoord[i][0] = s * invW; @@ -840,8 +842,8 @@ interpolate_varying(GLcontext *ctx, SWspan *span) for (j = 0; j < 4; j++) { const GLfloat dvdx = span->attrStepX[attr][j]; GLfloat v = span->attrStart[attr][j]; - const GLfloat dwdx = span->dwdx; - GLfloat w = span->w; + const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3]; + GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3]; GLuint k; for (k = 0; k < span->end; k++) { GLfloat invW = 1.0f / w; @@ -877,7 +879,8 @@ interpolate_wpos(GLcontext *ctx, SWspan *span) } for (i = 0; i < span->end; i++) { wpos[i][2] = (GLfloat) span->array->z[i] / ctx->DrawBuffer->_DepthMaxF; - wpos[i][3] = span->w + i * span->dwdx; + wpos[i][3] = span->attrStart[FRAG_ATTRIB_WPOS][3] + + i * span->attrStepX[FRAG_ATTRIB_WPOS][3]; } } diff --git a/src/mesa/swrast/s_span.h b/src/mesa/swrast/s_span.h index f60d4279e1..26ef399df3 100644 --- a/src/mesa/swrast/s_span.h +++ b/src/mesa/swrast/s_span.h @@ -127,6 +127,7 @@ typedef struct sw_span_arrays */ typedef struct sw_span { + /** Coord of first fragment in horizontal span/run */ GLint x, y; /** Number of fragments in the span */ @@ -143,10 +144,17 @@ typedef struct sw_span /** * This bitmask (of \link SpanFlags SPAN_* flags\endlink) indicates - * which of the x/xStep variables are relevant. + * which of the attrStart/StepX/StepY variables are relevant. */ GLbitfield interpMask; + /** Fragment attribute interpolants */ + GLfloat attrStart[FRAG_ATTRIB_MAX][4]; /**< initial value */ + GLfloat attrStepX[FRAG_ATTRIB_MAX][4]; /**< dvalue/dx */ + GLfloat attrStepY[FRAG_ATTRIB_MAX][4]; /**< dvalue/dy */ + + /* XXX the rest of these will go away eventually... */ + /* For horizontal spans, step is the partial derivative wrt X. * For lines, step is the delta from one fragment to the next. */ @@ -169,24 +177,8 @@ typedef struct sw_span #endif GLfixed index, indexStep; GLfixed z, zStep; /* XXX z should probably be GLuint */ - GLfloat tex[MAX_TEXTURE_COORD_UNITS][4]; /* s, t, r, q */ - GLfloat texStepX[MAX_TEXTURE_COORD_UNITS][4]; - GLfloat texStepY[MAX_TEXTURE_COORD_UNITS][4]; GLfixed intTex[2], intTexStep[2]; /* s, t only */ - /** Fragment attribute interpolants */ - GLfloat attrStart[FRAG_ATTRIB_MAX][4]; /**< initial value */ - GLfloat attrStepX[FRAG_ATTRIB_MAX][4]; /**< dvalue/dx */ - GLfloat attrStepY[FRAG_ATTRIB_MAX][4]; /**< dvalue/dy */ - - /* partial derivatives wrt X and Y. */ - GLfloat dzdx, dzdy; - GLfloat w, dwdx, dwdy; - GLfloat drdx, drdy; - GLfloat dgdx, dgdy; - GLfloat dbdx, dbdy; - GLfloat dadx, dady; - /** * This bitmask (of \link SpanFlags SPAN_* flags\endlink) indicates * which of the fragment arrays in the span_arrays struct are relevant. diff --git a/src/mesa/swrast/s_triangle.c b/src/mesa/swrast/s_triangle.c index 9b775928cd..6c2e3862a3 100644 --- a/src/mesa/swrast/s_triangle.c +++ b/src/mesa/swrast/s_triangle.c @@ -676,13 +676,13 @@ fast_persp_span(GLcontext *ctx, SWspan *span, const GLuint savedTexEnable = ctx->Texture._EnabledUnits; ctx->Texture._EnabledUnits = 0; - tex_coord[0] = span->tex[0][0] * (info->smask + 1); - tex_step[0] = span->texStepX[0][0] * (info->smask + 1); - tex_coord[1] = span->tex[0][1] * (info->tmask + 1); - tex_step[1] = span->texStepX[0][1] * (info->tmask + 1); - /* span->tex[0][2] only if 3D-texturing, here only 2D */ - tex_coord[2] = span->tex[0][3]; - tex_step[2] = span->texStepX[0][3]; + tex_coord[0] = span->attrStart[FRAG_ATTRIB_TEX0][0] * (info->smask + 1); + tex_step[0] = span->attrStepX[FRAG_ATTRIB_TEX0][0] * (info->smask + 1); + tex_coord[1] = span->attrStart[FRAG_ATTRIB_TEX0][1] * (info->tmask + 1); + tex_step[1] = span->attrStepX[FRAG_ATTRIB_TEX0][1] * (info->tmask + 1); + /* span->attrStart[FRAG_ATTRIB_TEX0][2] only if 3D-texturing, here only 2D */ + tex_coord[2] = span->attrStart[FRAG_ATTRIB_TEX0][3]; + tex_step[2] = span->attrStepX[FRAG_ATTRIB_TEX0][3]; switch (info->filter) { case GL_NEAREST: diff --git a/src/mesa/swrast/s_tritemp.h b/src/mesa/swrast/s_tritemp.h index c8fe4b6e9e..83b2f03781 100644 --- a/src/mesa/swrast/s_tritemp.h +++ b/src/mesa/swrast/s_tritemp.h @@ -128,6 +128,8 @@ GLuint u; \ for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { \ if (ctx->Texture._EnabledCoordUnits & (1 << u)) { \ + const GLuint attr = FRAG_ATTRIB_TEX0 + u; \ + (void) attr; \ CODE \ } \ } \ @@ -137,6 +139,8 @@ #define TEX_UNIT_LOOP(CODE) \ { \ const GLuint u = 0; \ + const GLuint attr = FRAG_ATTRIB_TEX0 + u; \ + (void) attr; \ CODE \ } #endif @@ -145,17 +149,18 @@ #ifdef INTERP_VARYING -#define VARYING_LOOP(CODE) \ - { \ - GLuint iv, ic; \ - for (iv = 0; iv < MAX_VARYING; iv++) { \ - if (inputsUsed & FRAG_BIT_VAR(iv)) { \ +#define VARYING_LOOP(CODE) \ + { \ + GLuint iv, ic; \ + for (iv = 0; iv < MAX_VARYING; iv++) { \ + if (inputsUsed & FRAG_BIT_VAR(iv)) { \ GLuint attr = FRAG_ATTRIB_VAR0 + iv; \ - for (ic = 0; ic < 4; ic++) { \ - CODE \ - } \ - } \ - } \ + (void) attr; \ + for (ic = 0; ic < 4; ic++) { \ + CODE \ + } \ + } \ + } \ } #endif @@ -473,19 +478,19 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, { GLfloat eMaj_dz = vMax->win[2] - vMin->win[2]; GLfloat eBot_dz = vMid->win[2] - vMin->win[2]; - span.dzdx = oneOverArea * (eMaj_dz * eBot.dy - eMaj.dy * eBot_dz); - if (span.dzdx > maxDepth || span.dzdx < -maxDepth) { + span.attrStepX[FRAG_ATTRIB_WPOS][2] = oneOverArea * (eMaj_dz * eBot.dy - eMaj.dy * eBot_dz); + if (span.attrStepX[FRAG_ATTRIB_WPOS][2] > maxDepth || span.attrStepX[FRAG_ATTRIB_WPOS][2] < -maxDepth) { /* probably a sliver triangle */ - span.dzdx = 0.0; - span.dzdy = 0.0; + span.attrStepX[FRAG_ATTRIB_WPOS][2] = 0.0; + span.attrStepY[FRAG_ATTRIB_WPOS][2] = 0.0; } else { - span.dzdy = oneOverArea * (eMaj.dx * eBot_dz - eMaj_dz * eBot.dx); + span.attrStepY[FRAG_ATTRIB_WPOS][2] = oneOverArea * (eMaj.dx * eBot_dz - eMaj_dz * eBot.dx); } if (depthBits <= 16) - span.zStep = SignedFloatToFixed(span.dzdx); + span.zStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_WPOS][2]); else - span.zStep = (GLint) span.dzdx; + span.zStep = (GLint) span.attrStepX[FRAG_ATTRIB_WPOS][2]; } #endif #ifdef INTERP_W @@ -493,8 +498,8 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, { const GLfloat eMaj_dw = vMax->win[3] - vMin->win[3]; const GLfloat eBot_dw = vMid->win[3] - vMin->win[3]; - span.dwdx = oneOverArea * (eMaj_dw * eBot.dy - eMaj.dy * eBot_dw); - span.dwdy = oneOverArea * (eMaj.dx * eBot_dw - eMaj_dw * eBot.dx); + span.attrStepX[FRAG_ATTRIB_WPOS][3] = oneOverArea * (eMaj_dw * eBot.dy - eMaj.dy * eBot_dw); + span.attrStepY[FRAG_ATTRIB_WPOS][3] = oneOverArea * (eMaj.dx * eBot_dw - eMaj_dw * eBot.dx); } #endif #ifdef INTERP_FOG @@ -525,37 +530,37 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, GLfloat eMaj_da = (GLfloat) ((ColorTemp) vMax->color[ACOMP] - (ColorTemp) vMin->color[ACOMP]); GLfloat eBot_da = (GLfloat) ((ColorTemp) vMid->color[ACOMP] - (ColorTemp) vMin->color[ACOMP]); # endif - span.drdx = oneOverArea * (eMaj_dr * eBot.dy - eMaj.dy * eBot_dr); - span.drdy = oneOverArea * (eMaj.dx * eBot_dr - eMaj_dr * eBot.dx); - span.dgdx = oneOverArea * (eMaj_dg * eBot.dy - eMaj.dy * eBot_dg); - span.dgdy = oneOverArea * (eMaj.dx * eBot_dg - eMaj_dg * eBot.dx); - span.dbdx = oneOverArea * (eMaj_db * eBot.dy - eMaj.dy * eBot_db); - span.dbdy = oneOverArea * (eMaj.dx * eBot_db - eMaj_db * eBot.dx); + span.attrStepX[FRAG_ATTRIB_COL0][0] = oneOverArea * (eMaj_dr * eBot.dy - eMaj.dy * eBot_dr); + span.attrStepY[FRAG_ATTRIB_COL0][0] = oneOverArea * (eMaj.dx * eBot_dr - eMaj_dr * eBot.dx); + span.attrStepX[FRAG_ATTRIB_COL0][1] = oneOverArea * (eMaj_dg * eBot.dy - eMaj.dy * eBot_dg); + span.attrStepY[FRAG_ATTRIB_COL0][1] = oneOverArea * (eMaj.dx * eBot_dg - eMaj_dg * eBot.dx); + span.attrStepX[FRAG_ATTRIB_COL0][2] = oneOverArea * (eMaj_db * eBot.dy - eMaj.dy * eBot_db); + span.attrStepY[FRAG_ATTRIB_COL0][2] = oneOverArea * (eMaj.dx * eBot_db - eMaj_db * eBot.dx); # if CHAN_TYPE == GL_FLOAT - span.redStep = span.drdx; - span.greenStep = span.dgdx; - span.blueStep = span.dbdx; + span.redStep = span.attrStepX[FRAG_ATTRIB_COL0][0]; + span.greenStep = span.attrStepX[FRAG_ATTRIB_COL0][1]; + span.blueStep = span.attrStepX[FRAG_ATTRIB_COL0][2]; # else - span.redStep = SignedFloatToFixed(span.drdx); - span.greenStep = SignedFloatToFixed(span.dgdx); - span.blueStep = SignedFloatToFixed(span.dbdx); + span.redStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][0]); + span.greenStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][1]); + span.blueStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][2]); # endif /* GL_FLOAT */ # ifdef INTERP_ALPHA - span.dadx = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da); - span.dady = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx); + span.attrStepX[FRAG_ATTRIB_COL0][3] = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da); + span.attrStepX[FRAG_ATTRIB_COL0][3] = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx); # if CHAN_TYPE == GL_FLOAT - span.alphaStep = span.dadx; + span.alphaStep = span.attrStepX[FRAG_ATTRIB_COL0][3]; # else - span.alphaStep = SignedFloatToFixed(span.dadx); + span.alphaStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][3]); # endif /* GL_FLOAT */ # endif /* INTERP_ALPHA */ } else { ASSERT(ctx->Light.ShadeModel == GL_FLAT); span.interpMask |= SPAN_FLAT; - span.drdx = span.drdy = 0.0F; - span.dgdx = span.dgdy = 0.0F; - span.dbdx = span.dbdy = 0.0F; + span.attrStepX[FRAG_ATTRIB_COL0][0] = span.attrStepY[FRAG_ATTRIB_COL0][0] = 0.0F; + span.attrStepX[FRAG_ATTRIB_COL0][1] = span.attrStepY[FRAG_ATTRIB_COL0][1] = 0.0F; + span.attrStepX[FRAG_ATTRIB_COL0][2] = span.attrStepY[FRAG_ATTRIB_COL0][2] = 0.0F; # if CHAN_TYPE == GL_FLOAT span.redStep = 0.0F; span.greenStep = 0.0F; @@ -566,7 +571,7 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, span.blueStep = 0; # endif /* GL_FLOAT */ # ifdef INTERP_ALPHA - span.dadx = span.dady = 0.0F; + span.attrStepX[FRAG_ATTRIB_COL0][3] = span.attrStepX[FRAG_ATTRIB_COL0][3] = 0.0F; # if CHAN_TYPE == GL_FLOAT span.alphaStep = 0.0F; # else @@ -637,12 +642,12 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, GLfloat eBot_ds = (vMid->texcoord[0][0] - vMin->texcoord[0][0]) * S_SCALE; GLfloat eMaj_dt = (vMax->texcoord[0][1] - vMin->texcoord[0][1]) * T_SCALE; GLfloat eBot_dt = (vMid->texcoord[0][1] - vMin->texcoord[0][1]) * T_SCALE; - span.texStepX[0][0] = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds); - span.texStepY[0][0] = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx); - span.texStepX[0][1] = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt); - span.texStepY[0][1] = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx); - span.intTexStep[0] = SignedFloatToFixed(span.texStepX[0][0]); - span.intTexStep[1] = SignedFloatToFixed(span.texStepX[0][1]); + span.attrStepX[FRAG_ATTRIB_TEX0][0] = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds); + span.attrStepY[FRAG_ATTRIB_TEX0][0] = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx); + span.attrStepX[FRAG_ATTRIB_TEX0][1] = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt); + span.attrStepY[FRAG_ATTRIB_TEX0][1] = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx); + span.intTexStep[0] = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_TEX0][0]); + span.intTexStep[1] = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_TEX0][1]); } #endif #ifdef INTERP_TEX @@ -659,14 +664,14 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, GLfloat eBot_du = vMid->texcoord[u][2] * wMid - vMin->texcoord[u][2] * wMin; GLfloat eMaj_dv = vMax->texcoord[u][3] * wMax - vMin->texcoord[u][3] * wMin; GLfloat eBot_dv = vMid->texcoord[u][3] * wMid - vMin->texcoord[u][3] * wMin; - span.texStepX[u][0] = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds); - span.texStepY[u][0] = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx); - span.texStepX[u][1] = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt); - span.texStepY[u][1] = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx); - span.texStepX[u][2] = oneOverArea * (eMaj_du * eBot.dy - eMaj.dy * eBot_du); - span.texStepY[u][2] = oneOverArea * (eMaj.dx * eBot_du - eMaj_du * eBot.dx); - span.texStepX[u][3] = oneOverArea * (eMaj_dv * eBot.dy - eMaj.dy * eBot_dv); - span.texStepY[u][3] = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx); + span.attrStepX[attr][0] = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds); + span.attrStepY[attr][0] = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx); + span.attrStepX[attr][1] = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt); + span.attrStepY[attr][1] = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx); + span.attrStepX[attr][2] = oneOverArea * (eMaj_du * eBot.dy - eMaj.dy * eBot_du); + span.attrStepY[attr][2] = oneOverArea * (eMaj.dx * eBot_du - eMaj_du * eBot.dx); + span.attrStepX[attr][3] = oneOverArea * (eMaj_dv * eBot.dy - eMaj.dy * eBot_dv); + span.attrStepY[attr][3] = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx); ) } #endif @@ -901,19 +906,20 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, GLfloat z0 = vLower->win[2]; if (depthBits <= 16) { /* interpolate fixed-pt values */ - GLfloat tmp = (z0 * FIXED_SCALE + span.dzdx * adjx - + span.dzdy * adjy) + FIXED_HALF; + GLfloat tmp = (z0 * FIXED_SCALE + + span.attrStepX[FRAG_ATTRIB_WPOS][2] * adjx + + span.attrStepY[FRAG_ATTRIB_WPOS][2] * adjy) + FIXED_HALF; if (tmp < MAX_GLUINT / 2) zLeft = (GLfixed) tmp; else zLeft = MAX_GLUINT / 2; - fdzOuter = SignedFloatToFixed(span.dzdy + dxOuter * span.dzdx); + fdzOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_WPOS][2] + dxOuter * span.attrStepX[FRAG_ATTRIB_WPOS][2]); } else { /* interpolate depth values w/out scaling */ - zLeft = (GLuint) (z0 + span.dzdx * FixedToFloat(adjx) - + span.dzdy * FixedToFloat(adjy)); - fdzOuter = (GLint) (span.dzdy + dxOuter * span.dzdx); + zLeft = (GLuint) (z0 + span.attrStepX[FRAG_ATTRIB_WPOS][2] * FixedToFloat(adjx) + + span.attrStepY[FRAG_ATTRIB_WPOS][2] * FixedToFloat(adjy)); + fdzOuter = (GLint) (span.attrStepY[FRAG_ATTRIB_WPOS][2] + dxOuter * span.attrStepX[FRAG_ATTRIB_WPOS][2]); } # ifdef DEPTH_TYPE zRow = (DEPTH_TYPE *) @@ -923,8 +929,8 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, } #endif #ifdef INTERP_W - wLeft = vLower->win[3] + (span.dwdx * adjx + span.dwdy * adjy) * (1.0F/FIXED_SCALE); - dwOuter = span.dwdy + dxOuter * span.dwdx; + wLeft = vLower->win[3] + (span.attrStepX[FRAG_ATTRIB_WPOS][3] * adjx + span.attrStepY[FRAG_ATTRIB_WPOS][3] * adjy) * (1.0F/FIXED_SCALE); + dwOuter = span.attrStepY[FRAG_ATTRIB_WPOS][3] + dxOuter * span.attrStepX[FRAG_ATTRIB_WPOS][3]; #endif #ifdef INTERP_FOG # ifdef INTERP_W @@ -937,27 +943,27 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, #ifdef INTERP_RGB if (ctx->Light.ShadeModel == GL_SMOOTH) { # if CHAN_TYPE == GL_FLOAT - rLeft = vLower->color[RCOMP] + (span.drdx * adjx + span.drdy * adjy) * (1.0F / FIXED_SCALE); - gLeft = vLower->color[GCOMP] + (span.dgdx * adjx + span.dgdy * adjy) * (1.0F / FIXED_SCALE); - bLeft = vLower->color[BCOMP] + (span.dbdx * adjx + span.dbdy * adjy) * (1.0F / FIXED_SCALE); - fdrOuter = span.drdy + dxOuter * span.drdx; - fdgOuter = span.dgdy + dxOuter * span.dgdx; - fdbOuter = span.dbdy + dxOuter * span.dbdx; + rLeft = vLower->color[RCOMP] + (span.attrStepX[FRAG_ATTRIB_COL0][0] * adjx + span.attrStepY[FRAG_ATTRIB_COL0][0] * adjy) * (1.0F / FIXED_SCALE); + gLeft = vLower->color[GCOMP] + (span.attrStepX[FRAG_ATTRIB_COL0][1] * adjx + span.attrStepY[FRAG_ATTRIB_COL0][1] * adjy) * (1.0F / FIXED_SCALE); + bLeft = vLower->color[BCOMP] + (span.attrStepX[FRAG_ATTRIB_COL0][2] * adjx + span.attrStepY[FRAG_ATTRIB_COL0][2] * adjy) * (1.0F / FIXED_SCALE); + fdrOuter = span.attrStepY[FRAG_ATTRIB_COL0][0] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][0]; + fdgOuter = span.attrStepY[FRAG_ATTRIB_COL0][1] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][1]; + fdbOuter = span.attrStepY[FRAG_ATTRIB_COL0][2] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][2]; # else - rLeft = (GLint)(ChanToFixed(vLower->color[RCOMP]) + span.drdx * adjx + span.drdy * adjy) + FIXED_HALF; - gLeft = (GLint)(ChanToFixed(vLower->color[GCOMP]) + span.dgdx * adjx + span.dgdy * adjy) + FIXED_HALF; - bLeft = (GLint)(ChanToFixed(vLower->color[BCOMP]) + span.dbdx * adjx + span.dbdy * adjy) + FIXED_HALF; - fdrOuter = SignedFloatToFixed(span.drdy + dxOuter * span.drdx); - fdgOuter = SignedFloatToFixed(span.dgdy + dxOuter * span.dgdx); - fdbOuter = SignedFloatToFixed(span.dbdy + dxOuter * span.dbdx); + rLeft = (GLint)(ChanToFixed(vLower->color[RCOMP]) + span.attrStepX[FRAG_ATTRIB_COL0][0] * adjx + span.attrStepY[FRAG_ATTRIB_COL0][0] * adjy) + FIXED_HALF; + gLeft = (GLint)(ChanToFixed(vLower->color[GCOMP]) + span.attrStepX[FRAG_ATTRIB_COL0][1] * adjx + span.attrStepY[FRAG_ATTRIB_COL0][1] * adjy) + FIXED_HALF; + bLeft = (GLint)(ChanToFixed(vLower->color[BCOMP]) + span.attrStepX[FRAG_ATTRIB_COL0][2] * adjx + span.attrStepY[FRAG_ATTRIB_COL0][2] * adjy) + FIXED_HALF; + fdrOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][0] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][0]); + fdgOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][1] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][1]); + fdbOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][2] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][2]); # endif # ifdef INTERP_ALPHA # if CHAN_TYPE == GL_FLOAT - aLeft = vLower->color[ACOMP] + (span.dadx * adjx + span.dady * adjy) * (1.0F / FIXED_SCALE); - fdaOuter = span.dady + dxOuter * span.dadx; + aLeft = vLower->color[ACOMP] + (span.attrStepX[FRAG_ATTRIB_COL0][3] * adjx + span.attrStepX[FRAG_ATTRIB_COL0][3] * adjy) * (1.0F / FIXED_SCALE); + fdaOuter = span.attrStepX[FRAG_ATTRIB_COL0][3] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][3]; # else - aLeft = (GLint)(ChanToFixed(vLower->color[ACOMP]) + span.dadx * adjx + span.dady * adjy) + FIXED_HALF; - fdaOuter = SignedFloatToFixed(span.dady + dxOuter * span.dadx); + aLeft = (GLint)(ChanToFixed(vLower->color[ACOMP]) + span.attrStepX[FRAG_ATTRIB_COL0][3] * adjx + span.attrStepX[FRAG_ATTRIB_COL0][3] * adjy) + FIXED_HALF; + fdaOuter = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][3] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][3]); # endif # endif } @@ -1037,14 +1043,14 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, { GLfloat s0, t0; s0 = vLower->texcoord[0][0] * S_SCALE; - sLeft = (GLfixed)(s0 * FIXED_SCALE + span.texStepX[0][0] * adjx - + span.texStepY[0][0] * adjy) + FIXED_HALF; - dsOuter = SignedFloatToFixed(span.texStepY[0][0] + dxOuter * span.texStepX[0][0]); + sLeft = (GLfixed)(s0 * FIXED_SCALE + span.attrStepX[FRAG_ATTRIB_TEX0][0] * adjx + + span.attrStepY[FRAG_ATTRIB_TEX0][0] * adjy) + FIXED_HALF; + dsOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_TEX0][0] + dxOuter * span.attrStepX[FRAG_ATTRIB_TEX0][0]); t0 = vLower->texcoord[0][1] * T_SCALE; - tLeft = (GLfixed)(t0 * FIXED_SCALE + span.texStepX[0][1] * adjx - + span.texStepY[0][1] * adjy) + FIXED_HALF; - dtOuter = SignedFloatToFixed(span.texStepY[0][1] + dxOuter * span.texStepX[0][1]); + tLeft = (GLfixed)(t0 * FIXED_SCALE + span.attrStepX[FRAG_ATTRIB_TEX0][1] * adjx + + span.attrStepY[FRAG_ATTRIB_TEX0][1] * adjy) + FIXED_HALF; + dtOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_TEX0][1] + dxOuter * span.attrStepX[FRAG_ATTRIB_TEX0][1]); } #endif #ifdef INTERP_TEX @@ -1054,14 +1060,14 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, const GLfloat t0 = vLower->texcoord[u][1] * invW; const GLfloat u0 = vLower->texcoord[u][2] * invW; const GLfloat v0 = vLower->texcoord[u][3] * invW; - sLeft[u] = s0 + (span.texStepX[u][0] * adjx + span.texStepY[u][0] * adjy) * (1.0F/FIXED_SCALE); - tLeft[u] = t0 + (span.texStepX[u][1] * adjx + span.texStepY[u][1] * adjy) * (1.0F/FIXED_SCALE); - uLeft[u] = u0 + (span.texStepX[u][2] * adjx + span.texStepY[u][2] * adjy) * (1.0F/FIXED_SCALE); - vLeft[u] = v0 + (span.texStepX[u][3] * adjx + span.texStepY[u][3] * adjy) * (1.0F/FIXED_SCALE); - dsOuter[u] = span.texStepY[u][0] + dxOuter * span.texStepX[u][0]; - dtOuter[u] = span.texStepY[u][1] + dxOuter * span.texStepX[u][1]; - duOuter[u] = span.texStepY[u][2] + dxOuter * span.texStepX[u][2]; - dvOuter[u] = span.texStepY[u][3] + dxOuter * span.texStepX[u][3]; + sLeft[u] = s0 + (span.attrStepX[attr][0] * adjx + span.attrStepY[attr][0] * adjy) * (1.0F/FIXED_SCALE); + tLeft[u] = t0 + (span.attrStepX[attr][1] * adjx + span.attrStepY[attr][1] * adjy) * (1.0F/FIXED_SCALE); + uLeft[u] = u0 + (span.attrStepX[attr][2] * adjx + span.attrStepY[attr][2] * adjy) * (1.0F/FIXED_SCALE); + vLeft[u] = v0 + (span.attrStepX[attr][3] * adjx + span.attrStepY[attr][3] * adjy) * (1.0F/FIXED_SCALE); + dsOuter[u] = span.attrStepY[attr][0] + dxOuter * span.attrStepX[attr][0]; + dtOuter[u] = span.attrStepY[attr][1] + dxOuter * span.attrStepX[attr][1]; + duOuter[u] = span.attrStepY[attr][2] + dxOuter * span.attrStepX[attr][2]; + dvOuter[u] = span.attrStepY[attr][3] + dxOuter * span.attrStepX[attr][3]; ) #endif #ifdef INTERP_VARYING @@ -1102,7 +1108,7 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, fdzInner = fdzOuter + span.zStep; #endif #ifdef INTERP_W - dwInner = dwOuter + span.dwdx; + dwInner = dwOuter + span.attrStepX[FRAG_ATTRIB_WPOS][3]; #endif #ifdef INTERP_FOG dfogInner = dfogOuter + span.attrStepX[FRAG_ATTRIB_FOGC][0]; @@ -1129,10 +1135,10 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, #endif #ifdef INTERP_TEX TEX_UNIT_LOOP( - dsInner[u] = dsOuter[u] + span.texStepX[u][0]; - dtInner[u] = dtOuter[u] + span.texStepX[u][1]; - duInner[u] = duOuter[u] + span.texStepX[u][2]; - dvInner[u] = dvOuter[u] + span.texStepX[u][3]; + dsInner[u] = dsOuter[u] + span.attrStepX[attr][0]; + dtInner[u] = dtOuter[u] + span.attrStepX[attr][1]; + duInner[u] = duOuter[u] + span.attrStepX[attr][2]; + dvInner[u] = dvOuter[u] + span.attrStepX[attr][3]; ) #endif #ifdef INTERP_VARYING @@ -1155,7 +1161,7 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, span.z = zLeft; #endif #ifdef INTERP_W - span.w = wLeft; + span.attrStart[FRAG_ATTRIB_WPOS][3] = wLeft; #endif #ifdef INTERP_FOG span.attrStart[FRAG_ATTRIB_FOGC][0] = fogLeft; @@ -1183,10 +1189,10 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, #ifdef INTERP_TEX TEX_UNIT_LOOP( - span.tex[u][0] = sLeft[u]; - span.tex[u][1] = tLeft[u]; - span.tex[u][2] = uLeft[u]; - span.tex[u][3] = vLeft[u]; + span.attrStart[attr][0] = sLeft[u]; + span.attrStart[attr][1] = tLeft[u]; + span.attrStart[attr][2] = uLeft[u]; + span.attrStart[attr][3] = vLeft[u]; ) #endif #ifdef INTERP_VARYING -- cgit v1.2.3 From e4f976b8b9d74a74b5816146cb11880c3a493929 Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 2 Feb 2007 11:19:43 -0700 Subject: simplify interpolate_texcoords() --- src/mesa/swrast/s_span.c | 388 +++++++++++++++-------------------------------- 1 file changed, 126 insertions(+), 262 deletions(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c index ddc63594f2..6fb5998627 100644 --- a/src/mesa/swrast/s_span.c +++ b/src/mesa/swrast/s_span.c @@ -75,7 +75,8 @@ _swrast_span_default_z( GLcontext *ctx, SWspan *span ) void _swrast_span_default_fog( GLcontext *ctx, SWspan *span ) { - span->attrStart[FRAG_ATTRIB_FOGC][0] = _swrast_z_to_fogfactor(ctx, ctx->Current.RasterDistance); + span->attrStart[FRAG_ATTRIB_FOGC][0] + = _swrast_z_to_fogfactor(ctx, ctx->Current.RasterDistance); span->attrStepX[FRAG_ATTRIB_FOGC][0] = 0.0; span->attrStepY[FRAG_ATTRIB_FOGC][0] = 0.0; span->interpMask |= SPAN_FOG; @@ -540,284 +541,147 @@ _swrast_compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy, static void interpolate_texcoords(GLcontext *ctx, SWspan *span) { + const GLuint maxUnit + = (ctx->Texture._EnabledCoordUnits > 1) ? ctx->Const.MaxTextureUnits : 1; + GLuint u; + ASSERT(span->interpMask & SPAN_TEXTURE); ASSERT(!(span->arrayMask & SPAN_TEXTURE)); - if (ctx->Texture._EnabledCoordUnits > 1) { - /* multitexture */ - GLuint u; - span->arrayMask |= SPAN_TEXTURE; - /* XXX CoordUnits vs. ImageUnits */ - for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { - if (ctx->Texture._EnabledCoordUnits & (1 << u)) { - const GLuint attr = FRAG_ATTRIB_TEX0 + u; - const struct gl_texture_object *obj =ctx->Texture.Unit[u]._Current; - GLfloat texW, texH; - GLboolean needLambda; - if (obj) { - const struct gl_texture_image *img = obj->Image[0][obj->BaseLevel]; - needLambda = (obj->MinFilter != obj->MagFilter) - || ctx->FragmentProgram._Current; - texW = img->WidthScale; - texH = img->HeightScale; - } - else { - /* using a fragment program */ - texW = 1.0; - texH = 1.0; - needLambda = GL_FALSE; - } - if (needLambda) { - GLfloat (*texcoord)[4] = span->array->attribs[FRAG_ATTRIB_TEX0 + u]; - GLfloat *lambda = span->array->lambda[u]; - const GLfloat dsdx = span->attrStepX[attr][0]; - const GLfloat dsdy = span->attrStepY[attr][0]; - const GLfloat dtdx = span->attrStepX[attr][1]; - const GLfloat dtdy = span->attrStepY[attr][1]; - const GLfloat drdx = span->attrStepX[attr][2]; - const GLfloat dqdx = span->attrStepX[attr][3]; - const GLfloat dqdy = span->attrStepY[attr][3]; - GLfloat s = span->attrStart[attr][0]; - GLfloat t = span->attrStart[attr][1]; - GLfloat r = span->attrStart[attr][2]; - GLfloat q = span->attrStart[attr][3]; - GLuint i; - if (ctx->FragmentProgram._Current - || ctx->ATIFragmentShader._Enabled) { - /* do perspective correction but don't divide s, t, r by q */ - const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3]; - GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3]; - for (i = 0; i < span->end; i++) { - const GLfloat invW = 1.0F / w; - texcoord[i][0] = s * invW; - texcoord[i][1] = t * invW; - texcoord[i][2] = r * invW; - texcoord[i][3] = q * invW; - lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy, - dqdx, dqdy, texW, texH, - s, t, q, invW); - s += dsdx; - t += dtdx; - r += drdx; - q += dqdx; - w += dwdx; - } - } - else { - for (i = 0; i < span->end; i++) { - const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); - texcoord[i][0] = s * invQ; - texcoord[i][1] = t * invQ; - texcoord[i][2] = r * invQ; - texcoord[i][3] = q; - lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy, - dqdx, dqdy, texW, texH, - s, t, q, invQ); - s += dsdx; - t += dtdx; - r += drdx; - q += dqdx; - } + span->arrayMask |= SPAN_TEXTURE; + + /* XXX CoordUnits vs. ImageUnits */ + for (u = 0; u < maxUnit; u++) { + if (ctx->Texture._EnabledCoordUnits & (1 << u)) { + const GLuint attr = FRAG_ATTRIB_TEX0 + u; + const struct gl_texture_object *obj =ctx->Texture.Unit[u]._Current; + GLfloat texW, texH; + GLboolean needLambda; + GLfloat (*texcoord)[4] = span->array->attribs[attr]; + GLfloat *lambda = span->array->lambda[u]; + const GLfloat dsdx = span->attrStepX[attr][0]; + const GLfloat dsdy = span->attrStepY[attr][0]; + const GLfloat dtdx = span->attrStepX[attr][1]; + const GLfloat dtdy = span->attrStepY[attr][1]; + const GLfloat drdx = span->attrStepX[attr][2]; + const GLfloat dqdx = span->attrStepX[attr][3]; + const GLfloat dqdy = span->attrStepY[attr][3]; + GLfloat s = span->attrStart[attr][0]; + GLfloat t = span->attrStart[attr][1]; + GLfloat r = span->attrStart[attr][2]; + GLfloat q = span->attrStart[attr][3]; + + if (obj) { + const struct gl_texture_image *img = obj->Image[0][obj->BaseLevel]; + needLambda = (obj->MinFilter != obj->MagFilter) + || ctx->FragmentProgram._Current; + texW = img->WidthScale; + texH = img->HeightScale; + } + else { + /* using a fragment program */ + texW = 1.0; + texH = 1.0; + needLambda = GL_FALSE; + } + + if (needLambda) { + GLuint i; + if (ctx->FragmentProgram._Current + || ctx->ATIFragmentShader._Enabled) { + /* do perspective correction but don't divide s, t, r by q */ + const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3]; + GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3]; + for (i = 0; i < span->end; i++) { + const GLfloat invW = 1.0F / w; + texcoord[i][0] = s * invW; + texcoord[i][1] = t * invW; + texcoord[i][2] = r * invW; + texcoord[i][3] = q * invW; + lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy, + dqdx, dqdy, texW, texH, + s, t, q, invW); + s += dsdx; + t += dtdx; + r += drdx; + q += dqdx; + w += dwdx; } - span->arrayMask |= SPAN_LAMBDA; } else { - GLfloat (*texcoord)[4] = span->array->attribs[FRAG_ATTRIB_TEX0 + u]; - GLfloat *lambda = span->array->lambda[u]; - const GLfloat dsdx = span->attrStepX[attr][0]; - const GLfloat dtdx = span->attrStepX[attr][1]; - const GLfloat drdx = span->attrStepX[attr][2]; - const GLfloat dqdx = span->attrStepX[attr][3]; - GLfloat s = span->attrStart[attr][0]; - GLfloat t = span->attrStart[attr][1]; - GLfloat r = span->attrStart[attr][2]; - GLfloat q = span->attrStart[attr][3]; - GLuint i; - if (ctx->FragmentProgram._Current || - ctx->ATIFragmentShader._Enabled) { - /* do perspective correction but don't divide s, t, r by q */ - const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3]; - GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3]; - for (i = 0; i < span->end; i++) { - const GLfloat invW = 1.0F / w; - texcoord[i][0] = s * invW; - texcoord[i][1] = t * invW; - texcoord[i][2] = r * invW; - texcoord[i][3] = q * invW; - lambda[i] = 0.0; - s += dsdx; - t += dtdx; - r += drdx; - q += dqdx; - w += dwdx; - } - } - else if (dqdx == 0.0F) { - /* Ortho projection or polygon's parallel to window X axis */ + for (i = 0; i < span->end; i++) { const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); - for (i = 0; i < span->end; i++) { - texcoord[i][0] = s * invQ; - texcoord[i][1] = t * invQ; - texcoord[i][2] = r * invQ; - texcoord[i][3] = q; - lambda[i] = 0.0; - s += dsdx; - t += dtdx; - r += drdx; - } - } - else { - for (i = 0; i < span->end; i++) { - const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); - texcoord[i][0] = s * invQ; - texcoord[i][1] = t * invQ; - texcoord[i][2] = r * invQ; - texcoord[i][3] = q; - lambda[i] = 0.0; - s += dsdx; - t += dtdx; - r += drdx; - q += dqdx; - } + texcoord[i][0] = s * invQ; + texcoord[i][1] = t * invQ; + texcoord[i][2] = r * invQ; + texcoord[i][3] = q; + lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy, + dqdx, dqdy, texW, texH, + s, t, q, invQ); + s += dsdx; + t += dtdx; + r += drdx; + q += dqdx; } - } /* lambda */ - } /* if */ - } /* for */ - } - else { - /* single texture */ - const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current; - GLfloat texW, texH; - GLboolean needLambda; - if (obj) { - const struct gl_texture_image *img = obj->Image[0][obj->BaseLevel]; - needLambda = (obj->MinFilter != obj->MagFilter) - || ctx->FragmentProgram._Current; - texW = (GLfloat) img->WidthScale; - texH = (GLfloat) img->HeightScale; - } - else { - needLambda = GL_FALSE; - texW = texH = 1.0; - } - span->arrayMask |= SPAN_TEXTURE; - if (needLambda) { - /* just texture unit 0, with lambda */ - GLfloat (*texcoord)[4] = span->array->attribs[FRAG_ATTRIB_TEX0]; - GLfloat *lambda = span->array->lambda[0]; - const GLfloat dsdx = span->attrStepX[FRAG_ATTRIB_TEX0][0]; - const GLfloat dsdy = span->attrStepY[FRAG_ATTRIB_TEX0][0]; - const GLfloat dtdx = span->attrStepX[FRAG_ATTRIB_TEX0][1]; - const GLfloat dtdy = span->attrStepY[FRAG_ATTRIB_TEX0][1]; - const GLfloat drdx = span->attrStepX[FRAG_ATTRIB_TEX0][2]; - const GLfloat dqdx = span->attrStepX[FRAG_ATTRIB_TEX0][3]; - const GLfloat dqdy = span->attrStepY[FRAG_ATTRIB_TEX0][3]; - GLfloat s = span->attrStart[FRAG_ATTRIB_TEX0][0]; - GLfloat t = span->attrStart[FRAG_ATTRIB_TEX0][1]; - GLfloat r = span->attrStart[FRAG_ATTRIB_TEX0][2]; - GLfloat q = span->attrStart[FRAG_ATTRIB_TEX0][3]; - GLuint i; - if (ctx->FragmentProgram._Current - || ctx->ATIFragmentShader._Enabled) { - /* do perspective correction but don't divide s, t, r by q */ - const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3]; - GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3]; - for (i = 0; i < span->end; i++) { - const GLfloat invW = 1.0F / w; - texcoord[i][0] = s * invW; - texcoord[i][1] = t * invW; - texcoord[i][2] = r * invW; - texcoord[i][3] = q * invW; - lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy, - dqdx, dqdy, texW, texH, - s, t, q, invW); - s += dsdx; - t += dtdx; - r += drdx; - q += dqdx; - w += dwdx; } + span->arrayMask |= SPAN_LAMBDA; } else { - /* tex.c */ - for (i = 0; i < span->end; i++) { - const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); - lambda[i] = _swrast_compute_lambda(dsdx, dsdy, dtdx, dtdy, - dqdx, dqdy, texW, texH, - s, t, q, invQ); - texcoord[i][0] = s * invQ; - texcoord[i][1] = t * invQ; - texcoord[i][2] = r * invQ; - texcoord[i][3] = q; - s += dsdx; - t += dtdx; - r += drdx; - q += dqdx; - } - } - span->arrayMask |= SPAN_LAMBDA; - } - else { - /* just texture 0, without lambda */ - GLfloat (*texcoord)[4] = span->array->attribs[FRAG_ATTRIB_TEX0]; - const GLfloat dsdx = span->attrStepX[FRAG_ATTRIB_TEX0][0]; - const GLfloat dtdx = span->attrStepX[FRAG_ATTRIB_TEX0][1]; - const GLfloat drdx = span->attrStepX[FRAG_ATTRIB_TEX0][2]; - const GLfloat dqdx = span->attrStepX[FRAG_ATTRIB_TEX0][3]; - GLfloat s = span->attrStart[FRAG_ATTRIB_TEX0][0]; - GLfloat t = span->attrStart[FRAG_ATTRIB_TEX0][1]; - GLfloat r = span->attrStart[FRAG_ATTRIB_TEX0][2]; - GLfloat q = span->attrStart[FRAG_ATTRIB_TEX0][3]; - GLuint i; - if (ctx->FragmentProgram._Current - || ctx->ATIFragmentShader._Enabled) { - /* do perspective correction but don't divide s, t, r by q */ - const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3]; - GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3]; - for (i = 0; i < span->end; i++) { - const GLfloat invW = 1.0F / w; - texcoord[i][0] = s * invW; - texcoord[i][1] = t * invW; - texcoord[i][2] = r * invW; - texcoord[i][3] = q * invW; - s += dsdx; - t += dtdx; - r += drdx; - q += dqdx; - w += dwdx; - } - } - else if (dqdx == 0.0F) { - /* Ortho projection or polygon's parallel to window X axis */ - const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); - for (i = 0; i < span->end; i++) { - texcoord[i][0] = s * invQ; - texcoord[i][1] = t * invQ; - texcoord[i][2] = r * invQ; - texcoord[i][3] = q; - s += dsdx; - t += dtdx; - r += drdx; + GLuint i; + if (ctx->FragmentProgram._Current || + ctx->ATIFragmentShader._Enabled) { + /* do perspective correction but don't divide s, t, r by q */ + const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3]; + GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3]; + for (i = 0; i < span->end; i++) { + const GLfloat invW = 1.0F / w; + texcoord[i][0] = s * invW; + texcoord[i][1] = t * invW; + texcoord[i][2] = r * invW; + texcoord[i][3] = q * invW; + lambda[i] = 0.0; + s += dsdx; + t += dtdx; + r += drdx; + q += dqdx; + w += dwdx; + } } - } - else { - for (i = 0; i < span->end; i++) { + else if (dqdx == 0.0F) { + /* Ortho projection or polygon's parallel to window X axis */ const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); - texcoord[i][0] = s * invQ; - texcoord[i][1] = t * invQ; - texcoord[i][2] = r * invQ; - texcoord[i][3] = q; - s += dsdx; - t += dtdx; - r += drdx; - q += dqdx; + for (i = 0; i < span->end; i++) { + texcoord[i][0] = s * invQ; + texcoord[i][1] = t * invQ; + texcoord[i][2] = r * invQ; + texcoord[i][3] = q; + lambda[i] = 0.0; + s += dsdx; + t += dtdx; + r += drdx; + } } - } - } - } + else { + for (i = 0; i < span->end; i++) { + const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q); + texcoord[i][0] = s * invQ; + texcoord[i][1] = t * invQ; + texcoord[i][2] = r * invQ; + texcoord[i][3] = q; + lambda[i] = 0.0; + s += dsdx; + t += dtdx; + r += drdx; + q += dqdx; + } + } + } /* lambda */ + } /* if */ + } /* for */ } + /** * Fill in the arrays->attribs[FRAG_ATTRIB_VARx] arrays from the * interpolation values. -- cgit v1.2.3 From 531348e814359a262eb1fe0a294749ab1b88045f Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 2 Feb 2007 11:20:08 -0700 Subject: simplify derivative-related code --- src/mesa/swrast/s_fragprog.c | 131 ++++++++++++++----------------------------- 1 file changed, 41 insertions(+), 90 deletions(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c index 090fd6dd97..343cdf5bc5 100644 --- a/src/mesa/swrast/s_fragprog.c +++ b/src/mesa/swrast/s_fragprog.c @@ -274,31 +274,18 @@ fetch_vector4_deriv( GLcontext *ctx, } break; case FRAG_ATTRIB_COL0: - if (xOrY == 'X') { - src[0] = span->attrStepX[FRAG_ATTRIB_COL0][0] * (1.0F / CHAN_MAXF); - src[1] = span->attrStepX[FRAG_ATTRIB_COL0][1] * (1.0F / CHAN_MAXF); - src[2] = span->attrStepX[FRAG_ATTRIB_COL0][2] * (1.0F / CHAN_MAXF); - src[3] = span->attrStepX[FRAG_ATTRIB_COL0][3] * (1.0F / CHAN_MAXF); - } - else { - src[0] = span->attrStepY[FRAG_ATTRIB_COL0][0] * (1.0F / CHAN_MAXF); - src[1] = span->attrStepY[FRAG_ATTRIB_COL0][1] * (1.0F / CHAN_MAXF); - src[2] = span->attrStepY[FRAG_ATTRIB_COL0][2] * (1.0F / CHAN_MAXF); - src[3] = span->attrStepY[FRAG_ATTRIB_COL0][3] * (1.0F / CHAN_MAXF); - } - break; case FRAG_ATTRIB_COL1: if (xOrY == 'X') { - src[0] = span->attrStepX[FRAG_ATTRIB_COL1][0] * (1.0F / CHAN_MAXF); - src[1] = span->attrStepX[FRAG_ATTRIB_COL1][1] * (1.0F / CHAN_MAXF); - src[2] = span->attrStepX[FRAG_ATTRIB_COL1][2] * (1.0F / CHAN_MAXF); - src[3] = span->attrStepX[FRAG_ATTRIB_COL1][3] * (1.0F / CHAN_MAXF); + src[0] = span->attrStepX[source->Index][0] * (1.0F / CHAN_MAXF); + src[1] = span->attrStepX[source->Index][1] * (1.0F / CHAN_MAXF); + src[2] = span->attrStepX[source->Index][2] * (1.0F / CHAN_MAXF); + src[3] = span->attrStepX[source->Index][3] * (1.0F / CHAN_MAXF); } else { - src[0] = span->attrStepY[FRAG_ATTRIB_COL1][0] * (1.0F / CHAN_MAXF); - src[1] = span->attrStepY[FRAG_ATTRIB_COL1][1] * (1.0F / CHAN_MAXF); - src[2] = span->attrStepY[FRAG_ATTRIB_COL1][2] * (1.0F / CHAN_MAXF); - src[3] = span->attrStepY[FRAG_ATTRIB_COL1][3] * (1.0F / CHAN_MAXF); + src[0] = span->attrStepY[source->Index][0] * (1.0F / CHAN_MAXF); + src[1] = span->attrStepY[source->Index][1] * (1.0F / CHAN_MAXF); + src[2] = span->attrStepY[source->Index][2] * (1.0F / CHAN_MAXF); + src[3] = span->attrStepY[source->Index][3] * (1.0F / CHAN_MAXF); } break; case FRAG_ATTRIB_FOGC: @@ -315,14 +302,9 @@ fetch_vector4_deriv( GLcontext *ctx, src[3] = 0.0; } break; - case FRAG_ATTRIB_TEX0: - case FRAG_ATTRIB_TEX1: - case FRAG_ATTRIB_TEX2: - case FRAG_ATTRIB_TEX3: - case FRAG_ATTRIB_TEX4: - case FRAG_ATTRIB_TEX5: - case FRAG_ATTRIB_TEX6: - case FRAG_ATTRIB_TEX7: + default: + assert(source->Index < FRAG_ATTRIB_MAX); + /* texcoord or varying */ if (xOrY == 'X') { /* this is a little tricky - I think I've got it right */ const GLfloat invQ = 1.0f / (span->attrStart[source->Index][3] @@ -342,8 +324,6 @@ fetch_vector4_deriv( GLcontext *ctx, src[3] = span->attrStepY[source->Index][3] * invQ; } break; - default: - return GL_FALSE; } result[0] = src[GET_SWZ(source->Swizzle, 0)]; @@ -543,7 +523,7 @@ init_machine_deriv( GLcontext *ctx, const SWspan *span, char xOrY, struct fp_machine *dMachine ) { - GLuint u, v; + GLuint attr; ASSERT(xOrY == 'X' || xOrY == 'Y'); @@ -572,34 +552,23 @@ init_machine_deriv( GLcontext *ctx, wpos[3] += span->attrStepY[FRAG_ATTRIB_WPOS][3]; } } - if (program->Base.InputsRead & FRAG_BIT_COL0) { - GLfloat *col0 = machine->Attribs[FRAG_ATTRIB_COL0][machine->CurFrag]; - if (xOrY == 'X') { - col0[0] += span->attrStepX[FRAG_ATTRIB_COL0][0] * (1.0F / CHAN_MAXF); - col0[1] += span->attrStepX[FRAG_ATTRIB_COL0][1] * (1.0F / CHAN_MAXF); - col0[2] += span->attrStepX[FRAG_ATTRIB_COL0][2] * (1.0F / CHAN_MAXF); - col0[3] += span->attrStepX[FRAG_ATTRIB_COL0][3] * (1.0F / CHAN_MAXF); - } - else { - col0[0] += span->attrStepY[FRAG_ATTRIB_COL0][0] * (1.0F / CHAN_MAXF); - col0[1] += span->attrStepY[FRAG_ATTRIB_COL0][1] * (1.0F / CHAN_MAXF); - col0[2] += span->attrStepY[FRAG_ATTRIB_COL0][2] * (1.0F / CHAN_MAXF); - col0[3] += span->attrStepY[FRAG_ATTRIB_COL0][3] * (1.0F / CHAN_MAXF); - } - } - if (program->Base.InputsRead & FRAG_BIT_COL1) { - GLfloat *col1 = machine->Attribs[FRAG_ATTRIB_COL1][machine->CurFrag]; - if (xOrY == 'X') { - col1[0] += span->attrStepX[FRAG_ATTRIB_COL1][0] * (1.0F / CHAN_MAXF); - col1[1] += span->attrStepX[FRAG_ATTRIB_COL1][1] * (1.0F / CHAN_MAXF); - col1[2] += span->attrStepX[FRAG_ATTRIB_COL1][2] * (1.0F / CHAN_MAXF); - col1[3] += span->attrStepX[FRAG_ATTRIB_COL1][3] * (1.0F / CHAN_MAXF); - } - else { - col1[0] += span->attrStepY[FRAG_ATTRIB_COL1][0] * (1.0F / CHAN_MAXF); - col1[1] += span->attrStepY[FRAG_ATTRIB_COL1][1] * (1.0F / CHAN_MAXF); - col1[2] += span->attrStepY[FRAG_ATTRIB_COL1][2] * (1.0F / CHAN_MAXF); - col1[3] += span->attrStepY[FRAG_ATTRIB_COL1][3] * (1.0F / CHAN_MAXF); + + /* primary, secondary colors */ + for (attr = FRAG_ATTRIB_COL0; attr <= FRAG_ATTRIB_COL1; attr++) { + if (program->Base.InputsRead & (1 << attr)) { + GLfloat *col = machine->Attribs[attr][machine->CurFrag]; + if (xOrY == 'X') { + col[0] += span->attrStepX[attr][0] * (1.0F / CHAN_MAXF); + col[1] += span->attrStepX[attr][1] * (1.0F / CHAN_MAXF); + col[2] += span->attrStepX[attr][2] * (1.0F / CHAN_MAXF); + col[3] += span->attrStepX[attr][3] * (1.0F / CHAN_MAXF); + } + else { + col[0] += span->attrStepY[attr][0] * (1.0F / CHAN_MAXF); + col[1] += span->attrStepY[attr][1] * (1.0F / CHAN_MAXF); + col[2] += span->attrStepY[attr][2] * (1.0F / CHAN_MAXF); + col[3] += span->attrStepY[attr][3] * (1.0F / CHAN_MAXF); + } } } if (program->Base.InputsRead & FRAG_BIT_FOGC) { @@ -611,40 +580,22 @@ init_machine_deriv( GLcontext *ctx, fogc[0] += span->attrStepY[FRAG_ATTRIB_FOGC][0]; } } - for (u = 0; u < ctx->Const.MaxTextureCoordUnits; u++) { - if (program->Base.InputsRead & FRAG_BIT_TEX(u)) { - GLfloat *tex = machine->Attribs[FRAG_ATTRIB_TEX0 + u][machine->CurFrag]; + /* texcoord and varying vars */ + for (attr = FRAG_ATTRIB_TEX0; attr < FRAG_ATTRIB_MAX; attr++) { + if (program->Base.InputsRead & (1 << attr)) { + GLfloat *val = machine->Attribs[attr][machine->CurFrag]; /* XXX perspective-correct interpolation */ if (xOrY == 'X') { - tex[0] += span->attrStepX[FRAG_ATTRIB_TEX0 + u][0]; - tex[1] += span->attrStepX[FRAG_ATTRIB_TEX0 + u][1]; - tex[2] += span->attrStepX[FRAG_ATTRIB_TEX0 + u][2]; - tex[3] += span->attrStepX[FRAG_ATTRIB_TEX0 + u][3]; - } - else { - tex[0] += span->attrStepY[FRAG_ATTRIB_TEX0 + u][0]; - tex[1] += span->attrStepY[FRAG_ATTRIB_TEX0 + u][1]; - tex[2] += span->attrStepY[FRAG_ATTRIB_TEX0 + u][2]; - tex[3] += span->attrStepY[FRAG_ATTRIB_TEX0 + u][3]; - } - } - } - - for (v = 0; v < ctx->Const.MaxVarying; v++) { - if (program->Base.InputsRead & FRAG_BIT_VAR(v)) { - GLfloat *var = machine->Attribs[FRAG_ATTRIB_VAR0 + v][machine->CurFrag]; - GLuint attr = FRAG_ATTRIB_VAR0 + v; - if (xOrY == 'X') { - var[0] += span->attrStepX[attr][0]; - var[1] += span->attrStepX[attr][1]; - var[2] += span->attrStepX[attr][2]; - var[3] += span->attrStepX[attr][3]; + val[0] += span->attrStepX[attr][0]; + val[1] += span->attrStepX[attr][1]; + val[2] += span->attrStepX[attr][2]; + val[3] += span->attrStepX[attr][3]; } else { - var[0] += span->attrStepY[attr][0]; - var[1] += span->attrStepY[attr][1]; - var[2] += span->attrStepY[attr][2]; - var[3] += span->attrStepY[attr][3]; + val[0] += span->attrStepY[attr][0]; + val[1] += span->attrStepY[attr][1]; + val[2] += span->attrStepY[attr][2]; + val[3] += span->attrStepY[attr][3]; } } } -- cgit v1.2.3 From 6147ccba630f42a76666d72ef0425c5166bc4018 Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 2 Feb 2007 11:23:16 -0700 Subject: unroll inner loop of interpolate_varying() --- src/mesa/swrast/s_span.c | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c index 6fb5998627..724cf616e8 100644 --- a/src/mesa/swrast/s_span.c +++ b/src/mesa/swrast/s_span.c @@ -702,19 +702,28 @@ interpolate_varying(GLcontext *ctx, SWspan *span) for (var = 0; var < MAX_VARYING; var++) { if (inputsUsed & FRAG_BIT_VAR(var)) { const GLuint attr = FRAG_ATTRIB_VAR0 + var; - GLuint j; - for (j = 0; j < 4; j++) { - const GLfloat dvdx = span->attrStepX[attr][j]; - GLfloat v = span->attrStart[attr][j]; - const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3]; - GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3]; - GLuint k; - for (k = 0; k < span->end; k++) { - GLfloat invW = 1.0f / w; - span->array->attribs[attr][k][j] = v * invW; - v += dvdx; - w += dwdx; - } + const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3]; + GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3]; + const GLfloat dv0dx = span->attrStepX[attr][0]; + const GLfloat dv1dx = span->attrStepX[attr][1]; + const GLfloat dv2dx = span->attrStepX[attr][2]; + const GLfloat dv3dx = span->attrStepX[attr][3]; + GLfloat v0 = span->attrStart[attr][0]; + GLfloat v1 = span->attrStart[attr][1]; + GLfloat v2 = span->attrStart[attr][2]; + GLfloat v3 = span->attrStart[attr][3]; + GLuint k; + for (k = 0; k < span->end; k++) { + GLfloat invW = 1.0f / w; + span->array->attribs[attr][k][0] = v0 * invW; + span->array->attribs[attr][k][1] = v1 * invW; + span->array->attribs[attr][k][2] = v2 * invW; + span->array->attribs[attr][k][3] = v3 * invW; + v0 += dv0dx; + v1 += dv1dx; + v2 += dv2dx; + v3 += dv3dx; + w += dwdx; } } } -- cgit v1.2.3 From 2f5b3c9607fd48418a5b3d3dcd6035a3b976b166 Mon Sep 17 00:00:00 2001 From: Brian Date: Fri, 2 Feb 2007 11:37:58 -0700 Subject: fix maxInst argument --- src/mesa/swrast/s_fragprog.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c index 343cdf5bc5..740360d460 100644 --- a/src/mesa/swrast/s_fragprog.c +++ b/src/mesa/swrast/s_fragprog.c @@ -1683,7 +1683,8 @@ run_program(GLcontext *ctx, SWspan *span, GLuint start, GLuint end) if (span->array->mask[i]) { init_machine(ctx, &machine, program, span, i); - if (execute_program(ctx, program, ~0, &machine, span, i)) { + if (execute_program(ctx, program, program->Base.NumInstructions, + &machine, span, i)) { /* Store result color */ COPY_4V(span->array->attribs[FRAG_ATTRIB_COL0][i], machine.Outputs[FRAG_RESULT_COLR]); -- cgit v1.2.3 From dd34fe8679fa200e55cfaf8e80bbecdecea084e3 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 5 Feb 2007 10:10:01 -0700 Subject: Merge SWvertex texcoord and varying fields into attrib[] array field. Fragment texcoords and varying code is now unified in the point/line/triangle rasterization code. In the future, merge color, fog, etc. attribs. --- src/mesa/swrast/s_aaline.c | 51 ++++----- src/mesa/swrast/s_aalinetemp.h | 121 ++++++++------------ src/mesa/swrast/s_aatriangle.c | 52 ++------- src/mesa/swrast/s_aatritemp.h | 217 ++++++++++++++--------------------- src/mesa/swrast/s_context.c | 56 ++++++++- src/mesa/swrast/s_context.h | 7 ++ src/mesa/swrast/s_feedback.c | 17 ++- src/mesa/swrast/s_linetemp.h | 81 ++++--------- src/mesa/swrast/s_pointtemp.h | 59 +++++----- src/mesa/swrast/s_triangle.c | 31 +---- src/mesa/swrast/s_tritemp.h | 229 ++++++++++++------------------------- src/mesa/swrast/swrast.h | 3 +- src/mesa/swrast_setup/ss_context.c | 13 ++- 13 files changed, 372 insertions(+), 565 deletions(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/swrast/s_aaline.c b/src/mesa/swrast/s_aaline.c index b3a209923f..c81095163b 100644 --- a/src/mesa/swrast/s_aaline.c +++ b/src/mesa/swrast/s_aaline.c @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.1 + * Version: 6.5.3 * - * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -67,14 +67,14 @@ struct LineInfo GLfloat iPlane[4]; /* DO_SPEC */ GLfloat srPlane[4], sgPlane[4], sbPlane[4]; - /* DO_TEX or DO_MULTITEX */ - GLfloat sPlane[MAX_TEXTURE_COORD_UNITS][4]; - GLfloat tPlane[MAX_TEXTURE_COORD_UNITS][4]; - GLfloat uPlane[MAX_TEXTURE_COORD_UNITS][4]; - GLfloat vPlane[MAX_TEXTURE_COORD_UNITS][4]; - GLfloat lambda[MAX_TEXTURE_COORD_UNITS]; - GLfloat texWidth[MAX_TEXTURE_COORD_UNITS]; - GLfloat texHeight[MAX_TEXTURE_COORD_UNITS]; + /* DO_TEXVAR */ + GLfloat sPlane[FRAG_ATTRIB_MAX][4]; + GLfloat tPlane[FRAG_ATTRIB_MAX][4]; + GLfloat uPlane[FRAG_ATTRIB_MAX][4]; + GLfloat vPlane[FRAG_ATTRIB_MAX][4]; + GLfloat lambda[FRAG_ATTRIB_MAX]; + GLfloat texWidth[FRAG_ATTRIB_MAX]; + GLfloat texHeight[FRAG_ATTRIB_MAX]; SWspan span; }; @@ -499,15 +499,7 @@ segment(GLcontext *ctx, #define DO_Z #define DO_FOG #define DO_RGBA -#define DO_TEX -#include "s_aalinetemp.h" - - -#define NAME(x) aa_multitex_rgba_##x -#define DO_Z -#define DO_FOG -#define DO_RGBA -#define DO_MULTITEX +#define DO_TEXVAR #include "s_aalinetemp.h" @@ -515,7 +507,7 @@ segment(GLcontext *ctx, #define DO_Z #define DO_FOG #define DO_RGBA -#define DO_MULTITEX +#define DO_TEXVAR #define DO_SPEC #include "s_aalinetemp.h" @@ -530,18 +522,15 @@ _swrast_choose_aa_line_function(GLcontext *ctx) if (ctx->Visual.rgbMode) { /* RGBA */ - if (ctx->Texture._EnabledCoordUnits != 0) { - if (ctx->Texture._EnabledCoordUnits > 1) { - /* Multitextured! */ - if (ctx->Light.Model.ColorControl==GL_SEPARATE_SPECULAR_COLOR || - ctx->Fog.ColorSumEnabled) - swrast->Line = aa_multitex_spec_line; - else - swrast->Line = aa_multitex_rgba_line; - } - else { + if (ctx->Texture._EnabledCoordUnits != 0 + || ctx->FragmentProgram._Current) { + + if (ctx->Light.Model.ColorControl==GL_SEPARATE_SPECULAR_COLOR || + ctx->Fog.ColorSumEnabled) + swrast->Line = aa_multitex_spec_line; + else swrast->Line = aa_tex_rgba_line; - } + } else { swrast->Line = aa_rgba_line; diff --git a/src/mesa/swrast/s_aalinetemp.h b/src/mesa/swrast/s_aalinetemp.h index b977ab8325..4d33b7dff7 100644 --- a/src/mesa/swrast/s_aalinetemp.h +++ b/src/mesa/swrast/s_aalinetemp.h @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * Version: 6.5.3 * - * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -36,6 +36,7 @@ static void NAME(plot)(GLcontext *ctx, struct LineInfo *line, int ix, int iy) { + const SWcontext *swrast = SWRAST_CONTEXT(ctx); const GLfloat fx = (GLfloat) ix; const GLfloat fy = (GLfloat) iy; #ifdef DO_INDEX @@ -45,6 +46,8 @@ NAME(plot)(GLcontext *ctx, struct LineInfo *line, int ix, int iy) #endif const GLuint i = line->span.end; + (void) swrast; + if (coverage == 0.0) return; @@ -77,41 +80,29 @@ NAME(plot)(GLcontext *ctx, struct LineInfo *line, int ix, int iy) line->span.array->spec[i][GCOMP] = solve_plane_chan(fx, fy, line->sgPlane); line->span.array->spec[i][BCOMP] = solve_plane_chan(fx, fy, line->sbPlane); #endif -#ifdef DO_TEX - { - GLfloat invQ; - if (ctx->FragmentProgram._Current) { - invQ = 1.0F; - } - else { - invQ = solve_plane_recip(fx, fy, line->vPlane[0]); - } - line->span.array->attribs[FRAG_ATTRIB_TEX0][i][0] = solve_plane(fx, fy, line->sPlane[0]) * invQ; - line->span.array->attribs[FRAG_ATTRIB_TEX0][i][1] = solve_plane(fx, fy, line->tPlane[0]) * invQ; - line->span.array->attribs[FRAG_ATTRIB_TEX0][i][2] = solve_plane(fx, fy, line->uPlane[0]) * invQ; - line->span.array->lambda[0][i] = compute_lambda(line->sPlane[0], - line->tPlane[0], invQ, - line->texWidth[0], - line->texHeight[0]); - } -#elif defined(DO_MULTITEX) +#if defined(DO_TEXVAR) { - GLuint unit; - for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { - if (ctx->Texture.Unit[unit]._ReallyEnabled) { + GLuint attr; + for (attr = swrast->_MinFragmentAttrib; attr < swrast->_MaxFragmentAttrib; attr++) { + if (swrast->_FragmentAttribs & (1 << attr)) { + GLfloat (*attribArray)[4] = line->span.array->attribs[attr]; GLfloat invQ; if (ctx->FragmentProgram._Current) { invQ = 1.0F; } else { - invQ = solve_plane_recip(fx, fy, line->vPlane[unit]); + invQ = solve_plane_recip(fx, fy, line->vPlane[attr]); + } + attribArray[i][0] = solve_plane(fx, fy, line->sPlane[attr]) * invQ; + attribArray[i][1] = solve_plane(fx, fy, line->tPlane[attr]) * invQ; + attribArray[i][2] = solve_plane(fx, fy, line->uPlane[attr]) * invQ; + if (attr < FRAG_ATTRIB_VAR0) { + const GLuint unit = attr - FRAG_ATTRIB_TEX0; + line->span.array->lambda[unit][i] + = compute_lambda(line->sPlane[attr], + line->tPlane[attr], invQ, + line->texWidth[attr], line->texHeight[attr]); } - line->span.array->attribs[FRAG_ATTRIB_TEX0 + unit][i][0] = solve_plane(fx, fy, line->sPlane[unit]) * invQ; - line->span.array->attribs[FRAG_ATTRIB_TEX0 + unit][i][1] = solve_plane(fx, fy, line->tPlane[unit]) * invQ; - line->span.array->attribs[FRAG_ATTRIB_TEX0 + unit][i][2] = solve_plane(fx, fy, line->uPlane[unit]) * invQ; - line->span.array->lambda[unit][i] = compute_lambda(line->sPlane[unit], - line->tPlane[unit], invQ, - line->texWidth[unit], line->texHeight[unit]); } } } @@ -214,52 +205,33 @@ NAME(line)(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1) constant_plane(v1->index, line.iPlane); } #endif -#ifdef DO_TEX +#if defined(DO_TEXVAR) { - const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current; - const struct gl_texture_image *texImage = obj->Image[0][obj->BaseLevel]; + GLuint attr; const GLfloat invW0 = v0->win[3]; const GLfloat invW1 = v1->win[3]; - const GLfloat s0 = v0->texcoord[0][0] * invW0; - const GLfloat s1 = v1->texcoord[0][0] * invW1; - const GLfloat t0 = v0->texcoord[0][1] * invW0; - const GLfloat t1 = v1->texcoord[0][1] * invW1; - const GLfloat r0 = v0->texcoord[0][2] * invW0; - const GLfloat r1 = v1->texcoord[0][2] * invW1; - const GLfloat q0 = v0->texcoord[0][3] * invW0; - const GLfloat q1 = v1->texcoord[0][3] * invW1; - line.span.arrayMask |= (SPAN_TEXTURE | SPAN_LAMBDA); - compute_plane(line.x0, line.y0, line.x1, line.y1, s0, s1, line.sPlane[0]); - compute_plane(line.x0, line.y0, line.x1, line.y1, t0, t1, line.tPlane[0]); - compute_plane(line.x0, line.y0, line.x1, line.y1, r0, r1, line.uPlane[0]); - compute_plane(line.x0, line.y0, line.x1, line.y1, q0, q1, line.vPlane[0]); - line.texWidth[0] = (GLfloat) texImage->Width; - line.texHeight[0] = (GLfloat) texImage->Height; - } -#elif defined(DO_MULTITEX) - { - GLuint u; - line.span.arrayMask |= (SPAN_TEXTURE | SPAN_LAMBDA); - for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { - if (ctx->Texture.Unit[u]._ReallyEnabled) { - const struct gl_texture_object *obj = ctx->Texture.Unit[u]._Current; - const struct gl_texture_image *texImage = obj->Image[0][obj->BaseLevel]; - const GLfloat invW0 = v0->win[3]; - const GLfloat invW1 = v1->win[3]; - const GLfloat s0 = v0->texcoord[u][0] * invW0; - const GLfloat s1 = v1->texcoord[u][0] * invW1; - const GLfloat t0 = v0->texcoord[u][1] * invW0; - const GLfloat t1 = v1->texcoord[u][1] * invW1; - const GLfloat r0 = v0->texcoord[u][2] * invW0; - const GLfloat r1 = v1->texcoord[u][2] * invW1; - const GLfloat q0 = v0->texcoord[u][3] * invW0; - const GLfloat q1 = v1->texcoord[u][3] * invW1; - compute_plane(line.x0, line.y0, line.x1, line.y1, s0, s1, line.sPlane[u]); - compute_plane(line.x0, line.y0, line.x1, line.y1, t0, t1, line.tPlane[u]); - compute_plane(line.x0, line.y0, line.x1, line.y1, r0, r1, line.uPlane[u]); - compute_plane(line.x0, line.y0, line.x1, line.y1, q0, q1, line.vPlane[u]); - line.texWidth[u] = (GLfloat) texImage->Width; - line.texHeight[u] = (GLfloat) texImage->Height; + line.span.arrayMask |= (SPAN_TEXTURE | SPAN_LAMBDA | SPAN_VARYING); + for (attr = swrast->_MinFragmentAttrib; attr < swrast->_MaxFragmentAttrib; attr++) { + if (swrast->_FragmentAttribs & (1 << attr)) { + const GLfloat s0 = v0->attrib[attr][0] * invW0; + const GLfloat s1 = v1->attrib[attr][0] * invW1; + const GLfloat t0 = v0->attrib[attr][1] * invW0; + const GLfloat t1 = v1->attrib[attr][1] * invW1; + const GLfloat r0 = v0->attrib[attr][2] * invW0; + const GLfloat r1 = v1->attrib[attr][2] * invW1; + const GLfloat q0 = v0->attrib[attr][3] * invW0; + const GLfloat q1 = v1->attrib[attr][3] * invW1; + compute_plane(line.x0, line.y0, line.x1, line.y1, s0, s1, line.sPlane[attr]); + compute_plane(line.x0, line.y0, line.x1, line.y1, t0, t1, line.tPlane[attr]); + compute_plane(line.x0, line.y0, line.x1, line.y1, r0, r1, line.uPlane[attr]); + compute_plane(line.x0, line.y0, line.x1, line.y1, q0, q1, line.vPlane[attr]); + if (attr < FRAG_ATTRIB_VAR0) { + const GLuint u = attr - FRAG_ATTRIB_TEX0; + const struct gl_texture_object *obj = ctx->Texture.Unit[u]._Current; + const struct gl_texture_image *texImage = obj->Image[0][obj->BaseLevel]; + line.texWidth[attr] = (GLfloat) texImage->Width; + line.texHeight[attr] = (GLfloat) texImage->Height; + } } } } @@ -324,6 +296,5 @@ NAME(line)(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1) #undef DO_RGBA #undef DO_INDEX #undef DO_SPEC -#undef DO_TEX -#undef DO_MULTITEX +#undef DO_TEXVAR #undef NAME diff --git a/src/mesa/swrast/s_aatriangle.c b/src/mesa/swrast/s_aatriangle.c index 63a13cf3fb..5e3059af93 100644 --- a/src/mesa/swrast/s_aatriangle.c +++ b/src/mesa/swrast/s_aatriangle.c @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.3 + * Version: 6.5.3 * - * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -408,7 +408,7 @@ tex_aa_tri(GLcontext *ctx, #define DO_Z #define DO_FOG #define DO_RGBA -#define DO_TEX +#define DO_TEXVAR #include "s_aatritemp.h" } @@ -422,39 +422,12 @@ spec_tex_aa_tri(GLcontext *ctx, #define DO_Z #define DO_FOG #define DO_RGBA -#define DO_TEX +#define DO_TEXVAR #define DO_SPEC #include "s_aatritemp.h" } -static void -multitex_aa_tri(GLcontext *ctx, - const SWvertex *v0, - const SWvertex *v1, - const SWvertex *v2) -{ -#define DO_Z -#define DO_FOG -#define DO_RGBA -#define DO_MULTITEX -#include "s_aatritemp.h" -} - -static void -spec_multitex_aa_tri(GLcontext *ctx, - const SWvertex *v0, - const SWvertex *v1, - const SWvertex *v2) -{ -#define DO_Z -#define DO_FOG -#define DO_RGBA -#define DO_MULTITEX -#define DO_SPEC -#include "s_aatritemp.h" -} - /* * Examine GL state and set swrast->Triangle to an @@ -465,22 +438,13 @@ _swrast_set_aa_triangle_function(GLcontext *ctx) { ASSERT(ctx->Polygon.SmoothFlag); - if (ctx->Texture._EnabledCoordUnits != 0) { + if (ctx->Texture._EnabledCoordUnits != 0 + || ctx->FragmentProgram._Current) { if (NEED_SECONDARY_COLOR(ctx)) { - if (ctx->Texture._EnabledCoordUnits > 1) { - SWRAST_CONTEXT(ctx)->Triangle = spec_multitex_aa_tri; - } - else { - SWRAST_CONTEXT(ctx)->Triangle = spec_tex_aa_tri; - } + SWRAST_CONTEXT(ctx)->Triangle = spec_tex_aa_tri; } else { - if (ctx->Texture._EnabledCoordUnits > 1) { - SWRAST_CONTEXT(ctx)->Triangle = multitex_aa_tri; - } - else { - SWRAST_CONTEXT(ctx)->Triangle = tex_aa_tri; - } + SWRAST_CONTEXT(ctx)->Triangle = tex_aa_tri; } } else if (ctx->Visual.rgbMode) { diff --git a/src/mesa/swrast/s_aatritemp.h b/src/mesa/swrast/s_aatritemp.h index 3359a919e5..bbf9cc611d 100644 --- a/src/mesa/swrast/s_aatritemp.h +++ b/src/mesa/swrast/s_aatritemp.h @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * Version: 6.5.3 * - * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -36,12 +36,12 @@ * DO_RGBA - if defined, compute RGBA values * DO_INDEX - if defined, compute color index values * DO_SPEC - if defined, compute specular RGB values - * DO_TEX - if defined, compute unit 0 STRQ texcoords - * DO_MULTITEX - if defined, compute all unit's STRQ texcoords + * DO_TEXVAR - if defined, compute texcoords, varying */ /*void triangle( GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint pv )*/ { + const SWcontext *swrast = SWRAST_CONTEXT(ctx); const GLfloat *p0 = v0->win; const GLfloat *p1 = v1->win; const GLfloat *p2 = v2->win; @@ -70,20 +70,18 @@ #ifdef DO_SPEC GLfloat srPlane[4], sgPlane[4], sbPlane[4]; #endif -#ifdef DO_TEX - GLfloat sPlane[4], tPlane[4], uPlane[4], vPlane[4]; - GLfloat texWidth, texHeight; -#elif defined(DO_MULTITEX) - GLfloat sPlane[MAX_TEXTURE_COORD_UNITS][4]; /* texture S */ - GLfloat tPlane[MAX_TEXTURE_COORD_UNITS][4]; /* texture T */ - GLfloat uPlane[MAX_TEXTURE_COORD_UNITS][4]; /* texture R */ - GLfloat vPlane[MAX_TEXTURE_COORD_UNITS][4]; /* texture Q */ - GLfloat texWidth[MAX_TEXTURE_COORD_UNITS]; - GLfloat texHeight[MAX_TEXTURE_COORD_UNITS]; +#if defined(DO_TEXVAR) + GLfloat sPlane[FRAG_ATTRIB_MAX][4]; /* texture S */ + GLfloat tPlane[FRAG_ATTRIB_MAX][4]; /* texture T */ + GLfloat uPlane[FRAG_ATTRIB_MAX][4]; /* texture R */ + GLfloat vPlane[FRAG_ATTRIB_MAX][4]; /* texture Q */ + GLfloat texWidth[FRAG_ATTRIB_MAX]; + GLfloat texHeight[FRAG_ATTRIB_MAX]; #endif GLfloat bf = SWRAST_CONTEXT(ctx)->_BackfaceSign; - + (void) swrast; + INIT_SPAN(span, GL_POLYGON, 0, 0, SPAN_COVERAGE); /* determine bottom to top order of vertices */ @@ -179,65 +177,44 @@ } span.arrayMask |= SPAN_SPEC; #endif -#ifdef DO_TEX +#if defined(DO_TEXVAR) { - const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current; - const struct gl_texture_image *texImage = obj->Image[0][obj->BaseLevel]; + GLuint attr; const GLfloat invW0 = v0->win[3]; const GLfloat invW1 = v1->win[3]; const GLfloat invW2 = v2->win[3]; - const GLfloat s0 = v0->texcoord[0][0] * invW0; - const GLfloat s1 = v1->texcoord[0][0] * invW1; - const GLfloat s2 = v2->texcoord[0][0] * invW2; - const GLfloat t0 = v0->texcoord[0][1] * invW0; - const GLfloat t1 = v1->texcoord[0][1] * invW1; - const GLfloat t2 = v2->texcoord[0][1] * invW2; - const GLfloat r0 = v0->texcoord[0][2] * invW0; - const GLfloat r1 = v1->texcoord[0][2] * invW1; - const GLfloat r2 = v2->texcoord[0][2] * invW2; - const GLfloat q0 = v0->texcoord[0][3] * invW0; - const GLfloat q1 = v1->texcoord[0][3] * invW1; - const GLfloat q2 = v2->texcoord[0][3] * invW2; - compute_plane(p0, p1, p2, s0, s1, s2, sPlane); - compute_plane(p0, p1, p2, t0, t1, t2, tPlane); - compute_plane(p0, p1, p2, r0, r1, r2, uPlane); - compute_plane(p0, p1, p2, q0, q1, q2, vPlane); - texWidth = (GLfloat) texImage->Width; - texHeight = (GLfloat) texImage->Height; - } - span.arrayMask |= (SPAN_TEXTURE | SPAN_LAMBDA); -#elif defined(DO_MULTITEX) - { - GLuint u; - for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { - if (ctx->Texture.Unit[u]._ReallyEnabled) { - const struct gl_texture_object *obj = ctx->Texture.Unit[u]._Current; - const struct gl_texture_image *texImage = obj->Image[0][obj->BaseLevel]; - const GLfloat invW0 = v0->win[3]; - const GLfloat invW1 = v1->win[3]; - const GLfloat invW2 = v2->win[3]; - const GLfloat s0 = v0->texcoord[u][0] * invW0; - const GLfloat s1 = v1->texcoord[u][0] * invW1; - const GLfloat s2 = v2->texcoord[u][0] * invW2; - const GLfloat t0 = v0->texcoord[u][1] * invW0; - const GLfloat t1 = v1->texcoord[u][1] * invW1; - const GLfloat t2 = v2->texcoord[u][1] * invW2; - const GLfloat r0 = v0->texcoord[u][2] * invW0; - const GLfloat r1 = v1->texcoord[u][2] * invW1; - const GLfloat r2 = v2->texcoord[u][2] * invW2; - const GLfloat q0 = v0->texcoord[u][3] * invW0; - const GLfloat q1 = v1->texcoord[u][3] * invW1; - const GLfloat q2 = v2->texcoord[u][3] * invW2; - compute_plane(p0, p1, p2, s0, s1, s2, sPlane[u]); - compute_plane(p0, p1, p2, t0, t1, t2, tPlane[u]); - compute_plane(p0, p1, p2, r0, r1, r2, uPlane[u]); - compute_plane(p0, p1, p2, q0, q1, q2, vPlane[u]); - texWidth[u] = (GLfloat) texImage->Width; - texHeight[u] = (GLfloat) texImage->Height; + for (attr = swrast->_MinFragmentAttrib; attr < swrast->_MaxFragmentAttrib; attr++) { + if (swrast->_FragmentAttribs & (1 << attr)) { + const GLfloat s0 = v0->attrib[attr][0] * invW0; + const GLfloat s1 = v1->attrib[attr][0] * invW1; + const GLfloat s2 = v2->attrib[attr][0] * invW2; + const GLfloat t0 = v0->attrib[attr][1] * invW0; + const GLfloat t1 = v1->attrib[attr][1] * invW1; + const GLfloat t2 = v2->attrib[attr][1] * invW2; + const GLfloat r0 = v0->attrib[attr][2] * invW0; + const GLfloat r1 = v1->attrib[attr][2] * invW1; + const GLfloat r2 = v2->attrib[attr][2] * invW2; + const GLfloat q0 = v0->attrib[attr][3] * invW0; + const GLfloat q1 = v1->attrib[attr][3] * invW1; + const GLfloat q2 = v2->attrib[attr][3] * invW2; + compute_plane(p0, p1, p2, s0, s1, s2, sPlane[attr]); + compute_plane(p0, p1, p2, t0, t1, t2, tPlane[attr]); + compute_plane(p0, p1, p2, r0, r1, r2, uPlane[attr]); + compute_plane(p0, p1, p2, q0, q1, q2, vPlane[attr]); + if (attr < FRAG_ATTRIB_VAR0) { + const GLuint u = attr - FRAG_ATTRIB_TEX0; + const struct gl_texture_object *obj = ctx->Texture.Unit[u]._Current; + const struct gl_texture_image *texImage = obj->Image[0][obj->BaseLevel]; + texWidth[attr] = (GLfloat) texImage->Width; + texHeight[attr] = (GLfloat) texImage->Height; + } + else { + texWidth[attr] = texHeight[attr] = 1.0; + } } } } - span.arrayMask |= (SPAN_TEXTURE | SPAN_LAMBDA); + span.arrayMask |= (SPAN_TEXTURE | SPAN_LAMBDA | SPAN_VARYING); #endif /* Begin bottom-to-top scan over the triangle. @@ -305,28 +282,21 @@ array->spec[count][GCOMP] = solve_plane_chan(cx, cy, sgPlane); array->spec[count][BCOMP] = solve_plane_chan(cx, cy, sbPlane); #endif -#ifdef DO_TEX +#if defined(DO_TEXVAR) { - const GLfloat invQ = solve_plane_recip(cx, cy, vPlane); - array->attribs[FRAG_ATTRIB_TEX0 + 0][count][0] = solve_plane(cx, cy, sPlane) * invQ; - array->attribs[FRAG_ATTRIB_TEX0 + 0][count][1] = solve_plane(cx, cy, tPlane) * invQ; - array->attribs[FRAG_ATTRIB_TEX0 + 0][count][2] = solve_plane(cx, cy, uPlane) * invQ; - array->lambda[0][count] = compute_lambda(sPlane, tPlane, vPlane, - cx, cy, invQ, - texWidth, texHeight); - } -#elif defined(DO_MULTITEX) - { - GLuint unit; - for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { - if (ctx->Texture.Unit[unit]._ReallyEnabled) { - GLfloat invQ = solve_plane_recip(cx, cy, vPlane[unit]); - array->attribs[FRAG_ATTRIB_TEX0 + unit][count][0] = solve_plane(cx, cy, sPlane[unit]) * invQ; - array->attribs[FRAG_ATTRIB_TEX0 + unit][count][1] = solve_plane(cx, cy, tPlane[unit]) * invQ; - array->attribs[FRAG_ATTRIB_TEX0 + unit][count][2] = solve_plane(cx, cy, uPlane[unit]) * invQ; - array->lambda[unit][count] = compute_lambda(sPlane[unit], - tPlane[unit], vPlane[unit], cx, cy, invQ, - texWidth[unit], texHeight[unit]); + GLuint attr; + for (attr = swrast->_MinFragmentAttrib; attr < swrast->_MaxFragmentAttrib; attr++) { + if (swrast->_FragmentAttribs & (1 << attr)) { + GLfloat invQ = solve_plane_recip(cx, cy, vPlane[attr]); + array->attribs[attr][count][0] = solve_plane(cx, cy, sPlane[attr]) * invQ; + array->attribs[attr][count][1] = solve_plane(cx, cy, tPlane[attr]) * invQ; + array->attribs[attr][count][2] = solve_plane(cx, cy, uPlane[attr]) * invQ; + if (attr < FRAG_ATTRIB_VAR0) { + const GLuint unit = attr - FRAG_ATTRIB_TEX0; + array->lambda[unit][count] = compute_lambda(sPlane[attr], tPlane[attr], + vPlane[attr], cx, cy, invQ, + texWidth[attr], texHeight[attr]); + } } } } @@ -409,30 +379,24 @@ array->spec[ix][GCOMP] = solve_plane_chan(cx, cy, sgPlane); array->spec[ix][BCOMP] = solve_plane_chan(cx, cy, sbPlane); #endif -#ifdef DO_TEX - { - const GLfloat invQ = solve_plane_recip(cx, cy, vPlane); - array->attribs[FRAG_ATTRIB_TEX0][ix][0] = solve_plane(cx, cy, sPlane) * invQ; - array->attribs[FRAG_ATTRIB_TEX0][ix][1] = solve_plane(cx, cy, tPlane) * invQ; - array->attribs[FRAG_ATTRIB_TEX0][ix][2] = solve_plane(cx, cy, uPlane) * invQ; - array->lambda[0][ix] = compute_lambda(sPlane, tPlane, vPlane, - cx, cy, invQ, texWidth, texHeight); - } -#elif defined(DO_MULTITEX) +#if defined(DO_TEXVAR) { - GLuint unit; - for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { - if (ctx->Texture.Unit[unit]._ReallyEnabled) { - GLfloat invQ = solve_plane_recip(cx, cy, vPlane[unit]); - array->attribs[FRAG_ATTRIB_TEX0 + unit][ix][0] = solve_plane(cx, cy, sPlane[unit]) * invQ; - array->attribs[FRAG_ATTRIB_TEX0 + unit][ix][1] = solve_plane(cx, cy, tPlane[unit]) * invQ; - array->attribs[FRAG_ATTRIB_TEX0 + unit][ix][2] = solve_plane(cx, cy, uPlane[unit]) * invQ; - array->lambda[unit][ix] = compute_lambda(sPlane[unit], - tPlane[unit], - vPlane[unit], - cx, cy, invQ, - texWidth[unit], - texHeight[unit]); + GLuint attr; + for (attr = swrast->_MinFragmentAttrib; attr < swrast->_MaxFragmentAttrib; attr++) { + if (swrast->_FragmentAttribs & (1 << attr)) { + GLfloat invQ = solve_plane_recip(cx, cy, vPlane[attr]); + array->attribs[attr][ix][0] = solve_plane(cx, cy, sPlane[attr]) * invQ; + array->attribs[attr][ix][1] = solve_plane(cx, cy, tPlane[attr]) * invQ; + array->attribs[attr][ix][2] = solve_plane(cx, cy, uPlane[attr]) * invQ; + if (attr < FRAG_ATTRIB_VAR0) { + const GLuint unit = attr - FRAG_ATTRIB_TEX0; + array->lambda[unit][ix] = compute_lambda(sPlane[attr], + tPlane[attr], + vPlane[attr], + cx, cy, invQ, + texWidth[attr], + texHeight[attr]); + } } } } @@ -471,28 +435,25 @@ array->attribs[FRAG_ATTRIB_FOGC][j][0] = array->attribs[FRAG_ATTRIB_FOGC][j + left][0]; #endif -#ifdef DO_TEX - COPY_4V(array->attribs[FRAG_ATTRIB_TEX0 + 0][j], array->attribs[FRAG_ATTRIB_TEX0 + 0][j + left]); -#endif -#if defined(DO_MULTITEX) || defined(DO_TEX) +#if defined(DO_TEXVAR) array->lambda[0][j] = array->lambda[0][j + left]; #endif array->coverage[j] = array->coverage[j + left]; } } -#ifdef DO_MULTITEX - /* shift texcoords */ +#ifdef DO_TEXVAR + /* shift texcoords, varying */ { SWspanarrays *array = span.array; - GLuint unit; - for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) { - if (ctx->Texture.Unit[unit]._ReallyEnabled) { + GLuint attr; + for (attr = swrast->_MinFragmentAttrib; attr < swrast->_MaxFragmentAttrib; attr++) { + if (swrast->_FragmentAttribs & (1 << attr)) { GLint j; for (j = 0; j < (GLint) n; j++) { - array->attribs[FRAG_ATTRIB_TEX0 + unit][j][0] = array->attribs[FRAG_ATTRIB_TEX0 + unit][j + left][0]; - array->attribs[FRAG_ATTRIB_TEX0 + unit][j][1] = array->attribs[FRAG_ATTRIB_TEX0 + unit][j + left][1]; - array->attribs[FRAG_ATTRIB_TEX0 + unit][j][2] = array->attribs[FRAG_ATTRIB_TEX0 + unit][j + left][2]; - array->lambda[unit][j] = array->lambda[unit][j + left]; + array->attribs[attr][j][0] = array->attribs[attr][j + left][0]; + array->attribs[attr][j][1] = array->attribs[attr][j + left][1]; + array->attribs[attr][j][2] = array->attribs[attr][j + left][2]; + /*array->lambda[unit][j] = array->lambda[unit][j + left];*/ } } } @@ -533,12 +494,8 @@ #undef DO_SPEC #endif -#ifdef DO_TEX -#undef DO_TEX -#endif - -#ifdef DO_MULTITEX -#undef DO_MULTITEX +#ifdef DO_TEXVAR +#undef DO_TEXVAR #endif #ifdef DO_OCCLUSION_TEST diff --git a/src/mesa/swrast/s_context.c b/src/mesa/swrast/s_context.c index ec2f3d68b8..d8a5520f6b 100644 --- a/src/mesa/swrast/s_context.c +++ b/src/mesa/swrast/s_context.c @@ -507,6 +507,50 @@ _swrast_update_texture_samplers(GLcontext *ctx) } +/** + * Update the swrast->_FragmentAttribs field. + */ +static void +_swrast_update_fragment_attribs(GLcontext *ctx) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + + if (ctx->FragmentProgram._Current) { + swrast->_FragmentAttribs + = ctx->FragmentProgram._Current->Base.InputsRead; + } + else { + GLuint u; + swrast->_FragmentAttribs = 0x0; + + if (ctx->Depth.Test) + swrast->_FragmentAttribs |= FRAG_BIT_WPOS; + if (NEED_SECONDARY_COLOR(ctx)) + swrast->_FragmentAttribs |= FRAG_BIT_COL1; + if (swrast->_FogEnabled) + swrast->_FragmentAttribs |= FRAG_BIT_FOGC; + + for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { + if (ctx->Texture.Unit[u]._ReallyEnabled) { + swrast->_FragmentAttribs |= FRAG_BIT_TEX(u); + } + } + } + + /* Find lowest, highest bit set in _FragmentAttribs */ + { + GLuint bits = swrast->_FragmentAttribs; + GLuint i = 0;; + while (bits) { + i++; + bits = bits >> 1; + } + swrast->_MaxFragmentAttrib = i; + swrast->_MinFragmentAttrib = FRAG_ATTRIB_TEX0; /* XXX temporary */ + } +} + + void _swrast_validate_derived( GLcontext *ctx ) { @@ -547,6 +591,12 @@ _swrast_validate_derived( GLcontext *ctx ) if (swrast->NewState & _SWRAST_NEW_RASTERMASK) _swrast_update_rasterflags( ctx ); + if (swrast->NewState & (_NEW_DEPTH | + _NEW_FOG | + _NEW_PROGRAM | + _NEW_TEXTURE)) + _swrast_update_fragment_attribs(ctx); + swrast->NewState = 0; swrast->StateChanges = 0; swrast->InvalidateState = _swrast_invalidate_state; @@ -806,8 +856,10 @@ _swrast_print_vertex( GLcontext *ctx, const SWvertex *v ) for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++) if (ctx->Texture.Unit[i]._ReallyEnabled) _mesa_debug(ctx, "texcoord[%d] %f %f %f %f\n", i, - v->texcoord[i][0], v->texcoord[i][1], - v->texcoord[i][2], v->texcoord[i][3]); + v->attrib[FRAG_ATTRIB_TEX0 + i][0], + v->attrib[FRAG_ATTRIB_TEX0 + i][1], + v->attrib[FRAG_ATTRIB_TEX0 + i][2], + v->attrib[FRAG_ATTRIB_TEX0 + i][3]); #if CHAN_TYPE == GL_FLOAT _mesa_debug(ctx, "color %f %f %f %f\n", diff --git a/src/mesa/swrast/s_context.h b/src/mesa/swrast/s_context.h index b15a22dbf0..a3f61cd5e5 100644 --- a/src/mesa/swrast/s_context.h +++ b/src/mesa/swrast/s_context.h @@ -133,6 +133,13 @@ typedef struct GLboolean _FogEnabled; GLenum _FogMode; /* either GL_FOG_MODE or fragment program's fog mode */ + /** Fragment attributes to compute during rasterization. + * Mask of FRAG_BIT_* flags. + */ + GLbitfield _FragmentAttribs; + GLuint _MinFragmentAttrib; /**< Lowest bit set in _FragmentAttribs */ + GLuint _MaxFragmentAttrib; /**< Highest bit set in _FragmentAttribs + 1 */ + /* Accum buffer temporaries. */ GLboolean _IntegerAccumMode; /**< Storing unscaled integers? */ diff --git a/src/mesa/swrast/s_feedback.c b/src/mesa/swrast/s_feedback.c index 26cb05cd56..5d3fbdfeb6 100644 --- a/src/mesa/swrast/s_feedback.c +++ b/src/mesa/swrast/s_feedback.c @@ -46,10 +46,10 @@ static void feedback_vertex( GLcontext *ctx, const SWvertex *v, const SWvertex *pv ) { - const GLuint texUnit = 0; /* See section 5.3 of 1.2.1 spec */ GLfloat win[4]; GLfloat color[4]; GLfloat tc[4]; + const GLfloat *vtc = v->attrib[FRAG_ATTRIB_TEX0]; win[0] = v->win[0]; win[1] = v->win[1]; @@ -61,16 +61,15 @@ static void feedback_vertex( GLcontext *ctx, color[2] = CHAN_TO_FLOAT(pv->color[2]); color[3] = CHAN_TO_FLOAT(pv->color[3]); - if (v->texcoord[texUnit][3] != 1.0 && - v->texcoord[texUnit][3] != 0.0) { - GLfloat invq = 1.0F / v->texcoord[texUnit][3]; - tc[0] = v->texcoord[texUnit][0] * invq; - tc[1] = v->texcoord[texUnit][1] * invq; - tc[2] = v->texcoord[texUnit][2] * invq; - tc[3] = v->texcoord[texUnit][3]; + if (vtc[3] != 1.0 && vtc[3] != 0.0) { + GLfloat invq = 1.0F / vtc[3]; + tc[0] = vtc[0] * invq; + tc[1] = vtc[1] * invq; + tc[2] = vtc[2] * invq; + tc[3] = vtc[3]; } else { - COPY_4V(tc, v->texcoord[texUnit]); + COPY_4V(tc, vtc); } _mesa_feedback_vertex( ctx, win, color, (GLfloat) v->index, tc ); diff --git a/src/mesa/swrast/s_linetemp.h b/src/mesa/swrast/s_linetemp.h index e3ca4bd0ac..d2f37bf391 100644 --- a/src/mesa/swrast/s_linetemp.h +++ b/src/mesa/swrast/s_linetemp.h @@ -71,6 +71,7 @@ static void NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 ) { + const SWcontext *swrast = SWRAST_CONTEXT(ctx); SWspan span; GLuint interpFlags = 0; GLint x0 = (GLint) vert0->win[0]; @@ -99,6 +100,8 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 ) SETUP_CODE #endif + (void) swrast; + /* Cull primitives with malformed coordinates. */ { @@ -286,14 +289,14 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 ) const GLfloat invw1 = vert1->win[3]; const GLfloat invLen = 1.0F / numPixels; GLfloat ds, dt, dr, dq; - span.attrStart[FRAG_ATTRIB_TEX0][0] = invw0 * vert0->texcoord[0][0]; - span.attrStart[FRAG_ATTRIB_TEX0][1] = invw0 * vert0->texcoord[0][1]; - span.attrStart[FRAG_ATTRIB_TEX0][2] = invw0 * vert0->texcoord[0][2]; - span.attrStart[FRAG_ATTRIB_TEX0][3] = invw0 * vert0->texcoord[0][3]; - ds = (invw1 * vert1->texcoord[0][0]) - span.attrStart[FRAG_ATTRIB_TEX0][0]; - dt = (invw1 * vert1->texcoord[0][1]) - span.attrStart[FRAG_ATTRIB_TEX0][1]; - dr = (invw1 * vert1->texcoord[0][2]) - span.attrStart[FRAG_ATTRIB_TEX0][2]; - dq = (invw1 * vert1->texcoord[0][3]) - span.attrStart[FRAG_ATTRIB_TEX0][3]; + span.attrStart[FRAG_ATTRIB_TEX0][0] = invw0 * vert0->attrib[FRAG_ATTRIB_TEX0][0]; + span.attrStart[FRAG_ATTRIB_TEX0][1] = invw0 * vert0->attrib[FRAG_ATTRIB_TEX0][1]; + span.attrStart[FRAG_ATTRIB_TEX0][2] = invw0 * vert0->attrib[FRAG_ATTRIB_TEX0][2]; + span.attrStart[FRAG_ATTRIB_TEX0][3] = invw0 * vert0->attrib[FRAG_ATTRIB_TEX0][3]; + ds = (invw1 * vert1->attrib[FRAG_ATTRIB_TEX0][0]) - span.attrStart[FRAG_ATTRIB_TEX0][0]; + dt = (invw1 * vert1->attrib[FRAG_ATTRIB_TEX0][1]) - span.attrStart[FRAG_ATTRIB_TEX0][1]; + dr = (invw1 * vert1->attrib[FRAG_ATTRIB_TEX0][2]) - span.attrStart[FRAG_ATTRIB_TEX0][2]; + dq = (invw1 * vert1->attrib[FRAG_ATTRIB_TEX0][3]) - span.attrStart[FRAG_ATTRIB_TEX0][3]; span.attrStepX[FRAG_ATTRIB_TEX0][0] = ds * invLen; span.attrStepX[FRAG_ATTRIB_TEX0][1] = dt * invLen; span.attrStepX[FRAG_ATTRIB_TEX0][2] = dr * invLen; @@ -304,58 +307,24 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 ) span.attrStepY[FRAG_ATTRIB_TEX0][3] = 0.0F; } #endif -#ifdef INTERP_MULTITEX - interpFlags |= SPAN_TEXTURE; +#if defined(INTERP_MULTITEX) || defined(INTERP_VARYING) + interpFlags |= (SPAN_TEXTURE | SPAN_VARYING); { const GLfloat invLen = 1.0F / numPixels; - GLuint u; - for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { - if (ctx->Texture.Unit[u]._ReallyEnabled) { - const GLuint attr = FRAG_ATTRIB_TEX0 + u; - const GLfloat invw0 = vert0->win[3]; - const GLfloat invw1 = vert1->win[3]; - GLfloat ds, dt, dr, dq; - span.attrStart[attr][0] = invw0 * vert0->texcoord[u][0]; - span.attrStart[attr][1] = invw0 * vert0->texcoord[u][1]; - span.attrStart[attr][2] = invw0 * vert0->texcoord[u][2]; - span.attrStart[attr][3] = invw0 * vert0->texcoord[u][3]; - ds = (invw1 * vert1->texcoord[u][0]) - span.attrStart[attr][0]; - dt = (invw1 * vert1->texcoord[u][1]) - span.attrStart[attr][1]; - dr = (invw1 * vert1->texcoord[u][2]) - span.attrStart[attr][2]; - dq = (invw1 * vert1->texcoord[u][3]) - span.attrStart[attr][3]; - span.attrStepX[attr][0] = ds * invLen; - span.attrStepX[attr][1] = dt * invLen; - span.attrStepX[attr][2] = dr * invLen; - span.attrStepX[attr][3] = dq * invLen; - span.attrStepY[attr][0] = 0.0F; - span.attrStepY[attr][1] = 0.0F; - span.attrStepY[attr][2] = 0.0F; - span.attrStepY[attr][3] = 0.0F; - } - } - } -#endif -#ifdef INTERP_VARYING - interpFlags |= SPAN_VARYING; - { - const GLfloat invLen = 1.0F / numPixels; - const GLbitfield inputsUsed = ctx->FragmentProgram._Current ? - ctx->FragmentProgram._Current->Base.InputsRead : 0x0; const GLfloat invw0 = vert0->win[3]; const GLfloat invw1 = vert1->win[3]; - GLuint v; - for (v = 0; v < MAX_VARYING; v++) { - if (inputsUsed & FRAG_BIT_VAR(v)) { - GLuint attr = FRAG_ATTRIB_VAR0 + v; + GLuint attr; + for (attr = swrast->_MinFragmentAttrib; attr < swrast->_MaxFragmentAttrib; attr++) { + if (swrast->_FragmentAttribs & (1 << attr)) { GLfloat ds, dt, dr, dq; - span.attrStart[attr][0] = invw0 * vert0->varying[v][0]; - span.attrStart[attr][1] = invw0 * vert0->varying[v][1]; - span.attrStart[attr][2] = invw0 * vert0->varying[v][2]; - span.attrStart[attr][3] = invw0 * vert0->varying[v][3]; - ds = (invw1 * vert1->varying[v][0]) - span.attrStart[attr][0]; - dt = (invw1 * vert1->varying[v][1]) - span.attrStart[attr][1]; - dr = (invw1 * vert1->varying[v][2]) - span.attrStart[attr][2]; - dq = (invw1 * vert1->varying[v][3]) - span.attrStart[attr][3]; + span.attrStart[attr][0] = invw0 * vert0->attrib[attr][0]; + span.attrStart[attr][1] = invw0 * vert0->attrib[attr][1]; + span.attrStart[attr][2] = invw0 * vert0->attrib[attr][2]; + span.attrStart[attr][3] = invw0 * vert0->attrib[attr][3]; + ds = (invw1 * vert1->attrib[attr][0]) - span.attrStart[attr][0]; + dt = (invw1 * vert1->attrib[attr][1]) - span.attrStart[attr][1]; + dr = (invw1 * vert1->attrib[attr][2]) - span.attrStart[attr][2]; + dq = (invw1 * vert1->attrib[attr][3]) - span.attrStart[attr][3]; span.attrStepX[attr][0] = ds * invLen; span.attrStepX[attr][1] = dt * invLen; span.attrStepX[attr][2] = dr * invLen; @@ -364,7 +333,7 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 ) span.attrStepY[attr][1] = 0.0F; span.attrStepY[attr][2] = 0.0F; span.attrStepY[attr][3] = 0.0F; - } + } } } #endif diff --git a/src/mesa/swrast/s_pointtemp.h b/src/mesa/swrast/s_pointtemp.h index d211a5a3a2..eca0b9d38d 100644 --- a/src/mesa/swrast/s_pointtemp.h +++ b/src/mesa/swrast/s_pointtemp.h @@ -88,8 +88,8 @@ NAME ( GLcontext *ctx, const SWvertex *vert ) const GLuint colorIndex = (GLuint) vert->index; /* XXX round? */ #endif #if FLAGS & TEXTURE - GLfloat texcoord[MAX_TEXTURE_COORD_UNITS][4]; - GLuint u; + GLfloat attrib[FRAG_ATTRIB_MAX][4]; /* texture & varying */ + GLuint attr; #endif SWcontext *swrast = SWRAST_CONTEXT(ctx); SWspan *span = &(swrast->PointSpan); @@ -123,22 +123,22 @@ NAME ( GLcontext *ctx, const SWvertex *vert ) span->arrayMask |= (SPAN_TEXTURE | SPAN_LAMBDA); if (ctx->FragmentProgram._Current) { /* Don't divide texture s,t,r by q (use TXP to do that) */ - for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { - if (ctx->Texture._EnabledCoordUnits & (1 << u)) { - COPY_4V(texcoord[u], vert->texcoord[u]); + for (attr = swrast->_MinFragmentAttrib; attr < swrast->_MaxFragmentAttrib; attr++) { + if (swrast->_FragmentAttribs & (1 << attr)) { + COPY_4V(attrib[attr], vert->attrib[attr]); } } } else { /* Divide texture s,t,r by q here */ - for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { - if (ctx->Texture._EnabledCoordUnits & (1 << u)) { - const GLfloat q = vert->texcoord[u][3]; + for (attr = swrast->_MinFragmentAttrib; attr < swrast->_MaxFragmentAttrib; attr++) { + if (swrast->_FragmentAttribs & (1 << attr)) { + const GLfloat q = vert->attrib[attr][3]; const GLfloat invQ = (q == 0.0F || q == 1.0F) ? 1.0F : (1.0F / q); - texcoord[u][0] = vert->texcoord[u][0] * invQ; - texcoord[u][1] = vert->texcoord[u][1] * invQ; - texcoord[u][2] = vert->texcoord[u][2] * invQ; - texcoord[u][3] = q; + attrib[attr][0] = vert->attrib[attr][0] * invQ; + attrib[attr][1] = vert->attrib[attr][1] * invQ; + attrib[attr][2] = vert->attrib[attr][2] * invQ; + attrib[attr][3] = q; } } } @@ -260,7 +260,7 @@ NAME ( GLcontext *ctx, const SWvertex *vert ) count = span->end = 0; } for (x = xmin; x <= xmax; x++) { -#if FLAGS & (SPRITE | TEXTURE) +#if FLAGS & SPRITE GLuint u; #endif @@ -279,10 +279,13 @@ NAME ( GLcontext *ctx, const SWvertex *vert ) span->array->index[count] = colorIndex; #endif #if FLAGS & TEXTURE - for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { - if (ctx->Texture._EnabledCoordUnits & (1 << u)) { - COPY_4V(span->array->attribs[FRAG_ATTRIB_TEX0 + u][count], texcoord[u]); - span->array->lambda[u][count] = 0.0; + for (attr = swrast->_MinFragmentAttrib; attr < swrast->_MaxFragmentAttrib; attr++) { + if (swrast->_FragmentAttribs & (1 << attr)) { + COPY_4V(span->array->attribs[attr][count], attrib[attr]); + if (attr < FRAG_ATTRIB_VAR0) { + const GLuint u = attr - FRAG_ATTRIB_TEX0; + span->array->lambda[u][count] = 0.0; + } } } #endif @@ -329,6 +332,7 @@ NAME ( GLcontext *ctx, const SWvertex *vert ) #if FLAGS & SPRITE for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { + GLuint attr = FRAG_ATTRIB_TEX0 + u; if (ctx->Texture.Unit[u]._ReallyEnabled) { if (ctx->Point.CoordReplace[u]) { GLfloat s = 0.5F + (x + 0.5F - vert->win[0]) / size; @@ -340,17 +344,18 @@ NAME ( GLcontext *ctx, const SWvertex *vert ) if (ctx->Point.SpriteRMode == GL_ZERO) r = 0.0F; else if (ctx->Point.SpriteRMode == GL_S) - r = vert->texcoord[u][0]; + r = vert->attrib[attr][0]; else /* GL_R */ - r = vert->texcoord[u][2]; - span->array->attribs[FRAG_ATTRIB_TEX0 + u][count][0] = s; - span->array->attribs[FRAG_ATTRIB_TEX0 + u][count][1] = t; - span->array->attribs[FRAG_ATTRIB_TEX0 + u][count][2] = r; - span->array->attribs[FRAG_ATTRIB_TEX0 + u][count][3] = 1.0F; + r = vert->attrib[attr][2]; + span->array->attribs[attr][count][0] = s; + span->array->attribs[attr][count][1] = t; + span->array->attribs[attr][count][2] = r; + span->array->attribs[attr][count][3] = 1.0F; span->array->lambda[u][count] = 0.0; /* XXX fix? */ } else { - COPY_4V(span->array->attribs[FRAG_ATTRIB_TEX0 + u][count], vert->texcoord[u]); + COPY_4V(span->array->attribs[attr][count], + vert->attrib[attr]); } } } @@ -401,9 +406,9 @@ NAME ( GLcontext *ctx, const SWvertex *vert ) span->array->index[count] = colorIndex; #endif #if FLAGS & TEXTURE - for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { - if (ctx->Texture.Unit[u]._ReallyEnabled) { - COPY_4V(span->array->attribs[FRAG_ATTRIB_TEX0 + u][count], texcoord[u]); + for (attr = swrast->_MinFragmentAttrib; attr < swrast->_MaxFragmentAttrib; attr++) { + if (swrast->_FragmentAttribs & (1 << attr)) { + COPY_4V(span->array->attribs[attr][count], attribs[attr]); } } #endif diff --git a/src/mesa/swrast/s_triangle.c b/src/mesa/swrast/s_triangle.c index 6c2e3862a3..3b7960bf80 100644 --- a/src/mesa/swrast/s_triangle.c +++ b/src/mesa/swrast/s_triangle.c @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.5.2 + * Version: 6.5.3 * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -866,7 +866,6 @@ fast_persp_span(GLcontext *ctx, SWspan *span, /* * Render a smooth-shaded, textured, RGBA triangle. - * Interpolate S,T,R with perspective correction, w/out mipmapping. */ #define NAME general_textured_triangle #define INTERP_Z 1 @@ -881,24 +880,6 @@ fast_persp_span(GLcontext *ctx, SWspan *span, -/* - * This is the big one! - * Interpolate Z, RGB, Alpha, specular, fog, N sets of texture coordinates, - * and varying floats. Yup, it's slow. - */ -#define NAME multitextured_triangle -#define INTERP_Z 1 -#define INTERP_W 1 -#define INTERP_FOG 1 -#define INTERP_RGB 1 -#define INTERP_ALPHA 1 -#define INTERP_SPEC 1 -#define INTERP_MULTITEX 1 -#define INTERP_VARYING 1 -#define RENDER_SPAN( span ) _swrast_write_rgba_span(ctx, &span); -#include "s_tritemp.h" - - /* * Special tri function for occlusion testing @@ -1137,13 +1118,7 @@ _swrast_choose_triangle( GLcontext *ctx ) } else { /* general case textured triangles */ - if (ctx->Texture._EnabledCoordUnits > 1 || - ctx->FragmentProgram._Current) { - USE(multitextured_triangle); - } - else { - USE(general_textured_triangle); - } + USE(general_textured_triangle); } } else { diff --git a/src/mesa/swrast/s_tritemp.h b/src/mesa/swrast/s_tritemp.h index 83b2f03781..435491a0c8 100644 --- a/src/mesa/swrast/s_tritemp.h +++ b/src/mesa/swrast/s_tritemp.h @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * Version: 6.5.3 * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -38,10 +38,8 @@ * INTERP_INDEX - if defined, interpolate color index values * INTERP_INT_TEX - if defined, interpolate integer ST texcoords * (fast, simple 2-D texture mapping) - * INTERP_TEX - if defined, interpolate set 0 float STRQ texcoords + * INTERP_TEX - if defined, interpolate texcoords and varying vars * NOTE: OpenGL STRQ = Mesa STUV (R was taken for red) - * INTERP_MULTITEX - if defined, interpolate N units of STRQ texcoords - * INTERP_VARYING - if defined, interpolate M GLSL varyings * * When one can directly address pixels in the color buffer the following * macros can be defined and used to compute pixel addresses during @@ -119,52 +117,19 @@ #endif -/* - * Either loop over all texture units, or just use unit zero. - */ -#ifdef INTERP_MULTITEX -#define TEX_UNIT_LOOP(CODE) \ - { \ - GLuint u; \ - for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { \ - if (ctx->Texture._EnabledCoordUnits & (1 << u)) { \ - const GLuint attr = FRAG_ATTRIB_TEX0 + u; \ - (void) attr; \ - CODE \ - } \ - } \ +#define TEXVAR_LOOP(CODE) \ + { \ + GLuint attr; \ + for (attr = swrast->_MinFragmentAttrib; \ + attr < swrast->_MaxFragmentAttrib; attr++) { \ + if (swrast->_FragmentAttribs & (1 << attr)) { \ + CODE \ + } \ + } \ } -#define INTERP_TEX -#elif defined(INTERP_TEX) -#define TEX_UNIT_LOOP(CODE) \ - { \ - const GLuint u = 0; \ - const GLuint attr = FRAG_ATTRIB_TEX0 + u; \ - (void) attr; \ - CODE \ - } -#endif -#ifdef INTERP_VARYING - -#define VARYING_LOOP(CODE) \ - { \ - GLuint iv, ic; \ - for (iv = 0; iv < MAX_VARYING; iv++) { \ - if (inputsUsed & FRAG_BIT_VAR(iv)) { \ - GLuint attr = FRAG_ATTRIB_VAR0 + iv; \ - (void) attr; \ - for (ic = 0; ic < 4; ic++) { \ - CODE \ - } \ - } \ - } \ - } -#endif - - /* * Some code we unfortunately need to prevent negative interpolated colors. @@ -210,6 +175,7 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, GLint lines; /* number of lines to be sampled on this edge */ } EdgeT; + const SWcontext *swrast = SWRAST_CONTEXT(ctx); #ifdef INTERP_Z const GLint depthBits = ctx->DrawBuffer->Visual.depthBits; const GLint fixedToDepthShift = depthBits <= 16 ? FIXED_SHIFT : 0; @@ -224,13 +190,11 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, const GLint snapMask = ~((FIXED_ONE / (1 << SUB_PIXEL_BITS)) - 1); /* for x/y coord snapping */ #endif GLinterp vMin_fx, vMin_fy, vMid_fx, vMid_fy, vMax_fx, vMax_fy; -#ifdef INTERP_VARYING - const GLbitfield inputsUsed = ctx->FragmentProgram._Current ? - ctx->FragmentProgram._Current->Base.InputsRead : 0x0; -#endif SWspan span; + (void) swrast; + INIT_SPAN(span, GL_POLYGON, 0, 0, 0); #ifdef INTERP_Z @@ -638,10 +602,10 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, #ifdef INTERP_INT_TEX span.interpMask |= SPAN_INT_TEXTURE; { - GLfloat eMaj_ds = (vMax->texcoord[0][0] - vMin->texcoord[0][0]) * S_SCALE; - GLfloat eBot_ds = (vMid->texcoord[0][0] - vMin->texcoord[0][0]) * S_SCALE; - GLfloat eMaj_dt = (vMax->texcoord[0][1] - vMin->texcoord[0][1]) * T_SCALE; - GLfloat eBot_dt = (vMid->texcoord[0][1] - vMin->texcoord[0][1]) * T_SCALE; + GLfloat eMaj_ds = (vMax->attrib[FRAG_ATTRIB_TEX0][0] - vMin->attrib[FRAG_ATTRIB_TEX0][0]) * S_SCALE; + GLfloat eBot_ds = (vMid->attrib[FRAG_ATTRIB_TEX0][0] - vMin->attrib[FRAG_ATTRIB_TEX0][0]) * S_SCALE; + GLfloat eMaj_dt = (vMax->attrib[FRAG_ATTRIB_TEX0][1] - vMin->attrib[FRAG_ATTRIB_TEX0][1]) * T_SCALE; + GLfloat eBot_dt = (vMid->attrib[FRAG_ATTRIB_TEX0][1] - vMin->attrib[FRAG_ATTRIB_TEX0][1]) * T_SCALE; span.attrStepX[FRAG_ATTRIB_TEX0][0] = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds); span.attrStepY[FRAG_ATTRIB_TEX0][0] = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx); span.attrStepX[FRAG_ATTRIB_TEX0][1] = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt); @@ -651,19 +615,19 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, } #endif #ifdef INTERP_TEX - span.interpMask |= SPAN_TEXTURE; + span.interpMask |= (SPAN_TEXTURE | SPAN_VARYING); { /* win[3] is 1/W */ const GLfloat wMax = vMax->win[3], wMin = vMin->win[3], wMid = vMid->win[3]; - TEX_UNIT_LOOP( - GLfloat eMaj_ds = vMax->texcoord[u][0] * wMax - vMin->texcoord[u][0] * wMin; - GLfloat eBot_ds = vMid->texcoord[u][0] * wMid - vMin->texcoord[u][0] * wMin; - GLfloat eMaj_dt = vMax->texcoord[u][1] * wMax - vMin->texcoord[u][1] * wMin; - GLfloat eBot_dt = vMid->texcoord[u][1] * wMid - vMin->texcoord[u][1] * wMin; - GLfloat eMaj_du = vMax->texcoord[u][2] * wMax - vMin->texcoord[u][2] * wMin; - GLfloat eBot_du = vMid->texcoord[u][2] * wMid - vMin->texcoord[u][2] * wMin; - GLfloat eMaj_dv = vMax->texcoord[u][3] * wMax - vMin->texcoord[u][3] * wMin; - GLfloat eBot_dv = vMid->texcoord[u][3] * wMid - vMin->texcoord[u][3] * wMin; + TEXVAR_LOOP( + GLfloat eMaj_ds = vMax->attrib[attr][0] * wMax - vMin->attrib[attr][0] * wMin; + GLfloat eBot_ds = vMid->attrib[attr][0] * wMid - vMin->attrib[attr][0] * wMin; + GLfloat eMaj_dt = vMax->attrib[attr][1] * wMax - vMin->attrib[attr][1] * wMin; + GLfloat eBot_dt = vMid->attrib[attr][1] * wMid - vMin->attrib[attr][1] * wMin; + GLfloat eMaj_du = vMax->attrib[attr][2] * wMax - vMin->attrib[attr][2] * wMin; + GLfloat eBot_du = vMid->attrib[attr][2] * wMid - vMin->attrib[attr][2] * wMin; + GLfloat eMaj_dv = vMax->attrib[attr][3] * wMax - vMin->attrib[attr][3] * wMin; + GLfloat eBot_dv = vMid->attrib[attr][3] * wMid - vMin->attrib[attr][3] * wMin; span.attrStepX[attr][0] = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds); span.attrStepY[attr][0] = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx); span.attrStepX[attr][1] = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt); @@ -675,19 +639,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, ) } #endif -#ifdef INTERP_VARYING - span.interpMask |= SPAN_VARYING; - { - /* win[3] is 1/W */ - const GLfloat wMax = vMax->win[3], wMin = vMin->win[3], wMid = vMid->win[3]; - VARYING_LOOP( - GLfloat eMaj_dvar = vMax->varying[iv][ic] * wMax - vMin->varying[iv][ic] * wMin; - GLfloat eBot_dvar = vMid->varying[iv][ic] * wMid - vMin->varying[iv][ic] * wMin; - span.attrStepX[attr][ic] = oneOverArea * (eMaj_dvar * eBot.dy - eMaj.dy * eBot_dvar); - span.attrStepY[attr][ic] = oneOverArea * (eMaj.dx * eBot_dvar - eMaj_dvar * eBot.dx); - ) - } -#endif /* * We always sample at pixel centers. However, we avoid @@ -782,19 +733,14 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, GLfixed tLeft=0, dtOuter=0, dtInner; #endif #ifdef INTERP_TEX - GLfloat sLeft[MAX_TEXTURE_COORD_UNITS]; - GLfloat tLeft[MAX_TEXTURE_COORD_UNITS]; - GLfloat uLeft[MAX_TEXTURE_COORD_UNITS]; - GLfloat vLeft[MAX_TEXTURE_COORD_UNITS]; - GLfloat dsOuter[MAX_TEXTURE_COORD_UNITS], dsInner[MAX_TEXTURE_COORD_UNITS]; - GLfloat dtOuter[MAX_TEXTURE_COORD_UNITS], dtInner[MAX_TEXTURE_COORD_UNITS]; - GLfloat duOuter[MAX_TEXTURE_COORD_UNITS], duInner[MAX_TEXTURE_COORD_UNITS]; - GLfloat dvOuter[MAX_TEXTURE_COORD_UNITS], dvInner[MAX_TEXTURE_COORD_UNITS]; -#endif -#ifdef INTERP_VARYING - GLfloat varLeft[MAX_VARYING][4]; - GLfloat dvarOuter[MAX_VARYING][4]; - GLfloat dvarInner[MAX_VARYING][4]; + GLfloat sLeft[FRAG_ATTRIB_MAX]; + GLfloat tLeft[FRAG_ATTRIB_MAX]; + GLfloat uLeft[FRAG_ATTRIB_MAX]; + GLfloat vLeft[FRAG_ATTRIB_MAX]; + GLfloat dsOuter[FRAG_ATTRIB_MAX], dsInner[FRAG_ATTRIB_MAX]; + GLfloat dtOuter[FRAG_ATTRIB_MAX], dtInner[FRAG_ATTRIB_MAX]; + GLfloat duOuter[FRAG_ATTRIB_MAX], duInner[FRAG_ATTRIB_MAX]; + GLfloat dvOuter[FRAG_ATTRIB_MAX], dvInner[FRAG_ATTRIB_MAX]; #endif for (subTriangle=0; subTriangle<=1; subTriangle++) { @@ -1042,41 +988,32 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, #ifdef INTERP_INT_TEX { GLfloat s0, t0; - s0 = vLower->texcoord[0][0] * S_SCALE; + s0 = vLower->attrib[FRAG_ATTRIB_TEX0][0] * S_SCALE; sLeft = (GLfixed)(s0 * FIXED_SCALE + span.attrStepX[FRAG_ATTRIB_TEX0][0] * adjx + span.attrStepY[FRAG_ATTRIB_TEX0][0] * adjy) + FIXED_HALF; dsOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_TEX0][0] + dxOuter * span.attrStepX[FRAG_ATTRIB_TEX0][0]); - t0 = vLower->texcoord[0][1] * T_SCALE; + t0 = vLower->attrib[FRAG_ATTRIB_TEX0][1] * T_SCALE; tLeft = (GLfixed)(t0 * FIXED_SCALE + span.attrStepX[FRAG_ATTRIB_TEX0][1] * adjx + span.attrStepY[FRAG_ATTRIB_TEX0][1] * adjy) + FIXED_HALF; dtOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_TEX0][1] + dxOuter * span.attrStepX[FRAG_ATTRIB_TEX0][1]); } #endif #ifdef INTERP_TEX - TEX_UNIT_LOOP( + TEXVAR_LOOP( const GLfloat invW = vLower->win[3]; - const GLfloat s0 = vLower->texcoord[u][0] * invW; - const GLfloat t0 = vLower->texcoord[u][1] * invW; - const GLfloat u0 = vLower->texcoord[u][2] * invW; - const GLfloat v0 = vLower->texcoord[u][3] * invW; - sLeft[u] = s0 + (span.attrStepX[attr][0] * adjx + span.attrStepY[attr][0] * adjy) * (1.0F/FIXED_SCALE); - tLeft[u] = t0 + (span.attrStepX[attr][1] * adjx + span.attrStepY[attr][1] * adjy) * (1.0F/FIXED_SCALE); - uLeft[u] = u0 + (span.attrStepX[attr][2] * adjx + span.attrStepY[attr][2] * adjy) * (1.0F/FIXED_SCALE); - vLeft[u] = v0 + (span.attrStepX[attr][3] * adjx + span.attrStepY[attr][3] * adjy) * (1.0F/FIXED_SCALE); - dsOuter[u] = span.attrStepY[attr][0] + dxOuter * span.attrStepX[attr][0]; - dtOuter[u] = span.attrStepY[attr][1] + dxOuter * span.attrStepX[attr][1]; - duOuter[u] = span.attrStepY[attr][2] + dxOuter * span.attrStepX[attr][2]; - dvOuter[u] = span.attrStepY[attr][3] + dxOuter * span.attrStepX[attr][3]; - ) -#endif -#ifdef INTERP_VARYING - VARYING_LOOP( - const GLfloat invW = vLower->win[3]; - const GLfloat var0 = vLower->varying[iv][ic] * invW; - varLeft[iv][ic] = var0 + (span.attrStepX[attr][ic] * adjx + - span.attrStepY[attr][ic] * adjy) * (1.0f / FIXED_SCALE); - dvarOuter[iv][ic] = span.attrStepY[attr][ic] + dxOuter * span.attrStepX[attr][ic]; + const GLfloat s0 = vLower->attrib[attr][0] * invW; + const GLfloat t0 = vLower->attrib[attr][1] * invW; + const GLfloat u0 = vLower->attrib[attr][2] * invW; + const GLfloat v0 = vLower->attrib[attr][3] * invW; + sLeft[attr] = s0 + (span.attrStepX[attr][0] * adjx + span.attrStepY[attr][0] * adjy) * (1.0F/FIXED_SCALE); + tLeft[attr] = t0 + (span.attrStepX[attr][1] * adjx + span.attrStepY[attr][1] * adjy) * (1.0F/FIXED_SCALE); + uLeft[attr] = u0 + (span.attrStepX[attr][2] * adjx + span.attrStepY[attr][2] * adjy) * (1.0F/FIXED_SCALE); + vLeft[attr] = v0 + (span.attrStepX[attr][3] * adjx + span.attrStepY[attr][3] * adjy) * (1.0F/FIXED_SCALE); + dsOuter[attr] = span.attrStepY[attr][0] + dxOuter * span.attrStepX[attr][0]; + dtOuter[attr] = span.attrStepY[attr][1] + dxOuter * span.attrStepX[attr][1]; + duOuter[attr] = span.attrStepY[attr][2] + dxOuter * span.attrStepX[attr][2]; + dvOuter[attr] = span.attrStepY[attr][3] + dxOuter * span.attrStepX[attr][3]; ) #endif } /*if setupLeft*/ @@ -1134,16 +1071,11 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, dtInner = dtOuter + span.intTexStep[1]; #endif #ifdef INTERP_TEX - TEX_UNIT_LOOP( - dsInner[u] = dsOuter[u] + span.attrStepX[attr][0]; - dtInner[u] = dtOuter[u] + span.attrStepX[attr][1]; - duInner[u] = duOuter[u] + span.attrStepX[attr][2]; - dvInner[u] = dvOuter[u] + span.attrStepX[attr][3]; - ) -#endif -#ifdef INTERP_VARYING - VARYING_LOOP( - dvarInner[iv][ic] = dvarOuter[iv][ic] + span.attrStepX[attr][ic]; + TEXVAR_LOOP( + dsInner[attr] = dsOuter[attr] + span.attrStepX[attr][0]; + dtInner[attr] = dtOuter[attr] + span.attrStepX[attr][1]; + duInner[attr] = duOuter[attr] + span.attrStepX[attr][2]; + dvInner[attr] = dvOuter[attr] + span.attrStepX[attr][3]; ) #endif @@ -1188,16 +1120,11 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, #endif #ifdef INTERP_TEX - TEX_UNIT_LOOP( - span.attrStart[attr][0] = sLeft[u]; - span.attrStart[attr][1] = tLeft[u]; - span.attrStart[attr][2] = uLeft[u]; - span.attrStart[attr][3] = vLeft[u]; - ) -#endif -#ifdef INTERP_VARYING - VARYING_LOOP( - span.attrStart[attr][ic] = varLeft[iv][ic]; + TEXVAR_LOOP( + span.attrStart[attr][0] = sLeft[attr]; + span.attrStart[attr][1] = tLeft[attr]; + span.attrStart[attr][2] = uLeft[attr]; + span.attrStart[attr][3] = vLeft[attr]; ) #endif @@ -1281,16 +1208,11 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, tLeft += dtOuter; #endif #ifdef INTERP_TEX - TEX_UNIT_LOOP( - sLeft[u] += dsOuter[u]; - tLeft[u] += dtOuter[u]; - uLeft[u] += duOuter[u]; - vLeft[u] += dvOuter[u]; - ) -#endif -#ifdef INTERP_VARYING - VARYING_LOOP( - varLeft[iv][ic] += dvarOuter[iv][ic]; + TEXVAR_LOOP( + sLeft[attr] += dsOuter[attr]; + tLeft[attr] += dtOuter[attr]; + uLeft[attr] += duOuter[attr]; + vLeft[attr] += dvOuter[attr]; ) #endif } @@ -1331,16 +1253,11 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, tLeft += dtInner; #endif #ifdef INTERP_TEX - TEX_UNIT_LOOP( - sLeft[u] += dsInner[u]; - tLeft[u] += dtInner[u]; - uLeft[u] += duInner[u]; - vLeft[u] += dvInner[u]; - ) -#endif -#ifdef INTERP_VARYING - VARYING_LOOP( - varLeft[iv][ic] += dvarInner[iv][ic]; + TEXVAR_LOOP( + sLeft[attr] += dsInner[attr]; + tLeft[attr] += dtInner[attr]; + uLeft[attr] += duInner[attr]; + vLeft[attr] += dvInner[attr]; ) #endif } @@ -1373,8 +1290,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, #undef INTERP_INDEX #undef INTERP_INT_TEX #undef INTERP_TEX -#undef INTERP_MULTITEX -#undef INTERP_VARYING #undef TEX_UNIT_LOOP #undef VARYING_LOOP diff --git a/src/mesa/swrast/swrast.h b/src/mesa/swrast/swrast.h index 2c1c0952af..9e1fe24bb4 100644 --- a/src/mesa/swrast/swrast.h +++ b/src/mesa/swrast/swrast.h @@ -67,13 +67,12 @@ typedef struct { * that clip{XYZ} were multiplied by to get ndc{XYZ}. */ GLfloat win[4]; - GLfloat texcoord[MAX_TEXTURE_COORD_UNITS][4]; GLchan color[4]; GLchan specular[4]; GLfloat fog; GLfloat index; GLfloat pointSize; - GLfloat varying[MAX_VERTEX_ATTRIBS][4]; + GLfloat attrib[FRAG_ATTRIB_MAX][4]; /**< texcoords & varying, more to come */ } SWvertex; diff --git a/src/mesa/swrast_setup/ss_context.c b/src/mesa/swrast_setup/ss_context.c index f17e69bfb2..e1b60d0e85 100644 --- a/src/mesa/swrast_setup/ss_context.c +++ b/src/mesa/swrast_setup/ss_context.c @@ -145,7 +145,7 @@ _swsetup_RenderStart( GLcontext *ctx ) if (RENDERINPUTS_TEST_RANGE( index_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX )) { for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) { if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX(i) )) { - EMIT_ATTR( _TNL_ATTRIB_TEX(i), EMIT_4F, texcoord[i] ); + EMIT_ATTR( _TNL_ATTRIB_TEX(i), EMIT_4F, attrib[FRAG_ATTRIB_TEX0 + i] ); } } } @@ -156,7 +156,7 @@ _swsetup_RenderStart( GLcontext *ctx ) for (i = 0; i < ctx->Const.MaxVarying; i++) { if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_GENERIC(i) )) { EMIT_ATTR( _TNL_ATTRIB_GENERIC(i), VARYING_EMIT_STYLE, - varying[i] ); + attrib[FRAG_ATTRIB_VAR0 + i] ); } } } @@ -242,8 +242,13 @@ _swsetup_Translate( GLcontext *ctx, const void *vertex, SWvertex *dest ) for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++) - _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_TEX0+i, dest->texcoord[i] ); - + _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_TEX0+i, + dest->attrib[FRAG_ATTRIB_TEX0 + i] ); + + for (i = 0 ; i < ctx->Const.MaxVarying ; i++) + _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_GENERIC0+i, + dest->attrib[FRAG_ATTRIB_VAR0 + i] ); + _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_COLOR0, tmp ); UNCLAMPED_FLOAT_TO_RGBA_CHAN( dest->color, tmp ); -- cgit v1.2.3 From 01001d80e26143ac768115ccb2266db2b24d4fa0 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 5 Feb 2007 11:28:15 -0700 Subject: Initial support of loop and subroutine instructions. New high-level flow-control instructions, both at IR level and GPU instructions for looping and subroutines. --- src/mesa/shader/prog_instruction.c | 6 ++++++ src/mesa/shader/prog_instruction.h | 12 +++++++++--- src/mesa/shader/slang/slang_codegen.c | 5 +++-- src/mesa/shader/slang/slang_emit.c | 29 ++++++++++++++++++++++++++--- src/mesa/shader/slang/slang_ir.h | 23 ++++++++++++++++++++--- src/mesa/swrast/s_fragprog.c | 13 +++++++++++++ src/mesa/tnl/t_vb_arbprogram.c | 6 ++++++ 7 files changed, 83 insertions(+), 11 deletions(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/shader/prog_instruction.c b/src/mesa/shader/prog_instruction.c index 0523f42125..c67831385f 100644 --- a/src/mesa/shader/prog_instruction.c +++ b/src/mesa/shader/prog_instruction.c @@ -120,9 +120,13 @@ static const struct instruction_info InstInfo[MAX_OPCODE] = { { OPCODE_ARL, "ARL", 1 }, { OPCODE_ARL_NV, "ARL", 1 }, { OPCODE_ARR, "ARL", 1 }, + { OPCODE_BGNLOOP,"BGNLOOP", 0 }, + { OPCODE_BGNSUB, "BGNSUB", 0 }, { OPCODE_BRA, "BRA", 0 }, + { OPCODE_BRK, "BRK", 0 }, { OPCODE_CAL, "CAL", 0 }, { OPCODE_CMP, "CMP", 3 }, + { OPCODE_CONT, "CONT", 1 }, { OPCODE_COS, "COS", 1 }, { OPCODE_DDX, "DDX", 1 }, { OPCODE_DDY, "DDY", 1 }, @@ -133,6 +137,8 @@ static const struct instruction_info InstInfo[MAX_OPCODE] = { { OPCODE_ELSE, "ELSE", 0 }, { OPCODE_END, "END", 0 }, { OPCODE_ENDIF, "ENDIF", 0 }, + { OPCODE_ENDLOOP,"ENDLOOP", 0 }, + { OPCODE_ENDSUB, "ENDSUB", 0 }, { OPCODE_EX2, "EX2", 1 }, { OPCODE_EXP, "EXP", 1 }, { OPCODE_FLR, "FLR", 1 }, diff --git a/src/mesa/shader/prog_instruction.h b/src/mesa/shader/prog_instruction.h index f018de82b3..100aac4b97 100644 --- a/src/mesa/shader/prog_instruction.h +++ b/src/mesa/shader/prog_instruction.h @@ -143,9 +143,13 @@ typedef enum prog_opcode { OPCODE_ARL, /* X X */ OPCODE_ARL_NV, /* 2 */ OPCODE_ARR, /* 2 */ + OPCODE_BGNLOOP, /* opt */ + OPCODE_BGNSUB, /* opt */ OPCODE_BRA, /* 2 X */ + OPCODE_BRK, /* 2 opt */ OPCODE_CAL, /* 2 2 */ OPCODE_CMP, /* X */ + OPCODE_CONT, /* opt */ OPCODE_COS, /* X 2 X X */ OPCODE_DDX, /* X X */ OPCODE_DDY, /* X X */ @@ -154,13 +158,15 @@ typedef enum prog_opcode { OPCODE_DPH, /* X X 1.1 */ OPCODE_DST, /* X X X X */ OPCODE_ELSE, /* X */ - OPCODE_END, /* X X X X X */ - OPCODE_ENDIF, /* X */ + OPCODE_END, /* X X X X opt */ + OPCODE_ENDIF, /* opt */ + OPCODE_ENDLOOP, /* opt */ + OPCODE_ENDSUB, /* opt */ OPCODE_EX2, /* X X 2 X X */ OPCODE_EXP, /* X X X */ OPCODE_FLR, /* X X 2 X X */ OPCODE_FRC, /* X X 2 X X */ - OPCODE_IF, /* X */ + OPCODE_IF, /* opt */ OPCODE_INT, /* X */ OPCODE_KIL, /* X */ OPCODE_KIL_NV, /* X X */ diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index 6b7df0597b..72f58a9ebd 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -1463,7 +1463,7 @@ _slang_gen_for(slang_assemble_ctx * A, const slang_operation *oper) /** - * Generate IR tree for an if/then/else conditional. + * Generate IR tree for an if/then/else conditional using BRAnch instructions. */ static slang_ir_node * _slang_gen_if(slang_assemble_ctx * A, const slang_operation *oper) @@ -1513,7 +1513,8 @@ _slang_gen_if(slang_assemble_ctx * A, const slang_operation *oper) /** - * Use high-level IF/ELSE/ENDIF instructions + * Generate IR tree for an if/then/else conditional using high-level + * IF/ELSE/ENDIF instructions */ static slang_ir_node * _slang_gen_if2(slang_assemble_ctx * A, const slang_operation *oper) diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c index 01fb5a41da..756bbe9587 100644 --- a/src/mesa/shader/slang/slang_emit.c +++ b/src/mesa/shader/slang/slang_emit.c @@ -297,6 +297,32 @@ slang_print_ir(const slang_ir_node *n, int indent) printf("ENDIF\n"); break; + case IR_BEGIN_SUB: + printf("BEGIN_SUB\n"); + break; + case IR_END_SUB: + printf("END_SUB\n"); + break; + case IR_RETURN: + printf("RETURN\n"); + break; + case IR_CALL: + printf("CALL\n"); + break; + + case IR_BEGIN_LOOP: + printf("BEGIN_LOOP\n"); + break; + case IR_END_LOOP: + printf("END_LOOP\n"); + break; + case IR_CONT: + printf("CONT\n"); + break; + case IR_BREAK: + printf("BREAK\n"); + break; + case IR_VAR: printf("VAR %s%s at %s store %p\n", (n->Var ? (char *) n->Var->a_name : "TEMP"), @@ -313,9 +339,6 @@ slang_print_ir(const slang_ir_node *n, int indent) printf("FIELD %s of\n", n->Target); slang_print_ir(n->Children[0], indent+3); break; - case IR_CALL: - printf("ASMCALL %s(%d args)\n", n->Target, 0/*XXX*/); - break; case IR_FLOAT: printf("FLOAT %f %f %f %f\n", n->Value[0], n->Value[1], n->Value[2], n->Value[3]); diff --git a/src/mesa/shader/slang/slang_ir.h b/src/mesa/shader/slang/slang_ir.h index 5fd72be36a..ac1ea4dbb4 100644 --- a/src/mesa/shader/slang/slang_ir.h +++ b/src/mesa/shader/slang/slang_ir.h @@ -46,15 +46,27 @@ typedef enum IR_NOP = 0, IR_SEQ, /* sequence (eval left, then right) */ IR_SCOPE, /* new variable scope (one child) */ + IR_LABEL, /* target of a jump or cjump */ IR_JUMP, /* unconditional jump */ IR_CJUMP0, /* conditional jump if zero */ IR_CJUMP1, /* conditional jump if one (or non-zero) */ - IR_COND, /* conditional expression */ + IR_COND, /* conditional expression/predicate */ + IR_IF, /* high-level IF */ IR_ELSE, /* high-level ELSE */ IR_ENDIF, /* high-level ENDIF */ - IR_CALL, /* call subroutine */ + + IR_BEGIN_SUB, /* begin subroutine */ + IR_END_SUB, /* end subroutine */ + IR_RETURN, /* return from subroutine */ + IR_CALL, /* call subroutine */ + + IR_BEGIN_LOOP,/* begin loop */ + IR_END_LOOP, /* end loop */ + IR_CONT, /* continue loop */ + IR_BREAK, /* break loop */ + IR_MOVE, IR_ADD, IR_SUB, @@ -90,17 +102,22 @@ typedef enum IR_NOISE3, /* noise(x, y, z) */ IR_NOISE4, /* noise(x, y, z, w) */ IR_NOT, /* logical not */ + IR_VAR, /* variable reference */ IR_VAR_DECL,/* var declaration */ + IR_ELEMENT, /* array element */ + IR_FIELD, /* struct field */ IR_SWIZZLE, /* swizzled storage access */ + IR_TEX, /* texture lookup */ IR_TEXB, /* texture lookup with LOD bias */ IR_TEXP, /* texture lookup with projection */ + IR_FLOAT, - IR_FIELD, IR_I_TO_F, /* int[4] to float[4] conversion */ IR_F_TO_I, /* float[4] to int[4] conversion */ + IR_KILL /* fragment kill/discard */ } slang_ir_opcode; diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c index 740360d460..00231aeae8 100644 --- a/src/mesa/swrast/s_fragprog.c +++ b/src/mesa/swrast/s_fragprog.c @@ -675,6 +675,14 @@ execute_program( GLcontext *ctx, } } break; + case OPCODE_BGNLOOP: /* begin loop */ + break; + case OPCODE_ENDLOOP: /* end loop */ + break; + case OPCODE_BGNSUB: /* begin subroutine */ + break; + case OPCODE_ENDSUB: /* end subroutine */ + break; case OPCODE_BRA: /* conditional branch */ { /* NOTE: The branch is conditional! */ @@ -692,6 +700,9 @@ execute_program( GLcontext *ctx, } } break; + case OPCODE_BRK: /* break out of loop */ + /* assert inside loop */ + break; case OPCODE_CAL: /* Call subroutine */ { /* NOTE: The call is conditional! */ @@ -722,6 +733,8 @@ execute_program( GLcontext *ctx, store_vector4( inst, machine, result ); } break; + case OPCODE_CONT: /* continue loop */ + break; case OPCODE_COS: { GLfloat a[4], result[4]; diff --git a/src/mesa/tnl/t_vb_arbprogram.c b/src/mesa/tnl/t_vb_arbprogram.c index 22b6089fc8..0a443b3e01 100644 --- a/src/mesa/tnl/t_vb_arbprogram.c +++ b/src/mesa/tnl/t_vb_arbprogram.c @@ -736,9 +736,13 @@ static void (* const opcode_func[MAX_OPCODE+3])(struct arb_vp_machine *, union i do_NOP,/*ARL*/ do_NOP,/*ARL_NV*/ do_NOP,/*ARR*/ + do_NOP,/*BGNLOOP*/ + do_NOP,/*BGNSUB*/ do_NOP,/*BRA*/ + do_NOP,/*BRK*/ do_NOP,/*CAL*/ do_NOP,/*CMP*/ + do_NOP,/*CONT*/ do_NOP,/*COS*/ do_NOP,/*DDX*/ do_NOP,/*DDY*/ @@ -749,6 +753,8 @@ static void (* const opcode_func[MAX_OPCODE+3])(struct arb_vp_machine *, union i do_NOP,/*ELSE*/ do_NOP,/*END*/ do_NOP,/*ENDIF*/ + do_NOP,/*ENDLOOP*/ + do_NOP,/*ENDSUB*/ do_EX2, do_EXP, do_FLR, -- cgit v1.2.3 From cf92c727979e434d148b23d20f2e4e0f4bc4de61 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 5 Feb 2007 15:00:07 -0700 Subject: Initial implementation of high-level flow-control instructions. IF/ELSE/ENDIF and BEGIN_LOOP/END_LOOP/BREAK instructions seem to work. Disabled by default though until better tested. Implemented IR_NOT, but needs optimization. --- src/mesa/shader/slang/slang_codegen.c | 88 ++++++++++++++++++++++++++++++++--- src/mesa/shader/slang/slang_emit.c | 72 ++++++++++++++++++++++++++++ src/mesa/shader/slang/slang_ir.h | 2 + src/mesa/swrast/s_fragprog.c | 38 ++++++++++++--- src/mesa/tnl/t_vp_build.c | 2 +- 5 files changed, 189 insertions(+), 13 deletions(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index 72f58a9ebd..2dd9ccc6fd 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -47,6 +47,8 @@ #include "slang_print.h" +static GLboolean UseHighLevelInstructions = GL_TRUE; + static slang_ir_node * _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper); @@ -506,6 +508,7 @@ new_node(slang_ir_opcode op, slang_ir_node *left, slang_ir_node *right) n->Children[0] = left; n->Children[1] = right; n->Writemask = WRITEMASK_XYZW; + n->InstLocation = -1; } return n; } @@ -567,6 +570,26 @@ new_jump(slang_atom target) } +static slang_ir_node * +new_begin_loop(void) +{ + slang_ir_node *n = new_node(IR_BEGIN_LOOP, NULL, NULL); + return n; +} + + +static slang_ir_node * +new_end_loop(slang_ir_node *beginNode) +{ + slang_ir_node *n = new_node(IR_END_LOOP, NULL, NULL); + assert(beginNode); + if (n) { + n->BranchNode = beginNode; + } + return n; +} + + /** * New IR_VAR node - a reference to a previously declared variable. */ @@ -1304,7 +1327,7 @@ _slang_gen_function_call_name(slang_assemble_ctx *A, const char *name, /** - * Generate IR tree for a while-loop. + * Generate IR tree for a while-loop. Use BRA-nch instruction. */ static slang_ir_node * _slang_gen_while(slang_assemble_ctx * A, const slang_operation *oper) @@ -1313,7 +1336,7 @@ _slang_gen_while(slang_assemble_ctx * A, const slang_operation *oper) * label "__startWhile" * eval expr (child[0]), updating condcodes * branch if false to "__endWhile" - * code body + * body code * jump "__startWhile" * label "__endWhile" */ @@ -1353,6 +1376,51 @@ _slang_gen_while(slang_assemble_ctx * A, const slang_operation *oper) } +/** + * Generate IR tree for a while-loop using high-level BGNLOOP/ENDLOOP, + * IF/ENDIF instructions. + */ +static slang_ir_node * +_slang_gen_hl_while(slang_assemble_ctx * A, const slang_operation *oper) +{ + /* + * BGNLOOP + * eval expr (child[0]), updating condcodes + * IF !expr THEN + * BRK + * ENDIF + * body code + * ENDLOOP + */ + slang_ir_node *beginLoop, *endLoop, *ifThen, *endif; + slang_ir_node *brk, *cond, *body, *tree; + + beginLoop = new_begin_loop(); + + cond = _slang_gen_operation(A, &oper->children[0]); + cond = new_node(IR_NOT, cond, NULL); + cond = _slang_gen_cond(cond); + + ifThen = new_node(IR_IF, cond, NULL); + tree = new_seq(beginLoop, ifThen); + + brk = new_node(IR_BREAK, NULL, NULL); + tree = new_seq(tree, brk); + + endif = new_node(IR_ENDIF, NULL, NULL); + tree = new_seq(tree, endif); + + body = _slang_gen_operation(A, &oper->children[1]); + if (body) + tree = new_seq(tree, body); + + endLoop = new_end_loop(beginLoop); + tree = new_seq(tree, endLoop); + + return tree; +} + + /** * Generate IR tree for a do-while-loop. */ @@ -1517,7 +1585,7 @@ _slang_gen_if(slang_assemble_ctx * A, const slang_operation *oper) * IF/ELSE/ENDIF instructions */ static slang_ir_node * -_slang_gen_if2(slang_assemble_ctx * A, const slang_operation *oper) +_slang_gen_hl_if(slang_assemble_ctx * A, const slang_operation *oper) { /* * eval expr (child[0]), updating condcodes @@ -1529,6 +1597,10 @@ _slang_gen_if2(slang_assemble_ctx * A, const slang_operation *oper) * "false" code block * label "__endif" */ + /* XXX special cases to check for: + * if body of conditiona is just a "break", emit a conditional break + * instruction. + */ const GLboolean haveElseClause = !_slang_is_noop(&oper->children[2]); slang_ir_node *ifNode, *cond, *trueBody, *elseNode, *falseBody, *endifNode; slang_ir_node *tree; @@ -2261,7 +2333,10 @@ _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper) return _slang_gen_operation(A, &oper->children[0]); break; case slang_oper_while: - return _slang_gen_while(A, oper); + if (UseHighLevelInstructions) + return _slang_gen_hl_while(A, oper); + else + return _slang_gen_while(A, oper); case slang_oper_do: return _slang_gen_do(A, oper); case slang_oper_for: @@ -2427,8 +2502,9 @@ _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper) case slang_oper_identifier: return _slang_gen_variable(A, oper); case slang_oper_if: - if (A->program->Target == GL_FRAGMENT_PROGRAM_ARB) { - return _slang_gen_if(A, oper); + if (A->program->Target == GL_FRAGMENT_PROGRAM_ARB + && UseHighLevelInstructions) { + return _slang_gen_hl_if(A, oper); } else { /* XXX update tnl executor */ diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c index 756bbe9587..311eea1e6a 100644 --- a/src/mesa/shader/slang/slang_emit.c +++ b/src/mesa/shader/slang/slang_emit.c @@ -1005,6 +1005,42 @@ emit_cond(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) } +/** + * Logical-NOT + */ +static struct prog_instruction * +emit_not(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) +{ + GLfloat zero = 0.0; + slang_ir_storage st; + struct prog_instruction *inst; + + /* need zero constant */ + st.File = PROGRAM_CONSTANT; + st.Size = 1; + st.Index = _mesa_add_unnamed_constant(prog->Parameters, &zero, + 1, &st.Swizzle); + + /* child expr */ + (void) emit(vt, n->Children[0], prog); + /* XXXX if child instr is SGT convert to SLE, if SEQ, SNE, etc */ + + if (!n->Store) + if (!alloc_temp_storage(vt, n, n->Children[0]->Store->Size)) + return NULL; + + inst = new_instruction(prog, OPCODE_SEQ); + storage_to_dst_reg(&inst->DstReg, n->Store, n->Writemask); + storage_to_src_reg(&inst->SrcReg[0], n->Children[0]->Store); + storage_to_src_reg(&inst->SrcReg[1], &st); + + free_temp_storage(vt, n->Children[0]); + + return inst; +} + + + /** * Remove any SWIZZLE_NIL terms from given swizzle mask (smear prev term). * Ex: fix_swizzle("zyNN") -> "zyyy" @@ -1202,6 +1238,9 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) case IR_COND: return emit_cond(vt, n, prog); + case IR_NOT: + return emit_not(vt, n, prog); + case IR_LABEL: return emit_label(n->Target, prog); case IR_JUMP: @@ -1235,6 +1274,39 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) return inst; } + case IR_BEGIN_LOOP: + { + /* save location of this instruction, used by OPCODE_ENDLOOP */ + n->InstLocation = prog->NumInstructions; + (void) new_instruction(prog, OPCODE_BGNLOOP); + } + break; + case IR_END_LOOP: + { + struct prog_instruction *inst; + inst = new_instruction(prog, OPCODE_ENDLOOP); + assert(n->BranchNode); + assert(n->BranchNode->InstLocation >= 0); + /* The instruction BranchTarget points to top of loop */ + inst->BranchTarget = n->BranchNode->InstLocation; + return inst; + } + case IR_CONT: + return new_instruction(prog, OPCODE_CONT); + case IR_BREAK: + { + struct prog_instruction *inst; + inst = new_instruction(prog, OPCODE_BRK); + inst->DstReg.CondMask = COND_TR; /* always true */ + return inst; + } + case IR_BEGIN_SUB: + return new_instruction(prog, OPCODE_BGNSUB); + case IR_END_SUB: + return new_instruction(prog, OPCODE_ENDSUB); + case IR_RETURN: + return new_instruction(prog, OPCODE_RET); + default: _mesa_problem(NULL, "Unexpected IR opcode in emit()\n"); abort(); diff --git a/src/mesa/shader/slang/slang_ir.h b/src/mesa/shader/slang/slang_ir.h index ac1ea4dbb4..df5fc06779 100644 --- a/src/mesa/shader/slang/slang_ir.h +++ b/src/mesa/shader/slang/slang_ir.h @@ -150,6 +150,8 @@ typedef struct slang_ir_node_ GLfloat Value[4]; /**< If Opcode == IR_FLOAT */ slang_variable *Var; /**< If Opcode == IR_VAR or IR_VAR_DECL */ slang_ir_storage *Store; /**< location of result of this operation */ + GLint InstLocation; /**< Location of instruction emitted for this node */ + struct slang_ir_node_ *BranchNode; /**< Used for branch instructions */ } slang_ir_node; diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c index 00231aeae8..287dd9b1db 100644 --- a/src/mesa/swrast/s_fragprog.c +++ b/src/mesa/swrast/s_fragprog.c @@ -625,7 +625,7 @@ execute_program( GLcontext *ctx, GLuint column ) { const GLuint MAX_EXEC = 10000; - GLuint pc, total = 0; + GLint pc, total = 0, loopDepth = 0; if (DEBUG_FRAG) { printf("execute fragment program --------------------\n"); @@ -642,7 +642,7 @@ execute_program( GLcontext *ctx, } if (DEBUG_FRAG) { - _mesa_print_instruction(inst); + _mesa_print_instruction(inst, 0); } switch (inst->Opcode) { @@ -676,8 +676,13 @@ execute_program( GLcontext *ctx, } break; case OPCODE_BGNLOOP: /* begin loop */ + loopDepth++; break; case OPCODE_ENDLOOP: /* end loop */ + loopDepth--; + assert(loopDepth >= 0); + /* subtract 1 here since pc is incremented by for(pc) loop */ + pc = inst->BranchTarget - 1; /* go to matching BNGLOOP */ break; case OPCODE_BGNSUB: /* begin subroutine */ break; @@ -701,7 +706,19 @@ execute_program( GLcontext *ctx, } break; case OPCODE_BRK: /* break out of loop */ - /* assert inside loop */ + if (loopDepth == 0) { + _mesa_problem(ctx, "BRK not inside a loop"); + } + /* search for OPCODE_ENDLOOP */ + do { + pc++; + inst = program->Base.Instructions + pc; + if (inst->Opcode == OPCODE_ENDLOOP) { + loopDepth--; + assert(loopDepth >= 0); + break; + } + } while (pc < maxInst); break; case OPCODE_CAL: /* Call subroutine */ { @@ -880,20 +897,25 @@ execute_program( GLcontext *ctx, /* do if-clause (just continue execution) */ } else { - /* do else-clause, or go to endif */ + /* search for else-clause or endif */ + /* XXX could encode location of the else/endif statement + * in the IF instruction to avoid searching... + */ GLint ifDepth = 1; do { pc++; inst = program->Base.Instructions + pc; if (inst->Opcode == OPCODE_END) { /* mal-formed program! */ - abort(); + _mesa_problem(ctx, "END found before ELSE/ENDIF"); + return GL_FALSE; } else if (inst->Opcode == OPCODE_IF) { + /* nested if */ ifDepth++; } else if (inst->Opcode == OPCODE_ELSE) { - if (ifDepth == 0) { + if (ifDepth == 1) { /* ok, continue normal execution */ break; } @@ -1335,6 +1357,10 @@ execute_program( GLcontext *ctx, result[2] = (a[2] > b[2]) ? 1.0F : 0.0F; result[3] = (a[3] > b[3]) ? 1.0F : 0.0F; store_vector4( inst, machine, result ); + if (DEBUG_FRAG) { + printf("SGT %g %g %g %g\n", + result[0], result[1], result[2], result[3]); + } } break; case OPCODE_SIN: diff --git a/src/mesa/tnl/t_vp_build.c b/src/mesa/tnl/t_vp_build.c index 47fed32904..6fb14e7caa 100644 --- a/src/mesa/tnl/t_vp_build.c +++ b/src/mesa/tnl/t_vp_build.c @@ -497,7 +497,7 @@ static void debug_insn( struct prog_instruction *inst, const char *fn, } _mesa_printf("%d:\t", line); - _mesa_print_instruction(inst); + _mesa_print_instruction(inst, 0); } } -- cgit v1.2.3 From 86080796471df6a9e126fd536b21c3b10cb5310c Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 5 Feb 2007 17:18:10 -0700 Subject: Use IR node's BranchNode field for IF/ELSE/ENDIF instructions. This allows us to back-patch the IF/ELSE instruction's BranchTarget field to point to the location of the ELSE/ENDIF instructions. No longer have to search for ELSE/ENDIF in the interpreter. Also makes it trivial to translate IF/ELSE instructions into conditional/unconditional BRA instructions. --- src/mesa/shader/prog_print.c | 7 ++-- src/mesa/shader/slang/slang_codegen.c | 64 ++++++++++++++++++++++++++++------- src/mesa/shader/slang/slang_emit.c | 12 +++++++ src/mesa/swrast/s_fragprog.c | 57 ++++--------------------------- 4 files changed, 73 insertions(+), 67 deletions(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c index 208c998661..aea11da0db 100644 --- a/src/mesa/shader/prog_print.c +++ b/src/mesa/shader/prog_print.c @@ -319,13 +319,14 @@ _mesa_print_instruction(const struct prog_instruction *inst, GLint indent) print_comment(inst); break; case OPCODE_IF: - _mesa_printf("IF (%s%s)", + _mesa_printf("IF (%s%s) (if false, goto %d)", condcode_string(inst->DstReg.CondMask), - swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE)); + swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE), + inst->BranchTarget); print_comment(inst); return indent + 3; case OPCODE_ELSE: - _mesa_printf("ELSE\n"); + _mesa_printf("ELSE (goto %d)\n", inst->BranchTarget); return indent + 3; case OPCODE_ENDIF: _mesa_printf("ENDIF\n"); diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index c70f73f15a..7a1881c68e 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -590,6 +590,47 @@ new_end_loop(slang_ir_node *beginNode) } +/** + * Child[0] is the condition. + * XXX we might re-design IR_IF so Children[1] is the "then" body and + * Children[0] is the "else" body. + */ +static slang_ir_node * +new_if(slang_ir_node *cond) +{ + slang_ir_node *n = new_node(IR_IF, NULL, NULL); + assert(cond); + if (n) { + n->Children[0] = cond; + } + return n; +} + + +static slang_ir_node * +new_else(slang_ir_node *ifNode) +{ + slang_ir_node *n = new_node(IR_ELSE, NULL, NULL); + assert(ifNode); + if (n) { + n->BranchNode = ifNode; + } + return n; +} + + +static slang_ir_node * +new_endif(slang_ir_node *elseOrIfNode) +{ + slang_ir_node *n = new_node(IR_ENDIF, NULL, NULL); + assert(elseOrIfNode); + if (n) { + n->BranchNode = elseOrIfNode; + } + return n; +} + + /** * New IR_VAR node - a reference to a previously declared variable. */ @@ -1401,13 +1442,13 @@ _slang_gen_hl_while(slang_assemble_ctx * A, const slang_operation *oper) cond = new_node(IR_NOT, cond, NULL); cond = _slang_gen_cond(cond); - ifThen = new_node(IR_IF, cond, NULL); + ifThen = new_if(cond); tree = new_seq(beginLoop, ifThen); brk = new_node(IR_BREAK, NULL, NULL); tree = new_seq(tree, brk); - endif = new_node(IR_ENDIF, NULL, NULL); + endif = new_endif(ifThen); tree = new_seq(tree, endif); body = _slang_gen_operation(A, &oper->children[1]); @@ -1589,13 +1630,11 @@ _slang_gen_hl_if(slang_assemble_ctx * A, const slang_operation *oper) { /* * eval expr (child[0]), updating condcodes - * branch if false to _else or _endif - * "true" code block - * if haveElseClause clause: - * jump "__endif" - * label "__else" - * "false" code block - * label "__endif" + * IF expr THEN + * if-body code + * ELSE + * else-body code + * ENDIF */ /* XXX special cases to check for: * if body of conditiona is just a "break", emit a conditional break @@ -1608,21 +1647,20 @@ _slang_gen_hl_if(slang_assemble_ctx * A, const slang_operation *oper) cond = _slang_gen_operation(A, &oper->children[0]); cond = _slang_gen_cond(cond); /*assert(cond->Store);*/ - ifNode = new_node(IR_IF, cond, NULL); + ifNode = new_if(cond); trueBody = _slang_gen_operation(A, &oper->children[1]); tree = new_seq(ifNode, trueBody); if (haveElseClause) { - /* else clause */ - elseNode = new_node(IR_ELSE, NULL, NULL); + elseNode = new_else(ifNode); tree = new_seq(tree, elseNode); falseBody = _slang_gen_operation(A, &oper->children[2]); tree = new_seq(tree, falseBody); } - endifNode = new_node(IR_ENDIF, NULL, NULL); + endifNode = new_endif(haveElseClause ? elseNode : ifNode); tree = new_seq(tree, endifNode); return tree; diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c index 311eea1e6a..b890a6d93c 100644 --- a/src/mesa/shader/slang/slang_emit.c +++ b/src/mesa/shader/slang/slang_emit.c @@ -1036,6 +1036,7 @@ emit_not(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) free_temp_storage(vt, n->Children[0]); + inst->Comment = _mesa_strdup("NOT"); return inst; } @@ -1259,18 +1260,29 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) inst = new_instruction(prog, OPCODE_IF); inst->DstReg.CondMask = COND_NE; /* if cond is non-zero */ inst->DstReg.CondSwizzle = SWIZZLE_X; + n->InstLocation = prog->NumInstructions - 1; return inst; } case IR_ELSE: { struct prog_instruction *inst; + n->InstLocation = prog->NumInstructions; inst = new_instruction(prog, OPCODE_ELSE); + /* point IF's BranchTarget just after this instruction */ + assert(n->BranchNode); + assert(n->BranchNode->InstLocation >= 0); + prog->Instructions[n->BranchNode->InstLocation].BranchTarget = prog->NumInstructions; return inst; } case IR_ENDIF: { struct prog_instruction *inst; + n->InstLocation = prog->NumInstructions; inst = new_instruction(prog, OPCODE_ENDIF); + /* point ELSE's BranchTarget to just after this inst */ + assert(n->BranchNode); + assert(n->BranchNode->InstLocation >= 0); + prog->Instructions[n->BranchNode->InstLocation].BranchTarget = prog->NumInstructions; return inst; } diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c index 287dd9b1db..fbd25c0fbf 100644 --- a/src/mesa/swrast/s_fragprog.c +++ b/src/mesa/swrast/s_fragprog.c @@ -897,62 +897,17 @@ execute_program( GLcontext *ctx, /* do if-clause (just continue execution) */ } else { - /* search for else-clause or endif */ - /* XXX could encode location of the else/endif statement - * in the IF instruction to avoid searching... - */ - GLint ifDepth = 1; - do { - pc++; - inst = program->Base.Instructions + pc; - if (inst->Opcode == OPCODE_END) { - /* mal-formed program! */ - _mesa_problem(ctx, "END found before ELSE/ENDIF"); - return GL_FALSE; - } - else if (inst->Opcode == OPCODE_IF) { - /* nested if */ - ifDepth++; - } - else if (inst->Opcode == OPCODE_ELSE) { - if (ifDepth == 1) { - /* ok, continue normal execution */ - break; - } - } - else if (inst->Opcode == OPCODE_ENDIF) { - ifDepth--; - if (ifDepth == 0) { - /* ok, continue normal execution */ - break; - } - } - assert(ifDepth >= 0); - } while (pc < maxInst); + /* go to the instruction after ELSE or ENDIF */ + assert(inst->BranchTarget >= 0); + pc = inst->BranchTarget - 1; } } break; case OPCODE_ELSE: { - /* find/goto ENDIF */ - GLint ifDepth = 1; - do { - pc++; - inst = program->Base.Instructions + pc; - if (inst->Opcode == OPCODE_END) { - /* mal-formed program! */ - abort(); - } - else if (inst->Opcode == OPCODE_IF) { - ifDepth++; - } - else if (inst->Opcode == OPCODE_ENDIF) { - ifDepth--; - if (ifDepth == 0) - break; - } - assert(ifDepth >= 0); - } while (pc < maxInst); + /* goto ENDIF */ + assert(inst->BranchTarget >= 0); + pc = inst->BranchTarget - 1; } break; case OPCODE_ENDIF: -- cgit v1.2.3 From 2755c798f3cb89fcd4ece16cd740af1cd86a6b99 Mon Sep 17 00:00:00 2001 From: Brian Date: Mon, 5 Feb 2007 18:01:02 -0700 Subject: BRK instruction's BranchTarget field now used for efficiently breaking out of loops. BRK's BranchTarget field actually points to the top of the loop, not the bottom, since we don't know the later's location yet. In the interpreter, basically do an indirect jump to update the PC. --- src/mesa/shader/prog_print.c | 8 ++-- src/mesa/shader/slang/slang_codegen.c | 90 +++++++++++++++++++++++++++++++++-- src/mesa/shader/slang/slang_emit.c | 24 ++++++++-- src/mesa/swrast/s_fragprog.c | 30 +++++------- 4 files changed, 123 insertions(+), 29 deletions(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c index aea11da0db..3d4a474b05 100644 --- a/src/mesa/shader/prog_print.c +++ b/src/mesa/shader/prog_print.c @@ -332,17 +332,17 @@ _mesa_print_instruction(const struct prog_instruction *inst, GLint indent) _mesa_printf("ENDIF\n"); break; case OPCODE_BGNLOOP: - _mesa_printf("BGNLOOP\n"); + _mesa_printf("BGNLOOP (end at %d)\n", inst->BranchTarget); return indent + 3; case OPCODE_ENDLOOP: _mesa_printf("ENDLOOP (goto %d)\n", inst->BranchTarget); break; case OPCODE_BRK: /* XXX just like BRA */ - _mesa_printf("BRK %u (%s%s)", - inst->BranchTarget, + _mesa_printf("BRK (%s%s) (for loop beginning at %d)", condcode_string(inst->DstReg.CondMask), - swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE)); + swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE), + inst->BranchTarget); print_comment(inst); break; case OPCODE_BGNSUB: diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index 7a1881c68e..a5f033d912 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -590,6 +590,18 @@ new_end_loop(slang_ir_node *beginNode) } +static slang_ir_node * +new_break(slang_ir_node *beginNode) +{ + slang_ir_node *n = new_node(IR_BREAK, NULL, NULL); + assert(beginNode); + if (n) { + n->BranchNode = beginNode; + } + return n; +} + + /** * Child[0] is the condition. * XXX we might re-design IR_IF so Children[1] is the "then" body and @@ -1430,7 +1442,7 @@ _slang_gen_hl_while(slang_assemble_ctx * A, const slang_operation *oper) * IF !expr THEN * BRK * ENDIF - * body code + * body code (child[1]) * ENDLOOP */ slang_ir_node *beginLoop, *endLoop, *ifThen, *endif; @@ -1445,7 +1457,7 @@ _slang_gen_hl_while(slang_assemble_ctx * A, const slang_operation *oper) ifThen = new_if(cond); tree = new_seq(beginLoop, ifThen); - brk = new_node(IR_BREAK, NULL, NULL); + brk = new_break(beginLoop); tree = new_seq(tree, brk); endif = new_endif(ifThen); @@ -1571,6 +1583,73 @@ _slang_gen_for(slang_assemble_ctx * A, const slang_operation *oper) } +/** + * Generate IR tree for a for-loop, using high-level BGNLOOP/ENDLOOP and + * IF/ENDIF instructions. + * + * XXX note done yet! + */ +static slang_ir_node * +_slang_gen_hl_for(slang_assemble_ctx * A, const slang_operation *oper) +{ + /* + * init code (child[0]) + * BGNLOOP + * eval expr (child[1]), updating condcodes + * IF !expr THEN + * BRK + * ENDIF + * code body (child[3]) + * label "__continueFor" // jump here for "continue" + * incr code (child[2]) + * ENDLOOP + */ + slang_atom startAtom = slang_atom_pool_gen(A->atoms, "__startFor"); + slang_atom contAtom = slang_atom_pool_gen(A->atoms, "__continueFor"); + slang_atom endAtom = slang_atom_pool_gen(A->atoms, "__endFor"); + slang_ir_node *init, *startLab, *cond, *bra, *body, *contLab; + slang_ir_node *incr, *jump, *endLab, *tree; + slang_atom prevLoopBreak = A->CurLoopBreak; + slang_atom prevLoopCont = A->CurLoopCont; + + /* Push this loop */ + A->CurLoopBreak = endAtom; + A->CurLoopCont = contAtom; + + init = _slang_gen_operation(A, &oper->children[0]); + startLab = new_label(startAtom); + tree = new_seq(init, startLab); + + cond = _slang_gen_operation(A, &oper->children[1]); + cond = _slang_gen_cond(cond); + tree = new_seq(tree, cond); + + bra = new_cjump(endAtom, 0); + tree = new_seq(tree, bra); + + body = _slang_gen_operation(A, &oper->children[3]); + tree = new_seq(tree, body); + + contLab = new_label(contAtom); + tree = new_seq(tree, contLab); + + incr = _slang_gen_operation(A, &oper->children[2]); + tree = new_seq(tree, incr); + + jump = new_jump(startAtom); + tree = new_seq(tree, jump); + + endLab = new_label(endAtom); + tree = new_seq(tree, endLab); + + /* Pop this loop */ + A->CurLoopBreak = prevLoopBreak; + A->CurLoopCont = prevLoopCont; + + return tree; +} + + /** * Generate IR tree for an if/then/else conditional using BRAnch instructions. */ @@ -2378,16 +2457,21 @@ _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper) case slang_oper_do: return _slang_gen_do(A, oper); case slang_oper_for: - return _slang_gen_for(A, oper); + if (UseHighLevelInstructions) + return _slang_gen_hl_for(A, oper); + else + return _slang_gen_for(A, oper); case slang_oper_break: if (!A->CurLoopBreak) { RETURN_ERROR("'break' not in loop", 0); } + /* XXX emit IR_BREAK instruction */ return new_jump(A->CurLoopBreak); case slang_oper_continue: if (!A->CurLoopCont) { RETURN_ERROR("'continue' not in loop", 0); } + /* XXX emit IR_CONT instruction */ return new_jump(A->CurLoopCont); case slang_oper_discard: return new_node(IR_KILL, NULL, NULL); diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c index b890a6d93c..3faacdd4cf 100644 --- a/src/mesa/shader/slang/slang_emit.c +++ b/src/mesa/shader/slang/slang_emit.c @@ -1265,24 +1265,29 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) } case IR_ELSE: { - struct prog_instruction *inst; + struct prog_instruction *inst, *ifInst; n->InstLocation = prog->NumInstructions; inst = new_instruction(prog, OPCODE_ELSE); /* point IF's BranchTarget just after this instruction */ assert(n->BranchNode); assert(n->BranchNode->InstLocation >= 0); - prog->Instructions[n->BranchNode->InstLocation].BranchTarget = prog->NumInstructions; + ifInst = prog->Instructions + n->BranchNode->InstLocation; + assert(ifInst->Opcode == OPCODE_IF); + ifInst->BranchTarget = prog->NumInstructions; return inst; } case IR_ENDIF: { - struct prog_instruction *inst; + struct prog_instruction *inst, *elseInst; n->InstLocation = prog->NumInstructions; inst = new_instruction(prog, OPCODE_ENDIF); /* point ELSE's BranchTarget to just after this inst */ assert(n->BranchNode); assert(n->BranchNode->InstLocation >= 0); - prog->Instructions[n->BranchNode->InstLocation].BranchTarget = prog->NumInstructions; + elseInst = prog->Instructions + n->BranchNode->InstLocation; + assert(elseInst->Opcode == OPCODE_ELSE || + elseInst->Opcode == OPCODE_IF); + elseInst->BranchTarget = prog->NumInstructions; return inst; } @@ -1295,12 +1300,15 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) break; case IR_END_LOOP: { - struct prog_instruction *inst; + struct prog_instruction *inst, *beginInst; inst = new_instruction(prog, OPCODE_ENDLOOP); assert(n->BranchNode); assert(n->BranchNode->InstLocation >= 0); /* The instruction BranchTarget points to top of loop */ inst->BranchTarget = n->BranchNode->InstLocation; + /* Update BEGIN_LOOP's BranchTarget to point to this instruction */ + beginInst = prog->Instructions + n->BranchNode->InstLocation; + beginInst->BranchTarget = prog->NumInstructions - 1; return inst; } case IR_CONT: @@ -1310,6 +1318,12 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) struct prog_instruction *inst; inst = new_instruction(prog, OPCODE_BRK); inst->DstReg.CondMask = COND_TR; /* always true */ + /* This instruction's branch target is top of loop, not bottom of + * loop because we don't know where it is yet! + */ + assert(n->BranchNode); + assert(n->BranchNode->InstLocation >= 0); + inst->BranchTarget = n->BranchNode->InstLocation; return inst; } case IR_BEGIN_SUB: diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c index fbd25c0fbf..12c8aee6ea 100644 --- a/src/mesa/swrast/s_fragprog.c +++ b/src/mesa/swrast/s_fragprog.c @@ -625,7 +625,7 @@ execute_program( GLcontext *ctx, GLuint column ) { const GLuint MAX_EXEC = 10000; - GLint pc, total = 0, loopDepth = 0; + GLint pc, total = 0; if (DEBUG_FRAG) { printf("execute fragment program --------------------\n"); @@ -676,11 +676,8 @@ execute_program( GLcontext *ctx, } break; case OPCODE_BGNLOOP: /* begin loop */ - loopDepth++; break; case OPCODE_ENDLOOP: /* end loop */ - loopDepth--; - assert(loopDepth >= 0); /* subtract 1 here since pc is incremented by for(pc) loop */ pc = inst->BranchTarget - 1; /* go to matching BNGLOOP */ break; @@ -706,19 +703,18 @@ execute_program( GLcontext *ctx, } break; case OPCODE_BRK: /* break out of loop */ - if (loopDepth == 0) { - _mesa_problem(ctx, "BRK not inside a loop"); - } - /* search for OPCODE_ENDLOOP */ - do { - pc++; - inst = program->Base.Instructions + pc; - if (inst->Opcode == OPCODE_ENDLOOP) { - loopDepth--; - assert(loopDepth >= 0); - break; - } - } while (pc < maxInst); + { + /* The location of the ENDLOOP instruction is saved in the + * BGNLOOP instruction. Get that instruction and jump to + * its BranchTarget + 1. + */ + const struct prog_instruction *loopBeginInst + = program->Base.Instructions + inst->BranchTarget; + ASSERT(loopBeginInst->Opcode == OPCODE_BGNLOOP); + ASSERT(loopBeginInst->BranchTarget >= 0); + /* we'll add one at bottom of for-loop */ + pc = loopBeginInst->BranchTarget; + } break; case OPCODE_CAL: /* Call subroutine */ { -- cgit v1.2.3 From f22ed0986a743e033d827c78371612c7115ff913 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 6 Feb 2007 22:31:19 -0700 Subject: Implement CONT, improve BRK. IR_LOOP's BranchNode ptr is the head of a linked list of CONT and BRK nodes. After emitting loop, walk over the linked list, filling in the CONT/BRK instruction's BranchTarget field (location of the ENDLOOP instruction, or one past). --- src/mesa/shader/prog_print.c | 10 ++++++-- src/mesa/shader/slang/slang_codegen.c | 29 ++++++++++++++++++--- src/mesa/shader/slang/slang_emit.c | 47 ++++++++++++++++++++++++++--------- src/mesa/swrast/s_fragprog.c | 6 +++++ 4 files changed, 74 insertions(+), 18 deletions(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c index 3d4a474b05..6c303de9b5 100644 --- a/src/mesa/shader/prog_print.c +++ b/src/mesa/shader/prog_print.c @@ -338,8 +338,14 @@ _mesa_print_instruction(const struct prog_instruction *inst, GLint indent) _mesa_printf("ENDLOOP (goto %d)\n", inst->BranchTarget); break; case OPCODE_BRK: - /* XXX just like BRA */ - _mesa_printf("BRK (%s%s) (for loop beginning at %d)", + _mesa_printf("BRK (%s%s) (goto %d)", + condcode_string(inst->DstReg.CondMask), + swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE), + inst->BranchTarget); + print_comment(inst); + break; + case OPCODE_CONT: + _mesa_printf("CONT (%s%s) (goto %d)", condcode_string(inst->DstReg.CondMask), swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE), inst->BranchTarget); diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index a4e2935ea8..42c1f0897e 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -608,7 +608,24 @@ new_break(slang_ir_node *loopNode) assert(loopNode); assert(loopNode->Opcode == IR_LOOP); if (n) { - n->BranchNode = loopNode; + /* insert this node at head of linked list */ + n->BranchNode = loopNode->BranchNode; + loopNode->BranchNode = n; + } + return n; +} + + +static slang_ir_node * +new_cont(slang_ir_node *loopNode) +{ + slang_ir_node *n = new_node0(IR_CONT); + assert(loopNode); + assert(loopNode->Opcode == IR_LOOP); + if (n) { + /* insert this node at head of linked list */ + n->BranchNode = loopNode->BranchNode; + loopNode->BranchNode = n; } return n; } @@ -2434,11 +2451,15 @@ _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper) return new_jump(A->CurLoopBreak); } case slang_oper_continue: - if (!A->CurLoopCont) { + if (!A->CurLoop && !A->CurLoopCont) { RETURN_ERROR("'continue' not in loop", 0); } - /* XXX emit IR_CONT instruction */ - return new_jump(A->CurLoopCont); + if (UseHighLevelInstructions) { + return new_cont(A->CurLoop); + } + else { + return new_jump(A->CurLoopCont); + } case slang_oper_discard: return new_node0(IR_KILL); diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c index c18f1e364c..2d5a7cf6f9 100644 --- a/src/mesa/shader/slang/slang_emit.c +++ b/src/mesa/shader/slang/slang_emit.c @@ -1303,7 +1303,9 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) case IR_LOOP: { - struct prog_instruction *beginInst; + struct prog_instruction *beginInst, *endInst; + GLuint endInstLoc; + slang_ir_node *p; /* save location of this instruction, used by OPCODE_ENDLOOP */ n->InstLocation = prog->NumInstructions; @@ -1312,27 +1314,48 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) /* body */ emit(vt, n->Children[0], prog); - inst = new_instruction(prog, OPCODE_ENDLOOP); - /* The instruction BranchTarget points to top of loop */ - inst->BranchTarget = n->InstLocation; + endInstLoc = prog->NumInstructions; + endInst = new_instruction(prog, OPCODE_ENDLOOP); + /* The ENDLOOP's BranchTarget points to top of loop */ + endInst->BranchTarget = n->InstLocation; /* Update BGNLOOP's BranchTarget to point to this instruction */ beginInst = prog->Instructions + n->InstLocation; beginInst->BranchTarget = prog->NumInstructions - 1; - return inst; + + /* Done emitting loop code. Now walk over the loop's linked list + * of BREAK and CONT nodes, filling in their BranchTarget fields. + */ + for (p = n->BranchNode; p; p = p->BranchNode) { + if (p->Opcode == IR_BREAK) { + struct prog_instruction *brkInst + = prog->Instructions + p->InstLocation; + assert(brkInst->Opcode == OPCODE_BRK); + brkInst->BranchTarget = endInstLoc + 1; + } + else { + assert(p->Opcode == IR_CONT); + struct prog_instruction *contInst + = prog->Instructions + p->InstLocation; + assert(contInst->Opcode == OPCODE_CONT); + contInst->BranchTarget = endInstLoc; + } + } + return NULL; } case IR_CONT: - return new_instruction(prog, OPCODE_CONT); + { + struct prog_instruction *inst; + n->InstLocation = prog->NumInstructions; + inst = new_instruction(prog, OPCODE_CONT); + inst->DstReg.CondMask = COND_TR; /* always true */ + return inst; + } case IR_BREAK: { struct prog_instruction *inst; + n->InstLocation = prog->NumInstructions; inst = new_instruction(prog, OPCODE_BRK); inst->DstReg.CondMask = COND_TR; /* always true */ - /* This instruction's branch target is top of loop, not bottom of - * loop because we don't know where it is yet! - */ - assert(n->BranchNode); - assert(n->BranchNode->InstLocation >= 0); - inst->BranchTarget = n->BranchNode->InstLocation; return inst; } diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c index 12c8aee6ea..63974b30f2 100644 --- a/src/mesa/swrast/s_fragprog.c +++ b/src/mesa/swrast/s_fragprog.c @@ -704,6 +704,7 @@ execute_program( GLcontext *ctx, break; case OPCODE_BRK: /* break out of loop */ { +#if 0 /* The location of the ENDLOOP instruction is saved in the * BGNLOOP instruction. Get that instruction and jump to * its BranchTarget + 1. @@ -714,6 +715,9 @@ execute_program( GLcontext *ctx, ASSERT(loopBeginInst->BranchTarget >= 0); /* we'll add one at bottom of for-loop */ pc = loopBeginInst->BranchTarget; +#else + pc = inst->BranchTarget - 1; +#endif } break; case OPCODE_CAL: /* Call subroutine */ @@ -747,6 +751,8 @@ execute_program( GLcontext *ctx, } break; case OPCODE_CONT: /* continue loop */ + /* Subtract 1 here since we'll do pc++ at end of for-loop */ + pc = inst->BranchTarget - 1; break; case OPCODE_COS: { -- cgit v1.2.3 From 1f99a7514e9c36b7ce2c6c1724a6584790656415 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 6 Feb 2007 22:34:09 -0700 Subject: BRK and CONT work the same --- src/mesa/swrast/s_fragprog.c | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c index 63974b30f2..403a03aa32 100644 --- a/src/mesa/swrast/s_fragprog.c +++ b/src/mesa/swrast/s_fragprog.c @@ -703,22 +703,10 @@ execute_program( GLcontext *ctx, } break; case OPCODE_BRK: /* break out of loop */ - { -#if 0 - /* The location of the ENDLOOP instruction is saved in the - * BGNLOOP instruction. Get that instruction and jump to - * its BranchTarget + 1. - */ - const struct prog_instruction *loopBeginInst - = program->Base.Instructions + inst->BranchTarget; - ASSERT(loopBeginInst->Opcode == OPCODE_BGNLOOP); - ASSERT(loopBeginInst->BranchTarget >= 0); - /* we'll add one at bottom of for-loop */ - pc = loopBeginInst->BranchTarget; -#else - pc = inst->BranchTarget - 1; -#endif - } + /* fall-through */ + case OPCODE_CONT: /* continue loop */ + /* Subtract 1 here since we'll do pc++ at end of for-loop */ + pc = inst->BranchTarget - 1; break; case OPCODE_CAL: /* Call subroutine */ { @@ -750,10 +738,6 @@ execute_program( GLcontext *ctx, store_vector4( inst, machine, result ); } break; - case OPCODE_CONT: /* continue loop */ - /* Subtract 1 here since we'll do pc++ at end of for-loop */ - pc = inst->BranchTarget - 1; - break; case OPCODE_COS: { GLfloat a[4], result[4]; -- cgit v1.2.3 From 4aa487e7968d015af4fe729f697105448fcb843f Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 7 Feb 2007 15:12:13 -0700 Subject: Use IR_LOOP to represent do-while and for-loops. Also, start moving high vs. low-level instruction selection into slang_emit.c --- src/mesa/shader/slang/slang_codegen.c | 110 ++++++++++++++++++++-------------- src/mesa/shader/slang/slang_emit.c | 82 +++++++++++++++---------- src/mesa/shader/slang/slang_ir.h | 7 ++- src/mesa/shader/slang/slang_link.c | 2 +- src/mesa/swrast/s_fragprog.c | 12 ++-- 5 files changed, 128 insertions(+), 85 deletions(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index 42c1f0897e..14870f57ae 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -1423,7 +1423,7 @@ _slang_gen_while(slang_assemble_ctx * A, const slang_operation *oper) /** - * Generate IR tree for a while-loop using high-level LOOP, IF instructions. + * Generate loop code using high-level IR_LOOP instruction */ static slang_ir_node * _slang_gen_hl_while(slang_assemble_ctx * A, const slang_operation *oper) @@ -1509,6 +1509,46 @@ _slang_gen_do(slang_assemble_ctx * A, const slang_operation *oper) } +/** + * Generate IR tree for a do-while loop using high-level LOOP, IF instructions. + */ +static slang_ir_node * +_slang_gen_hl_do(slang_assemble_ctx * A, const slang_operation *oper) +{ + slang_ir_node *prevLoop; + /* + * LOOP: + * body code (child[0]) + * eval expr (child[1]), updating condcodes + * IF !expr: + * BRK + */ + slang_ir_node *ifThen, *cond, *body, *loop; + + loop = new_loop(NULL); + + /* save old, push new loop */ + prevLoop = A->CurLoop; + A->CurLoop = loop; + + body = _slang_gen_operation(A, &oper->children[0]); + + cond = _slang_gen_operation(A, &oper->children[1]); + cond = new_node1(IR_NOT, cond); + cond = _slang_gen_cond(cond); + + ifThen = new_if(cond, + new_break(A->CurLoop), + NULL); + + loop->Children[0] = new_seq(body, ifThen); + + A->CurLoop = prevLoop; /* pop loop, restore prev */ + + return loop; +} + + /** * Generate IR tree for a for-loop. */ @@ -1573,69 +1613,48 @@ _slang_gen_for(slang_assemble_ctx * A, const slang_operation *oper) /** - * Generate IR tree for a for-loop, using high-level BGNLOOP/ENDLOOP and - * IF/ENDIF instructions. - * - * XXX note done yet! + * Generate for-loop using high-level IR_LOOP instruction. */ static slang_ir_node * _slang_gen_hl_for(slang_assemble_ctx * A, const slang_operation *oper) { + slang_ir_node *prevLoop; /* - * init code (child[0]) - * BGNLOOP + * init (child[0]) + * LOOP: * eval expr (child[1]), updating condcodes - * IF !expr THEN + * IF !expr: * BRK - * ENDIF - * code body (child[3]) - * label "__continueFor" // jump here for "continue" - * incr code (child[2]) - * ENDLOOP + * body code (child[3]) + * incr code (child[2]) // XXX continue here */ - slang_atom startAtom = slang_atom_pool_gen(A->atoms, "__startFor"); - slang_atom contAtom = slang_atom_pool_gen(A->atoms, "__continueFor"); - slang_atom endAtom = slang_atom_pool_gen(A->atoms, "__endFor"); - slang_ir_node *init, *startLab, *cond, *bra, *body, *contLab; - slang_ir_node *incr, *jump, *endLab, *tree; - slang_atom prevLoopBreak = A->CurLoopBreak; - slang_atom prevLoopCont = A->CurLoopCont; - - /* Push this loop */ - A->CurLoopBreak = endAtom; - A->CurLoopCont = contAtom; + slang_ir_node *init, *ifThen, *cond, *body, *loop, *incr; init = _slang_gen_operation(A, &oper->children[0]); - startLab = new_label(startAtom); - tree = new_seq(init, startLab); + loop = new_loop(NULL); + + /* save old, push new loop */ + prevLoop = A->CurLoop; + A->CurLoop = loop; cond = _slang_gen_operation(A, &oper->children[1]); + cond = new_node1(IR_NOT, cond); cond = _slang_gen_cond(cond); - tree = new_seq(tree, cond); - bra = new_cjump(endAtom, 0); - tree = new_seq(tree, bra); + ifThen = new_if(cond, + new_break(A->CurLoop), + NULL); body = _slang_gen_operation(A, &oper->children[3]); - tree = new_seq(tree, body); - - contLab = new_label(contAtom); - tree = new_seq(tree, contLab); incr = _slang_gen_operation(A, &oper->children[2]); - tree = new_seq(tree, incr); - - jump = new_jump(startAtom); - tree = new_seq(tree, jump); - endLab = new_label(endAtom); - tree = new_seq(tree, endLab); + loop->Children[0] = new_seq(ifThen, + new_seq(body,incr)); - /* Pop this loop */ - A->CurLoopBreak = prevLoopBreak; - A->CurLoopCont = prevLoopCont; + A->CurLoop = prevLoop; /* pop loop, restore prev */ - return tree; + return new_seq(init, loop); } @@ -2434,7 +2453,10 @@ _slang_gen_operation(slang_assemble_ctx * A, slang_operation *oper) else return _slang_gen_while(A, oper); case slang_oper_do: - return _slang_gen_do(A, oper); + if (UseHighLevelInstructions) + return _slang_gen_hl_do(A, oper); + else + return _slang_gen_do(A, oper); case slang_oper_for: if (UseHighLevelInstructions) return _slang_gen_hl_for(A, oper); diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c index 2d5a7cf6f9..29588379a2 100644 --- a/src/mesa/shader/slang/slang_emit.c +++ b/src/mesa/shader/slang/slang_emit.c @@ -43,6 +43,9 @@ #define ANNOTATE 1 +static GLboolean EmitHighLevelInstructions = GL_FALSE; + + /** * Assembly and IR info */ @@ -1304,57 +1307,72 @@ emit(slang_var_table *vt, slang_ir_node *n, struct gl_program *prog) case IR_LOOP: { struct prog_instruction *beginInst, *endInst; - GLuint endInstLoc; - slang_ir_node *p; + GLuint beginInstLoc, endInstLoc; + slang_ir_node *ir; - /* save location of this instruction, used by OPCODE_ENDLOOP */ - n->InstLocation = prog->NumInstructions; - (void) new_instruction(prog, OPCODE_BGNLOOP); + /* emit OPCODE_BGNLOOP */ + beginInstLoc = prog->NumInstructions; + if (EmitHighLevelInstructions) { + (void) new_instruction(prog, OPCODE_BGNLOOP); + } /* body */ emit(vt, n->Children[0], prog); endInstLoc = prog->NumInstructions; - endInst = new_instruction(prog, OPCODE_ENDLOOP); - /* The ENDLOOP's BranchTarget points to top of loop */ - endInst->BranchTarget = n->InstLocation; - /* Update BGNLOOP's BranchTarget to point to this instruction */ - beginInst = prog->Instructions + n->InstLocation; - beginInst->BranchTarget = prog->NumInstructions - 1; + if (EmitHighLevelInstructions) { + /* emit OPCODE_ENDLOOP */ + endInst = new_instruction(prog, OPCODE_ENDLOOP); + } + else { + /* emit unconditional BRA-nch */ + endInst = new_instruction(prog, OPCODE_BRA); + endInst->DstReg.CondMask = COND_TR; /* always true */ + } + /* end instruction's BranchTarget points to top of loop */ + endInst->BranchTarget = beginInstLoc; + + if (EmitHighLevelInstructions) { + /* BGNLOOP's BranchTarget points to the ENDLOOP inst */ + beginInst = prog->Instructions + beginInstLoc; + beginInst->BranchTarget = prog->NumInstructions - 1; + } /* Done emitting loop code. Now walk over the loop's linked list - * of BREAK and CONT nodes, filling in their BranchTarget fields. + * of BREAK and CONT nodes, filling in their BranchTarget fields + * (which will point to the ENDLOOP or ENDLOOP+1 instructions). */ - for (p = n->BranchNode; p; p = p->BranchNode) { - if (p->Opcode == IR_BREAK) { - struct prog_instruction *brkInst - = prog->Instructions + p->InstLocation; - assert(brkInst->Opcode == OPCODE_BRK); - brkInst->BranchTarget = endInstLoc + 1; + for (ir = n->BranchNode; ir; ir = ir->BranchNode) { + struct prog_instruction *inst + = prog->Instructions + ir->InstLocation; + if (ir->Opcode == IR_BREAK) { + assert(inst->Opcode == OPCODE_BRK || + inst->Opcode == OPCODE_BRA); + inst->BranchTarget = endInstLoc + 1; } else { - assert(p->Opcode == IR_CONT); - struct prog_instruction *contInst - = prog->Instructions + p->InstLocation; - assert(contInst->Opcode == OPCODE_CONT); - contInst->BranchTarget = endInstLoc; + assert(ir->Opcode == IR_CONT); + assert(inst->Opcode == OPCODE_CONT || + inst->Opcode == OPCODE_BRA); + inst->BranchTarget = endInstLoc; } } return NULL; } - case IR_CONT: - { - struct prog_instruction *inst; - n->InstLocation = prog->NumInstructions; - inst = new_instruction(prog, OPCODE_CONT); - inst->DstReg.CondMask = COND_TR; /* always true */ - return inst; - } case IR_BREAK: + /* fall-through */ + case IR_CONT: { + gl_inst_opcode opcode; struct prog_instruction *inst; n->InstLocation = prog->NumInstructions; - inst = new_instruction(prog, OPCODE_BRK); + if (EmitHighLevelInstructions) { + opcode = (n->Opcode == IR_CONT) ? OPCODE_CONT : OPCODE_BRK; + } + else { + opcode = OPCODE_BRA; + } + inst = new_instruction(prog, opcode); inst->DstReg.CondMask = COND_TR; /* always true */ return inst; } diff --git a/src/mesa/shader/slang/slang_ir.h b/src/mesa/shader/slang/slang_ir.h index a7c858c69f..0c827d9cd8 100644 --- a/src/mesa/shader/slang/slang_ir.h +++ b/src/mesa/shader/slang/slang_ir.h @@ -39,7 +39,7 @@ /** - * Intermediate Representation opcode + * Intermediate Representation opcodes */ typedef enum { @@ -64,6 +64,11 @@ typedef enum IR_CONT, /* continue loop */ IR_BREAK, /* break loop */ + IR_BREAK_IF_TRUE, + IR_BREAK_IF_FALSE, + IR_CONT_IF_TRUE, + IR_CONT_IF_FALSE, + IR_MOVE, IR_ADD, IR_SUB, diff --git a/src/mesa/shader/slang/slang_link.c b/src/mesa/shader/slang/slang_link.c index 017cf6078c..b1d355ff80 100644 --- a/src/mesa/shader/slang/slang_link.c +++ b/src/mesa/shader/slang/slang_link.c @@ -298,7 +298,7 @@ _slang_resolve_branches(struct gl_program *prog) for (i = 0; i < prog->NumInstructions; i++) { struct prog_instruction *inst = prog->Instructions + i; - if (inst->Opcode == OPCODE_BRA) { + if (inst->Opcode == OPCODE_BRA && inst->BranchTarget < 0) { for (j = 0; j < numTargets; j++) { if (!strcmp(inst->Comment, targets[j].Name)) { inst->BranchTarget = targets[j].Pos; diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c index 403a03aa32..ace10a9222 100644 --- a/src/mesa/swrast/s_fragprog.c +++ b/src/mesa/swrast/s_fragprog.c @@ -675,9 +675,10 @@ execute_program( GLcontext *ctx, } } break; - case OPCODE_BGNLOOP: /* begin loop */ + case OPCODE_BGNLOOP: + /* no-op */ break; - case OPCODE_ENDLOOP: /* end loop */ + case OPCODE_ENDLOOP: /* subtract 1 here since pc is incremented by for(pc) loop */ pc = inst->BranchTarget - 1; /* go to matching BNGLOOP */ break; @@ -695,10 +696,7 @@ execute_program( GLcontext *ctx, test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) || test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) { /* take branch */ - pc = inst->BranchTarget; - /* - printf("Take branch to %u\n", pc); - */ + pc = inst->BranchTarget - 1; } } break; @@ -721,7 +719,7 @@ execute_program( GLcontext *ctx, return GL_TRUE; /* Per GL_NV_vertex_program2 spec */ } machine->CallStack[machine->StackDepth++] = pc + 1; - pc = inst->BranchTarget; + pc = inst->BranchTarget; /* XXX - 1 ??? */ } } break; -- cgit v1.2.3 From 97125fb370faa6aee0967254fad69f27189b9325 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 8 Feb 2007 13:22:31 -0700 Subject: Simplify code with eval_condition(). Implement conditional BRK. --- src/mesa/swrast/s_fragprog.c | 125 +++++++++++++++++++------------------------ 1 file changed, 56 insertions(+), 69 deletions(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c index ace10a9222..ce028f72bf 100644 --- a/src/mesa/swrast/s_fragprog.c +++ b/src/mesa/swrast/s_fragprog.c @@ -417,6 +417,29 @@ test_cc(GLuint condCode, GLuint ccMaskRule) } +/** + * Evaluate the 4 condition codes against a predicate and return GL_TRUE + * or GL_FALSE to indicate result. + */ +static INLINE GLboolean +eval_condition(const struct fp_machine *machine, + const struct prog_instruction *inst) +{ + const GLuint swizzle = inst->DstReg.CondSwizzle; + const GLuint condMask = inst->DstReg.CondMask; + if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) || + test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) || + test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) || + test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) { + return GL_TRUE; + } + else { + return GL_FALSE; + } +} + + + /** * Store 4 floats into a register. Observe the instructions saturate and * set-condition-code flags. @@ -687,40 +710,28 @@ execute_program( GLcontext *ctx, case OPCODE_ENDSUB: /* end subroutine */ break; case OPCODE_BRA: /* conditional branch */ - { - /* NOTE: The branch is conditional! */ - const GLuint swizzle = inst->DstReg.CondSwizzle; - const GLuint condMask = inst->DstReg.CondMask; - if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) || - test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) || - test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) || - test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) { - /* take branch */ - pc = inst->BranchTarget - 1; - } + if (eval_condition(machine, inst)) { + /* take branch */ + pc = inst->BranchTarget - 1; } break; - case OPCODE_BRK: /* break out of loop */ + case OPCODE_BRK: /* break out of loop (conditional) */ /* fall-through */ - case OPCODE_CONT: /* continue loop */ + case OPCODE_CONT: /* continue loop (conditional) */ /* Subtract 1 here since we'll do pc++ at end of for-loop */ - pc = inst->BranchTarget - 1; + if (eval_condition(machine, inst)) { + /* take branch */ + pc = inst->BranchTarget - 1; + } break; - case OPCODE_CAL: /* Call subroutine */ - { - /* NOTE: The call is conditional! */ - const GLuint swizzle = inst->DstReg.CondSwizzle; - const GLuint condMask = inst->DstReg.CondMask; - if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) || - test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) || - test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) || - test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) { - if (machine->StackDepth >= MAX_PROGRAM_CALL_DEPTH) { - return GL_TRUE; /* Per GL_NV_vertex_program2 spec */ - } - machine->CallStack[machine->StackDepth++] = pc + 1; - pc = inst->BranchTarget; /* XXX - 1 ??? */ + case OPCODE_CAL: /* Call subroutine (conditional) */ + if (eval_condition(machine, inst)) { + /* call the subroutine */ + if (machine->StackDepth >= MAX_PROGRAM_CALL_DEPTH) { + return GL_TRUE; /* Per GL_NV_vertex_program2 spec */ } + machine->CallStack[machine->StackDepth++] = pc + 1; + pc = inst->BranchTarget; /* XXX - 1 ??? */ } break; case OPCODE_CMP: @@ -871,29 +882,20 @@ execute_program( GLcontext *ctx, } break; case OPCODE_IF: - { - const GLuint swizzle = inst->DstReg.CondSwizzle; - const GLuint condMask = inst->DstReg.CondMask; - if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) || - test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) || - test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) || - test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) { - /* do if-clause (just continue execution) */ - } - else { - /* go to the instruction after ELSE or ENDIF */ - assert(inst->BranchTarget >= 0); - pc = inst->BranchTarget - 1; - } + if (eval_condition(machine, inst)) { + /* do if-clause (just continue execution) */ } - break; - case OPCODE_ELSE: - { - /* goto ENDIF */ + else { + /* go to the instruction after ELSE or ENDIF */ assert(inst->BranchTarget >= 0); pc = inst->BranchTarget - 1; } break; + case OPCODE_ELSE: + /* goto ENDIF */ + assert(inst->BranchTarget >= 0); + pc = inst->BranchTarget - 1; + break; case OPCODE_ENDIF: /* nothing */ break; @@ -908,16 +910,9 @@ execute_program( GLcontext *ctx, store_vector4( inst, machine, result ); } break; - case OPCODE_KIL_NV: /* NV_f_p only */ - { - const GLuint swizzle = inst->DstReg.CondSwizzle; - const GLuint condMask = inst->DstReg.CondMask; - if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) || - test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) || - test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) || - test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) { - return GL_FALSE; - } + case OPCODE_KIL_NV: /* NV_f_p only (conditional) */ + if (eval_condition(machine, inst)) { + return GL_FALSE; } break; case OPCODE_KIL: /* ARB_f_p only */ @@ -1203,20 +1198,12 @@ execute_program( GLcontext *ctx, store_vector4( inst, machine, result ); } break; - case OPCODE_RET: /* return from subroutine */ - { - /* NOTE: The return is conditional! */ - const GLuint swizzle = inst->DstReg.CondSwizzle; - const GLuint condMask = inst->DstReg.CondMask; - if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) || - test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) || - test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) || - test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) { - if (machine->StackDepth == 0) { - return GL_TRUE; /* Per GL_NV_vertex_program2 spec */ - } - pc = machine->CallStack[--machine->StackDepth]; + case OPCODE_RET: /* return from subroutine (conditional) */ + if (eval_condition(machine, inst)) { + if (machine->StackDepth == 0) { + return GL_TRUE; /* Per GL_NV_vertex_program2 spec */ } + pc = machine->CallStack[--machine->StackDepth]; } break; case OPCODE_RFL: /* reflection vector */ -- cgit v1.2.3 From 34af2b7194ad473c8ae20bcff933910f8386c3f0 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 8 Feb 2007 14:10:19 -0700 Subject: consolidate BRA with BRK, CONT --- src/mesa/swrast/s_fragprog.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c index ce028f72bf..fe41c0b5f4 100644 --- a/src/mesa/swrast/s_fragprog.c +++ b/src/mesa/swrast/s_fragprog.c @@ -709,18 +709,14 @@ execute_program( GLcontext *ctx, break; case OPCODE_ENDSUB: /* end subroutine */ break; - case OPCODE_BRA: /* conditional branch */ - if (eval_condition(machine, inst)) { - /* take branch */ - pc = inst->BranchTarget - 1; - } - break; + case OPCODE_BRA: /* branch (conditional) */ + /* fall-through */ case OPCODE_BRK: /* break out of loop (conditional) */ /* fall-through */ case OPCODE_CONT: /* continue loop (conditional) */ - /* Subtract 1 here since we'll do pc++ at end of for-loop */ if (eval_condition(machine, inst)) { /* take branch */ + /* Subtract 1 here since we'll do pc++ at end of for-loop */ pc = inst->BranchTarget - 1; } break; -- cgit v1.2.3 From 501ee87180047dd04afc69103c31e1eae5374bf1 Mon Sep 17 00:00:00 2001 From: Brian Date: Sat, 17 Feb 2007 09:15:00 -0700 Subject: Lots of changes to prog_print.c code. Mainly, allow printing programs in either ARB, NV or "debug" formats. --- src/mesa/shader/prog_print.c | 352 ++++++++++++++++++++++++++++++++++++++----- src/mesa/shader/prog_print.h | 24 ++- src/mesa/swrast/s_fragprog.c | 3 +- src/mesa/tnl/t_vp_build.c | 2 +- 4 files changed, 336 insertions(+), 45 deletions(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c index 0adb589daa..647ade9505 100644 --- a/src/mesa/shader/prog_print.c +++ b/src/mesa/shader/prog_print.c @@ -37,11 +37,12 @@ #include "prog_statevars.h" + /** * Return string name for given program/register file. */ static const char * -program_file_string(enum register_file f) +file_string(enum register_file f, gl_prog_print_mode mode) { switch (f) { case PROGRAM_TEMPORARY: @@ -76,6 +77,213 @@ program_file_string(enum register_file f) } +/** + * Return ARB_v/f_prog-style input attrib string. + */ +static const char * +arb_input_attrib_string(GLint index, GLenum progType) +{ + const char *vertAttribs[] = { + "vertex.position", + "vertex.weight", + "vertex.normal", + "vertex.color.primary", + "vertex.color.secondary", + "vertex.fogcoord", + "vertex.(six)", + "vertex.(seven)", + "vertex.texcoord[0]", + "vertex.texcoord[1]", + "vertex.texcoord[2]", + "vertex.texcoord[3]", + "vertex.texcoord[4]", + "vertex.texcoord[5]", + "vertex.texcoord[6]", + "vertex.texcoord[7]" + }; + const char *fragAttribs[] = { + "fragment.position", + "fragment.color.primary", + "fragment.color.secondary", + "fragment.fogcoord", + "fragment.texcoord[0]", + "fragment.texcoord[1]", + "fragment.texcoord[2]", + "fragment.texcoord[3]", + "fragment.texcoord[4]", + "fragment.texcoord[5]", + "fragment.texcoord[6]", + "fragment.texcoord[7]", + "fragment.varying[0]", + "fragment.varying[1]", + "fragment.varying[2]", + "fragment.varying[3]", + "fragment.varying[4]", + "fragment.varying[5]", + "fragment.varying[6]", + "fragment.varying[7]" + }; + + if (progType == GL_VERTEX_PROGRAM_ARB) { + assert(index < sizeof(vertAttribs) / sizeof(vertAttribs[0])); + return vertAttribs[index]; + } + else { + assert(index < sizeof(fragAttribs) / sizeof(fragAttribs[0])); + return fragAttribs[index]; + } +} + + +/** + * Return ARB_v/f_prog-style output attrib string. + */ +static const char * +arb_output_attrib_string(GLint index, GLenum progType) +{ + const char *vertResults[] = { + "result.position", + "result.color.primary", + "result.color.secondary", + "result.fogcoord", + "result.texcoord[0]", + "result.texcoord[1]", + "result.texcoord[2]", + "result.texcoord[3]", + "result.texcoord[4]", + "result.texcoord[5]", + "result.texcoord[6]", + "result.texcoord[7]", + "result.varying[0]", + "result.varying[1]", + "result.varying[2]", + "result.varying[3]", + "result.varying[4]", + "result.varying[5]", + "result.varying[6]", + "result.varying[7]" + }; + const char *fragResults[] = { + "result.color", + "result.depth" + }; + + if (progType == GL_VERTEX_PROGRAM_ARB) { + assert(index < sizeof(vertResults) / sizeof(vertResults[0])); + return vertResults[index]; + } + else { + assert(index < sizeof(fragResults) / sizeof(fragResults[0])); + return fragResults[index]; + } +} + + +/** + * Return string representation of the given register. + * Note that some types of registers (like PROGRAM_UNIFORM) aren't defined + * by the ARB/NV program languages so we've taken some liberties here. + * \param file the register file (PROGRAM_INPUT, PROGRAM_TEMPORARY, etc) + * \param index number of the register in the register file + * \param mode the output format/mode/style + * \param prog pointer to containing program + */ +static const char * +reg_string(enum register_file f, GLint index, gl_prog_print_mode mode, + const struct gl_program *prog) +{ + static char str[100]; + + str[0] = 0; + + switch (mode) { + case PROG_PRINT_DEBUG: + sprintf(str, "%s[%d]", file_string(f, mode), index); + break; + + case PROG_PRINT_ARB: + switch (f) { + case PROGRAM_INPUT: + sprintf(str, "%s", arb_input_attrib_string(index, prog->Target)); + break; + case PROGRAM_OUTPUT: + sprintf(str, "%s", arb_output_attrib_string(index, prog->Target)); + break; + case PROGRAM_TEMPORARY: + sprintf(str, "temp%d", index); + break; + case PROGRAM_ENV_PARAM: + sprintf(str, "program.env[%d]", index); + break; + case PROGRAM_LOCAL_PARAM: + sprintf(str, "program.local[%d]", index); + break; + case PROGRAM_VARYING: /* extension */ + sprintf(str, "varying[%d]", index); + break; + case PROGRAM_CONSTANT: /* extension */ + sprintf(str, "constant[%d]", index); + break; + case PROGRAM_UNIFORM: /* extension */ + sprintf(str, "uniform[%d]", index); + break; + case PROGRAM_STATE_VAR: + { + struct gl_program_parameter *param + = prog->Parameters->Parameters + index; + sprintf(str, _mesa_program_state_string(param->StateIndexes)); + } + break; + case PROGRAM_ADDRESS: + sprintf(str, "A%d", index); + break; + default: + _mesa_problem(NULL, "bad file in reg_string()"); + } + break; + + case PROG_PRINT_NV: + switch (f) { + case PROGRAM_INPUT: + if (prog->Target == GL_VERTEX_PROGRAM_ARB) + sprintf(str, "v[%d]", index); + else + sprintf(str, "f[%d]", index); + break; + case PROGRAM_OUTPUT: + sprintf(str, "o[%d]", index); + break; + case PROGRAM_TEMPORARY: + sprintf(str, "R%d", index); + break; + case PROGRAM_ENV_PARAM: + sprintf(str, "c[%d]", index); + break; + case PROGRAM_VARYING: /* extension */ + sprintf(str, "varying[%d]", index); + break; + case PROGRAM_UNIFORM: /* extension */ + sprintf(str, "uniform[%d]", index); + break; + case PROGRAM_CONSTANT: /* extension */ + sprintf(str, "constant[%d]", index); + break; + case PROGRAM_STATE_VAR: /* extension */ + sprintf(str, "state[%d]", index); + break; + default: + _mesa_problem(NULL, "bad file in reg_string()"); + } + break; + + default: + _mesa_problem(NULL, "bad mode in reg_string()"); + } + + return str; +} + + /** * Return a string representation of the given swizzle word. * If extended is true, use extended (comma-separated) format. @@ -172,22 +380,38 @@ condcode_string(GLuint condcode) static void -print_dst_reg(const struct prog_dst_register *dstReg) +print_dst_reg(const struct prog_dst_register *dstReg, gl_prog_print_mode mode, + const struct gl_program *prog) { - _mesa_printf(" %s[%d]%s", - program_file_string((enum register_file) dstReg->File), + _mesa_printf("%s%s", + reg_string((enum register_file) dstReg->File, + dstReg->Index, mode, prog), + writemask_string(dstReg->WriteMask)); + +#if 0 + _mesa_printf("%s[%d]%s", + file_string((enum register_file) dstReg->File, mode), dstReg->Index, writemask_string(dstReg->WriteMask)); +#endif } static void -print_src_reg(const struct prog_src_register *srcReg) +print_src_reg(const struct prog_src_register *srcReg, gl_prog_print_mode mode, + const struct gl_program *prog) { + _mesa_printf("%s%s", + reg_string((enum register_file) srcReg->File, + srcReg->Index, mode, prog), + swizzle_string(srcReg->Swizzle, + srcReg->NegateBase, GL_FALSE)); +#if 0 _mesa_printf("%s[%d]%s", - program_file_string((enum register_file) srcReg->File), + file_string((enum register_file) srcReg->File, mode), srcReg->Index, swizzle_string(srcReg->Swizzle, srcReg->NegateBase, GL_FALSE)); +#endif } static void @@ -200,10 +424,11 @@ print_comment(const struct prog_instruction *inst) } -void -_mesa_print_alu_instruction(const struct prog_instruction *inst, - const char *opcode_string, - GLuint numRegs) +static void +print_alu_instruction(const struct prog_instruction *inst, + const char *opcode_string, GLuint numRegs, + gl_prog_print_mode mode, + const struct gl_program *prog) { GLuint j; @@ -215,8 +440,9 @@ _mesa_print_alu_instruction(const struct prog_instruction *inst, if (inst->SaturateMode == SATURATE_ZERO_ONE) _mesa_printf("_SAT"); + _mesa_printf(" "); if (inst->DstReg.File != PROGRAM_UNDEFINED) { - print_dst_reg(&inst->DstReg); + print_dst_reg(&inst->DstReg, mode, prog); } else { _mesa_printf(" ???"); @@ -226,7 +452,7 @@ _mesa_print_alu_instruction(const struct prog_instruction *inst, _mesa_printf(", "); for (j = 0; j < numRegs; j++) { - print_src_reg(inst->SrcReg + j); + print_src_reg(inst->SrcReg + j, mode, prog); if (j + 1 < numRegs) _mesa_printf(", "); } @@ -235,11 +461,21 @@ _mesa_print_alu_instruction(const struct prog_instruction *inst, } +void +_mesa_print_instruction(const struct prog_instruction *inst) +{ + /* note: 4th param should be ignored for PROG_PRINT_DEBUG */ + _mesa_print_instruction_opt(inst, 0, PROG_PRINT_DEBUG, NULL); +} + + /** * Print a single vertex/fragment program instruction. */ GLint -_mesa_print_instruction(const struct prog_instruction *inst, GLint indent) +_mesa_print_instruction_opt(const struct prog_instruction *inst, GLint indent, + gl_prog_print_mode mode, + const struct gl_program *prog) { GLuint i; @@ -260,7 +496,8 @@ _mesa_print_instruction(const struct prog_instruction *inst, GLint indent) if (inst->SrcReg[0].File != PROGRAM_UNDEFINED) { _mesa_printf(", "); _mesa_printf("%s[%d]%s", - program_file_string((enum register_file) inst->SrcReg[0].File), + file_string((enum register_file) inst->SrcReg[0].File, + mode), inst->SrcReg[0].Index, swizzle_string(inst->SrcReg[0].Swizzle, inst->SrcReg[0].NegateBase, GL_FALSE)); @@ -273,9 +510,11 @@ _mesa_print_instruction(const struct prog_instruction *inst, GLint indent) _mesa_printf("SWZ"); if (inst->SaturateMode == SATURATE_ZERO_ONE) _mesa_printf("_SAT"); - print_dst_reg(&inst->DstReg); + _mesa_printf(" "); + print_dst_reg(&inst->DstReg, mode, prog); _mesa_printf("%s[%d], %s", - program_file_string((enum register_file) inst->SrcReg[0].File), + file_string((enum register_file) inst->SrcReg[0].File, + mode), inst->SrcReg[0].Index, swizzle_string(inst->SrcReg[0].Swizzle, inst->SrcReg[0].NegateBase, GL_TRUE)); @@ -287,9 +526,10 @@ _mesa_print_instruction(const struct prog_instruction *inst, GLint indent) _mesa_printf("%s", _mesa_opcode_string(inst->Opcode)); if (inst->SaturateMode == SATURATE_ZERO_ONE) _mesa_printf("_SAT"); - print_dst_reg(&inst->DstReg); + _mesa_printf(" "); + print_dst_reg(&inst->DstReg, mode, prog); _mesa_printf(", "); - print_src_reg(&inst->SrcReg[0]); + print_src_reg(&inst->SrcReg[0], mode, prog); _mesa_printf(", texture[%d], ", inst->TexSrcUnit); switch (inst->TexSrcTarget) { case TEXTURE_1D_INDEX: _mesa_printf("1D"); break; @@ -304,7 +544,7 @@ _mesa_print_instruction(const struct prog_instruction *inst, GLint indent) break; case OPCODE_ARL: _mesa_printf("ARL addr.x, "); - print_src_reg(&inst->SrcReg[0]); + print_src_reg(&inst->SrcReg[0], mode, prog); print_comment(inst); break; case OPCODE_BRA: @@ -319,49 +559,48 @@ _mesa_print_instruction(const struct prog_instruction *inst, GLint indent) print_comment(inst); break; case OPCODE_IF: - _mesa_printf("IF (%s%s) (if false, goto %d)", + _mesa_printf("IF (%s%s); # (if false, goto %d)", condcode_string(inst->DstReg.CondMask), swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE), inst->BranchTarget); print_comment(inst); return indent + 3; case OPCODE_ELSE: - _mesa_printf("ELSE (goto %d)\n", inst->BranchTarget); + _mesa_printf("ELSE; # (goto %d)\n", inst->BranchTarget); return indent + 3; case OPCODE_ENDIF: - _mesa_printf("ENDIF\n"); + _mesa_printf("ENDIF;\n"); break; case OPCODE_BGNLOOP: - _mesa_printf("BGNLOOP (end at %d)\n", inst->BranchTarget); + _mesa_printf("BGNLOOP; # (end at %d)\n", inst->BranchTarget); return indent + 3; case OPCODE_ENDLOOP: - _mesa_printf("ENDLOOP (goto %d)\n", inst->BranchTarget); + _mesa_printf("ENDLOOP; # (goto %d)\n", inst->BranchTarget); break; case OPCODE_BRK: - _mesa_printf("BRK (%s%s) (goto %d)", + _mesa_printf("BRK (%s%s); #(goto %d)", condcode_string(inst->DstReg.CondMask), swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE), inst->BranchTarget); print_comment(inst); break; case OPCODE_CONT: - _mesa_printf("CONT (%s%s) (goto %d)", + _mesa_printf("CONT (%s%s); #(goto %d)", condcode_string(inst->DstReg.CondMask), swizzle_string(inst->DstReg.CondSwizzle, 0, GL_FALSE), inst->BranchTarget); print_comment(inst); break; case OPCODE_BGNSUB: - _mesa_printf("SUB;\n"); + _mesa_printf("SUB"); print_comment(inst); return indent + 3; case OPCODE_ENDSUB: - _mesa_printf("ENDSUB;\n"); + _mesa_printf("ENDSUB"); print_comment(inst); break; case OPCODE_END: - _mesa_printf("END"); - print_comment(inst); + _mesa_printf("END\n"); break; case OPCODE_NOP: _mesa_printf("NOP"); @@ -370,9 +609,10 @@ _mesa_print_instruction(const struct prog_instruction *inst, GLint indent) /* 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)); + print_alu_instruction(inst, + _mesa_opcode_string(inst->Opcode), + _mesa_num_inst_src_regs(inst->Opcode), + mode, prog); break; } return indent; @@ -380,16 +620,50 @@ _mesa_print_instruction(const struct prog_instruction *inst, GLint indent) /** - * Print a vertx/fragment program to stdout. - * XXX this function could be greatly improved. + * Print program to stdout, default options. */ void _mesa_print_program(const struct gl_program *prog) +{ + _mesa_print_program_opt(prog, PROG_PRINT_ARB, GL_TRUE); +} + + +/** + * Print program, with options. + */ +void +_mesa_print_program_opt(const struct gl_program *prog, + gl_prog_print_mode mode, + GLboolean lineNumbers) { GLuint i, indent = 0; + + switch (prog->Target) { + case GL_VERTEX_PROGRAM_ARB: + if (mode == PROG_PRINT_ARB) + _mesa_printf("!!ARBvp1.0\n"); + else if (mode == PROG_PRINT_NV) + _mesa_printf("!!VP1.0\n"); + else + _mesa_printf("# Vertex Program/Shader\n"); + break; + case GL_FRAGMENT_PROGRAM_ARB: + case GL_FRAGMENT_PROGRAM_NV: + if (mode == PROG_PRINT_ARB) + _mesa_printf("!!ARBfp1.0\n"); + else if (mode == PROG_PRINT_NV) + _mesa_printf("!!FP1.0\n"); + else + _mesa_printf("# Fragment Program/Shader\n"); + break; + } + for (i = 0; i < prog->NumInstructions; i++) { - _mesa_printf("%3d: ", i); - indent = _mesa_print_instruction(prog->Instructions + i, indent); + if (lineNumbers) + _mesa_printf("%3d: ", i); + indent = _mesa_print_instruction_opt(prog->Instructions + i, + indent, mode, prog); } } @@ -424,14 +698,16 @@ _mesa_print_program_parameters(GLcontext *ctx, const struct gl_program *prog) void _mesa_print_parameter_list(const struct gl_program_parameter_list *list) { + const gl_prog_print_mode mode = PROG_PRINT_DEBUG; GLuint i; + _mesa_printf("param list %p\n", (void *) list); for (i = 0; i < list->NumParameters; i++){ struct gl_program_parameter *param = list->Parameters + i; const GLfloat *v = list->ParameterValues[i]; _mesa_printf("param[%d] sz=%d %s %s = {%.3g, %.3g, %.3g, %.3g};\n", i, param->Size, - program_file_string(list->Parameters[i].Type), + file_string(list->Parameters[i].Type, mode), param->Name, v[0], v[1], v[2], v[3]); } } diff --git a/src/mesa/shader/prog_print.h b/src/mesa/shader/prog_print.h index 19aaa53800..79c599f5a7 100644 --- a/src/mesa/shader/prog_print.h +++ b/src/mesa/shader/prog_print.h @@ -27,17 +27,31 @@ #define PROG_PRINT_H -extern GLint -_mesa_print_instruction(const struct prog_instruction *inst, GLint indent); +/** + * The output style to use when printing programs. + */ +typedef enum { + PROG_PRINT_ARB, + PROG_PRINT_NV, + PROG_PRINT_DEBUG +} gl_prog_print_mode; + extern void -_mesa_print_alu_instruction(const struct prog_instruction *inst, - const char *opcode_string, - GLuint numRegs); +_mesa_print_instruction(const struct prog_instruction *inst); + +extern GLint +_mesa_print_instruction_opt(const struct prog_instruction *inst, GLint indent, + gl_prog_print_mode mode, + const struct gl_program *prog); extern void _mesa_print_program(const struct gl_program *prog); +extern void +_mesa_print_program_opt(const struct gl_program *prog, gl_prog_print_mode mode, + GLboolean lineNumbers); + extern void _mesa_print_program_parameters(GLcontext *ctx, const struct gl_program *prog); diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c index fe41c0b5f4..89907f73c6 100644 --- a/src/mesa/swrast/s_fragprog.c +++ b/src/mesa/swrast/s_fragprog.c @@ -554,6 +554,7 @@ init_machine_deriv( GLcontext *ctx, _mesa_memcpy(dMachine, machine, sizeof(struct fp_machine)); if (program->Base.Target == GL_FRAGMENT_PROGRAM_NV) { + /* XXX also need to do this when using valgrind */ /* Clear temporary registers (undefined for ARB_f_p) */ _mesa_bzero( (void*) machine->Temporaries, MAX_NV_FRAGMENT_PROGRAM_TEMPS * 4 * sizeof(GLfloat)); @@ -665,7 +666,7 @@ execute_program( GLcontext *ctx, } if (DEBUG_FRAG) { - _mesa_print_instruction(inst, 0); + _mesa_print_instruction(inst); } switch (inst->Opcode) { diff --git a/src/mesa/tnl/t_vp_build.c b/src/mesa/tnl/t_vp_build.c index 6fb14e7caa..47fed32904 100644 --- a/src/mesa/tnl/t_vp_build.c +++ b/src/mesa/tnl/t_vp_build.c @@ -497,7 +497,7 @@ static void debug_insn( struct prog_instruction *inst, const char *fn, } _mesa_printf("%d:\t", line); - _mesa_print_instruction(inst, 0); + _mesa_print_instruction(inst); } } -- cgit v1.2.3 From 3ed1acd13c7876288a5d1ab6d288b1654f0c2e6d Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 22 Feb 2007 14:57:40 -0700 Subject: use MAX_PROGRAM_ENV_PARAMS --- src/mesa/swrast/s_fragprog.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c index 89907f73c6..a41b3ce125 100644 --- a/src/mesa/swrast/s_fragprog.c +++ b/src/mesa/swrast/s_fragprog.c @@ -172,7 +172,7 @@ get_register_pointer( GLcontext *ctx, ASSERT(source->Index < MAX_PROGRAM_LOCAL_PARAMS); return program->Base.LocalParams[source->Index]; case PROGRAM_ENV_PARAM: - ASSERT(source->Index < MAX_NV_FRAGMENT_PROGRAM_PARAMS); + ASSERT(source->Index < MAX_PROGRAM_ENV_PARAMS); return ctx->FragmentProgram.Parameters[source->Index]; case PROGRAM_STATE_VAR: /* Fallthrough */ @@ -557,7 +557,7 @@ init_machine_deriv( GLcontext *ctx, /* XXX also need to do this when using valgrind */ /* Clear temporary registers (undefined for ARB_f_p) */ _mesa_bzero( (void*) machine->Temporaries, - MAX_NV_FRAGMENT_PROGRAM_TEMPS * 4 * sizeof(GLfloat)); + MAX_PROGRAM_TEMPS * 4 * sizeof(GLfloat)); } /* Add derivatives */ @@ -1611,7 +1611,7 @@ init_machine( GLcontext *ctx, struct fp_machine *machine, if (program->Base.Target == GL_FRAGMENT_PROGRAM_NV) { /* Clear temporary registers (undefined for ARB_f_p) */ _mesa_bzero(machine->Temporaries, - MAX_NV_FRAGMENT_PROGRAM_TEMPS * 4 * sizeof(GLfloat)); + MAX_PROGRAM_TEMPS * 4 * sizeof(GLfloat)); } /* Setup pointer to input attributes */ -- cgit v1.2.3 From f6803de7396edda2223adf7ff7445579dbe475c9 Mon Sep 17 00:00:00 2001 From: Brian Date: Thu, 22 Feb 2007 16:08:01 -0700 Subject: Use the new unified vertex/fragment program interpreter from prog_execute.c. Currently, DDX, DDY don't work. --- src/mesa/swrast/s_fragprog.c | 1523 +----------------------------------------- 1 file changed, 12 insertions(+), 1511 deletions(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c index a41b3ce125..4482006ba6 100644 --- a/src/mesa/swrast/s_fragprog.c +++ b/src/mesa/swrast/s_fragprog.c @@ -25,6 +25,7 @@ #include "glheader.h" #include "colormac.h" #include "context.h" +#include "prog_execute.h" #include "prog_instruction.h" #include "prog_parameter.h" #include "prog_print.h" @@ -35,63 +36,6 @@ #include "slang_library_noise.h" -/* See comments below for info about this */ -#define LAMBDA_ZERO 1 - -/* debug predicate */ -#define DEBUG_FRAG 0 - - -/** - * Virtual machine state used during execution of a fragment programs. - */ -struct fp_machine -{ - /** Fragment Input attributes */ - GLfloat (*Attribs)[MAX_WIDTH][4]; - GLuint CurFrag; /**< Index into Attribs arrays */ - - GLfloat Temporaries[MAX_PROGRAM_TEMPS][4]; - GLfloat Outputs[FRAG_RESULT_MAX][4]; - GLuint CondCodes[4]; /**< COND_* value for x/y/z/w */ - - GLuint CallStack[MAX_PROGRAM_CALL_DEPTH]; /**< For CAL/RET instructions */ - GLuint StackDepth; /**< Index/ptr to top of CallStack[] */ -}; - - -#if FEATURE_MESA_program_debug -static struct fp_machine *CurrentMachine = NULL; - -/** - * For GL_MESA_program_debug. - * Return current value (4*GLfloat) of a fragment program register. - * Called via ctx->Driver.GetFragmentProgramRegister(). - */ -void -_swrast_get_program_register(GLcontext *ctx, enum register_file file, - GLuint index, GLfloat val[4]) -{ - if (CurrentMachine) { - switch (file) { - case PROGRAM_INPUT: - COPY_4V(val, CurrentMachine->Attribs[index][CurrentMachine->CurFrag]); - break; - case PROGRAM_OUTPUT: - COPY_4V(val, CurrentMachine->Outputs[index]); - break; - case PROGRAM_TEMPORARY: - COPY_4V(val, CurrentMachine->Temporaries[index]); - break; - default: - _mesa_problem(NULL, - "bad register file in _swrast_get_program_register"); - } - } -} -#endif /* FEATURE_MESA_program_debug */ - - /** * Fetch a texel. */ @@ -146,1449 +90,6 @@ fetch_texel_deriv( GLcontext *ctx, const GLfloat texcoord[4], } -/** - * Return a pointer to the 4-element float vector specified by the given - * source register. - */ -static INLINE const GLfloat * -get_register_pointer( GLcontext *ctx, - const struct prog_src_register *source, - const struct fp_machine *machine, - const struct gl_fragment_program *program ) -{ - /* XXX relative addressing... */ - switch (source->File) { - case PROGRAM_TEMPORARY: - ASSERT(source->Index < MAX_PROGRAM_TEMPS); - return machine->Temporaries[source->Index]; - case PROGRAM_INPUT: - ASSERT(source->Index < FRAG_ATTRIB_MAX); - return machine->Attribs[source->Index][machine->CurFrag]; - case PROGRAM_OUTPUT: - /* This is only for PRINT */ - ASSERT(source->Index < FRAG_RESULT_MAX); - return machine->Outputs[source->Index]; - case PROGRAM_LOCAL_PARAM: - ASSERT(source->Index < MAX_PROGRAM_LOCAL_PARAMS); - return program->Base.LocalParams[source->Index]; - case PROGRAM_ENV_PARAM: - ASSERT(source->Index < MAX_PROGRAM_ENV_PARAMS); - return ctx->FragmentProgram.Parameters[source->Index]; - case PROGRAM_STATE_VAR: - /* Fallthrough */ - case PROGRAM_CONSTANT: - /* Fallthrough */ - case PROGRAM_UNIFORM: - /* Fallthrough */ - case PROGRAM_NAMED_PARAM: - ASSERT(source->Index < (GLint) program->Base.Parameters->NumParameters); - return program->Base.Parameters->ParameterValues[source->Index]; - default: - _mesa_problem(ctx, "Invalid input register file %d in fp " - "get_register_pointer", source->File); - return NULL; - } -} - - -/** - * Fetch a 4-element float vector from the given source register. - * Apply swizzling and negating as needed. - */ -static void -fetch_vector4( GLcontext *ctx, - const struct prog_src_register *source, - const struct fp_machine *machine, - const struct gl_fragment_program *program, - GLfloat result[4] ) -{ - const GLfloat *src = get_register_pointer(ctx, source, machine, program); - ASSERT(src); - - if (source->Swizzle == SWIZZLE_NOOP) { - /* no swizzling */ - COPY_4V(result, src); - } - else { - ASSERT(GET_SWZ(source->Swizzle, 0) <= 3); - ASSERT(GET_SWZ(source->Swizzle, 1) <= 3); - ASSERT(GET_SWZ(source->Swizzle, 2) <= 3); - ASSERT(GET_SWZ(source->Swizzle, 3) <= 3); - result[0] = src[GET_SWZ(source->Swizzle, 0)]; - result[1] = src[GET_SWZ(source->Swizzle, 1)]; - result[2] = src[GET_SWZ(source->Swizzle, 2)]; - result[3] = src[GET_SWZ(source->Swizzle, 3)]; - } - - if (source->NegateBase) { - result[0] = -result[0]; - result[1] = -result[1]; - result[2] = -result[2]; - result[3] = -result[3]; - } - if (source->Abs) { - result[0] = FABSF(result[0]); - result[1] = FABSF(result[1]); - result[2] = FABSF(result[2]); - result[3] = FABSF(result[3]); - } - if (source->NegateAbs) { - result[0] = -result[0]; - result[1] = -result[1]; - result[2] = -result[2]; - result[3] = -result[3]; - } -} - - -/** - * Fetch the derivative with respect to X for the given register. - * \return GL_TRUE if it was easily computed or GL_FALSE if we - * need to execute another instance of the program (ugh)! - */ -static GLboolean -fetch_vector4_deriv( GLcontext *ctx, - const struct prog_src_register *source, - const SWspan *span, - char xOrY, GLint column, GLfloat result[4] ) -{ - GLfloat src[4]; - - ASSERT(xOrY == 'X' || xOrY == 'Y'); - - switch (source->Index) { - case FRAG_ATTRIB_WPOS: - if (xOrY == 'X') { - src[0] = 1.0; - src[1] = 0.0; - src[2] = span->attrStepX[FRAG_ATTRIB_WPOS][2] - / ctx->DrawBuffer->_DepthMaxF; - src[3] = span->attrStepX[FRAG_ATTRIB_WPOS][3]; - } - else { - src[0] = 0.0; - src[1] = 1.0; - src[2] = span->attrStepY[FRAG_ATTRIB_WPOS][2] - / ctx->DrawBuffer->_DepthMaxF; - src[3] = span->attrStepY[FRAG_ATTRIB_WPOS][3]; - } - break; - case FRAG_ATTRIB_COL0: - case FRAG_ATTRIB_COL1: - if (xOrY == 'X') { - src[0] = span->attrStepX[source->Index][0] * (1.0F / CHAN_MAXF); - src[1] = span->attrStepX[source->Index][1] * (1.0F / CHAN_MAXF); - src[2] = span->attrStepX[source->Index][2] * (1.0F / CHAN_MAXF); - src[3] = span->attrStepX[source->Index][3] * (1.0F / CHAN_MAXF); - } - else { - src[0] = span->attrStepY[source->Index][0] * (1.0F / CHAN_MAXF); - src[1] = span->attrStepY[source->Index][1] * (1.0F / CHAN_MAXF); - src[2] = span->attrStepY[source->Index][2] * (1.0F / CHAN_MAXF); - src[3] = span->attrStepY[source->Index][3] * (1.0F / CHAN_MAXF); - } - break; - case FRAG_ATTRIB_FOGC: - if (xOrY == 'X') { - src[0] = span->attrStepX[FRAG_ATTRIB_FOGC][0] * (1.0F / CHAN_MAXF); - src[1] = 0.0; - src[2] = 0.0; - src[3] = 0.0; - } - else { - src[0] = span->attrStepY[FRAG_ATTRIB_FOGC][0] * (1.0F / CHAN_MAXF); - src[1] = 0.0; - src[2] = 0.0; - src[3] = 0.0; - } - break; - default: - assert(source->Index < FRAG_ATTRIB_MAX); - /* texcoord or varying */ - if (xOrY == 'X') { - /* this is a little tricky - I think I've got it right */ - const GLfloat invQ = 1.0f / (span->attrStart[source->Index][3] - + span->attrStepX[source->Index][3] * column); - src[0] = span->attrStepX[source->Index][0] * invQ; - src[1] = span->attrStepX[source->Index][1] * invQ; - src[2] = span->attrStepX[source->Index][2] * invQ; - src[3] = span->attrStepX[source->Index][3] * invQ; - } - else { - /* Tricky, as above, but in Y direction */ - const GLfloat invQ = 1.0f / (span->attrStart[source->Index][3] - + span->attrStepY[source->Index][3]); - src[0] = span->attrStepY[source->Index][0] * invQ; - src[1] = span->attrStepY[source->Index][1] * invQ; - src[2] = span->attrStepY[source->Index][2] * invQ; - src[3] = span->attrStepY[source->Index][3] * invQ; - } - break; - } - - result[0] = src[GET_SWZ(source->Swizzle, 0)]; - result[1] = src[GET_SWZ(source->Swizzle, 1)]; - result[2] = src[GET_SWZ(source->Swizzle, 2)]; - result[3] = src[GET_SWZ(source->Swizzle, 3)]; - - if (source->NegateBase) { - result[0] = -result[0]; - result[1] = -result[1]; - result[2] = -result[2]; - result[3] = -result[3]; - } - if (source->Abs) { - result[0] = FABSF(result[0]); - result[1] = FABSF(result[1]); - result[2] = FABSF(result[2]); - result[3] = FABSF(result[3]); - } - if (source->NegateAbs) { - result[0] = -result[0]; - result[1] = -result[1]; - result[2] = -result[2]; - result[3] = -result[3]; - } - return GL_TRUE; -} - - -/** - * As above, but only return result[0] element. - */ -static void -fetch_vector1( GLcontext *ctx, - const struct prog_src_register *source, - const struct fp_machine *machine, - const struct gl_fragment_program *program, - GLfloat result[4] ) -{ - const GLfloat *src = get_register_pointer(ctx, source, machine, program); - ASSERT(src); - - result[0] = src[GET_SWZ(source->Swizzle, 0)]; - - if (source->NegateBase) { - result[0] = -result[0]; - } - if (source->Abs) { - result[0] = FABSF(result[0]); - } - if (source->NegateAbs) { - result[0] = -result[0]; - } -} - - -/** - * Test value against zero and return GT, LT, EQ or UN if NaN. - */ -static INLINE GLuint -generate_cc( float value ) -{ - if (value != value) - return COND_UN; /* NaN */ - if (value > 0.0F) - return COND_GT; - if (value < 0.0F) - return COND_LT; - return COND_EQ; -} - - -/** - * Test if the ccMaskRule is satisfied by the given condition code. - * Used to mask destination writes according to the current condition code. - */ -static INLINE GLboolean -test_cc(GLuint condCode, GLuint ccMaskRule) -{ - switch (ccMaskRule) { - case COND_EQ: return (condCode == COND_EQ); - case COND_NE: return (condCode != COND_EQ); - case COND_LT: return (condCode == COND_LT); - case COND_GE: return (condCode == COND_GT || condCode == COND_EQ); - case COND_LE: return (condCode == COND_LT || condCode == COND_EQ); - case COND_GT: return (condCode == COND_GT); - case COND_TR: return GL_TRUE; - case COND_FL: return GL_FALSE; - default: return GL_TRUE; - } -} - - -/** - * Evaluate the 4 condition codes against a predicate and return GL_TRUE - * or GL_FALSE to indicate result. - */ -static INLINE GLboolean -eval_condition(const struct fp_machine *machine, - const struct prog_instruction *inst) -{ - const GLuint swizzle = inst->DstReg.CondSwizzle; - const GLuint condMask = inst->DstReg.CondMask; - if (test_cc(machine->CondCodes[GET_SWZ(swizzle, 0)], condMask) || - test_cc(machine->CondCodes[GET_SWZ(swizzle, 1)], condMask) || - test_cc(machine->CondCodes[GET_SWZ(swizzle, 2)], condMask) || - test_cc(machine->CondCodes[GET_SWZ(swizzle, 3)], condMask)) { - return GL_TRUE; - } - else { - return GL_FALSE; - } -} - - - -/** - * Store 4 floats into a register. Observe the instructions saturate and - * set-condition-code flags. - */ -static void -store_vector4( const struct prog_instruction *inst, - struct fp_machine *machine, - const GLfloat value[4] ) -{ - const struct prog_dst_register *dest = &(inst->DstReg); - const GLboolean clamp = inst->SaturateMode == SATURATE_ZERO_ONE; - GLfloat *dstReg; - GLfloat dummyReg[4]; - GLfloat clampedValue[4]; - GLuint writeMask = dest->WriteMask; - - switch (dest->File) { - case PROGRAM_OUTPUT: - dstReg = machine->Outputs[dest->Index]; - break; - case PROGRAM_TEMPORARY: - dstReg = machine->Temporaries[dest->Index]; - break; - case PROGRAM_WRITE_ONLY: - dstReg = dummyReg; - return; - default: - _mesa_problem(NULL, "bad register file in store_vector4(fp)"); - return; - } - -#if 0 - if (value[0] > 1.0e10 || - IS_INF_OR_NAN(value[0]) || - IS_INF_OR_NAN(value[1]) || - IS_INF_OR_NAN(value[2]) || - IS_INF_OR_NAN(value[3]) ) - printf("store %g %g %g %g\n", value[0], value[1], value[2], value[3]); -#endif - - if (clamp) { - clampedValue[0] = CLAMP(value[0], 0.0F, 1.0F); - clampedValue[1] = CLAMP(value[1], 0.0F, 1.0F); - clampedValue[2] = CLAMP(value[2], 0.0F, 1.0F); - clampedValue[3] = CLAMP(value[3], 0.0F, 1.0F); - value = clampedValue; - } - - if (dest->CondMask != COND_TR) { - /* condition codes may turn off some writes */ - if (writeMask & WRITEMASK_X) { - if (!test_cc(machine->CondCodes[GET_SWZ(dest->CondSwizzle, 0)], - dest->CondMask)) - writeMask &= ~WRITEMASK_X; - } - if (writeMask & WRITEMASK_Y) { - if (!test_cc(machine->CondCodes[GET_SWZ(dest->CondSwizzle, 1)], - dest->CondMask)) - writeMask &= ~WRITEMASK_Y; - } - if (writeMask & WRITEMASK_Z) { - if (!test_cc(machine->CondCodes[GET_SWZ(dest->CondSwizzle, 2)], - dest->CondMask)) - writeMask &= ~WRITEMASK_Z; - } - if (writeMask & WRITEMASK_W) { - if (!test_cc(machine->CondCodes[GET_SWZ(dest->CondSwizzle, 3)], - dest->CondMask)) - writeMask &= ~WRITEMASK_W; - } - } - - if (writeMask & WRITEMASK_X) - dstReg[0] = value[0]; - if (writeMask & WRITEMASK_Y) - dstReg[1] = value[1]; - if (writeMask & WRITEMASK_Z) - dstReg[2] = value[2]; - if (writeMask & WRITEMASK_W) - dstReg[3] = value[3]; - - if (inst->CondUpdate) { - if (writeMask & WRITEMASK_X) - machine->CondCodes[0] = generate_cc(value[0]); - if (writeMask & WRITEMASK_Y) - machine->CondCodes[1] = generate_cc(value[1]); - if (writeMask & WRITEMASK_Z) - machine->CondCodes[2] = generate_cc(value[2]); - if (writeMask & WRITEMASK_W) - machine->CondCodes[3] = generate_cc(value[3]); - } -} - - -/** - * Initialize a new machine state instance from an existing one, adding - * the partial derivatives onto the input registers. - * Used to implement DDX and DDY instructions in non-trivial cases. - */ -static void -init_machine_deriv( GLcontext *ctx, - const struct fp_machine *machine, - const struct gl_fragment_program *program, - const SWspan *span, char xOrY, - struct fp_machine *dMachine ) -{ - GLuint attr; - - ASSERT(xOrY == 'X' || xOrY == 'Y'); - - /* copy existing machine */ - _mesa_memcpy(dMachine, machine, sizeof(struct fp_machine)); - - if (program->Base.Target == GL_FRAGMENT_PROGRAM_NV) { - /* XXX also need to do this when using valgrind */ - /* Clear temporary registers (undefined for ARB_f_p) */ - _mesa_bzero( (void*) machine->Temporaries, - MAX_PROGRAM_TEMPS * 4 * sizeof(GLfloat)); - } - - /* Add derivatives */ - if (program->Base.InputsRead & FRAG_BIT_WPOS) { - GLfloat *wpos = machine->Attribs[FRAG_ATTRIB_WPOS][machine->CurFrag]; - if (xOrY == 'X') { - wpos[0] += 1.0F; - wpos[1] += 0.0F; - wpos[2] += span->attrStepX[FRAG_ATTRIB_WPOS][2]; - wpos[3] += span->attrStepX[FRAG_ATTRIB_WPOS][3]; - } - else { - wpos[0] += 0.0F; - wpos[1] += 1.0F; - wpos[2] += span->attrStepY[FRAG_ATTRIB_WPOS][2]; - wpos[3] += span->attrStepY[FRAG_ATTRIB_WPOS][3]; - } - } - - /* primary, secondary colors */ - for (attr = FRAG_ATTRIB_COL0; attr <= FRAG_ATTRIB_COL1; attr++) { - if (program->Base.InputsRead & (1 << attr)) { - GLfloat *col = machine->Attribs[attr][machine->CurFrag]; - if (xOrY == 'X') { - col[0] += span->attrStepX[attr][0] * (1.0F / CHAN_MAXF); - col[1] += span->attrStepX[attr][1] * (1.0F / CHAN_MAXF); - col[2] += span->attrStepX[attr][2] * (1.0F / CHAN_MAXF); - col[3] += span->attrStepX[attr][3] * (1.0F / CHAN_MAXF); - } - else { - col[0] += span->attrStepY[attr][0] * (1.0F / CHAN_MAXF); - col[1] += span->attrStepY[attr][1] * (1.0F / CHAN_MAXF); - col[2] += span->attrStepY[attr][2] * (1.0F / CHAN_MAXF); - col[3] += span->attrStepY[attr][3] * (1.0F / CHAN_MAXF); - } - } - } - if (program->Base.InputsRead & FRAG_BIT_FOGC) { - GLfloat *fogc = machine->Attribs[FRAG_ATTRIB_FOGC][machine->CurFrag]; - if (xOrY == 'X') { - fogc[0] += span->attrStepX[FRAG_ATTRIB_FOGC][0]; - } - else { - fogc[0] += span->attrStepY[FRAG_ATTRIB_FOGC][0]; - } - } - /* texcoord and varying vars */ - for (attr = FRAG_ATTRIB_TEX0; attr < FRAG_ATTRIB_MAX; attr++) { - if (program->Base.InputsRead & (1 << attr)) { - GLfloat *val = machine->Attribs[attr][machine->CurFrag]; - /* XXX perspective-correct interpolation */ - if (xOrY == 'X') { - val[0] += span->attrStepX[attr][0]; - val[1] += span->attrStepX[attr][1]; - val[2] += span->attrStepX[attr][2]; - val[3] += span->attrStepX[attr][3]; - } - else { - val[0] += span->attrStepY[attr][0]; - val[1] += span->attrStepY[attr][1]; - val[2] += span->attrStepY[attr][2]; - val[3] += span->attrStepY[attr][3]; - } - } - } - - /* init condition codes */ - dMachine->CondCodes[0] = COND_EQ; - dMachine->CondCodes[1] = COND_EQ; - dMachine->CondCodes[2] = COND_EQ; - dMachine->CondCodes[3] = COND_EQ; -} - - -/** - * Execute the given vertex program. - * NOTE: we do everything in single-precision floating point; we don't - * currently observe the single/half/fixed-precision qualifiers. - * \param ctx - rendering context - * \param program - the fragment program to execute - * \param machine - machine state (register file) - * \param maxInst - max number of instructions to execute - * \return GL_TRUE if program completed or GL_FALSE if program executed KIL. - */ -static GLboolean -execute_program( GLcontext *ctx, - const struct gl_fragment_program *program, GLuint maxInst, - struct fp_machine *machine, const SWspan *span, - GLuint column ) -{ - const GLuint MAX_EXEC = 10000; - GLint pc, total = 0; - - if (DEBUG_FRAG) { - printf("execute fragment program --------------------\n"); - } - - for (pc = 0; pc < maxInst; pc++) { - const struct prog_instruction *inst = program->Base.Instructions + pc; - - if (ctx->FragmentProgram.CallbackEnabled && - ctx->FragmentProgram.Callback) { - ctx->FragmentProgram.CurrentPosition = inst->StringPos; - ctx->FragmentProgram.Callback(program->Base.Target, - ctx->FragmentProgram.CallbackData); - } - - if (DEBUG_FRAG) { - _mesa_print_instruction(inst); - } - - switch (inst->Opcode) { - case OPCODE_ABS: - { - GLfloat a[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - result[0] = FABSF(a[0]); - result[1] = FABSF(a[1]); - result[2] = FABSF(a[2]); - result[3] = FABSF(a[3]); - store_vector4( inst, machine, result ); - } - break; - case OPCODE_ADD: - { - GLfloat a[4], b[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - result[0] = a[0] + b[0]; - result[1] = a[1] + b[1]; - result[2] = a[2] + b[2]; - result[3] = a[3] + b[3]; - store_vector4( inst, machine, result ); - if (DEBUG_FRAG) { - printf("ADD (%g %g %g %g) = (%g %g %g %g) + (%g %g %g %g)\n", - result[0], result[1], result[2], result[3], - a[0], a[1], a[2], a[3], - b[0], b[1], b[2], b[3]); - } - } - break; - case OPCODE_BGNLOOP: - /* no-op */ - break; - case OPCODE_ENDLOOP: - /* subtract 1 here since pc is incremented by for(pc) loop */ - pc = inst->BranchTarget - 1; /* go to matching BNGLOOP */ - break; - case OPCODE_BGNSUB: /* begin subroutine */ - break; - case OPCODE_ENDSUB: /* end subroutine */ - break; - case OPCODE_BRA: /* branch (conditional) */ - /* fall-through */ - case OPCODE_BRK: /* break out of loop (conditional) */ - /* fall-through */ - case OPCODE_CONT: /* continue loop (conditional) */ - if (eval_condition(machine, inst)) { - /* take branch */ - /* Subtract 1 here since we'll do pc++ at end of for-loop */ - pc = inst->BranchTarget - 1; - } - break; - case OPCODE_CAL: /* Call subroutine (conditional) */ - if (eval_condition(machine, inst)) { - /* call the subroutine */ - if (machine->StackDepth >= MAX_PROGRAM_CALL_DEPTH) { - return GL_TRUE; /* Per GL_NV_vertex_program2 spec */ - } - machine->CallStack[machine->StackDepth++] = pc + 1; - pc = inst->BranchTarget; /* XXX - 1 ??? */ - } - break; - case OPCODE_CMP: - { - GLfloat a[4], b[4], c[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - fetch_vector4( ctx, &inst->SrcReg[2], machine, program, c ); - result[0] = a[0] < 0.0F ? b[0] : c[0]; - result[1] = a[1] < 0.0F ? b[1] : c[1]; - result[2] = a[2] < 0.0F ? b[2] : c[2]; - result[3] = a[3] < 0.0F ? b[3] : c[3]; - store_vector4( inst, machine, result ); - } - break; - case OPCODE_COS: - { - GLfloat a[4], result[4]; - fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); - result[0] = result[1] = result[2] = result[3] - = (GLfloat) _mesa_cos(a[0]); - store_vector4( inst, machine, result ); - } - break; - case OPCODE_DDX: /* Partial derivative with respect to X */ - { - GLfloat a[4], aNext[4], result[4]; - struct fp_machine dMachine; - if (!fetch_vector4_deriv(ctx, &inst->SrcReg[0], span, 'X', - column, result)) { - /* This is tricky. Make a copy of the current machine state, - * increment the input registers by the dx or dy partial - * derivatives, then re-execute the program up to the - * preceeding instruction, then fetch the source register. - * Finally, find the difference in the register values for - * the original and derivative runs. - */ - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a); - init_machine_deriv(ctx, machine, program, span, - 'X', &dMachine); - execute_program(ctx, program, pc, &dMachine, span, column); - fetch_vector4( ctx, &inst->SrcReg[0], &dMachine, program, aNext ); - result[0] = aNext[0] - a[0]; - result[1] = aNext[1] - a[1]; - result[2] = aNext[2] - a[2]; - result[3] = aNext[3] - a[3]; - } - store_vector4( inst, machine, result ); - } - break; - case OPCODE_DDY: /* Partial derivative with respect to Y */ - { - GLfloat a[4], aNext[4], result[4]; - struct fp_machine dMachine; - if (!fetch_vector4_deriv(ctx, &inst->SrcReg[0], span, 'Y', - column, result)) { - init_machine_deriv(ctx, machine, program, span, - 'Y', &dMachine); - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a); - execute_program(ctx, program, pc, &dMachine, span, column); - fetch_vector4( ctx, &inst->SrcReg[0], &dMachine, program, aNext ); - result[0] = aNext[0] - a[0]; - result[1] = aNext[1] - a[1]; - result[2] = aNext[2] - a[2]; - result[3] = aNext[3] - a[3]; - } - store_vector4( inst, machine, result ); - } - break; - case OPCODE_DP3: - { - GLfloat a[4], b[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - result[0] = result[1] = result[2] = result[3] = DOT3(a, b); - store_vector4( inst, machine, result ); - if (DEBUG_FRAG) { - printf("DP3 %g = (%g %g %g) . (%g %g %g)\n", - result[0], a[0], a[1], a[2], b[0], b[1], b[2]); - } - } - break; - case OPCODE_DP4: - { - GLfloat a[4], b[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - result[0] = result[1] = result[2] = result[3] = DOT4(a,b); - store_vector4( inst, machine, result ); - if (DEBUG_FRAG) { - printf("DP4 %g = (%g, %g %g %g) . (%g, %g %g %g)\n", - result[0], a[0], a[1], a[2], a[3], - b[0], b[1], b[2], b[3]); - } - } - break; - case OPCODE_DPH: - { - GLfloat a[4], b[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - result[0] = result[1] = result[2] = result[3] = - a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + b[3]; - store_vector4( inst, machine, result ); - } - break; - case OPCODE_DST: /* Distance vector */ - { - GLfloat a[4], b[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - result[0] = 1.0F; - result[1] = a[1] * b[1]; - result[2] = a[2]; - result[3] = b[3]; - store_vector4( inst, machine, result ); - } - break; - case OPCODE_EX2: /* Exponential base 2 */ - { - GLfloat a[4], result[4]; - fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); - result[0] = result[1] = result[2] = result[3] = - (GLfloat) _mesa_pow(2.0, a[0]); - store_vector4( inst, machine, result ); - } - break; - case OPCODE_FLR: - { - GLfloat a[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - result[0] = FLOORF(a[0]); - result[1] = FLOORF(a[1]); - result[2] = FLOORF(a[2]); - result[3] = FLOORF(a[3]); - store_vector4( inst, machine, result ); - } - break; - case OPCODE_FRC: - { - GLfloat a[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - result[0] = a[0] - FLOORF(a[0]); - result[1] = a[1] - FLOORF(a[1]); - result[2] = a[2] - FLOORF(a[2]); - result[3] = a[3] - FLOORF(a[3]); - store_vector4( inst, machine, result ); - } - break; - case OPCODE_IF: - if (eval_condition(machine, inst)) { - /* do if-clause (just continue execution) */ - } - else { - /* go to the instruction after ELSE or ENDIF */ - assert(inst->BranchTarget >= 0); - pc = inst->BranchTarget - 1; - } - break; - case OPCODE_ELSE: - /* goto ENDIF */ - assert(inst->BranchTarget >= 0); - pc = inst->BranchTarget - 1; - break; - case OPCODE_ENDIF: - /* nothing */ - break; - case OPCODE_INT: /* float to int */ - { - GLfloat a[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - result[0] = (GLfloat) (GLint) a[0]; - result[1] = (GLfloat) (GLint) a[1]; - result[2] = (GLfloat) (GLint) a[2]; - result[3] = (GLfloat) (GLint) a[3]; - store_vector4( inst, machine, result ); - } - break; - case OPCODE_KIL_NV: /* NV_f_p only (conditional) */ - if (eval_condition(machine, inst)) { - return GL_FALSE; - } - break; - case OPCODE_KIL: /* ARB_f_p only */ - { - GLfloat a[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - if (a[0] < 0.0F || a[1] < 0.0F || a[2] < 0.0F || a[3] < 0.0F) { - return GL_FALSE; - } - } - break; - case OPCODE_LG2: /* log base 2 */ - { - GLfloat a[4], result[4]; - fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); - result[0] = result[1] = result[2] = result[3] = LOG2(a[0]); - store_vector4( inst, machine, result ); - } - break; - case OPCODE_LIT: - { - const GLfloat epsilon = 1.0F / 256.0F; /* from NV VP spec */ - GLfloat a[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - a[0] = MAX2(a[0], 0.0F); - a[1] = MAX2(a[1], 0.0F); - /* XXX ARB version clamps a[3], NV version doesn't */ - a[3] = CLAMP(a[3], -(128.0F - epsilon), (128.0F - epsilon)); - result[0] = 1.0F; - result[1] = a[0]; - /* XXX we could probably just use pow() here */ - if (a[0] > 0.0F) { - if (a[1] == 0.0 && a[3] == 0.0) - result[2] = 1.0; - else - result[2] = EXPF(a[3] * LOGF(a[1])); - } - else { - result[2] = 0.0; - } - result[3] = 1.0F; - store_vector4( inst, machine, result ); - if (DEBUG_FRAG) { - printf("LIT (%g %g %g %g) : (%g %g %g %g)\n", - result[0], result[1], result[2], result[3], - a[0], a[1], a[2], a[3]); - } - } - break; - case OPCODE_LRP: - { - GLfloat a[4], b[4], c[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - fetch_vector4( ctx, &inst->SrcReg[2], machine, program, c ); - result[0] = a[0] * b[0] + (1.0F - a[0]) * c[0]; - result[1] = a[1] * b[1] + (1.0F - a[1]) * c[1]; - result[2] = a[2] * b[2] + (1.0F - a[2]) * c[2]; - result[3] = a[3] * b[3] + (1.0F - a[3]) * c[3]; - store_vector4( inst, machine, result ); - if (DEBUG_FRAG) { - printf("LRP (%g %g %g %g) = (%g %g %g %g), " - "(%g %g %g %g), (%g %g %g %g)\n", - result[0], result[1], result[2], result[3], - a[0], a[1], a[2], a[3], - b[0], b[1], b[2], b[3], - c[0], c[1], c[2], c[3]); - } - } - break; - case OPCODE_MAD: - { - GLfloat a[4], b[4], c[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - fetch_vector4( ctx, &inst->SrcReg[2], machine, program, c ); - result[0] = a[0] * b[0] + c[0]; - result[1] = a[1] * b[1] + c[1]; - result[2] = a[2] * b[2] + c[2]; - result[3] = a[3] * b[3] + c[3]; - store_vector4( inst, machine, result ); - if (DEBUG_FRAG) { - printf("MAD (%g %g %g %g) = (%g %g %g %g) * " - "(%g %g %g %g) + (%g %g %g %g)\n", - result[0], result[1], result[2], result[3], - a[0], a[1], a[2], a[3], - b[0], b[1], b[2], b[3], - c[0], c[1], c[2], c[3]); - } - } - break; - case OPCODE_MAX: - { - GLfloat a[4], b[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - result[0] = MAX2(a[0], b[0]); - result[1] = MAX2(a[1], b[1]); - result[2] = MAX2(a[2], b[2]); - result[3] = MAX2(a[3], b[3]); - store_vector4( inst, machine, result ); - if (DEBUG_FRAG) { - printf("MAX (%g %g %g %g) = (%g %g %g %g), (%g %g %g %g)\n", - result[0], result[1], result[2], result[3], - a[0], a[1], a[2], a[3], - b[0], b[1], b[2], b[3]); - } - } - break; - case OPCODE_MIN: - { - GLfloat a[4], b[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - result[0] = MIN2(a[0], b[0]); - result[1] = MIN2(a[1], b[1]); - result[2] = MIN2(a[2], b[2]); - result[3] = MIN2(a[3], b[3]); - store_vector4( inst, machine, result ); - } - break; - case OPCODE_MOV: - { - GLfloat result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, result ); - store_vector4( inst, machine, result ); - if (DEBUG_FRAG) { - printf("MOV (%g %g %g %g)\n", - result[0], result[1], result[2], result[3]); - } - } - break; - case OPCODE_MUL: - { - GLfloat a[4], b[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - result[0] = a[0] * b[0]; - result[1] = a[1] * b[1]; - result[2] = a[2] * b[2]; - result[3] = a[3] * b[3]; - store_vector4( inst, machine, result ); - if (DEBUG_FRAG) { - printf("MUL (%g %g %g %g) = (%g %g %g %g) * (%g %g %g %g)\n", - result[0], result[1], result[2], result[3], - a[0], a[1], a[2], a[3], - b[0], b[1], b[2], b[3]); - } - } - break; - case OPCODE_NOISE1: - { - GLfloat a[4], result[4]; - fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); - result[0] = - result[1] = - result[2] = - result[3] = _slang_library_noise1(a[0]); - store_vector4( inst, machine, result ); - } - break; - case OPCODE_NOISE2: - { - GLfloat a[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - result[0] = - result[1] = - result[2] = - result[3] = _slang_library_noise2(a[0], a[1]); - store_vector4( inst, machine, result ); - } - break; - case OPCODE_NOISE3: - { - GLfloat a[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - result[0] = - result[1] = - result[2] = - result[3] = _slang_library_noise3(a[0], a[1], a[2]); - store_vector4( inst, machine, result ); - } - break; - case OPCODE_NOISE4: - { - GLfloat a[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - result[0] = - result[1] = - result[2] = - result[3] = _slang_library_noise4(a[0], a[1], a[2], a[3]); - store_vector4( inst, machine, result ); - } - break; - case OPCODE_NOP: - break; - case OPCODE_PK2H: /* pack two 16-bit floats in one 32-bit float */ - { - GLfloat a[4], result[4]; - GLhalfNV hx, hy; - GLuint *rawResult = (GLuint *) result; - GLuint twoHalves; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - hx = _mesa_float_to_half(a[0]); - hy = _mesa_float_to_half(a[1]); - twoHalves = hx | (hy << 16); - rawResult[0] = rawResult[1] = rawResult[2] = rawResult[3] - = twoHalves; - store_vector4( inst, machine, result ); - } - break; - case OPCODE_PK2US: /* pack two GLushorts into one 32-bit float */ - { - GLfloat a[4], result[4]; - GLuint usx, usy, *rawResult = (GLuint *) result; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - a[0] = CLAMP(a[0], 0.0F, 1.0F); - a[1] = CLAMP(a[1], 0.0F, 1.0F); - usx = IROUND(a[0] * 65535.0F); - usy = IROUND(a[1] * 65535.0F); - rawResult[0] = rawResult[1] = rawResult[2] = rawResult[3] - = usx | (usy << 16); - store_vector4( inst, machine, result ); - } - break; - case OPCODE_PK4B: /* pack four GLbytes into one 32-bit float */ - { - GLfloat a[4], result[4]; - GLuint ubx, uby, ubz, ubw, *rawResult = (GLuint *) result; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - a[0] = CLAMP(a[0], -128.0F / 127.0F, 1.0F); - a[1] = CLAMP(a[1], -128.0F / 127.0F, 1.0F); - a[2] = CLAMP(a[2], -128.0F / 127.0F, 1.0F); - a[3] = CLAMP(a[3], -128.0F / 127.0F, 1.0F); - ubx = IROUND(127.0F * a[0] + 128.0F); - uby = IROUND(127.0F * a[1] + 128.0F); - ubz = IROUND(127.0F * a[2] + 128.0F); - ubw = IROUND(127.0F * a[3] + 128.0F); - rawResult[0] = rawResult[1] = rawResult[2] = rawResult[3] - = ubx | (uby << 8) | (ubz << 16) | (ubw << 24); - store_vector4( inst, machine, result ); - } - break; - case OPCODE_PK4UB: /* pack four GLubytes into one 32-bit float */ - { - GLfloat a[4], result[4]; - GLuint ubx, uby, ubz, ubw, *rawResult = (GLuint *) result; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - a[0] = CLAMP(a[0], 0.0F, 1.0F); - a[1] = CLAMP(a[1], 0.0F, 1.0F); - a[2] = CLAMP(a[2], 0.0F, 1.0F); - a[3] = CLAMP(a[3], 0.0F, 1.0F); - ubx = IROUND(255.0F * a[0]); - uby = IROUND(255.0F * a[1]); - ubz = IROUND(255.0F * a[2]); - ubw = IROUND(255.0F * a[3]); - rawResult[0] = rawResult[1] = rawResult[2] = rawResult[3] - = ubx | (uby << 8) | (ubz << 16) | (ubw << 24); - store_vector4( inst, machine, result ); - } - break; - case OPCODE_POW: - { - GLfloat a[4], b[4], result[4]; - fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector1( ctx, &inst->SrcReg[1], machine, program, b ); - result[0] = result[1] = result[2] = result[3] - = (GLfloat)_mesa_pow(a[0], b[0]); - store_vector4( inst, machine, result ); - } - break; - case OPCODE_RCP: - { - GLfloat a[4], result[4]; - fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); - if (DEBUG_FRAG) { - if (a[0] == 0) - printf("RCP(0)\n"); - else if (IS_INF_OR_NAN(a[0])) - printf("RCP(inf)\n"); - } - result[0] = result[1] = result[2] = result[3] = 1.0F / a[0]; - store_vector4( inst, machine, result ); - } - break; - case OPCODE_RET: /* return from subroutine (conditional) */ - if (eval_condition(machine, inst)) { - if (machine->StackDepth == 0) { - return GL_TRUE; /* Per GL_NV_vertex_program2 spec */ - } - pc = machine->CallStack[--machine->StackDepth]; - } - break; - case OPCODE_RFL: /* reflection vector */ - { - GLfloat axis[4], dir[4], result[4], tmpX, tmpW; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, axis ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, dir ); - tmpW = DOT3(axis, axis); - tmpX = (2.0F * DOT3(axis, dir)) / tmpW; - result[0] = tmpX * axis[0] - dir[0]; - result[1] = tmpX * axis[1] - dir[1]; - result[2] = tmpX * axis[2] - dir[2]; - /* result[3] is never written! XXX enforce in parser! */ - store_vector4( inst, machine, result ); - } - break; - case OPCODE_RSQ: /* 1 / sqrt() */ - { - GLfloat a[4], result[4]; - fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); - a[0] = FABSF(a[0]); - result[0] = result[1] = result[2] = result[3] = INV_SQRTF(a[0]); - store_vector4( inst, machine, result ); - if (DEBUG_FRAG) { - printf("RSQ %g = 1/sqrt(|%g|)\n", result[0], a[0]); - } - } - break; - case OPCODE_SCS: /* sine and cos */ - { - GLfloat a[4], result[4]; - fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); - result[0] = (GLfloat) _mesa_cos(a[0]); - result[1] = (GLfloat) _mesa_sin(a[0]); - result[2] = 0.0; /* undefined! */ - result[3] = 0.0; /* undefined! */ - store_vector4( inst, machine, result ); - } - break; - case OPCODE_SEQ: /* set on equal */ - { - GLfloat a[4], b[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - result[0] = (a[0] == b[0]) ? 1.0F : 0.0F; - result[1] = (a[1] == b[1]) ? 1.0F : 0.0F; - result[2] = (a[2] == b[2]) ? 1.0F : 0.0F; - result[3] = (a[3] == b[3]) ? 1.0F : 0.0F; - store_vector4( inst, machine, result ); - } - break; - case OPCODE_SFL: /* set false, operands ignored */ - { - static const GLfloat result[4] = { 0.0F, 0.0F, 0.0F, 0.0F }; - store_vector4( inst, machine, result ); - } - break; - case OPCODE_SGE: /* set on greater or equal */ - { - GLfloat a[4], b[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - result[0] = (a[0] >= b[0]) ? 1.0F : 0.0F; - result[1] = (a[1] >= b[1]) ? 1.0F : 0.0F; - result[2] = (a[2] >= b[2]) ? 1.0F : 0.0F; - result[3] = (a[3] >= b[3]) ? 1.0F : 0.0F; - store_vector4( inst, machine, result ); - } - break; - case OPCODE_SGT: /* set on greater */ - { - GLfloat a[4], b[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - result[0] = (a[0] > b[0]) ? 1.0F : 0.0F; - result[1] = (a[1] > b[1]) ? 1.0F : 0.0F; - result[2] = (a[2] > b[2]) ? 1.0F : 0.0F; - result[3] = (a[3] > b[3]) ? 1.0F : 0.0F; - store_vector4( inst, machine, result ); - if (DEBUG_FRAG) { - printf("SGT %g %g %g %g\n", - result[0], result[1], result[2], result[3]); - } - } - break; - case OPCODE_SIN: - { - GLfloat a[4], result[4]; - fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); - result[0] = result[1] = result[2] = result[3] - = (GLfloat) _mesa_sin(a[0]); - store_vector4( inst, machine, result ); - } - break; - case OPCODE_SLE: /* set on less or equal */ - { - GLfloat a[4], b[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - result[0] = (a[0] <= b[0]) ? 1.0F : 0.0F; - result[1] = (a[1] <= b[1]) ? 1.0F : 0.0F; - result[2] = (a[2] <= b[2]) ? 1.0F : 0.0F; - result[3] = (a[3] <= b[3]) ? 1.0F : 0.0F; - store_vector4( inst, machine, result ); - } - break; - case OPCODE_SLT: /* set on less */ - { - GLfloat a[4], b[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - result[0] = (a[0] < b[0]) ? 1.0F : 0.0F; - result[1] = (a[1] < b[1]) ? 1.0F : 0.0F; - result[2] = (a[2] < b[2]) ? 1.0F : 0.0F; - result[3] = (a[3] < b[3]) ? 1.0F : 0.0F; - store_vector4( inst, machine, result ); - } - break; - case OPCODE_SNE: /* set on not equal */ - { - GLfloat a[4], b[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - result[0] = (a[0] != b[0]) ? 1.0F : 0.0F; - result[1] = (a[1] != b[1]) ? 1.0F : 0.0F; - result[2] = (a[2] != b[2]) ? 1.0F : 0.0F; - result[3] = (a[3] != b[3]) ? 1.0F : 0.0F; - store_vector4( inst, machine, result ); - } - break; - case OPCODE_STR: /* set true, operands ignored */ - { - static const GLfloat result[4] = { 1.0F, 1.0F, 1.0F, 1.0F }; - store_vector4( inst, machine, result ); - } - break; - case OPCODE_SUB: - { - GLfloat a[4], b[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - result[0] = a[0] - b[0]; - result[1] = a[1] - b[1]; - result[2] = a[2] - b[2]; - result[3] = a[3] - b[3]; - store_vector4( inst, machine, result ); - if (DEBUG_FRAG) { - printf("SUB (%g %g %g %g) = (%g %g %g %g) - (%g %g %g %g)\n", - result[0], result[1], result[2], result[3], - a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3]); - } - } - break; - case OPCODE_SWZ: /* extended swizzle */ - { - const struct prog_src_register *source = &inst->SrcReg[0]; - const GLfloat *src = get_register_pointer(ctx, source, - machine, program); - GLfloat result[4]; - GLuint i; - for (i = 0; i < 4; i++) { - const GLuint swz = GET_SWZ(source->Swizzle, i); - if (swz == SWIZZLE_ZERO) - result[i] = 0.0; - else if (swz == SWIZZLE_ONE) - result[i] = 1.0; - else { - ASSERT(swz >= 0); - ASSERT(swz <= 3); - result[i] = src[swz]; - } - if (source->NegateBase & (1 << i)) - result[i] = -result[i]; - } - store_vector4( inst, machine, result ); - } - break; - case OPCODE_TEX: /* Both ARB and NV frag prog */ - /* Texel lookup */ - { - /* Note: only use the precomputed lambda value when we're - * sampling texture unit [K] with texcoord[K]. - * Otherwise, the lambda value may have no relation to the - * instruction's texcoord or texture image. Using the wrong - * lambda is usually bad news. - * The rest of the time, just use zero (until we get a more - * sophisticated way of computing lambda). - */ - GLfloat coord[4], color[4], lambda; - if (inst->SrcReg[0].File == PROGRAM_INPUT && - inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0+inst->TexSrcUnit) - lambda = span->array->lambda[inst->TexSrcUnit][column]; - else - lambda = 0.0; - fetch_vector4(ctx, &inst->SrcReg[0], machine, program, coord); - fetch_texel( ctx, coord, lambda, inst->TexSrcUnit, color ); - if (DEBUG_FRAG) { - printf("TEX (%g, %g, %g, %g) = texture[%d][%g, %g, %g, %g], " - "lod %f\n", - color[0], color[1], color[2], color[3], - inst->TexSrcUnit, - coord[0], coord[1], coord[2], coord[3], lambda); - } - store_vector4( inst, machine, color ); - } - break; - case OPCODE_TXB: /* GL_ARB_fragment_program only */ - /* Texel lookup with LOD bias */ - { - const struct gl_texture_unit *texUnit - = &ctx->Texture.Unit[inst->TexSrcUnit]; - GLfloat coord[4], color[4], lambda, bias; - if (inst->SrcReg[0].File == PROGRAM_INPUT && - inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0+inst->TexSrcUnit) - lambda = span->array->lambda[inst->TexSrcUnit][column]; - else - lambda = 0.0; - fetch_vector4(ctx, &inst->SrcReg[0], machine, program, coord); - /* coord[3] is the bias to add to lambda */ - bias = texUnit->LodBias + coord[3]; - if (texUnit->_Current) - bias += texUnit->_Current->LodBias; - fetch_texel(ctx, coord, lambda + bias, inst->TexSrcUnit, color); - store_vector4( inst, machine, color ); - } - break; - case OPCODE_TXD: /* GL_NV_fragment_program only */ - /* Texture lookup w/ partial derivatives for LOD */ - { - GLfloat texcoord[4], dtdx[4], dtdy[4], color[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, texcoord ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, dtdx ); - fetch_vector4( ctx, &inst->SrcReg[2], machine, program, dtdy ); - fetch_texel_deriv( ctx, texcoord, dtdx, dtdy, inst->TexSrcUnit, - color ); - store_vector4( inst, machine, color ); - } - break; - case OPCODE_TXP: /* GL_ARB_fragment_program only */ - /* Texture lookup w/ projective divide */ - { - GLfloat texcoord[4], color[4], lambda; - if (inst->SrcReg[0].File == PROGRAM_INPUT && - inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0+inst->TexSrcUnit) - lambda = span->array->lambda[inst->TexSrcUnit][column]; - else - lambda = 0.0; - fetch_vector4(ctx, &inst->SrcReg[0], machine, program,texcoord); - /* Not so sure about this test - if texcoord[3] is - * zero, we'd probably be fine except for an ASSERT in - * IROUND_POS() which gets triggered by the inf values created. - */ - if (texcoord[3] != 0.0) { - texcoord[0] /= texcoord[3]; - texcoord[1] /= texcoord[3]; - texcoord[2] /= texcoord[3]; - } - fetch_texel( ctx, texcoord, lambda, inst->TexSrcUnit, color ); - store_vector4( inst, machine, color ); - } - break; - case OPCODE_TXP_NV: /* GL_NV_fragment_program only */ - /* Texture lookup w/ projective divide */ - { - GLfloat texcoord[4], color[4], lambda; - if (inst->SrcReg[0].File == PROGRAM_INPUT && - inst->SrcReg[0].Index == FRAG_ATTRIB_TEX0+inst->TexSrcUnit) - lambda = span->array->lambda[inst->TexSrcUnit][column]; - else - lambda = 0.0; - fetch_vector4(ctx, &inst->SrcReg[0], machine, program,texcoord); - if (inst->TexSrcTarget != TEXTURE_CUBE_INDEX && - texcoord[3] != 0.0) { - texcoord[0] /= texcoord[3]; - texcoord[1] /= texcoord[3]; - texcoord[2] /= texcoord[3]; - } - fetch_texel( ctx, texcoord, lambda, inst->TexSrcUnit, color ); - store_vector4( inst, machine, color ); - } - break; - case OPCODE_UP2H: /* unpack two 16-bit floats */ - { - GLfloat a[4], result[4]; - const GLuint *rawBits = (const GLuint *) a; - GLhalfNV hx, hy; - fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); - hx = rawBits[0] & 0xffff; - hy = rawBits[0] >> 16; - result[0] = result[2] = _mesa_half_to_float(hx); - result[1] = result[3] = _mesa_half_to_float(hy); - store_vector4( inst, machine, result ); - } - break; - case OPCODE_UP2US: /* unpack two GLushorts */ - { - GLfloat a[4], result[4]; - const GLuint *rawBits = (const GLuint *) a; - GLushort usx, usy; - fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); - usx = rawBits[0] & 0xffff; - usy = rawBits[0] >> 16; - result[0] = result[2] = usx * (1.0f / 65535.0f); - result[1] = result[3] = usy * (1.0f / 65535.0f); - store_vector4( inst, machine, result ); - } - break; - case OPCODE_UP4B: /* unpack four GLbytes */ - { - GLfloat a[4], result[4]; - const GLuint *rawBits = (const GLuint *) a; - fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); - result[0] = (((rawBits[0] >> 0) & 0xff) - 128) / 127.0F; - result[1] = (((rawBits[0] >> 8) & 0xff) - 128) / 127.0F; - result[2] = (((rawBits[0] >> 16) & 0xff) - 128) / 127.0F; - result[3] = (((rawBits[0] >> 24) & 0xff) - 128) / 127.0F; - store_vector4( inst, machine, result ); - } - break; - case OPCODE_UP4UB: /* unpack four GLubytes */ - { - GLfloat a[4], result[4]; - const GLuint *rawBits = (const GLuint *) a; - fetch_vector1( ctx, &inst->SrcReg[0], machine, program, a ); - result[0] = ((rawBits[0] >> 0) & 0xff) / 255.0F; - result[1] = ((rawBits[0] >> 8) & 0xff) / 255.0F; - result[2] = ((rawBits[0] >> 16) & 0xff) / 255.0F; - result[3] = ((rawBits[0] >> 24) & 0xff) / 255.0F; - store_vector4( inst, machine, result ); - } - break; - case OPCODE_XPD: /* cross product */ - { - GLfloat a[4], b[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - result[0] = a[1] * b[2] - a[2] * b[1]; - result[1] = a[2] * b[0] - a[0] * b[2]; - result[2] = a[0] * b[1] - a[1] * b[0]; - result[3] = 1.0; - store_vector4( inst, machine, result ); - } - break; - case OPCODE_X2D: /* 2-D matrix transform */ - { - GLfloat a[4], b[4], c[4], result[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a ); - fetch_vector4( ctx, &inst->SrcReg[1], machine, program, b ); - fetch_vector4( ctx, &inst->SrcReg[2], machine, program, c ); - result[0] = a[0] + b[0] * c[0] + b[1] * c[1]; - result[1] = a[1] + b[0] * c[2] + b[1] * c[3]; - result[2] = a[2] + b[0] * c[0] + b[1] * c[1]; - result[3] = a[3] + b[0] * c[2] + b[1] * c[3]; - store_vector4( inst, machine, result ); - } - break; - case OPCODE_PRINT: - { - if (inst->SrcReg[0].File != -1) { - GLfloat a[4]; - fetch_vector4( ctx, &inst->SrcReg[0], machine, program, a); - _mesa_printf("%s%g, %g, %g, %g\n", (const char *) inst->Data, - a[0], a[1], a[2], a[3]); - } - else { - _mesa_printf("%s\n", (const char *) inst->Data); - } - } - break; - case OPCODE_END: - return GL_TRUE; - default: - _mesa_problem(ctx, "Bad opcode %d in _mesa_exec_fragment_program", - inst->Opcode); - return GL_TRUE; /* return value doesn't matter */ - - } - total++; - if (total > MAX_EXEC) { - _mesa_problem(ctx, "Infinite loop detected in fragment program"); - return GL_TRUE; - abort(); - } - } - return GL_TRUE; -} - - /** * Initialize the virtual fragment program machine state prior to running * fragment program on a fragment. This involves initializing the input @@ -1599,9 +100,9 @@ execute_program( GLcontext *ctx, * \param col which element (column) of the span we'll operate on */ static void -init_machine( GLcontext *ctx, struct fp_machine *machine, - const struct gl_fragment_program *program, - const SWspan *span, GLuint col ) +init_machine(GLcontext *ctx, struct gl_program_machine *machine, + const struct gl_fragment_program *program, + const SWspan *span, GLuint col) { GLuint inputsRead = program->Base.InputsRead; @@ -1616,7 +117,7 @@ init_machine( GLcontext *ctx, struct fp_machine *machine, /* Setup pointer to input attributes */ machine->Attribs = span->array->attribs; - machine->CurFrag = col; + machine->CurElement = col; /* init condition codes */ machine->CondCodes[0] = COND_EQ; @@ -1626,6 +127,9 @@ init_machine( GLcontext *ctx, struct fp_machine *machine, /* init call stack */ machine->StackDepth = 0; + + machine->FetchTexelLod = fetch_texel; + machine->FetchTexelDeriv = fetch_texel_deriv; } @@ -1636,17 +140,16 @@ static void run_program(GLcontext *ctx, SWspan *span, GLuint start, GLuint end) { const struct gl_fragment_program *program = ctx->FragmentProgram._Current; - struct fp_machine machine; + struct gl_program_machine machine; GLuint i; - CurrentMachine = &machine; - for (i = start; i < end; i++) { if (span->array->mask[i]) { init_machine(ctx, &machine, program, span, i); - if (execute_program(ctx, program, program->Base.NumInstructions, - &machine, span, i)) { + if (_mesa_execute_program(ctx, &program->Base, + program->Base.NumInstructions, + &machine, i)) { /* Store result color */ COPY_4V(span->array->attribs[FRAG_ATTRIB_COL0][i], machine.Outputs[FRAG_RESULT_COLR]); @@ -1669,8 +172,6 @@ run_program(GLcontext *ctx, SWspan *span, GLuint start, GLuint end) } } } - - CurrentMachine = NULL; } -- cgit v1.2.3 From 5e80c62f3178a65bebca942aa0b1e5d16c34b2a9 Mon Sep 17 00:00:00 2001 From: Brian Date: Sat, 24 Feb 2007 15:39:37 -0700 Subject: Remove unneeded _Fragment/VertexShaderPresent fields, update comments. --- src/mesa/main/mtypes.h | 16 +++++++++------- src/mesa/shader/shader_api.c | 3 +-- src/mesa/swrast/s_context.c | 4 ---- 3 files changed, 10 insertions(+), 13 deletions(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index b83beb8f91..bd9198ef12 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1929,9 +1929,11 @@ struct gl_vertex_program_state GLboolean _Enabled; /**< Enabled and valid program? */ 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 */ + struct gl_vertex_program *Current; /**< user-bound vertex program */ - /** Currently enabled and valid program (including internal programs) */ + /** Currently enabled and valid program (including internal programs + * and compiled shader programs). + */ struct gl_vertex_program *_Current; GLfloat Parameters[MAX_PROGRAM_ENV_PARAMS][4]; /**< Env params */ @@ -1962,9 +1964,11 @@ struct gl_fragment_program_state { GLboolean Enabled; /**< User-set fragment program enable flag */ GLboolean _Enabled; /**< Fragment program enabled and valid? */ - struct gl_fragment_program *Current; /**< User-bound program */ + struct gl_fragment_program *Current; /**< User-bound fragment program */ - /** Currently enabled and valid program (including internal programs) */ + /** Currently enabled and valid program (including internal programs + * and compiled shader programs). + */ struct gl_fragment_program *_Current; GLfloat Parameters[MAX_PROGRAM_ENV_PARAMS][4]; /**< Env params */ @@ -2099,9 +2103,7 @@ struct gl_shader_program */ struct gl_shader_state { - GLboolean _VertexShaderPresent; - GLboolean _FragmentShaderPresent; - struct gl_shader_program *CurrentProgram; + struct gl_shader_program *CurrentProgram; /**< The user-bound program */ }; diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c index c439f71f41..70ceb70fe7 100644 --- a/src/mesa/shader/shader_api.c +++ b/src/mesa/shader/shader_api.c @@ -199,8 +199,7 @@ _mesa_lookup_shader(GLcontext *ctx, GLuint name) void _mesa_init_shader_state(GLcontext * ctx) { - ctx->Shader._FragmentShaderPresent = GL_FALSE; - ctx->Shader._VertexShaderPresent = GL_FALSE; + /* no-op */ } diff --git a/src/mesa/swrast/s_context.c b/src/mesa/swrast/s_context.c index 5e174f81d5..031d74f31b 100644 --- a/src/mesa/swrast/s_context.c +++ b/src/mesa/swrast/s_context.c @@ -102,10 +102,6 @@ _swrast_update_rasterflags( GLcontext *ctx ) rasterMask |= FRAGPROG_BIT; } - if (ctx->Shader._FragmentShaderPresent) { - rasterMask |= FRAGPROG_BIT; - } - if (ctx->ATIFragmentShader._Enabled) { rasterMask |= ATIFRAGSHADER_BIT; } -- cgit v1.2.3 From 085d7d59f0e167bb546c4a1675e09631b14fc9f7 Mon Sep 17 00:00:00 2001 From: Brian Date: Sun, 25 Feb 2007 18:23:37 -0700 Subject: remove unused 'element' parameter from _mesa_execute_program() --- src/mesa/shader/prog_execute.c | 2 +- src/mesa/shader/prog_execute.h | 2 +- src/mesa/swrast/s_fragprog.c | 3 +-- src/mesa/tnl/t_vb_program.c | 2 +- 4 files changed, 4 insertions(+), 5 deletions(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/shader/prog_execute.c b/src/mesa/shader/prog_execute.c index 063d572428..0982e3e322 100644 --- a/src/mesa/shader/prog_execute.c +++ b/src/mesa/shader/prog_execute.c @@ -641,7 +641,7 @@ init_machine_deriv(GLcontext * ctx, GLboolean _mesa_execute_program(GLcontext * ctx, const struct gl_program *program, GLuint maxInst, - struct gl_program_machine *machine, GLuint element) + struct gl_program_machine *machine) { const GLuint MAX_EXEC = 10000; GLint pc, total = 0; diff --git a/src/mesa/shader/prog_execute.h b/src/mesa/shader/prog_execute.h index 1eb9e73d01..feda65fe03 100644 --- a/src/mesa/shader/prog_execute.h +++ b/src/mesa/shader/prog_execute.h @@ -75,7 +75,7 @@ _mesa_get_program_register(GLcontext *ctx, enum register_file file, extern GLboolean _mesa_execute_program(GLcontext *ctx, const struct gl_program *program, GLuint maxInst, - struct gl_program_machine *machine, GLuint element); + struct gl_program_machine *machine); #endif /* PROG_EXECUTE_H */ diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c index 4482006ba6..f88714d5c7 100644 --- a/src/mesa/swrast/s_fragprog.c +++ b/src/mesa/swrast/s_fragprog.c @@ -148,8 +148,7 @@ run_program(GLcontext *ctx, SWspan *span, GLuint start, GLuint end) init_machine(ctx, &machine, program, span, i); if (_mesa_execute_program(ctx, &program->Base, - program->Base.NumInstructions, - &machine, i)) { + program->Base.NumInstructions, &machine)) { /* Store result color */ COPY_4V(span->array->attribs[FRAG_ATTRIB_COL0][i], machine.Outputs[FRAG_RESULT_COLR]); diff --git a/src/mesa/tnl/t_vb_program.c b/src/mesa/tnl/t_vb_program.c index 3fe796ac56..05b1a4aaab 100644 --- a/src/mesa/tnl/t_vb_program.c +++ b/src/mesa/tnl/t_vb_program.c @@ -258,7 +258,7 @@ run_vp( GLcontext *ctx, struct tnl_pipeline_stage *stage ) /* execute the program */ _mesa_execute_program(ctx, &program->Base, program->Base.NumInstructions, - &machine, 0); + &machine); /* Fixup fog an point size results if needed */ if (ctx->Fog.Enabled && -- cgit v1.2.3 From 8b34b7da4131d2b07037ce062c522fddd614f127 Mon Sep 17 00:00:00 2001 From: Brian Date: Sun, 25 Feb 2007 18:26:50 -0700 Subject: remove 'maxInst' parameter from _mesa_execute_program() --- src/mesa/shader/prog_execute.c | 6 +++--- src/mesa/shader/prog_execute.h | 2 +- src/mesa/swrast/s_fragprog.c | 3 +-- src/mesa/tnl/t_vb_program.c | 3 +-- 4 files changed, 6 insertions(+), 8 deletions(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/shader/prog_execute.c b/src/mesa/shader/prog_execute.c index 0982e3e322..b3d017bd9b 100644 --- a/src/mesa/shader/prog_execute.c +++ b/src/mesa/shader/prog_execute.c @@ -635,14 +635,14 @@ init_machine_deriv(GLcontext * ctx, * \param ctx - rendering context * \param program - the fragment program to execute * \param machine - machine state (register file) - * \param maxInst - max number of instructions to execute * \return GL_TRUE if program completed or GL_FALSE if program executed KIL. */ GLboolean _mesa_execute_program(GLcontext * ctx, - const struct gl_program *program, GLuint maxInst, + const struct gl_program *program, struct gl_program_machine *machine) { + const GLuint numInst = program->NumInstructions; const GLuint MAX_EXEC = 10000; GLint pc, total = 0; @@ -656,7 +656,7 @@ _mesa_execute_program(GLcontext * ctx, CurrentMachine = machine; #endif - for (pc = 0; pc < maxInst; pc++) { + for (pc = 0; pc < numInst; pc++) { const struct prog_instruction *inst = program->Instructions + pc; #if FEATURE_MESA_program_debug diff --git a/src/mesa/shader/prog_execute.h b/src/mesa/shader/prog_execute.h index feda65fe03..2dbd922fb0 100644 --- a/src/mesa/shader/prog_execute.h +++ b/src/mesa/shader/prog_execute.h @@ -74,7 +74,7 @@ _mesa_get_program_register(GLcontext *ctx, enum register_file file, extern GLboolean _mesa_execute_program(GLcontext *ctx, - const struct gl_program *program, GLuint maxInst, + const struct gl_program *program, struct gl_program_machine *machine); diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c index f88714d5c7..4e1c829773 100644 --- a/src/mesa/swrast/s_fragprog.c +++ b/src/mesa/swrast/s_fragprog.c @@ -147,8 +147,7 @@ run_program(GLcontext *ctx, SWspan *span, GLuint start, GLuint end) if (span->array->mask[i]) { init_machine(ctx, &machine, program, span, i); - if (_mesa_execute_program(ctx, &program->Base, - program->Base.NumInstructions, &machine)) { + if (_mesa_execute_program(ctx, &program->Base, &machine)) { /* Store result color */ COPY_4V(span->array->attribs[FRAG_ATTRIB_COL0][i], machine.Outputs[FRAG_RESULT_COLR]); diff --git a/src/mesa/tnl/t_vb_program.c b/src/mesa/tnl/t_vb_program.c index 05b1a4aaab..17eefe7032 100644 --- a/src/mesa/tnl/t_vb_program.c +++ b/src/mesa/tnl/t_vb_program.c @@ -257,8 +257,7 @@ run_vp( GLcontext *ctx, struct tnl_pipeline_stage *stage ) } /* execute the program */ - _mesa_execute_program(ctx, &program->Base, program->Base.NumInstructions, - &machine); + _mesa_execute_program(ctx, &program->Base, &machine); /* Fixup fog an point size results if needed */ if (ctx->Fog.Enabled && -- cgit v1.2.3 From 4e53ce81cfa2a98d045433ffbc4d295a239ad0b6 Mon Sep 17 00:00:00 2001 From: Brian Date: Sun, 25 Feb 2007 20:05:22 -0700 Subject: remove unneeded includes --- src/mesa/swrast/s_fragprog.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c index 4e1c829773..698925cdba 100644 --- a/src/mesa/swrast/s_fragprog.c +++ b/src/mesa/swrast/s_fragprog.c @@ -27,13 +27,9 @@ #include "context.h" #include "prog_execute.h" #include "prog_instruction.h" -#include "prog_parameter.h" -#include "prog_print.h" -#include "program.h" #include "s_fragprog.h" #include "s_span.h" -#include "slang_library_noise.h" /** -- cgit v1.2.3 From 1dca0891492dc5d2974239f04883a41a1738d91f Mon Sep 17 00:00:00 2001 From: Brian Date: Wed, 7 Mar 2007 10:42:44 -0700 Subject: fix deferredTexture bug --- src/mesa/swrast/s_span.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c index 724cf616e8..a2044d0042 100644 --- a/src/mesa/swrast/s_span.c +++ b/src/mesa/swrast/s_span.c @@ -1351,7 +1351,7 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span) } else if (shaderOrTexture) { if (ctx->FragmentProgram._Current) { - if (ctx->FragmentProgram.Current->Base.OutputsWritten + if (ctx->FragmentProgram._Current->Base.OutputsWritten & (1 << FRAG_RESULT_DEPR)) { /* Z comes from fragment program/shader */ deferredTexture = GL_FALSE; -- cgit v1.2.3 From 1fcb4ecc07685872c9c42569ba13faa1cad54d3c Mon Sep 17 00:00:00 2001 From: Brian Date: Sat, 10 Mar 2007 10:56:06 -0700 Subject: clean-up formatting --- src/mesa/swrast/s_context.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/swrast/s_context.c b/src/mesa/swrast/s_context.c index 031d74f31b..8864c217a5 100644 --- a/src/mesa/swrast/s_context.c +++ b/src/mesa/swrast/s_context.c @@ -125,27 +125,28 @@ _swrast_update_rasterflags( GLcontext *ctx ) static void _swrast_update_polygon( GLcontext *ctx ) { - GLfloat backface_sign = 1; + GLfloat backface_sign; if (ctx->Polygon.CullFlag) { - backface_sign = 1; - switch(ctx->Polygon.CullFaceMode) { + backface_sign = 1.0; + switch (ctx->Polygon.CullFaceMode) { case GL_BACK: - if(ctx->Polygon.FrontFace==GL_CCW) - backface_sign = -1; + if (ctx->Polygon.FrontFace == GL_CCW) + backface_sign = -1.0; break; case GL_FRONT: - if(ctx->Polygon.FrontFace!=GL_CCW) - backface_sign = -1; + if (ctx->Polygon.FrontFace != GL_CCW) + backface_sign = -1.0; break; - default: case GL_FRONT_AND_BACK: - backface_sign = 0; + /* fallthrough */ + default: + backface_sign = 0.0; break; } } else { - backface_sign = 0; + backface_sign = 0.0; } SWRAST_CONTEXT(ctx)->_BackfaceSign = backface_sign; -- cgit v1.2.3 From 10b5895597d5e069183cb647d17eb412effceb4f Mon Sep 17 00:00:00 2001 From: Brian Date: Sat, 10 Mar 2007 11:30:19 -0700 Subject: Implement gl_FrontFacing for fragment shaders. For the time being, we put the gl_FrontFacing value in the FOGC.Y input register. Combining FOGC and FrontFacing in one register is a bit of a hack and may need to be changed someday. --- src/mesa/shader/slang/slang_codegen.c | 60 +++++++++++++++++++++-------------- src/mesa/swrast/s_fragprog.c | 4 +++ src/mesa/swrast_setup/ss_triangle.c | 4 ++- src/mesa/swrast_setup/ss_tritmp.h | 3 +- 4 files changed, 44 insertions(+), 27 deletions(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index 64bb9141bc..640b87a34d 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -209,35 +209,37 @@ sampler_to_texture_index(const slang_type_specifier_type type) * XXX return size too */ static GLint -_slang_input_index(const char *name, GLenum target) +_slang_input_index(const char *name, GLenum target, GLuint *swizzleOut) { struct input_info { const char *Name; GLuint Attrib; + GLuint Swizzle; }; static const struct input_info vertInputs[] = { - { "gl_Vertex", VERT_ATTRIB_POS }, - { "gl_Normal", VERT_ATTRIB_NORMAL }, - { "gl_Color", VERT_ATTRIB_COLOR0 }, - { "gl_SecondaryColor", VERT_ATTRIB_COLOR1 }, - { "gl_FogCoord", VERT_ATTRIB_FOG }, - { "gl_MultiTexCoord0", VERT_ATTRIB_TEX0 }, - { "gl_MultiTexCoord1", VERT_ATTRIB_TEX1 }, - { "gl_MultiTexCoord2", VERT_ATTRIB_TEX2 }, - { "gl_MultiTexCoord3", VERT_ATTRIB_TEX3 }, - { "gl_MultiTexCoord4", VERT_ATTRIB_TEX4 }, - { "gl_MultiTexCoord5", VERT_ATTRIB_TEX5 }, - { "gl_MultiTexCoord6", VERT_ATTRIB_TEX6 }, - { "gl_MultiTexCoord7", VERT_ATTRIB_TEX7 }, - { NULL, 0 } + { "gl_Vertex", VERT_ATTRIB_POS, SWIZZLE_NOOP }, + { "gl_Normal", VERT_ATTRIB_NORMAL, SWIZZLE_NOOP }, + { "gl_Color", VERT_ATTRIB_COLOR0, SWIZZLE_NOOP }, + { "gl_SecondaryColor", VERT_ATTRIB_COLOR1, SWIZZLE_NOOP }, + { "gl_FogCoord", VERT_ATTRIB_FOG, SWIZZLE_XXXX }, + { "gl_MultiTexCoord0", VERT_ATTRIB_TEX0, SWIZZLE_NOOP }, + { "gl_MultiTexCoord1", VERT_ATTRIB_TEX1, SWIZZLE_NOOP }, + { "gl_MultiTexCoord2", VERT_ATTRIB_TEX2, SWIZZLE_NOOP }, + { "gl_MultiTexCoord3", VERT_ATTRIB_TEX3, SWIZZLE_NOOP }, + { "gl_MultiTexCoord4", VERT_ATTRIB_TEX4, SWIZZLE_NOOP }, + { "gl_MultiTexCoord5", VERT_ATTRIB_TEX5, SWIZZLE_NOOP }, + { "gl_MultiTexCoord6", VERT_ATTRIB_TEX6, SWIZZLE_NOOP }, + { "gl_MultiTexCoord7", VERT_ATTRIB_TEX7, SWIZZLE_NOOP }, + { NULL, 0, SWIZZLE_NOOP } }; static const struct input_info fragInputs[] = { - { "gl_FragCoord", FRAG_ATTRIB_WPOS }, - { "gl_Color", FRAG_ATTRIB_COL0 }, - { "gl_SecondaryColor", FRAG_ATTRIB_COL1 }, - { "gl_FogFragCoord", FRAG_ATTRIB_FOGC }, - { "gl_TexCoord", FRAG_ATTRIB_TEX0 }, - { NULL, 0 } + { "gl_FragCoord", FRAG_ATTRIB_WPOS, SWIZZLE_NOOP }, + { "gl_Color", FRAG_ATTRIB_COL0, SWIZZLE_NOOP }, + { "gl_SecondaryColor", FRAG_ATTRIB_COL1, SWIZZLE_NOOP }, + { "gl_FogFragCoord", FRAG_ATTRIB_FOGC, SWIZZLE_XXXX }, + { "gl_TexCoord", FRAG_ATTRIB_TEX0, SWIZZLE_NOOP }, + { "gl_FrontFacing", FRAG_ATTRIB_FOGC, SWIZZLE_YYYY }, /*XXX*/ + { NULL, 0, SWIZZLE_NOOP } }; GLuint i; const struct input_info *inputs @@ -248,6 +250,7 @@ _slang_input_index(const char *name, GLenum target) for (i = 0; inputs[i].Name; i++) { if (strcmp(inputs[i].Name, name) == 0) { /* found */ + *swizzleOut = inputs[i].Swizzle; return inputs[i].Attrib; } } @@ -2571,9 +2574,12 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var, else { /* pre-defined varying, like gl_Color or gl_TexCoord */ if (type == SLANG_UNIT_FRAGMENT_BUILTIN) { - GLint index = _slang_input_index(varName, GL_FRAGMENT_PROGRAM_ARB); + GLuint swizzle; + GLint index = _slang_input_index(varName, GL_FRAGMENT_PROGRAM_ARB, + &swizzle); assert(index >= 0); store = _slang_new_ir_storage(PROGRAM_INPUT, index, size); + store->Swizzle = swizzle; assert(index < FRAG_ATTRIB_MAX); } else { @@ -2600,17 +2606,23 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var, } else { /* pre-defined vertex attrib */ - GLint index = _slang_input_index(varName, GL_VERTEX_PROGRAM_ARB); + GLuint swizzle; + GLint index = _slang_input_index(varName, GL_VERTEX_PROGRAM_ARB, + &swizzle); GLint size = 4; /* XXX? */ assert(index >= 0); store = _slang_new_ir_storage(PROGRAM_INPUT, index, size); + store->Swizzle = swizzle; } if (dbg) printf("ATTRIB "); } else if (var->type.qualifier == SLANG_QUAL_FIXEDINPUT) { - GLint index = _slang_input_index(varName, GL_FRAGMENT_PROGRAM_ARB); + GLuint swizzle; + GLint index = _slang_input_index(varName, GL_FRAGMENT_PROGRAM_ARB, + &swizzle); GLint size = 4; /* XXX? */ store = _slang_new_ir_storage(PROGRAM_INPUT, index, size); + store->Swizzle = swizzle; if (dbg) printf("INPUT "); } else if (var->type.qualifier == SLANG_QUAL_FIXEDOUTPUT) { diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c index 698925cdba..dbfc1b8c0c 100644 --- a/src/mesa/swrast/s_fragprog.c +++ b/src/mesa/swrast/s_fragprog.c @@ -113,6 +113,10 @@ init_machine(GLcontext *ctx, struct gl_program_machine *machine, /* Setup pointer to input attributes */ machine->Attribs = span->array->attribs; + + /* Store front/back facing value in register FOGC.Y */ + machine->Attribs[FRAG_ATTRIB_FOGC][col][1] = (GLfloat) ctx->_Facing; + machine->CurElement = col; /* init condition codes */ diff --git a/src/mesa/swrast_setup/ss_triangle.c b/src/mesa/swrast_setup/ss_triangle.c index 09244d9c4b..628e9288e8 100644 --- a/src/mesa/swrast_setup/ss_triangle.c +++ b/src/mesa/swrast_setup/ss_triangle.c @@ -290,8 +290,10 @@ void _swsetup_choose_trifuncs( GLcontext *ctx ) ctx->Polygon.OffsetFill) ind |= SS_OFFSET_BIT; + /* Note: gl_FrontFacing lives in fragment input FOGC.Y at this time */ if ((ctx->Light.Enabled && ctx->Light.Model.TwoSide) || - (ctx->VertexProgram._Enabled && ctx->VertexProgram.TwoSideEnabled)) + (ctx->VertexProgram._Enabled && ctx->VertexProgram.TwoSideEnabled) || + (ctx->FragmentProgram._Current && ctx->FragmentProgram._Current->Base.InputsRead & (1 << FRAG_ATTRIB_FOGC))) ind |= SS_TWOSIDE_BIT; /* We piggyback the two-sided stencil front/back determination on the diff --git a/src/mesa/swrast_setup/ss_tritmp.h b/src/mesa/swrast_setup/ss_tritmp.h index 61c9b2817e..5b14b283f1 100644 --- a/src/mesa/swrast_setup/ss_tritmp.h +++ b/src/mesa/swrast_setup/ss_tritmp.h @@ -55,8 +55,7 @@ static void TAG(triangle)(GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2 ) if (IND & (SS_TWOSIDE_BIT | SS_UNFILLED_BIT)) { facing = (cc < 0.0) ^ ctx->Polygon._FrontBit; - if (ctx->Stencil.TestTwoSide) - ctx->_Facing = facing; /* for 2-sided stencil test */ + ctx->_Facing = facing; if (IND & SS_UNFILLED_BIT) mode = facing ? ctx->Polygon.BackMode : ctx->Polygon.FrontMode; -- cgit v1.2.3 From 1c09bcfdda4083636a3ac27d804a34ef87875ce7 Mon Sep 17 00:00:00 2001 From: Brian Date: Sun, 11 Mar 2007 17:00:39 -0600 Subject: Implement support for GL_ARB_draw_buffers with GL_MAX_DRAW_BUFFERS > 1. GL_MAX_DRAW_BUFFERS is currently 4. Added gl_FragData[] output for fragment programs. In _swrast_write_rgba_span() loop over the color outputs/renderbuffers. --- src/mesa/main/config.h | 2 +- src/mesa/main/mtypes.h | 3 +- src/mesa/shader/slang/slang_codegen.c | 1 + src/mesa/swrast/s_context.c | 41 +++++++++ src/mesa/swrast/s_context.h | 4 + src/mesa/swrast/s_fragprog.c | 24 +++++- src/mesa/swrast/s_span.c | 152 ++++++++++++++++++---------------- 7 files changed, 152 insertions(+), 75 deletions(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/main/config.h b/src/mesa/main/config.h index 00df084fc8..8ea2d2c615 100644 --- a/src/mesa/main/config.h +++ b/src/mesa/main/config.h @@ -216,7 +216,7 @@ /** For GL_ARB_draw_buffers */ /*@{*/ -#define MAX_DRAW_BUFFERS 1 +#define MAX_DRAW_BUFFERS 4 /*@}*/ diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index b08e77ea88..25a5a3cc36 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -306,7 +306,8 @@ enum FRAG_RESULT_COLR = 0, FRAG_RESULT_COLH = 1, FRAG_RESULT_DEPR = 2, - FRAG_RESULT_MAX = 3 + FRAG_RESULT_DATA0 = 3, + FRAG_RESULT_MAX = (FRAG_RESULT_DATA0 + MAX_DRAW_BUFFERS) }; diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index 640b87a34d..88a4b2d657 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -284,6 +284,7 @@ _slang_output_index(const char *name, GLenum target) static const struct output_info fragOutputs[] = { { "gl_FragColor", FRAG_RESULT_COLR }, { "gl_FragDepth", FRAG_RESULT_DEPR }, + { "gl_FragData", FRAG_RESULT_DATA0 }, { NULL, 0 } }; GLuint i; diff --git a/src/mesa/swrast/s_context.c b/src/mesa/swrast/s_context.c index 8864c217a5..00702b4301 100644 --- a/src/mesa/swrast/s_context.c +++ b/src/mesa/swrast/s_context.c @@ -548,6 +548,44 @@ _swrast_update_fragment_attribs(GLcontext *ctx) } +/** + * Update the swrast->_ColorOutputsMask which indicates which color + * renderbuffers (aka rendertargets) are being written to by the current + * fragment program. + * We also take glDrawBuffers() into account to skip outputs that are + * set to GL_NONE. + */ +static void +_swrast_update_color_outputs(GLcontext *ctx) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + const struct gl_framebuffer *fb = ctx->DrawBuffer; + + swrast->_ColorOutputsMask = 0; + swrast->_NumColorOutputs = 0; + + if (ctx->FragmentProgram._Current) { + const GLbitfield outputsWritten + = ctx->FragmentProgram._Current->Base.OutputsWritten; + GLuint output; + for (output = 0; output < ctx->Const.MaxDrawBuffers; output++) { + if ((outputsWritten & (1 << (FRAG_RESULT_DATA0 + output))) + && (fb->_NumColorDrawBuffers[output] > 0)) { + swrast->_ColorOutputsMask |= (1 << output); + swrast->_NumColorOutputs = output + 1; + } + } + } + if (swrast->_ColorOutputsMask == 0x0) { + /* no fragment program, or frag prog didn't write to gl_FragData[] */ + if (fb->_NumColorDrawBuffers[0] > 0) { + swrast->_ColorOutputsMask = 0x1; + swrast->_NumColorOutputs = 1; + } + } +} + + void _swrast_validate_derived( GLcontext *ctx ) { @@ -594,6 +632,9 @@ _swrast_validate_derived( GLcontext *ctx ) _NEW_TEXTURE)) _swrast_update_fragment_attribs(ctx); + if (swrast->NewState & (_NEW_PROGRAM | _NEW_BUFFERS)) + _swrast_update_color_outputs(ctx); + swrast->NewState = 0; swrast->StateChanges = 0; swrast->InvalidateState = _swrast_invalidate_state; diff --git a/src/mesa/swrast/s_context.h b/src/mesa/swrast/s_context.h index a3f61cd5e5..3a9a48922e 100644 --- a/src/mesa/swrast/s_context.h +++ b/src/mesa/swrast/s_context.h @@ -133,6 +133,10 @@ typedef struct GLboolean _FogEnabled; GLenum _FogMode; /* either GL_FOG_MODE or fragment program's fog mode */ + /** Multiple render targets */ + GLbitfield _ColorOutputsMask; + GLuint _NumColorOutputs; + /** Fragment attributes to compute during rasterization. * Mask of FRAG_BIT_* flags. */ diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c index dbfc1b8c0c..7260759306 100644 --- a/src/mesa/swrast/s_fragprog.c +++ b/src/mesa/swrast/s_fragprog.c @@ -139,7 +139,9 @@ init_machine(GLcontext *ctx, struct gl_program_machine *machine, static void run_program(GLcontext *ctx, SWspan *span, GLuint start, GLuint end) { + SWcontext *swrast = SWRAST_CONTEXT(ctx); const struct gl_fragment_program *program = ctx->FragmentProgram._Current; + const GLbitfield outputsWritten = program->Base.OutputsWritten; struct gl_program_machine machine; GLuint i; @@ -148,12 +150,28 @@ run_program(GLcontext *ctx, SWspan *span, GLuint start, GLuint end) init_machine(ctx, &machine, program, span, i); if (_mesa_execute_program(ctx, &program->Base, &machine)) { + /* Store result color */ - COPY_4V(span->array->attribs[FRAG_ATTRIB_COL0][i], - machine.Outputs[FRAG_RESULT_COLR]); + if (outputsWritten & (1 << FRAG_RESULT_COLR)) { + COPY_4V(span->array->attribs[FRAG_ATTRIB_COL0][i], + machine.Outputs[FRAG_RESULT_COLR]); + } + else { + /* Multiple drawbuffers / render targets + * Note that colors beyond 0 and 1 will overwrite other + * attributes, such as FOGC, TEX0, TEX1, etc. That's OK. + */ + GLuint output; + for (output = 0; output < swrast->_NumColorOutputs; output++) { + if (outputsWritten & (1 << (FRAG_RESULT_DATA0 + output))) { + COPY_4V(span->array->attribs[FRAG_ATTRIB_COL0+output][i], + machine.Outputs[FRAG_RESULT_DATA0 + output]); + } + } + } /* Store result depth/z */ - if (program->Base.OutputsWritten & (1 << FRAG_RESULT_DEPR)) { + if (outputsWritten & (1 << FRAG_RESULT_DEPR)) { const GLfloat depth = machine.Outputs[FRAG_RESULT_DEPR][2]; if (depth <= 0.0) span->array->z[i] = 0; diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c index a2044d0042..f9f0a1f813 100644 --- a/src/mesa/swrast/s_span.c +++ b/src/mesa/swrast/s_span.c @@ -1215,24 +1215,31 @@ clamp_colors(SWspan *span) /** * Convert the span's color arrays to the given type. + * The only way 'output' can be greater than one is when we have a fragment + * program that writes to gl_FragData[1] or higher. + * \param output which fragment program color output is being processed */ static INLINE void -convert_color_type(SWspan *span, GLenum newType) +convert_color_type(SWspan *span, GLenum newType, GLuint output) { GLvoid *src, *dst; - if (span->array->ChanType == GL_UNSIGNED_BYTE) { - src = span->array->color.sz1.rgba; + + if (output > 0 || span->array->ChanType == GL_FLOAT) { + src = span->array->attribs[FRAG_ATTRIB_COL0 + output]; + span->array->ChanType = GL_FLOAT; } else if (span->array->ChanType == GL_UNSIGNED_BYTE) { - src = span->array->color.sz2.rgba; + src = span->array->color.sz1.rgba; } else { - src = span->array->attribs[FRAG_ATTRIB_COL0]; + ASSERT(span->array->ChanType == GL_UNSIGNED_SHORT); + src = span->array->color.sz2.rgba; } + if (newType == GL_UNSIGNED_BYTE) { dst = span->array->color.sz1.rgba; } - else if (newType == GL_UNSIGNED_BYTE) { + else if (newType == GL_UNSIGNED_SHORT) { dst = span->array->color.sz2.rgba; } else { @@ -1329,6 +1336,8 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span) const GLboolean shader = (ctx->FragmentProgram._Current || ctx->ATIFragmentShader._Enabled); const GLboolean shaderOrTexture = shader || ctx->Texture._EnabledUnits; + struct gl_framebuffer *fb = ctx->DrawBuffer; + GLuint output; GLboolean deferredTexture; /* @@ -1393,10 +1402,10 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span) GLuint i; for (i = 0; i < span->end; i++) { if (span->array->mask[i]) { - assert(span->array->x[i] >= ctx->DrawBuffer->_Xmin); - assert(span->array->x[i] < ctx->DrawBuffer->_Xmax); - assert(span->array->y[i] >= ctx->DrawBuffer->_Ymin); - assert(span->array->y[i] < ctx->DrawBuffer->_Ymax); + assert(span->array->x[i] >= fb->_Xmin); + assert(span->array->x[i] < fb->_Xmax); + assert(span->array->y[i] >= fb->_Ymin); + assert(span->array->y[i] < fb->_Ymax); } } } @@ -1428,13 +1437,13 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span) if (span->interpMask & SPAN_Z) _swrast_span_interpolate_z(ctx, span); - if (ctx->Stencil.Enabled && ctx->DrawBuffer->Visual.stencilBits > 0) { + if (ctx->Stencil.Enabled && fb->Visual.stencilBits > 0) { /* Combined Z/stencil tests */ if (!_swrast_stencil_and_ztest_span(ctx, span)) { goto end; } } - else if (ctx->DrawBuffer->Visual.depthBits > 0) { + else if (fb->Visual.depthBits > 0) { /* Just regular depth testing */ ASSERT(ctx->Depth.Test); ASSERT(span->arrayMask & SPAN_Z); @@ -1514,64 +1523,67 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span) /* * Write to renderbuffers */ - { - struct gl_framebuffer *fb = ctx->DrawBuffer; - const GLuint output = 0; /* only frag progs can write to other outputs */ - const GLuint numDrawBuffers = fb->_NumColorDrawBuffers[output]; - GLchan rgbaSave[MAX_WIDTH][4]; - GLuint buf; - - if (numDrawBuffers > 0) { - if (fb->_ColorDrawBuffers[output][0]->DataType - != span->array->ChanType) { - convert_color_type(span, - fb->_ColorDrawBuffers[output][0]->DataType); - } - } - - if (numDrawBuffers > 1) { - /* save colors for second, third renderbuffer writes */ - _mesa_memcpy(rgbaSave, span->array->rgba, - 4 * span->end * sizeof(GLchan)); - } - - for (buf = 0; buf < numDrawBuffers; buf++) { - struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[output][buf]; - ASSERT(rb->_BaseFormat == GL_RGBA || rb->_BaseFormat == GL_RGB); - - if (ctx->Color._LogicOpEnabled) { - _swrast_logicop_rgba_span(ctx, rb, span); - } - else if (ctx->Color.BlendEnabled) { - _swrast_blend_span(ctx, rb, span); - } - - if (colorMask != 0xffffffff) { - _swrast_mask_rgba_span(ctx, rb, span); - } - - if (span->arrayMask & SPAN_XY) { - /* array of pixel coords */ - ASSERT(rb->PutValues); - rb->PutValues(ctx, rb, span->end, - span->array->x, span->array->y, - span->array->rgba, span->array->mask); - } - else { - /* horizontal run of pixels */ - ASSERT(rb->PutRow); - rb->PutRow(ctx, rb, span->end, span->x, span->y, span->array->rgba, - span->writeAll ? NULL: span->array->mask); - } - - if (buf + 1 < numDrawBuffers) { - /* restore original span values */ - _mesa_memcpy(span->array->rgba, rgbaSave, - 4 * span->end * sizeof(GLchan)); - } - } /* for buf */ - - } + /* Loop over color outputs (GL_ARB_draw_buffers) written by frag prog */ + for (output = 0; output < swrast->_NumColorOutputs; output++) { + if (swrast->_ColorOutputsMask & (1 << output)) { + const GLuint numDrawBuffers = fb->_NumColorDrawBuffers[output]; + GLchan rgbaSave[MAX_WIDTH][4]; + GLuint buf; + + ASSERT(numDrawBuffers > 0); + + if (fb->_ColorDrawBuffers[output][0]->DataType + != span->array->ChanType || output > 0) { + convert_color_type(span, + fb->_ColorDrawBuffers[output][0]->DataType, + output); + } + + if (numDrawBuffers > 1) { + /* save colors for second, third renderbuffer writes */ + _mesa_memcpy(rgbaSave, span->array->rgba, + 4 * span->end * sizeof(GLchan)); + } + + /* Loop over renderbuffers (i.e. GL_FRONT_AND_BACK) */ + for (buf = 0; buf < numDrawBuffers; buf++) { + struct gl_renderbuffer *rb = fb->_ColorDrawBuffers[output][buf]; + ASSERT(rb->_BaseFormat == GL_RGBA || rb->_BaseFormat == GL_RGB); + + if (ctx->Color._LogicOpEnabled) { + _swrast_logicop_rgba_span(ctx, rb, span); + } + else if (ctx->Color.BlendEnabled) { + _swrast_blend_span(ctx, rb, span); + } + + if (colorMask != 0xffffffff) { + _swrast_mask_rgba_span(ctx, rb, span); + } + + if (span->arrayMask & SPAN_XY) { + /* array of pixel coords */ + ASSERT(rb->PutValues); + rb->PutValues(ctx, rb, span->end, + span->array->x, span->array->y, + span->array->rgba, span->array->mask); + } + else { + /* horizontal run of pixels */ + ASSERT(rb->PutRow); + rb->PutRow(ctx, rb, span->end, span->x, span->y, + span->array->rgba, + span->writeAll ? NULL: span->array->mask); + } + + if (buf + 1 < numDrawBuffers) { + /* restore original span values */ + _mesa_memcpy(span->array->rgba, rgbaSave, + 4 * span->end * sizeof(GLchan)); + } + } /* for buf */ + } /* if output is written to */ + } /* for output */ end: /* restore these values before returning */ -- cgit v1.2.3 From 17ad1d12ebf04ebf4b2b35c1c37d36bb4d2bb550 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 13 Mar 2007 10:53:16 -0600 Subject: Check if FRAG_RESULT_COLR is written and update span->interpMask, arrayMask. Also, fix an assertion. --- src/mesa/swrast/s_fragprog.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c index 7260759306..7f7c0d6db5 100644 --- a/src/mesa/swrast/s_fragprog.c +++ b/src/mesa/swrast/s_fragprog.c @@ -201,12 +201,19 @@ _swrast_exec_fragment_program( GLcontext *ctx, SWspan *span ) const struct gl_fragment_program *program = ctx->FragmentProgram._Current; /* incoming colors should be floats */ - ASSERT(span->array->ChanType == GL_FLOAT); + if (program->Base.InputsRead & FRAG_BIT_COL0) { + ASSERT(span->array->ChanType == GL_FLOAT); + } ctx->_CurrentProgram = GL_FRAGMENT_PROGRAM_ARB; /* or NV, doesn't matter */ run_program(ctx, span, 0, span->end); + if (program->Base.OutputsWritten & (1 << FRAG_RESULT_COLR)) { + span->interpMask &= ~SPAN_RGBA; + span->arrayMask |= SPAN_RGBA; + } + if (program->Base.OutputsWritten & (1 << FRAG_RESULT_DEPR)) { span->interpMask &= ~SPAN_Z; span->arrayMask |= SPAN_Z; -- cgit v1.2.3 From da554309521e8f351eecb30ce197535fb7541f40 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 13 Mar 2007 10:58:23 -0600 Subject: comment about SPAN_* vs FRAG_BIT_* values --- src/mesa/swrast/s_span.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/mesa/swrast') diff --git a/src/mesa/swrast/s_span.h b/src/mesa/swrast/s_span.h index 26ef399df3..8a9b9eb21c 100644 --- a/src/mesa/swrast/s_span.h +++ b/src/mesa/swrast/s_span.h @@ -35,6 +35,8 @@ * \defgroup SpanFlags * Bitflags used for interpMask and arrayMask fields below to indicate * which interpolant values and fragment arrays are in use, respectively. + * + * XXX We should replace these flags with the FRAG_BIT_ values someday... */ /*@{*/ #define SPAN_RGBA 0x001 -- cgit v1.2.3 From c000843a14e73d593d87ff6674d0295d2cb64a12 Mon Sep 17 00:00:00 2001 From: Brian Date: Tue, 13 Mar 2007 10:58:48 -0600 Subject: be smarter about which fragment attribs are interpolated before running frag progs --- src/mesa/swrast/s_span.c | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) (limited to 'src/mesa/swrast') diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c index f9f0a1f813..fa7761269d 100644 --- a/src/mesa/swrast/s_span.c +++ b/src/mesa/swrast/s_span.c @@ -554,7 +554,7 @@ interpolate_texcoords(GLcontext *ctx, SWspan *span) for (u = 0; u < maxUnit; u++) { if (ctx->Texture._EnabledCoordUnits & (1 << u)) { const GLuint attr = FRAG_ATTRIB_TEX0 + u; - const struct gl_texture_object *obj =ctx->Texture.Unit[u]._Current; + const struct gl_texture_object *obj = ctx->Texture.Unit[u]._Current; GLfloat texW, texH; GLboolean needLambda; GLfloat (*texcoord)[4] = span->array->attribs[attr]; @@ -1261,8 +1261,18 @@ convert_color_type(SWspan *span, GLenum newType, GLuint output) static INLINE void shade_texture_span(GLcontext *ctx, SWspan *span) { - /* Now we need the rgba array, fill it in if needed */ - if (span->interpMask & SPAN_RGBA) + GLbitfield inputsRead; + + /* Determine which fragment attributes are actually needed */ + if (ctx->FragmentProgram._Current) { + inputsRead = ctx->FragmentProgram._Current->Base.InputsRead; + } + else { + /* XXX we could be a bit smarter about this */ + inputsRead = ~0; + } + + if ((inputsRead & FRAG_BIT_COL0) && (span->interpMask & SPAN_RGBA)) interpolate_colors(span); if (ctx->Texture._EnabledCoordUnits && (span->interpMask & SPAN_TEXTURE)) @@ -1270,35 +1280,35 @@ shade_texture_span(GLcontext *ctx, SWspan *span) if (ctx->FragmentProgram._Current || ctx->ATIFragmentShader._Enabled) { - /* use float colors if running a fragment program or shader */ const GLenum oldType = span->array->ChanType; const GLenum newType = GL_FLOAT; - if (oldType != newType) { + + if ((inputsRead & FRAG_BIT_COL0) && (oldType != newType)) { GLvoid *src = (oldType == GL_UNSIGNED_BYTE) ? (GLvoid *) span->array->color.sz1.rgba : (GLvoid *) span->array->color.sz2.rgba; + assert(span->arrayMask & SPAN_RGBA); _mesa_convert_colors(oldType, src, newType, span->array->attribs[FRAG_ATTRIB_COL0], span->end, span->array->mask); - span->array->ChanType = newType; } + span->array->ChanType = newType; /* fragment programs/shaders may need specular, fog and Z coords */ - if (span->interpMask & SPAN_SPEC) + if ((inputsRead & FRAG_BIT_COL1) && (span->interpMask & SPAN_SPEC)) interpolate_specular(span); - if (span->interpMask & SPAN_FOG) + if ((inputsRead & FRAG_BIT_FOGC) && (span->interpMask & SPAN_FOG)) interpolate_fog(ctx, span); if (span->interpMask & SPAN_Z) _swrast_span_interpolate_z (ctx, span); - if (ctx->Shader.CurrentProgram && span->interpMask & SPAN_VARYING) + if ((inputsRead >= FRAG_BIT_VAR0) && (span->interpMask & SPAN_VARYING)) interpolate_varying(ctx, span); - if (ctx->FragmentProgram._Current && - (ctx->FragmentProgram._Current->Base.InputsRead & FRAG_BIT_WPOS)) + if (inputsRead & FRAG_BIT_WPOS) interpolate_wpos(ctx, span); /* Run fragment program/shader now */ -- cgit v1.2.3