diff options
-rw-r--r-- | src/mesa/drivers/dri/r200/r200_tcl.c | 4 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_tcl.c | 4 | ||||
-rw-r--r-- | src/mesa/main/light.c | 124 | ||||
-rw-r--r-- | src/mesa/main/light.h | 23 | ||||
-rw-r--r-- | src/mesa/main/mtypes.h | 19 | ||||
-rw-r--r-- | src/mesa/tnl/t_context.c | 21 | ||||
-rw-r--r-- | src/mesa/tnl/t_context.h | 18 | ||||
-rw-r--r-- | src/mesa/tnl/t_vb_light.c | 134 | ||||
-rw-r--r-- | src/mesa/tnl/t_vb_lighttmp.h | 12 | ||||
-rw-r--r-- | src/mesa/tnl/tnl.h | 3 |
10 files changed, 183 insertions, 179 deletions
diff --git a/src/mesa/drivers/dri/r200/r200_tcl.c b/src/mesa/drivers/dri/r200/r200_tcl.c index ba8d0db449b..a667bd3530d 100644 --- a/src/mesa/drivers/dri/r200/r200_tcl.c +++ b/src/mesa/drivers/dri/r200/r200_tcl.c @@ -520,10 +520,10 @@ static void transition_to_swtnl( struct gl_context *ctx ) r200ChooseVertexState( ctx ); r200ChooseRenderState( ctx ); - _mesa_validate_all_lighting_tables( ctx ); + _tnl_validate_shine_tables( ctx ); tnl->Driver.NotifyMaterialChange = - _mesa_validate_all_lighting_tables; + _tnl_validate_shine_tables; radeonReleaseArrays( ctx, ~0 ); diff --git a/src/mesa/drivers/dri/radeon/radeon_tcl.c b/src/mesa/drivers/dri/radeon/radeon_tcl.c index 071f98f31a6..09f097c4b4d 100644 --- a/src/mesa/drivers/dri/radeon/radeon_tcl.c +++ b/src/mesa/drivers/dri/radeon/radeon_tcl.c @@ -461,10 +461,10 @@ static void transition_to_swtnl( struct gl_context *ctx ) radeonChooseVertexState( ctx ); radeonChooseRenderState( ctx ); - _mesa_validate_all_lighting_tables( ctx ); + _tnl_validate_shine_tables( ctx ); tnl->Driver.NotifyMaterialChange = - _mesa_validate_all_lighting_tables; + _tnl_validate_shine_tables; radeonReleaseArrays( ctx, ~0 ); diff --git a/src/mesa/main/light.c b/src/mesa/main/light.c index f40e561a893..962a3e6893d 100644 --- a/src/mesa/main/light.c +++ b/src/mesa/main/light.c @@ -861,112 +861,6 @@ _mesa_GetMaterialiv( GLenum face, GLenum pname, GLint *params ) -/**********************************************************************/ -/***** Lighting computation *****/ -/**********************************************************************/ - - -/* - * Notes: - * When two-sided lighting is enabled we compute the color (or index) - * for both the front and back side of the primitive. Then, when the - * orientation of the facet is later learned, we can determine which - * color (or index) to use for rendering. - * - * KW: We now know orientation in advance and only shade for - * the side or sides which are actually required. - * - * Variables: - * n = normal vector - * V = vertex position - * P = light source position - * Pe = (0,0,0,1) - * - * Precomputed: - * IF P[3]==0 THEN - * // light at infinity - * IF local_viewer THEN - * _VP_inf_norm = unit vector from V to P // Precompute - * ELSE - * // eye at infinity - * _h_inf_norm = Normalize( VP + <0,0,1> ) // Precompute - * ENDIF - * ENDIF - * - * Functions: - * Normalize( v ) = normalized vector v - * Magnitude( v ) = length of vector v - */ - - - -static void -validate_shine_table( struct gl_context *ctx, GLuint side, GLfloat shininess ) -{ - struct gl_shine_tab *list = ctx->_ShineTabList; - struct gl_shine_tab *s; - - ASSERT(side < 2); - - foreach(s, list) - if ( s->shininess == shininess ) - break; - - if (s == list) { - GLint j; - GLfloat *m; - - foreach(s, list) - if (s->refcount == 0) - break; - - m = s->tab; - m[0] = 0.0; - if (shininess == 0.0) { - for (j = 1 ; j <= SHINE_TABLE_SIZE ; j++) - m[j] = 1.0; - } - else { - for (j = 1 ; j < SHINE_TABLE_SIZE ; j++) { - GLdouble t, x = j / (GLfloat) (SHINE_TABLE_SIZE - 1); - if (x < 0.005) /* underflow check */ - x = 0.005; - t = pow(x, shininess); - if (t > 1e-20) - m[j] = (GLfloat) t; - else - m[j] = 0.0; - } - m[SHINE_TABLE_SIZE] = 1.0; - } - - s->shininess = shininess; - } - - if (ctx->_ShineTable[side]) - ctx->_ShineTable[side]->refcount--; - - ctx->_ShineTable[side] = s; - move_to_tail( list, s ); - s->refcount++; -} - - -void -_mesa_validate_all_lighting_tables( struct gl_context *ctx ) -{ - GLfloat shininess; - - shininess = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_SHININESS][0]; - if (!ctx->_ShineTable[0] || ctx->_ShineTable[0]->shininess != shininess) - validate_shine_table( ctx, 0, shininess ); - - shininess = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_SHININESS][0]; - if (!ctx->_ShineTable[1] || ctx->_ShineTable[1]->shininess != shininess) - validate_shine_table( ctx, 1, shininess ); -} - - /** * Examine current lighting parameters to determine if the optimized lighting * function can be used. @@ -1304,17 +1198,6 @@ _mesa_init_lighting( struct gl_context *ctx ) ctx->Light.ColorMaterialEnabled = GL_FALSE; ctx->Light.ClampVertexColor = GL_TRUE; - /* Lighting miscellaneous */ - ctx->_ShineTabList = MALLOC_STRUCT( gl_shine_tab ); - make_empty_list( ctx->_ShineTabList ); - /* Allocate 10 (arbitrary) shininess lookup tables */ - for (i = 0 ; i < 10 ; i++) { - struct gl_shine_tab *s = MALLOC_STRUCT( gl_shine_tab ); - s->shininess = -1; - s->refcount = 0; - insert_at_tail( ctx->_ShineTabList, s ); - } - /* Miscellaneous */ ctx->Light._NeedEyeCoords = GL_FALSE; ctx->_NeedEyeCoords = GL_FALSE; @@ -1329,11 +1212,4 @@ _mesa_init_lighting( struct gl_context *ctx ) void _mesa_free_lighting_data( struct gl_context *ctx ) { - struct gl_shine_tab *s, *tmps; - - /* Free lighting shininess exponentiation table */ - foreach_s( s, tmps, ctx->_ShineTabList ) { - free( s ); - } - free( ctx->_ShineTabList ); } diff --git a/src/mesa/main/light.h b/src/mesa/main/light.h index 996698793f5..c751d6d6bd4 100644 --- a/src/mesa/main/light.h +++ b/src/mesa/main/light.h @@ -87,33 +87,11 @@ extern void _mesa_light(struct gl_context *ctx, GLuint lnum, GLenum pname, const GLfloat *params); -/* - * Compute dp ^ SpecularExponent. - * Lerp between adjacent values in the f(x) lookup table, giving a - * continuous function, with adequate overall accuracy. (Though still - * pretty good compared to a straight lookup). - */ -static inline GLfloat -_mesa_lookup_shininess(const struct gl_context *ctx, GLuint face, GLfloat dp) -{ - const struct gl_shine_tab *tab = ctx->_ShineTable[face]; - float f = dp * (SHINE_TABLE_SIZE - 1); - int k = (int) f; - if (k < 0 /* gcc may cast an overflow float value to negative int value */ - || k > SHINE_TABLE_SIZE - 2) - return powf(dp, tab->shininess); - else - return tab->tab[k] + (f - k) * (tab->tab[k+1] - tab->tab[k]); -} - - extern GLuint _mesa_material_bitmask( struct gl_context *ctx, GLenum face, GLenum pname, GLuint legal, const char * ); -extern void _mesa_validate_all_lighting_tables( struct gl_context *ctx ); - extern void _mesa_update_lighting( struct gl_context *ctx ); extern void _mesa_update_tnl_spaces( struct gl_context *ctx, GLuint new_state ); @@ -132,7 +110,6 @@ extern void _mesa_allow_light_in_model( struct gl_context *ctx, GLboolean flag ) #else #define _mesa_update_color_material( c, r ) ((void)0) -#define _mesa_validate_all_lighting_tables( c ) ((void)0) #define _mesa_material_bitmask( c, f, p, l, s ) 0 #define _mesa_init_lighting( c ) ((void)0) #define _mesa_free_lighting_data( c ) ((void)0) diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 2f5f85f4ea7..480b1cf28e2 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -629,21 +629,6 @@ struct gl_config /*@}*/ -#define EXP_TABLE_SIZE 512 /**< Specular exponent lookup table sizes */ -#define SHINE_TABLE_SIZE 256 /**< Material shininess lookup table sizes */ - -/** - * Material shininess lookup table. - */ -struct gl_shine_tab -{ - struct gl_shine_tab *next, *prev; - GLfloat tab[SHINE_TABLE_SIZE+1]; - GLfloat shininess; - GLuint refcount; -}; - - /** * Light source state. */ @@ -3387,10 +3372,6 @@ struct gl_context GLuint TextureStateTimestamp; /**< detect changes to shared state */ - struct gl_shine_tab *_ShineTable[2]; /**< Active shine tables */ - struct gl_shine_tab *_ShineTabList; /**< MRU list of inactive shine tables */ - /**@}*/ - struct gl_list_extensions *ListExt; /**< driver dlist extensions */ /** \name For debugging/development only */ diff --git a/src/mesa/tnl/t_context.c b/src/mesa/tnl/t_context.c index 1ded44ccffb..ede1d742835 100644 --- a/src/mesa/tnl/t_context.c +++ b/src/mesa/tnl/t_context.c @@ -46,6 +46,7 @@ GLboolean _tnl_CreateContext( struct gl_context *ctx ) { TNLcontext *tnl; + GLuint i; /* Create the TNLcontext structure */ @@ -76,10 +77,21 @@ _tnl_CreateContext( struct gl_context *ctx ) */ tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts; tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts; - tnl->Driver.NotifyMaterialChange = _mesa_validate_all_lighting_tables; + tnl->Driver.NotifyMaterialChange = _tnl_validate_shine_tables; tnl->nr_blocks = 0; + /* Lighting miscellaneous */ + tnl->_ShineTabList = MALLOC_STRUCT( tnl_shine_tab ); + make_empty_list( tnl->_ShineTabList ); + /* Allocate 10 (arbitrary) shininess lookup tables */ + for (i = 0 ; i < 10 ; i++) { + struct tnl_shine_tab *s = MALLOC_STRUCT( tnl_shine_tab ); + s->shininess = -1; + s->refcount = 0; + insert_at_tail( tnl->_ShineTabList, s ); + } + /* plug in the VBO drawing function */ vbo_set_draw_func(ctx, _tnl_vbo_draw_prims); @@ -93,8 +105,15 @@ _tnl_CreateContext( struct gl_context *ctx ) void _tnl_DestroyContext( struct gl_context *ctx ) { + struct tnl_shine_tab *s, *tmps; TNLcontext *tnl = TNL_CONTEXT(ctx); + /* Free lighting shininess exponentiation table */ + foreach_s( s, tmps, tnl->_ShineTabList ) { + free( s ); + } + free( tnl->_ShineTabList ); + _tnl_destroy_pipeline( ctx ); FREE(tnl); diff --git a/src/mesa/tnl/t_context.h b/src/mesa/tnl/t_context.h index c5a902082b8..8f18ddeb17a 100644 --- a/src/mesa/tnl/t_context.h +++ b/src/mesa/tnl/t_context.h @@ -384,6 +384,20 @@ struct tnl_clipspace }; +#define SHINE_TABLE_SIZE 256 /**< Material shininess lookup table sizes */ + +/** + * Material shininess lookup table. + */ +struct tnl_shine_tab +{ + struct tnl_shine_tab *next, *prev; + GLfloat tab[SHINE_TABLE_SIZE+1]; + GLfloat shininess; + GLuint refcount; +}; + + struct tnl_device_driver { /*** @@ -518,6 +532,10 @@ typedef struct GLuint nr_blocks; GLuint CurInstance; + + struct tnl_shine_tab *_ShineTable[2]; /**< Active shine tables */ + struct tnl_shine_tab *_ShineTabList; /**< MRU list of inactive shine tables */ + /**@}*/ } TNLcontext; diff --git a/src/mesa/tnl/t_vb_light.c b/src/mesa/tnl/t_vb_light.c index 3acedf6e577..39467fac731 100644 --- a/src/mesa/tnl/t_vb_light.c +++ b/src/mesa/tnl/t_vb_light.c @@ -36,6 +36,7 @@ #include "t_context.h" #include "t_pipeline.h" +#include "tnl.h" #define LIGHT_TWOSIDE 0x1 #define LIGHT_MATERIAL 0x2 @@ -76,6 +77,114 @@ struct light_stage_data { +/**********************************************************************/ +/***** Lighting computation *****/ +/**********************************************************************/ + + +/* + * Notes: + * When two-sided lighting is enabled we compute the color (or index) + * for both the front and back side of the primitive. Then, when the + * orientation of the facet is later learned, we can determine which + * color (or index) to use for rendering. + * + * KW: We now know orientation in advance and only shade for + * the side or sides which are actually required. + * + * Variables: + * n = normal vector + * V = vertex position + * P = light source position + * Pe = (0,0,0,1) + * + * Precomputed: + * IF P[3]==0 THEN + * // light at infinity + * IF local_viewer THEN + * _VP_inf_norm = unit vector from V to P // Precompute + * ELSE + * // eye at infinity + * _h_inf_norm = Normalize( VP + <0,0,1> ) // Precompute + * ENDIF + * ENDIF + * + * Functions: + * Normalize( v ) = normalized vector v + * Magnitude( v ) = length of vector v + */ + + + +static void +validate_shine_table( struct gl_context *ctx, GLuint side, GLfloat shininess ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct tnl_shine_tab *list = tnl->_ShineTabList; + struct tnl_shine_tab *s; + + ASSERT(side < 2); + + foreach(s, list) + if ( s->shininess == shininess ) + break; + + if (s == list) { + GLint j; + GLfloat *m; + + foreach(s, list) + if (s->refcount == 0) + break; + + m = s->tab; + m[0] = 0.0; + if (shininess == 0.0) { + for (j = 1 ; j <= SHINE_TABLE_SIZE ; j++) + m[j] = 1.0; + } + else { + for (j = 1 ; j < SHINE_TABLE_SIZE ; j++) { + GLdouble t, x = j / (GLfloat) (SHINE_TABLE_SIZE - 1); + if (x < 0.005) /* underflow check */ + x = 0.005; + t = pow(x, shininess); + if (t > 1e-20) + m[j] = (GLfloat) t; + else + m[j] = 0.0; + } + m[SHINE_TABLE_SIZE] = 1.0; + } + + s->shininess = shininess; + } + + if (tnl->_ShineTable[side]) + tnl->_ShineTable[side]->refcount--; + + tnl->_ShineTable[side] = s; + move_to_tail( list, s ); + s->refcount++; +} + + +void +_tnl_validate_shine_tables( struct gl_context *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + GLfloat shininess; + + shininess = ctx->Light.Material.Attrib[MAT_ATTRIB_FRONT_SHININESS][0]; + if (!tnl->_ShineTable[0] || tnl->_ShineTable[0]->shininess != shininess) + validate_shine_table( ctx, 0, shininess ); + + shininess = ctx->Light.Material.Attrib[MAT_ATTRIB_BACK_SHININESS][0]; + if (!tnl->_ShineTable[1] || tnl->_ShineTable[1]->shininess != shininess) + validate_shine_table( ctx, 1, shininess ); +} + + /** * In the case of colormaterial, the effected material attributes * should already have been bound to point to the incoming color data, @@ -101,7 +210,7 @@ update_materials(struct gl_context *ctx, struct light_stage_data *store) /* XXX we should only call this if we're tracking/changing the specular * exponent. */ - _mesa_validate_all_lighting_tables( ctx ); + _tnl_validate_shine_tables( ctx ); } @@ -149,11 +258,32 @@ prepare_materials(struct gl_context *ctx, /* FIXME: Is this already done? */ _mesa_update_material( ctx, ~0 ); - _mesa_validate_all_lighting_tables( ctx ); + + _tnl_validate_shine_tables( ctx ); return store->mat_count; } +/* + * Compute dp ^ SpecularExponent. + * Lerp between adjacent values in the f(x) lookup table, giving a + * continuous function, with adequate overall accuracy. (Though still + * pretty good compared to a straight lookup). + */ +static inline GLfloat +lookup_shininess(const struct gl_context *ctx, GLuint face, GLfloat dp) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + const struct tnl_shine_tab *tab = tnl->_ShineTable[face]; + float f = dp * (SHINE_TABLE_SIZE - 1); + int k = (int) f; + if (k < 0 /* gcc may cast an overflow float value to negative int value */ + || k > SHINE_TABLE_SIZE - 2) + return powf(dp, tab->shininess); + else + return tab->tab[k] + (f - k) * (tab->tab[k+1] - tab->tab[k]); +} + /* Tables for all the shading functions. */ static light_func _tnl_light_tab[MAX_LIGHT_FUNC]; diff --git a/src/mesa/tnl/t_vb_lighttmp.h b/src/mesa/tnl/t_vb_lighttmp.h index 1041a24e761..1944e5ddc6d 100644 --- a/src/mesa/tnl/t_vb_lighttmp.h +++ b/src/mesa/tnl/t_vb_lighttmp.h @@ -204,7 +204,7 @@ static void TAG(light_rgba_spec)( struct gl_context *ctx, n_dot_h = correction * DOT3(normal, h); if (n_dot_h > 0.0F) { - GLfloat spec_coef = _mesa_lookup_shininess(ctx, side, n_dot_h); + GLfloat spec_coef = lookup_shininess(ctx, side, n_dot_h); if (spec_coef > 1.0e-10) { spec_coef *= attenuation; ACC_SCALE_SCALAR_3V( spec[side], spec_coef, @@ -383,7 +383,7 @@ static void TAG(light_rgba)( struct gl_context *ctx, n_dot_h = correction * DOT3(normal, h); if (n_dot_h > 0.0F) { - GLfloat spec_coef = _mesa_lookup_shininess(ctx, side, n_dot_h); + GLfloat spec_coef = lookup_shininess(ctx, side, n_dot_h); ACC_SCALE_SCALAR_3V( contrib, spec_coef, light->_MatSpecular[side]); } @@ -483,7 +483,7 @@ static void TAG(light_fast_rgba_single)( struct gl_context *ctx, COPY_3V(sum, base[1]); ACC_SCALE_SCALAR_3V(sum, -n_dot_VP, light->_MatDiffuse[1]); if (n_dot_h > 0.0F) { - GLfloat spec = _mesa_lookup_shininess(ctx, 1, n_dot_h); + GLfloat spec = lookup_shininess(ctx, 1, n_dot_h); ACC_SCALE_SCALAR_3V(sum, spec, light->_MatSpecular[1]); } COPY_3V(Bcolor[j], sum ); @@ -497,7 +497,7 @@ static void TAG(light_fast_rgba_single)( struct gl_context *ctx, COPY_3V(sum, base[0]); ACC_SCALE_SCALAR_3V(sum, n_dot_VP, light->_MatDiffuse[0]); if (n_dot_h > 0.0F) { - GLfloat spec = _mesa_lookup_shininess(ctx, 0, n_dot_h); + GLfloat spec = lookup_shininess(ctx, 0, n_dot_h); ACC_SCALE_SCALAR_3V(sum, spec, light->_MatSpecular[0]); } COPY_3V(Fcolor[j], sum ); @@ -589,7 +589,7 @@ static void TAG(light_fast_rgba)( struct gl_context *ctx, ACC_SCALE_SCALAR_3V(sum[0], n_dot_VP, light->_MatDiffuse[0]); n_dot_h = DOT3(normal, light->_h_inf_norm); if (n_dot_h > 0.0F) { - spec = _mesa_lookup_shininess(ctx, 0, n_dot_h); + spec = lookup_shininess(ctx, 0, n_dot_h); ACC_SCALE_SCALAR_3V( sum[0], spec, light->_MatSpecular[0]); } } @@ -598,7 +598,7 @@ static void TAG(light_fast_rgba)( struct gl_context *ctx, ACC_SCALE_SCALAR_3V(sum[1], -n_dot_VP, light->_MatDiffuse[1]); n_dot_h = -DOT3(normal, light->_h_inf_norm); if (n_dot_h > 0.0F) { - spec = _mesa_lookup_shininess(ctx, 1, n_dot_h); + spec = lookup_shininess(ctx, 1, n_dot_h); ACC_SCALE_SCALAR_3V( sum[1], spec, light->_MatSpecular[1]); } } diff --git a/src/mesa/tnl/tnl.h b/src/mesa/tnl/tnl.h index d3889811e21..434bd7fcd95 100644 --- a/src/mesa/tnl/tnl.h +++ b/src/mesa/tnl/tnl.h @@ -101,4 +101,7 @@ _mesa_load_tracked_matrices(struct gl_context *ctx); extern void _tnl_RasterPos(struct gl_context *ctx, const GLfloat vObj[4]); +extern void +_tnl_validate_shine_tables( struct gl_context *ctx ); + #endif |