소스 검색

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…
취소
저장