diff options
Diffstat (limited to 'src/x11')
-rw-r--r-- | src/x11/Makefile.am | 30 | ||||
-rw-r--r-- | src/x11/dri1_util.c | 158 | ||||
-rw-r--r-- | src/x11/dri2_util.c | 200 | ||||
-rw-r--r-- | src/x11/va_dri.c | 624 | ||||
-rw-r--r-- | src/x11/va_dri.h | 120 | ||||
-rw-r--r-- | src/x11/va_dri2.c | 307 | ||||
-rw-r--r-- | src/x11/va_dri2.h | 71 | ||||
-rw-r--r-- | src/x11/va_dri2str.h | 193 | ||||
-rw-r--r-- | src/x11/va_dri2tokens.h | 48 | ||||
-rw-r--r-- | src/x11/va_dricommon.c | 62 | ||||
-rw-r--r-- | src/x11/va_dricommon.h | 68 | ||||
-rw-r--r-- | src/x11/va_dristr.h | 344 | ||||
-rw-r--r-- | src/x11/va_nvctrl.c | 392 | ||||
-rw-r--r-- | src/x11/va_nvctrl.h | 36 | ||||
-rw-r--r-- | src/x11/va_x11.c | 283 | ||||
-rw-r--r-- | src/x11/va_x11.h | 67 |
16 files changed, 3003 insertions, 0 deletions
diff --git a/src/x11/Makefile.am b/src/x11/Makefile.am new file mode 100644 index 0000000..c70380d --- /dev/null +++ b/src/x11/Makefile.am @@ -0,0 +1,30 @@ +# INTEL CONFIDENTIAL +# Copyright 2007 Intel Corporation. All Rights Reserved. +# +# The source code contained or described herein and all documents related to +# the source code ("Material") are owned by Intel Corporation or its suppliers +# or licensors. Title to the Material remains with Intel Corporation or its +# suppliers and licensors. The Material may contain trade secrets and +# proprietary and confidential information of Intel Corporation and its +# suppliers and licensors, and is protected by worldwide copyright and trade +# secret laws and treaty provisions. No part of the Material may be used, +# copied, reproduced, modified, published, uploaded, posted, transmitted, +# distributed, or disclosed in any way without Intel's prior express written +# permission. +# +# No license under any patent, copyright, trade secret or other intellectual +# property right is granted to or conferred upon you by disclosure or delivery +# of the Materials, either expressly, by implication, inducement, estoppel or +# otherwise. Any license under such intellectual property rights must be +# express and approved by Intel in writing. + +AM_CFLAGS = -DLINUX -DIN_LIBVA -I$(top_srcdir)/src $(DRM_CFLAGS) + +noinst_LTLIBRARIES = libva_x11.la + +libva_x11includedir = ${includedir}/va +libva_x11include_HEADERS = va_x11.h va_dri.h va_dri2.h va_dricommon.h + +libva_x11_la_SOURCES = va_x11.c va_dri.c va_dri2.c va_dricommon.c dri2_util.c dri1_util.c va_nvctrl.c + +EXTRA_DIST = va_dristr.h va_dri2str.h va_dri2tokens.h va_nvctrl.h diff --git a/src/x11/dri1_util.c b/src/x11/dri1_util.c new file mode 100644 index 0000000..b3db5b4 --- /dev/null +++ b/src/x11/dri1_util.c @@ -0,0 +1,158 @@ +#include <stdlib.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/mman.h> +#include <assert.h> + +#include <xf86drm.h> + +#include "X11/Xlib.h" +#include "va.h" +#include "va_backend.h" + +#include "va_dri.h" +#include "va_dricommon.h" + +struct dri1_drawable +{ + struct dri_drawable base; + union dri_buffer buffer; + int width; + int height; +}; + +static struct dri_drawable * +dri1CreateDrawable(VADriverContextP ctx, XID x_drawable) +{ + struct dri1_drawable *dri1_drawable; + + dri1_drawable = calloc(1, sizeof(*dri1_drawable)); + + if (!dri1_drawable) + return NULL; + + dri1_drawable->base.x_drawable = x_drawable; + + return &dri1_drawable->base; +} + +static void +dri1DestroyDrawable(VADriverContextP ctx, struct dri_drawable *dri_drawable) +{ + free(dri_drawable); +} + +static void +dri1SwapBuffer(VADriverContextP ctx, struct dri_drawable *dri_drawable) +{ + +} + +static union dri_buffer * +dri1GetRenderingBuffer(VADriverContextP ctx, struct dri_drawable *dri_drawable) +{ + struct dri1_drawable *dri1_drawable = (struct dri1_drawable *)dri_drawable; + + return &dri1_drawable->buffer; +} + +static void +dri1Close(VADriverContextP ctx) +{ + struct dri_state *dri_state = (struct dri_state *)ctx->dri_state; + + free_drawable_hashtable(ctx); + VA_DRIDestroyContext(ctx->x11_dpy, ctx->x11_screen, dri_state->hwContextID); + assert(dri_state->pSAREA != MAP_FAILED); + drmUnmap(dri_state->pSAREA, SAREA_MAX); + assert(dri_state->fd >= 0); + drmCloseOnce(dri_state->fd); + VA_DRICloseConnection(ctx->x11_dpy, ctx->x11_screen); +} + +Bool +isDRI1Connected(VADriverContextP ctx, char **driver_name) +{ + struct dri_state *dri_state = (struct dri_state *)ctx->dri_state; + int direct_capable; + int driver_major; + int driver_minor; + int driver_patch; + int newlyopened; + char *BusID; + drm_magic_t magic; + + *driver_name = NULL; + dri_state->fd = -1; + dri_state->pSAREA = MAP_FAILED; + dri_state->driConnectedFlag = VA_NONE; + + if (!VA_DRIQueryDirectRenderingCapable(ctx->x11_dpy, + ctx->x11_screen, + &direct_capable)) + goto err_out0; + + if (!direct_capable) + goto err_out0; + + if (!VA_DRIGetClientDriverName(ctx->x11_dpy, ctx->x11_screen, + &driver_major, &driver_minor, + &driver_patch, driver_name)) + goto err_out0; + + if (!VA_DRIOpenConnection(ctx->x11_dpy, ctx->x11_screen, + &dri_state->hSAREA, &BusID)) + goto err_out0; + + + dri_state->fd = drmOpenOnce(NULL, BusID, &newlyopened); + XFree(BusID); + assert(dri_state->fd >= 0); + + if (dri_state->fd < 0) + goto err_out1; + + + if (drmGetMagic(dri_state->fd, &magic)) + goto err_out1; + + if (newlyopened && !VA_DRIAuthConnection(ctx->x11_dpy, ctx->x11_screen, magic)) + goto err_out1; + + if (drmMap(dri_state->fd, dri_state->hSAREA, SAREA_MAX, &dri_state->pSAREA)) + goto err_out1; + + if (!VA_DRICreateContext(ctx->x11_dpy, ctx->x11_screen, + DefaultVisual(ctx->x11_dpy, ctx->x11_screen), + &dri_state->hwContextID, &dri_state->hwContext)) + goto err_out1; + + dri_state->driConnectedFlag = VA_DRI1; + dri_state->createDrawable = dri1CreateDrawable; + dri_state->destroyDrawable = dri1DestroyDrawable; + dri_state->swapBuffer = dri1SwapBuffer; + dri_state->getRenderingBuffer = dri1GetRenderingBuffer; + dri_state->close = dri1Close; + + return True; + +err_out1: + if (dri_state->pSAREA != MAP_FAILED) + drmUnmap(dri_state->pSAREA, SAREA_MAX); + + if (dri_state->fd >= 0) + drmCloseOnce(dri_state->fd); + + VA_DRICloseConnection(ctx->x11_dpy, ctx->x11_screen); + +err_out0: + if (*driver_name) + XFree(*driver_name); + + dri_state->pSAREA = MAP_FAILED; + dri_state->fd = -1; + *driver_name = NULL; + + return False; +} + diff --git a/src/x11/dri2_util.c b/src/x11/dri2_util.c new file mode 100644 index 0000000..ebe7a2c --- /dev/null +++ b/src/x11/dri2_util.c @@ -0,0 +1,200 @@ +#include <stdlib.h> +#include <fcntl.h> +#include <unistd.h> +#include <assert.h> + +#include <xf86drm.h> + +#include <X11/Xlibint.h> +#include <X11/Xlib.h> +#include "va.h" +#include "va_backend.h" + +#include "va_dri2.h" +#include "va_dri2tokens.h" +#include "va_dricommon.h" + +#define __DRI_BUFFER_FRONT_LEFT 0 +#define __DRI_BUFFER_BACK_LEFT 1 +#define __DRI_BUFFER_FRONT_RIGHT 2 +#define __DRI_BUFFER_BACK_RIGHT 3 +#define __DRI_BUFFER_DEPTH 4 +#define __DRI_BUFFER_STENCIL 5 +#define __DRI_BUFFER_ACCUM 6 +#define __DRI_BUFFER_FAKE_FRONT_LEFT 7 +#define __DRI_BUFFER_FAKE_FRONT_RIGHT 8 + +struct dri2_drawable +{ + struct dri_drawable base; + union dri_buffer buffers[5]; + int width; + int height; + int has_backbuffer; + int back_index; + int front_index; +}; + +static struct dri_drawable * +dri2CreateDrawable(VADriverContextP ctx, XID x_drawable) +{ + struct dri2_drawable *dri2_drawable; + + dri2_drawable = calloc(1, sizeof(*dri2_drawable)); + + if (!dri2_drawable) + return NULL; + + dri2_drawable->base.x_drawable = x_drawable; + dri2_drawable->base.x = 0; + dri2_drawable->base.y = 0; + VA_DRI2CreateDrawable(ctx->x11_dpy, x_drawable); + + return &dri2_drawable->base; +} + +static void +dri2DestroyDrawable(VADriverContextP ctx, struct dri_drawable *dri_drawable) +{ + VA_DRI2DestroyDrawable(ctx->x11_dpy, dri_drawable->x_drawable); + free(dri_drawable); +} + +static void +dri2SwapBuffer(VADriverContextP ctx, struct dri_drawable *dri_drawable) +{ + struct dri2_drawable *dri2_drawable = (struct dri2_drawable *)dri_drawable; + XRectangle xrect; + XserverRegion region; + + if (dri2_drawable->has_backbuffer) { + xrect.x = 0; + xrect.y = 0; + xrect.width = dri2_drawable->width; + xrect.height = dri2_drawable->height; + + region = XFixesCreateRegion(ctx->x11_dpy, &xrect, 1); + VA_DRI2CopyRegion(ctx->x11_dpy, dri_drawable->x_drawable, region, + DRI2BufferFrontLeft, DRI2BufferBackLeft); + XFixesDestroyRegion(ctx->x11_dpy, region); + } +} + +static union dri_buffer * +dri2GetRenderingBuffer(VADriverContextP ctx, struct dri_drawable *dri_drawable) +{ + struct dri2_drawable *dri2_drawable = (struct dri2_drawable *)dri_drawable; + int i; + int count; + unsigned int attachments[5]; + VA_DRI2Buffer *buffers; + + i = 0; + attachments[i++] = __DRI_BUFFER_BACK_LEFT; + attachments[i++] = __DRI_BUFFER_FRONT_LEFT; + buffers = VA_DRI2GetBuffers(ctx->x11_dpy, dri_drawable->x_drawable, + &dri2_drawable->width, &dri2_drawable->height, + attachments, i, &count); + assert(buffers); + if (buffers == NULL) + return NULL; + + dri2_drawable->has_backbuffer = 0; + + for (i = 0; i < count; i++) { + dri2_drawable->buffers[i].dri2.attachment = buffers[i].attachment; + dri2_drawable->buffers[i].dri2.name = buffers[i].name; + dri2_drawable->buffers[i].dri2.pitch = buffers[i].pitch; + dri2_drawable->buffers[i].dri2.cpp = buffers[i].cpp; + dri2_drawable->buffers[i].dri2.flags = buffers[i].flags; + + if (buffers[i].attachment == __DRI_BUFFER_BACK_LEFT) { + dri2_drawable->has_backbuffer = 1; + dri2_drawable->back_index = i; + } + + if (buffers[i].attachment == __DRI_BUFFER_FRONT_LEFT) + dri2_drawable->front_index = i; + } + + dri_drawable->width = dri2_drawable->width; + dri_drawable->height = dri2_drawable->height; + Xfree(buffers); + + if (dri2_drawable->has_backbuffer) + return &dri2_drawable->buffers[dri2_drawable->back_index]; + + return &dri2_drawable->buffers[dri2_drawable->front_index]; +} + +static void +dri2Close(VADriverContextP ctx) +{ + struct dri_state *dri_state = (struct dri_state *)ctx->dri_state; + + free_drawable_hashtable(ctx); + assert(dri_state->fd >= 0); + close(dri_state->fd); +} + +Bool +isDRI2Connected(VADriverContextP ctx, char **driver_name) +{ + struct dri_state *dri_state = (struct dri_state *)ctx->dri_state; + int major, minor; + int error_base; + int event_base; + char *device_name = NULL; + drm_magic_t magic; + *driver_name = NULL; + dri_state->fd = -1; + dri_state->driConnectedFlag = VA_NONE; + if (!VA_DRI2QueryExtension(ctx->x11_dpy, &event_base, &error_base)) + goto err_out; + + if (!VA_DRI2QueryVersion(ctx->x11_dpy, &major, &minor)) + goto err_out; + + + if (!VA_DRI2Connect(ctx->x11_dpy, RootWindow(ctx->x11_dpy, ctx->x11_screen), + driver_name, &device_name)) + goto err_out; + + dri_state->fd = open(device_name, O_RDWR); + assert(dri_state->fd >= 0); + + if (dri_state->fd < 0) + goto err_out; + + if (drmGetMagic(dri_state->fd, &magic)) + goto err_out; + + if (!VA_DRI2Authenticate(ctx->x11_dpy, RootWindow(ctx->x11_dpy, ctx->x11_screen), + magic)) + goto err_out; + + dri_state->driConnectedFlag = VA_DRI2; + dri_state->createDrawable = dri2CreateDrawable; + dri_state->destroyDrawable = dri2DestroyDrawable; + dri_state->swapBuffer = dri2SwapBuffer; + dri_state->getRenderingBuffer = dri2GetRenderingBuffer; + dri_state->close = dri2Close; + + return True; + +err_out: + if (device_name) + Xfree(device_name); + + if (*driver_name) + Xfree(*driver_name); + + if (dri_state->fd >= 0) + close(dri_state->fd); + + *driver_name = NULL; + dri_state->fd = -1; + + return False; +} + diff --git a/src/x11/va_dri.c b/src/x11/va_dri.c new file mode 100644 index 0000000..ce3b7cd --- /dev/null +++ b/src/x11/va_dri.c @@ -0,0 +1,624 @@ +/* $XFree86: xc/lib/GL/dri/XF86dri.c,v 1.13 2002/10/30 12:51:25 alanh Exp $ */ +/************************************************************************** + +Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +Copyright 2000 VA Linux Systems, Inc. +Copyright 2007 Intel Corporation +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sub license, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Jens Owen <jens@tungstengraphics.com> + * Rickard E. (Rik) Faith <faith@valinux.com> + * + */ + +/* THIS IS NOT AN X CONSORTIUM STANDARD */ + +#define NEED_REPLIES +#include <X11/Xlibint.h> +#include <X11/extensions/Xext.h> +#include <X11/extensions/extutil.h> +#include "va_dristr.h" + +#define PUBLIC + +static XExtensionInfo _va_dri_info_data; +static XExtensionInfo *va_dri_info = &_va_dri_info_data; +static char va_dri_extension_name[] = VA_DRINAME; + +#define VA_DRICheckExtension(dpy,i,val) \ + XextCheckExtension (dpy, i, va_dri_extension_name, val) + +/***************************************************************************** + * * + * private utility routines * + * * + *****************************************************************************/ + +static int close_display(Display *dpy, XExtCodes *extCodes); +static /* const */ XExtensionHooks va_dri_extension_hooks = { + NULL, /* create_gc */ + NULL, /* copy_gc */ + NULL, /* flush_gc */ + NULL, /* free_gc */ + NULL, /* create_font */ + NULL, /* free_font */ + close_display, /* close_display */ + NULL, /* wire_to_event */ + NULL, /* event_to_wire */ + NULL, /* error */ + NULL, /* error_string */ +}; + +static XEXT_GENERATE_FIND_DISPLAY (find_display, va_dri_info, + va_dri_extension_name, + &va_dri_extension_hooks, + 0, NULL) + +static XEXT_GENERATE_CLOSE_DISPLAY (close_display, va_dri_info) + + +/***************************************************************************** + * * + * public XFree86-DRI Extension routines * + * * + *****************************************************************************/ + +#if 0 +#include <stdio.h> +#define TRACE(msg) fprintf(stderr,"XF86DRI%s\n", msg); +#else +#define TRACE(msg) +#endif + + +PUBLIC Bool VA_DRIQueryExtension (dpy, event_basep, error_basep) + Display *dpy; + int *event_basep, *error_basep; +{ + XExtDisplayInfo *info = find_display (dpy); + + TRACE("QueryExtension..."); + if (XextHasExtension(info)) { + *event_basep = info->codes->first_event; + *error_basep = info->codes->first_error; + TRACE("QueryExtension... return True"); + return True; + } else { + TRACE("QueryExtension... return False"); + return False; + } +} + +PUBLIC Bool VA_DRIQueryVersion(dpy, majorVersion, minorVersion, patchVersion) + Display* dpy; + int* majorVersion; + int* minorVersion; + int* patchVersion; +{ + XExtDisplayInfo *info = find_display (dpy); + xVA_DRIQueryVersionReply rep; + xVA_DRIQueryVersionReq *req; + + TRACE("QueryVersion..."); + VA_DRICheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(VA_DRIQueryVersion, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_VA_DRIQueryVersion; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("QueryVersion... return False"); + return False; + } + *majorVersion = rep.majorVersion; + *minorVersion = rep.minorVersion; + *patchVersion = rep.patchVersion; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("QueryVersion... return True"); + return True; +} + +PUBLIC Bool VA_DRIQueryDirectRenderingCapable(dpy, screen, isCapable) + Display* dpy; + int screen; + Bool* isCapable; +{ + XExtDisplayInfo *info = find_display (dpy); + xVA_DRIQueryDirectRenderingCapableReply rep; + xVA_DRIQueryDirectRenderingCapableReq *req; + + TRACE("QueryDirectRenderingCapable..."); + VA_DRICheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(VA_DRIQueryDirectRenderingCapable, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_VA_DRIQueryDirectRenderingCapable; + req->screen = screen; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("QueryDirectRenderingCapable... return False"); + return False; + } + *isCapable = rep.isCapable; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("QueryDirectRenderingCapable... return True"); + return True; +} + +PUBLIC Bool VA_DRIOpenConnection(dpy, screen, hSAREA, busIdString) + Display* dpy; + int screen; + drm_handle_t * hSAREA; + char **busIdString; +{ + XExtDisplayInfo *info = find_display (dpy); + xVA_DRIOpenConnectionReply rep; + xVA_DRIOpenConnectionReq *req; + + TRACE("OpenConnection..."); + VA_DRICheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(VA_DRIOpenConnection, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_VA_DRIOpenConnection; + req->screen = screen; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("OpenConnection... return False"); + return False; + } + + *hSAREA = rep.hSAREALow; + if (sizeof(drm_handle_t) == 8) { + int shift = 32; /* var to prevent warning on next line */ + *hSAREA |= ((drm_handle_t) rep.hSAREAHigh) << shift; + } + + if (rep.length) { + if (!(*busIdString = (char *)Xcalloc(rep.busIdStringLength + 1, 1))) { + _XEatData(dpy, ((rep.busIdStringLength+3) & ~3)); + UnlockDisplay(dpy); + SyncHandle(); + TRACE("OpenConnection... return False"); + return False; + } + _XReadPad(dpy, *busIdString, rep.busIdStringLength); + } else { + *busIdString = NULL; + } + UnlockDisplay(dpy); + SyncHandle(); + TRACE("OpenConnection... return True"); + return True; +} + +PUBLIC Bool VA_DRIAuthConnection(dpy, screen, magic) + Display* dpy; + int screen; + drm_magic_t magic; +{ + XExtDisplayInfo *info = find_display (dpy); + xVA_DRIAuthConnectionReq *req; + xVA_DRIAuthConnectionReply rep; + + TRACE("AuthConnection..."); + VA_DRICheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(VA_DRIAuthConnection, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_VA_DRIAuthConnection; + req->screen = screen; + req->magic = magic; + rep.authenticated = 0; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse) || !rep.authenticated) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("AuthConnection... return False"); + return False; + } + UnlockDisplay(dpy); + SyncHandle(); + TRACE("AuthConnection... return True"); + return True; +} + +PUBLIC Bool VA_DRICloseConnection(dpy, screen) + Display* dpy; + int screen; +{ + XExtDisplayInfo *info = find_display (dpy); + xVA_DRICloseConnectionReq *req; + + TRACE("CloseConnection..."); + + VA_DRICheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(VA_DRICloseConnection, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_VA_DRICloseConnection; + req->screen = screen; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("CloseConnection... return True"); + return True; +} + +PUBLIC Bool VA_DRIGetClientDriverName(dpy, screen, ddxDriverMajorVersion, + ddxDriverMinorVersion, ddxDriverPatchVersion, clientDriverName) + Display* dpy; + int screen; + int* ddxDriverMajorVersion; + int* ddxDriverMinorVersion; + int* ddxDriverPatchVersion; + char** clientDriverName; +{ + XExtDisplayInfo *info = find_display (dpy); + xVA_DRIGetClientDriverNameReply rep; + xVA_DRIGetClientDriverNameReq *req; + + TRACE("GetClientDriverName..."); + VA_DRICheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(VA_DRIGetClientDriverName, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_VA_DRIGetClientDriverName; + req->screen = screen; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetClientDriverName... return False"); + return False; + } + + *ddxDriverMajorVersion = rep.ddxDriverMajorVersion; + *ddxDriverMinorVersion = rep.ddxDriverMinorVersion; + *ddxDriverPatchVersion = rep.ddxDriverPatchVersion; + + if (rep.length) { + if (!(*clientDriverName = (char *)Xcalloc(rep.clientDriverNameLength + 1, 1))) { + _XEatData(dpy, ((rep.clientDriverNameLength+3) & ~3)); + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetClientDriverName... return False"); + return False; + } + _XReadPad(dpy, *clientDriverName, rep.clientDriverNameLength); + } else { + *clientDriverName = NULL; + } + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetClientDriverName... return True"); + return True; +} + +PUBLIC Bool VA_DRICreateContextWithConfig(dpy, screen, configID, context, + hHWContext) + Display* dpy; + int screen; + int configID; + XID* context; + drm_context_t * hHWContext; +{ + XExtDisplayInfo *info = find_display (dpy); + xVA_DRICreateContextReply rep; + xVA_DRICreateContextReq *req; + + TRACE("CreateContext..."); + VA_DRICheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(VA_DRICreateContext, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_VA_DRICreateContext; + req->visual = configID; + req->screen = screen; + *context = XAllocID(dpy); + req->context = *context; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("CreateContext... return False"); + return False; + } + *hHWContext = rep.hHWContext; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("CreateContext... return True"); + return True; +} + +PUBLIC Bool VA_DRICreateContext(dpy, screen, visual, context, hHWContext) + Display* dpy; + int screen; + Visual* visual; + XID* context; + drm_context_t * hHWContext; +{ + return VA_DRICreateContextWithConfig( dpy, screen, visual->visualid, + context, hHWContext ); +} + +PUBLIC Bool VA_DRIDestroyContext( __DRInativeDisplay * ndpy, int screen, + __DRIid context ) +{ + Display * const dpy = (Display *) ndpy; + XExtDisplayInfo *info = find_display (dpy); + xVA_DRIDestroyContextReq *req; + + TRACE("DestroyContext..."); + VA_DRICheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(VA_DRIDestroyContext, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_VA_DRIDestroyContext; + req->screen = screen; + req->context = context; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("DestroyContext... return True"); + return True; +} + +PUBLIC Bool VA_DRICreateDrawable( __DRInativeDisplay * ndpy, int screen, + __DRIid drawable, drm_drawable_t * hHWDrawable ) +{ + Display * const dpy = (Display *) ndpy; + XExtDisplayInfo *info = find_display (dpy); + xVA_DRICreateDrawableReply rep; + xVA_DRICreateDrawableReq *req; + + TRACE("CreateDrawable..."); + VA_DRICheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(VA_DRICreateDrawable, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_VA_DRICreateDrawable; + req->screen = screen; + req->drawable = drawable; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("CreateDrawable... return False"); + return False; + } + *hHWDrawable = rep.hHWDrawable; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("CreateDrawable... return True"); + return True; +} + +PUBLIC Bool VA_DRIDestroyDrawable( __DRInativeDisplay * ndpy, int screen, + __DRIid drawable ) +{ + Display * const dpy = (Display *) ndpy; + XExtDisplayInfo *info = find_display (dpy); + xVA_DRIDestroyDrawableReq *req; + + TRACE("DestroyDrawable..."); + VA_DRICheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(VA_DRIDestroyDrawable, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_VA_DRIDestroyDrawable; + req->screen = screen; + req->drawable = drawable; + UnlockDisplay(dpy); + SyncHandle(); + TRACE("DestroyDrawable... return True"); + return True; +} + +PUBLIC Bool VA_DRIGetDrawableInfo(Display* dpy, int screen, Drawable drawable, + unsigned int* index, unsigned int* stamp, + int* X, int* Y, int* W, int* H, + int* numClipRects, drm_clip_rect_t ** pClipRects, + int* backX, int* backY, + int* numBackClipRects, drm_clip_rect_t ** pBackClipRects ) +{ + XExtDisplayInfo *info = find_display (dpy); + xVA_DRIGetDrawableInfoReply rep; + xVA_DRIGetDrawableInfoReq *req; + int total_rects; + + TRACE("GetDrawableInfo..."); + VA_DRICheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(VA_DRIGetDrawableInfo, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_VA_DRIGetDrawableInfo; + req->screen = screen; + req->drawable = drawable; + + if (!_XReply(dpy, (xReply *)&rep, 1, xFalse)) + { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetDrawableInfo... return False"); + return False; + } + *index = rep.drawableTableIndex; + *stamp = rep.drawableTableStamp; + *X = (int)rep.drawableX; + *Y = (int)rep.drawableY; + *W = (int)rep.drawableWidth; + *H = (int)rep.drawableHeight; + *numClipRects = rep.numClipRects; + total_rects = *numClipRects; + + *backX = rep.backX; + *backY = rep.backY; + *numBackClipRects = rep.numBackClipRects; + total_rects += *numBackClipRects; + +#if 0 + /* Because of the fix in Xserver/GL/dri/xf86dri.c, this check breaks + * backwards compatibility (Because of the >> 2 shift) but the fix + * enables multi-threaded apps to work. + */ + if (rep.length != ((((SIZEOF(xVA_DRIGetDrawableInfoReply) - + SIZEOF(xGenericReply) + + total_rects * sizeof(drm_clip_rect_t)) + 3) & ~3) >> 2)) { + _XEatData(dpy, rep.length); + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetDrawableInfo... return False"); + return False; + } +#endif + + if (*numClipRects) { + int len = sizeof(drm_clip_rect_t) * (*numClipRects); + + *pClipRects = (drm_clip_rect_t *)Xcalloc(len, 1); + if (*pClipRects) + _XRead(dpy, (char*)*pClipRects, len); + } else { + *pClipRects = NULL; + } + + if (*numBackClipRects) { + int len = sizeof(drm_clip_rect_t) * (*numBackClipRects); + + *pBackClipRects = (drm_clip_rect_t *)Xcalloc(len, 1); + if (*pBackClipRects) + _XRead(dpy, (char*)*pBackClipRects, len); + } else { + *pBackClipRects = NULL; + } + + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetDrawableInfo... return True"); + return True; +} + +PUBLIC Bool VA_DRIGetDeviceInfo(dpy, screen, hFrameBuffer, + fbOrigin, fbSize, fbStride, devPrivateSize, pDevPrivate) + Display* dpy; + int screen; + drm_handle_t * hFrameBuffer; + int* fbOrigin; + int* fbSize; + int* fbStride; + int* devPrivateSize; + void** pDevPrivate; +{ + XExtDisplayInfo *info = find_display (dpy); + xVA_DRIGetDeviceInfoReply rep; + xVA_DRIGetDeviceInfoReq *req; + + TRACE("GetDeviceInfo..."); + VA_DRICheckExtension (dpy, info, False); + + LockDisplay(dpy); + GetReq(VA_DRIGetDeviceInfo, req); + req->reqType = info->codes->major_opcode; + req->driReqType = X_VA_DRIGetDeviceInfo; + req->screen = screen; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetDeviceInfo... return False"); + return False; + } + + *hFrameBuffer = rep.hFrameBufferLow; + if (sizeof(drm_handle_t) == 8) { + int shift = 32; /* var to prevent warning on next line */ + *hFrameBuffer |= ((drm_handle_t) rep.hFrameBufferHigh) << shift; + } + + *fbOrigin = rep.framebufferOrigin; + *fbSize = rep.framebufferSize; + *fbStride = rep.framebufferStride; + *devPrivateSize = rep.devPrivateSize; + + if (rep.length) { + if (!(*pDevPrivate = (void *)Xcalloc(rep.devPrivateSize, 1))) { + _XEatData(dpy, ((rep.devPrivateSize+3) & ~3)); + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetDeviceInfo... return False"); + return False; + } + _XRead(dpy, (char*)*pDevPrivate, rep.devPrivateSize); + } else { + *pDevPrivate = NULL; + } + + UnlockDisplay(dpy); + SyncHandle(); + TRACE("GetDeviceInfo... return True"); + return True; +} + +PUBLIC Bool VA_DRIOpenFullScreen(dpy, screen, drawable) + Display* dpy; + int screen; + Drawable drawable; +{ + /* This function and the underlying X protocol are deprecated. + */ + (void) dpy; + (void) screen; + (void) drawable; + return False; +} + +PUBLIC Bool VA_DRICloseFullScreen(dpy, screen, drawable) + Display* dpy; + int screen; + Drawable drawable; +{ + /* This function and the underlying X protocol are deprecated. + */ + (void) dpy; + (void) screen; + (void) drawable; + return True; +} + +#undef TRACE + diff --git a/src/x11/va_dri.h b/src/x11/va_dri.h new file mode 100644 index 0000000..91f87a2 --- /dev/null +++ b/src/x11/va_dri.h @@ -0,0 +1,120 @@ +/* $XFree86: xc/lib/GL/dri/xf86dri.h,v 1.8 2002/10/30 12:51:25 alanh Exp $ */ +/************************************************************************** + +Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +Copyright 2000 VA Linux Systems, Inc. +Copyright 2007 Intel Corporation +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sub license, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/** + * \file xf86dri.h + * Protocol numbers and function prototypes for DRI X protocol. + * + * \author Kevin E. Martin <martin@valinux.com> + * \author Jens Owen <jens@tungstengraphics.com> + * \author Rickard E. (Rik) Faith <faith@valinux.com> + */ + +#ifndef _VA_DRI_H_ +#define _VA_DRI_H_ + +#include <X11/Xfuncproto.h> +#include <xf86drm.h> + +#define X_VA_DRIQueryVersion 0 +#define X_VA_DRIQueryDirectRenderingCapable 1 +#define X_VA_DRIOpenConnection 2 +#define X_VA_DRICloseConnection 3 +#define X_VA_DRIGetClientDriverName 4 +#define X_VA_DRICreateContext 5 +#define X_VA_DRIDestroyContext 6 +#define X_VA_DRICreateDrawable 7 +#define X_VA_DRIDestroyDrawable 8 +#define X_VA_DRIGetDrawableInfo 9 +#define X_VA_DRIGetDeviceInfo 10 +#define X_VA_DRIAuthConnection 11 +#define X_VA_DRIOpenFullScreen 12 /* Deprecated */ +#define X_VA_DRICloseFullScreen 13 /* Deprecated */ + +#define VA_DRINumberEvents 0 + +#define VA_DRIClientNotLocal 0 +#define VA_DRIOperationNotSupported 1 +#define VA_DRINumberErrors (VA_DRIOperationNotSupported + 1) + +typedef unsigned long __DRIid; +typedef void __DRInativeDisplay; + +_XFUNCPROTOBEGIN + +Bool VA_DRIQueryExtension( Display *dpy, int *event_base, int *error_base ); + +Bool VA_DRIQueryVersion( Display *dpy, int *majorVersion, int *minorVersion, + int *patchVersion ); + +Bool VA_DRIQueryDirectRenderingCapable( Display *dpy, int screen, + Bool *isCapable ); + +Bool VA_DRIOpenConnection( Display *dpy, int screen, drm_handle_t *hSAREA, + char **busIDString ); + +Bool VA_DRIAuthConnection( Display *dpy, int screen, drm_magic_t magic ); + +Bool VA_DRICloseConnection( Display *dpy, int screen ); + +Bool VA_DRIGetClientDriverName( Display *dpy, int screen, + int *ddxDriverMajorVersion, int *ddxDriverMinorVersion, + int *ddxDriverPatchVersion, char **clientDriverName ); + +Bool VA_DRICreateContext( Display *dpy, int screen, Visual *visual, + XID *ptr_to_returned_context_id, drm_context_t *hHWContext ); + +Bool VA_DRICreateContextWithConfig( Display *dpy, int screen, int configID, + XID *ptr_to_returned_context_id, drm_context_t *hHWContext ); + +Bool VA_DRIDestroyContext( __DRInativeDisplay *dpy, int screen, + __DRIid context_id ); + +Bool VA_DRICreateDrawable( __DRInativeDisplay *dpy, int screen, + __DRIid drawable, drm_drawable_t *hHWDrawable ); + +Bool VA_DRIDestroyDrawable( __DRInativeDisplay *dpy, int screen, + __DRIid drawable); + +Bool VA_DRIGetDrawableInfo( Display *dpy, int screen, Drawable drawable, + unsigned int *index, unsigned int *stamp, + int *X, int *Y, int *W, int *H, + int *numClipRects, drm_clip_rect_t ** pClipRects, + int *backX, int *backY, + int *numBackClipRects, drm_clip_rect_t **pBackClipRects ); + +Bool VA_DRIGetDeviceInfo( Display *dpy, int screen, + drm_handle_t *hFrameBuffer, int *fbOrigin, int *fbSize, + int *fbStride, int *devPrivateSize, void **pDevPrivate ); + +_XFUNCPROTOEND + +#endif /* _VA_DRI_H_ */ + diff --git a/src/x11/va_dri2.c b/src/x11/va_dri2.c new file mode 100644 index 0000000..c602bba --- /dev/null +++ b/src/x11/va_dri2.c @@ -0,0 +1,307 @@ +/* + * Copyright © 2008 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Soft- + * ware"), to deal in the Software without restriction, including without + * limitation the rights to use, copy, modify, merge, publish, distribute, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, provided that the above copyright + * notice(s) and this permission notice appear in all copies of the Soft- + * ware and that both the above copyright notice(s) and this permission + * notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- + * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY + * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN + * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE- + * QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR- + * MANCE OF THIS SOFTWARE. + * + * Except as contained in this notice, the name of a copyright holder shall + * not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization of + * the copyright holder. + * + * Authors: + * Kristian Høgsberg (krh@redhat.com) + */ + + +#define NEED_REPLIES +#include <X11/Xlibint.h> +#include <X11/extensions/Xext.h> +#include <X11/extensions/extutil.h> +#include "xf86drm.h" +#include "va_dri2.h" +#include "va_dri2str.h" +#include "va_dri2tokens.h" + +#ifndef DRI2DriverDRI +#define DRI2DriverDRI 0 +#endif + +static char va_dri2ExtensionName[] = DRI2_NAME; +static XExtensionInfo _va_dri2_info_data; +static XExtensionInfo *va_dri2Info = &_va_dri2_info_data; +static XEXT_GENERATE_CLOSE_DISPLAY (VA_DRI2CloseDisplay, va_dri2Info) +static /* const */ XExtensionHooks va_dri2ExtensionHooks = { + NULL, /* create_gc */ + NULL, /* copy_gc */ + NULL, /* flush_gc */ + NULL, /* free_gc */ + NULL, /* create_font */ + NULL, /* free_font */ + VA_DRI2CloseDisplay, /* close_display */ + NULL, /* wire_to_event */ + NULL, /* event_to_wire */ + NULL, /* error */ + NULL, /* error_string */ +}; + +static XEXT_GENERATE_FIND_DISPLAY (DRI2FindDisplay, va_dri2Info, + va_dri2ExtensionName, + &va_dri2ExtensionHooks, + 0, NULL) + +Bool VA_DRI2QueryExtension(Display *dpy, int *eventBase, int *errorBase) +{ + XExtDisplayInfo *info = DRI2FindDisplay(dpy); + + if (XextHasExtension(info)) { + *eventBase = info->codes->first_event; + *errorBase = info->codes->first_error; + return True; + } + + return False; +} + +Bool VA_DRI2QueryVersion(Display *dpy, int *major, int *minor) +{ + XExtDisplayInfo *info = DRI2FindDisplay (dpy); + xDRI2QueryVersionReply rep; + xDRI2QueryVersionReq *req; + + XextCheckExtension (dpy, info, va_dri2ExtensionName, False); + + LockDisplay(dpy); + GetReq(DRI2QueryVersion, req); + req->reqType = info->codes->major_opcode; + req->dri2ReqType = X_DRI2QueryVersion; + req->majorVersion = DRI2_MAJOR; + req->minorVersion = DRI2_MINOR; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + *major = rep.majorVersion; + *minor = rep.minorVersion; + UnlockDisplay(dpy); + SyncHandle(); + + return True; +} + +Bool VA_DRI2Connect(Display *dpy, XID window, + char **driverName, char **deviceName) +{ + XExtDisplayInfo *info = DRI2FindDisplay(dpy); + xDRI2ConnectReply rep; + xDRI2ConnectReq *req; + + XextCheckExtension (dpy, info, va_dri2ExtensionName, False); + + LockDisplay(dpy); + GetReq(DRI2Connect, req); + req->reqType = info->codes->major_opcode; + req->dri2ReqType = X_DRI2Connect; + req->window = window; + req->driverType = DRI2DriverDRI; + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + + if (rep.driverNameLength == 0 && rep.deviceNameLength == 0) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + + *driverName = Xmalloc(rep.driverNameLength + 1); + if (*driverName == NULL) { + _XEatData(dpy, + ((rep.driverNameLength + 3) & ~3) + + ((rep.deviceNameLength + 3) & ~3)); + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + _XReadPad(dpy, *driverName, rep.driverNameLength); + (*driverName)[rep.driverNameLength] = '\0'; + + *deviceName = Xmalloc(rep.deviceNameLength + 1); + if (*deviceName == NULL) { + Xfree(*driverName); + _XEatData(dpy, ((rep.deviceNameLength + 3) & ~3)); + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + _XReadPad(dpy, *deviceName, rep.deviceNameLength); + (*deviceName)[rep.deviceNameLength] = '\0'; + + UnlockDisplay(dpy); + SyncHandle(); + + return True; +} + +Bool VA_DRI2Authenticate(Display *dpy, XID window, drm_magic_t magic) +{ + XExtDisplayInfo *info = DRI2FindDisplay(dpy); + xDRI2AuthenticateReq *req; + xDRI2AuthenticateReply rep; + + XextCheckExtension (dpy, info, va_dri2ExtensionName, False); + + LockDisplay(dpy); + GetReq(DRI2Authenticate, req); + req->reqType = info->codes->major_opcode; + req->dri2ReqType = X_DRI2Authenticate; + req->window = window; + req->magic = magic; + + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return False; + } + + UnlockDisplay(dpy); + SyncHandle(); + + return rep.authenticated; +} + +void VA_DRI2CreateDrawable(Display *dpy, XID drawable) +{ + XExtDisplayInfo *info = DRI2FindDisplay(dpy); + xDRI2CreateDrawableReq *req; + + XextSimpleCheckExtension (dpy, info, va_dri2ExtensionName); + + LockDisplay(dpy); + GetReq(DRI2CreateDrawable, req); + req->reqType = info->codes->major_opcode; + req->dri2ReqType = X_DRI2CreateDrawable; + req->drawable = drawable; + UnlockDisplay(dpy); + SyncHandle(); +} + +void VA_DRI2DestroyDrawable(Display *dpy, XID drawable) +{ + XExtDisplayInfo *info = DRI2FindDisplay(dpy); + xDRI2DestroyDrawableReq *req; + + XextSimpleCheckExtension (dpy, info, va_dri2ExtensionName); + + XSync(dpy, False); + + LockDisplay(dpy); + GetReq(DRI2DestroyDrawable, req); + req->reqType = info->codes->major_opcode; + req->dri2ReqType = X_DRI2DestroyDrawable; + req->drawable = drawable; + UnlockDisplay(dpy); + SyncHandle(); +} + +VA_DRI2Buffer *VA_DRI2GetBuffers(Display *dpy, XID drawable, + int *width, int *height, + unsigned int *attachments, int count, + int *outCount) +{ + XExtDisplayInfo *info = DRI2FindDisplay(dpy); + xDRI2GetBuffersReply rep; + xDRI2GetBuffersReq *req; + VA_DRI2Buffer *buffers; + xDRI2Buffer repBuffer; + CARD32 *p; + int i; + + XextCheckExtension (dpy, info, va_dri2ExtensionName, False); + + LockDisplay(dpy); + GetReqExtra(DRI2GetBuffers, count * 4, req); + req->reqType = info->codes->major_opcode; + req->dri2ReqType = X_DRI2GetBuffers; + req->drawable = drawable; + req->count = count; + p = (CARD32 *) &req[1]; + for (i = 0; i < count; i++) + p[i] = attachments[i]; + + if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) { + UnlockDisplay(dpy); + SyncHandle(); + return NULL; + } + + *width = rep.width; + *height = rep.height; + *outCount = rep.count; + + buffers = Xmalloc(rep.count * sizeof buffers[0]); + if (buffers == NULL) { + _XEatData(dpy, rep.count * sizeof repBuffer); + UnlockDisplay(dpy); + SyncHandle(); + return NULL; + } + + for (i = 0; i < rep.count; i++) { + _XReadPad(dpy, (char *) &repBuffer, sizeof repBuffer); + buffers[i].attachment = repBuffer.attachment; + buffers[i].name = repBuffer.name; + buffers[i].pitch = repBuffer.pitch; + buffers[i].cpp = repBuffer.cpp; + buffers[i].flags = repBuffer.flags; + } + + UnlockDisplay(dpy); + SyncHandle(); + + return buffers; +} + +void VA_DRI2CopyRegion(Display *dpy, XID drawable, XserverRegion region, + CARD32 dest, CARD32 src) +{ + XExtDisplayInfo *info = DRI2FindDisplay(dpy); + xDRI2CopyRegionReq *req; + xDRI2CopyRegionReply rep; + + XextSimpleCheckExtension (dpy, info, va_dri2ExtensionName); + + LockDisplay(dpy); + GetReq(DRI2CopyRegion, req); + req->reqType = info->codes->major_opcode; + req->dri2ReqType = X_DRI2CopyRegion; + req->drawable = drawable; + req->region = region; + req->dest = dest; + req->src = src; + + _XReply(dpy, (xReply *)&rep, 0, xFalse); + + UnlockDisplay(dpy); + SyncHandle(); +} diff --git a/src/x11/va_dri2.h b/src/x11/va_dri2.h new file mode 100644 index 0000000..a26a839 --- /dev/null +++ b/src/x11/va_dri2.h @@ -0,0 +1,71 @@ +/* + * Copyright © 2007,2008 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Soft- + * ware"), to deal in the Software without restriction, including without + * limitation the rights to use, copy, modify, merge, publish, distribute, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, provided that the above copyright + * notice(s) and this permission notice appear in all copies of the Soft- + * ware and that both the above copyright notice(s) and this permission + * notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- + * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY + * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN + * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE- + * QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR- + * MANCE OF THIS SOFTWARE. + * + * Except as contained in this notice, the name of a copyright holder shall + * not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization of + * the copyright holder. + * + * Authors: + * Kristian Høgsberg (krh@redhat.com) + */ + +#ifndef _VA_DRI2_H_ +#define _VA_DRI2_H_ + +#include <X11/extensions/Xfixes.h> +#include <X11/Xfuncproto.h> +#include <xf86drm.h> + +typedef struct { + unsigned int attachment; + unsigned int name; + unsigned int pitch; + unsigned int cpp; + unsigned int flags; +} VA_DRI2Buffer; + +extern Bool +VA_DRI2QueryExtension(Display *display, int *eventBase, int *errorBase); +extern Bool +VA_DRI2QueryVersion(Display *display, int *major, int *minor); +extern Bool +VA_DRI2Connect(Display *display, XID window, + char **driverName, char **deviceName); +extern Bool +VA_DRI2Authenticate(Display *display, XID window, drm_magic_t magic); +extern void +VA_DRI2CreateDrawable(Display *display, XID drawable); +extern void +VA_DRI2DestroyDrawable(Display *display, XID handle); +extern VA_DRI2Buffer * +VA_DRI2GetBuffers(Display *dpy, XID drawable, + int *width, int *height, + unsigned int *attachments, int count, + int *outCount); +#if 0 +extern void +VA_DRI2CopyRegion(Display *dpy, XID drawable, XserverRegion region, + CARD32 dest, CARD32 src); +#endif +#endif diff --git a/src/x11/va_dri2str.h b/src/x11/va_dri2str.h new file mode 100644 index 0000000..dc3f2d1 --- /dev/null +++ b/src/x11/va_dri2str.h @@ -0,0 +1,193 @@ +/* + * Copyright © 2008 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Soft- + * ware"), to deal in the Software without restriction, including without + * limitation the rights to use, copy, modify, merge, publish, distribute, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, provided that the above copyright + * notice(s) and this permission notice appear in all copies of the Soft- + * ware and that both the above copyright notice(s) and this permission + * notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- + * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY + * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN + * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE- + * QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR- + * MANCE OF THIS SOFTWARE. + * + * Except as contained in this notice, the name of a copyright holder shall + * not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization of + * the copyright holder. + * + * Authors: + * Kristian Høgsberg (krh@redhat.com) + */ + +#ifndef _DRI2_PROTO_H_ +#define _DRI2_PROTO_H_ + +#define DRI2_NAME "DRI2" +#define DRI2_MAJOR 1 +#define DRI2_MINOR 0 + +#define DRI2NumberErrors 0 +#define DRI2NumberEvents 0 +#define DRI2NumberRequests 7 + +#define X_DRI2QueryVersion 0 +#define X_DRI2Connect 1 +#define X_DRI2Authenticate 2 +#define X_DRI2CreateDrawable 3 +#define X_DRI2DestroyDrawable 4 +#define X_DRI2GetBuffers 5 +#define X_DRI2CopyRegion 6 + +typedef struct { + CARD32 attachment B32; + CARD32 name B32; + CARD32 pitch B32; + CARD32 cpp B32; + CARD32 flags B32; +} xDRI2Buffer; + +typedef struct { + CARD8 reqType; + CARD8 dri2ReqType; + CARD16 length B16; + CARD32 majorVersion B32; + CARD32 minorVersion B32; +} xDRI2QueryVersionReq; +#define sz_xDRI2QueryVersionReq 12 + +typedef struct { + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 majorVersion B32; + CARD32 minorVersion B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; +} xDRI2QueryVersionReply; +#define sz_xDRI2QueryVersionReply 32 + +typedef struct { + CARD8 reqType; + CARD8 dri2ReqType; + CARD16 length B16; + CARD32 window B32; + CARD32 driverType B32; +} xDRI2ConnectReq; +#define sz_xDRI2ConnectReq 12 + +typedef struct { + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 driverNameLength B32; + CARD32 deviceNameLength B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; +} xDRI2ConnectReply; +#define sz_xDRI2ConnectReply 32 + +typedef struct { + CARD8 reqType; + CARD8 dri2ReqType; + CARD16 length B16; + CARD32 window B32; + CARD32 magic B32; +} xDRI2AuthenticateReq; +#define sz_xDRI2AuthenticateReq 12 + +typedef struct { + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 authenticated B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xDRI2AuthenticateReply; +#define sz_xDRI2AuthenticateReply 32 + +typedef struct { + CARD8 reqType; + CARD8 dri2ReqType; + CARD16 length B16; + CARD32 drawable B32; +} xDRI2CreateDrawableReq; +#define sz_xDRI2CreateDrawableReq 8 + +typedef struct { + CARD8 reqType; + CARD8 dri2ReqType; + CARD16 length B16; + CARD32 drawable B32; +} xDRI2DestroyDrawableReq; +#define sz_xDRI2DestroyDrawableReq 8 + +typedef struct { + CARD8 reqType; + CARD8 dri2ReqType; + CARD16 length B16; + CARD32 drawable B32; + CARD32 count B32; +} xDRI2GetBuffersReq; +#define sz_xDRI2GetBuffersReq 12 + +typedef struct { + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 width B32; + CARD32 height B32; + CARD32 count B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; +} xDRI2GetBuffersReply; +#define sz_xDRI2GetBuffersReply 32 + +typedef struct { + CARD8 reqType; + CARD8 dri2ReqType; + CARD16 length B16; + CARD32 drawable B32; + CARD32 region B32; + CARD32 dest B32; + CARD32 src B32; +} xDRI2CopyRegionReq; +#define sz_xDRI2CopyRegionReq 20 + +typedef struct { + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; +} xDRI2CopyRegionReply; +#define sz_xDRI2CopyRegionReply 32 + +#endif diff --git a/src/x11/va_dri2tokens.h b/src/x11/va_dri2tokens.h new file mode 100644 index 0000000..087159f --- /dev/null +++ b/src/x11/va_dri2tokens.h @@ -0,0 +1,48 @@ +/* + * Copyright © 2008 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Soft- + * ware"), to deal in the Software without restriction, including without + * limitation the rights to use, copy, modify, merge, publish, distribute, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, provided that the above copyright + * notice(s) and this permission notice appear in all copies of the Soft- + * ware and that both the above copyright notice(s) and this permission + * notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- + * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY + * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN + * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE- + * QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR- + * MANCE OF THIS SOFTWARE. + * + * Except as contained in this notice, the name of a copyright holder shall + * not be used in advertising or otherwise to promote the sale, use or + * other dealings in this Software without prior written authorization of + * the copyright holder. + * + * Authors: + * Kristian Høgsberg (krh@redhat.com) + */ + +#ifndef _DRI2_TOKENS_H_ +#define _DRI2_TOKENS_H_ + +#define DRI2BufferFrontLeft 0 +#define DRI2BufferBackLeft 1 +#define DRI2BufferFrontRight 2 +#define DRI2BufferBackRight 3 +#define DRI2BufferDepth 4 +#define DRI2BufferStencil 5 +#define DRI2BufferAccum 6 +#define DRI2BufferFakeFrontLeft 7 +#define DRI2BufferFakeFrontRight 8 + +#define DRI2DriverDRI 0 + +#endif diff --git a/src/x11/va_dricommon.c b/src/x11/va_dricommon.c new file mode 100644 index 0000000..f9c3dfd --- /dev/null +++ b/src/x11/va_dricommon.c @@ -0,0 +1,62 @@ +#include "va_dricommon.h" + +static struct dri_drawable * +do_drawable_hash(VADriverContextP ctx, XID drawable) +{ + struct dri_state *dri_state = (struct dri_state *)ctx->dri_state; + int index = drawable % DRAWABLE_HASH_SZ; + struct dri_drawable *dri_drawable = dri_state->drawable_hash[index]; + + while (dri_drawable) { + if (dri_drawable->x_drawable == drawable) + return dri_drawable; + dri_drawable = dri_drawable->next; + } + + dri_drawable = dri_state->createDrawable(ctx, drawable); + dri_drawable->x_drawable = drawable; + dri_drawable->next = dri_state->drawable_hash[index]; + dri_state->drawable_hash[index] = dri_drawable; + + return dri_drawable; +} + +void +free_drawable_hashtable(VADriverContextP ctx) +{ + struct dri_state *dri_state = (struct dri_state *)ctx->dri_state; + int i; + struct dri_drawable *dri_drawable, *prev; + + for (i = 0; i < DRAWABLE_HASH_SZ; i++) { + dri_drawable = dri_state->drawable_hash[i]; + + while (dri_drawable) { + prev = dri_drawable; + dri_drawable = prev->next; + dri_state->destroyDrawable(ctx, prev); + } + } +} + +struct dri_drawable * +dri_get_drawable(VADriverContextP ctx, XID drawable) +{ + return do_drawable_hash(ctx, drawable); +} + +void +dri_swap_buffer(VADriverContextP ctx, struct dri_drawable *dri_drawable) +{ + struct dri_state *dri_state = (struct dri_state *)ctx->dri_state; + + dri_state->swapBuffer(ctx, dri_drawable); +} + +union dri_buffer * +dri_get_rendering_buffer(VADriverContextP ctx, struct dri_drawable *dri_drawable) +{ + struct dri_state *dri_state = (struct dri_state *)ctx->dri_state; + + return dri_state->getRenderingBuffer(ctx, dri_drawable); +} diff --git a/src/x11/va_dricommon.h b/src/x11/va_dricommon.h new file mode 100644 index 0000000..a2a51a6 --- /dev/null +++ b/src/x11/va_dricommon.h @@ -0,0 +1,68 @@ +#ifndef _VA_DRICOMMON_H_ +#define _VA_DRICOMMON_H_ + +#include <X11/Xlib.h> + +#include <xf86drm.h> +#include <drm.h> +#include <drm_sarea.h> + +#include "va_backend.h" + +enum +{ + VA_NONE = 0, + VA_DRI1 = 1, + VA_DRI2 = 2 +}; + +union dri_buffer +{ + struct { + unsigned int attachment; + unsigned int name; + unsigned int pitch; + unsigned int cpp; + unsigned int flags; + } dri2; + + struct { + } dri1; +}; + +struct dri_drawable +{ + XID x_drawable; + int x; + int y; + unsigned int width; + unsigned int height; + struct dri_drawable *next; +}; + +#define DRAWABLE_HASH_SZ 32 +struct dri_state +{ + int fd; + int driConnectedFlag; /* 0: disconnected, 1: DRI, 2: DRI2 */ + drm_handle_t hSAREA; + drm_context_t hwContext; + drmAddress pSAREA; + XID hwContextID; + struct dri_drawable *drawable_hash[DRAWABLE_HASH_SZ]; + + struct dri_drawable *(*createDrawable)(VADriverContextP ctx, XID x_drawable); + void (*destroyDrawable)(VADriverContextP ctx, struct dri_drawable *dri_drawable); + void (*swapBuffer)(VADriverContextP ctx, struct dri_drawable *dri_drawable); + union dri_buffer *(*getRenderingBuffer)(VADriverContextP ctx, struct dri_drawable *dri_drawable); + void (*close)(VADriverContextP ctx); +}; + +Bool isDRI2Connected(VADriverContextP ctx, char **driver_name); +Bool isDRI1Connected(VADriverContextP ctx, char **driver_name); +void free_drawable_hashtable(VADriverContextP ctx); +struct dri_drawable *dri_get_drawable(VADriverContextP ctx, XID drawable); +void dri_swap_buffer(VADriverContextP ctx, struct dri_drawable *dri_drawable); +union dri_buffer *dri_get_rendering_buffer(VADriverContextP ctx, struct dri_drawable *dri_drawable); + +#endif /* _VA_DRICOMMON_H_ */ diff --git a/src/x11/va_dristr.h b/src/x11/va_dristr.h new file mode 100644 index 0000000..3e391de --- /dev/null +++ b/src/x11/va_dristr.h @@ -0,0 +1,344 @@ +/* $XFree86: xc/lib/GL/dri/xf86dristr.h,v 1.10 2002/10/30 12:51:25 alanh Exp $ */ +/************************************************************************** + +Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. +Copyright 2000 VA Linux Systems, Inc. +Copyright 2007 Intel Corporation +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sub license, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice (including the +next paragraph) shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. +IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR +ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Jens Owen <jens@tungstengraphics.com> + * Rickard E. (Rik) Fiath <faith@valinux.com> + * + */ + +#ifndef _VA_DRISTR_H_ +#define _VA_DRISTR_H_ + +#include "va_dri.h" + +#define VA_DRINAME "XFree86-DRI" + +/* The DRI version number. This was originally set to be the same of the + * XFree86 version number. However, this version is really indepedent of + * the XFree86 version. + * + * Version History: + * 4.0.0: Original + * 4.0.1: Patch to bump clipstamp when windows are destroyed, 28 May 02 + * 4.1.0: Add transition from single to multi in DRMInfo rec, 24 Jun 02 + */ +#define VA_DRI_MAJOR_VERSION 4 +#define VA_DRI_MINOR_VERSION 1 +#define VA_DRI_PATCH_VERSION 0 + +typedef struct _VA_DRIQueryVersion { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIQueryVersion */ + CARD16 length B16; +} xVA_DRIQueryVersionReq; +#define sz_xVA_DRIQueryVersionReq 4 + +typedef struct { + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD16 majorVersion B16; /* major version of DRI protocol */ + CARD16 minorVersion B16; /* minor version of DRI protocol */ + CARD32 patchVersion B32; /* patch version of DRI protocol */ + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xVA_DRIQueryVersionReply; +#define sz_xVA_DRIQueryVersionReply 32 + +typedef struct _VA_DRIQueryDirectRenderingCapable { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* X_DRIQueryDirectRenderingCapable */ + CARD16 length B16; + CARD32 screen B32; +} xVA_DRIQueryDirectRenderingCapableReq; +#define sz_xVA_DRIQueryDirectRenderingCapableReq 8 + +typedef struct { + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + BOOL isCapable; + BOOL pad2; + BOOL pad3; + BOOL pad4; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; + CARD32 pad8 B32; + CARD32 pad9 B32; +} xVA_DRIQueryDirectRenderingCapableReply; +#define sz_xVA_DRIQueryDirectRenderingCapableReply 32 + +typedef struct _VA_DRIOpenConnection { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIOpenConnection */ + CARD16 length B16; + CARD32 screen B32; +} xVA_DRIOpenConnectionReq; +#define sz_xVA_DRIOpenConnectionReq 8 + +typedef struct { + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 hSAREALow B32; + CARD32 hSAREAHigh B32; + CARD32 busIdStringLength B32; + CARD32 pad6 B32; + CARD32 pad7 B32; + CARD32 pad8 B32; +} xVA_DRIOpenConnectionReply; +#define sz_xVA_DRIOpenConnectionReply 32 + +typedef struct _VA_DRIAuthConnection { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRICloseConnection */ + CARD16 length B16; + CARD32 screen B32; + CARD32 magic B32; +} xVA_DRIAuthConnectionReq; +#define sz_xVA_DRIAuthConnectionReq 12 + +typedef struct { + BYTE type; + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 authenticated B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xVA_DRIAuthConnectionReply; +#define zx_xVA_DRIAuthConnectionReply 32 + +typedef struct _VA_DRICloseConnection { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRICloseConnection */ + CARD16 length B16; + CARD32 screen B32; +} xVA_DRICloseConnectionReq; +#define sz_xVA_DRICloseConnectionReq 8 + +typedef struct _VA_DRIGetClientDriverName { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIGetClientDriverName */ + CARD16 length B16; + CARD32 screen B32; +} xVA_DRIGetClientDriverNameReq; +#define sz_xVA_DRIGetClientDriverNameReq 8 + +typedef struct { + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 ddxDriverMajorVersion B32; + CARD32 ddxDriverMinorVersion B32; + CARD32 ddxDriverPatchVersion B32; + CARD32 clientDriverNameLength B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xVA_DRIGetClientDriverNameReply; +#define sz_xVA_DRIGetClientDriverNameReply 32 + +typedef struct _VA_DRICreateContext { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRICreateContext */ + CARD16 length B16; + CARD32 screen B32; + CARD32 visual B32; + CARD32 context B32; +} xVA_DRICreateContextReq; +#define sz_xVA_DRICreateContextReq 16 + +typedef struct { + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 hHWContext B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xVA_DRICreateContextReply; +#define sz_xVA_DRICreateContextReply 32 + +typedef struct _VA_DRIDestroyContext { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIDestroyContext */ + CARD16 length B16; + CARD32 screen B32; + CARD32 context B32; +} xVA_DRIDestroyContextReq; +#define sz_xVA_DRIDestroyContextReq 12 + +typedef struct _VA_DRICreateDrawable { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRICreateDrawable */ + CARD16 length B16; + CARD32 screen B32; + CARD32 drawable B32; +} xVA_DRICreateDrawableReq; +#define sz_xVA_DRICreateDrawableReq 12 + +typedef struct { + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 hHWDrawable B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xVA_DRICreateDrawableReply; +#define sz_xVA_DRICreateDrawableReply 32 + +typedef struct _VA_DRIDestroyDrawable { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIDestroyDrawable */ + CARD16 length B16; + CARD32 screen B32; + CARD32 drawable B32; +} xVA_DRIDestroyDrawableReq; +#define sz_xVA_DRIDestroyDrawableReq 12 + +typedef struct _VA_DRIGetDrawableInfo { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIGetDrawableInfo */ + CARD16 length B16; + CARD32 screen B32; + CARD32 drawable B32; +} xVA_DRIGetDrawableInfoReq; +#define sz_xVA_DRIGetDrawableInfoReq 12 + +typedef struct { + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 drawableTableIndex B32; + CARD32 drawableTableStamp B32; + INT16 drawableX B16; + INT16 drawableY B16; + INT16 drawableWidth B16; + INT16 drawableHeight B16; + CARD32 numClipRects B32; + INT16 backX B16; + INT16 backY B16; + CARD32 numBackClipRects B32; +} xVA_DRIGetDrawableInfoReply; + +#define sz_xVA_DRIGetDrawableInfoReply 36 + + +typedef struct _VA_DRIGetDeviceInfo { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIGetDeviceInfo */ + CARD16 length B16; + CARD32 screen B32; +} xVA_DRIGetDeviceInfoReq; +#define sz_xVA_DRIGetDeviceInfoReq 8 + +typedef struct { + BYTE type; /* X_Reply */ + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 hFrameBufferLow B32; + CARD32 hFrameBufferHigh B32; + CARD32 framebufferOrigin B32; + CARD32 framebufferSize B32; + CARD32 framebufferStride B32; + CARD32 devPrivateSize B32; +} xVA_DRIGetDeviceInfoReply; +#define sz_xVA_DRIGetDeviceInfoReply 32 + +typedef struct _VA_DRIOpenFullScreen { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRIOpenFullScreen */ + CARD16 length B16; + CARD32 screen B32; + CARD32 drawable B32; +} xVA_DRIOpenFullScreenReq; +#define sz_xVA_DRIOpenFullScreenReq 12 + +typedef struct { + BYTE type; + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 isFullScreen B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xVA_DRIOpenFullScreenReply; +#define sz_xVA_DRIOpenFullScreenReply 32 + +typedef struct _VA_DRICloseFullScreen { + CARD8 reqType; /* always DRIReqCode */ + CARD8 driReqType; /* always X_DRICloseFullScreen */ + CARD16 length B16; + CARD32 screen B32; + CARD32 drawable B32; +} xVA_DRICloseFullScreenReq; +#define sz_xVA_DRICloseFullScreenReq 12 + +typedef struct { + BYTE type; + BOOL pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; +} xVA_DRICloseFullScreenReply; +#define sz_xVA_DRICloseFullScreenReply 32 + + +#endif /* _VA_DRISTR_H_ */ diff --git a/src/x11/va_nvctrl.c b/src/x11/va_nvctrl.c new file mode 100644 index 0000000..46fcca5 --- /dev/null +++ b/src/x11/va_nvctrl.c @@ -0,0 +1,392 @@ +/* + * Copyright (c) 2008 NVIDIA, Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#define _GNU_SOURCE 1 +#include <string.h> + +#define NEED_REPLIES +#include <stdlib.h> +#include <X11/Xlibint.h> +#include <X11/Xutil.h> +#include <X11/extensions/Xext.h> +#include <X11/extensions/extutil.h> +#include "va_nvctrl.h" + +#define NV_CONTROL_ERRORS 0 +#define NV_CONTROL_EVENTS 5 +#define NV_CONTROL_NAME "NV-CONTROL" + +#define NV_CTRL_TARGET_TYPE_X_SCREEN 0 +#define NV_CTRL_TARGET_TYPE_GPU 1 +#define NV_CTRL_TARGET_TYPE_FRAMELOCK 2 +#define NV_CTRL_TARGET_TYPE_VCSC 3 /* Visual Computing System */ + +#define NV_CTRL_STRING_NVIDIA_DRIVER_VERSION 3 /* R--G */ + +#define X_nvCtrlQueryExtension 0 +#define X_nvCtrlIsNv 1 +#define X_nvCtrlQueryStringAttribute 4 + +typedef struct { + CARD8 reqType; + CARD8 nvReqType; + CARD16 length B16; +} xnvCtrlQueryExtensionReq; +#define sz_xnvCtrlQueryExtensionReq 4 + +typedef struct { + BYTE type; /* X_Reply */ + CARD8 padb1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD16 major B16; + CARD16 minor B16; + CARD32 padl4 B32; + CARD32 padl5 B32; + CARD32 padl6 B32; + CARD32 padl7 B32; + CARD32 padl8 B32; +} xnvCtrlQueryExtensionReply; +#define sz_xnvCtrlQueryExtensionReply 32 + +typedef struct { + CARD8 reqType; + CARD8 nvReqType; + CARD16 length B16; + CARD32 screen B32; +} xnvCtrlIsNvReq; +#define sz_xnvCtrlIsNvReq 8 + +typedef struct { + BYTE type; /* X_Reply */ + CARD8 padb1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 isnv B32; + CARD32 padl4 B32; + CARD32 padl5 B32; + CARD32 padl6 B32; + CARD32 padl7 B32; + CARD32 padl8 B32; +} xnvCtrlIsNvReply; +#define sz_xnvCtrlIsNvReply 32 + +typedef struct { + CARD8 reqType; + CARD8 nvReqType; + CARD16 length B16; + CARD16 target_id B16; /* X screen number or GPU number */ + CARD16 target_type B16; /* X screen or GPU */ + CARD32 display_mask B32; + CARD32 attribute B32; +} xnvCtrlQueryStringAttributeReq; +#define sz_xnvCtrlQueryStringAttributeReq 16 + +typedef struct { + BYTE type; + BYTE pad0; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 flags B32; + CARD32 n B32; /* Length of string */ + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; +} xnvCtrlQueryStringAttributeReply; +#define sz_xnvCtrlQueryStringAttributeReply 32 + +#define NVCTRL_EXT_NEED_CHECK (XPointer)(~0) +#define NVCTRL_EXT_NEED_NOTHING (XPointer)(0) +#define NVCTRL_EXT_NEED_TARGET_SWAP (XPointer)(1) + +static XExtensionInfo _nvctrl_ext_info_data; +static XExtensionInfo *nvctrl_ext_info = &_nvctrl_ext_info_data; +static /* const */ char *nvctrl_extension_name = NV_CONTROL_NAME; + +#define XNVCTRLCheckExtension(dpy,i,val) \ + XextCheckExtension (dpy, i, nvctrl_extension_name, val) +#define XNVCTRLSimpleCheckExtension(dpy,i) \ + XextSimpleCheckExtension (dpy, i, nvctrl_extension_name) + +static int close_display(); +static /* const */ XExtensionHooks nvctrl_extension_hooks = { + NULL, /* create_gc */ + NULL, /* copy_gc */ + NULL, /* flush_gc */ + NULL, /* free_gc */ + NULL, /* create_font */ + NULL, /* free_font */ + close_display, /* close_display */ + NULL, /* wire_to_event */ + NULL, /* event_to_wire */ + NULL, /* error */ + NULL, /* error_string */ +}; + +static XEXT_GENERATE_FIND_DISPLAY (find_display, nvctrl_ext_info, + nvctrl_extension_name, + &nvctrl_extension_hooks, + NV_CONTROL_EVENTS, NVCTRL_EXT_NEED_CHECK) + +static XEXT_GENERATE_CLOSE_DISPLAY (close_display, nvctrl_ext_info) + +static Bool XNVCTRLQueryVersion (Display *dpy, int *major, int *minor); + +/* + * NV-CONTROL versions 1.8 and 1.9 pack the target_type and target_id + * fields in reversed order. In order to talk to one of these servers, + * we need to swap these fields. + */ +static void XNVCTRLCheckTargetData(Display *dpy, XExtDisplayInfo *info, + int *target_type, int *target_id) +{ + /* Find out what the server's NV-CONTROL version is and + * setup for swapping if we need to. + */ + if (info->data == NVCTRL_EXT_NEED_CHECK) { + int major, minor; + + if (XNVCTRLQueryVersion(dpy, &major, &minor)) { + if (major == 1 && + (minor == 8 || minor == 9)) { + info->data = NVCTRL_EXT_NEED_TARGET_SWAP; + } else { + info->data = NVCTRL_EXT_NEED_NOTHING; + } + } else { + info->data = NVCTRL_EXT_NEED_NOTHING; + } + } + + /* We need to swap the target_type and target_id */ + if (info->data == NVCTRL_EXT_NEED_TARGET_SWAP) { + int tmp; + tmp = *target_type; + *target_type = *target_id; + *target_id = tmp; + } +} + + +static Bool XNVCTRLQueryExtension ( + Display *dpy, + int *event_basep, + int *error_basep +){ + XExtDisplayInfo *info = find_display (dpy); + + if (XextHasExtension(info)) { + if (event_basep) *event_basep = info->codes->first_event; + if (error_basep) *error_basep = info->codes->first_error; + return True; + } else { + return False; + } +} + + +static Bool XNVCTRLQueryVersion ( + Display *dpy, + int *major, + int *minor +){ + XExtDisplayInfo *info = find_display (dpy); + xnvCtrlQueryExtensionReply rep; + xnvCtrlQueryExtensionReq *req; + + if(!XextHasExtension(info)) + return False; + + XNVCTRLCheckExtension (dpy, info, False); + + LockDisplay (dpy); + GetReq (nvCtrlQueryExtension, req); + req->reqType = info->codes->major_opcode; + req->nvReqType = X_nvCtrlQueryExtension; + if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { + UnlockDisplay (dpy); + SyncHandle (); + return False; + } + if (major) *major = rep.major; + if (minor) *minor = rep.minor; + UnlockDisplay (dpy); + SyncHandle (); + return True; +} + + +static Bool XNVCTRLIsNvScreen ( + Display *dpy, + int screen +){ + XExtDisplayInfo *info = find_display (dpy); + xnvCtrlIsNvReply rep; + xnvCtrlIsNvReq *req; + Bool isnv; + + if(!XextHasExtension(info)) + return False; + + XNVCTRLCheckExtension (dpy, info, False); + + LockDisplay (dpy); + GetReq (nvCtrlIsNv, req); + req->reqType = info->codes->major_opcode; + req->nvReqType = X_nvCtrlIsNv; + req->screen = screen; + if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) { + UnlockDisplay (dpy); + SyncHandle (); + return False; + } + isnv = rep.isnv; + UnlockDisplay (dpy); + SyncHandle (); + return isnv; +} + + +static Bool XNVCTRLQueryTargetStringAttribute ( + Display *dpy, + int target_type, + int target_id, + unsigned int display_mask, + unsigned int attribute, + char **ptr +){ + XExtDisplayInfo *info = find_display (dpy); + xnvCtrlQueryStringAttributeReply rep; + xnvCtrlQueryStringAttributeReq *req; + Bool exists; + int length, numbytes, slop; + + if (!ptr) return False; + + if(!XextHasExtension(info)) + return False; + + XNVCTRLCheckExtension (dpy, info, False); + XNVCTRLCheckTargetData(dpy, info, &target_type, &target_id); + + LockDisplay (dpy); + GetReq (nvCtrlQueryStringAttribute, req); + req->reqType = info->codes->major_opcode; + req->nvReqType = X_nvCtrlQueryStringAttribute; + req->target_type = target_type; + req->target_id = target_id; + req->display_mask = display_mask; + req->attribute = attribute; + if (!_XReply (dpy, (xReply *) &rep, 0, False)) { + UnlockDisplay (dpy); + SyncHandle (); + return False; + } + length = rep.length; + numbytes = rep.n; + slop = numbytes & 3; + *ptr = (char *) Xmalloc(numbytes); + if (! *ptr) { + _XEatData(dpy, length); + UnlockDisplay (dpy); + SyncHandle (); + return False; + } else { + _XRead(dpy, (char *) *ptr, numbytes); + if (slop) _XEatData(dpy, 4-slop); + } + exists = rep.flags; + UnlockDisplay (dpy); + SyncHandle (); + return exists; +} + +static Bool XNVCTRLQueryStringAttribute ( + Display *dpy, + int screen, + unsigned int display_mask, + unsigned int attribute, + char **ptr +){ + return XNVCTRLQueryTargetStringAttribute(dpy, NV_CTRL_TARGET_TYPE_X_SCREEN, + screen, display_mask, + attribute, ptr); +} + + +Bool VA_NVCTRLQueryDirectRenderingCapable( Display *dpy, int screen, + Bool *isCapable ) +{ + int event_base; + int error_base; + + if (isCapable) + *isCapable = False; + + if (!XNVCTRLQueryExtension(dpy, &event_base, &error_base)) + return False; + + if (isCapable && XNVCTRLIsNvScreen(dpy, screen)) + *isCapable = True; + + return True; +} + +Bool VA_NVCTRLGetClientDriverName( Display *dpy, int screen, + int *ddxDriverMajorVersion, int *ddxDriverMinorVersion, + int *ddxDriverPatchVersion, char **clientDriverName ) +{ + if (ddxDriverMajorVersion) + *ddxDriverMajorVersion = 0; + if (ddxDriverMinorVersion) + *ddxDriverMinorVersion = 0; + if (ddxDriverPatchVersion) + *ddxDriverPatchVersion = 0; + if (clientDriverName) + *clientDriverName = NULL; + + char *nvidia_driver_version = NULL; + if (!XNVCTRLQueryStringAttribute(dpy, screen, 0, NV_CTRL_STRING_NVIDIA_DRIVER_VERSION, &nvidia_driver_version)) + return False; + + char *end, *str = nvidia_driver_version; + unsigned long v = strtoul(str, &end, 10); + if (end && end != str) { + if (ddxDriverMajorVersion) + *ddxDriverMajorVersion = v; + if (*(str = end) == '.') { + v = strtoul(str + 1, &end, 10); + if (end && end != str && *end == '\0') { + if (ddxDriverMinorVersion) + *ddxDriverMinorVersion = v; + } + } + } + Xfree(nvidia_driver_version); + + if (clientDriverName) + *clientDriverName = strdup("nvidia"); + + return True; +} diff --git a/src/x11/va_nvctrl.h b/src/x11/va_nvctrl.h new file mode 100644 index 0000000..c137b86 --- /dev/null +++ b/src/x11/va_nvctrl.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2008 NVIDIA, Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef VA_NVCTRLLIB_H +#define VA_NVCTRLLIB_H + +#include <X11/Xlib.h> + +Bool VA_NVCTRLQueryDirectRenderingCapable( Display *dpy, int screen, + Bool *isCapable ); + +Bool VA_NVCTRLGetClientDriverName( Display *dpy, int screen, + int *ddxDriverMajorVersion, int *ddxDriverMinorVersion, + int *ddxDriverPatchVersion, char **clientDriverName ); + +#endif /* VA_NVCTRLLIB_H */ diff --git a/src/x11/va_x11.c b/src/x11/va_x11.c new file mode 100644 index 0000000..ec0bbc8 --- /dev/null +++ b/src/x11/va_x11.c @@ -0,0 +1,283 @@ +/* + * Copyright (c) 2007 Intel Corporation. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#define _GNU_SOURCE 1 +#include "config.h" +#include "va.h" +#include "va_backend.h" +#include "va_x11.h" +#include "va_dri.h" +#include "va_dri2.h" +#include "va_dricommon.h" +#include "va_nvctrl.h" +#include <stdio.h> +#include <stdarg.h> +#include <string.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> + +static VADisplayContextP pDisplayContexts = NULL; + +static void va_errorMessage(const char *msg, ...) +{ + va_list args; + + fprintf(stderr, "libva error: "); + va_start(args, msg); + vfprintf(stderr, msg, args); + va_end(args); +} + +static void va_infoMessage(const char *msg, ...) +{ + va_list args; + + fprintf(stderr, "libva: "); + va_start(args, msg); + vfprintf(stderr, msg, args); + va_end(args); +} + +static int va_DisplayContextIsValid ( + VADisplayContextP pDisplayContext +) +{ + VADisplayContextP ctx = pDisplayContexts; + + while (ctx) + { + if (ctx == pDisplayContext && pDisplayContext->pDriverContext) + return 1; + ctx = ctx->pNext; + } + return 0; +} + +static void va_DisplayContextDestroy ( + VADisplayContextP pDisplayContext +) +{ + VADisplayContextP *ctx = &pDisplayContexts; + + /* Throw away pDisplayContext */ + while (*ctx) + { + if (*ctx == pDisplayContext) + { + *ctx = pDisplayContext->pNext; + pDisplayContext->pNext = NULL; + break; + } + ctx = &((*ctx)->pNext); + } + free(pDisplayContext->pDriverContext->dri_state); + free(pDisplayContext->pDriverContext); + free(pDisplayContext); +} + + +static VAStatus va_DRI2GetDriverName ( + VADisplayContextP pDisplayContext, + char **driver_name +) +{ + VADriverContextP ctx = pDisplayContext->pDriverContext; + + if (!isDRI2Connected(ctx, driver_name)) + return VA_STATUS_ERROR_UNKNOWN; + + return VA_STATUS_SUCCESS; +} + +static VAStatus va_DRIGetDriverName ( + VADisplayContextP pDisplayContext, + char **driver_name +) +{ + VADriverContextP ctx = pDisplayContext->pDriverContext; + + if (!isDRI1Connected(ctx, driver_name)) + return VA_STATUS_ERROR_UNKNOWN; + + return VA_STATUS_SUCCESS; +} + +static VAStatus va_NVCTRL_GetDriverName ( + VADisplayContextP pDisplayContext, + char **driver_name +) +{ + VADriverContextP ctx = pDisplayContext->pDriverContext; + VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN; + int direct_capable; + int driver_major; + int driver_minor; + int driver_patch; + Bool result = True; + char *nvidia_driver_name = NULL; + + if (result) + { + result = VA_NVCTRLQueryDirectRenderingCapable(ctx->x11_dpy, ctx->x11_screen, &direct_capable); + if (!result) + { + va_errorMessage("VA_NVCTRLQueryDirectRenderingCapable failed\n"); + } + } + if (result) + { + result = direct_capable; + if (!result) + { + va_errorMessage("VA_NVCTRLQueryDirectRenderingCapable returned false\n"); + } + } + if (result) + { + result = VA_NVCTRLGetClientDriverName(ctx->x11_dpy, ctx->x11_screen, &driver_major, &driver_minor, + &driver_patch, &nvidia_driver_name); + if (!result) + { + va_errorMessage("VA_NVCTRLGetClientDriverName returned false\n"); + } + } + if (result) + { + vaStatus = VA_STATUS_SUCCESS; + va_infoMessage("va_NVCTRL_GetDriverName: %d.%d.%d %s (screen %d)\n", + driver_major, driver_minor, driver_patch, + nvidia_driver_name, ctx->x11_screen); + if (driver_name) + *driver_name = nvidia_driver_name; + } + return vaStatus; +} + +static VAStatus va_DisplayContextGetDriverName ( + VADisplayContextP pDisplayContext, + char **driver_name +) +{ + VAStatus vaStatus; + char *driver_name_env; + + if (driver_name) + *driver_name = NULL; + + if ((driver_name_env = getenv("LIBVA_DRIVER_NAME")) != NULL + && geteuid() == getuid()) + { + /* don't allow setuid apps to use LIBVA_DRIVER_NAME */ + *driver_name = strdup(driver_name_env); + return VA_STATUS_SUCCESS; + } + + vaStatus = va_DRI2GetDriverName(pDisplayContext, driver_name); + if (vaStatus != VA_STATUS_SUCCESS) + vaStatus = va_DRIGetDriverName(pDisplayContext, driver_name); + if (vaStatus != VA_STATUS_SUCCESS) + vaStatus = va_NVCTRL_GetDriverName(pDisplayContext, driver_name); + + return vaStatus; +} + +int vaDisplayIsValid(VADisplay dpy) +{ + VADisplayContextP tmp=NULL; + VADisplayContextP pDisplayContext = pDisplayContexts; + + while (pDisplayContext) + { + if (pDisplayContext == (VADisplayContextP)dpy) + { + tmp = (VADisplay)pDisplayContext; + break; + } + pDisplayContext = pDisplayContext->pNext; + } + + if (!tmp) + return 0; + + return tmp->vaIsValid(pDisplayContext); +} + + +VADisplay vaGetDisplay ( + Display *native_dpy /* implementation specific */ +) +{ + VADisplay dpy = NULL; + VADisplayContextP pDisplayContext = pDisplayContexts; + + if (!native_dpy) + return NULL; + + while (pDisplayContext) + { + if (pDisplayContext->pDriverContext && + pDisplayContext->pDriverContext->x11_dpy == native_dpy) + { + dpy = (VADisplay)pDisplayContext; + break; + } + pDisplayContext = pDisplayContext->pNext; + } + + if (!dpy) + { + /* create new entry */ + VADriverContextP pDriverContext; + struct dri_state *dri_state; + pDisplayContext = calloc(1, sizeof(*pDisplayContext)); + pDriverContext = calloc(1, sizeof(*pDriverContext)); + dri_state = calloc(1, sizeof(*dri_state)); + if (pDisplayContext && pDriverContext && dri_state) + { + pDriverContext->x11_dpy = native_dpy; + pDisplayContext->pNext = pDisplayContexts; + pDisplayContext->pDriverContext = pDriverContext; + pDisplayContext->vaIsValid = va_DisplayContextIsValid; + pDisplayContext->vaDestroy = va_DisplayContextDestroy; + pDisplayContext->vaGetDriverName = va_DisplayContextGetDriverName; + pDisplayContexts = pDisplayContext; + pDriverContext->dri_state = dri_state; + dpy = (VADisplay)pDisplayContext; + } + else + { + if (pDisplayContext) + free(pDisplayContext); + if (pDriverContext) + free(pDriverContext); + if (dri_state) + free(dri_state); + } + } + + return dpy; +} diff --git a/src/x11/va_x11.h b/src/x11/va_x11.h new file mode 100644 index 0000000..2171ac6 --- /dev/null +++ b/src/x11/va_x11.h @@ -0,0 +1,67 @@ +#ifndef _VA_X11_H_ +#define _VA_X11_H_ + +#ifdef IN_LIBVA +#include "va.h" +#else +#include <va/va.h> +#endif +#include <X11/Xlib.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Returns a suitable VADisplay for VA API + */ +VADisplay vaGetDisplay ( + Display *dpy +); + +/* + * Output rendering + * Following is the rendering interface for X windows, + * to get the decode output surface to a X drawable + * It basically performs a de-interlacing (if needed), + * color space conversion and scaling to the destination + * rectangle + */ +/* de-interlacing flags for vaPutSurface */ +#define VA_FRAME_PICTURE 0x00000000 +#define VA_TOP_FIELD 0x00000001 +#define VA_BOTTOM_FIELD 0x00000002 + +/* + * clears the drawable with background color. + * for hardware overlay based implementation this flag + * can be used to turn off the overlay + */ +#define VA_CLEAR_DRAWABLE 0x00000008 + +/* color space conversion flags for vaPutSurface */ +#define VA_SRC_BT601 0x00000010 +#define VA_SRC_BT709 0x00000020 + +VAStatus vaPutSurface ( + VADisplay dpy, + VASurfaceID surface, + Drawable draw, /* X Drawable */ + short srcx, + short srcy, + unsigned short srcw, + unsigned short srch, + short destx, + short desty, + unsigned short destw, + unsigned short desth, + VARectangle *cliprects, /* client supplied destination clip list */ + unsigned int number_cliprects, /* number of clip rects in the clip list */ + unsigned int flags /* PutSurface flags */ +); + +#ifdef __cplusplus +} +#endif + +#endif /* _VA_X11_H_ */ |