diff options
author | Luca Barbieri <luca@luca-barbieri.com> | 2010-08-26 18:09:41 +0200 |
---|---|---|
committer | Luca Barbieri <luca@luca-barbieri.com> | 2010-09-05 18:01:36 +0200 |
commit | 3a9cb5e59b676b6148c50907ce6eef5441677e36 (patch) | |
tree | 4f535b38e13e220e8f2a3be27100873e63ea48c4 | |
parent | 123bb110852739dffadcc81ad80b005b1c4f586d (diff) |
mesa: respect color clamping in texenv programs (v2)
Changes in v2:
- Fix attributes other than vertex color sometimes getting clamped
-rw-r--r-- | src/mesa/drivers/dri/i915/i915_fragprog.c | 2 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_program.c | 2 | ||||
-rw-r--r-- | src/mesa/main/state.c | 2 | ||||
-rw-r--r-- | src/mesa/main/texenvprogram.c | 24 | ||||
-rw-r--r-- | src/mesa/program/arbprogparse.c | 5 | ||||
-rw-r--r-- | src/mesa/program/prog_statevars.c | 33 | ||||
-rw-r--r-- | src/mesa/program/prog_statevars.h | 1 | ||||
-rw-r--r-- | src/mesa/program/programopt.c | 5 | ||||
-rw-r--r-- | src/mesa/program/programopt.h | 2 |
9 files changed, 57 insertions, 19 deletions
diff --git a/src/mesa/drivers/dri/i915/i915_fragprog.c b/src/mesa/drivers/dri/i915/i915_fragprog.c index 4a2e6209d0..ea727523e8 100644 --- a/src/mesa/drivers/dri/i915/i915_fragprog.c +++ b/src/mesa/drivers/dri/i915/i915_fragprog.c @@ -1294,7 +1294,7 @@ i915ProgramStringNotify(GLcontext * ctx, */ if (p->FragProg.FogOption) { /* add extra instructions to do fog, then turn off FogOption field */ - _mesa_append_fog_code(ctx, &p->FragProg); + _mesa_append_fog_code(ctx, &p->FragProg, TRUE); p->FragProg.FogOption = GL_NONE; } } diff --git a/src/mesa/drivers/dri/i965/brw_program.c b/src/mesa/drivers/dri/i965/brw_program.c index bc152204a4..9537a03538 100644 --- a/src/mesa/drivers/dri/i965/brw_program.c +++ b/src/mesa/drivers/dri/i965/brw_program.c @@ -134,7 +134,7 @@ static GLboolean brwProgramStringNotify( GLcontext *ctx, brw_fragment_program_const(brw->fragment_program); if (fprog->FogOption) { - _mesa_append_fog_code(ctx, fprog); + _mesa_append_fog_code(ctx, fprog, TRUE); fprog->FogOption = GL_NONE; } diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index b71d068f4d..0cfb2bb236 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -596,7 +596,7 @@ _mesa_update_state_locked( GLcontext *ctx ) if (ctx->FragmentProgram._MaintainTexEnvProgram) { prog_flags |= (_NEW_BUFFERS | _NEW_TEXTURE | _NEW_FOG | _NEW_ARRAY | _NEW_LIGHT | _NEW_POINT | _NEW_RENDERMODE | - _NEW_PROGRAM); + _NEW_PROGRAM | _NEW_FRAG_CLAMP); } if (ctx->VertexProgram._MaintainTnlProgram) { prog_flags |= (_NEW_ARRAY | _NEW_TEXTURE | _NEW_TEXTURE_MATRIX | diff --git a/src/mesa/main/texenvprogram.c b/src/mesa/main/texenvprogram.c index 640d55da40..c4677f7846 100644 --- a/src/mesa/main/texenvprogram.c +++ b/src/mesa/main/texenvprogram.c @@ -100,6 +100,9 @@ struct state_key { GLuint inputs_available:12; GLuint num_draw_buffers:4; + /* enabling clamping throughout the shader, see ClampFragmentColor */ + GLuint clamp_color:1; + /* NOTE: This array of structs must be last! (see "keySize" below) */ struct { GLuint enabled:1; @@ -491,6 +494,9 @@ static GLuint make_state_key( GLcontext *ctx, struct state_key *key ) key->inputs_available = (inputs_available & inputs_referenced); + /* _NEW_BUFFERS | _NEW_FRAG_CLAMP */ + key->clamp_color = ctx->Color._ClampFragmentColor; + /* compute size of state key, ignoring unused texture units */ keySize = sizeof(*key) - sizeof(key->unit) + key->nr_enabled_units * sizeof(key->unit[0]); @@ -722,7 +728,7 @@ static struct ureg register_input( struct texenv_fragment_program *p, GLuint inp } else { GLuint idx = frag_to_vert_attrib( input ); - return register_param3( p, STATE_INTERNAL, STATE_CURRENT_ATTRIB, idx ); + return register_param3( p, STATE_INTERNAL, STATE_CURRENT_ATTRIB_MAYBE_VP_CLAMPED, idx ); } } @@ -824,7 +830,7 @@ static struct ureg emit_texld( struct texenv_fragment_program *p, { struct prog_instruction *inst = emit_op( p, op, dest, destmask, - GL_TRUE, /* ARB_texture_float requires saturation here */ + p->state->clamp_color, /* ARB_texture_float requires saturation here */ coord, /* arg 0? */ undef, undef); @@ -1192,14 +1198,14 @@ emit_texenv(struct texenv_fragment_program *p, GLuint unit) if (rgb_shift) rgb_saturate = GL_FALSE; /* saturate after rgb shift */ else if (need_saturate(key->unit[unit].ModeRGB)) - rgb_saturate = GL_TRUE; + rgb_saturate = key->clamp_color; else rgb_saturate = GL_FALSE; if (alpha_shift) alpha_saturate = GL_FALSE; /* saturate after alpha shift */ else if (need_saturate(key->unit[unit].ModeA)) - alpha_saturate = GL_TRUE; + alpha_saturate = key->clamp_color; else alpha_saturate = GL_FALSE; @@ -1254,7 +1260,7 @@ emit_texenv(struct texenv_fragment_program *p, GLuint unit) */ if (alpha_shift || rgb_shift) { struct ureg shift; - GLboolean saturate = GL_TRUE; /* always saturate at this point */ + GLboolean saturate = key->clamp_color; /* always saturate at this point */ if (rgb_shift == alpha_shift) { shift = register_scalar_const(p, (GLfloat)(1<<rgb_shift)); @@ -1511,14 +1517,14 @@ create_new_program(GLcontext *ctx, struct state_key *key, /* Emit specular add. */ struct ureg s = register_input(&p, FRAG_ATTRIB_COL1); - emit_arith( &p, OPCODE_ADD, out, WRITEMASK_XYZ, 0, cf, s, undef ); - emit_arith( &p, OPCODE_MOV, out, WRITEMASK_W, 0, cf, undef, undef ); + emit_arith( &p, OPCODE_ADD, out, WRITEMASK_XYZ, key->clamp_color, cf, s, undef ); + emit_arith( &p, OPCODE_MOV, out, WRITEMASK_W, key->clamp_color, cf, undef, undef ); } else if (memcmp(&cf, &out, sizeof(cf)) != 0) { /* Will wind up in here if no texture enabled or a couple of * other scenarios (GL_REPLACE for instance). */ - emit_arith( &p, OPCODE_MOV, out, WRITEMASK_XYZW, 0, cf, undef, undef ); + emit_arith( &p, OPCODE_MOV, out, WRITEMASK_XYZW, key->clamp_color, cf, undef, undef ); } } /* Finish up: @@ -1559,7 +1565,7 @@ create_new_program(GLcontext *ctx, struct state_key *key, p.program->Base.NumInstructions); if (p.program->FogOption) { - _mesa_append_fog_code(ctx, p.program); + _mesa_append_fog_code(ctx, p.program, key->clamp_color); p.program->FogOption = GL_NONE; } diff --git a/src/mesa/program/arbprogparse.c b/src/mesa/program/arbprogparse.c index f834aaf568..2c67b29896 100644 --- a/src/mesa/program/arbprogparse.c +++ b/src/mesa/program/arbprogparse.c @@ -144,7 +144,10 @@ _mesa_parse_arb_fragment_program(GLcontext* ctx, GLenum target, * from the fragment shader. */ if (program->FogOption != GL_NONE) { - _mesa_append_fog_code(ctx, program); + /* XXX: we should somehow recompile this to remove clamping if disabled + * On the ATI driver, this is unclampled if fragment clamping is disabled + */ + _mesa_append_fog_code(ctx, program, GL_TRUE); program->FogOption = GL_NONE; } diff --git a/src/mesa/program/prog_statevars.c b/src/mesa/program/prog_statevars.c index ead3ece95d..6a52ec42b9 100644 --- a/src/mesa/program/prog_statevars.c +++ b/src/mesa/program/prog_statevars.c @@ -237,11 +237,17 @@ _mesa_fetch_state(GLcontext *ctx, const gl_state_index state[], { /* state[1] is the texture unit */ const GLuint unit = (GLuint) state[1]; - COPY_4V(value, ctx->Texture.Unit[unit].EnvColor); + if(ctx->Color._ClampFragmentColor) + COPY_4V(value, ctx->Texture.Unit[unit].EnvColor); + else + COPY_4V(value, ctx->Texture.Unit[unit].EnvColorUnclamped); } return; case STATE_FOG_COLOR: - COPY_4V(value, ctx->Fog.Color); + if(ctx->Color._ClampFragmentColor) + COPY_4V(value, ctx->Fog.Color); + else + COPY_4V(value, ctx->Fog.ColorUnclamped); return; case STATE_FOG_PARAMS: value[0] = ctx->Fog.Density; @@ -403,6 +409,23 @@ _mesa_fetch_state(GLcontext *ctx, const gl_state_index state[], } return; + case STATE_CURRENT_ATTRIB_MAYBE_VP_CLAMPED: + { + const GLuint idx = (GLuint) state[2]; + if(ctx->Light._ClampVertexColor + && (ctx->Current.Attrib == VERT_ATTRIB_COLOR0 + || ctx->Current.Attrib == VERT_ATTRIB_COLOR1)) + { + value[0] = CLAMP(ctx->Current.Attrib[idx][0], 0.0f, 1.0f); + value[1] = CLAMP(ctx->Current.Attrib[idx][1], 0.0f, 1.0f); + value[2] = CLAMP(ctx->Current.Attrib[idx][2], 0.0f, 1.0f); + value[3] = CLAMP(ctx->Current.Attrib[idx][3], 0.0f, 1.0f); + } + else + COPY_4V(value, ctx->Current.Attrib[idx]); + } + return; + case STATE_NORMAL_SCALE: ASSIGN_4V(value, ctx->_ModelViewInvScale, @@ -643,10 +666,12 @@ _mesa_program_state_flags(const gl_state_index state[STATE_LENGTH]) return _NEW_LIGHT; case STATE_TEXGEN: - case STATE_TEXENV_COLOR: return _NEW_TEXTURE; + case STATE_TEXENV_COLOR: + return _NEW_TEXTURE | _NEW_BUFFERS | _NEW_FRAG_CLAMP; case STATE_FOG_COLOR: + return _NEW_FOG | _NEW_BUFFERS | _NEW_FRAG_CLAMP; case STATE_FOG_PARAMS: return _NEW_FOG; @@ -684,6 +709,8 @@ _mesa_program_state_flags(const gl_state_index state[STATE_LENGTH]) switch (state[1]) { case STATE_CURRENT_ATTRIB: return _NEW_CURRENT_ATTRIB; + case STATE_CURRENT_ATTRIB_MAYBE_VP_CLAMPED: + return _NEW_CURRENT_ATTRIB | _NEW_LIGHT | _NEW_BUFFERS; case STATE_NORMAL_SCALE: return _NEW_MODELVIEW; diff --git a/src/mesa/program/prog_statevars.h b/src/mesa/program/prog_statevars.h index 1753471ffb..c0fe54eddb 100644 --- a/src/mesa/program/prog_statevars.h +++ b/src/mesa/program/prog_statevars.h @@ -105,6 +105,7 @@ typedef enum gl_state_index_ { STATE_INTERNAL, /* Mesa additions */ STATE_CURRENT_ATTRIB, /* ctx->Current vertex attrib value */ + STATE_CURRENT_ATTRIB_MAYBE_VP_CLAMPED, /* ctx->Current vertex attrib value after passthrough vertex processing */ STATE_NORMAL_SCALE, STATE_TEXRECT_SCALE, STATE_FOG_PARAMS_OPTIMIZED, /* for faster fog calc */ diff --git a/src/mesa/program/programopt.c b/src/mesa/program/programopt.c index fb2ebe6338..8f7e7dc25c 100644 --- a/src/mesa/program/programopt.c +++ b/src/mesa/program/programopt.c @@ -238,7 +238,7 @@ _mesa_insert_mvp_code(GLcontext *ctx, struct gl_vertex_program *vprog) * to vertex programs too. */ void -_mesa_append_fog_code(GLcontext *ctx, struct gl_fragment_program *fprog) +_mesa_append_fog_code(GLcontext *ctx, struct gl_fragment_program *fprog, GLboolean saturate) { static const gl_state_index fogPStateOpt[STATE_LENGTH] = { STATE_INTERNAL, STATE_FOG_PARAMS_OPTIMIZED, 0, 0, 0 }; @@ -290,7 +290,7 @@ _mesa_append_fog_code(GLcontext *ctx, struct gl_fragment_program *fprog) /* change the instruction to write to colorTemp w/ clamping */ inst->DstReg.File = PROGRAM_TEMPORARY; inst->DstReg.Index = colorTemp; - inst->SaturateMode = SATURATE_ZERO_ONE; + inst->SaturateMode = saturate; /* don't break (may be several writes to result.color) */ } inst++; @@ -300,6 +300,7 @@ _mesa_append_fog_code(GLcontext *ctx, struct gl_fragment_program *fprog) _mesa_init_instructions(inst, 5); /* emit instructions to compute fog blending factor */ + /* this is always clamped to [0, 1] regardless of fragment clamping */ if (fprog->FogOption == GL_LINEAR) { /* MAD fogFactorTemp.x, fragment.fogcoord.x, fogPRefOpt.x, fogPRefOpt.y; */ inst->Opcode = OPCODE_MAD; diff --git a/src/mesa/program/programopt.h b/src/mesa/program/programopt.h index 4af6357f97..78906da57b 100644 --- a/src/mesa/program/programopt.h +++ b/src/mesa/program/programopt.h @@ -32,7 +32,7 @@ extern void _mesa_insert_mvp_code(GLcontext *ctx, struct gl_vertex_program *vprog); extern void -_mesa_append_fog_code(GLcontext *ctx, struct gl_fragment_program *fprog); +_mesa_append_fog_code(GLcontext *ctx, struct gl_fragment_program *fprog, GLboolean saturate); extern void _mesa_count_texture_indirections(struct gl_program *prog); |