tnl: Use bitmask/ffs to iterate enabled lights
authorMathias Fröhlich <mathias.froehlich@web.de>
Sun, 22 May 2016 12:10:19 +0000 (14:10 +0200)
committerMathias Fröhlich <mathias.froehlich@web.de>
Thu, 16 Jun 2016 03:50:53 +0000 (05:50 +0200)
Replaces loops that iterate all lights and test
which of them is enabled by a loop only iterating over
the bits set in the enabled bitmask.

v2: Use _mesa_bit_scan{,64} instead of open coding.
v3: Use u_bit_scan{,64} instead of _mesa_bit_scan{,64}.

Reviewed-by: Brian Paul <brianp@vmware.com>
Signed-off-by: Mathias Fröhlich <Mathias.Froehlich@web.de>
src/mesa/tnl/t_vb_light.c
src/mesa/tnl/t_vb_lighttmp.h

index 029265a4f83885ef29910596761366e3fa436772..4342b6ed46588c45a0ca325248b903133d12606e 100644 (file)
@@ -33,6 +33,8 @@
 
 #include "math/m_translate.h"
 
+#include "util/bitscan.h"
+
 #include "t_context.h"
 #include "t_pipeline.h"
 #include "tnl.h"
@@ -394,7 +396,8 @@ static void validate_lighting( struct gl_context *ctx,
         tab = _tnl_light_tab;
    }
    else {
-      if (ctx->Light.EnabledList.next == ctx->Light.EnabledList.prev)
+      /* Power of two means only a single active light. */
+      if (_mesa_is_pow_two(ctx->Light._EnabledLights))
         tab = _tnl_light_fast_single_tab;
       else
         tab = _tnl_light_fast_tab;
index 3aebcd4b79949db6375a42adba492977721ef550..ac88095a969b96e0ee39a5316fb43c4b4f4b8de8 100644 (file)
@@ -87,7 +87,7 @@ static void TAG(light_rgba_spec)( struct gl_context *ctx,
 
    for (j = 0; j < nr; j++,STRIDE_F(vertex,vstride),STRIDE_F(normal,nstride)) {
       GLfloat sum[2][3], spec[2][3];
-      struct gl_light *light;
+      GLbitfield mask;
 
 #if IDX & LIGHT_MATERIAL
       update_materials( ctx, store );
@@ -106,7 +106,10 @@ static void TAG(light_rgba_spec)( struct gl_context *ctx,
 #endif
 
       /* Add contribution from each enabled light source */
-      foreach (light, &ctx->Light.EnabledList) {
+      mask = ctx->Light._EnabledLights;
+      while (mask) {
+         const int l = u_bit_scan(&mask);
+         struct gl_light *light = &ctx->Light.Light[l];
         GLfloat n_dot_h;
         GLfloat correction;
         GLint side;
@@ -265,7 +268,7 @@ static void TAG(light_rgba)( struct gl_context *ctx,
 
    for (j = 0; j < nr; j++,STRIDE_F(vertex,vstride),STRIDE_F(normal,nstride)) {
       GLfloat sum[2][3];
-      struct gl_light *light;
+      GLbitfield mask;
 
 #if IDX & LIGHT_MATERIAL
       update_materials( ctx, store );
@@ -282,7 +285,10 @@ static void TAG(light_rgba)( struct gl_context *ctx,
 #endif
 
       /* Add contribution from each enabled light source */
-      foreach (light, &ctx->Light.EnabledList) {
+      mask = ctx->Light._EnabledLights;
+      while (mask) {
+         const int l = u_bit_scan(&mask);
+         struct gl_light *light = &ctx->Light.Light[l];
         GLfloat n_dot_h;
         GLfloat correction;
         GLint side;
@@ -417,7 +423,8 @@ static void TAG(light_fast_rgba_single)( struct gl_context *ctx,
 #if IDX & LIGHT_TWOSIDE
    GLfloat (*Bcolor)[4] = (GLfloat (*)[4]) store->LitColor[1].data;
 #endif
-   const struct gl_light *light = ctx->Light.EnabledList.next;
+   const struct gl_light *light =
+      &ctx->Light.Light[ffs(ctx->Light._EnabledLights) - 1];
    GLuint j = 0;
    GLfloat base[2][4];
 #if IDX & LIGHT_MATERIAL
@@ -528,7 +535,6 @@ static void TAG(light_fast_rgba)( struct gl_context *ctx,
 #else
    const GLuint nr = VB->AttribPtr[_TNL_ATTRIB_NORMAL]->count;
 #endif
-   const struct gl_light *light;
 
 #ifdef TRACE
    fprintf(stderr, "%s %d\n", __func__, nr );
@@ -556,6 +562,7 @@ static void TAG(light_fast_rgba)( struct gl_context *ctx,
    for (j = 0; j < nr; j++, STRIDE_F(normal,nstride)) {
 
       GLfloat sum[2][3];
+      GLbitfield mask;
 
 #if IDX & LIGHT_MATERIAL
       update_materials( ctx, store );
@@ -572,7 +579,10 @@ static void TAG(light_fast_rgba)( struct gl_context *ctx,
       COPY_3V(sum[1], ctx->Light._BaseColor[1]);
 #endif
 
-      foreach (light, &ctx->Light.EnabledList) {
+      mask = ctx->Light._EnabledLights;
+      while (mask) {
+         const int l = u_bit_scan(&mask);
+         const struct gl_light *light = &ctx->Light.Light[l];
         GLfloat n_dot_h, n_dot_VP, spec;
 
         ACC_3V(sum[0], light->_MatAmbient[0]);