aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amdfalconx86/recipes-graphics/drm/files/0079-amdgpu-Add-interface-amdgpu_get_bo_from_fb_id.patch
blob: 31fac2c53e0dc16203b0b522b6177284ee3d0eb4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
From 562a5585d1c46a99b192c6cf080eb2aad582fa25 Mon Sep 17 00:00:00 2001
From: jqdeng <Emily.Deng@amd.com>
Date: Tue, 5 Jul 2016 15:44:51 +0800
Subject: [PATCH 079/117] amdgpu: Add interface amdgpu_get_bo_from_fb_id

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.

Signed-off-by: jqdeng <Emily.Deng@amd.com>
Reviewed-by: Chunming Zhou <David1.Zhou@amd.com>
---
 amdgpu/amdgpu-symbol-check |  1 +
 amdgpu/amdgpu.h            | 17 +++++++++
 amdgpu/amdgpu_bo.c         | 92 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 110 insertions(+)

diff --git a/amdgpu/amdgpu-symbol-check b/amdgpu/amdgpu-symbol-check
index e26ffe2..028ff78 100755
--- a/amdgpu/amdgpu-symbol-check
+++ b/amdgpu/amdgpu-symbol-check
@@ -49,6 +49,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 0f31100..08593ca 100644
--- a/amdgpu/amdgpu.h
+++ b/amdgpu/amdgpu.h
@@ -652,6 +652,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 49b951b..f311b94 100644
--- a/amdgpu/amdgpu_bo.c
+++ b/amdgpu/amdgpu_bo.c
@@ -465,6 +465,98 @@ 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);
+
+	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);
+			return r;
+		}
+		r = drmPrimeFDToHandle(dev->fd, dma_fd, &fbcur->handle );
+
+		close(dma_fd);
+
+		if (r) {
+			pthread_mutex_unlock(&dev->bo_table_mutex);
+			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;
+		return 0;
+	}
+
+	bo = calloc(1, sizeof(struct amdgpu_bo));
+	if (!bo) {
+		pthread_mutex_unlock(&dev->bo_table_mutex);
+		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);
+		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;
+	return r;
+}
+
 int amdgpu_bo_free(amdgpu_bo_handle buf_handle)
 {
 	/* Just drop the reference. */
-- 
2.7.4