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)
AC_SUBST(X11_CFLAGS)
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 has it in libc), or if libdl is needed to get it.
AC_CHECK_FUNC([dlopen], [],
......
AM_CFLAGS = \
-I$(top_srcdir)/include \
-DVDPAU_MODULEDIR="\"$(moduledir)\"" \
$(X11_CFLAGS)
$(X11_CFLAGS) \
$(XEXT_CFLAGS)
lib_LTLIBRARIES = libvdpau.la
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 = \
$(DLOPEN_LIBS)
$(DLOPEN_LIBS) \
$(XEXT_LIBS)
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 @@
* SOFTWARE.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <dlfcn.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vdpau/vdpau_x11.h>
#if DRI2
#include "mesa_dri2.h"
#include <X11/Xlib.h>
#endif
typedef void SetDllHandle(
void * driver_dll_handle
......@@ -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"
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(
Display * display,
int screen,
......@@ -58,6 +96,7 @@ VdpStatus vdp_device_create_x11(
)
{
char const * vdpau_driver;
char * vdpau_driver_dri2 = NULL;
char vdpau_driver_lib[PATH_MAX];
void * backend_dll;
char const * vdpau_trace;
......@@ -65,8 +104,11 @@ VdpStatus vdp_device_create_x11(
VdpDeviceCreateX11 * vdp_imp_device_create_x11;
/* FIXME: Determine driver name using an X extension */
vdpau_driver = getenv("VDPAU_DRIVER");
if (!vdpau_driver) {
vdpau_driver = vdpau_driver_dri2 =
_vdp_get_driver_name_from_dri2(display, screen);
}
if (!vdpau_driver) {
vdpau_driver = "nvidia";
}
......@@ -75,6 +117,10 @@ VdpStatus vdp_device_create_x11(
VDPAU_MODULEDIR "/", vdpau_driver, ".1") >=
sizeof(vdpau_driver_lib)) {
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();
return VDP_STATUS_NO_IMPLEMENTATION;
}
......@@ -88,6 +134,11 @@ VdpStatus vdp_device_create_x11(
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) {
fprintf(stderr, "Failed to open VDPAU backend %s\n", dlerror());
_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