intel_dri3.c revision 13496ba1
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#if USE_UXA 33#include "intel_uxa.h" 34#endif 35#include "dri3.h" 36 37static int 38intel_dri3_open(ScreenPtr screen, 39 RRProviderPtr provider, 40 int *out) 41{ 42 ScrnInfoPtr scrn = xf86ScreenToScrn(screen); 43 intel_screen_private *intel = intel_get_screen_private(scrn); 44 int fd; 45 46 fd = intel_get_client_fd(intel->dev); 47 if (fd < 0) 48 return -fd; 49 50 *out = fd; 51 return Success; 52} 53 54static PixmapPtr intel_dri3_pixmap_from_fd(ScreenPtr screen, 55 int fd, 56 CARD16 width, 57 CARD16 height, 58 CARD16 stride, 59 CARD8 depth, 60 CARD8 bpp) 61{ 62 ScrnInfoPtr scrn = xf86ScreenToScrn(screen); 63 intel_screen_private *intel = intel_get_screen_private(scrn); 64 struct intel_uxa_pixmap *priv; 65 PixmapPtr pixmap; 66 dri_bo *bo; 67 68 if (depth < 8) 69 return NULL; 70 71 switch (bpp) { 72 case 8: 73 case 16: 74 case 32: 75 break; 76 default: 77 return NULL; 78 } 79 80 pixmap = fbCreatePixmap(screen, 0, 0, depth, 0); 81 if (!pixmap) 82 return NULL; 83 84 if (!screen->ModifyPixmapHeader(pixmap, width, height, 0, 0, stride, NULL)) 85 goto free_pixmap; 86 87 bo = drm_intel_bo_gem_create_from_prime(intel->bufmgr, 88 fd, (uint32_t)height * stride); 89 if (bo == NULL) 90 goto free_pixmap; 91 92 intel_uxa_set_pixmap_bo(pixmap, bo); 93 dri_bo_unreference(bo); 94 95 priv = intel_uxa_get_pixmap_private(pixmap); 96 if (priv == NULL) 97 goto free_pixmap; 98 99 priv->pinned |= PIN_DRI3; 100 101 return pixmap; 102 103free_pixmap: 104 fbDestroyPixmap(pixmap); 105 return NULL; 106} 107 108static int intel_dri3_fd_from_pixmap(ScreenPtr screen, 109 PixmapPtr pixmap, 110 CARD16 *stride, 111 CARD32 *size) 112{ 113 struct intel_uxa_pixmap *priv; 114 int fd; 115 116 priv = intel_uxa_get_pixmap_private(pixmap); 117 if (!priv) 118 return -1; 119 120 if (intel_pixmap_pitch(pixmap) > UINT16_MAX) 121 return -1; 122 123 if (drm_intel_bo_gem_export_to_prime(priv->bo, &fd) < 0) 124 return -1; 125 126 priv->pinned |= PIN_DRI3; 127 128 *stride = intel_pixmap_pitch(pixmap); 129 *size = priv->bo->size; 130 return fd; 131} 132 133static dri3_screen_info_rec intel_dri3_screen_info = { 134 .version = DRI3_SCREEN_INFO_VERSION, 135 136 .open = intel_dri3_open, 137 .pixmap_from_fd = intel_dri3_pixmap_from_fd, 138 .fd_from_pixmap = intel_dri3_fd_from_pixmap 139}; 140 141Bool 142intel_dri3_screen_init(ScreenPtr screen) 143{ 144 return dri3_screen_init(screen, &intel_dri3_screen_info); 145} 146