From f9ecca2ff0bc4d04da4e87f64106151bf604c19f Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Fri, 14 Jun 2019 11:23:24 -0700 Subject: [PATCH] panfrost: Disable the tiler for clear-only jobs 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 --- 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.30.2