summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configs/autoconf.in3
-rw-r--r--configs/linux-dri8
-rw-r--r--configs/linux-dri-x86-642
-rw-r--r--configure.ac53
-rw-r--r--src/driclient/src/Makefile19
-rw-r--r--src/gallium/auxiliary/Makefile13
-rw-r--r--src/gallium/auxiliary/SConscript10
-rw-r--r--src/gallium/auxiliary/util/u_format.csv8
-rw-r--r--src/gallium/auxiliary/util/u_format_yuv.c135
-rw-r--r--src/gallium/auxiliary/util/u_format_yuv.h135
-rw-r--r--src/gallium/auxiliary/util/u_video.h (renamed from src/gallium/tests/unit/pipe_barrier_test.c)93
-rw-r--r--src/gallium/auxiliary/vl/vl_bitstream_parser.c208
-rw-r--r--src/gallium/auxiliary/vl/vl_bitstream_parser.h63
-rw-r--r--src/gallium/auxiliary/vl/vl_compositor.c636
-rw-r--r--src/gallium/auxiliary/vl/vl_compositor.h98
-rw-r--r--src/gallium/auxiliary/vl/vl_csc.c206
-rw-r--r--src/gallium/auxiliary/vl/vl_csc.h53
-rw-r--r--src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c1472
-rw-r--r--src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h132
-rw-r--r--src/gallium/auxiliary/vl/vl_types.h41
-rw-r--r--src/gallium/drivers/nv40/nv40_video_context.c48
-rw-r--r--src/gallium/drivers/nv40/nv40_video_context.h38
-rw-r--r--src/gallium/drivers/nvfx/Makefile3
-rw-r--r--src/gallium/drivers/nvfx/nvfx_screen.c2
-rw-r--r--src/gallium/drivers/nvfx/nvfx_state.h1
-rw-r--r--src/gallium/drivers/nvfx/nvfx_video_context.c49
-rw-r--r--src/gallium/drivers/nvfx/nvfx_video_context.h38
-rw-r--r--src/gallium/drivers/r300/r300_video_context.c329
-rw-r--r--src/gallium/drivers/r300/r300_video_context.h40
-rw-r--r--src/gallium/drivers/softpipe/Makefile5
-rw-r--r--src/gallium/drivers/softpipe/SConscript1
-rw-r--r--src/gallium/drivers/softpipe/sp_screen.c2
-rw-r--r--src/gallium/drivers/softpipe/sp_texture.h1
-rw-r--r--src/gallium/drivers/softpipe/sp_video_context.c526
-rw-r--r--src/gallium/drivers/softpipe/sp_video_context.h69
-rw-r--r--src/gallium/include/pipe/p_defines.h28
-rw-r--r--src/gallium/include/pipe/p_format.h18
-rw-r--r--src/gallium/include/pipe/p_screen.h9
-rw-r--r--src/gallium/include/pipe/p_video_context.h178
-rw-r--r--src/gallium/include/pipe/p_video_state.h133
-rw-r--r--src/gallium/state_trackers/vdpau/Makefile27
-rw-r--r--src/gallium/state_trackers/vdpau/bitmap.c75
-rw-r--r--src/gallium/state_trackers/vdpau/color.c0
-rw-r--r--src/gallium/state_trackers/vdpau/decode.c277
-rw-r--r--src/gallium/state_trackers/vdpau/device.c155
-rw-r--r--src/gallium/state_trackers/vdpau/ftab.c122
-rw-r--r--src/gallium/state_trackers/vdpau/header.c0
-rw-r--r--src/gallium/state_trackers/vdpau/htab.c94
-rw-r--r--src/gallium/state_trackers/vdpau/mixer.c0
-rw-r--r--src/gallium/state_trackers/vdpau/mpeg2_bitstream_parser.c44
-rw-r--r--src/gallium/state_trackers/vdpau/mpeg2_bitstream_parser.h41
-rw-r--r--src/gallium/state_trackers/vdpau/output.c43
-rw-r--r--src/gallium/state_trackers/vdpau/preemption.c0
-rw-r--r--src/gallium/state_trackers/vdpau/presentation.c121
-rw-r--r--src/gallium/state_trackers/vdpau/query.c281
-rw-r--r--src/gallium/state_trackers/vdpau/render.c0
-rw-r--r--src/gallium/state_trackers/vdpau/surface.c192
-rw-r--r--src/gallium/state_trackers/vdpau/vdpau_private.h216
-rw-r--r--src/gallium/state_trackers/xorg/xvmc/Makefile16
-rw-r--r--src/gallium/state_trackers/xorg/xvmc/attributes.c50
-rw-r--r--src/gallium/state_trackers/xorg/xvmc/block.c92
-rw-r--r--src/gallium/state_trackers/xorg/xvmc/context.c298
-rw-r--r--src/gallium/state_trackers/xorg/xvmc/subpicture.c440
-rw-r--r--src/gallium/state_trackers/xorg/xvmc/surface.c501
-rw-r--r--src/gallium/state_trackers/xorg/xvmc/tests/.gitignore6
-rw-r--r--src/gallium/state_trackers/xorg/xvmc/tests/Makefile31
-rw-r--r--src/gallium/state_trackers/xorg/xvmc/tests/test_blocks.c111
-rw-r--r--src/gallium/state_trackers/xorg/xvmc/tests/test_context.c119
-rw-r--r--src/gallium/state_trackers/xorg/xvmc/tests/test_rendering.c317
-rw-r--r--src/gallium/state_trackers/xorg/xvmc/tests/test_subpicture.c182
-rw-r--r--src/gallium/state_trackers/xorg/xvmc/tests/test_surface.c98
-rw-r--r--src/gallium/state_trackers/xorg/xvmc/tests/testlib.c146
-rw-r--r--src/gallium/state_trackers/xorg/xvmc/tests/testlib.h69
-rw-r--r--src/gallium/state_trackers/xorg/xvmc/tests/xvmc_bench.c300
-rw-r--r--src/gallium/state_trackers/xorg/xvmc/xvmc_private.h102
-rw-r--r--src/gallium/targets/Makefile.vdpau62
-rw-r--r--src/gallium/targets/Makefile.xvmc61
-rw-r--r--src/gallium/targets/dri-nouveau/Makefile1
-rw-r--r--src/gallium/targets/vdpau-softpipe/Makefile19
-rw-r--r--src/gallium/targets/xvmc-nouveau/Makefile23
-rw-r--r--src/gallium/targets/xvmc-softpipe/Makefile19
-rw-r--r--src/gallium/tests/python/retrace/README17
-rwxr-xr-xsrc/gallium/tests/python/retrace/format.py173
-rwxr-xr-xsrc/gallium/tests/python/retrace/model.py213
-rwxr-xr-xsrc/gallium/tests/python/retrace/parse.py392
-rwxr-xr-xsrc/gallium/tests/python/retrace/parser.py34
-rw-r--r--src/gallium/tests/python/samples/gs.py254
-rw-r--r--src/gallium/tests/python/samples/tri.py233
-rw-r--r--src/gallium/tests/python/tests/.gitignore3
-rwxr-xr-xsrc/gallium/tests/python/tests/base.py399
-rw-r--r--src/gallium/tests/python/tests/regress/fragment-shader/.gitignore1
-rw-r--r--src/gallium/tests/python/tests/regress/fragment-shader/frag-abs.sh13
-rw-r--r--src/gallium/tests/python/tests/regress/fragment-shader/frag-add.sh8
-rw-r--r--src/gallium/tests/python/tests/regress/fragment-shader/frag-cb-1d.sh13
-rw-r--r--src/gallium/tests/python/tests/regress/fragment-shader/frag-dp3.sh8
-rw-r--r--src/gallium/tests/python/tests/regress/fragment-shader/frag-dp4.sh8
-rw-r--r--src/gallium/tests/python/tests/regress/fragment-shader/frag-dst.sh8
-rw-r--r--src/gallium/tests/python/tests/regress/fragment-shader/frag-ex2.sh11
-rw-r--r--src/gallium/tests/python/tests/regress/fragment-shader/frag-flr.sh15
-rw-r--r--src/gallium/tests/python/tests/regress/fragment-shader/frag-frc.sh13
-rw-r--r--src/gallium/tests/python/tests/regress/fragment-shader/frag-lg2.sh15
-rw-r--r--src/gallium/tests/python/tests/regress/fragment-shader/frag-lit.sh8
-rw-r--r--src/gallium/tests/python/tests/regress/fragment-shader/frag-lrp.sh11
-rw-r--r--src/gallium/tests/python/tests/regress/fragment-shader/frag-mad.sh11
-rw-r--r--src/gallium/tests/python/tests/regress/fragment-shader/frag-max.sh10
-rw-r--r--src/gallium/tests/python/tests/regress/fragment-shader/frag-min.sh10
-rw-r--r--src/gallium/tests/python/tests/regress/fragment-shader/frag-mov.sh8
-rw-r--r--src/gallium/tests/python/tests/regress/fragment-shader/frag-mul.sh10
-rw-r--r--src/gallium/tests/python/tests/regress/fragment-shader/frag-rcp.sh15
-rw-r--r--src/gallium/tests/python/tests/regress/fragment-shader/frag-rsq.sh15
-rw-r--r--src/gallium/tests/python/tests/regress/fragment-shader/frag-sge.sh13
-rw-r--r--src/gallium/tests/python/tests/regress/fragment-shader/frag-slt.sh13
-rw-r--r--src/gallium/tests/python/tests/regress/fragment-shader/frag-srcmod-abs.sh13
-rw-r--r--src/gallium/tests/python/tests/regress/fragment-shader/frag-srcmod-absneg.sh15
-rw-r--r--src/gallium/tests/python/tests/regress/fragment-shader/frag-srcmod-neg.sh11
-rw-r--r--src/gallium/tests/python/tests/regress/fragment-shader/frag-srcmod-swz.sh8
-rw-r--r--src/gallium/tests/python/tests/regress/fragment-shader/frag-sub.sh8
-rw-r--r--src/gallium/tests/python/tests/regress/fragment-shader/frag-xpd.sh8
-rw-r--r--src/gallium/tests/python/tests/regress/fragment-shader/fragment-shader.py257
-rw-r--r--src/gallium/tests/python/tests/regress/vertex-shader/.gitignore1
-rw-r--r--src/gallium/tests/python/tests/regress/vertex-shader/vertex-shader.py287
-rwxr-xr-xsrc/gallium/tests/python/tests/texture_render.py320
-rwxr-xr-xsrc/gallium/tests/python/tests/tree.py23
-rw-r--r--src/gallium/tests/trivial/.gitignore3
-rw-r--r--src/gallium/tests/trivial/Makefile49
-rw-r--r--src/gallium/tests/unit/Makefile49
-rw-r--r--src/gallium/tests/unit/SConscript33
-rw-r--r--src/gallium/tests/unit/u_cache_test.c121
-rw-r--r--src/gallium/tests/unit/u_format_test.c716
-rw-r--r--src/gallium/tests/unit/u_half_test.c32
-rw-r--r--src/gallium/winsys/g3dvl/Makefile12
-rw-r--r--src/gallium/winsys/g3dvl/dri/Makefile15
-rw-r--r--src/gallium/winsys/g3dvl/dri/XF86dri.c (renamed from src/driclient/src/XF86dri.c)0
-rw-r--r--src/gallium/winsys/g3dvl/dri/dri2.c669
-rw-r--r--src/gallium/winsys/g3dvl/dri/dri2.h106
-rw-r--r--src/gallium/winsys/g3dvl/dri/dri_winsys.c287
-rw-r--r--src/gallium/winsys/g3dvl/dri/driclient.c (renamed from src/driclient/src/driclient.c)90
-rw-r--r--src/gallium/winsys/g3dvl/dri/driclient.h (renamed from src/driclient/include/driclient.h)20
-rw-r--r--src/gallium/winsys/g3dvl/dri/xf86dri.h (renamed from src/driclient/include/xf86dri.h)0
-rw-r--r--src/gallium/winsys/g3dvl/dri/xf86dristr.h (renamed from src/driclient/src/xf86dristr.h)0
-rw-r--r--src/gallium/winsys/g3dvl/drm/Makefile12
-rw-r--r--src/gallium/winsys/g3dvl/drm/Makefile.template66
-rw-r--r--src/gallium/winsys/g3dvl/drm/nouveau/Makefile23
-rw-r--r--src/gallium/winsys/g3dvl/drm/radeon/Makefile20
-rw-r--r--src/gallium/winsys/g3dvl/vl_winsys.h69
-rw-r--r--src/gallium/winsys/g3dvl/xlib/xsp_winsys.c202
146 files changed, 11142 insertions, 4015 deletions
diff --git a/configs/autoconf.in b/configs/autoconf.in
index 9bdbefebddd..d7eb162b684 100644
--- a/configs/autoconf.in
+++ b/configs/autoconf.in
@@ -157,6 +157,9 @@ DRI_DRIVER_SEARCH_DIR = @DRI_DRIVER_SEARCH_DIR@
# EGL driver install directory
EGL_DRIVER_INSTALL_DIR = @EGL_DRIVER_INSTALL_DIR@
+# VDPAU library install directory
+VDPAU_LIB_INSTALL_DIR=@VDPAU_LIB_INSTALL_DIR@
+
# Xorg driver install directory (for xorg state-tracker)
XORG_DRIVER_INSTALL_DIR = @XORG_DRIVER_INSTALL_DIR@
diff --git a/configs/linux-dri b/configs/linux-dri
index 64fc407c42e..9a0253f919b 100644
--- a/configs/linux-dri
+++ b/configs/linux-dri
@@ -57,12 +57,12 @@ SRC_DIRS := glx egl $(SRC_DIRS)
EGL_DRIVERS_DIRS = glx
DRIVER_DIRS = dri
+
GALLIUM_WINSYS_DIRS = sw sw/xlib drm/vmware drm/intel drm/i965
-GALLIUM_TARGET_DIRS =
-GALLIUM_STATE_TRACKERS_DIRS = egl
+GALLIUM_TARGET_DIRS = egl-swrast
+GALLIUM_STATE_TRACKERS_DIRS = egl vdpau
-DRI_DIRS = i810 i915 i965 mach64 mga r128 r200 r300 radeon \
- savage sis tdfx unichrome swrast
+DRI_DIRS = r300 radeon swrast
INTEL_LIBS = `pkg-config --libs libdrm_intel`
INTEL_CFLAGS = `pkg-config --cflags libdrm_intel`
diff --git a/configs/linux-dri-x86-64 b/configs/linux-dri-x86-64
index 656cf6140d7..90e6c215adb 100644
--- a/configs/linux-dri-x86-64
+++ b/configs/linux-dri-x86-64
@@ -20,5 +20,5 @@ EXTRA_LIB_PATH=-L/usr/X11R6/lib64
# the new interface. i810 are missing because there is no x86-64
# system where they could *ever* be used.
#
-DRI_DIRS = i915 i965 mach64 mga r128 r200 r300 radeon savage tdfx unichrome
+DRI_DIRS = swrast
diff --git a/configure.ac b/configure.ac
index 364ee039470..0344be00703 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1331,6 +1331,20 @@ yes)
VG_LIB_DEPS="$VG_LIB_DEPS -lpthread"
EGL_CLIENT_APIS="$EGL_CLIENT_APIS "'$(VG_LIB)'
;;
+ xorg/xvmc)
+ # Check for xvmc?
+ if test "x$enable_gallium_g3dvl" != xyes; then
+ AC_MSG_ERROR([cannot build XvMC state tracker without --enable-gallium-g3dvl])
+ fi
+ HAVE_ST_XVMC="yes"
+ ;;
+ vdpau)
+ # Check for libvdpau?
+ if test "x$enable_gallium_g3dvl" != xyes; then
+ AC_MSG_ERROR([cannot build vdpau state tracker without --enable-gallium-g3dvl])
+ fi
+ HAVE_ST_VDPAU="yes"
+ ;;
esac
if test -n "$tracker"; then
@@ -1465,7 +1479,7 @@ dnl
dnl Gallium helper functions
dnl
gallium_check_st() {
- if test "x$HAVE_ST_DRI" = xyes || test "x$HAVE_ST_XORG" = xyes; then
+ if test "x$HAVE_ST_DRI" = xyes || test "x$HAVE_ST_EGL" = xyes || test "x$HAVE_ST_XORG" = xyes || test "x$HAVE_ST_XVMC" = xyes || test "x$HAVE_ST_VDPAU" = xyes; then
GALLIUM_WINSYS_DIRS="$GALLIUM_WINSYS_DIRS $1"
fi
if test "x$HAVE_ST_DRI" = xyes && test "x$2" != x; then
@@ -1474,6 +1488,15 @@ gallium_check_st() {
if test "x$HAVE_ST_XORG" = xyes && test "x$3" != x; then
GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS $3"
fi
+ if test "x$HAVE_ST_XORG" = xyes && test "x$4" != x; then
+ GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS $4"
+ fi
+ if test "x$HAVE_ST_XVMC" = xyes && test "x$5" != x; then
+ GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS $5"
+ fi
+ if test "x$HAVE_ST_VDPAU" = xyes && test "x$6" != x; then
+ GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS $6"
+ fi
}
@@ -1576,8 +1599,34 @@ AC_ARG_ENABLE([gallium-nouveau],
[enable_gallium_nouveau=no])
if test "x$enable_gallium_nouveau" = xyes; then
GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS nouveau nvfx nv50"
- gallium_check_st "nouveau/drm" "dri-nouveau" "xorg-nouveau"
+ gallium_check_st "nouveau/drm" "dri-nouveau" "egl-nouveau" "xorg-nouveau" "xvmc-nouveau"
+fi
+
+dnl
+dnl Gallium G3DVL configuration
+dnl
+AC_ARG_ENABLE([gallium-g3dvl],
+ [AS_HELP_STRING([--enable-gallium-g3dvl],
+ [build gallium g3dvl @<:@default=disabled@:>@])],
+ [enable_gallium_g3dvl="$enableval"],
+ [enable_gallium_g3dvl=no])
+if test "x$enable_gallium_g3dvl" = xyes; then
+ case "$mesa_driver" in
+ xlib)
+ GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS vdpau-softpipe"
+ ;;
+ dri)
+ GALLIUM_WINSYS_DIRS="$GALLIUM_WINSYS_DIRS g3dvl/dri"
+ ;;
+ esac
fi
+dnl Directory for VDPAU libs
+AC_ARG_WITH([vdpau-libdir],
+ [AS_HELP_STRING([--with-vdpau-libdir=DIR],
+ [directory for the VDPAU libraries @<:@default=${libdir}/vdpau@:>@])],
+ [VDPAU_LIB_INSTALL_DIR="$withval"],
+ [VDPAU_LIB_INSTALL_DIR='${libdir}/vdpau'])
+AC_SUBST([VDPAU_LIB_INSTALL_DIR])
dnl
dnl Gallium swrast configuration
diff --git a/src/driclient/src/Makefile b/src/driclient/src/Makefile
deleted file mode 100644
index 34435a2086e..00000000000
--- a/src/driclient/src/Makefile
+++ /dev/null
@@ -1,19 +0,0 @@
-TARGET = libdriclient.a
-OBJECTS = driclient.o XF86dri.o
-DRMDIR ?= /usr
-
-CFLAGS += -g -Wall -fPIC -I../include -I${DRMDIR}/include -I${DRMDIR}/include/drm
-
-#############################################
-
-.PHONY = all clean
-
-all: ${TARGET}
-
-${TARGET}: ${OBJECTS}
- ar rcs $@ $^
- if ! test -d ../lib; then mkdir ../lib; fi
- cp ${TARGET} ../lib
-
-clean:
- rm -rf ${OBJECTS} ${TARGET} ../lib/${TARGET}
diff --git a/src/gallium/auxiliary/Makefile b/src/gallium/auxiliary/Makefile
index 02af4d9280a..05096b12a86 100644
--- a/src/gallium/auxiliary/Makefile
+++ b/src/gallium/auxiliary/Makefile
@@ -143,14 +143,11 @@ C_SOURCES = \
util/u_transfer.c \
util/u_resource.c \
util/u_upload_mgr.c \
- target-helpers/wrap_screen.c
-
- # Disabling until pipe-video branch gets merged in
- #vl/vl_bitstream_parser.c \
- #vl/vl_mpeg12_mc_renderer.c \
- #vl/vl_compositor.c \
- #vl/vl_csc.c \
- #vl/vl_shader_build.c \
+ target-helpers/wrap_screen.c \
+ vl/vl_bitstream_parser.c \
+ vl/vl_mpeg12_mc_renderer.c \
+ vl/vl_compositor.c \
+ vl/vl_csc.c
GALLIVM_SOURCES = \
gallivm/lp_bld_arit.c \
diff --git a/src/gallium/auxiliary/SConscript b/src/gallium/auxiliary/SConscript
index 48547c4b2c6..a18f7c0b2a3 100644
--- a/src/gallium/auxiliary/SConscript
+++ b/src/gallium/auxiliary/SConscript
@@ -192,12 +192,10 @@ source = [
'util/u_tile.c',
'util/u_transfer.c',
'util/u_upload_mgr.c',
- # Disabling until pipe-video branch gets merged in
- #'vl/vl_bitstream_parser.c',
- #'vl/vl_mpeg12_mc_renderer.c',
- #'vl/vl_compositor.c',
- #'vl/vl_csc.c',
- #'vl/vl_shader_build.c',
+ 'vl/vl_bitstream_parser.c',
+ 'vl/vl_mpeg12_mc_renderer.c',
+ 'vl/vl_compositor.c',
+ 'vl/vl_csc.c',
'target-helpers/wrap_screen.c',
]
diff --git a/src/gallium/auxiliary/util/u_format.csv b/src/gallium/auxiliary/util/u_format.csv
index 016e73c4a1d..0811280b97b 100644
--- a/src/gallium/auxiliary/util/u_format.csv
+++ b/src/gallium/auxiliary/util/u_format.csv
@@ -230,3 +230,11 @@ PIPE_FORMAT_R32G32B32A32_FIXED , plain, 1, 1, h32 , h32 , h32 , h32 , xyzw, r
PIPE_FORMAT_R10G10B10X2_USCALED , plain, 1, 1, u10 , u10 , u10 , x2 , xyz1, rgb
# A.k.a. D3DDECLTYPE_DEC3N
PIPE_FORMAT_R10G10B10X2_SNORM , plain, 1, 1, sn10, sn10, sn10 , x2 , xyz1, rgb
+
+PIPE_FORMAT_YV12 , subsampled, 1, 1, x8 , x8 , x8 , x8 , xyzw, yuv
+PIPE_FORMAT_YV16 , subsampled, 1, 1, x8 , x8 , x8 , x8 , xyzw, yuv
+PIPE_FORMAT_IYUV , subsampled, 1, 1, x8 , x8 , x8 , x8 , xyzw, yuv
+PIPE_FORMAT_NV12 , subsampled, 1, 1, x8 , x8 , x8 , x8 , xyzw, yuv
+PIPE_FORMAT_NV21 , subsampled, 1, 1, x8 , x8 , x8 , x8 , xyzw, yuv
+PIPE_FORMAT_IA44 , subsampled, 1, 1, x8 , x8 , x8 , x8 , xyzw, yuv
+PIPE_FORMAT_AI44 , subsampled, 1, 1, x8 , x8 , x8 , x8 , xyzw, yuv
diff --git a/src/gallium/auxiliary/util/u_format_yuv.c b/src/gallium/auxiliary/util/u_format_yuv.c
index ab8bf29c97b..64ea0b35347 100644
--- a/src/gallium/auxiliary/util/u_format_yuv.c
+++ b/src/gallium/auxiliary/util/u_format_yuv.c
@@ -1045,3 +1045,138 @@ util_format_yuyv_fetch_rgba_float(float *dst, const uint8_t *src,
dst[3] = 1.0f;
}
+
+/* XXX: Stubbed for now */
+void
+util_format_yv12_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
+ const uint8_t *src_row, unsigned src_stride,
+ unsigned width, unsigned height) {}
+void
+util_format_yv12_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
+ const uint8_t *src_row, unsigned src_stride,
+ unsigned width, unsigned height) {}
+void
+util_format_yv12_unpack_rgba_float(float *dst_row, unsigned dst_stride,
+ const uint8_t *src_row, unsigned src_stride,
+ unsigned width, unsigned height) {}
+void
+util_format_yv12_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
+ const float *src_row, unsigned src_stride,
+ unsigned width, unsigned height) {}
+void
+util_format_yv12_fetch_rgba_float(float *dst, const uint8_t *src,
+ unsigned i, unsigned j) {}
+void
+util_format_yv16_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
+ const uint8_t *src_row, unsigned src_stride,
+ unsigned width, unsigned height) {}
+void
+util_format_yv16_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
+ const uint8_t *src_row, unsigned src_stride,
+ unsigned width, unsigned height) {}
+void
+util_format_yv16_unpack_rgba_float(float *dst_row, unsigned dst_stride,
+ const uint8_t *src_row, unsigned src_stride,
+ unsigned width, unsigned height) {}
+void
+util_format_yv16_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
+ const float *src_row, unsigned src_stride,
+ unsigned width, unsigned height) {}
+void
+util_format_yv16_fetch_rgba_float(float *dst, const uint8_t *src,
+ unsigned i, unsigned j) {}
+void
+util_format_iyuv_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
+ const uint8_t *src_row, unsigned src_stride,
+ unsigned width, unsigned height) {}
+void
+util_format_iyuv_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
+ const uint8_t *src_row, unsigned src_stride,
+ unsigned width, unsigned height) {}
+void
+util_format_iyuv_unpack_rgba_float(float *dst_row, unsigned dst_stride,
+ const uint8_t *src_row, unsigned src_stride,
+ unsigned width, unsigned height) {}
+void
+util_format_iyuv_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
+ const float *src_row, unsigned src_stride,
+ unsigned width, unsigned height) {}
+void
+util_format_iyuv_fetch_rgba_float(float *dst, const uint8_t *src,
+ unsigned i, unsigned j) {}
+void
+util_format_nv12_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
+ const uint8_t *src_row, unsigned src_stride,
+ unsigned width, unsigned height) {}
+void
+util_format_nv12_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
+ const uint8_t *src_row, unsigned src_stride,
+ unsigned width, unsigned height) {}
+void
+util_format_nv12_unpack_rgba_float(float *dst_row, unsigned dst_stride,
+ const uint8_t *src_row, unsigned src_stride,
+ unsigned width, unsigned height) {}
+void
+util_format_nv12_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
+ const float *src_row, unsigned src_stride,
+ unsigned width, unsigned height) {}
+void
+util_format_nv12_fetch_rgba_float(float *dst, const uint8_t *src,
+ unsigned i, unsigned j) {}
+void
+util_format_nv21_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
+ const uint8_t *src_row, unsigned src_stride,
+ unsigned width, unsigned height) {}
+void
+util_format_nv21_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
+ const uint8_t *src_row, unsigned src_stride,
+ unsigned width, unsigned height) {}
+void
+util_format_nv21_unpack_rgba_float(float *dst_row, unsigned dst_stride,
+ const uint8_t *src_row, unsigned src_stride,
+ unsigned width, unsigned height) {}
+void
+util_format_nv21_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
+ const float *src_row, unsigned src_stride,
+ unsigned width, unsigned height) {}
+void
+util_format_nv21_fetch_rgba_float(float *dst, const uint8_t *src,
+ unsigned i, unsigned j) {}
+void
+util_format_ia44_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
+ const uint8_t *src_row, unsigned src_stride,
+ unsigned width, unsigned height) {}
+void
+util_format_ia44_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
+ const uint8_t *src_row, unsigned src_stride,
+ unsigned width, unsigned height) {}
+void
+util_format_ia44_unpack_rgba_float(float *dst_row, unsigned dst_stride,
+ const uint8_t *src_row, unsigned src_stride,
+ unsigned width, unsigned height) {}
+void
+util_format_ia44_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
+ const float *src_row, unsigned src_stride,
+ unsigned width, unsigned height) {}
+void
+util_format_ia44_fetch_rgba_float(float *dst, const uint8_t *src,
+ unsigned i, unsigned j) {}
+void
+util_format_ai44_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
+ const uint8_t *src_row, unsigned src_stride,
+ unsigned width, unsigned height) {}
+void
+util_format_ai44_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
+ const uint8_t *src_row, unsigned src_stride,
+ unsigned width, unsigned height) {}
+void
+util_format_ai44_unpack_rgba_float(float *dst_row, unsigned dst_stride,
+ const uint8_t *src_row, unsigned src_stride,
+ unsigned width, unsigned height) {}
+void
+util_format_ai44_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
+ const float *src_row, unsigned src_stride,
+ unsigned width, unsigned height) {}
+void
+util_format_ai44_fetch_rgba_float(float *dst, const uint8_t *src,
+ unsigned i, unsigned j) {}
diff --git a/src/gallium/auxiliary/util/u_format_yuv.h b/src/gallium/auxiliary/util/u_format_yuv.h
index dc9632346d1..9f2365a5266 100644
--- a/src/gallium/auxiliary/util/u_format_yuv.h
+++ b/src/gallium/auxiliary/util/u_format_yuv.h
@@ -169,6 +169,141 @@ void
util_format_yuyv_fetch_rgba_float(float *dst, const uint8_t *src,
unsigned i, unsigned j);
+/* XXX: Stubbed for now */
+void
+util_format_yv12_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
+ const uint8_t *src_row, unsigned src_stride,
+ unsigned width, unsigned height);
+void
+util_format_yv12_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
+ const uint8_t *src_row, unsigned src_stride,
+ unsigned width, unsigned height);
+void
+util_format_yv12_unpack_rgba_float(float *dst_row, unsigned dst_stride,
+ const uint8_t *src_row, unsigned src_stride,
+ unsigned width, unsigned height);
+void
+util_format_yv12_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
+ const float *src_row, unsigned src_stride,
+ unsigned width, unsigned height);
+void
+util_format_yv12_fetch_rgba_float(float *dst, const uint8_t *src,
+ unsigned i, unsigned j);
+void
+util_format_yv16_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
+ const uint8_t *src_row, unsigned src_stride,
+ unsigned width, unsigned height);
+void
+util_format_yv16_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
+ const uint8_t *src_row, unsigned src_stride,
+ unsigned width, unsigned height);
+void
+util_format_yv16_unpack_rgba_float(float *dst_row, unsigned dst_stride,
+ const uint8_t *src_row, unsigned src_stride,
+ unsigned width, unsigned height);
+void
+util_format_yv16_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
+ const float *src_row, unsigned src_stride,
+ unsigned width, unsigned height);
+void
+util_format_yv16_fetch_rgba_float(float *dst, const uint8_t *src,
+ unsigned i, unsigned j);
+void
+util_format_iyuv_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
+ const uint8_t *src_row, unsigned src_stride,
+ unsigned width, unsigned height);
+void
+util_format_iyuv_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
+ const uint8_t *src_row, unsigned src_stride,
+ unsigned width, unsigned height);
+void
+util_format_iyuv_unpack_rgba_float(float *dst_row, unsigned dst_stride,
+ const uint8_t *src_row, unsigned src_stride,
+ unsigned width, unsigned height);
+void
+util_format_iyuv_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
+ const float *src_row, unsigned src_stride,
+ unsigned width, unsigned height);
+void
+util_format_iyuv_fetch_rgba_float(float *dst, const uint8_t *src,
+ unsigned i, unsigned j);
+void
+util_format_nv12_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
+ const uint8_t *src_row, unsigned src_stride,
+ unsigned width, unsigned height);
+void
+util_format_nv12_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
+ const uint8_t *src_row, unsigned src_stride,
+ unsigned width, unsigned height);
+void
+util_format_nv12_unpack_rgba_float(float *dst_row, unsigned dst_stride,
+ const uint8_t *src_row, unsigned src_stride,
+ unsigned width, unsigned height);
+void
+util_format_nv12_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
+ const float *src_row, unsigned src_stride,
+ unsigned width, unsigned height);
+void
+util_format_nv12_fetch_rgba_float(float *dst, const uint8_t *src,
+ unsigned i, unsigned j);
+void
+util_format_nv21_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
+ const uint8_t *src_row, unsigned src_stride,
+ unsigned width, unsigned height);
+void
+util_format_nv21_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
+ const uint8_t *src_row, unsigned src_stride,
+ unsigned width, unsigned height);
+void
+util_format_nv21_unpack_rgba_float(float *dst_row, unsigned dst_stride,
+ const uint8_t *src_row, unsigned src_stride,
+ unsigned width, unsigned height);
+void
+util_format_nv21_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
+ const float *src_row, unsigned src_stride,
+ unsigned width, unsigned height);
+void
+util_format_nv21_fetch_rgba_float(float *dst, const uint8_t *src,
+ unsigned i, unsigned j);
+void
+util_format_ia44_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
+ const uint8_t *src_row, unsigned src_stride,
+ unsigned width, unsigned height);
+void
+util_format_ia44_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
+ const uint8_t *src_row, unsigned src_stride,
+ unsigned width, unsigned height);
+void
+util_format_ia44_unpack_rgba_float(float *dst_row, unsigned dst_stride,
+ const uint8_t *src_row, unsigned src_stride,
+ unsigned width, unsigned height);
+void
+util_format_ia44_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
+ const float *src_row, unsigned src_stride,
+ unsigned width, unsigned height);
+void
+util_format_ia44_fetch_rgba_float(float *dst, const uint8_t *src,
+ unsigned i, unsigned j);
+void
+util_format_ai44_unpack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
+ const uint8_t *src_row, unsigned src_stride,
+ unsigned width, unsigned height);
+void
+util_format_ai44_pack_rgba_8unorm(uint8_t *dst_row, unsigned dst_stride,
+ const uint8_t *src_row, unsigned src_stride,
+ unsigned width, unsigned height);
+void
+util_format_ai44_unpack_rgba_float(float *dst_row, unsigned dst_stride,
+ const uint8_t *src_row, unsigned src_stride,
+ unsigned width, unsigned height);
+void
+util_format_ai44_pack_rgba_float(uint8_t *dst_row, unsigned dst_stride,
+ const float *src_row, unsigned src_stride,
+ unsigned width, unsigned height);
+void
+util_format_ai44_fetch_rgba_float(float *dst, const uint8_t *src,
+ unsigned i, unsigned j);
+
void
util_format_r8g8_b8g8_unorm_unpack_rgba_float(float *dst_row, unsigned dst_stride,
diff --git a/src/gallium/tests/unit/pipe_barrier_test.c b/src/gallium/auxiliary/util/u_video.h
index f5d72b0abae..78cceb6bcf2 100644
--- a/src/gallium/tests/unit/pipe_barrier_test.c
+++ b/src/gallium/auxiliary/util/u_video.h
@@ -1,6 +1,6 @@
/**************************************************************************
*
- * Copyright 2009-2010 VMware, Inc.
+ * Copyright 2009 Younes Manton.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -18,69 +18,54 @@
* 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 VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS 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 U_VIDEO_H
+#define U_VIDEO_H
-/*
- * Test case for pipe_barrier.
- *
- * The test succeeds if no thread exits before all the other threads reach
- * the barrier.
- */
-
-
-#include <stdio.h>
-
-#include "os/os_thread.h"
-#include "os/os_time.h"
-
-
-#define NUM_THREADS 10
+#ifdef __cplusplus
+extern "C" {
+#endif
-static pipe_thread threads[NUM_THREADS];
-static pipe_barrier barrier;
-static int thread_ids[NUM_THREADS];
+#include <pipe/p_defines.h>
+/* u_reduce_video_profile() needs these */
+#include <pipe/p_compiler.h>
+#include <util/u_debug.h>
-static PIPE_THREAD_ROUTINE(thread_function, thread_data)
+static INLINE enum pipe_video_codec
+u_reduce_video_profile(enum pipe_video_profile profile)
{
- int thread_id = *((int *) thread_data);
-
- printf("thread %d starting\n", thread_id);
- os_time_sleep(thread_id * 1000 * 1000);
- printf("thread %d before barrier\n", thread_id);
- pipe_barrier_wait(&barrier);
- printf("thread %d exiting\n", thread_id);
-
- return NULL;
-}
-
-
-int main()
-{
- int i;
-
- printf("pipe_barrier_test starting\n");
-
- pipe_barrier_init(&barrier, NUM_THREADS);
-
- for (i = 0; i < NUM_THREADS; i++) {
- thread_ids[i] = i;
- threads[i] = pipe_thread_create(thread_function, (void *) &thread_ids[i]);
- }
-
- for (i = 0; i < NUM_THREADS; i++ ) {
- pipe_thread_wait(threads[i]);
+ switch (profile)
+ {
+ case PIPE_VIDEO_PROFILE_MPEG1:
+ case PIPE_VIDEO_PROFILE_MPEG2_SIMPLE:
+ case PIPE_VIDEO_PROFILE_MPEG2_MAIN:
+ return PIPE_VIDEO_CODEC_MPEG12;
+
+ case PIPE_VIDEO_PROFILE_MPEG4_SIMPLE:
+ case PIPE_VIDEO_PROFILE_MPEG4_ADVANCED_SIMPLE:
+ return PIPE_VIDEO_CODEC_MPEG4;
+
+ case PIPE_VIDEO_PROFILE_VC1_SIMPLE:
+ case PIPE_VIDEO_PROFILE_VC1_MAIN:
+ case PIPE_VIDEO_PROFILE_VC1_ADVANCED:
+ return PIPE_VIDEO_CODEC_VC1;
+
+ case PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE:
+ case PIPE_VIDEO_PROFILE_MPEG4_AVC_MAIN:
+ case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH:
+ return PIPE_VIDEO_CODEC_MPEG4_AVC;
+
+ default:
+ assert(0);
+ return PIPE_VIDEO_CODEC_UNKNOWN;
}
-
- pipe_barrier_destroy(&barrier);
-
- printf("pipe_barrier_test exiting\n");
-
- return 0;
}
+
+#endif /* U_VIDEO_H */
diff --git a/src/gallium/auxiliary/vl/vl_bitstream_parser.c b/src/gallium/auxiliary/vl/vl_bitstream_parser.c
new file mode 100644
index 00000000000..f07b3443b92
--- /dev/null
+++ b/src/gallium/auxiliary/vl/vl_bitstream_parser.c
@@ -0,0 +1,208 @@
+/**************************************************************************
+ *
+ * Copyright 2009 Younes Manton.
+ * 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 TUNGSTEN GRAPHICS 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.
+ *
+ **************************************************************************/
+
+#include "vl_bitstream_parser.h"
+#include <assert.h>
+#include <limits.h>
+#include <util/u_memory.h>
+#include <stdio.h>
+
+inline void endian_swap_ushort(unsigned short *x)
+{
+ x[0] = (x[0]>>8) |
+ (x[0]<<8);
+}
+
+inline void endian_swap_uint(unsigned int *x)
+{
+ x[0] = (x[0]>>24) |
+ ((x[0]<<8) & 0x00FF0000) |
+ ((x[0]>>8) & 0x0000FF00) |
+ (x[0]<<24);
+}
+
+inline void endian_swap_ulonglong(unsigned long long *x)
+{
+ x[0] = (x[0]>>56) |
+ ((x[0]<<40) & 0x00FF000000000000) |
+ ((x[0]<<24) & 0x0000FF0000000000) |
+ ((x[0]<<8) & 0x000000FF00000000) |
+ ((x[0]>>8) & 0x00000000FF000000) |
+ ((x[0]>>24) & 0x0000000000FF0000) |
+ ((x[0]>>40) & 0x000000000000FF00) |
+ (x[0]<<56);
+}
+
+static unsigned
+grab_bits(unsigned cursor, unsigned how_many_bits, unsigned bitstream_elt)
+{
+ unsigned excess_bits = sizeof(unsigned) * CHAR_BIT - how_many_bits;
+
+ assert(cursor < sizeof(unsigned) * CHAR_BIT);
+ assert(how_many_bits > 0 && how_many_bits <= sizeof(unsigned) * CHAR_BIT);
+ assert(cursor + how_many_bits <= sizeof(unsigned) * CHAR_BIT);
+
+ #ifndef PIPE_ARCH_BIG_ENDIAN
+ switch (sizeof(unsigned)) {
+ case 2:
+ endian_swap_ushort(&bitstream_elt);
+ break;
+ case 4:
+ endian_swap_uint(&bitstream_elt);
+ break;
+ case 8:
+ endian_swap_ulonglong(&bitstream_elt);
+ break;
+ }
+ #endif // !PIPE_ARCH_BIG_ENDIAN
+
+ return (bitstream_elt << cursor) >> (excess_bits);
+}
+
+static unsigned
+show_bits(unsigned cursor, unsigned how_many_bits, const unsigned *bitstream)
+{
+ unsigned cur_int = cursor / (sizeof(unsigned) * CHAR_BIT);
+ unsigned cur_bit = cursor % (sizeof(unsigned) * CHAR_BIT);
+
+ assert(bitstream);
+
+ if (cur_bit + how_many_bits > sizeof(unsigned) * CHAR_BIT) {
+ unsigned lower = grab_bits(cur_bit, sizeof(unsigned) * CHAR_BIT - cur_bit,
+ bitstream[cur_int]);
+ unsigned upper = grab_bits(0, cur_bit + how_many_bits - sizeof(unsigned) * CHAR_BIT,
+ bitstream[cur_int + 1]);
+ return lower | upper << (sizeof(unsigned) * CHAR_BIT - cur_bit);
+ }
+ else
+ return grab_bits(cur_bit, how_many_bits, bitstream[cur_int]);
+}
+
+bool vl_bitstream_parser_init(struct vl_bitstream_parser *parser,
+ unsigned num_bitstreams,
+ const void **bitstreams,
+ const unsigned *sizes)
+{
+ assert(parser);
+ assert(num_bitstreams);
+ assert(bitstreams);
+ assert(sizes);
+
+ parser->num_bitstreams = num_bitstreams;
+ parser->bitstreams = (const unsigned**)bitstreams;
+ parser->sizes = sizes;
+ parser->cur_bitstream = 0;
+ parser->cursor = 0;
+
+ return true;
+}
+
+void vl_bitstream_parser_cleanup(struct vl_bitstream_parser *parser)
+{
+ assert(parser);
+}
+
+unsigned
+vl_bitstream_parser_get_bits(struct vl_bitstream_parser *parser,
+ unsigned how_many_bits)
+{
+ unsigned bits;
+
+ assert(parser);
+
+ bits = vl_bitstream_parser_show_bits(parser, how_many_bits);
+
+ vl_bitstream_parser_forward(parser, how_many_bits);
+
+ return bits;
+}
+
+unsigned
+vl_bitstream_parser_show_bits(struct vl_bitstream_parser *parser,
+ unsigned how_many_bits)
+{
+ unsigned bits = 0;
+ unsigned shift = 0;
+ unsigned cursor;
+ unsigned cur_bitstream;
+
+ assert(parser);
+
+ cursor = parser->cursor;
+ cur_bitstream = parser->cur_bitstream;
+
+ while (1) {
+ unsigned bits_left = parser->sizes[cur_bitstream] * CHAR_BIT - cursor;
+ unsigned bits_to_show = how_many_bits > bits_left ? bits_left : how_many_bits;
+
+ bits |= show_bits(cursor, bits_to_show,
+ parser->bitstreams[cur_bitstream]) << shift;
+
+ if (how_many_bits > bits_to_show) {
+ how_many_bits -= bits_to_show;
+ cursor = 0;
+ ++cur_bitstream;
+ shift += bits_to_show;
+ }
+ else
+ break;
+ }
+
+ return bits;
+}
+
+void vl_bitstream_parser_forward(struct vl_bitstream_parser *parser,
+ unsigned how_many_bits)
+{
+ assert(parser);
+ assert(how_many_bits);
+
+ parser->cursor += how_many_bits;
+
+ while (parser->cursor > parser->sizes[parser->cur_bitstream] * CHAR_BIT) {
+ parser->cursor -= parser->sizes[parser->cur_bitstream++] * CHAR_BIT;
+ assert(parser->cur_bitstream < parser->num_bitstreams);
+ }
+}
+
+void vl_bitstream_parser_rewind(struct vl_bitstream_parser *parser,
+ unsigned how_many_bits)
+{
+ signed c;
+
+ assert(parser);
+ assert(how_many_bits);
+
+ c = parser->cursor - how_many_bits;
+
+ while (c < 0) {
+ c += parser->sizes[parser->cur_bitstream--] * CHAR_BIT;
+ assert(parser->cur_bitstream < parser->num_bitstreams);
+ }
+
+ parser->cursor = (unsigned)c;
+}
diff --git a/src/gallium/auxiliary/vl/vl_bitstream_parser.h b/src/gallium/auxiliary/vl/vl_bitstream_parser.h
new file mode 100644
index 00000000000..30ec743fa75
--- /dev/null
+++ b/src/gallium/auxiliary/vl/vl_bitstream_parser.h
@@ -0,0 +1,63 @@
+/**************************************************************************
+ *
+ * Copyright 2009 Younes Manton.
+ * 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 TUNGSTEN GRAPHICS 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 vl_bitstream_parser_h
+#define vl_bitstream_parser_h
+
+#include "pipe/p_compiler.h"
+
+struct vl_bitstream_parser
+{
+ unsigned num_bitstreams;
+ const unsigned **bitstreams;
+ const unsigned *sizes;
+ unsigned cur_bitstream;
+ unsigned cursor;
+};
+
+bool vl_bitstream_parser_init(struct vl_bitstream_parser *parser,
+ unsigned num_bitstreams,
+ const void **bitstreams,
+ const unsigned *sizes);
+
+void vl_bitstream_parser_cleanup(struct vl_bitstream_parser *parser);
+
+unsigned
+vl_bitstream_parser_get_bits(struct vl_bitstream_parser *parser,
+ unsigned how_many_bits);
+
+unsigned
+vl_bitstream_parser_show_bits(struct vl_bitstream_parser *parser,
+ unsigned how_many_bits);
+
+void vl_bitstream_parser_forward(struct vl_bitstream_parser *parser,
+ unsigned how_many_bits);
+
+void vl_bitstream_parser_rewind(struct vl_bitstream_parser *parser,
+ unsigned how_many_bits);
+
+#endif /* vl_bitstream_parser_h */
diff --git a/src/gallium/auxiliary/vl/vl_compositor.c b/src/gallium/auxiliary/vl/vl_compositor.c
new file mode 100644
index 00000000000..415dc92555f
--- /dev/null
+++ b/src/gallium/auxiliary/vl/vl_compositor.c
@@ -0,0 +1,636 @@
+/**************************************************************************
+ *
+ * Copyright 2009 Younes Manton.
+ * 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 TUNGSTEN GRAPHICS 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.
+ *
+ **************************************************************************/
+
+#include "vl_compositor.h"
+#include <assert.h>
+#include <pipe/p_context.h>
+#include <util/u_inlines.h>
+#include <util/u_memory.h>
+#include <util/u_keymap.h>
+#include <util/u_sampler.h>
+#include <tgsi/tgsi_ureg.h>
+#include "vl_csc.h"
+
+struct vertex_shader_consts
+{
+ struct vertex4f dst_scale;
+ struct vertex4f dst_trans;
+ struct vertex4f src_scale;
+ struct vertex4f src_trans;
+};
+
+struct fragment_shader_consts
+{
+ float matrix[16];
+};
+
+static bool
+u_video_rects_equal(struct pipe_video_rect *a, struct pipe_video_rect *b)
+{
+ assert(a && b);
+
+ if (a->x != b->x)
+ return false;
+ if (a->y != b->y)
+ return false;
+ if (a->w != b->w)
+ return false;
+ if (a->h != b->h)
+ return false;
+
+ return true;
+}
+
+static bool
+create_vert_shader(struct vl_compositor *c)
+{
+ struct ureg_program *shader;
+ struct ureg_src vpos, vtex;
+ struct ureg_dst o_vpos, o_vtex;
+
+ shader = ureg_create(TGSI_PROCESSOR_VERTEX);
+ if (!shader)
+ return false;
+
+ vpos = ureg_DECL_vs_input(shader, 0);
+ vtex = ureg_DECL_vs_input(shader, 1);
+ o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, 0);
+ o_vtex = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, 1);
+
+ /*
+ * o_vpos = vpos
+ * o_vtex = vtex
+ */
+ ureg_MOV(shader, o_vpos, vpos);
+ ureg_MOV(shader, o_vtex, vtex);
+
+ ureg_END(shader);
+
+ c->vertex_shader = ureg_create_shader_and_destroy(shader, c->pipe);
+ if (!c->vertex_shader)
+ return false;
+
+ return true;
+}
+
+static bool
+create_frag_shader_ycbcr_2_rgb(struct vl_compositor *c)
+{
+ struct ureg_program *shader;
+ struct ureg_src tc;
+ struct ureg_src csc[4];
+ struct ureg_src sampler;
+ struct ureg_dst texel;
+ struct ureg_dst fragment;
+ unsigned i;
+
+ shader = ureg_create(TGSI_PROCESSOR_FRAGMENT);
+ if (!shader)
+ return false;
+
+ tc = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, 1, TGSI_INTERPOLATE_LINEAR);
+ for (i = 0; i < 4; ++i)
+ csc[i] = ureg_DECL_constant(shader, i);
+ sampler = ureg_DECL_sampler(shader, 0);
+ texel = ureg_DECL_temporary(shader);
+ fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0);
+
+ /*
+ * texel = tex(tc, sampler)
+ * fragment = csc * texel
+ */
+ ureg_TEX(shader, texel, TGSI_TEXTURE_2D, tc, sampler);
+ for (i = 0; i < 4; ++i)
+ ureg_DP4(shader, ureg_writemask(fragment, TGSI_WRITEMASK_X << i), csc[i], ureg_src(texel));
+
+ ureg_release_temporary(shader, texel);
+ ureg_END(shader);
+
+ c->fragment_shader.ycbcr_2_rgb = ureg_create_shader_and_destroy(shader, c->pipe);
+ if (!c->fragment_shader.ycbcr_2_rgb)
+ return false;
+
+ return true;
+}
+
+static bool
+create_frag_shader_rgb_2_rgb(struct vl_compositor *c)
+{
+ struct ureg_program *shader;
+ struct ureg_src tc;
+ struct ureg_src sampler;
+ struct ureg_dst fragment;
+
+ shader = ureg_create(TGSI_PROCESSOR_FRAGMENT);
+ if (!shader)
+ return false;
+
+ tc = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, 1, TGSI_INTERPOLATE_LINEAR);
+ sampler = ureg_DECL_sampler(shader, 0);
+ fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0);
+
+ /*
+ * fragment = tex(tc, sampler)
+ */
+ ureg_TEX(shader, fragment, TGSI_TEXTURE_2D, tc, sampler);
+ ureg_END(shader);
+
+ c->fragment_shader.rgb_2_rgb = ureg_create_shader_and_destroy(shader, c->pipe);
+ if (!c->fragment_shader.rgb_2_rgb)
+ return false;
+
+ return true;
+}
+
+static bool
+init_pipe_state(struct vl_compositor *c)
+{
+ struct pipe_sampler_state sampler;
+
+ assert(c);
+
+ c->fb_state.nr_cbufs = 1;
+ c->fb_state.zsbuf = NULL;
+
+ sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+ sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+ sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+ sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR;
+ sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
+ sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR;
+ sampler.compare_mode = PIPE_TEX_COMPARE_NONE;
+ sampler.compare_func = PIPE_FUNC_ALWAYS;
+ sampler.normalized_coords = 1;
+ /*sampler.lod_bias = ;*/
+ /*sampler.min_lod = ;*/
+ /*sampler.max_lod = ;*/
+ /*sampler.border_color[i] = ;*/
+ /*sampler.max_anisotropy = ;*/
+ c->sampler = c->pipe->create_sampler_state(c->pipe, &sampler);
+
+ return true;
+}
+
+static void cleanup_pipe_state(struct vl_compositor *c)
+{
+ assert(c);
+
+ c->pipe->delete_sampler_state(c->pipe, c->sampler);
+}
+
+static bool
+init_shaders(struct vl_compositor *c)
+{
+ assert(c);
+
+ if (!create_vert_shader(c)) {
+ debug_printf("Unable to create vertex shader.\n");
+ return false;
+ }
+ if (!create_frag_shader_ycbcr_2_rgb(c)) {
+ debug_printf("Unable to create YCbCr-to-RGB fragment shader.\n");
+ return false;
+ }
+ if (!create_frag_shader_rgb_2_rgb(c)) {
+ debug_printf("Unable to create RGB-to-RGB fragment shader.\n");
+ return false;
+ }
+
+ return true;
+}
+
+static void cleanup_shaders(struct vl_compositor *c)
+{
+ assert(c);
+
+ c->pipe->delete_vs_state(c->pipe, c->vertex_shader);
+ c->pipe->delete_fs_state(c->pipe, c->fragment_shader.ycbcr_2_rgb);
+ c->pipe->delete_fs_state(c->pipe, c->fragment_shader.rgb_2_rgb);
+}
+
+static bool
+init_buffers(struct vl_compositor *c)
+{
+ struct fragment_shader_consts fsc;
+ struct pipe_vertex_element vertex_elems[2];
+
+ assert(c);
+
+ /*
+ * Create our vertex buffer and vertex buffer elements
+ */
+ c->vertex_buf.stride = sizeof(struct vertex4f);
+ c->vertex_buf.max_index = (VL_COMPOSITOR_MAX_LAYERS + 2) * 6 - 1;
+ c->vertex_buf.buffer_offset = 0;
+ /* XXX: Create with DYNAMIC or STREAM */
+ c->vertex_buf.buffer = pipe_buffer_create
+ (
+ c->pipe->screen,
+ PIPE_BIND_VERTEX_BUFFER,
+ sizeof(struct vertex4f) * (VL_COMPOSITOR_MAX_LAYERS + 2) * 6
+ );
+
+ vertex_elems[0].src_offset = 0;
+ vertex_elems[0].instance_divisor = 0;
+ vertex_elems[0].vertex_buffer_index = 0;
+ vertex_elems[0].src_format = PIPE_FORMAT_R32G32_FLOAT;
+ vertex_elems[1].src_offset = sizeof(struct vertex2f);
+ vertex_elems[1].instance_divisor = 0;
+ vertex_elems[1].vertex_buffer_index = 0;
+ vertex_elems[1].src_format = PIPE_FORMAT_R32G32_FLOAT;
+ c->vertex_elems_state = c->pipe->create_vertex_elements_state(c->pipe, 2, vertex_elems);
+
+ /*
+ * Create our fragment shader's constant buffer
+ * Const buffer contains the color conversion matrix and bias vectors
+ */
+ /* XXX: Create with IMMUTABLE/STATIC... although it does change every once in a long while... */
+ c->fs_const_buf = pipe_buffer_create
+ (
+ c->pipe->screen,
+ PIPE_BIND_CONSTANT_BUFFER,
+ sizeof(struct fragment_shader_consts)
+ );
+
+ vl_csc_get_matrix(VL_CSC_COLOR_STANDARD_IDENTITY, NULL, true, fsc.matrix);
+
+ vl_compositor_set_csc_matrix(c, fsc.matrix);
+
+ return true;
+}
+
+static void
+cleanup_buffers(struct vl_compositor *c)
+{
+ assert(c);
+
+ c->pipe->delete_vertex_elements_state(c->pipe, c->vertex_elems_state);
+ pipe_resource_reference(&c->vertex_buf.buffer, NULL);
+ pipe_resource_reference(&c->fs_const_buf, NULL);
+}
+
+static void
+texview_map_delete(const struct keymap *map,
+ const void *key, void *data,
+ void *user)
+{
+ struct pipe_sampler_view *sv = (struct pipe_sampler_view*)data;
+
+ assert(map);
+ assert(key);
+ assert(data);
+ assert(user);
+
+ pipe_sampler_view_reference(&sv, NULL);
+}
+
+bool vl_compositor_init(struct vl_compositor *compositor, struct pipe_context *pipe)
+{
+ unsigned i;
+
+ assert(compositor);
+
+ memset(compositor, 0, sizeof(struct vl_compositor));
+
+ compositor->pipe = pipe;
+
+ compositor->texview_map = util_new_keymap(sizeof(struct pipe_surface*), -1,
+ texview_map_delete);
+ if (!compositor->texview_map)
+ return false;
+
+ if (!init_pipe_state(compositor)) {
+ util_delete_keymap(compositor->texview_map, compositor->pipe);
+ return false;
+ }
+ if (!init_shaders(compositor)) {
+ util_delete_keymap(compositor->texview_map, compositor->pipe);
+ cleanup_pipe_state(compositor);
+ return false;
+ }
+ if (!init_buffers(compositor)) {
+ util_delete_keymap(compositor->texview_map, compositor->pipe);
+ cleanup_shaders(compositor);
+ cleanup_pipe_state(compositor);
+ return false;
+ }
+
+ compositor->fb_state.width = 0;
+ compositor->fb_state.height = 0;
+ compositor->bg = NULL;
+ compositor->dirty_bg = false;
+ for (i = 0; i < VL_COMPOSITOR_MAX_LAYERS; ++i)
+ compositor->layers[i] = NULL;
+ compositor->dirty_layers = 0;
+
+ return true;
+}
+
+void vl_compositor_cleanup(struct vl_compositor *compositor)
+{
+ assert(compositor);
+
+ util_delete_keymap(compositor->texview_map, compositor->pipe);
+ cleanup_buffers(compositor);
+ cleanup_shaders(compositor);
+ cleanup_pipe_state(compositor);
+}
+
+void vl_compositor_set_background(struct vl_compositor *compositor,
+ struct pipe_surface *bg, struct pipe_video_rect *bg_src_rect)
+{
+ assert(compositor);
+ assert((bg && bg_src_rect) || (!bg && !bg_src_rect));
+
+ if (compositor->bg != bg ||
+ !u_video_rects_equal(&compositor->bg_src_rect, bg_src_rect)) {
+ pipe_surface_reference(&compositor->bg, bg);
+ /*if (!u_video_rects_equal(&compositor->bg_src_rect, bg_src_rect))*/
+ compositor->bg_src_rect = *bg_src_rect;
+ compositor->dirty_bg = true;
+ }
+}
+
+void vl_compositor_set_layers(struct vl_compositor *compositor,
+ struct pipe_surface *layers[],
+ struct pipe_video_rect *src_rects[],
+ struct pipe_video_rect *dst_rects[],
+ unsigned num_layers)
+{
+ unsigned i;
+
+ assert(compositor);
+ assert(num_layers <= VL_COMPOSITOR_MAX_LAYERS);
+
+ for (i = 0; i < num_layers; ++i)
+ {
+ assert((layers[i] && src_rects[i] && dst_rects[i]) ||
+ (!layers[i] && !src_rects[i] && !dst_rects[i]));
+
+ if (compositor->layers[i] != layers[i] ||
+ !u_video_rects_equal(&compositor->layer_src_rects[i], src_rects[i]) ||
+ !u_video_rects_equal(&compositor->layer_dst_rects[i], dst_rects[i]))
+ {
+ pipe_surface_reference(&compositor->layers[i], layers[i]);
+ /*if (!u_video_rects_equal(&compositor->layer_src_rects[i], src_rects[i]))*/
+ compositor->layer_src_rects[i] = *src_rects[i];
+ /*if (!u_video_rects_equal(&compositor->layer_dst_rects[i], dst_rects[i]))*/
+ compositor->layer_dst_rects[i] = *dst_rects[i];
+ compositor->dirty_layers |= 1 << i;
+ }
+
+ if (layers[i])
+ compositor->dirty_layers |= 1 << i;
+ }
+
+ for (; i < VL_COMPOSITOR_MAX_LAYERS; ++i)
+ pipe_surface_reference(&compositor->layers[i], NULL);
+}
+
+static void gen_rect_verts(unsigned pos,
+ struct pipe_video_rect *src_rect,
+ struct vertex2f *src_inv_size,
+ struct pipe_video_rect *dst_rect,
+ struct vertex2f *dst_inv_size,
+ struct vertex4f *vb)
+{
+ assert(pos < VL_COMPOSITOR_MAX_LAYERS + 2);
+ assert(src_rect);
+ assert(src_inv_size);
+ assert((dst_rect && dst_inv_size) /*|| (!dst_rect && !dst_inv_size)*/);
+ assert(vb);
+
+ vb[pos * 6 + 0].x = dst_rect->x * dst_inv_size->x;
+ vb[pos * 6 + 0].y = dst_rect->y * dst_inv_size->y;
+ vb[pos * 6 + 0].z = src_rect->x * src_inv_size->x;
+ vb[pos * 6 + 0].w = src_rect->y * src_inv_size->y;
+
+ vb[pos * 6 + 1].x = dst_rect->x * dst_inv_size->x;
+ vb[pos * 6 + 1].y = (dst_rect->y + dst_rect->h) * dst_inv_size->y;
+ vb[pos * 6 + 1].z = src_rect->x * src_inv_size->x;
+ vb[pos * 6 + 1].w = (src_rect->y + src_rect->h) * src_inv_size->y;
+
+ vb[pos * 6 + 2].x = (dst_rect->x + dst_rect->w) * dst_inv_size->x;
+ vb[pos * 6 + 2].y = dst_rect->y * dst_inv_size->y;
+ vb[pos * 6 + 2].z = (src_rect->x + src_rect->w) * src_inv_size->x;
+ vb[pos * 6 + 2].w = src_rect->y * src_inv_size->y;
+
+ vb[pos * 6 + 3].x = (dst_rect->x + dst_rect->w) * dst_inv_size->x;
+ vb[pos * 6 + 3].y = dst_rect->y * dst_inv_size->y;
+ vb[pos * 6 + 3].z = (src_rect->x + src_rect->w) * src_inv_size->x;
+ vb[pos * 6 + 3].w = src_rect->y * src_inv_size->y;
+
+ vb[pos * 6 + 4].x = dst_rect->x * dst_inv_size->x;
+ vb[pos * 6 + 4].y = (dst_rect->y + dst_rect->h) * dst_inv_size->y;
+ vb[pos * 6 + 4].z = src_rect->x * src_inv_size->x;
+ vb[pos * 6 + 4].w = (src_rect->y + src_rect->h) * src_inv_size->y;
+
+ vb[pos * 6 + 5].x = (dst_rect->x + dst_rect->w) * dst_inv_size->x;
+ vb[pos * 6 + 5].y = (dst_rect->y + dst_rect->h) * dst_inv_size->y;
+ vb[pos * 6 + 5].z = (src_rect->x + src_rect->w) * src_inv_size->x;
+ vb[pos * 6 + 5].w = (src_rect->y + src_rect->h) * src_inv_size->y;
+}
+
+static unsigned gen_data(struct vl_compositor *c,
+ struct pipe_surface *src_surface,
+ struct pipe_video_rect *src_rect,
+ struct pipe_video_rect *dst_rect,
+ struct pipe_surface **textures,
+ void **frag_shaders)
+{
+ void *vb;
+ struct pipe_transfer *buf_transfer;
+ unsigned num_rects = 0;
+ unsigned i;
+
+ assert(c);
+ assert(src_surface);
+ assert(src_rect);
+ assert(dst_rect);
+ assert(textures);
+
+ vb = pipe_buffer_map(c->pipe, c->vertex_buf.buffer,
+ PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD,
+ &buf_transfer);
+
+ if (!vb)
+ return 0;
+
+ if (c->dirty_bg) {
+ struct vertex2f bg_inv_size = {1.0f / c->bg->width, 1.0f / c->bg->height};
+ gen_rect_verts(num_rects, &c->bg_src_rect, &bg_inv_size, NULL, NULL, vb);
+ textures[num_rects] = c->bg;
+ /* XXX: Hack */
+ frag_shaders[num_rects] = c->fragment_shader.rgb_2_rgb;
+ ++num_rects;
+ c->dirty_bg = false;
+ }
+
+ {
+ struct vertex2f src_inv_size = { 1.0f / src_surface->width, 1.0f / src_surface->height};
+ gen_rect_verts(num_rects, src_rect, &src_inv_size, dst_rect, &c->fb_inv_size, vb);
+ textures[num_rects] = src_surface;
+ /* XXX: Hack, sort of */
+ frag_shaders[num_rects] = c->fragment_shader.ycbcr_2_rgb;
+ ++num_rects;
+ }
+
+ for (i = 0; c->dirty_layers > 0; i++) {
+ assert(i < VL_COMPOSITOR_MAX_LAYERS);
+
+ if (c->dirty_layers & (1 << i)) {
+ struct vertex2f layer_inv_size = {1.0f / c->layers[i]->width, 1.0f / c->layers[i]->height};
+ gen_rect_verts(num_rects, &c->layer_src_rects[i], &layer_inv_size,
+ &c->layer_dst_rects[i], &c->fb_inv_size, vb);
+ textures[num_rects] = c->layers[i];
+ /* XXX: Hack */
+ frag_shaders[num_rects] = c->fragment_shader.rgb_2_rgb;
+ ++num_rects;
+ c->dirty_layers &= ~(1 << i);
+ }
+ }
+
+ pipe_buffer_unmap(c->pipe, c->vertex_buf.buffer, buf_transfer);
+
+ return num_rects;
+}
+
+static void draw_layers(struct vl_compositor *c,
+ struct pipe_surface *src_surface,
+ struct pipe_video_rect *src_rect,
+ struct pipe_video_rect *dst_rect)
+{
+ unsigned num_rects;
+ struct pipe_surface *src_surfaces[VL_COMPOSITOR_MAX_LAYERS + 2];
+ void *frag_shaders[VL_COMPOSITOR_MAX_LAYERS + 2];
+ unsigned i;
+
+ assert(c);
+ assert(src_surface);
+ assert(src_rect);
+ assert(dst_rect);
+
+ num_rects = gen_data(c, src_surface, src_rect, dst_rect, src_surfaces, frag_shaders);
+
+ for (i = 0; i < num_rects; ++i) {
+ boolean delete_view = FALSE;
+ struct pipe_sampler_view *surface_view = (struct pipe_sampler_view*)util_keymap_lookup(c->texview_map,
+ &src_surfaces[i]);
+ if (!surface_view) {
+ struct pipe_sampler_view templat;
+ u_sampler_view_default_template(&templat, src_surfaces[i]->texture,
+ src_surfaces[i]->texture->format);
+ surface_view = c->pipe->create_sampler_view(c->pipe, src_surfaces[i]->texture,
+ &templat);
+ if (!surface_view)
+ return;
+
+ delete_view = !util_keymap_insert(c->texview_map, &src_surfaces[i],
+ surface_view, c->pipe);
+ }
+
+ c->pipe->bind_fs_state(c->pipe, frag_shaders[i]);
+ c->pipe->set_fragment_sampler_views(c->pipe, 1, &surface_view);
+ c->pipe->draw_arrays(c->pipe, PIPE_PRIM_TRIANGLES, i * 6, 6);
+
+ if (delete_view) {
+ pipe_sampler_view_reference(&surface_view, NULL);
+ }
+ }
+}
+
+void vl_compositor_render(struct vl_compositor *compositor,
+ struct pipe_surface *src_surface,
+ enum pipe_mpeg12_picture_type picture_type,
+ /*unsigned num_past_surfaces,
+ struct pipe_surface *past_surfaces,
+ unsigned num_future_surfaces,
+ struct pipe_surface *future_surfaces,*/
+ struct pipe_video_rect *src_area,
+ struct pipe_surface *dst_surface,
+ struct pipe_video_rect *dst_area,
+ struct pipe_fence_handle **fence)
+{
+ assert(compositor);
+ assert(src_surface);
+ assert(src_area);
+ assert(dst_surface);
+ assert(dst_area);
+ assert(picture_type == PIPE_MPEG12_PICTURE_TYPE_FRAME);
+
+ if (compositor->fb_state.width != dst_surface->width) {
+ compositor->fb_inv_size.x = 1.0f / dst_surface->width;
+ compositor->fb_state.width = dst_surface->width;
+ }
+ if (compositor->fb_state.height != dst_surface->height) {
+ compositor->fb_inv_size.y = 1.0f / dst_surface->height;
+ compositor->fb_state.height = dst_surface->height;
+ }
+
+ compositor->fb_state.cbufs[0] = dst_surface;
+
+ compositor->viewport.scale[0] = compositor->fb_state.width;
+ compositor->viewport.scale[1] = compositor->fb_state.height;
+ compositor->viewport.scale[2] = 1;
+ compositor->viewport.scale[3] = 1;
+ compositor->viewport.translate[0] = 0;
+ compositor->viewport.translate[1] = 0;
+ compositor->viewport.translate[2] = 0;
+ compositor->viewport.translate[3] = 0;
+
+ compositor->pipe->set_framebuffer_state(compositor->pipe, &compositor->fb_state);
+ compositor->pipe->set_viewport_state(compositor->pipe, &compositor->viewport);
+ compositor->pipe->bind_fragment_sampler_states(compositor->pipe, 1, &compositor->sampler);
+ compositor->pipe->bind_vs_state(compositor->pipe, compositor->vertex_shader);
+ compositor->pipe->set_vertex_buffers(compositor->pipe, 1, &compositor->vertex_buf);
+ compositor->pipe->bind_vertex_elements_state(compositor->pipe, compositor->vertex_elems_state);
+ compositor->pipe->set_constant_buffer(compositor->pipe, PIPE_SHADER_FRAGMENT, 0, compositor->fs_const_buf);
+
+ draw_layers(compositor, src_surface, src_area, dst_area);
+
+ assert(!compositor->dirty_bg && !compositor->dirty_layers);
+ compositor->pipe->flush(compositor->pipe, PIPE_FLUSH_RENDER_CACHE, fence);
+}
+
+void vl_compositor_set_csc_matrix(struct vl_compositor *compositor, const float *mat)
+{
+ struct pipe_transfer *buf_transfer;
+
+ assert(compositor);
+
+ memcpy
+ (
+ pipe_buffer_map(compositor->pipe, compositor->fs_const_buf,
+ PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD,
+ &buf_transfer),
+ mat,
+ sizeof(struct fragment_shader_consts)
+ );
+
+ pipe_buffer_unmap(compositor->pipe, compositor->fs_const_buf,
+ buf_transfer);
+}
diff --git a/src/gallium/auxiliary/vl/vl_compositor.h b/src/gallium/auxiliary/vl/vl_compositor.h
new file mode 100644
index 00000000000..820c9ef6ddb
--- /dev/null
+++ b/src/gallium/auxiliary/vl/vl_compositor.h
@@ -0,0 +1,98 @@
+/**************************************************************************
+ *
+ * Copyright 2009 Younes Manton.
+ * 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 TUNGSTEN GRAPHICS 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 vl_compositor_h
+#define vl_compositor_h
+
+#include <pipe/p_compiler.h>
+#include <pipe/p_state.h>
+#include <pipe/p_video_state.h>
+#include "vl_types.h"
+
+struct pipe_context;
+struct keymap;
+
+#define VL_COMPOSITOR_MAX_LAYERS 16
+
+struct vl_compositor
+{
+ struct pipe_context *pipe;
+
+ struct pipe_framebuffer_state fb_state;
+ struct vertex2f fb_inv_size;
+ void *sampler;
+ struct pipe_sampler_view *sampler_view;
+ void *vertex_shader;
+ struct
+ {
+ void *ycbcr_2_rgb;
+ void *rgb_2_rgb;
+ } fragment_shader;
+ struct pipe_viewport_state viewport;
+ struct pipe_vertex_buffer vertex_buf;
+ void *vertex_elems_state;
+ struct pipe_resource *fs_const_buf;
+
+ struct pipe_surface *bg;
+ struct pipe_video_rect bg_src_rect;
+ bool dirty_bg;
+ struct pipe_surface *layers[VL_COMPOSITOR_MAX_LAYERS];
+ struct pipe_video_rect layer_src_rects[VL_COMPOSITOR_MAX_LAYERS];
+ struct pipe_video_rect layer_dst_rects[VL_COMPOSITOR_MAX_LAYERS];
+ unsigned dirty_layers;
+
+ struct keymap *texview_map;
+};
+
+bool vl_compositor_init(struct vl_compositor *compositor, struct pipe_context *pipe);
+
+void vl_compositor_cleanup(struct vl_compositor *compositor);
+
+void vl_compositor_set_background(struct vl_compositor *compositor,
+ struct pipe_surface *bg, struct pipe_video_rect *bg_src_rect);
+
+void vl_compositor_set_layers(struct vl_compositor *compositor,
+ struct pipe_surface *layers[],
+ struct pipe_video_rect *src_rects[],
+ struct pipe_video_rect *dst_rects[],
+ unsigned num_layers);
+
+void vl_compositor_render(struct vl_compositor *compositor,
+ struct pipe_surface *src_surface,
+ enum pipe_mpeg12_picture_type picture_type,
+ /*unsigned num_past_surfaces,
+ struct pipe_surface *past_surfaces,
+ unsigned num_future_surfaces,
+ struct pipe_surface *future_surfaces,*/
+ struct pipe_video_rect *src_area,
+ struct pipe_surface *dst_surface,
+ struct pipe_video_rect *dst_area,
+ struct pipe_fence_handle **fence);
+
+void vl_compositor_set_csc_matrix(struct vl_compositor *compositor, const float *mat);
+
+#endif /* vl_compositor_h */
diff --git a/src/gallium/auxiliary/vl/vl_csc.c b/src/gallium/auxiliary/vl/vl_csc.c
new file mode 100644
index 00000000000..5ecc43a5fa3
--- /dev/null
+++ b/src/gallium/auxiliary/vl/vl_csc.c
@@ -0,0 +1,206 @@
+/**************************************************************************
+ *
+ * Copyright 2009 Younes Manton.
+ * 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 TUNGSTEN GRAPHICS 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.
+ *
+ **************************************************************************/
+
+#include "vl_csc.h"
+#include <util/u_math.h>
+#include <util/u_debug.h>
+
+/*
+ * Color space conversion formulas
+ *
+ * To convert YCbCr to RGB,
+ * vec4 ycbcr, rgb
+ * mat44 csc
+ * rgb = csc * ycbcr
+ *
+ * To calculate the color space conversion matrix csc with ProcAmp adjustments,
+ * mat44 csc, cstd, procamp, bias
+ * csc = cstd * (procamp * bias)
+ *
+ * Where cstd is a matrix corresponding to one of the color standards (BT.601, BT.709, etc)
+ * adjusted for the kind of YCbCr -> RGB mapping wanted (1:1, full),
+ * bias is a matrix corresponding to the kind of YCbCr -> RGB mapping wanted (1:1, full)
+ *
+ * To calculate procamp,
+ * mat44 procamp, hue, saturation, brightness, contrast
+ * procamp = brightness * (saturation * (contrast * hue))
+ * Alternatively,
+ * procamp = saturation * (brightness * (contrast * hue))
+ *
+ * contrast
+ * [ c, 0, 0, 0]
+ * [ 0, c, 0, 0]
+ * [ 0, 0, c, 0]
+ * [ 0, 0, 0, 1]
+ *
+ * brightness
+ * [ 1, 0, 0, b]
+ * [ 0, 1, 0, 0]
+ * [ 0, 0, 1, 0]
+ * [ 0, 0, 0, 1]
+ *
+ * saturation
+ * [ 1, 0, 0, 0]
+ * [ 0, s, 0, 0]
+ * [ 0, 0, s, 0]
+ * [ 0, 0, 0, 1]
+ *
+ * hue
+ * [ 1, 0, 0, 0]
+ * [ 0, cos(h), sin(h), 0]
+ * [ 0, -sin(h), cos(h), 0]
+ * [ 0, 0, 0, 1]
+ *
+ * procamp
+ * [ c, 0, 0, b]
+ * [ 0, c*s*cos(h), c*s*sin(h), 0]
+ * [ 0, -c*s*sin(h), c*s*cos(h), 0]
+ * [ 0, 0, 0, 1]
+ *
+ * bias
+ * [ 1, 0, 0, ybias]
+ * [ 0, 1, 0, cbbias]
+ * [ 0, 0, 1, crbias]
+ * [ 0, 0, 0, 1]
+ *
+ * csc
+ * [ c*cstd[ 0], c*cstd[ 1]*s*cos(h) - c*cstd[ 2]*s*sin(h), c*cstd[ 2]*s*cos(h) + c*cstd[ 1]*s*sin(h), cstd[ 3] + cstd[ 0]*(b + c*ybias) + cstd[ 1]*(c*cbbias*s*cos(h) + c*crbias*s*sin(h)) + cstd[ 2]*(c*crbias*s*cos(h) - c*cbbias*s*sin(h))]
+ * [ c*cstd[ 4], c*cstd[ 5]*s*cos(h) - c*cstd[ 6]*s*sin(h), c*cstd[ 6]*s*cos(h) + c*cstd[ 5]*s*sin(h), cstd[ 7] + cstd[ 4]*(b + c*ybias) + cstd[ 5]*(c*cbbias*s*cos(h) + c*crbias*s*sin(h)) + cstd[ 6]*(c*crbias*s*cos(h) - c*cbbias*s*sin(h))]
+ * [ c*cstd[ 8], c*cstd[ 9]*s*cos(h) - c*cstd[10]*s*sin(h), c*cstd[10]*s*cos(h) + c*cstd[ 9]*s*sin(h), cstd[11] + cstd[ 8]*(b + c*ybias) + cstd[ 9]*(c*cbbias*s*cos(h) + c*crbias*s*sin(h)) + cstd[10]*(c*crbias*s*cos(h) - c*cbbias*s*sin(h))]
+ * [ c*cstd[12], c*cstd[13]*s*cos(h) - c*cstd[14]*s*sin(h), c*cstd[14]*s*cos(h) + c*cstd[13]*s*sin(h), cstd[15] + cstd[12]*(b + c*ybias) + cstd[13]*(c*cbbias*s*cos(h) + c*crbias*s*sin(h)) + cstd[14]*(c*crbias*s*cos(h) - c*cbbias*s*sin(h))]
+ */
+
+/*
+ * Converts ITU-R BT.601 YCbCr pixels to RGB pixels where:
+ * Y is in [16,235], Cb and Cr are in [16,240]
+ * R, G, and B are in [16,235]
+ */
+static const float bt_601[16] =
+{
+ 1.0f, 0.0f, 1.371f, 0.0f,
+ 1.0f, -0.336f, -0.698f, 0.0f,
+ 1.0f, 1.732f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f
+};
+
+/*
+ * Converts ITU-R BT.601 YCbCr pixels to RGB pixels where:
+ * Y is in [16,235], Cb and Cr are in [16,240]
+ * R, G, and B are in [0,255]
+ */
+static const float bt_601_full[16] =
+{
+ 1.164f, 0.0f, 1.596f, 0.0f,
+ 1.164f, -0.391f, -0.813f, 0.0f,
+ 1.164f, 2.018f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f
+};
+
+/*
+ * Converts ITU-R BT.709 YCbCr pixels to RGB pixels where:
+ * Y is in [16,235], Cb and Cr are in [16,240]
+ * R, G, and B are in [16,235]
+ */
+static const float bt_709[16] =
+{
+ 1.0f, 0.0f, 1.540f, 0.0f,
+ 1.0f, -0.183f, -0.459f, 0.0f,
+ 1.0f, 1.816f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f
+};
+
+/*
+ * Converts ITU-R BT.709 YCbCr pixels to RGB pixels where:
+ * Y is in [16,235], Cb and Cr are in [16,240]
+ * R, G, and B are in [0,255]
+ */
+static const float bt_709_full[16] =
+{
+ 1.164f, 0.0f, 1.793f, 0.0f,
+ 1.164f, -0.213f, -0.534f, 0.0f,
+ 1.164f, 2.115f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f
+};
+
+static const float identity[16] =
+{
+ 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f
+};
+
+void vl_csc_get_matrix(enum VL_CSC_COLOR_STANDARD cs,
+ struct vl_procamp *procamp,
+ bool full_range,
+ float *matrix)
+{
+ float ybias = full_range ? -16.0f/255.0f : 0.0f;
+ float cbbias = -128.0f/255.0f;
+ float crbias = -128.0f/255.0f;
+ float c = procamp ? procamp->contrast : 1.0f;
+ float s = procamp ? procamp->saturation : 1.0f;
+ float b = procamp ? procamp->brightness : 0.0f;
+ float h = procamp ? procamp->hue : 0.0f;
+ const float *cstd;
+
+ assert(matrix);
+
+ switch (cs) {
+ case VL_CSC_COLOR_STANDARD_BT_601:
+ cstd = full_range ? &bt_601_full[0] : &bt_601[0];
+ break;
+ case VL_CSC_COLOR_STANDARD_BT_709:
+ cstd = full_range ? &bt_709_full[0] : &bt_709[0];
+ break;
+ case VL_CSC_COLOR_STANDARD_IDENTITY:
+ default:
+ assert(cs == VL_CSC_COLOR_STANDARD_IDENTITY);
+ memcpy(matrix, &identity[0], sizeof(float) * 16);
+ return;
+ }
+
+ matrix[ 0] = c*cstd[ 0];
+ matrix[ 1] = c*cstd[ 1]*s*cosf(h) - c*cstd[ 2]*s*sinf(h);
+ matrix[ 2] = c*cstd[ 2]*s*cosf(h) + c*cstd[ 1]*s*sinf(h);
+ matrix[ 3] = cstd[ 3] + cstd[ 0]*(b + c*ybias) + cstd[ 1]*(c*cbbias*s*cosf(h) + c*crbias*s*sinf(h)) + cstd[ 2]*(c*crbias*s*cosf(h) - c*cbbias*s*sinf(h));
+
+ matrix[ 4] = c*cstd[ 4];
+ matrix[ 5] = c*cstd[ 5]*s*cosf(h) - c*cstd[ 6]*s*sinf(h);
+ matrix[ 6] = c*cstd[ 6]*s*cosf(h) + c*cstd[ 5]*s*sinf(h);
+ matrix[ 7] = cstd[ 7] + cstd[ 4]*(b + c*ybias) + cstd[ 5]*(c*cbbias*s*cosf(h) + c*crbias*s*sinf(h)) + cstd[ 6]*(c*crbias*s*cosf(h) - c*cbbias*s*sinf(h));
+
+ matrix[ 8] = c*cstd[ 8];
+ matrix[ 9] = c*cstd[ 9]*s*cosf(h) - c*cstd[10]*s*sinf(h);
+ matrix[10] = c*cstd[10]*s*cosf(h) + c*cstd[ 9]*s*sinf(h);
+ matrix[11] = cstd[11] + cstd[ 8]*(b + c*ybias) + cstd[ 9]*(c*cbbias*s*cosf(h) + c*crbias*s*sinf(h)) + cstd[10]*(c*crbias*s*cosf(h) - c*cbbias*s*sinf(h));
+
+ matrix[12] = c*cstd[12];
+ matrix[13] = c*cstd[13]*s*cos(h) - c*cstd[14]*s*sin(h);
+ matrix[14] = c*cstd[14]*s*cos(h) + c*cstd[13]*s*sin(h);
+ matrix[15] = cstd[15] + cstd[12]*(b + c*ybias) + cstd[13]*(c*cbbias*s*cos(h) + c*crbias*s*sin(h)) + cstd[14]*(c*crbias*s*cos(h) - c*cbbias*s*sin(h));
+}
diff --git a/src/gallium/auxiliary/vl/vl_csc.h b/src/gallium/auxiliary/vl/vl_csc.h
new file mode 100644
index 00000000000..722ca35f339
--- /dev/null
+++ b/src/gallium/auxiliary/vl/vl_csc.h
@@ -0,0 +1,53 @@
+/**************************************************************************
+ *
+ * Copyright 2009 Younes Manton.
+ * 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 TUNGSTEN GRAPHICS 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 vl_csc_h
+#define vl_csc_h
+
+#include <pipe/p_compiler.h>
+
+struct vl_procamp
+{
+ float brightness;
+ float contrast;
+ float saturation;
+ float hue;
+};
+
+enum VL_CSC_COLOR_STANDARD
+{
+ VL_CSC_COLOR_STANDARD_IDENTITY,
+ VL_CSC_COLOR_STANDARD_BT_601,
+ VL_CSC_COLOR_STANDARD_BT_709
+};
+
+void vl_csc_get_matrix(enum VL_CSC_COLOR_STANDARD cs,
+ struct vl_procamp *procamp,
+ bool full_range,
+ float *matrix);
+
+#endif /* vl_csc_h */
diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c
new file mode 100644
index 00000000000..e9024e4a409
--- /dev/null
+++ b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c
@@ -0,0 +1,1472 @@
+/**************************************************************************
+ *
+ * Copyright 2009 Younes Manton.
+ * 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 TUNGSTEN GRAPHICS 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.
+ *
+ **************************************************************************/
+
+#include "vl_mpeg12_mc_renderer.h"
+#include <assert.h>
+#include <pipe/p_context.h>
+#include <util/u_inlines.h>
+#include <util/u_format.h>
+#include <util/u_math.h>
+#include <util/u_memory.h>
+#include <util/u_keymap.h>
+#include <util/u_sampler.h>
+#include <tgsi/tgsi_ureg.h>
+
+#define DEFAULT_BUF_ALIGNMENT 1
+#define MACROBLOCK_WIDTH 16
+#define MACROBLOCK_HEIGHT 16
+#define BLOCK_WIDTH 8
+#define BLOCK_HEIGHT 8
+#define ZERO_BLOCK_NIL -1.0f
+#define ZERO_BLOCK_IS_NIL(zb) ((zb).x < 0.0f)
+#define SCALE_FACTOR_16_TO_9 (32767.0f / 255.0f)
+
+struct vertex_shader_consts
+{
+ struct vertex4f denorm;
+};
+
+struct fragment_shader_consts
+{
+ struct vertex4f multiplier;
+ struct vertex4f div;
+};
+
+struct vert_stream_0
+{
+ struct vertex2f pos;
+ struct vertex2f luma_tc;
+ struct vertex2f cb_tc;
+ struct vertex2f cr_tc;
+};
+
+enum MACROBLOCK_TYPE
+{
+ MACROBLOCK_TYPE_INTRA,
+ MACROBLOCK_TYPE_FWD_FRAME_PRED,
+ MACROBLOCK_TYPE_FWD_FIELD_PRED,
+ MACROBLOCK_TYPE_BKWD_FRAME_PRED,
+ MACROBLOCK_TYPE_BKWD_FIELD_PRED,
+ MACROBLOCK_TYPE_BI_FRAME_PRED,
+ MACROBLOCK_TYPE_BI_FIELD_PRED,
+
+ NUM_MACROBLOCK_TYPES
+};
+
+static bool
+create_intra_vert_shader(struct vl_mpeg12_mc_renderer *r)
+{
+ struct ureg_program *shader;
+ struct ureg_src vpos, vtex[3];
+ struct ureg_dst o_vpos, o_vtex[3];
+ unsigned i;
+
+ shader = ureg_create(TGSI_PROCESSOR_VERTEX);
+ if (!shader)
+ return false;
+
+ vpos = ureg_DECL_vs_input(shader, 0);
+ for (i = 0; i < 3; ++i)
+ vtex[i] = ureg_DECL_vs_input(shader, i + 1);
+ o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, 0);
+ for (i = 0; i < 3; ++i)
+ o_vtex[i] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, i + 1);
+
+ /*
+ * o_vpos = vpos
+ * o_vtex[0..2] = vtex[0..2]
+ */
+ ureg_MOV(shader, o_vpos, vpos);
+ for (i = 0; i < 3; ++i)
+ ureg_MOV(shader, o_vtex[i], vtex[i]);
+
+ ureg_END(shader);
+
+ r->i_vs = ureg_create_shader_and_destroy(shader, r->pipe);
+ if (!r->i_vs)
+ return false;
+
+ return true;
+}
+
+static bool
+create_intra_frag_shader(struct vl_mpeg12_mc_renderer *r)
+{
+ struct ureg_program *shader;
+ struct ureg_src tc[3];
+ struct ureg_src sampler[3];
+ struct ureg_dst texel, temp;
+ struct ureg_dst fragment;
+ unsigned i;
+
+ shader = ureg_create(TGSI_PROCESSOR_FRAGMENT);
+ if (!shader)
+ return false;
+
+ for (i = 0; i < 3; ++i) {
+ tc[i] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, i + 1, TGSI_INTERPOLATE_LINEAR);
+ sampler[i] = ureg_DECL_sampler(shader, i);
+ }
+ texel = ureg_DECL_temporary(shader);
+ temp = ureg_DECL_temporary(shader);
+ fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0);
+
+ /*
+ * texel.r = tex(tc[0], sampler[0])
+ * texel.g = tex(tc[1], sampler[1])
+ * texel.b = tex(tc[2], sampler[2])
+ * fragment = texel * scale
+ */
+ for (i = 0; i < 3; ++i) {
+ /* Nouveau can't writemask tex dst regs (yet?), do in two steps */
+ ureg_TEX(shader, temp, TGSI_TEXTURE_2D, tc[i], sampler[i]);
+ ureg_MOV(shader, ureg_writemask(texel, TGSI_WRITEMASK_X << i), ureg_scalar(ureg_src(temp), TGSI_SWIZZLE_X));
+ }
+ ureg_MUL(shader, fragment, ureg_src(texel), ureg_scalar(ureg_imm1f(shader, SCALE_FACTOR_16_TO_9), TGSI_SWIZZLE_X));
+
+ ureg_release_temporary(shader, texel);
+ ureg_release_temporary(shader, temp);
+ ureg_END(shader);
+
+ r->i_fs = ureg_create_shader_and_destroy(shader, r->pipe);
+ if (!r->i_fs)
+ return false;
+
+ return true;
+}
+
+static bool
+create_frame_pred_vert_shader(struct vl_mpeg12_mc_renderer *r)
+{
+ struct ureg_program *shader;
+ struct ureg_src vpos, vtex[4];
+ struct ureg_dst o_vpos, o_vtex[4];
+ unsigned i;
+
+ shader = ureg_create(TGSI_PROCESSOR_VERTEX);
+ if (!shader)
+ return false;
+
+ vpos = ureg_DECL_vs_input(shader, 0);
+ for (i = 0; i < 4; ++i)
+ vtex[i] = ureg_DECL_vs_input(shader, i + 1);
+ o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, 0);
+ for (i = 0; i < 4; ++i)
+ o_vtex[i] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, i + 1);
+
+ /*
+ * o_vpos = vpos
+ * o_vtex[0..2] = vtex[0..2]
+ * o_vtex[3] = vpos + vtex[3] // Apply motion vector
+ */
+ ureg_MOV(shader, o_vpos, vpos);
+ for (i = 0; i < 3; ++i)
+ ureg_MOV(shader, o_vtex[i], vtex[i]);
+ ureg_ADD(shader, o_vtex[3], vpos, vtex[3]);
+
+ ureg_END(shader);
+
+ r->p_vs[0] = ureg_create_shader_and_destroy(shader, r->pipe);
+ if (!r->p_vs[0])
+ return false;
+
+ return true;
+}
+
+#if 0
+static void
+create_field_pred_vert_shader(struct vl_mpeg12_mc_renderer *r)
+{
+ assert(false);
+}
+#endif
+
+static bool
+create_frame_pred_frag_shader(struct vl_mpeg12_mc_renderer *r)
+{
+ struct ureg_program *shader;
+ struct ureg_src tc[4];
+ struct ureg_src sampler[4];
+ struct ureg_dst texel, ref;
+ struct ureg_dst fragment;
+ unsigned i;
+
+ shader = ureg_create(TGSI_PROCESSOR_FRAGMENT);
+ if (!shader)
+ return false;
+
+ for (i = 0; i < 4; ++i) {
+ tc[i] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, i + 1, TGSI_INTERPOLATE_LINEAR);
+ sampler[i] = ureg_DECL_sampler(shader, i);
+ }
+ texel = ureg_DECL_temporary(shader);
+ ref = ureg_DECL_temporary(shader);
+ fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0);
+
+ /*
+ * texel.r = tex(tc[0], sampler[0])
+ * texel.g = tex(tc[1], sampler[1])
+ * texel.b = tex(tc[2], sampler[2])
+ * ref = tex(tc[3], sampler[3])
+ * fragment = texel * scale + ref
+ */
+ for (i = 0; i < 3; ++i) {
+ /* Nouveau can't writemask tex dst regs (yet?), do in two steps */
+ ureg_TEX(shader, ref, TGSI_TEXTURE_2D, tc[i], sampler[i]);
+ ureg_MOV(shader, ureg_writemask(texel, TGSI_WRITEMASK_X << i), ureg_scalar(ureg_src(ref), TGSI_SWIZZLE_X));
+ }
+ ureg_TEX(shader, ref, TGSI_TEXTURE_2D, tc[3], sampler[3]);
+ ureg_MAD(shader, fragment, ureg_src(texel), ureg_scalar(ureg_imm1f(shader, SCALE_FACTOR_16_TO_9), TGSI_SWIZZLE_X), ureg_src(ref));
+
+ ureg_release_temporary(shader, texel);
+ ureg_release_temporary(shader, ref);
+ ureg_END(shader);
+
+ r->p_fs[0] = ureg_create_shader_and_destroy(shader, r->pipe);
+ if (!r->p_fs[0])
+ return false;
+
+ return true;
+}
+
+#if 0
+static void
+create_field_pred_frag_shader(struct vl_mpeg12_mc_renderer *r)
+{
+ assert(false);
+}
+#endif
+
+static bool
+create_frame_bi_pred_vert_shader(struct vl_mpeg12_mc_renderer *r)
+{
+ struct ureg_program *shader;
+ struct ureg_src vpos, vtex[5];
+ struct ureg_dst o_vpos, o_vtex[5];
+ unsigned i;
+
+ shader = ureg_create(TGSI_PROCESSOR_VERTEX);
+ if (!shader)
+ return false;
+
+ vpos = ureg_DECL_vs_input(shader, 0);
+ for (i = 0; i < 4; ++i)
+ vtex[i] = ureg_DECL_vs_input(shader, i + 1);
+ /* Skip input 5 */
+ vtex[4] = ureg_DECL_vs_input(shader, 6);
+ o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, 0);
+ for (i = 0; i < 5; ++i)
+ o_vtex[i] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, i + 1);
+
+ /*
+ * o_vpos = vpos
+ * o_vtex[0..2] = vtex[0..2]
+ * o_vtex[3..4] = vpos + vtex[3..4] // Apply motion vector
+ */
+ ureg_MOV(shader, o_vpos, vpos);
+ for (i = 0; i < 3; ++i)
+ ureg_MOV(shader, o_vtex[i], vtex[i]);
+ for (i = 3; i < 5; ++i)
+ ureg_ADD(shader, o_vtex[i], vpos, vtex[i]);
+
+ ureg_END(shader);
+
+ r->b_vs[0] = ureg_create_shader_and_destroy(shader, r->pipe);
+ if (!r->b_vs[0])
+ return false;
+
+ return true;
+}
+
+#if 0
+static void
+create_field_bi_pred_vert_shader(struct vl_mpeg12_mc_renderer *r)
+{
+ assert(false);
+}
+#endif
+
+static bool
+create_frame_bi_pred_frag_shader(struct vl_mpeg12_mc_renderer *r)
+{
+ struct ureg_program *shader;
+ struct ureg_src tc[5];
+ struct ureg_src sampler[5];
+ struct ureg_dst texel, ref[2];
+ struct ureg_dst fragment;
+ unsigned i;
+
+ shader = ureg_create(TGSI_PROCESSOR_FRAGMENT);
+ if (!shader)
+ return false;
+
+ for (i = 0; i < 5; ++i) {
+ tc[i] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, i + 1, TGSI_INTERPOLATE_LINEAR);
+ sampler[i] = ureg_DECL_sampler(shader, i);
+ }
+ texel = ureg_DECL_temporary(shader);
+ ref[0] = ureg_DECL_temporary(shader);
+ ref[1] = ureg_DECL_temporary(shader);
+ fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0);
+
+ /*
+ * texel.r = tex(tc[0], sampler[0])
+ * texel.g = tex(tc[1], sampler[1])
+ * texel.b = tex(tc[2], sampler[2])
+ * ref[0..1 = tex(tc[3..4], sampler[3..4])
+ * ref[0] = lerp(ref[0], ref[1], 0.5)
+ * fragment = texel * scale + ref[0]
+ */
+ for (i = 0; i < 3; ++i) {
+ /* Nouveau can't writemask tex dst regs (yet?), do in two steps */
+ ureg_TEX(shader, ref[0], TGSI_TEXTURE_2D, tc[i], sampler[i]);
+ ureg_MOV(shader, ureg_writemask(texel, TGSI_WRITEMASK_X << i), ureg_scalar(ureg_src(ref[0]), TGSI_SWIZZLE_X));
+ }
+ ureg_TEX(shader, ref[0], TGSI_TEXTURE_2D, tc[3], sampler[3]);
+ ureg_TEX(shader, ref[1], TGSI_TEXTURE_2D, tc[4], sampler[4]);
+ ureg_LRP(shader, ref[0], ureg_scalar(ureg_imm1f(shader, 0.5f), TGSI_SWIZZLE_X), ureg_src(ref[0]), ureg_src(ref[1]));
+
+ ureg_MAD(shader, fragment, ureg_src(texel), ureg_scalar(ureg_imm1f(shader, SCALE_FACTOR_16_TO_9), TGSI_SWIZZLE_X), ureg_src(ref[0]));
+
+ ureg_release_temporary(shader, texel);
+ ureg_release_temporary(shader, ref[0]);
+ ureg_release_temporary(shader, ref[1]);
+ ureg_END(shader);
+
+ r->b_fs[0] = ureg_create_shader_and_destroy(shader, r->pipe);
+ if (!r->b_fs[0])
+ return false;
+
+ return true;
+}
+
+#if 0
+static void
+create_field_bi_pred_frag_shader(struct vl_mpeg12_mc_renderer *r)
+{
+ assert(false);
+}
+#endif
+
+static void
+xfer_buffers_map(struct vl_mpeg12_mc_renderer *r)
+{
+ unsigned i;
+
+ assert(r);
+
+ for (i = 0; i < 3; ++i) {
+ struct pipe_box rect =
+ {
+ 0, 0, 0,
+ r->textures.all[i]->width0,
+ r->textures.all[i]->height0,
+ 1
+ };
+
+ r->tex_transfer[i] = r->pipe->get_transfer
+ (
+ r->pipe, r->textures.all[i],
+ u_subresource(0, 0),
+ PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD,
+ &rect
+ );
+
+ r->texels[i] = r->pipe->transfer_map(r->pipe, r->tex_transfer[i]);
+ }
+}
+
+static void
+xfer_buffers_unmap(struct vl_mpeg12_mc_renderer *r)
+{
+ unsigned i;
+
+ assert(r);
+
+ for (i = 0; i < 3; ++i) {
+ r->pipe->transfer_unmap(r->pipe, r->tex_transfer[i]);
+ r->pipe->transfer_destroy(r->pipe, r->tex_transfer[i]);
+ }
+}
+
+static bool
+init_pipe_state(struct vl_mpeg12_mc_renderer *r)
+{
+ struct pipe_sampler_state sampler;
+ unsigned filters[5];
+ unsigned i;
+
+ assert(r);
+
+ r->viewport.scale[0] = r->pot_buffers ?
+ util_next_power_of_two(r->picture_width) : r->picture_width;
+ r->viewport.scale[1] = r->pot_buffers ?
+ util_next_power_of_two(r->picture_height) : r->picture_height;
+ r->viewport.scale[2] = 1;
+ r->viewport.scale[3] = 1;
+ r->viewport.translate[0] = 0;
+ r->viewport.translate[1] = 0;
+ r->viewport.translate[2] = 0;
+ r->viewport.translate[3] = 0;
+
+ r->fb_state.width = r->pot_buffers ?
+ util_next_power_of_two(r->picture_width) : r->picture_width;
+ r->fb_state.height = r->pot_buffers ?
+ util_next_power_of_two(r->picture_height) : r->picture_height;
+ r->fb_state.nr_cbufs = 1;
+ r->fb_state.zsbuf = NULL;
+
+ /* Luma filter */
+ filters[0] = PIPE_TEX_FILTER_NEAREST;
+ /* Chroma filters */
+ if (r->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_444 ||
+ r->eb_handling == VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ONE) {
+ filters[1] = PIPE_TEX_FILTER_NEAREST;
+ filters[2] = PIPE_TEX_FILTER_NEAREST;
+ }
+ else {
+ filters[1] = PIPE_TEX_FILTER_LINEAR;
+ filters[2] = PIPE_TEX_FILTER_LINEAR;
+ }
+ /* Fwd, bkwd ref filters */
+ filters[3] = PIPE_TEX_FILTER_LINEAR;
+ filters[4] = PIPE_TEX_FILTER_LINEAR;
+
+ for (i = 0; i < 5; ++i) {
+ sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+ sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+ sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+ sampler.min_img_filter = filters[i];
+ sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
+ sampler.mag_img_filter = filters[i];
+ sampler.compare_mode = PIPE_TEX_COMPARE_NONE;
+ sampler.compare_func = PIPE_FUNC_ALWAYS;
+ sampler.normalized_coords = 1;
+ /*sampler.shadow_ambient = ; */
+ /*sampler.lod_bias = ; */
+ sampler.min_lod = 0;
+ /*sampler.max_lod = ; */
+ /*sampler.border_color[i] = ; */
+ /*sampler.max_anisotropy = ; */
+ r->samplers.all[i] = r->pipe->create_sampler_state(r->pipe, &sampler);
+ }
+
+ return true;
+}
+
+static void
+cleanup_pipe_state(struct vl_mpeg12_mc_renderer *r)
+{
+ unsigned i;
+
+ assert(r);
+
+ for (i = 0; i < 5; ++i)
+ r->pipe->delete_sampler_state(r->pipe, r->samplers.all[i]);
+}
+
+static bool
+init_shaders(struct vl_mpeg12_mc_renderer *r)
+{
+ assert(r);
+
+ create_intra_vert_shader(r);
+ create_intra_frag_shader(r);
+ create_frame_pred_vert_shader(r);
+ create_frame_pred_frag_shader(r);
+ create_frame_bi_pred_vert_shader(r);
+ create_frame_bi_pred_frag_shader(r);
+
+ return true;
+}
+
+static void
+cleanup_shaders(struct vl_mpeg12_mc_renderer *r)
+{
+ assert(r);
+
+ r->pipe->delete_vs_state(r->pipe, r->i_vs);
+ r->pipe->delete_fs_state(r->pipe, r->i_fs);
+ r->pipe->delete_vs_state(r->pipe, r->p_vs[0]);
+ r->pipe->delete_fs_state(r->pipe, r->p_fs[0]);
+ r->pipe->delete_vs_state(r->pipe, r->b_vs[0]);
+ r->pipe->delete_fs_state(r->pipe, r->b_fs[0]);
+}
+
+static bool
+init_buffers(struct vl_mpeg12_mc_renderer *r)
+{
+ struct pipe_resource template;
+ struct pipe_vertex_element vertex_elems[8];
+ struct pipe_sampler_view sampler_view;
+
+ const unsigned mbw =
+ align(r->picture_width, MACROBLOCK_WIDTH) / MACROBLOCK_WIDTH;
+ const unsigned mbh =
+ align(r->picture_height, MACROBLOCK_HEIGHT) / MACROBLOCK_HEIGHT;
+
+ unsigned i;
+
+ assert(r);
+
+ r->macroblocks_per_batch =
+ mbw * (r->bufmode == VL_MPEG12_MC_RENDERER_BUFFER_PICTURE ? mbh : 1);
+ r->num_macroblocks = 0;
+ r->macroblock_buf = MALLOC(r->macroblocks_per_batch * sizeof(struct pipe_mpeg12_macroblock));
+
+ memset(&template, 0, sizeof(struct pipe_resource));
+ template.target = PIPE_TEXTURE_2D;
+ /* TODO: Accomodate HW that can't do this and also for cases when this isn't precise enough */
+ template.format = PIPE_FORMAT_R16_SNORM;
+ template.last_level = 0;
+ template.width0 = r->pot_buffers ?
+ util_next_power_of_two(r->picture_width) : r->picture_width;
+ template.height0 = r->pot_buffers ?
+ util_next_power_of_two(r->picture_height) : r->picture_height;
+ template.depth0 = 1;
+ template.usage = PIPE_USAGE_DYNAMIC;
+ template.bind = PIPE_BIND_SAMPLER_VIEW;
+ template.flags = 0;
+
+ r->textures.individual.y = r->pipe->screen->resource_create(r->pipe->screen, &template);
+
+ if (r->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420) {
+ template.width0 = r->pot_buffers ?
+ util_next_power_of_two(r->picture_width / 2) :
+ r->picture_width / 2;
+ template.height0 = r->pot_buffers ?
+ util_next_power_of_two(r->picture_height / 2) :
+ r->picture_height / 2;
+ }
+ else if (r->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_422)
+ template.height0 = r->pot_buffers ?
+ util_next_power_of_two(r->picture_height / 2) :
+ r->picture_height / 2;
+
+ r->textures.individual.cb =
+ r->pipe->screen->resource_create(r->pipe->screen, &template);
+ r->textures.individual.cr =
+ r->pipe->screen->resource_create(r->pipe->screen, &template);
+
+ for (i = 0; i < 3; ++i) {
+ u_sampler_view_default_template(&sampler_view,
+ r->textures.all[i],
+ r->textures.all[i]->format);
+ r->sampler_views.all[i] = r->pipe->create_sampler_view(r->pipe, r->textures.all[i], &sampler_view);
+ }
+
+ r->vertex_bufs.individual.ycbcr.stride = sizeof(struct vertex2f) * 4;
+ r->vertex_bufs.individual.ycbcr.max_index = 24 * r->macroblocks_per_batch - 1;
+ r->vertex_bufs.individual.ycbcr.buffer_offset = 0;
+ /* XXX: Create with usage DYNAMIC or STREAM */
+ r->vertex_bufs.individual.ycbcr.buffer = pipe_buffer_create
+ (
+ r->pipe->screen,
+ PIPE_BIND_VERTEX_BUFFER,
+ sizeof(struct vertex2f) * 4 * 24 * r->macroblocks_per_batch
+ );
+
+ for (i = 1; i < 3; ++i) {
+ r->vertex_bufs.all[i].stride = sizeof(struct vertex2f) * 2;
+ r->vertex_bufs.all[i].max_index = 24 * r->macroblocks_per_batch - 1;
+ r->vertex_bufs.all[i].buffer_offset = 0;
+ /* XXX: Create with usage DYNAMIC or STREAM */
+ r->vertex_bufs.all[i].buffer = pipe_buffer_create
+ (
+ r->pipe->screen,
+ PIPE_BIND_VERTEX_BUFFER,
+ sizeof(struct vertex2f) * 2 * 24 * r->macroblocks_per_batch
+ );
+ }
+
+ /* Position element */
+ vertex_elems[0].src_offset = 0;
+ vertex_elems[0].instance_divisor = 0;
+ vertex_elems[0].vertex_buffer_index = 0;
+ vertex_elems[0].src_format = PIPE_FORMAT_R32G32_FLOAT;
+
+ /* Luma, texcoord element */
+ vertex_elems[1].src_offset = sizeof(struct vertex2f);
+ vertex_elems[1].instance_divisor = 0;
+ vertex_elems[1].vertex_buffer_index = 0;
+ vertex_elems[1].src_format = PIPE_FORMAT_R32G32_FLOAT;
+
+ /* Chroma Cr texcoord element */
+ vertex_elems[2].src_offset = sizeof(struct vertex2f) * 2;
+ vertex_elems[2].instance_divisor = 0;
+ vertex_elems[2].vertex_buffer_index = 0;
+ vertex_elems[2].src_format = PIPE_FORMAT_R32G32_FLOAT;
+
+ /* Chroma Cb texcoord element */
+ vertex_elems[3].src_offset = sizeof(struct vertex2f) * 3;
+ vertex_elems[3].instance_divisor = 0;
+ vertex_elems[3].vertex_buffer_index = 0;
+ vertex_elems[3].src_format = PIPE_FORMAT_R32G32_FLOAT;
+
+ /* First ref surface top field texcoord element */
+ vertex_elems[4].src_offset = 0;
+ vertex_elems[4].instance_divisor = 0;
+ vertex_elems[4].vertex_buffer_index = 1;
+ vertex_elems[4].src_format = PIPE_FORMAT_R32G32_FLOAT;
+
+ /* First ref surface bottom field texcoord element */
+ vertex_elems[5].src_offset = sizeof(struct vertex2f);
+ vertex_elems[5].instance_divisor = 0;
+ vertex_elems[5].vertex_buffer_index = 1;
+ vertex_elems[5].src_format = PIPE_FORMAT_R32G32_FLOAT;
+
+ /* Second ref surface top field texcoord element */
+ vertex_elems[6].src_offset = 0;
+ vertex_elems[6].instance_divisor = 0;
+ vertex_elems[6].vertex_buffer_index = 2;
+ vertex_elems[6].src_format = PIPE_FORMAT_R32G32_FLOAT;
+
+ /* Second ref surface bottom field texcoord element */
+ vertex_elems[7].src_offset = sizeof(struct vertex2f);
+ vertex_elems[7].instance_divisor = 0;
+ vertex_elems[7].vertex_buffer_index = 2;
+ vertex_elems[7].src_format = PIPE_FORMAT_R32G32_FLOAT;
+
+ r->vertex_elems_state.individual.i = r->pipe->create_vertex_elements_state(r->pipe, 4, vertex_elems);
+ r->vertex_elems_state.individual.p = r->pipe->create_vertex_elements_state(r->pipe, 6, vertex_elems);
+ r->vertex_elems_state.individual.b = r->pipe->create_vertex_elements_state(r->pipe, 8, vertex_elems);
+
+ r->vs_const_buf = pipe_buffer_create
+ (
+ r->pipe->screen,
+ PIPE_BIND_CONSTANT_BUFFER,
+ sizeof(struct vertex_shader_consts)
+ );
+
+ return true;
+}
+
+static void
+cleanup_buffers(struct vl_mpeg12_mc_renderer *r)
+{
+ unsigned i;
+
+ assert(r);
+
+ pipe_resource_reference(&r->vs_const_buf, NULL);
+
+ for (i = 0; i < 3; ++i) {
+ pipe_sampler_view_reference(&r->sampler_views.all[i], NULL);
+ r->pipe->delete_vertex_elements_state(r->pipe, r->vertex_elems_state.all[i]);
+ pipe_resource_reference(&r->vertex_bufs.all[i].buffer, NULL);
+ pipe_resource_reference(&r->textures.all[i], NULL);
+ }
+
+ FREE(r->macroblock_buf);
+}
+
+static enum MACROBLOCK_TYPE
+get_macroblock_type(struct pipe_mpeg12_macroblock *mb)
+{
+ assert(mb);
+
+ switch (mb->mb_type) {
+ case PIPE_MPEG12_MACROBLOCK_TYPE_INTRA:
+ return MACROBLOCK_TYPE_INTRA;
+ case PIPE_MPEG12_MACROBLOCK_TYPE_FWD:
+ return mb->mo_type == PIPE_MPEG12_MOTION_TYPE_FRAME ?
+ MACROBLOCK_TYPE_FWD_FRAME_PRED : MACROBLOCK_TYPE_FWD_FIELD_PRED;
+ case PIPE_MPEG12_MACROBLOCK_TYPE_BKWD:
+ return mb->mo_type == PIPE_MPEG12_MOTION_TYPE_FRAME ?
+ MACROBLOCK_TYPE_BKWD_FRAME_PRED : MACROBLOCK_TYPE_BKWD_FIELD_PRED;
+ case PIPE_MPEG12_MACROBLOCK_TYPE_BI:
+ return mb->mo_type == PIPE_MPEG12_MOTION_TYPE_FRAME ?
+ MACROBLOCK_TYPE_BI_FRAME_PRED : MACROBLOCK_TYPE_BI_FIELD_PRED;
+ default:
+ assert(0);
+ }
+
+ /* Unreachable */
+ return -1;
+}
+
+static void
+gen_block_verts(struct vert_stream_0 *vb, unsigned cbp, unsigned mbx, unsigned mby,
+ const struct vertex2f *unit, const struct vertex2f *half, const struct vertex2f *offset,
+ unsigned luma_mask, unsigned cb_mask, unsigned cr_mask,
+ bool use_zeroblocks, struct vertex2f *zero_blocks)
+{
+ struct vertex2f v;
+
+ assert(vb);
+ assert(unit && half && offset);
+ assert(zero_blocks || !use_zeroblocks);
+
+ /* Generate vertices for two triangles covering a block */
+ v.x = mbx * unit->x + offset->x;
+ v.y = mby * unit->y + offset->y;
+
+ vb[0].pos.x = v.x;
+ vb[0].pos.y = v.y;
+ vb[1].pos.x = v.x;
+ vb[1].pos.y = v.y + half->y;
+ vb[2].pos.x = v.x + half->x;
+ vb[2].pos.y = v.y;
+ vb[3].pos.x = v.x + half->x;
+ vb[3].pos.y = v.y;
+ vb[4].pos.x = v.x;
+ vb[4].pos.y = v.y + half->y;
+ vb[5].pos.x = v.x + half->x;
+ vb[5].pos.y = v.y + half->y;
+
+ /* Generate texcoords for the triangles, either pointing to the correct area on the luma/chroma texture
+ or if zero blocks are being used, to the zero block if the appropriate CBP bits aren't set (i.e. no data
+ for this channel is defined for this block) */
+
+ if (!use_zeroblocks || cbp & luma_mask) {
+ v.x = mbx * unit->x + offset->x;
+ v.y = mby * unit->y + offset->y;
+ }
+ else {
+ v.x = zero_blocks[0].x;
+ v.y = zero_blocks[0].y;
+ }
+
+ vb[0].luma_tc.x = v.x;
+ vb[0].luma_tc.y = v.y;
+ vb[1].luma_tc.x = v.x;
+ vb[1].luma_tc.y = v.y + half->y;
+ vb[2].luma_tc.x = v.x + half->x;
+ vb[2].luma_tc.y = v.y;
+ vb[3].luma_tc.x = v.x + half->x;
+ vb[3].luma_tc.y = v.y;
+ vb[4].luma_tc.x = v.x;
+ vb[4].luma_tc.y = v.y + half->y;
+ vb[5].luma_tc.x = v.x + half->x;
+ vb[5].luma_tc.y = v.y + half->y;
+
+ if (!use_zeroblocks || cbp & cb_mask) {
+ v.x = mbx * unit->x + offset->x;
+ v.y = mby * unit->y + offset->y;
+ }
+ else {
+ v.x = zero_blocks[1].x;
+ v.y = zero_blocks[1].y;
+ }
+
+ vb[0].cb_tc.x = v.x;
+ vb[0].cb_tc.y = v.y;
+ vb[1].cb_tc.x = v.x;
+ vb[1].cb_tc.y = v.y + half->y;
+ vb[2].cb_tc.x = v.x + half->x;
+ vb[2].cb_tc.y = v.y;
+ vb[3].cb_tc.x = v.x + half->x;
+ vb[3].cb_tc.y = v.y;
+ vb[4].cb_tc.x = v.x;
+ vb[4].cb_tc.y = v.y + half->y;
+ vb[5].cb_tc.x = v.x + half->x;
+ vb[5].cb_tc.y = v.y + half->y;
+
+ if (!use_zeroblocks || cbp & cr_mask) {
+ v.x = mbx * unit->x + offset->x;
+ v.y = mby * unit->y + offset->y;
+ }
+ else {
+ v.x = zero_blocks[2].x;
+ v.y = zero_blocks[2].y;
+ }
+
+ vb[0].cr_tc.x = v.x;
+ vb[0].cr_tc.y = v.y;
+ vb[1].cr_tc.x = v.x;
+ vb[1].cr_tc.y = v.y + half->y;
+ vb[2].cr_tc.x = v.x + half->x;
+ vb[2].cr_tc.y = v.y;
+ vb[3].cr_tc.x = v.x + half->x;
+ vb[3].cr_tc.y = v.y;
+ vb[4].cr_tc.x = v.x;
+ vb[4].cr_tc.y = v.y + half->y;
+ vb[5].cr_tc.x = v.x + half->x;
+ vb[5].cr_tc.y = v.y + half->y;
+}
+
+static void
+gen_macroblock_verts(struct vl_mpeg12_mc_renderer *r,
+ struct pipe_mpeg12_macroblock *mb, unsigned pos,
+ struct vert_stream_0 *ycbcr_vb, struct vertex2f **ref_vb)
+{
+ struct vertex2f mo_vec[2];
+
+ unsigned i;
+
+ assert(r);
+ assert(mb);
+ assert(ycbcr_vb);
+ assert(pos < r->macroblocks_per_batch);
+
+ mo_vec[1].x = 0;
+ mo_vec[1].y = 0;
+
+ switch (mb->mb_type) {
+ case PIPE_MPEG12_MACROBLOCK_TYPE_BI:
+ {
+ struct vertex2f *vb;
+
+ assert(ref_vb && ref_vb[1]);
+
+ vb = ref_vb[1] + pos * 2 * 24;
+
+ mo_vec[0].x = mb->pmv[0][1][0] * 0.5f * r->surface_tex_inv_size.x;
+ mo_vec[0].y = mb->pmv[0][1][1] * 0.5f * r->surface_tex_inv_size.y;
+
+ if (mb->mo_type == PIPE_MPEG12_MOTION_TYPE_FRAME) {
+ for (i = 0; i < 24 * 2; i += 2) {
+ vb[i].x = mo_vec[0].x;
+ vb[i].y = mo_vec[0].y;
+ }
+ }
+ else {
+ mo_vec[1].x = mb->pmv[1][1][0] * 0.5f * r->surface_tex_inv_size.x;
+ mo_vec[1].y = mb->pmv[1][1][1] * 0.5f * r->surface_tex_inv_size.y;
+
+ for (i = 0; i < 24 * 2; i += 2) {
+ vb[i].x = mo_vec[0].x;
+ vb[i].y = mo_vec[0].y;
+ vb[i + 1].x = mo_vec[1].x;
+ vb[i + 1].y = mo_vec[1].y;
+ }
+ }
+
+ /* fall-through */
+ }
+ case PIPE_MPEG12_MACROBLOCK_TYPE_FWD:
+ case PIPE_MPEG12_MACROBLOCK_TYPE_BKWD:
+ {
+ struct vertex2f *vb;
+
+ assert(ref_vb && ref_vb[0]);
+
+ vb = ref_vb[0] + pos * 2 * 24;
+
+ if (mb->mb_type == PIPE_MPEG12_MACROBLOCK_TYPE_BKWD) {
+ mo_vec[0].x = mb->pmv[0][1][0] * 0.5f * r->surface_tex_inv_size.x;
+ mo_vec[0].y = mb->pmv[0][1][1] * 0.5f * r->surface_tex_inv_size.y;
+
+ if (mb->mo_type == PIPE_MPEG12_MOTION_TYPE_FIELD) {
+ mo_vec[1].x = mb->pmv[1][1][0] * 0.5f * r->surface_tex_inv_size.x;
+ mo_vec[1].y = mb->pmv[1][1][1] * 0.5f * r->surface_tex_inv_size.y;
+ }
+ }
+ else {
+ mo_vec[0].x = mb->pmv[0][0][0] * 0.5f * r->surface_tex_inv_size.x;
+ mo_vec[0].y = mb->pmv[0][0][1] * 0.5f * r->surface_tex_inv_size.y;
+
+ if (mb->mo_type == PIPE_MPEG12_MOTION_TYPE_FIELD) {
+ mo_vec[1].x = mb->pmv[1][0][0] * 0.5f * r->surface_tex_inv_size.x;
+ mo_vec[1].y = mb->pmv[1][0][1] * 0.5f * r->surface_tex_inv_size.y;
+ }
+ }
+
+ if (mb->mo_type == PIPE_MPEG12_MOTION_TYPE_FRAME) {
+ for (i = 0; i < 24 * 2; i += 2) {
+ vb[i].x = mo_vec[0].x;
+ vb[i].y = mo_vec[0].y;
+ }
+ }
+ else {
+ for (i = 0; i < 24 * 2; i += 2) {
+ vb[i].x = mo_vec[0].x;
+ vb[i].y = mo_vec[0].y;
+ vb[i + 1].x = mo_vec[1].x;
+ vb[i + 1].y = mo_vec[1].y;
+ }
+ }
+
+ /* fall-through */
+ }
+ case PIPE_MPEG12_MACROBLOCK_TYPE_INTRA:
+ {
+ const struct vertex2f unit =
+ {
+ r->surface_tex_inv_size.x * MACROBLOCK_WIDTH,
+ r->surface_tex_inv_size.y * MACROBLOCK_HEIGHT
+ };
+ const struct vertex2f half =
+ {
+ r->surface_tex_inv_size.x * (MACROBLOCK_WIDTH / 2),
+ r->surface_tex_inv_size.y * (MACROBLOCK_HEIGHT / 2)
+ };
+ const struct vertex2f offsets[2][2] =
+ {
+ {
+ {0, 0}, {0, half.y}
+ },
+ {
+ {half.x, 0}, {half.x, half.y}
+ }
+ };
+ const bool use_zb = r->eb_handling == VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ONE;
+
+ struct vert_stream_0 *vb = ycbcr_vb + pos * 24;
+
+ gen_block_verts(vb, mb->cbp, mb->mbx, mb->mby,
+ &unit, &half, &offsets[0][0],
+ 32, 2, 1, use_zb, r->zero_block);
+
+ gen_block_verts(vb + 6, mb->cbp, mb->mbx, mb->mby,
+ &unit, &half, &offsets[1][0],
+ 16, 2, 1, use_zb, r->zero_block);
+
+ gen_block_verts(vb + 12, mb->cbp, mb->mbx, mb->mby,
+ &unit, &half, &offsets[0][1],
+ 8, 2, 1, use_zb, r->zero_block);
+
+ gen_block_verts(vb + 18, mb->cbp, mb->mbx, mb->mby,
+ &unit, &half, &offsets[1][1],
+ 4, 2, 1, use_zb, r->zero_block);
+
+ break;
+ }
+ default:
+ assert(0);
+ }
+}
+
+static void
+gen_macroblock_stream(struct vl_mpeg12_mc_renderer *r,
+ unsigned *num_macroblocks)
+{
+ unsigned offset[NUM_MACROBLOCK_TYPES];
+ struct vert_stream_0 *ycbcr_vb;
+ struct vertex2f *ref_vb[2];
+ struct pipe_transfer *buf_transfer[3];
+ unsigned i;
+
+ assert(r);
+ assert(num_macroblocks);
+
+ for (i = 0; i < r->num_macroblocks; ++i) {
+ enum MACROBLOCK_TYPE mb_type = get_macroblock_type(&r->macroblock_buf[i]);
+ ++num_macroblocks[mb_type];
+ }
+
+ offset[0] = 0;
+
+ for (i = 1; i < NUM_MACROBLOCK_TYPES; ++i)
+ offset[i] = offset[i - 1] + num_macroblocks[i - 1];
+
+ ycbcr_vb = (struct vert_stream_0 *)pipe_buffer_map
+ (
+ r->pipe,
+ r->vertex_bufs.individual.ycbcr.buffer,
+ PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD,
+ &buf_transfer[0]
+ );
+
+ for (i = 0; i < 2; ++i)
+ ref_vb[i] = (struct vertex2f *)pipe_buffer_map
+ (
+ r->pipe,
+ r->vertex_bufs.individual.ref[i].buffer,
+ PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD,
+ &buf_transfer[i + 1]
+ );
+
+ for (i = 0; i < r->num_macroblocks; ++i) {
+ enum MACROBLOCK_TYPE mb_type = get_macroblock_type(&r->macroblock_buf[i]);
+
+ gen_macroblock_verts(r, &r->macroblock_buf[i], offset[mb_type],
+ ycbcr_vb, ref_vb);
+
+ ++offset[mb_type];
+ }
+
+ pipe_buffer_unmap(r->pipe, r->vertex_bufs.individual.ycbcr.buffer, buf_transfer[0]);
+ for (i = 0; i < 2; ++i)
+ pipe_buffer_unmap(r->pipe, r->vertex_bufs.individual.ref[i].buffer, buf_transfer[i + 1]);
+}
+
+static struct pipe_sampler_view
+*find_or_create_sampler_view(struct vl_mpeg12_mc_renderer *r, struct pipe_surface *surface)
+{
+ struct pipe_sampler_view *sampler_view;
+ assert(r);
+ assert(surface);
+
+ sampler_view = (struct pipe_sampler_view*)util_keymap_lookup(r->texview_map, &surface);
+ if (!sampler_view) {
+ struct pipe_sampler_view templat;
+ boolean added_to_map;
+
+ u_sampler_view_default_template(&templat, surface->texture,
+ surface->texture->format);
+ sampler_view = r->pipe->create_sampler_view(r->pipe, surface->texture,
+ &templat);
+ if (!sampler_view)
+ return NULL;
+
+ added_to_map = util_keymap_insert(r->texview_map, &surface,
+ sampler_view, r->pipe);
+ assert(added_to_map);
+ }
+
+ return sampler_view;
+}
+
+static void
+flush(struct vl_mpeg12_mc_renderer *r)
+{
+ unsigned num_macroblocks[NUM_MACROBLOCK_TYPES] = { 0 };
+ unsigned vb_start = 0;
+ struct vertex_shader_consts *vs_consts;
+ struct pipe_transfer *buf_transfer;
+ unsigned i;
+
+ assert(r);
+ assert(r->num_macroblocks == r->macroblocks_per_batch);
+
+ gen_macroblock_stream(r, num_macroblocks);
+
+ r->fb_state.cbufs[0] = r->surface;
+
+ r->pipe->set_framebuffer_state(r->pipe, &r->fb_state);
+ r->pipe->set_viewport_state(r->pipe, &r->viewport);
+
+ vs_consts = pipe_buffer_map
+ (
+ r->pipe, r->vs_const_buf,
+ PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD,
+ &buf_transfer
+ );
+
+ vs_consts->denorm.x = r->surface->width;
+ vs_consts->denorm.y = r->surface->height;
+
+ pipe_buffer_unmap(r->pipe, r->vs_const_buf, buf_transfer);
+
+ r->pipe->set_constant_buffer(r->pipe, PIPE_SHADER_VERTEX, 0,
+ r->vs_const_buf);
+
+ if (num_macroblocks[MACROBLOCK_TYPE_INTRA] > 0) {
+ r->pipe->set_vertex_buffers(r->pipe, 1, r->vertex_bufs.all);
+ r->pipe->bind_vertex_elements_state(r->pipe, r->vertex_elems_state.individual.i);
+ r->pipe->set_fragment_sampler_views(r->pipe, 3, r->sampler_views.all);
+ r->pipe->bind_fragment_sampler_states(r->pipe, 3, r->samplers.all);
+ r->pipe->bind_vs_state(r->pipe, r->i_vs);
+ r->pipe->bind_fs_state(r->pipe, r->i_fs);
+
+ r->pipe->draw_arrays(r->pipe, PIPE_PRIM_TRIANGLES, vb_start,
+ num_macroblocks[MACROBLOCK_TYPE_INTRA] * 24);
+ vb_start += num_macroblocks[MACROBLOCK_TYPE_INTRA] * 24;
+ }
+
+ if (num_macroblocks[MACROBLOCK_TYPE_FWD_FRAME_PRED] > 0) {
+ r->pipe->set_vertex_buffers(r->pipe, 2, r->vertex_bufs.all);
+ r->pipe->bind_vertex_elements_state(r->pipe, r->vertex_elems_state.individual.p);
+ r->textures.individual.ref[0] = r->past->texture;
+ r->sampler_views.individual.ref[0] = find_or_create_sampler_view(r, r->past);
+ r->pipe->set_fragment_sampler_views(r->pipe, 4, r->sampler_views.all);
+ r->pipe->bind_fragment_sampler_states(r->pipe, 4, r->samplers.all);
+ r->pipe->bind_vs_state(r->pipe, r->p_vs[0]);
+ r->pipe->bind_fs_state(r->pipe, r->p_fs[0]);
+
+ r->pipe->draw_arrays(r->pipe, PIPE_PRIM_TRIANGLES, vb_start,
+ num_macroblocks[MACROBLOCK_TYPE_FWD_FRAME_PRED] * 24);
+ vb_start += num_macroblocks[MACROBLOCK_TYPE_FWD_FRAME_PRED] * 24;
+ }
+
+ if (false /*num_macroblocks[MACROBLOCK_TYPE_FWD_FIELD_PRED] > 0 */ ) {
+ r->pipe->set_vertex_buffers(r->pipe, 2, r->vertex_bufs.all);
+ r->pipe->bind_vertex_elements_state(r->pipe, r->vertex_elems_state.individual.p);
+ r->textures.individual.ref[0] = r->past->texture;
+ r->sampler_views.individual.ref[0] = find_or_create_sampler_view(r, r->past);
+ r->pipe->set_fragment_sampler_views(r->pipe, 4, r->sampler_views.all);
+ r->pipe->bind_fragment_sampler_states(r->pipe, 4, r->samplers.all);
+ r->pipe->bind_vs_state(r->pipe, r->p_vs[1]);
+ r->pipe->bind_fs_state(r->pipe, r->p_fs[1]);
+
+ r->pipe->draw_arrays(r->pipe, PIPE_PRIM_TRIANGLES, vb_start,
+ num_macroblocks[MACROBLOCK_TYPE_FWD_FIELD_PRED] * 24);
+ vb_start += num_macroblocks[MACROBLOCK_TYPE_FWD_FIELD_PRED] * 24;
+ }
+
+ if (num_macroblocks[MACROBLOCK_TYPE_BKWD_FRAME_PRED] > 0) {
+ r->pipe->set_vertex_buffers(r->pipe, 2, r->vertex_bufs.all);
+ r->pipe->bind_vertex_elements_state(r->pipe, r->vertex_elems_state.individual.p);
+ r->textures.individual.ref[0] = r->future->texture;
+ r->sampler_views.individual.ref[0] = find_or_create_sampler_view(r, r->future);
+ r->pipe->set_fragment_sampler_views(r->pipe, 4, r->sampler_views.all);
+ r->pipe->bind_fragment_sampler_states(r->pipe, 4, r->samplers.all);
+ r->pipe->bind_vs_state(r->pipe, r->p_vs[0]);
+ r->pipe->bind_fs_state(r->pipe, r->p_fs[0]);
+
+ r->pipe->draw_arrays(r->pipe, PIPE_PRIM_TRIANGLES, vb_start,
+ num_macroblocks[MACROBLOCK_TYPE_BKWD_FRAME_PRED] * 24);
+ vb_start += num_macroblocks[MACROBLOCK_TYPE_BKWD_FRAME_PRED] * 24;
+ }
+
+ if (false /*num_macroblocks[MACROBLOCK_TYPE_BKWD_FIELD_PRED] > 0*/ ) {
+ r->pipe->set_vertex_buffers(r->pipe, 2, r->vertex_bufs.all);
+ r->pipe->bind_vertex_elements_state(r->pipe, r->vertex_elems_state.individual.p);
+ r->textures.individual.ref[0] = r->future->texture;
+ r->sampler_views.individual.ref[0] = find_or_create_sampler_view(r, r->future);
+ r->pipe->set_fragment_sampler_views(r->pipe, 4, r->sampler_views.all);
+ r->pipe->bind_fragment_sampler_states(r->pipe, 4, r->samplers.all);
+ r->pipe->bind_vs_state(r->pipe, r->p_vs[1]);
+ r->pipe->bind_fs_state(r->pipe, r->p_fs[1]);
+
+ r->pipe->draw_arrays(r->pipe, PIPE_PRIM_TRIANGLES, vb_start,
+ num_macroblocks[MACROBLOCK_TYPE_BKWD_FIELD_PRED] * 24);
+ vb_start += num_macroblocks[MACROBLOCK_TYPE_BKWD_FIELD_PRED] * 24;
+ }
+
+ if (num_macroblocks[MACROBLOCK_TYPE_BI_FRAME_PRED] > 0) {
+ r->pipe->set_vertex_buffers(r->pipe, 3, r->vertex_bufs.all);
+ r->pipe->bind_vertex_elements_state(r->pipe, r->vertex_elems_state.individual.b);
+ r->textures.individual.ref[0] = r->past->texture;
+ r->textures.individual.ref[1] = r->future->texture;
+ r->sampler_views.individual.ref[0] = find_or_create_sampler_view(r, r->past);
+ r->sampler_views.individual.ref[1] = find_or_create_sampler_view(r, r->future);
+ r->pipe->set_fragment_sampler_views(r->pipe, 5, r->sampler_views.all);
+ r->pipe->bind_fragment_sampler_states(r->pipe, 5, r->samplers.all);
+ r->pipe->bind_vs_state(r->pipe, r->b_vs[0]);
+ r->pipe->bind_fs_state(r->pipe, r->b_fs[0]);
+
+ r->pipe->draw_arrays(r->pipe, PIPE_PRIM_TRIANGLES, vb_start,
+ num_macroblocks[MACROBLOCK_TYPE_BI_FRAME_PRED] * 24);
+ vb_start += num_macroblocks[MACROBLOCK_TYPE_BI_FRAME_PRED] * 24;
+ }
+
+ if (false /*num_macroblocks[MACROBLOCK_TYPE_BI_FIELD_PRED] > 0 */ ) {
+ r->pipe->set_vertex_buffers(r->pipe, 3, r->vertex_bufs.all);
+ r->pipe->bind_vertex_elements_state(r->pipe, r->vertex_elems_state.individual.b);
+ r->textures.individual.ref[0] = r->past->texture;
+ r->textures.individual.ref[1] = r->future->texture;
+ r->sampler_views.individual.ref[0] = find_or_create_sampler_view(r, r->past);
+ r->sampler_views.individual.ref[1] = find_or_create_sampler_view(r, r->future);
+ r->pipe->set_fragment_sampler_views(r->pipe, 5, r->sampler_views.all);
+ r->pipe->bind_fragment_sampler_states(r->pipe, 5, r->samplers.all);
+ r->pipe->bind_vs_state(r->pipe, r->b_vs[1]);
+ r->pipe->bind_fs_state(r->pipe, r->b_fs[1]);
+
+ r->pipe->draw_arrays(r->pipe, PIPE_PRIM_TRIANGLES, vb_start,
+ num_macroblocks[MACROBLOCK_TYPE_BI_FIELD_PRED] * 24);
+ vb_start += num_macroblocks[MACROBLOCK_TYPE_BI_FIELD_PRED] * 24;
+ }
+
+ r->pipe->flush(r->pipe, PIPE_FLUSH_RENDER_CACHE, r->fence);
+
+ if (r->eb_handling == VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ONE)
+ for (i = 0; i < 3; ++i)
+ r->zero_block[i].x = ZERO_BLOCK_NIL;
+
+ r->num_macroblocks = 0;
+}
+
+static void
+grab_frame_coded_block(short *src, short *dst, unsigned dst_pitch)
+{
+ unsigned y;
+
+ assert(src);
+ assert(dst);
+
+ for (y = 0; y < BLOCK_HEIGHT; ++y)
+ memcpy(dst + y * dst_pitch, src + y * BLOCK_WIDTH, BLOCK_WIDTH * 2);
+}
+
+static void
+grab_field_coded_block(short *src, short *dst, unsigned dst_pitch)
+{
+ unsigned y;
+
+ assert(src);
+ assert(dst);
+
+ for (y = 0; y < BLOCK_HEIGHT; ++y)
+ memcpy(dst + y * dst_pitch * 2, src + y * BLOCK_WIDTH, BLOCK_WIDTH * 2);
+}
+
+static void
+fill_zero_block(short *dst, unsigned dst_pitch)
+{
+ unsigned y;
+
+ assert(dst);
+
+ for (y = 0; y < BLOCK_HEIGHT; ++y)
+ memset(dst + y * dst_pitch, 0, BLOCK_WIDTH * 2);
+}
+
+static void
+grab_blocks(struct vl_mpeg12_mc_renderer *r, unsigned mbx, unsigned mby,
+ enum pipe_mpeg12_dct_type dct_type, unsigned cbp, short *blocks)
+{
+ unsigned tex_pitch;
+ short *texels;
+ unsigned tb = 0, sb = 0;
+ unsigned mbpx = mbx * MACROBLOCK_WIDTH, mbpy = mby * MACROBLOCK_HEIGHT;
+ unsigned x, y;
+
+ assert(r);
+ assert(blocks);
+
+ tex_pitch = r->tex_transfer[0]->stride / util_format_get_blocksize(r->tex_transfer[0]->resource->format);
+ texels = r->texels[0] + mbpy * tex_pitch + mbpx;
+
+ for (y = 0; y < 2; ++y) {
+ for (x = 0; x < 2; ++x, ++tb) {
+ if ((cbp >> (5 - tb)) & 1) {
+ if (dct_type == PIPE_MPEG12_DCT_TYPE_FRAME) {
+ grab_frame_coded_block(blocks + sb * BLOCK_WIDTH * BLOCK_HEIGHT,
+ texels + y * tex_pitch * BLOCK_WIDTH +
+ x * BLOCK_WIDTH, tex_pitch);
+ }
+ else {
+ grab_field_coded_block(blocks + sb * BLOCK_WIDTH * BLOCK_HEIGHT,
+ texels + y * tex_pitch + x * BLOCK_WIDTH,
+ tex_pitch);
+ }
+
+ ++sb;
+ }
+ else if (r->eb_handling != VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_NONE) {
+ if (r->eb_handling == VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ALL ||
+ ZERO_BLOCK_IS_NIL(r->zero_block[0])) {
+ fill_zero_block(texels + y * tex_pitch * BLOCK_WIDTH + x * BLOCK_WIDTH, tex_pitch);
+ if (r->eb_handling == VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ONE) {
+ r->zero_block[0].x = (mbpx + x * 8) * r->surface_tex_inv_size.x;
+ r->zero_block[0].y = (mbpy + y * 8) * r->surface_tex_inv_size.y;
+ }
+ }
+ }
+ }
+ }
+
+ /* TODO: Implement 422, 444 */
+ assert(r->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420);
+
+ mbpx /= 2;
+ mbpy /= 2;
+
+ for (tb = 0; tb < 2; ++tb) {
+ tex_pitch = r->tex_transfer[tb + 1]->stride / util_format_get_blocksize(r->tex_transfer[tb + 1]->resource->format);
+ texels = r->texels[tb + 1] + mbpy * tex_pitch + mbpx;
+
+ if ((cbp >> (1 - tb)) & 1) {
+ grab_frame_coded_block(blocks + sb * BLOCK_WIDTH * BLOCK_HEIGHT, texels, tex_pitch);
+ ++sb;
+ }
+ else if (r->eb_handling != VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_NONE) {
+ if (r->eb_handling == VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ALL ||
+ ZERO_BLOCK_IS_NIL(r->zero_block[tb + 1])) {
+ fill_zero_block(texels, tex_pitch);
+ if (r->eb_handling == VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ONE) {
+ r->zero_block[tb + 1].x = (mbpx << 1) * r->surface_tex_inv_size.x;
+ r->zero_block[tb + 1].y = (mbpy << 1) * r->surface_tex_inv_size.y;
+ }
+ }
+ }
+ }
+}
+
+static void
+grab_macroblock(struct vl_mpeg12_mc_renderer *r,
+ struct pipe_mpeg12_macroblock *mb)
+{
+ assert(r);
+ assert(mb);
+ assert(mb->blocks);
+ assert(r->num_macroblocks < r->macroblocks_per_batch);
+
+ memcpy(&r->macroblock_buf[r->num_macroblocks], mb,
+ sizeof(struct pipe_mpeg12_macroblock));
+
+ grab_blocks(r, mb->mbx, mb->mby, mb->dct_type, mb->cbp, mb->blocks);
+
+ ++r->num_macroblocks;
+}
+
+static void
+texview_map_delete(const struct keymap *map,
+ const void *key, void *data,
+ void *user)
+{
+ struct pipe_sampler_view *sv = (struct pipe_sampler_view*)data;
+
+ assert(map);
+ assert(key);
+ assert(data);
+ assert(user);
+
+ pipe_sampler_view_reference(&sv, NULL);
+}
+
+bool
+vl_mpeg12_mc_renderer_init(struct vl_mpeg12_mc_renderer *renderer,
+ struct pipe_context *pipe,
+ unsigned picture_width,
+ unsigned picture_height,
+ enum pipe_video_chroma_format chroma_format,
+ enum VL_MPEG12_MC_RENDERER_BUFFER_MODE bufmode,
+ enum VL_MPEG12_MC_RENDERER_EMPTY_BLOCK eb_handling,
+ bool pot_buffers)
+{
+ unsigned i;
+
+ assert(renderer);
+ assert(pipe);
+ /* TODO: Implement other policies */
+ assert(bufmode == VL_MPEG12_MC_RENDERER_BUFFER_PICTURE);
+ /* TODO: Implement this */
+ /* XXX: XFER_ALL sampling issue at block edges when using bilinear filtering */
+ assert(eb_handling != VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_NONE);
+ /* TODO: Non-pot buffers untested, probably doesn't work without changes to texcoord generation, vert shader, etc */
+ assert(pot_buffers);
+
+ memset(renderer, 0, sizeof(struct vl_mpeg12_mc_renderer));
+
+ renderer->pipe = pipe;
+ renderer->picture_width = picture_width;
+ renderer->picture_height = picture_height;
+ renderer->chroma_format = chroma_format;
+ renderer->bufmode = bufmode;
+ renderer->eb_handling = eb_handling;
+ renderer->pot_buffers = pot_buffers;
+
+ renderer->texview_map = util_new_keymap(sizeof(struct pipe_surface*), -1,
+ texview_map_delete);
+ if (!renderer->texview_map)
+ return false;
+
+ if (!init_pipe_state(renderer)) {
+ util_delete_keymap(renderer->texview_map, renderer->pipe);
+ return false;
+ }
+ if (!init_shaders(renderer)) {
+ util_delete_keymap(renderer->texview_map, renderer->pipe);
+ cleanup_pipe_state(renderer);
+ return false;
+ }
+ if (!init_buffers(renderer)) {
+ util_delete_keymap(renderer->texview_map, renderer->pipe);
+ cleanup_shaders(renderer);
+ cleanup_pipe_state(renderer);
+ return false;
+ }
+
+ renderer->surface = NULL;
+ renderer->past = NULL;
+ renderer->future = NULL;
+ for (i = 0; i < 3; ++i)
+ renderer->zero_block[i].x = ZERO_BLOCK_NIL;
+ renderer->num_macroblocks = 0;
+
+ xfer_buffers_map(renderer);
+
+ return true;
+}
+
+void
+vl_mpeg12_mc_renderer_cleanup(struct vl_mpeg12_mc_renderer *renderer)
+{
+ assert(renderer);
+
+ xfer_buffers_unmap(renderer);
+
+ util_delete_keymap(renderer->texview_map, renderer->pipe);
+ cleanup_pipe_state(renderer);
+ cleanup_shaders(renderer);
+ cleanup_buffers(renderer);
+
+ pipe_surface_reference(&renderer->surface, NULL);
+ pipe_surface_reference(&renderer->past, NULL);
+ pipe_surface_reference(&renderer->future, NULL);
+}
+
+void
+vl_mpeg12_mc_renderer_render_macroblocks(struct vl_mpeg12_mc_renderer
+ *renderer,
+ struct pipe_surface *surface,
+ struct pipe_surface *past,
+ struct pipe_surface *future,
+ unsigned num_macroblocks,
+ struct pipe_mpeg12_macroblock
+ *mpeg12_macroblocks,
+ struct pipe_fence_handle **fence)
+{
+ bool new_surface = false;
+
+ assert(renderer);
+ assert(surface);
+ assert(num_macroblocks);
+ assert(mpeg12_macroblocks);
+
+ if (renderer->surface) {
+ if (surface != renderer->surface) {
+ if (renderer->num_macroblocks > 0) {
+ xfer_buffers_unmap(renderer);
+ flush(renderer);
+ }
+
+ new_surface = true;
+ }
+
+ /* If the surface we're rendering hasn't changed the ref frames shouldn't change. */
+ assert(surface != renderer->surface || renderer->past == past);
+ assert(surface != renderer->surface || renderer->future == future);
+ }
+ else
+ new_surface = true;
+
+ if (new_surface) {
+ pipe_surface_reference(&renderer->surface, surface);
+ pipe_surface_reference(&renderer->past, past);
+ pipe_surface_reference(&renderer->future, future);
+ renderer->fence = fence;
+ renderer->surface_tex_inv_size.x = 1.0f / surface->width;
+ renderer->surface_tex_inv_size.y = 1.0f / surface->height;
+ }
+
+ while (num_macroblocks) {
+ unsigned left_in_batch = renderer->macroblocks_per_batch - renderer->num_macroblocks;
+ unsigned num_to_submit = MIN2(num_macroblocks, left_in_batch);
+ unsigned i;
+
+ for (i = 0; i < num_to_submit; ++i) {
+ assert(mpeg12_macroblocks[i].base.codec == PIPE_VIDEO_CODEC_MPEG12);
+ grab_macroblock(renderer, &mpeg12_macroblocks[i]);
+ }
+
+ num_macroblocks -= num_to_submit;
+
+ if (renderer->num_macroblocks == renderer->macroblocks_per_batch) {
+ xfer_buffers_unmap(renderer);
+ flush(renderer);
+ xfer_buffers_map(renderer);
+ /* Next time we get this surface it may have new ref frames */
+ pipe_surface_reference(&renderer->surface, NULL);
+ pipe_surface_reference(&renderer->past, NULL);
+ pipe_surface_reference(&renderer->future, NULL);
+ }
+ }
+}
diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h
new file mode 100644
index 00000000000..85191cf6b02
--- /dev/null
+++ b/src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h
@@ -0,0 +1,132 @@
+/**************************************************************************
+ *
+ * Copyright 2009 Younes Manton.
+ * 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 TUNGSTEN GRAPHICS 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 vl_mpeg12_mc_renderer_h
+#define vl_mpeg12_mc_renderer_h
+
+#include <pipe/p_compiler.h>
+#include <pipe/p_state.h>
+#include <pipe/p_video_state.h>
+#include "vl_types.h"
+
+struct pipe_context;
+struct pipe_macroblock;
+struct keymap;
+
+/* A slice is video-width (rounded up to a multiple of macroblock width) x macroblock height */
+enum VL_MPEG12_MC_RENDERER_BUFFER_MODE
+{
+ VL_MPEG12_MC_RENDERER_BUFFER_SLICE, /* Saves memory at the cost of smaller batches */
+ VL_MPEG12_MC_RENDERER_BUFFER_PICTURE /* Larger batches, more memory */
+};
+
+enum VL_MPEG12_MC_RENDERER_EMPTY_BLOCK
+{
+ VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ALL, /* Waste of memory bandwidth */
+ VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ONE, /* Can only do point-filtering when interpolating subsampled chroma channels */
+ VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_NONE /* Needs conditional texel fetch! */
+};
+
+struct vl_mpeg12_mc_renderer
+{
+ struct pipe_context *pipe;
+ unsigned picture_width;
+ unsigned picture_height;
+ enum pipe_video_chroma_format chroma_format;
+ enum VL_MPEG12_MC_RENDERER_BUFFER_MODE bufmode;
+ enum VL_MPEG12_MC_RENDERER_EMPTY_BLOCK eb_handling;
+ bool pot_buffers;
+ unsigned macroblocks_per_batch;
+
+ struct pipe_viewport_state viewport;
+ struct pipe_resource *vs_const_buf;
+ struct pipe_framebuffer_state fb_state;
+ union
+ {
+ void *all[3];
+ struct { void *i, *p, *b; } individual;
+ } vertex_elems_state;
+
+ union
+ {
+ void *all[5];
+ struct { void *y, *cb, *cr, *ref[2]; } individual;
+ } samplers;
+
+ union
+ {
+ struct pipe_sampler_view *all[5];
+ struct { struct pipe_sampler_view *y, *cb, *cr, *ref[2]; } individual;
+ } sampler_views;
+
+ void *i_vs, *p_vs[2], *b_vs[2];
+ void *i_fs, *p_fs[2], *b_fs[2];
+
+ union
+ {
+ struct pipe_resource *all[5];
+ struct { struct pipe_resource *y, *cb, *cr, *ref[2]; } individual;
+ } textures;
+
+ union
+ {
+ struct pipe_vertex_buffer all[3];
+ struct { struct pipe_vertex_buffer ycbcr, ref[2]; } individual;
+ } vertex_bufs;
+
+ struct pipe_surface *surface, *past, *future;
+ struct pipe_fence_handle **fence;
+ unsigned num_macroblocks;
+ struct pipe_mpeg12_macroblock *macroblock_buf;
+ struct pipe_transfer *tex_transfer[3];
+ short *texels[3];
+ struct vertex2f surface_tex_inv_size;
+ struct vertex2f zero_block[3];
+
+ struct keymap *texview_map;
+};
+
+bool vl_mpeg12_mc_renderer_init(struct vl_mpeg12_mc_renderer *renderer,
+ struct pipe_context *pipe,
+ unsigned picture_width,
+ unsigned picture_height,
+ enum pipe_video_chroma_format chroma_format,
+ enum VL_MPEG12_MC_RENDERER_BUFFER_MODE bufmode,
+ enum VL_MPEG12_MC_RENDERER_EMPTY_BLOCK eb_handling,
+ bool pot_buffers);
+
+void vl_mpeg12_mc_renderer_cleanup(struct vl_mpeg12_mc_renderer *renderer);
+
+void vl_mpeg12_mc_renderer_render_macroblocks(struct vl_mpeg12_mc_renderer *renderer,
+ struct pipe_surface *surface,
+ struct pipe_surface *past,
+ struct pipe_surface *future,
+ unsigned num_macroblocks,
+ struct pipe_mpeg12_macroblock *mpeg12_macroblocks,
+ struct pipe_fence_handle **fence);
+
+#endif /* vl_mpeg12_mc_renderer_h */
diff --git a/src/gallium/auxiliary/vl/vl_types.h b/src/gallium/auxiliary/vl/vl_types.h
new file mode 100644
index 00000000000..ce175546894
--- /dev/null
+++ b/src/gallium/auxiliary/vl/vl_types.h
@@ -0,0 +1,41 @@
+/**************************************************************************
+ *
+ * Copyright 2009 Younes Manton.
+ * 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 TUNGSTEN GRAPHICS 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 vl_types_h
+#define vl_types_h
+
+struct vertex2f
+{
+ float x, y;
+};
+
+struct vertex4f
+{
+ float x, y, z, w;
+};
+
+#endif /* vl_types_h */
diff --git a/src/gallium/drivers/nv40/nv40_video_context.c b/src/gallium/drivers/nv40/nv40_video_context.c
new file mode 100644
index 00000000000..15a26ea3b3b
--- /dev/null
+++ b/src/gallium/drivers/nv40/nv40_video_context.c
@@ -0,0 +1,48 @@
+/**************************************************************************
+ *
+ * Copyright 2009 Younes Manton.
+ * 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 TUNGSTEN GRAPHICS 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.
+ *
+ **************************************************************************/
+
+#include "nv40_video_context.h"
+#include <softpipe/sp_video_context.h>
+
+struct pipe_video_context *
+nv40_video_create(struct pipe_screen *screen, enum pipe_video_profile profile,
+ enum pipe_video_chroma_format chroma_format,
+ unsigned width, unsigned height, void *priv)
+{
+ struct pipe_context *pipe;
+
+ assert(screen);
+
+ pipe = screen->context_create(screen, priv);
+ if (!pipe)
+ return NULL;
+
+ return sp_video_create_ex(pipe, profile, chroma_format, width, height,
+ VL_MPEG12_MC_RENDERER_BUFFER_PICTURE,
+ VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ONE,
+ true);
+}
diff --git a/src/gallium/drivers/nv40/nv40_video_context.h b/src/gallium/drivers/nv40/nv40_video_context.h
new file mode 100644
index 00000000000..64196caca72
--- /dev/null
+++ b/src/gallium/drivers/nv40/nv40_video_context.h
@@ -0,0 +1,38 @@
+/**************************************************************************
+ *
+ * Copyright 2009 Younes Manton.
+ * 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 TUNGSTEN GRAPHICS 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 __NV40_VIDEO_CONTEXT_H__
+#define __NV40_VIDEO_CONTEXT_H__
+
+#include <pipe/p_video_context.h>
+
+struct pipe_video_context *
+nv40_video_create(struct pipe_screen *screen, enum pipe_video_profile profile,
+ enum pipe_video_chroma_format chroma_format,
+ unsigned width, unsigned height, void *priv);
+
+#endif
diff --git a/src/gallium/drivers/nvfx/Makefile b/src/gallium/drivers/nvfx/Makefile
index 46bb0823881..95da7782256 100644
--- a/src/gallium/drivers/nvfx/Makefile
+++ b/src/gallium/drivers/nvfx/Makefile
@@ -24,7 +24,8 @@ C_SOURCES = \
nvfx_surface.c \
nvfx_transfer.c \
nvfx_vbo.c \
- nvfx_vertprog.c
+ nvfx_vertprog.c \
+ nvfx_video_context.c
LIBRARY_INCLUDES = \
-I$(TOP)/src/gallium/drivers/nouveau/include
diff --git a/src/gallium/drivers/nvfx/nvfx_screen.c b/src/gallium/drivers/nvfx/nvfx_screen.c
index 8024800bd09..875b3a96ca6 100644
--- a/src/gallium/drivers/nvfx/nvfx_screen.c
+++ b/src/gallium/drivers/nvfx/nvfx_screen.c
@@ -6,6 +6,7 @@
#include "nouveau/nouveau_screen.h"
#include "nouveau/nv_object.xml.h"
#include "nvfx_context.h"
+#include "nvfx_video_context.h"
#include "nvfx_screen.h"
#include "nvfx_resource.h"
#include "nvfx_tex.h"
@@ -434,6 +435,7 @@ nvfx_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
pscreen->get_paramf = nvfx_screen_get_paramf;
pscreen->is_format_supported = nvfx_screen_is_format_supported;
pscreen->context_create = nvfx_create;
+ pscreen->video_context_create = nvfx_video_create;
switch (dev->chipset & 0xf0) {
case 0x30:
diff --git a/src/gallium/drivers/nvfx/nvfx_state.h b/src/gallium/drivers/nvfx/nvfx_state.h
index 8fafca1950c..15e1cbb1986 100644
--- a/src/gallium/drivers/nvfx/nvfx_state.h
+++ b/src/gallium/drivers/nvfx/nvfx_state.h
@@ -2,6 +2,7 @@
#define __NVFX_STATE_H__
#include "pipe/p_state.h"
+#include "pipe/p_video_state.h"
#include "tgsi/tgsi_scan.h"
#include "nouveau/nouveau_statebuf.h"
#include "util/u_dynarray.h"
diff --git a/src/gallium/drivers/nvfx/nvfx_video_context.c b/src/gallium/drivers/nvfx/nvfx_video_context.c
new file mode 100644
index 00000000000..9212ae57fc0
--- /dev/null
+++ b/src/gallium/drivers/nvfx/nvfx_video_context.c
@@ -0,0 +1,49 @@
+/**************************************************************************
+ *
+ * Copyright 2009 Younes Manton.
+ * 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 TUNGSTEN GRAPHICS 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.
+ *
+ **************************************************************************/
+
+#include "nvfx_video_context.h"
+#include <softpipe/sp_video_context.h>
+
+struct pipe_video_context *
+nvfx_video_create(struct pipe_screen *screen, enum pipe_video_profile profile,
+ enum pipe_video_chroma_format chroma_format,
+ unsigned width, unsigned height, void *priv)
+{
+ struct pipe_context *pipe;
+
+ assert(screen);
+
+ pipe = screen->context_create(screen, priv);
+ if (!pipe)
+ return NULL;
+
+ return sp_video_create_ex(pipe, profile, chroma_format, width, height,
+ VL_MPEG12_MC_RENDERER_BUFFER_PICTURE,
+ VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ONE,
+ true,
+ PIPE_FORMAT_VUYX);
+}
diff --git a/src/gallium/drivers/nvfx/nvfx_video_context.h b/src/gallium/drivers/nvfx/nvfx_video_context.h
new file mode 100644
index 00000000000..6619427cc29
--- /dev/null
+++ b/src/gallium/drivers/nvfx/nvfx_video_context.h
@@ -0,0 +1,38 @@
+/**************************************************************************
+ *
+ * Copyright 2009 Younes Manton.
+ * 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 TUNGSTEN GRAPHICS 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 __NVFX_VIDEO_CONTEXT_H__
+#define __NVFX_VIDEO_CONTEXT_H__
+
+#include <pipe/p_video_context.h>
+
+struct pipe_video_context *
+nvfx_video_create(struct pipe_screen *screen, enum pipe_video_profile profile,
+ enum pipe_video_chroma_format chroma_format,
+ unsigned width, unsigned height, void *priv);
+
+#endif
diff --git a/src/gallium/drivers/r300/r300_video_context.c b/src/gallium/drivers/r300/r300_video_context.c
new file mode 100644
index 00000000000..622f1b8820b
--- /dev/null
+++ b/src/gallium/drivers/r300/r300_video_context.c
@@ -0,0 +1,329 @@
+/*
+ * Copyright (C) 2009-2010 Advanced Micro Devices, Inc.
+ *
+ * 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 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 COPYRIGHT HOLDER(S) 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:
+ */
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <pipe/p_defines.h>
+#include <pipe/p_context.h>
+#include <pipe/p_screen.h>
+#include <pipe/p_inlines.h>
+#include <util/u_memory.h>
+#include <X11/Xlib.h>
+
+#include <fcntl.h>
+
+#include "radeon_buffer.h"
+#include "radeon_r300.h"
+#include "r300_screen.h"
+#include "r300_texture.h"
+#include "p_video_context.h"
+#include "radeon_vl.h"
+#include "softpipe/sp_winsys.h"
+#include "softpipe/sp_texture.h"
+
+#include "r300_video_context.h"
+#include <softpipe/sp_video_context.h>
+
+static void r300_mpeg12_destroy(struct pipe_video_context *vpipe)
+{
+ struct radeon_mpeg12_context *ctx = (struct radeon_mpeg12_context*)vpipe;
+
+ assert(vpipe);
+
+ ctx->pipe->bind_vs_state(ctx->pipe, NULL);
+ ctx->pipe->bind_fs_state(ctx->pipe, NULL);
+
+ ctx->pipe->delete_blend_state(ctx->pipe, ctx->blend);
+ ctx->pipe->delete_rasterizer_state(ctx->pipe, ctx->rast);
+ ctx->pipe->delete_depth_stencil_alpha_state(ctx->pipe, ctx->dsa);
+
+ pipe_video_surface_reference(&ctx->decode_target, NULL);
+ vl_compositor_cleanup(&ctx->compositor);
+ vl_mpeg12_mc_renderer_cleanup(&ctx->mc_renderer);
+ ctx->pipe->destroy(ctx->pipe);
+
+ FREE(ctx);
+}
+
+static void
+r300_mpeg12_decode_macroblocks(struct pipe_video_context *vpipe,
+ struct pipe_video_surface *past,
+ struct pipe_video_surface *future,
+ unsigned num_macroblocks,
+ struct pipe_macroblock *macroblocks,
+ struct pipe_fence_handle **fence)
+{
+ struct radeon_mpeg12_context *ctx = (struct radeon_mpeg12_context*)vpipe;
+ struct pipe_mpeg12_macroblock *mpeg12_macroblocks =
+ (struct pipe_mpeg12_macroblock*)macroblocks;
+
+ assert(vpipe);
+ assert(num_macroblocks);
+ assert(macroblocks);
+ assert(macroblocks->codec == PIPE_VIDEO_CODEC_MPEG12);
+ assert(ctx->decode_target);
+
+ vl_mpeg12_mc_renderer_render_macroblocks(
+ &ctx->mc_renderer,
+ r300_video_surface(ctx->decode_target)->tex,
+ past ? r300_video_surface(past)->tex : NULL,
+ future ? r300_video_surface(future)->tex : NULL,
+ num_macroblocks, mpeg12_macroblocks, fence);
+}
+
+static void r300_mpeg12_clear_surface(struct pipe_video_context *vpipe,
+ unsigned x, unsigned y,
+ unsigned width, unsigned height,
+ unsigned value,
+ struct pipe_surface *surface)
+{
+ struct radeon_mpeg12_context *ctx = (struct radeon_mpeg12_context*)vpipe;
+
+ assert(vpipe);
+ assert(surface);
+
+ if (ctx->pipe->surface_fill)
+ ctx->pipe->surface_fill(ctx->pipe, surface, x, y, width, height, value);
+ else
+ util_surface_fill(ctx->pipe, surface, x, y, width, height, value);
+}
+
+static void
+r300_mpeg12_render_picture(struct pipe_video_context *vpipe,
+ struct pipe_video_surface *src_surface,
+ enum pipe_mpeg12_picture_type picture_type,
+ struct pipe_video_rect *src_area,
+ struct pipe_surface *dst_surface,
+ struct pipe_video_rect *dst_area,
+ struct pipe_fence_handle **fence)
+{
+ struct radeon_mpeg12_context *ctx = (struct radeon_mpeg12_context*)vpipe;
+
+ assert(vpipe);
+ assert(src_surface);
+ assert(src_area);
+ assert(dst_surface);
+ assert(dst_area);
+
+ vl_compositor_render(&ctx->compositor,
+ r300_video_surface(src_surface)->tex,
+ picture_type, src_area, dst_surface->texture,
+ dst_area, fence);
+}
+
+static void r300_mpeg12_set_decode_target(struct pipe_video_context *vpipe,
+ struct pipe_video_surface *dt)
+{
+ struct radeon_mpeg12_context *ctx = (struct radeon_mpeg12_context*)vpipe;
+
+ assert(vpipe);
+ assert(dt);
+
+ pipe_video_surface_reference(&ctx->decode_target, dt);
+}
+
+static void r300_mpeg12_set_csc_matrix(struct pipe_video_context *vpipe,
+ const float *mat)
+{
+ struct radeon_mpeg12_context *ctx = (struct radeon_mpeg12_context*)vpipe;
+
+ assert(vpipe);
+
+ vl_compositor_set_csc_matrix(&ctx->compositor, mat);
+}
+
+static bool r300_mpeg12_init_pipe_state(struct radeon_mpeg12_context *ctx)
+{
+ struct pipe_rasterizer_state rast;
+ struct pipe_blend_state blend;
+ struct pipe_depth_stencil_alpha_state dsa;
+ unsigned i;
+
+ assert(ctx);
+
+ rast.flatshade = 1;
+ rast.flatshade_first = 0;
+ rast.light_twoside = 0;
+ rast.front_winding = PIPE_WINDING_CCW;
+ rast.cull_mode = PIPE_WINDING_CW;
+ rast.fill_cw = PIPE_POLYGON_MODE_FILL;
+ rast.fill_ccw = PIPE_POLYGON_MODE_FILL;
+ rast.offset_cw = 0;
+ rast.offset_ccw = 0;
+ rast.scissor = 0;
+ rast.poly_smooth = 0;
+ rast.poly_stipple_enable = 0;
+ rast.point_sprite = 0;
+ rast.point_size_per_vertex = 0;
+ rast.multisample = 0;
+ rast.line_smooth = 0;
+ rast.line_stipple_enable = 0;
+ rast.line_stipple_factor = 0;
+ rast.line_stipple_pattern = 0;
+ rast.line_last_pixel = 0;
+ rast.bypass_vs_clip_and_viewport = 0;
+ rast.line_width = 1;
+ rast.point_smooth = 0;
+ rast.point_size = 1;
+ rast.offset_units = 1;
+ rast.offset_scale = 1;
+ /*rast.sprite_coord_mode[i] = ;*/
+ ctx->rast = ctx->pipe->create_rasterizer_state(ctx->pipe, &rast);
+ ctx->pipe->bind_rasterizer_state(ctx->pipe, ctx->rast);
+
+ blend.blend_enable = 0;
+ blend.rgb_func = PIPE_BLEND_ADD;
+ blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rgb_dst_factor = PIPE_BLENDFACTOR_ONE;
+ blend.alpha_func = PIPE_BLEND_ADD;
+ blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.alpha_dst_factor = PIPE_BLENDFACTOR_ONE;
+ blend.logicop_enable = 0;
+ blend.logicop_func = PIPE_LOGICOP_CLEAR;
+ /* Needed to allow color writes to FB, even if blending disabled */
+ blend.colormask = PIPE_MASK_RGBA;
+ blend.dither = 0;
+ ctx->blend = ctx->pipe->create_blend_state(ctx->pipe, &blend);
+ ctx->pipe->bind_blend_state(ctx->pipe, ctx->blend);
+
+ dsa.depth.enabled = 0;
+ dsa.depth.writemask = 0;
+ dsa.depth.func = PIPE_FUNC_ALWAYS;
+ for (i = 0; i < 2; ++i)
+ {
+ dsa.stencil[i].enabled = 0;
+ dsa.stencil[i].func = PIPE_FUNC_ALWAYS;
+ dsa.stencil[i].fail_op = PIPE_STENCIL_OP_KEEP;
+ dsa.stencil[i].zpass_op = PIPE_STENCIL_OP_KEEP;
+ dsa.stencil[i].zfail_op = PIPE_STENCIL_OP_KEEP;
+ dsa.stencil[i].ref_value = 0;
+ dsa.stencil[i].valuemask = 0;
+ dsa.stencil[i].writemask = 0;
+ }
+ dsa.alpha.enabled = 0;
+ dsa.alpha.func = PIPE_FUNC_ALWAYS;
+ dsa.alpha.ref_value = 0;
+ ctx->dsa = ctx->pipe->create_depth_stencil_alpha_state(ctx->pipe, &dsa);
+ ctx->pipe->bind_depth_stencil_alpha_state(ctx->pipe, ctx->dsa);
+
+ return true;
+}
+
+static struct pipe_video_context *
+r300_mpeg12_context_create(struct pipe_screen *screen,
+ enum pipe_video_profile profile,
+ enum pipe_video_chroma_format chroma_format,
+ unsigned int width,
+ unsigned int height)
+{
+ struct radeon_mpeg12_context *ctx;
+ ctx = CALLOC_STRUCT(radeon_mpeg12_context);
+ if (!ctx)
+ return NULL;
+
+ ctx->base.profile = profile;
+ ctx->base.chroma_format = chroma_format;
+ ctx->base.width = width;
+ ctx->base.height = height;
+ ctx->base.screen = screen;
+
+ ctx->base.destroy = radeon_mpeg12_destroy;
+ ctx->base.decode_macroblocks = radeon_mpeg12_decode_macroblocks;
+ ctx->base.clear_surface = radeon_mpeg12_clear_surface;
+ ctx->base.render_picture = radeon_mpeg12_render_picture;
+ ctx->base.set_decode_target = radeon_mpeg12_set_decode_target;
+ ctx->base.set_csc_matrix = radeon_mpeg12_set_csc_matrix;
+
+ ctx->pipe = r300_create_context(screen,(struct r300_winsys*)screen->winsys);
+ if (!ctx->pipe)
+ {
+ FREE(ctx);
+ return NULL;
+ }
+
+ if (!vl_mpeg12_mc_renderer_init(&ctx->mc_renderer, ctx->pipe,
+ width, height, chroma_format,
+ VL_MPEG12_MC_RENDERER_BUFFER_PICTURE,
+ VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ONE,
+ true))
+ {
+ ctx->pipe->destroy(ctx->pipe);
+ FREE(ctx);
+ return NULL;
+ }
+
+ if (!vl_compositor_init(&ctx->compositor, ctx->pipe))
+ {
+ vl_mpeg12_mc_renderer_cleanup(&ctx->mc_renderer);
+ ctx->pipe->destroy(ctx->pipe);
+ FREE(ctx);
+ return NULL;
+ }
+
+ if (!radeon_mpeg12_init_pipe_state(ctx))
+ {
+ vl_compositor_cleanup(&ctx->compositor);
+ vl_mpeg12_mc_renderer_cleanup(&ctx->mc_renderer);
+ ctx->pipe->destroy(ctx->pipe);
+ FREE(ctx);
+ return NULL;
+ }
+
+ return &ctx->base;
+}
+
+struct pipe_video_context *
+r300_video_create(struct pipe_context *pipe, enum pipe_video_profile profile,
+ enum pipe_video_chroma_format chroma_format,
+ unsigned width, unsigned height,
+ unsigned pvctx_id)
+{
+ struct pipe_video_context *vpipe;
+ struct radeon_vl_context *rvl_ctx;
+
+ assert(p_screen);
+ assert(width && height);
+
+ /* create radeon pipe_context */
+ switch(u_reduce_video_profile(profile))
+ {
+ case PIPE_VIDEO_CODEC_MPEG12:
+ vpipe = radeon_mpeg12_context_create(p_screen, profile, chr_f,
+ width, height);
+ break;
+ default:
+ return NULL;
+ }
+
+ /* create radeon_vl_context */
+ rvl_ctx = calloc(1, sizeof(struct radeon_vl_context));
+ rvl_ctx->display = display;
+ rvl_ctx->screen = screen;
+
+ vpipe->priv = rvl_ctx;
+
+ return vpipe;
+}
diff --git a/src/gallium/drivers/r300/r300_video_context.h b/src/gallium/drivers/r300/r300_video_context.h
new file mode 100644
index 00000000000..a8210ba7b71
--- /dev/null
+++ b/src/gallium/drivers/r300/r300_video_context.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2009-2010 Advanced Micro Devices, Inc.
+ *
+ * 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 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 COPYRIGHT HOLDER(S) 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:
+ */
+
+#ifndef __R300_VIDEO_CONTEXT_H__
+#define __R300_VIDEO_CONTEXT_H__
+
+#include <pipe/p_video_context.h>
+
+struct pipe_context;
+
+struct pipe_video_context*
+r300_video_create(struct pipe_context *pipe, enum pipe_video_profile profile,
+ enum pipe_video_chroma_format chroma_format,
+ unsigned width, unsigned height,
+ unsigned pvctx_id);
+
+#endif
diff --git a/src/gallium/drivers/softpipe/Makefile b/src/gallium/drivers/softpipe/Makefile
index 28953582f0a..8876bd16398 100644
--- a/src/gallium/drivers/softpipe/Makefile
+++ b/src/gallium/drivers/softpipe/Makefile
@@ -19,7 +19,7 @@ C_SOURCES = \
sp_quad_fs.c \
sp_quad_blend.c \
sp_screen.c \
- sp_setup.c \
+ sp_setup.c \
sp_state_blend.c \
sp_state_clip.c \
sp_state_derived.c \
@@ -33,6 +33,7 @@ C_SOURCES = \
sp_tex_sample.c \
sp_tex_tile_cache.c \
sp_tile_cache.c \
- sp_surface.c
+ sp_surface.c \
+ sp_video_context.c
include ../../Makefile.template
diff --git a/src/gallium/drivers/softpipe/SConscript b/src/gallium/drivers/softpipe/SConscript
index d5f4d28aeff..dea7f885e0d 100644
--- a/src/gallium/drivers/softpipe/SConscript
+++ b/src/gallium/drivers/softpipe/SConscript
@@ -35,6 +35,7 @@ softpipe = env.ConvenienceLibrary(
'sp_tex_tile_cache.c',
'sp_texture.c',
'sp_tile_cache.c',
+ 'sp_video_context.c',
])
Export('softpipe')
diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c
index 2053d02f628..25a0a622179 100644
--- a/src/gallium/drivers/softpipe/sp_screen.c
+++ b/src/gallium/drivers/softpipe/sp_screen.c
@@ -39,6 +39,7 @@
#include "sp_texture.h"
#include "sp_screen.h"
#include "sp_context.h"
+#include "sp_video_context.h"
#include "sp_fence.h"
#include "sp_public.h"
@@ -301,6 +302,7 @@ softpipe_create_screen(struct sw_winsys *winsys)
screen->base.is_format_supported = softpipe_is_format_supported;
screen->base.context_create = softpipe_create_context;
screen->base.flush_frontbuffer = softpipe_flush_frontbuffer;
+ screen->base.video_context_create = sp_video_create;
util_format_s3tc_init();
diff --git a/src/gallium/drivers/softpipe/sp_texture.h b/src/gallium/drivers/softpipe/sp_texture.h
index 6b205dc5329..7e3249b46f0 100644
--- a/src/gallium/drivers/softpipe/sp_texture.h
+++ b/src/gallium/drivers/softpipe/sp_texture.h
@@ -82,7 +82,6 @@ struct softpipe_transfer
};
-
/** cast wrappers */
static INLINE struct softpipe_resource *
softpipe_resource(struct pipe_resource *pt)
diff --git a/src/gallium/drivers/softpipe/sp_video_context.c b/src/gallium/drivers/softpipe/sp_video_context.c
new file mode 100644
index 00000000000..44df00e0b78
--- /dev/null
+++ b/src/gallium/drivers/softpipe/sp_video_context.c
@@ -0,0 +1,526 @@
+/**************************************************************************
+ *
+ * Copyright 2009 Younes Manton.
+ * 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 TUNGSTEN GRAPHICS 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.
+ *
+ **************************************************************************/
+
+#include "util/u_inlines.h"
+#include "util/u_memory.h"
+
+#include "sp_video_context.h"
+#include <util/u_inlines.h>
+#include <util/u_memory.h>
+#include <util/u_rect.h>
+#include <util/u_video.h>
+#include "sp_public.h"
+#include "sp_texture.h"
+
+static void
+sp_mpeg12_destroy(struct pipe_video_context *vpipe)
+{
+ struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
+
+ assert(vpipe);
+
+ /* Asserted in softpipe_delete_fs_state() for some reason */
+ ctx->pipe->bind_vs_state(ctx->pipe, NULL);
+ ctx->pipe->bind_fs_state(ctx->pipe, NULL);
+
+ ctx->pipe->delete_blend_state(ctx->pipe, ctx->blend);
+ ctx->pipe->delete_rasterizer_state(ctx->pipe, ctx->rast);
+ ctx->pipe->delete_depth_stencil_alpha_state(ctx->pipe, ctx->dsa);
+
+ pipe_surface_reference(&ctx->decode_target, NULL);
+ vl_compositor_cleanup(&ctx->compositor);
+ vl_mpeg12_mc_renderer_cleanup(&ctx->mc_renderer);
+ ctx->pipe->destroy(ctx->pipe);
+
+ FREE(ctx);
+}
+
+static int
+sp_mpeg12_get_param(struct pipe_video_context *vpipe, int param)
+{
+ struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
+
+ assert(vpipe);
+
+ switch (param) {
+ case PIPE_CAP_NPOT_TEXTURES:
+ /* XXX: Temporary; not all paths are NPOT-tested */
+#if 0
+ return ctx->pipe->screen->get_param(ctx->pipe->screen, param);
+#endif
+ return FALSE;
+ case PIPE_CAP_DECODE_TARGET_PREFERRED_FORMAT:
+ return ctx->decode_format;
+ default:
+ {
+ debug_printf("Softpipe: Unknown PIPE_CAP %d\n", param);
+ return 0;
+ }
+ }
+}
+
+static boolean
+sp_mpeg12_is_format_supported(struct pipe_video_context *vpipe,
+ enum pipe_format format,
+ unsigned usage,
+ unsigned geom)
+{
+ struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
+
+ assert(vpipe);
+
+ /* XXX: Temporary; not all paths are NPOT-tested */
+ if (geom & PIPE_TEXTURE_GEOM_NON_POWER_OF_TWO)
+ return FALSE;
+
+ return ctx->pipe->screen->is_format_supported(ctx->pipe->screen, PIPE_TEXTURE_2D,
+ format, usage, geom);
+}
+
+static void
+sp_mpeg12_decode_macroblocks(struct pipe_video_context *vpipe,
+ struct pipe_surface *past,
+ struct pipe_surface *future,
+ unsigned num_macroblocks,
+ struct pipe_macroblock *macroblocks,
+ struct pipe_fence_handle **fence)
+{
+ struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
+ struct pipe_mpeg12_macroblock *mpeg12_macroblocks = (struct pipe_mpeg12_macroblock*)macroblocks;
+
+ assert(vpipe);
+ assert(num_macroblocks);
+ assert(macroblocks);
+ assert(macroblocks->codec == PIPE_VIDEO_CODEC_MPEG12);
+ assert(ctx->decode_target);
+
+ vl_mpeg12_mc_renderer_render_macroblocks(&ctx->mc_renderer,
+ ctx->decode_target,
+ past, future, num_macroblocks,
+ mpeg12_macroblocks, fence);
+}
+
+static void
+sp_mpeg12_surface_fill(struct pipe_video_context *vpipe,
+ struct pipe_surface *dst,
+ unsigned dstx, unsigned dsty,
+ unsigned width, unsigned height,
+ unsigned value)
+{
+ struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
+
+ assert(vpipe);
+ assert(dst);
+
+ if (ctx->pipe->surface_fill)
+ ctx->pipe->surface_fill(ctx->pipe, dst, dstx, dsty, width, height, value);
+ else
+ util_surface_fill(ctx->pipe, dst, dstx, dsty, width, height, value);
+}
+
+static void
+sp_mpeg12_surface_copy(struct pipe_video_context *vpipe,
+ struct pipe_surface *dst,
+ unsigned dstx, unsigned dsty,
+ struct pipe_surface *src,
+ unsigned srcx, unsigned srcy,
+ unsigned width, unsigned height)
+{
+ struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
+
+ assert(vpipe);
+ assert(dst);
+
+ if (ctx->pipe->surface_copy)
+ ctx->pipe->surface_copy(ctx->pipe, dst, dstx, dsty, src, srcx, srcy, width, height);
+ else
+ util_surface_copy(ctx->pipe, FALSE, dst, dstx, dsty, src, srcx, srcy, width, height);
+}
+
+static struct pipe_transfer*
+sp_mpeg12_get_transfer(struct pipe_video_context *vpipe,
+ struct pipe_resource *resource,
+ struct pipe_subresource subresource,
+ unsigned usage, /* a combination of PIPE_TRANSFER_x */
+ const struct pipe_box *box)
+{
+ struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
+
+ assert(vpipe);
+ assert(resource);
+ assert(box);
+
+ return ctx->pipe->get_transfer(ctx->pipe, resource, subresource, usage, box);
+}
+
+static void
+sp_mpeg12_transfer_destroy(struct pipe_video_context *vpipe,
+ struct pipe_transfer *transfer)
+{
+ struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
+
+ assert(vpipe);
+ assert(transfer);
+
+ ctx->pipe->transfer_destroy(ctx->pipe, transfer);
+}
+
+static void*
+sp_mpeg12_transfer_map(struct pipe_video_context *vpipe,
+ struct pipe_transfer *transfer)
+{
+ struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
+
+ assert(vpipe);
+ assert(transfer);
+
+ return ctx->pipe->transfer_map(ctx->pipe, transfer);
+}
+
+static void
+sp_mpeg12_transfer_flush_region(struct pipe_video_context *vpipe,
+ struct pipe_transfer *transfer,
+ const struct pipe_box *box)
+{
+ struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
+
+ assert(vpipe);
+ assert(transfer);
+ assert(box);
+
+ ctx->pipe->transfer_flush_region(ctx->pipe, transfer, box);
+}
+
+static void
+sp_mpeg12_transfer_unmap(struct pipe_video_context *vpipe,
+ struct pipe_transfer *transfer)
+{
+ struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
+
+ assert(vpipe);
+ assert(transfer);
+
+ ctx->pipe->transfer_unmap(ctx->pipe, transfer);
+}
+
+static void
+sp_mpeg12_transfer_inline_write(struct pipe_video_context *vpipe,
+ struct pipe_resource *resource,
+ struct pipe_subresource subresource,
+ unsigned usage, /* a combination of PIPE_TRANSFER_x */
+ const struct pipe_box *box,
+ const void *data,
+ unsigned stride,
+ unsigned slice_stride)
+{
+ struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
+
+ assert(vpipe);
+ assert(resource);
+ assert(box);
+ assert(data);
+ assert(ctx->pipe->transfer_inline_write);
+
+ ctx->pipe->transfer_inline_write(ctx->pipe, resource, subresource, usage,
+ box, data, stride, slice_stride);
+}
+
+static void
+sp_mpeg12_render_picture(struct pipe_video_context *vpipe,
+ struct pipe_surface *src_surface,
+ enum pipe_mpeg12_picture_type picture_type,
+ /*unsigned num_past_surfaces,
+ struct pipe_surface *past_surfaces,
+ unsigned num_future_surfaces,
+ struct pipe_surface *future_surfaces,*/
+ struct pipe_video_rect *src_area,
+ struct pipe_surface *dst_surface,
+ struct pipe_video_rect *dst_area,
+ struct pipe_fence_handle **fence)
+{
+ struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
+
+ assert(vpipe);
+ assert(src_surface);
+ assert(src_area);
+ assert(dst_surface);
+ assert(dst_area);
+
+ vl_compositor_render(&ctx->compositor, src_surface,
+ picture_type, src_area, dst_surface, dst_area, fence);
+}
+
+static void
+sp_mpeg12_set_picture_background(struct pipe_video_context *vpipe,
+ struct pipe_surface *bg,
+ struct pipe_video_rect *bg_src_rect)
+{
+ struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
+
+ assert(vpipe);
+ assert(bg);
+ assert(bg_src_rect);
+
+ vl_compositor_set_background(&ctx->compositor, bg, bg_src_rect);
+}
+
+static void
+sp_mpeg12_set_picture_layers(struct pipe_video_context *vpipe,
+ struct pipe_surface *layers[],
+ struct pipe_video_rect *src_rects[],
+ struct pipe_video_rect *dst_rects[],
+ unsigned num_layers)
+{
+ struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
+
+ assert(vpipe);
+ assert((layers && src_rects && dst_rects) ||
+ (!layers && !src_rects && !dst_rects));
+
+ vl_compositor_set_layers(&ctx->compositor, layers, src_rects, dst_rects, num_layers);
+}
+
+static void
+sp_mpeg12_set_decode_target(struct pipe_video_context *vpipe,
+ struct pipe_surface *dt)
+{
+ struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
+
+ assert(vpipe);
+ assert(dt);
+
+ pipe_surface_reference(&ctx->decode_target, dt);
+}
+
+static void
+sp_mpeg12_set_csc_matrix(struct pipe_video_context *vpipe, const float *mat)
+{
+ struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
+
+ assert(vpipe);
+
+ vl_compositor_set_csc_matrix(&ctx->compositor, mat);
+}
+
+static bool
+init_pipe_state(struct sp_mpeg12_context *ctx)
+{
+ struct pipe_rasterizer_state rast;
+ struct pipe_blend_state blend;
+ struct pipe_depth_stencil_alpha_state dsa;
+ unsigned i;
+
+ assert(ctx);
+
+ rast.flatshade = 1;
+ rast.flatshade_first = 0;
+ rast.light_twoside = 0;
+ rast.front_winding = PIPE_WINDING_CCW;
+ rast.cull_mode = PIPE_WINDING_CW;
+ rast.fill_cw = PIPE_POLYGON_MODE_FILL;
+ rast.fill_ccw = PIPE_POLYGON_MODE_FILL;
+ rast.offset_cw = 0;
+ rast.offset_ccw = 0;
+ rast.scissor = 0;
+ rast.poly_smooth = 0;
+ rast.poly_stipple_enable = 0;
+ rast.sprite_coord_enable = 0;
+ rast.point_size_per_vertex = 0;
+ rast.multisample = 0;
+ rast.line_smooth = 0;
+ rast.line_stipple_enable = 0;
+ rast.line_stipple_factor = 0;
+ rast.line_stipple_pattern = 0;
+ rast.line_last_pixel = 0;
+ rast.line_width = 1;
+ rast.point_smooth = 0;
+ rast.point_quad_rasterization = 0;
+ rast.point_size = 1;
+ rast.offset_units = 1;
+ rast.offset_scale = 1;
+ rast.gl_rasterization_rules = 1;
+ ctx->rast = ctx->pipe->create_rasterizer_state(ctx->pipe, &rast);
+ ctx->pipe->bind_rasterizer_state(ctx->pipe, ctx->rast);
+
+ blend.independent_blend_enable = 0;
+ blend.rt[0].blend_enable = 0;
+ blend.rt[0].rgb_func = PIPE_BLEND_ADD;
+ blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].alpha_func = PIPE_BLEND_ADD;
+ blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ONE;
+ blend.logicop_enable = 0;
+ blend.logicop_func = PIPE_LOGICOP_CLEAR;
+ /* Needed to allow color writes to FB, even if blending disabled */
+ blend.rt[0].colormask = PIPE_MASK_RGBA;
+ blend.dither = 0;
+ ctx->blend = ctx->pipe->create_blend_state(ctx->pipe, &blend);
+ ctx->pipe->bind_blend_state(ctx->pipe, ctx->blend);
+
+ dsa.depth.enabled = 0;
+ dsa.depth.writemask = 0;
+ dsa.depth.func = PIPE_FUNC_ALWAYS;
+ for (i = 0; i < 2; ++i) {
+ dsa.stencil[i].enabled = 0;
+ dsa.stencil[i].func = PIPE_FUNC_ALWAYS;
+ dsa.stencil[i].fail_op = PIPE_STENCIL_OP_KEEP;
+ dsa.stencil[i].zpass_op = PIPE_STENCIL_OP_KEEP;
+ dsa.stencil[i].zfail_op = PIPE_STENCIL_OP_KEEP;
+ dsa.stencil[i].valuemask = 0;
+ dsa.stencil[i].writemask = 0;
+ }
+ dsa.alpha.enabled = 0;
+ dsa.alpha.func = PIPE_FUNC_ALWAYS;
+ dsa.alpha.ref_value = 0;
+ ctx->dsa = ctx->pipe->create_depth_stencil_alpha_state(ctx->pipe, &dsa);
+ ctx->pipe->bind_depth_stencil_alpha_state(ctx->pipe, ctx->dsa);
+
+ return true;
+}
+
+static struct pipe_video_context *
+sp_mpeg12_create(struct pipe_context *pipe, enum pipe_video_profile profile,
+ enum pipe_video_chroma_format chroma_format,
+ unsigned width, unsigned height,
+ enum VL_MPEG12_MC_RENDERER_BUFFER_MODE bufmode,
+ enum VL_MPEG12_MC_RENDERER_EMPTY_BLOCK eb_handling,
+ bool pot_buffers,
+ enum pipe_format decode_format)
+{
+ struct sp_mpeg12_context *ctx;
+
+ assert(u_reduce_video_profile(profile) == PIPE_VIDEO_CODEC_MPEG12);
+
+ ctx = CALLOC_STRUCT(sp_mpeg12_context);
+
+ if (!ctx)
+ return NULL;
+
+ ctx->base.profile = profile;
+ ctx->base.chroma_format = chroma_format;
+ ctx->base.width = width;
+ ctx->base.height = height;
+
+ ctx->base.screen = pipe->screen;
+ ctx->base.destroy = sp_mpeg12_destroy;
+ ctx->base.get_param = sp_mpeg12_get_param;
+ ctx->base.is_format_supported = sp_mpeg12_is_format_supported;
+ ctx->base.decode_macroblocks = sp_mpeg12_decode_macroblocks;
+ ctx->base.render_picture = sp_mpeg12_render_picture;
+ ctx->base.surface_fill = sp_mpeg12_surface_fill;
+ ctx->base.surface_copy = sp_mpeg12_surface_copy;
+ ctx->base.get_transfer = sp_mpeg12_get_transfer;
+ ctx->base.transfer_destroy = sp_mpeg12_transfer_destroy;
+ ctx->base.transfer_map = sp_mpeg12_transfer_map;
+ ctx->base.transfer_flush_region = sp_mpeg12_transfer_flush_region;
+ ctx->base.transfer_unmap = sp_mpeg12_transfer_unmap;
+ if (pipe->transfer_inline_write)
+ ctx->base.transfer_inline_write = sp_mpeg12_transfer_inline_write;
+ ctx->base.set_picture_background = sp_mpeg12_set_picture_background;
+ ctx->base.set_picture_layers = sp_mpeg12_set_picture_layers;
+ ctx->base.set_decode_target = sp_mpeg12_set_decode_target;
+ ctx->base.set_csc_matrix = sp_mpeg12_set_csc_matrix;
+
+ ctx->pipe = pipe;
+ ctx->decode_format = decode_format;
+
+ if (!vl_mpeg12_mc_renderer_init(&ctx->mc_renderer, ctx->pipe,
+ width, height, chroma_format,
+ bufmode, eb_handling, pot_buffers)) {
+ ctx->pipe->destroy(ctx->pipe);
+ FREE(ctx);
+ return NULL;
+ }
+
+ if (!vl_compositor_init(&ctx->compositor, ctx->pipe)) {
+ vl_mpeg12_mc_renderer_cleanup(&ctx->mc_renderer);
+ ctx->pipe->destroy(ctx->pipe);
+ FREE(ctx);
+ return NULL;
+ }
+
+ if (!init_pipe_state(ctx)) {
+ vl_compositor_cleanup(&ctx->compositor);
+ vl_mpeg12_mc_renderer_cleanup(&ctx->mc_renderer);
+ ctx->pipe->destroy(ctx->pipe);
+ FREE(ctx);
+ return NULL;
+ }
+
+ return &ctx->base;
+}
+
+struct pipe_video_context *
+sp_video_create(struct pipe_screen *screen, enum pipe_video_profile profile,
+ enum pipe_video_chroma_format chroma_format,
+ unsigned width, unsigned height, void *priv)
+{
+ struct pipe_context *pipe;
+
+ assert(screen);
+ assert(width && height);
+
+ pipe = screen->context_create(screen, NULL);
+ if (!pipe)
+ return NULL;
+
+ /* TODO: Use slice buffering for softpipe when implemented, no advantage to buffering an entire picture with softpipe */
+ /* TODO: Use XFER_NONE when implemented */
+ return sp_video_create_ex(pipe, profile,
+ chroma_format,
+ width, height,
+ VL_MPEG12_MC_RENDERER_BUFFER_PICTURE,
+ VL_MPEG12_MC_RENDERER_EMPTY_BLOCK_XFER_ONE,
+ true,
+ PIPE_FORMAT_XYUV);
+}
+
+struct pipe_video_context *
+sp_video_create_ex(struct pipe_context *pipe, enum pipe_video_profile profile,
+ enum pipe_video_chroma_format chroma_format,
+ unsigned width, unsigned height,
+ enum VL_MPEG12_MC_RENDERER_BUFFER_MODE bufmode,
+ enum VL_MPEG12_MC_RENDERER_EMPTY_BLOCK eb_handling,
+ bool pot_buffers,
+ enum pipe_format decode_format)
+{
+ assert(pipe);
+ assert(width && height);
+
+ switch (u_reduce_video_profile(profile)) {
+ case PIPE_VIDEO_CODEC_MPEG12:
+ return sp_mpeg12_create(pipe, profile,
+ chroma_format,
+ width, height,
+ bufmode, eb_handling,
+ pot_buffers,
+ decode_format);
+ default:
+ return NULL;
+ }
+}
diff --git a/src/gallium/drivers/softpipe/sp_video_context.h b/src/gallium/drivers/softpipe/sp_video_context.h
new file mode 100644
index 00000000000..0fe48d7a872
--- /dev/null
+++ b/src/gallium/drivers/softpipe/sp_video_context.h
@@ -0,0 +1,69 @@
+/**************************************************************************
+ *
+ * Copyright 2009 Younes Manton.
+ * 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 TUNGSTEN GRAPHICS 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 SP_VIDEO_CONTEXT_H
+#define SP_VIDEO_CONTEXT_H
+
+#include <pipe/p_video_context.h>
+#include <vl/vl_mpeg12_mc_renderer.h>
+#include <vl/vl_compositor.h>
+
+struct pipe_screen;
+struct pipe_context;
+
+struct sp_mpeg12_context
+{
+ struct pipe_video_context base;
+ struct pipe_context *pipe;
+ struct pipe_surface *decode_target;
+ struct vl_mpeg12_mc_renderer mc_renderer;
+ struct vl_compositor compositor;
+
+ void *rast;
+ void *dsa;
+ void *blend;
+
+ enum pipe_format decode_format;
+};
+
+struct pipe_video_context *
+sp_video_create(struct pipe_screen *screen, enum pipe_video_profile profile,
+ enum pipe_video_chroma_format chroma_format,
+ unsigned width, unsigned height, void *priv);
+
+/* Other drivers can call this function in their pipe_video_context constructors and pass it
+ an accelerated pipe_context along with suitable buffering modes, etc */
+struct pipe_video_context *
+sp_video_create_ex(struct pipe_context *pipe, enum pipe_video_profile profile,
+ enum pipe_video_chroma_format chroma_format,
+ unsigned width, unsigned height,
+ enum VL_MPEG12_MC_RENDERER_BUFFER_MODE bufmode,
+ enum VL_MPEG12_MC_RENDERER_EMPTY_BLOCK eb_handling,
+ bool pot_buffers,
+ enum pipe_format decode_format);
+
+#endif /* SP_VIDEO_CONTEXT_H */
diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h
index 8b4663742fa..d2273b334a6 100644
--- a/src/gallium/include/pipe/p_defines.h
+++ b/src/gallium/include/pipe/p_defines.h
@@ -492,6 +492,33 @@ enum pipe_shader_cap
#define PIPE_REFERENCED_FOR_READ (1 << 0)
#define PIPE_REFERENCED_FOR_WRITE (1 << 1)
+
+enum pipe_video_codec
+{
+ PIPE_VIDEO_CODEC_UNKNOWN = 0,
+ PIPE_VIDEO_CODEC_MPEG12, /**< MPEG1, MPEG2 */
+ PIPE_VIDEO_CODEC_MPEG4, /**< DIVX, XVID */
+ PIPE_VIDEO_CODEC_VC1, /**< WMV */
+ PIPE_VIDEO_CODEC_MPEG4_AVC /**< H.264 */
+};
+
+enum pipe_video_profile
+{
+ PIPE_VIDEO_PROFILE_UNKNOWN,
+ PIPE_VIDEO_PROFILE_MPEG1,
+ PIPE_VIDEO_PROFILE_MPEG2_SIMPLE,
+ PIPE_VIDEO_PROFILE_MPEG2_MAIN,
+ PIPE_VIDEO_PROFILE_MPEG4_SIMPLE,
+ PIPE_VIDEO_PROFILE_MPEG4_ADVANCED_SIMPLE,
+ PIPE_VIDEO_PROFILE_VC1_SIMPLE,
+ PIPE_VIDEO_PROFILE_VC1_MAIN,
+ PIPE_VIDEO_PROFILE_VC1_ADVANCED,
+ PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE,
+ PIPE_VIDEO_PROFILE_MPEG4_AVC_MAIN,
+ PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH
+};
+
+
/**
* Composite query types
*/
@@ -506,6 +533,7 @@ struct pipe_query_data_timestamp_disjoint
boolean disjoint;
};
+
#ifdef __cplusplus
}
#endif
diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h
index 06412f4894c..240e349ba7e 100644
--- a/src/gallium/include/pipe/p_format.h
+++ b/src/gallium/include/pipe/p_format.h
@@ -186,9 +186,27 @@ enum pipe_format {
PIPE_FORMAT_R8G8B8X8_UNORM = 134,
PIPE_FORMAT_B4G4R4X4_UNORM = 135,
+ PIPE_FORMAT_YV12 = 136,
+ PIPE_FORMAT_YV16 = 137,
+ PIPE_FORMAT_IYUV = 138, /**< aka I420 */
+ PIPE_FORMAT_NV12 = 139,
+ PIPE_FORMAT_NV21 = 140,
+ PIPE_FORMAT_AYUV = PIPE_FORMAT_A8R8G8B8_UNORM,
+ PIPE_FORMAT_VUYA = PIPE_FORMAT_B8G8R8A8_UNORM,
+ PIPE_FORMAT_XYUV = PIPE_FORMAT_X8R8G8B8_UNORM,
+ PIPE_FORMAT_VUYX = PIPE_FORMAT_B8G8R8X8_UNORM,
+ PIPE_FORMAT_IA44 = 141,
+ PIPE_FORMAT_AI44 = 142,
+
PIPE_FORMAT_COUNT
};
+enum pipe_video_chroma_format
+{
+ PIPE_VIDEO_CHROMA_FORMAT_420,
+ PIPE_VIDEO_CHROMA_FORMAT_422,
+ PIPE_VIDEO_CHROMA_FORMAT_444
+};
#ifdef __cplusplus
}
diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h
index 912631242f5..75eeaeba1f7 100644
--- a/src/gallium/include/pipe/p_screen.h
+++ b/src/gallium/include/pipe/p_screen.h
@@ -92,8 +92,13 @@ struct pipe_screen {
*/
int (*get_shader_param)( struct pipe_screen *, unsigned shader, enum pipe_shader_cap param );
- struct pipe_context * (*context_create)( struct pipe_screen *,
- void *priv );
+ struct pipe_context * (*context_create)( struct pipe_screen *, void *priv );
+
+ struct pipe_video_context * (*video_context_create)( struct pipe_screen *screen,
+ enum pipe_video_profile profile,
+ enum pipe_video_chroma_format chroma_format,
+ unsigned width, unsigned height, void *priv );
+
/**
* Check if the given pipe_format is supported as a texture or
diff --git a/src/gallium/include/pipe/p_video_context.h b/src/gallium/include/pipe/p_video_context.h
new file mode 100644
index 00000000000..294dc464c36
--- /dev/null
+++ b/src/gallium/include/pipe/p_video_context.h
@@ -0,0 +1,178 @@
+/**************************************************************************
+ *
+ * Copyright 2009 Younes Manton.
+ * 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 TUNGSTEN GRAPHICS 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 PIPE_VIDEO_CONTEXT_H
+#define PIPE_VIDEO_CONTEXT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <pipe/p_video_state.h>
+
+/* XXX: Move to an appropriate place */
+#define PIPE_CAP_DECODE_TARGET_PREFERRED_FORMAT 256
+
+struct pipe_screen;
+struct pipe_buffer;
+struct pipe_surface;
+struct pipe_macroblock;
+struct pipe_picture_desc;
+struct pipe_fence_handle;
+
+/**
+ * Gallium video rendering context
+ */
+struct pipe_video_context
+{
+ struct pipe_screen *screen;
+ enum pipe_video_profile profile;
+ enum pipe_video_chroma_format chroma_format;
+ unsigned width;
+ unsigned height;
+
+ void *priv; /**< context private data (for DRI for example) */
+
+ /**
+ * Query an integer-valued capability/parameter/limit
+ * \param param one of PIPE_CAP_x
+ */
+ int (*get_param)(struct pipe_video_context *vpipe, int param);
+
+ /**
+ * Check if the given pipe_format is supported as a texture or
+ * drawing surface.
+ */
+ boolean (*is_format_supported)(struct pipe_video_context *vpipe,
+ enum pipe_format format,
+ unsigned usage,
+ unsigned geom);
+
+ void (*destroy)(struct pipe_video_context *vpipe);
+
+ /**
+ * Picture decoding and displaying
+ */
+ /*@{*/
+ void (*decode_bitstream)(struct pipe_video_context *vpipe,
+ unsigned num_bufs,
+ struct pipe_buffer **bitstream_buf);
+
+ void (*decode_macroblocks)(struct pipe_video_context *vpipe,
+ struct pipe_surface *past,
+ struct pipe_surface *future,
+ unsigned num_macroblocks,
+ struct pipe_macroblock *macroblocks,
+ struct pipe_fence_handle **fence);
+
+ void (*render_picture)(struct pipe_video_context *vpipe,
+ struct pipe_surface *src_surface,
+ enum pipe_mpeg12_picture_type picture_type,
+ /*unsigned num_past_surfaces,
+ struct pipe_surface *past_surfaces,
+ unsigned num_future_surfaces,
+ struct pipe_surface *future_surfaces,*/
+ struct pipe_video_rect *src_area,
+ struct pipe_surface *dst_surface,
+ struct pipe_video_rect *dst_area,
+ struct pipe_fence_handle **fence);
+
+ void (*surface_fill)(struct pipe_video_context *vpipe,
+ struct pipe_surface *dst,
+ unsigned dstx, unsigned dsty,
+ unsigned width, unsigned height,
+ unsigned value);
+
+ void (*surface_copy)(struct pipe_video_context *vpipe,
+ struct pipe_surface *dst,
+ unsigned dstx, unsigned dsty,
+ struct pipe_surface *src,
+ unsigned srcx, unsigned srcy,
+ unsigned width, unsigned height);
+
+ struct pipe_transfer *(*get_transfer)(struct pipe_video_context *vpipe,
+ struct pipe_resource *resource,
+ struct pipe_subresource subresource,
+ unsigned usage, /* a combination of PIPE_TRANSFER_x */
+ const struct pipe_box *box);
+
+ void (*transfer_destroy)(struct pipe_video_context *vpipe,
+ struct pipe_transfer *transfer);
+
+ void* (*transfer_map)(struct pipe_video_context *vpipe,
+ struct pipe_transfer *transfer);
+
+ void (*transfer_flush_region)(struct pipe_video_context *vpipe,
+ struct pipe_transfer *transfer,
+ const struct pipe_box *box);
+
+ void (*transfer_unmap)(struct pipe_video_context *vpipe,
+ struct pipe_transfer *transfer);
+
+ void (*transfer_inline_write)(struct pipe_video_context *vpipe,
+ struct pipe_resource *resource,
+ struct pipe_subresource subresource,
+ unsigned usage, /* a combination of PIPE_TRANSFER_x */
+ const struct pipe_box *box,
+ const void *data,
+ unsigned stride,
+ unsigned slice_stride);
+
+ /*@}*/
+
+ /**
+ * Parameter-like states (or properties)
+ */
+ /*@{*/
+ void (*set_picture_background)(struct pipe_video_context *vpipe,
+ struct pipe_surface *bg,
+ struct pipe_video_rect *bg_src_rect);
+
+ void (*set_picture_layers)(struct pipe_video_context *vpipe,
+ struct pipe_surface *layers[],
+ struct pipe_video_rect *src_rects[],
+ struct pipe_video_rect *dst_rects[],
+ unsigned num_layers);
+
+ void (*set_picture_desc)(struct pipe_video_context *vpipe,
+ const struct pipe_picture_desc *desc);
+
+ void (*set_decode_target)(struct pipe_video_context *vpipe,
+ struct pipe_surface *dt);
+
+ void (*set_csc_matrix)(struct pipe_video_context *vpipe, const float *mat);
+
+ /* TODO: Interface for scaling modes, post-processing, etc. */
+ /*@}*/
+};
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PIPE_VIDEO_CONTEXT_H */
diff --git a/src/gallium/include/pipe/p_video_state.h b/src/gallium/include/pipe/p_video_state.h
new file mode 100644
index 00000000000..1450f3488f9
--- /dev/null
+++ b/src/gallium/include/pipe/p_video_state.h
@@ -0,0 +1,133 @@
+/**************************************************************************
+ *
+ * Copyright 2009 Younes Manton.
+ * 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 TUNGSTEN GRAPHICS 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 PIPE_VIDEO_STATE_H
+#define PIPE_VIDEO_STATE_H
+
+#include <pipe/p_defines.h>
+#include <pipe/p_format.h>
+#include <pipe/p_state.h>
+#include <pipe/p_screen.h>
+#include <util/u_inlines.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct pipe_video_rect
+{
+ unsigned x, y, w, h;
+};
+
+enum pipe_mpeg12_picture_type
+{
+ PIPE_MPEG12_PICTURE_TYPE_FIELD_TOP,
+ PIPE_MPEG12_PICTURE_TYPE_FIELD_BOTTOM,
+ PIPE_MPEG12_PICTURE_TYPE_FRAME
+};
+
+enum pipe_mpeg12_macroblock_type
+{
+ PIPE_MPEG12_MACROBLOCK_TYPE_INTRA,
+ PIPE_MPEG12_MACROBLOCK_TYPE_FWD,
+ PIPE_MPEG12_MACROBLOCK_TYPE_BKWD,
+ PIPE_MPEG12_MACROBLOCK_TYPE_BI,
+
+ PIPE_MPEG12_MACROBLOCK_NUM_TYPES
+};
+
+enum pipe_mpeg12_motion_type
+{
+ PIPE_MPEG12_MOTION_TYPE_FIELD,
+ PIPE_MPEG12_MOTION_TYPE_FRAME,
+ PIPE_MPEG12_MOTION_TYPE_DUALPRIME,
+ PIPE_MPEG12_MOTION_TYPE_16x8
+};
+
+enum pipe_mpeg12_dct_type
+{
+ PIPE_MPEG12_DCT_TYPE_FIELD,
+ PIPE_MPEG12_DCT_TYPE_FRAME
+};
+
+
+struct pipe_macroblock
+{
+ enum pipe_video_codec codec;
+};
+
+struct pipe_mpeg12_macroblock
+{
+ struct pipe_macroblock base;
+
+ unsigned mbx;
+ unsigned mby;
+ enum pipe_mpeg12_macroblock_type mb_type;
+ enum pipe_mpeg12_motion_type mo_type;
+ enum pipe_mpeg12_dct_type dct_type;
+ signed pmv[2][2][2];
+ unsigned cbp;
+ short *blocks;
+};
+
+#if 0
+struct pipe_picture_desc
+{
+ enum pipe_video_format format;
+};
+
+struct pipe_mpeg12_picture_desc
+{
+ struct pipe_picture_desc base;
+
+ /* TODO: Use bitfields where possible? */
+ struct pipe_surface *forward_reference;
+ struct pipe_surface *backward_reference;
+ unsigned picture_coding_type;
+ unsigned fcode;
+ unsigned intra_dc_precision;
+ unsigned picture_structure;
+ unsigned top_field_first;
+ unsigned frame_pred_frame_dct;
+ unsigned concealment_motion_vectors;
+ unsigned q_scale_type;
+ unsigned intra_vlc_format;
+ unsigned alternate_scan;
+ unsigned full_pel_forward_vector;
+ unsigned full_pel_backward_vector;
+ struct pipe_buffer *intra_quantizer_matrix;
+ struct pipe_buffer *non_intra_quantizer_matrix;
+ struct pipe_buffer *chroma_intra_quantizer_matrix;
+ struct pipe_buffer *chroma_non_intra_quantizer_matrix;
+};
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PIPE_VIDEO_STATE_H */
diff --git a/src/gallium/state_trackers/vdpau/Makefile b/src/gallium/state_trackers/vdpau/Makefile
new file mode 100644
index 00000000000..ad37676b95e
--- /dev/null
+++ b/src/gallium/state_trackers/vdpau/Makefile
@@ -0,0 +1,27 @@
+TOP = ../../../..
+include $(TOP)/configs/current
+
+LIBNAME = vdpautracker
+
+VDPAU_MAJOR = 1
+VDPAU_MINOR = 0
+LIBRARY_DEFINES = -DVER_MAJOR=$(VDPAU_MAJOR) -DVER_MINOR=$(VDPAU_MINOR) $(STATE_TRACKER_DEFINES)
+
+LIBRARY_INCLUDES = \
+ $(shell pkg-config --cflags-only-I vdpau) \
+ -I$(TOP)/src/gallium/winsys/g3dvl
+
+C_SOURCES = htab.c \
+ ftab.c \
+ device.c \
+ query.c \
+ surface.c \
+ decode.c \
+ presentation.c \
+ bitmap.c \
+ mpeg2_bitstream_parser.c \
+ output.c
+
+
+include ../../Makefile.template
+
diff --git a/src/gallium/state_trackers/vdpau/bitmap.c b/src/gallium/state_trackers/vdpau/bitmap.c
new file mode 100644
index 00000000000..f1a9d9a6828
--- /dev/null
+++ b/src/gallium/state_trackers/vdpau/bitmap.c
@@ -0,0 +1,75 @@
+/**************************************************************************
+ *
+ * Copyright 2010 Thomas Balling Sørensen.
+ * 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 TUNGSTEN GRAPHICS 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.
+ *
+ **************************************************************************/
+
+#include <vdpau/vdpau.h>
+#include "vdpau_private.h"
+#include <util/u_debug.h>
+
+VdpStatus
+vlVdpBitmapSurfaceCreate( VdpDevice device,
+ VdpRGBAFormat rgba_format,
+ uint32_t width, uint32_t height,
+ VdpBool frequently_accessed,
+ VdpBitmapSurface *surface)
+{
+ debug_printf("[VDPAU] Creating a bitmap surface\n");
+ if (!surface)
+ return VDP_STATUS_INVALID_POINTER;
+
+ return VDP_STATUS_NO_IMPLEMENTATION;
+}
+
+VdpStatus
+vlVdpBitmapSurfaceDestroy ( VdpBitmapSurface surface )
+{
+
+ return VDP_STATUS_NO_IMPLEMENTATION;
+}
+
+VdpStatus
+vlVdpBitmapSurfaceGetParameters ( VdpBitmapSurface surface,
+ VdpRGBAFormat *rgba_format,
+ uint32_t *width, uint32_t *height,
+ VdpBool *frequently_accessed)
+{
+ if (!(rgba_format && width && height && frequently_accessed))
+ return VDP_STATUS_INVALID_POINTER;
+
+ return VDP_STATUS_NO_IMPLEMENTATION;
+}
+
+VdpStatus
+vlVdpBitmapSurfacePutBitsNative ( VdpBitmapSurface surface,
+ void const *const *source_data,
+ uint32_t const *source_pitches,
+ VdpRect const *destination_rect )
+{
+ if (!(source_data && source_pitches && destination_rect))
+ return VDP_STATUS_INVALID_POINTER;
+
+ return VDP_STATUS_NO_IMPLEMENTATION;
+} \ No newline at end of file
diff --git a/src/gallium/state_trackers/vdpau/color.c b/src/gallium/state_trackers/vdpau/color.c
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/src/gallium/state_trackers/vdpau/color.c
diff --git a/src/gallium/state_trackers/vdpau/decode.c b/src/gallium/state_trackers/vdpau/decode.c
new file mode 100644
index 00000000000..3e7cb4a3cab
--- /dev/null
+++ b/src/gallium/state_trackers/vdpau/decode.c
@@ -0,0 +1,277 @@
+/**************************************************************************
+ *
+ * Copyright 2010 Thomas Balling Sørensen.
+ * 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 TUNGSTEN GRAPHICS 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.
+ *
+ **************************************************************************/
+
+#include "vdpau_private.h"
+#include "mpeg2_bitstream_parser.h"
+#include <util/u_memory.h>
+#include <util/u_math.h>
+#include <pipe/p_video_context.h>
+#include <util/u_debug.h>
+
+VdpStatus
+vlVdpDecoderCreate ( VdpDevice device,
+ VdpDecoderProfile profile,
+ uint32_t width, uint32_t height,
+ uint32_t max_references,
+ VdpDecoder *decoder
+)
+{
+ struct vl_screen *vscreen;
+ enum pipe_video_profile p_profile;
+ VdpStatus ret;
+ vlVdpDecoder *vldecoder;
+
+ debug_printf("[VDPAU] Creating decoder\n");
+
+ if (!decoder)
+ return VDP_STATUS_INVALID_POINTER;
+
+ if (!(width && height))
+ return VDP_STATUS_INVALID_VALUE;
+
+ vlVdpDevice *dev = vlGetDataHTAB(device);
+ if (!dev) {
+ ret = VDP_STATUS_INVALID_HANDLE;
+ goto inv_device;
+ }
+
+ vldecoder = CALLOC(1,sizeof(vlVdpDecoder));
+ if (!vldecoder) {
+ ret = VDP_STATUS_RESOURCES;
+ goto no_decoder;
+ }
+
+ p_profile = ProfileToPipe(profile);
+ if (p_profile == PIPE_VIDEO_PROFILE_UNKNOWN) {
+ ret = VDP_STATUS_INVALID_DECODER_PROFILE;
+ goto inv_profile;
+ }
+
+ // TODO: Define max_references. Used mainly for H264
+
+ vldecoder->profile = p_profile;
+ vldecoder->device = dev;
+
+ *decoder = vlAddDataHTAB(vldecoder);
+ if (*decoder == 0) {
+ ret = VDP_STATUS_ERROR;
+ goto no_handle;
+ }
+ debug_printf("[VDPAU] Decoder created succesfully\n");
+
+ return VDP_STATUS_OK;
+
+ no_handle:
+ FREE(vldecoder);
+ inv_profile:
+ no_screen:
+ no_decoder:
+ inv_device:
+ return ret;
+}
+
+VdpStatus
+vlVdpDecoderDestroy (VdpDecoder decoder
+)
+{
+ vlVdpDecoder *vldecoder;
+
+ vldecoder = (vlVdpDecoder *)vlGetDataHTAB(decoder);
+ if (!vldecoder) {
+ return VDP_STATUS_INVALID_HANDLE;
+ }
+
+ if (vldecoder->vctx->vscreen)
+ vl_screen_destroy(vldecoder->vctx->vscreen);
+
+ if (vldecoder->vctx)
+ vl_video_destroy(vldecoder->vctx);
+
+ FREE(vldecoder);
+
+ return VDP_STATUS_OK;
+}
+
+VdpStatus
+vlVdpCreateSurfaceTarget (vlVdpDecoder *vldecoder,
+ vlVdpSurface *vlsurf
+)
+{
+ struct pipe_resource tmplt;
+ struct pipe_resource *surf_tex;
+ struct pipe_video_context *vpipe;
+
+ if(!(vldecoder && vlsurf))
+ return VDP_STATUS_INVALID_POINTER;
+
+ vpipe = vldecoder->vctx;
+
+ memset(&tmplt, 0, sizeof(struct pipe_resource));
+ tmplt.target = PIPE_TEXTURE_2D;
+ tmplt.format = vlsurf->format;
+ tmplt.last_level = 0;
+ if (vpipe->is_format_supported(vpipe, tmplt.format,
+ PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET,
+ PIPE_TEXTURE_GEOM_NON_POWER_OF_TWO)) {
+ tmplt.width0 = vlsurf->width;
+ tmplt.height0 = vlsurf->height;
+ }
+ else {
+ assert(vpipe->is_format_supported(vpipe, tmplt.format,
+ PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET,
+ PIPE_TEXTURE_GEOM_NON_SQUARE));
+ tmplt.width0 = util_next_power_of_two(vlsurf->width);
+ tmplt.height0 = util_next_power_of_two(vlsurf->height);
+ }
+ tmplt.depth0 = 1;
+ tmplt.usage = PIPE_USAGE_DEFAULT;
+ tmplt.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
+ tmplt.flags = 0;
+
+ surf_tex = vpipe->screen->resource_create(vpipe->screen, &tmplt);
+
+ vlsurf->psurface = vpipe->screen->get_tex_surface(vpipe->screen, surf_tex, 0, 0, 0,
+ PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET);
+
+ pipe_resource_reference(&surf_tex, NULL);
+
+ if (!vlsurf->psurface)
+ return VDP_STATUS_RESOURCES;
+
+
+ return VDP_STATUS_OK;
+}
+
+VdpStatus
+vlVdpDecoderRenderMpeg2 (vlVdpDecoder *vldecoder,
+ vlVdpSurface *vlsurf,
+ VdpPictureInfoMPEG1Or2 *picture_info,
+ uint32_t bitstream_buffer_count,
+ VdpBitstreamBuffer const *bitstream_buffers
+ )
+{
+ struct pipe_video_context *vpipe;
+ vlVdpSurface *t_vdp_surf;
+ vlVdpSurface *p_vdp_surf;
+ vlVdpSurface *f_vdp_surf;
+ struct pipe_surface *t_surf;
+ struct pipe_surface *p_surf;
+ struct pipe_surface *f_surf;
+ uint32_t num_macroblocks;
+ struct pipe_mpeg12_macroblock *pipe_macroblocks;
+ VdpStatus ret;
+
+
+ vpipe = vldecoder->vctx->vpipe;
+ t_vdp_surf = vlsurf;
+
+ /* if surfaces equals VDP_STATUS_INVALID_HANDLE, they are not used */
+ if (picture_info->backward_reference == VDP_INVALID_HANDLE)
+ p_vdp_surf = NULL;
+ else {
+ p_vdp_surf = (vlVdpSurface *)vlGetDataHTAB(picture_info->backward_reference);
+ if (!p_vdp_surf)
+ return VDP_STATUS_INVALID_HANDLE;
+ }
+
+ if (picture_info->forward_reference == VDP_INVALID_HANDLE)
+ f_vdp_surf = NULL;
+ else {
+ f_vdp_surf = (vlVdpSurface *)vlGetDataHTAB(picture_info->forward_reference);
+ if (!f_vdp_surf)
+ return VDP_STATUS_INVALID_HANDLE;
+ }
+
+
+ if (f_vdp_surf == VDP_INVALID_HANDLE) f_vdp_surf = NULL;
+
+ ret = vlVdpCreateSurfaceTarget(vldecoder,t_vdp_surf);
+
+ vlVdpBitstreamToMacroblock(vpipe->screen, bitstream_buffers,
+ &num_macroblocks, &pipe_macroblocks);
+
+ vpipe->set_decode_target(vpipe,t_surf);
+ vpipe->decode_macroblocks(vpipe, p_surf, f_surf, num_macroblocks, pipe_macroblocks, NULL);
+ return ret;
+}
+
+VdpStatus
+vlVdpDecoderRender (VdpDecoder decoder,
+ VdpVideoSurface target,
+ VdpPictureInfo const *picture_info,
+ uint32_t bitstream_buffer_count,
+ VdpBitstreamBuffer const *bitstream_buffers
+)
+{
+ vlVdpDecoder *vldecoder;
+ vlVdpSurface *vlsurf;
+ struct vl_screen *vscreen;
+ VdpStatus ret;
+ debug_printf("[VDPAU] Decoding\n");
+
+ if (!(picture_info && bitstream_buffers))
+ return VDP_STATUS_INVALID_POINTER;
+
+
+ vldecoder = (vlVdpDecoder *)vlGetDataHTAB(decoder);
+ if (!vldecoder)
+ return VDP_STATUS_INVALID_HANDLE;
+
+ vlsurf = (vlVdpSurface *)vlGetDataHTAB(target);
+ if (!vlsurf)
+ return VDP_STATUS_INVALID_HANDLE;
+
+ if (vlsurf->device != vldecoder->device)
+ return VDP_STATUS_HANDLE_DEVICE_MISMATCH;
+
+ if (vlsurf->chroma_format != vldecoder->chroma_format)
+ return VDP_STATUS_INVALID_CHROMA_TYPE;
+
+ vscreen = vl_screen_create(vldecoder->device->display, vldecoder->device->screen);
+ if (!vscreen)
+ return VDP_STATUS_RESOURCES;
+
+ vldecoder->vctx = vl_video_create(vscreen, vldecoder->profile, vlsurf->format, vlsurf->width, vlsurf->height);
+ if (!vldecoder->vctx)
+ return VDP_STATUS_RESOURCES;
+
+ vldecoder->vctx->vscreen = vscreen;
+
+ // TODO: Right now only mpeg2 is supported.
+ switch (vldecoder->vctx->vpipe->profile) {
+ case PIPE_VIDEO_PROFILE_MPEG2_SIMPLE:
+ case PIPE_VIDEO_PROFILE_MPEG2_MAIN:
+ ret = vlVdpDecoderRenderMpeg2(vldecoder,vlsurf,(VdpPictureInfoMPEG1Or2 *)picture_info,
+ bitstream_buffer_count,bitstream_buffers);
+ break;
+ default:
+ return VDP_STATUS_INVALID_DECODER_PROFILE;
+ }
+ assert(0);
+
+ return ret;
+}
diff --git a/src/gallium/state_trackers/vdpau/device.c b/src/gallium/state_trackers/vdpau/device.c
new file mode 100644
index 00000000000..d370d1c6610
--- /dev/null
+++ b/src/gallium/state_trackers/vdpau/device.c
@@ -0,0 +1,155 @@
+/**************************************************************************
+ *
+ * Copyright 2010 Younes Manton.
+ * 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 TUNGSTEN GRAPHICS 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.
+ *
+ **************************************************************************/
+
+#include <vdpau/vdpau_x11.h>
+#include <pipe/p_compiler.h>
+#include <vl_winsys.h>
+#include <util/u_memory.h>
+#include <util/u_debug.h>
+#include "vdpau_private.h"
+
+VdpDeviceCreateX11 vdp_imp_device_create_x11;
+
+PUBLIC VdpStatus
+vdp_imp_device_create_x11(Display *display, int screen, VdpDevice *device, VdpGetProcAddress **get_proc_address)
+{
+ VdpStatus ret;
+ vlVdpDevice *dev = NULL;
+ struct vl_screen *vlscreen = NULL;
+
+ if (!(display && device && get_proc_address))
+ return VDP_STATUS_INVALID_POINTER;
+
+ if (!vlCreateHTAB()) {
+ ret = VDP_STATUS_RESOURCES;
+ goto no_htab;
+ }
+
+ dev = CALLOC(1, sizeof(vlVdpDevice));
+ if (!dev) {
+ ret = VDP_STATUS_RESOURCES;
+ goto no_dev;
+ }
+ dev->display = display;
+ dev->screen = screen;
+
+ *device = vlAddDataHTAB(dev);
+ if (*device == 0) {
+ ret = VDP_STATUS_ERROR;
+ goto no_handle;
+ }
+
+ *get_proc_address = &vlVdpGetProcAddress;
+
+ debug_printf("[VDPAU] Device created succesfully\n");
+
+ return VDP_STATUS_OK;
+
+no_handle:
+ FREE(dev);
+no_dev:
+ vlDestroyHTAB();
+no_htab:
+ return ret;
+}
+
+VdpStatus
+vlVdpDeviceDestroy(VdpDevice device)
+{
+ vlVdpDevice *dev = vlGetDataHTAB(device);
+ if (!dev)
+ return VDP_STATUS_INVALID_HANDLE;
+ FREE(dev);
+ vlDestroyHTAB();
+
+ debug_printf("[VDPAU] Device destroyed succesfully\n");
+
+ return VDP_STATUS_OK;
+}
+
+VdpStatus
+vlVdpGetProcAddress(VdpDevice device, VdpFuncId function_id, void **function_pointer)
+{
+ vlVdpDevice *dev = vlGetDataHTAB(device);
+ if (!dev)
+ return VDP_STATUS_INVALID_HANDLE;
+
+ if (!function_pointer)
+ return VDP_STATUS_INVALID_POINTER;
+
+ if (!vlGetFuncFTAB(function_id, function_pointer))
+ return VDP_STATUS_INVALID_FUNC_ID;
+
+ return VDP_STATUS_OK;
+}
+
+#define _ERROR_TYPE(TYPE,STRING) \
+ case TYPE: \
+ return STRING; \
+ break
+
+char const *
+vlVdpGetErrorString (
+VdpStatus status)
+{
+ switch (status)
+ {
+ _ERROR_TYPE(VDP_STATUS_OK,"The operation completed successfully; no error.");
+ _ERROR_TYPE(VDP_STATUS_NO_IMPLEMENTATION,"No backend implementation could be loaded.");
+ _ERROR_TYPE(VDP_STATUS_DISPLAY_PREEMPTED,"The display was preempted, or a fatal error occurred. The application must re-initialize VDPAU.");
+ _ERROR_TYPE(VDP_STATUS_INVALID_HANDLE,"An invalid handle value was provided. Either the handle does not exist at all, or refers to an object of an incorrect type.");
+ _ERROR_TYPE(VDP_STATUS_INVALID_POINTER ,"An invalid pointer was provided. Typically, this means that a NULL pointer was provided for an 'output' parameter.");
+ _ERROR_TYPE(VDP_STATUS_INVALID_CHROMA_TYPE ,"An invalid/unsupported VdpChromaType value was supplied.");
+ _ERROR_TYPE(VDP_STATUS_INVALID_Y_CB_CR_FORMAT,"An invalid/unsupported VdpYCbCrFormat value was supplied.");
+ _ERROR_TYPE(VDP_STATUS_INVALID_RGBA_FORMAT,"An invalid/unsupported VdpRGBAFormat value was supplied.");
+ _ERROR_TYPE(VDP_STATUS_INVALID_INDEXED_FORMAT,"An invalid/unsupported VdpIndexedFormat value was supplied.");
+ _ERROR_TYPE(VDP_STATUS_INVALID_COLOR_STANDARD,"An invalid/unsupported VdpColorStandard value was supplied.");
+ _ERROR_TYPE(VDP_STATUS_INVALID_COLOR_TABLE_FORMAT,"An invalid/unsupported VdpColorTableFormat value was supplied.");
+ _ERROR_TYPE(VDP_STATUS_INVALID_BLEND_FACTOR,"An invalid/unsupported VdpOutputSurfaceRenderBlendFactor value was supplied.");
+ _ERROR_TYPE(VDP_STATUS_INVALID_BLEND_EQUATION,"An invalid/unsupported VdpOutputSurfaceRenderBlendEquation value was supplied.");
+ _ERROR_TYPE(VDP_STATUS_INVALID_FLAG,"An invalid/unsupported flag value/combination was supplied.");
+ _ERROR_TYPE(VDP_STATUS_INVALID_DECODER_PROFILE,"An invalid/unsupported VdpDecoderProfile value was supplied.");
+ _ERROR_TYPE(VDP_STATUS_INVALID_VIDEO_MIXER_FEATURE,"An invalid/unsupported VdpVideoMixerFeature value was supplied.");
+ _ERROR_TYPE(VDP_STATUS_INVALID_VIDEO_MIXER_PARAMETER ,"An invalid/unsupported VdpVideoMixerParameter value was supplied.");
+ _ERROR_TYPE(VDP_STATUS_INVALID_VIDEO_MIXER_ATTRIBUTE,"An invalid/unsupported VdpVideoMixerAttribute value was supplied.");
+ _ERROR_TYPE(VDP_STATUS_INVALID_VIDEO_MIXER_PICTURE_STRUCTURE,"An invalid/unsupported VdpVideoMixerPictureStructure value was supplied.");
+ _ERROR_TYPE(VDP_STATUS_INVALID_FUNC_ID,"An invalid/unsupported VdpFuncId value was supplied.");
+ _ERROR_TYPE(VDP_STATUS_INVALID_SIZE,"The size of a supplied object does not match the object it is being used with.\
+ For example, a VdpVideoMixer is configured to process VdpVideoSurface objects of a specific size.\
+ If presented with a VdpVideoSurface of a different size, this error will be raised.");
+ _ERROR_TYPE(VDP_STATUS_INVALID_VALUE,"An invalid/unsupported value was supplied.\
+ This is a catch-all error code for values of type other than those with a specific error code.");
+ _ERROR_TYPE(VDP_STATUS_INVALID_STRUCT_VERSION,"An invalid/unsupported structure version was specified in a versioned structure. \
+ This implies that the implementation is older than the header file the application was built against.");
+ _ERROR_TYPE(VDP_STATUS_RESOURCES,"The system does not have enough resources to complete the requested operation at this time.");
+ _ERROR_TYPE(VDP_STATUS_HANDLE_DEVICE_MISMATCH,"The set of handles supplied are not all related to the same VdpDevice.When performing operations \
+ that operate on multiple surfaces, such as VdpOutputSurfaceRenderOutputSurface or VdpVideoMixerRender, \
+ all supplied surfaces must have been created within the context of the same VdpDevice object. \
+ This error is raised if they were not.");
+ _ERROR_TYPE(VDP_STATUS_ERROR,"A catch-all error, used when no other error code applies.");
+ }
+}
diff --git a/src/gallium/state_trackers/vdpau/ftab.c b/src/gallium/state_trackers/vdpau/ftab.c
new file mode 100644
index 00000000000..1842c4da0ea
--- /dev/null
+++ b/src/gallium/state_trackers/vdpau/ftab.c
@@ -0,0 +1,122 @@
+/**************************************************************************
+ *
+ * Copyright 2010 Younes Manton.
+ * 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 TUNGSTEN GRAPHICS 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.
+ *
+ **************************************************************************/
+
+#include <assert.h>
+#include "vdpau_private.h"
+
+static void* ftab[67] =
+{
+ &vlVdpGetErrorString, /* VDP_FUNC_ID_GET_ERROR_STRING */
+ &vlVdpGetProcAddress, /* VDP_FUNC_ID_GET_PROC_ADDRESS */
+ &vlVdpGetApiVersion, /* VDP_FUNC_ID_GET_API_VERSION */
+ 0,
+ &vlVdpGetInformationString, /* VDP_FUNC_ID_GET_INFORMATION_STRING */
+ &vlVdpDeviceDestroy, /* VDP_FUNC_ID_DEVICE_DESTROY */
+ 0, /* VDP_FUNC_ID_GENERATE_CSC_MATRIX */
+ &vlVdpVideoSurfaceQueryCapabilities, /* VDP_FUNC_ID_VIDEO_SURFACE_QUERY_CAPABILITIES */
+ &vlVdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities, /* VDP_FUNC_ID_VIDEO_SURFACE_QUERY_GET_PUT_BITS_Y_CB_CR_CAPABILITIES */
+ &vlVdpVideoSurfaceCreate, /* VDP_FUNC_ID_VIDEO_SURFACE_CREATE */
+ &vlVdpVideoSurfaceDestroy, /* VDP_FUNC_ID_VIDEO_SURFACE_DESTROY */
+ &vlVdpVideoSurfaceGetParameters, /* VDP_FUNC_ID_VIDEO_SURFACE_GET_PARAMETERS */
+ &vlVdpVideoSurfaceGetBitsYCbCr, /* VDP_FUNC_ID_VIDEO_SURFACE_GET_BITS_Y_CB_CR */
+ &vlVdpVideoSurfacePutBitsYCbCr, /* VDP_FUNC_ID_VIDEO_SURFACE_PUT_BITS_Y_CB_CR */
+ &vlVdpOutputSurfaceQueryCapabilities, /* VDP_FUNC_ID_OUTPUT_SURFACE_QUERY_CAPABILITIES */
+ &vlVdpOutputSurfaceQueryGetPutBitsNativeCapabilities, /* VDP_FUNC_ID_OUTPUT_SURFACE_QUERY_GET_PUT_BITS_NATIVE_CAPABILITIES */
+ 0, /* VDP_FUNC_ID_OUTPUT_SURFACE_QUERY_PUT_BITS_INDEXED_CAPABILITIES */
+ &vlVdpOutputSurfaceQueryPutBitsYCbCrCapabilities, /* VDP_FUNC_ID_OUTPUT_SURFACE_QUERY_PUT_BITS_Y_CB_CR_CAPABILITIES */
+ &vlVdpOutputSurfaceCreate, /* VDP_FUNC_ID_OUTPUT_SURFACE_CREATE */
+ 0, /* VDP_FUNC_ID_OUTPUT_SURFACE_DESTROY */
+ 0, /* VDP_FUNC_ID_OUTPUT_SURFACE_GET_PARAMETERS */
+ 0, /* VDP_FUNC_ID_OUTPUT_SURFACE_GET_BITS_NATIVE */
+ 0, /* VDP_FUNC_ID_OUTPUT_SURFACE_PUT_BITS_NATIVE */
+ 0, /* VDP_FUNC_ID_OUTPUT_SURFACE_PUT_BITS_INDEXED */
+ 0, /* VDP_FUNC_ID_OUTPUT_SURFACE_PUT_BITS_Y_CB_CR */
+ &vlVdpBitmapSurfaceQueryCapabilities, /* VDP_FUNC_ID_BITMAP_SURFACE_QUERY_CAPABILITIES */
+ &vlVdpBitmapSurfaceCreate, /* VDP_FUNC_ID_BITMAP_SURFACE_CREATE */
+ &vlVdpBitmapSurfaceDestroy, /* VDP_FUNC_ID_BITMAP_SURFACE_DESTROY */
+ &vlVdpBitmapSurfaceGetParameters, /* VDP_FUNC_ID_BITMAP_SURFACE_GET_PARAMETERS */
+ &vlVdpBitmapSurfacePutBitsNative, /* VDP_FUNC_ID_BITMAP_SURFACE_PUT_BITS_NATIVE */
+ 0,
+ 0,
+ 0,
+ 0, /* VDP_FUNC_ID_OUTPUT_SURFACE_RENDER_OUTPUT_SURFACE */
+ 0, /* VDP_FUNC_ID_OUTPUT_SURFACE_RENDER_BITMAP_SURFACE */
+ 0, /* VDP_FUNC_ID_OUTPUT_SURFACE_RENDER_VIDEO_SURFACE_LUMA */
+ &vlVdpDecoderQueryCapabilities, /* VDP_FUNC_ID_DECODER_QUERY_CAPABILITIES */
+ &vlVdpDecoderCreate, /* VDP_FUNC_ID_DECODER_CREATE */
+ &vlVdpDecoderDestroy, /* VDP_FUNC_ID_DECODER_DESTROY */
+ 0, /* VDP_FUNC_ID_DECODER_GET_PARAMETERS */
+ &vlVdpDecoderRender, /* VDP_FUNC_ID_DECODER_RENDER */
+ &vlVdpVideoMixerQueryFeatureSupport, /* VDP_FUNC_ID_VIDEO_MIXER_QUERY_FEATURE_SUPPORT */
+ &vlVdpVideoMixerQueryParameterSupport, /* VDP_FUNC_ID_VIDEO_MIXER_QUERY_PARAMETER_SUPPORT */
+ &vlVdpVideoMixerQueryAttributeSupport, /* VDP_FUNC_ID_VIDEO_MIXER_QUERY_ATTRIBUTE_SUPPORT */
+ &vlVdpVideoMixerQueryParameterValueRange, /* VDP_FUNC_ID_VIDEO_MIXER_QUERY_PARAMETER_VALUE_RANGE */
+ &vlVdpVideoMixerQueryAttributeValueRange, /* VDP_FUNC_ID_VIDEO_MIXER_QUERY_ATTRIBUTE_VALUE_RANGE */
+ 0, /* VDP_FUNC_ID_VIDEO_MIXER_CREATE */
+ 0, /* VDP_FUNC_ID_VIDEO_MIXER_SET_FEATURE_ENABLES */
+ 0, /* VDP_FUNC_ID_VIDEO_MIXER_SET_ATTRIBUTE_VALUES */
+ 0, /* VDP_FUNC_ID_VIDEO_MIXER_GET_FEATURE_SUPPORT */
+ 0, /* VDP_FUNC_ID_VIDEO_MIXER_GET_FEATURE_ENABLES */
+ 0, /* VDP_FUNC_ID_VIDEO_MIXER_GET_PARAMETER_VALUES */
+ 0, /* VDP_FUNC_ID_VIDEO_MIXER_GET_ATTRIBUTE_VALUES */
+ 0, /* VDP_FUNC_ID_VIDEO_MIXER_DESTROY */
+ 0, /* VDP_FUNC_ID_VIDEO_MIXER_RENDER */
+ &vlVdpPresentationQueueTargetDestroy, /* VDP_FUNC_ID_PRESENTATION_QUEUE_TARGET_DESTROY */
+ &vlVdpPresentationQueueCreate, /* VDP_FUNC_ID_PRESENTATION_QUEUE_CREATE */
+ &vlVdpPresentationQueueDestroy, /* VDP_FUNC_ID_PRESENTATION_QUEUE_DESTROY */
+ &vlVdpPresentationQueueSetBackgroundColor, /* VDP_FUNC_ID_PRESENTATION_QUEUE_SET_BACKGROUND_COLOR */
+ &vlVdpPresentationQueueGetBackgroundColor, /* VDP_FUNC_ID_PRESENTATION_QUEUE_GET_BACKGROUND_COLOR */
+ 0,
+ 0,
+ &vlVdpPresentationQueueGetTime, /* VDP_FUNC_ID_PRESENTATION_QUEUE_GET_TIME */
+ &vlVdpPresentationQueueDisplay, /* VDP_FUNC_ID_PRESENTATION_QUEUE_DISPLAY */
+ &vlVdpPresentationQueueBlockUntilSurfaceIdle, /* VDP_FUNC_ID_PRESENTATION_QUEUE_BLOCK_UNTIL_SURFACE_IDLE */
+ &vlVdpPresentationQueueQuerySurfaceStatus, /* VDP_FUNC_ID_PRESENTATION_QUEUE_QUERY_SURFACE_STATUS */
+ 0 /* VDP_FUNC_ID_PREEMPTION_CALLBACK_REGISTER */
+};
+
+static void* ftab_winsys[1] =
+{
+ 0 /* VDP_FUNC_ID_PRESENTATION_QUEUE_TARGET_CREATE_X11 */
+};
+
+boolean vlGetFuncFTAB(VdpFuncId function_id, void **func)
+{
+ assert(func);
+ if (function_id < VDP_FUNC_ID_BASE_WINSYS) {
+ if (function_id > 66)
+ return FALSE;
+ *func = ftab[function_id];
+ }
+ else {
+ function_id -= VDP_FUNC_ID_BASE_WINSYS;
+ if (function_id > 0)
+ return FALSE;
+ *func = ftab_winsys[function_id];
+ }
+ return TRUE;
+}
diff --git a/src/gallium/state_trackers/vdpau/header.c b/src/gallium/state_trackers/vdpau/header.c
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/src/gallium/state_trackers/vdpau/header.c
diff --git a/src/gallium/state_trackers/vdpau/htab.c b/src/gallium/state_trackers/vdpau/htab.c
new file mode 100644
index 00000000000..0c958055374
--- /dev/null
+++ b/src/gallium/state_trackers/vdpau/htab.c
@@ -0,0 +1,94 @@
+/**************************************************************************
+ *
+ * Copyright 2010 Younes Manton.
+ * 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 TUNGSTEN GRAPHICS 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.
+ *
+ **************************************************************************/
+
+#include <util/u_handle_table.h>
+#include <os/os_thread.h>
+#include "vdpau_private.h"
+
+#ifdef VL_HANDLES
+static struct handle_table *htab = NULL;
+pipe_static_mutex(htab_lock);
+#endif
+
+boolean vlCreateHTAB(void)
+{
+#ifdef VL_HANDLES
+ boolean ret;
+ /* Make sure handle table handles match VDPAU handles. */
+ assert(sizeof(unsigned) <= sizeof(vlHandle));
+ pipe_mutex_lock(htab_lock);
+ if (!htab)
+ htab = handle_table_create();
+ ret = htab != NULL;
+ pipe_mutex_unlock(htab_lock);
+ return ret;
+#else
+ return TRUE;
+#endif
+}
+
+void vlDestroyHTAB(void)
+{
+#ifdef VL_HANDLES
+ pipe_mutex_lock(htab_lock);
+ if (htab) {
+ handle_table_destroy(htab);
+ htab = NULL;
+ }
+ pipe_mutex_unlock(htab_lock);
+#endif
+}
+
+vlHandle vlAddDataHTAB(void *data)
+{
+ assert(data);
+#ifdef VL_HANDLES
+ vlHandle handle = 0;
+ pipe_mutex_lock(htab_lock);
+ if (htab)
+ handle = handle_table_add(htab, data);
+ pipe_mutex_unlock(htab_lock);
+ return handle;
+#else
+ return (vlHandle)data;
+#endif
+}
+
+void* vlGetDataHTAB(vlHandle handle)
+{
+ assert(handle);
+#ifdef VL_HANDLES
+ void *data = NULL;
+ pipe_mutex_lock(htab_lock);
+ if (htab)
+ data = handle_table_get(htab, handle);
+ pipe_mutex_unlock(htab_lock);
+ return data;
+#else
+ return (void*)handle;
+#endif
+}
diff --git a/src/gallium/state_trackers/vdpau/mixer.c b/src/gallium/state_trackers/vdpau/mixer.c
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/src/gallium/state_trackers/vdpau/mixer.c
diff --git a/src/gallium/state_trackers/vdpau/mpeg2_bitstream_parser.c b/src/gallium/state_trackers/vdpau/mpeg2_bitstream_parser.c
new file mode 100644
index 00000000000..39019660edd
--- /dev/null
+++ b/src/gallium/state_trackers/vdpau/mpeg2_bitstream_parser.c
@@ -0,0 +1,44 @@
+/**************************************************************************
+ *
+ * Copyright 2010 Thomas Balling Sørensen.
+ * 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 TUNGSTEN GRAPHICS 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.
+ *
+ **************************************************************************/
+
+#include "mpeg2_bitstream_parser.h"
+
+void
+vlVdpBitstreamToMacroblock (
+ struct pipe_screen *screen,
+ VdpBitstreamBuffer const *bitstream_buffers,
+ unsigned int *num_macroblocks,
+ struct pipe_mpeg12_macroblock **pipe_macroblocks)
+{
+ debug_printf("[VDPAU] BitstreamToMacroblock not implemented yet");
+ assert(0);
+
+
+
+ return;
+}
+
diff --git a/src/gallium/state_trackers/vdpau/mpeg2_bitstream_parser.h b/src/gallium/state_trackers/vdpau/mpeg2_bitstream_parser.h
new file mode 100644
index 00000000000..534503df53f
--- /dev/null
+++ b/src/gallium/state_trackers/vdpau/mpeg2_bitstream_parser.h
@@ -0,0 +1,41 @@
+/**************************************************************************
+ *
+ * Copyright 2010 Thomas Balling Sørensen.
+ * 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 TUNGSTEN GRAPHICS 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 MPEG2_BITSTREAM_PARSER_H
+#define MPEG2_BITSTREAM_PARSER_H
+
+#include <vdpau/vdpau.h>
+#include <pipe/p_video_state.h>
+#include "vdpau_private.h"
+
+void
+vlVdpBitstreamToMacroblock(struct pipe_screen *screen,
+ VdpBitstreamBuffer const *bitstream_buffers,
+ unsigned int *num_macroblocks,
+ struct pipe_mpeg12_macroblock **pipe_macroblocks);
+
+#endif // MPEG2_BITSTREAM_PARSER_H
diff --git a/src/gallium/state_trackers/vdpau/output.c b/src/gallium/state_trackers/vdpau/output.c
new file mode 100644
index 00000000000..c5f06896c58
--- /dev/null
+++ b/src/gallium/state_trackers/vdpau/output.c
@@ -0,0 +1,43 @@
+/**************************************************************************
+ *
+ * Copyright 2010 Thomas Balling Sørensen.
+ * 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 TUNGSTEN GRAPHICS 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.
+ *
+ **************************************************************************/
+
+#include "vdpau_private.h"
+#include <vdpau/vdpau.h>
+#include <util/u_debug.h>
+
+VdpStatus
+vlVdpOutputSurfaceCreate ( VdpDevice device,
+ VdpRGBAFormat rgba_format,
+ uint32_t width, uint32_t height,
+ VdpOutputSurface *surface)
+{
+ debug_printf("[VDPAU] Creating output surface\n");
+ if (!(width && height))
+ return VDP_STATUS_INVALID_SIZE;
+
+ return VDP_STATUS_NO_IMPLEMENTATION;
+} \ No newline at end of file
diff --git a/src/gallium/state_trackers/vdpau/preemption.c b/src/gallium/state_trackers/vdpau/preemption.c
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/src/gallium/state_trackers/vdpau/preemption.c
diff --git a/src/gallium/state_trackers/vdpau/presentation.c b/src/gallium/state_trackers/vdpau/presentation.c
new file mode 100644
index 00000000000..8200cf04326
--- /dev/null
+++ b/src/gallium/state_trackers/vdpau/presentation.c
@@ -0,0 +1,121 @@
+/**************************************************************************
+ *
+ * Copyright 2010 Thomas Balling Sørensen.
+ * 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 TUNGSTEN GRAPHICS 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.
+ *
+ **************************************************************************/
+
+#include "vdpau_private.h"
+#include <vdpau/vdpau.h>
+#include <util/u_debug.h>
+
+VdpStatus
+vlVdpPresentationQueueTargetDestroy (VdpPresentationQueueTarget presentation_queue_target)
+{
+
+ return VDP_STATUS_NO_IMPLEMENTATION;
+}
+
+VdpStatus
+vlVdpPresentationQueueCreate ( VdpDevice device,
+ VdpPresentationQueueTarget presentation_queue_target,
+ VdpPresentationQueue *presentation_queue)
+{
+ debug_printf("[VDPAU] Creating presentation queue\n");
+
+ if (!presentation_queue)
+ return VDP_STATUS_INVALID_POINTER;
+
+ return VDP_STATUS_NO_IMPLEMENTATION;
+}
+
+VdpStatus
+vlVdpPresentationQueueDestroy (VdpPresentationQueue presentation_queue)
+{
+
+ return VDP_STATUS_NO_IMPLEMENTATION;
+}
+
+VdpStatus
+vlVdpPresentationQueueSetBackgroundColor ( VdpPresentationQueue presentation_queue,
+ VdpColor *const background_color)
+{
+ if (!background_color)
+ return VDP_STATUS_INVALID_POINTER;
+
+ return VDP_STATUS_NO_IMPLEMENTATION;
+}
+
+VdpStatus
+vlVdpPresentationQueueGetBackgroundColor ( VdpPresentationQueue presentation_queue,
+ VdpColor *const background_color)
+{
+ if (!background_color)
+ return VDP_STATUS_INVALID_POINTER;
+
+ return VDP_STATUS_NO_IMPLEMENTATION;
+}
+
+VdpStatus
+vlVdpPresentationQueueGetTime ( VdpPresentationQueue presentation_queue,
+ VdpTime *current_time)
+{
+ if (!current_time)
+ return VDP_STATUS_INVALID_POINTER;
+
+ return VDP_STATUS_NO_IMPLEMENTATION;
+}
+
+VdpStatus
+vlVdpPresentationQueueDisplay ( VdpPresentationQueue presentation_queue,
+ VdpOutputSurface surface,
+ uint32_t clip_width,
+ uint32_t clip_height,
+ VdpTime earliest_presentation_time)
+{
+
+ return VDP_STATUS_NO_IMPLEMENTATION;
+}
+
+VdpStatus
+vlVdpPresentationQueueBlockUntilSurfaceIdle ( VdpPresentationQueue presentation_queue,
+ VdpOutputSurface surface,
+ VdpTime *first_presentation_time)
+{
+ if (!first_presentation_time)
+ return VDP_STATUS_INVALID_POINTER;
+
+ return VDP_STATUS_NO_IMPLEMENTATION;
+}
+
+VdpStatus
+vlVdpPresentationQueueQuerySurfaceStatus ( VdpPresentationQueue presentation_queue,
+ VdpOutputSurface surface,
+ VdpPresentationQueueStatus *status,
+ VdpTime *first_presentation_time)
+{
+ if (!(status && first_presentation_time))
+ return VDP_STATUS_INVALID_POINTER;
+
+ return VDP_STATUS_NO_IMPLEMENTATION;
+} \ No newline at end of file
diff --git a/src/gallium/state_trackers/vdpau/query.c b/src/gallium/state_trackers/vdpau/query.c
new file mode 100644
index 00000000000..86b5098f178
--- /dev/null
+++ b/src/gallium/state_trackers/vdpau/query.c
@@ -0,0 +1,281 @@
+/**************************************************************************
+ *
+ * Copyright 2010 Younes Manton.
+ * 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 TUNGSTEN GRAPHICS 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.
+ *
+ **************************************************************************/
+
+#include "vdpau_private.h"
+#include <vl_winsys.h>
+#include <assert.h>
+#include <pipe/p_screen.h>
+#include <pipe/p_defines.h>
+#include <math.h>
+#include <util/u_debug.h>
+
+
+VdpStatus
+vlVdpGetApiVersion(uint32_t *api_version)
+{
+ if (!api_version)
+ return VDP_STATUS_INVALID_POINTER;
+
+ *api_version = 1;
+ return VDP_STATUS_OK;
+}
+
+VdpStatus
+vlVdpGetInformationString(char const **information_string)
+{
+ if (!information_string)
+ return VDP_STATUS_INVALID_POINTER;
+
+ *information_string = INFORMATION_STRING;
+ return VDP_STATUS_OK;
+}
+
+VdpStatus
+vlVdpVideoSurfaceQueryCapabilities(VdpDevice device, VdpChromaType surface_chroma_type,
+ VdpBool *is_supported, uint32_t *max_width, uint32_t *max_height)
+{
+ struct vl_screen *vlscreen;
+ uint32_t max_2d_texture_level;
+ VdpStatus ret;
+
+ debug_printf("[VDPAU] Querying video surfaces\n");
+
+ if (!(is_supported && max_width && max_height))
+ return VDP_STATUS_INVALID_POINTER;
+
+ vlVdpDevice *dev = vlGetDataHTAB(device);
+ if (!dev)
+ return VDP_STATUS_INVALID_HANDLE;
+
+ vlscreen = vl_screen_create(dev->display, dev->screen);
+ if (!vlscreen)
+ return VDP_STATUS_RESOURCES;
+
+ /* XXX: Current limits */
+ *is_supported = true;
+ if (surface_chroma_type != VDP_CHROMA_TYPE_420) {
+ *is_supported = false;
+ goto no_sup;
+ }
+
+ max_2d_texture_level = vlscreen->pscreen->get_param( vlscreen->pscreen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS );
+ if (!max_2d_texture_level) {
+ ret = VDP_STATUS_RESOURCES;
+ goto no_sup;
+ }
+
+ /* I am not quite sure if it is max_2d_texture_level-1 or just max_2d_texture_level */
+ *max_width = *max_height = pow(2,max_2d_texture_level-1);
+
+ vl_screen_destroy(vlscreen);
+
+ return VDP_STATUS_OK;
+ no_sup:
+ return ret;
+}
+
+VdpStatus
+vlVdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities(VdpDevice device, VdpChromaType surface_chroma_type,
+ VdpYCbCrFormat bits_ycbcr_format,
+ VdpBool *is_supported)
+{
+ struct vl_screen *vlscreen;
+
+ debug_printf("[VDPAU] Querying get put video surfaces\n");
+
+ if (!is_supported)
+ return VDP_STATUS_INVALID_POINTER;
+
+ vlVdpDevice *dev = vlGetDataHTAB(device);
+ if (!dev)
+ return VDP_STATUS_INVALID_HANDLE;
+
+ vlscreen = vl_screen_create(dev->display, dev->screen);
+ if (!vlscreen)
+ return VDP_STATUS_RESOURCES;
+
+ if (bits_ycbcr_format != VDP_YCBCR_FORMAT_Y8U8V8A8 && bits_ycbcr_format != VDP_YCBCR_FORMAT_V8U8Y8A8)
+ *is_supported = vlscreen->pscreen->is_format_supported(vlscreen->pscreen,
+ FormatToPipe(bits_ycbcr_format),
+ PIPE_TEXTURE_2D,
+ PIPE_BIND_RENDER_TARGET,
+ PIPE_TEXTURE_GEOM_NON_SQUARE );
+
+ vl_screen_destroy(vlscreen);
+
+ return VDP_STATUS_OK;
+}
+
+VdpStatus
+vlVdpDecoderQueryCapabilities(VdpDevice device, VdpDecoderProfile profile,
+ VdpBool *is_supported, uint32_t *max_level, uint32_t *max_macroblocks,
+ uint32_t *max_width, uint32_t *max_height)
+{
+ enum pipe_video_profile p_profile;
+ uint32_t max_decode_width;
+ uint32_t max_decode_height;
+ uint32_t max_2d_texture_level;
+ struct vl_screen *vlscreen;
+
+ debug_printf("[VDPAU] Querying decoder\n");
+
+ if (!(is_supported && max_level && max_macroblocks && max_width && max_height))
+ return VDP_STATUS_INVALID_POINTER;
+
+ vlVdpDevice *dev = vlGetDataHTAB(device);
+ if (!dev)
+ return VDP_STATUS_INVALID_HANDLE;
+
+ vlscreen = vl_screen_create(dev->display, dev->screen);
+ if (!vlscreen)
+ return VDP_STATUS_RESOURCES;
+
+ p_profile = ProfileToPipe(profile);
+ if (p_profile == PIPE_VIDEO_PROFILE_UNKNOWN) {
+ *is_supported = false;
+ return VDP_STATUS_OK;
+ }
+
+ if (p_profile != PIPE_VIDEO_PROFILE_MPEG2_SIMPLE && p_profile != PIPE_VIDEO_PROFILE_MPEG2_MAIN) {
+ *is_supported = false;
+ return VDP_STATUS_OK;
+ }
+
+ /* XXX hack, need to implement something more sane when the decoders have been implemented */
+ max_2d_texture_level = vlscreen->pscreen->get_param( vlscreen->pscreen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS );
+ max_decode_width = max_decode_height = pow(2,max_2d_texture_level-2);
+ if (!(max_decode_width && max_decode_height))
+ return VDP_STATUS_RESOURCES;
+
+ *is_supported = true;
+ *max_width = max_decode_width;
+ *max_height = max_decode_height;
+ *max_level = 16;
+ *max_macroblocks = (max_decode_width/16) * (max_decode_height/16);
+
+ vl_screen_destroy(vlscreen);
+
+ return VDP_STATUS_OK;
+}
+
+VdpStatus
+vlVdpOutputSurfaceQueryCapabilities(VdpDevice device, VdpRGBAFormat surface_rgba_format,
+ VdpBool *is_supported, uint32_t *max_width, uint32_t *max_height)
+{
+ if (!(is_supported && max_width && max_height))
+ return VDP_STATUS_INVALID_POINTER;
+
+ debug_printf("[VDPAU] Querying ouput surfaces\n");
+
+ return VDP_STATUS_NO_IMPLEMENTATION;
+}
+
+VdpStatus
+vlVdpOutputSurfaceQueryGetPutBitsNativeCapabilities(VdpDevice device, VdpRGBAFormat surface_rgba_format,
+ VdpBool *is_supported)
+{
+ debug_printf("[VDPAU] Querying output surfaces get put native cap\n");
+
+ if (!is_supported)
+ return VDP_STATUS_INVALID_POINTER;
+
+ return VDP_STATUS_NO_IMPLEMENTATION;
+}
+
+VdpStatus
+vlVdpOutputSurfaceQueryPutBitsYCbCrCapabilities(VdpDevice device, VdpRGBAFormat surface_rgba_format,
+ VdpYCbCrFormat bits_ycbcr_format,
+ VdpBool *is_supported)
+{
+ debug_printf("[VDPAU] Querying output surfaces put ycrcb cap\n");
+ if (!is_supported)
+ return VDP_STATUS_INVALID_POINTER;
+
+ return VDP_STATUS_NO_IMPLEMENTATION;
+}
+
+VdpStatus
+vlVdpBitmapSurfaceQueryCapabilities(VdpDevice device, VdpRGBAFormat surface_rgba_format,
+ VdpBool *is_supported, uint32_t *max_width, uint32_t *max_height)
+{
+ debug_printf("[VDPAU] Querying bitmap surfaces\n");
+ if (!(is_supported && max_width && max_height))
+ return VDP_STATUS_INVALID_POINTER;
+
+ return VDP_STATUS_NO_IMPLEMENTATION;
+}
+
+VdpStatus
+vlVdpVideoMixerQueryFeatureSupport(VdpDevice device, VdpVideoMixerFeature feature,
+ VdpBool *is_supported)
+{
+ debug_printf("[VDPAU] Querying mixer feature support\n");
+ if (!is_supported)
+ return VDP_STATUS_INVALID_POINTER;
+
+ return VDP_STATUS_NO_IMPLEMENTATION;
+}
+
+VdpStatus
+vlVdpVideoMixerQueryParameterSupport(VdpDevice device, VdpVideoMixerParameter parameter,
+ VdpBool *is_supported)
+{
+ if (!is_supported)
+ return VDP_STATUS_INVALID_POINTER;
+
+ return VDP_STATUS_NO_IMPLEMENTATION;
+}
+
+VdpStatus
+vlVdpVideoMixerQueryParameterValueRange(VdpDevice device, VdpVideoMixerParameter parameter,
+ void *min_value, void *max_value)
+{
+ if (!(min_value && max_value))
+ return VDP_STATUS_INVALID_POINTER;
+
+ return VDP_STATUS_NO_IMPLEMENTATION;
+}
+
+VdpStatus
+vlVdpVideoMixerQueryAttributeSupport(VdpDevice device, VdpVideoMixerAttribute attribute,
+ VdpBool *is_supported)
+{
+ if (!is_supported)
+ return VDP_STATUS_INVALID_POINTER;
+
+ return VDP_STATUS_NO_IMPLEMENTATION;
+}
+
+VdpStatus
+vlVdpVideoMixerQueryAttributeValueRange(VdpDevice device, VdpVideoMixerAttribute attribute,
+ void *min_value, void *max_value)
+{
+ if (!(min_value && max_value))
+ return VDP_STATUS_INVALID_POINTER;
+
+ return VDP_STATUS_NO_IMPLEMENTATION;
+}
diff --git a/src/gallium/state_trackers/vdpau/render.c b/src/gallium/state_trackers/vdpau/render.c
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/src/gallium/state_trackers/vdpau/render.c
diff --git a/src/gallium/state_trackers/vdpau/surface.c b/src/gallium/state_trackers/vdpau/surface.c
new file mode 100644
index 00000000000..f957d94bdf7
--- /dev/null
+++ b/src/gallium/state_trackers/vdpau/surface.c
@@ -0,0 +1,192 @@
+/**************************************************************************
+ *
+ * Copyright 2010 Thomas Balling Sørensen.
+ * 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 TUNGSTEN GRAPHICS 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.
+ *
+ **************************************************************************/
+
+#include "vdpau_private.h"
+#include <pipe/p_screen.h>
+#include <pipe/p_state.h>
+#include <util/u_memory.h>
+#include <util/u_format.h>
+#include <stdio.h>
+
+VdpStatus
+vlVdpVideoSurfaceCreate(VdpDevice device,
+ VdpChromaType chroma_type,
+ uint32_t width,
+ uint32_t height,
+ VdpVideoSurface *surface)
+{
+ printf("[VDPAU] Creating a surface\n");
+
+ vlVdpSurface *p_surf;
+ VdpStatus ret;
+
+ if (!(width && height))
+ {
+ ret = VDP_STATUS_INVALID_SIZE;
+ goto inv_size;
+ }
+
+
+ if (!vlCreateHTAB()) {
+ ret = VDP_STATUS_RESOURCES;
+ goto no_htab;
+ }
+
+ p_surf = CALLOC(1, sizeof(p_surf));
+ if (!p_surf) {
+ ret = VDP_STATUS_RESOURCES;
+ goto no_res;
+ }
+
+ vlVdpDevice *dev = vlGetDataHTAB(device);
+ if (!dev) {
+ ret = VDP_STATUS_INVALID_HANDLE;
+ goto inv_device;
+ }
+
+ p_surf->chroma_format = FormatToPipe(chroma_type);
+ p_surf->device = dev;
+
+ *surface = vlAddDataHTAB(p_surf);
+ if (*surface == 0) {
+ ret = VDP_STATUS_ERROR;
+ goto no_handle;
+ }
+
+ return VDP_STATUS_OK;
+
+no_handle:
+ FREE(p_surf->psurface);
+inv_device:
+no_surf:
+ FREE(p_surf);
+no_res:
+ // vlDestroyHTAB(); XXX: Do not destroy this tab, I think.
+no_htab:
+inv_size:
+ return ret;
+}
+
+VdpStatus
+vlVdpVideoSurfaceDestroy ( VdpVideoSurface surface )
+{
+ vlVdpSurface *p_surf;
+
+ p_surf = (vlVdpSurface *)vlGetDataHTAB((vlHandle)surface);
+ if (!p_surf)
+ return VDP_STATUS_INVALID_HANDLE;
+
+ if (p_surf->psurface) {
+ if (p_surf->psurface->texture) {
+ if (p_surf->psurface->texture->screen)
+ p_surf->psurface->texture->screen->tex_surface_destroy(p_surf->psurface);
+ }
+ }
+ FREE(p_surf);
+ return VDP_STATUS_OK;
+}
+
+VdpStatus
+vlVdpVideoSurfaceGetParameters ( VdpVideoSurface surface,
+ VdpChromaType *chroma_type,
+ uint32_t *width,
+ uint32_t *height
+)
+{
+ if (!(width && height && chroma_type))
+ return VDP_STATUS_INVALID_POINTER;
+
+
+ vlVdpSurface *p_surf = vlGetDataHTAB(surface);
+ if (!p_surf)
+ return VDP_STATUS_INVALID_HANDLE;
+
+
+ if (!(p_surf->chroma_format > 0 && p_surf->chroma_format < 3))
+ return VDP_STATUS_INVALID_CHROMA_TYPE;
+
+ *width = p_surf->width;
+ *height = p_surf->height;
+ *chroma_type = PipeToType(p_surf->chroma_format);
+
+ return VDP_STATUS_OK;
+}
+
+VdpStatus
+vlVdpVideoSurfaceGetBitsYCbCr ( VdpVideoSurface surface,
+ VdpYCbCrFormat destination_ycbcr_format,
+ void *const *destination_data,
+ uint32_t const *destination_pitches
+)
+{
+ if (!vlCreateHTAB())
+ return VDP_STATUS_RESOURCES;
+
+
+ vlVdpSurface *p_surf = vlGetDataHTAB(surface);
+ if (!p_surf)
+ return VDP_STATUS_INVALID_HANDLE;
+
+ if (!p_surf->psurface)
+ return VDP_STATUS_RESOURCES;
+
+
+ return VDP_STATUS_OK;
+}
+
+VdpStatus
+vlVdpVideoSurfacePutBitsYCbCr ( VdpVideoSurface surface,
+ VdpYCbCrFormat source_ycbcr_format,
+ void const *const *source_data,
+ uint32_t const *source_pitches
+)
+{
+ uint32_t size_surface_bytes;
+ const struct util_format_description *format_desc;
+ enum pipe_format pformat = FormatToPipe(source_ycbcr_format);
+
+ if (!vlCreateHTAB())
+ return VDP_STATUS_RESOURCES;
+
+
+ vlVdpSurface *p_surf = vlGetDataHTAB(surface);
+ if (!p_surf)
+ return VDP_STATUS_INVALID_HANDLE;
+
+
+ //size_surface_bytes = ( source_pitches[0] * p_surf->height util_format_get_blockheight(pformat) );
+ /*util_format_translate(enum pipe_format dst_format,
+ void *dst, unsigned dst_stride,
+ unsigned dst_x, unsigned dst_y,
+ enum pipe_format src_format,
+ const void *src, unsigned src_stride,
+ unsigned src_x, unsigned src_y,
+ unsigned width, unsigned height);*/
+
+ return VDP_STATUS_NO_IMPLEMENTATION;
+
+}
diff --git a/src/gallium/state_trackers/vdpau/vdpau_private.h b/src/gallium/state_trackers/vdpau/vdpau_private.h
new file mode 100644
index 00000000000..635d6c8acdb
--- /dev/null
+++ b/src/gallium/state_trackers/vdpau/vdpau_private.h
@@ -0,0 +1,216 @@
+/**************************************************************************
+ *
+ * Copyright 2010 Younes Manton.
+ * 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 TUNGSTEN GRAPHICS 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 VDPAU_PRIVATE_H
+#define VDPAU_PRIVATE_H
+
+
+#include <vdpau/vdpau.h>
+#include <pipe/p_compiler.h>
+#include <pipe/p_video_context.h>
+#include <vl_winsys.h>
+#include <assert.h>
+
+#define INFORMATION G3DVL VDPAU Driver Shared Library version VER_MAJOR.VER_MINOR
+#define QUOTEME(x) #x
+#define TOSTRING(x) QUOTEME(x)
+#define INFORMATION_STRING TOSTRING(INFORMATION)
+#define VL_HANDLES
+
+static enum pipe_video_chroma_format TypeToPipe(VdpChromaType vdpau_type)
+{
+ switch (vdpau_type) {
+ case VDP_CHROMA_TYPE_420:
+ return PIPE_VIDEO_CHROMA_FORMAT_420;
+ case VDP_CHROMA_TYPE_422:
+ return PIPE_VIDEO_CHROMA_FORMAT_422;
+ case VDP_CHROMA_TYPE_444:
+ return PIPE_VIDEO_CHROMA_FORMAT_444;
+ default:
+ assert(0);
+ }
+
+ return -1;
+}
+
+static VdpChromaType PipeToType(enum pipe_video_chroma_format pipe_type)
+{
+ switch (pipe_type) {
+ case PIPE_VIDEO_CHROMA_FORMAT_420:
+ return VDP_CHROMA_TYPE_420;
+ case PIPE_VIDEO_CHROMA_FORMAT_422:
+ return VDP_CHROMA_TYPE_422;
+ case PIPE_VIDEO_CHROMA_FORMAT_444:
+ return VDP_CHROMA_TYPE_444;
+ default:
+ assert(0);
+ }
+
+ return -1;
+}
+
+static enum pipe_format FormatToPipe(VdpYCbCrFormat vdpau_format)
+{
+ switch (vdpau_format) {
+ case VDP_YCBCR_FORMAT_NV12:
+ return PIPE_FORMAT_NV12;
+ case VDP_YCBCR_FORMAT_YV12:
+ return PIPE_FORMAT_YV12;
+ case VDP_YCBCR_FORMAT_UYVY:
+ return PIPE_FORMAT_UYVY;
+ case VDP_YCBCR_FORMAT_YUYV:
+ return PIPE_FORMAT_YUYV;
+ case VDP_YCBCR_FORMAT_Y8U8V8A8: /* Not defined in p_format.h */
+ return 0;
+ case VDP_YCBCR_FORMAT_V8U8Y8A8:
+ return PIPE_FORMAT_VUYA;
+ default:
+ assert(0);
+ }
+
+ return -1;
+}
+
+static VdpYCbCrFormat PipeToFormat(enum pipe_format p_format)
+{
+ switch (p_format) {
+ case PIPE_FORMAT_NV12:
+ return VDP_YCBCR_FORMAT_NV12;
+ case PIPE_FORMAT_YV12:
+ return VDP_YCBCR_FORMAT_YV12;
+ case PIPE_FORMAT_UYVY:
+ return VDP_YCBCR_FORMAT_UYVY;
+ case PIPE_FORMAT_YUYV:
+ return VDP_YCBCR_FORMAT_YUYV;
+ //case PIPE_FORMAT_YUVA:
+ // return VDP_YCBCR_FORMAT_Y8U8V8A8;
+ case PIPE_FORMAT_VUYA:
+ return VDP_YCBCR_FORMAT_V8U8Y8A8;
+ default:
+ assert(0);
+ }
+
+ return -1;
+}
+
+static enum pipe_video_profile ProfileToPipe(VdpDecoderProfile vdpau_profile)
+{
+ switch (vdpau_profile) {
+ case VDP_DECODER_PROFILE_MPEG1:
+ return PIPE_VIDEO_PROFILE_MPEG1;
+ case VDP_DECODER_PROFILE_MPEG2_SIMPLE:
+ return PIPE_VIDEO_PROFILE_MPEG2_SIMPLE;
+ case VDP_DECODER_PROFILE_MPEG2_MAIN:
+ return PIPE_VIDEO_PROFILE_MPEG2_MAIN;
+ case VDP_DECODER_PROFILE_H264_BASELINE:
+ return PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE;
+ case VDP_DECODER_PROFILE_H264_MAIN: /* Not defined in p_format.h */
+ return PIPE_VIDEO_PROFILE_MPEG4_AVC_MAIN;
+ case VDP_DECODER_PROFILE_H264_HIGH:
+ return PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH;
+ default:
+ PIPE_VIDEO_PROFILE_UNKNOWN;
+ }
+
+ return -1;
+}
+
+typedef struct
+{
+ void *display;
+ int screen;
+} vlVdpDevice;
+
+typedef struct
+{
+ vlVdpDevice *device;
+ uint32_t width;
+ uint32_t height;
+ uint32_t pitch;
+ struct pipe_surface *psurface;
+ enum pipe_format format;
+ enum pipe_video_chroma_format chroma_format;
+ uint8_t *data;
+} vlVdpSurface;
+
+typedef struct
+{
+ vlVdpDevice *device;
+ struct vl_screen *vlscreen;
+ struct vl_context *vctx;
+ enum pipe_video_chroma_format chroma_format;
+ enum pipe_video_profile profile;
+} vlVdpDecoder;
+
+typedef uint32_t vlHandle;
+
+boolean vlCreateHTAB(void);
+void vlDestroyHTAB(void);
+vlHandle vlAddDataHTAB(void *data);
+void* vlGetDataHTAB(vlHandle handle);
+boolean vlGetFuncFTAB(VdpFuncId function_id, void **func);
+
+VdpGetErrorString vlVdpGetErrorString;
+VdpDeviceDestroy vlVdpDeviceDestroy;
+VdpGetProcAddress vlVdpGetProcAddress;
+VdpGetApiVersion vlVdpGetApiVersion;
+VdpGetInformationString vlVdpGetInformationString;
+VdpVideoSurfaceQueryCapabilities vlVdpVideoSurfaceQueryCapabilities;
+VdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities vlVdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities;
+VdpDecoderQueryCapabilities vlVdpDecoderQueryCapabilities;
+VdpOutputSurfaceQueryCapabilities vlVdpOutputSurfaceQueryCapabilities;
+VdpOutputSurfaceQueryGetPutBitsNativeCapabilities vlVdpOutputSurfaceQueryGetPutBitsNativeCapabilities;
+VdpOutputSurfaceQueryPutBitsYCbCrCapabilities vlVdpOutputSurfaceQueryPutBitsYCbCrCapabilities;
+VdpBitmapSurfaceQueryCapabilities vlVdpBitmapSurfaceQueryCapabilities;
+VdpVideoMixerQueryFeatureSupport vlVdpVideoMixerQueryFeatureSupport;
+VdpVideoMixerQueryParameterSupport vlVdpVideoMixerQueryParameterSupport;
+VdpVideoMixerQueryParameterValueRange vlVdpVideoMixerQueryParameterValueRange;
+VdpVideoMixerQueryAttributeSupport vlVdpVideoMixerQueryAttributeSupport;
+VdpVideoMixerQueryAttributeValueRange vlVdpVideoMixerQueryAttributeValueRange;
+VdpVideoSurfaceCreate vlVdpVideoSurfaceCreate;
+VdpVideoSurfaceDestroy vlVdpVideoSurfaceDestroy;
+VdpVideoSurfaceGetParameters vlVdpVideoSurfaceGetParameters;
+VdpVideoSurfaceGetBitsYCbCr vlVdpVideoSurfaceGetBitsYCbCr;
+VdpVideoSurfacePutBitsYCbCr vlVdpVideoSurfacePutBitsYCbCr;
+VdpDecoderCreate vlVdpDecoderCreate;
+VdpDecoderDestroy vlVdpDecoderDestroy;
+VdpDecoderRender vlVdpDecoderRender;
+VdpOutputSurfaceCreate vlVdpOutputSurfaceCreate;
+VdpBitmapSurfaceCreate vlVdpBitmapSurfaceCreate;
+VdpBitmapSurfaceDestroy vlVdpBitmapSurfaceDestroy;
+VdpBitmapSurfaceGetParameters vlVdpBitmapSurfaceGetParameters;
+VdpBitmapSurfacePutBitsNative vlVdpBitmapSurfacePutBitsNative;
+VdpPresentationQueueTargetDestroy vlVdpPresentationQueueTargetDestroy;
+VdpPresentationQueueCreate vlVdpPresentationQueueCreate;
+VdpPresentationQueueDestroy vlVdpPresentationQueueDestroy;
+VdpPresentationQueueSetBackgroundColor vlVdpPresentationQueueSetBackgroundColor;
+VdpPresentationQueueGetBackgroundColor vlVdpPresentationQueueGetBackgroundColor;
+VdpPresentationQueueGetTime vlVdpPresentationQueueGetTime;
+VdpPresentationQueueDisplay vlVdpPresentationQueueDisplay;
+VdpPresentationQueueBlockUntilSurfaceIdle vlVdpPresentationQueueBlockUntilSurfaceIdle;
+VdpPresentationQueueQuerySurfaceStatus vlVdpPresentationQueueQuerySurfaceStatus;
+#endif // VDPAU_PRIVATE_H
diff --git a/src/gallium/state_trackers/xorg/xvmc/Makefile b/src/gallium/state_trackers/xorg/xvmc/Makefile
new file mode 100644
index 00000000000..126dc6d58f1
--- /dev/null
+++ b/src/gallium/state_trackers/xorg/xvmc/Makefile
@@ -0,0 +1,16 @@
+TOP = ../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = xvmctracker
+
+LIBRARY_INCLUDES = \
+ $(shell pkg-config --cflags-only-I xvmc) \
+ -I$(TOP)/src/gallium/winsys/g3dvl
+
+C_SOURCES = block.c \
+ surface.c \
+ context.c \
+ subpicture.c \
+ attributes.c
+
+include ../../../Makefile.template
diff --git a/src/gallium/state_trackers/xorg/xvmc/attributes.c b/src/gallium/state_trackers/xorg/xvmc/attributes.c
new file mode 100644
index 00000000000..d23d8635b66
--- /dev/null
+++ b/src/gallium/state_trackers/xorg/xvmc/attributes.c
@@ -0,0 +1,50 @@
+/**************************************************************************
+ *
+ * Copyright 2009 Younes Manton.
+ * 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 TUNGSTEN GRAPHICS 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.
+ *
+ **************************************************************************/
+
+#include <assert.h>
+#include <X11/Xlib.h>
+#include <X11/extensions/Xvlib.h>
+#include <X11/extensions/XvMClib.h>
+#include <pipe/p_compiler.h>
+
+PUBLIC
+XvAttribute* XvMCQueryAttributes(Display *dpy, XvMCContext *context, int *number)
+{
+ return NULL;
+}
+
+PUBLIC
+Status XvMCSetAttribute(Display *dpy, XvMCContext *context, Atom attribute, int value)
+{
+ return BadImplementation;
+}
+
+PUBLIC
+Status XvMCGetAttribute(Display *dpy, XvMCContext *context, Atom attribute, int *value)
+{
+ return BadImplementation;
+}
diff --git a/src/gallium/state_trackers/xorg/xvmc/block.c b/src/gallium/state_trackers/xorg/xvmc/block.c
new file mode 100644
index 00000000000..c7da7a84a7b
--- /dev/null
+++ b/src/gallium/state_trackers/xorg/xvmc/block.c
@@ -0,0 +1,92 @@
+/**************************************************************************
+ *
+ * Copyright 2009 Younes Manton.
+ * 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 TUNGSTEN GRAPHICS 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.
+ *
+ **************************************************************************/
+
+#include <assert.h>
+#include <X11/Xlib.h>
+#include <X11/extensions/XvMClib.h>
+#include <util/u_memory.h>
+#include "xvmc_private.h"
+
+PUBLIC
+Status XvMCCreateBlocks(Display *dpy, XvMCContext *context, unsigned int num_blocks, XvMCBlockArray *blocks)
+{
+ assert(dpy);
+
+ if (!context)
+ return XvMCBadContext;
+ if (num_blocks == 0)
+ return BadValue;
+
+ assert(blocks);
+
+ blocks->context_id = context->context_id;
+ blocks->num_blocks = num_blocks;
+ blocks->blocks = MALLOC(BLOCK_SIZE_BYTES * num_blocks);
+ blocks->privData = NULL;
+
+ return Success;
+}
+
+PUBLIC
+Status XvMCDestroyBlocks(Display *dpy, XvMCBlockArray *blocks)
+{
+ assert(dpy);
+ assert(blocks);
+ FREE(blocks->blocks);
+
+ return Success;
+}
+
+PUBLIC
+Status XvMCCreateMacroBlocks(Display *dpy, XvMCContext *context, unsigned int num_blocks, XvMCMacroBlockArray *blocks)
+{
+ assert(dpy);
+
+ if (!context)
+ return XvMCBadContext;
+ if (num_blocks == 0)
+ return BadValue;
+
+ assert(blocks);
+
+ blocks->context_id = context->context_id;
+ blocks->num_blocks = num_blocks;
+ blocks->macro_blocks = MALLOC(sizeof(XvMCMacroBlock) * num_blocks);
+ blocks->privData = NULL;
+
+ return Success;
+}
+
+PUBLIC
+Status XvMCDestroyMacroBlocks(Display *dpy, XvMCMacroBlockArray *blocks)
+{
+ assert(dpy);
+ assert(blocks);
+ FREE(blocks->macro_blocks);
+
+ return Success;
+}
diff --git a/src/gallium/state_trackers/xorg/xvmc/context.c b/src/gallium/state_trackers/xorg/xvmc/context.c
new file mode 100644
index 00000000000..5e4af9e555a
--- /dev/null
+++ b/src/gallium/state_trackers/xorg/xvmc/context.c
@@ -0,0 +1,298 @@
+/**************************************************************************
+ *
+ * Copyright 2009 Younes Manton.
+ * 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 TUNGSTEN GRAPHICS 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.
+ *
+ **************************************************************************/
+
+#include <assert.h>
+#include <X11/Xlibint.h>
+#include <X11/extensions/XvMClib.h>
+#include <pipe/p_screen.h>
+#include <pipe/p_video_context.h>
+#include <pipe/p_video_state.h>
+#include <pipe/p_state.h>
+#include <vl_winsys.h>
+#include <util/u_memory.h>
+#include <vl/vl_csc.h>
+#include "xvmc_private.h"
+
+static Status Validate(Display *dpy, XvPortID port, int surface_type_id,
+ unsigned int width, unsigned int height, int flags,
+ bool *found_port, int *screen, int *chroma_format,
+ int *mc_type, int *surface_flags,
+ unsigned short *subpic_max_w,
+ unsigned short *subpic_max_h)
+{
+ bool found_surface = false;
+ XvAdaptorInfo *adaptor_info;
+ unsigned int num_adaptors;
+ int num_types;
+ unsigned int max_width, max_height;
+ Status ret;
+
+ assert(dpy);
+ assert(found_port);
+ assert(screen);
+ assert(chroma_format);
+ assert(mc_type);
+ assert(surface_flags);
+ assert(subpic_max_w);
+ assert(subpic_max_h);
+
+ *found_port = false;
+
+ for (unsigned int i = 0; i < XScreenCount(dpy); ++i) {
+ ret = XvQueryAdaptors(dpy, XRootWindow(dpy, i), &num_adaptors, &adaptor_info);
+ if (ret != Success)
+ return ret;
+
+ for (unsigned int j = 0; j < num_adaptors && !*found_port; ++j) {
+ for (unsigned int k = 0; k < adaptor_info[j].num_ports && !*found_port; ++k) {
+ XvMCSurfaceInfo *surface_info;
+
+ if (adaptor_info[j].base_id + k != port)
+ continue;
+
+ *found_port = true;
+
+ surface_info = XvMCListSurfaceTypes(dpy, adaptor_info[j].base_id, &num_types);
+ if (!surface_info) {
+ XvFreeAdaptorInfo(adaptor_info);
+ return BadAlloc;
+ }
+
+ for (unsigned int l = 0; l < num_types && !found_surface; ++l) {
+ if (surface_info[l].surface_type_id != surface_type_id)
+ continue;
+
+ found_surface = true;
+ max_width = surface_info[l].max_width;
+ max_height = surface_info[l].max_height;
+ *chroma_format = surface_info[l].chroma_format;
+ *mc_type = surface_info[l].mc_type;
+ *surface_flags = surface_info[l].flags;
+ *subpic_max_w = surface_info[l].subpicture_max_width;
+ *subpic_max_h = surface_info[l].subpicture_max_height;
+ *screen = i;
+
+ XVMC_MSG(XVMC_TRACE, "[XvMC] Found requested context surface format.\n" \
+ "[XvMC] screen=%u, port=%u\n" \
+ "[XvMC] id=0x%08X\n" \
+ "[XvMC] max width=%u, max height=%u\n" \
+ "[XvMC] chroma format=0x%08X\n" \
+ "[XvMC] acceleration level=0x%08X\n" \
+ "[XvMC] flags=0x%08X\n" \
+ "[XvMC] subpicture max width=%u, max height=%u\n",
+ i, port, surface_type_id, max_width, max_height, *chroma_format,
+ *mc_type, *surface_flags, *subpic_max_w, *subpic_max_h);
+ }
+
+ XFree(surface_info);
+ }
+ }
+
+ XvFreeAdaptorInfo(adaptor_info);
+ }
+
+ if (!*found_port) {
+ XVMC_MSG(XVMC_ERR, "[XvMC] Could not find a suitable port.\n");
+ return XvBadPort;
+ }
+ if (!found_surface) {
+ XVMC_MSG(XVMC_ERR, "[XvMC] Could not find a suitable surface.\n");
+ return BadMatch;
+ }
+ if (width > max_width || height > max_height) {
+ XVMC_MSG(XVMC_ERR, "[XvMC] Requested context dimensions (w=%u,h=%u) too large (max w=%u,h=%u).\n",
+ width, height, max_width, max_height);
+ return BadValue;
+ }
+ if (flags != XVMC_DIRECT && flags != 0) {
+ XVMC_MSG(XVMC_ERR, "[XvMC] Invalid context flags 0x%08X.\n", flags);
+ return BadValue;
+ }
+
+ return Success;
+}
+
+static enum pipe_video_profile ProfileToPipe(int xvmc_profile)
+{
+ if (xvmc_profile & XVMC_MPEG_1)
+ assert(0);
+ if (xvmc_profile & XVMC_MPEG_2)
+ return PIPE_VIDEO_PROFILE_MPEG2_MAIN;
+ if (xvmc_profile & XVMC_H263)
+ assert(0);
+ if (xvmc_profile & XVMC_MPEG_4)
+ assert(0);
+
+ assert(0);
+
+ XVMC_MSG(XVMC_ERR, "[XvMC] Unrecognized profile 0x%08X.\n", xvmc_profile);
+
+ return -1;
+}
+
+static enum pipe_video_chroma_format FormatToPipe(int xvmc_format)
+{
+ switch (xvmc_format) {
+ case XVMC_CHROMA_FORMAT_420:
+ return PIPE_VIDEO_CHROMA_FORMAT_420;
+ case XVMC_CHROMA_FORMAT_422:
+ return PIPE_VIDEO_CHROMA_FORMAT_422;
+ case XVMC_CHROMA_FORMAT_444:
+ return PIPE_VIDEO_CHROMA_FORMAT_444;
+ default:
+ assert(0);
+ }
+
+ XVMC_MSG(XVMC_ERR, "[XvMC] Unrecognized format 0x%08X.\n", xvmc_format);
+
+ return -1;
+}
+
+PUBLIC
+Status XvMCCreateContext(Display *dpy, XvPortID port, int surface_type_id,
+ int width, int height, int flags, XvMCContext *context)
+{
+ bool found_port;
+ int scrn;
+ int chroma_format;
+ int mc_type;
+ int surface_flags;
+ unsigned short subpic_max_w;
+ unsigned short subpic_max_h;
+ Status ret;
+ struct vl_screen *vscreen;
+ struct vl_context *vctx;
+ XvMCContextPrivate *context_priv;
+ float csc[16];
+
+ XVMC_MSG(XVMC_TRACE, "[XvMC] Creating context %p.\n", context);
+
+ assert(dpy);
+
+ if (!context)
+ return XvMCBadContext;
+
+ ret = Validate(dpy, port, surface_type_id, width, height, flags,
+ &found_port, &scrn, &chroma_format, &mc_type, &surface_flags,
+ &subpic_max_w, &subpic_max_h);
+
+ /* Success and XvBadPort have the same value */
+ if (ret != Success || !found_port)
+ return ret;
+
+ /* XXX: Current limits */
+ if (chroma_format != XVMC_CHROMA_FORMAT_420) {
+ XVMC_MSG(XVMC_ERR, "[XvMC] Cannot decode requested surface type. Unsupported chroma format.\n");
+ return BadImplementation;
+ }
+ if (mc_type != (XVMC_MOCOMP | XVMC_MPEG_2)) {
+ XVMC_MSG(XVMC_ERR, "[XvMC] Cannot decode requested surface type. Non-MPEG2/Mocomp acceleration unsupported.\n");
+ return BadImplementation;
+ }
+ if (!(surface_flags & XVMC_INTRA_UNSIGNED)) {
+ XVMC_MSG(XVMC_ERR, "[XvMC] Cannot decode requested surface type. Signed intra unsupported.\n");
+ return BadImplementation;
+ }
+
+ context_priv = CALLOC(1, sizeof(XvMCContextPrivate));
+ if (!context_priv)
+ return BadAlloc;
+
+ /* TODO: Reuse screen if process creates another context */
+ vscreen = vl_screen_create(dpy, scrn);
+
+ if (!vscreen) {
+ XVMC_MSG(XVMC_ERR, "[XvMC] Could not create VL screen.\n");
+ FREE(context_priv);
+ return BadAlloc;
+ }
+
+ vctx = vl_video_create(vscreen, ProfileToPipe(mc_type),
+ FormatToPipe(chroma_format), width, height);
+
+ if (!vctx) {
+ XVMC_MSG(XVMC_ERR, "[XvMC] Could not create VL context.\n");
+ vl_screen_destroy(vscreen);
+ FREE(context_priv);
+ return BadAlloc;
+ }
+
+ /* TODO: Define some Xv attribs to allow users to specify color standard, procamp */
+ vl_csc_get_matrix
+ (
+ debug_get_bool_option("G3DVL_NO_CSC", FALSE) ?
+ VL_CSC_COLOR_STANDARD_IDENTITY : VL_CSC_COLOR_STANDARD_BT_601,
+ NULL, true, csc
+ );
+ vctx->vpipe->set_csc_matrix(vctx->vpipe, csc);
+
+ context_priv->vctx = vctx;
+ context_priv->subpicture_max_width = subpic_max_w;
+ context_priv->subpicture_max_height = subpic_max_h;
+
+ context->context_id = XAllocID(dpy);
+ context->surface_type_id = surface_type_id;
+ context->width = width;
+ context->height = height;
+ context->flags = flags;
+ context->port = port;
+ context->privData = context_priv;
+
+ SyncHandle();
+
+ XVMC_MSG(XVMC_TRACE, "[XvMC] Context %p created.\n", context);
+
+ return Success;
+}
+
+PUBLIC
+Status XvMCDestroyContext(Display *dpy, XvMCContext *context)
+{
+ struct vl_screen *vscreen;
+ struct vl_context *vctx;
+ XvMCContextPrivate *context_priv;
+
+ XVMC_MSG(XVMC_TRACE, "[XvMC] Destroying context %p.\n", context);
+
+ assert(dpy);
+
+ if (!context || !context->privData)
+ return XvMCBadContext;
+
+ context_priv = context->privData;
+ vctx = context_priv->vctx;
+ pipe_surface_reference(&context_priv->backbuffer, NULL);
+ vscreen = vctx->vscreen;
+ vl_video_destroy(vctx);
+ vl_screen_destroy(vscreen);
+ FREE(context_priv);
+ context->privData = NULL;
+
+ XVMC_MSG(XVMC_TRACE, "[XvMC] Context %p destroyed.\n", context);
+
+ return Success;
+}
diff --git a/src/gallium/state_trackers/xorg/xvmc/subpicture.c b/src/gallium/state_trackers/xorg/xvmc/subpicture.c
new file mode 100644
index 00000000000..e0c9e303817
--- /dev/null
+++ b/src/gallium/state_trackers/xorg/xvmc/subpicture.c
@@ -0,0 +1,440 @@
+/**************************************************************************
+ *
+ * Copyright 2009 Younes Manton.
+ * 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 TUNGSTEN GRAPHICS 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.
+ *
+ **************************************************************************/
+
+#include <assert.h>
+#include <X11/Xlibint.h>
+#include <X11/extensions/XvMClib.h>
+#include <xorg/fourcc.h>
+#include <vl_winsys.h>
+#include <pipe/p_screen.h>
+#include <pipe/p_video_context.h>
+#include <pipe/p_state.h>
+#include <util/u_memory.h>
+#include <util/u_math.h>
+#include "xvmc_private.h"
+
+#define FOURCC_RGB 0x0000003
+
+static enum pipe_format XvIDToPipe(int xvimage_id)
+{
+ switch (xvimage_id) {
+ case FOURCC_RGB:
+ return PIPE_FORMAT_B8G8R8X8_UNORM;
+ default:
+ XVMC_MSG(XVMC_ERR, "[XvMC] Unrecognized Xv image ID 0x%08X.\n", xvimage_id);
+ return PIPE_FORMAT_NONE;
+ }
+}
+
+static int PipeToComponentOrder(enum pipe_format format, char *component_order)
+{
+ assert(component_order);
+
+ switch (format) {
+ case PIPE_FORMAT_B8G8R8X8_UNORM:
+ return 0;
+ default:
+ XVMC_MSG(XVMC_ERR, "[XvMC] Unrecognized PIPE_FORMAT 0x%08X.\n", format);
+ component_order[0] = 0;
+ component_order[1] = 0;
+ component_order[2] = 0;
+ component_order[3] = 0;
+ }
+
+ return 0;
+}
+
+static Status Validate(Display *dpy, XvPortID port, int surface_type_id, int xvimage_id)
+{
+ XvImageFormatValues *subpictures;
+ int num_subpics;
+ unsigned int i;
+
+ subpictures = XvMCListSubpictureTypes(dpy, port, surface_type_id, &num_subpics);
+ if (num_subpics < 1) {
+ if (subpictures)
+ XFree(subpictures);
+ return BadMatch;
+ }
+ if (!subpictures)
+ return BadAlloc;
+
+ for (i = 0; i < num_subpics; ++i) {
+ if (subpictures[i].id == xvimage_id) {
+ XVMC_MSG(XVMC_TRACE, "[XvMC] Found requested subpicture format.\n" \
+ "[XvMC] port=%u\n" \
+ "[XvMC] surface id=0x%08X\n" \
+ "[XvMC] image id=0x%08X\n" \
+ "[XvMC] type=%08X\n" \
+ "[XvMC] byte order=%08X\n" \
+ "[XvMC] bits per pixel=%u\n" \
+ "[XvMC] format=%08X\n" \
+ "[XvMC] num planes=%d\n",
+ port, surface_type_id, xvimage_id, subpictures[i].type, subpictures[i].byte_order,
+ subpictures[i].bits_per_pixel, subpictures[i].format, subpictures[i].num_planes);
+ if (subpictures[i].type == XvRGB) {
+ XVMC_MSG(XVMC_TRACE, "[XvMC] depth=%d\n" \
+ "[XvMC] red mask=0x%08X\n" \
+ "[XvMC] green mask=0x%08X\n" \
+ "[XvMC] blue mask=0x%08X\n",
+ subpictures[i].depth, subpictures[i].red_mask, subpictures[i].green_mask, subpictures[i].blue_mask);
+ }
+ else if (subpictures[i].type == XvYUV) {
+ XVMC_MSG(XVMC_TRACE, "[XvMC] y sample bits=0x%08X\n" \
+ "[XvMC] u sample bits=0x%08X\n" \
+ "[XvMC] v sample bits=0x%08X\n" \
+ "[XvMC] horz y period=%u\n" \
+ "[XvMC] horz u period=%u\n" \
+ "[XvMC] horz v period=%u\n" \
+ "[XvMC] vert y period=%u\n" \
+ "[XvMC] vert u period=%u\n" \
+ "[XvMC] vert v period=%u\n",
+ subpictures[i].y_sample_bits, subpictures[i].u_sample_bits, subpictures[i].v_sample_bits,
+ subpictures[i].horz_y_period, subpictures[i].horz_u_period, subpictures[i].horz_v_period,
+ subpictures[i].vert_y_period, subpictures[i].vert_u_period, subpictures[i].vert_v_period);
+ }
+ break;
+ }
+ }
+
+ XFree(subpictures);
+
+ return i < num_subpics ? Success : BadMatch;
+}
+
+PUBLIC
+Status XvMCCreateSubpicture(Display *dpy, XvMCContext *context, XvMCSubpicture *subpicture,
+ unsigned short width, unsigned short height, int xvimage_id)
+{
+ XvMCContextPrivate *context_priv;
+ XvMCSubpicturePrivate *subpicture_priv;
+ struct pipe_video_context *vpipe;
+ struct pipe_resource template;
+ struct pipe_resource *tex;
+ Status ret;
+
+ XVMC_MSG(XVMC_TRACE, "[XvMC] Creating subpicture %p.\n", subpicture);
+
+ assert(dpy);
+
+ if (!context)
+ return XvMCBadContext;
+
+ context_priv = context->privData;
+ vpipe = context_priv->vctx->vpipe;
+
+ if (!subpicture)
+ return XvMCBadSubpicture;
+
+ if (width > context_priv->subpicture_max_width ||
+ height > context_priv->subpicture_max_height)
+ return BadValue;
+
+ ret = Validate(dpy, context->port, context->surface_type_id, xvimage_id);
+ if (ret != Success)
+ return ret;
+
+ subpicture_priv = CALLOC(1, sizeof(XvMCSubpicturePrivate));
+ if (!subpicture_priv)
+ return BadAlloc;
+
+ memset(&template, 0, sizeof(struct pipe_resource));
+ template.target = PIPE_TEXTURE_2D;
+ template.format = XvIDToPipe(xvimage_id);
+ template.last_level = 0;
+ if (vpipe->get_param(vpipe, PIPE_CAP_NPOT_TEXTURES)) {
+ template.width0 = width;
+ template.height0 = height;
+ }
+ else {
+ template.width0 = util_next_power_of_two(width);
+ template.height0 = util_next_power_of_two(height);
+ }
+ template.depth0 = 1;
+ template.usage = PIPE_USAGE_DYNAMIC;
+ template.bind = PIPE_BIND_SAMPLER_VIEW;
+ template.flags = 0;
+
+ subpicture_priv->context = context;
+ tex = vpipe->screen->resource_create(vpipe->screen, &template);
+ subpicture_priv->sfc = vpipe->screen->get_tex_surface(vpipe->screen, tex, 0, 0, 0,
+ PIPE_BIND_SAMPLER_VIEW);
+ pipe_resource_reference(&tex, NULL);
+ if (!subpicture_priv->sfc) {
+ FREE(subpicture_priv);
+ return BadAlloc;
+ }
+
+ subpicture->subpicture_id = XAllocID(dpy);
+ subpicture->context_id = context->context_id;
+ subpicture->xvimage_id = xvimage_id;
+ subpicture->width = width;
+ subpicture->height = height;
+ subpicture->num_palette_entries = 0;
+ subpicture->entry_bytes = PipeToComponentOrder(template.format, subpicture->component_order);
+ subpicture->privData = subpicture_priv;
+
+ SyncHandle();
+
+ XVMC_MSG(XVMC_TRACE, "[XvMC] Subpicture %p created.\n", subpicture);
+
+ return Success;
+}
+
+PUBLIC
+Status XvMCClearSubpicture(Display *dpy, XvMCSubpicture *subpicture, short x, short y,
+ unsigned short width, unsigned short height, unsigned int color)
+{
+ XvMCSubpicturePrivate *subpicture_priv;
+ XvMCContextPrivate *context_priv;
+
+ assert(dpy);
+
+ if (!subpicture)
+ return XvMCBadSubpicture;
+
+ subpicture_priv = subpicture->privData;
+ context_priv = subpicture_priv->context->privData;
+ /* TODO: Assert clear rect is within bounds? Or clip? */
+ context_priv->vctx->vpipe->surface_fill(context_priv->vctx->vpipe,
+ subpicture_priv->sfc, x, y,
+ width, height, color);
+
+ return Success;
+}
+
+PUBLIC
+Status XvMCCompositeSubpicture(Display *dpy, XvMCSubpicture *subpicture, XvImage *image,
+ short srcx, short srcy, unsigned short width, unsigned short height,
+ short dstx, short dsty)
+{
+ XvMCSubpicturePrivate *subpicture_priv;
+ XvMCContextPrivate *context_priv;
+ struct pipe_video_context *vpipe;
+ struct pipe_transfer *xfer;
+ unsigned char *src, *dst, *dst_line;
+ unsigned x, y;
+ struct pipe_box dst_box = {dstx, dsty, 0, width, height, 1};
+ struct pipe_subresource sr = {0, 0};
+
+ XVMC_MSG(XVMC_TRACE, "[XvMC] Compositing subpicture %p.\n", subpicture);
+
+ assert(dpy);
+
+ if (!subpicture)
+ return XvMCBadSubpicture;
+
+ assert(image);
+
+ if (subpicture->xvimage_id != image->id)
+ return BadMatch;
+
+ /* No planar support for now */
+ if (image->num_planes != 1)
+ return BadMatch;
+
+ subpicture_priv = subpicture->privData;
+ context_priv = subpicture_priv->context->privData;
+ vpipe = context_priv->vctx->vpipe;
+
+ /* TODO: Assert rects are within bounds? Or clip? */
+
+ xfer = vpipe->get_transfer(vpipe, subpicture_priv->sfc->texture,
+ sr, PIPE_TRANSFER_WRITE, &dst_box);
+ if (!xfer)
+ return BadAlloc;
+
+ src = image->data;
+ dst = vpipe->transfer_map(vpipe, xfer);
+ if (!dst) {
+ vpipe->transfer_destroy(vpipe, xfer);
+ return BadAlloc;
+ }
+
+ switch (image->id) {
+ case FOURCC_RGB:
+ assert(subpicture_priv->sfc->format == XvIDToPipe(image->id));
+ for (y = 0; y < height; ++y) {
+ dst_line = dst;
+ for (x = 0; x < width; ++x, src += 3, dst_line += 4) {
+ dst_line[0] = src[2]; /* B */
+ dst_line[1] = src[1]; /* G */
+ dst_line[2] = src[0]; /* R */
+ }
+ dst += xfer->stride;
+ }
+ break;
+ default:
+ XVMC_MSG(XVMC_ERR, "[XvMC] Unrecognized Xv image ID 0x%08X.\n", image->id);
+ }
+
+ vpipe->transfer_unmap(vpipe, xfer);
+ vpipe->transfer_destroy(vpipe, xfer);
+
+ XVMC_MSG(XVMC_TRACE, "[XvMC] Subpicture %p composited.\n", subpicture);
+
+ return Success;
+}
+
+PUBLIC
+Status XvMCDestroySubpicture(Display *dpy, XvMCSubpicture *subpicture)
+{
+ XvMCSubpicturePrivate *subpicture_priv;
+
+ XVMC_MSG(XVMC_TRACE, "[XvMC] Destroying subpicture %p.\n", subpicture);
+
+ assert(dpy);
+
+ if (!subpicture)
+ return XvMCBadSubpicture;
+
+ subpicture_priv = subpicture->privData;
+ pipe_surface_reference(&subpicture_priv->sfc, NULL);
+ FREE(subpicture_priv);
+
+ XVMC_MSG(XVMC_TRACE, "[XvMC] Subpicture %p destroyed.\n", subpicture);
+
+ return Success;
+}
+
+PUBLIC
+Status XvMCSetSubpicturePalette(Display *dpy, XvMCSubpicture *subpicture, unsigned char *palette)
+{
+ assert(dpy);
+
+ if (!subpicture)
+ return XvMCBadSubpicture;
+
+ assert(palette);
+
+ /* We don't support paletted subpictures */
+ return BadMatch;
+}
+
+PUBLIC
+Status XvMCBlendSubpicture(Display *dpy, XvMCSurface *target_surface, XvMCSubpicture *subpicture,
+ short subx, short suby, unsigned short subw, unsigned short subh,
+ short surfx, short surfy, unsigned short surfw, unsigned short surfh)
+{
+ XvMCSurfacePrivate *surface_priv;
+ XvMCSubpicturePrivate *subpicture_priv;
+
+ XVMC_MSG(XVMC_TRACE, "[XvMC] Associating subpicture %p with surface %p.\n", subpicture, target_surface);
+
+ assert(dpy);
+
+ if (!target_surface)
+ return XvMCBadSurface;
+
+ if (!subpicture)
+ return XvMCBadSubpicture;
+
+ if (target_surface->context_id != subpicture->context_id)
+ return BadMatch;
+
+ /* TODO: Verify against subpicture independent scaling */
+
+ surface_priv = target_surface->privData;
+ subpicture_priv = subpicture->privData;
+
+ /* TODO: Assert rects are within bounds? Or clip? */
+
+ surface_priv->subpicture = subpicture;
+ surface_priv->subx = subx;
+ surface_priv->suby = suby;
+ surface_priv->subw = subw;
+ surface_priv->subh = subh;
+ surface_priv->surfx = surfx;
+ surface_priv->surfy = surfy;
+ surface_priv->surfw = surfw;
+ surface_priv->surfh = surfh;
+ subpicture_priv->surface = target_surface;
+
+ return Success;
+}
+
+PUBLIC
+Status XvMCBlendSubpicture2(Display *dpy, XvMCSurface *source_surface, XvMCSurface *target_surface,
+ XvMCSubpicture *subpicture, short subx, short suby, unsigned short subw, unsigned short subh,
+ short surfx, short surfy, unsigned short surfw, unsigned short surfh)
+{
+ assert(dpy);
+
+ if (!source_surface || !target_surface)
+ return XvMCBadSurface;
+
+ if (!subpicture)
+ return XvMCBadSubpicture;
+
+ if (source_surface->context_id != subpicture->context_id)
+ return BadMatch;
+
+ if (source_surface->context_id != subpicture->context_id)
+ return BadMatch;
+
+ /* TODO: Assert rects are within bounds? Or clip? */
+
+ return Success;
+}
+
+PUBLIC
+Status XvMCSyncSubpicture(Display *dpy, XvMCSubpicture *subpicture)
+{
+ assert(dpy);
+
+ if (!subpicture)
+ return XvMCBadSubpicture;
+
+ return Success;
+}
+
+PUBLIC
+Status XvMCFlushSubpicture(Display *dpy, XvMCSubpicture *subpicture)
+{
+ assert(dpy);
+
+ if (!subpicture)
+ return XvMCBadSubpicture;
+
+ return Success;
+}
+
+PUBLIC
+Status XvMCGetSubpictureStatus(Display *dpy, XvMCSubpicture *subpicture, int *status)
+{
+ assert(dpy);
+
+ if (!subpicture)
+ return XvMCBadSubpicture;
+
+ assert(status);
+
+ /* TODO */
+ *status = 0;
+
+ return Success;
+}
diff --git a/src/gallium/state_trackers/xorg/xvmc/surface.c b/src/gallium/state_trackers/xorg/xvmc/surface.c
new file mode 100644
index 00000000000..0decc45a0bb
--- /dev/null
+++ b/src/gallium/state_trackers/xorg/xvmc/surface.c
@@ -0,0 +1,501 @@
+/**************************************************************************
+ *
+ * Copyright 2009 Younes Manton.
+ * 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 TUNGSTEN GRAPHICS 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.
+ *
+ **************************************************************************/
+
+#include <assert.h>
+#include <X11/Xlibint.h>
+#include <vl_winsys.h>
+#include <pipe/p_video_context.h>
+#include <pipe/p_video_state.h>
+#include <pipe/p_state.h>
+#include <util/u_inlines.h>
+#include <util/u_memory.h>
+#include <util/u_math.h>
+#include "xvmc_private.h"
+
+static enum pipe_mpeg12_macroblock_type TypeToPipe(int xvmc_mb_type)
+{
+ if (xvmc_mb_type & XVMC_MB_TYPE_INTRA)
+ return PIPE_MPEG12_MACROBLOCK_TYPE_INTRA;
+ if ((xvmc_mb_type & (XVMC_MB_TYPE_MOTION_FORWARD | XVMC_MB_TYPE_MOTION_BACKWARD)) == XVMC_MB_TYPE_MOTION_FORWARD)
+ return PIPE_MPEG12_MACROBLOCK_TYPE_FWD;
+ if ((xvmc_mb_type & (XVMC_MB_TYPE_MOTION_FORWARD | XVMC_MB_TYPE_MOTION_BACKWARD)) == XVMC_MB_TYPE_MOTION_BACKWARD)
+ return PIPE_MPEG12_MACROBLOCK_TYPE_BKWD;
+ if ((xvmc_mb_type & (XVMC_MB_TYPE_MOTION_FORWARD | XVMC_MB_TYPE_MOTION_BACKWARD)) == (XVMC_MB_TYPE_MOTION_FORWARD | XVMC_MB_TYPE_MOTION_BACKWARD))
+ return PIPE_MPEG12_MACROBLOCK_TYPE_BI;
+
+ assert(0);
+
+ XVMC_MSG(XVMC_ERR, "[XvMC] Unrecognized mb type 0x%08X.\n", xvmc_mb_type);
+
+ return -1;
+}
+
+static enum pipe_mpeg12_picture_type PictureToPipe(int xvmc_pic)
+{
+ switch (xvmc_pic) {
+ case XVMC_TOP_FIELD:
+ return PIPE_MPEG12_PICTURE_TYPE_FIELD_TOP;
+ case XVMC_BOTTOM_FIELD:
+ return PIPE_MPEG12_PICTURE_TYPE_FIELD_BOTTOM;
+ case XVMC_FRAME_PICTURE:
+ return PIPE_MPEG12_PICTURE_TYPE_FRAME;
+ default:
+ assert(0);
+ }
+
+ XVMC_MSG(XVMC_ERR, "[XvMC] Unrecognized picture type 0x%08X.\n", xvmc_pic);
+
+ return -1;
+}
+
+static enum pipe_mpeg12_motion_type MotionToPipe(int xvmc_motion_type, int xvmc_dct_type)
+{
+ switch (xvmc_motion_type) {
+ case XVMC_PREDICTION_FRAME:
+ if (xvmc_dct_type == XVMC_DCT_TYPE_FIELD)
+ return PIPE_MPEG12_MOTION_TYPE_16x8;
+ else if (xvmc_dct_type == XVMC_DCT_TYPE_FRAME)
+ return PIPE_MPEG12_MOTION_TYPE_FRAME;
+ break;
+ case XVMC_PREDICTION_FIELD:
+ return PIPE_MPEG12_MOTION_TYPE_FIELD;
+ case XVMC_PREDICTION_DUAL_PRIME:
+ return PIPE_MPEG12_MOTION_TYPE_DUALPRIME;
+ default:
+ assert(0);
+ }
+
+ XVMC_MSG(XVMC_ERR, "[XvMC] Unrecognized motion type 0x%08X (with DCT type 0x%08X).\n", xvmc_motion_type, xvmc_dct_type);
+
+ return -1;
+}
+
+#if 0
+static bool
+CreateOrResizeBackBuffer(struct vl_context *vctx, unsigned int width, unsigned int height,
+ struct pipe_surface **backbuffer)
+{
+ struct pipe_video_context *vpipe;
+ struct pipe_resource template;
+ struct pipe_resource *tex;
+
+ assert(vctx);
+
+ vpipe = vctx->vpipe;
+
+ if (*backbuffer) {
+ if ((*backbuffer)->width != width || (*backbuffer)->height != height)
+ pipe_surface_reference(backbuffer, NULL);
+ else
+ return true;
+ }
+
+ memset(&template, 0, sizeof(struct pipe_resource));
+ template.target = PIPE_TEXTURE_2D;
+ template.format = vctx->vscreen->format;
+ template.last_level = 0;
+ template.width0 = width;
+ template.height0 = height;
+ template.depth0 = 1;
+ template.usage = PIPE_USAGE_DEFAULT;
+ template.bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_BLIT_SOURCE;
+ template.flags = 0;
+
+ tex = vpipe->screen->resource_create(vpipe->screen, &template);
+ if (!tex)
+ return false;
+
+ *backbuffer = vpipe->screen->get_tex_surface(vpipe->screen, tex, 0, 0, 0,
+ template.bind);
+ pipe_resource_reference(&tex, NULL);
+
+ if (!*backbuffer)
+ return false;
+
+ /* Clear the backbuffer in case the video doesn't cover the whole window */
+ /* FIXME: Need to clear every time a frame moves and leaves dirty rects */
+ vpipe->surface_fill(vpipe, *backbuffer, 0, 0, width, height, 0);
+
+ return true;
+}
+#endif
+
+static void
+MacroBlocksToPipe(struct pipe_screen *screen,
+ const XvMCMacroBlockArray *xvmc_macroblocks,
+ const XvMCBlockArray *xvmc_blocks,
+ unsigned int first_macroblock,
+ unsigned int num_macroblocks,
+ struct pipe_mpeg12_macroblock *pipe_macroblocks)
+{
+ unsigned int i, j, k, l;
+ XvMCMacroBlock *xvmc_mb;
+
+ assert(xvmc_macroblocks);
+ assert(xvmc_blocks);
+ assert(pipe_macroblocks);
+ assert(num_macroblocks);
+
+ xvmc_mb = xvmc_macroblocks->macro_blocks + first_macroblock;
+
+ for (i = 0; i < num_macroblocks; ++i) {
+ pipe_macroblocks->base.codec = PIPE_VIDEO_CODEC_MPEG12;
+ pipe_macroblocks->mbx = xvmc_mb->x;
+ pipe_macroblocks->mby = xvmc_mb->y;
+ pipe_macroblocks->mb_type = TypeToPipe(xvmc_mb->macroblock_type);
+ if (pipe_macroblocks->mb_type != PIPE_MPEG12_MACROBLOCK_TYPE_INTRA)
+ pipe_macroblocks->mo_type = MotionToPipe(xvmc_mb->motion_type, xvmc_mb->dct_type);
+ /* Get rid of Valgrind 'undefined' warnings */
+ else
+ pipe_macroblocks->mo_type = -1;
+ pipe_macroblocks->dct_type = xvmc_mb->dct_type == XVMC_DCT_TYPE_FIELD ?
+ PIPE_MPEG12_DCT_TYPE_FIELD : PIPE_MPEG12_DCT_TYPE_FRAME;
+
+ for (j = 0; j < 2; ++j)
+ for (k = 0; k < 2; ++k)
+ for (l = 0; l < 2; ++l)
+ pipe_macroblocks->pmv[j][k][l] = xvmc_mb->PMV[j][k][l];
+
+ pipe_macroblocks->cbp = xvmc_mb->coded_block_pattern;
+ pipe_macroblocks->blocks = xvmc_blocks->blocks + xvmc_mb->index * BLOCK_SIZE_SAMPLES;
+
+ ++pipe_macroblocks;
+ ++xvmc_mb;
+ }
+}
+
+PUBLIC
+Status XvMCCreateSurface(Display *dpy, XvMCContext *context, XvMCSurface *surface)
+{
+ XvMCContextPrivate *context_priv;
+ struct pipe_video_context *vpipe;
+ XvMCSurfacePrivate *surface_priv;
+ struct pipe_resource template;
+ struct pipe_resource *vsfc_tex;
+ struct pipe_surface *vsfc;
+
+ XVMC_MSG(XVMC_TRACE, "[XvMC] Creating surface %p.\n", surface);
+
+ assert(dpy);
+
+ if (!context)
+ return XvMCBadContext;
+ if (!surface)
+ return XvMCBadSurface;
+
+ context_priv = context->privData;
+ vpipe = context_priv->vctx->vpipe;
+
+ surface_priv = CALLOC(1, sizeof(XvMCSurfacePrivate));
+ if (!surface_priv)
+ return BadAlloc;
+
+ memset(&template, 0, sizeof(struct pipe_resource));
+ template.target = PIPE_TEXTURE_2D;
+ template.format = (enum pipe_format)vpipe->get_param(vpipe, PIPE_CAP_DECODE_TARGET_PREFERRED_FORMAT);
+ template.last_level = 0;
+ if (vpipe->is_format_supported(vpipe, template.format,
+ PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET,
+ PIPE_TEXTURE_GEOM_NON_POWER_OF_TWO)) {
+ template.width0 = context->width;
+ template.height0 = context->height;
+ }
+ else {
+ assert(vpipe->is_format_supported(vpipe, template.format,
+ PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET,
+ PIPE_TEXTURE_GEOM_NON_SQUARE));
+ template.width0 = util_next_power_of_two(context->width);
+ template.height0 = util_next_power_of_two(context->height);
+ }
+ template.depth0 = 1;
+ template.usage = PIPE_USAGE_DEFAULT;
+ template.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
+ template.flags = 0;
+ vsfc_tex = vpipe->screen->resource_create(vpipe->screen, &template);
+ if (!vsfc_tex) {
+ FREE(surface_priv);
+ return BadAlloc;
+ }
+
+ vsfc = vpipe->screen->get_tex_surface(vpipe->screen, vsfc_tex, 0, 0, 0,
+ PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET);
+ pipe_resource_reference(&vsfc_tex, NULL);
+ if (!vsfc) {
+ FREE(surface_priv);
+ return BadAlloc;
+ }
+
+ surface_priv->pipe_vsfc = vsfc;
+ surface_priv->context = context;
+
+ surface->surface_id = XAllocID(dpy);
+ surface->context_id = context->context_id;
+ surface->surface_type_id = context->surface_type_id;
+ surface->width = context->width;
+ surface->height = context->height;
+ surface->privData = surface_priv;
+
+ SyncHandle();
+
+ XVMC_MSG(XVMC_TRACE, "[XvMC] Surface %p created.\n", surface);
+
+ return Success;
+}
+
+PUBLIC
+Status XvMCRenderSurface(Display *dpy, XvMCContext *context, unsigned int picture_structure,
+ XvMCSurface *target_surface, XvMCSurface *past_surface, XvMCSurface *future_surface,
+ unsigned int flags, unsigned int num_macroblocks, unsigned int first_macroblock,
+ XvMCMacroBlockArray *macroblocks, XvMCBlockArray *blocks
+)
+{
+ struct pipe_video_context *vpipe;
+ struct pipe_surface *t_vsfc;
+ struct pipe_surface *p_vsfc;
+ struct pipe_surface *f_vsfc;
+ XvMCContextPrivate *context_priv;
+ XvMCSurfacePrivate *target_surface_priv;
+ XvMCSurfacePrivate *past_surface_priv;
+ XvMCSurfacePrivate *future_surface_priv;
+ struct pipe_mpeg12_macroblock pipe_macroblocks[num_macroblocks];
+
+ XVMC_MSG(XVMC_TRACE, "[XvMC] Rendering to surface %p.\n", target_surface);
+
+ assert(dpy);
+
+ if (!context || !context->privData)
+ return XvMCBadContext;
+ if (!target_surface || !target_surface->privData)
+ return XvMCBadSurface;
+
+ if (picture_structure != XVMC_TOP_FIELD &&
+ picture_structure != XVMC_BOTTOM_FIELD &&
+ picture_structure != XVMC_FRAME_PICTURE)
+ return BadValue;
+ /* Bkwd pred equivalent to fwd (past && !future) */
+ if (future_surface && !past_surface)
+ return BadMatch;
+
+ assert(context->context_id == target_surface->context_id);
+ assert(!past_surface || context->context_id == past_surface->context_id);
+ assert(!future_surface || context->context_id == future_surface->context_id);
+
+ assert(macroblocks);
+ assert(blocks);
+
+ assert(macroblocks->context_id == context->context_id);
+ assert(blocks->context_id == context->context_id);
+
+ assert(flags == 0 || flags == XVMC_SECOND_FIELD);
+
+ target_surface_priv = target_surface->privData;
+ past_surface_priv = past_surface ? past_surface->privData : NULL;
+ future_surface_priv = future_surface ? future_surface->privData : NULL;
+
+ assert(target_surface_priv->context == context);
+ assert(!past_surface || past_surface_priv->context == context);
+ assert(!future_surface || future_surface_priv->context == context);
+
+ context_priv = context->privData;
+ vpipe = context_priv->vctx->vpipe;
+
+ t_vsfc = target_surface_priv->pipe_vsfc;
+ p_vsfc = past_surface ? past_surface_priv->pipe_vsfc : NULL;
+ f_vsfc = future_surface ? future_surface_priv->pipe_vsfc : NULL;
+
+ MacroBlocksToPipe(vpipe->screen, macroblocks, blocks, first_macroblock,
+ num_macroblocks, pipe_macroblocks);
+
+ vpipe->set_decode_target(vpipe, t_vsfc);
+ vpipe->decode_macroblocks(vpipe, p_vsfc, f_vsfc, num_macroblocks,
+ &pipe_macroblocks->base, &target_surface_priv->render_fence);
+
+ XVMC_MSG(XVMC_TRACE, "[XvMC] Submitted surface %p for rendering.\n", target_surface);
+
+ return Success;
+}
+
+PUBLIC
+Status XvMCFlushSurface(Display *dpy, XvMCSurface *surface)
+{
+ assert(dpy);
+
+ if (!surface)
+ return XvMCBadSurface;
+
+ return Success;
+}
+
+PUBLIC
+Status XvMCSyncSurface(Display *dpy, XvMCSurface *surface)
+{
+ assert(dpy);
+
+ if (!surface)
+ return XvMCBadSurface;
+
+ return Success;
+}
+
+PUBLIC
+Status XvMCPutSurface(Display *dpy, XvMCSurface *surface, Drawable drawable,
+ short srcx, short srcy, unsigned short srcw, unsigned short srch,
+ short destx, short desty, unsigned short destw, unsigned short desth,
+ int flags)
+{
+ struct pipe_video_context *vpipe;
+ XvMCSurfacePrivate *surface_priv;
+ XvMCContextPrivate *context_priv;
+ XvMCSubpicturePrivate *subpicture_priv;
+ XvMCContext *context;
+ struct pipe_video_rect src_rect = {srcx, srcy, srcw, srch};
+ struct pipe_video_rect dst_rect = {destx, desty, destw, desth};
+ struct pipe_surface *drawable_surface;
+
+ XVMC_MSG(XVMC_TRACE, "[XvMC] Displaying surface %p.\n", surface);
+
+ assert(dpy);
+
+ if (!surface || !surface->privData)
+ return XvMCBadSurface;
+
+ surface_priv = surface->privData;
+ context = surface_priv->context;
+ context_priv = context->privData;
+
+ drawable_surface = vl_drawable_surface_get(context_priv->vctx->vscreen, drawable);
+ if (!drawable_surface)
+ return BadDrawable;
+
+ assert(flags == XVMC_TOP_FIELD || flags == XVMC_BOTTOM_FIELD || flags == XVMC_FRAME_PICTURE);
+ assert(srcx + srcw - 1 < surface->width);
+ assert(srcy + srch - 1 < surface->height);
+ /*
+ * Some apps (mplayer) hit these asserts because they call
+ * this function after the window has been resized by the WM
+ * but before they've handled the corresponding XEvent and
+ * know about the new dimensions. The output should be clipped
+ * until the app updates destw and desth.
+ */
+ /*
+ assert(destx + destw - 1 < drawable_surface->width);
+ assert(desty + desth - 1 < drawable_surface->height);
+ */
+
+ subpicture_priv = surface_priv->subpicture ? surface_priv->subpicture->privData : NULL;
+ vpipe = context_priv->vctx->vpipe;
+
+#if 0
+ if (!CreateOrResizeBackBuffer(context_priv->vctx, width, height, &context_priv->backbuffer))
+ return BadAlloc;
+#endif
+
+ if (subpicture_priv) {
+ struct pipe_video_rect src_rect = {surface_priv->subx, surface_priv->suby, surface_priv->subw, surface_priv->subh};
+ struct pipe_video_rect dst_rect = {surface_priv->surfx, surface_priv->surfy, surface_priv->surfw, surface_priv->surfh};
+ struct pipe_video_rect *src_rects[1] = {&src_rect};
+ struct pipe_video_rect *dst_rects[1] = {&dst_rect};
+
+ XVMC_MSG(XVMC_TRACE, "[XvMC] Surface %p has subpicture %p.\n", surface, surface_priv->subpicture);
+
+ assert(subpicture_priv->surface == surface);
+ vpipe->set_picture_layers(vpipe, &subpicture_priv->sfc, src_rects, dst_rects, 1);
+
+ surface_priv->subpicture = NULL;
+ subpicture_priv->surface = NULL;
+ }
+ else
+ vpipe->set_picture_layers(vpipe, NULL, NULL, NULL, 0);
+
+ vpipe->render_picture(vpipe, surface_priv->pipe_vsfc, PictureToPipe(flags), &src_rect,
+ drawable_surface, &dst_rect, &surface_priv->disp_fence);
+
+ XVMC_MSG(XVMC_TRACE, "[XvMC] Submitted surface %p for display. Pushing to front buffer.\n", surface);
+
+ vpipe->screen->flush_frontbuffer
+ (
+ vpipe->screen,
+ drawable_surface,
+ vl_contextprivate_get(context_priv->vctx, drawable_surface)
+ );
+
+ pipe_surface_reference(&drawable_surface, NULL);
+
+ XVMC_MSG(XVMC_TRACE, "[XvMC] Pushed surface %p to front buffer.\n", surface);
+
+ return Success;
+}
+
+PUBLIC
+Status XvMCGetSurfaceStatus(Display *dpy, XvMCSurface *surface, int *status)
+{
+ assert(dpy);
+
+ if (!surface)
+ return XvMCBadSurface;
+
+ assert(status);
+
+ *status = 0;
+
+ return Success;
+}
+
+PUBLIC
+Status XvMCDestroySurface(Display *dpy, XvMCSurface *surface)
+{
+ XvMCSurfacePrivate *surface_priv;
+
+ XVMC_MSG(XVMC_TRACE, "[XvMC] Destroying surface %p.\n", surface);
+
+ assert(dpy);
+
+ if (!surface || !surface->privData)
+ return XvMCBadSurface;
+
+ surface_priv = surface->privData;
+ pipe_surface_reference(&surface_priv->pipe_vsfc, NULL);
+ FREE(surface_priv);
+ surface->privData = NULL;
+
+ XVMC_MSG(XVMC_TRACE, "[XvMC] Surface %p destroyed.\n", surface);
+
+ return Success;
+}
+
+PUBLIC
+Status XvMCHideSurface(Display *dpy, XvMCSurface *surface)
+{
+ assert(dpy);
+
+ if (!surface || !surface->privData)
+ return XvMCBadSurface;
+
+ /* No op, only for overlaid rendering */
+
+ return Success;
+}
diff --git a/src/gallium/state_trackers/xorg/xvmc/tests/.gitignore b/src/gallium/state_trackers/xorg/xvmc/tests/.gitignore
new file mode 100644
index 00000000000..9a8e05d9472
--- /dev/null
+++ b/src/gallium/state_trackers/xorg/xvmc/tests/.gitignore
@@ -0,0 +1,6 @@
+test_context
+test_surface
+test_subpicture
+test_blocks
+test_rendering
+xvmc_bench
diff --git a/src/gallium/state_trackers/xorg/xvmc/tests/Makefile b/src/gallium/state_trackers/xorg/xvmc/tests/Makefile
new file mode 100644
index 00000000000..88b03763563
--- /dev/null
+++ b/src/gallium/state_trackers/xorg/xvmc/tests/Makefile
@@ -0,0 +1,31 @@
+TOP = ../../../../../..
+include $(TOP)/configs/current
+
+LIBS = -lXvMCW -lXvMC -lXv -lX11
+
+#############################################
+
+.PHONY: default clean
+
+default: test_context test_surface test_subpicture test_blocks test_rendering xvmc_bench
+
+test_context: test_context.o testlib.o
+ $(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
+
+test_surface: test_surface.o testlib.o
+ $(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
+
+test_subpicture: test_subpicture.o testlib.o
+ $(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
+
+test_blocks: test_blocks.o testlib.o
+ $(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
+
+test_rendering: test_rendering.o testlib.o
+ $(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
+
+xvmc_bench: xvmc_bench.o testlib.o
+ $(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
+
+clean:
+ $(RM) -rf *.o test_context test_surface test_subpicture test_blocks test_rendering xvmc_bench
diff --git a/src/gallium/state_trackers/xorg/xvmc/tests/test_blocks.c b/src/gallium/state_trackers/xorg/xvmc/tests/test_blocks.c
new file mode 100644
index 00000000000..994e3ca4d14
--- /dev/null
+++ b/src/gallium/state_trackers/xorg/xvmc/tests/test_blocks.c
@@ -0,0 +1,111 @@
+/**************************************************************************
+ *
+ * Copyright 2009 Younes Manton.
+ * 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 TUNGSTEN GRAPHICS 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.
+ *
+ **************************************************************************/
+
+#include <assert.h>
+#include <error.h>
+#include "testlib.h"
+
+int main(int argc, char **argv)
+{
+ const unsigned int width = 16, height = 16;
+ const unsigned int min_required_blocks = 1, min_required_macroblocks = 1;
+ const unsigned int mc_types[2] = {XVMC_MOCOMP | XVMC_MPEG_2, XVMC_IDCT | XVMC_MPEG_2};
+
+ Display *display;
+ XvPortID port_num;
+ int surface_type_id;
+ unsigned int is_overlay, intra_unsigned;
+ int colorkey;
+ XvMCContext context;
+ XvMCSurface surface;
+ XvMCBlockArray blocks = {0};
+ XvMCMacroBlockArray macroblocks = {0};
+
+ display = XOpenDisplay(NULL);
+
+ if (!GetPort
+ (
+ display,
+ width,
+ height,
+ XVMC_CHROMA_FORMAT_420,
+ mc_types,
+ 2,
+ &port_num,
+ &surface_type_id,
+ &is_overlay,
+ &intra_unsigned
+ ))
+ {
+ XCloseDisplay(display);
+ error(1, 0, "Error, unable to find a good port.\n");
+ }
+
+ if (is_overlay)
+ {
+ Atom xv_colorkey = XInternAtom(display, "XV_COLORKEY", 0);
+ XvGetPortAttribute(display, port_num, xv_colorkey, &colorkey);
+ }
+
+ assert(XvMCCreateContext(display, port_num, surface_type_id, width, height, XVMC_DIRECT, &context) == Success);
+ assert(XvMCCreateSurface(display, &context, &surface) == Success);
+
+ /* Test NULL context */
+ assert(XvMCCreateBlocks(display, NULL, 1, &blocks) == XvMCBadContext);
+ /* Test 0 blocks */
+ assert(XvMCCreateBlocks(display, &context, 0, &blocks) == BadValue);
+ /* Test valid params */
+ assert(XvMCCreateBlocks(display, &context, min_required_blocks, &blocks) == Success);
+ /* Test context id assigned and correct */
+ assert(blocks.context_id == context.context_id);
+ /* Test number of blocks assigned and correct */
+ assert(blocks.num_blocks == min_required_blocks);
+ /* Test block pointer valid */
+ assert(blocks.blocks != NULL);
+ /* Test NULL context */
+ assert(XvMCCreateMacroBlocks(display, NULL, 1, &macroblocks) == XvMCBadContext);
+ /* Test 0 macroblocks */
+ assert(XvMCCreateMacroBlocks(display, &context, 0, &macroblocks) == BadValue);
+ /* Test valid params */
+ assert(XvMCCreateMacroBlocks(display, &context, min_required_macroblocks, &macroblocks) == Success);
+ /* Test context id assigned and correct */
+ assert(macroblocks.context_id == context.context_id);
+ /* Test macroblock pointer valid */
+ assert(macroblocks.macro_blocks != NULL);
+ /* Test valid params */
+ assert(XvMCDestroyMacroBlocks(display, &macroblocks) == Success);
+ /* Test valid params */
+ assert(XvMCDestroyBlocks(display, &blocks) == Success);
+
+ assert(XvMCDestroySurface(display, &surface) == Success);
+ assert(XvMCDestroyContext(display, &context) == Success);
+
+ XvUngrabPort(display, port_num, CurrentTime);
+ XCloseDisplay(display);
+
+ return 0;
+}
diff --git a/src/gallium/state_trackers/xorg/xvmc/tests/test_context.c b/src/gallium/state_trackers/xorg/xvmc/tests/test_context.c
new file mode 100644
index 00000000000..3da957c9330
--- /dev/null
+++ b/src/gallium/state_trackers/xorg/xvmc/tests/test_context.c
@@ -0,0 +1,119 @@
+/**************************************************************************
+ *
+ * Copyright 2009 Younes Manton.
+ * 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 TUNGSTEN GRAPHICS 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.
+ *
+ **************************************************************************/
+
+#include <assert.h>
+#include <error.h>
+#include "testlib.h"
+
+int main(int argc, char **argv)
+{
+ const unsigned int width = 16, height = 16;
+ const unsigned int mc_types[2] = {XVMC_MOCOMP | XVMC_MPEG_2, XVMC_IDCT | XVMC_MPEG_2};
+
+ Display *display;
+ XvPortID port_num;
+ int surface_type_id;
+ unsigned int is_overlay, intra_unsigned;
+ int colorkey;
+ XvMCContext context = {0};
+
+ display = XOpenDisplay(NULL);
+
+ if (!GetPort
+ (
+ display,
+ width,
+ height,
+ XVMC_CHROMA_FORMAT_420,
+ mc_types,
+ 2,
+ &port_num,
+ &surface_type_id,
+ &is_overlay,
+ &intra_unsigned
+ ))
+ {
+ XCloseDisplay(display);
+ error(1, 0, "Error, unable to find a good port.\n");
+ }
+
+ if (is_overlay)
+ {
+ Atom xv_colorkey = XInternAtom(display, "XV_COLORKEY", 0);
+ XvGetPortAttribute(display, port_num, xv_colorkey, &colorkey);
+ }
+
+ /* Test NULL context */
+ /* XXX: XvMCBadContext not a valid return for XvMCCreateContext in the XvMC API, but openChrome driver returns it */
+ assert(XvMCCreateContext(display, port_num, surface_type_id, width, height, XVMC_DIRECT, NULL) == XvMCBadContext);
+ /* Test invalid port */
+ /* XXX: Success and XvBadPort have the same value, if this call actually gets passed the validation step as of now we'll crash later */
+ assert(XvMCCreateContext(display, -1, surface_type_id, width, height, XVMC_DIRECT, &context) == XvBadPort);
+ /* Test invalid surface */
+ assert(XvMCCreateContext(display, port_num, -1, width, height, XVMC_DIRECT, &context) == BadMatch);
+ /* Test invalid flags */
+ assert(XvMCCreateContext(display, port_num, surface_type_id, width, height, -1, &context) == BadValue);
+ /* Test huge width */
+ assert(XvMCCreateContext(display, port_num, surface_type_id, 16384, height, XVMC_DIRECT, &context) == BadValue);
+ /* Test huge height */
+ assert(XvMCCreateContext(display, port_num, surface_type_id, width, 16384, XVMC_DIRECT, &context) == BadValue);
+ /* Test huge width & height */
+ assert(XvMCCreateContext(display, port_num, surface_type_id, 16384, 16384, XVMC_DIRECT, &context) == BadValue);
+ /* Test valid params */
+ assert(XvMCCreateContext(display, port_num, surface_type_id, width, height, XVMC_DIRECT, &context) == Success);
+ /* Test context id assigned */
+ assert(context.context_id != 0);
+ /* Test surface type id assigned and correct */
+ assert(context.surface_type_id == surface_type_id);
+ /* Test width & height assigned and correct */
+ assert(context.width == width && context.height == height);
+ /* Test port assigned and correct */
+ assert(context.port == port_num);
+ /* Test flags assigned and correct */
+ assert(context.flags == XVMC_DIRECT);
+ /* Test NULL context */
+ assert(XvMCDestroyContext(display, NULL) == XvMCBadContext);
+ /* Test valid params */
+ assert(XvMCDestroyContext(display, &context) == Success);
+ /* Test awkward but valid width */
+ assert(XvMCCreateContext(display, port_num, surface_type_id, width + 1, height, XVMC_DIRECT, &context) == Success);
+ assert(context.width >= width + 1);
+ assert(XvMCDestroyContext(display, &context) == Success);
+ /* Test awkward but valid height */
+ assert(XvMCCreateContext(display, port_num, surface_type_id, width, height + 1, XVMC_DIRECT, &context) == Success);
+ assert(context.height >= height + 1);
+ assert(XvMCDestroyContext(display, &context) == Success);
+ /* Test awkward but valid width & height */
+ assert(XvMCCreateContext(display, port_num, surface_type_id, width + 1, height + 1, XVMC_DIRECT, &context) == Success);
+ assert(context.width >= width + 1 && context.height >= height + 1);
+ assert(XvMCDestroyContext(display, &context) == Success);
+
+ XvUngrabPort(display, port_num, CurrentTime);
+ XCloseDisplay(display);
+
+ return 0;
+}
diff --git a/src/gallium/state_trackers/xorg/xvmc/tests/test_rendering.c b/src/gallium/state_trackers/xorg/xvmc/tests/test_rendering.c
new file mode 100644
index 00000000000..6058783a798
--- /dev/null
+++ b/src/gallium/state_trackers/xorg/xvmc/tests/test_rendering.c
@@ -0,0 +1,317 @@
+/**************************************************************************
+ *
+ * Copyright 2009 Younes Manton.
+ * 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 TUNGSTEN GRAPHICS 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.
+ *
+ **************************************************************************/
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include <error.h>
+#include "testlib.h"
+
+#define BLOCK_WIDTH 8
+#define BLOCK_HEIGHT 8
+#define BLOCK_SIZE (BLOCK_WIDTH * BLOCK_HEIGHT)
+#define MACROBLOCK_WIDTH 16
+#define MACROBLOCK_HEIGHT 16
+#define MACROBLOCK_WIDTH_IN_BLOCKS (MACROBLOCK_WIDTH / BLOCK_WIDTH)
+#define MACROBLOCK_HEIGHT_IN_BLOCKS (MACROBLOCK_HEIGHT / BLOCK_HEIGHT)
+#define BLOCKS_PER_MACROBLOCK 6
+
+#define INPUT_WIDTH 16
+#define INPUT_HEIGHT 16
+#define INPUT_WIDTH_IN_MACROBLOCKS (INPUT_WIDTH / MACROBLOCK_WIDTH)
+#define INPUT_HEIGHT_IN_MACROBLOCKS (INPUT_HEIGHT / MACROBLOCK_HEIGHT)
+#define NUM_MACROBLOCKS (INPUT_WIDTH_IN_MACROBLOCKS * INPUT_HEIGHT_IN_MACROBLOCKS)
+
+#define DEFAULT_OUTPUT_WIDTH INPUT_WIDTH
+#define DEFAULT_OUTPUT_HEIGHT INPUT_HEIGHT
+#define DEFAULT_ACCEPTABLE_ERR 0.01
+
+void ParseArgs(int argc, char **argv, unsigned int *output_width, unsigned int *output_height, double *acceptable_error, int *prompt);
+void Gradient(short *block, unsigned int start, unsigned int stop, int horizontal);
+
+void ParseArgs(int argc, char **argv, unsigned int *output_width, unsigned int *output_height, double *acceptable_error, int *prompt)
+{
+ int fail = 0;
+ int i;
+
+ *output_width = DEFAULT_OUTPUT_WIDTH;
+ *output_height = DEFAULT_OUTPUT_WIDTH;
+ *acceptable_error = DEFAULT_ACCEPTABLE_ERR;
+ *prompt = 1;
+
+ for (i = 1; i < argc && !fail; ++i)
+ {
+ if (!strcmp(argv[i], "-w"))
+ {
+ if (sscanf(argv[++i], "%u", output_width) != 1)
+ fail = 1;
+ }
+ else if (!strcmp(argv[i], "-h"))
+ {
+ if (sscanf(argv[++i], "%u", output_height) != 1)
+ fail = 1;
+ }
+ else if (!strcmp(argv[i], "-e"))
+ {
+ if (sscanf(argv[++i], "%lf", acceptable_error) != 1)
+ fail = 1;
+ }
+ else if (strcmp(argv[i], "-n"))
+ *prompt = 0;
+ else
+ fail = 1;
+ }
+
+ if (fail)
+ error
+ (
+ 1, 0,
+ "Bad argument.\n"
+ "\n"
+ "Usage: %s [options]\n"
+ "\t-w <width>\tOutput width\n"
+ "\t-h <height>\tOutput height\n"
+ "\t-e <error>\tAcceptable margin of error per pixel, from 0 to 1\n"
+ "\t-n\tDon't prompt for quit\n",
+ argv[0]
+ );
+}
+
+void Gradient(short *block, unsigned int start, unsigned int stop, int horizontal)
+{
+ unsigned int x, y;
+ unsigned int range = stop - start;
+
+ if (horizontal)
+ {
+ for (y = 0; y < BLOCK_HEIGHT; ++y)
+ for (x = 0; x < BLOCK_WIDTH; ++x)
+ block[y * BLOCK_WIDTH + x] = (short)(start + range * (x / (float)(BLOCK_WIDTH - 1)));
+ }
+ else
+ {
+ for (y = 0; y < BLOCK_HEIGHT; ++y)
+ for (x = 0; x < BLOCK_WIDTH; ++x)
+ block[y * BLOCK_WIDTH + x] = (short)(start + range * (y / (float)(BLOCK_HEIGHT - 1)));
+ }
+}
+
+int main(int argc, char **argv)
+{
+ unsigned int output_width;
+ unsigned int output_height;
+ double acceptable_error;
+ int prompt;
+ Display *display;
+ Window root, window;
+ const unsigned int mc_types[2] = {XVMC_MOCOMP | XVMC_MPEG_2, XVMC_IDCT | XVMC_MPEG_2};
+ XvPortID port_num;
+ int surface_type_id;
+ unsigned int is_overlay, intra_unsigned;
+ int colorkey;
+ XvMCContext context;
+ XvMCSurface surface;
+ XvMCBlockArray block_array;
+ XvMCMacroBlockArray mb_array;
+ int mbx, mby, bx, by;
+ XvMCMacroBlock *mb;
+ short *blocks;
+ int quit = 0;
+
+ ParseArgs(argc, argv, &output_width, &output_height, &acceptable_error, &prompt);
+
+ display = XOpenDisplay(NULL);
+
+ if (!GetPort
+ (
+ display,
+ INPUT_WIDTH,
+ INPUT_HEIGHT,
+ XVMC_CHROMA_FORMAT_420,
+ mc_types,
+ 2,
+ &port_num,
+ &surface_type_id,
+ &is_overlay,
+ &intra_unsigned
+ ))
+ {
+ XCloseDisplay(display);
+ error(1, 0, "Error, unable to find a good port.\n");
+ }
+
+ if (is_overlay)
+ {
+ Atom xv_colorkey = XInternAtom(display, "XV_COLORKEY", 0);
+ XvGetPortAttribute(display, port_num, xv_colorkey, &colorkey);
+ }
+
+ root = XDefaultRootWindow(display);
+ window = XCreateSimpleWindow(display, root, 0, 0, output_width, output_height, 0, 0, colorkey);
+
+ assert(XvMCCreateContext(display, port_num, surface_type_id, INPUT_WIDTH, INPUT_HEIGHT, XVMC_DIRECT, &context) == Success);
+ assert(XvMCCreateSurface(display, &context, &surface) == Success);
+ assert(XvMCCreateBlocks(display, &context, NUM_MACROBLOCKS * BLOCKS_PER_MACROBLOCK, &block_array) == Success);
+ assert(XvMCCreateMacroBlocks(display, &context, NUM_MACROBLOCKS, &mb_array) == Success);
+
+ mb = mb_array.macro_blocks;
+ blocks = block_array.blocks;
+
+ for (mby = 0; mby < INPUT_HEIGHT_IN_MACROBLOCKS; ++mby)
+ for (mbx = 0; mbx < INPUT_WIDTH_IN_MACROBLOCKS; ++mbx)
+ {
+ mb->x = mbx;
+ mb->y = mby;
+ mb->macroblock_type = XVMC_MB_TYPE_INTRA;
+ /*mb->motion_type = ;*/
+ /*mb->motion_vertical_field_select = ;*/
+ mb->dct_type = XVMC_DCT_TYPE_FRAME;
+ /*mb->PMV[0][0][0] = ;
+ mb->PMV[0][0][1] = ;
+ mb->PMV[0][1][0] = ;
+ mb->PMV[0][1][1] = ;
+ mb->PMV[1][0][0] = ;
+ mb->PMV[1][0][1] = ;
+ mb->PMV[1][1][0] = ;
+ mb->PMV[1][1][1] = ;*/
+ mb->index = (mby * INPUT_WIDTH_IN_MACROBLOCKS + mbx) * BLOCKS_PER_MACROBLOCK;
+ mb->coded_block_pattern = 0x3F;
+
+ mb++;
+
+ for (by = 0; by < MACROBLOCK_HEIGHT_IN_BLOCKS; ++by)
+ for (bx = 0; bx < MACROBLOCK_WIDTH_IN_BLOCKS; ++bx)
+ {
+ const int start = 16, stop = 235, range = stop - start;
+
+ Gradient
+ (
+ blocks,
+ (short)(start + range * ((mbx * MACROBLOCK_WIDTH + bx * BLOCK_WIDTH) / (float)(INPUT_WIDTH - 1))),
+ (short)(start + range * ((mbx * MACROBLOCK_WIDTH + bx * BLOCK_WIDTH + BLOCK_WIDTH - 1) / (float)(INPUT_WIDTH - 1))),
+ 1
+ );
+
+ blocks += BLOCK_SIZE;
+ }
+
+ for (by = 0; by < MACROBLOCK_HEIGHT_IN_BLOCKS / 2; ++by)
+ for (bx = 0; bx < MACROBLOCK_WIDTH_IN_BLOCKS / 2; ++bx)
+ {
+ const int start = 16, stop = 240, range = stop - start;
+
+ Gradient
+ (
+ blocks,
+ (short)(start + range * ((mbx * MACROBLOCK_WIDTH + bx * BLOCK_WIDTH) / (float)(INPUT_WIDTH - 1))),
+ (short)(start + range * ((mbx * MACROBLOCK_WIDTH + bx * BLOCK_WIDTH + BLOCK_WIDTH - 1) / (float)(INPUT_WIDTH - 1))),
+ 1
+ );
+
+ blocks += BLOCK_SIZE;
+
+ Gradient
+ (
+ blocks,
+ (short)(start + range * ((mbx * MACROBLOCK_WIDTH + bx * BLOCK_WIDTH) / (float)(INPUT_WIDTH - 1))),
+ (short)(start + range * ((mbx * MACROBLOCK_WIDTH + bx * BLOCK_WIDTH + BLOCK_WIDTH - 1) / (float)(INPUT_WIDTH - 1))),
+ 1
+ );
+
+ blocks += BLOCK_SIZE;
+ }
+ }
+
+ XSelectInput(display, window, ExposureMask | KeyPressMask);
+ XMapWindow(display, window);
+ XSync(display, 0);
+
+ /* Test NULL context */
+ assert(XvMCRenderSurface(display, NULL, XVMC_FRAME_PICTURE, &surface, NULL, NULL, 0, NUM_MACROBLOCKS, 0, &mb_array, &block_array) == XvMCBadContext);
+ /* Test NULL surface */
+ assert(XvMCRenderSurface(display, &context, XVMC_FRAME_PICTURE, NULL, NULL, NULL, 0, NUM_MACROBLOCKS, 0, &mb_array, &block_array) == XvMCBadSurface);
+ /* Test bad picture structure */
+ assert(XvMCRenderSurface(display, &context, 0, &surface, NULL, NULL, 0, NUM_MACROBLOCKS, 0, &mb_array, &block_array) == BadValue);
+ /* Test valid params */
+ assert(XvMCRenderSurface(display, &context, XVMC_FRAME_PICTURE, &surface, NULL, NULL, 0, NUM_MACROBLOCKS, 0, &mb_array, &block_array) == Success);
+
+ /* Test NULL surface */
+ assert(XvMCPutSurface(display, NULL, window, 0, 0, INPUT_WIDTH, INPUT_HEIGHT, 0, 0, output_width, output_height, XVMC_FRAME_PICTURE) == XvMCBadSurface);
+ /* Test bad window */
+ /* XXX: X halts with a bad drawable for some reason, doesn't return BadDrawable as expected */
+ /*assert(XvMCPutSurface(display, &surface, 0, 0, 0, width, height, 0, 0, width, height, XVMC_FRAME_PICTURE) == BadDrawable);*/
+
+ if (prompt)
+ {
+ puts("Press any button to quit...");
+
+ while (!quit)
+ {
+ if (XPending(display) > 0)
+ {
+ XEvent event;
+
+ XNextEvent(display, &event);
+
+ switch (event.type)
+ {
+ case Expose:
+ {
+ /* Test valid params */
+ assert
+ (
+ XvMCPutSurface
+ (
+ display, &surface, window,
+ 0, 0, INPUT_WIDTH, INPUT_HEIGHT,
+ 0, 0, output_width, output_height,
+ XVMC_FRAME_PICTURE
+ ) == Success
+ );
+ break;
+ }
+ case KeyPress:
+ {
+ quit = 1;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ assert(XvMCDestroyBlocks(display, &block_array) == Success);
+ assert(XvMCDestroyMacroBlocks(display, &mb_array) == Success);
+ assert(XvMCDestroySurface(display, &surface) == Success);
+ assert(XvMCDestroyContext(display, &context) == Success);
+
+ XvUngrabPort(display, port_num, CurrentTime);
+ XDestroyWindow(display, window);
+ XCloseDisplay(display);
+
+ return 0;
+}
diff --git a/src/gallium/state_trackers/xorg/xvmc/tests/test_subpicture.c b/src/gallium/state_trackers/xorg/xvmc/tests/test_subpicture.c
new file mode 100644
index 00000000000..20d0907a07f
--- /dev/null
+++ b/src/gallium/state_trackers/xorg/xvmc/tests/test_subpicture.c
@@ -0,0 +1,182 @@
+/**************************************************************************
+ *
+ * Copyright 2009 Younes Manton.
+ * 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 TUNGSTEN GRAPHICS 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.
+ *
+ **************************************************************************/
+
+#include <assert.h>
+#include <error.h>
+#include <stdio.h>
+#include "testlib.h"
+
+static void PrintGUID(const char *guid)
+{
+ int i;
+ printf("\tguid: ");
+ for (i = 0; i < 4; ++i)
+ printf("%C,", guid[i] == 0 ? '0' : guid[i]);
+ for (; i < 15; ++i)
+ printf("%x,", (unsigned char)guid[i]);
+ printf("%x\n", (unsigned int)guid[15]);
+}
+
+static void PrintComponentOrder(const char *co)
+{
+ int i;
+ printf("\tcomponent_order:\n\t ");
+ for (i = 0; i < 4; ++i)
+ printf("%C,", co[i] == 0 ? '0' : co[i]);
+ for (; i < 31; ++i)
+ printf("%x,", (unsigned int)co[i]);
+ printf("%x\n", (unsigned int)co[31]);
+}
+
+int main(int argc, char **argv)
+{
+ const unsigned int width = 16, height = 16;
+ const unsigned int mc_types[2] = {XVMC_MOCOMP | XVMC_MPEG_2, XVMC_IDCT | XVMC_MPEG_2};
+ const unsigned int subpic_width = 16, subpic_height = 16;
+
+ Display *display;
+ XvPortID port_num;
+ int surface_type_id;
+ unsigned int is_overlay, intra_unsigned;
+ int colorkey;
+ XvMCContext context;
+ XvImageFormatValues *subpics;
+ int num_subpics;
+ XvMCSubpicture subpicture = {0};
+ int i;
+
+ display = XOpenDisplay(NULL);
+
+ if (!GetPort
+ (
+ display,
+ width,
+ height,
+ XVMC_CHROMA_FORMAT_420,
+ mc_types,
+ 2,
+ &port_num,
+ &surface_type_id,
+ &is_overlay,
+ &intra_unsigned
+ ))
+ {
+ XCloseDisplay(display);
+ error(1, 0, "Error, unable to find a good port.\n");
+ }
+
+ if (is_overlay)
+ {
+ Atom xv_colorkey = XInternAtom(display, "XV_COLORKEY", 0);
+ XvGetPortAttribute(display, port_num, xv_colorkey, &colorkey);
+ }
+
+ assert(XvMCCreateContext(display, port_num, surface_type_id, width, height, XVMC_DIRECT, &context) == Success);
+
+ subpics = XvMCListSubpictureTypes(display, port_num, surface_type_id, &num_subpics);
+ assert((subpics && num_subpics) > 0 || (!subpics && num_subpics == 0));
+
+ for (i = 0; i < num_subpics; ++i)
+ {
+ printf("Subpicture %d:\n", i);
+ printf("\tid: 0x%08x\n", subpics[i].id);
+ printf("\ttype: %s\n", subpics[i].type == XvRGB ? "XvRGB" : (subpics[i].type == XvYUV ? "XvYUV" : "Unknown"));
+ printf("\tbyte_order: %s\n", subpics[i].byte_order == LSBFirst ? "LSB First" : (subpics[i].byte_order == MSBFirst ? "MSB First" : "Unknown"));
+ PrintGUID(subpics[i].guid);
+ printf("\tbpp: %u\n", subpics[i].bits_per_pixel);
+ printf("\tformat: %s\n", subpics[i].format == XvPacked ? "XvPacked" : (subpics[i].format == XvPlanar ? "XvPlanar" : "Unknown"));
+ printf("\tnum_planes: %u\n", subpics[i].num_planes);
+
+ if (subpics[i].type == XvRGB)
+ {
+ printf("\tdepth: %u\n", subpics[i].depth);
+ printf("\tred_mask: 0x%08x\n", subpics[i].red_mask);
+ printf("\tgreen_mask: 0x%08x\n", subpics[i].green_mask);
+ printf("\tblue_mask: 0x%08x\n", subpics[i].blue_mask);
+ }
+ else if (subpics[i].type == XvYUV)
+ {
+ printf("\ty_sample_bits: %u\n", subpics[i].y_sample_bits);
+ printf("\tu_sample_bits: %u\n", subpics[i].u_sample_bits);
+ printf("\tv_sample_bits: %u\n", subpics[i].v_sample_bits);
+ printf("\thorz_y_period: %u\n", subpics[i].horz_y_period);
+ printf("\thorz_u_period: %u\n", subpics[i].horz_u_period);
+ printf("\thorz_v_period: %u\n", subpics[i].horz_v_period);
+ printf("\tvert_y_period: %u\n", subpics[i].vert_y_period);
+ printf("\tvert_u_period: %u\n", subpics[i].vert_u_period);
+ printf("\tvert_v_period: %u\n", subpics[i].vert_v_period);
+ }
+ PrintComponentOrder(subpics[i].component_order);
+ printf("\tscanline_order: %s\n", subpics[i].scanline_order == XvTopToBottom ? "XvTopToBottom" : (subpics[i].scanline_order == XvBottomToTop ? "XvBottomToTop" : "Unknown"));
+ }
+
+ if (num_subpics == 0)
+ {
+ printf("Subpictures not supported, nothing to test.\n");
+ return 0;
+ }
+
+ /* Test NULL context */
+ assert(XvMCCreateSubpicture(display, NULL, &subpicture, subpic_width, subpic_height, subpics[0].id) == XvMCBadContext);
+ /* Test NULL subpicture */
+ assert(XvMCCreateSubpicture(display, &context, NULL, subpic_width, subpic_height, subpics[0].id) == XvMCBadSubpicture);
+ /* Test invalid subpicture */
+ assert(XvMCCreateSubpicture(display, &context, &subpicture, subpic_width, subpic_height, -1) == BadMatch);
+ /* Test huge width */
+ assert(XvMCCreateSubpicture(display, &context, &subpicture, 16384, subpic_height, subpics[0].id) == BadValue);
+ /* Test huge height */
+ assert(XvMCCreateSubpicture(display, &context, &subpicture, subpic_width, 16384, subpics[0].id) == BadValue);
+ /* Test huge width & height */
+ assert(XvMCCreateSubpicture(display, &context, &subpicture, 16384, 16384, subpics[0].id) == BadValue);
+ for (i = 0; i < num_subpics; ++i)
+ {
+ /* Test valid params */
+ assert(XvMCCreateSubpicture(display, &context, &subpicture, subpic_width, subpic_height, subpics[i].id) == Success);
+ /* Test subpicture id assigned */
+ assert(subpicture.subpicture_id != 0);
+ /* Test context id assigned and correct */
+ assert(subpicture.context_id == context.context_id);
+ /* Test subpicture type id assigned and correct */
+ assert(subpicture.xvimage_id == subpics[i].id);
+ /* Test width & height assigned and correct */
+ assert(subpicture.width == width && subpicture.height == height);
+ /* Test no palette support */
+ assert(subpicture.num_palette_entries == 0 && subpicture.entry_bytes == 0);
+ /* Test valid params */
+ assert(XvMCDestroySubpicture(display, &subpicture) == Success);
+ }
+ /* Test NULL surface */
+ assert(XvMCDestroySubpicture(display, NULL) == XvMCBadSubpicture);
+
+ assert(XvMCDestroyContext(display, &context) == Success);
+
+ XFree(subpics);
+ XvUngrabPort(display, port_num, CurrentTime);
+ XCloseDisplay(display);
+
+ return 0;
+}
diff --git a/src/gallium/state_trackers/xorg/xvmc/tests/test_surface.c b/src/gallium/state_trackers/xorg/xvmc/tests/test_surface.c
new file mode 100644
index 00000000000..b65eb265c0a
--- /dev/null
+++ b/src/gallium/state_trackers/xorg/xvmc/tests/test_surface.c
@@ -0,0 +1,98 @@
+/**************************************************************************
+ *
+ * Copyright 2009 Younes Manton.
+ * 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 TUNGSTEN GRAPHICS 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.
+ *
+ **************************************************************************/
+
+#include <assert.h>
+#include <error.h>
+#include "testlib.h"
+
+int main(int argc, char **argv)
+{
+ const unsigned int width = 16, height = 16;
+ const unsigned int mc_types[2] = {XVMC_MOCOMP | XVMC_MPEG_2, XVMC_IDCT | XVMC_MPEG_2};
+
+ Display *display;
+ XvPortID port_num;
+ int surface_type_id;
+ unsigned int is_overlay, intra_unsigned;
+ int colorkey;
+ XvMCContext context;
+ XvMCSurface surface = {0};
+
+ display = XOpenDisplay(NULL);
+
+ if (!GetPort
+ (
+ display,
+ width,
+ height,
+ XVMC_CHROMA_FORMAT_420,
+ mc_types,
+ 2,
+ &port_num,
+ &surface_type_id,
+ &is_overlay,
+ &intra_unsigned
+ ))
+ {
+ XCloseDisplay(display);
+ error(1, 0, "Error, unable to find a good port.\n");
+ }
+
+ if (is_overlay)
+ {
+ Atom xv_colorkey = XInternAtom(display, "XV_COLORKEY", 0);
+ XvGetPortAttribute(display, port_num, xv_colorkey, &colorkey);
+ }
+
+ assert(XvMCCreateContext(display, port_num, surface_type_id, width, height, XVMC_DIRECT, &context) == Success);
+
+ /* Test NULL context */
+ assert(XvMCCreateSurface(display, NULL, &surface) == XvMCBadContext);
+ /* Test NULL surface */
+ assert(XvMCCreateSurface(display, &context, NULL) == XvMCBadSurface);
+ /* Test valid params */
+ assert(XvMCCreateSurface(display, &context, &surface) == Success);
+ /* Test surface id assigned */
+ assert(surface.surface_id != 0);
+ /* Test context id assigned and correct */
+ assert(surface.context_id == context.context_id);
+ /* Test surface type id assigned and correct */
+ assert(surface.surface_type_id == surface_type_id);
+ /* Test width & height assigned and correct */
+ assert(surface.width == width && surface.height == height);
+ /* Test valid params */
+ assert(XvMCDestroySurface(display, &surface) == Success);
+ /* Test NULL surface */
+ assert(XvMCDestroySurface(display, NULL) == XvMCBadSurface);
+
+ assert(XvMCDestroyContext(display, &context) == Success);
+
+ XvUngrabPort(display, port_num, CurrentTime);
+ XCloseDisplay(display);
+
+ return 0;
+}
diff --git a/src/gallium/state_trackers/xorg/xvmc/tests/testlib.c b/src/gallium/state_trackers/xorg/xvmc/tests/testlib.c
new file mode 100644
index 00000000000..142c09bb590
--- /dev/null
+++ b/src/gallium/state_trackers/xorg/xvmc/tests/testlib.c
@@ -0,0 +1,146 @@
+/**************************************************************************
+ *
+ * Copyright 2009 Younes Manton.
+ * 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 TUNGSTEN GRAPHICS 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.
+ *
+ **************************************************************************/
+
+#include "testlib.h"
+#include <stdio.h>
+
+/*
+void test(int pred, const char *pred_string, const char *doc_string, const char *file, unsigned int line)
+{
+ fputs(doc_string, stderr);
+ if (!pred)
+ fprintf(stderr, " FAIL!\n\t\"%s\" at %s:%u\n", pred_string, file, line);
+ else
+ fputs(" PASS!\n", stderr);
+}
+*/
+
+int GetPort
+(
+ Display *display,
+ unsigned int width,
+ unsigned int height,
+ unsigned int chroma_format,
+ const unsigned int *mc_types,
+ unsigned int num_mc_types,
+ XvPortID *port_id,
+ int *surface_type_id,
+ unsigned int *is_overlay,
+ unsigned int *intra_unsigned
+)
+{
+ unsigned int found_port = 0;
+ XvAdaptorInfo *adaptor_info;
+ unsigned int num_adaptors;
+ int num_types;
+ int ev_base, err_base;
+ unsigned int i, j, k, l;
+
+ if (!XvMCQueryExtension(display, &ev_base, &err_base))
+ return 0;
+ if (XvQueryAdaptors(display, XDefaultRootWindow(display), &num_adaptors, &adaptor_info) != Success)
+ return 0;
+
+ for (i = 0; i < num_adaptors && !found_port; ++i)
+ {
+ if (adaptor_info[i].type & XvImageMask)
+ {
+ XvMCSurfaceInfo *surface_info = XvMCListSurfaceTypes(display, adaptor_info[i].base_id, &num_types);
+
+ if (surface_info)
+ {
+ for (j = 0; j < num_types && !found_port; ++j)
+ {
+ if
+ (
+ surface_info[j].chroma_format == chroma_format &&
+ surface_info[j].max_width >= width &&
+ surface_info[j].max_height >= height
+ )
+ {
+ for (k = 0; k < num_mc_types && !found_port; ++k)
+ {
+ if (surface_info[j].mc_type == mc_types[k])
+ {
+ for (l = 0; l < adaptor_info[i].num_ports && !found_port; ++l)
+ {
+ if (XvGrabPort(display, adaptor_info[i].base_id + l, CurrentTime) == Success)
+ {
+ *port_id = adaptor_info[i].base_id + l;
+ *surface_type_id = surface_info[j].surface_type_id;
+ *is_overlay = surface_info[j].flags & XVMC_OVERLAID_SURFACE;
+ *intra_unsigned = surface_info[j].flags & XVMC_INTRA_UNSIGNED;
+ found_port = 1;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ XFree(surface_info);
+ }
+ }
+ }
+
+ XvFreeAdaptorInfo(adaptor_info);
+
+ return found_port;
+}
+
+unsigned int align(unsigned int value, unsigned int alignment)
+{
+ return (value + alignment - 1) & ~(alignment - 1);
+}
+
+/* From the glibc manual */
+int timeval_subtract(struct timeval *result, struct timeval *x, struct timeval *y)
+{
+ /* Perform the carry for the later subtraction by updating y. */
+ if (x->tv_usec < y->tv_usec)
+ {
+ int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1;
+ y->tv_usec -= 1000000 * nsec;
+ y->tv_sec += nsec;
+ }
+ if (x->tv_usec - y->tv_usec > 1000000)
+ {
+ int nsec = (x->tv_usec - y->tv_usec) / 1000000;
+ y->tv_usec += 1000000 * nsec;
+ y->tv_sec -= nsec;
+ }
+
+ /*
+ * Compute the time remaining to wait.
+ * tv_usec is certainly positive.
+ */
+ result->tv_sec = x->tv_sec - y->tv_sec;
+ result->tv_usec = x->tv_usec - y->tv_usec;
+
+ /* Return 1 if result is negative. */
+ return x->tv_sec < y->tv_sec;
+}
diff --git a/src/gallium/state_trackers/xorg/xvmc/tests/testlib.h b/src/gallium/state_trackers/xorg/xvmc/tests/testlib.h
new file mode 100644
index 00000000000..0438e52928b
--- /dev/null
+++ b/src/gallium/state_trackers/xorg/xvmc/tests/testlib.h
@@ -0,0 +1,69 @@
+/**************************************************************************
+ *
+ * Copyright 2009 Younes Manton.
+ * 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 TUNGSTEN GRAPHICS 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 testlib_h
+#define testlib_h
+
+/*
+#define TEST(pred, doc) test(pred, #pred, doc, __FILE__, __LINE__)
+
+void test(int pred, const char *pred_string, const char *doc_string, const char *file, unsigned int line);
+*/
+
+#include <sys/time.h>
+#include <X11/Xlib.h>
+#include <X11/extensions/XvMClib.h>
+
+/*
+ * display: IN A valid X display
+ * width, height: IN Surface size that the port must display
+ * chroma_format: IN Chroma format that the port must display
+ * mc_types, num_mc_types: IN List of MC types that the port must support, first port that matches the first mc_type will be returned
+ * port_id: OUT Your port's ID
+ * surface_type_id: OUT Your port's surface ID
+ * is_overlay: OUT If 1, port uses overlay surfaces, you need to set a colorkey
+ * intra_unsigned: OUT If 1, port uses unsigned values for intra-coded blocks
+ */
+int GetPort
+(
+ Display *display,
+ unsigned int width,
+ unsigned int height,
+ unsigned int chroma_format,
+ const unsigned int *mc_types,
+ unsigned int num_mc_types,
+ XvPortID *port_id,
+ int *surface_type_id,
+ unsigned int *is_overlay,
+ unsigned int *intra_unsigned
+);
+
+unsigned int align(unsigned int value, unsigned int alignment);
+
+int timeval_subtract(struct timeval *result, struct timeval *x, struct timeval *y);
+
+#endif
diff --git a/src/gallium/state_trackers/xorg/xvmc/tests/xvmc_bench.c b/src/gallium/state_trackers/xorg/xvmc/tests/xvmc_bench.c
new file mode 100644
index 00000000000..bf94d856234
--- /dev/null
+++ b/src/gallium/state_trackers/xorg/xvmc/tests/xvmc_bench.c
@@ -0,0 +1,300 @@
+/**************************************************************************
+ *
+ * Copyright 2009 Younes Manton.
+ * 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 TUNGSTEN GRAPHICS 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.
+ *
+ **************************************************************************/
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include <error.h>
+#include <sys/time.h>
+#include "testlib.h"
+
+#define MACROBLOCK_WIDTH 16
+#define MACROBLOCK_HEIGHT 16
+#define BLOCKS_PER_MACROBLOCK 6
+
+#define DEFAULT_INPUT_WIDTH 720
+#define DEFAULT_INPUT_HEIGHT 480
+#define DEFAULT_REPS 100
+
+#define PIPELINE_STEP_MC 1
+#define PIPELINE_STEP_CSC 2
+#define PIPELINE_STEP_SWAP 4
+
+#define MB_TYPE_I 1
+#define MB_TYPE_P 2
+#define MB_TYPE_B 4
+
+struct Config
+{
+ unsigned int input_width;
+ unsigned int input_height;
+ unsigned int output_width;
+ unsigned int output_height;
+ unsigned int pipeline;
+ unsigned int mb_types;
+ unsigned int reps;
+};
+
+void ParseArgs(int argc, char **argv, struct Config *config);
+
+void ParseArgs(int argc, char **argv, struct Config *config)
+{
+ int fail = 0;
+ int i;
+
+ config->input_width = DEFAULT_INPUT_WIDTH;
+ config->input_height = DEFAULT_INPUT_HEIGHT;
+ config->output_width = 0;
+ config->output_height = 0;
+ config->pipeline = 0;
+ config->mb_types = 0;
+ config->reps = DEFAULT_REPS;
+
+ for (i = 1; i < argc && !fail; ++i)
+ {
+ if (!strcmp(argv[i], "-iw"))
+ {
+ if (sscanf(argv[++i], "%u", &config->input_width) != 1)
+ fail = 1;
+ }
+ else if (!strcmp(argv[i], "-ih"))
+ {
+ if (sscanf(argv[++i], "%u", &config->input_height) != 1)
+ fail = 1;
+ }
+ else if (!strcmp(argv[i], "-ow"))
+ {
+ if (sscanf(argv[++i], "%u", &config->output_width) != 1)
+ fail = 1;
+ }
+ else if (!strcmp(argv[i], "-oh"))
+ {
+ if (sscanf(argv[++i], "%u", &config->output_height) != 1)
+ fail = 1;
+ }
+ else if (!strcmp(argv[i], "-p"))
+ {
+ char *token = strtok(argv[++i], ",");
+
+ while (token && !fail)
+ {
+ if (!strcmp(token, "mc"))
+ config->pipeline |= PIPELINE_STEP_MC;
+ else if (!strcmp(token, "csc"))
+ config->pipeline |= PIPELINE_STEP_CSC;
+ else if (!strcmp(token, "swp"))
+ config->pipeline |= PIPELINE_STEP_SWAP;
+ else
+ fail = 1;
+
+ if (!fail)
+ token = strtok(NULL, ",");
+ }
+ }
+ else if (!strcmp(argv[i], "-mb"))
+ {
+ char *token = strtok(argv[++i], ",");
+
+ while (token && !fail)
+ {
+ if (strcmp(token, "i"))
+ config->mb_types |= MB_TYPE_I;
+ else if (strcmp(token, "p"))
+ config->mb_types |= MB_TYPE_P;
+ else if (strcmp(token, "b"))
+ config->mb_types |= MB_TYPE_B;
+ else
+ fail = 1;
+
+ if (!fail)
+ token = strtok(NULL, ",");
+ }
+ }
+ else if (!strcmp(argv[i], "-r"))
+ {
+ if (sscanf(argv[++i], "%u", &config->reps) != 1)
+ fail = 1;
+ }
+ else
+ fail = 1;
+ }
+
+ if (fail)
+ error
+ (
+ 1, 0,
+ "Bad argument.\n"
+ "\n"
+ "Usage: %s [options]\n"
+ "\t-iw <width>\tInput width\n"
+ "\t-ih <height>\tInput height\n"
+ "\t-ow <width>\tOutput width\n"
+ "\t-oh <height>\tOutput height\n"
+ "\t-p <pipeline>\tPipeline to test\n"
+ "\t-mb <mb type>\tMacroBlock types to use\n"
+ "\t-r <reps>\tRepetitions\n\n"
+ "\tPipeline steps: mc,csc,swap\n"
+ "\tMB types: i,p,b\n",
+ argv[0]
+ );
+
+ if (config->output_width == 0)
+ config->output_width = config->input_width;
+ if (config->output_height == 0)
+ config->output_height = config->input_height;
+ if (!config->pipeline)
+ config->pipeline = PIPELINE_STEP_MC | PIPELINE_STEP_CSC | PIPELINE_STEP_SWAP;
+ if (!config->mb_types)
+ config->mb_types = MB_TYPE_I | MB_TYPE_P | MB_TYPE_B;
+}
+
+int main(int argc, char **argv)
+{
+ struct Config config;
+ Display *display;
+ Window root, window;
+ const unsigned int mc_types[2] = {XVMC_MOCOMP | XVMC_MPEG_2, XVMC_IDCT | XVMC_MPEG_2};
+ XvPortID port_num;
+ int surface_type_id;
+ unsigned int is_overlay, intra_unsigned;
+ int colorkey;
+ XvMCContext context;
+ XvMCSurface surface;
+ XvMCBlockArray block_array;
+ XvMCMacroBlockArray mb_array;
+ unsigned int mbw, mbh;
+ unsigned int mbx, mby;
+ unsigned int reps;
+ struct timeval start, stop, diff;
+ double diff_secs;
+
+ ParseArgs(argc, argv, &config);
+
+ mbw = align(config.input_width, MACROBLOCK_WIDTH) / MACROBLOCK_WIDTH;
+ mbh = align(config.input_height, MACROBLOCK_HEIGHT) / MACROBLOCK_HEIGHT;
+
+ display = XOpenDisplay(NULL);
+
+ if (!GetPort
+ (
+ display,
+ config.input_width,
+ config.input_height,
+ XVMC_CHROMA_FORMAT_420,
+ mc_types,
+ 2,
+ &port_num,
+ &surface_type_id,
+ &is_overlay,
+ &intra_unsigned
+ ))
+ {
+ XCloseDisplay(display);
+ error(1, 0, "Error, unable to find a good port.\n");
+ }
+
+ if (is_overlay)
+ {
+ Atom xv_colorkey = XInternAtom(display, "XV_COLORKEY", 0);
+ XvGetPortAttribute(display, port_num, xv_colorkey, &colorkey);
+ }
+
+ root = XDefaultRootWindow(display);
+ window = XCreateSimpleWindow(display, root, 0, 0, config.output_width, config.output_height, 0, 0, colorkey);
+
+ assert(XvMCCreateContext(display, port_num, surface_type_id, config.input_width, config.input_height, XVMC_DIRECT, &context) == Success);
+ assert(XvMCCreateSurface(display, &context, &surface) == Success);
+ assert(XvMCCreateBlocks(display, &context, mbw * mbh * BLOCKS_PER_MACROBLOCK, &block_array) == Success);
+ assert(XvMCCreateMacroBlocks(display, &context, mbw * mbh, &mb_array) == Success);
+
+ for (mby = 0; mby < mbh; ++mby)
+ for (mbx = 0; mbx < mbw; ++mbx)
+ {
+ mb_array.macro_blocks[mby * mbw + mbx].x = mbx;
+ mb_array.macro_blocks[mby * mbw + mbx].y = mby;
+ mb_array.macro_blocks[mby * mbw + mbx].macroblock_type = XVMC_MB_TYPE_INTRA;
+ /*mb->motion_type = ;*/
+ /*mb->motion_vertical_field_select = ;*/
+ mb_array.macro_blocks[mby * mbw + mbx].dct_type = XVMC_DCT_TYPE_FRAME;
+ /*mb->PMV[0][0][0] = ;
+ mb->PMV[0][0][1] = ;
+ mb->PMV[0][1][0] = ;
+ mb->PMV[0][1][1] = ;
+ mb->PMV[1][0][0] = ;
+ mb->PMV[1][0][1] = ;
+ mb->PMV[1][1][0] = ;
+ mb->PMV[1][1][1] = ;*/
+ mb_array.macro_blocks[mby * mbw + mbx].index = (mby * mbw + mbx) * BLOCKS_PER_MACROBLOCK;
+ mb_array.macro_blocks[mby * mbw + mbx].coded_block_pattern = 0x3F;
+ }
+
+ XSelectInput(display, window, ExposureMask | KeyPressMask);
+ XMapWindow(display, window);
+ XSync(display, 0);
+
+ gettimeofday(&start, NULL);
+
+ for (reps = 0; reps < config.reps; ++reps)
+ {
+ if (config.pipeline & PIPELINE_STEP_MC)
+ {
+ assert(XvMCRenderSurface(display, &context, XVMC_FRAME_PICTURE, &surface, NULL, NULL, 0, mbw * mbh, 0, &mb_array, &block_array) == Success);
+ assert(XvMCFlushSurface(display, &surface) == Success);
+ }
+ if (config.pipeline & PIPELINE_STEP_CSC)
+ assert(XvMCPutSurface(display, &surface, window, 0, 0, config.input_width, config.input_height, 0, 0, config.output_width, config.output_height, XVMC_FRAME_PICTURE) == Success);
+ }
+
+ gettimeofday(&stop, NULL);
+
+ timeval_subtract(&diff, &stop, &start);
+ diff_secs = (double)diff.tv_sec + (double)diff.tv_usec / 1000000.0;
+
+ printf("XvMC Benchmark\n");
+ printf("Input: %u,%u\nOutput: %u,%u\n", config.input_width, config.input_height, config.output_width, config.output_height);
+ printf("Pipeline: ");
+ if (config.pipeline & PIPELINE_STEP_MC)
+ printf("|mc|");
+ if (config.pipeline & PIPELINE_STEP_CSC)
+ printf("|csc|");
+ if (config.pipeline & PIPELINE_STEP_SWAP)
+ printf("|swap|");
+ printf("\n");
+ printf("Reps: %u\n", config.reps);
+ printf("Total time: %.2lf (%.2lf reps / sec)\n", diff_secs, config.reps / diff_secs);
+
+ assert(XvMCDestroyBlocks(display, &block_array) == Success);
+ assert(XvMCDestroyMacroBlocks(display, &mb_array) == Success);
+ assert(XvMCDestroySurface(display, &surface) == Success);
+ assert(XvMCDestroyContext(display, &context) == Success);
+
+ XvUngrabPort(display, port_num, CurrentTime);
+ XDestroyWindow(display, window);
+ XCloseDisplay(display);
+
+ return 0;
+}
diff --git a/src/gallium/state_trackers/xorg/xvmc/xvmc_private.h b/src/gallium/state_trackers/xorg/xvmc/xvmc_private.h
new file mode 100644
index 00000000000..1e2dfb4223a
--- /dev/null
+++ b/src/gallium/state_trackers/xorg/xvmc/xvmc_private.h
@@ -0,0 +1,102 @@
+/**************************************************************************
+ *
+ * Copyright 2009 Younes Manton.
+ * 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 TUNGSTEN GRAPHICS 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 xvmc_private_h
+#define xvmc_private_h
+
+#include <X11/Xlib.h>
+#include <X11/extensions/XvMClib.h>
+#include <util/u_debug.h>
+
+#define BLOCK_SIZE_SAMPLES 64
+#define BLOCK_SIZE_BYTES (BLOCK_SIZE_SAMPLES * 2)
+
+struct vl_context;
+struct pipe_surface;
+struct pipe_fence_handle;
+
+typedef struct
+{
+ struct vl_context *vctx;
+ struct pipe_surface *backbuffer;
+ unsigned short subpicture_max_width;
+ unsigned short subpicture_max_height;
+} XvMCContextPrivate;
+
+typedef struct
+{
+ struct pipe_surface *pipe_vsfc;
+ struct pipe_fence_handle *render_fence;
+ struct pipe_fence_handle *disp_fence;
+
+ /* The subpicture associated with this surface, if any. */
+ XvMCSubpicture *subpicture;
+ short subx, suby;
+ unsigned short subw, subh;
+ short surfx, surfy;
+ unsigned short surfw, surfh;
+
+ /* Some XvMC functions take a surface but not a context,
+ so we keep track of which context each surface belongs to. */
+ XvMCContext *context;
+} XvMCSurfacePrivate;
+
+typedef struct
+{
+ struct pipe_surface *sfc;
+
+ /* The surface this subpicture is currently associated with, if any. */
+ XvMCSurface *surface;
+
+ /* Some XvMC functions take a subpicture but not a context,
+ so we keep track of which context each subpicture belongs to. */
+ XvMCContext *context;
+} XvMCSubpicturePrivate;
+
+#define XVMC_OUT 0
+#define XVMC_ERR 1
+#define XVMC_WARN 2
+#define XVMC_TRACE 3
+static INLINE void XVMC_MSG(unsigned int level, const char *fmt, ...)
+{
+ static boolean check_dbg_level = TRUE;
+ static unsigned int debug_level;
+
+ if (check_dbg_level) {
+ debug_level = debug_get_num_option("XVMC_DEBUG", 0);
+ check_dbg_level = FALSE;
+ }
+
+ if (level <= debug_level) {
+ va_list ap;
+ va_start(ap, fmt);
+ _debug_vprintf(fmt, ap);
+ va_end(ap);
+ }
+}
+
+#endif /* xvmc_private_h */
diff --git a/src/gallium/targets/Makefile.vdpau b/src/gallium/targets/Makefile.vdpau
new file mode 100644
index 00000000000..2accbeb702e
--- /dev/null
+++ b/src/gallium/targets/Makefile.vdpau
@@ -0,0 +1,62 @@
+# This makefile template is used to build libvdpau_g3dvl.so
+
+LIBBASENAME = vdpau_g3dvl
+LIBNAME = lib$(LIBBASENAME).so
+VDPAU_LIB_GLOB=lib$(LIBBASENAME).*so*
+VDPAU_MAJOR = 1
+VDPAU_MINOR = 0
+INCLUDES = -I$(TOP)/src/gallium/include \
+ -I$(TOP)/src/gallium/drivers \
+ -I$(TOP)/src/gallium/auxiliary \
+ -I$(TOP)/src/gallium/winsys/g3dvl \
+ $(DRIVER_INCLUDES)
+DEFINES = -DGALLIUM_TRACE -DVER_MAJOR=$(VDPAU_MAJOR) -DVER_MINOR=$(VDPAU_MINOR) $(DRIVER_DEFINES)
+LIBS = $(EXTRA_LIB_PATH) $(DRIVER_LIBS) -lvdpau -lXext -lX11 -lm
+STATE_TRACKER_LIB = $(TOP)/src/gallium/state_trackers/vdpau/libvdpautracker.a
+
+# XXX: Hack, VDPAU public funcs aren't exported if we link to libvdpautracker.a :(
+OBJECTS = $(C_SOURCES:.c=.o) \
+ $(ASM_SOURCES:.S=.o) \
+ $(TOP)/src/gallium/state_trackers/vdpau/*.o
+
+##### RULES #####
+
+.c.o:
+ $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
+
+.S.o:
+ $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
+
+##### TARGETS #####
+
+default: depend symlinks $(TOP)/$(LIB_DIR)/gallium/$(LIBNAME)
+
+$(TOP)/$(LIB_DIR)/gallium/$(LIBNAME): $(OBJECTS) $(PIPE_DRIVERS) $(STATE_TRACKER_LIB) $(TOP)/$(LIB_DIR)/gallium Makefile
+ $(MKLIB) -o $(LIBBASENAME) -linker '$(CC)' -ldflags '$(LDFLAGS)' \
+ -major $(VDPAU_MAJOR) -minor $(VDPAU_MINOR) $(MKLIB_OPTIONS) \
+ -install $(TOP)/$(LIB_DIR)/gallium \
+ $(OBJECTS) $(STATE_TRACKER_LIB) $(PIPE_DRIVERS) $(LIBS)
+
+$(TOP)/$(LIB_DIR)/gallium:
+ mkdir -p $@
+
+depend: $(C_SOURCES) $(ASM_SOURCES) $(SYMLINKS)
+ rm -f depend
+ touch depend
+ $(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDES) $(C_SOURCES) \
+ $(ASM_SOURCES) 2> /dev/null
+
+# Emacs tags
+tags:
+ etags `find . -name \*.[ch]` `find ../include`
+
+# Remove .o and backup files
+clean:
+ -rm -f *.o *~ *.so $(SYMLINKS)
+ -rm -f depend depend.bak
+
+install: default
+ $(INSTALL) -d $(DESTDIR)$(VDPAU_LIB_INSTALL_DIR)
+ $(MINSTALL) -m 755 $(TOP)/$(LIB_DIR)/gallium/$(VDPAU_LIB_GLOB) $(DESTDIR)$(VDPAU_LIB_INSTALL_DIR)
+
+include depend
diff --git a/src/gallium/targets/Makefile.xvmc b/src/gallium/targets/Makefile.xvmc
new file mode 100644
index 00000000000..e48906a1345
--- /dev/null
+++ b/src/gallium/targets/Makefile.xvmc
@@ -0,0 +1,61 @@
+# This makefile template is used to build libXvMCg3dvl.so
+
+LIBBASENAME = XvMCg3dvl
+LIBNAME = lib$(LIBBASENAME).so
+XVMC_MAJOR = 1
+XVMC_MINOR = 0
+INCLUDES = -I$(TOP)/src/gallium/include \
+ -I$(TOP)/src/gallium/drivers \
+ -I$(TOP)/src/gallium/auxiliary \
+ -I$(TOP)/src/gallium/winsys/g3dvl \
+ $(DRIVER_INCLUDES)
+DEFINES = -DGALLIUM_TRACE $(DRIVER_DEFINES)
+LIBS = $(EXTRA_LIB_PATH) $(DRIVER_LIBS) -lXvMC -lXv -lX11 -lm
+STATE_TRACKER_LIB = $(TOP)/src/gallium/state_trackers/xorg/xvmc/libxvmctracker.a
+
+# XXX: Hack, XvMC public funcs aren't exported if we link to libxvmctracker.a :(
+OBJECTS = $(C_SOURCES:.c=.o) \
+ $(ASM_SOURCES:.S=.o) \
+ $(TOP)/src/gallium/state_trackers/xorg/xvmc/*.o
+
+##### RULES #####
+
+.c.o:
+ $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
+
+.S.o:
+ $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
+
+##### TARGETS #####
+
+default: depend symlinks $(TOP)/$(LIB_DIR)/gallium/$(LIBNAME)
+
+$(TOP)/$(LIB_DIR)/gallium/$(LIBNAME): $(OBJECTS) $(PIPE_DRIVERS) $(STATE_TRACKER_LIB) $(TOP)/$(LIB_DIR)/gallium Makefile
+ $(MKLIB) -o $(LIBBASENAME) -linker '$(CC)' -ldflags '$(LDFLAGS)' \
+ -major $(XVMC_MAJOR) -minor $(XVMC_MINOR) $(MKLIB_OPTIONS) \
+ -install $(TOP)/$(LIB_DIR)/gallium \
+ $(OBJECTS) $(STATE_TRACKER_LIB) $(PIPE_DRIVERS) $(LIBS)
+
+$(TOP)/$(LIB_DIR)/gallium:
+ mkdir -p $@
+
+depend: $(C_SOURCES) $(ASM_SOURCES) $(SYMLINKS)
+ rm -f depend
+ touch depend
+ $(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDES) $(C_SOURCES) \
+ $(ASM_SOURCES) 2> /dev/null
+
+# Emacs tags
+tags:
+ etags `find . -name \*.[ch]` `find ../include`
+
+# Remove .o and backup files
+clean:
+ -rm -f *.o *~ *.so $(SYMLINKS)
+ -rm -f depend depend.bak
+
+#install: $(LIBNAME)
+# $(INSTALL) -d $(DESTDIR)$(DRI_DRIVER_INSTALL_DIR)
+# $(MINSTALL) -m 755 $(LIBNAME) $(DESTDIR)$(DRI_DRIVER_INSTALL_DIR)
+
+include depend
diff --git a/src/gallium/targets/dri-nouveau/Makefile b/src/gallium/targets/dri-nouveau/Makefile
index 2f64f312b84..9dfe86c8949 100644
--- a/src/gallium/targets/dri-nouveau/Makefile
+++ b/src/gallium/targets/dri-nouveau/Makefile
@@ -10,6 +10,7 @@ PIPE_DRIVERS = \
$(TOP)/src/gallium/drivers/rbug/librbug.a \
$(TOP)/src/gallium/drivers/nvfx/libnvfx.a \
$(TOP)/src/gallium/drivers/nv50/libnv50.a \
+ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
$(TOP)/src/gallium/drivers/nouveau/libnouveau.a
C_SOURCES = \
diff --git a/src/gallium/targets/vdpau-softpipe/Makefile b/src/gallium/targets/vdpau-softpipe/Makefile
new file mode 100644
index 00000000000..29dea50e7fb
--- /dev/null
+++ b/src/gallium/targets/vdpau-softpipe/Makefile
@@ -0,0 +1,19 @@
+TOP = ../../../..
+include $(TOP)/configs/current
+
+DRIVER_DEFINES = -DGALLIUM_SOFTPIPE
+DRIVER_INCLUDES =
+
+PIPE_DRIVERS = \
+ $(TOP)/src/gallium/winsys/sw/xlib/libws_xlib.a \
+ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
+ $(TOP)/src/gallium/auxiliary/libgallium.a
+
+C_SOURCES = \
+ $(TOP)/src/gallium/winsys/g3dvl/xlib/xsp_winsys.c
+
+DRIVER_LIBS =
+
+include ../Makefile.vdpau
+
+symlinks:
diff --git a/src/gallium/targets/xvmc-nouveau/Makefile b/src/gallium/targets/xvmc-nouveau/Makefile
new file mode 100644
index 00000000000..fe418b07681
--- /dev/null
+++ b/src/gallium/targets/xvmc-nouveau/Makefile
@@ -0,0 +1,23 @@
+TOP = ../../../..
+include $(TOP)/configs/current
+
+#LIBNAME =
+
+PIPE_DRIVERS = \
+ $(TOP)/src/gallium/winsys/g3dvl/dri/libvldri.a \
+ $(TOP)/src/gallium/winsys/nouveau/drm/libnouveaudrm.a \
+ $(TOP)/src/gallium/drivers/nvfx/libnvfx.a \
+ $(TOP)/src/gallium/drivers/nv50/libnv50.a \
+ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
+ $(TOP)/src/gallium/drivers/nouveau/libnouveau.a \
+ $(TOP)/src/gallium/auxiliary/libgallium.a
+
+C_SOURCES = \
+ $(COMMON_GALLIUM_SOURCES) \
+ $(DRIVER_SOURCES)
+
+DRIVER_LIBS = $(shell pkg-config libdrm_nouveau --libs) -lXfixes
+
+include ../Makefile.xvmc
+
+symlinks:
diff --git a/src/gallium/targets/xvmc-softpipe/Makefile b/src/gallium/targets/xvmc-softpipe/Makefile
new file mode 100644
index 00000000000..1e3ff8ac89c
--- /dev/null
+++ b/src/gallium/targets/xvmc-softpipe/Makefile
@@ -0,0 +1,19 @@
+TOP = ../../../..
+include $(TOP)/configs/current
+
+DRIVER_DEFINES = -DGALLIUM_SOFTPIPE
+DRIVER_INCLUDES =
+
+PIPE_DRIVERS = \
+ $(TOP)/src/gallium/winsys/sw/xlib/libws_xlib.a \
+ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
+ $(TOP)/src/gallium/auxiliary/libgallium.a
+
+C_SOURCES = \
+ $(TOP)/src/gallium/winsys/g3dvl/xlib/xsp_winsys.c
+
+DRIVER_LIBS =
+
+include ../Makefile.xvmc
+
+symlinks:
diff --git a/src/gallium/tests/python/retrace/README b/src/gallium/tests/python/retrace/README
deleted file mode 100644
index 822cd114044..00000000000
--- a/src/gallium/tests/python/retrace/README
+++ /dev/null
@@ -1,17 +0,0 @@
-This is an application written in python to replay the traces captured by the
- trace pipe driver.
-
-
-To use it follow the instructions in src/gallium/drivers/trace/README and
-src/gallium/state_trackers/python/README, and then do
-
- python src/gallium/state_trackers/python/samples/retrace/interpreter.py filename.trace
-
-
-This is still work in progress:
-- not everything is captured/replayed
- - surface/textures contents
-- any tiny error will result in a crash
-
---
-Jose Fonseca <[email protected]>
diff --git a/src/gallium/tests/python/retrace/format.py b/src/gallium/tests/python/retrace/format.py
deleted file mode 100755
index a4285bfe075..00000000000
--- a/src/gallium/tests/python/retrace/format.py
+++ /dev/null
@@ -1,173 +0,0 @@
-#!/usr/bin/env python
-##########################################################################
-#
-# Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
-# 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 TUNGSTEN GRAPHICS 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.
-#
-##########################################################################
-
-
-import sys
-
-
-class Formatter:
- '''Plain formatter'''
-
- def __init__(self, stream):
- self.stream = stream
-
- def text(self, text):
- self.stream.write(text)
-
- def newline(self):
- self.text('\n')
-
- def function(self, name):
- self.text(name)
-
- def variable(self, name):
- self.text(name)
-
- def literal(self, value):
- self.text(str(value))
-
- def address(self, addr):
- self.text(str(addr))
-
-
-class AnsiFormatter(Formatter):
- '''Formatter for plain-text files which outputs ANSI escape codes. See
- http://en.wikipedia.org/wiki/ANSI_escape_code for more information
- concerning ANSI escape codes.
- '''
-
- _csi = '\33['
-
- _normal = '0m'
- _bold = '1m'
- _italic = '3m'
- _red = '31m'
- _green = '32m'
- _blue = '34m'
-
- def _escape(self, code):
- self.text(self._csi + code)
-
- def function(self, name):
- self._escape(self._bold)
- Formatter.function(self, name)
- self._escape(self._normal)
-
- def variable(self, name):
- self._escape(self._italic)
- Formatter.variable(self, name)
- self._escape(self._normal)
-
- def literal(self, value):
- self._escape(self._blue)
- Formatter.literal(self, value)
- self._escape(self._normal)
-
- def address(self, value):
- self._escape(self._green)
- Formatter.address(self, value)
- self._escape(self._normal)
-
-
-class WindowsConsoleFormatter(Formatter):
- '''Formatter for the Windows Console. See
- http://code.activestate.com/recipes/496901/ for more information.
- '''
-
- STD_INPUT_HANDLE = -10
- STD_OUTPUT_HANDLE = -11
- STD_ERROR_HANDLE = -12
-
- FOREGROUND_BLUE = 0x01
- FOREGROUND_GREEN = 0x02
- FOREGROUND_RED = 0x04
- FOREGROUND_INTENSITY = 0x08
- BACKGROUND_BLUE = 0x10
- BACKGROUND_GREEN = 0x20
- BACKGROUND_RED = 0x40
- BACKGROUND_INTENSITY = 0x80
-
- _normal = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED
- _bold = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY
- _italic = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED
- _red = FOREGROUND_RED | FOREGROUND_INTENSITY
- _green = FOREGROUND_GREEN | FOREGROUND_INTENSITY
- _blue = FOREGROUND_BLUE | FOREGROUND_INTENSITY
-
- def __init__(self, stream):
- Formatter.__init__(self, stream)
-
- if stream is sys.stdin:
- nStdHandle = self.STD_INPUT_HANDLE
- elif stream is sys.stdout:
- nStdHandle = self.STD_OUTPUT_HANDLE
- elif stream is sys.stderr:
- nStdHandle = self.STD_ERROR_HANDLE
- else:
- nStdHandle = None
-
- if nStdHandle:
- import ctypes
- self.handle = ctypes.windll.kernel32.GetStdHandle(nStdHandle)
- else:
- self.handle = None
-
- def _attribute(self, attr):
- if self.handle:
- import ctypes
- ctypes.windll.kernel32.SetConsoleTextAttribute(self.handle, attr)
-
- def function(self, name):
- self._attribute(self._bold)
- Formatter.function(self, name)
- self._attribute(self._normal)
-
- def variable(self, name):
- self._attribute(self._italic)
- Formatter.variable(self, name)
- self._attribute(self._normal)
-
- def literal(self, value):
- self._attribute(self._blue)
- Formatter.literal(self, value)
- self._attribute(self._normal)
-
- def address(self, value):
- self._attribute(self._green)
- Formatter.address(self, value)
- self._attribute(self._normal)
-
-
-def DefaultFormatter(stream):
- if sys.platform in ('linux2', 'cygwin'):
- return AnsiFormatter(stream)
- elif sys.platform in ('win32',):
- return WindowsConsoleFormatter(stream)
- else:
- return Formatter(stream)
-
diff --git a/src/gallium/tests/python/retrace/model.py b/src/gallium/tests/python/retrace/model.py
deleted file mode 100755
index d4a079fb1e5..00000000000
--- a/src/gallium/tests/python/retrace/model.py
+++ /dev/null
@@ -1,213 +0,0 @@
-#!/usr/bin/env python
-##########################################################################
-#
-# Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
-# 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 TUNGSTEN GRAPHICS 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.
-#
-##########################################################################
-
-
-'''Trace data model.'''
-
-
-import sys
-import string
-import format
-
-try:
- from cStringIO import StringIO
-except ImportError:
- from StringIO import StringIO
-
-
-class Node:
-
- def visit(self, visitor):
- raise NotImplementedError
-
- def __str__(self):
- stream = StringIO()
- formatter = format.DefaultFormatter(stream)
- pretty_printer = PrettyPrinter(formatter)
- self.visit(pretty_printer)
- return stream.getvalue()
-
-
-class Literal(Node):
-
- def __init__(self, value):
- self.value = value
-
- def visit(self, visitor):
- visitor.visit_literal(self)
-
-
-class NamedConstant(Node):
-
- def __init__(self, name):
- self.name = name
-
- def visit(self, visitor):
- visitor.visit_named_constant(self)
-
-
-class Array(Node):
-
- def __init__(self, elements):
- self.elements = elements
-
- def visit(self, visitor):
- visitor.visit_array(self)
-
-
-class Struct(Node):
-
- def __init__(self, name, members):
- self.name = name
- self.members = members
-
- def visit(self, visitor):
- visitor.visit_struct(self)
-
-
-class Pointer(Node):
-
- def __init__(self, address):
- self.address = address
-
- def visit(self, visitor):
- visitor.visit_pointer(self)
-
-
-class Call:
-
- def __init__(self, no, klass, method, args, ret):
- self.no = no
- self.klass = klass
- self.method = method
- self.args = args
- self.ret = ret
-
- def visit(self, visitor):
- visitor.visit_call(self)
-
-
-class Trace:
-
- def __init__(self, calls):
- self.calls = calls
-
- def visit(self, visitor):
- visitor.visit_trace(self)
-
-
-class Visitor:
-
- def visit_literal(self, node):
- raise NotImplementedError
-
- def visit_named_constant(self, node):
- raise NotImplementedError
-
- def visit_array(self, node):
- raise NotImplementedError
-
- def visit_struct(self, node):
- raise NotImplementedError
-
- def visit_pointer(self, node):
- raise NotImplementedError
-
- def visit_call(self, node):
- raise NotImplementedError
-
- def visit_trace(self, node):
- raise NotImplementedError
-
-
-class PrettyPrinter:
-
- def __init__(self, formatter):
- self.formatter = formatter
-
- def visit_literal(self, node):
- if isinstance(node.value, basestring):
- if len(node.value) >= 4096 or node.value.strip(string.printable):
- self.formatter.text('...')
- return
-
- self.formatter.literal('"' + node.value + '"')
- return
-
- self.formatter.literal(repr(node.value))
-
- def visit_named_constant(self, node):
- self.formatter.literal(node.name)
-
- def visit_array(self, node):
- self.formatter.text('{')
- sep = ''
- for value in node.elements:
- self.formatter.text(sep)
- value.visit(self)
- sep = ', '
- self.formatter.text('}')
-
- def visit_struct(self, node):
- self.formatter.text('{')
- sep = ''
- for name, value in node.members:
- self.formatter.text(sep)
- self.formatter.variable(name)
- self.formatter.text(' = ')
- value.visit(self)
- sep = ', '
- self.formatter.text('}')
-
- def visit_pointer(self, node):
- self.formatter.address(node.address)
-
- def visit_call(self, node):
- self.formatter.text('%s ' % node.no)
- if node.klass is not None:
- self.formatter.function(node.klass + '::' + node.method)
- else:
- self.formatter.function(node.method)
- self.formatter.text('(')
- sep = ''
- for name, value in node.args:
- self.formatter.text(sep)
- self.formatter.variable(name)
- self.formatter.text(' = ')
- value.visit(self)
- sep = ', '
- self.formatter.text(')')
- if node.ret is not None:
- self.formatter.text(' = ')
- node.ret.visit(self)
-
- def visit_trace(self, node):
- for call in node.calls:
- call.visit(self)
- self.formatter.newline()
-
diff --git a/src/gallium/tests/python/retrace/parse.py b/src/gallium/tests/python/retrace/parse.py
deleted file mode 100755
index b08d3686715..00000000000
--- a/src/gallium/tests/python/retrace/parse.py
+++ /dev/null
@@ -1,392 +0,0 @@
-#!/usr/bin/env python
-##########################################################################
-#
-# Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
-# 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 TUNGSTEN GRAPHICS 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.
-#
-##########################################################################
-
-
-import sys
-import xml.parsers.expat
-import binascii
-import optparse
-
-from model import *
-
-
-ELEMENT_START, ELEMENT_END, CHARACTER_DATA, EOF = range(4)
-
-
-class XmlToken:
-
- def __init__(self, type, name_or_data, attrs = None, line = None, column = None):
- assert type in (ELEMENT_START, ELEMENT_END, CHARACTER_DATA, EOF)
- self.type = type
- self.name_or_data = name_or_data
- self.attrs = attrs
- self.line = line
- self.column = column
-
- def __str__(self):
- if self.type == ELEMENT_START:
- return '<' + self.name_or_data + ' ...>'
- if self.type == ELEMENT_END:
- return '</' + self.name_or_data + '>'
- if self.type == CHARACTER_DATA:
- return self.name_or_data
- if self.type == EOF:
- return 'end of file'
- assert 0
-
-
-class XmlTokenizer:
- """Expat based XML tokenizer."""
-
- def __init__(self, fp, skip_ws = True):
- self.fp = fp
- self.tokens = []
- self.index = 0
- self.final = False
- self.skip_ws = skip_ws
-
- self.character_pos = 0, 0
- self.character_data = ''
-
- self.parser = xml.parsers.expat.ParserCreate()
- self.parser.StartElementHandler = self.handle_element_start
- self.parser.EndElementHandler = self.handle_element_end
- self.parser.CharacterDataHandler = self.handle_character_data
-
- def handle_element_start(self, name, attributes):
- self.finish_character_data()
- line, column = self.pos()
- token = XmlToken(ELEMENT_START, name, attributes, line, column)
- self.tokens.append(token)
-
- def handle_element_end(self, name):
- self.finish_character_data()
- line, column = self.pos()
- token = XmlToken(ELEMENT_END, name, None, line, column)
- self.tokens.append(token)
-
- def handle_character_data(self, data):
- if not self.character_data:
- self.character_pos = self.pos()
- self.character_data += data
-
- def finish_character_data(self):
- if self.character_data:
- if not self.skip_ws or not self.character_data.isspace():
- line, column = self.character_pos
- token = XmlToken(CHARACTER_DATA, self.character_data, None, line, column)
- self.tokens.append(token)
- self.character_data = ''
-
- def next(self):
- size = 16*1024
- while self.index >= len(self.tokens) and not self.final:
- self.tokens = []
- self.index = 0
- data = self.fp.read(size)
- self.final = len(data) < size
- data = data.rstrip('\0')
- try:
- self.parser.Parse(data, self.final)
- except xml.parsers.expat.ExpatError, e:
- #if e.code == xml.parsers.expat.errors.XML_ERROR_NO_ELEMENTS:
- if e.code == 3:
- pass
- else:
- raise e
- if self.index >= len(self.tokens):
- line, column = self.pos()
- token = XmlToken(EOF, None, None, line, column)
- else:
- token = self.tokens[self.index]
- self.index += 1
- return token
-
- def pos(self):
- return self.parser.CurrentLineNumber, self.parser.CurrentColumnNumber
-
-
-class TokenMismatch(Exception):
-
- def __init__(self, expected, found):
- self.expected = expected
- self.found = found
-
- def __str__(self):
- return '%u:%u: %s expected, %s found' % (self.found.line, self.found.column, str(self.expected), str(self.found))
-
-
-
-class XmlParser:
- """Base XML document parser."""
-
- def __init__(self, fp):
- self.tokenizer = XmlTokenizer(fp)
- self.consume()
-
- def consume(self):
- self.token = self.tokenizer.next()
-
- def match_element_start(self, name):
- return self.token.type == ELEMENT_START and self.token.name_or_data == name
-
- def match_element_end(self, name):
- return self.token.type == ELEMENT_END and self.token.name_or_data == name
-
- def element_start(self, name):
- while self.token.type == CHARACTER_DATA:
- self.consume()
- if self.token.type != ELEMENT_START:
- raise TokenMismatch(XmlToken(ELEMENT_START, name), self.token)
- if self.token.name_or_data != name:
- raise TokenMismatch(XmlToken(ELEMENT_START, name), self.token)
- attrs = self.token.attrs
- self.consume()
- return attrs
-
- def element_end(self, name):
- while self.token.type == CHARACTER_DATA:
- self.consume()
- if self.token.type != ELEMENT_END:
- raise TokenMismatch(XmlToken(ELEMENT_END, name), self.token)
- if self.token.name_or_data != name:
- raise TokenMismatch(XmlToken(ELEMENT_END, name), self.token)
- self.consume()
-
- def character_data(self, strip = True):
- data = ''
- while self.token.type == CHARACTER_DATA:
- data += self.token.name_or_data
- self.consume()
- if strip:
- data = data.strip()
- return data
-
-
-class TraceParser(XmlParser):
-
- def __init__(self, fp):
- XmlParser.__init__(self, fp)
- self.last_call_no = 0
-
- def parse(self):
- self.element_start('trace')
- while self.token.type not in (ELEMENT_END, EOF):
- call = self.parse_call()
- self.handle_call(call)
- if self.token.type != EOF:
- self.element_end('trace')
-
- def parse_call(self):
- attrs = self.element_start('call')
- try:
- no = int(attrs['no'])
- except KeyError:
- self.last_call_no += 1
- no = self.last_call_no
- else:
- self.last_call_no = no
- klass = attrs['class']
- method = attrs['method']
- args = []
- ret = None
- while self.token.type == ELEMENT_START:
- if self.token.name_or_data == 'arg':
- arg = self.parse_arg()
- args.append(arg)
- elif self.token.name_or_data == 'ret':
- ret = self.parse_ret()
- elif self.token.name_or_data == 'call':
- # ignore nested function calls
- self.parse_call()
- else:
- raise TokenMismatch("<arg ...> or <ret ...>", self.token)
- self.element_end('call')
-
- return Call(no, klass, method, args, ret)
-
- def parse_arg(self):
- attrs = self.element_start('arg')
- name = attrs['name']
- value = self.parse_value()
- self.element_end('arg')
-
- return name, value
-
- def parse_ret(self):
- attrs = self.element_start('ret')
- value = self.parse_value()
- self.element_end('ret')
-
- return value
-
- def parse_value(self):
- expected_tokens = ('null', 'bool', 'int', 'uint', 'float', 'string', 'enum', 'array', 'struct', 'ptr', 'bytes')
- if self.token.type == ELEMENT_START:
- if self.token.name_or_data in expected_tokens:
- method = getattr(self, 'parse_' + self.token.name_or_data)
- return method()
- raise TokenMismatch(" or " .join(expected_tokens), self.token)
-
- def parse_null(self):
- self.element_start('null')
- self.element_end('null')
- return Literal(None)
-
- def parse_bool(self):
- self.element_start('bool')
- value = int(self.character_data())
- self.element_end('bool')
- return Literal(value)
-
- def parse_int(self):
- self.element_start('int')
- value = int(self.character_data())
- self.element_end('int')
- return Literal(value)
-
- def parse_uint(self):
- self.element_start('uint')
- value = int(self.character_data())
- self.element_end('uint')
- return Literal(value)
-
- def parse_float(self):
- self.element_start('float')
- value = float(self.character_data())
- self.element_end('float')
- return Literal(value)
-
- def parse_enum(self):
- self.element_start('enum')
- name = self.character_data()
- self.element_end('enum')
- return NamedConstant(name)
-
- def parse_string(self):
- self.element_start('string')
- value = self.character_data()
- self.element_end('string')
- return Literal(value)
-
- def parse_bytes(self):
- self.element_start('bytes')
- value = binascii.a2b_hex(self.character_data())
- self.element_end('bytes')
- return Literal(value)
-
- def parse_array(self):
- self.element_start('array')
- elems = []
- while self.token.type != ELEMENT_END:
- elems.append(self.parse_elem())
- self.element_end('array')
- return Array(elems)
-
- def parse_elem(self):
- self.element_start('elem')
- value = self.parse_value()
- self.element_end('elem')
- return value
-
- def parse_struct(self):
- attrs = self.element_start('struct')
- name = attrs['name']
- members = []
- while self.token.type != ELEMENT_END:
- members.append(self.parse_member())
- self.element_end('struct')
- return Struct(name, members)
-
- def parse_member(self):
- attrs = self.element_start('member')
- name = attrs['name']
- value = self.parse_value()
- self.element_end('member')
-
- return name, value
-
- def parse_ptr(self):
- self.element_start('ptr')
- address = self.character_data()
- self.element_end('ptr')
-
- return Pointer(address)
-
- def handle_call(self, call):
- pass
-
-
-class TraceDumper(TraceParser):
-
- def __init__(self, fp):
- TraceParser.__init__(self, fp)
- self.formatter = format.DefaultFormatter(sys.stdout)
- self.pretty_printer = PrettyPrinter(self.formatter)
-
- def handle_call(self, call):
- call.visit(self.pretty_printer)
- self.formatter.newline()
-
-
-class Main:
- '''Common main class for all retrace command line utilities.'''
-
- def __init__(self):
- pass
-
- def main(self):
- optparser = self.get_optparser()
- (options, args) = optparser.parse_args(sys.argv[1:])
-
- if args:
- for arg in args:
- if arg.endswith('.gz'):
- from gzip import GzipFile
- stream = GzipFile(arg, 'rt')
- elif arg.endswith('.bz2'):
- from bz2 import BZ2File
- stream = BZ2File(arg, 'rU')
- else:
- stream = open(arg, 'rt')
- self.process_arg(stream, options)
- else:
- self.process_arg(stream, options)
-
- def get_optparser(self):
- optparser = optparse.OptionParser(
- usage="\n\t%prog [options] [traces] ...")
- return optparser
-
- def process_arg(self, stream, options):
- parser = TraceDumper(stream)
- parser.parse()
-
-
-if __name__ == '__main__':
- Main().main()
diff --git a/src/gallium/tests/python/retrace/parser.py b/src/gallium/tests/python/retrace/parser.py
deleted file mode 100755
index bd47c9a6b06..00000000000
--- a/src/gallium/tests/python/retrace/parser.py
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/usr/bin/env python
-##########################################################################
-#
-# Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
-# 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 TUNGSTEN GRAPHICS 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.
-#
-##########################################################################
-
-
-from parse import *
-
-
-if __name__ == '__main__':
- Main().main()
diff --git a/src/gallium/tests/python/samples/gs.py b/src/gallium/tests/python/samples/gs.py
deleted file mode 100644
index 936c0b3f33a..00000000000
--- a/src/gallium/tests/python/samples/gs.py
+++ /dev/null
@@ -1,254 +0,0 @@
-#!/usr/bin/env python
-##########################################################################
-#
-# Copyright 2009 VMware
-# 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 TUNGSTEN GRAPHICS 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.
-#
-##########################################################################
-
-
-from gallium import *
-
-
-def make_image(surface):
- data = surface.get_tile_rgba8(0, 0, surface.width, surface.height)
-
- import Image
- outimage = Image.fromstring('RGBA', (surface.width, surface.height), data, "raw", 'RGBA', 0, 1)
- return outimage
-
-def save_image(filename, surface):
- outimage = make_image(surface)
- outimage.save(filename, "PNG")
-
-def show_image(surface):
- outimage = make_image(surface)
-
- import Tkinter as tk
- from PIL import Image, ImageTk
- root = tk.Tk()
-
- root.title('background image')
-
- image1 = ImageTk.PhotoImage(outimage)
- w = image1.width()
- h = image1.height()
- x = 100
- y = 100
- root.geometry("%dx%d+%d+%d" % (w, h, x, y))
- panel1 = tk.Label(root, image=image1)
- panel1.pack(side='top', fill='both', expand='yes')
- panel1.image = image1
- root.mainloop()
-
-
-def test(dev):
- ctx = dev.context_create()
-
- width = 255
- height = 255
- minz = 0.0
- maxz = 1.0
-
- # disabled blending/masking
- blend = Blend()
- blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE
- blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE
- blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO
- blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO
- blend.rt[0].colormask = PIPE_MASK_RGBA
- ctx.set_blend(blend)
-
- # depth/stencil/alpha
- depth_stencil_alpha = DepthStencilAlpha()
- depth_stencil_alpha.depth.enabled = 1
- depth_stencil_alpha.depth.writemask = 1
- depth_stencil_alpha.depth.func = PIPE_FUNC_LESS
- ctx.set_depth_stencil_alpha(depth_stencil_alpha)
-
- # rasterizer
- rasterizer = Rasterizer()
- rasterizer.front_winding = PIPE_WINDING_CW
- rasterizer.cull_mode = PIPE_WINDING_NONE
- rasterizer.scissor = 1
- ctx.set_rasterizer(rasterizer)
-
- # viewport
- viewport = Viewport()
- scale = FloatArray(4)
- scale[0] = width / 2.0
- scale[1] = -height / 2.0
- scale[2] = (maxz - minz) / 2.0
- scale[3] = 1.0
- viewport.scale = scale
- translate = FloatArray(4)
- translate[0] = width / 2.0
- translate[1] = height / 2.0
- translate[2] = (maxz - minz) / 2.0
- translate[3] = 0.0
- viewport.translate = translate
- ctx.set_viewport(viewport)
-
- # samplers
- sampler = Sampler()
- sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE
- sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE
- sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE
- sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE
- sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST
- sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST
- sampler.normalized_coords = 1
- ctx.set_sampler(0, sampler)
-
- # scissor
- scissor = Scissor()
- scissor.minx = 0
- scissor.miny = 0
- scissor.maxx = width
- scissor.maxy = height
- ctx.set_scissor(scissor)
-
- clip = Clip()
- clip.nr = 0
- ctx.set_clip(clip)
-
- # framebuffer
- cbuf = dev.resource_create(
- PIPE_FORMAT_B8G8R8X8_UNORM,
- width, height,
- bind=PIPE_BIND_RENDER_TARGET,
- ).get_surface()
- zbuf = dev.resource_create(
- PIPE_FORMAT_Z32_UNORM,
- width, height,
- bind=PIPE_BIND_DEPTH_STENCIL,
- ).get_surface()
- fb = Framebuffer()
- fb.width = width
- fb.height = height
- fb.nr_cbufs = 1
- fb.set_cbuf(0, cbuf)
- fb.set_zsbuf(zbuf)
- ctx.set_framebuffer(fb)
- rgba = FloatArray(4);
- rgba[0] = 0.0
- rgba[1] = 0.0
- rgba[2] = 0.0
- rgba[3] = 0.0
- ctx.clear(PIPE_CLEAR_COLOR | PIPE_CLEAR_DEPTHSTENCIL, rgba, 1.0, 0xff)
-
- # vertex shader
- vs = Shader('''
- VERT
- DCL IN[0], POSITION, CONSTANT
- DCL IN[1], COLOR, CONSTANT
- DCL OUT[0], POSITION, CONSTANT
- DCL OUT[1], COLOR, CONSTANT
- 0:MOV OUT[0], IN[0]
- 1:MOV OUT[1], IN[1]
- 2:END
- ''')
- ctx.set_vertex_shader(vs)
-
- gs = Shader('''
- GEOM
- PROPERTY GS_INPUT_PRIMITIVE TRIANGLES
- PROPERTY GS_OUTPUT_PRIMITIVE TRIANGLE_STRIP
- DCL IN[][0], POSITION, CONSTANT
- DCL IN[][1], COLOR, CONSTANT
- DCL OUT[0], POSITION, CONSTANT
- DCL OUT[1], COLOR, CONSTANT
- 0:MOV OUT[0], IN[0][0]
- 1:MOV OUT[1], IN[0][1]
- 2:EMIT
- 3:MOV OUT[0], IN[1][0]
- 4:MOV OUT[1], IN[1][1]
- 5:EMIT
- 6:MOV OUT[0], IN[2][0]
- 7:MOV OUT[1], IN[2][1]
- 8:EMIT
- 9:ENDPRIM
- 10:END
- ''')
- ctx.set_geometry_shader(gs)
-
- # fragment shader
- fs = Shader('''
- FRAG
- DCL IN[0], COLOR, LINEAR
- DCL OUT[0], COLOR, CONSTANT
- 0:MOV OUT[0], IN[0]
- 1:END
- ''')
- ctx.set_fragment_shader(fs)
-
- nverts = 3
- nattrs = 2
- verts = FloatArray(nverts * nattrs * 4)
-
- verts[ 0] = 0.0 # x1
- verts[ 1] = 0.8 # y1
- verts[ 2] = 0.2 # z1
- verts[ 3] = 1.0 # w1
- verts[ 4] = 1.0 # r1
- verts[ 5] = 0.0 # g1
- verts[ 6] = 0.0 # b1
- verts[ 7] = 1.0 # a1
- verts[ 8] = -0.8 # x2
- verts[ 9] = -0.8 # y2
- verts[10] = 0.5 # z2
- verts[11] = 1.0 # w2
- verts[12] = 0.0 # r2
- verts[13] = 1.0 # g2
- verts[14] = 0.0 # b2
- verts[15] = 1.0 # a2
- verts[16] = 0.8 # x3
- verts[17] = -0.8 # y3
- verts[18] = 0.8 # z3
- verts[19] = 1.0 # w3
- verts[20] = 0.0 # r3
- verts[21] = 0.0 # g3
- verts[22] = 1.0 # b3
- verts[23] = 1.0 # a3
-
- ctx.draw_vertices(PIPE_PRIM_TRIANGLES,
- nverts,
- nattrs,
- verts)
-
- ctx.flush()
-
- show_image(cbuf)
- #show_image(zbuf)
- #save_image('cbuf.png', cbuf)
- #save_image('zbuf.png', zbuf)
-
-
-
-def main():
- dev = Device()
- test(dev)
-
-
-if __name__ == '__main__':
- main()
diff --git a/src/gallium/tests/python/samples/tri.py b/src/gallium/tests/python/samples/tri.py
deleted file mode 100644
index 6d17c88c057..00000000000
--- a/src/gallium/tests/python/samples/tri.py
+++ /dev/null
@@ -1,233 +0,0 @@
-#!/usr/bin/env python
-##########################################################################
-#
-# Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
-# 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 TUNGSTEN GRAPHICS 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.
-#
-##########################################################################
-
-
-from gallium import *
-
-
-def make_image(ctx, surface):
- data = ctx.surface_read_rgba8(surface, 0, 0, surface.width, surface.height)
-
- import Image
- outimage = Image.fromstring('RGBA', (surface.width, surface.height), data, "raw", 'RGBA', 0, 1)
- return outimage
-
-def save_image(ctx, surface, filename):
- outimage = make_image(ctx, surface)
- outimage.save(filename, "PNG")
-
-def show_image(ctx, surface):
- outimage = make_image(ctx, surface)
-
- import Tkinter as tk
- from PIL import Image, ImageTk
- root = tk.Tk()
-
- root.title('background image')
-
- image1 = ImageTk.PhotoImage(outimage)
- w = image1.width()
- h = image1.height()
- x = 100
- y = 100
- root.geometry("%dx%d+%d+%d" % (w, h, x, y))
- panel1 = tk.Label(root, image=image1)
- panel1.pack(side='top', fill='both', expand='yes')
- panel1.image = image1
- root.mainloop()
-
-
-def test(dev):
- ctx = dev.context_create()
-
- width = 255
- height = 255
- minz = 0.0
- maxz = 1.0
-
- # disabled blending/masking
- blend = Blend()
- blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE
- blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE
- blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO
- blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO
- blend.rt[0].colormask = PIPE_MASK_RGBA
- ctx.set_blend(blend)
-
- # depth/stencil/alpha
- depth_stencil_alpha = DepthStencilAlpha()
- depth_stencil_alpha.depth.enabled = 1
- depth_stencil_alpha.depth.writemask = 1
- depth_stencil_alpha.depth.func = PIPE_FUNC_LESS
- ctx.set_depth_stencil_alpha(depth_stencil_alpha)
-
- # rasterizer
- rasterizer = Rasterizer()
- rasterizer.front_ccw = False
- rasterizer.cull_face = PIPE_FACE_NONE
- rasterizer.scissor = 1
- ctx.set_rasterizer(rasterizer)
-
- # viewport
- viewport = Viewport()
- scale = FloatArray(4)
- scale[0] = width / 2.0
- scale[1] = -height / 2.0
- scale[2] = (maxz - minz) / 2.0
- scale[3] = 1.0
- viewport.scale = scale
- translate = FloatArray(4)
- translate[0] = width / 2.0
- translate[1] = height / 2.0
- translate[2] = (maxz - minz) / 2.0
- translate[3] = 0.0
- viewport.translate = translate
- ctx.set_viewport(viewport)
-
- # samplers
- sampler = Sampler()
- sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE
- sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE
- sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE
- sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE
- sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST
- sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST
- sampler.normalized_coords = 1
- ctx.set_fragment_sampler(0, sampler)
-
- # scissor
- scissor = Scissor()
- scissor.minx = 0
- scissor.miny = 0
- scissor.maxx = width
- scissor.maxy = height
- ctx.set_scissor(scissor)
-
- # clip
- clip = Clip()
- clip.nr = 0
- ctx.set_clip(clip)
-
- # framebuffer
- cbuf = dev.resource_create(
- PIPE_FORMAT_B8G8R8X8_UNORM,
- width, height,
- bind=PIPE_BIND_RENDER_TARGET,
- ).get_surface()
- zbuf = dev.resource_create(
- PIPE_FORMAT_Z32_UNORM,
- width, height,
- bind=PIPE_BIND_DEPTH_STENCIL,
- ).get_surface()
- fb = Framebuffer()
- fb.width = width
- fb.height = height
- fb.nr_cbufs = 1
- fb.set_cbuf(0, cbuf)
- fb.set_zsbuf(zbuf)
- ctx.set_framebuffer(fb)
- rgba = FloatArray(4);
- rgba[0] = 0.0
- rgba[1] = 0.0
- rgba[2] = 0.0
- rgba[3] = 0.0
- ctx.clear(PIPE_CLEAR_COLOR | PIPE_CLEAR_DEPTHSTENCIL, rgba, 1.0, 0xff)
-
- # vertex shader
- vs = Shader('''
- VERT
- DCL IN[0]
- DCL IN[1]
- DCL OUT[0], POSITION, CONSTANT
- DCL OUT[1], COLOR, CONSTANT
- 0:MOV OUT[0], IN[0]
- 1:MOV OUT[1], IN[1]
- 2:END
- ''')
- ctx.set_vertex_shader(vs)
-
- # fragment shader
- fs = Shader('''
- FRAG
- DCL IN[0], COLOR, LINEAR
- DCL OUT[0], COLOR, CONSTANT
- 0:MOV OUT[0], IN[0]
- 1:END
- ''')
- ctx.set_fragment_shader(fs)
-
- nverts = 3
- nattrs = 2
- verts = FloatArray(nverts * nattrs * 4)
-
- verts[ 0] = 0.0 # x1
- verts[ 1] = 0.8 # y1
- verts[ 2] = 0.2 # z1
- verts[ 3] = 1.0 # w1
- verts[ 4] = 1.0 # r1
- verts[ 5] = 0.0 # g1
- verts[ 6] = 0.0 # b1
- verts[ 7] = 1.0 # a1
- verts[ 8] = -0.8 # x2
- verts[ 9] = -0.8 # y2
- verts[10] = 0.5 # z2
- verts[11] = 1.0 # w2
- verts[12] = 0.0 # r2
- verts[13] = 1.0 # g2
- verts[14] = 0.0 # b2
- verts[15] = 1.0 # a2
- verts[16] = 0.8 # x3
- verts[17] = -0.8 # y3
- verts[18] = 0.8 # z3
- verts[19] = 1.0 # w3
- verts[20] = 0.0 # r3
- verts[21] = 0.0 # g3
- verts[22] = 1.0 # b3
- verts[23] = 1.0 # a3
-
- ctx.draw_vertices(PIPE_PRIM_TRIANGLES,
- nverts,
- nattrs,
- verts)
-
- ctx.flush()
-
- show_image(ctx, cbuf)
- show_image(ctx, zbuf)
- save_image(ctx, cbuf, 'cbuf.png')
- save_image(ctx, zbuf, 'zbuf.png')
-
-
-
-def main():
- dev = Device()
- test(dev)
-
-
-if __name__ == '__main__':
- main()
diff --git a/src/gallium/tests/python/tests/.gitignore b/src/gallium/tests/python/tests/.gitignore
deleted file mode 100644
index 0dbbaeea16b..00000000000
--- a/src/gallium/tests/python/tests/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-*.txt
-*.tsv
-*.dot
diff --git a/src/gallium/tests/python/tests/base.py b/src/gallium/tests/python/tests/base.py
deleted file mode 100755
index d8cf84db363..00000000000
--- a/src/gallium/tests/python/tests/base.py
+++ /dev/null
@@ -1,399 +0,0 @@
-#!/usr/bin/env python
-##########################################################################
-#
-# Copyright 2009 VMware, Inc.
-# Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
-# 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 VMWARE 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.
-#
-##########################################################################
-
-
-"""Base classes for tests.
-
-Loosely inspired on Python's unittest module.
-"""
-
-
-import os.path
-import sys
-
-from gallium import *
-
-
-# Enumerate all pixel formats
-formats = {}
-for name, value in globals().items():
- if name.startswith("PIPE_FORMAT_") and isinstance(value, int) and name not in ("PIPE_FORMAT_NONE", "PIPE_FORMAT_COUNT"):
- formats[value] = name
-
-def make_image(width, height, rgba):
- import Image
- outimage = Image.new(
- mode='RGB',
- size=(width, height),
- color=(0,0,0))
- outpixels = outimage.load()
- for y in range(0, height):
- for x in range(0, width):
- offset = (y*width + x)*4
- r, g, b, a = [int(min(max(rgba[offset + ch], 0.0), 1.0)*255) for ch in range(4)]
- outpixels[x, y] = r, g, b
- return outimage
-
-def save_image(width, height, rgba, filename):
- outimage = make_image(width, height, rgba)
- outimage.save(filename, "PNG")
-
-def show_image(width, height, **rgbas):
- import Tkinter as tk
- from PIL import Image, ImageTk
-
- root = tk.Tk()
-
- x = 64
- y = 64
-
- labels = rgbas.keys()
- labels.sort()
- for i in range(len(labels)):
- label = labels[i]
- outimage = make_image(width, height, rgbas[label])
-
- if i:
- window = tk.Toplevel(root)
- else:
- window = root
- window.title(label)
- image1 = ImageTk.PhotoImage(outimage)
- w = image1.width()
- h = image1.height()
- window.geometry("%dx%d+%d+%d" % (w, h, x, y))
- panel1 = tk.Label(window, image=image1)
- panel1.pack(side='top', fill='both', expand='yes')
- panel1.image = image1
- x += w + 2
-
- root.mainloop()
-
-
-class TestFailure(Exception):
-
- pass
-
-class TestSkip(Exception):
-
- pass
-
-
-class Test:
-
- def __init__(self):
- pass
-
- def _run(self, result):
- raise NotImplementedError
-
- def run(self):
- result = TestResult()
- self._run(result)
- result.report()
-
- def assert_rgba(self, ctx, surface, x, y, w, h, expected_rgba, pixel_tol=4.0/256, surface_tol=0.85):
- total = h*w
- different = ctx.surface_compare_rgba(surface, x, y, w, h, expected_rgba, tol=pixel_tol)
- if different:
- sys.stderr.write("%u out of %u pixels differ\n" % (different, total))
-
- if float(total - different)/float(total) < surface_tol:
- if 0:
- rgba = FloatArray(h*w*4)
- ctx.surface_read_rgba(surface, x, y, w, h, rgba)
- show_image(w, h, Result=rgba, Expected=expected_rgba)
- save_image(w, h, rgba, "result.png")
- save_image(w, h, expected_rgba, "expected.png")
- #sys.exit(0)
-
- raise TestFailure
-
-
-class TestCase(Test):
-
- tags = ()
-
- def __init__(self, dev, **kargs):
- Test.__init__(self)
- self.dev = dev
- self.__dict__.update(kargs)
-
- def description(self):
- descriptions = []
- for tag in self.tags:
- value = self.get(tag)
- if value is not None and value != '':
- descriptions.append(tag + '=' + str(value))
- return ' '.join(descriptions)
-
- def get(self, tag):
- try:
- method = getattr(self, '_get_' + tag)
- except AttributeError:
- return getattr(self, tag, None)
- else:
- return method()
-
- def _get_target(self):
- return {
- PIPE_TEXTURE_1D: "1d",
- PIPE_TEXTURE_2D: "2d",
- PIPE_TEXTURE_3D: "3d",
- PIPE_TEXTURE_CUBE: "cube",
- }[self.target]
-
- def _get_format(self):
- name = formats[self.format]
- if name.startswith('PIPE_FORMAT_'):
- name = name[12:]
- name = name.lower()
- return name
-
- def _get_face(self):
- if self.target == PIPE_TEXTURE_CUBE:
- return {
- PIPE_TEX_FACE_POS_X: "+x",
- PIPE_TEX_FACE_NEG_X: "-x",
- PIPE_TEX_FACE_POS_Y: "+y",
- PIPE_TEX_FACE_NEG_Y: "-y",
- PIPE_TEX_FACE_POS_Z: "+z",
- PIPE_TEX_FACE_NEG_Z: "-z",
- }[self.face]
- else:
- return ''
-
- def test(self):
- raise NotImplementedError
-
- def _run(self, result):
- result.test_start(self)
- try:
- self.test()
- except KeyboardInterrupt:
- raise
- except TestSkip:
- result.test_skipped(self)
- except TestFailure:
- result.test_failed(self)
- else:
- result.test_passed(self)
-
-
-class TestSuite(Test):
-
- def __init__(self, tests = None):
- Test.__init__(self)
- if tests is None:
- self.tests = []
- else:
- self.tests = tests
-
- def add_test(self, test):
- self.tests.append(test)
-
- def _run(self, result):
- for test in self.tests:
- test._run(result)
-
-
-class TestResult:
-
- def __init__(self):
- self.tests = 0
- self.passed = 0
- self.skipped = 0
- self.failed = 0
-
- self.names = ['result']
- self.types = ['pass skip fail']
- self.rows = []
-
- def test_start(self, test):
- sys.stdout.write("Running %s...\n" % test.description())
- sys.stdout.flush()
- self.tests += 1
-
- def test_passed(self, test):
- sys.stdout.write("PASS\n")
- sys.stdout.flush()
- self.passed += 1
- self.log_result(test, 'pass')
-
- def test_skipped(self, test):
- sys.stdout.write("SKIP\n")
- sys.stdout.flush()
- self.skipped += 1
- self.log_result(test, 'skip')
-
- def test_failed(self, test):
- sys.stdout.write("FAIL\n")
- sys.stdout.flush()
- self.failed += 1
- self.log_result(test, 'fail')
-
- def log_result(self, test, result):
- row = ['']*len(self.names)
-
- # add result
- assert self.names[0] == 'result'
- assert result in ('pass', 'skip', 'fail')
- row[0] = result
-
- # add tags
- for tag in test.tags:
- value = test.get(tag)
-
- # infer type
- if value is None:
- continue
- elif isinstance(value, (int, float)):
- value = str(value)
- type = 'c' # continous
- elif isinstance(value, basestring):
- type = 'd' # discrete
- else:
- assert False
- value = str(value)
- type = 'd' # discrete
-
- # insert value
- try:
- col = self.names.index(tag, 1)
- except ValueError:
- self.names.append(tag)
- self.types.append(type)
- row.append(value)
- else:
- row[col] = value
- assert self.types[col] == type
-
- self.rows.append(row)
-
- def report(self):
- sys.stdout.write("%u tests, %u passed, %u skipped, %u failed\n\n" % (self.tests, self.passed, self.skipped, self.failed))
- sys.stdout.flush()
-
- name, ext = os.path.splitext(os.path.basename(sys.argv[0]))
-
- tree = self.report_tree(name)
- self.report_junit(name, stdout=tree)
-
- def report_tree(self, name):
- filename = name + '.tsv'
- stream = file(filename, 'wt')
-
- # header
- stream.write('\t'.join(self.names) + '\n')
- stream.write('\t'.join(self.types) + '\n')
- stream.write('class\n')
-
- # rows
- for row in self.rows:
- if row[0] == 'skip':
- continue
- row += ['']*(len(self.names) - len(row))
- stream.write('\t'.join(row) + '\n')
-
- stream.close()
-
- # See http://www.ailab.si/orange/doc/ofb/c_otherclass.htm
- try:
- import orange
- import orngTree
- except ImportError:
- sys.stderr.write('Install Orange from http://www.ailab.si/orange/ for a classification tree.\n')
- return None
-
- data = orange.ExampleTable(filename)
-
- tree = orngTree.TreeLearner(data, sameMajorityPruning=1, mForPruning=2)
-
- orngTree.printTxt(tree, maxDepth=4)
-
- text_tree = orngTree.dumpTree(tree)
-
- file(name + '.txt', 'wt').write(text_tree)
-
- orngTree.printDot(tree, fileName=name+'.dot', nodeShape='ellipse', leafShape='box')
-
- return text_tree
-
- def report_junit(self, name, stdout=None, stderr=None):
- """Write test results in ANT's junit XML format, to use with Hudson CI.
-
- See also:
- - http://fisheye.hudson-ci.org/browse/Hudson/trunk/hudson/main/core/src/test/resources/hudson/tasks/junit
- - http://www.junit.org/node/399
- - http://wiki.apache.org/ant/Proposals/EnhancedTestReports
- """
-
- stream = file(name + '.xml', 'wt')
-
- stream.write('<?xml version="1.0" encoding="UTF-8" ?>\n')
- stream.write('<testsuite name="%s">\n' % self.escape_xml(name))
- stream.write(' <properties>\n')
- stream.write(' </properties>\n')
-
- names = self.names[1:]
-
- for row in self.rows:
-
- test_name = ' '.join(['%s=%s' % pair for pair in zip(self.names[1:], row[1:])])
-
- stream.write(' <testcase name="%s">\n' % (self.escape_xml(test_name)))
-
- result = row[0]
- if result == 'pass':
- pass
- elif result == 'skip':
- stream.write(' <skipped/>\n')
- else:
- stream.write(' <failure/>\n')
-
- stream.write(' </testcase>\n')
-
- if stdout:
- stream.write(' <system-out>%s</system-out>\n' % self.escape_xml(stdout))
- if stderr:
- stream.write(' <system-err>%s</system-err>\n' % self.escape_xml(stderr))
-
- stream.write('</testsuite>\n')
-
- stream.close()
-
- def escape_xml(self, s):
- '''Escape a XML string.'''
- s = s.replace('&', '&amp;')
- s = s.replace('<', '&lt;')
- s = s.replace('>', '&gt;')
- s = s.replace('"', '&quot;')
- s = s.replace("'", '&apos;')
- return s
-
diff --git a/src/gallium/tests/python/tests/regress/fragment-shader/.gitignore b/src/gallium/tests/python/tests/regress/fragment-shader/.gitignore
deleted file mode 100644
index e33609d251c..00000000000
--- a/src/gallium/tests/python/tests/regress/fragment-shader/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-*.png
diff --git a/src/gallium/tests/python/tests/regress/fragment-shader/frag-abs.sh b/src/gallium/tests/python/tests/regress/fragment-shader/frag-abs.sh
deleted file mode 100644
index 103d7497f48..00000000000
--- a/src/gallium/tests/python/tests/regress/fragment-shader/frag-abs.sh
+++ /dev/null
@@ -1,13 +0,0 @@
-FRAG
-
-DCL IN[0], COLOR, LINEAR
-DCL OUT[0], COLOR
-
-DCL TEMP[0]
-
-IMM FLT32 { -0.5, -0.4, -0.6, 0.0 }
-
-ADD TEMP[0], IN[0], IMM[0]
-ABS OUT[0], TEMP[0]
-
-END
diff --git a/src/gallium/tests/python/tests/regress/fragment-shader/frag-add.sh b/src/gallium/tests/python/tests/regress/fragment-shader/frag-add.sh
deleted file mode 100644
index bcb94205963..00000000000
--- a/src/gallium/tests/python/tests/regress/fragment-shader/frag-add.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-FRAG
-
-DCL IN[0], COLOR, LINEAR
-DCL OUT[0], COLOR
-
-ADD OUT[0], IN[0], IN[0]
-
-END
diff --git a/src/gallium/tests/python/tests/regress/fragment-shader/frag-cb-1d.sh b/src/gallium/tests/python/tests/regress/fragment-shader/frag-cb-1d.sh
deleted file mode 100644
index 85fb9ea4e7f..00000000000
--- a/src/gallium/tests/python/tests/regress/fragment-shader/frag-cb-1d.sh
+++ /dev/null
@@ -1,13 +0,0 @@
-FRAG
-
-DCL IN[0], COLOR, LINEAR
-DCL OUT[0], COLOR
-DCL CONST[1]
-DCL CONST[3]
-DCL TEMP[0..1]
-
-ADD TEMP[0], IN[0], CONST[1]
-RCP TEMP[1], CONST[3].xxxx
-MUL OUT[0], TEMP[0], TEMP[1]
-
-END
diff --git a/src/gallium/tests/python/tests/regress/fragment-shader/frag-dp3.sh b/src/gallium/tests/python/tests/regress/fragment-shader/frag-dp3.sh
deleted file mode 100644
index b5281975d4a..00000000000
--- a/src/gallium/tests/python/tests/regress/fragment-shader/frag-dp3.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-FRAG
-
-DCL IN[0], COLOR, LINEAR
-DCL OUT[0], COLOR
-
-DP3 OUT[0], IN[0], IN[0]
-
-END
diff --git a/src/gallium/tests/python/tests/regress/fragment-shader/frag-dp4.sh b/src/gallium/tests/python/tests/regress/fragment-shader/frag-dp4.sh
deleted file mode 100644
index d59df76e70b..00000000000
--- a/src/gallium/tests/python/tests/regress/fragment-shader/frag-dp4.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-FRAG
-
-DCL IN[0], COLOR, LINEAR
-DCL OUT[0], COLOR
-
-DP4 OUT[0], IN[0].xyzx, IN[0].xyzx
-
-END
diff --git a/src/gallium/tests/python/tests/regress/fragment-shader/frag-dst.sh b/src/gallium/tests/python/tests/regress/fragment-shader/frag-dst.sh
deleted file mode 100644
index fbb20fa9f62..00000000000
--- a/src/gallium/tests/python/tests/regress/fragment-shader/frag-dst.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-FRAG
-
-DCL IN[0], COLOR, LINEAR
-DCL OUT[0], COLOR
-
-DST OUT[0], IN[0], IN[0]
-
-END
diff --git a/src/gallium/tests/python/tests/regress/fragment-shader/frag-ex2.sh b/src/gallium/tests/python/tests/regress/fragment-shader/frag-ex2.sh
deleted file mode 100644
index b511288f4b6..00000000000
--- a/src/gallium/tests/python/tests/regress/fragment-shader/frag-ex2.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-FRAG
-
-DCL IN[0], COLOR, LINEAR
-DCL OUT[0], COLOR
-
-DCL TEMP[0]
-
-EX2 TEMP[0], IN[0].xxxx
-MUL OUT[0], TEMP[0], IN[0]
-
-END
diff --git a/src/gallium/tests/python/tests/regress/fragment-shader/frag-flr.sh b/src/gallium/tests/python/tests/regress/fragment-shader/frag-flr.sh
deleted file mode 100644
index 99a2f96103a..00000000000
--- a/src/gallium/tests/python/tests/regress/fragment-shader/frag-flr.sh
+++ /dev/null
@@ -1,15 +0,0 @@
-FRAG
-
-DCL IN[0], COLOR, LINEAR
-DCL OUT[0], COLOR
-
-DCL TEMP[0]
-
-IMM FLT32 { 2.5, 4.0, 2.0, 1.0 }
-IMM FLT32 { 0.4, 0.25, 0.5, 1.0 }
-
-MUL TEMP[0], IN[0], IMM[0]
-FLR TEMP[0], TEMP[0]
-MUL OUT[0], TEMP[0], IMM[1]
-
-END
diff --git a/src/gallium/tests/python/tests/regress/fragment-shader/frag-frc.sh b/src/gallium/tests/python/tests/regress/fragment-shader/frag-frc.sh
deleted file mode 100644
index a54c2623b0a..00000000000
--- a/src/gallium/tests/python/tests/regress/fragment-shader/frag-frc.sh
+++ /dev/null
@@ -1,13 +0,0 @@
-FRAG
-
-DCL IN[0], COLOR, LINEAR
-DCL OUT[0], COLOR
-
-DCL TEMP[0]
-
-IMM FLT32 { 2.7, 3.1, 4.5, 1.0 }
-
-MUL TEMP[0], IN[0], IMM[0]
-FRC OUT[0], TEMP[0]
-
-END
diff --git a/src/gallium/tests/python/tests/regress/fragment-shader/frag-lg2.sh b/src/gallium/tests/python/tests/regress/fragment-shader/frag-lg2.sh
deleted file mode 100644
index 5f5b4be1092..00000000000
--- a/src/gallium/tests/python/tests/regress/fragment-shader/frag-lg2.sh
+++ /dev/null
@@ -1,15 +0,0 @@
-FRAG
-
-DCL IN[0], COLOR, LINEAR
-DCL OUT[0], COLOR
-
-DCL TEMP[0]
-
-IMM FLT32 { 1.0, 0.0, 0.0, 0.0 }
-IMM FLT32 { 0.5, 0.0, 0.0, 0.0 }
-
-ADD TEMP[0], IN[0], IMM[0]
-LG2 TEMP[0].x, TEMP[0].xxxx
-ADD OUT[0], TEMP[0], IMM[1]
-
-END
diff --git a/src/gallium/tests/python/tests/regress/fragment-shader/frag-lit.sh b/src/gallium/tests/python/tests/regress/fragment-shader/frag-lit.sh
deleted file mode 100644
index 6323c4712dc..00000000000
--- a/src/gallium/tests/python/tests/regress/fragment-shader/frag-lit.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-FRAG
-
-DCL IN[0], COLOR, LINEAR
-DCL OUT[0], COLOR
-
-LIT OUT[0], IN[0]
-
-END
diff --git a/src/gallium/tests/python/tests/regress/fragment-shader/frag-lrp.sh b/src/gallium/tests/python/tests/regress/fragment-shader/frag-lrp.sh
deleted file mode 100644
index 740809d22e0..00000000000
--- a/src/gallium/tests/python/tests/regress/fragment-shader/frag-lrp.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-FRAG
-
-DCL IN[0], COLOR, LINEAR
-DCL OUT[0], COLOR
-
-DCL TEMP[0]
-
-ABS TEMP[0], IN[0]
-LRP OUT[0], TEMP[0], IN[0].xxxx, IN[0].yyyy
-
-END
diff --git a/src/gallium/tests/python/tests/regress/fragment-shader/frag-mad.sh b/src/gallium/tests/python/tests/regress/fragment-shader/frag-mad.sh
deleted file mode 100644
index 413b9dc3916..00000000000
--- a/src/gallium/tests/python/tests/regress/fragment-shader/frag-mad.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-FRAG
-
-DCL IN[0], COLOR, LINEAR
-DCL OUT[0], COLOR
-
-IMM FLT32 { 0.5, 0.4, 0.6, 1.0 }
-IMM FLT32 { 0.5, 0.4, 0.6, 0.0 }
-
-MAD OUT[0], IN[0], IMM[0], IMM[1]
-
-END
diff --git a/src/gallium/tests/python/tests/regress/fragment-shader/frag-max.sh b/src/gallium/tests/python/tests/regress/fragment-shader/frag-max.sh
deleted file mode 100644
index b69f2132612..00000000000
--- a/src/gallium/tests/python/tests/regress/fragment-shader/frag-max.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-FRAG
-
-DCL IN[0], COLOR, LINEAR
-DCL OUT[0], COLOR
-
-IMM FLT32 { 0.4, 0.4, 0.4, 0.0 }
-
-MAX OUT[0], IN[0], IMM[0]
-
-END
diff --git a/src/gallium/tests/python/tests/regress/fragment-shader/frag-min.sh b/src/gallium/tests/python/tests/regress/fragment-shader/frag-min.sh
deleted file mode 100644
index df284f49e71..00000000000
--- a/src/gallium/tests/python/tests/regress/fragment-shader/frag-min.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-FRAG
-
-DCL IN[0], COLOR, LINEAR
-DCL OUT[0], COLOR
-
-IMM FLT32 { 0.6, 0.6, 0.6, 1.0 }
-
-MIN OUT[0], IN[0], IMM[0]
-
-END
diff --git a/src/gallium/tests/python/tests/regress/fragment-shader/frag-mov.sh b/src/gallium/tests/python/tests/regress/fragment-shader/frag-mov.sh
deleted file mode 100644
index 64af72f381b..00000000000
--- a/src/gallium/tests/python/tests/regress/fragment-shader/frag-mov.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-FRAG
-
-DCL IN[0], COLOR, LINEAR
-DCL OUT[0], COLOR
-
-MOV OUT[0], IN[0]
-
-END
diff --git a/src/gallium/tests/python/tests/regress/fragment-shader/frag-mul.sh b/src/gallium/tests/python/tests/regress/fragment-shader/frag-mul.sh
deleted file mode 100644
index bdd0b0026b9..00000000000
--- a/src/gallium/tests/python/tests/regress/fragment-shader/frag-mul.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-FRAG
-
-DCL IN[0], COLOR, LINEAR
-DCL OUT[0], COLOR
-
-IMM FLT32 { 0.5, 0.6, 0.7, 1.0 }
-
-MUL OUT[0], IN[0], IMM[0]
-
-END
diff --git a/src/gallium/tests/python/tests/regress/fragment-shader/frag-rcp.sh b/src/gallium/tests/python/tests/regress/fragment-shader/frag-rcp.sh
deleted file mode 100644
index f4b611b26ab..00000000000
--- a/src/gallium/tests/python/tests/regress/fragment-shader/frag-rcp.sh
+++ /dev/null
@@ -1,15 +0,0 @@
-FRAG
-
-DCL IN[0], COLOR, LINEAR
-DCL OUT[0], COLOR
-
-DCL TEMP[0]
-
-IMM FLT32 { 1.0, 0.0, 0.0, 0.0 }
-IMM FLT32 { 1.5, 0.0, 0.0, 0.0 }
-
-ADD TEMP[0], IN[0], IMM[0]
-RCP TEMP[0].x, TEMP[0].xxxx
-SUB OUT[0], TEMP[0], IMM[1]
-
-END
diff --git a/src/gallium/tests/python/tests/regress/fragment-shader/frag-rsq.sh b/src/gallium/tests/python/tests/regress/fragment-shader/frag-rsq.sh
deleted file mode 100644
index d1e9b0b53be..00000000000
--- a/src/gallium/tests/python/tests/regress/fragment-shader/frag-rsq.sh
+++ /dev/null
@@ -1,15 +0,0 @@
-FRAG
-
-DCL IN[0], COLOR, LINEAR
-DCL OUT[0], COLOR
-
-DCL TEMP[0]
-
-IMM FLT32 { 1.0, 0.0, 0.0, 0.0 }
-IMM FLT32 { 1.5, 0.0, 0.0, 0.0 }
-
-ADD TEMP[0], IN[0], IMM[0]
-RSQ TEMP[0].x, TEMP[0].xxxx
-SUB OUT[0], TEMP[0], IMM[1]
-
-END
diff --git a/src/gallium/tests/python/tests/regress/fragment-shader/frag-sge.sh b/src/gallium/tests/python/tests/regress/fragment-shader/frag-sge.sh
deleted file mode 100644
index 1f33fac4727..00000000000
--- a/src/gallium/tests/python/tests/regress/fragment-shader/frag-sge.sh
+++ /dev/null
@@ -1,13 +0,0 @@
-FRAG
-
-DCL IN[0], COLOR, LINEAR
-DCL OUT[0], COLOR
-
-DCL TEMP[0]
-
-IMM FLT32 { 0.6, 0.6, 0.6, 0.0 }
-
-SGE TEMP[0], IN[0], IMM[0]
-MUL OUT[0], IN[0], TEMP[0]
-
-END
diff --git a/src/gallium/tests/python/tests/regress/fragment-shader/frag-slt.sh b/src/gallium/tests/python/tests/regress/fragment-shader/frag-slt.sh
deleted file mode 100644
index d58b7886a12..00000000000
--- a/src/gallium/tests/python/tests/regress/fragment-shader/frag-slt.sh
+++ /dev/null
@@ -1,13 +0,0 @@
-FRAG
-
-DCL IN[0], COLOR, LINEAR
-DCL OUT[0], COLOR
-
-DCL TEMP[0]
-
-IMM FLT32 { 0.6, 0.6, 0.6, 0.0 }
-
-SLT TEMP[0], IN[0], IMM[0]
-MUL OUT[0], IN[0], TEMP[0]
-
-END
diff --git a/src/gallium/tests/python/tests/regress/fragment-shader/frag-srcmod-abs.sh b/src/gallium/tests/python/tests/regress/fragment-shader/frag-srcmod-abs.sh
deleted file mode 100644
index ecd19248c64..00000000000
--- a/src/gallium/tests/python/tests/regress/fragment-shader/frag-srcmod-abs.sh
+++ /dev/null
@@ -1,13 +0,0 @@
-FRAG
-
-DCL IN[0], COLOR, LINEAR
-DCL OUT[0], COLOR
-
-DCL TEMP[0]
-
-IMM FLT32 { -0.3, -0.5, -0.4, 0.0 }
-
-ADD TEMP[0], IN[0], IMM[0]
-MOV OUT[0], |TEMP[0]|
-
-END
diff --git a/src/gallium/tests/python/tests/regress/fragment-shader/frag-srcmod-absneg.sh b/src/gallium/tests/python/tests/regress/fragment-shader/frag-srcmod-absneg.sh
deleted file mode 100644
index c2d99ddd15b..00000000000
--- a/src/gallium/tests/python/tests/regress/fragment-shader/frag-srcmod-absneg.sh
+++ /dev/null
@@ -1,15 +0,0 @@
-FRAG
-
-DCL IN[0], COLOR, LINEAR
-DCL OUT[0], COLOR
-
-DCL TEMP[0]
-
-IMM FLT32 { -0.2, -0.3, -0.4, 0.0 }
-IMM FLT32 { -1.0, -1.0, -1.0, -1.0 }
-
-ADD TEMP[0], IN[0], IMM[0]
-MOV TEMP[0], -|TEMP[0]|
-MUL OUT[0], TEMP[0], IMM[1]
-
-END
diff --git a/src/gallium/tests/python/tests/regress/fragment-shader/frag-srcmod-neg.sh b/src/gallium/tests/python/tests/regress/fragment-shader/frag-srcmod-neg.sh
deleted file mode 100644
index a08ab6d2dcb..00000000000
--- a/src/gallium/tests/python/tests/regress/fragment-shader/frag-srcmod-neg.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-FRAG
-
-DCL IN[0], COLOR, LINEAR
-DCL OUT[0], COLOR
-
-DCL TEMP[0]
-
-SUB TEMP[0], IN[0], IN[0].yzxw
-MOV OUT[0], -TEMP[0]
-
-END
diff --git a/src/gallium/tests/python/tests/regress/fragment-shader/frag-srcmod-swz.sh b/src/gallium/tests/python/tests/regress/fragment-shader/frag-srcmod-swz.sh
deleted file mode 100644
index 6110647d979..00000000000
--- a/src/gallium/tests/python/tests/regress/fragment-shader/frag-srcmod-swz.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-FRAG
-
-DCL IN[0], COLOR, LINEAR
-DCL OUT[0], COLOR
-
-MOV OUT[0], IN[0].yxzw
-
-END
diff --git a/src/gallium/tests/python/tests/regress/fragment-shader/frag-sub.sh b/src/gallium/tests/python/tests/regress/fragment-shader/frag-sub.sh
deleted file mode 100644
index 673fca139aa..00000000000
--- a/src/gallium/tests/python/tests/regress/fragment-shader/frag-sub.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-FRAG
-
-DCL IN[0], COLOR, LINEAR
-DCL OUT[0], COLOR
-
-SUB OUT[0], IN[0], IN[0].yzxw
-
-END
diff --git a/src/gallium/tests/python/tests/regress/fragment-shader/frag-xpd.sh b/src/gallium/tests/python/tests/regress/fragment-shader/frag-xpd.sh
deleted file mode 100644
index 6ec8b1184cc..00000000000
--- a/src/gallium/tests/python/tests/regress/fragment-shader/frag-xpd.sh
+++ /dev/null
@@ -1,8 +0,0 @@
-FRAG
-
-DCL IN[0], COLOR, LINEAR
-DCL OUT[0], COLOR
-
-XPD OUT[0], IN[0], IN[0].yzxw
-
-END
diff --git a/src/gallium/tests/python/tests/regress/fragment-shader/fragment-shader.py b/src/gallium/tests/python/tests/regress/fragment-shader/fragment-shader.py
deleted file mode 100644
index ef65a9c5a1b..00000000000
--- a/src/gallium/tests/python/tests/regress/fragment-shader/fragment-shader.py
+++ /dev/null
@@ -1,257 +0,0 @@
-#!/usr/bin/env python
-##########################################################################
-#
-# Copyright 2009 VMware, Inc.
-# 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 VMWARE 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.
-#
-##########################################################################
-
-import struct
-
-from gallium import *
-
-def make_image(surface):
- data = surface.get_tile_rgba8(0, 0, surface.width, surface.height)
-
- import Image
- outimage = Image.fromstring('RGBA', (surface.width, surface.height), data, "raw", 'RGBA', 0, 1)
- return outimage
-
-def save_image(filename, surface):
- outimage = make_image(surface)
- outimage.save(filename, "PNG")
-
-def test(dev, name):
- ctx = dev.context_create()
-
- width = 320
- height = 320
- minz = 0.0
- maxz = 1.0
-
- # disabled blending/masking
- blend = Blend()
- blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE
- blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE
- blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO
- blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO
- blend.rt[0].colormask = PIPE_MASK_RGBA
- ctx.set_blend(blend)
-
- # depth/stencil/alpha
- depth_stencil_alpha = DepthStencilAlpha()
- depth_stencil_alpha.depth.enabled = 0
- depth_stencil_alpha.depth.writemask = 1
- depth_stencil_alpha.depth.func = PIPE_FUNC_LESS
- ctx.set_depth_stencil_alpha(depth_stencil_alpha)
-
- # rasterizer
- rasterizer = Rasterizer()
- rasterizer.front_winding = PIPE_WINDING_CW
- rasterizer.cull_mode = PIPE_WINDING_NONE
- rasterizer.scissor = 1
- ctx.set_rasterizer(rasterizer)
-
- # viewport
- viewport = Viewport()
- scale = FloatArray(4)
- scale[0] = width / 2.0
- scale[1] = -height / 2.0
- scale[2] = (maxz - minz) / 2.0
- scale[3] = 1.0
- viewport.scale = scale
- translate = FloatArray(4)
- translate[0] = width / 2.0
- translate[1] = height / 2.0
- translate[2] = (maxz - minz) / 2.0
- translate[3] = 0.0
- viewport.translate = translate
- ctx.set_viewport(viewport)
-
- # samplers
- sampler = Sampler()
- sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE
- sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE
- sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE
- sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE
- sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST
- sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST
- sampler.normalized_coords = 1
- ctx.set_fragment_sampler(0, sampler)
-
- # scissor
- scissor = Scissor()
- scissor.minx = 0
- scissor.miny = 0
- scissor.maxx = width
- scissor.maxy = height
- ctx.set_scissor(scissor)
-
- clip = Clip()
- clip.nr = 0
- ctx.set_clip(clip)
-
- # framebuffer
- cbuf = dev.resource_create(
- PIPE_FORMAT_B8G8R8X8_UNORM,
- width, height,
- bind=PIPE_BIND_RENDER_TARGET,
- ).get_surface()
- fb = Framebuffer()
- fb.width = width
- fb.height = height
- fb.nr_cbufs = 1
- fb.set_cbuf(0, cbuf)
- ctx.set_framebuffer(fb)
- rgba = FloatArray(4);
- rgba[0] = 0.5
- rgba[1] = 0.5
- rgba[2] = 0.5
- rgba[3] = 0.5
- ctx.clear(PIPE_CLEAR_COLOR, rgba, 0.0, 0)
-
- # vertex shader
- vs = Shader('''
- VERT
- DCL IN[0], POSITION
- DCL IN[1], COLOR
- DCL OUT[0], POSITION
- DCL OUT[1], COLOR
- MOV OUT[0], IN[0]
- MOV OUT[1], IN[1]
- END
- ''')
- ctx.set_vertex_shader(vs)
-
- # fragment shader
- fs = Shader(file('frag-' + name + '.sh', 'rt').read())
- ctx.set_fragment_shader(fs)
-
- constbuf0 = dev.buffer_create(64,
- (PIPE_BUFFER_USAGE_CONSTANT |
- PIPE_BUFFER_USAGE_GPU_READ |
- PIPE_BUFFER_USAGE_CPU_WRITE),
- 4 * 4 * 4)
-
- cbdata = ''
- cbdata += struct.pack('4f', 0.4, 0.0, 0.0, 1.0)
- cbdata += struct.pack('4f', 1.0, 1.0, 1.0, 1.0)
- cbdata += struct.pack('4f', 2.0, 2.0, 2.0, 2.0)
- cbdata += struct.pack('4f', 4.0, 8.0, 16.0, 32.0)
-
- constbuf0.write(cbdata, 0)
-
- ctx.set_constant_buffer(PIPE_SHADER_FRAGMENT,
- 0,
- constbuf0)
-
- constbuf1 = dev.buffer_create(64,
- (PIPE_BUFFER_USAGE_CONSTANT |
- PIPE_BUFFER_USAGE_GPU_READ |
- PIPE_BUFFER_USAGE_CPU_WRITE),
- 4 * 4 * 4)
-
- cbdata = ''
- cbdata += struct.pack('4f', 0.1, 0.1, 0.1, 0.1)
- cbdata += struct.pack('4f', 0.25, 0.25, 0.25, 0.25)
- cbdata += struct.pack('4f', 0.5, 0.5, 0.5, 0.5)
- cbdata += struct.pack('4f', 0.75, 0.75, 0.75, 0.75)
-
- constbuf1.write(cbdata, 0)
-
- ctx.set_constant_buffer(PIPE_SHADER_FRAGMENT,
- 1,
- constbuf1)
-
- xy = [
- -0.8, -0.8,
- 0.8, -0.8,
- 0.0, 0.8,
- ]
- color = [
- 1.0, 0.0, 0.0,
- 0.0, 1.0, 0.0,
- 0.0, 0.0, 1.0,
- ]
-
- nverts = 3
- nattrs = 2
- verts = FloatArray(nverts * nattrs * 4)
-
- for i in range(0, nverts):
- verts[i * nattrs * 4 + 0] = xy[i * 2 + 0] # x
- verts[i * nattrs * 4 + 1] = xy[i * 2 + 1] # y
- verts[i * nattrs * 4 + 2] = 0.5 # z
- verts[i * nattrs * 4 + 3] = 1.0 # w
- verts[i * nattrs * 4 + 4] = color[i * 3 + 0] # r
- verts[i * nattrs * 4 + 5] = color[i * 3 + 1] # g
- verts[i * nattrs * 4 + 6] = color[i * 3 + 2] # b
- verts[i * nattrs * 4 + 7] = 1.0 # a
-
- ctx.draw_vertices(PIPE_PRIM_TRIANGLES,
- nverts,
- nattrs,
- verts)
-
- ctx.flush()
-
- save_image('frag-' + name + '.png', cbuf)
-
-def main():
- tests = [
- 'abs',
- 'add',
- 'cb-1d',
- 'cb-2d',
- 'dp3',
- 'dp4',
- 'dst',
- 'ex2',
- 'flr',
- 'frc',
- 'lg2',
- 'lit',
- 'lrp',
- 'mad',
- 'max',
- 'min',
- 'mov',
- 'mul',
- 'rcp',
- 'rsq',
- 'sge',
- 'slt',
- 'srcmod-abs',
- 'srcmod-absneg',
- 'srcmod-neg',
- 'srcmod-swz',
- 'sub',
- 'xpd',
- ]
-
- dev = Device()
- for t in tests:
- test(dev, t)
-
-if __name__ == '__main__':
- main()
diff --git a/src/gallium/tests/python/tests/regress/vertex-shader/.gitignore b/src/gallium/tests/python/tests/regress/vertex-shader/.gitignore
deleted file mode 100644
index e33609d251c..00000000000
--- a/src/gallium/tests/python/tests/regress/vertex-shader/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-*.png
diff --git a/src/gallium/tests/python/tests/regress/vertex-shader/vertex-shader.py b/src/gallium/tests/python/tests/regress/vertex-shader/vertex-shader.py
deleted file mode 100644
index 05e40dbd5f1..00000000000
--- a/src/gallium/tests/python/tests/regress/vertex-shader/vertex-shader.py
+++ /dev/null
@@ -1,287 +0,0 @@
-#!/usr/bin/env python
-##########################################################################
-#
-# Copyright 2009 VMware, Inc.
-# 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 VMWARE 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.
-#
-##########################################################################
-
-
-import struct
-
-from gallium import *
-
-def make_image(surface):
- data = surface.get_tile_rgba8(0, 0, surface.width, surface.height)
-
- import Image
- outimage = Image.fromstring('RGBA', (surface.width, surface.height), data, "raw", 'RGBA', 0, 1)
- return outimage
-
-def save_image(filename, surface):
- outimage = make_image(surface)
- outimage.save(filename, "PNG")
-
-def test(dev, name):
- ctx = dev.context_create()
-
- width = 320
- height = 320
- minz = 0.0
- maxz = 1.0
-
- # disabled blending/masking
- blend = Blend()
- blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE
- blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE
- blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO
- blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO
- blend.rt[0].colormask = PIPE_MASK_RGBA
- ctx.set_blend(blend)
-
- # depth/stencil/alpha
- depth_stencil_alpha = DepthStencilAlpha()
- depth_stencil_alpha.depth.enabled = 0
- depth_stencil_alpha.depth.writemask = 1
- depth_stencil_alpha.depth.func = PIPE_FUNC_LESS
- ctx.set_depth_stencil_alpha(depth_stencil_alpha)
-
- # rasterizer
- rasterizer = Rasterizer()
- rasterizer.front_winding = PIPE_WINDING_CW
- rasterizer.cull_mode = PIPE_WINDING_NONE
- rasterizer.scissor = 1
- ctx.set_rasterizer(rasterizer)
-
- # viewport
- viewport = Viewport()
- scale = FloatArray(4)
- scale[0] = width / 2.0
- scale[1] = -height / 2.0
- scale[2] = (maxz - minz) / 2.0
- scale[3] = 1.0
- viewport.scale = scale
- translate = FloatArray(4)
- translate[0] = width / 2.0
- translate[1] = height / 2.0
- translate[2] = (maxz - minz) / 2.0
- translate[3] = 0.0
- viewport.translate = translate
- ctx.set_viewport(viewport)
-
- # samplers
- sampler = Sampler()
- sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE
- sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE
- sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE
- sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE
- sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST
- sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST
- sampler.normalized_coords = 1
- ctx.set_fragment_sampler(0, sampler)
-
- # scissor
- scissor = Scissor()
- scissor.minx = 0
- scissor.miny = 0
- scissor.maxx = width
- scissor.maxy = height
- ctx.set_scissor(scissor)
-
- clip = Clip()
- clip.nr = 0
- ctx.set_clip(clip)
-
- # framebuffer
- cbuf = dev.resource_create(
- PIPE_FORMAT_B8G8R8X8_UNORM,
- width, height,
- bind=PIPE_BIND_RENDER_TARGET,
- ).get_surface()
- fb = Framebuffer()
- fb.width = width
- fb.height = height
- fb.nr_cbufs = 1
- fb.set_cbuf(0, cbuf)
- ctx.set_framebuffer(fb)
- rgba = FloatArray(4);
- rgba[0] = 0.5
- rgba[1] = 0.5
- rgba[2] = 0.5
- rgba[3] = 0.5
- ctx.clear(PIPE_CLEAR_COLOR, rgba, 0.0, 0)
-
- # vertex shader
- vs = Shader(file('vert-' + name + '.sh', 'rt').read())
- ctx.set_vertex_shader(vs)
-
- # fragment shader
- fs = Shader('''
- FRAG
- DCL IN[0], COLOR, LINEAR
- DCL OUT[0], COLOR, CONSTANT
- 0:MOV OUT[0], IN[0]
- 1:END
- ''')
- ctx.set_fragment_shader(fs)
-
- constbuf0 = dev.buffer_create(64,
- (PIPE_BUFFER_USAGE_CONSTANT |
- PIPE_BUFFER_USAGE_GPU_READ |
- PIPE_BUFFER_USAGE_CPU_WRITE),
- 4 * 4 * 4)
-
- cbdata = ''
- cbdata += struct.pack('4f', 0.4, 0.0, 0.0, 1.0)
- cbdata += struct.pack('4f', 1.0, 1.0, 1.0, 1.0)
- cbdata += struct.pack('4f', 2.0, 2.0, 2.0, 2.0)
- cbdata += struct.pack('4f', 4.0, 8.0, 16.0, 32.0)
-
- constbuf0.write(cbdata, 0)
-
- ctx.set_constant_buffer(PIPE_SHADER_VERTEX,
- 0,
- constbuf0)
-
- constbuf1 = dev.buffer_create(64,
- (PIPE_BUFFER_USAGE_CONSTANT |
- PIPE_BUFFER_USAGE_GPU_READ |
- PIPE_BUFFER_USAGE_CPU_WRITE),
- 4 * 4 * 4)
-
- cbdata = ''
- cbdata += struct.pack('4f', 0.1, 0.1, 0.1, 0.1)
- cbdata += struct.pack('4f', 0.25, 0.25, 0.25, 0.25)
- cbdata += struct.pack('4f', 0.5, 0.5, 0.5, 0.5)
- cbdata += struct.pack('4f', 0.75, 0.75, 0.75, 0.75)
-
- constbuf1.write(cbdata, 0)
-
- ctx.set_constant_buffer(PIPE_SHADER_VERTEX,
- 1,
- constbuf1)
-
- xy = [
- 0.0, 0.8,
- -0.2, 0.4,
- 0.2, 0.4,
- -0.4, 0.0,
- 0.0, 0.0,
- 0.4, 0.0,
- -0.6, -0.4,
- -0.2, -0.4,
- 0.2, -0.4,
- 0.6, -0.4,
- -0.8, -0.8,
- -0.4, -0.8,
- 0.0, -0.8,
- 0.4, -0.8,
- 0.8, -0.8,
- ]
- color = [
- 1.0, 0.0, 0.0,
- 0.0, 1.0, 0.0,
- 0.0, 0.0, 1.0,
- ]
- tri = [
- 1, 2, 0,
- 3, 4, 1,
- 4, 2, 1,
- 4, 5, 2,
- 6, 7, 3,
- 7, 4, 3,
- 7, 8, 4,
- 8, 5, 4,
- 8, 9, 5,
- 10, 11, 6,
- 11, 7, 6,
- 11, 12, 7,
- 12, 8, 7,
- 12, 13, 8,
- 13, 9, 8,
- 13, 14, 9,
- ]
-
- nverts = 16 * 3
- nattrs = 2
- verts = FloatArray(nverts * nattrs * 4)
-
- for i in range(0, nverts):
- verts[i * nattrs * 4 + 0] = xy[tri[i] * 2 + 0] # x
- verts[i * nattrs * 4 + 1] = xy[tri[i] * 2 + 1] # y
- verts[i * nattrs * 4 + 2] = 0.5 # z
- verts[i * nattrs * 4 + 3] = 1.0 # w
- verts[i * nattrs * 4 + 4] = color[(i % 3) * 3 + 0] # r
- verts[i * nattrs * 4 + 5] = color[(i % 3) * 3 + 1] # g
- verts[i * nattrs * 4 + 6] = color[(i % 3) * 3 + 2] # b
- verts[i * nattrs * 4 + 7] = 1.0 # a
-
- ctx.draw_vertices(PIPE_PRIM_TRIANGLES,
- nverts,
- nattrs,
- verts)
-
- ctx.flush()
-
- save_image('vert-' + name + '.png', cbuf)
-
-def main():
- tests = [
- 'abs',
- 'add',
- 'arl',
- 'arr',
- 'cb-1d',
- 'cb-2d',
- 'dp3',
- 'dp4',
- 'dst',
- 'ex2',
- 'flr',
- 'frc',
- 'lg2',
- 'lit',
- 'lrp',
- 'mad',
- 'max',
- 'min',
- 'mov',
- 'mul',
- 'rcp',
- 'rsq',
- 'sge',
- 'slt',
- 'srcmod-abs',
- 'srcmod-absneg',
- 'srcmod-neg',
- 'srcmod-swz',
- 'sub',
- 'xpd',
- ]
-
- dev = Device()
- for t in tests:
- test(dev, t)
-
-if __name__ == '__main__':
- main()
diff --git a/src/gallium/tests/python/tests/texture_render.py b/src/gallium/tests/python/tests/texture_render.py
deleted file mode 100755
index 23f3d2a57de..00000000000
--- a/src/gallium/tests/python/tests/texture_render.py
+++ /dev/null
@@ -1,320 +0,0 @@
-#!/usr/bin/env python
-##########################################################################
-#
-# Copyright 2009 VMware, Inc.
-# 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 VMWARE 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.
-#
-##########################################################################
-
-
-from gallium import *
-from base import *
-
-
-def lods(*dims):
- size = max(dims)
- lods = 0
- while size:
- lods += 1
- size >>= 1
- return lods
-
-
-class TextureTest(TestCase):
-
- tags = (
- 'target',
- 'format',
- 'width',
- 'height',
- 'depth',
- 'last_level',
- 'face',
- 'level',
- 'zslice',
- )
-
- def test(self):
- dev = self.dev
-
- target = self.target
- format = self.format
- width = self.width
- height = self.height
- depth = self.depth
- last_level = self.last_level
- face = self.face
- level = self.level
- zslice = self.zslice
-
- # textures
- dst_texture = dev.resource_create(
- target = target,
- format = format,
- width = width,
- height = height,
- depth = depth,
- last_level = last_level,
- bind = PIPE_BIND_RENDER_TARGET,
- )
- if dst_texture is None:
- raise TestSkip
-
- dst_surface = dst_texture.get_surface(face = face, level = level, zslice = zslice)
-
- ref_texture = dev.resource_create(
- target = target,
- format = format,
- width = dst_surface.width,
- height = dst_surface.height,
- depth = 1,
- last_level = 0,
- bind = PIPE_BIND_SAMPLER_VIEW,
- )
-
- ref_surface = ref_texture.get_surface()
-
- src_texture = dev.resource_create(
- target = target,
- format = PIPE_FORMAT_B8G8R8A8_UNORM,
- width = dst_surface.width,
- height = dst_surface.height,
- depth = 1,
- last_level = 0,
- bind = PIPE_BIND_SAMPLER_VIEW,
- )
-
- src_surface = src_texture.get_surface()
-
- expected_rgba = FloatArray(height*width*4)
- ref_surface.sample_rgba(expected_rgba)
-
- src_surface.put_tile_rgba(0, 0, src_surface.width, src_surface.height, expected_rgba)
-
- ctx = self.dev.context_create()
-
- # disabled blending/masking
- blend = Blend()
- blend.rt[0].rgb_src_factor = PIPE_BLENDFACTOR_ONE
- blend.rt[0].alpha_src_factor = PIPE_BLENDFACTOR_ONE
- blend.rt[0].rgb_dst_factor = PIPE_BLENDFACTOR_ZERO
- blend.rt[0].alpha_dst_factor = PIPE_BLENDFACTOR_ZERO
- blend.rt[0].colormask = PIPE_MASK_RGBA
- ctx.set_blend(blend)
-
- # no-op depth/stencil/alpha
- depth_stencil_alpha = DepthStencilAlpha()
- ctx.set_depth_stencil_alpha(depth_stencil_alpha)
-
- # rasterizer
- rasterizer = Rasterizer()
- rasterizer.front_winding = PIPE_WINDING_CW
- rasterizer.cull_mode = PIPE_WINDING_NONE
- rasterizer.bypass_vs_clip_and_viewport = 1
- ctx.set_rasterizer(rasterizer)
-
- # samplers
- sampler = Sampler()
- sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE
- sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE
- sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE
- sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST
- sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST
- sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST
- sampler.normalized_coords = 1
- sampler.min_lod = 0
- sampler.max_lod = PIPE_MAX_TEXTURE_LEVELS - 1
- ctx.set_fragment_sampler(0, sampler)
- ctx.set_fragment_sampler_texture(0, src_texture)
-
- # framebuffer
- cbuf_tex = dev.resource_create(
- PIPE_FORMAT_B8G8R8A8_UNORM,
- width,
- height,
- bind = PIPE_BIND_RENDER_TARGET,
- )
-
- fb = Framebuffer()
- fb.width = dst_surface.width
- fb.height = dst_surface.height
- fb.nr_cbufs = 1
- fb.set_cbuf(0, dst_surface)
- ctx.set_framebuffer(fb)
- rgba = FloatArray(4);
- rgba[0] = 0.0
- rgba[1] = 0.0
- rgba[2] = 0.0
- rgba[3] = 0.0
- ctx.clear(PIPE_CLEAR_COLOR, rgba, 0.0, 0)
- del fb
-
- # vertex shader
- vs = Shader('''
- VERT
- DCL IN[0], POSITION, CONSTANT
- DCL IN[1], GENERIC, CONSTANT
- DCL OUT[0], POSITION, CONSTANT
- DCL OUT[1], GENERIC, CONSTANT
- 0:MOV OUT[0], IN[0]
- 1:MOV OUT[1], IN[1]
- 2:END
- ''')
- #vs.dump()
- ctx.set_vertex_shader(vs)
-
- # fragment shader
- fs = Shader('''
- FRAG
- DCL IN[0], GENERIC[0], LINEAR
- DCL OUT[0], COLOR, CONSTANT
- DCL SAMP[0], CONSTANT
- 0:TEX OUT[0], IN[0], SAMP[0], 2D
- 1:END
- ''')
- #fs.dump()
- ctx.set_fragment_shader(fs)
-
- nverts = 4
- nattrs = 2
- verts = FloatArray(nverts * nattrs * 4)
-
- x = 0
- y = 0
- w = dst_surface.width
- h = dst_surface.height
-
- pos = [
- [x, y],
- [x+w, y],
- [x+w, y+h],
- [x, y+h],
- ]
-
- tex = [
- [0.0, 0.0],
- [1.0, 0.0],
- [1.0, 1.0],
- [0.0, 1.0],
- ]
-
- for i in range(0, 4):
- j = 8*i
- verts[j + 0] = pos[i][0] # x
- verts[j + 1] = pos[i][1] # y
- verts[j + 2] = 0.0 # z
- verts[j + 3] = 1.0 # w
- verts[j + 4] = tex[i][0] # s
- verts[j + 5] = tex[i][1] # r
- verts[j + 6] = 0.0
- verts[j + 7] = 1.0
-
- ctx.draw_vertices(PIPE_PRIM_TRIANGLE_FAN,
- nverts,
- nattrs,
- verts)
-
- ctx.flush()
-
- self.assert_rgba(dst_surface, x, y, w, h, expected_rgba, 4.0/256, 0.85)
-
-
-
-def main():
- dev = Device()
- suite = TestSuite()
-
- targets = [
- PIPE_TEXTURE_2D,
- PIPE_TEXTURE_CUBE,
- #PIPE_TEXTURE_3D,
- ]
-
- formats = [
- PIPE_FORMAT_B8G8R8A8_UNORM,
- PIPE_FORMAT_B8G8R8X8_UNORM,
- #PIPE_FORMAT_B8G8R8A8_SRGB,
- PIPE_FORMAT_B5G6R5_UNORM,
- PIPE_FORMAT_B5G5R5A1_UNORM,
- PIPE_FORMAT_B4G4R4A4_UNORM,
- #PIPE_FORMAT_Z32_UNORM,
- #PIPE_FORMAT_S8_USCALED_Z24_UNORM,
- #PIPE_FORMAT_X8Z24_UNORM,
- #PIPE_FORMAT_Z16_UNORM,
- #PIPE_FORMAT_S8_USCALED,
- PIPE_FORMAT_A8_UNORM,
- PIPE_FORMAT_L8_UNORM,
- #PIPE_FORMAT_DXT1_RGB,
- #PIPE_FORMAT_DXT1_RGBA,
- #PIPE_FORMAT_DXT3_RGBA,
- #PIPE_FORMAT_DXT5_RGBA,
- ]
-
- sizes = [64, 32, 16, 8, 4, 2, 1]
- #sizes = [1020, 508, 252, 62, 30, 14, 6, 3]
- #sizes = [64]
- #sizes = [63]
-
- faces = [
- PIPE_TEX_FACE_POS_X,
- PIPE_TEX_FACE_NEG_X,
- PIPE_TEX_FACE_POS_Y,
- PIPE_TEX_FACE_NEG_Y,
- PIPE_TEX_FACE_POS_Z,
- PIPE_TEX_FACE_NEG_Z,
- ]
-
- for target in targets:
- for format in formats:
- for size in sizes:
- if target == PIPE_TEXTURE_3D:
- depth = size
- else:
- depth = 1
- for face in faces:
- if target != PIPE_TEXTURE_CUBE and face:
- continue
- levels = lods(size)
- for last_level in range(levels):
- for level in range(0, last_level + 1):
- zslice = 0
- while zslice < depth >> level:
- test = TextureTest(
- dev = dev,
- target = target,
- format = format,
- width = size,
- height = size,
- depth = depth,
- last_level = last_level,
- face = face,
- level = level,
- zslice = zslice,
- )
- suite.add_test(test)
- zslice = (zslice + 1)*2 - 1
- suite.run()
-
-
-if __name__ == '__main__':
- main()
diff --git a/src/gallium/tests/python/tests/tree.py b/src/gallium/tests/python/tests/tree.py
deleted file mode 100755
index 0c1bcda4cf2..00000000000
--- a/src/gallium/tests/python/tests/tree.py
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/usr/bin/env python
-#
-# See also:
-# http://www.ailab.si/orange/doc/ofb/c_otherclass.htm
-
-import os.path
-import sys
-
-import orange
-import orngTree
-
-for arg in sys.argv[1:]:
- name, ext = os.path.splitext(arg)
-
- data = orange.ExampleTable(arg)
-
- tree = orngTree.TreeLearner(data, sameMajorityPruning=1, mForPruning=2)
-
- orngTree.printTxt(tree)
-
- file(name+'.txt', 'wt').write(orngTree.dumpTree(tree) + '\n')
-
- orngTree.printDot(tree, fileName=name+'.dot', nodeShape='ellipse', leafShape='box')
diff --git a/src/gallium/tests/trivial/.gitignore b/src/gallium/tests/trivial/.gitignore
deleted file mode 100644
index af6cdedbeba..00000000000
--- a/src/gallium/tests/trivial/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-tri
-quad-tex
-result.bmp
diff --git a/src/gallium/tests/trivial/Makefile b/src/gallium/tests/trivial/Makefile
deleted file mode 100644
index 2ed63419c7e..00000000000
--- a/src/gallium/tests/trivial/Makefile
+++ /dev/null
@@ -1,49 +0,0 @@
-# progs/gallium/simple/Makefile
-
-TOP = ../../../..
-include $(TOP)/configs/current
-
-INCLUDES = \
- -I. \
- -I$(TOP)/src/gallium/include \
- -I$(TOP)/src/gallium/auxiliary \
- -I$(TOP)/src/gallium/drivers \
- -I$(TOP)/src/gallium/winsys \
- $(PROG_INCLUDES)
-
-LINKS = \
- $(TOP)/src/gallium/drivers/rbug/librbug.a \
- $(TOP)/src/gallium/drivers/trace/libtrace.a \
- $(TOP)/src/gallium/drivers/galahad/libgalahad.a \
- $(TOP)/src/gallium/winsys/sw/null/libws_null.a \
- $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
- $(GALLIUM_AUXILIARIES) \
- $(PROG_LINKS)
-
-SOURCES = \
- tri.c \
- quad-tex.c
-
-OBJECTS = $(SOURCES:.c=.o)
-
-PROGS = $(OBJECTS:.o=)
-
-PROG_DEFINES = \
- -DGALLIUM_SOFTPIPE -DGALLIUM_RBUG -DGALLIUM_TRACE -DGALLIUM_GALAHAD
-
-##### TARGETS #####
-
-default: $(PROGS)
-
-clean:
- -rm -f $(PROGS)
- -rm -f *.o
- -rm -f result.bmp
-
-##### RULES #####
-
-$(OBJECTS): %.o: %.c
- $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $(PROG_DEFINES) $< -o $@
-
-$(PROGS): %: %.o $(LINKS)
- $(CC) $(LDFLAGS) $< $(LINKS) -lm -lpthread -ldl -o $@
diff --git a/src/gallium/tests/unit/Makefile b/src/gallium/tests/unit/Makefile
deleted file mode 100644
index bb3039f3bc7..00000000000
--- a/src/gallium/tests/unit/Makefile
+++ /dev/null
@@ -1,49 +0,0 @@
-# progs/gallium/simple/Makefile
-
-TOP = ../../../..
-include $(TOP)/configs/current
-
-INCLUDES = \
- -I. \
- -I$(TOP)/src/gallium/include \
- -I$(TOP)/src/gallium/auxiliary \
- -I$(TOP)/src/gallium/drivers \
- -I$(TOP)/src/gallium/winsys \
- $(PROG_INCLUDES)
-
-LINKS = \
- $(TOP)/src/gallium/drivers/trace/libtrace.a \
- $(TOP)/src/gallium/winsys/sw/null/libws_null.a \
- $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
- $(GALLIUM_AUXILIARIES) \
- $(PROG_LINKS)
-
-SOURCES = \
- pipe_barrier_test.c \
- u_cache_test.c \
- u_half_test.c \
- u_format_test.c \
- u_format_compatible_test.c \
- translate_test.c
-
-
-OBJECTS = $(SOURCES:.c=.o)
-
-PROGS = $(OBJECTS:.o=)
-
-##### TARGETS #####
-
-default: $(PROGS)
-
-clean:
- -rm -f $(PROGS)
- -rm -f *.o
- -rm -f result.bmp
-
-##### RULES #####
-
-$(OBJECTS): %.o: %.c
- $(CC) -c $(INCLUDES) $(CFLAGS) $(DEFINES) $(PROG_DEFINES) $< -o $@
-
-$(PROGS): %: %.o
- $(CC) $(LDFLAGS) $< $(LINKS) -lm -lpthread -ldl -o $@
diff --git a/src/gallium/tests/unit/SConscript b/src/gallium/tests/unit/SConscript
deleted file mode 100644
index 359759e22b2..00000000000
--- a/src/gallium/tests/unit/SConscript
+++ /dev/null
@@ -1,33 +0,0 @@
-Import('*')
-
-env = env.Clone()
-
-env.Prepend(LIBS = [gallium])
-
-if platform in ('freebsd8', 'sunos5'):
- env.Append(LIBS = ['m'])
-
-if platform == 'freebsd8':
- env.Append(LIBS = ['pthread'])
-
-progs = [
- 'pipe_barrier_test',
- 'u_cache_test',
- 'u_format_test',
- 'u_format_compatible_test',
- 'u_half_test',
- 'translate_test'
-]
-
-for prog in progs:
- prog = env.Program(
- target = prog,
- source = prog + '.c',
- )
-
- env.InstallProgram(prog)
-
- # http://www.scons.org/wiki/UnitTests
- test_alias = env.Alias('unit', [prog], prog[0].abspath)
- AlwaysBuild(test_alias)
-
diff --git a/src/gallium/tests/unit/u_cache_test.c b/src/gallium/tests/unit/u_cache_test.c
deleted file mode 100644
index 0b62a765230..00000000000
--- a/src/gallium/tests/unit/u_cache_test.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2010 VMware, Inc.
- * 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 VMWARE 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.
- *
- **************************************************************************/
-
-
-/*
- * Test case for u_cache.
- */
-
-
-#include <assert.h>
-#include <stdio.h>
-
-#include "util/u_cache.h"
-#include "util/u_hash.h"
-
-
-typedef uint32_t cache_test_key;
-typedef uint32_t cache_test_value;
-
-
-static uint32_t
-cache_test_hash(const void *key)
-{
- return util_hash_crc32(key, sizeof(cache_test_key));
-}
-
-
-static void
-cache_test_destroy(void *key, void *value)
-{
- free(key);
- free(value);
-}
-
-
-static int
-cache_test_compare(const void *key1, const void *key2) {
- return !(key1 == key2);
-}
-
-
-int main() {
- unsigned cache_size;
- unsigned cache_count;
-
- for (cache_size = 2; cache_size < (1 << 15); cache_size *= 2) {
- for (cache_count = (cache_size << 5); cache_count < (cache_size << 10); cache_count *= 2) {
- struct util_cache * cache;
- cache_test_key *key;
- cache_test_value *value_in;
- cache_test_value *value_out;
- int i;
-
- printf("Testing cache size of %d with %d values.\n", cache_size, cache_count);
-
- cache = util_cache_create(cache_test_hash,
- cache_test_compare,
- cache_test_destroy,
- cache_size);
-
- /*
- * Retrieve a value from an empty cache.
- */
- key = malloc(sizeof(cache_test_key));
- *key = 0xdeadbeef;
- value_out = (cache_test_value *) util_cache_get(cache, key);
- assert(value_out == NULL);
- free(key);
-
-
- /*
- * Repeatedly insert into and retrieve values from the cache.
- */
- for (i = 0; i < cache_count; i++) {
- key = malloc(sizeof(cache_test_key));
- value_in = malloc(sizeof(cache_test_value));
-
- *key = rand();
- *value_in = rand();
- util_cache_set(cache, key, value_in);
-
- value_out = util_cache_get(cache, key);
- assert(value_out != NULL);
- assert(value_in == value_out);
- assert(*value_in == *value_out);
- }
-
- /*
- * In debug builds, this will trigger a self-check by the cache of
- * the distribution of hits in its internal cache entries.
- */
- util_cache_destroy(cache);
- }
- }
-
- return 0;
-}
diff --git a/src/gallium/tests/unit/u_format_test.c b/src/gallium/tests/unit/u_format_test.c
deleted file mode 100644
index ba0dd17957e..00000000000
--- a/src/gallium/tests/unit/u_format_test.c
+++ /dev/null
@@ -1,716 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2009-2010 VMware, Inc.
- * 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 VMWARE 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.
- *
- **************************************************************************/
-
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <float.h>
-
-#include "util/u_half.h"
-#include "util/u_format.h"
-#include "util/u_format_tests.h"
-#include "util/u_format_s3tc.h"
-
-
-static boolean
-compare_float(float x, float y)
-{
- float error = y - x;
-
- if (error < 0.0f)
- error = -error;
-
- if (error > FLT_EPSILON) {
- return FALSE;
- }
-
- return TRUE;
-}
-
-
-static void
-print_packed(const struct util_format_description *format_desc,
- const char *prefix,
- const uint8_t *packed,
- const char *suffix)
-{
- unsigned i;
- const char *sep = "";
-
- printf("%s", prefix);
- for (i = 0; i < format_desc->block.bits/8; ++i) {
- printf("%s%02x", sep, packed[i]);
- sep = " ";
- }
- printf("%s", suffix);
- fflush(stdout);
-}
-
-
-static void
-print_unpacked_rgba_doubl(const struct util_format_description *format_desc,
- const char *prefix,
- const double unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4],
- const char *suffix)
-{
- unsigned i, j;
- const char *sep = "";
-
- printf("%s", prefix);
- for (i = 0; i < format_desc->block.height; ++i) {
- for (j = 0; j < format_desc->block.width; ++j) {
- printf("%s{%f, %f, %f, %f}", sep, unpacked[i][j][0], unpacked[i][j][1], unpacked[i][j][2], unpacked[i][j][3]);
- sep = ", ";
- }
- sep = ",\n";
- }
- printf("%s", suffix);
- fflush(stdout);
-}
-
-
-static void
-print_unpacked_rgba_float(const struct util_format_description *format_desc,
- const char *prefix,
- float unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4],
- const char *suffix)
-{
- unsigned i, j;
- const char *sep = "";
-
- printf("%s", prefix);
- for (i = 0; i < format_desc->block.height; ++i) {
- for (j = 0; j < format_desc->block.width; ++j) {
- printf("%s{%f, %f, %f, %f}", sep, unpacked[i][j][0], unpacked[i][j][1], unpacked[i][j][2], unpacked[i][j][3]);
- sep = ", ";
- }
- sep = ",\n";
- }
- printf("%s", suffix);
- fflush(stdout);
-}
-
-
-static void
-print_unpacked_rgba_8unorm(const struct util_format_description *format_desc,
- const char *prefix,
- uint8_t unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4],
- const char *suffix)
-{
- unsigned i, j;
- const char *sep = "";
-
- printf("%s", prefix);
- for (i = 0; i < format_desc->block.height; ++i) {
- for (j = 0; j < format_desc->block.width; ++j) {
- printf("%s{0x%02x, 0x%02x, 0x%02x, 0x%02x}", sep, unpacked[i][j][0], unpacked[i][j][1], unpacked[i][j][2], unpacked[i][j][3]);
- sep = ", ";
- }
- }
- printf("%s", suffix);
- fflush(stdout);
-}
-
-
-static void
-print_unpacked_z_float(const struct util_format_description *format_desc,
- const char *prefix,
- float unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH],
- const char *suffix)
-{
- unsigned i, j;
- const char *sep = "";
-
- printf("%s", prefix);
- for (i = 0; i < format_desc->block.height; ++i) {
- for (j = 0; j < format_desc->block.width; ++j) {
- printf("%s%f", sep, unpacked[i][j]);
- sep = ", ";
- }
- sep = ",\n";
- }
- printf("%s", suffix);
- fflush(stdout);
-}
-
-
-static void
-print_unpacked_z_32unorm(const struct util_format_description *format_desc,
- const char *prefix,
- uint32_t unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH],
- const char *suffix)
-{
- unsigned i, j;
- const char *sep = "";
-
- printf("%s", prefix);
- for (i = 0; i < format_desc->block.height; ++i) {
- for (j = 0; j < format_desc->block.width; ++j) {
- printf("%s0x%08x", sep, unpacked[i][j]);
- sep = ", ";
- }
- }
- printf("%s", suffix);
- fflush(stdout);
-}
-
-
-static void
-print_unpacked_s_8uscaled(const struct util_format_description *format_desc,
- const char *prefix,
- uint8_t unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH],
- const char *suffix)
-{
- unsigned i, j;
- const char *sep = "";
-
- printf("%s", prefix);
- for (i = 0; i < format_desc->block.height; ++i) {
- for (j = 0; j < format_desc->block.width; ++j) {
- printf("%s0x%02x", sep, unpacked[i][j]);
- sep = ", ";
- }
- }
- printf("%s", suffix);
- fflush(stdout);
-}
-
-
-static boolean
-test_format_fetch_rgba_float(const struct util_format_description *format_desc,
- const struct util_format_test_case *test)
-{
- float unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4] = { { { 0 } } };
- unsigned i, j, k;
- boolean success;
-
- success = TRUE;
- for (i = 0; i < format_desc->block.height; ++i) {
- for (j = 0; j < format_desc->block.width; ++j) {
- format_desc->fetch_rgba_float(unpacked[i][j], test->packed, j, i);
- for (k = 0; k < 4; ++k) {
- if (!compare_float(test->unpacked[i][j][k], unpacked[i][j][k])) {
- success = FALSE;
- }
- }
- }
- }
-
- if (!success) {
- print_unpacked_rgba_float(format_desc, "FAILED: ", unpacked, " obtained\n");
- print_unpacked_rgba_doubl(format_desc, " ", test->unpacked, " expected\n");
- }
-
- return success;
-}
-
-
-static boolean
-test_format_unpack_rgba_float(const struct util_format_description *format_desc,
- const struct util_format_test_case *test)
-{
- float unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4] = { { { 0 } } };
- unsigned i, j, k;
- boolean success;
-
- format_desc->unpack_rgba_float(&unpacked[0][0][0], sizeof unpacked[0],
- test->packed, 0,
- format_desc->block.width, format_desc->block.height);
-
- success = TRUE;
- for (i = 0; i < format_desc->block.height; ++i) {
- for (j = 0; j < format_desc->block.width; ++j) {
- for (k = 0; k < 4; ++k) {
- if (!compare_float(test->unpacked[i][j][k], unpacked[i][j][k])) {
- success = FALSE;
- }
- }
- }
- }
-
- if (!success) {
- print_unpacked_rgba_float(format_desc, "FAILED: ", unpacked, " obtained\n");
- print_unpacked_rgba_doubl(format_desc, " ", test->unpacked, " expected\n");
- }
-
- return success;
-}
-
-
-static boolean
-test_format_pack_rgba_float(const struct util_format_description *format_desc,
- const struct util_format_test_case *test)
-{
- float unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4];
- uint8_t packed[UTIL_FORMAT_MAX_PACKED_BYTES];
- unsigned i, j, k;
- boolean success;
-
- if (test->format == PIPE_FORMAT_DXT1_RGBA) {
- /*
- * Skip S3TC as packed representation is not canonical.
- *
- * TODO: Do a round trip conversion.
- */
- return TRUE;
- }
-
- memset(packed, 0, sizeof packed);
- for (i = 0; i < format_desc->block.height; ++i) {
- for (j = 0; j < format_desc->block.width; ++j) {
- for (k = 0; k < 4; ++k) {
- unpacked[i][j][k] = (float) test->unpacked[i][j][k];
- }
- }
- }
-
- format_desc->pack_rgba_float(packed, 0,
- &unpacked[0][0][0], sizeof unpacked[0],
- format_desc->block.width, format_desc->block.height);
-
- success = TRUE;
- for (i = 0; i < format_desc->block.bits/8; ++i)
- if ((test->packed[i] & test->mask[i]) != (packed[i] & test->mask[i]))
- success = FALSE;
-
- if (!success) {
- print_packed(format_desc, "FAILED: ", packed, " obtained\n");
- print_packed(format_desc, " ", test->packed, " expected\n");
- }
-
- return success;
-}
-
-
-static boolean
-convert_float_to_8unorm(uint8_t *dst, const double *src)
-{
- unsigned i;
- boolean accurate = TRUE;
-
- for (i = 0; i < UTIL_FORMAT_MAX_UNPACKED_HEIGHT*UTIL_FORMAT_MAX_UNPACKED_WIDTH*4; ++i) {
- if (src[i] < 0.0) {
- accurate = FALSE;
- dst[i] = 0;
- }
- else if (src[i] > 1.0) {
- accurate = FALSE;
- dst[i] = 255;
- }
- else {
- dst[i] = src[i] * 255.0;
- }
- }
-
- return accurate;
-}
-
-
-static boolean
-test_format_unpack_rgba_8unorm(const struct util_format_description *format_desc,
- const struct util_format_test_case *test)
-{
- uint8_t unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4] = { { { 0 } } };
- uint8_t expected[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4] = { { { 0 } } };
- unsigned i, j, k;
- boolean success;
-
- format_desc->unpack_rgba_8unorm(&unpacked[0][0][0], sizeof unpacked[0],
- test->packed, 0,
- format_desc->block.width, format_desc->block.height);
-
- convert_float_to_8unorm(&expected[0][0][0], &test->unpacked[0][0][0]);
-
- success = TRUE;
- for (i = 0; i < format_desc->block.height; ++i) {
- for (j = 0; j < format_desc->block.width; ++j) {
- for (k = 0; k < 4; ++k) {
- if (expected[i][j][k] != unpacked[i][j][k]) {
- success = FALSE;
- }
- }
- }
- }
-
- if (!success) {
- print_unpacked_rgba_8unorm(format_desc, "FAILED: ", unpacked, " obtained\n");
- print_unpacked_rgba_8unorm(format_desc, " ", expected, " expected\n");
- }
-
- return success;
-}
-
-
-static boolean
-test_format_pack_rgba_8unorm(const struct util_format_description *format_desc,
- const struct util_format_test_case *test)
-{
- uint8_t unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH][4];
- uint8_t packed[UTIL_FORMAT_MAX_PACKED_BYTES];
- unsigned i;
- boolean success;
-
- if (test->format == PIPE_FORMAT_DXT1_RGBA) {
- /*
- * Skip S3TC as packed representation is not canonical.
- *
- * TODO: Do a round trip conversion.
- */
- return TRUE;
- }
-
- if (!convert_float_to_8unorm(&unpacked[0][0][0], &test->unpacked[0][0][0])) {
- /*
- * Skip test cases which cannot be represented by four unorm bytes.
- */
- return TRUE;
- }
-
- memset(packed, 0, sizeof packed);
-
- format_desc->pack_rgba_8unorm(packed, 0,
- &unpacked[0][0][0], sizeof unpacked[0],
- format_desc->block.width, format_desc->block.height);
-
- success = TRUE;
- for (i = 0; i < format_desc->block.bits/8; ++i)
- if ((test->packed[i] & test->mask[i]) != (packed[i] & test->mask[i]))
- success = FALSE;
-
- if (!success) {
- print_packed(format_desc, "FAILED: ", packed, " obtained\n");
- print_packed(format_desc, " ", test->packed, " expected\n");
- }
-
- return success;
-}
-
-
-static boolean
-test_format_unpack_z_float(const struct util_format_description *format_desc,
- const struct util_format_test_case *test)
-{
- float unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH] = { { 0 } };
- unsigned i, j;
- boolean success;
-
- format_desc->unpack_z_float(&unpacked[0][0], sizeof unpacked[0],
- test->packed, 0,
- format_desc->block.width, format_desc->block.height);
-
- success = TRUE;
- for (i = 0; i < format_desc->block.height; ++i) {
- for (j = 0; j < format_desc->block.width; ++j) {
- if (!compare_float(test->unpacked[i][j][0], unpacked[i][j])) {
- success = FALSE;
- }
- }
- }
-
- if (!success) {
- print_unpacked_z_float(format_desc, "FAILED: ", unpacked, " obtained\n");
- print_unpacked_rgba_doubl(format_desc, " ", test->unpacked, " expected\n");
- }
-
- return success;
-}
-
-
-static boolean
-test_format_pack_z_float(const struct util_format_description *format_desc,
- const struct util_format_test_case *test)
-{
- float unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH];
- uint8_t packed[UTIL_FORMAT_MAX_PACKED_BYTES];
- unsigned i, j;
- boolean success;
-
- memset(packed, 0, sizeof packed);
- for (i = 0; i < format_desc->block.height; ++i) {
- for (j = 0; j < format_desc->block.width; ++j) {
- unpacked[i][j] = (float) test->unpacked[i][j][0];
- if (test->unpacked[i][j][1]) {
- return TRUE;
- }
- }
- }
-
- format_desc->pack_z_float(packed, 0,
- &unpacked[0][0], sizeof unpacked[0],
- format_desc->block.width, format_desc->block.height);
-
- success = TRUE;
- for (i = 0; i < format_desc->block.bits/8; ++i)
- if ((test->packed[i] & test->mask[i]) != (packed[i] & test->mask[i]))
- success = FALSE;
-
- if (!success) {
- print_packed(format_desc, "FAILED: ", packed, " obtained\n");
- print_packed(format_desc, " ", test->packed, " expected\n");
- }
-
- return success;
-}
-
-
-static boolean
-test_format_unpack_z_32unorm(const struct util_format_description *format_desc,
- const struct util_format_test_case *test)
-{
- uint32_t unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH] = { { 0 } };
- uint32_t expected[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH] = { { 0 } };
- unsigned i, j;
- boolean success;
-
- format_desc->unpack_z_32unorm(&unpacked[0][0], sizeof unpacked[0],
- test->packed, 0,
- format_desc->block.width, format_desc->block.height);
-
- for (i = 0; i < format_desc->block.height; ++i) {
- for (j = 0; j < format_desc->block.width; ++j) {
- expected[i][j] = test->unpacked[i][j][0] * 0xffffffff;
- }
- }
-
- success = TRUE;
- for (i = 0; i < format_desc->block.height; ++i) {
- for (j = 0; j < format_desc->block.width; ++j) {
- if (expected[i][j] != unpacked[i][j]) {
- success = FALSE;
- }
- }
- }
-
- if (!success) {
- print_unpacked_z_32unorm(format_desc, "FAILED: ", unpacked, " obtained\n");
- print_unpacked_z_32unorm(format_desc, " ", expected, " expected\n");
- }
-
- return success;
-}
-
-
-static boolean
-test_format_pack_z_32unorm(const struct util_format_description *format_desc,
- const struct util_format_test_case *test)
-{
- uint32_t unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH];
- uint8_t packed[UTIL_FORMAT_MAX_PACKED_BYTES];
- unsigned i, j;
- boolean success;
-
- for (i = 0; i < format_desc->block.height; ++i) {
- for (j = 0; j < format_desc->block.width; ++j) {
- unpacked[i][j] = test->unpacked[i][j][0] * 0xffffffff;
- if (test->unpacked[i][j][1]) {
- return TRUE;
- }
- }
- }
-
- memset(packed, 0, sizeof packed);
-
- format_desc->pack_z_32unorm(packed, 0,
- &unpacked[0][0], sizeof unpacked[0],
- format_desc->block.width, format_desc->block.height);
-
- success = TRUE;
- for (i = 0; i < format_desc->block.bits/8; ++i)
- if ((test->packed[i] & test->mask[i]) != (packed[i] & test->mask[i]))
- success = FALSE;
-
- if (!success) {
- print_packed(format_desc, "FAILED: ", packed, " obtained\n");
- print_packed(format_desc, " ", test->packed, " expected\n");
- }
-
- return success;
-}
-
-
-static boolean
-test_format_unpack_s_8uscaled(const struct util_format_description *format_desc,
- const struct util_format_test_case *test)
-{
- uint8_t unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH] = { { 0 } };
- uint8_t expected[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH] = { { 0 } };
- unsigned i, j;
- boolean success;
-
- format_desc->unpack_s_8uscaled(&unpacked[0][0], sizeof unpacked[0],
- test->packed, 0,
- format_desc->block.width, format_desc->block.height);
-
- for (i = 0; i < format_desc->block.height; ++i) {
- for (j = 0; j < format_desc->block.width; ++j) {
- expected[i][j] = test->unpacked[i][j][1];
- }
- }
-
- success = TRUE;
- for (i = 0; i < format_desc->block.height; ++i) {
- for (j = 0; j < format_desc->block.width; ++j) {
- if (expected[i][j] != unpacked[i][j]) {
- success = FALSE;
- }
- }
- }
-
- if (!success) {
- print_unpacked_s_8uscaled(format_desc, "FAILED: ", unpacked, " obtained\n");
- print_unpacked_s_8uscaled(format_desc, " ", expected, " expected\n");
- }
-
- return success;
-}
-
-
-static boolean
-test_format_pack_s_8uscaled(const struct util_format_description *format_desc,
- const struct util_format_test_case *test)
-{
- uint8_t unpacked[UTIL_FORMAT_MAX_UNPACKED_HEIGHT][UTIL_FORMAT_MAX_UNPACKED_WIDTH];
- uint8_t packed[UTIL_FORMAT_MAX_PACKED_BYTES];
- unsigned i, j;
- boolean success;
-
- for (i = 0; i < format_desc->block.height; ++i) {
- for (j = 0; j < format_desc->block.width; ++j) {
- unpacked[i][j] = test->unpacked[i][j][1];
- if (test->unpacked[i][j][0]) {
- return TRUE;
- }
- }
- }
-
- memset(packed, 0, sizeof packed);
-
- format_desc->pack_s_8uscaled(packed, 0,
- &unpacked[0][0], sizeof unpacked[0],
- format_desc->block.width, format_desc->block.height);
-
- success = TRUE;
- for (i = 0; i < format_desc->block.bits/8; ++i)
- if ((test->packed[i] & test->mask[i]) != (packed[i] & test->mask[i]))
- success = FALSE;
-
- if (!success) {
- print_packed(format_desc, "FAILED: ", packed, " obtained\n");
- print_packed(format_desc, " ", test->packed, " expected\n");
- }
-
- return success;
-}
-
-
-typedef boolean
-(*test_func_t)(const struct util_format_description *format_desc,
- const struct util_format_test_case *test);
-
-
-static boolean
-test_one_func(const struct util_format_description *format_desc,
- test_func_t func,
- const char *suffix)
-{
- unsigned i;
- bool success = TRUE;
-
- printf("Testing util_format_%s_%s ...\n",
- format_desc->short_name, suffix);
- fflush(stdout);
-
- for (i = 0; i < util_format_nr_test_cases; ++i) {
- const struct util_format_test_case *test = &util_format_test_cases[i];
-
- if (test->format == format_desc->format) {
- if (!func(format_desc, &util_format_test_cases[i])) {
- success = FALSE;
- }
- }
- }
-
- return success;
-}
-
-
-static boolean
-test_all(void)
-{
- enum pipe_format format;
- bool success = TRUE;
-
- for (format = 1; format < PIPE_FORMAT_COUNT; ++format) {
- const struct util_format_description *format_desc;
-
- format_desc = util_format_description(format);
- if (!format_desc) {
- continue;
- }
-
- if (format_desc->layout == UTIL_FORMAT_LAYOUT_S3TC &&
- !util_format_s3tc_enabled) {
- continue;
- }
-
-# define TEST_ONE_FUNC(name) \
- if (format_desc->name) { \
- if (!test_one_func(format_desc, &test_format_##name, #name)) { \
- success = FALSE; \
- } \
- }
-
- TEST_ONE_FUNC(fetch_rgba_float);
- TEST_ONE_FUNC(pack_rgba_float);
- TEST_ONE_FUNC(unpack_rgba_float);
- TEST_ONE_FUNC(pack_rgba_8unorm);
- TEST_ONE_FUNC(unpack_rgba_8unorm);
-
- TEST_ONE_FUNC(unpack_z_32unorm);
- TEST_ONE_FUNC(pack_z_32unorm);
- TEST_ONE_FUNC(unpack_z_float);
- TEST_ONE_FUNC(pack_z_float);
- TEST_ONE_FUNC(unpack_s_8uscaled);
- TEST_ONE_FUNC(pack_s_8uscaled);
-
-# undef TEST_ONE_FUNC
- }
-
- return success;
-}
-
-
-int main(int argc, char **argv)
-{
- boolean success;
-
- util_format_s3tc_init();
-
- success = test_all();
-
- return success ? 0 : 1;
-}
diff --git a/src/gallium/tests/unit/u_half_test.c b/src/gallium/tests/unit/u_half_test.c
deleted file mode 100644
index 00bda7f50a6..00000000000
--- a/src/gallium/tests/unit/u_half_test.c
+++ /dev/null
@@ -1,32 +0,0 @@
-#include <stdlib.h>
-#include <stdio.h>
-#include <float.h>
-
-#include "util/u_math.h"
-#include "util/u_half.h"
-
-int
-main(int argc, char **argv)
-{
- unsigned i;
- unsigned roundtrip_fails = 0;
- for(i = 0; i < 1 << 16; ++i)
- {
- uint16_t h = (uint16_t) i;
- union fi f;
- uint16_t rh;
- f.ui = util_half_to_floatui(h);
- rh = util_floatui_to_half(f.ui);
- if(h != rh)
- {
- printf("Roundtrip failed: %x -> %x = %f -> %x\n", h, f.ui, f.f, rh);
- ++roundtrip_fails;
- }
- }
-
- if(roundtrip_fails)
- printf("Failure! %u/65536 half floats failed a conversion to float and back.\n", roundtrip_fails);
- else
- printf("Success!\n");
- return 0;
-}
diff --git a/src/gallium/winsys/g3dvl/Makefile b/src/gallium/winsys/g3dvl/Makefile
new file mode 100644
index 00000000000..6c793e0f15b
--- /dev/null
+++ b/src/gallium/winsys/g3dvl/Makefile
@@ -0,0 +1,12 @@
+# src/gallium/winsys/Makefile
+TOP = ../../../..
+include $(TOP)/configs/current
+
+SUBDIRS = $(GALLIUM_STATE_TRACKERS_DIRS) $(GALLIUM_WINSYS_DIRS)
+
+default install clean:
+ @for dir in $(SUBDIRS) ; do \
+ if [ -d $$dir ] ; then \
+ (cd $$dir && $(MAKE) $@) || exit 1; \
+ fi \
+ done
diff --git a/src/gallium/winsys/g3dvl/dri/Makefile b/src/gallium/winsys/g3dvl/dri/Makefile
new file mode 100644
index 00000000000..b270e780fec
--- /dev/null
+++ b/src/gallium/winsys/g3dvl/dri/Makefile
@@ -0,0 +1,15 @@
+TOP = ../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = vldri
+
+LIBRARY_INCLUDES = -I$(TOP)/src/gallium/winsys/g3dvl \
+ $(shell pkg-config libdrm --cflags-only-I)
+
+C_SOURCES = \
+ driclient.c \
+ XF86dri.c \
+ dri2.c \
+ dri_winsys.c
+
+include ../../../Makefile.template
diff --git a/src/driclient/src/XF86dri.c b/src/gallium/winsys/g3dvl/dri/XF86dri.c
index 831a7603396..831a7603396 100644
--- a/src/driclient/src/XF86dri.c
+++ b/src/gallium/winsys/g3dvl/dri/XF86dri.c
diff --git a/src/gallium/winsys/g3dvl/dri/dri2.c b/src/gallium/winsys/g3dvl/dri/dri2.c
new file mode 100644
index 00000000000..23fb7780882
--- /dev/null
+++ b/src/gallium/winsys/g3dvl/dri/dri2.c
@@ -0,0 +1,669 @@
+/*
+ * 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 ([email protected])
+ */
+
+
+#define NEED_REPLIES
+#include <stdio.h>
+#include <X11/Xlibint.h>
+#include <X11/extensions/Xext.h>
+#include <X11/extensions/extutil.h>
+#include <X11/extensions/dri2proto.h>
+#include "xf86drm.h"
+#include "dri2.h"
+#if 0
+#include "glxclient.h"
+#include "GL/glxext.h"
+#endif
+
+/* Allow the build to work with an older versions of dri2proto.h and
+ * dri2tokens.h.
+ */
+#if DRI2_MINOR < 1
+#undef DRI2_MINOR
+#define DRI2_MINOR 1
+#define X_DRI2GetBuffersWithFormat 7
+#endif
+
+
+static char dri2ExtensionName[] = DRI2_NAME;
+static XExtensionInfo *dri2Info;
+static XEXT_GENERATE_CLOSE_DISPLAY (DRI2CloseDisplay, dri2Info)
+
+static Bool
+DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire);
+static Status
+DRI2EventToWire(Display *dpy, XEvent *event, xEvent *wire);
+
+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 */
+ DRI2WireToEvent, /* wire_to_event */
+ DRI2EventToWire, /* event_to_wire */
+ NULL, /* error */
+ NULL, /* error_string */
+};
+
+static XEXT_GENERATE_FIND_DISPLAY (DRI2FindDisplay,
+ dri2Info,
+ dri2ExtensionName,
+ &dri2ExtensionHooks,
+ 0, NULL)
+
+static Bool
+DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire)
+{
+#if 0
+ XExtDisplayInfo *info = DRI2FindDisplay(dpy);
+ XExtDisplayInfo *glx_info = __glXFindDisplay(dpy);
+
+ XextCheckExtension(dpy, info, dri2ExtensionName, False);
+
+ switch ((wire->u.u.type & 0x7f) - info->codes->first_event) {
+
+#ifdef X_DRI2SwapBuffers
+ case DRI2_BufferSwapComplete:
+ {
+ GLXBufferSwapComplete *aevent = (GLXBufferSwapComplete *)event;
+ xDRI2BufferSwapComplete *awire = (xDRI2BufferSwapComplete *)wire;
+ aevent->serial = _XSetLastRequestRead(dpy, (xGenericReply *) wire);
+ aevent->type =
+ (glx_info->codes->first_event + GLX_BufferSwapComplete) & 0x75;
+ aevent->send_event = (awire->type & 0x80) != 0;
+ aevent->display = dpy;
+ aevent->drawable = awire->drawable;
+ switch (awire->event_type) {
+ case DRI2_EXCHANGE_COMPLETE:
+ aevent->event_type = GLX_EXCHANGE_COMPLETE_INTEL;
+ break;
+ case DRI2_BLIT_COMPLETE:
+ aevent->event_type = GLX_BLIT_COMPLETE_INTEL;
+ break;
+ case DRI2_FLIP_COMPLETE:
+ aevent->event_type = GLX_FLIP_COMPLETE_INTEL;
+ break;
+ default:
+ /* unknown swap completion type */
+ return False;
+ }
+ aevent->ust = ((CARD64)awire->ust_hi << 32) | awire->ust_lo;
+ aevent->msc = ((CARD64)awire->msc_hi << 32) | awire->msc_lo;
+ aevent->sbc = ((CARD64)awire->sbc_hi << 32) | awire->sbc_lo;
+ return True;
+ }
+#endif
+#ifdef DRI2_InvalidateBuffers
+ case DRI2_InvalidateBuffers:
+ {
+ xDRI2InvalidateBuffers *awire = (xDRI2InvalidateBuffers *)wire;
+
+ dri2InvalidateBuffers(dpy, awire->drawable);
+ return False;
+ }
+#endif
+ default:
+ /* client doesn't support server event */
+ break;
+ }
+#endif
+ return False;
+}
+
+/* We don't actually support this. It doesn't make sense for clients to
+ * send each other DRI2 events.
+ */
+static Status
+DRI2EventToWire(Display *dpy, XEvent *event, xEvent *wire)
+{
+ XExtDisplayInfo *info = DRI2FindDisplay(dpy);
+
+ XextCheckExtension(dpy, info, dri2ExtensionName, False);
+
+ switch (event->type) {
+ default:
+ /* client doesn't support server event */
+ break;
+ }
+
+ return Success;
+}
+
+Bool
+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
+DRI2QueryVersion(Display * dpy, int *major, int *minor)
+{
+ XExtDisplayInfo *info = DRI2FindDisplay(dpy);
+ xDRI2QueryVersionReply rep;
+ xDRI2QueryVersionReq *req;
+ int i, nevents;
+
+ 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();
+
+ switch (rep.minorVersion) {
+ case 1:
+ nevents = 0;
+ break;
+ case 2:
+ nevents = 1;
+ break;
+ case 3:
+ default:
+ nevents = 2;
+ break;
+ }
+
+ for (i = 0; i < nevents; i++) {
+ XESetWireToEvent (dpy, info->codes->first_event + i, DRI2WireToEvent);
+ XESetEventToWire (dpy, info->codes->first_event + i, DRI2EventToWire);
+ }
+
+ return True;
+}
+
+Bool
+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 = 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
+DRI2Authenticate(Display * dpy, XID window, drm_magic_t magic)
+{
+ XExtDisplayInfo *info = DRI2FindDisplay(dpy);
+ xDRI2AuthenticateReq *req;
+ xDRI2AuthenticateReply rep;
+
+ XextCheckExtension(dpy, info, 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
+DRI2CreateDrawable(Display * dpy, XID drawable)
+{
+ XExtDisplayInfo *info = DRI2FindDisplay(dpy);
+ xDRI2CreateDrawableReq *req;
+
+ XextSimpleCheckExtension(dpy, info, dri2ExtensionName);
+
+ LockDisplay(dpy);
+ GetReq(DRI2CreateDrawable, req);
+ req->reqType = info->codes->major_opcode;
+ req->dri2ReqType = X_DRI2CreateDrawable;
+ req->drawable = drawable;
+ UnlockDisplay(dpy);
+ SyncHandle();
+}
+
+void
+DRI2DestroyDrawable(Display * dpy, XID drawable)
+{
+ XExtDisplayInfo *info = DRI2FindDisplay(dpy);
+ xDRI2DestroyDrawableReq *req;
+
+ XextSimpleCheckExtension(dpy, info, 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();
+}
+
+DRI2Buffer *
+DRI2GetBuffers(Display * dpy, XID drawable,
+ int *width, int *height,
+ unsigned int *attachments, int count, int *outCount)
+{
+ XExtDisplayInfo *info = DRI2FindDisplay(dpy);
+ xDRI2GetBuffersReply rep;
+ xDRI2GetBuffersReq *req;
+ DRI2Buffer *buffers;
+ xDRI2Buffer repBuffer;
+ CARD32 *p;
+ int i;
+
+ XextCheckExtension(dpy, info, 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;
+}
+
+
+DRI2Buffer *
+DRI2GetBuffersWithFormat(Display * dpy, XID drawable,
+ int *width, int *height,
+ unsigned int *attachments, int count, int *outCount)
+{
+ XExtDisplayInfo *info = DRI2FindDisplay(dpy);
+ xDRI2GetBuffersReply rep;
+ xDRI2GetBuffersReq *req;
+ DRI2Buffer *buffers;
+ xDRI2Buffer repBuffer;
+ CARD32 *p;
+ int i;
+
+ XextCheckExtension(dpy, info, dri2ExtensionName, False);
+
+ LockDisplay(dpy);
+ GetReqExtra(DRI2GetBuffers, count * (4 * 2), req);
+ req->reqType = info->codes->major_opcode;
+ req->dri2ReqType = X_DRI2GetBuffersWithFormat;
+ req->drawable = drawable;
+ req->count = count;
+ p = (CARD32 *) & req[1];
+ for (i = 0; i < (count * 2); 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
+DRI2CopyRegion(Display * dpy, XID drawable, XserverRegion region,
+ CARD32 dest, CARD32 src)
+{
+ XExtDisplayInfo *info = DRI2FindDisplay(dpy);
+ xDRI2CopyRegionReq *req;
+ xDRI2CopyRegionReply rep;
+
+ XextSimpleCheckExtension(dpy, info, 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();
+}
+
+#ifdef X_DRI2SwapBuffers
+static void
+load_swap_req(xDRI2SwapBuffersReq *req, CARD64 target, CARD64 divisor,
+ CARD64 remainder)
+{
+ req->target_msc_hi = target >> 32;
+ req->target_msc_lo = target & 0xffffffff;
+ req->divisor_hi = divisor >> 32;
+ req->divisor_lo = divisor & 0xffffffff;
+ req->remainder_hi = remainder >> 32;
+ req->remainder_lo = remainder & 0xffffffff;
+}
+
+static CARD64
+vals_to_card64(CARD32 lo, CARD32 hi)
+{
+ return (CARD64)hi << 32 | lo;
+}
+
+void DRI2SwapBuffers(Display *dpy, XID drawable, CARD64 target_msc,
+ CARD64 divisor, CARD64 remainder, CARD64 *count)
+{
+ XExtDisplayInfo *info = DRI2FindDisplay(dpy);
+ xDRI2SwapBuffersReq *req;
+ xDRI2SwapBuffersReply rep;
+
+ XextSimpleCheckExtension (dpy, info, dri2ExtensionName);
+
+ LockDisplay(dpy);
+ GetReq(DRI2SwapBuffers, req);
+ req->reqType = info->codes->major_opcode;
+ req->dri2ReqType = X_DRI2SwapBuffers;
+ req->drawable = drawable;
+ load_swap_req(req, target_msc, divisor, remainder);
+
+ _XReply(dpy, (xReply *)&rep, 0, xFalse);
+
+ *count = vals_to_card64(rep.swap_lo, rep.swap_hi);
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+}
+#endif
+
+#ifdef X_DRI2GetMSC
+Bool DRI2GetMSC(Display *dpy, XID drawable, CARD64 *ust, CARD64 *msc,
+ CARD64 *sbc)
+{
+ XExtDisplayInfo *info = DRI2FindDisplay(dpy);
+ xDRI2GetMSCReq *req;
+ xDRI2MSCReply rep;
+
+ XextCheckExtension (dpy, info, dri2ExtensionName, False);
+
+ LockDisplay(dpy);
+ GetReq(DRI2GetMSC, req);
+ req->reqType = info->codes->major_opcode;
+ req->dri2ReqType = X_DRI2GetMSC;
+ req->drawable = drawable;
+
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return False;
+ }
+
+ *ust = vals_to_card64(rep.ust_lo, rep.ust_hi);
+ *msc = vals_to_card64(rep.msc_lo, rep.msc_hi);
+ *sbc = vals_to_card64(rep.sbc_lo, rep.sbc_hi);
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return True;
+}
+#endif
+
+#ifdef X_DRI2WaitMSC
+static void
+load_msc_req(xDRI2WaitMSCReq *req, CARD64 target, CARD64 divisor,
+ CARD64 remainder)
+{
+ req->target_msc_hi = target >> 32;
+ req->target_msc_lo = target & 0xffffffff;
+ req->divisor_hi = divisor >> 32;
+ req->divisor_lo = divisor & 0xffffffff;
+ req->remainder_hi = remainder >> 32;
+ req->remainder_lo = remainder & 0xffffffff;
+}
+
+Bool DRI2WaitMSC(Display *dpy, XID drawable, CARD64 target_msc, CARD64 divisor,
+ CARD64 remainder, CARD64 *ust, CARD64 *msc, CARD64 *sbc)
+{
+ XExtDisplayInfo *info = DRI2FindDisplay(dpy);
+ xDRI2WaitMSCReq *req;
+ xDRI2MSCReply rep;
+
+ XextCheckExtension (dpy, info, dri2ExtensionName, False);
+
+ LockDisplay(dpy);
+ GetReq(DRI2WaitMSC, req);
+ req->reqType = info->codes->major_opcode;
+ req->dri2ReqType = X_DRI2WaitMSC;
+ req->drawable = drawable;
+ load_msc_req(req, target_msc, divisor, remainder);
+
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return False;
+ }
+
+ *ust = ((CARD64)rep.ust_hi << 32) | (CARD64)rep.ust_lo;
+ *msc = ((CARD64)rep.msc_hi << 32) | (CARD64)rep.msc_lo;
+ *sbc = ((CARD64)rep.sbc_hi << 32) | (CARD64)rep.sbc_lo;
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return True;
+}
+#endif
+
+#ifdef X_DRI2WaitSBC
+static void
+load_sbc_req(xDRI2WaitSBCReq *req, CARD64 target)
+{
+ req->target_sbc_hi = target >> 32;
+ req->target_sbc_lo = target & 0xffffffff;
+}
+
+Bool DRI2WaitSBC(Display *dpy, XID drawable, CARD64 target_sbc, CARD64 *ust,
+ CARD64 *msc, CARD64 *sbc)
+{
+ XExtDisplayInfo *info = DRI2FindDisplay(dpy);
+ xDRI2WaitSBCReq *req;
+ xDRI2MSCReply rep;
+
+ XextCheckExtension (dpy, info, dri2ExtensionName, False);
+
+ LockDisplay(dpy);
+ GetReq(DRI2WaitSBC, req);
+ req->reqType = info->codes->major_opcode;
+ req->dri2ReqType = X_DRI2WaitSBC;
+ req->drawable = drawable;
+ load_sbc_req(req, target_sbc);
+
+ if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return False;
+ }
+
+ *ust = ((CARD64)rep.ust_hi << 32) | rep.ust_lo;
+ *msc = ((CARD64)rep.msc_hi << 32) | rep.msc_lo;
+ *sbc = ((CARD64)rep.sbc_hi << 32) | rep.sbc_lo;
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return True;
+}
+#endif
+
+#ifdef X_DRI2SwapInterval
+void DRI2SwapInterval(Display *dpy, XID drawable, int interval)
+{
+ XExtDisplayInfo *info = DRI2FindDisplay(dpy);
+ xDRI2SwapIntervalReq *req;
+
+ XextSimpleCheckExtension (dpy, info, dri2ExtensionName);
+
+ LockDisplay(dpy);
+ GetReq(DRI2SwapInterval, req);
+ req->reqType = info->codes->major_opcode;
+ req->dri2ReqType = X_DRI2SwapInterval;
+ req->drawable = drawable;
+ req->interval = interval;
+ UnlockDisplay(dpy);
+ SyncHandle();
+}
+#endif
diff --git a/src/gallium/winsys/g3dvl/dri/dri2.h b/src/gallium/winsys/g3dvl/dri/dri2.h
new file mode 100644
index 00000000000..114e9f8f965
--- /dev/null
+++ b/src/gallium/winsys/g3dvl/dri/dri2.h
@@ -0,0 +1,106 @@
+/*
+ * 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 ([email protected])
+ */
+
+#ifndef _DRI2_H_
+#define _DRI2_H_
+
+#include <X11/extensions/Xfixes.h>
+#include <X11/extensions/dri2tokens.h>
+
+typedef struct
+{
+ unsigned int attachment;
+ unsigned int name;
+ unsigned int pitch;
+ unsigned int cpp;
+ unsigned int flags;
+} DRI2Buffer;
+
+extern Bool
+DRI2QueryExtension(Display * display, int *eventBase, int *errorBase);
+
+extern Bool
+DRI2QueryVersion(Display * display, int *major, int *minor);
+
+extern Bool
+DRI2Connect(Display * display, XID window,
+ char **driverName, char **deviceName);
+
+extern Bool
+DRI2Authenticate(Display * display, XID window, drm_magic_t magic);
+
+extern void
+DRI2CreateDrawable(Display * display, XID drawable);
+
+extern void
+DRI2DestroyDrawable(Display * display, XID handle);
+
+extern DRI2Buffer*
+DRI2GetBuffers(Display * dpy, XID drawable,
+ int *width, int *height,
+ unsigned int *attachments, int count,
+ int *outCount);
+
+/**
+ * \note
+ * This function is only supported with DRI2 version 1.1 or later.
+ */
+extern DRI2Buffer*
+DRI2GetBuffersWithFormat(Display * dpy, XID drawable,
+ int *width, int *height,
+ unsigned int *attachments,
+ int count, int *outCount);
+
+extern void
+DRI2CopyRegion(Display * dpy, XID drawable,
+ XserverRegion region,
+ CARD32 dest, CARD32 src);
+
+extern void
+DRI2SwapBuffers(Display *dpy, XID drawable, CARD64 target_msc, CARD64 divisor,
+ CARD64 remainder, CARD64 *count);
+
+extern Bool
+DRI2GetMSC(Display *dpy, XID drawable, CARD64 *ust, CARD64 *msc, CARD64 *sbc);
+
+extern Bool
+DRI2WaitMSC(Display *dpy, XID drawable, CARD64 target_msc, CARD64 divisor,
+ CARD64 remainder, CARD64 *ust, CARD64 *msc, CARD64 *sbc);
+
+extern Bool
+DRI2WaitSBC(Display *dpy, XID drawable, CARD64 target_sbc, CARD64 *ust,
+ CARD64 *msc, CARD64 *sbc);
+
+extern void
+DRI2SwapInterval(Display *dpy, XID drawable, int interval);
+
+#endif
diff --git a/src/gallium/winsys/g3dvl/dri/dri_winsys.c b/src/gallium/winsys/g3dvl/dri/dri_winsys.c
new file mode 100644
index 00000000000..06631840f78
--- /dev/null
+++ b/src/gallium/winsys/g3dvl/dri/dri_winsys.c
@@ -0,0 +1,287 @@
+/**************************************************************************
+ *
+ * Copyright 2009 Younes Manton.
+ * 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 TUNGSTEN GRAPHICS 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.
+ *
+ **************************************************************************/
+
+#include <vl_winsys.h>
+#include <driclient.h>
+#include <pipe/p_video_context.h>
+#include <pipe/p_state.h>
+#include <util/u_memory.h>
+#include <util/u_hash.h>
+#include <util/u_hash_table.h>
+#include <state_tracker/drm_api.h>
+#include <X11/Xlibint.h>
+
+struct vl_dri_screen
+{
+ struct vl_screen base;
+ struct drm_api *api;
+ dri_screen_t *dri_screen;
+ struct util_hash_table *drawable_table;
+ Drawable last_seen_drawable;
+};
+
+struct vl_dri_context
+{
+ struct vl_context base;
+ int fd;
+};
+
+static struct pipe_surface*
+vl_dri2_get_front(struct vl_dri_screen *vl_dri_scrn, Drawable drawable)
+{
+ int w, h;
+ unsigned int attachments[1] = {DRI_BUFFER_FRONT_LEFT};
+ int count;
+ DRI2Buffer *dri2_front;
+ struct pipe_resource *front_tex;
+ struct pipe_surface *front_surf = NULL;
+
+ assert(vl_dri_scrn);
+
+ dri2_front = DRI2GetBuffers(vl_dri_scrn->dri_screen->display,
+ drawable, &w, &h, attachments, 1, &count);
+
+ assert(count == 1);
+
+ if (dri2_front) {
+ struct winsys_handle dri2_front_handle =
+ {
+ .type = DRM_API_HANDLE_TYPE_SHARED,
+ .handle = dri2_front->name,
+ .stride = dri2_front->pitch
+ };
+ struct pipe_resource template;
+
+ memset(&template, 0, sizeof(struct pipe_resource));
+ template.target = PIPE_TEXTURE_2D;
+ template.format = PIPE_FORMAT_B8G8R8X8_UNORM;
+ template.last_level = 0;
+ template.width0 = w;
+ template.height0 = h;
+ template.depth0 = 1;
+ template.usage = PIPE_USAGE_STATIC;
+ template.bind = PIPE_BIND_RENDER_TARGET;
+ template.flags = 0;
+
+ front_tex = vl_dri_scrn->base.pscreen->resource_from_handle(vl_dri_scrn->base.pscreen, &template, &dri2_front_handle);
+ if (front_tex)
+ front_surf = vl_dri_scrn->base.pscreen->get_tex_surface(vl_dri_scrn->base.pscreen,
+ front_tex, 0, 0, 0,
+ PIPE_BIND_RENDER_TARGET);
+ pipe_resource_reference(&front_tex, NULL);
+ Xfree(dri2_front);
+ }
+
+ return front_surf;
+}
+
+static void
+vl_dri2_flush_frontbuffer(struct pipe_screen *screen,
+ struct pipe_surface *surf, void *context_private)
+{
+ struct vl_dri_context *vl_dri_ctx = (struct vl_dri_context*)context_private;
+ struct vl_dri_screen *vl_dri_scrn = (struct vl_dri_screen*)vl_dri_ctx->base.vscreen;
+
+ assert(screen);
+ assert(surf);
+ assert(context_private);
+
+ dri2CopyDrawable(vl_dri_scrn->dri_screen, vl_dri_scrn->last_seen_drawable,
+ DRI_BUFFER_FRONT_LEFT, DRI_BUFFER_FAKE_FRONT_LEFT);
+}
+
+struct pipe_surface*
+vl_drawable_surface_get(struct vl_screen *vscreen, Drawable drawable)
+{
+ struct vl_dri_screen *vl_dri_scrn = (struct vl_dri_screen*)vscreen;
+
+ assert(vscreen);
+
+ if (vl_dri_scrn->last_seen_drawable != drawable) {
+ /* Hash table business depends on this equality */
+ assert(None == NULL);
+ Drawable lookup_drawable = (Drawable)util_hash_table_get(vl_dri_scrn->drawable_table, (void*)drawable);
+ if (lookup_drawable == None) {
+ dri2CreateDrawable(vl_dri_scrn->dri_screen, drawable);
+ util_hash_table_set(vl_dri_scrn->drawable_table, (void*)drawable, (void*)drawable);
+ }
+ vl_dri_scrn->last_seen_drawable = drawable;
+ }
+
+ return vl_dri2_get_front(vl_dri_scrn, drawable);
+}
+
+void*
+vl_contextprivate_get(struct vl_context *vctx, struct pipe_surface *displaytarget)
+{
+ return vctx;
+}
+
+static unsigned drawable_hash(void *key)
+{
+ Drawable drawable = (Drawable)key;
+ assert(drawable != None);
+ return util_hash_crc32(&drawable, sizeof(Drawable));
+}
+
+static int drawable_cmp(void *key1, void *key2)
+{
+ Drawable d1 = (Drawable)key1;
+ Drawable d2 = (Drawable)key2;
+ assert(d1 != None);
+ assert(d2 != None);
+ return d1 != d2;
+}
+
+static enum pipe_error
+drawable_destroy(void *key, void *value, void *data)
+{
+ Drawable drawable = (Drawable)key;
+ struct vl_dri_screen *vl_dri_scrn = (struct vl_dri_screen*)data;
+
+ assert(drawable != None);
+ assert(value);
+ assert(data);
+
+ dri2DestroyDrawable(vl_dri_scrn->dri_screen, drawable);
+
+ return PIPE_OK;
+}
+
+struct vl_screen*
+vl_screen_create(Display *display, int screen)
+{
+ struct vl_dri_screen *vl_dri_scrn;
+ struct drm_create_screen_arg arg;
+
+ assert(display);
+
+ vl_dri_scrn = CALLOC_STRUCT(vl_dri_screen);
+ if (!vl_dri_scrn)
+ goto no_struct;
+
+ if (dri2CreateScreen(display, screen, &vl_dri_scrn->dri_screen))
+ goto no_dri2screen;
+
+ vl_dri_scrn->api = drm_api_create();
+ if (!vl_dri_scrn->api)
+ goto no_drmapi;
+
+ arg.mode = DRM_CREATE_NORMAL;
+
+ vl_dri_scrn->base.pscreen = vl_dri_scrn->api->create_screen(vl_dri_scrn->api,
+ vl_dri_scrn->dri_screen->fd,
+ &arg);
+
+ if (!vl_dri_scrn->base.pscreen)
+ goto no_pscreen;
+
+ vl_dri_scrn->drawable_table = util_hash_table_create(&drawable_hash, &drawable_cmp);
+ if (!vl_dri_scrn->drawable_table)
+ goto no_hash;
+
+ vl_dri_scrn->last_seen_drawable = None;
+ vl_dri_scrn->base.pscreen->flush_frontbuffer = vl_dri2_flush_frontbuffer;
+
+ return &vl_dri_scrn->base;
+
+no_hash:
+ vl_dri_scrn->base.pscreen->destroy(vl_dri_scrn->base.pscreen);
+no_pscreen:
+ vl_dri_scrn->api->destroy(vl_dri_scrn->api);
+no_drmapi:
+ dri2DestroyScreen(vl_dri_scrn->dri_screen);
+no_dri2screen:
+ FREE(vl_dri_scrn);
+no_struct:
+ return NULL;
+}
+
+void vl_screen_destroy(struct vl_screen *vscreen)
+{
+ struct vl_dri_screen *vl_dri_scrn = (struct vl_dri_screen*)vscreen;
+
+ assert(vscreen);
+
+ util_hash_table_foreach(vl_dri_scrn->drawable_table, drawable_destroy, vl_dri_scrn);
+ util_hash_table_destroy(vl_dri_scrn->drawable_table);
+ vl_dri_scrn->base.pscreen->destroy(vl_dri_scrn->base.pscreen);
+ if (vl_dri_scrn->api->destroy)
+ vl_dri_scrn->api->destroy(vl_dri_scrn->api);
+ dri2DestroyScreen(vl_dri_scrn->dri_screen);
+ FREE(vl_dri_scrn);
+}
+
+struct vl_context*
+vl_video_create(struct vl_screen *vscreen,
+ enum pipe_video_profile profile,
+ enum pipe_video_chroma_format chroma_format,
+ unsigned width, unsigned height)
+{
+ struct vl_dri_screen *vl_dri_scrn = (struct vl_dri_screen*)vscreen;
+ struct vl_dri_context *vl_dri_ctx;
+
+ vl_dri_ctx = CALLOC_STRUCT(vl_dri_context);
+ if (!vl_dri_ctx)
+ goto no_struct;
+
+ if (!vscreen->pscreen->video_context_create) {
+ debug_printf("[G3DVL] No video support found on %s/%s.\n",
+ vscreen->pscreen->get_vendor(vscreen->pscreen),
+ vscreen->pscreen->get_name(vscreen->pscreen));
+ goto no_vpipe;
+ }
+
+ vl_dri_ctx->base.vpipe = vscreen->pscreen->video_context_create(vscreen->pscreen,
+ profile, chroma_format,
+ width, height,
+ vl_dri_ctx);
+
+ if (!vl_dri_ctx->base.vpipe)
+ goto no_vpipe;
+
+ vl_dri_ctx->base.vpipe->priv = vl_dri_ctx;
+ vl_dri_ctx->base.vscreen = vscreen;
+ vl_dri_ctx->fd = vl_dri_scrn->dri_screen->fd;
+
+ return &vl_dri_ctx->base;
+
+no_vpipe:
+ FREE(vl_dri_ctx);
+no_struct:
+ return NULL;
+}
+
+void vl_video_destroy(struct vl_context *vctx)
+{
+ struct vl_dri_context *vl_dri_ctx = (struct vl_dri_context*)vctx;
+
+ assert(vctx);
+
+ vl_dri_ctx->base.vpipe->destroy(vl_dri_ctx->base.vpipe);
+ FREE(vl_dri_ctx);
+}
diff --git a/src/driclient/src/driclient.c b/src/gallium/winsys/g3dvl/dri/driclient.c
index dc2189afec3..90e48a7cb28 100644
--- a/src/driclient/src/driclient.c
+++ b/src/gallium/winsys/g3dvl/dri/driclient.c
@@ -1,6 +1,8 @@
#include "driclient.h"
#include <assert.h>
#include <stdlib.h>
+#include <fcntl.h>
+#include <X11/Xlibint.h>
int driCreateScreen(Display *display, int screen, dri_screen_t **dri_screen, dri_framebuffer_t *dri_framebuf)
{
@@ -222,12 +224,12 @@ int driUpdateDrawableInfo(dri_drawable_t *dri_drawable)
dri_drawable->dri_screen->display,
dri_drawable->dri_screen->num,
dri_drawable->x_drawable,
- &dri_drawable->sarea_index,
- &dri_drawable->last_sarea_stamp,
- &dri_drawable->x,
- &dri_drawable->y,
- &dri_drawable->w,
- &dri_drawable->h,
+ &dri_drawable->sarea_index,
+ &dri_drawable->last_sarea_stamp,
+ &dri_drawable->x,
+ &dri_drawable->y,
+ &dri_drawable->w,
+ &dri_drawable->h,
&dri_drawable->num_cliprects,
&dri_drawable->cliprects,
&dri_drawable->back_x,
@@ -308,3 +310,79 @@ int driDestroyContext(dri_context_t *dri_context)
return 0;
}
+
+int dri2CreateScreen(Display *display, int screen, dri_screen_t **dri_screen)
+{
+ dri_screen_t *dri_scrn;
+ drm_magic_t magic;
+ char *drvName;
+ char *devName;
+
+ dri_scrn = calloc(1, sizeof(dri_screen_t));
+
+ if (!dri_scrn)
+ return 1;
+
+ if (!DRI2Connect(display, XRootWindow(display, screen), &drvName, &devName))
+ goto free_screen;
+
+ dri_scrn->fd = open(devName, O_RDWR);
+ Xfree(drvName);
+ Xfree(devName);
+ if (dri_scrn->fd < 0)
+ goto free_screen;
+
+ if (drmGetMagic(dri_scrn->fd, &magic))
+ goto free_screen;
+
+ if (!DRI2Authenticate(display, RootWindow(display, screen), magic))
+ goto free_screen;
+
+ dri_scrn->display = display;
+ dri_scrn->num = screen;
+ *dri_screen = dri_scrn;
+
+ return 0;
+
+free_screen:
+ free(dri_scrn);
+
+ return 1;
+}
+
+int dri2DestroyScreen(dri_screen_t *dri_screen)
+{
+ /* Not much to do here apparently... */
+ assert(dri_screen);
+ free(dri_screen);
+ return 0;
+}
+
+int dri2CreateDrawable(dri_screen_t *dri_screen, XID drawable)
+{
+ assert(dri_screen);
+ DRI2CreateDrawable(dri_screen->display, drawable);
+ return 0;
+}
+
+int dri2DestroyDrawable(dri_screen_t *dri_screen, XID drawable)
+{
+ assert(dri_screen);
+ DRI2DestroyDrawable(dri_screen->display, drawable);
+ return 0;
+}
+
+int dri2CopyDrawable(dri_screen_t *dri_screen, XID drawable, int dest, int src)
+{
+ XserverRegion region;
+
+ assert(dri_screen);
+ assert(dest >= DRI_BUFFER_FRONT_LEFT && dest <= DRI_BUFFER_DEPTH_STENCIL);
+ assert(src >= DRI_BUFFER_FRONT_LEFT && src <= DRI_BUFFER_DEPTH_STENCIL);
+
+ region = XFixesCreateRegionFromWindow(dri_screen->display, drawable, WindowRegionBounding);
+ DRI2CopyRegion(dri_screen->display, drawable, region, dest, src);
+ XFixesDestroyRegion(dri_screen->display, region);
+
+ return 0;
+}
diff --git a/src/driclient/include/driclient.h b/src/gallium/winsys/g3dvl/dri/driclient.h
index d3915250392..4e4fd362395 100644
--- a/src/driclient/include/driclient.h
+++ b/src/gallium/winsys/g3dvl/dri/driclient.h
@@ -2,9 +2,12 @@
#define driclient_h
#include <stdint.h>
+#include <X11/Xmd.h>
#include <X11/Xlib.h>
#include <drm_sarea.h>
+//#include <X11/extensions/dri2proto.h>
#include "xf86dri.h"
+#include "dri2.h"
/* TODO: Bring in DRI XML options */
@@ -93,5 +96,22 @@ do \
} \
} while (0)
+int dri2CreateScreen(Display *display, int screen, dri_screen_t **dri_screen);
+int dri2DestroyScreen(dri_screen_t *dri_screen);
+int dri2CreateDrawable(dri_screen_t *dri_screen, XID drawable);
+int dri2DestroyDrawable(dri_screen_t *dri_screen, XID drawable);
+int dri2CopyDrawable(dri_screen_t *dri_screen, XID drawable, int dest, int src);
+
+#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
+#define DRI_BUFFER_DEPTH_STENCIL 9 /**< Only available with DRI2 1.1 */
+
#endif
diff --git a/src/driclient/include/xf86dri.h b/src/gallium/winsys/g3dvl/dri/xf86dri.h
index baf80a7a9dd..baf80a7a9dd 100644
--- a/src/driclient/include/xf86dri.h
+++ b/src/gallium/winsys/g3dvl/dri/xf86dri.h
diff --git a/src/driclient/src/xf86dristr.h b/src/gallium/winsys/g3dvl/dri/xf86dristr.h
index b834bd1a1a0..b834bd1a1a0 100644
--- a/src/driclient/src/xf86dristr.h
+++ b/src/gallium/winsys/g3dvl/dri/xf86dristr.h
diff --git a/src/gallium/winsys/g3dvl/drm/Makefile b/src/gallium/winsys/g3dvl/drm/Makefile
new file mode 100644
index 00000000000..0711f44d8e3
--- /dev/null
+++ b/src/gallium/winsys/g3dvl/drm/Makefile
@@ -0,0 +1,12 @@
+# src/gallium/winsys/Makefile
+TOP = ../../../../..
+include $(TOP)/configs/current
+
+SUBDIRS = $(GALLIUM_WINSYS_DRM_DIRS)
+
+default install clean:
+ @for dir in $(SUBDIRS) ; do \
+ if [ -d $$dir ] ; then \
+ (cd $$dir && $(MAKE) $@) || exit 1; \
+ fi \
+ done
diff --git a/src/gallium/winsys/g3dvl/drm/Makefile.template b/src/gallium/winsys/g3dvl/drm/Makefile.template
new file mode 100644
index 00000000000..2b79deef4bc
--- /dev/null
+++ b/src/gallium/winsys/g3dvl/drm/Makefile.template
@@ -0,0 +1,66 @@
+XVMC_MAJOR = 1
+XVMC_MINOR = 0
+XVMC_LIB = XvMCg3dvl
+XVMC_LIB_NAME = lib$(XVMC_LIB).so
+XVMC_LIB_DEPS = $(EXTRA_LIB_PATH) -lXvMC -lXv -lX11 -lm
+
+###############################################################
+
+INCLUDES = $(DRIVER_INCLUDES) \
+ -I$(TOP)/src/gallium/include \
+ -I$(TOP)/src/gallium/auxiliary \
+ -I$(TOP)/src/gallium/drivers \
+ -I$(TOP)/src/gallium/winsys/g3dvl \
+ -I$(TOP)/src/gallium/winsys/g3dvl/dri
+
+DEFINES += $(DRIVER_DEFINES) \
+ -DGALLIUM_SOFTPIPE \
+ -DGALLIUM_TRACE
+
+# XXX: Hack, if we include libxvmctracker.a in LIBS none of the symbols are
+# pulled in by the linker because xsp_winsys.c doesn't refer to them
+OBJECTS = $(C_SOURCES:.c=.o) $(TOP)/src/gallium/state_trackers/xorg/xvmc/*.o
+
+LIBS = $(TOP)/src/gallium/winsys/g3dvl/dri/libvldri.a \
+ $(PIPE_DRIVERS) \
+ $(TOP)/src/gallium/auxiliary/libgallium.a
+
+.c.o:
+ $(CC) -c $(INCLUDES) $(DEFINES) $(CFLAGS) $< -o $@
+
+.S.o:
+ $(CC) -c $(INCLUDES) $(DEFINES) $(CFLAGS) $< -o $@
+
+.PHONY: default $(TOP)/$(LIB_DIR)/gallium clean
+
+default: depend $(TOP)/$(LIB_DIR)/gallium $(TOP)/$(LIB_DIR)/gallium/$(XVMC_LIB_NAME)
+
+$(TOP)/$(LIB_DIR)/gallium:
+ @mkdir -p $(TOP)/$(LIB_DIR)/gallium
+
+# Make the libXvMCg3dvl.so library
+$(TOP)/$(LIB_DIR)/gallium/$(XVMC_LIB_NAME): $(OBJECTS) $(LIBS) Makefile
+ $(MKLIB) -o $(XVMC_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \
+ -major $(XVMC_MAJOR) -minor $(XVMC_MINOR) $(MKLIB_OPTIONS) \
+ -install $(TOP)/$(LIB_DIR)/gallium -id $(INSTALL_LIB_DIR)/lib$(XVMC_LIB).1.dylib \
+ $(XVMC_LIB_DEPS) $(DRIVER_LIB_DEPS) $(OBJECTS) $(LIBS)
+
+depend: $(SOURCES) Makefile
+ $(RM) depend
+ touch depend
+ $(MKDEP) $(MKDEP_OPTIONS) $(DEFINES) $(INCLUDES) $(SOURCES)
+
+#install: default
+# $(INSTALL) -d $(INSTALL_DIR)/include/GL
+# $(INSTALL) -d $(INSTALL_DIR)/$(LIB_DIR)
+# $(INSTALL) -m 644 $(TOP)/include/GL/*.h $(INSTALL_DIR)/include/GL
+# @if [ -e $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) ]; then \
+# $(INSTALL) $(TOP)/$(LIB_DIR)/libGL* $(INSTALL_DIR)/$(LIB_DIR); \
+# fi
+
+clean: Makefile
+ $(RM) $(TOP)/$(LIB_DIR)/gallium/$(XVMC_LIB_NAME)
+ $(RM) *.o *~
+ $(RM) depend depend.bak
+
+-include depend
diff --git a/src/gallium/winsys/g3dvl/drm/nouveau/Makefile b/src/gallium/winsys/g3dvl/drm/nouveau/Makefile
new file mode 100644
index 00000000000..5c55186f672
--- /dev/null
+++ b/src/gallium/winsys/g3dvl/drm/nouveau/Makefile
@@ -0,0 +1,23 @@
+# This makefile produces a libXvMCg3dvl.so which is
+# based on DRM/DRI
+
+TOP = ../../../../../..
+include $(TOP)/configs/current
+
+C_SOURCES =
+
+DRIVER_INCLUDES = $(shell pkg-config libdrm libdrm_nouveau --cflags-only-I) \
+ -I$(TOP)/src/gallium/winsys/drm/nouveau
+DRIVER_DEFINES = $(shell pkg-config libdrm libdrm_nouveau --cflags-only-other)
+
+PIPE_DRIVERS = \
+ $(TOP)/src/gallium/winsys/drm/nouveau/drm/libnouveaudrm.a \
+ $(TOP)/src/gallium/drivers/nv30/libnv30.a \
+ $(TOP)/src/gallium/drivers/nv40/libnv40.a \
+ $(TOP)/src/gallium/drivers/nv50/libnv50.a \
+ $(TOP)/src/gallium/drivers/nouveau/libnouveau.a \
+ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a
+
+DRIVER_LIB_DEPS += $(shell pkg-config libdrm_nouveau --libs)
+
+include ../Makefile.template
diff --git a/src/gallium/winsys/g3dvl/drm/radeon/Makefile b/src/gallium/winsys/g3dvl/drm/radeon/Makefile
new file mode 100644
index 00000000000..0f7fd1c15ad
--- /dev/null
+++ b/src/gallium/winsys/g3dvl/drm/radeon/Makefile
@@ -0,0 +1,20 @@
+# This makefile produces a libXvMCg3dvl.so which is
+# based on DRM/DRI
+
+TOP = ../../../../../..
+include $(TOP)/configs/current
+
+C_SOURCES =
+
+DRIVER_INCLUDES = $(shell pkg-config libdrm libdrm_radeon --cflags-only-I) \
+ -I$(TOP)/src/gallium/winsys/drm/radeon \
+DRIVER_DEFINES = $(shell pkg-config libdrm libdrm_radeon --cflags-only-other)
+
+PIPE_DRIVERS = \
+ $(TOP)/src/gallium/winsys/drm/radeon/core/libradeonwinsys.a \
+ $(TOP)/src/gallium/drivers/r300/libr300.a \
+ $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a
+
+DRIVER_LIB_DEPS += $(shell pkg-config libdrm_radeon --libs)
+
+include ../Makefile.template
diff --git a/src/gallium/winsys/g3dvl/vl_winsys.h b/src/gallium/winsys/g3dvl/vl_winsys.h
new file mode 100644
index 00000000000..381478637a8
--- /dev/null
+++ b/src/gallium/winsys/g3dvl/vl_winsys.h
@@ -0,0 +1,69 @@
+/**************************************************************************
+ *
+ * Copyright 2009 Younes Manton.
+ * 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 TUNGSTEN GRAPHICS 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 vl_winsys_h
+#define vl_winsys_h
+
+#include <X11/Xlib.h>
+#include <pipe/p_defines.h>
+#include <pipe/p_format.h>
+
+struct pipe_screen;
+struct pipe_video_context;
+struct pipe_surface;
+
+struct vl_screen
+{
+ struct pipe_screen *pscreen;
+};
+
+struct vl_context
+{
+ struct vl_screen *vscreen;
+ struct pipe_video_context *vpipe;
+};
+
+struct vl_screen*
+vl_screen_create(Display *display, int screen);
+
+void vl_screen_destroy(struct vl_screen *vscreen);
+
+struct vl_context*
+vl_video_create(struct vl_screen *vscreen,
+ enum pipe_video_profile profile,
+ enum pipe_video_chroma_format chroma_format,
+ unsigned width, unsigned height);
+
+void vl_video_destroy(struct vl_context *vctx);
+
+struct pipe_surface*
+vl_drawable_surface_get(struct vl_screen *vscreen, Drawable drawable);
+
+void*
+vl_contextprivate_get(struct vl_context *vctx, struct pipe_surface *drawable_surface);
+
+#endif
diff --git a/src/gallium/winsys/g3dvl/xlib/xsp_winsys.c b/src/gallium/winsys/g3dvl/xlib/xsp_winsys.c
new file mode 100644
index 00000000000..0a7f324a77c
--- /dev/null
+++ b/src/gallium/winsys/g3dvl/xlib/xsp_winsys.c
@@ -0,0 +1,202 @@
+/**************************************************************************
+ *
+ * Copyright 2009 Younes Manton.
+ * 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 TUNGSTEN GRAPHICS 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.
+ *
+ **************************************************************************/
+
+#include <vl_winsys.h>
+#include <X11/Xlibint.h>
+#include <state_tracker/xlib_sw_winsys.h>
+#include <util/u_memory.h>
+#include <util/u_format.h>
+#include <softpipe/sp_public.h>
+#include <softpipe/sp_video_context.h>
+
+struct vl_xsp_screen
+{
+ struct vl_screen base;
+ Display *display;
+ int screen;
+ Visual visual;
+ struct xlib_drawable xdraw;
+ struct pipe_surface *drawable_surface;
+};
+
+struct pipe_surface*
+vl_drawable_surface_get(struct vl_screen *vscreen, Drawable drawable)
+{
+ struct vl_xsp_screen *xsp_screen = (struct vl_xsp_screen*)vscreen;
+ Window root;
+ int x, y;
+ unsigned int width, height;
+ unsigned int border_width;
+ unsigned int depth;
+ struct pipe_resource templat, *drawable_tex;
+ struct pipe_surface *drawable_surface = NULL;
+
+ assert(vscreen);
+ assert(drawable != None);
+
+ if (XGetGeometry(xsp_screen->display, drawable, &root, &x, &y, &width, &height, &border_width, &depth) == BadDrawable)
+ return NULL;
+
+ xsp_screen->xdraw.drawable = drawable;
+
+ if (xsp_screen->drawable_surface) {
+ if (xsp_screen->drawable_surface->width == width &&
+ xsp_screen->drawable_surface->height == height) {
+ pipe_surface_reference(&drawable_surface, xsp_screen->drawable_surface);
+ return drawable_surface;
+ }
+ else
+ pipe_surface_reference(&xsp_screen->drawable_surface, NULL);
+ }
+
+ memset(&templat, 0, sizeof(struct pipe_resource));
+ templat.target = PIPE_TEXTURE_2D;
+ /* XXX: Need to figure out drawable's format */
+ templat.format = PIPE_FORMAT_B8G8R8X8_UNORM;
+ templat.last_level = 0;
+ templat.width0 = width;
+ templat.height0 = height;
+ templat.depth0 = 1;
+ templat.usage = PIPE_USAGE_DEFAULT;
+ templat.bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_DISPLAY_TARGET | PIPE_BIND_BLIT_SOURCE;
+ templat.flags = 0;
+
+ drawable_tex = vscreen->pscreen->resource_create(vscreen->pscreen, &templat);
+ if (!drawable_tex)
+ return NULL;
+
+ xsp_screen->drawable_surface = vscreen->pscreen->get_tex_surface(vscreen->pscreen, drawable_tex,
+ 0, 0, 0,
+ templat.bind);
+ pipe_resource_reference(&drawable_tex, NULL);
+
+ if (!xsp_screen->drawable_surface)
+ return NULL;
+
+ pipe_surface_reference(&drawable_surface, xsp_screen->drawable_surface);
+
+ xsp_screen->xdraw.depth = 24/*util_format_get_blocksizebits(templat.format) /
+ util_format_get_blockwidth(templat.format)*/;
+
+ return drawable_surface;
+}
+
+void*
+vl_contextprivate_get(struct vl_context *vctx, struct pipe_surface *drawable_surface)
+{
+ struct vl_xsp_screen *xsp_screen = (struct vl_xsp_screen*)vctx->vscreen;
+
+ assert(vctx);
+ assert(drawable_surface);
+ assert(xsp_screen->drawable_surface == drawable_surface);
+
+ return &xsp_screen->xdraw;
+}
+
+struct vl_screen*
+vl_screen_create(Display *display, int screen)
+{
+ struct vl_xsp_screen *xsp_screen;
+ struct sw_winsys *winsys;
+
+ assert(display);
+
+ xsp_screen = CALLOC_STRUCT(vl_xsp_screen);
+ if (!xsp_screen)
+ return NULL;
+
+ winsys = xlib_create_sw_winsys(display);
+ if (!winsys) {
+ FREE(xsp_screen);
+ return NULL;
+ }
+
+ xsp_screen->base.pscreen = softpipe_create_screen(winsys);
+ if (!xsp_screen->base.pscreen) {
+ winsys->destroy(winsys);
+ FREE(xsp_screen);
+ return NULL;
+ }
+
+ xsp_screen->display = display;
+ xsp_screen->screen = screen;
+ xsp_screen->xdraw.visual = XDefaultVisual(display, screen);
+
+ return &xsp_screen->base;
+}
+
+void vl_screen_destroy(struct vl_screen *vscreen)
+{
+ struct vl_xsp_screen *xsp_screen = (struct vl_xsp_screen*)vscreen;
+
+ assert(vscreen);
+
+ pipe_surface_reference(&xsp_screen->drawable_surface, NULL);
+ vscreen->pscreen->destroy(vscreen->pscreen);
+ FREE(vscreen);
+}
+
+struct vl_context*
+vl_video_create(struct vl_screen *vscreen,
+ enum pipe_video_profile profile,
+ enum pipe_video_chroma_format chroma_format,
+ unsigned width, unsigned height)
+{
+ struct pipe_video_context *vpipe;
+ struct vl_context *vctx;
+
+ assert(vscreen);
+ assert(width && height);
+ assert(vscreen->pscreen->video_context_create);
+
+ vpipe = vscreen->pscreen->video_context_create(vscreen->pscreen,
+ profile,
+ chroma_format,
+ width, height, NULL);
+ if (!vpipe)
+ return NULL;
+
+ vctx = CALLOC_STRUCT(vl_context);
+ if (!vctx) {
+ vpipe->destroy(vpipe);
+ return NULL;
+ }
+
+ vpipe->priv = vctx;
+ vctx->vpipe = vpipe;
+ vctx->vscreen = vscreen;
+
+ return vctx;
+}
+
+void vl_video_destroy(struct vl_context *vctx)
+{
+ assert(vctx);
+
+ vctx->vpipe->destroy(vctx->vpipe);
+ FREE(vctx);
+}