panfrost: Skip shading unaffected tiles

Submitted by Alyssa Rosenzweig on June 20, 2019, 2:18 p.m.

Details

Message ID 20190620141830.6558-1-alyssa.rosenzweig@collabora.com
State New
Headers show
Series "panfrost: Skip shading unaffected tiles" ( rev: 2 ) in Mesa

Not browsing as part of any series.

Commit Message

Alyssa Rosenzweig June 20, 2019, 2:18 p.m.
Looking at the scissor, we can discard some tiles. We specifially don't
care about the scissor on the wallpaper, since that's a no-op if the
entire tile is culled.

Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
---
 src/gallium/drivers/panfrost/pan_context.c  |  9 +++++++++
 src/gallium/drivers/panfrost/pan_context.h  |  1 +
 src/gallium/drivers/panfrost/pan_fragment.c |  6 ++++--
 src/gallium/drivers/panfrost/pan_job.c      | 22 +++++++++++++++++++++
 src/gallium/drivers/panfrost/pan_job.h      | 11 +++++++++++
 5 files changed, 47 insertions(+), 2 deletions(-)

Patch hide | download patch | download mbox

diff --git a/src/gallium/drivers/panfrost/pan_context.c b/src/gallium/drivers/panfrost/pan_context.c
index e4a04dd821f..e543542d4fc 100644
--- a/src/gallium/drivers/panfrost/pan_context.c
+++ b/src/gallium/drivers/panfrost/pan_context.c
@@ -1372,6 +1372,13 @@  panfrost_emit_for_draw(struct panfrost_context *ctx, bool with_vertex_data)
         miny = MIN2(ctx->pipe_framebuffer.height, miny);
         maxy = MIN2(ctx->pipe_framebuffer.height, maxy);
 
+        /* Update the job, unless we're doing wallpapering (whose lack of
+         * scissor we can ignore, since if we "miss" a tile of wallpaper, it'll
+         * just... be faster :) */
+
+        if (!ctx->in_wallpaper)
+                panfrost_job_union_scissor(job, minx, miny, maxx, maxy);
+
         /* Upload */
 
         view.viewport0[0] = minx;
@@ -1466,7 +1473,9 @@  panfrost_draw_wallpaper(struct pipe_context *pipe)
 		return;
 
         /* Blit the wallpaper in */
+        ctx->in_wallpaper = true;
         panfrost_blit_wallpaper(ctx);
+        ctx->in_wallpaper = false;
 
         /* We are flushing all queued draws and we know that no more jobs will
          * be added until the next frame.
diff --git a/src/gallium/drivers/panfrost/pan_context.h b/src/gallium/drivers/panfrost/pan_context.h
index d0365310223..deba4668767 100644
--- a/src/gallium/drivers/panfrost/pan_context.h
+++ b/src/gallium/drivers/panfrost/pan_context.h
@@ -201,6 +201,7 @@  struct panfrost_context {
 
         struct primconvert_context *primconvert;
         struct blitter_context *blitter;
+        bool in_wallpaper;
 
         struct panfrost_blend_state *blend;
 
diff --git a/src/gallium/drivers/panfrost/pan_fragment.c b/src/gallium/drivers/panfrost/pan_fragment.c
index ea0bd6cebdf..70358fec3f3 100644
--- a/src/gallium/drivers/panfrost/pan_fragment.c
+++ b/src/gallium/drivers/panfrost/pan_fragment.c
@@ -46,9 +46,11 @@  panfrost_fragment_job(struct panfrost_context *ctx, bool has_draws)
 #endif
         };
 
+        struct panfrost_job *job = panfrost_get_job_for_fbo(ctx);
+
         struct mali_payload_fragment payload = {
-                .min_tile_coord = MALI_COORDINATE_TO_TILE_MIN(0, 0),
-                .max_tile_coord = MALI_COORDINATE_TO_TILE_MAX(ctx->pipe_framebuffer.width, ctx->pipe_framebuffer.height),
+                .min_tile_coord = MALI_COORDINATE_TO_TILE_MIN(job->minx, job->miny),
+                .max_tile_coord = MALI_COORDINATE_TO_TILE_MAX(job->maxx, job->maxy),
                 .framebuffer = framebuffer,
         };
 
diff --git a/src/gallium/drivers/panfrost/pan_job.c b/src/gallium/drivers/panfrost/pan_job.c
index 96f05c66354..cf64d2862c9 100644
--- a/src/gallium/drivers/panfrost/pan_job.c
+++ b/src/gallium/drivers/panfrost/pan_job.c
@@ -38,6 +38,9 @@  panfrost_create_job(struct panfrost_context *ctx)
         job->bos = _mesa_set_create(job,
                                     _mesa_hash_pointer,
                                     _mesa_key_pointer_equal);
+
+        job->minx = job->miny = ~0;
+        job->maxx = job->maxy = 0;
  
         return job;
 }
@@ -233,6 +236,11 @@  panfrost_job_clear(struct panfrost_context *ctx,
         }
 
         job->clear |= buffers;
+
+        /* Clearing affects the entire framebuffer */
+        panfrost_job_union_scissor(job, 0, 0,
+                        ctx->pipe_framebuffer.width,
+                        ctx->pipe_framebuffer.height);
 }
 
 void
@@ -266,6 +274,20 @@  panfrost_job_hash(const void *key)
         return _mesa_hash_data(key, sizeof(struct panfrost_job_key));
 }
 
+/* Given a new bounding rectangle (scissor), let the job cover the union of the
+ * new and old bounding rectangles */
+
+void
+panfrost_job_union_scissor(struct panfrost_job *job,
+                unsigned minx, unsigned miny,
+                unsigned maxx, unsigned maxy)
+{
+        job->minx = MIN2(job->minx, minx);
+        job->miny = MIN2(job->miny, miny);
+        job->maxx = MAX2(job->maxx, maxx);
+        job->maxy = MAX2(job->maxy, maxy);
+}
+
 void
 panfrost_job_init(struct panfrost_context *ctx)
 {
diff --git a/src/gallium/drivers/panfrost/pan_job.h b/src/gallium/drivers/panfrost/pan_job.h
index 2e7c0532341..ed8b084246a 100644
--- a/src/gallium/drivers/panfrost/pan_job.h
+++ b/src/gallium/drivers/panfrost/pan_job.h
@@ -55,6 +55,12 @@  struct panfrost_job {
          * bitmask) */
         unsigned requirements;
 
+        /* The bounding box covered by this job, taking scissors into account.
+         * Basically, the bounding box we have to run fragment shaders for */
+
+        unsigned minx, miny;
+        unsigned maxx, maxy;
+
         /* BOs referenced -- will be used for flushing logic */
         struct set *bos;
 };
@@ -102,4 +108,9 @@  panfrost_job_clear(struct panfrost_context *ctx,
                 const union pipe_color_union *color,
                 double depth, unsigned stencil);
 
+void
+panfrost_job_union_scissor(struct panfrost_job *job,
+                unsigned minx, unsigned miny,
+                unsigned maxx, unsigned maxy);
+
 #endif

Comments

On 6/20/19 4:18 PM, Alyssa Rosenzweig wrote:
> Looking at the scissor, we can discard some tiles. We specifially don't
> care about the scissor on the wallpaper, since that's a no-op if the
> entire tile is culled.
> 
> Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
> ---
>   src/gallium/drivers/panfrost/pan_context.c  |  9 +++++++++
>   src/gallium/drivers/panfrost/pan_context.h  |  1 +
>   src/gallium/drivers/panfrost/pan_fragment.c |  6 ++++--
>   src/gallium/drivers/panfrost/pan_job.c      | 22 +++++++++++++++++++++
>   src/gallium/drivers/panfrost/pan_job.h      | 11 +++++++++++
>   5 files changed, 47 insertions(+), 2 deletions(-)
> 
> diff --git a/src/gallium/drivers/panfrost/pan_context.c b/src/gallium/drivers/panfrost/pan_context.c
> index e4a04dd821f..e543542d4fc 100644
> --- a/src/gallium/drivers/panfrost/pan_context.c
> +++ b/src/gallium/drivers/panfrost/pan_context.c
> @@ -1372,6 +1372,13 @@ panfrost_emit_for_draw(struct panfrost_context *ctx, bool with_vertex_data)
>           miny = MIN2(ctx->pipe_framebuffer.height, miny);
>           maxy = MIN2(ctx->pipe_framebuffer.height, maxy);
>   
> +        /* Update the job, unless we're doing wallpapering (whose lack of
> +         * scissor we can ignore, since if we "miss" a tile of wallpaper, it'll
> +         * just... be faster :) */
> +
> +        if (!ctx->in_wallpaper)

Isn't enough with ctx->blitter->running ?

Cheers,

Tomeu

> +                panfrost_job_union_scissor(job, minx, miny, maxx, maxy);
> +
>           /* Upload */
>   
>           view.viewport0[0] = minx;
> @@ -1466,7 +1473,9 @@ panfrost_draw_wallpaper(struct pipe_context *pipe)
>   		return;
>   
>           /* Blit the wallpaper in */
> +        ctx->in_wallpaper = true;
>           panfrost_blit_wallpaper(ctx);
> +        ctx->in_wallpaper = false;
>   
>           /* We are flushing all queued draws and we know that no more jobs will
>            * be added until the next frame.
> diff --git a/src/gallium/drivers/panfrost/pan_context.h b/src/gallium/drivers/panfrost/pan_context.h
> index d0365310223..deba4668767 100644
> --- a/src/gallium/drivers/panfrost/pan_context.h
> +++ b/src/gallium/drivers/panfrost/pan_context.h
> @@ -201,6 +201,7 @@ struct panfrost_context {
>   
>           struct primconvert_context *primconvert;
>           struct blitter_context *blitter;
> +        bool in_wallpaper;
>   
>           struct panfrost_blend_state *blend;
>   
> diff --git a/src/gallium/drivers/panfrost/pan_fragment.c b/src/gallium/drivers/panfrost/pan_fragment.c
> index ea0bd6cebdf..70358fec3f3 100644
> --- a/src/gallium/drivers/panfrost/pan_fragment.c
> +++ b/src/gallium/drivers/panfrost/pan_fragment.c
> @@ -46,9 +46,11 @@ panfrost_fragment_job(struct panfrost_context *ctx, bool has_draws)
>   #endif
>           };
>   
> +        struct panfrost_job *job = panfrost_get_job_for_fbo(ctx);
> +
>           struct mali_payload_fragment payload = {
> -                .min_tile_coord = MALI_COORDINATE_TO_TILE_MIN(0, 0),
> -                .max_tile_coord = MALI_COORDINATE_TO_TILE_MAX(ctx->pipe_framebuffer.width, ctx->pipe_framebuffer.height),
> +                .min_tile_coord = MALI_COORDINATE_TO_TILE_MIN(job->minx, job->miny),
> +                .max_tile_coord = MALI_COORDINATE_TO_TILE_MAX(job->maxx, job->maxy),
>                   .framebuffer = framebuffer,
>           };
>   
> diff --git a/src/gallium/drivers/panfrost/pan_job.c b/src/gallium/drivers/panfrost/pan_job.c
> index 96f05c66354..cf64d2862c9 100644
> --- a/src/gallium/drivers/panfrost/pan_job.c
> +++ b/src/gallium/drivers/panfrost/pan_job.c
> @@ -38,6 +38,9 @@ panfrost_create_job(struct panfrost_context *ctx)
>           job->bos = _mesa_set_create(job,
>                                       _mesa_hash_pointer,
>                                       _mesa_key_pointer_equal);
> +
> +        job->minx = job->miny = ~0;
> +        job->maxx = job->maxy = 0;
>    
>           return job;
>   }
> @@ -233,6 +236,11 @@ panfrost_job_clear(struct panfrost_context *ctx,
>           }
>   
>           job->clear |= buffers;
> +
> +        /* Clearing affects the entire framebuffer */
> +        panfrost_job_union_scissor(job, 0, 0,
> +                        ctx->pipe_framebuffer.width,
> +                        ctx->pipe_framebuffer.height);
>   }
>   
>   void
> @@ -266,6 +274,20 @@ panfrost_job_hash(const void *key)
>           return _mesa_hash_data(key, sizeof(struct panfrost_job_key));
>   }
>   
> +/* Given a new bounding rectangle (scissor), let the job cover the union of the
> + * new and old bounding rectangles */
> +
> +void
> +panfrost_job_union_scissor(struct panfrost_job *job,
> +                unsigned minx, unsigned miny,
> +                unsigned maxx, unsigned maxy)
> +{
> +        job->minx = MIN2(job->minx, minx);
> +        job->miny = MIN2(job->miny, miny);
> +        job->maxx = MAX2(job->maxx, maxx);
> +        job->maxy = MAX2(job->maxy, maxy);
> +}
> +
>   void
>   panfrost_job_init(struct panfrost_context *ctx)
>   {
> diff --git a/src/gallium/drivers/panfrost/pan_job.h b/src/gallium/drivers/panfrost/pan_job.h
> index 2e7c0532341..ed8b084246a 100644
> --- a/src/gallium/drivers/panfrost/pan_job.h
> +++ b/src/gallium/drivers/panfrost/pan_job.h
> @@ -55,6 +55,12 @@ struct panfrost_job {
>            * bitmask) */
>           unsigned requirements;
>   
> +        /* The bounding box covered by this job, taking scissors into account.
> +         * Basically, the bounding box we have to run fragment shaders for */
> +
> +        unsigned minx, miny;
> +        unsigned maxx, maxy;
> +
>           /* BOs referenced -- will be used for flushing logic */
>           struct set *bos;
>   };
> @@ -102,4 +108,9 @@ panfrost_job_clear(struct panfrost_context *ctx,
>                   const union pipe_color_union *color,
>                   double depth, unsigned stencil);
>   
> +void
> +panfrost_job_union_scissor(struct panfrost_job *job,
> +                unsigned minx, unsigned miny,
> +                unsigned maxx, unsigned maxy);
> +
>   #endif
>
> Isn't enough with ctx->blitter->running ?

What if we're legitimately blitting something?
On Thu, 20 Jun 2019 at 16:56, Alyssa Rosenzweig
<alyssa.rosenzweig@collabora.com> wrote:
>
> > Isn't enough with ctx->blitter->running ?
>
> What if we're legitimately blitting something?

Forgot about that.

Reviewed-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>

Thanks!

Tomeu