From: Nicolai Hähnle <nicolai.haeh...@amd.com> --- src/gallium/winsys/amdgpu/drm/amdgpu_cs.c | 35 +++++++++++++++++++++---------- src/gallium/winsys/amdgpu/drm/amdgpu_cs.h | 3 +++ 2 files changed, 27 insertions(+), 11 deletions(-)
diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c b/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c index e2d3a45..bffa725 100644 --- a/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c +++ b/src/gallium/winsys/amdgpu/drm/amdgpu_cs.c @@ -945,59 +945,72 @@ static void amdgpu_add_fence_dependency(struct amdgpu_cs *acs, dep = &cs->request.dependencies[idx]; memcpy(dep, &bo_fence->fence, sizeof(*dep)); } for (unsigned j = new_num_fences; j < bo->num_fences; ++j) amdgpu_fence_reference(&bo->fences[j], NULL); bo->num_fences = new_num_fences; } -static void amdgpu_add_fence(struct amdgpu_winsys_bo *bo, - struct pipe_fence_handle *fence) +/* Add the given list of fences to the buffer's fence list. + * + * Must be called with the winsys bo_fence_lock held. + */ +void amdgpu_add_fences(struct amdgpu_winsys_bo *bo, + unsigned num_fences, + struct pipe_fence_handle **fences) { - if (bo->num_fences >= bo->max_fences) { - unsigned new_max_fences = MAX2(1, bo->max_fences * 2); + if (bo->num_fences + num_fences > bo->max_fences) { + unsigned new_max_fences = MAX2(bo->num_fences + num_fences, bo->max_fences * 2); struct pipe_fence_handle **new_fences = REALLOC(bo->fences, bo->num_fences * sizeof(*new_fences), new_max_fences * sizeof(*new_fences)); - if (new_fences) { + if (likely(new_fences)) { bo->fences = new_fences; bo->max_fences = new_max_fences; } else { - fprintf(stderr, "amdgpu_add_fence: allocation failure, dropping fence\n"); + unsigned drop; + + fprintf(stderr, "amdgpu_add_fences: allocation failure, dropping fence(s)\n"); if (!bo->num_fences) return; - bo->num_fences--; /* prefer to keep a more recent fence if possible */ + bo->num_fences--; /* prefer to keep the most recent fence if possible */ amdgpu_fence_reference(&bo->fences[bo->num_fences], NULL); + + drop = bo->num_fences + num_fences - bo->max_fences; + num_fences -= drop; + fences += drop; } } - bo->fences[bo->num_fences] = NULL; - amdgpu_fence_reference(&bo->fences[bo->num_fences], fence); - bo->num_fences++; + for (unsigned i = 0; i < num_fences; ++i) { + bo->fences[bo->num_fences] = NULL; + amdgpu_fence_reference(&bo->fences[bo->num_fences], fences[i]); + bo->num_fences++; + } } static void amdgpu_add_fence_dependencies_list(struct amdgpu_cs *acs, struct pipe_fence_handle *fence, unsigned num_buffers, struct amdgpu_cs_buffer *buffers) { for (unsigned i = 0; i < num_buffers; i++) { struct amdgpu_cs_buffer *buffer = &buffers[i]; struct amdgpu_winsys_bo *bo = buffer->bo; amdgpu_add_fence_dependency(acs, buffer); p_atomic_inc(&bo->num_active_ioctls); - amdgpu_add_fence(bo, fence); + amdgpu_add_fences(bo, 1, &fence); } } /* Since the kernel driver doesn't synchronize execution between different * rings automatically, we have to add fence dependencies manually. */ static void amdgpu_add_fence_dependencies(struct amdgpu_cs *acs) { struct amdgpu_cs_context *cs = acs->csc; diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_cs.h b/src/gallium/winsys/amdgpu/drm/amdgpu_cs.h index bdf7cb2..242410f 100644 --- a/src/gallium/winsys/amdgpu/drm/amdgpu_cs.h +++ b/src/gallium/winsys/amdgpu/drm/amdgpu_cs.h @@ -233,15 +233,18 @@ amdgpu_bo_is_referenced_by_cs_with_usage(struct amdgpu_cs *cs, } static inline bool amdgpu_bo_is_referenced_by_any_cs(struct amdgpu_winsys_bo *bo) { return bo->num_cs_references != 0; } bool amdgpu_fence_wait(struct pipe_fence_handle *fence, uint64_t timeout, bool absolute); +void amdgpu_add_fences(struct amdgpu_winsys_bo *bo, + unsigned num_fences, + struct pipe_fence_handle **fences); void amdgpu_cs_sync_flush(struct radeon_winsys_cs *rcs); void amdgpu_cs_init_functions(struct amdgpu_winsys *ws); void amdgpu_cs_submit_ib(void *job, int thread_index); #endif -- 2.9.3 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev