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