Module: Mesa
Branch: master
Commit: d760a995e3cb1725c87c6f1b62867a1205a8f2fc
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=d760a995e3cb1725c87c6f1b62867a1205a8f2fc

Author: Boris Brezillon <[email protected]>
Date:   Mon Jan 25 12:00:56 2021 +0100

panfrost: Hook up indirect draw support

Signed-off-by: Boris Brezillon <[email protected]>
Reviewed-by: Alyssa Rosenzweig <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8700>

---

 src/gallium/drivers/panfrost/pan_cmdstream.c |   9 +-
 src/gallium/drivers/panfrost/pan_context.c   | 133 ++++++++++++++++++++++++++-
 src/gallium/drivers/panfrost/pan_job.h       |   4 +
 src/gallium/drivers/panfrost/pan_screen.c    |   5 +
 4 files changed, 147 insertions(+), 4 deletions(-)

diff --git a/src/gallium/drivers/panfrost/pan_cmdstream.c 
b/src/gallium/drivers/panfrost/pan_cmdstream.c
index 815f5c1b5ab..1e8462e5e4d 100644
--- a/src/gallium/drivers/panfrost/pan_cmdstream.c
+++ b/src/gallium/drivers/panfrost/pan_cmdstream.c
@@ -2237,11 +2237,14 @@ panfrost_emit_vertex_tiler_jobs(struct panfrost_batch 
*batch,
 
         unsigned vertex = panfrost_add_job(&batch->pool, &batch->scoreboard,
                                            MALI_JOB_TYPE_VERTEX, false, false,
-                                           0, 0, vertex_job, false);
+                                           ctx->indirect_draw ?
+                                           batch->indirect_draw_job_id : 0,
+                                           0, vertex_job, false);
 
         if (ctx->rasterizer->base.rasterizer_discard)
                 return;
 
-        panfrost_add_job(&batch->pool, &batch->scoreboard, MALI_JOB_TYPE_TILER,
-                         false, false, vertex, 0, tiler_job, false);
+        panfrost_add_job(&batch->pool, &batch->scoreboard,
+                         MALI_JOB_TYPE_TILER, false, false,
+                         vertex, 0, tiler_job, false);
 }
diff --git a/src/gallium/drivers/panfrost/pan_context.c 
b/src/gallium/drivers/panfrost/pan_context.c
index 34eb5b58874..11e32c86b45 100644
--- a/src/gallium/drivers/panfrost/pan_context.c
+++ b/src/gallium/drivers/panfrost/pan_context.c
@@ -52,6 +52,7 @@
 #include "midgard_pack.h"
 #include "pan_screen.h"
 #include "pan_cmdstream.h"
+#include "pan_indirect_draw.h"
 #include "pan_util.h"
 #include "decode.h"
 #include "util/pan_lower_framebuffer.h"
@@ -596,7 +597,137 @@ panfrost_indirect_draw(struct panfrost_context *ctx,
                 return;
         }
 
-        assert(0);
+        /* Indirect draw count and multi-draw not supported. */
+        assert(indirect->draw_count == 1 && !indirect->indirect_draw_count);
+
+        /* TODO: update statistics (see panfrost_statistics_record()) */
+        /* TODO: Increment transform feedback offsets */
+        assert(ctx->streamout.num_targets == 0);
+
+        struct panfrost_device *dev = pan_device(ctx->base.screen);
+
+        assert(ctx->draw_modes & (1 << info->mode));
+        ctx->active_prim = info->mode;
+        ctx->indirect_draw = true;
+
+        struct panfrost_batch *batch = panfrost_get_batch_for_fbo(ctx);
+
+        /* Don't add too many jobs to a single batch */
+        if (batch->scoreboard.job_index + (indirect->draw_count * 3) > 10000)
+                batch = panfrost_get_fresh_batch_for_fbo(ctx);
+
+        panfrost_batch_set_requirements(batch);
+
+        mali_ptr shared_mem = panfrost_batch_reserve_framebuffer(batch);
+
+        struct panfrost_ptr tiler =
+                panfrost_pool_alloc_aligned(&batch->pool,
+                                            pan_is_bifrost(dev) ?
+                                            MALI_BIFROST_TILER_JOB_LENGTH :
+                                            MALI_MIDGARD_TILER_JOB_LENGTH,
+                                            64);
+        struct panfrost_ptr vertex =
+                panfrost_pool_alloc_aligned(&batch->pool,
+                                            MALI_COMPUTE_JOB_LENGTH,
+                                            64);
+
+        struct panfrost_shader_state *vs =
+                panfrost_get_shader_state(ctx, PIPE_SHADER_VERTEX);
+
+        struct panfrost_bo *index_buf = NULL;
+
+        if (info->index_size) {
+                assert(!info->has_user_indices);
+                index_buf = pan_resource(info->index.resource)->bo;
+                panfrost_batch_add_bo(batch,
+                                      index_buf,
+                                      PAN_BO_ACCESS_SHARED | 
PAN_BO_ACCESS_READ |
+                                      PAN_BO_ACCESS_VERTEX_TILER);
+        }
+
+        mali_ptr varyings = 0, vs_vary = 0, fs_vary = 0, pos = 0, psiz = 0;
+        unsigned varying_buf_count;
+
+        /* We want to create templates, set all count fields to 0 to reflect
+         * that.
+         */
+        ctx->instance_count = ctx->vertex_count = ctx->padded_count = 0;
+        ctx->offset_start = 0;
+
+        panfrost_emit_varying_descriptor(batch, 0,
+                                         &vs_vary, &fs_vary, &varyings,
+                                         &varying_buf_count, &pos, &psiz);
+
+        mali_ptr attribs, attrib_bufs;
+        attribs = panfrost_emit_vertex_data(batch, &attrib_bufs);
+
+        /* Zero-ed invocation, the compute job will update it. */
+        static struct mali_invocation_packed invocation;
+
+        /* Fire off the draw itself */
+        panfrost_draw_emit_vertex(batch, info, &invocation, shared_mem,
+                                  vs_vary, varyings, attribs, attrib_bufs,
+                                  vertex.cpu);
+        panfrost_draw_emit_tiler(batch, info, NULL, &invocation, shared_mem,
+                                 index_buf ? index_buf->ptr.gpu : 0,
+                                 fs_vary, varyings, pos, psiz, tiler.cpu);
+
+        /* Add the varying heap BO to the batch if we're allocating varyings. 
*/
+        if (varyings) {
+                panfrost_batch_add_bo(batch,
+                                      dev->indirect_draw_shaders.varying_heap,
+                                      PAN_BO_ACCESS_SHARED | PAN_BO_ACCESS_RW |
+                                      PAN_BO_ACCESS_VERTEX_TILER);
+        }
+
+        assert(indirect->buffer);
+
+        struct panfrost_resource *draw_buf = pan_resource(indirect->buffer);
+
+        /* Don't count images: those attributes don't need to be patched. */
+        unsigned attrib_count =
+                vs->info.attribute_count -
+                util_bitcount(ctx->image_mask[PIPE_SHADER_VERTEX]);
+
+        panfrost_batch_add_bo(batch, draw_buf->bo,
+                              PAN_BO_ACCESS_SHARED | PAN_BO_ACCESS_READ |
+                              PAN_BO_ACCESS_VERTEX_TILER);
+
+        struct pan_indirect_draw_info draw_info = {
+                .last_indirect_draw = batch->indirect_draw_job_id,
+                .draw_buf = draw_buf->bo->ptr.gpu + indirect->offset,
+                .index_buf = index_buf ? index_buf->ptr.gpu : 0,
+                .vertex_job = vertex.gpu,
+                .tiler_job = tiler.gpu,
+                .attrib_bufs = attrib_bufs,
+                .attribs = attribs,
+                .attrib_count = attrib_count,
+                .varying_bufs = varyings,
+                .index_size = info->index_size,
+        };
+
+        if (panfrost_writes_point_size(ctx))
+                draw_info.flags |= PAN_INDIRECT_DRAW_UPDATE_PRIM_SIZE;
+
+        if (vs->info.vs.writes_point_size)
+                draw_info.flags |= PAN_INDIRECT_DRAW_HAS_PSIZ;
+
+
+        if (info->primitive_restart) {
+                draw_info.restart_index = info->restart_index;
+                draw_info.flags |= PAN_INDIRECT_DRAW_PRIMITIVE_RESTART;
+        }
+
+        batch->indirect_draw_job_id =
+                panfrost_emit_indirect_draw(&batch->pool,
+                                            &batch->scoreboard,
+                                            &draw_info,
+                                            &batch->indirect_draw_ctx);
+
+        panfrost_emit_vertex_tiler_jobs(batch, &vertex, &tiler);
+
+        /* Adjust the batch stack size based on the new shader stack sizes. */
+        panfrost_batch_adjust_stack_size(batch);
 }
 
 static void
diff --git a/src/gallium/drivers/panfrost/pan_job.h 
b/src/gallium/drivers/panfrost/pan_job.h
index 0b316d9c15b..088a3af2d64 100644
--- a/src/gallium/drivers/panfrost/pan_job.h
+++ b/src/gallium/drivers/panfrost/pan_job.h
@@ -125,6 +125,10 @@ struct panfrost_batch {
 
         /* Batch dependencies */
         struct util_dynarray dependencies;
+
+        /* Indirect draw data */
+        struct panfrost_ptr indirect_draw_ctx;
+        unsigned indirect_draw_job_id;
 };
 
 /* Functions for managing the above */
diff --git a/src/gallium/drivers/panfrost/pan_screen.c 
b/src/gallium/drivers/panfrost/pan_screen.c
index 7d754d4c3e5..43ed6f6d0fe 100644
--- a/src/gallium/drivers/panfrost/pan_screen.c
+++ b/src/gallium/drivers/panfrost/pan_screen.c
@@ -301,6 +301,9 @@ panfrost_get_param(struct pipe_screen *screen, enum 
pipe_cap param)
         case PIPE_CAP_SHAREABLE_SHADERS:
                 return 0;
 
+        case PIPE_CAP_DRAW_INDIRECT:
+                return is_deqp;
+
         default:
                 return u_pipe_screen_get_param_defaults(screen, param);
         }
@@ -686,6 +689,7 @@ panfrost_destroy_screen(struct pipe_screen *pscreen)
 {
         struct panfrost_device *dev = pan_device(pscreen);
 
+        panfrost_cleanup_indirect_draw_shaders(dev);
         pan_blend_shaders_cleanup(dev);
 
         if (dev->ro)
@@ -860,6 +864,7 @@ panfrost_create_screen(int fd, struct renderonly *ro)
         panfrost_resource_screen_init(&screen->base);
         panfrost_init_blit_shaders(dev);
         pan_blend_shaders_init(dev);
+        panfrost_init_indirect_draw_shaders(dev);
 
         return &screen->base;
 }

_______________________________________________
mesa-commit mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-commit

Reply via email to