From a1b9b1a4409729fa8b6714e5847544576fcee404 Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Tue, 10 Feb 2004 02:20:29 +0000 Subject: [PATCH] Changed lighting to use SOURCE_MATERIAL instead of PREMULT (moves some light color calculations to the GPU). Two-side lighting fallback no longer needed and eliminated. --- src/mesa/drivers/dri/r200/r200_state.c | 175 ++++++++++++-------- src/mesa/drivers/dri/r200/r200_state_init.c | 26 ++- 2 files changed, 121 insertions(+), 80 deletions(-) diff --git a/src/mesa/drivers/dri/r200/r200_state.c b/src/mesa/drivers/dri/r200/r200_state.c index 2b61098cc9a..21b73c92188 100644 --- a/src/mesa/drivers/dri/r200/r200_state.c +++ b/src/mesa/drivers/dri/r200/r200_state.c @@ -786,6 +786,8 @@ static void update_global_ambient( GLcontext *ctx ) float *fcmd = (float *)R200_DB_STATE( glt ); /* Need to do more if both emmissive & ambient are PREMULT: + * I believe this is not nessary when using source_material. This condition thus + * will never happen currently, and the function has no dependencies on materials now */ if ((rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_1] & ((3 << R200_FRONT_EMISSIVE_SOURCE_SHIFT) | @@ -808,9 +810,6 @@ static void update_global_ambient( GLcontext *ctx ) /* Update on change to * - light[p].colors * - light[p].enabled - * - material, - * - colormaterial enabled - * - colormaterial bitmask */ static void update_light_colors( GLcontext *ctx, GLuint p ) { @@ -821,102 +820,115 @@ static void update_light_colors( GLcontext *ctx, GLuint p ) if (l->Enabled) { r200ContextPtr rmesa = R200_CONTEXT(ctx); float *fcmd = (float *)R200_DB_STATE( lit[p] ); - GLuint bitmask = ctx->Light.ColorMaterialBitmask; - GLfloat (*mat)[4] = ctx->Light.Material.Attrib; COPY_4V( &fcmd[LIT_AMBIENT_RED], l->Ambient ); COPY_4V( &fcmd[LIT_DIFFUSE_RED], l->Diffuse ); COPY_4V( &fcmd[LIT_SPECULAR_RED], l->Specular ); - if (!ctx->Light.ColorMaterialEnabled) - bitmask = 0; - - if ((bitmask & MAT_BIT_FRONT_AMBIENT) == 0) - SELF_SCALE_3V( &fcmd[LIT_AMBIENT_RED], mat[MAT_ATTRIB_FRONT_AMBIENT] ); - - if ((bitmask & MAT_BIT_FRONT_DIFFUSE) == 0) - SELF_SCALE_3V( &fcmd[LIT_DIFFUSE_RED], mat[MAT_ATTRIB_FRONT_DIFFUSE] ); - - if ((bitmask & MAT_BIT_FRONT_SPECULAR) == 0) - SELF_SCALE_3V( &fcmd[LIT_SPECULAR_RED], mat[MAT_ATTRIB_FRONT_SPECULAR] ); - R200_DB_STATECHANGE( rmesa, &rmesa->hw.lit[p] ); } } -/* Also fallback for asym colormaterial mode in twoside lighting... - */ -static void check_twoside_fallback( GLcontext *ctx ) -{ - GLboolean fallback = GL_FALSE; - GLint i; - - if (ctx->Light.Enabled && ctx->Light.Model.TwoSide) { - if (ctx->Light.ColorMaterialEnabled && - (ctx->Light.ColorMaterialBitmask & BACK_MATERIAL_BITS) != - ((ctx->Light.ColorMaterialBitmask & FRONT_MATERIAL_BITS)<<1)) - fallback = GL_TRUE; - else { - for (i = MAT_ATTRIB_FRONT_AMBIENT; i < MAT_ATTRIB_FRONT_INDEXES; i+=2) - if (memcmp( ctx->Light.Material.Attrib[i], - ctx->Light.Material.Attrib[i+1], - sizeof(GLfloat)*4) != 0) { - fallback = GL_TRUE; - break; - } - } - } - - TCL_FALLBACK( ctx, R200_TCL_FALLBACK_LIGHT_TWOSIDE, fallback ); -} - static void r200ColorMaterial( GLcontext *ctx, GLenum face, GLenum mode ) { - if (ctx->Light.ColorMaterialEnabled) { r200ContextPtr rmesa = R200_CONTEXT(ctx); GLuint light_model_ctl1 = rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_1]; - GLuint mask = ctx->Light.ColorMaterialBitmask; - - /* Default to PREMULT: - */ light_model_ctl1 &= ~((0xf << R200_FRONT_EMISSIVE_SOURCE_SHIFT) | (0xf << R200_FRONT_AMBIENT_SOURCE_SHIFT) | (0xf << R200_FRONT_DIFFUSE_SOURCE_SHIFT) | - (0xf << R200_FRONT_SPECULAR_SOURCE_SHIFT)); + (0xf << R200_FRONT_SPECULAR_SOURCE_SHIFT) | + (0xf << R200_BACK_EMISSIVE_SOURCE_SHIFT) | + (0xf << R200_BACK_AMBIENT_SOURCE_SHIFT) | + (0xf << R200_BACK_DIFFUSE_SOURCE_SHIFT) | + (0xf << R200_BACK_SPECULAR_SOURCE_SHIFT)); + + if (ctx->Light.ColorMaterialEnabled) { + GLuint mask = ctx->Light.ColorMaterialBitmask; if (mask & MAT_BIT_FRONT_EMISSION) { light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 << R200_FRONT_EMISSIVE_SOURCE_SHIFT); } + else + light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_0 << + R200_FRONT_EMISSIVE_SOURCE_SHIFT); if (mask & MAT_BIT_FRONT_AMBIENT) { light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 << R200_FRONT_AMBIENT_SOURCE_SHIFT); } + else + light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_0 << + R200_FRONT_AMBIENT_SOURCE_SHIFT); if (mask & MAT_BIT_FRONT_DIFFUSE) { light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 << R200_FRONT_DIFFUSE_SOURCE_SHIFT); } + else + light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_0 << + R200_FRONT_DIFFUSE_SOURCE_SHIFT); if (mask & MAT_BIT_FRONT_SPECULAR) { light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 << R200_FRONT_SPECULAR_SOURCE_SHIFT); } + else { + light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_0 << + R200_FRONT_SPECULAR_SOURCE_SHIFT); + } - if (light_model_ctl1 != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_1]) { - GLuint p; + if (mask & MAT_BIT_BACK_EMISSION) { + light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 << + R200_BACK_EMISSIVE_SOURCE_SHIFT); + } - R200_STATECHANGE( rmesa, tcl ); - rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_1] = light_model_ctl1; + else light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_1 << + R200_BACK_EMISSIVE_SOURCE_SHIFT); - for (p = 0 ; p < MAX_LIGHTS; p++) - update_light_colors( ctx, p ); - update_global_ambient( ctx ); + if (mask & MAT_BIT_BACK_AMBIENT) { + light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 << + R200_BACK_AMBIENT_SOURCE_SHIFT); + } + else light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_1 << + R200_BACK_AMBIENT_SOURCE_SHIFT); + + if (mask & MAT_BIT_BACK_DIFFUSE) { + light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 << + R200_BACK_DIFFUSE_SOURCE_SHIFT); + } + else light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_1 << + R200_BACK_DIFFUSE_SOURCE_SHIFT); + + if (mask & MAT_BIT_BACK_SPECULAR) { + light_model_ctl1 |= (R200_LM1_SOURCE_VERTEX_COLOR_0 << + R200_BACK_SPECULAR_SOURCE_SHIFT); + } + else { + light_model_ctl1 |= (R200_LM1_SOURCE_MATERIAL_1 << + R200_BACK_SPECULAR_SOURCE_SHIFT); + } } + else { + /* Default to SOURCE_MATERIAL: + */ + light_model_ctl1 |= + (R200_LM1_SOURCE_MATERIAL_0 << R200_FRONT_EMISSIVE_SOURCE_SHIFT) | + (R200_LM1_SOURCE_MATERIAL_0 << R200_FRONT_AMBIENT_SOURCE_SHIFT) | + (R200_LM1_SOURCE_MATERIAL_0 << R200_FRONT_DIFFUSE_SOURCE_SHIFT) | + (R200_LM1_SOURCE_MATERIAL_0 << R200_FRONT_SPECULAR_SOURCE_SHIFT) | + (R200_LM1_SOURCE_MATERIAL_1 << R200_BACK_EMISSIVE_SOURCE_SHIFT) | + (R200_LM1_SOURCE_MATERIAL_1 << R200_BACK_AMBIENT_SOURCE_SHIFT) | + (R200_LM1_SOURCE_MATERIAL_1 << R200_BACK_DIFFUSE_SOURCE_SHIFT) | + (R200_LM1_SOURCE_MATERIAL_1 << R200_BACK_SPECULAR_SOURCE_SHIFT); + } + + if (light_model_ctl1 != rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_1]) { + R200_STATECHANGE( rmesa, tcl ); + rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_1] = light_model_ctl1; } - check_twoside_fallback( ctx ); + } void r200UpdateMaterial( GLcontext *ctx ) @@ -924,16 +936,16 @@ void r200UpdateMaterial( GLcontext *ctx ) r200ContextPtr rmesa = R200_CONTEXT(ctx); GLfloat (*mat)[4] = ctx->Light.Material.Attrib; GLfloat *fcmd = (GLfloat *)R200_DB_STATE( mtl[0] ); - GLuint p; + GLfloat *fcmd2 = (GLfloat *)R200_DB_STATE( mtl[1] ); GLuint mask = ~0; + /* Might be possible and faster to update everything unconditionally? */ if (ctx->Light.ColorMaterialEnabled) mask &= ~ctx->Light.ColorMaterialBitmask; if (R200_DEBUG & DEBUG_STATE) fprintf(stderr, "%s\n", __FUNCTION__); - if (mask & MAT_BIT_FRONT_EMISSION) { fcmd[MTL_EMMISSIVE_RED] = mat[MAT_ATTRIB_FRONT_EMISSION][0]; fcmd[MTL_EMMISSIVE_GREEN] = mat[MAT_ATTRIB_FRONT_EMISSION][1]; @@ -962,13 +974,39 @@ void r200UpdateMaterial( GLcontext *ctx ) fcmd[MTL_SHININESS] = mat[MAT_ATTRIB_FRONT_SHININESS][0]; } - R200_DB_STATECHANGE( rmesa, &rmesa->hw.mtl[0] ); + if (mask & MAT_BIT_BACK_EMISSION) { + fcmd2[MTL_EMMISSIVE_RED] = mat[MAT_ATTRIB_BACK_EMISSION][0]; + fcmd2[MTL_EMMISSIVE_GREEN] = mat[MAT_ATTRIB_BACK_EMISSION][1]; + fcmd2[MTL_EMMISSIVE_BLUE] = mat[MAT_ATTRIB_BACK_EMISSION][2]; + fcmd2[MTL_EMMISSIVE_ALPHA] = mat[MAT_ATTRIB_BACK_EMISSION][3]; + } + if (mask & MAT_BIT_BACK_AMBIENT) { + fcmd2[MTL_AMBIENT_RED] = mat[MAT_ATTRIB_BACK_AMBIENT][0]; + fcmd2[MTL_AMBIENT_GREEN] = mat[MAT_ATTRIB_BACK_AMBIENT][1]; + fcmd2[MTL_AMBIENT_BLUE] = mat[MAT_ATTRIB_BACK_AMBIENT][2]; + fcmd2[MTL_AMBIENT_ALPHA] = mat[MAT_ATTRIB_BACK_AMBIENT][3]; + } + if (mask & MAT_BIT_BACK_DIFFUSE) { + fcmd2[MTL_DIFFUSE_RED] = mat[MAT_ATTRIB_BACK_DIFFUSE][0]; + fcmd2[MTL_DIFFUSE_GREEN] = mat[MAT_ATTRIB_BACK_DIFFUSE][1]; + fcmd2[MTL_DIFFUSE_BLUE] = mat[MAT_ATTRIB_BACK_DIFFUSE][2]; + fcmd2[MTL_DIFFUSE_ALPHA] = mat[MAT_ATTRIB_BACK_DIFFUSE][3]; + } + if (mask & MAT_BIT_BACK_SPECULAR) { + fcmd2[MTL_SPECULAR_RED] = mat[MAT_ATTRIB_BACK_SPECULAR][0]; + fcmd2[MTL_SPECULAR_GREEN] = mat[MAT_ATTRIB_BACK_SPECULAR][1]; + fcmd2[MTL_SPECULAR_BLUE] = mat[MAT_ATTRIB_BACK_SPECULAR][2]; + fcmd2[MTL_SPECULAR_ALPHA] = mat[MAT_ATTRIB_BACK_SPECULAR][3]; + } + if (mask & MAT_BIT_BACK_SHININESS) { + fcmd2[MTL_SHININESS] = mat[MAT_ATTRIB_BACK_SHININESS][0]; + } - for (p = 0 ; p < MAX_LIGHTS; p++) - update_light_colors( ctx, p ); + R200_DB_STATECHANGE( rmesa, &rmesa->hw.mtl[0] ); + R200_DB_STATECHANGE( rmesa, &rmesa->hw.mtl[1] ); - check_twoside_fallback( ctx ); - update_global_ambient( ctx ); + /* currently material changes cannot trigger a global ambient change, I believe this is correct + update_global_ambient( ctx ); */ } /* _NEW_LIGHT @@ -1185,10 +1223,7 @@ static void r200LightModelfv( GLcontext *ctx, GLenum pname, if (ctx->Light.Model.TwoSide) rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] |= R200_LIGHT_TWOSIDE; else - rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] &= ~R200_LIGHT_TWOSIDE; - - check_twoside_fallback( ctx ); - + rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] &= ~(R200_LIGHT_TWOSIDE); if (rmesa->TclFallback) { r200ChooseRenderState( ctx ); r200ChooseVertexState( ctx ); @@ -1809,7 +1844,6 @@ static void r200Enable( GLcontext *ctx, GLenum cap, GLboolean state ) case GL_LIGHTING: r200UpdateSpecular(ctx); - check_twoside_fallback( ctx ); break; case GL_LINE_SMOOTH: @@ -2131,7 +2165,7 @@ static void r200InvalidateState( GLcontext *ctx, GLuint new_state ) } /* A hack. The r200 can actually cope just fine with materials - * between begin/ends, so fix this. + * between begin/ends, so fix this. But how ? */ static GLboolean check_material( GLcontext *ctx ) { @@ -2148,7 +2182,6 @@ static GLboolean check_material( GLcontext *ctx ) return GL_FALSE; } - static void r200WrapRunPipeline( GLcontext *ctx ) { r200ContextPtr rmesa = R200_CONTEXT(ctx); diff --git a/src/mesa/drivers/dri/r200/r200_state_init.c b/src/mesa/drivers/dri/r200/r200_state_init.c index b9fc724f569..3601390ad2f 100644 --- a/src/mesa/drivers/dri/r200/r200_state_init.c +++ b/src/mesa/drivers/dri/r200/r200_state_init.c @@ -247,6 +247,7 @@ void r200InitState( r200ContextPtr rmesa ) ALLOC_STATE( msl, tcl, MSL_STATE_SIZE, "MSL/matrix-select", 0 ); ALLOC_STATE( tcg, tcl, TCG_STATE_SIZE, "TCG/texcoordgen", 0 ); ALLOC_STATE( mtl[0], tcl_lighting, MTL_STATE_SIZE, "MTL0/material0", 0 ); + ALLOC_STATE( mtl[1], tcl_lighting, MTL_STATE_SIZE, "MTL1/material1", 1 ); ALLOC_STATE( grd, tcl, GRD_STATE_SIZE, "GRD/guard-band", 0 ); ALLOC_STATE( fog, fog, FOG_STATE_SIZE, "FOG/fog", 0 ); ALLOC_STATE( glt, tcl_lighting, GLT_STATE_SIZE, "GLT/light-global", 0 ); @@ -318,6 +319,11 @@ void r200InitState( r200ContextPtr rmesa ) cmdvec( R200_VS_MAT_0_EMISS, 1, 16 ); rmesa->hw.mtl[0].cmd[MTL_CMD_1] = cmdscl2( R200_SS_MAT_0_SHININESS, 1, 1 ); + rmesa->hw.mtl[1].cmd[MTL_CMD_0] = + cmdvec( R200_VS_MAT_1_EMISS, 1, 16 ); + rmesa->hw.mtl[1].cmd[MTL_CMD_1] = + cmdscl2( R200_SS_MAT_1_SHININESS, 1, 1 ); + rmesa->hw.grd.cmd[GRD_CMD_0] = cmdscl( R200_SS_VERT_GUARD_CLIP_ADJ_ADDR, 1, 4 ); rmesa->hw.fog.cmd[FOG_CMD_0] = @@ -622,17 +628,19 @@ void r200InitState( r200ContextPtr rmesa ) rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] = (R200_SPECULAR_LIGHTS | R200_DIFFUSE_SPECULAR_COMBINE | - R200_LOCAL_LIGHT_VEC_GL); + R200_LOCAL_LIGHT_VEC_GL | + R200_LM0_SOURCE_MATERIAL_0 << R200_FRONT_SHININESS_SOURCE_SHIFT | + R200_LM0_SOURCE_MATERIAL_1 << R200_BACK_SHININESS_SOURCE_SHIFT); rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_1] = - ((R200_LM1_SOURCE_LIGHT_PREMULT << R200_FRONT_EMISSIVE_SOURCE_SHIFT) | - (R200_LM1_SOURCE_LIGHT_PREMULT << R200_FRONT_AMBIENT_SOURCE_SHIFT) | - (R200_LM1_SOURCE_LIGHT_PREMULT << R200_FRONT_DIFFUSE_SOURCE_SHIFT) | - (R200_LM1_SOURCE_LIGHT_PREMULT << R200_FRONT_SPECULAR_SOURCE_SHIFT) | - (R200_LM1_SOURCE_LIGHT_PREMULT << R200_BACK_EMISSIVE_SOURCE_SHIFT) | - (R200_LM1_SOURCE_LIGHT_PREMULT << R200_BACK_AMBIENT_SOURCE_SHIFT) | - (R200_LM1_SOURCE_LIGHT_PREMULT << R200_BACK_DIFFUSE_SOURCE_SHIFT) | - (R200_LM1_SOURCE_LIGHT_PREMULT << R200_BACK_SPECULAR_SOURCE_SHIFT)); + ((R200_LM1_SOURCE_MATERIAL_0 << R200_FRONT_EMISSIVE_SOURCE_SHIFT) | + (R200_LM1_SOURCE_MATERIAL_0 << R200_FRONT_AMBIENT_SOURCE_SHIFT) | + (R200_LM1_SOURCE_MATERIAL_0 << R200_FRONT_DIFFUSE_SOURCE_SHIFT) | + (R200_LM1_SOURCE_MATERIAL_0 << R200_FRONT_SPECULAR_SOURCE_SHIFT) | + (R200_LM1_SOURCE_MATERIAL_1 << R200_BACK_EMISSIVE_SOURCE_SHIFT) | + (R200_LM1_SOURCE_MATERIAL_1 << R200_BACK_AMBIENT_SOURCE_SHIFT) | + (R200_LM1_SOURCE_MATERIAL_1 << R200_BACK_DIFFUSE_SOURCE_SHIFT) | + (R200_LM1_SOURCE_MATERIAL_1 << R200_BACK_SPECULAR_SOURCE_SHIFT)); rmesa->hw.tcl.cmd[TCL_PER_LIGHT_CTL_0] = 0; /* filled in via callbacks */ rmesa->hw.tcl.cmd[TCL_PER_LIGHT_CTL_1] = 0; -- 2.30.2