amdgpu_pixmap.h revision 24b90cf4
1/*
2 * Copyright © 2014 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use, copy,
8 * modify, merge, publish, distribute, sublicense, and/or sell copies
9 * of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including
13 * the next paragraph) shall be included in all copies or substantial
14 * portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
24 */
25
26#ifndef AMDGPU_PIXMAP_H
27#define AMDGPU_PIXMAP_H
28
29#include "amdgpu_drv.h"
30
31struct amdgpu_pixmap {
32	uint_fast32_t gpu_read;
33	uint_fast32_t gpu_write;
34
35	uint64_t tiling_info;
36
37	struct amdgpu_buffer *bo;
38	struct drmmode_fb *fb;
39
40	/* GEM handle for pixmaps shared via DRI2/3 */
41	Bool handle_valid;
42	uint32_t handle;
43};
44
45extern DevPrivateKeyRec amdgpu_pixmap_index;
46
47static inline struct amdgpu_pixmap *amdgpu_get_pixmap_private(PixmapPtr pixmap)
48{
49	return dixGetPrivate(&pixmap->devPrivates, &amdgpu_pixmap_index);
50}
51
52static inline void amdgpu_set_pixmap_private(PixmapPtr pixmap,
53					     struct amdgpu_pixmap *priv)
54{
55	dixSetPrivate(&pixmap->devPrivates, &amdgpu_pixmap_index, priv);
56}
57
58static inline Bool amdgpu_set_pixmap_bo(PixmapPtr pPix, struct amdgpu_buffer *bo)
59{
60	ScrnInfoPtr scrn = xf86ScreenToScrn(pPix->drawable.pScreen);
61	AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(scrn);
62	struct amdgpu_pixmap *priv;
63
64	priv = amdgpu_get_pixmap_private(pPix);
65	if (priv == NULL && bo == NULL)
66		return TRUE;
67
68	if (priv) {
69		if (priv->bo) {
70			if (priv->bo == bo)
71				return TRUE;
72
73			amdgpu_bo_unref(&priv->bo);
74			priv->handle_valid = FALSE;
75		}
76
77		drmmode_fb_reference(pAMDGPUEnt->fd, &priv->fb, NULL);
78
79		if (!bo) {
80			free(priv);
81			priv = NULL;
82		}
83	}
84
85	if (bo) {
86		if (!priv) {
87			priv = calloc(1, sizeof(struct amdgpu_pixmap));
88			if (!priv)
89				return FALSE;
90		}
91		amdgpu_bo_ref(bo);
92		priv->bo = bo;
93	}
94
95	amdgpu_set_pixmap_private(pPix, priv);
96	return TRUE;
97}
98
99static inline struct amdgpu_buffer *amdgpu_get_pixmap_bo(PixmapPtr pPix)
100{
101	struct amdgpu_pixmap *priv;
102	priv = amdgpu_get_pixmap_private(pPix);
103	return priv ? priv->bo : NULL;
104}
105
106static inline struct drmmode_fb*
107amdgpu_fb_create(ScrnInfoPtr scrn, int drm_fd, uint32_t width, uint32_t height,
108		 uint32_t pitch, uint32_t handle)
109{
110	struct drmmode_fb *fb  = malloc(sizeof(*fb));
111
112	if (!fb)
113		return NULL;
114
115	fb->refcnt = 1;
116	if (drmModeAddFB(drm_fd, width, height, scrn->depth, scrn->bitsPerPixel,
117			 pitch, handle, &fb->handle) == 0)
118		return fb;
119
120	free(fb);
121	return NULL;
122}
123
124static inline struct drmmode_fb**
125amdgpu_pixmap_get_fb_ptr(PixmapPtr pix)
126{
127	ScrnInfoPtr scrn = xf86ScreenToScrn(pix->drawable.pScreen);
128	AMDGPUInfoPtr info = AMDGPUPTR(scrn);
129
130	if (info->use_glamor) {
131		struct amdgpu_pixmap *priv = amdgpu_get_pixmap_private(pix);
132
133		if (!priv)
134			return NULL;
135
136		return &priv->fb;
137	}
138
139	return NULL;
140}
141
142static inline struct drmmode_fb*
143amdgpu_pixmap_get_fb(PixmapPtr pix)
144{
145	struct drmmode_fb **fb_ptr = amdgpu_pixmap_get_fb_ptr(pix);
146
147	if (!fb_ptr)
148		return NULL;
149
150	if (!*fb_ptr) {
151		uint32_t handle;
152
153		if (amdgpu_pixmap_get_handle(pix, &handle)) {
154			ScrnInfoPtr scrn = xf86ScreenToScrn(pix->drawable.pScreen);
155			AMDGPUEntPtr pAMDGPUEnt = AMDGPUEntPriv(scrn);
156
157			*fb_ptr = amdgpu_fb_create(scrn, pAMDGPUEnt->fd, pix->drawable.width,
158						   pix->drawable.height, pix->devKind,
159						   handle);
160		}
161	}
162
163	return *fb_ptr;
164}
165
166enum {
167	AMDGPU_CREATE_PIXMAP_DRI2    = 0x08000000,
168	AMDGPU_CREATE_PIXMAP_LINEAR  = 0x04000000,
169	AMDGPU_CREATE_PIXMAP_SCANOUT = 0x02000000,
170	AMDGPU_CREATE_PIXMAP_GTT     = 0x01000000,
171};
172
173extern Bool amdgpu_pixmap_init(ScreenPtr screen);
174
175#endif /* AMDGPU_PIXMAP_H */
176