freedreno: rework blit API
authorRob Clark <robdclark@gmail.com>
Wed, 2 Jan 2019 15:54:06 +0000 (10:54 -0500)
committerRob Clark <robdclark@gmail.com>
Thu, 3 Jan 2019 13:09:52 +0000 (08:09 -0500)
First step to unify the way fd5 and fd6 blitter works.  Currently a6xx
bypasses the blit API in order to also accelerate resource_copy_region()

But this approach can lead to infinite recursion:

  #0  fd_alloc_staging (ctx=0x5555936480, rsc=0x7fac485f90, level=0, box=0x7fbab29220) at ../src/gallium/drivers/freedreno/freedreno_resource.c:291
  #1  0x0000007fbdebed04 in fd_resource_transfer_map (pctx=0x5555936480, prsc=0x7fac485f90, level=0, usage=258, box=0x7fbab29220, pptrans=0x7fbab29240) at ../src/gallium/drivers/freedreno/freedreno_resource.c:479
  #2  0x0000007fbe5c5068 in u_transfer_helper_transfer_map (pctx=0x5555936480, prsc=0x7fac485f90, level=0, usage=258, box=0x7fbab29220, pptrans=0x7fbab29240) at ../src/gallium/auxiliary/util/u_transfer_helper.c:243
  #3  0x0000007fbde2dcb8 in util_resource_copy_region (pipe=0x5555936480, dst=0x7fac485f90, dst_level=0, dst_x=0, dst_y=0, dst_z=0, src=0x7fac47c780, src_level=0, src_box_in=0x7fbab2945c) at ../src/gallium/auxiliary/util/u_surface.c:350
  #4  0x0000007fbdf2282c in fd_resource_copy_region (pctx=0x5555936480, dst=0x7fac485f90, dst_level=0, dstx=0, dsty=0, dstz=0, src=0x7fac47c780, src_level=0, src_box=0x7fbab2945c) at ../src/gallium/drivers/freedreno/freedreno_blitter.c:173
  #5  0x0000007fbdf085d4 in fd6_resource_copy_region (pctx=0x5555936480, dst=0x7fac485f90, dst_level=0, dstx=0, dsty=0, dstz=0, src=0x7fac47c780, src_level=0, src_box=0x7fbab2945c) at ../src/gallium/drivers/freedreno/a6xx/fd6_blitter.c:587
  #6  0x0000007fbde2f3d0 in util_try_blit_via_copy_region (ctx=0x5555936480, blit=0x7fbab29430) at ../src/gallium/auxiliary/util/u_surface.c:864
  #7  0x0000007fbdec02c4 in fd_blit (pctx=0x5555936480, blit_info=0x7fbab29588) at ../src/gallium/drivers/freedreno/freedreno_resource.c:993
  #8  0x0000007fbdf08408 in fd6_blit (pctx=0x5555936480, info=0x7fbab29588) at ../src/gallium/drivers/freedreno/a6xx/fd6_blitter.c:546
  #9  0x0000007fbdebdc74 in do_blit (ctx=0x5555936480, blit=0x7fbab29588, fallback=false) at ../src/gallium/drivers/freedreno/freedreno_resource.c:129
  #10 0x0000007fbdebe58c in fd_blit_from_staging (ctx=0x5555936480, trans=0x7fac47b7e8) at ../src/gallium/drivers/freedreno/freedreno_resource.c:326
  #11 0x0000007fbdebea38 in fd_resource_transfer_unmap (pctx=0x5555936480, ptrans=0x7fac47b7e8) at ../src/gallium/drivers/freedreno/freedreno_resource.c:416
  #12 0x0000007fbe5c5c68 in u_transfer_helper_transfer_unmap (pctx=0x5555936480, ptrans=0x7fac47b7e8) at ../src/gallium/auxiliary/util/u_transfer_helper.c:516
  #13 0x0000007fbde2de24 in util_resource_copy_region (pipe=0x5555936480, dst=0x7fac485f90, dst_level=0, dst_x=0, dst_y=0, dst_z=0, src=0x7fac47b8e0, src_level=0, src_box_in=0x7fbab2997c) at ../src/gallium/auxiliary/util/u_surface.c:376
  #14 0x0000007fbdf2282c in fd_resource_copy_region (pctx=0x5555936480, dst=0x7fac485f90, dst_level=0, dstx=0, dsty=0, dstz=0, src=0x7fac47b8e0, src_level=0, src_box=0x7fbab2997c) at ../src/gallium/drivers/freedreno/freedreno_blitter.c:173
  #15 0x0000007fbdf085d4 in fd6_resource_copy_region (pctx=0x5555936480, dst=0x7fac485f90, dst_level=0, dstx=0, dsty=0, dstz=0, src=0x7fac47b8e0, src_level=0, src_box=0x7fbab2997c) at ../src/gallium/drivers/freedreno/a6xx/fd6_blitter.c:587
  ...

Instead rework the API to push the fallback back to core code, so that
we can rework resource_copy_region() to have it's own fallback path,
and then finally convert fd6 over to work in the same way.

This also makes ctx->blit() optional, and cleans up some unnecessary
callers.

Signed-off-by: Rob Clark <robdclark@gmail.com>
src/gallium/drivers/freedreno/a5xx/fd5_blitter.c
src/gallium/drivers/freedreno/a5xx/fd5_blitter.h
src/gallium/drivers/freedreno/a6xx/fd6_blitter.c
src/gallium/drivers/freedreno/freedreno_blitter.c
src/gallium/drivers/freedreno/freedreno_blitter.h
src/gallium/drivers/freedreno/freedreno_context.c
src/gallium/drivers/freedreno/freedreno_context.h
src/gallium/drivers/freedreno/freedreno_resource.c

index 09ff2b7..0cfe92a 100644 (file)
@@ -449,14 +449,13 @@ emit_blit(struct fd_ringbuffer *ring, const struct pipe_blit_info *info)
        }
 }
 
-void
+bool
 fd5_blitter_blit(struct fd_context *ctx, const struct pipe_blit_info *info)
 {
        struct fd_batch *batch;
 
        if (!can_do_blit(info)) {
-               fd_blitter_blit(ctx, info);
-               return;
+               return false;
        }
 
        batch = fd_bc_alloc_batch(&ctx->screen->batch_cache, ctx, true);
@@ -482,6 +481,8 @@ fd5_blitter_blit(struct fd_context *ctx, const struct pipe_blit_info *info)
        batch->needs_flush = true;
 
        fd_batch_flush(batch, false, false);
+
+       return true;
 }
 
 unsigned
index b03c77e..69a071c 100644 (file)
@@ -31,7 +31,7 @@
 
 #include "freedreno_context.h"
 
-void fd5_blitter_blit(struct fd_context *ctx, const struct pipe_blit_info *info);
+bool fd5_blitter_blit(struct fd_context *ctx, const struct pipe_blit_info *info);
 unsigned fd5_tile_mode(const struct pipe_resource *tmpl);
 
 #endif /* FD5_BLIT_H_ */
index 97e015d..e163596 100644 (file)
@@ -562,9 +562,7 @@ fd6_blit(struct pipe_context *pctx, const struct pipe_blit_info *info)
        struct fd_context *ctx = fd_context(pctx);
 
        if (!can_do_blit(info)) {
-               fd_blitter_pipe_begin(ctx, info->render_condition_enable, false, FD_STAGE_BLIT);
                fd_blitter_blit(ctx, info);
-               fd_blitter_pipe_end(ctx);
                return;
        }
 
index f1ed538..5c48075 100644 (file)
@@ -82,7 +82,7 @@ default_src_texture(struct pipe_sampler_view *src_templ,
        src_templ->swizzle_a = PIPE_SWIZZLE_W;
 }
 
-void
+bool
 fd_blitter_blit(struct fd_context *ctx, const struct pipe_blit_info *info)
 {
        struct pipe_resource *dst = info->dst.resource;
@@ -90,6 +90,16 @@ fd_blitter_blit(struct fd_context *ctx, const struct pipe_blit_info *info)
        struct pipe_context *pipe = &ctx->base;
        struct pipe_surface *dst_view, dst_templ;
        struct pipe_sampler_view src_templ, *src_view;
+       bool discard = false;
+
+       if (!info->scissor_enable && !info->alpha_blend) {
+               discard = util_texrange_covers_whole_level(info->dst.resource,
+                               info->dst.level, info->dst.box.x, info->dst.box.y,
+                               info->dst.box.z, info->dst.box.width,
+                               info->dst.box.height, info->dst.box.depth);
+       }
+
+       fd_blitter_pipe_begin(ctx, info->render_condition_enable, discard, FD_STAGE_BLIT);
 
        /* Initialize the surface. */
        default_dst_texture(&dst_templ, dst, info->dst.level,
@@ -111,6 +121,11 @@ fd_blitter_blit(struct fd_context *ctx, const struct pipe_blit_info *info)
 
        pipe_surface_reference(&dst_view, NULL);
        pipe_sampler_view_reference(&src_view, NULL);
+
+       fd_blitter_pipe_end(ctx);
+
+       /* The fallback blitter must never fail: */
+       return true;
 }
 
 /**
index 1fe85a8..70f71fc 100644 (file)
@@ -31,7 +31,7 @@
 
 #include "freedreno_context.h"
 
-void fd_blitter_blit(struct fd_context *ctx, const struct pipe_blit_info *info);
+bool fd_blitter_blit(struct fd_context *ctx, const struct pipe_blit_info *info);
 
 void fd_resource_copy_region(struct pipe_context *pctx,
                struct pipe_resource *dst,
index a08acea..6c01c15 100644 (file)
@@ -333,9 +333,6 @@ fd_context_init(struct fd_context *ctx, struct pipe_screen *pscreen,
 
        slab_create_child(&ctx->transfer_pool, &screen->transfer_pool);
 
-       if (!ctx->blit)
-               ctx->blit = fd_blitter_blit;
-
        fd_draw_init(pctx);
        fd_resource_context_init(pctx);
        fd_query_context_init(pctx);
index 3a03845..f44738f 100644 (file)
@@ -343,7 +343,7 @@ struct fd_context {
        void (*query_set_stage)(struct fd_batch *batch, enum fd_render_stage stage);
 
        /* blitter: */
-       void (*blit)(struct fd_context *ctx, const struct pipe_blit_info *info);
+       bool (*blit)(struct fd_context *ctx, const struct pipe_blit_info *info);
 
        /* simple gpu "memcpy": */
        void (*mem_to_mem)(struct fd_ringbuffer *ring, struct pipe_resource *dst,
index 482ce94..f1e439b 100644 (file)
@@ -122,15 +122,15 @@ realloc_bo(struct fd_resource *rsc, uint32_t size)
 static void
 do_blit(struct fd_context *ctx, const struct pipe_blit_info *blit, bool fallback)
 {
+       struct pipe_context *pctx = &ctx->base;
+
        /* TODO size threshold too?? */
        if (!fallback) {
                /* do blit on gpu: */
-               fd_blitter_pipe_begin(ctx, false, true, FD_STAGE_BLIT);
-               ctx->blit(ctx, blit);
-               fd_blitter_pipe_end(ctx);
+               pctx->blit(pctx, blit);
        } else {
                /* do blit on cpu: */
-               util_resource_copy_region(&ctx->base,
+               util_resource_copy_region(pctx,
                                blit->dst.resource, blit->dst.level, blit->dst.box.x,
                                blit->dst.box.y, blit->dst.box.z,
                                blit->src.resource, blit->src.level, &blit->src.box);
@@ -975,18 +975,10 @@ fd_blit(struct pipe_context *pctx, const struct pipe_blit_info *blit_info)
 {
        struct fd_context *ctx = fd_context(pctx);
        struct pipe_blit_info info = *blit_info;
-       bool discard = false;
 
        if (info.render_condition_enable && !fd_render_condition_check(pctx))
                return;
 
-       if (!info.scissor_enable && !info.alpha_blend) {
-               discard = util_texrange_covers_whole_level(info.dst.resource,
-                               info.dst.level, info.dst.box.x, info.dst.box.y,
-                               info.dst.box.z, info.dst.box.width,
-                               info.dst.box.height, info.dst.box.depth);
-       }
-
        if (util_try_blit_via_copy_region(pctx, &info)) {
                return; /* done */
        }
@@ -1003,9 +995,8 @@ fd_blit(struct pipe_context *pctx, const struct pipe_blit_info *blit_info)
                return;
        }
 
-       fd_blitter_pipe_begin(ctx, info.render_condition_enable, discard, FD_STAGE_BLIT);
-       ctx->blit(ctx, &info);
-       fd_blitter_pipe_end(ctx);
+       if (!(ctx->blit && ctx->blit(ctx, &info)))
+               fd_blitter_blit(ctx, &info);
 }
 
 void