From 5d00e131d8a264498b8d050c3eded093ee5c42f2 Mon Sep 17 00:00:00 2001 From: Michel Dänzer Date: Fri, 23 Jan 2004 03:19:47 +0000 Subject: 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?) --- src/mesa/drivers/dri/r200/r200_context.h | 6 ++-- src/mesa/drivers/dri/r200/r200_state.c | 39 +++++++++++++++++++++++++ src/mesa/drivers/dri/r200/r200_state_init.c | 1 + src/mesa/drivers/dri/radeon/radeon_context.h | 6 ++-- src/mesa/drivers/dri/radeon/radeon_state.c | 39 +++++++++++++++++-------- src/mesa/drivers/dri/radeon/radeon_state_init.c | 1 + 6 files changed, 74 insertions(+), 18 deletions(-) diff --git a/src/mesa/drivers/dri/r200/r200_context.h b/src/mesa/drivers/dri/r200/r200_context.h index 5de1cb6eed..65ca9ef762 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 37da564986..7ea45f3d78 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 22ad4e376e..b9fc724f56 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, diff --git a/src/mesa/drivers/dri/radeon/radeon_context.h b/src/mesa/drivers/dri/radeon/radeon_context.h index 0a32fd8aa3..3ce67044f9 100644 --- a/src/mesa/drivers/dri/radeon/radeon_context.h +++ b/src/mesa/drivers/dri/radeon/radeon_context.h @@ -340,9 +340,9 @@ struct radeon_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 @@ -350,7 +350,7 @@ struct radeon_state_atom { #define LIT_SPOT_CUTOFF 28 #define LIT_SPECULAR_THRESH 29 #define LIT_RANGE_CUTOFF 30 /* ? */ -#define LIT_RANGE_ATTEN 31 /* ? */ +#define LIT_ATTEN_CONST_INV 31 #define LIT_STATE_SIZE 32 /* Fog diff --git a/src/mesa/drivers/dri/radeon/radeon_state.c b/src/mesa/drivers/dri/radeon/radeon_state.c index e71f5adf27..db198074ee 100644 --- a/src/mesa/drivers/dri/radeon/radeon_state.c +++ b/src/mesa/drivers/dri/radeon/radeon_state.c @@ -1101,6 +1101,10 @@ static void radeonLightfv( GLcontext *ctx, GLenum light, case GL_CONSTANT_ATTENUATION: RADEON_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: RADEON_STATECHANGE(rmesa, lit[p]); @@ -1117,23 +1121,34 @@ static void radeonLightfv( GLcontext *ctx, GLenum light, /* Set RANGE_ATTEN only when needed */ switch (pname) { case GL_POSITION: + case GL_CONSTANT_ATTENUATION: case GL_LINEAR_ATTENUATION: case GL_QUADRATIC_ATTENUATION: { - GLuint flag; + GLuint *icmd = (GLuint *)RADEON_DB_STATE( tcl ); GLuint idx = TCL_PER_LIGHT_CTL_0 + p/2; + GLuint atten_flag = ( p&1 ) ? RADEON_LIGHT_1_ENABLE_RANGE_ATTEN + : RADEON_LIGHT_0_ENABLE_RANGE_ATTEN; + GLuint atten_const_flag = ( p&1 ) ? RADEON_LIGHT_1_CONSTANT_RANGE_ATTEN + : RADEON_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; + } + } - if (p&1) - flag = RADEON_LIGHT_1_ENABLE_RANGE_ATTEN; - else - flag = RADEON_LIGHT_0_ENABLE_RANGE_ATTEN; - - RADEON_STATECHANGE(rmesa, tcl); - if (l->EyePosition[3] != 0.0F && - (l->LinearAttenuation != 0.0F || l->QuadraticAttenuation != 0.0F)) - rmesa->hw.tcl.cmd[idx] |= flag; - else - rmesa->hw.tcl.cmd[idx] &= ~flag; + RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.tcl ); break; } default: diff --git a/src/mesa/drivers/dri/radeon/radeon_state_init.c b/src/mesa/drivers/dri/radeon/radeon_state_init.c index 2aa8dbe40a..ceb313a7e7 100644 --- a/src/mesa/drivers/dri/radeon/radeon_state_init.c +++ b/src/mesa/drivers/dri/radeon/radeon_state_init.c @@ -522,6 +522,7 @@ void radeonInitState( radeonContextPtr 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, -- cgit v1.2.3