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 <leo.liu@amd.com> Acked-by: Leo Liu <leo.liu@amd.com>
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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 *
|
||||
|
||||
Reference in New Issue
Block a user