summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Whitwell <keith@tungstengraphics.com>2005-05-04 11:44:44 +0000
committerKeith Whitwell <keith@tungstengraphics.com>2005-05-04 11:44:44 +0000
commit47b29f511a8e917c65536fde90397d54d2ad23d3 (patch)
treec8db61607defe55b4540af3e4614df9831d2021d
parentc3f764f7bb5a0571ddb0bc8b37aff9d663188d79 (diff)
Add a facility to route all rasterization through a fragment program
which is automatically generated to match the current texture environment state. Introduces a new value ctx->FragmentProgram._Active which is true when either _Enabled is true or there is such a fragment program ready to run. To test out on a driver running the software rasterizer, set MESA_TEX_PROG=t in the environment. It goes without saying that performance is lower for the software rasterizer in this mode.
-rw-r--r--src/mesa/main/context.c3
-rw-r--r--src/mesa/main/mtypes.h5
-rw-r--r--src/mesa/main/state.c13
-rw-r--r--src/mesa/main/texenvprogram.c254
-rw-r--r--src/mesa/main/texenvprogram.h39
-rw-r--r--src/mesa/sources1
-rw-r--r--src/mesa/swrast/s_aalinetemp.h4
-rw-r--r--src/mesa/swrast/s_context.c20
-rw-r--r--src/mesa/swrast/s_fragprog_to_c.c2
-rw-r--r--src/mesa/swrast/s_nvfragprog.c4
-rw-r--r--src/mesa/swrast/s_pointtemp.h2
-rw-r--r--src/mesa/swrast/s_span.c20
-rw-r--r--src/mesa/swrast/s_triangle.c4
-rw-r--r--src/mesa/tnl/t_vp_build.c27
14 files changed, 213 insertions, 185 deletions
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index acf5cc7d8b..087cc64c33 100644
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -1602,6 +1602,9 @@ _mesa_initialize_context( GLcontext *ctx,
ctx->TnlModule.SwapCount = 0;
#endif
+ ctx->_MaintainTexEnvProgram = (_mesa_getenv("MESA_TEX_PROG") != NULL);
+ ctx->_MaintainTnlProgram = (_mesa_getenv("MESA_TNL_PROG") != NULL);
+
return GL_TRUE;
}
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 4ece984f38..b50bf0e4f1 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -1829,7 +1829,9 @@ struct gl_fragment_program_state
{
GLboolean Enabled; /* GL_VERTEX_PROGRAM_NV */
GLboolean _Enabled; /* Really enabled? */
+ GLboolean _Active; /* Really really enabled? */
struct fragment_program *Current; /* ptr to currently bound program */
+ struct fragment_program *_Current; /* ptr to currently active program */
struct fp_machine Machine; /* machine state */
GLfloat Parameters[MAX_NV_FRAGMENT_PROGRAM_PARAMS][4]; /* Env params */
@@ -2652,6 +2654,9 @@ struct __GLcontextRec
struct fragment_program _TexEnvProgram; /**< Texture state as fragment program */
struct vertex_program _TnlProgram; /**< Fixed func TNL state as vertex program */
+ GLboolean _MaintainTexEnvProgram;
+ GLboolean _MaintainTnlProgram;
+
struct gl_occlusion_state Occlusion; /**< GL_ARB_occlusion_query */
struct gl_shader_objects_state ShaderObjects; /* GL_ARB_shader_objects */
diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c
index 3cb9044701..540d3ce993 100644
--- a/src/mesa/main/state.c
+++ b/src/mesa/main/state.c
@@ -933,6 +933,14 @@ update_program(GLcontext *ctx)
&& ctx->FragmentProgram.Current->Instructions;
ctx->ATIFragmentShader._Enabled = ctx->ATIFragmentShader.Enabled
&& ctx->ATIFragmentShader.Current->Instructions;
+
+ ctx->FragmentProgram._Current = ctx->FragmentProgram.Current;
+ ctx->FragmentProgram._Active = ctx->FragmentProgram._Enabled;
+
+ if (ctx->_MaintainTexEnvProgram && !ctx->FragmentProgram._Enabled) {
+ ctx->FragmentProgram._Current = &ctx->_TexEnvProgram;
+ ctx->FragmentProgram._Active = GL_TRUE;
+ }
}
@@ -984,6 +992,11 @@ _mesa_update_state( GLcontext *ctx )
if (new_state & (_NEW_ARRAY | _NEW_PROGRAM))
update_arrays( ctx );
+ if (ctx->_MaintainTexEnvProgram) {
+ if (new_state & (_NEW_TEXTURE | _DD_NEW_SEPARATE_SPECULAR))
+ _mesa_UpdateTexEnvProgram(ctx);
+ }
+
/* ctx->_NeedEyeCoords is now up to date.
*
* If the truth value of this variable has changed, update for the
diff --git a/src/mesa/main/texenvprogram.c b/src/mesa/main/texenvprogram.c
index 448c577b79..187526e677 100644
--- a/src/mesa/main/texenvprogram.c
+++ b/src/mesa/main/texenvprogram.c
@@ -37,7 +37,7 @@
#include "shader/arbfragparse.h"
-#define DISASSEM 1
+#define DISASSEM 0
/* Use uregs to represent registers internally, translate to Mesa's
* expected formats on emit.
@@ -76,30 +76,17 @@ const static struct ureg undef = {
#define Z 2
#define W 3
-#define MAX_CONSTANT 32
-
/* State used to build the fragment program:
*/
struct texenv_fragment_program {
- struct fragment_program *prog;
+ struct fragment_program *program;
GLcontext *ctx;
- GLfloat constant[MAX_CONSTANT][4];
- GLuint constant_flags[MAX_CONSTANT];
- GLuint nr_constants;
-
GLuint temp_flag; /* Tracks temporary regs which are in
* use.
*/
- struct {
- GLuint reg; /* Hardware constant idx */
- const GLfloat *values; /* Pointer to tracked values */
- } param[MAX_CONSTANT];
- GLuint nr_params;
-
-
GLboolean error;
struct ureg src_texture; /* Reg containing sampled texture color,
@@ -167,22 +154,40 @@ static void release_temps( struct texenv_fragment_program *p )
}
-static struct ureg emit_decl( struct texenv_fragment_program *p,
- GLuint type, GLuint nr )
+static struct ureg register_param6( struct texenv_fragment_program *p,
+ GLint s0,
+ GLint s1,
+ GLint s2,
+ GLint s3,
+ GLint s4,
+ GLint s5)
{
- struct ureg reg = make_ureg(type, nr);
+ GLint tokens[6];
+ GLuint idx;
+ tokens[0] = s0;
+ tokens[1] = s1;
+ tokens[2] = s2;
+ tokens[3] = s3;
+ tokens[4] = s4;
+ tokens[5] = s5;
+ idx = _mesa_add_state_reference( p->program->Parameters, tokens );
+ return make_ureg(PROGRAM_STATE_VAR, idx);
+}
- if (type == PROGRAM_INPUT) {
- p->prog->InputsRead |= 1<<nr;
- }
- else {
- /* Other ???
- */
- }
- return reg;
+#define register_param1(p,s0) register_param6(p,s0,0,0,0,0,0)
+#define register_param2(p,s0,s1) register_param6(p,s0,s1,0,0,0,0)
+#define register_param3(p,s0,s1,s2) register_param6(p,s0,s1,s2,0,0,0)
+#define register_param4(p,s0,s1,s2,s3) register_param6(p,s0,s1,s2,s3,0,0)
+
+
+static struct ureg register_input( struct texenv_fragment_program *p, GLuint input )
+{
+ p->program->InputsRead |= (1<<input);
+ return make_ureg(PROGRAM_INPUT, input);
}
+
static void emit_arg( struct fp_src_register *reg,
struct ureg ureg )
{
@@ -214,15 +219,15 @@ emit_op(struct texenv_fragment_program *p,
struct ureg src1,
struct ureg src2 )
{
- GLuint nr = p->prog->Base.NumInstructions++;
- struct fp_instruction *inst = &p->prog->Instructions[nr];
+ GLuint nr = p->program->Base.NumInstructions++;
+ struct fp_instruction *inst = &p->program->Instructions[nr];
memset(inst, 0, sizeof(*inst));
inst->Opcode = op;
- if (!is_undef(src0)) emit_arg( &inst->SrcReg[0], src0 );
- if (!is_undef(src1)) emit_arg( &inst->SrcReg[1], src1 );
- if (!is_undef(src2)) emit_arg( &inst->SrcReg[2], src2 );
+ emit_arg( &inst->SrcReg[0], src0 );
+ emit_arg( &inst->SrcReg[1], src1 );
+ emit_arg( &inst->SrcReg[2], src2 );
inst->Saturate = saturate;
@@ -233,17 +238,17 @@ emit_op(struct texenv_fragment_program *p,
static struct ureg emit_arith( struct texenv_fragment_program *p,
- GLuint op,
- struct ureg dest,
- GLuint mask,
- GLuint saturate,
- struct ureg src0,
- struct ureg src1,
- struct ureg src2 )
+ GLuint op,
+ struct ureg dest,
+ GLuint mask,
+ GLuint saturate,
+ struct ureg src0,
+ struct ureg src1,
+ struct ureg src2 )
{
emit_op(p, op, dest, mask, saturate, src0, src1, src2);
- p->prog->NumAluInstructions++;
+ p->program->NumAluInstructions++;
return dest;
}
@@ -265,99 +270,39 @@ static struct ureg emit_texld( struct texenv_fragment_program *p,
inst->TexSrcIdx = tex_idx;
inst->TexSrcUnit = tex_unit;
- p->prog->NumTexInstructions++;
+ p->program->NumTexInstructions++;
if (coord.file != PROGRAM_INPUT &&
- (coord.idx < VERT_ATTRIB_TEX0 ||
- coord.idx > VERT_ATTRIB_TEX7)) {
- p->prog->NumTexIndirections++;
+ (coord.idx < FRAG_ATTRIB_TEX0 ||
+ coord.idx > FRAG_ATTRIB_TEX7)) {
+ p->program->NumTexIndirections++;
}
return dest;
}
-static struct ureg emit_const1f( struct texenv_fragment_program *p, GLfloat c0 )
-{
- GLint reg, idx;
-
- for (reg = 0; reg < MAX_CONSTANT; reg++) {
- for (idx = 0; idx < 4; idx++) {
- if (!(p->constant_flags[reg] & (1<<idx)) ||
- p->constant[reg][idx] == c0) {
- p->constant[reg][idx] = c0;
- p->constant_flags[reg] |= 1<<idx;
- if (reg+1 > p->nr_constants) p->nr_constants = reg+1;
- return swizzle1(make_ureg(PROGRAM_LOCAL_PARAM, reg),idx);
- }
- }
- }
-
- fprintf(stderr, "%s: out of constants\n", __FUNCTION__);
- p->error = 1;
- return undef;
-}
-
-static struct ureg emit_const2f( struct texenv_fragment_program *p,
- GLfloat c0, GLfloat c1 )
+static struct ureg register_const4f( struct texenv_fragment_program *p,
+ GLfloat s0,
+ GLfloat s1,
+ GLfloat s2,
+ GLfloat s3)
{
- GLint reg, idx;
-
- for (reg = 0; reg < MAX_CONSTANT; reg++) {
- if (p->constant_flags[reg] == 0xf)
- continue;
- for (idx = 0; idx < 3; idx++) {
- if (!(p->constant_flags[reg] & (3<<idx))) {
- p->constant[reg][idx] = c0;
- p->constant[reg][idx+1] = c1;
- p->constant_flags[reg] |= 3<<idx;
- if (reg+1 > p->nr_constants) p->nr_constants = reg+1;
- return swizzle(make_ureg(PROGRAM_LOCAL_PARAM, reg),idx,idx+1,idx,idx+1);
- }
- }
- }
-
- fprintf(stderr, "%s: out of constants\n", __FUNCTION__);
- p->error = 1;
- return undef;
+ GLfloat values[4];
+ GLuint idx;
+ values[0] = s0;
+ values[1] = s1;
+ values[2] = s2;
+ values[3] = s3;
+ idx = _mesa_add_unnamed_constant( p->program->Parameters, values );
+ return make_ureg(PROGRAM_STATE_VAR, idx);
}
+#define register_const1f(p, s0) register_const4f(p, s0, 0, 0, 1)
+#define register_const2f(p, s0, s1) register_const4f(p, s0, s1, 0, 1)
+#define register_const3f(p, s0, s1, s2) register_const4f(p, s0, s1, s2, 1)
-static struct ureg emit_const4f( struct texenv_fragment_program *p,
- GLfloat c0, GLfloat c1, GLfloat c2, GLfloat c3 )
-{
- GLint reg;
-
- for (reg = 0; reg < MAX_CONSTANT; reg++) {
- if (p->constant_flags[reg] == 0xf &&
- p->constant[reg][0] == c0 &&
- p->constant[reg][1] == c1 &&
- p->constant[reg][2] == c2 &&
- p->constant[reg][3] == c3) {
- return make_ureg(PROGRAM_LOCAL_PARAM, reg);
- }
- else if (p->constant_flags[reg] == 0) {
- p->constant[reg][0] = c0;
- p->constant[reg][1] = c1;
- p->constant[reg][2] = c2;
- p->constant[reg][3] = c3;
- p->constant_flags[reg] = 0xf;
- if (reg+1 > p->nr_constants) p->nr_constants = reg+1;
- return make_ureg(PROGRAM_LOCAL_PARAM, reg);
- }
- }
-
- fprintf(stderr, "%s: out of constants\n", __FUNCTION__);
- p->error = 1;
- return undef;
-}
-
-
-static struct ureg emit_const4fv( struct texenv_fragment_program *p, const GLfloat *c )
-{
- return emit_const4f( p, c[0], c[1], c[2], c[3] );
-}
@@ -393,9 +338,7 @@ static struct ureg get_source( struct texenv_fragment_program *p,
if (is_undef(p->src_texture)) {
GLuint dim = translate_tex_src_bit( p, p->ctx->Texture.Unit[unit]._ReallyEnabled);
- struct ureg texcoord = emit_decl(p,
- PROGRAM_INPUT,
- VERT_ATTRIB_TEX0+unit);
+ struct ureg texcoord = register_input(p, FRAG_ATTRIB_TEX0+unit);
struct ureg tmp = get_temp( p );
/* TODO: Use D0_MASK_XY where possible.
@@ -420,14 +363,15 @@ static struct ureg get_source( struct texenv_fragment_program *p,
}
case GL_CONSTANT:
- return emit_const4fv( p, p->ctx->Texture.Unit[unit].EnvColor );
+ return register_param2(p, STATE_TEXENV_COLOR, unit);
case GL_PRIMARY_COLOR:
- return emit_decl(p, PROGRAM_INPUT, VERT_ATTRIB_COLOR0);
+ return register_input(p, FRAG_ATTRIB_COL0);
case GL_PREVIOUS:
default:
- return emit_decl(p,
- p->src_previous.file,
- p->src_previous.idx);
+ if (is_undef(p->src_previous))
+ return register_input(p, FRAG_ATTRIB_COL0);
+ else
+ return p->src_previous;
}
}
@@ -448,7 +392,7 @@ static struct ureg emit_combine_source( struct texenv_fragment_program *p,
* Emit tmp = 1.0 - arg.xyzw
*/
arg = get_temp( p );
- one = emit_const1f(p, 1);
+ one = register_const1f(p, 1.0);
return emit_arith( p, FP_OPCODE_SUB, arg, mask, 0, one, src, undef);
case GL_SRC_ALPHA:
@@ -461,7 +405,7 @@ static struct ureg emit_combine_source( struct texenv_fragment_program *p,
* Emit tmp = 1.0 - arg.wwww
*/
arg = get_temp( p );
- one = emit_const1f(p, 1);
+ one = register_const1f(p, 1.0);
return emit_arith( p, FP_OPCODE_SUB, arg, mask, 0,
one, swizzle1(src, W), undef);
case GL_SRC_COLOR:
@@ -559,7 +503,7 @@ static struct ureg emit_combine( struct texenv_fragment_program *p,
/* tmp = arg0 + arg1
* result = tmp + -.5
*/
- tmp = emit_const1f(p, .5);
+ tmp = register_const1f(p, .5);
tmp = swizzle1(tmp,X);
emit_arith( p, FP_OPCODE_ADD, dest, mask, 0, src[0], src[1], undef );
emit_arith( p, FP_OPCODE_SUB, dest, mask, saturate, dest, tmp, undef );
@@ -578,8 +522,8 @@ static struct ureg emit_combine( struct texenv_fragment_program *p,
case GL_DOT3_RGB: {
struct ureg tmp0 = get_temp( p );
struct ureg tmp1 = get_temp( p );
- struct ureg neg1 = emit_const1f(p, -1);
- struct ureg two = emit_const1f(p, 2);
+ struct ureg neg1 = register_const1f(p, -1);
+ struct ureg two = register_const1f(p, 2);
/* tmp0 = 2*src0 - 1
* tmp1 = 2*src1 - 1
@@ -610,7 +554,7 @@ static struct ureg get_dest( struct texenv_fragment_program *p, int unit )
else if (unit != p->last_tex_stage)
return get_temp( p );
else
- return make_ureg(PROGRAM_OUTPUT, VERT_ATTRIB_COLOR0);
+ return make_ureg(PROGRAM_OUTPUT, FRAG_OUTPUT_COLR);
}
@@ -684,11 +628,11 @@ static struct ureg emit_texenv( struct texenv_fragment_program *p, int unit )
*/
if (alpha_shift || rgb_shift) {
if (rgb_shift == alpha_shift) {
- shift = emit_const1f(p, 1<<rgb_shift);
+ shift = register_const1f(p, 1<<rgb_shift);
shift = swizzle1(shift,X);
}
else {
- shift = emit_const2f(p, 1<<rgb_shift, 1<<alpha_shift);
+ shift = register_const2f(p, 1<<rgb_shift, 1<<alpha_shift);
shift = swizzle(shift,X,X,X,Y);
}
return emit_arith( p, FP_OPCODE_MUL, dest, WRITEMASK_XYZW,
@@ -704,22 +648,23 @@ void _mesa_UpdateTexEnvProgram( GLcontext *ctx )
GLuint unit;
struct ureg cf, out;
+ if (ctx->FragmentProgram._Enabled)
+ return;
+
p.ctx = ctx;
- p.prog = &ctx->_TexEnvProgram;
+ p.program = &ctx->_TexEnvProgram;
- if (p.prog->Instructions == NULL) {
- p.prog->Instructions = MALLOC(sizeof(struct fp_instruction) * 100);
+ if (p.program->Instructions == NULL) {
+ p.program->Instructions = MALLOC(sizeof(struct fp_instruction) * 100);
}
- p.prog->Base.NumInstructions = 0;
- p.prog->NumTexIndirections = 1; /* correct? */
- p.prog->NumTexInstructions = 0;
- p.prog->NumAluInstructions = 0;
-
- memset( p.constant_flags, 0, sizeof(p.constant_flags) );
+ p.program->Base.NumInstructions = 0;
+ p.program->NumTexIndirections = 1; /* correct? */
+ p.program->NumTexInstructions = 0;
+ p.program->NumAluInstructions = 0;
p.src_texture = undef;
- p.src_previous = make_ureg(PROGRAM_INPUT, VERT_ATTRIB_COLOR0);
+ p.src_previous = undef;
p.last_tex_stage = 0;
if (ctx->Texture._EnabledUnits) {
@@ -738,12 +683,12 @@ void _mesa_UpdateTexEnvProgram( GLcontext *ctx )
}
cf = get_source( &p, GL_PREVIOUS, 0 );
- out = make_ureg( PROGRAM_OUTPUT, VERT_ATTRIB_COLOR0 );
+ out = make_ureg( PROGRAM_OUTPUT, FRAG_OUTPUT_COLR );
if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) {
/* Emit specular add.
*/
- struct ureg s = emit_decl(&p, PROGRAM_INPUT, VERT_ATTRIB_COLOR1);
+ struct ureg s = register_input(&p, FRAG_ATTRIB_COL1);
emit_arith( &p, FP_OPCODE_ADD, out, WRITEMASK_XYZ, 0, cf, s, undef );
}
else if (memcmp(&cf, &out, sizeof(cf)) != 0) {
@@ -753,18 +698,23 @@ void _mesa_UpdateTexEnvProgram( GLcontext *ctx )
emit_arith( &p, FP_OPCODE_MOV, out, WRITEMASK_XYZW, 0, cf, undef, undef );
}
- if (p.prog->NumTexIndirections > ctx->Const.MaxFragmentProgramTexIndirections)
+ /* Finish up:
+ */
+ emit_arith( &p, FP_OPCODE_END, undef, WRITEMASK_XYZW, 0, undef, undef, undef);
+
+
+ if (p.program->NumTexIndirections > ctx->Const.MaxFragmentProgramTexIndirections)
program_error(&p, "Exceeded max nr indirect texture lookups");
- if (p.prog->NumTexInstructions > ctx->Const.MaxFragmentProgramTexInstructions)
+ if (p.program->NumTexInstructions > ctx->Const.MaxFragmentProgramTexInstructions)
program_error(&p, "Exceeded max TEX instructions");
- if (p.prog->NumAluInstructions > ctx->Const.MaxFragmentProgramAluInstructions)
+ if (p.program->NumAluInstructions > ctx->Const.MaxFragmentProgramAluInstructions)
program_error(&p, "Exceeded max ALU instructions");
#if DISASSEM
- _mesa_debug_fp_inst(p.prog->NumTexInstructions + p.prog->NumAluInstructions,
- p.prog->Instructions);
+ _mesa_debug_fp_inst(p.program->NumTexInstructions + p.program->NumAluInstructions,
+ p.program->Instructions);
_mesa_printf("\n");
#endif
}
diff --git a/src/mesa/main/texenvprogram.h b/src/mesa/main/texenvprogram.h
new file mode 100644
index 0000000000..bca05d00e0
--- /dev/null
+++ b/src/mesa/main/texenvprogram.h
@@ -0,0 +1,39 @@
+/**
+ * \file texenvprogram.h
+ * Texture state management.
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 5.1
+ *
+ * Copyright (C) 1999-2002 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 TEXENVPROGRAM_H
+#define TEXENVPROGRAM_H
+
+
+#include "mtypes.h"
+
+extern void _mesa_UpdateTexEnvProgram( GLcontext *ctx );
+
+#endif
diff --git a/src/mesa/sources b/src/mesa/sources
index e461840a9e..54cd290524 100644
--- a/src/mesa/sources
+++ b/src/mesa/sources
@@ -46,6 +46,7 @@ MAIN_SOURCES = \
main/texcompress.c \
main/texcompress_s3tc.c \
main/texcompress_fxt1.c \
+ main/texenvprogram.c \
main/texformat.c \
main/teximage.c \
main/texobj.c \
diff --git a/src/mesa/swrast/s_aalinetemp.h b/src/mesa/swrast/s_aalinetemp.h
index aa78ef7b59..4a1e1ebda2 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._Enabled) {
+ if (ctx->FragmentProgram._Active) {
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._Enabled) {
+ if (ctx->FragmentProgram._Active) {
invQ = 1.0F;
}
else {
diff --git a/src/mesa/swrast/s_context.c b/src/mesa/swrast/s_context.c
index b923f0a673..f6dcdbb964 100644
--- a/src/mesa/swrast/s_context.c
+++ b/src/mesa/swrast/s_context.c
@@ -104,7 +104,7 @@ _swrast_update_rasterflags( GLcontext *ctx )
rasterMask |= MULTI_DRAW_BIT; /* all color index bits disabled */
}
- if (ctx->FragmentProgram._Enabled) {
+ if (ctx->FragmentProgram._Active) {
rasterMask |= FRAGPROG_BIT;
}
@@ -161,7 +161,7 @@ _swrast_update_fog_hint( GLcontext *ctx )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
swrast->_PreferPixelFog = (!swrast->AllowVertexFog ||
- ctx->FragmentProgram._Enabled ||
+ ctx->FragmentProgram._Active ||
(ctx->Hint.Fog == GL_NICEST &&
swrast->AllowPixelFog));
}
@@ -202,10 +202,10 @@ _swrast_update_fog_state( GLcontext *ctx )
/* 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) {
+ if (ctx->FragmentProgram._Active) {
+ if (ctx->FragmentProgram._Current->Base.Target==GL_FRAGMENT_PROGRAM_ARB) {
const struct fragment_program *p
- = (struct fragment_program *) ctx->FragmentProgram.Current;
+ = (struct fragment_program *) ctx->FragmentProgram._Current;
if (p->FogOption != GL_NONE) {
swrast->_FogEnabled = GL_TRUE;
swrast->_FogMode = p->FogOption;
@@ -226,8 +226,8 @@ _swrast_update_fog_state( GLcontext *ctx )
static void
_swrast_update_fragment_program( GLcontext *ctx )
{
- if (ctx->FragmentProgram._Enabled) {
- struct fragment_program *program = ctx->FragmentProgram.Current;
+ if (ctx->FragmentProgram._Active) {
+ struct fragment_program *program = ctx->FragmentProgram._Current;
_mesa_load_state_parameters(ctx, program->Parameters);
}
}
@@ -295,7 +295,7 @@ _swrast_validate_triangle( GLcontext *ctx,
if (ctx->Texture._EnabledUnits == 0
&& NEED_SECONDARY_COLOR(ctx)
- && !ctx->FragmentProgram._Enabled) {
+ && !ctx->FragmentProgram._Active) {
/* separate specular color, but no texture */
swrast->SpecTriangle = swrast->Triangle;
swrast->Triangle = _swrast_add_spec_terms_triangle;
@@ -318,7 +318,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._Active) {
swrast->SpecLine = swrast->Line;
swrast->Line = _swrast_add_spec_terms_line;
}
@@ -341,7 +341,7 @@ _swrast_validate_point( GLcontext *ctx, const SWvertex *v0 )
if (ctx->Texture._EnabledUnits == 0
&& NEED_SECONDARY_COLOR(ctx)
- && !ctx->FragmentProgram._Enabled) {
+ && !ctx->FragmentProgram._Active) {
swrast->SpecPoint = swrast->Point;
swrast->Point = _swrast_add_spec_terms_point;
}
diff --git a/src/mesa/swrast/s_fragprog_to_c.c b/src/mesa/swrast/s_fragprog_to_c.c
index fa66969330..1953e8c73c 100644
--- a/src/mesa/swrast/s_fragprog_to_c.c
+++ b/src/mesa/swrast/s_fragprog_to_c.c
@@ -808,7 +808,7 @@ static void translate_program( struct fragment_program *p )
void _swrast_translate_program( GLcontext *ctx )
{
- struct fragment_program *p = ctx->FragmentProgram.Current;
+ struct fragment_program *p = ctx->FragmentProgram._Current;
if (p) {
p->c_strlen = 0;
diff --git a/src/mesa/swrast/s_nvfragprog.c b/src/mesa/swrast/s_nvfragprog.c
index 2fea568cc9..51d36c0a2b 100644
--- a/src/mesa/swrast/s_nvfragprog.c
+++ b/src/mesa/swrast/s_nvfragprog.c
@@ -1410,7 +1410,7 @@ init_machine( GLcontext *ctx, struct fp_machine *machine,
void
_swrast_exec_fragment_program( GLcontext *ctx, struct sw_span *span )
{
- const struct fragment_program *program = ctx->FragmentProgram.Current;
+ const struct fragment_program *program = ctx->FragmentProgram._Current;
GLuint i;
ctx->_CurrentProgram = GL_FRAGMENT_PROGRAM_ARB; /* or NV, doesn't matter */
@@ -1418,7 +1418,7 @@ _swrast_exec_fragment_program( GLcontext *ctx, struct sw_span *span )
for (i = 0; i < span->end; i++) {
if (span->array->mask[i]) {
init_machine(ctx, &ctx->FragmentProgram.Machine,
- ctx->FragmentProgram.Current, span, i);
+ ctx->FragmentProgram._Current, span, i);
#ifdef USE_TCC
if (!_swrast_execute_codegen_program(ctx, program, ~0,
diff --git a/src/mesa/swrast/s_pointtemp.h b/src/mesa/swrast/s_pointtemp.h
index ef48d239ec..b0c110f300 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;
- if (ctx->FragmentProgram._Enabled) {
+ if (ctx->FragmentProgram._Active) {
/* 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 a541b66ceb..e6afee1eaa 100644
--- a/src/mesa/swrast/s_span.c
+++ b/src/mesa/swrast/s_span.c
@@ -128,7 +128,7 @@ _swrast_span_default_texcoords( GLcontext *ctx, struct sw_span *span )
GLuint i;
for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
const GLfloat *tc = ctx->Current.RasterTexCoords[i];
- if (ctx->FragmentProgram._Enabled || ctx->ATIFragmentShader._Enabled) {
+ if (ctx->FragmentProgram._Active || ctx->ATIFragmentShader._Enabled) {
COPY_4V(span->tex[i], tc);
}
else if (tc[3] > 0.0F) {
@@ -406,7 +406,7 @@ interpolate_texcoords(GLcontext *ctx, struct sw_span *span)
if (obj) {
const struct gl_texture_image *img = obj->Image[0][obj->BaseLevel];
needLambda = (obj->MinFilter != obj->MagFilter)
- || ctx->FragmentProgram._Enabled;
+ || ctx->FragmentProgram._Active;
texW = img->WidthScale;
texH = img->HeightScale;
}
@@ -431,7 +431,7 @@ interpolate_texcoords(GLcontext *ctx, struct sw_span *span)
GLfloat r = span->tex[u][2];
GLfloat q = span->tex[u][3];
GLuint i;
- if (ctx->FragmentProgram._Enabled) {
+ if (ctx->FragmentProgram._Active) {
/* do perspective correction but don't divide s, t, r by q */
const GLfloat dwdx = span->dwdx;
GLfloat w = span->w;
@@ -482,7 +482,7 @@ interpolate_texcoords(GLcontext *ctx, struct sw_span *span)
GLfloat r = span->tex[u][2];
GLfloat q = span->tex[u][3];
GLuint i;
- if (ctx->FragmentProgram._Enabled) {
+ if (ctx->FragmentProgram._Active) {
/* do perspective correction but don't divide s, t, r by q */
const GLfloat dwdx = span->dwdx;
GLfloat w = span->w;
@@ -540,7 +540,7 @@ interpolate_texcoords(GLcontext *ctx, struct sw_span *span)
if (obj) {
const struct gl_texture_image *img = obj->Image[0][obj->BaseLevel];
needLambda = (obj->MinFilter != obj->MagFilter)
- || ctx->FragmentProgram._Enabled;
+ || ctx->FragmentProgram._Active;
texW = (GLfloat) img->WidthScale;
texH = (GLfloat) img->HeightScale;
}
@@ -565,7 +565,7 @@ interpolate_texcoords(GLcontext *ctx, struct sw_span *span)
GLfloat r = span->tex[0][2];
GLfloat q = span->tex[0][3];
GLuint i;
- if (ctx->FragmentProgram._Enabled) {
+ if (ctx->FragmentProgram._Active) {
/* do perspective correction but don't divide s, t, r by q */
const GLfloat dwdx = span->dwdx;
GLfloat w = span->w;
@@ -616,7 +616,7 @@ interpolate_texcoords(GLcontext *ctx, struct sw_span *span)
GLfloat r = span->tex[0][2];
GLfloat q = span->tex[0][3];
GLuint i;
- if (ctx->FragmentProgram._Enabled) {
+ if (ctx->FragmentProgram._Active) {
/* do perspective correction but don't divide s, t, r by q */
const GLfloat dwdx = span->dwdx;
GLfloat w = span->w;
@@ -1174,7 +1174,7 @@ _swrast_write_rgba_span( GLcontext *ctx, struct sw_span *span)
interpolate_fog(ctx, span);
/* Compute fragment colors with fragment program or texture lookups */
- if (ctx->FragmentProgram._Enabled)
+ if (ctx->FragmentProgram._Active)
/* XXX interpolate depth values here??? */
_swrast_exec_fragment_program( ctx, span );
else if (ctx->ATIFragmentShader._Enabled)
@@ -1252,7 +1252,7 @@ _swrast_write_rgba_span( GLcontext *ctx, struct sw_span *span)
if (span->interpMask & SPAN_FOG)
interpolate_fog(ctx, span);
- if (ctx->FragmentProgram._Enabled)
+ if (ctx->FragmentProgram._Active)
_swrast_exec_fragment_program( ctx, span );
else if (ctx->ATIFragmentShader._Enabled)
_swrast_exec_fragment_shader( ctx, span );
@@ -1262,7 +1262,7 @@ _swrast_write_rgba_span( GLcontext *ctx, struct sw_span *span)
ASSERT(span->arrayMask & SPAN_RGBA);
- if (!ctx->FragmentProgram._Enabled) {
+ if (!ctx->FragmentProgram._Active) {
/* Add base and specular colors */
if (ctx->Fog.ColorSumEnabled ||
(ctx->Light.Enabled &&
diff --git a/src/mesa/swrast/s_triangle.c b/src/mesa/swrast/s_triangle.c
index c236e52570..4533980455 100644
--- a/src/mesa/swrast/s_triangle.c
+++ b/src/mesa/swrast/s_triangle.c
@@ -1075,7 +1075,7 @@ _swrast_choose_triangle( GLcontext *ctx )
}
}
- if (ctx->Texture._EnabledCoordUnits || ctx->FragmentProgram._Enabled) {
+ if (ctx->Texture._EnabledCoordUnits || ctx->FragmentProgram._Active) {
/* 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;
@@ -1090,7 +1090,7 @@ _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._Active
&& ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT
&& texObj2D->WrapS == GL_REPEAT
&& texObj2D->WrapT == GL_REPEAT
diff --git a/src/mesa/tnl/t_vp_build.c b/src/mesa/tnl/t_vp_build.c
index eefede7913..9034fc7712 100644
--- a/src/mesa/tnl/t_vp_build.c
+++ b/src/mesa/tnl/t_vp_build.c
@@ -367,6 +367,10 @@ static void emit_matrix_transform_vec4( struct tnl_program *p,
emit_op2(p, VP_OPCODE_DP4, dest, WRITEMASK_W, src, mat[3]);
}
+/* This version is much easier to implement if writemasks are not
+ * supported natively on the target or (like SSE), the target doesn't
+ * have a clean/obvious dotproduct implementation.
+ */
static void emit_transpose_matrix_transform_vec4( struct tnl_program *p,
struct ureg dest,
const struct ureg *mat,
@@ -692,14 +696,12 @@ static void build_lighting( struct tnl_program *p )
count++;
if (light->EyePosition[3] == 0) {
- /* Can used precomputed constants in this case:
+ /* Can used precomputed constants in this case.
+ * Attenuation never applies to infinite lights.
*/
VPpli = register_param3(p, STATE_LIGHT, i,
STATE_POSITION_NORMALIZED);
half = register_param3(p, STATE_LIGHT, i, STATE_HALF);
-
- /* Spot attenuation maybe applies to this case? Could
- * precompute if so? */
}
else {
struct ureg Ppli = register_param3(p, STATE_LIGHT, i,
@@ -767,7 +769,7 @@ static void build_lighting( struct tnl_program *p )
if (!is_undef(att))
emit_op2(p, VP_OPCODE_MUL, lit, 0, lit, att);
-
+
if (count == nr_lights) {
if (separate) {
res0 = register_output( p, VERT_RESULT_COL0 );
@@ -1082,9 +1084,15 @@ static void build_pointsize( struct tnl_program *p )
}
+static void build_passthrough( struct tnl_program *p, GLuint inputs )
+{
+}
+
+
void _tnl_UpdateFixedFunctionProgram( GLcontext *ctx )
{
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
struct tnl_program p;
if (ctx->VertexProgram._Enabled)
@@ -1136,6 +1144,15 @@ void _tnl_UpdateFixedFunctionProgram( GLcontext *ctx )
if (ctx->Point._Attenuated)
build_pointsize(&p);
+ /* Is there a need to copy inputs to outputs? The software
+ * implementation might do this more efficiently by just assigning
+ * the missing results to point at input arrays.
+ */
+ if (/* tnl->vp_copy_inputs && */
+ (tnl->render_inputs & ~p.program->OutputsWritten)) {
+ build_passthrough(&p, tnl->render_inputs);
+ }
+
/* Finish up:
*/