amdgpu: add public bo list interface v3
v2: cleanup comments and function parameter v3: rebased on internal branch Signed-off-by: Christian König <christian.koenig@amd.com> Reviewed-by: Jammy Zhou <Jammy.Zhou@amd.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>main
parent
9c2afffedb
commit
6dc2eaf2cc
|
@ -165,6 +165,11 @@ typedef struct amdgpu_context *amdgpu_context_handle;
|
|||
*/
|
||||
typedef struct amdgpu_bo *amdgpu_bo_handle;
|
||||
|
||||
/**
|
||||
* Define handle for list of BOs
|
||||
*/
|
||||
typedef struct amdgpu_bo_list *amdgpu_bo_list_handle;
|
||||
|
||||
/**
|
||||
* Define handle to be used when dealing with command
|
||||
* buffers (a.k.a. ibs)
|
||||
|
@ -400,17 +405,9 @@ struct amdgpu_cs_request {
|
|||
uint32_t ring;
|
||||
|
||||
/**
|
||||
* Specify number of resource handles passed.
|
||||
* Size of 'handles' array
|
||||
*
|
||||
* List handle with resources used by this request.
|
||||
*/
|
||||
uint32_t number_of_resources;
|
||||
|
||||
/** Array of resources used by submission. */
|
||||
amdgpu_bo_handle *resources;
|
||||
|
||||
/** Array of resources flags. This is optional and can be NULL. */
|
||||
uint8_t *resource_flags;
|
||||
amdgpu_bo_list_handle resources;
|
||||
|
||||
/** Number of IBs to submit in the field ibs. */
|
||||
uint32_t number_of_ibs;
|
||||
|
@ -788,6 +785,40 @@ int amdgpu_bo_wait_for_idle(amdgpu_bo_handle buf_handle,
|
|||
uint64_t timeout_ns,
|
||||
bool *buffer_busy);
|
||||
|
||||
/**
|
||||
* Creates a BO list handle for command submission.
|
||||
*
|
||||
* \param dev - \c [in] Device handle.
|
||||
* See #amdgpu_device_initialize()
|
||||
* \param number_of_resources - \c [in] Number of BOs in the list
|
||||
* \param resources - \c [in] List of BO handles
|
||||
* \param resource_prios - \c [in] Optional priority for each handle
|
||||
* \param result - \c [out] Created BO list handle
|
||||
*
|
||||
* \return 0 on success\n
|
||||
* >0 - AMD specific error code\n
|
||||
* <0 - Negative POSIX Error code
|
||||
*
|
||||
* \sa amdgpu_bo_list_destroy()
|
||||
*/
|
||||
int amdgpu_bo_list_create(amdgpu_device_handle dev,
|
||||
uint32_t number_of_resources,
|
||||
amdgpu_bo_handle *resources,
|
||||
uint8_t *resource_prios,
|
||||
amdgpu_bo_list_handle *result);
|
||||
|
||||
/**
|
||||
* Destroys a BO list handle.
|
||||
*
|
||||
* \param handle - \c [in] BO list handle.
|
||||
*
|
||||
* \return 0 on success\n
|
||||
* >0 - AMD specific error code\n
|
||||
* <0 - Negative POSIX Error code
|
||||
*
|
||||
* \sa amdgpu_bo_list_create()
|
||||
*/
|
||||
int amdgpu_bo_list_destroy(amdgpu_bo_list_handle handle);
|
||||
|
||||
/*
|
||||
* Special GPU Resources
|
||||
|
|
|
@ -636,3 +636,59 @@ int amdgpu_create_bo_from_user_mem(amdgpu_device_handle dev,
|
|||
|
||||
return r;
|
||||
}
|
||||
|
||||
int amdgpu_bo_list_create(amdgpu_device_handle dev,
|
||||
uint32_t number_of_resources,
|
||||
amdgpu_bo_handle *resources,
|
||||
uint8_t *resource_prios,
|
||||
amdgpu_bo_list_handle *result)
|
||||
{
|
||||
struct drm_amdgpu_bo_list_entry *list;
|
||||
union drm_amdgpu_bo_list args;
|
||||
unsigned i;
|
||||
int r;
|
||||
|
||||
list = alloca(sizeof(struct drm_amdgpu_bo_list_entry) * number_of_resources);
|
||||
|
||||
memset(&args, 0, sizeof(args));
|
||||
args.in.operation = AMDGPU_BO_LIST_OP_CREATE;
|
||||
args.in.bo_number = number_of_resources;
|
||||
args.in.bo_info_size = sizeof(struct drm_amdgpu_bo_list_entry);
|
||||
args.in.bo_info_ptr = (uint64_t)(uintptr_t)list;
|
||||
|
||||
for (i = 0; i < number_of_resources; i++) {
|
||||
list[i].bo_handle = resources[i]->handle;
|
||||
if (resource_prios)
|
||||
list[i].bo_priority = resource_prios[i];
|
||||
else
|
||||
list[i].bo_priority = 0;
|
||||
}
|
||||
|
||||
r = drmCommandWriteRead(dev->fd, DRM_AMDGPU_BO_LIST,
|
||||
&args, sizeof(args));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
*result = calloc(1, sizeof(struct amdgpu_bo_list));
|
||||
(*result)->dev = dev;
|
||||
(*result)->handle = args.out.list_handle;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int amdgpu_bo_list_destroy(amdgpu_bo_list_handle list)
|
||||
{
|
||||
union drm_amdgpu_bo_list args;
|
||||
int r;
|
||||
|
||||
memset(&args, 0, sizeof(args));
|
||||
args.in.operation = AMDGPU_BO_LIST_OP_DESTROY;
|
||||
args.in.list_handle = list->handle;
|
||||
|
||||
r = drmCommandWriteRead(list->dev->fd, DRM_AMDGPU_BO_LIST,
|
||||
&args, sizeof(args));
|
||||
|
||||
if (!r)
|
||||
free(list);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -611,73 +611,6 @@ int amdgpu_cs_ctx_free(amdgpu_context_handle context)
|
|||
return r;
|
||||
}
|
||||
|
||||
static int amdgpu_cs_create_bo_list(amdgpu_context_handle context,
|
||||
struct amdgpu_cs_request *request,
|
||||
amdgpu_ib_handle fence_ib,
|
||||
uint32_t *handle)
|
||||
{
|
||||
struct drm_amdgpu_bo_list_entry *list;
|
||||
union drm_amdgpu_bo_list args;
|
||||
unsigned num_resources;
|
||||
unsigned i;
|
||||
int r;
|
||||
|
||||
num_resources = request->number_of_resources;
|
||||
|
||||
if (!num_resources) {
|
||||
*handle = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (fence_ib)
|
||||
++num_resources;
|
||||
|
||||
list = alloca(sizeof(struct drm_amdgpu_bo_list_entry) * num_resources);
|
||||
|
||||
memset(&args, 0, sizeof(args));
|
||||
args.in.operation = AMDGPU_BO_LIST_OP_CREATE;
|
||||
args.in.bo_number = num_resources;
|
||||
args.in.bo_info_size = sizeof(struct drm_amdgpu_bo_list_entry);
|
||||
args.in.bo_info_ptr = (uint64_t)(uintptr_t)list;
|
||||
|
||||
for (i = 0; i < request->number_of_resources; i++) {
|
||||
list[i].bo_handle = request->resources[i]->handle;
|
||||
if (request->resource_flags)
|
||||
list[i].bo_priority = request->resource_flags[i];
|
||||
else
|
||||
list[i].bo_priority = 0;
|
||||
}
|
||||
|
||||
if (fence_ib)
|
||||
list[i].bo_handle = fence_ib->buf_handle->handle;
|
||||
|
||||
r = drmCommandWriteRead(context->dev->fd, DRM_AMDGPU_BO_LIST,
|
||||
&args, sizeof(args));
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
*handle = args.out.list_handle;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int amdgpu_cs_free_bo_list(amdgpu_context_handle context, uint32_t handle)
|
||||
{
|
||||
union drm_amdgpu_bo_list args;
|
||||
int r;
|
||||
|
||||
if (!handle)
|
||||
return 0;
|
||||
|
||||
memset(&args, 0, sizeof(args));
|
||||
args.in.operation = AMDGPU_BO_LIST_OP_DESTROY;
|
||||
args.in.list_handle = handle;
|
||||
|
||||
r = drmCommandWriteRead(context->dev->fd, DRM_AMDGPU_BO_LIST,
|
||||
&args, sizeof(args));
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static uint32_t amdgpu_cs_fence_index(unsigned ip, unsigned ring)
|
||||
{
|
||||
return ip * AMDGPU_CS_MAX_RINGS + ring;
|
||||
|
@ -703,7 +636,6 @@ static int amdgpu_cs_submit_one(amdgpu_context_handle context,
|
|||
uint64_t *chunk_array;
|
||||
struct drm_amdgpu_cs_chunk *chunks;
|
||||
struct drm_amdgpu_cs_chunk_data *chunk_data;
|
||||
uint32_t bo_list_handle;
|
||||
|
||||
if (ibs_request->ip_type >= AMDGPU_HW_IP_NUM)
|
||||
return -EINVAL;
|
||||
|
@ -712,11 +644,10 @@ static int amdgpu_cs_submit_one(amdgpu_context_handle context,
|
|||
if (ibs_request->number_of_ibs > AMDGPU_CS_MAX_IBS_PER_SUBMIT)
|
||||
return -EINVAL;
|
||||
|
||||
size = (ibs_request->number_of_ibs + 1) * ((sizeof(uint64_t) +
|
||||
size = (ibs_request->number_of_ibs + 1) * (
|
||||
sizeof(uint64_t) +
|
||||
sizeof(struct drm_amdgpu_cs_chunk) +
|
||||
sizeof(struct drm_amdgpu_cs_chunk_data)) +
|
||||
ibs_request->number_of_resources + 1) *
|
||||
sizeof(struct drm_amdgpu_bo_list_entry);
|
||||
sizeof(struct drm_amdgpu_cs_chunk_data));
|
||||
chunk_array = malloc(size);
|
||||
if (NULL == chunk_array)
|
||||
return -ENOMEM;
|
||||
|
@ -728,6 +659,7 @@ static int amdgpu_cs_submit_one(amdgpu_context_handle context,
|
|||
memset(&cs, 0, sizeof(cs));
|
||||
cs.in.chunks = (uint64_t)(uintptr_t)chunk_array;
|
||||
cs.in.ctx_id = context->id;
|
||||
cs.in.bo_list_handle = ibs_request->resources->handle;
|
||||
cs.in.num_chunks = ibs_request->number_of_ibs;
|
||||
/* IB chunks */
|
||||
for (i = 0; i < ibs_request->number_of_ibs; i++) {
|
||||
|
@ -750,12 +682,6 @@ static int amdgpu_cs_submit_one(amdgpu_context_handle context,
|
|||
chunk_data[i].ib_data.flags = AMDGPU_IB_FLAG_CE;
|
||||
}
|
||||
|
||||
r = amdgpu_cs_create_bo_list(context, ibs_request, NULL,
|
||||
&bo_list_handle);
|
||||
if (r)
|
||||
goto error_unlock;
|
||||
|
||||
cs.in.bo_list_handle = bo_list_handle;
|
||||
pthread_mutex_lock(&context->sequence_mutex);
|
||||
|
||||
if (ibs_request->ip_type != AMDGPU_HW_IP_UVD &&
|
||||
|
@ -803,17 +729,11 @@ static int amdgpu_cs_submit_one(amdgpu_context_handle context,
|
|||
|
||||
pthread_mutex_unlock(&context->sequence_mutex);
|
||||
|
||||
r = amdgpu_cs_free_bo_list(context, bo_list_handle);
|
||||
if (r)
|
||||
goto error_free;
|
||||
|
||||
free(chunk_array);
|
||||
return 0;
|
||||
|
||||
error_unlock:
|
||||
pthread_mutex_unlock(&context->sequence_mutex);
|
||||
|
||||
error_free:
|
||||
free(chunk_array);
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -88,6 +88,12 @@ struct amdgpu_bo {
|
|||
int cpu_map_count;
|
||||
};
|
||||
|
||||
struct amdgpu_bo_list {
|
||||
struct amdgpu_device *dev;
|
||||
|
||||
uint32_t handle;
|
||||
};
|
||||
|
||||
/*
|
||||
* There are three mutexes.
|
||||
* To avoid deadlock, only hold the mutexes in this order:
|
||||
|
|
|
@ -306,9 +306,10 @@ static void amdgpu_sdma_test_exec_cs(amdgpu_context_handle context_handle,
|
|||
ibs_request->ring = instance;
|
||||
ibs_request->number_of_ibs = 1;
|
||||
ibs_request->ibs = ib_info;
|
||||
ibs_request->number_of_resources = res_cnt;
|
||||
ibs_request->resources = resources;
|
||||
|
||||
r = amdgpu_bo_list_create(device_handle, res_cnt, resources,
|
||||
NULL, &ibs_request->resources);
|
||||
CU_ASSERT_EQUAL(r, 0);
|
||||
|
||||
CU_ASSERT_NOT_EQUAL(ibs_request, NULL);
|
||||
|
||||
|
@ -317,6 +318,9 @@ static void amdgpu_sdma_test_exec_cs(amdgpu_context_handle context_handle,
|
|||
ibs_request, 1, &fence_status.fence);
|
||||
CU_ASSERT_EQUAL(r, 0);
|
||||
|
||||
r = amdgpu_bo_list_destroy(ibs_request->resources);
|
||||
CU_ASSERT_EQUAL(r, 0);
|
||||
|
||||
fence_status.ip_type = AMDGPU_HW_IP_DMA;
|
||||
fence_status.ring = ibs_request->ring;
|
||||
fence_status.context = context_handle;
|
||||
|
|
|
@ -115,8 +115,12 @@ static int submit(unsigned ndw, unsigned ip)
|
|||
ib_info.size = ndw;
|
||||
|
||||
ibs_request.ip_type = ip;
|
||||
ibs_request.number_of_resources = num_resources;
|
||||
ibs_request.resources = resources;
|
||||
|
||||
r = amdgpu_bo_list_create(device_handle, num_resources, resources,
|
||||
NULL, &ibs_request.resources);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
ibs_request.number_of_ibs = 1;
|
||||
ibs_request.ibs = &ib_info;
|
||||
|
||||
|
@ -125,6 +129,10 @@ static int submit(unsigned ndw, unsigned ip)
|
|||
if (r)
|
||||
return r;
|
||||
|
||||
r = amdgpu_bo_list_destroy(ibs_request.resources);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
r = amdgpu_cs_alloc_ib(context_handle, IB_SIZE, &ib_result);
|
||||
if (r)
|
||||
return r;
|
||||
|
|
Loading…
Reference in New Issue