amdgpu: add public bo list interface v3
authorChristian König <christian.koenig@amd.com>
Wed, 22 Apr 2015 12:52:34 +0000 (14:52 +0200)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 5 Aug 2015 17:47:49 +0000 (13:47 -0400)
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>
amdgpu/amdgpu.h
amdgpu/amdgpu_bo.c
amdgpu/amdgpu_cs.c
amdgpu/amdgpu_internal.h
tests/amdgpu/basic_tests.c
tests/amdgpu/cs_tests.c

index d010d99cac3cc9ca41cf762859ee24b48920e8fc..7baa1839f27e755f416f4eb7dbde01ddda4fba63 100644 (file)
@@ -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
index b4ca7f72c510dd9d6a5d9acdd04af1b23e8d9e9f..9321f8b3ac1134dfe56e6100c7bc64b845355aa2 100644 (file)
@@ -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;
+}
index 4d5b3ecf25219933960d0468e1226e3efabc586f..8a473a1d98f12e5da4568318da0bc607f00d174e 100644 (file)
@@ -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;
 }
index c91452ef7ca656d0ede89eee10bf0ea4fd7faf37..9cb21566f911394c8ea57a442e61571bb78e725e 100644 (file)
@@ -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:
index 9f03c5a00fde384f1ae16791ed622b0a025b051d..c8c759f445de2c1929c063391012d7f885eaaa76 100644 (file)
@@ -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;
index 2bfdec37d40300bb855be5af94acf2880ebffd29..6d485ae3c42b4d6bec53d3c7dceb2237174b1a69 100644 (file)
@@ -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;