Commit 3a9cb5e5 authored by Luca Barbieri's avatar Luca Barbieri

mesa: respect color clamping in texenv programs (v2)

Changes in v2:
- Fix attributes other than vertex color sometimes getting clamped
parent 123bb110
......@@ -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;
}
}
......
......@@ -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;
}
......
......@@ -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 |
......
......@@ -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;
}
......
......@@ -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;
}
......
......@@ -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;
......
......@@ -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 */
......
......@@ -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;
......
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment