aboutsummaryrefslogtreecommitdiffstats
path: root/amdgpu
diff options
context:
space:
mode:
authorChristian König2015-04-22 07:52:34 -0500
committerAlex Deucher2015-08-05 12:47:49 -0500
commit6dc2eaf2cc8428d11498a57bbe72cdf0df4a3306 (patch)
tree2e46dc9744ab1890a1bca5019dcb5c4df120e95a /amdgpu
parent9c2afffedb773da27fd7506b31fc2164f329d3a8 (diff)
downloadexternal-libgbm-6dc2eaf2cc8428d11498a57bbe72cdf0df4a3306.tar.gz
external-libgbm-6dc2eaf2cc8428d11498a57bbe72cdf0df4a3306.tar.xz
external-libgbm-6dc2eaf2cc8428d11498a57bbe72cdf0df4a3306.zip
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>
Diffstat (limited to 'amdgpu')
-rw-r--r--amdgpu/amdgpu.h51
-rw-r--r--amdgpu/amdgpu_bo.c56
-rw-r--r--amdgpu/amdgpu_cs.c88
-rw-r--r--amdgpu/amdgpu_internal.h6
4 files changed, 107 insertions, 94 deletions
diff --git a/amdgpu/amdgpu.h b/amdgpu/amdgpu.h
index d010d99c..7baa1839 100644
--- a/amdgpu/amdgpu.h
+++ b/amdgpu/amdgpu.h
@@ -166,6 +166,11 @@ typedef struct amdgpu_context *amdgpu_context_handle;
166typedef struct amdgpu_bo *amdgpu_bo_handle; 166typedef struct amdgpu_bo *amdgpu_bo_handle;
167 167
168/** 168/**
169 * Define handle for list of BOs
170 */
171typedef struct amdgpu_bo_list *amdgpu_bo_list_handle;
172
173/**
169 * Define handle to be used when dealing with command 174 * Define handle to be used when dealing with command
170 * buffers (a.k.a. ibs) 175 * buffers (a.k.a. ibs)
171 * 176 *
@@ -400,17 +405,9 @@ struct amdgpu_cs_request {
400 uint32_t ring; 405 uint32_t ring;
401 406
402 /** 407 /**
403 * Specify number of resource handles passed. 408 * List handle with resources used by this request.
404 * Size of 'handles' array
405 *
406 */ 409 */
407 uint32_t number_of_resources; 410 amdgpu_bo_list_handle resources;
408
409 /** Array of resources used by submission. */
410 amdgpu_bo_handle *resources;
411
412 /** Array of resources flags. This is optional and can be NULL. */
413 uint8_t *resource_flags;
414 411
415 /** Number of IBs to submit in the field ibs. */ 412 /** Number of IBs to submit in the field ibs. */
416 uint32_t number_of_ibs; 413 uint32_t number_of_ibs;
@@ -788,6 +785,40 @@ int amdgpu_bo_wait_for_idle(amdgpu_bo_handle buf_handle,
788 uint64_t timeout_ns, 785 uint64_t timeout_ns,
789 bool *buffer_busy); 786 bool *buffer_busy);
790 787
788/**
789 * Creates a BO list handle for command submission.
790 *
791 * \param dev - \c [in] Device handle.
792 * See #amdgpu_device_initialize()
793 * \param number_of_resources - \c [in] Number of BOs in the list
794 * \param resources - \c [in] List of BO handles
795 * \param resource_prios - \c [in] Optional priority for each handle
796 * \param result - \c [out] Created BO list handle
797 *
798 * \return 0 on success\n
799 * >0 - AMD specific error code\n
800 * <0 - Negative POSIX Error code
801 *
802 * \sa amdgpu_bo_list_destroy()
803*/
804int amdgpu_bo_list_create(amdgpu_device_handle dev,
805 uint32_t number_of_resources,
806 amdgpu_bo_handle *resources,
807 uint8_t *resource_prios,
808 amdgpu_bo_list_handle *result);
809
810/**
811 * Destroys a BO list handle.
812 *
813 * \param handle - \c [in] BO list handle.
814 *
815 * \return 0 on success\n
816 * >0 - AMD specific error code\n
817 * <0 - Negative POSIX Error code
818 *
819 * \sa amdgpu_bo_list_create()
820*/
821int amdgpu_bo_list_destroy(amdgpu_bo_list_handle handle);
791 822
792/* 823/*
793 * Special GPU Resources 824 * Special GPU Resources
diff --git a/amdgpu/amdgpu_bo.c b/amdgpu/amdgpu_bo.c
index b4ca7f72..9321f8b3 100644
--- a/amdgpu/amdgpu_bo.c
+++ b/amdgpu/amdgpu_bo.c
@@ -636,3 +636,59 @@ int amdgpu_create_bo_from_user_mem(amdgpu_device_handle dev,
636 636
637 return r; 637 return r;
638} 638}
639
640int amdgpu_bo_list_create(amdgpu_device_handle dev,
641 uint32_t number_of_resources,
642 amdgpu_bo_handle *resources,
643 uint8_t *resource_prios,
644 amdgpu_bo_list_handle *result)
645{
646 struct drm_amdgpu_bo_list_entry *list;
647 union drm_amdgpu_bo_list args;
648 unsigned i;
649 int r;
650
651 list = alloca(sizeof(struct drm_amdgpu_bo_list_entry) * number_of_resources);
652
653 memset(&args, 0, sizeof(args));
654 args.in.operation = AMDGPU_BO_LIST_OP_CREATE;
655 args.in.bo_number = number_of_resources;
656 args.in.bo_info_size = sizeof(struct drm_amdgpu_bo_list_entry);
657 args.in.bo_info_ptr = (uint64_t)(uintptr_t)list;
658
659 for (i = 0; i < number_of_resources; i++) {
660 list[i].bo_handle = resources[i]->handle;
661 if (resource_prios)
662 list[i].bo_priority = resource_prios[i];
663 else
664 list[i].bo_priority = 0;
665 }
666
667 r = drmCommandWriteRead(dev->fd, DRM_AMDGPU_BO_LIST,
668 &args, sizeof(args));
669 if (r)
670 return r;
671
672 *result = calloc(1, sizeof(struct amdgpu_bo_list));
673 (*result)->dev = dev;
674 (*result)->handle = args.out.list_handle;
675 return 0;
676}
677
678int amdgpu_bo_list_destroy(amdgpu_bo_list_handle list)
679{
680 union drm_amdgpu_bo_list args;
681 int r;
682
683 memset(&args, 0, sizeof(args));
684 args.in.operation = AMDGPU_BO_LIST_OP_DESTROY;
685 args.in.list_handle = list->handle;
686
687 r = drmCommandWriteRead(list->dev->fd, DRM_AMDGPU_BO_LIST,
688 &args, sizeof(args));
689
690 if (!r)
691 free(list);
692
693 return r;
694}
diff --git a/amdgpu/amdgpu_cs.c b/amdgpu/amdgpu_cs.c
index 4d5b3ecf..8a473a1d 100644
--- a/amdgpu/amdgpu_cs.c
+++ b/amdgpu/amdgpu_cs.c
@@ -611,73 +611,6 @@ int amdgpu_cs_ctx_free(amdgpu_context_handle context)
611 return r; 611 return r;
612} 612}
613 613
614static int amdgpu_cs_create_bo_list(amdgpu_context_handle context,
615 struct amdgpu_cs_request *request,
616 amdgpu_ib_handle fence_ib,
617 uint32_t *handle)
618{
619 struct drm_amdgpu_bo_list_entry *list;
620 union drm_amdgpu_bo_list args;
621 unsigned num_resources;
622 unsigned i;
623 int r;
624
625 num_resources = request->number_of_resources;
626
627 if (!num_resources) {
628 *handle = 0;
629 return 0;
630 }
631
632 if (fence_ib)
633 ++num_resources;
634
635 list = alloca(sizeof(struct drm_amdgpu_bo_list_entry) * num_resources);
636
637 memset(&args, 0, sizeof(args));
638 args.in.operation = AMDGPU_BO_LIST_OP_CREATE;
639 args.in.bo_number = num_resources;
640 args.in.bo_info_size = sizeof(struct drm_amdgpu_bo_list_entry);
641 args.in.bo_info_ptr = (uint64_t)(uintptr_t)list;
642
643 for (i = 0; i < request->number_of_resources; i++) {
644 list[i].bo_handle = request->resources[i]->handle;
645 if (request->resource_flags)
646 list[i].bo_priority = request->resource_flags[i];
647 else
648 list[i].bo_priority = 0;
649 }
650
651 if (fence_ib)
652 list[i].bo_handle = fence_ib->buf_handle->handle;
653
654 r = drmCommandWriteRead(context->dev->fd, DRM_AMDGPU_BO_LIST,
655 &args, sizeof(args));
656 if (r)
657 return r;
658
659 *handle = args.out.list_handle;
660 return 0;
661}
662
663static int amdgpu_cs_free_bo_list(amdgpu_context_handle context, uint32_t handle)
664{
665 union drm_amdgpu_bo_list args;
666 int r;
667
668 if (!handle)
669 return 0;
670
671 memset(&args, 0, sizeof(args));
672 args.in.operation = AMDGPU_BO_LIST_OP_DESTROY;
673 args.in.list_handle = handle;
674
675 r = drmCommandWriteRead(context->dev->fd, DRM_AMDGPU_BO_LIST,
676 &args, sizeof(args));
677
678 return r;
679}
680
681static uint32_t amdgpu_cs_fence_index(unsigned ip, unsigned ring) 614static uint32_t amdgpu_cs_fence_index(unsigned ip, unsigned ring)
682{ 615{
683 return ip * AMDGPU_CS_MAX_RINGS + ring; 616 return ip * AMDGPU_CS_MAX_RINGS + ring;
@@ -703,7 +636,6 @@ static int amdgpu_cs_submit_one(amdgpu_context_handle context,
703 uint64_t *chunk_array; 636 uint64_t *chunk_array;
704 struct drm_amdgpu_cs_chunk *chunks; 637 struct drm_amdgpu_cs_chunk *chunks;
705 struct drm_amdgpu_cs_chunk_data *chunk_data; 638 struct drm_amdgpu_cs_chunk_data *chunk_data;
706 uint32_t bo_list_handle;
707 639
708 if (ibs_request->ip_type >= AMDGPU_HW_IP_NUM) 640 if (ibs_request->ip_type >= AMDGPU_HW_IP_NUM)
709 return -EINVAL; 641 return -EINVAL;
@@ -712,11 +644,10 @@ static int amdgpu_cs_submit_one(amdgpu_context_handle context,
712 if (ibs_request->number_of_ibs > AMDGPU_CS_MAX_IBS_PER_SUBMIT) 644 if (ibs_request->number_of_ibs > AMDGPU_CS_MAX_IBS_PER_SUBMIT)
713 return -EINVAL; 645 return -EINVAL;
714 646
715 size = (ibs_request->number_of_ibs + 1) * ((sizeof(uint64_t) + 647 size = (ibs_request->number_of_ibs + 1) * (
648 sizeof(uint64_t) +
716 sizeof(struct drm_amdgpu_cs_chunk) + 649 sizeof(struct drm_amdgpu_cs_chunk) +
717 sizeof(struct drm_amdgpu_cs_chunk_data)) + 650 sizeof(struct drm_amdgpu_cs_chunk_data));
718 ibs_request->number_of_resources + 1) *
719 sizeof(struct drm_amdgpu_bo_list_entry);
720 chunk_array = malloc(size); 651 chunk_array = malloc(size);
721 if (NULL == chunk_array) 652 if (NULL == chunk_array)
722 return -ENOMEM; 653 return -ENOMEM;
@@ -728,6 +659,7 @@ static int amdgpu_cs_submit_one(amdgpu_context_handle context,
728 memset(&cs, 0, sizeof(cs)); 659 memset(&cs, 0, sizeof(cs));
729 cs.in.chunks = (uint64_t)(uintptr_t)chunk_array; 660 cs.in.chunks = (uint64_t)(uintptr_t)chunk_array;
730 cs.in.ctx_id = context->id; 661 cs.in.ctx_id = context->id;
662 cs.in.bo_list_handle = ibs_request->resources->handle;
731 cs.in.num_chunks = ibs_request->number_of_ibs; 663 cs.in.num_chunks = ibs_request->number_of_ibs;
732 /* IB chunks */ 664 /* IB chunks */
733 for (i = 0; i < ibs_request->number_of_ibs; i++) { 665 for (i = 0; i < ibs_request->number_of_ibs; i++) {
@@ -750,12 +682,6 @@ static int amdgpu_cs_submit_one(amdgpu_context_handle context,
750 chunk_data[i].ib_data.flags = AMDGPU_IB_FLAG_CE; 682 chunk_data[i].ib_data.flags = AMDGPU_IB_FLAG_CE;
751 } 683 }
752 684
753 r = amdgpu_cs_create_bo_list(context, ibs_request, NULL,
754 &bo_list_handle);
755 if (r)
756 goto error_unlock;
757
758 cs.in.bo_list_handle = bo_list_handle;
759 pthread_mutex_lock(&context->sequence_mutex); 685 pthread_mutex_lock(&context->sequence_mutex);
760 686
761 if (ibs_request->ip_type != AMDGPU_HW_IP_UVD && 687 if (ibs_request->ip_type != AMDGPU_HW_IP_UVD &&
@@ -803,17 +729,11 @@ static int amdgpu_cs_submit_one(amdgpu_context_handle context,
803 729
804 pthread_mutex_unlock(&context->sequence_mutex); 730 pthread_mutex_unlock(&context->sequence_mutex);
805 731
806 r = amdgpu_cs_free_bo_list(context, bo_list_handle);
807 if (r)
808 goto error_free;
809
810 free(chunk_array); 732 free(chunk_array);
811 return 0; 733 return 0;
812 734
813error_unlock: 735error_unlock:
814 pthread_mutex_unlock(&context->sequence_mutex); 736 pthread_mutex_unlock(&context->sequence_mutex);
815
816error_free:
817 free(chunk_array); 737 free(chunk_array);
818 return r; 738 return r;
819} 739}
diff --git a/amdgpu/amdgpu_internal.h b/amdgpu/amdgpu_internal.h
index c91452ef..9cb21566 100644
--- a/amdgpu/amdgpu_internal.h
+++ b/amdgpu/amdgpu_internal.h
@@ -88,6 +88,12 @@ struct amdgpu_bo {
88 int cpu_map_count; 88 int cpu_map_count;
89}; 89};
90 90
91struct amdgpu_bo_list {
92 struct amdgpu_device *dev;
93
94 uint32_t handle;
95};
96
91/* 97/*
92 * There are three mutexes. 98 * There are three mutexes.
93 * To avoid deadlock, only hold the mutexes in this order: 99 * To avoid deadlock, only hold the mutexes in this order: