summaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/dri/r200
diff options
context:
space:
mode:
authorMichel Dänzer <[email protected]>2004-01-23 03:19:47 +0000
committerMichel Dänzer <[email protected]>2004-01-23 03:19:47 +0000
commit5d00e131d8a264498b8d050c3eded093ee5c42f2 (patch)
treec6cf958662658c178807c0330fb4110760632244 /src/mesa/drivers/dri/r200
parent4f295cee73bae1f687efe2dc062522b40d90b1e4 (diff)
Fix attenuation hardware state handling, inspired by the R200 DDK reference
driver (our r200 driver basically didn't do this at all, maybe got lost along the way?)
Diffstat (limited to 'src/mesa/drivers/dri/r200')
-rw-r--r--src/mesa/drivers/dri/r200/r200_context.h6
-rw-r--r--src/mesa/drivers/dri/r200/r200_state.c39
-rw-r--r--src/mesa/drivers/dri/r200/r200_state_init.c1
3 files changed, 43 insertions, 3 deletions
diff --git a/src/mesa/drivers/dri/r200/r200_context.h b/src/mesa/drivers/dri/r200/r200_context.h
index 5de1cb6eedf..65ca9ef7622 100644
--- a/src/mesa/drivers/dri/r200/r200_context.h
+++ b/src/mesa/drivers/dri/r200/r200_context.h
@@ -399,9 +399,9 @@ struct r200_state_atom {
#define LIT_DIRECTION_Y 18
#define LIT_DIRECTION_Z 19
#define LIT_DIRECTION_W 20
-#define LIT_ATTEN_CONST 21
+#define LIT_ATTEN_QUADRATIC 21
#define LIT_ATTEN_LINEAR 22
-#define LIT_ATTEN_QUADRATIC 23
+#define LIT_ATTEN_CONST 23
#define LIT_ATTEN_XXX 24
#define LIT_CMD_1 25
#define LIT_SPOT_DCD 26
@@ -410,7 +410,7 @@ struct r200_state_atom {
#define LIT_SPOT_CUTOFF 29
#define LIT_SPECULAR_THRESH 30
#define LIT_RANGE_CUTOFF 31 /* ? */
-#define LIT_RANGE_ATTEN 32 /* ? */
+#define LIT_ATTEN_CONST_INV 32
#define LIT_STATE_SIZE 33
/* Fog
diff --git a/src/mesa/drivers/dri/r200/r200_state.c b/src/mesa/drivers/dri/r200/r200_state.c
index 37da564986d..7ea45f3d788 100644
--- a/src/mesa/drivers/dri/r200/r200_state.c
+++ b/src/mesa/drivers/dri/r200/r200_state.c
@@ -1104,6 +1104,10 @@ static void r200Lightfv( GLcontext *ctx, GLenum light,
case GL_CONSTANT_ATTENUATION:
R200_STATECHANGE(rmesa, lit[p]);
fcmd[LIT_ATTEN_CONST] = params[0];
+ if ( params[0] == 0.0 )
+ fcmd[LIT_ATTEN_CONST_INV] = FLT_MAX;
+ else
+ fcmd[LIT_ATTEN_CONST_INV] = 1.0 / params[0];
break;
case GL_LINEAR_ATTENUATION:
R200_STATECHANGE(rmesa, lit[p]);
@@ -1117,6 +1121,41 @@ static void r200Lightfv( GLcontext *ctx, GLenum light,
return;
}
+ /* Set RANGE_ATTEN only when needed */
+ switch (pname) {
+ case GL_POSITION:
+ case GL_CONSTANT_ATTENUATION:
+ case GL_LINEAR_ATTENUATION:
+ case GL_QUADRATIC_ATTENUATION: {
+ GLuint *icmd = (GLuint *)R200_DB_STATE( tcl );
+ GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2;
+ GLuint atten_flag = ( p&1 ) ? R200_LIGHT_1_ENABLE_RANGE_ATTEN
+ : R200_LIGHT_0_ENABLE_RANGE_ATTEN;
+ GLuint atten_const_flag = ( p&1 ) ? R200_LIGHT_1_CONSTANT_RANGE_ATTEN
+ : R200_LIGHT_0_CONSTANT_RANGE_ATTEN;
+
+ if ( l->EyePosition[3] == 0.0F ||
+ ( ( fcmd[LIT_ATTEN_CONST] == 0.0 || fcmd[LIT_ATTEN_CONST] == 1.0 ) &&
+ fcmd[LIT_ATTEN_QUADRATIC] == 0.0 && fcmd[LIT_ATTEN_LINEAR] == 0.0 ) ) {
+ /* Disable attenuation */
+ icmd[idx] &= ~atten_flag;
+ } else {
+ if ( fcmd[LIT_ATTEN_QUADRATIC] == 0.0 && fcmd[LIT_ATTEN_LINEAR] == 0.0 ) {
+ /* Enable only constant portion of attenuation calculation */
+ icmd[idx] |= ( atten_flag | atten_const_flag );
+ } else {
+ /* Enable full attenuation calculation */
+ icmd[idx] &= ~atten_const_flag;
+ icmd[idx] |= atten_flag;
+ }
+ }
+
+ R200_DB_STATECHANGE( rmesa, &rmesa->hw.tcl );
+ break;
+ }
+ default:
+ break;
+ }
}
diff --git a/src/mesa/drivers/dri/r200/r200_state_init.c b/src/mesa/drivers/dri/r200/r200_state_init.c
index 22ad4e376e7..b9fc724f569 100644
--- a/src/mesa/drivers/dri/r200/r200_state_init.c
+++ b/src/mesa/drivers/dri/r200/r200_state_init.c
@@ -683,6 +683,7 @@ void r200InitState( r200ContextPtr rmesa )
&l->LinearAttenuation );
ctx->Driver.Lightfv( ctx, p, GL_QUADRATIC_ATTENUATION,
&l->QuadraticAttenuation );
+ *(float *)&(rmesa->hw.lit[i].cmd[LIT_ATTEN_XXX]) = 0.0;
}
ctx->Driver.LightModelfv( ctx, GL_LIGHT_MODEL_AMBIENT,