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

Lucas Stach dev at lynxeye.de
Wed Dec 28 11:00:48 PST 2011


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




More information about the mesa-dev mailing list