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

Lucas Stach dev at lynxeye.de
Thu Dec 29 06:22:02 PST 2011


Ok, disregard this patch.

I see this is a bad idea and will fix the issue in another way in nvfx.

Thanks,
Lucas

Am Donnerstag, den 29.12.2011, 01:12 +0100 schrieb Marek Olšák:
> 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