nvfx: allow nested blitter usage, fixing bug in clear
authorLuca Barbieri <luca@luca-barbieri.com>
Fri, 3 Sep 2010 21:27:49 +0000 (23:27 +0200)
committerLuca Barbieri <luca@luca-barbieri.com>
Sat, 4 Sep 2010 00:08:02 +0000 (02:08 +0200)
src/gallium/drivers/nvfx/nvfx_context.h
src/gallium/drivers/nvfx/nvfx_state_emit.c
src/gallium/drivers/nvfx/nvfx_surface.c

index 9e46f5d..b837437 100644 (file)
@@ -144,7 +144,9 @@ struct nvfx_context {
        boolean use_vp_clipping;
 
        struct draw_context *draw;
-       struct blitter_context* blitter;
+       /* one is for user-requested operations, the other is for temporary copying inside them */
+       struct blitter_context* blitter[2];
+       unsigned blitters_in_use;
        struct list_head render_cache;
 
        /* HW state derived from pipe states */
index 390bca8..128cf2b 100644 (file)
@@ -296,9 +296,6 @@ nvfx_state_validate(struct nvfx_context *nvfx)
        if(!nvfx_state_validate_common(nvfx))
                return FALSE;
 
-       if (was_sw)
-               NOUVEAU_ERR("swtnl->hw\n");
-
        return TRUE;
 }
 
index a5931b6..6743d06 100644 (file)
@@ -187,15 +187,18 @@ nv04_scaled_image_format(enum pipe_format format)
        }
 }
 
-// XXX: must save index buffer too!
+// don't save index buffer because blitter doesn't setit
 static struct blitter_context*
 nvfx_get_blitter(struct pipe_context* pipe, int copy)
 {
        struct nvfx_context* nvfx = nvfx_context(pipe);
 
-       struct blitter_context* blitter = nvfx->blitter;
-       if(!blitter)
-               nvfx->blitter = blitter = util_blitter_create(pipe);
+       assert(nvfx->blitters_in_use < Elements(nvfx->blitter));
+
+       struct blitter_context** pblitter = &nvfx->blitter[nvfx->blitters_in_use++];
+       if(!*pblitter)
+               *pblitter = util_blitter_create(pipe);
+       struct blitter_context* blitter = *pblitter;
 
        util_blitter_save_blend(blitter, nvfx->blend);
        util_blitter_save_depth_stencil_alpha(blitter, nvfx->zsa);
@@ -218,6 +221,14 @@ nvfx_get_blitter(struct pipe_context* pipe, int copy)
        return blitter;
 }
 
+static inline void
+nvfx_put_blitter(struct pipe_context* pipe, struct blitter_context* blitter)
+{
+       struct nvfx_context* nvfx = nvfx_context(pipe);
+       --nvfx->blitters_in_use;
+       assert(nvfx->blitters_in_use >= 0);
+}
+
 static unsigned
 nvfx_region_clone(struct nv04_2d_context* ctx, struct nv04_region* rgn, unsigned w, unsigned h, boolean for_read)
 {
@@ -279,6 +290,7 @@ nvfx_resource_copy_region(struct pipe_context *pipe,
        {
                struct blitter_context* blitter = nvfx_get_blitter(pipe, 1);
                util_blitter_copy_region(blitter, dstr, subdst, dstx, dsty, dstz, srcr, subsrc, srcx, srcy, srcz, w, h, TRUE);
+               nvfx_put_blitter(pipe, blitter);
        }
        else
        {
@@ -459,6 +471,7 @@ nvfx_clear_render_target(struct pipe_context *pipe,
                // TODO: probably should use hardware clear here instead if possible
                struct blitter_context* blitter = nvfx_get_blitter(pipe, 0);
                util_blitter_clear_render_target(blitter, dst, rgba, dstx, dsty, width, height);
+               nvfx_put_blitter(pipe, blitter);
        }
 }
 
@@ -477,6 +490,7 @@ nvfx_clear_depth_stencil(struct pipe_context *pipe,
                // TODO: probably should use hardware clear here instead if possible
                struct blitter_context* blitter = nvfx_get_blitter(pipe, 0);
                util_blitter_clear_depth_stencil(blitter, dst, clear_flags, depth, stencil, dstx, dsty, width, height);
+               nvfx_put_blitter(pipe, blitter);
        }
 }