diff options
author | Marek Olšák <[email protected]> | 2018-07-16 13:11:29 -0400 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2018-07-18 11:56:28 -0400 |
commit | 51d6b163da1faa01e95cfd2f3493a843285a7ce9 (patch) | |
tree | 13e92a8dbcbbd9a7123be04f93f48f847a22e856 /src/gallium/winsys/amdgpu/drm | |
parent | e06b8ec106e64880a56d1cb990836ec3ad6536e6 (diff) |
winsys/amdgpu: fix VDPAU interop by having one amdgpu_winsys_bo per BO (v2)
Dependencies between rings are inserted correctly if a buffer is
represented by only one unique amdgpu_winsys_bo instance.
Use a hash table keyed by amdgpu_bo_handle to have exactly one
amdgpu_winsys_bo per amdgpu_bo_handle.
v2: return offset and stride properly
Tested-by: Leo Liu <[email protected]>
Acked-by: Leo Liu <[email protected]>
Diffstat (limited to 'src/gallium/winsys/amdgpu/drm')
-rw-r--r-- | src/gallium/winsys/amdgpu/drm/amdgpu_bo.c | 36 | ||||
-rw-r--r-- | src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c | 5 | ||||
-rw-r--r-- | src/gallium/winsys/amdgpu/drm/amdgpu_winsys.h | 5 |
3 files changed, 41 insertions, 5 deletions
diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c b/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c index d9192c209e2..80563d3df98 100644 --- a/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c +++ b/src/gallium/winsys/amdgpu/drm/amdgpu_bo.c @@ -28,6 +28,7 @@ #include "amdgpu_cs.h" #include "util/os_time.h" +#include "util/u_hash_table.h" #include "state_tracker/drm_driver.h" #include <amdgpu_drm.h> #include <xf86drm.h> @@ -179,6 +180,10 @@ void amdgpu_bo_destroy(struct pb_buffer *_buf) simple_mtx_unlock(&ws->global_bo_list_lock); } + simple_mtx_lock(&ws->bo_export_table_lock); + util_hash_table_remove(ws->bo_export_table, bo->bo); + simple_mtx_unlock(&ws->bo_export_table_lock); + amdgpu_bo_va_op(bo->bo, 0, bo->base.size, bo->va, 0, AMDGPU_VA_OP_UNMAP); amdgpu_va_range_free(bo->u.real.va_handle); amdgpu_bo_free(bo->bo); @@ -1285,10 +1290,27 @@ static struct pb_buffer *amdgpu_bo_from_handle(struct radeon_winsys *rws, return NULL; } + if (stride) + *stride = whandle->stride; + if (offset) + *offset = whandle->offset; + r = amdgpu_bo_import(ws->dev, type, whandle->handle, &result); if (r) return NULL; + simple_mtx_lock(&ws->bo_export_table_lock); + bo = util_hash_table_get(ws->bo_export_table, result.buf_handle); + + /* If the amdgpu_winsys_bo instance already exists, bump the reference + * counter and return it. + */ + if (bo) { + p_atomic_inc(&bo->base.reference.count); + simple_mtx_unlock(&ws->bo_export_table_lock); + return &bo->base; + } + /* Get initial domains. */ r = amdgpu_bo_query_info(result.buf_handle, &info); if (r) @@ -1326,11 +1348,6 @@ static struct pb_buffer *amdgpu_bo_from_handle(struct radeon_winsys *rws, bo->unique_id = __sync_fetch_and_add(&ws->next_bo_unique_id, 1); bo->is_shared = true; - if (stride) - *stride = whandle->stride; - if (offset) - *offset = whandle->offset; - if (bo->initial_domain & RADEON_DOMAIN_VRAM) ws->allocated_vram += align64(bo->base.size, ws->info.gart_page_size); else if (bo->initial_domain & RADEON_DOMAIN_GTT) @@ -1338,9 +1355,13 @@ static struct pb_buffer *amdgpu_bo_from_handle(struct radeon_winsys *rws, amdgpu_add_buffer_to_global_list(bo); + util_hash_table_set(ws->bo_export_table, bo->bo, bo); + simple_mtx_unlock(&ws->bo_export_table_lock); + return &bo->base; error: + simple_mtx_unlock(&ws->bo_export_table_lock); if (bo) FREE(bo); if (va_handle) @@ -1355,6 +1376,7 @@ static bool amdgpu_bo_get_handle(struct pb_buffer *buffer, struct winsys_handle *whandle) { struct amdgpu_winsys_bo *bo = amdgpu_winsys_bo(buffer); + struct amdgpu_winsys *ws = bo->ws; enum amdgpu_bo_handle_type type; int r; @@ -1382,6 +1404,10 @@ static bool amdgpu_bo_get_handle(struct pb_buffer *buffer, if (r) return false; + simple_mtx_lock(&ws->bo_export_table_lock); + util_hash_table_set(ws->bo_export_table, bo->bo, bo); + simple_mtx_unlock(&ws->bo_export_table_lock); + whandle->stride = stride; whandle->offset = offset; whandle->offset += slice_size * whandle->layer; diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c b/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c index db7a4d7033c..882f500bc69 100644 --- a/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c +++ b/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.c @@ -92,7 +92,9 @@ static void amdgpu_winsys_destroy(struct radeon_winsys *rws) simple_mtx_destroy(&ws->bo_fence_lock); pb_slabs_deinit(&ws->bo_slabs); pb_cache_deinit(&ws->bo_cache); + util_hash_table_destroy(ws->bo_export_table); simple_mtx_destroy(&ws->global_bo_list_lock); + simple_mtx_destroy(&ws->bo_export_table_lock); do_winsys_deinit(ws); FREE(rws); } @@ -314,8 +316,11 @@ amdgpu_winsys_create(int fd, const struct pipe_screen_config *config, amdgpu_surface_init_functions(ws); LIST_INITHEAD(&ws->global_bo_list); + ws->bo_export_table = util_hash_table_create(hash_pointer, compare_pointers); + (void) simple_mtx_init(&ws->global_bo_list_lock, mtx_plain); (void) simple_mtx_init(&ws->bo_fence_lock, mtx_plain); + (void) simple_mtx_init(&ws->bo_export_table_lock, mtx_plain); if (!util_queue_init(&ws->cs_queue, "cs", 8, 1, UTIL_QUEUE_INIT_RESIZE_IF_FULL)) { diff --git a/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.h b/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.h index 8079255e4cf..c355eff5262 100644 --- a/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.h +++ b/src/gallium/winsys/amdgpu/drm/amdgpu_winsys.h @@ -85,6 +85,11 @@ struct amdgpu_winsys { simple_mtx_t global_bo_list_lock; struct list_head global_bo_list; unsigned num_buffers; + + /* For returning the same amdgpu_winsys_bo instance for exported + * and re-imported buffers. */ + struct util_hash_table *bo_export_table; + simple_mtx_t bo_export_table_lock; }; static inline struct amdgpu_winsys * |