diff --git a/src/gallium/drivers/freedreno/freedreno_query_acc.c b/src/gallium/drivers/freedreno/freedreno_query_acc.c index 9fad076f01f..e7c5db9aa67 100644 --- a/src/gallium/drivers/freedreno/freedreno_query_acc.c +++ b/src/gallium/drivers/freedreno/freedreno_query_acc.c @@ -171,7 +171,7 @@ fd_acc_get_query_result(struct fd_context *ctx, struct fd_query *q, return false; } - ret = fd_bo_cpu_prep(rsc->bo, ctx->pipe, + ret = fd_resource_wait(ctx, rsc, DRM_FREEDRENO_PREP_READ | DRM_FREEDRENO_PREP_NOSYNC); if (ret) return false; @@ -186,7 +186,7 @@ fd_acc_get_query_result(struct fd_context *ctx, struct fd_query *q, } /* get the result: */ - fd_bo_cpu_prep(rsc->bo, ctx->pipe, DRM_FREEDRENO_PREP_READ); + fd_resource_wait(ctx, rsc, DRM_FREEDRENO_PREP_READ); void *ptr = fd_bo_map(rsc->bo); p->result(aq, ptr, result); diff --git a/src/gallium/drivers/freedreno/freedreno_query_hw.c b/src/gallium/drivers/freedreno/freedreno_query_hw.c index 8677b029a59..445c86d4552 100644 --- a/src/gallium/drivers/freedreno/freedreno_query_hw.c +++ b/src/gallium/drivers/freedreno/freedreno_query_hw.c @@ -230,7 +230,7 @@ fd_hw_get_query_result(struct fd_context *ctx, struct fd_query *q, if (!rsc->bo) return false; - ret = fd_bo_cpu_prep(rsc->bo, ctx->pipe, + ret = fd_resource_wait(ctx, rsc, DRM_FREEDRENO_PREP_READ | DRM_FREEDRENO_PREP_NOSYNC); if (ret) return false; @@ -260,7 +260,7 @@ fd_hw_get_query_result(struct fd_context *ctx, struct fd_query *q, if (!rsc->bo) continue; - fd_bo_cpu_prep(rsc->bo, ctx->pipe, DRM_FREEDRENO_PREP_READ); + fd_resource_wait(ctx, rsc, DRM_FREEDRENO_PREP_READ); void *ptr = fd_bo_map(rsc->bo); diff --git a/src/gallium/drivers/freedreno/freedreno_resource.c b/src/gallium/drivers/freedreno/freedreno_resource.c index 66c400f2e87..d8d471f84bc 100644 --- a/src/gallium/drivers/freedreno/freedreno_resource.c +++ b/src/gallium/drivers/freedreno/freedreno_resource.c @@ -177,6 +177,25 @@ fd_resource_set_bo(struct fd_resource *rsc, struct fd_bo *bo) rsc->seqno = p_atomic_inc_return(&screen->rsc_seqno); } +int +__fd_resource_wait(struct fd_context *ctx, struct fd_resource *rsc, + unsigned op, const char *func) +{ + if (op & DRM_FREEDRENO_PREP_NOSYNC) + return fd_bo_cpu_prep(rsc->bo, ctx->pipe, op); + + int64_t elapsed = -os_time_get_nano(); + int ret = fd_bo_cpu_prep(rsc->bo, ctx->pipe, op); + + elapsed += os_time_get_nano(); + if (elapsed > 10000) /* 0.01ms */ { + perf_debug_ctx(ctx, "%s: a busy \"%"PRSC_FMT"\" BO stalled and took %.03f ms.\n", + func, PRSC_ARGS(&rsc->base), 1000000 * (double)elapsed); + } + + return ret; +} + static void realloc_bo(struct fd_resource *rsc, uint32_t size) { @@ -695,7 +714,7 @@ fd_resource_transfer_map(struct pipe_context *pctx, if (usage & PIPE_MAP_READ) { fd_blit_to_staging(ctx, trans); - fd_bo_cpu_prep(staging_rsc->bo, ctx->pipe, + fd_resource_wait(ctx, staging_rsc, DRM_FREEDRENO_PREP_READ); } @@ -809,7 +828,7 @@ fd_resource_transfer_map(struct pipe_context *pctx, * completed. */ if (busy) { - ret = fd_bo_cpu_prep(rsc->bo, ctx->pipe, op); + ret = fd_resource_wait(ctx, rsc, op); if (ret) goto fail; } diff --git a/src/gallium/drivers/freedreno/freedreno_resource.h b/src/gallium/drivers/freedreno/freedreno_resource.h index a90e8eb66fd..71dc24da13d 100644 --- a/src/gallium/drivers/freedreno/freedreno_resource.h +++ b/src/gallium/drivers/freedreno/freedreno_resource.h @@ -165,6 +165,9 @@ fd_resource_busy(struct fd_resource *rsc, unsigned op) return fd_bo_cpu_prep(rsc->bo, NULL, op | DRM_FREEDRENO_PREP_NOSYNC) != 0; } +int __fd_resource_wait(struct fd_context *ctx, struct fd_resource *rsc, unsigned op, const char *func); +#define fd_resource_wait(ctx, rsc, op) __fd_resource_wait(ctx, rsc, op, __func__) + static inline void fd_resource_lock(struct fd_resource *rsc) {