Commit 3c02e5c6 authored by Aaron Plattner's avatar Aaron Plattner
Browse files

Query DRI2 for the driver name.



If the VDPAU_DRIVER environment variable is not set, use DRI2Connect to query
the VDPAU driver name from the X server.
Signed-off-by: default avatarAaron Plattner <aplattner@nvidia.com>
Reviewed-by: default avatarStephen Warren <swarren@nvidia.com>
parent a9c69d29
...@@ -20,6 +20,23 @@ PKG_CHECK_MODULES(X11, x11) ...@@ -20,6 +20,23 @@ PKG_CHECK_MODULES(X11, x11)
AC_SUBST(X11_CFLAGS) AC_SUBST(X11_CFLAGS)
AC_SUBST(X11_LIBS) AC_SUBST(X11_LIBS)
# Check for optional dependencies.
AC_ARG_ENABLE(dri2, AS_HELP_STRING([--disable-dri2], [Disable driver name query through DRI2 (default: auto)]), [DRI2=$enableval], [DRI2=auto])
PKG_CHECK_MODULES(dri2proto, dri2proto >= 2.2, [HAVE_DRI2PROTO=yes], [HAVE_DRI2PROTO=no])
case "$DRI2,$HAVE_DRI2PROTO" in
yes,no)
AC_MSG_ERROR([DRI2 queries require dri2proto >= 2.2])
;;
yes,yes | auto,yes)
AC_DEFINE(DRI2, 1, [Request driver name from DRI2])
DRI2=yes
PKG_CHECK_MODULES(XEXT, xext)
AC_SUBST([XEXT_CFLAGS])
AC_SUBST([XEXT_LIBS])
;;
esac
AM_CONDITIONAL(DRI2, test "x$DRI2" = xyes)
dnl Check to see if dlopen is in default libraries (like Solaris, which dnl Check to see if dlopen is in default libraries (like Solaris, which
dnl has it in libc), or if libdl is needed to get it. dnl has it in libc), or if libdl is needed to get it.
AC_CHECK_FUNC([dlopen], [], AC_CHECK_FUNC([dlopen], [],
......
AM_CFLAGS = \ AM_CFLAGS = \
-I$(top_srcdir)/include \ -I$(top_srcdir)/include \
-DVDPAU_MODULEDIR="\"$(moduledir)\"" \ -DVDPAU_MODULEDIR="\"$(moduledir)\"" \
$(X11_CFLAGS) $(X11_CFLAGS) \
$(XEXT_CFLAGS)
lib_LTLIBRARIES = libvdpau.la lib_LTLIBRARIES = libvdpau.la
libvdpau_la_SOURCES = \ libvdpau_la_SOURCES = \
vdpau_wrapper.c vdpau_wrapper.c \
$(DRI2_SOURCES)
if DRI2
DRI2_SOURCES = \
mesa_dri2.c \
mesa_dri2.h
endif
libvdpau_la_LIBADD = \ libvdpau_la_LIBADD = \
$(DLOPEN_LIBS) $(DLOPEN_LIBS) \
$(XEXT_LIBS)
libvdpau_la_LDFLAGS = -version-info 1:0:0 -no-undefined libvdpau_la_LDFLAGS = -version-info 1:0:0 -no-undefined
......
/*
* Copyright © 2008 Red Hat, Inc.
* Copyright © 2010 NVIDIA Corporation
*
* 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)
* Modified for VDPAU by Aaron Plattner (aplattner@nvidia.com)
*/
#define NEED_REPLIES
#include <X11/Xlibint.h>
#include <X11/extensions/Xext.h>
#include <X11/extensions/extutil.h>
#include <X11/extensions/dri2proto.h>
#include "mesa_dri2.h"
static char dri2ExtensionName[] = DRI2_NAME;
static XExtensionInfo *dri2Info;
static XEXT_GENERATE_CLOSE_DISPLAY (DRI2CloseDisplay, dri2Info)
static /* const */ XExtensionHooks dri2ExtensionHooks = {
NULL, /* create_gc */
NULL, /* copy_gc */
NULL, /* flush_gc */
NULL, /* free_gc */
NULL, /* create_font */
NULL, /* free_font */
DRI2CloseDisplay, /* close_display */
NULL, /* wire_to_event */
NULL, /* event_to_wire */
NULL, /* error */
NULL, /* error_string */
};
static XEXT_GENERATE_FIND_DISPLAY (DRI2FindDisplay,
dri2Info,
dri2ExtensionName,
&dri2ExtensionHooks,
0, NULL)
Bool
_vdp_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
_vdp_DRI2QueryVersion(Display * dpy, int *major, int *minor)
{
XExtDisplayInfo *info = DRI2FindDisplay(dpy);
xDRI2QueryVersionReply rep;
xDRI2QueryVersionReq *req;
XextCheckExtension(dpy, info, 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
_vdp_DRI2Connect(Display * dpy, XID window, char **driverName, char **deviceName)
{
XExtDisplayInfo *info = DRI2FindDisplay(dpy);
xDRI2ConnectReply rep;
xDRI2ConnectReq *req;
XextCheckExtension(dpy, info, dri2ExtensionName, False);
LockDisplay(dpy);
GetReq(DRI2Connect, req);
req->reqType = info->codes->major_opcode;
req->dri2ReqType = X_DRI2Connect;
req->window = window;
req->driverType = DRI2DriverVDPAU;
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;
}
/*
* Copyright © 2007,2008 Red Hat, Inc.
* Copyright © 2010 NVIDIA Corporation
*
* 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)
* Modified for VDPAU by Aaron Plattner (aplattner@nvidia.com)
*/
#ifndef _VDP_DRI2_H_
#define _VDP_DRI2_H_
#include <X11/extensions/dri2tokens.h>
extern Bool
_vdp_DRI2QueryExtension(Display * display, int *eventBase, int *errorBase);
extern Bool
_vdp_DRI2QueryVersion(Display * display, int *major, int *minor);
extern Bool
_vdp_DRI2Connect(Display * display, XID window, char **driverName,
char **deviceName);
#endif
...@@ -21,12 +21,20 @@ ...@@ -21,12 +21,20 @@
* SOFTWARE. * SOFTWARE.
*/ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <dlfcn.h> #include <dlfcn.h>
#include <limits.h> #include <limits.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <vdpau/vdpau_x11.h> #include <vdpau/vdpau_x11.h>
#if DRI2
#include "mesa_dri2.h"
#include <X11/Xlib.h>
#endif
typedef void SetDllHandle( typedef void SetDllHandle(
void * driver_dll_handle void * driver_dll_handle
...@@ -49,6 +57,36 @@ static void _vdp_wrapper_error_breakpoint(char const * file, int line, char cons ...@@ -49,6 +57,36 @@ static void _vdp_wrapper_error_breakpoint(char const * file, int line, char cons
#define DRIVER_LIB_FORMAT "%slibvdpau_%s.so%s" #define DRIVER_LIB_FORMAT "%slibvdpau_%s.so%s"
static char * _vdp_get_driver_name_from_dri2(
Display * display,
int screen
)
{
char * driver_name = NULL;
#if DRI2
Window root = RootWindow(display, screen);
int event_base, error_base;
int major, minor;
char * device_name;
if (!_vdp_DRI2QueryExtension(display, &event_base, &error_base)) {
return NULL;
}
if (!_vdp_DRI2QueryVersion(display, &major, &minor) ||
(major < 1 || (major == 1 && minor < 2))) {
return NULL;
}
if (!_vdp_DRI2Connect(display, root, &driver_name, &device_name)) {
return NULL;
}
XFree(device_name);
#endif /* DRI2 */
return driver_name;
}
VdpStatus vdp_device_create_x11( VdpStatus vdp_device_create_x11(
Display * display, Display * display,
int screen, int screen,
...@@ -58,6 +96,7 @@ VdpStatus vdp_device_create_x11( ...@@ -58,6 +96,7 @@ VdpStatus vdp_device_create_x11(
) )
{ {
char const * vdpau_driver; char const * vdpau_driver;
char * vdpau_driver_dri2 = NULL;
char vdpau_driver_lib[PATH_MAX]; char vdpau_driver_lib[PATH_MAX];
void * backend_dll; void * backend_dll;
char const * vdpau_trace; char const * vdpau_trace;
...@@ -65,8 +104,11 @@ VdpStatus vdp_device_create_x11( ...@@ -65,8 +104,11 @@ VdpStatus vdp_device_create_x11(
VdpDeviceCreateX11 * vdp_imp_device_create_x11; VdpDeviceCreateX11 * vdp_imp_device_create_x11;
/* FIXME: Determine driver name using an X extension */
vdpau_driver = getenv("VDPAU_DRIVER"); vdpau_driver = getenv("VDPAU_DRIVER");
if (!vdpau_driver) {
vdpau_driver = vdpau_driver_dri2 =
_vdp_get_driver_name_from_dri2(display, screen);
}
if (!vdpau_driver) { if (!vdpau_driver) {
vdpau_driver = "nvidia"; vdpau_driver = "nvidia";
} }
...@@ -75,6 +117,10 @@ VdpStatus vdp_device_create_x11( ...@@ -75,6 +117,10 @@ VdpStatus vdp_device_create_x11(
VDPAU_MODULEDIR "/", vdpau_driver, ".1") >= VDPAU_MODULEDIR "/", vdpau_driver, ".1") >=
sizeof(vdpau_driver_lib)) { sizeof(vdpau_driver_lib)) {
fprintf(stderr, "Failed to construct driver path: path too long\n"); fprintf(stderr, "Failed to construct driver path: path too long\n");
if (vdpau_driver_dri2) {
XFree(vdpau_driver_dri2);
vdpau_driver_dri2 = NULL;
}
_VDP_ERROR_BREAKPOINT(); _VDP_ERROR_BREAKPOINT();
return VDP_STATUS_NO_IMPLEMENTATION; return VDP_STATUS_NO_IMPLEMENTATION;
} }
...@@ -88,6 +134,11 @@ VdpStatus vdp_device_create_x11( ...@@ -88,6 +134,11 @@ VdpStatus vdp_device_create_x11(
backend_dll = dlopen(vdpau_driver_lib, RTLD_NOW | RTLD_GLOBAL); backend_dll = dlopen(vdpau_driver_lib, RTLD_NOW | RTLD_GLOBAL);
} }
if (vdpau_driver_dri2) {
XFree(vdpau_driver_dri2);
vdpau_driver_dri2 = NULL;
}
if (!backend_dll) { if (!backend_dll) {
fprintf(stderr, "Failed to open VDPAU backend %s\n", dlerror()); fprintf(stderr, "Failed to open VDPAU backend %s\n", dlerror());
_VDP_ERROR_BREAKPOINT(); _VDP_ERROR_BREAKPOINT();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment