[Mesa-dev] [PATCH 1/2] util: Move ffs, _mesa_bitcount, and friends to the util folder

Roland Scheidegger sroland at vmware.com
Wed Oct 29 13:45:08 PDT 2014


I like the idea of the series, however gallium still uses its own
definitions (by the looks of it supporting more compilers for native
definitions but in some cases with worse code for the fallback)
sometimes with different names (fls/util_last_bit) and sometimes with
the same even (ffs and util_bitcount) which looks like it might
conflict. I think it would be great if these would be unified.

Roland

Am 29.10.2014 um 19:27 schrieb Jason Ekstrand:
> ---
>  src/gallium/state_trackers/glx/xlib/glx_api.c     |   6 +-
>  src/gallium/state_trackers/glx/xlib/xm_api.c      |  10 +-
>  src/mesa/drivers/common/meta.c                    |   3 +-
>  src/mesa/drivers/dri/i965/brw_blorp_blit.cpp      |   4 +-
>  src/mesa/drivers/dri/i965/brw_curbe.c             |   2 +-
>  src/mesa/drivers/dri/i965/brw_draw.c              |   6 +-
>  src/mesa/drivers/dri/i965/brw_fs.cpp              |  12 +--
>  src/mesa/drivers/dri/i965/brw_shader.cpp          |   2 +-
>  src/mesa/drivers/dri/i965/brw_vec4.cpp            |   2 +-
>  src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp |   2 +-
>  src/mesa/drivers/dri/i965/brw_wm.c                |   4 +-
>  src/mesa/drivers/dri/i965/brw_wm_surface_state.c  |   2 +-
>  src/mesa/drivers/x11/fakeglx.c                    |   6 +-
>  src/mesa/drivers/x11/xm_api.c                     |  16 +--
>  src/mesa/main/bitset.h                            |   1 +
>  src/mesa/main/buffers.c                           |   6 +-
>  src/mesa/main/imports.c                           |  88 -----------------
>  src/mesa/main/imports.h                           |  54 +---------
>  src/mesa/program/program_parse.y                  |   2 +-
>  src/util/Makefile.sources                         |   1 +
>  src/util/bitcount.c                               | 115 ++++++++++++++++++++++
>  src/util/bitcount.h                               |  94 ++++++++++++++++++
>  22 files changed, 255 insertions(+), 183 deletions(-)
>  create mode 100644 src/util/bitcount.c
>  create mode 100644 src/util/bitcount.h
> 
> diff --git a/src/gallium/state_trackers/glx/xlib/glx_api.c b/src/gallium/state_trackers/glx/xlib/glx_api.c
> index 976791b..9914116 100644
> --- a/src/gallium/state_trackers/glx/xlib/glx_api.c
> +++ b/src/gallium/state_trackers/glx/xlib/glx_api.c
> @@ -402,9 +402,9 @@ get_visual( Display *dpy, int scr, unsigned int depth, int xclass )
>      * 10 bits per color channel.  Mesa's limited to a max of 8 bits/channel.
>      */
>     if (vis && depth > 24 && (xclass==TrueColor || xclass==DirectColor)) {
> -      if (_mesa_bitcount((GLuint) vis->red_mask  ) <= 8 &&
> -          _mesa_bitcount((GLuint) vis->green_mask) <= 8 &&
> -          _mesa_bitcount((GLuint) vis->blue_mask ) <= 8) {
> +      if (util_bitcount((GLuint) vis->red_mask  ) <= 8 &&
> +          util_bitcount((GLuint) vis->green_mask) <= 8 &&
> +          util_bitcount((GLuint) vis->blue_mask ) <= 8) {
>           return vis;
>        }
>        else {
> diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.c b/src/gallium/state_trackers/glx/xlib/xm_api.c
> index 1b77729..74c5637 100644
> --- a/src/gallium/state_trackers/glx/xlib/xm_api.c
> +++ b/src/gallium/state_trackers/glx/xlib/xm_api.c
> @@ -736,9 +736,9 @@ XMesaVisual XMesaCreateVisual( Display *display,
>     {
>        const int xclass = v->visualType;
>        if (xclass == GLX_TRUE_COLOR || xclass == GLX_DIRECT_COLOR) {
> -         red_bits   = _mesa_bitcount(GET_REDMASK(v));
> -         green_bits = _mesa_bitcount(GET_GREENMASK(v));
> -         blue_bits  = _mesa_bitcount(GET_BLUEMASK(v));
> +         red_bits   = util_bitcount(GET_REDMASK(v));
> +         green_bits = util_bitcount(GET_GREENMASK(v));
> +         blue_bits  = util_bitcount(GET_BLUEMASK(v));
>        }
>        else {
>           /* this is an approximation */
> @@ -1067,8 +1067,8 @@ XMesaCreatePixmapTextureBuffer(XMesaVisual v, Pixmap p,
>        if (ctx->Extensions.ARB_texture_non_power_of_two) {
>           target = GLX_TEXTURE_2D_EXT;
>        }
> -      else if (   _mesa_bitcount(b->width)  == 1
> -               && _mesa_bitcount(b->height) == 1) {
> +      else if (   util_bitcount(b->width)  == 1
> +               && util_bitcount(b->height) == 1) {
>           /* power of two size */
>           if (b->height == 1) {
>              target = GLX_TEXTURE_1D_EXT;
> diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c
> index 87532c1..22a5b3e 100644
> --- a/src/mesa/drivers/common/meta.c
> +++ b/src/mesa/drivers/common/meta.c
> @@ -85,6 +85,7 @@
>  #include "main/enums.h"
>  #include "main/glformats.h"
>  #include "util/ralloc.h"
> +#include "util/bitcount.h"
>  
>  /** Return offset in bytes of the field within a vertex struct */
>  #define OFFSET(FIELD) ((void *) offsetof(struct vertex, FIELD))
> @@ -1640,7 +1641,7 @@ _mesa_meta_drawbuffers_from_bitfield(GLbitfield bits)
>     assert((bits & ~BUFFER_BITS_COLOR) == 0);
>  
>     /* Make sure we don't overflow any arrays. */
> -   assert(_mesa_bitcount(bits) <= MAX_DRAW_BUFFERS);
> +   assert(util_bitcount(bits) <= MAX_DRAW_BUFFERS);
>  
>     enums[0] = GL_NONE;
>  
> diff --git a/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp b/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp
> index 844f5e4..7ccdff5 100644
> --- a/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp
> +++ b/src/mesa/drivers/dri/i965/brw_blorp_blit.cpp
> @@ -1346,7 +1346,7 @@ inline int count_trailing_one_bits(unsigned value)
>  #ifdef HAVE___BUILTIN_CTZ
>     return __builtin_ctz(~value);
>  #else
> -   return _mesa_bitcount(value & ~(value + 1));
> +   return util_bitcount(value & ~(value + 1));
>  #endif
>  }
>  
> @@ -1388,7 +1388,7 @@ brw_blorp_blit_program::manual_blend_average(unsigned num_samples)
>      */
>     unsigned stack_depth = 0;
>     for (unsigned i = 0; i < num_samples; ++i) {
> -      assert(stack_depth == _mesa_bitcount(i)); /* Loop invariant */
> +      assert(stack_depth == util_bitcount(i)); /* Loop invariant */
>  
>        /* Push sample i onto the stack */
>        assert(stack_depth < ARRAY_SIZE(texture_data));
> diff --git a/src/mesa/drivers/dri/i965/brw_curbe.c b/src/mesa/drivers/dri/i965/brw_curbe.c
> index 1a828ed..46a3ccb 100644
> --- a/src/mesa/drivers/dri/i965/brw_curbe.c
> +++ b/src/mesa/drivers/dri/i965/brw_curbe.c
> @@ -85,7 +85,7 @@ static void calculate_curbe_offsets( struct brw_context *brw )
>  
>     /* _NEW_TRANSFORM */
>     if (ctx->Transform.ClipPlanesEnabled) {
> -      GLuint nr_planes = 6 + _mesa_bitcount_64(ctx->Transform.ClipPlanesEnabled);
> +      GLuint nr_planes = 6 + util_bitcount_64(ctx->Transform.ClipPlanesEnabled);
>        nr_clip_regs = (nr_planes * 4 + 15) / 16;
>     }
>  
> diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c
> index b28eaf2..fb843e4 100644
> --- a/src/mesa/drivers/dri/i965/brw_draw.c
> +++ b/src/mesa/drivers/dri/i965/brw_draw.c
> @@ -369,11 +369,11 @@ static bool brw_try_draw_prims( struct gl_context *ctx,
>      * index.
>      */
>     brw->wm.base.sampler_count =
> -      _mesa_fls(ctx->FragmentProgram._Current->Base.SamplersUsed);
> +      util_fls(ctx->FragmentProgram._Current->Base.SamplersUsed);
>     brw->gs.base.sampler_count = ctx->GeometryProgram._Current ?
> -      _mesa_fls(ctx->GeometryProgram._Current->Base.SamplersUsed) : 0;
> +      util_fls(ctx->GeometryProgram._Current->Base.SamplersUsed) : 0;
>     brw->vs.base.sampler_count =
> -      _mesa_fls(ctx->VertexProgram._Current->Base.SamplersUsed);
> +      util_fls(ctx->VertexProgram._Current->Base.SamplersUsed);
>  
>     /* We have to validate the textures *before* checking for fallbacks;
>      * otherwise, the software fallback won't be able to rely on the
> diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
> index aa1d8d2..1732b7f 100644
> --- a/src/mesa/drivers/dri/i965/brw_fs.cpp
> +++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
> @@ -1719,8 +1719,8 @@ fs_visitor::calculate_urb_setup()
>     int urb_next = 0;
>     /* Figure out where each of the incoming setup attributes lands. */
>     if (brw->gen >= 6) {
> -      if (_mesa_bitcount_64(prog->InputsRead &
> -                            BRW_FS_VARYING_INPUT_MASK) <= 16) {
> +      if (util_bitcount_64(prog->InputsRead &
> +                           BRW_FS_VARYING_INPUT_MASK) <= 16) {
>           /* The SF/SBE pipeline stage can do arbitrary rearrangement of the
>            * first 16 varying inputs, so we can put them wherever we want.
>            * Just put them in order.
> @@ -3791,11 +3791,11 @@ brw_fs_precompile(struct gl_context *ctx, struct gl_shader_program *prog)
>        key.iz_lookup |= IZ_DEPTH_WRITE_ENABLE_BIT;
>     }
>  
> -   if (brw->gen < 6 || _mesa_bitcount_64(fp->Base.InputsRead &
> -                                         BRW_FS_VARYING_INPUT_MASK) > 16)
> +   if (brw->gen < 6 || util_bitcount_64(fp->Base.InputsRead &
> +                                        BRW_FS_VARYING_INPUT_MASK) > 16)
>        key.input_slots_valid = fp->Base.InputsRead | VARYING_BIT_POS;
>  
> -   unsigned sampler_count = _mesa_fls(fp->Base.SamplersUsed);
> +   unsigned sampler_count = util_fls(fp->Base.SamplersUsed);
>     for (unsigned i = 0; i < sampler_count; i++) {
>        if (fp->Base.ShadowSamplers & (1 << i)) {
>           /* Assume DEPTH_TEXTURE_MODE is the default: X, X, X, 1 */
> @@ -3811,7 +3811,7 @@ brw_fs_precompile(struct gl_context *ctx, struct gl_shader_program *prog)
>        key.drawable_height = ctx->DrawBuffer->Height;
>     }
>  
> -   key.nr_color_regions = _mesa_bitcount_64(fp->Base.OutputsWritten &
> +   key.nr_color_regions = util_bitcount_64(fp->Base.OutputsWritten &
>           ~(BITFIELD64_BIT(FRAG_RESULT_DEPTH) |
>           BITFIELD64_BIT(FRAG_RESULT_SAMPLE_MASK)));
>  
> diff --git a/src/mesa/drivers/dri/i965/brw_shader.cpp b/src/mesa/drivers/dri/i965/brw_shader.cpp
> index 21dcf2d..adfe3b0 100644
> --- a/src/mesa/drivers/dri/i965/brw_shader.cpp
> +++ b/src/mesa/drivers/dri/i965/brw_shader.cpp
> @@ -864,7 +864,7 @@ backend_visitor::invalidate_cfg()
>  void
>  backend_visitor::assign_common_binding_table_offsets(uint32_t next_binding_table_offset)
>  {
> -   int num_textures = _mesa_fls(prog->SamplersUsed);
> +   int num_textures = util_fls(prog->SamplersUsed);
>  
>     stage_prog_data->binding_table.texture_start = next_binding_table_offset;
>     next_binding_table_offset += num_textures;
> diff --git a/src/mesa/drivers/dri/i965/brw_vec4.cpp b/src/mesa/drivers/dri/i965/brw_vec4.cpp
> index df589b8..89f9ee0 100644
> --- a/src/mesa/drivers/dri/i965/brw_vec4.cpp
> +++ b/src/mesa/drivers/dri/i965/brw_vec4.cpp
> @@ -1918,7 +1918,7 @@ brw_vec4_setup_prog_key_for_precompile(struct gl_context *ctx,
>     key->program_string_id = id;
>     key->clamp_vertex_color = ctx->API == API_OPENGL_COMPAT;
>  
> -   unsigned sampler_count = _mesa_fls(prog->SamplersUsed);
> +   unsigned sampler_count = util_fls(prog->SamplersUsed);
>     for (unsigned i = 0; i < sampler_count; i++) {
>        if (prog->ShadowSamplers & (1 << i)) {
>           /* Assume DEPTH_TEXTURE_MODE is the default: X, X, X, 1 */
> diff --git a/src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp
> index db0e6cc..4da02c7 100644
> --- a/src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp
> +++ b/src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp
> @@ -368,7 +368,7 @@ vec4_gs_visitor::emit_control_data_bits()
>           src_reg prev_count(this, glsl_type::uint_type);
>           emit(ADD(dst_reg(prev_count), this->vertex_count, 0xffffffffu));
>           unsigned log2_bits_per_vertex =
> -            _mesa_fls(c->control_data_bits_per_vertex);
> +            util_fls(c->control_data_bits_per_vertex);
>           emit(SHR(dst_reg(dword_index), prev_count,
>                    (uint32_t) (6 - log2_bits_per_vertex)));
>        }
> diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c
> index 5863573..5b692ee 100644
> --- a/src/mesa/drivers/dri/i965/brw_wm.c
> +++ b/src/mesa/drivers/dri/i965/brw_wm.c
> @@ -539,8 +539,8 @@ static void brw_wm_populate_key( struct brw_context *brw,
>        (fp->program.Base.SystemValuesRead & SYSTEM_BIT_SAMPLE_ID);
>  
>     /* BRW_NEW_VUE_MAP_GEOM_OUT */
> -   if (brw->gen < 6 || _mesa_bitcount_64(fp->program.Base.InputsRead &
> -                                         BRW_FS_VARYING_INPUT_MASK) > 16)
> +   if (brw->gen < 6 || util_bitcount_64(fp->program.Base.InputsRead &
> +                                        BRW_FS_VARYING_INPUT_MASK) > 16)
>        key->input_slots_valid = brw->vue_map_geom_out.slots_valid;
>  
>  
> diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
> index ef46dd7..4bd1087 100644
> --- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
> +++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
> @@ -769,7 +769,7 @@ update_stage_texture_surfaces(struct brw_context *brw,
>     else
>        surf_offset += stage_state->prog_data->binding_table.texture_start;
>  
> -   unsigned num_samplers = _mesa_fls(prog->SamplersUsed);
> +   unsigned num_samplers = util_fls(prog->SamplersUsed);
>     for (unsigned s = 0; s < num_samplers; s++) {
>        surf_offset[s] = 0;
>  
> diff --git a/src/mesa/drivers/x11/fakeglx.c b/src/mesa/drivers/x11/fakeglx.c
> index ee05f8a..b1b470a 100644
> --- a/src/mesa/drivers/x11/fakeglx.c
> +++ b/src/mesa/drivers/x11/fakeglx.c
> @@ -528,9 +528,9 @@ get_visual( Display *dpy, int scr, unsigned int depth, int xclass )
>      * 10 bits per color channel.  Mesa's limited to a max of 8 bits/channel.
>      */
>     if (vis && depth > 24 && (xclass==TrueColor || xclass==DirectColor)) {
> -      if (_mesa_bitcount((GLuint) vis->red_mask  ) <= 8 &&
> -          _mesa_bitcount((GLuint) vis->green_mask) <= 8 &&
> -          _mesa_bitcount((GLuint) vis->blue_mask ) <= 8) {
> +      if (util_bitcount((GLuint) vis->red_mask  ) <= 8 &&
> +          util_bitcount((GLuint) vis->green_mask) <= 8 &&
> +          util_bitcount((GLuint) vis->blue_mask ) <= 8) {
>           return vis;
>        }
>        else {
> diff --git a/src/mesa/drivers/x11/xm_api.c b/src/mesa/drivers/x11/xm_api.c
> index 2d66dbd..c85b9f6 100644
> --- a/src/mesa/drivers/x11/xm_api.c
> +++ b/src/mesa/drivers/x11/xm_api.c
> @@ -462,9 +462,9 @@ setup_truecolor(XMesaVisual v, XMesaBuffer buffer, XMesaColormap cmap)
>            3*16, 11*16,  1*16,  9*16,
>           15*16,  7*16, 13*16,  5*16,
>        };
> -      GLint rBits = _mesa_bitcount(rmask);
> -      GLint gBits = _mesa_bitcount(gmask);
> -      GLint bBits = _mesa_bitcount(bmask);
> +      GLint rBits = util_bitcount(rmask);
> +      GLint gBits = util_bitcount(gmask);
> +      GLint bBits = util_bitcount(bmask);
>        GLint maxBits;
>        GLuint i;
>  
> @@ -827,9 +827,9 @@ XMesaVisual XMesaCreateVisual( XMesaDisplay *display,
>     {
>        const int xclass = v->visualType;
>        if (xclass == GLX_TRUE_COLOR || xclass == GLX_DIRECT_COLOR) {
> -         red_bits   = _mesa_bitcount(GET_REDMASK(v));
> -         green_bits = _mesa_bitcount(GET_GREENMASK(v));
> -         blue_bits  = _mesa_bitcount(GET_BLUEMASK(v));
> +         red_bits   = util_bitcount(GET_REDMASK(v));
> +         green_bits = util_bitcount(GET_GREENMASK(v));
> +         blue_bits  = util_bitcount(GET_BLUEMASK(v));
>        }
>        else {
>           /* this is an approximation */
> @@ -1091,8 +1091,8 @@ XMesaCreatePixmapTextureBuffer(XMesaVisual v, XMesaPixmap p,
>        if (ctx->Extensions.ARB_texture_non_power_of_two) {
>           target = GLX_TEXTURE_2D_EXT;
>        }
> -      else if (   _mesa_bitcount(width)  == 1
> -               && _mesa_bitcount(height) == 1) {
> +      else if (   util_bitcount(width)  == 1
> +               && util_bitcount(height) == 1) {
>           /* power of two size */
>           if (height == 1) {
>              target = GLX_TEXTURE_1D_EXT;
> diff --git a/src/mesa/main/bitset.h b/src/mesa/main/bitset.h
> index 601fd0e..f50b14f 100644
> --- a/src/mesa/main/bitset.h
> +++ b/src/mesa/main/bitset.h
> @@ -32,6 +32,7 @@
>  #define BITSET_H
>  
>  #include "imports.h"
> +#include "util/bitcount.h"
>  
>  /****************************************************************************
>   * generic bitset implementation
> diff --git a/src/mesa/main/buffers.c b/src/mesa/main/buffers.c
> index 1ee2009..8d50447 100644
> --- a/src/mesa/main/buffers.c
> +++ b/src/mesa/main/buffers.c
> @@ -374,7 +374,7 @@ _mesa_DrawBuffers(GLsizei n, const GLenum *buffers)
>            *  Previous versions of the OpenGL specification say INVALID_OPERATION,
>            *  but the Khronos conformance tests expect INVALID_ENUM.
>            */
> -         if (_mesa_bitcount(destMask[output]) > 1) {
> +         if (util_bitcount(destMask[output]) > 1) {
>              _mesa_error(ctx, GL_INVALID_ENUM, "glDrawBuffersARB(buffer)");
>              return;
>           }
> @@ -497,7 +497,7 @@ _mesa_drawbuffers(struct gl_context *ctx, GLuint n, const GLenum *buffers,
>      * (ex: glDrawBuffer(GL_FRONT_AND_BACK)).
>      * Otherwise, destMask[x] can only have one bit set.
>      */
> -   if (n > 0 && _mesa_bitcount(destMask[0]) > 1) {
> +   if (n > 0 && util_bitcount(destMask[0]) > 1) {
>        GLuint count = 0, destMask0 = destMask[0];
>        while (destMask0) {
>           GLint bufIndex = ffs(destMask0) - 1;
> @@ -517,7 +517,7 @@ _mesa_drawbuffers(struct gl_context *ctx, GLuint n, const GLenum *buffers,
>           if (destMask[buf]) {
>              GLint bufIndex = ffs(destMask[buf]) - 1;
>              /* only one bit should be set in the destMask[buf] field */
> -            ASSERT(_mesa_bitcount(destMask[buf]) == 1);
> +            ASSERT(util_bitcount(destMask[buf]) == 1);
>              if (fb->_ColorDrawBufferIndexes[buf] != bufIndex) {
>  	       updated_drawbuffers(ctx);
>                 fb->_ColorDrawBufferIndexes[buf] = bufIndex;
> diff --git a/src/mesa/main/imports.c b/src/mesa/main/imports.c
> index b8c7548..ac4b698 100644
> --- a/src/mesa/main/imports.c
> +++ b/src/mesa/main/imports.c
> @@ -217,94 +217,6 @@ _mesa_align_realloc(void *oldBuffer, size_t oldSize, size_t newSize,
>  /*@{*/
>  
>  
> -#ifndef HAVE___BUILTIN_FFS
> -/**
> - * Find the first bit set in a word.
> - */
> -int
> -ffs(int i)
> -{
> -   register int bit = 0;
> -   if (i != 0) {
> -      if ((i & 0xffff) == 0) {
> -         bit += 16;
> -         i >>= 16;
> -      }
> -      if ((i & 0xff) == 0) {
> -         bit += 8;
> -         i >>= 8;
> -      }
> -      if ((i & 0xf) == 0) {
> -         bit += 4;
> -         i >>= 4;
> -      }
> -      while ((i & 1) == 0) {
> -         bit++;
> -         i >>= 1;
> -      }
> -      bit++;
> -   }
> -   return bit;
> -}
> -#endif
> -
> -#ifndef HAVE___BUILTIN_FFSLL
> -/**
> - * Find position of first bit set in given value.
> - * XXX Warning: this function can only be used on 64-bit systems!
> - * \return  position of least-significant bit set, starting at 1, return zero
> - *          if no bits set.
> - */
> -int
> -ffsll(long long int val)
> -{
> -   int bit;
> -
> -   assert(sizeof(val) == 8);
> -
> -   bit = ffs((int) val);
> -   if (bit != 0)
> -      return bit;
> -
> -   bit = ffs((int) (val >> 32));
> -   if (bit != 0)
> -      return 32 + bit;
> -
> -   return 0;
> -}
> -#endif
> -
> -
> -#ifndef HAVE___BUILTIN_POPCOUNT
> -/**
> - * Return number of bits set in given GLuint.
> - */
> -unsigned int
> -_mesa_bitcount(unsigned int n)
> -{
> -   unsigned int bits;
> -   for (bits = 0; n > 0; n = n >> 1) {
> -      bits += (n & 1);
> -   }
> -   return bits;
> -}
> -#endif
> -
> -#ifndef HAVE___BUILTIN_POPCOUNTLL
> -/**
> - * Return number of bits set in given 64-bit uint.
> - */
> -unsigned int
> -_mesa_bitcount_64(uint64_t n)
> -{
> -   unsigned int bits;
> -   for (bits = 0; n > 0; n = n >> 1) {
> -      bits += (n & 1);
> -   }
> -   return bits;
> -}
> -#endif
> -
>  
>  /* Using C99 rounding functions for roundToEven() implementation is
>   * difficult, because round(), rint, and nearbyint() are affected by
> diff --git a/src/mesa/main/imports.h b/src/mesa/main/imports.h
> index 436d165..0b03816 100644
> --- a/src/mesa/main/imports.h
> +++ b/src/mesa/main/imports.h
> @@ -39,6 +39,7 @@
>  #include "compiler.h"
>  #include "glheader.h"
>  #include "errors.h"
> +#include "util/bitcount.h"
>  
>  #ifdef __cplusplus
>  extern "C" {
> @@ -469,59 +470,6 @@ extern void
>  _mesa_exec_free( void *addr );
>  
>  
> -#ifndef FFS_DEFINED
> -#define FFS_DEFINED 1
> -#ifdef HAVE___BUILTIN_FFS
> -#define ffs __builtin_ffs
> -#else
> -extern int ffs(int i);
> -#endif
> -
> -#ifdef HAVE___BUILTIN_FFSLL
> -#define ffsll __builtin_ffsll
> -#else
> -extern int ffsll(long long int i);
> -#endif
> -#endif /* FFS_DEFINED */
> -
> -
> -#ifdef HAVE___BUILTIN_POPCOUNT
> -#define _mesa_bitcount(i) __builtin_popcount(i)
> -#else
> -extern unsigned int
> -_mesa_bitcount(unsigned int n);
> -#endif
> -
> -#ifdef HAVE___BUILTIN_POPCOUNTLL
> -#define _mesa_bitcount_64(i) __builtin_popcountll(i)
> -#else
> -extern unsigned int
> -_mesa_bitcount_64(uint64_t n);
> -#endif
> -
> -/**
> - * Find the last (most significant) bit set in a word.
> - *
> - * Essentially ffs() in the reverse direction.
> - */
> -static inline unsigned int
> -_mesa_fls(unsigned int n)
> -{
> -#ifdef HAVE___BUILTIN_CLZ
> -   return n == 0 ? 0 : 32 - __builtin_clz(n);
> -#else
> -   unsigned int v = 1;
> -
> -   if (n == 0)
> -      return 0;
> -
> -   while (n >>= 1)
> -       v++;
> -
> -   return v;
> -#endif
> -}
> -
>  extern int
>  _mesa_round_to_even(float val);
>  
> diff --git a/src/mesa/program/program_parse.y b/src/mesa/program/program_parse.y
> index 1664740..e79c944 100644
> --- a/src/mesa/program/program_parse.y
> +++ b/src/mesa/program/program_parse.y
> @@ -2771,7 +2771,7 @@ _mesa_parse_arb_program(struct gl_context *ctx, GLenum target, const GLubyte *st
>     state->prog->NumInstructions++;
>  
>     state->prog->NumParameters = state->prog->Parameters->NumParameters;
> -   state->prog->NumAttributes = _mesa_bitcount_64(state->prog->InputsRead);
> +   state->prog->NumAttributes = util_bitcount_64(state->prog->InputsRead);
>  
>     /*
>      * Initialize native counts to logical counts.  The device driver may
> diff --git a/src/util/Makefile.sources b/src/util/Makefile.sources
> index 952b799..605c524 100644
> --- a/src/util/Makefile.sources
> +++ b/src/util/Makefile.sources
> @@ -1,6 +1,7 @@
>  MESA_UTIL_FILES :=	\
>  	hash_table.c	\
>  	ralloc.c \
> +        bitcount.c \
>  	register_allocate.c \
>  	register_allocate.h \
>  	rgtc.c
> diff --git a/src/util/bitcount.c b/src/util/bitcount.c
> new file mode 100644
> index 0000000..1e65000
> --- /dev/null
> +++ b/src/util/bitcount.c
> @@ -0,0 +1,115 @@
> +/*
> + * Mesa 3-D graphics library
> + *
> + * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
> + * Copyright (C) 2014 Intel Corporation
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included
> + * in all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
> + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
> + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
> + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
> + * OTHER DEALINGS IN THE SOFTWARE.
> + */
> +
> +#include "bitcount.h"
> +
> +#ifndef HAVE___BUILTIN_FFS
> +/**
> + * Find the first bit set in a word.
> + */
> +int
> +ffs(int i)
> +{
> +   register int bit = 0;
> +   if (i != 0) {
> +      if ((i & 0xffff) == 0) {
> +         bit += 16;
> +         i >>= 16;
> +      }
> +      if ((i & 0xff) == 0) {
> +         bit += 8;
> +         i >>= 8;
> +      }
> +      if ((i & 0xf) == 0) {
> +         bit += 4;
> +         i >>= 4;
> +      }
> +      while ((i & 1) == 0) {
> +         bit++;
> +         i >>= 1;
> +      }
> +      bit++;
> +   }
> +   return bit;
> +}
> +#endif
> +
> +#ifndef HAVE___BUILTIN_FFSLL
> +/**
> + * Find position of first bit set in given value.
> + * XXX Warning: this function can only be used on 64-bit systems!
> + * \return  position of least-significant bit set, starting at 1, return zero
> + *          if no bits set.
> + */
> +int
> +ffsll(long long int val)
> +{
> +   int bit;
> +
> +   assert(sizeof(val) == 8);
> +
> +   bit = ffs((int) val);
> +   if (bit != 0)
> +      return bit;
> +
> +   bit = ffs((int) (val >> 32));
> +   if (bit != 0)
> +      return 32 + bit;
> +
> +   return 0;
> +}
> +#endif
> +
> +
> +#ifndef HAVE___BUILTIN_POPCOUNT
> +/**
> + * Return number of bits set in given GLuint.
> + */
> +unsigned int
> +util_bitcount(unsigned int n)
> +{
> +   unsigned int bits;
> +   for (bits = 0; n > 0; n = n >> 1) {
> +      bits += (n & 1);
> +   }
> +   return bits;
> +}
> +#endif
> +
> +#ifndef HAVE___BUILTIN_POPCOUNTLL
> +/**
> + * Return number of bits set in given 64-bit uint.
> + */
> +unsigned int
> +util_bitcount_64(uint64_t n)
> +{
> +   unsigned int bits;
> +   for (bits = 0; n > 0; n = n >> 1) {
> +      bits += (n & 1);
> +   }
> +   return bits;
> +}
> +#endif
> +
> diff --git a/src/util/bitcount.h b/src/util/bitcount.h
> new file mode 100644
> index 0000000..a1ab2b3
> --- /dev/null
> +++ b/src/util/bitcount.h
> @@ -0,0 +1,94 @@
> +/*
> + * Mesa 3-D graphics library
> + *
> + * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
> + * Copyright (C) 2014 Intel Corporation
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice shall be included
> + * in all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
> + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
> + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
> + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
> + * OTHER DEALINGS IN THE SOFTWARE.
> + */
> +
> +/**
> + * Various utilities for counting bits.
> + */
> +
> +#ifndef UTIL_BITCOUNT_H
> +#define UTIL_BITCOUNT_H
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +#ifndef FFS_DEFINED
> +#define FFS_DEFINED 1
> +#ifdef HAVE___BUILTIN_FFS
> +#define ffs __builtin_ffs
> +#else
> +extern int ffs(int i);
> +#endif
> +
> +#ifdef HAVE___BUILTIN_FFSLL
> +#define ffsll __builtin_ffsll
> +#else
> +extern int ffsll(long long int i);
> +#endif
> +#endif /* FFS_DEFINED */
> +
> +
> +#ifdef HAVE___BUILTIN_POPCOUNT
> +#define util_bitcount(i) __builtin_popcount(i)
> +#else
> +extern unsigned int
> +util_bitcount(unsigned int n);
> +#endif
> +
> +#ifdef HAVE___BUILTIN_POPCOUNTLL
> +#define util_bitcount_64(i) __builtin_popcountll(i)
> +#else
> +extern unsigned int
> +util_bitcount_64(uint64_t n);
> +#endif
> +
> +/**
> + * Find the last (most significant) bit set in a word.
> + *
> + * Essentially ffs() in the reverse direction.
> + */
> +static inline unsigned int
> +util_fls(unsigned int n)
> +{
> +#ifdef HAVE___BUILTIN_CLZ
> +   return n == 0 ? 0 : 32 - __builtin_clz(n);
> +#else
> +   unsigned int v = 1;
> +
> +   if (n == 0)
> +      return 0;
> +
> +   while (n >>= 1)
> +       v++;
> +
> +   return v;
> +#endif
> +}
> +
> +#ifdef __cplusplus
> +} /* extern "C" */
> +#endif
> +
> +#endif /* UTIL_BITCOUNT_H */
> 



More information about the mesa-dev mailing list