[Mesa-dev] [PATCH 13/29] nouveau: Use bitmask/ffs to iterate enabled lights
From: Mathias FröhlichReplaces a loop that iterates 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 Signed-off-by: Mathias Fröhlich --- src/mesa/drivers/dri/nouveau/nouveau_state.c | 10 ++ src/mesa/drivers/dri/nouveau/nv10_state_tnl.c | 27 --- src/mesa/drivers/dri/nouveau/nv20_state_tnl.c | 27 --- 3 files changed, 38 insertions(+), 26 deletions(-) diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state.c b/src/mesa/drivers/dri/nouveau/nouveau_state.c index 3aad10e..6189997 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_state.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_state.c @@ -31,6 +31,7 @@ #include "swrast/swrast.h" #include "tnl/tnl.h" +#include "util/bitscan.h" static void nouveau_alpha_func(struct gl_context *ctx, GLenum func, GLfloat ref) @@ -122,7 +123,7 @@ nouveau_draw_buffers(struct gl_context *ctx, GLsizei n, const GLenum *buffers) static void nouveau_enable(struct gl_context *ctx, GLenum cap, GLboolean state) { - int i; + GLbitfield mask; switch (cap) { case GL_ALPHA_TEST: @@ -187,9 +188,10 @@ nouveau_enable(struct gl_context *ctx, GLenum cap, GLboolean state) context_dirty(ctx, LIGHT_MODEL); context_dirty(ctx, LIGHT_ENABLE); - for (i = 0; i < MAX_LIGHTS; i++) { - if (ctx->Light.Light[i].Enabled) - context_dirty_i(ctx, LIGHT_SOURCE, i); + mask = ctx->Light._EnabledLights; + while (mask) { + const int i = u_bit_scan(); + context_dirty_i(ctx, LIGHT_SOURCE, i); } context_dirty(ctx, MATERIAL_FRONT_AMBIENT); diff --git a/src/mesa/drivers/dri/nouveau/nv10_state_tnl.c b/src/mesa/drivers/dri/nouveau/nv10_state_tnl.c index 1398385..9f80e41 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state_tnl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state_tnl.c @@ -30,8 +30,7 @@ #include "nouveau_util.h" #include "nv10_3d.xml.h" #include "nv10_driver.h" - -#include "util/simple_list.h" +#include "util/bitscan.h" void nv10_emit_clip_plane(struct gl_context *ctx, int emit) @@ -323,7 +322,7 @@ nv10_emit_material_ambient(struct gl_context *ctx, int emit) struct nouveau_pushbuf *push = context_push(ctx); float (*mat)[4] = ctx->Light.Material.Attrib; float c_scene[3], c_factor[3]; - struct gl_light *l; + GLbitfield mask; if (USE_COLOR_MATERIAL(AMBIENT)) { COPY_3V(c_scene, ctx->Light.Model.Ambient); @@ -347,8 +346,10 @@ nv10_emit_material_ambient(struct gl_context *ctx, int emit) PUSH_DATAp(push, c_factor, 3); } - foreach(l, >Light.EnabledList) { - const int i = l - ctx->Light.Light; + mask = ctx->Light._EnabledLights; + while (mask) { + const int i = u_bit_scan(); + struct gl_light *l = >Light.Light[i]; float *c_light = (USE_COLOR_MATERIAL(AMBIENT) ? l->Ambient : l->_MatAmbient[0]); @@ -363,13 +364,15 @@ nv10_emit_material_diffuse(struct gl_context *ctx, int emit) { struct nouveau_pushbuf *push = context_push(ctx); GLfloat (*mat)[4] = ctx->Light.Material.Attrib; - struct gl_light *l; + GLbitfield mask; BEGIN_NV04(push, NV10_3D(MATERIAL_FACTOR_A), 1); PUSH_DATAf(push, mat[MAT_ATTRIB_FRONT_DIFFUSE][3]); - foreach(l, >Light.EnabledList) { - const int i = l - ctx->Light.Light; + mask = ctx->Light._EnabledLights; + while (mask) { + const int i = u_bit_scan(); + struct gl_light *l = >Light.Light[i]; float *c_light = (USE_COLOR_MATERIAL(DIFFUSE) ? l->Diffuse : l->_MatDiffuse[0]); @@ -383,10 +386,12 @@ void nv10_emit_material_specular(struct gl_context *ctx, int emit) { struct nouveau_pushbuf *push = context_push(ctx); - struct gl_light *l; + GLbitfield mask; - foreach(l, >Light.EnabledList) { - const int i = l - ctx->Light.Light; + mask = ctx->Light._EnabledLights; + while (mask) { + const int i = u_bit_scan(); + struct gl_light *l = >Light.Light[i]; float *c_light = (USE_COLOR_MATERIAL(SPECULAR) ? l->Specular : l->_MatSpecular[0]); diff --git a/src/mesa/drivers/dri/nouveau/nv20_state_tnl.c b/src/mesa/drivers/dri/nouveau/nv20_state_tnl.c index
[Mesa-dev] [PATCH 13/29] nouveau: Use bitmask/ffs to iterate enabled lights
From: Mathias FröhlichReplaces a loop that iterates all lights and test which of them is enabled by a loop only iterating over the bits set in the enabled bitmask. Signed-off-by: Mathias Fröhlich --- src/mesa/drivers/dri/nouveau/nouveau_state.c | 10 + src/mesa/drivers/dri/nouveau/nv10_state_tnl.c | 29 +-- src/mesa/drivers/dri/nouveau/nv20_state_tnl.c | 29 +-- 3 files changed, 42 insertions(+), 26 deletions(-) diff --git a/src/mesa/drivers/dri/nouveau/nouveau_state.c b/src/mesa/drivers/dri/nouveau/nouveau_state.c index 3aad10e..a624211 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_state.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_state.c @@ -122,7 +122,7 @@ nouveau_draw_buffers(struct gl_context *ctx, GLsizei n, const GLenum *buffers) static void nouveau_enable(struct gl_context *ctx, GLenum cap, GLboolean state) { - int i; + GLbitfield mask; switch (cap) { case GL_ALPHA_TEST: @@ -187,9 +187,11 @@ nouveau_enable(struct gl_context *ctx, GLenum cap, GLboolean state) context_dirty(ctx, LIGHT_MODEL); context_dirty(ctx, LIGHT_ENABLE); - for (i = 0; i < MAX_LIGHTS; i++) { - if (ctx->Light.Light[i].Enabled) - context_dirty_i(ctx, LIGHT_SOURCE, i); + mask = ctx->Light._EnabledLights; + while (mask) { + const int i = ffs(mask) - 1; + mask ^= (1u << i); + context_dirty_i(ctx, LIGHT_SOURCE, i); } context_dirty(ctx, MATERIAL_FRONT_AMBIENT); diff --git a/src/mesa/drivers/dri/nouveau/nv10_state_tnl.c b/src/mesa/drivers/dri/nouveau/nv10_state_tnl.c index 1398385..4a3ad57 100644 --- a/src/mesa/drivers/dri/nouveau/nv10_state_tnl.c +++ b/src/mesa/drivers/dri/nouveau/nv10_state_tnl.c @@ -31,8 +31,6 @@ #include "nv10_3d.xml.h" #include "nv10_driver.h" -#include "util/simple_list.h" - void nv10_emit_clip_plane(struct gl_context *ctx, int emit) { @@ -323,7 +321,7 @@ nv10_emit_material_ambient(struct gl_context *ctx, int emit) struct nouveau_pushbuf *push = context_push(ctx); float (*mat)[4] = ctx->Light.Material.Attrib; float c_scene[3], c_factor[3]; - struct gl_light *l; + GLbitfield mask; if (USE_COLOR_MATERIAL(AMBIENT)) { COPY_3V(c_scene, ctx->Light.Model.Ambient); @@ -347,11 +345,14 @@ nv10_emit_material_ambient(struct gl_context *ctx, int emit) PUSH_DATAp(push, c_factor, 3); } - foreach(l, >Light.EnabledList) { - const int i = l - ctx->Light.Light; + mask = ctx->Light._EnabledLights; + while (mask) { + const int i = ffs(mask) - 1; + struct gl_light *l = >Light.Light[i]; float *c_light = (USE_COLOR_MATERIAL(AMBIENT) ? l->Ambient : l->_MatAmbient[0]); + mask ^= (1u << i); BEGIN_NV04(push, NV10_3D(LIGHT_AMBIENT_R(i)), 3); PUSH_DATAp(push, c_light, 3); @@ -363,16 +364,19 @@ nv10_emit_material_diffuse(struct gl_context *ctx, int emit) { struct nouveau_pushbuf *push = context_push(ctx); GLfloat (*mat)[4] = ctx->Light.Material.Attrib; - struct gl_light *l; + GLbitfield mask; BEGIN_NV04(push, NV10_3D(MATERIAL_FACTOR_A), 1); PUSH_DATAf(push, mat[MAT_ATTRIB_FRONT_DIFFUSE][3]); - foreach(l, >Light.EnabledList) { - const int i = l - ctx->Light.Light; + mask = ctx->Light._EnabledLights; + while (mask) { + const int i = ffs(mask) - 1; + struct gl_light *l = >Light.Light[i]; float *c_light = (USE_COLOR_MATERIAL(DIFFUSE) ? l->Diffuse : l->_MatDiffuse[0]); + mask ^= (1u << i); BEGIN_NV04(push, NV10_3D(LIGHT_DIFFUSE_R(i)), 3); PUSH_DATAp(push, c_light, 3); @@ -383,13 +387,16 @@ void nv10_emit_material_specular(struct gl_context *ctx, int emit) { struct nouveau_pushbuf *push = context_push(ctx); - struct gl_light *l; + GLbitfield mask; - foreach(l, >Light.EnabledList) { - const int i = l - ctx->Light.Light; + mask = ctx->Light._EnabledLights; + while (mask) { + const int i = ffs(mask) - 1; + struct gl_light *l = >Light.Light[i]; float *c_light = (USE_COLOR_MATERIAL(SPECULAR) ? l->Specular : l->_MatSpecular[0]); + mask ^= (1u << i); BEGIN_NV04(push, NV10_3D(LIGHT_SPECULAR_R(i)), 3); PUSH_DATAp(push, c_light, 3); diff --git