summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjqdeng <Emily.Deng@amd.com>2016-07-05 15:44:51 +0800
committerQiang Yu <Qiang.Yu@amd.com>2017-05-17 11:10:47 +0800
commitf55770906f308f5033e5b1f82922a9910d7bf46f (patch)
treeac5e9b868d1bdf74e88ebffac68eceeab3741298
parentaddc5d713867c81d13dbef16327cf927f132bf0a (diff)
amdgpu: Add interface amdgpu_get_bo_from_fb_id v2
The amdgpu_get_bo_from_fb_id is used to export the crtc's framebuffer's buffer object to OpenGL driver for capturing desktop to OpenGL texture.This is alse used by linux rapidfire server. v2: 51547965007f4e4cdbd47a40b3879528412be7eb Fix memory leak in amdgpu_get_bo_from_fb_id Change-Id: Id315a05147035b4ce16f72d627881c5166015473 Signed-off-by: jqdeng <Emily.Deng@amd.com> Reviewed-by: Chunming Zhou <David1.Zhou@amd.com>
-rwxr-xr-xamdgpu/amdgpu-symbol-check1
-rw-r--r--amdgpu/amdgpu.h17
-rw-r--r--amdgpu/amdgpu_bo.c101
3 files changed, 119 insertions, 0 deletions
diff --git a/amdgpu/amdgpu-symbol-check b/amdgpu/amdgpu-symbol-check
index b18bf39b..7f8e2cb4 100755
--- a/amdgpu/amdgpu-symbol-check
+++ b/amdgpu/amdgpu-symbol-check
@@ -53,6 +53,7 @@ amdgpu_va_range_alloc
amdgpu_va_range_free
amdgpu_va_range_query
amdgpu_get_fb_id
+amdgpu_get_bo_from_fb_id
EOF
done)
diff --git a/amdgpu/amdgpu.h b/amdgpu/amdgpu.h
index 0b908616..4765ea41 100644
--- a/amdgpu/amdgpu.h
+++ b/amdgpu/amdgpu.h
@@ -657,6 +657,23 @@ int amdgpu_bo_import(amdgpu_device_handle dev,
int amdgpu_get_fb_id(amdgpu_device_handle dev, unsigned int *fb_id);
/**
+ * Get the framebuffer's bo by fb_id
+ *
+ * \param dev - \c [in] Device handle.
+ * See #amdgpu_device_initialize()
+ * \param fb_id - \c [in] the framebuffer's buffer_id
+ *
+ * \param output - \c [output] the bo of fb_id
+ *
+ * \return 0 on success\n
+ * <0 - Negative POSIX Error code
+ *
+ * \sa amdgpu_get_bo_from_fb_id()
+ *
+*/
+int amdgpu_get_bo_from_fb_id(amdgpu_device_handle dev, unsigned int fb_id, struct amdgpu_bo_import_result *output);
+
+/**
* Request GPU access to user allocated memory e.g. via "malloc"
*
* \param dev - [in] Device handle. See #amdgpu_device_initialize()
diff --git a/amdgpu/amdgpu_bo.c b/amdgpu/amdgpu_bo.c
index aa374624..fef6152e 100644
--- a/amdgpu/amdgpu_bo.c
+++ b/amdgpu/amdgpu_bo.c
@@ -469,6 +469,107 @@ int amdgpu_get_fb_id(amdgpu_device_handle dev, unsigned int *fb_id)
return r;
}
+/* Get the frame buffer's gem object handle by the fb_id. */
+int amdgpu_get_bo_from_fb_id(amdgpu_device_handle dev, unsigned int fb_id, struct amdgpu_bo_import_result *output)
+{
+ drmModeFBPtr fbcur;
+ struct drm_amdgpu_gem_create_in bo_info = {};
+ struct drm_amdgpu_gem_op gem_op = {};
+ int r = 0;
+ int i;
+ struct amdgpu_bo *bo = NULL;
+ int dma_fd;
+ int flag_auth = 0;
+ int fd = dev->fd;
+
+ amdgpu_get_auth(dev->fd, &flag_auth);
+ if (flag_auth) {
+ fd = dev->fd;
+ } else {
+ amdgpu_get_auth(dev->flink_fd, &flag_auth);
+ if (flag_auth) {
+ fd = dev->flink_fd;
+ } else {
+ fprintf(stderr, "amdgpu: amdgpu_get_bo_from_fb_id, couldn't get the auth fd\n");
+ return EINVAL;
+ }
+ }
+
+ fbcur = drmModeGetFB(fd, fb_id);
+
+ if (fbcur == NULL)
+ return EFAULT;
+
+ pthread_mutex_lock(&dev->bo_table_mutex);
+ if (fd != dev->fd) {
+ r = drmPrimeHandleToFD(fd, fbcur->handle, DRM_CLOEXEC, &dma_fd);
+ if (r) {
+ pthread_mutex_unlock(&dev->bo_table_mutex);
+ drmModeFreeFB(fbcur);
+ return r;
+ }
+ r = drmPrimeFDToHandle(dev->fd, dma_fd, &fbcur->handle );
+
+ close(dma_fd);
+
+ if (r) {
+ pthread_mutex_unlock(&dev->bo_table_mutex);
+ drmModeFreeFB(fbcur);
+ return r;
+ }
+ }
+ bo = util_hash_table_get(dev->bo_handles,
+ (void*)(uintptr_t)fbcur->handle);
+
+ if (bo) {
+ pthread_mutex_unlock(&dev->bo_table_mutex);
+
+ /* The buffer already exists, just bump the refcount. */
+ atomic_inc(&bo->refcount);
+
+ output->buf_handle = bo;
+ output->alloc_size = bo->alloc_size;
+ drmModeFreeFB(fbcur);
+ return 0;
+ }
+
+ bo = calloc(1, sizeof(struct amdgpu_bo));
+ if (!bo) {
+ pthread_mutex_unlock(&dev->bo_table_mutex);
+ drmModeFreeFB(fbcur);
+ return -ENOMEM;
+ }
+
+ /* Query buffer info. */
+ gem_op.handle = fbcur->handle;
+ gem_op.op = AMDGPU_GEM_OP_GET_GEM_CREATE_INFO;
+ gem_op.value = (uintptr_t)&bo_info;
+
+ r = drmCommandWriteRead(dev->fd, DRM_AMDGPU_GEM_OP,
+ &gem_op, sizeof(gem_op));
+ if (r) {
+ free(bo);
+ pthread_mutex_unlock(&dev->bo_table_mutex);
+ drmModeFreeFB(fbcur);
+ return r;
+ }
+
+ /* Initialize it. */
+ atomic_set(&bo->refcount, 1);
+ bo->handle = fbcur->handle;
+ bo->dev = dev;
+ bo->alloc_size = bo_info.bo_size;
+ output->buf_handle = bo;
+ pthread_mutex_init(&bo->cpu_access_mutex, NULL);
+
+ util_hash_table_set(dev->bo_handles, (void*)(uintptr_t)bo->handle, bo);
+ pthread_mutex_unlock(&dev->bo_table_mutex);
+
+ output->alloc_size = bo->alloc_size;
+ drmModeFreeFB(fbcur);
+ return r;
+}
+
int amdgpu_bo_free(amdgpu_bo_handle buf_handle)
{
/* Just drop the reference. */