intel_dri3.c revision 42542f5f
1/* 2 * Copyright © 2013-2014 Intel Corporation 3 * 4 * Permission to use, copy, modify, distribute, and sell this software and its 5 * documentation for any purpose is hereby granted without fee, provided that 6 * the above copyright notice appear in all copies and that both that copyright 7 * notice and this permission notice appear in supporting documentation, and 8 * that the name of the copyright holders not be used in advertising or 9 * publicity pertaining to distribution of the software without specific, 10 * written prior permission. The copyright holders make no representations 11 * about the suitability of this software for any purpose. It is provided "as 12 * is" without express or implied warranty. 13 * 14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 20 * OF THIS SOFTWARE. 21 */ 22 23#ifdef HAVE_CONFIG_H 24#include "config.h" 25#endif 26 27#include "xorg-server.h" 28#include "xf86.h" 29#include "fb.h" 30 31#include "intel.h" 32#include "dri3.h" 33 34static int 35intel_dri3_open(ScreenPtr screen, 36 RRProviderPtr provider, 37 int *out) 38{ 39 int fd; 40 41 fd = intel_get_client_fd(xf86ScreenToScrn(screen)); 42 if (fd < 0) 43 return -fd; 44 45 *out = fd; 46 return Success; 47} 48 49static PixmapPtr intel_dri3_pixmap_from_fd(ScreenPtr screen, 50 int fd, 51 CARD16 width, 52 CARD16 height, 53 CARD16 stride, 54 CARD8 depth, 55 CARD8 bpp) 56{ 57 ScrnInfoPtr scrn = xf86ScreenToScrn(screen); 58 intel_screen_private *intel = intel_get_screen_private(scrn); 59 struct intel_pixmap *priv; 60 PixmapPtr pixmap; 61 dri_bo *bo; 62 63 if (depth < 8) 64 return NULL; 65 66 switch (bpp) { 67 case 8: 68 case 16: 69 case 32: 70 break; 71 default: 72 return NULL; 73 } 74 75 pixmap = fbCreatePixmap(screen, 0, 0, depth, 0); 76 if (!pixmap) 77 return NULL; 78 79 if (!screen->ModifyPixmapHeader(pixmap, width, height, 0, 0, stride, NULL)) 80 goto free_pixmap; 81 82 bo = drm_intel_bo_gem_create_from_prime(intel->bufmgr, 83 fd, (uint32_t)height * stride); 84 if (bo == NULL) 85 goto free_pixmap; 86 87 intel_set_pixmap_bo(pixmap, bo); 88 dri_bo_unreference(bo); 89 90 priv = intel_get_pixmap_private(pixmap); 91 if (priv == NULL) 92 goto free_pixmap; 93 94 priv->pinned |= PIN_DRI3; 95 96 return pixmap; 97 98free_pixmap: 99 fbDestroyPixmap(pixmap); 100 return NULL; 101} 102 103static int intel_dri3_fd_from_pixmap(ScreenPtr screen, 104 PixmapPtr pixmap, 105 CARD16 *stride, 106 CARD32 *size) 107{ 108 struct intel_pixmap *priv; 109 int fd; 110 111 priv = intel_get_pixmap_private(pixmap); 112 if (!priv) 113 return -1; 114 115 if (priv->stride > UINT16_MAX) 116 return -1; 117 118 if (drm_intel_bo_gem_export_to_prime(priv->bo, &fd) < 0) 119 return -1; 120 121 priv->pinned |= PIN_DRI3; 122 123 *stride = priv->stride; 124 *size = priv->bo->size; 125 return fd; 126} 127 128static dri3_screen_info_rec intel_dri3_screen_info = { 129 .version = DRI3_SCREEN_INFO_VERSION, 130 131 .open = intel_dri3_open, 132 .pixmap_from_fd = intel_dri3_pixmap_from_fd, 133 .fd_from_pixmap = intel_dri3_fd_from_pixmap 134}; 135 136Bool 137intel_dri3_screen_init(ScreenPtr screen) 138{ 139 return dri3_screen_init(screen, &intel_dri3_screen_info); 140} 141