[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