1/* Copyright © 2014 Advanced Micro Devices, Inc. 2 * 3 * Permission is hereby granted, free of charge, to any person 4 * obtaining a copy of this software and associated documentation 5 * files (the "Software"), to deal in the Software without 6 * restriction, including without limitation the rights to use, copy, 7 * modify, merge, publish, distribute, sublicense, and/or sell copies 8 * of the Software, and to permit persons to whom the Software is 9 * furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including 12 * the next paragraph) shall be included in all copies or substantial 13 * portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 * DEALINGS IN THE SOFTWARE. 23 */ 24 25#ifdef HAVE_CONFIG_H 26#include "config.h" 27#endif 28 29#include <xf86.h> 30#include "amdgpu_pixmap.h" 31#include "amdgpu_bo_helper.h" 32 33static PixmapPtr 34amdgpu_pixmap_create(ScreenPtr screen, int w, int h, int depth, unsigned usage) 35{ 36 ScrnInfoPtr scrn; 37 struct amdgpu_pixmap *priv; 38 PixmapPtr pixmap; 39 AMDGPUInfoPtr info; 40 41 /* only DRI2 pixmap is supported */ 42 if (!(usage & AMDGPU_CREATE_PIXMAP_DRI2)) 43 return fbCreatePixmap(screen, w, h, depth, usage); 44 45 if (w > 32767 || h > 32767) 46 return NullPixmap; 47 48 if (depth == 1) 49 return fbCreatePixmap(screen, w, h, depth, usage); 50 51 pixmap = fbCreatePixmap(screen, 0, 0, depth, usage); 52 if (pixmap == NullPixmap) 53 return pixmap; 54 55 if (w && h) { 56 int stride; 57 58 priv = calloc(1, sizeof(struct amdgpu_pixmap)); 59 if (!priv) 60 goto fallback_pixmap; 61 62 scrn = xf86ScreenToScrn(screen); 63 info = AMDGPUPTR(scrn); 64 if (!info->use_glamor) 65 usage |= AMDGPU_CREATE_PIXMAP_LINEAR; 66 priv->bo = amdgpu_alloc_pixmap_bo(scrn, w, h, depth, usage, 67 pixmap->drawable.bitsPerPixel, 68 &stride); 69 if (!priv->bo) 70 goto fallback_priv; 71 72 amdgpu_set_pixmap_private(pixmap, priv); 73 74 if (amdgpu_bo_map(scrn, priv->bo)) { 75 ErrorF("Failed to mmap the bo\n"); 76 goto fallback_bo; 77 } 78 79 screen->ModifyPixmapHeader(pixmap, w, h, 0, 0, stride, 80 priv->bo->cpu_ptr); 81 } 82 83 return pixmap; 84 85fallback_bo: 86 amdgpu_bo_unref(&priv->bo); 87fallback_priv: 88 free(priv); 89fallback_pixmap: 90 fbDestroyPixmap(pixmap); 91 return fbCreatePixmap(screen, w, h, depth, usage); 92} 93 94static Bool amdgpu_pixmap_destroy(PixmapPtr pixmap) 95{ 96 if (pixmap->refcnt == 1) { 97 amdgpu_set_pixmap_bo(pixmap, NULL); 98 } 99 fbDestroyPixmap(pixmap); 100 return TRUE; 101} 102 103/* This should only be called when glamor is disabled */ 104Bool amdgpu_pixmap_init(ScreenPtr screen) 105{ 106 if (!dixRegisterPrivateKey(&amdgpu_pixmap_index, PRIVATE_PIXMAP, 0)) 107 return FALSE; 108 109 screen->CreatePixmap = amdgpu_pixmap_create; 110 screen->DestroyPixmap = amdgpu_pixmap_destroy; 111 return TRUE; 112} 113