[Mesa-dev] [PATCH] util: u_gen_mipmap: use software path for small mipmap levels

Marek Olšák maraeo at gmail.com
Wed Dec 28 16:12:58 PST 2011


HI Lucas,

The fallback will be slower on Radeons for these two reasons:
- Texture transfers are implemented using a blit to or from a
temporary texture, which is allocated in get_transfer, so it takes
more CPU time than simply generating all mipmap levels on hardware
- Mapping a texture causes waiting for the GPU to complete all of its
work, i.e. there will be a stall in transfer_map for an unspecified
time. At the time of calling transfer_map, the GPU may not have even
started generating any mipmap levels, so the waiting would be quite
noticable. This applies to all GPUs. Also, some rendering techniques
use mipmap generation every frame, i.e. to compute an average color of
the back buffer, which is common in HDR rendering. I would not like to
have any stalls there.

Marek

On Wed, Dec 28, 2011 at 8:28 PM, Lucas Stach <dev at lynxeye.de> wrote:
> From 1273dd1e1ede35b9a434c3f9d9eaa4a03eb8d0b3 Mon Sep 17 00:00:00 2001
> From: Lucas Stach <dev at lynxeye.de>
> Date: Wed, 28 Dec 2011 20:00:48 +0100
> Subject: [PATCH] util: u_gen_mipmap: use software path for small mipmap
>  levels
>
> We are changing a lot of states to generate mipmaps with the
> hardware 3D engine, which is a good thing for big mipmap levels as
> it is fast. Generating the small mipmap levels this way is unlikely
> to outperform the software path, which is using a transfer.
>
> Additionally some hardware, like the nv3x and nv4x ones, have
> alignment requirements for render targets which prevents them from
> rendering into smaller render targets than 16x16 pixel. To
> generate those small mipmap levels the nvfx driver has to render to
> a temporary surface just to copy the result to the real render
> target using the 2D engine.
>
> Avoid all this overhead by just generating small mipmap levels
> using the software path.
>
> Signed-off-by: Lucas Stach <dev at lynxeye.de>
> ---
>  src/gallium/auxiliary/util/u_gen_mipmap.c |   23 +++++++++++++++++++----
>  1 files changed, 19 insertions(+), 4 deletions(-)
>
> diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c
> index 7cce815..88351b6 100644
> --- a/src/gallium/auxiliary/util/u_gen_mipmap.c
> +++ b/src/gallium/auxiliary/util/u_gen_mipmap.c
> @@ -911,6 +911,8 @@ format_to_type_comps(enum pipe_format pformat,
>    case PIPE_FORMAT_B8G8R8X8_UNORM:
>    case PIPE_FORMAT_A8R8G8B8_UNORM:
>    case PIPE_FORMAT_X8R8G8B8_UNORM:
> +   case PIPE_FORMAT_R8G8B8A8_UNORM:
> +   case PIPE_FORMAT_R8G8B8X8_UNORM:
>    case PIPE_FORMAT_A8B8G8R8_SRGB:
>    case PIPE_FORMAT_X8B8G8R8_SRGB:
>    case PIPE_FORMAT_B8G8R8A8_SRGB:
> @@ -1506,7 +1508,7 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
>    struct pipe_screen *screen = pipe->screen;
>    struct pipe_framebuffer_state fb;
>    struct pipe_resource *pt = psv->texture;
> -   uint dstLevel;
> +   uint dstLevel, hwLastLevel;
>    uint offset;
>    uint type;
>
> @@ -1588,10 +1590,17 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
>    ctx->sampler.min_img_filter = filter;
>
>    /*
> -    * XXX for small mipmap levels, it may be faster to use the software
> -    * fallback path...
> +    *  for small mipmap levels we use the software path as it is likely faster
> +    *  as we avoid a bunch of state changes and avoid triggering fallback paths
> +    *  in drivers incapable of rendering to images smaller than 16x16 pixel.
>     */
> -   for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) {
> +   for(hwLastLevel = baseLevel; hwLastLevel <= lastLevel; hwLastLevel++) {
> +          if((pt->height0 >> hwLastLevel <= 16) ||
> +                 (pt->width0 >> hwLastLevel <= 16))
> +                  break;
> +   }
> +
> +   for (dstLevel = baseLevel + 1; dstLevel <= hwLastLevel; dstLevel++) {
>       const uint srcLevel = dstLevel - 1;
>       struct pipe_viewport_state vp;
>       unsigned nr_layers, layer, i;
> @@ -1677,6 +1686,12 @@ util_gen_mipmap(struct gen_mipmap_state *ctx,
>       }
>    }
>
> +   /* if hardware path didn't fill all requested mip levels fill the remaining
> +    * levels with the software path
> +    */
> +   if(dstLevel < lastLevel)
> +          fallback_gen_mipmap(ctx, pt, face, dstLevel-1, lastLevel);
> +
>    /* restore state we changed */
>    cso_restore_blend(ctx->cso);
>    cso_restore_depth_stencil_alpha(ctx->cso);
> --
> 1.7.7.4
>
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list