1409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan/* 2409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * Copyright (c) 2012 Intel Corporation. All Rights Reserved. 3409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * 4409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * Permission is hereby granted, free of charge, to any person obtaining a 5409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * copy of this software and associated documentation files (the 6409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * "Software"), to deal in the Software without restriction, including 7409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * without limitation the rights to use, copy, modify, merge, publish, 8409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * distribute, sub license, and/or sell copies of the Software, and to 9409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * permit persons to whom the Software is furnished to do so, subject to 10409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * the following conditions: 11409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * 12409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * The above copyright notice and this permission notice (including the 13409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * next paragraph) shall be included in all copies or substantial portions 14409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * of the Software. 15409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * 16409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 19409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR 20409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan */ 2486c93d9c46415cf7746351c502a3513f637e77e4root#include <stdlib.h> 2586c93d9c46415cf7746351c502a3513f637e77e4root#include <fcntl.h> 2686c93d9c46415cf7746351c502a3513f637e77e4root#include <unistd.h> 2786c93d9c46415cf7746351c502a3513f637e77e4root#include <assert.h> 2886c93d9c46415cf7746351c502a3513f637e77e4root 2986c93d9c46415cf7746351c502a3513f637e77e4root#include <xf86drm.h> 3086c93d9c46415cf7746351c502a3513f637e77e4root 3186c93d9c46415cf7746351c502a3513f637e77e4root#include <X11/Xlibint.h> 3286c93d9c46415cf7746351c502a3513f637e77e4root#include <X11/Xlib.h> 3386c93d9c46415cf7746351c502a3513f637e77e4root#include "va.h" 3486c93d9c46415cf7746351c502a3513f637e77e4root#include "va_backend.h" 3586c93d9c46415cf7746351c502a3513f637e77e4root 3686c93d9c46415cf7746351c502a3513f637e77e4root#include "va_dri2.h" 3786c93d9c46415cf7746351c502a3513f637e77e4root#include "va_dri2tokens.h" 3886c93d9c46415cf7746351c502a3513f637e77e4root#include "va_dricommon.h" 3986c93d9c46415cf7746351c502a3513f637e77e4root 4086c93d9c46415cf7746351c502a3513f637e77e4root#define __DRI_BUFFER_FRONT_LEFT 0 4186c93d9c46415cf7746351c502a3513f637e77e4root#define __DRI_BUFFER_BACK_LEFT 1 4286c93d9c46415cf7746351c502a3513f637e77e4root#define __DRI_BUFFER_FRONT_RIGHT 2 4386c93d9c46415cf7746351c502a3513f637e77e4root#define __DRI_BUFFER_BACK_RIGHT 3 4486c93d9c46415cf7746351c502a3513f637e77e4root#define __DRI_BUFFER_DEPTH 4 4586c93d9c46415cf7746351c502a3513f637e77e4root#define __DRI_BUFFER_STENCIL 5 4686c93d9c46415cf7746351c502a3513f637e77e4root#define __DRI_BUFFER_ACCUM 6 4786c93d9c46415cf7746351c502a3513f637e77e4root#define __DRI_BUFFER_FAKE_FRONT_LEFT 7 4886c93d9c46415cf7746351c502a3513f637e77e4root#define __DRI_BUFFER_FAKE_FRONT_RIGHT 8 4986c93d9c46415cf7746351c502a3513f637e77e4root 5086c93d9c46415cf7746351c502a3513f637e77e4rootstruct dri2_drawable 5186c93d9c46415cf7746351c502a3513f637e77e4root{ 5286c93d9c46415cf7746351c502a3513f637e77e4root struct dri_drawable base; 5386c93d9c46415cf7746351c502a3513f637e77e4root union dri_buffer buffers[5]; 5486c93d9c46415cf7746351c502a3513f637e77e4root int width; 5586c93d9c46415cf7746351c502a3513f637e77e4root int height; 5686c93d9c46415cf7746351c502a3513f637e77e4root int has_backbuffer; 5786c93d9c46415cf7746351c502a3513f637e77e4root int back_index; 5886c93d9c46415cf7746351c502a3513f637e77e4root int front_index; 5986c93d9c46415cf7746351c502a3513f637e77e4root}; 6086c93d9c46415cf7746351c502a3513f637e77e4root 61b0fac498ca4863166252f1268fda83394db54153Fei Jiangstatic int gsDRI2SwapAvailable; 62b0fac498ca4863166252f1268fda83394db54153Fei Jiang 6386c93d9c46415cf7746351c502a3513f637e77e4rootstatic struct dri_drawable * 6486c93d9c46415cf7746351c502a3513f637e77e4rootdri2CreateDrawable(VADriverContextP ctx, XID x_drawable) 6586c93d9c46415cf7746351c502a3513f637e77e4root{ 6686c93d9c46415cf7746351c502a3513f637e77e4root struct dri2_drawable *dri2_drawable; 6786c93d9c46415cf7746351c502a3513f637e77e4root 6886c93d9c46415cf7746351c502a3513f637e77e4root dri2_drawable = calloc(1, sizeof(*dri2_drawable)); 6986c93d9c46415cf7746351c502a3513f637e77e4root 7086c93d9c46415cf7746351c502a3513f637e77e4root if (!dri2_drawable) 7186c93d9c46415cf7746351c502a3513f637e77e4root return NULL; 7286c93d9c46415cf7746351c502a3513f637e77e4root 7386c93d9c46415cf7746351c502a3513f637e77e4root dri2_drawable->base.x_drawable = x_drawable; 7486c93d9c46415cf7746351c502a3513f637e77e4root dri2_drawable->base.x = 0; 7586c93d9c46415cf7746351c502a3513f637e77e4root dri2_drawable->base.y = 0; 765b3d55a0433b48477823f81821817a78ef53ac2eShuduo Sang VA_DRI2CreateDrawable(ctx->native_dpy, x_drawable); 7786c93d9c46415cf7746351c502a3513f637e77e4root 7886c93d9c46415cf7746351c502a3513f637e77e4root return &dri2_drawable->base; 7986c93d9c46415cf7746351c502a3513f637e77e4root} 8086c93d9c46415cf7746351c502a3513f637e77e4root 8186c93d9c46415cf7746351c502a3513f637e77e4rootstatic void 8286c93d9c46415cf7746351c502a3513f637e77e4rootdri2DestroyDrawable(VADriverContextP ctx, struct dri_drawable *dri_drawable) 8386c93d9c46415cf7746351c502a3513f637e77e4root{ 845b3d55a0433b48477823f81821817a78ef53ac2eShuduo Sang VA_DRI2DestroyDrawable(ctx->native_dpy, dri_drawable->x_drawable); 8586c93d9c46415cf7746351c502a3513f637e77e4root free(dri_drawable); 8686c93d9c46415cf7746351c502a3513f637e77e4root} 8786c93d9c46415cf7746351c502a3513f637e77e4root 8886c93d9c46415cf7746351c502a3513f637e77e4rootstatic void 8986c93d9c46415cf7746351c502a3513f637e77e4rootdri2SwapBuffer(VADriverContextP ctx, struct dri_drawable *dri_drawable) 9086c93d9c46415cf7746351c502a3513f637e77e4root{ 9186c93d9c46415cf7746351c502a3513f637e77e4root struct dri2_drawable *dri2_drawable = (struct dri2_drawable *)dri_drawable; 9286c93d9c46415cf7746351c502a3513f637e77e4root XRectangle xrect; 9386c93d9c46415cf7746351c502a3513f637e77e4root XserverRegion region; 9486c93d9c46415cf7746351c502a3513f637e77e4root 9586c93d9c46415cf7746351c502a3513f637e77e4root if (dri2_drawable->has_backbuffer) { 96b0fac498ca4863166252f1268fda83394db54153Fei Jiang if (gsDRI2SwapAvailable) { 97b0fac498ca4863166252f1268fda83394db54153Fei Jiang CARD64 ret; 98b0fac498ca4863166252f1268fda83394db54153Fei Jiang VA_DRI2SwapBuffers(ctx->native_dpy, dri_drawable->x_drawable, 0, 0, 99b0fac498ca4863166252f1268fda83394db54153Fei Jiang 0, &ret); 100b0fac498ca4863166252f1268fda83394db54153Fei Jiang } else { 101b0fac498ca4863166252f1268fda83394db54153Fei Jiang xrect.x = 0; 102b0fac498ca4863166252f1268fda83394db54153Fei Jiang xrect.y = 0; 103b0fac498ca4863166252f1268fda83394db54153Fei Jiang xrect.width = dri2_drawable->width; 104b0fac498ca4863166252f1268fda83394db54153Fei Jiang xrect.height = dri2_drawable->height; 105b0fac498ca4863166252f1268fda83394db54153Fei Jiang 106b0fac498ca4863166252f1268fda83394db54153Fei Jiang region = XFixesCreateRegion(ctx->native_dpy, &xrect, 1); 107b0fac498ca4863166252f1268fda83394db54153Fei Jiang VA_DRI2CopyRegion(ctx->native_dpy, dri_drawable->x_drawable, region, 108b0fac498ca4863166252f1268fda83394db54153Fei Jiang DRI2BufferFrontLeft, DRI2BufferBackLeft); 109b0fac498ca4863166252f1268fda83394db54153Fei Jiang XFixesDestroyRegion(ctx->native_dpy, region); 110b0fac498ca4863166252f1268fda83394db54153Fei Jiang } 11186c93d9c46415cf7746351c502a3513f637e77e4root } 11286c93d9c46415cf7746351c502a3513f637e77e4root} 11386c93d9c46415cf7746351c502a3513f637e77e4root 11486c93d9c46415cf7746351c502a3513f637e77e4rootstatic union dri_buffer * 11586c93d9c46415cf7746351c502a3513f637e77e4rootdri2GetRenderingBuffer(VADriverContextP ctx, struct dri_drawable *dri_drawable) 11686c93d9c46415cf7746351c502a3513f637e77e4root{ 11786c93d9c46415cf7746351c502a3513f637e77e4root struct dri2_drawable *dri2_drawable = (struct dri2_drawable *)dri_drawable; 11886c93d9c46415cf7746351c502a3513f637e77e4root int i; 11986c93d9c46415cf7746351c502a3513f637e77e4root int count; 12086c93d9c46415cf7746351c502a3513f637e77e4root unsigned int attachments[5]; 12186c93d9c46415cf7746351c502a3513f637e77e4root VA_DRI2Buffer *buffers; 12286c93d9c46415cf7746351c502a3513f637e77e4root 12386c93d9c46415cf7746351c502a3513f637e77e4root i = 0; 124901c77a7aa491f56b63af7b655b67439481e4177Fei Jiang if (dri_drawable->is_window) 125901c77a7aa491f56b63af7b655b67439481e4177Fei Jiang attachments[i++] = __DRI_BUFFER_BACK_LEFT; 126901c77a7aa491f56b63af7b655b67439481e4177Fei Jiang else 127901c77a7aa491f56b63af7b655b67439481e4177Fei Jiang attachments[i++] = __DRI_BUFFER_FRONT_LEFT; 128901c77a7aa491f56b63af7b655b67439481e4177Fei Jiang 129b0fac498ca4863166252f1268fda83394db54153Fei Jiang buffers = VA_DRI2GetBuffers(ctx->native_dpy, dri_drawable->x_drawable, 13086c93d9c46415cf7746351c502a3513f637e77e4root &dri2_drawable->width, &dri2_drawable->height, 13186c93d9c46415cf7746351c502a3513f637e77e4root attachments, i, &count); 13286c93d9c46415cf7746351c502a3513f637e77e4root assert(buffers); 13386c93d9c46415cf7746351c502a3513f637e77e4root if (buffers == NULL) 13486c93d9c46415cf7746351c502a3513f637e77e4root return NULL; 13586c93d9c46415cf7746351c502a3513f637e77e4root 13686c93d9c46415cf7746351c502a3513f637e77e4root dri2_drawable->has_backbuffer = 0; 13786c93d9c46415cf7746351c502a3513f637e77e4root 13886c93d9c46415cf7746351c502a3513f637e77e4root for (i = 0; i < count; i++) { 13986c93d9c46415cf7746351c502a3513f637e77e4root dri2_drawable->buffers[i].dri2.attachment = buffers[i].attachment; 14086c93d9c46415cf7746351c502a3513f637e77e4root dri2_drawable->buffers[i].dri2.name = buffers[i].name; 14186c93d9c46415cf7746351c502a3513f637e77e4root dri2_drawable->buffers[i].dri2.pitch = buffers[i].pitch; 14286c93d9c46415cf7746351c502a3513f637e77e4root dri2_drawable->buffers[i].dri2.cpp = buffers[i].cpp; 14386c93d9c46415cf7746351c502a3513f637e77e4root dri2_drawable->buffers[i].dri2.flags = buffers[i].flags; 14486c93d9c46415cf7746351c502a3513f637e77e4root 14586c93d9c46415cf7746351c502a3513f637e77e4root if (buffers[i].attachment == __DRI_BUFFER_BACK_LEFT) { 14686c93d9c46415cf7746351c502a3513f637e77e4root dri2_drawable->has_backbuffer = 1; 14786c93d9c46415cf7746351c502a3513f637e77e4root dri2_drawable->back_index = i; 14886c93d9c46415cf7746351c502a3513f637e77e4root } 14986c93d9c46415cf7746351c502a3513f637e77e4root 15086c93d9c46415cf7746351c502a3513f637e77e4root if (buffers[i].attachment == __DRI_BUFFER_FRONT_LEFT) 15186c93d9c46415cf7746351c502a3513f637e77e4root dri2_drawable->front_index = i; 15286c93d9c46415cf7746351c502a3513f637e77e4root } 15386c93d9c46415cf7746351c502a3513f637e77e4root 15486c93d9c46415cf7746351c502a3513f637e77e4root dri_drawable->width = dri2_drawable->width; 15586c93d9c46415cf7746351c502a3513f637e77e4root dri_drawable->height = dri2_drawable->height; 15686c93d9c46415cf7746351c502a3513f637e77e4root Xfree(buffers); 15786c93d9c46415cf7746351c502a3513f637e77e4root 15886c93d9c46415cf7746351c502a3513f637e77e4root if (dri2_drawable->has_backbuffer) 15986c93d9c46415cf7746351c502a3513f637e77e4root return &dri2_drawable->buffers[dri2_drawable->back_index]; 16086c93d9c46415cf7746351c502a3513f637e77e4root 16186c93d9c46415cf7746351c502a3513f637e77e4root return &dri2_drawable->buffers[dri2_drawable->front_index]; 16286c93d9c46415cf7746351c502a3513f637e77e4root} 16386c93d9c46415cf7746351c502a3513f637e77e4root 16410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wangvoid 16586c93d9c46415cf7746351c502a3513f637e77e4rootdri2Close(VADriverContextP ctx) 16686c93d9c46415cf7746351c502a3513f637e77e4root{ 167409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan struct dri_state *dri_state = (struct dri_state *)ctx->drm_state; 16886c93d9c46415cf7746351c502a3513f637e77e4root 16986c93d9c46415cf7746351c502a3513f637e77e4root free_drawable_hashtable(ctx); 170601e657275d5edf21b79d64a49d9d392628ae487Austin Yuan 171409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan if (dri_state->base.fd >= 0); 172409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan close(dri_state->base.fd); 17386c93d9c46415cf7746351c502a3513f637e77e4root} 17486c93d9c46415cf7746351c502a3513f637e77e4root 17586c93d9c46415cf7746351c502a3513f637e77e4rootBool 17686c93d9c46415cf7746351c502a3513f637e77e4rootisDRI2Connected(VADriverContextP ctx, char **driver_name) 17786c93d9c46415cf7746351c502a3513f637e77e4root{ 178409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan struct dri_state *dri_state = (struct dri_state *)ctx->drm_state; 17986c93d9c46415cf7746351c502a3513f637e77e4root int major, minor; 18086c93d9c46415cf7746351c502a3513f637e77e4root int error_base; 18186c93d9c46415cf7746351c502a3513f637e77e4root int event_base; 18286c93d9c46415cf7746351c502a3513f637e77e4root char *device_name = NULL; 18386c93d9c46415cf7746351c502a3513f637e77e4root drm_magic_t magic; 18486c93d9c46415cf7746351c502a3513f637e77e4root *driver_name = NULL; 185409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan dri_state->base.fd = -1; 186409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan dri_state->base.auth_type = VA_NONE; 1875b3d55a0433b48477823f81821817a78ef53ac2eShuduo Sang if (!VA_DRI2QueryExtension(ctx->native_dpy, &event_base, &error_base)) 18886c93d9c46415cf7746351c502a3513f637e77e4root goto err_out; 18986c93d9c46415cf7746351c502a3513f637e77e4root 1905b3d55a0433b48477823f81821817a78ef53ac2eShuduo Sang if (!VA_DRI2QueryVersion(ctx->native_dpy, &major, &minor)) 19186c93d9c46415cf7746351c502a3513f637e77e4root goto err_out; 19286c93d9c46415cf7746351c502a3513f637e77e4root 193409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan 1945b3d55a0433b48477823f81821817a78ef53ac2eShuduo Sang if (!VA_DRI2Connect(ctx->native_dpy, RootWindow(ctx->native_dpy, ctx->x11_screen), 1956044ab9a375eb73b08f45d87966652f98f918668Austin Yuan driver_name, &device_name) || !device_name) 19686c93d9c46415cf7746351c502a3513f637e77e4root goto err_out; 19786c93d9c46415cf7746351c502a3513f637e77e4root 198409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan dri_state->base.fd = open(device_name, O_RDWR); 199409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan assert(dri_state->base.fd >= 0); 20086c93d9c46415cf7746351c502a3513f637e77e4root 201409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan if (dri_state->base.fd < 0) 20286c93d9c46415cf7746351c502a3513f637e77e4root goto err_out; 20386c93d9c46415cf7746351c502a3513f637e77e4root 204409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan if (drmGetMagic(dri_state->base.fd, &magic)) 20586c93d9c46415cf7746351c502a3513f637e77e4root goto err_out; 20686c93d9c46415cf7746351c502a3513f637e77e4root 2075b3d55a0433b48477823f81821817a78ef53ac2eShuduo Sang if (!VA_DRI2Authenticate(ctx->native_dpy, RootWindow(ctx->native_dpy, ctx->x11_screen), 20886c93d9c46415cf7746351c502a3513f637e77e4root magic)) 20986c93d9c46415cf7746351c502a3513f637e77e4root goto err_out; 21086c93d9c46415cf7746351c502a3513f637e77e4root 211409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan dri_state->base.auth_type = VA_DRI2; 21286c93d9c46415cf7746351c502a3513f637e77e4root dri_state->createDrawable = dri2CreateDrawable; 21386c93d9c46415cf7746351c502a3513f637e77e4root dri_state->destroyDrawable = dri2DestroyDrawable; 21486c93d9c46415cf7746351c502a3513f637e77e4root dri_state->swapBuffer = dri2SwapBuffer; 21586c93d9c46415cf7746351c502a3513f637e77e4root dri_state->getRenderingBuffer = dri2GetRenderingBuffer; 21686c93d9c46415cf7746351c502a3513f637e77e4root dri_state->close = dri2Close; 217b0fac498ca4863166252f1268fda83394db54153Fei Jiang gsDRI2SwapAvailable = (minor >= 2); 21886c93d9c46415cf7746351c502a3513f637e77e4root 2196044ab9a375eb73b08f45d87966652f98f918668Austin Yuan Xfree(device_name); 22036bee3ca78947ad82f87473b5d29b9a7177ebaedShuduo Sang 22186c93d9c46415cf7746351c502a3513f637e77e4root return True; 22286c93d9c46415cf7746351c502a3513f637e77e4root 22386c93d9c46415cf7746351c502a3513f637e77e4rooterr_out: 22486c93d9c46415cf7746351c502a3513f637e77e4root if (device_name) 22586c93d9c46415cf7746351c502a3513f637e77e4root Xfree(device_name); 22686c93d9c46415cf7746351c502a3513f637e77e4root 22786c93d9c46415cf7746351c502a3513f637e77e4root if (*driver_name) 22886c93d9c46415cf7746351c502a3513f637e77e4root Xfree(*driver_name); 22986c93d9c46415cf7746351c502a3513f637e77e4root 230409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan if (dri_state->base.fd >= 0) 231409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan close(dri_state->base.fd); 23286c93d9c46415cf7746351c502a3513f637e77e4root 23386c93d9c46415cf7746351c502a3513f637e77e4root *driver_name = NULL; 234409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan dri_state->base.fd = -1; 23586c93d9c46415cf7746351c502a3513f637e77e4root 23686c93d9c46415cf7746351c502a3513f637e77e4root return False; 23786c93d9c46415cf7746351c502a3513f637e77e4root} 23886c93d9c46415cf7746351c502a3513f637e77e4root 239