[Mesa-dev] [PATCH 2/6] panfrost: Disable the tiler for clear-only jobs

Alyssa Rosenzweig alyssa.rosenzweig at collabora.com
Fri Jun 14 21:58:27 UTC 2019


To do so, we route some basic information through to the FBD creation
routines (currently just a binary toggle of "has draws?"). Eventually,
more refactoring will enable dynamic hierarchy mask selection, but right
now we do the most basic.

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig at collabora.com>
---
 src/gallium/drivers/panfrost/pan_context.c  | 60 ++++++++++++---------
 src/gallium/drivers/panfrost/pan_context.h  | 11 ++--
 src/gallium/drivers/panfrost/pan_drm.c      |  2 +-
 src/gallium/drivers/panfrost/pan_fragment.c |  6 +--
 src/gallium/drivers/panfrost/pan_mfbd.c     |  4 +-
 src/gallium/drivers/panfrost/pan_sfbd.c     |  4 +-
 6 files changed, 50 insertions(+), 37 deletions(-)

diff --git a/src/gallium/drivers/panfrost/pan_context.c b/src/gallium/drivers/panfrost/pan_context.c
index fc6b8fbb0a1..de8da320b02 100644
--- a/src/gallium/drivers/panfrost/pan_context.c
+++ b/src/gallium/drivers/panfrost/pan_context.c
@@ -112,7 +112,7 @@ panfrost_set_framebuffer_resolution(struct mali_single_framebuffer *fb, int w, i
 }
 
 struct mali_single_framebuffer
-panfrost_emit_sfbd(struct panfrost_context *ctx)
+panfrost_emit_sfbd(struct panfrost_context *ctx, unsigned vertex_count)
 {
         struct mali_single_framebuffer framebuffer = {
                 .unknown2 = 0x1f,
@@ -133,27 +133,12 @@ panfrost_emit_sfbd(struct panfrost_context *ctx)
 }
 
 struct bifrost_framebuffer
-panfrost_emit_mfbd(struct panfrost_context *ctx)
+panfrost_emit_mfbd(struct panfrost_context *ctx, unsigned vertex_count)
 {
         unsigned width = ctx->pipe_framebuffer.width;
         unsigned height = ctx->pipe_framebuffer.height;
 
         struct bifrost_framebuffer framebuffer = {
-                /* The lower 0x1ff controls the hierarchy mask. Set more bits
-                 * on for more tile granularity (which can be a performance win
-                 * on some scenes, at memory bandwidth costs). For now, be lazy
-                 * and enable everything. This might be a terrible idea. */
-
-                .tiler_hierarchy_mask = 0xff,
-                .tiler_flags = 0x0,
-
-                /* The hardware deals with suballocation; we don't care */
-                .tiler_heap_start = ctx->tiler_heap.gpu,
-                .tiler_heap_end = ctx->tiler_heap.gpu + ctx->tiler_heap.size,
-
-                /* See pan_tiler.c */
-                .tiler_polygon_list  = ctx->tiler_polygon_list.gpu,
-
                 .width1 = MALI_POSITIVE(width),
                 .height1 = MALI_POSITIVE(height),
                 .width2 = MALI_POSITIVE(width),
@@ -170,6 +155,9 @@ panfrost_emit_mfbd(struct panfrost_context *ctx)
                 .scratchpad = ctx->scratchpad.gpu,
         };
 
+        framebuffer.tiler_hierarchy_mask =
+                panfrost_choose_hierarchy_mask(width, height, vertex_count);
+
         /* Compute the polygon header size and use that to offset the body */
 
         unsigned header_size = panfrost_tiler_header_size(
@@ -181,7 +169,28 @@ panfrost_emit_mfbd(struct panfrost_context *ctx)
         /* Sanity check */
 
         unsigned total_size = header_size + body_size;
-        assert(ctx->tiler_polygon_list.size >= total_size);
+
+        if (framebuffer.tiler_hierarchy_mask) {
+               assert(ctx->tiler_polygon_list.size >= total_size);
+
+                /* Specify allocated tiler structures */
+                framebuffer.tiler_polygon_list = ctx->tiler_polygon_list.gpu;
+
+                /* Allow the entire tiler heap */
+                framebuffer.tiler_heap_start = ctx->tiler_heap.gpu;
+                framebuffer.tiler_heap_end =
+                        ctx->tiler_heap.gpu + ctx->tiler_heap.size;
+        } else {
+                /* The tiler is disabled, so don't allow the tiler heap */
+                framebuffer.tiler_heap_start = ctx->tiler_heap.gpu;
+                framebuffer.tiler_heap_end = framebuffer.tiler_heap_start;
+
+                /* Use a dummy polygon list */
+                framebuffer.tiler_polygon_list = ctx->tiler_dummy.gpu;
+
+                /* Also, set a "tiler disabled?" flag? */
+                framebuffer.tiler_hierarchy_mask |= 0x1000;
+        }
 
         framebuffer.tiler_polygon_list_body =
                 framebuffer.tiler_polygon_list + header_size;
@@ -189,6 +198,8 @@ panfrost_emit_mfbd(struct panfrost_context *ctx)
         framebuffer.tiler_polygon_list_size =
                 header_size + body_size;
 
+
+
         return framebuffer;
 }
 
@@ -307,9 +318,9 @@ panfrost_invalidate_frame(struct panfrost_context *ctx)
                 ctx->cmdstream_i = 0;
 
         if (ctx->require_sfbd)
-                ctx->vt_framebuffer_sfbd = panfrost_emit_sfbd(ctx);
+                ctx->vt_framebuffer_sfbd = panfrost_emit_sfbd(ctx, ~0);
         else
-                ctx->vt_framebuffer_mfbd = panfrost_emit_mfbd(ctx);
+                ctx->vt_framebuffer_mfbd = panfrost_emit_mfbd(ctx, ~0);
 
         /* Reset varyings allocated */
         ctx->varying_height = 0;
@@ -2145,9 +2156,9 @@ panfrost_set_framebuffer_state(struct pipe_context *pctx,
                         continue;
 
                 if (ctx->require_sfbd)
-                        ctx->vt_framebuffer_sfbd = panfrost_emit_sfbd(ctx);
+                        ctx->vt_framebuffer_sfbd = panfrost_emit_sfbd(ctx, ~0);
                 else
-                        ctx->vt_framebuffer_mfbd = panfrost_emit_mfbd(ctx);
+                        ctx->vt_framebuffer_mfbd = panfrost_emit_mfbd(ctx, ~0);
 
                 panfrost_attach_vt_framebuffer(ctx);
 
@@ -2172,9 +2183,9 @@ panfrost_set_framebuffer_state(struct pipe_context *pctx,
 
                         if (zb) {
                                 if (ctx->require_sfbd)
-                                        ctx->vt_framebuffer_sfbd = panfrost_emit_sfbd(ctx);
+                                        ctx->vt_framebuffer_sfbd = panfrost_emit_sfbd(ctx, ~0);
                                 else
-                                        ctx->vt_framebuffer_mfbd = panfrost_emit_mfbd(ctx);
+                                        ctx->vt_framebuffer_mfbd = panfrost_emit_mfbd(ctx, ~0);
 
                                 panfrost_attach_vt_framebuffer(ctx);
 
@@ -2545,6 +2556,7 @@ panfrost_setup_hardware(struct panfrost_context *ctx)
         screen->driver->allocate_slab(screen, &ctx->shaders, 4096, true, PAN_ALLOCATE_EXECUTE, 0, 0);
         screen->driver->allocate_slab(screen, &ctx->tiler_heap, 32768, false, PAN_ALLOCATE_INVISIBLE | PAN_ALLOCATE_GROWABLE, 1, 128);
         screen->driver->allocate_slab(screen, &ctx->tiler_polygon_list, 128*128, false, PAN_ALLOCATE_INVISIBLE | PAN_ALLOCATE_GROWABLE, 1, 128);
+        screen->driver->allocate_slab(screen, &ctx->tiler_dummy, 1, false, PAN_ALLOCATE_INVISIBLE, 0, 0);
 
 }
 
diff --git a/src/gallium/drivers/panfrost/pan_context.h b/src/gallium/drivers/panfrost/pan_context.h
index 58a913d9338..d0365310223 100644
--- a/src/gallium/drivers/panfrost/pan_context.h
+++ b/src/gallium/drivers/panfrost/pan_context.h
@@ -134,6 +134,7 @@ struct panfrost_context {
         struct panfrost_memory tiler_heap;
         struct panfrost_memory varying_mem;
         struct panfrost_memory tiler_polygon_list;
+        struct panfrost_memory tiler_dummy;
         struct panfrost_memory depth_stencil_buffer;
 
         struct panfrost_query *occlusion_query;
@@ -333,17 +334,17 @@ panfrost_flush(
 bool
 panfrost_is_scanout(struct panfrost_context *ctx);
 
-mali_ptr panfrost_sfbd_fragment(struct panfrost_context *ctx);
-mali_ptr panfrost_mfbd_fragment(struct panfrost_context *ctx);
+mali_ptr panfrost_sfbd_fragment(struct panfrost_context *ctx, bool has_draws);
+mali_ptr panfrost_mfbd_fragment(struct panfrost_context *ctx, bool has_draws);
 
 struct bifrost_framebuffer
-panfrost_emit_mfbd(struct panfrost_context *ctx);
+panfrost_emit_mfbd(struct panfrost_context *ctx, unsigned vertex_count);
 
 struct mali_single_framebuffer
-panfrost_emit_sfbd(struct panfrost_context *ctx);
+panfrost_emit_sfbd(struct panfrost_context *ctx, unsigned vertex_count);
 
 mali_ptr
-panfrost_fragment_job(struct panfrost_context *ctx);
+panfrost_fragment_job(struct panfrost_context *ctx, bool has_draws);
 
 void
 panfrost_shader_compile(struct panfrost_context *ctx, struct mali_shader_meta *meta, const char *src, int type, struct panfrost_shader_state *state);
diff --git a/src/gallium/drivers/panfrost/pan_drm.c b/src/gallium/drivers/panfrost/pan_drm.c
index 2b4097c5ce5..98e40b57c3e 100644
--- a/src/gallium/drivers/panfrost/pan_drm.c
+++ b/src/gallium/drivers/panfrost/pan_drm.c
@@ -263,7 +263,7 @@ panfrost_drm_submit_vs_fs_job(struct panfrost_context *ctx, bool has_draws, bool
 		assert(!ret);
 	}
 
-	ret = panfrost_drm_submit_job(ctx, panfrost_fragment_job(ctx), PANFROST_JD_REQ_FS, surf);
+	ret = panfrost_drm_submit_job(ctx, panfrost_fragment_job(ctx, has_draws), PANFROST_JD_REQ_FS, surf);
 
         return ret;
 }
diff --git a/src/gallium/drivers/panfrost/pan_fragment.c b/src/gallium/drivers/panfrost/pan_fragment.c
index 16405a4ed21..ea0bd6cebdf 100644
--- a/src/gallium/drivers/panfrost/pan_fragment.c
+++ b/src/gallium/drivers/panfrost/pan_fragment.c
@@ -32,11 +32,11 @@
  * presentations, this is supposed to correspond to eglSwapBuffers) */
 
 mali_ptr
-panfrost_fragment_job(struct panfrost_context *ctx)
+panfrost_fragment_job(struct panfrost_context *ctx, bool has_draws)
 {
         mali_ptr framebuffer = ctx->require_sfbd ?
-                panfrost_sfbd_fragment(ctx) :
-                panfrost_mfbd_fragment(ctx);
+                panfrost_sfbd_fragment(ctx, has_draws) :
+                panfrost_mfbd_fragment(ctx, has_draws);
 
         struct mali_job_descriptor_header header = {
                 .job_type = JOB_TYPE_FRAGMENT,
diff --git a/src/gallium/drivers/panfrost/pan_mfbd.c b/src/gallium/drivers/panfrost/pan_mfbd.c
index 8f1ae32fa40..f325c2339b4 100644
--- a/src/gallium/drivers/panfrost/pan_mfbd.c
+++ b/src/gallium/drivers/panfrost/pan_mfbd.c
@@ -203,11 +203,11 @@ panfrost_mfbd_upload(
 /* Creates an MFBD for the FRAGMENT section of the bound framebuffer */
 
 mali_ptr
-panfrost_mfbd_fragment(struct panfrost_context *ctx)
+panfrost_mfbd_fragment(struct panfrost_context *ctx, bool has_draws)
 {
         struct panfrost_job *job = panfrost_get_job_for_fbo(ctx);
 
-        struct bifrost_framebuffer fb = panfrost_emit_mfbd(ctx);
+        struct bifrost_framebuffer fb = panfrost_emit_mfbd(ctx, has_draws);
         struct bifrost_fb_extra fbx = {};
         struct bifrost_render_target rts[4] = {};
 
diff --git a/src/gallium/drivers/panfrost/pan_sfbd.c b/src/gallium/drivers/panfrost/pan_sfbd.c
index 6989cd925a8..c9b0414b50c 100644
--- a/src/gallium/drivers/panfrost/pan_sfbd.c
+++ b/src/gallium/drivers/panfrost/pan_sfbd.c
@@ -107,10 +107,10 @@ panfrost_sfbd_set_cbuf(
 /* Creates an SFBD for the FRAGMENT section of the bound framebuffer */
 
 mali_ptr
-panfrost_sfbd_fragment(struct panfrost_context *ctx)
+panfrost_sfbd_fragment(struct panfrost_context *ctx, bool has_draws)
 {
         struct panfrost_job *job = panfrost_get_job_for_fbo(ctx);
-        struct mali_single_framebuffer fb = panfrost_emit_sfbd(ctx);
+        struct mali_single_framebuffer fb = panfrost_emit_sfbd(ctx, has_draws);
 
         panfrost_sfbd_clear(job, &fb);
 
-- 
2.20.1



More information about the mesa-dev mailing list