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; } }