diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c b/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c index 29a706ca030..7dac24528f5 100644 --- a/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c +++ b/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c @@ -23,13 +23,12 @@ amdgpu_fence_create(struct amdgpu_cs *cs) fence->reference.count = 1; fence->ws = ctx->ws; - fence->ctx = ctx; + amdgpu_ctx_reference(&fence->ctx, ctx); fence->fence.context = ctx->ctx; fence->fence.ip_type = cs->ip_type; util_queue_fence_init(&fence->submitted); util_queue_fence_reset(&fence->submitted); fence->queue_index = cs->queue_index; - p_atomic_inc(&ctx->refcount); return (struct pipe_fence_handle *)fence; } @@ -287,7 +286,7 @@ static struct radeon_winsys_ctx *amdgpu_ctx_create(struct radeon_winsys *ws, return NULL; ctx->ws = amdgpu_winsys(ws); - ctx->refcount = 1; + ctx->reference.count = 1; ctx->allow_context_lost = allow_context_lost; r = amdgpu_cs_ctx_create2(ctx->ws->dev, amdgpu_priority, &ctx->ctx); @@ -328,7 +327,9 @@ error_create: static void amdgpu_ctx_destroy(struct radeon_winsys_ctx *rwctx) { - amdgpu_ctx_unref((struct amdgpu_ctx*)rwctx); + struct amdgpu_ctx *ctx = (struct amdgpu_ctx*)rwctx; + + amdgpu_ctx_reference(&ctx, NULL); } static void amdgpu_pad_gfx_compute_ib(struct amdgpu_winsys *ws, enum amd_ip_type ip_type, diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_cs.h b/src/gallium/winsys/amdgpu/drm/amdgpu_cs.h index 044b3d8888a..2476c2f7fc2 100644 --- a/src/gallium/winsys/amdgpu/drm/amdgpu_cs.h +++ b/src/gallium/winsys/amdgpu/drm/amdgpu_cs.h @@ -19,11 +19,11 @@ #define IB_MAX_SUBMIT_DWORDS (20 * 1024) struct amdgpu_ctx { + struct pipe_reference reference; struct amdgpu_winsys *ws; amdgpu_context_handle ctx; amdgpu_bo_handle user_fence_bo; uint64_t *user_fence_cpu_address_base; - int refcount; /* If true, report lost contexts and skip command submission. * If false, terminate the process. @@ -178,13 +178,17 @@ static inline bool amdgpu_fence_is_syncobj(struct amdgpu_fence *fence) return fence->ctx == NULL; } -static inline void amdgpu_ctx_unref(struct amdgpu_ctx *ctx) +static inline void amdgpu_ctx_reference(struct amdgpu_ctx **dst, struct amdgpu_ctx *src) { - if (p_atomic_dec_zero(&ctx->refcount)) { - amdgpu_cs_ctx_free(ctx->ctx); - amdgpu_bo_free(ctx->user_fence_bo); - FREE(ctx); + struct amdgpu_ctx *old_dst = *dst; + + if (pipe_reference(old_dst ? &old_dst->reference : NULL, + src ? &src->reference : NULL)) { + amdgpu_cs_ctx_free(old_dst->ctx); + amdgpu_bo_free(old_dst->user_fence_bo); + FREE(old_dst); } + *dst = src; } static inline void amdgpu_fence_reference(struct pipe_fence_handle **dst, @@ -199,7 +203,7 @@ static inline void amdgpu_fence_reference(struct pipe_fence_handle **dst, if (amdgpu_fence_is_syncobj(fence)) amdgpu_cs_destroy_syncobj(fence->ws->dev, fence->syncobj); else - amdgpu_ctx_unref(fence->ctx); + amdgpu_ctx_reference(&fence->ctx, NULL); util_queue_fence_destroy(&fence->submitted); FREE(fence);