Mesa (main): v3d: attach performance monitor to jobs

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Aug 3 09:46:48 UTC 2021


Module: Mesa
Branch: main
Commit: 9969703547244b4b3aee4f940c434bca9d6e4c36
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=9969703547244b4b3aee4f940c434bca9d6e4c36

Author: Juan A. Suarez Romero <jasuarez at igalia.com>
Date:   Wed Apr 21 12:59:21 2021 +0200

v3d: attach performance monitor to jobs

When a performance monitor is enabled in the context, all the jobs
submitted to the kernel will have attached this monitor ID, so the
kernel will measuring the performance counters selected in the monitor
when these jobs are executed by the GPU (accumulating the results).

v2 (Iago):
 - Update comment
 - Assert fence is not NULL
 - Assert has_perfmon when using perfmon
 - Rewrite conditional
 - Implement performance counters in CSD

v4 (Juan):
 - Track previous perfmon and sync BCL if required (Juan).
 - Track if a job with perfmon was submitted (Juan)

v7 (Iago)
 - No braces for single-line body conditionals

Reviewed-by: Iago Toral Quiroga <itoral at igalia.com>
Signed-off-by: Juan A. Suarez Romero <jasuarez at igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/10666>

---

 src/gallium/drivers/v3d/v3d_context.h | 18 ++++++++++++++++++
 src/gallium/drivers/v3d/v3d_fence.c   | 11 +++++++++++
 src/gallium/drivers/v3d/v3d_job.c     | 17 +++++++++++++++++
 src/gallium/drivers/v3d/v3dx_draw.c   | 10 ++++++++++
 4 files changed, 56 insertions(+)

diff --git a/src/gallium/drivers/v3d/v3d_context.h b/src/gallium/drivers/v3d/v3d_context.h
index 04ff23e859d..56e5b87a2f9 100644
--- a/src/gallium/drivers/v3d/v3d_context.h
+++ b/src/gallium/drivers/v3d/v3d_context.h
@@ -304,6 +304,19 @@ struct v3d_shaderimg_stateobj {
         uint32_t enabled_mask;
 };
 
+struct v3d_perfmon_state {
+        /* The kernel perfmon id */
+        uint32_t kperfmon_id;
+        /* True if at least one job was submitted with this perfmon. */
+        bool job_submitted;
+        /* Fence to be signaled when the last job submitted with this perfmon
+         * is executed by the GPU.
+         */
+        struct v3d_fence *last_job_fence;
+        uint8_t counters[DRM_V3D_MAX_PERF_COUNTERS];
+        uint64_t values[DRM_V3D_MAX_PERF_COUNTERS];
+};
+
 /**
  * A complete bin/render job.
  *
@@ -576,6 +589,8 @@ struct v3d_context {
         struct pipe_resource *prim_counts;
         uint32_t prim_counts_offset;
         struct pipe_debug_callback debug;
+        struct v3d_perfmon_state *active_perfmon;
+        struct v3d_perfmon_state *last_perfmon;
         /** @} */
 };
 
@@ -730,6 +745,9 @@ bool v3d_generate_mipmap(struct pipe_context *pctx,
                          unsigned int first_layer,
                          unsigned int last_layer);
 
+void
+v3d_fence_unreference(struct v3d_fence **fence);
+
 struct v3d_fence *v3d_fence_create(struct v3d_context *v3d);
 
 void v3d_update_primitive_counters(struct v3d_context *v3d);
diff --git a/src/gallium/drivers/v3d/v3d_fence.c b/src/gallium/drivers/v3d/v3d_fence.c
index d4b4e48c46f..7076c58f9b7 100644
--- a/src/gallium/drivers/v3d/v3d_fence.c
+++ b/src/gallium/drivers/v3d/v3d_fence.c
@@ -61,6 +61,17 @@ v3d_fence_reference(struct pipe_screen *pscreen,
         *p = f;
 }
 
+void
+v3d_fence_unreference(struct v3d_fence **fence)
+{
+        assert(fence);
+
+        if (!*fence)
+                return;
+
+        v3d_fence_reference(NULL, (struct pipe_fence_handle **)fence, NULL);
+}
+
 static bool
 v3d_fence_finish(struct pipe_screen *pscreen,
 		 struct pipe_context *ctx,
diff --git a/src/gallium/drivers/v3d/v3d_job.c b/src/gallium/drivers/v3d/v3d_job.c
index 5b96d5582a0..6cd88999124 100644
--- a/src/gallium/drivers/v3d/v3d_job.c
+++ b/src/gallium/drivers/v3d/v3d_job.c
@@ -502,6 +502,20 @@ v3d_job_submit(struct v3d_context *v3d, struct v3d_job *job)
         job->submit.bcl_end = job->bcl.bo->offset + cl_offset(&job->bcl);
         job->submit.rcl_end = job->rcl.bo->offset + cl_offset(&job->rcl);
 
+        if (v3d->active_perfmon) {
+                assert(screen->has_perfmon);
+                job->submit.perfmon_id = v3d->active_perfmon->kperfmon_id;
+        }
+
+        /* If we are submitting a job with a different perfmon, we need to
+         * ensure the previous one fully finishes before starting this;
+         * otherwise it would wrongly mix counter results.
+         */
+        if (v3d->active_perfmon != v3d->last_perfmon) {
+                v3d->last_perfmon = v3d->active_perfmon;
+                job->submit.in_sync_bcl = v3d->out_sync;
+        }
+
         job->submit.flags = 0;
         if (job->tmu_dirty_rcl && screen->has_cache_flush)
                 job->submit.flags |= DRM_V3D_SUBMIT_CL_FLUSH_CACHE;
@@ -529,6 +543,9 @@ v3d_job_submit(struct v3d_context *v3d, struct v3d_job *job)
                         fprintf(stderr, "Draw call returned %s.  "
                                         "Expect corruption.\n", strerror(errno));
                         warned = true;
+                } else if (!ret) {
+                        if (v3d->active_perfmon)
+                                v3d->active_perfmon->job_submitted = true;
                 }
 
                 /* If we are submitting a job in the middle of transform
diff --git a/src/gallium/drivers/v3d/v3dx_draw.c b/src/gallium/drivers/v3d/v3dx_draw.c
index b637ca679d1..ba94df748fe 100644
--- a/src/gallium/drivers/v3d/v3dx_draw.c
+++ b/src/gallium/drivers/v3d/v3dx_draw.c
@@ -1448,6 +1448,13 @@ v3d_launch_grid(struct pipe_context *pctx, const struct pipe_grid_info *info)
         submit.in_sync = v3d->out_sync;
         submit.out_sync = v3d->out_sync;
 
+        if (v3d->active_perfmon) {
+                assert(screen->has_perfmon);
+                submit.perfmon_id = v3d->active_perfmon->kperfmon_id;
+        }
+
+        v3d->last_perfmon = v3d->active_perfmon;
+
         if (!(V3D_DEBUG & V3D_DEBUG_NORAST)) {
                 int ret = v3d_ioctl(screen->fd, DRM_IOCTL_V3D_SUBMIT_CSD,
                                     &submit);
@@ -1456,6 +1463,9 @@ v3d_launch_grid(struct pipe_context *pctx, const struct pipe_grid_info *info)
                         fprintf(stderr, "CSD submit call returned %s.  "
                                 "Expect corruption.\n", strerror(errno));
                         warned = true;
+                } else if (!ret) {
+                        if (v3d->active_perfmon)
+                                v3d->active_perfmon->job_submitted = true;
                 }
         }
 



More information about the mesa-commit mailing list