diff options
-rw-r--r-- | Makefile.am | 16 | ||||
-rw-r--r-- | configure.ac | 74 | ||||
-rw-r--r-- | dummy_drv_video/Makefile.am | 5 | ||||
-rw-r--r-- | dummy_drv_video/dummy_drv_video.c | 6 | ||||
-rw-r--r-- | i965_drv_video/Makefile.am | 2 | ||||
-rw-r--r-- | libva.pc.in | 1 | ||||
-rw-r--r-- | src/Makefile.am | 25 | ||||
-rw-r--r-- | src/va.c | 33 | ||||
-rw-r--r-- | src/va.h | 43 | ||||
-rw-r--r-- | src/va_backend.h | 3 | ||||
-rw-r--r-- | src/va_version.h.in | 94 | ||||
-rw-r--r-- | src/x11/Makefile.am | 6 | ||||
-rw-r--r-- | src/x11/dri2_util.c | 3 | ||||
-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 | 117 | ||||
-rw-r--r-- | test/Makefile.am | 5 | ||||
-rw-r--r-- | test/test_common.c | 2 |
18 files changed, 723 insertions, 140 deletions
diff --git a/Makefile.am b/Makefile.am index 3515b69..cd0ee58 100644 --- a/Makefile.am +++ b/Makefile.am @@ -21,9 +21,21 @@ # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. AUTOMAKE_OPTIONS = foreign -SUBDIRS = src dummy_drv_video i965_drv_video test + +SUBDIRS = src test +if BUILD_DUMMY_DRIVER +SUBDIRS += dummy_drv_video +endif +if BUILD_I965_DRIVER +SUBDIRS += i965_drv_video +endif + +pcfiles = \ + libva.pc pkgconfigdir = @pkgconfigdir@ -pkgconfig_DATA = libva.pc +pkgconfig_DATA = $(pcfiles) EXTRA_DIST = libva.pc.in + +CLEANFILES = $(pcfiles) diff --git a/configure.ac b/configure.ac index 50fd976..6e9f95c 100644 --- a/configure.ac +++ b/configure.ac @@ -20,13 +20,70 @@ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# libva package version number, (as distinct from shared library version) +m4_define([libva_major_version], [0]) +m4_define([libva_minor_version], [30]) +m4_define([libva_micro_version], [4]) + +m4_define([libva_version], + [libva_major_version.libva_minor_version.libva_micro_version]) + +# increase this number for each API change +m4_define([libva_sds_version], [2]) + +# if the library source code has changed, increment revision +m4_define([libva_lt_revision], [1]) +# if any interface was added/removed/changed, then inc current, reset revision +m4_define([libva_lt_current], [0]) +# if any interface was added since last public release, then increment age +# if any interface was removed since last public release, then set age to 0 +m4_define([libva_lt_age], [0]) + AC_PREREQ(2.57) -AC_INIT([libva], 0.30.4, [waldo.bastian@intel.com], libva) +AC_INIT([libva], [libva_version], [waldo.bastian@intel.com], libva) AC_CONFIG_SRCDIR([Makefile.am]) AM_INIT_AUTOMAKE([dist-bzip2]) AM_CONFIG_HEADER([config.h]) +LIBVA_MAJOR_VERSION=libva_major_version +LIBVA_MINOR_VERSION=libva_minor_version +LIBVA_MICRO_VERSION=libva_micro_version +LIBVA_VERSION=libva_version +AC_SUBST(LIBVA_MAJOR_VERSION) +AC_SUBST(LIBVA_MINOR_VERSION) +AC_SUBST(LIBVA_MICRO_VERSION) +AC_SUBST(LIBVA_VERSION) + +LIBVA_SDS_VERSION=libva_sds_version +AC_SUBST(LIBVA_SDS_VERSION) + +LIBVA_LT_CURRENT=libva_lt_current +LIBVA_LT_REV=libva_lt_revision +LIBVA_LT_AGE=libva_lt_age +LIBVA_LT_VERSION="$LIBVA_LT_CURRENT:$LIBVA_LT_REV:$LIBVA_LT_AGE" +LIBVA_LT_LDFLAGS="-version-info $LIBVA_LT_VERSION" +AC_SUBST(LIBVA_LT_VERSION) +AC_SUBST(LIBVA_LT_LDFLAGS) + +AC_ARG_ENABLE(dummy-driver, + [AC_HELP_STRING([--enable-dummy-driver], + [build dummy video driver])], + [], [enable_dummy_driver=yes]) +AM_CONDITIONAL(BUILD_DUMMY_DRIVER, test x$enable_dummy_driver = xyes) + +AC_ARG_ENABLE(i965-driver, + [AC_HELP_STRING([--enable-i965-driver], + [build i965 video driver])], + [], [enable_i965_driver=no]) + +AC_ARG_WITH(drivers-path, + [AC_HELP_STRING([--with-drivers-path=[[path]]], [drivers path])],, + [with_drivers_path="$libdir/dri"]) + +LIBVA_DRIVERS_PATH="$with_drivers_path" +AC_SUBST(LIBVA_DRIVERS_PATH) + AC_DISABLE_STATIC AC_PROG_LIBTOOL AC_PROG_CC @@ -36,23 +93,34 @@ AC_SYS_LARGEFILE PKG_CHECK_MODULES([X11], [x11]) PKG_CHECK_MODULES([XEXT],[xext]) +PKG_CHECK_MODULES([XFIXES], [xfixes]) PKG_CHECK_MODULES([DRM], [libdrm]) -PKG_CHECK_MODULES(LIBDRM_DEPS, [libdrm]) PKG_CHECK_MODULES(GEN4ASM, [intel-gen4asm >= 1.0], [gen4asm=yes], [gen4asm=no]) AM_CONDITIONAL(HAVE_GEN4ASM, test x$gen4asm = xyes) +# Check for libdrm >= 2.4 (needed for i965_drv_video.so) +if test x$enable_i965_driver = xyes && ! $PKG_CONFIG --atleast-version=2.4 libdrm; then + AC_MSG_WARN([libdrm < 2.4 found, disabling build of i965 video driver]) + enable_i965_driver=no +fi +AM_CONDITIONAL(BUILD_I965_DRIVER, test x$enable_i965_driver = xyes) + # We only need the headers, we don't link against the DRM libraries -LIBVA_CFLAGS="$LIBDRM_DEPS_CFLAGS" +LIBVA_CFLAGS="$DRM_CFLAGS" AC_SUBST(LIBVA_CFLAGS) AC_SUBST(LIBVA_LIBS) pkgconfigdir=${libdir}/pkgconfig AC_SUBST(pkgconfigdir) +libvabackendlib=libva.la +AC_SUBST([libvabackendlib]) + AC_OUTPUT([ Makefile src/Makefile + src/va_version.h src/x11/Makefile dummy_drv_video/Makefile i965_drv_video/Makefile diff --git a/dummy_drv_video/Makefile.am b/dummy_drv_video/Makefile.am index f782c71..4e75a7b 100644 --- a/dummy_drv_video/Makefile.am +++ b/dummy_drv_video/Makefile.am @@ -21,9 +21,10 @@ # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. dummy_drv_video_la_LTLIBRARIES = dummy_drv_video.la -dummy_drv_video_ladir = /usr/lib/dri +dummy_drv_video_ladir = @LIBVA_DRIVERS_PATH@ dummy_drv_video_la_LDFLAGS = -module -avoid-version -no-undefined -Wl,--no-undefined -dummy_drv_video_la_LIBADD = ../src/libva.la +dummy_drv_video_la_LIBADD = $(top_srcdir)/src/$(libvabackendlib) +dummy_drv_video_la_DEPENDENCIES = $(top_srcdir)/src/$(libvabackendlib) AM_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/../../include/external/ -I$(top_srcdir)/../../include/kmd -DIN_LIBVA dummy_drv_video_la_SOURCES = dummy_drv_video.c object_heap.c diff --git a/dummy_drv_video/dummy_drv_video.c b/dummy_drv_video/dummy_drv_video.c index 20ee3ae..1eb51a0 100644 --- a/dummy_drv_video/dummy_drv_video.c +++ b/dummy_drv_video/dummy_drv_video.c @@ -1211,15 +1211,15 @@ VAStatus dummy_Terminate( VADriverContextP ctx ) return VA_STATUS_SUCCESS; } -VAStatus __vaDriverInit_0_29( VADriverContextP ctx ) +VAStatus __vaDriverInit_0_30( VADriverContextP ctx ) { object_base_p obj; int result; struct dummy_driver_data *driver_data; int i; - ctx->version_major = 0; - ctx->version_minor = 29; + ctx->version_major = VA_MAJOR_VERSION; + ctx->version_minor = VA_MINOR_VERSION; ctx->max_profiles = DUMMY_MAX_PROFILES; ctx->max_entrypoints = DUMMY_MAX_ENTRYPOINTS; ctx->max_attributes = DUMMY_MAX_CONFIG_ATTRIBUTES; diff --git a/i965_drv_video/Makefile.am b/i965_drv_video/Makefile.am index 83fb8f1..c0117c9 100644 --- a/i965_drv_video/Makefile.am +++ b/i965_drv_video/Makefile.am @@ -25,7 +25,7 @@ SUBDIRS = shaders AM_CFLAGS = -Wall -I$(top_srcdir)/src -I$(top_srcdir)/src/x11 @DRM_CFLAGS@ -DIN_LIBVA i965_drv_video_la_LTLIBRARIES = i965_drv_video.la -i965_drv_video_ladir = $(libdir)/dri +i965_drv_video_ladir = @LIBVA_DRIVERS_PATH@ i965_drv_video_la_LDFLAGS = -module -avoid-version -no-undefined -Wl,--no-undefined @DRM_LIBS@ -ldrm_intel i965_drv_video_la_LIBADD = ../src/libva.la -lpthread diff --git a/libva.pc.in b/libva.pc.in index 16fb6aa..60f1483 100644 --- a/libva.pc.in +++ b/libva.pc.in @@ -2,6 +2,7 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ +driverdir=@LIBVA_DRIVERS_PATH@ Name: libva Description: Userspace Video Acceleration (VA) core interface diff --git a/src/Makefile.am b/src/Makefile.am index e990979..5fac8b5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -22,25 +22,26 @@ INCLUDES = \ $(LIBVA_CFLAGS) -I$(top_srcdir)/src/x11 \ - -DIN_LIBVA + -DIN_LIBVA \ + -DVA_DRIVERS_PATH="\"$(LIBVA_DRIVERS_PATH)\"" + +LDADD = \ + $(LIBVA_LT_LDFLAGS) libva_la_LTLIBRARIES = libva.la libva_ladir = $(libdir) -libva_la_LDFLAGS = -version-number 0:30:4 -no-undefined +libva_la_LDFLAGS = $(LDADD) -no-undefined libva_la_LIBADD = $(LIBVA_LIBS) -ldl -lX11 -lXext x11/libva_x11.la -ldrm -lXfixes -nodist_libva_la_SOURCES = va_version.h -BUILT_SOURCES = va_version.h - -CLEANFILES = va_version.h - -va_version.h: Makefile - echo "#define VA_BUILD_DATE \"$(shell date +'%Y%m%d') $(shell date +'1%H%M%S') \"" > va_version.h - echo "#define VA_BUILD_GIT \"($(shell git log | head -n1 | cut -f2 -d' ')) \" " >> va_version.h - SUBDIRS = x11 libva_la_SOURCES = va.c libvaincludedir = ${includedir}/va -libvainclude_HEADERS = va.h va_backend.h +libvainclude_HEADERS = va.h va_backend.h va_version.h + +DISTCLEANFILES = \ + va_version.h + +EXTRA_DIST = \ + va_version.h.in @@ -22,11 +22,10 @@ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#define _GNU_SOURCE 1 #include "va.h" #include "va_backend.h" -#include "va_version.h" - #include <assert.h> #include <stdarg.h> #include <stdio.h> @@ -40,13 +39,9 @@ #include "va_dricommon.h" -#define VA_STR_VERSION VA_BUILD_DATE VA_BUILD_GIT - -#define VA_MAJOR_VERSION 0 -#define VA_MINOR_VERSION 30 #define DRIVER_INIT_FUNC "__vaDriverInit_0_30" +#define DRIVER_INIT_FUNC_SDS "__vaDriverInit_0_30_sds" -#define DEFAULT_DRIVER_DIR "/usr/lib/dri/" #define DRIVER_EXTENSION "_drv_video.so" #define CTX(dpy) (((VADisplayContextP)dpy)->pDriverContext) @@ -116,21 +111,8 @@ static Bool va_checkString(const char* value, char *variable) static VAStatus va_getDriverName(VADisplay dpy, char **driver_name) { VADisplayContextP pDisplayContext = (VADisplayContextP)dpy; - VADriverContextP ctx = CTX(dpy); - VAStatus ret; - ret = pDisplayContext->vaGetDriverName(pDisplayContext, driver_name); - if (ret == VA_STATUS_SUCCESS) - { - if (isDRI2Connected(ctx, driver_name)) - { - ret = VA_STATUS_SUCCESS; - } else if (isDRI1Connected(ctx, driver_name)) - { - ret = VA_STATUS_SUCCESS; - } - } - return ret; + return pDisplayContext->vaGetDriverName(pDisplayContext, driver_name); } static VAStatus va_openDriver(VADisplay dpy, char *driver_name) @@ -152,7 +134,7 @@ static VAStatus va_openDriver(VADisplay dpy, char *driver_name) } if (!search_path) { - search_path = DEFAULT_DRIVER_DIR; + search_path = VA_DRIVERS_PATH; } search_path = strdup((const char *)search_path); @@ -185,6 +167,11 @@ static VAStatus va_openDriver(VADisplay dpy, char *driver_name) init_func = (VADriverInit) dlsym(handle, DRIVER_INIT_FUNC); if (!init_func) { + /* Then try SDS extensions (VDPAU and XvBA backends) */ + init_func = (VADriverInit) dlsym(handle, DRIVER_INIT_FUNC_SDS); + } + if (!init_func) + { va_errorMessage("%s has no function %s\n", driver_path, DRIVER_INIT_FUNC); dlclose(handle); } @@ -347,7 +334,7 @@ VAStatus vaInitialize ( va_debug_trace = (getenv("LIBVA_DEBUG_TRACE") != NULL); - va_infoMessage("libva build on %s\n", VA_STR_VERSION); + va_infoMessage("libva version %s\n", VA_VERSION_S); vaStatus = va_getDriverName(dpy, &driver_name); va_infoMessage("va_getDriverName() returns %d\n", vaStatus); @@ -63,6 +63,12 @@ #ifndef _VA_H_ #define _VA_H_ +#ifdef IN_LIBVA +#include "va_version.h" +#else +#include <va/va_version.h> +#endif + #ifdef __cplusplus extern "C" { #endif @@ -364,7 +370,8 @@ typedef VAGenericID VAContextID; typedef VAGenericID VASurfaceID; -#define VA_INVALID_SURFACE -1 +#define VA_INVALID_ID 0xffffffff +#define VA_INVALID_SURFACE VA_INVALID_ID /* * vaCreateSurfaces - Create an array of surfaces used for decode and display @@ -465,6 +472,27 @@ typedef enum } VABufferType; +/* + * There will be cases where the bitstream buffer will not have enough room to hold + * the data for the entire slice, and the following flags will be used in the slice + * parameter to signal to the server for the possible cases. + * If a slice parameter buffer and slice data buffer pair is sent to the server with + * the slice data partially in the slice data buffer (BEGIN and MIDDLE cases below), + * then a slice parameter and data buffer needs to be sent again to complete this slice. + */ +#define VA_SLICE_DATA_FLAG_ALL 0x00 /* whole slice is in the buffer */ +#define VA_SLICE_DATA_FLAG_BEGIN 0x01 /* The beginning of the slice is in the buffer but the end if not */ +#define VA_SLICE_DATA_FLAG_MIDDLE 0x02 /* Neither beginning nor end of the slice is in the buffer */ +#define VA_SLICE_DATA_FLAG_END 0x04 /* end of the slice is in the buffer */ + +/* Codec-independent Slice Parameter Buffer base */ +typedef struct _VASliceParameterBufferBase +{ + unsigned int slice_data_size; /* number of bytes in the slice data buffer for this slice */ + unsigned int slice_data_offset; /* the offset to the first byte of slice data */ + unsigned int slice_data_flag; /* see VA_SLICE_DATA_FLAG_XXX definitions */ +} VASliceParameterBufferBase; + /**************************** * MPEG-2 data structures ****************************/ @@ -516,19 +544,6 @@ typedef struct _VAIQMatrixBufferMPEG2 unsigned char chroma_non_intra_quantiser_matrix[64]; } VAIQMatrixBufferMPEG2; -/* - * There will be cases where the bitstream buffer will not have enough room to hold - * the data for the entire slice, and the following flags will be used in the slice - * parameter to signal to the server for the possible cases. - * If a slice parameter buffer and slice data buffer pair is sent to the server with - * the slice data partially in the slice data buffer (BEGIN and MIDDLE cases below), - * then a slice parameter and data buffer needs to be sent again to complete this slice. - */ -#define VA_SLICE_DATA_FLAG_ALL 0x00 /* whole slice is in the buffer */ -#define VA_SLICE_DATA_FLAG_BEGIN 0x01 /* The beginning of the slice is in the buffer but the end if not */ -#define VA_SLICE_DATA_FLAG_MIDDLE 0x02 /* Neither beginning nor end of the slice is in the buffer */ -#define VA_SLICE_DATA_FLAG_END 0x04 /* end of the slice is in the buffer */ - /* MPEG-2 Slice Parameter Buffer */ typedef struct _VASliceParameterBufferMPEG2 { diff --git a/src/va_backend.h b/src/va_backend.h index 7dc2302..619dd99 100644 --- a/src/va_backend.h +++ b/src/va_backend.h @@ -407,14 +407,11 @@ struct VADriverVTable struct VADriverContext { - void *old_pNext; /* preserved for binary compatibility */ - void *pDriverData; struct VADriverVTable vtable; Display *x11_dpy; int x11_screen; - int dri2; int version_major; int version_minor; int max_profiles; diff --git a/src/va_version.h.in b/src/va_version.h.in new file mode 100644 index 0000000..197c482 --- /dev/null +++ b/src/va_version.h.in @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2009 Splitted-Desktop Systems. 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. + */ + +#ifndef VA_VERSION_H +#define VA_VERSION_H + +/** + * VA_MAJOR_VERSION: + * + * The major version of the VA library (1, if %VA_VERSION is 1.2.3) + */ +#define VA_MAJOR_VERSION (@LIBVA_MAJOR_VERSION@) + +/** + * VA_MINOR_VERSION: + * + * The minor version of the VA library (2, if %VA_VERSION is 1.2.3) + */ +#define VA_MINOR_VERSION (@LIBVA_MINOR_VERSION@) + +/** + * VA_MICRO_VERSION: + * + * The micro version of the VA library (3, if %VA_VERSION is 1.2.3) + */ +#define VA_MICRO_VERSION (@LIBVA_MICRO_VERSION@) + +/** + * VA_SDS_VERSION: + * + * The version of the SDS API extensions to the VA library + */ +#define VA_SDS_VERSION (@LIBVA_SDS_VERSION@) + +/** + * VA_VERSION: + * + * The full version of the VA library, like 1.2.3 + */ +#define VA_VERSION @LIBVA_VERSION@ + +/** + * VA_VERSION_S: + * + * The full version of the VA library, in string form (suited for + * string concatenation) + */ +#define VA_VERSION_S "@LIBVA_VERSION@-sds@LIBVA_SDS_VERSION@" + +/** + * VA_VERSION_HEX: + * + * Numerically encoded version of the VA library, like 0x010203 + */ +#define VA_VERSION_HEX ((VA_MAJOR_VERSION << 24) | \ + (VA_MINOR_VERSION << 16) | \ + (VA_MICRO_VERSION << 8)) + +/** + * VA_CHECK_VERSION: + * @major: major version, like 1 in 1.2.3 + * @minor: minor version, like 2 in 1.2.3 + * @micro: micro version, like 3 in 1.2.3 + * + * Evaluates to %TRUE if the version of the VA library is greater + * than @major, @minor and @micro + */ +#define VA_CHECK_VERSION(major,minor,micro) \ + (VA_MAJOR_VERSION > (major) || \ + (VA_MAJOR_VERSION == (major) && VA_MINOR_VERSION > (minor)) || \ + (VA_MAJOR_VERSION == (major) && VA_MINOR_VERSION == (minor) && VA_MICRO_VERSION >= (micro))) + +#endif /* VA_VERSION_H */ diff --git a/src/x11/Makefile.am b/src/x11/Makefile.am index 06129db..c70380d 100644 --- a/src/x11/Makefile.am +++ b/src/x11/Makefile.am @@ -22,9 +22,9 @@ AM_CFLAGS = -DLINUX -DIN_LIBVA -I$(top_srcdir)/src $(DRM_CFLAGS) noinst_LTLIBRARIES = libva_x11.la -libva_x11includedir = ${includedir}/va +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 +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 +EXTRA_DIST = va_dristr.h va_dri2str.h va_dri2tokens.h va_nvctrl.h diff --git a/src/x11/dri2_util.c b/src/x11/dri2_util.c index 1d3c141..ebe7a2c 100644 --- a/src/x11/dri2_util.c +++ b/src/x11/dri2_util.c @@ -5,7 +5,8 @@ #include <xf86drm.h> -#include "X11/Xlib.h" +#include <X11/Xlibint.h> +#include <X11/Xlib.h> #include "va.h" #include "va_backend.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 index 4cb8fcd..ec0bbc8 100644 --- a/src/x11/va_x11.c +++ b/src/x11/va_x11.c @@ -22,6 +22,7 @@ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +#define _GNU_SOURCE 1 #include "config.h" #include "va.h" #include "va_backend.h" @@ -29,9 +30,11 @@ #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> @@ -91,6 +94,7 @@ static void va_DisplayContextDestroy ( } ctx = &((*ctx)->pNext); } + free(pDisplayContext->pDriverContext->dri_state); free(pDisplayContext->pDriverContext); free(pDisplayContext); } @@ -102,63 +106,46 @@ static VAStatus va_DRI2GetDriverName ( ) { 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"); + if (!isDRI2Connected(ctx, driver_name)) 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_SUCCESS; +} + +static VAStatus va_DRIGetDriverName ( + VADisplayContextP pDisplayContext, + char **driver_name +) +{ + VADriverContextP ctx = pDisplayContext->pDriverContext; + + if (!isDRI1Connected(ctx, driver_name)) 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 ( +static VAStatus va_NVCTRL_GetDriverName ( 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; int driver_patch; Bool result = True; - char *x_driver_name = NULL; + char *nvidia_driver_name = NULL; - 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); + result = VA_NVCTRLQueryDirectRenderingCapable(ctx->x11_dpy, ctx->x11_screen, &direct_capable); if (!result) { - va_errorMessage("VA_DRIQueryDirectRenderingCapable failed\n"); + va_errorMessage("VA_NVCTRLQueryDirectRenderingCapable failed\n"); } } if (result) @@ -166,29 +153,27 @@ static VAStatus va_DRIGetDriverName ( result = direct_capable; if (!result) { - va_errorMessage("VA_DRIQueryDirectRenderingCapable returned false\n"); + va_errorMessage("VA_NVCTRLQueryDirectRenderingCapable returned false\n"); } } if (result) { - result = VA_DRIGetClientDriverName(ctx->x11_dpy, ctx->x11_screen, &driver_major, &driver_minor, - &driver_patch, &x_driver_name); + result = VA_NVCTRLGetClientDriverName(ctx->x11_dpy, ctx->x11_screen, &driver_major, &driver_minor, + &driver_patch, &nvidia_driver_name); if (!result) { - va_errorMessage("VA_DRIGetClientDriverName returned false\n"); + va_errorMessage("VA_NVCTRLGetClientDriverName returned false\n"); } } if (result) { vaStatus = VA_STATUS_SUCCESS; - va_infoMessage("VA_DRIGetClientDriverName: %d.%d.%d %s (screen %d)\n", - driver_major, driver_minor, driver_patch, x_driver_name, ctx->x11_screen); - if (driver_name) - *driver_name = strdup(x_driver_name); + 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; } - if (x_driver_name) - XFree(x_driver_name); - return vaStatus; } @@ -197,37 +182,26 @@ static VAStatus va_DisplayContextGetDriverName ( 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; + VAStatus vaStatus; + char *driver_name_env; 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) + if ((driver_name_env = getenv("LIBVA_DRIVER_NAME")) != NULL && 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; - } + *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; } @@ -278,11 +252,12 @@ VADisplay vaGetDisplay ( { /* create new entry */ VADriverContextP pDriverContext; + struct dri_state *dri_state; pDisplayContext = calloc(1, sizeof(*pDisplayContext)); pDriverContext = calloc(1, sizeof(*pDriverContext)); - if (pDisplayContext && pDriverContext) + dri_state = calloc(1, sizeof(*dri_state)); + if (pDisplayContext && pDriverContext && dri_state) { - pDriverContext->old_pNext = (void *)(unsigned long)0xdeadbeef; pDriverContext->x11_dpy = native_dpy; pDisplayContext->pNext = pDisplayContexts; pDisplayContext->pDriverContext = pDriverContext; @@ -290,7 +265,7 @@ VADisplay vaGetDisplay ( pDisplayContext->vaDestroy = va_DisplayContextDestroy; pDisplayContext->vaGetDriverName = va_DisplayContextGetDriverName; pDisplayContexts = pDisplayContext; - pDriverContext->dri_state = calloc(1, sizeof(struct dri_state)); + pDriverContext->dri_state = dri_state; dpy = (VADisplay)pDisplayContext; } else @@ -299,6 +274,8 @@ VADisplay vaGetDisplay ( free(pDisplayContext); if (pDriverContext) free(pDriverContext); + if (dri_state) + free(dri_state); } } diff --git a/test/Makefile.am b/test/Makefile.am index 04a24ab..58e1677 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -31,9 +31,10 @@ AM_CFLAGS = -I$(top_srcdir)/../../include/external/ -I$(top_srcdir)/src -I$(top_ TESTS = $(check_PROGRAMS) -TEST_LIBS = ../src/libva.la +TEST_LIBS = $(top_srcdir)/src/$(libvabackendlib) -vainfo_LDADD = ../src/libva.la +vainfo_LDADD = $(top_srcdir)/src/$(libvabackendlib) +vainfo_DEPENDENCIES = $(top_srcdir)/src/$(libvabackendlib) vainfo_SOURCES = vainfo.c test_01_LDADD = $(TEST_LIBS) diff --git a/test/test_common.c b/test/test_common.c index 8a6ca9f..91774da 100644 --- a/test/test_common.c +++ b/test/test_common.c @@ -63,7 +63,7 @@ void status(const char *msg, ...) int main(int argc, const char* argv[]) { - const char *name = rindex(argv[0], '/'); + const char *name = strrchr(argv[0], '/'); if (name) name++; else |