1428d7b3dSmrg/* 2428d7b3dSmrg * Copyright (c) 2014 Intel Corporation 3428d7b3dSmrg * 4428d7b3dSmrg * Permission is hereby granted, free of charge, to any person obtaining a 5428d7b3dSmrg * copy of this software and associated documentation files (the "Software"), 6428d7b3dSmrg * to deal in the Software without restriction, including without limitation 7428d7b3dSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8428d7b3dSmrg * and/or sell copies of the Software, and to permit persons to whom the 9428d7b3dSmrg * Software is furnished to do so, subject to the following conditions: 10428d7b3dSmrg * 11428d7b3dSmrg * The above copyright notice and this permission notice (including the next 12428d7b3dSmrg * paragraph) shall be included in all copies or substantial portions of the 13428d7b3dSmrg * Software. 14428d7b3dSmrg * 15428d7b3dSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16428d7b3dSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17428d7b3dSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18428d7b3dSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19428d7b3dSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20428d7b3dSmrg * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21428d7b3dSmrg * SOFTWARE. 22428d7b3dSmrg * 23428d7b3dSmrg */ 24428d7b3dSmrg 25428d7b3dSmrg#include <X11/Xlib.h> 26428d7b3dSmrg#include <X11/Xlib-xcb.h> 27428d7b3dSmrg#include <X11/xshmfence.h> 28428d7b3dSmrg#include <xcb/xcb.h> 29428d7b3dSmrg#include <xcb/dri3.h> 30428d7b3dSmrg#include <xcb/sync.h> 31428d7b3dSmrg#include <unistd.h> 32428d7b3dSmrg 33428d7b3dSmrg#include "dri3.h" 34428d7b3dSmrg 35428d7b3dSmrgPixmap dri3_create_pixmap(Display *dpy, 36428d7b3dSmrg Drawable draw, 37428d7b3dSmrg int width, int height, int depth, 38428d7b3dSmrg int fd, int bpp, int stride, int size) 39428d7b3dSmrg{ 40428d7b3dSmrg xcb_connection_t *c = XGetXCBConnection(dpy); 41428d7b3dSmrg if (fd >= 0) { 42428d7b3dSmrg xcb_pixmap_t pixmap = xcb_generate_id(c); 43428d7b3dSmrg xcb_dri3_pixmap_from_buffer(c, pixmap, draw, size, width, height, stride, depth, bpp, fd); 44428d7b3dSmrg return pixmap; 45428d7b3dSmrg } 46428d7b3dSmrg return 0; 47428d7b3dSmrg} 48428d7b3dSmrg 49428d7b3dSmrgint dri3_create_fd(Display *dpy, 50428d7b3dSmrg Pixmap pixmap, 51428d7b3dSmrg int *stride) 52428d7b3dSmrg{ 53428d7b3dSmrg xcb_connection_t *c = XGetXCBConnection(dpy); 54428d7b3dSmrg xcb_dri3_buffer_from_pixmap_cookie_t cookie; 55428d7b3dSmrg xcb_dri3_buffer_from_pixmap_reply_t *reply; 56428d7b3dSmrg 57428d7b3dSmrg cookie = xcb_dri3_buffer_from_pixmap(c, pixmap); 58428d7b3dSmrg reply = xcb_dri3_buffer_from_pixmap_reply(c, cookie, NULL); 59428d7b3dSmrg if (!reply) 60428d7b3dSmrg return -1; 61428d7b3dSmrg 62428d7b3dSmrg if (reply->nfd != 1) 63428d7b3dSmrg return -1; 64428d7b3dSmrg 65428d7b3dSmrg *stride = reply->stride; 66428d7b3dSmrg return xcb_dri3_buffer_from_pixmap_reply_fds(c, reply)[0]; 67428d7b3dSmrg} 68428d7b3dSmrg 69428d7b3dSmrgint dri3_create_fence(Display *dpy, Pixmap pixmap, struct dri3_fence *fence) 70428d7b3dSmrg{ 71428d7b3dSmrg xcb_connection_t *c = XGetXCBConnection(dpy); 72428d7b3dSmrg struct dri3_fence f; 73428d7b3dSmrg int fd; 74428d7b3dSmrg 75428d7b3dSmrg fd = xshmfence_alloc_shm(); 76428d7b3dSmrg if (fd < 0) 77428d7b3dSmrg return -1; 78428d7b3dSmrg 79428d7b3dSmrg f.addr = xshmfence_map_shm(fd); 80428d7b3dSmrg if (f.addr == NULL) { 81428d7b3dSmrg close(fd); 82428d7b3dSmrg return -1; 83428d7b3dSmrg } 84428d7b3dSmrg 85428d7b3dSmrg f.xid = xcb_generate_id(c); 86428d7b3dSmrg xcb_dri3_fence_from_fd(c, pixmap, f.xid, 0, fd); 87428d7b3dSmrg 88428d7b3dSmrg *fence = f; 89428d7b3dSmrg return 0; 90428d7b3dSmrg} 91428d7b3dSmrg 92428d7b3dSmrgvoid dri3_fence_sync(Display *dpy, struct dri3_fence *fence) 93428d7b3dSmrg{ 94428d7b3dSmrg xcb_connection_t *c = XGetXCBConnection(dpy); 95428d7b3dSmrg 96428d7b3dSmrg xshmfence_reset(fence->addr); 97428d7b3dSmrg 98428d7b3dSmrg xcb_sync_trigger_fence(c, fence->xid); 99428d7b3dSmrg xcb_flush(c); 100428d7b3dSmrg 101428d7b3dSmrg xshmfence_await(fence->addr); 102428d7b3dSmrg} 103428d7b3dSmrg 104428d7b3dSmrgvoid dri3_fence_free(Display *dpy, struct dri3_fence *fence) 105428d7b3dSmrg{ 106428d7b3dSmrg xcb_connection_t *c = XGetXCBConnection(dpy); 107428d7b3dSmrg 108428d7b3dSmrg xshmfence_unmap_shm(fence->addr); 109428d7b3dSmrg xcb_sync_destroy_fence(c, fence->xid); 110428d7b3dSmrg} 111428d7b3dSmrg 112428d7b3dSmrgint dri3_open__full(Display *dpy, Window root, unsigned provider) 113428d7b3dSmrg{ 114428d7b3dSmrg xcb_connection_t *c = XGetXCBConnection(dpy); 115428d7b3dSmrg xcb_dri3_open_cookie_t cookie; 116428d7b3dSmrg xcb_dri3_open_reply_t *reply; 117428d7b3dSmrg 118428d7b3dSmrg cookie = xcb_dri3_open(c, root, provider); 119428d7b3dSmrg reply = xcb_dri3_open_reply(c, cookie, NULL); 120428d7b3dSmrg 121428d7b3dSmrg if (!reply) 122428d7b3dSmrg return -1; 123428d7b3dSmrg 124428d7b3dSmrg if (reply->nfd != 1) 125428d7b3dSmrg return -1; 126428d7b3dSmrg 127428d7b3dSmrg return xcb_dri3_open_reply_fds(c, reply)[0]; 128428d7b3dSmrg} 129428d7b3dSmrg 130428d7b3dSmrgint dri3_open(Display *dpy) 131428d7b3dSmrg{ 132428d7b3dSmrg return dri3_open__full(dpy, RootWindow(dpy, DefaultScreen(dpy)), None); 133428d7b3dSmrg} 134