Преглед на файлове

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?)
tags/R300_DRIVER_0
Michel Dänzer преди 21 години
родител
ревизия
5d00e131d8

+ 3
- 3
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

+ 39
- 0
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;
}
}


+ 1
- 0
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,

+ 3
- 3
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

+ 27
- 12
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:

+ 1
- 0
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,

Loading…
Отказ
Запис