OSDN Git Service

Merge branch 'DRI2'
authorAustin Yuan <shengquan.yuan@intel.com>
Wed, 22 Apr 2009 20:03:45 +0000 (16:03 -0400)
committerAustin Yuan <shengquan.yuan@intel.com>
Wed, 22 Apr 2009 20:03:45 +0000 (16:03 -0400)
configure.ac
src/Makefile.am
src/X11/Makefile.am
src/X11/va_dri2.c [new file with mode: 0644]
src/X11/va_dri2.h [new file with mode: 0644]
src/X11/va_x11.c
src/va_backend.h

index 9ffc13d..a0e599f 100644 (file)
@@ -36,9 +36,8 @@ AC_SYS_LARGEFILE
 
 PKG_CHECK_MODULES([X11], [x11])
 PKG_CHECK_MODULES([XEXT], [xext])
-PKG_CHECK_MODULES([Xfixes], [xfixes])
-PKG_CHECK_MODULES([XDAMAGE], [xdamage])
 PKG_CHECK_MODULES([DRM], [libdrm])
+PKG_CHECK_MODULES([XV], [xv]) #neccessary, orelse segment fault when XCloseDisplay
 PKG_CHECK_MODULES(LIBDRM_DEPS, [libdrm])
 
 # We only need the headers, we don't link against the DRM libraries
index 06aeaff..555249e 100644 (file)
@@ -27,7 +27,7 @@ INCLUDES = \
 libva_la_LTLIBRARIES = libva.la
 libva_ladir = $(libdir)
 libva_la_LDFLAGS = -version-number 0:30:0 -no-undefined
-libva_la_LIBADD = $(LIBVA_LIBS) -ldl -lX11 -lXext -lXfixes -lXdamage -lXv -lXrandr X11/libva_X11.la
+libva_la_LIBADD = $(LIBVA_LIBS) -ldl -ldrm -lX11 -lXext -lXv X11/libva_X11.la
 
 SUBDIRS = X11
 
index 7413dd7..537c3f0 100644 (file)
@@ -23,6 +23,6 @@ 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
+libva_X11include_HEADERS = va_x11.h va_dri.h va_dri2.h
 
-libva_X11_la_SOURCES = va_x11.c va_dri.c
+libva_X11_la_SOURCES = va_x11.c va_dri.c va_dri2.c
diff --git a/src/X11/va_dri2.c b/src/X11/va_dri2.c
new file mode 100644 (file)
index 0000000..4bd5b52
--- /dev/null
@@ -0,0 +1,302 @@
+/*
+ * 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 <X11/extensions/dri2proto.h>
+#include "xf86drm.h"
+#include "va_dri2.h"
+
+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 (file)
index 0000000..0231649
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * 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/extensions/dri2tokens.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
index bc2429e..85b21d5 100644 (file)
 #include "va_backend.h"
 #include "va_x11.h"
 #include "va_dri.h"
+#include "va_dri2.h"
 #include <stdio.h>
 #include <stdarg.h>
 #include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
 
 static VADisplayContextP pDisplayContexts = NULL;
 
@@ -89,13 +94,52 @@ static void va_DisplayContextDestroy (
     free(pDisplayContext);
 }
 
-static VAStatus va_DisplayContextGetDriverName (
+
+static VAStatus va_DRI2GetDriverName (
+    VADisplayContextP pDisplayContext,
+    char **driver_name
+)
+{
+    VADriverContextP ctx = pDisplayContext->pDriverContext;
+    VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
+    int eventBase, errorBase;
+    char *device_name;
+    int driver_major;
+    int driver_minor;
+    int driver_patch;
+    Bool result = True;
+
+    if (!VA_DRI2QueryExtension(ctx->x11_dpy, &eventBase, &errorBase)) {
+        va_infoMessage("DRI2 extension isn't present\n");
+        return VA_STATUS_ERROR_UNKNOWN;
+    }
+
+    if (!VA_DRI2QueryVersion(ctx->x11_dpy, &driver_major, &driver_minor)) {
+        va_errorMessage("VA_DRI2QueryVersion failed\n");
+        return VA_STATUS_ERROR_UNKNOWN;
+    }
+    
+    if (!VA_DRI2Connect(ctx->x11_dpy, RootWindow(ctx->x11_dpy, ctx->x11_screen),
+                    driver_name, &device_name)) {
+        va_infoMessage("DRI2 isn't enabled, fallback to DRI1\n");
+        return VA_STATUS_ERROR_UNKNOWN;
+    }
+
+    va_infoMessage("VA_DRI2Connect: %d.%d.%d %s (screen %d)\n",
+                   driver_major, driver_minor, driver_patch, *driver_name, ctx->x11_screen);
+    ctx->dri2 = 1;
+    
+    return VA_STATUS_SUCCESS;
+}
+
+static VAStatus va_DRIGetDriverName (
     VADisplayContextP pDisplayContext,
     char **driver_name
 )
 {
     VADriverContextP ctx = pDisplayContext->pDriverContext;
     VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN;
+    int eventBase, errorBase;
     int direct_capable;
     int driver_major;
     int driver_minor;
@@ -103,18 +147,11 @@ static VAStatus va_DisplayContextGetDriverName (
     Bool result = True;
     char *x_driver_name = NULL;
 
-    if (driver_name)
-       *driver_name = NULL;
-    if (geteuid() == getuid())
-    {
-        /* don't allow setuid apps to use LIBVA_DRIVER_NAME */
-        if (getenv("LIBVA_DRIVER_NAME"))
-        {
-            /* For easier debugging */
-            *driver_name = strdup(getenv("LIBVA_DRIVER_NAME"));
-            return VA_STATUS_SUCCESS;
-        }
+    if (!VA_DRIQueryExtension(ctx->x11_dpy, &eventBase, &errorBase)) {
+        va_errorMessage("VA_DRIQueryExtension failed\n");
+        return VA_STATUS_ERROR_UNKNOWN;
     }
+    
     if (result)
     {
         result = VA_DRIQueryDirectRenderingCapable(ctx->x11_dpy, ctx->x11_screen, &direct_capable);
@@ -154,6 +191,45 @@ static VAStatus va_DisplayContextGetDriverName (
     return vaStatus;
 }
 
+static VAStatus va_DisplayContextGetDriverName (
+    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 *x_driver_name = NULL;
+
+    if (driver_name)
+       *driver_name = NULL;
+    
+    vaStatus = va_DRI2GetDriverName(pDisplayContext, driver_name);
+    if (vaStatus != VA_STATUS_SUCCESS)
+        vaStatus = va_DRIGetDriverName(pDisplayContext, driver_name);
+
+    if ((vaStatus == VA_STATUS_SUCCESS)
+        && geteuid() == getuid())
+    {
+        /* don't allow setuid apps to use LIBVA_DRIVER_NAME */
+        if (getenv("LIBVA_DRIVER_NAME"))
+        {
+            /* For easier debugging */
+            if (*driver_name)
+                XFree(*driver_name);
+            
+            *driver_name = strdup(getenv("LIBVA_DRIVER_NAME"));
+            return VA_STATUS_SUCCESS;
+        }
+    }
+    
+    return vaStatus;
+}
+
 int vaDisplayIsValid(VADisplay dpy)
 {
   VADisplayContextP tmp=NULL;
index 9ab4ce1..5d0785c 100755 (executable)
@@ -423,7 +423,7 @@ struct VADriverContext
 
     Display *x11_dpy;
     int x11_screen;
-
+    int dri2;
     int version_major;
     int version_minor;
     int max_profiles;