Merge remote branch 'origin/master' into pipe-video
authorChristian König <deathsimple@vodafone.de>
Thu, 24 Feb 2011 21:02:42 +0000 (22:02 +0100)
committerChristian König <deathsimple@vodafone.de>
Thu, 24 Feb 2011 21:02:42 +0000 (22:02 +0100)
Conflicts:
configure.ac
src/gallium/auxiliary/Makefile
src/gallium/auxiliary/SConscript
src/gallium/drivers/r600/r600_asm.c
src/gallium/drivers/r600/r600_asm.h
src/gallium/drivers/r600/r600_shader.c
src/gallium/drivers/r600/r600_state_inlines.h
src/gallium/drivers/r600/r600_texture.c

184 files changed:
configs/autoconf.in
configs/linux-dri
configs/linux-dri-x86-64
configure.ac
src/driclient/include/driclient.h [deleted file]
src/driclient/include/xf86dri.h [deleted file]
src/driclient/src/Makefile [deleted file]
src/driclient/src/XF86dri.c [deleted file]
src/driclient/src/driclient.c [deleted file]
src/driclient/src/xf86dristr.h [deleted file]
src/gallium/auxiliary/Makefile
src/gallium/auxiliary/SConscript
src/gallium/auxiliary/util/u_format.csv
src/gallium/auxiliary/util/u_format_yuv.c
src/gallium/auxiliary/util/u_format_yuv.h
src/gallium/auxiliary/util/u_video.h [new file with mode: 0644]
src/gallium/auxiliary/vl/vl_bitstream_parser.c [new file with mode: 0644]
src/gallium/auxiliary/vl/vl_bitstream_parser.h [new file with mode: 0644]
src/gallium/auxiliary/vl/vl_compositor.c [new file with mode: 0644]
src/gallium/auxiliary/vl/vl_compositor.h [new file with mode: 0644]
src/gallium/auxiliary/vl/vl_csc.c [new file with mode: 0644]
src/gallium/auxiliary/vl/vl_csc.h [new file with mode: 0644]
src/gallium/auxiliary/vl/vl_idct.c [new file with mode: 0644]
src/gallium/auxiliary/vl/vl_idct.h [new file with mode: 0644]
src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.c [new file with mode: 0644]
src/gallium/auxiliary/vl/vl_mpeg12_mc_renderer.h [new file with mode: 0644]
src/gallium/auxiliary/vl/vl_types.h [new file with mode: 0644]
src/gallium/auxiliary/vl/vl_vertex_buffers.c [new file with mode: 0644]
src/gallium/auxiliary/vl/vl_vertex_buffers.h [new file with mode: 0644]
src/gallium/drivers/nv40/nv40_video_context.c [new file with mode: 0644]
src/gallium/drivers/nv40/nv40_video_context.h [new file with mode: 0644]
src/gallium/drivers/nvfx/Makefile
src/gallium/drivers/nvfx/nvfx_screen.c
src/gallium/drivers/nvfx/nvfx_state.h
src/gallium/drivers/nvfx/nvfx_video_context.c [new file with mode: 0644]
src/gallium/drivers/nvfx/nvfx_video_context.h [new file with mode: 0644]
src/gallium/drivers/r300/r300_video_context.c [new file with mode: 0644]
src/gallium/drivers/r300/r300_video_context.h [new file with mode: 0644]
src/gallium/drivers/r600/Makefile
src/gallium/drivers/r600/eg_asm.c
src/gallium/drivers/r600/r600_asm.c
src/gallium/drivers/r600/r600_asm.h
src/gallium/drivers/r600/r600_pipe.c
src/gallium/drivers/r600/r600_shader.c
src/gallium/drivers/r600/r600_state.c
src/gallium/drivers/r600/r600_state_inlines.h
src/gallium/drivers/r600/r600_texture.c
src/gallium/drivers/r600/r600_video_context.c [new file with mode: 0644]
src/gallium/drivers/r600/r600_video_context.h [new file with mode: 0644]
src/gallium/drivers/softpipe/Makefile
src/gallium/drivers/softpipe/SConscript
src/gallium/drivers/softpipe/sp_screen.c
src/gallium/drivers/softpipe/sp_texture.h
src/gallium/drivers/softpipe/sp_video_context.c [new file with mode: 0644]
src/gallium/drivers/softpipe/sp_video_context.h [new file with mode: 0644]
src/gallium/include/pipe/p_defines.h
src/gallium/include/pipe/p_format.h
src/gallium/include/pipe/p_screen.h
src/gallium/include/pipe/p_video_context.h [new file with mode: 0644]
src/gallium/include/pipe/p_video_state.h [new file with mode: 0644]
src/gallium/state_trackers/va/Makefile [new file with mode: 0644]
src/gallium/state_trackers/va/ftab.c [new file with mode: 0644]
src/gallium/state_trackers/va/htab.c [new file with mode: 0644]
src/gallium/state_trackers/va/va_buffer.c [new file with mode: 0644]
src/gallium/state_trackers/va/va_config.c [new file with mode: 0644]
src/gallium/state_trackers/va/va_context.c [new file with mode: 0644]
src/gallium/state_trackers/va/va_display.c [new file with mode: 0644]
src/gallium/state_trackers/va/va_image.c [new file with mode: 0644]
src/gallium/state_trackers/va/va_picture.c [new file with mode: 0644]
src/gallium/state_trackers/va/va_private.h [new file with mode: 0644]
src/gallium/state_trackers/va/va_subpicture.c [new file with mode: 0644]
src/gallium/state_trackers/va/va_surface.c [new file with mode: 0644]
src/gallium/state_trackers/vdpau/Makefile [new file with mode: 0644]
src/gallium/state_trackers/vdpau/bitmap.c [new file with mode: 0644]
src/gallium/state_trackers/vdpau/color.c [new file with mode: 0644]
src/gallium/state_trackers/vdpau/decode.c [new file with mode: 0644]
src/gallium/state_trackers/vdpau/device.c [new file with mode: 0644]
src/gallium/state_trackers/vdpau/ftab.c [new file with mode: 0644]
src/gallium/state_trackers/vdpau/htab.c [new file with mode: 0644]
src/gallium/state_trackers/vdpau/mixer.c [new file with mode: 0644]
src/gallium/state_trackers/vdpau/mpeg2_bitstream_parser.c [new file with mode: 0644]
src/gallium/state_trackers/vdpau/mpeg2_bitstream_parser.h [new file with mode: 0644]
src/gallium/state_trackers/vdpau/output.c [new file with mode: 0644]
src/gallium/state_trackers/vdpau/preemption.c [new file with mode: 0644]
src/gallium/state_trackers/vdpau/presentation.c [new file with mode: 0644]
src/gallium/state_trackers/vdpau/query.c [new file with mode: 0644]
src/gallium/state_trackers/vdpau/surface.c [new file with mode: 0644]
src/gallium/state_trackers/vdpau/vdpau_private.h [new file with mode: 0644]
src/gallium/state_trackers/xorg/xvmc/Makefile [new file with mode: 0644]
src/gallium/state_trackers/xorg/xvmc/attributes.c [new file with mode: 0644]
src/gallium/state_trackers/xorg/xvmc/block.c [new file with mode: 0644]
src/gallium/state_trackers/xorg/xvmc/context.c [new file with mode: 0644]
src/gallium/state_trackers/xorg/xvmc/subpicture.c [new file with mode: 0644]
src/gallium/state_trackers/xorg/xvmc/surface.c [new file with mode: 0644]
src/gallium/state_trackers/xorg/xvmc/tests/.gitignore [new file with mode: 0644]
src/gallium/state_trackers/xorg/xvmc/tests/Makefile [new file with mode: 0644]
src/gallium/state_trackers/xorg/xvmc/tests/test_blocks.c [new file with mode: 0644]
src/gallium/state_trackers/xorg/xvmc/tests/test_context.c [new file with mode: 0644]
src/gallium/state_trackers/xorg/xvmc/tests/test_rendering.c [new file with mode: 0644]
src/gallium/state_trackers/xorg/xvmc/tests/test_subpicture.c [new file with mode: 0644]
src/gallium/state_trackers/xorg/xvmc/tests/test_surface.c [new file with mode: 0644]
src/gallium/state_trackers/xorg/xvmc/tests/testlib.c [new file with mode: 0644]
src/gallium/state_trackers/xorg/xvmc/tests/testlib.h [new file with mode: 0644]
src/gallium/state_trackers/xorg/xvmc/tests/xvmc_bench.c [new file with mode: 0644]
src/gallium/state_trackers/xorg/xvmc/xvmc_private.h [new file with mode: 0644]
src/gallium/targets/Makefile.va [new file with mode: 0644]
src/gallium/targets/Makefile.vdpau [new file with mode: 0644]
src/gallium/targets/Makefile.xvmc [new file with mode: 0644]
src/gallium/targets/dri-nouveau/Makefile
src/gallium/targets/va-r600/Makefile [new file with mode: 0644]
src/gallium/targets/va-r600/target.c [new file with mode: 0644]
src/gallium/targets/va-softpipe/Makefile [new file with mode: 0644]
src/gallium/targets/vdpau-softpipe/Makefile [new file with mode: 0644]
src/gallium/targets/xvmc-nouveau/Makefile [new file with mode: 0644]
src/gallium/targets/xvmc-r600/Makefile [new file with mode: 0644]
src/gallium/targets/xvmc-r600/target.c [new file with mode: 0644]
src/gallium/targets/xvmc-softpipe/Makefile [new file with mode: 0644]
src/gallium/tests/python/retrace/README [deleted file]
src/gallium/tests/python/retrace/format.py [deleted file]
src/gallium/tests/python/retrace/model.py [deleted file]
src/gallium/tests/python/retrace/parse.py [deleted file]
src/gallium/tests/python/retrace/parser.py [deleted file]
src/gallium/tests/python/samples/gs.py [deleted file]
src/gallium/tests/python/samples/tri.py [deleted file]
src/gallium/tests/python/tests/.gitignore [deleted file]
src/gallium/tests/python/tests/base.py [deleted file]
src/gallium/tests/python/tests/regress/fragment-shader/.gitignore [deleted file]
src/gallium/tests/python/tests/regress/fragment-shader/frag-abs.sh [deleted file]
src/gallium/tests/python/tests/regress/fragment-shader/frag-add.sh [deleted file]
src/gallium/tests/python/tests/regress/fragment-shader/frag-cb-1d.sh [deleted file]
src/gallium/tests/python/tests/regress/fragment-shader/frag-dp3.sh [deleted file]
src/gallium/tests/python/tests/regress/fragment-shader/frag-dp4.sh [deleted file]
src/gallium/tests/python/tests/regress/fragment-shader/frag-dst.sh [deleted file]
src/gallium/tests/python/tests/regress/fragment-shader/frag-ex2.sh [deleted file]
src/gallium/tests/python/tests/regress/fragment-shader/frag-flr.sh [deleted file]
src/gallium/tests/python/tests/regress/fragment-shader/frag-frc.sh [deleted file]
src/gallium/tests/python/tests/regress/fragment-shader/frag-lg2.sh [deleted file]
src/gallium/tests/python/tests/regress/fragment-shader/frag-lit.sh [deleted file]
src/gallium/tests/python/tests/regress/fragment-shader/frag-lrp.sh [deleted file]
src/gallium/tests/python/tests/regress/fragment-shader/frag-mad.sh [deleted file]
src/gallium/tests/python/tests/regress/fragment-shader/frag-max.sh [deleted file]
src/gallium/tests/python/tests/regress/fragment-shader/frag-min.sh [deleted file]
src/gallium/tests/python/tests/regress/fragment-shader/frag-mov.sh [deleted file]
src/gallium/tests/python/tests/regress/fragment-shader/frag-mul.sh [deleted file]
src/gallium/tests/python/tests/regress/fragment-shader/frag-rcp.sh [deleted file]
src/gallium/tests/python/tests/regress/fragment-shader/frag-rsq.sh [deleted file]
src/gallium/tests/python/tests/regress/fragment-shader/frag-sge.sh [deleted file]
src/gallium/tests/python/tests/regress/fragment-shader/frag-slt.sh [deleted file]
src/gallium/tests/python/tests/regress/fragment-shader/frag-srcmod-abs.sh [deleted file]
src/gallium/tests/python/tests/regress/fragment-shader/frag-srcmod-absneg.sh [deleted file]
src/gallium/tests/python/tests/regress/fragment-shader/frag-srcmod-neg.sh [deleted file]
src/gallium/tests/python/tests/regress/fragment-shader/frag-srcmod-swz.sh [deleted file]
src/gallium/tests/python/tests/regress/fragment-shader/frag-sub.sh [deleted file]
src/gallium/tests/python/tests/regress/fragment-shader/frag-xpd.sh [deleted file]
src/gallium/tests/python/tests/regress/fragment-shader/fragment-shader.py [deleted file]
src/gallium/tests/python/tests/regress/vertex-shader/.gitignore [deleted file]
src/gallium/tests/python/tests/regress/vertex-shader/vertex-shader.py [deleted file]
src/gallium/tests/python/tests/texture_render.py [deleted file]
src/gallium/tests/python/tests/tree.py [deleted file]
src/gallium/tests/trivial/.gitignore [deleted file]
src/gallium/tests/trivial/Makefile [deleted file]
src/gallium/tests/unit/Makefile [deleted file]
src/gallium/tests/unit/SConscript [deleted file]
src/gallium/tests/unit/pipe_barrier_test.c [deleted file]
src/gallium/tests/unit/u_cache_test.c [deleted file]
src/gallium/tests/unit/u_format_test.c [deleted file]
src/gallium/tests/unit/u_half_test.c [deleted file]
src/gallium/winsys/g3dvl/Makefile [new file with mode: 0644]
src/gallium/winsys/g3dvl/dri/Makefile [new file with mode: 0644]
src/gallium/winsys/g3dvl/dri/XF86dri.c [new file with mode: 0644]
src/gallium/winsys/g3dvl/dri/dri2.c [new file with mode: 0644]
src/gallium/winsys/g3dvl/dri/dri2.h [new file with mode: 0644]
src/gallium/winsys/g3dvl/dri/dri_winsys.c [new file with mode: 0644]
src/gallium/winsys/g3dvl/dri/driclient.c [new file with mode: 0644]
src/gallium/winsys/g3dvl/dri/driclient.h [new file with mode: 0644]
src/gallium/winsys/g3dvl/dri/xf86dri.h [new file with mode: 0644]
src/gallium/winsys/g3dvl/dri/xf86dristr.h [new file with mode: 0644]
src/gallium/winsys/g3dvl/drm/Makefile [new file with mode: 0644]
src/gallium/winsys/g3dvl/drm/Makefile.template [new file with mode: 0644]
src/gallium/winsys/g3dvl/drm/nouveau/Makefile [new file with mode: 0644]
src/gallium/winsys/g3dvl/drm/radeon/Makefile [new file with mode: 0644]
src/gallium/winsys/g3dvl/vl_winsys.h [new file with mode: 0644]
src/gallium/winsys/g3dvl/xlib/xsp_winsys.c [new file with mode: 0644]
src/gallium/winsys/r600/drm/r600_bo.c

index a3c69e1d398b97e7ed0ecbd59d409ac3df21d9b5..9defba21afbf16b0c3d02bd26cf8e2a620fb9a6b 100644 (file)
@@ -171,6 +171,12 @@ 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@
+
+# VA library install directory
+VA_LIB_INSTALL_DIR=@VA_LIB_INSTALL_DIR@
+
 # Xorg driver install directory (for xorg state-tracker)
 XORG_DRIVER_INSTALL_DIR = @XORG_DRIVER_INSTALL_DIR@
 
index 22190bfc64f537b4db9b8ae2c6ba24b7c49286f5..ce2da8317d754443ad88d6d75b16f4e84b395ddf 100644 (file)
@@ -59,12 +59,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`
index 656cf6140d7e3b301b37699233b79ff57d526198..90e6c215adb03922a042c7e90dc3bb34fa80fc63 100644 (file)
@@ -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
 
index fbc743650c6c9f2f63e10fddb6508525a057e335..19455eed186bbf3c253e30fbc7686cf63a64a1f2 100644 (file)
@@ -1500,6 +1500,27 @@ yes)
             fi
             have_st_vega="yes"
             ;;
+       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"
+            ;;
+       va)
+            # Check for libva?
+            if test "x$enable_gallium_g3dvl" != xyes; then
+                AC_MSG_ERROR([cannot build va state tracker without --enable-gallium-g3dvl])
+            fi
+            HAVE_ST_VA="yes"
+            ;;
         esac
 
        if test -n "$tracker"; then
@@ -1669,7 +1690,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_XORG" = xyes || test "x$HAVE_ST_XVMC" = xyes || test "x$HAVE_ST_VDPAU" = xyes || test "x$HAVE_ST_VA" = xyes; then
          GALLIUM_WINSYS_DIRS="$GALLIUM_WINSYS_DIRS $1"
     fi
     if test "x$HAVE_ST_DRI" = xyes && test "x$2" != x; then
@@ -1678,6 +1699,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_XVMC" = xyes && test "x$4" != x; then
+         GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS $4"
+    fi
+    if test "x$HAVE_ST_VDPAU" = xyes && test "x$5" != x; then
+         GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS $5"
+    fi
+    if test "x$HAVE_ST_VA" = xyes && test "x$6" != x; then
+         GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS $6"
+    fi
 }
 
 
@@ -1755,7 +1785,7 @@ AC_ARG_ENABLE([gallium-r600],
     [enable_gallium_r600=auto])
 if test "x$enable_gallium_r600" = xyes; then
     GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS r600"
-    gallium_check_st "r600/drm" "dri-r600"
+    gallium_check_st "r600/drm" "dri-r600" "xvmc-r600"
 fi
 
 dnl
@@ -1768,8 +1798,50 @@ 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 nvc0"
-    gallium_check_st "nouveau/drm" "dri-nouveau" "xorg-nouveau"
+    gallium_check_st "nouveau/drm" "dri-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)
+       if test "x$HAVE_ST_VDPAU" = xyes; then
+        GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS vdpau-softpipe"
+       fi
+       if test "x$HAVE_ST_XVMC" = xyes; then
+        GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS xvmc-softpipe"
+       fi
+       if test "x$HAVE_ST_VA" = xyes; then
+       GALLIUM_TARGET_DIRS="$GALLIUM_TARGET_DIRS va-softpipe"
+       fi
+       ;;
+    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 Directory for VA libs
+AC_ARG_WITH([va-libdir],
+    [AS_HELP_STRING([--with-va-libdir=DIR],
+        [directory for the VA libraries @<:@default=${libdir}/va@:>@])],
+    [VA_LIB_INSTALL_DIR="$withval"],
+    [VA_LIB_INSTALL_DIR='${libdir}/va'])
+AC_SUBST([VA_LIB_INSTALL_DIR])
 
 dnl
 dnl Gallium swrast configuration
diff --git a/src/driclient/include/driclient.h b/src/driclient/include/driclient.h
deleted file mode 100644 (file)
index d391525..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-#ifndef driclient_h
-#define driclient_h
-
-#include <stdint.h>
-#include <X11/Xlib.h>
-#include <drm_sarea.h>
-#include "xf86dri.h"
-
-/* TODO: Bring in DRI XML options */
-
-typedef struct dri_version
-{
-       int major;
-       int minor;
-       int patch;
-} dri_version_t;
-
-typedef struct dri_screen
-{
-       Display                 *display;
-       unsigned int            num;
-       dri_version_t           ddx, dri, drm;
-       int                     draw_lock_id;
-       int                     fd;
-       drm_sarea_t             *sarea;
-       void                    *drawable_hash;
-       void                    *private;
-} dri_screen_t;
-
-struct dri_context;
-
-typedef struct dri_drawable
-{
-       drm_drawable_t          drm_drawable;
-       Drawable                x_drawable;
-       unsigned int            sarea_index;
-       unsigned int            *sarea_stamp;
-       unsigned int            last_sarea_stamp;
-       int                     x, y, w, h;
-       int                     back_x, back_y;
-       int                     num_cliprects, num_back_cliprects;
-       drm_clip_rect_t         *cliprects, *back_cliprects;
-       dri_screen_t            *dri_screen;
-       unsigned int            refcount;
-       void                    *private;
-} dri_drawable_t;
-
-typedef struct dri_context
-{
-       XID                     id;
-       drm_context_t           drm_context;
-       dri_screen_t            *dri_screen;
-       void                    *private;
-} dri_context_t;
-
-typedef struct dri_framebuffer
-{
-       drm_handle_t            drm_handle;
-       int                     base, size, stride;
-       int                     private_size;
-       void                    *private;
-} dri_framebuffer_t;
-
-int driCreateScreen(Display *display, int screen, dri_screen_t **dri_screen, dri_framebuffer_t *dri_framebuf);
-int driDestroyScreen(dri_screen_t *dri_screen);
-int driCreateDrawable(dri_screen_t *dri_screen, Drawable drawable, dri_drawable_t **dri_drawable);
-int driUpdateDrawableInfo(dri_drawable_t *dri_drawable);
-int driDestroyDrawable(dri_drawable_t *dri_drawable);
-int driCreateContext(dri_screen_t *dri_screen, Visual *visual, dri_context_t **dri_context);
-int driDestroyContext(dri_context_t *dri_context);
-
-#define DRI_VALIDATE_DRAWABLE_INFO_ONCE(dri_drawable)                                  \
-do                                                                                     \
-{                                                                                      \
-       if (*(dri_drawable->sarea_stamp) != dri_drawable->last_sarea_stamp)             \
-               driUpdateDrawableInfo(dri_drawable);                                    \
-} while (0)
-
-#define DRI_VALIDATE_DRAWABLE_INFO(dri_screen, dri_drawable)                                   \
-do                                                                                             \
-{                                                                                              \
-       while (*(dri_drawable->sarea_stamp) != dri_drawable->last_sarea_stamp)                  \
-       {                                                                                       \
-               register unsigned int hwContext = dri_screen->sarea->lock.lock &                \
-               ~(DRM_LOCK_HELD | DRM_LOCK_CONT);                                               \
-               DRM_UNLOCK(dri_screen->fd, &dri_screen->sarea->lock, hwContext);                \
-                                                                                               \
-               DRM_SPINLOCK(&dri_screen->sarea->drawable_lock, dri_screen->draw_lock_id);      \
-               DRI_VALIDATE_DRAWABLE_INFO_ONCE(dri_drawable);                                  \
-               DRM_SPINUNLOCK(&dri_screen->sarea->drawable_lock, dri_screen->draw_lock_id);    \
-                                                                                               \
-               DRM_LIGHT_LOCK(dri_screen->fd, &dri_screen->sarea->lock, hwContext);            \
-       }                                                                                       \
-} while (0)
-
-#endif
-
diff --git a/src/driclient/include/xf86dri.h b/src/driclient/include/xf86dri.h
deleted file mode 100644 (file)
index baf80a7..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-/**************************************************************************
-
-Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
-Copyright 2000 VA Linux Systems, 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 PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
-ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-/**
- * \file xf86dri.h
- * Protocol numbers and function prototypes for DRI X protocol.
- *
- * \author Kevin E. Martin <martin@valinux.com>
- * \author Jens Owen <jens@tungstengraphics.com>
- * \author Rickard E. (Rik) Faith <faith@valinux.com>
- */
-
-#ifndef _XF86DRI_H_
-#define _XF86DRI_H_
-
-#include <X11/Xfuncproto.h>
-#include <xf86drm.h>
-
-#define X_XF86DRIQueryVersion                  0
-#define X_XF86DRIQueryDirectRenderingCapable   1
-#define X_XF86DRIOpenConnection                        2
-#define X_XF86DRICloseConnection               3
-#define X_XF86DRIGetClientDriverName           4
-#define X_XF86DRICreateContext                 5
-#define X_XF86DRIDestroyContext                        6
-#define X_XF86DRICreateDrawable                        7
-#define X_XF86DRIDestroyDrawable               8
-#define X_XF86DRIGetDrawableInfo               9
-#define X_XF86DRIGetDeviceInfo                 10
-#define X_XF86DRIAuthConnection                 11
-#define X_XF86DRIOpenFullScreen                 12   /* Deprecated */
-#define X_XF86DRICloseFullScreen                13   /* Deprecated */
-
-#define XF86DRINumberEvents            0
-
-#define XF86DRIClientNotLocal          0
-#define XF86DRIOperationNotSupported   1
-#define XF86DRINumberErrors            (XF86DRIOperationNotSupported + 1)
-
-#ifndef _XF86DRI_SERVER_
-
-_XFUNCPROTOBEGIN
-
-Bool XF86DRIQueryExtension( Display *dpy, int *event_base, int *error_base );
-
-Bool XF86DRIQueryVersion( Display *dpy, int *majorVersion, int *minorVersion,
-    int *patchVersion );
-
-Bool XF86DRIQueryDirectRenderingCapable( Display *dpy, int screen,
-    Bool *isCapable );
-
-Bool XF86DRIOpenConnection( Display *dpy, int screen, drm_handle_t *hSAREA,
-    char **busIDString );
-
-Bool XF86DRIAuthConnection( Display *dpy, int screen, drm_magic_t magic );
-
-Bool XF86DRICloseConnection( Display *dpy, int screen );
-
-Bool XF86DRIGetClientDriverName( Display *dpy, int screen,
-    int *ddxDriverMajorVersion, int *ddxDriverMinorVersion,
-    int *ddxDriverPatchVersion, char **clientDriverName );
-
-Bool XF86DRICreateContext( Display *dpy, int screen, Visual *visual,
-    XID *ptr_to_returned_context_id, drm_context_t *hHWContext );
-
-Bool XF86DRICreateContextWithConfig( Display *dpy, int screen, int configID,
-    XID *ptr_to_returned_context_id, drm_context_t *hHWContext );
-
-Bool XF86DRIDestroyContext( Display *dpy, int screen,
-    XID context_id );
-
-Bool XF86DRICreateDrawable( Display *dpy, int screen,
-    Drawable drawable, drm_drawable_t *hHWDrawable );
-
-Bool XF86DRIDestroyDrawable( Display *dpy, int screen, 
-    Drawable drawable);
-
-Bool XF86DRIGetDrawableInfo( Display *dpy, int screen, Drawable drawable,
-    unsigned int *index, unsigned int *stamp, 
-    int *X, int *Y, int *W, int *H,
-    int *numClipRects, drm_clip_rect_t ** pClipRects,
-    int *backX, int *backY,
-    int *numBackClipRects, drm_clip_rect_t **pBackClipRects );
-
-Bool XF86DRIGetDeviceInfo( Display *dpy, int screen,
-    drm_handle_t *hFrameBuffer, int *fbOrigin, int *fbSize,
-    int *fbStride, int *devPrivateSize, void **pDevPrivate );
-
-_XFUNCPROTOEND
-
-#endif /* _XF86DRI_SERVER_ */
-
-#endif /* _XF86DRI_H_ */
-
diff --git a/src/driclient/src/Makefile b/src/driclient/src/Makefile
deleted file mode 100644 (file)
index 34435a2..0000000
+++ /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/driclient/src/XF86dri.c b/src/driclient/src/XF86dri.c
deleted file mode 100644 (file)
index 831a760..0000000
+++ /dev/null
@@ -1,618 +0,0 @@
-/**************************************************************************
-
-Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
-Copyright 2000 VA Linux Systems, 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 PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
-ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-/*
- * Authors:
- *   Kevin E. Martin <martin@valinux.com>
- *   Jens Owen <jens@tungstengraphics.com>
- *   Rickard E. (Rik) Faith <faith@valinux.com>
- *
- */
-
-/* THIS IS NOT AN X CONSORTIUM STANDARD */
-
-#include <X11/Xlibint.h>
-#include <X11/extensions/Xext.h>
-#include <X11/extensions/extutil.h>
-#include "xf86dristr.h"
-
-static XExtensionInfo _xf86dri_info_data;
-static XExtensionInfo *xf86dri_info = &_xf86dri_info_data;
-static char xf86dri_extension_name[] = XF86DRINAME;
-
-#define XF86DRICheckExtension(dpy,i,val) \
-  XextCheckExtension (dpy, i, xf86dri_extension_name, val)
-
-/*****************************************************************************
- *                                                                           *
- *                        private utility routines                          *
- *                                                                           *
- *****************************************************************************/
-
-static int close_display(Display *dpy, XExtCodes *extCodes);
-static /* const */ XExtensionHooks xf86dri_extension_hooks = {
-    NULL,                              /* create_gc */
-    NULL,                              /* copy_gc */
-    NULL,                              /* flush_gc */
-    NULL,                              /* free_gc */
-    NULL,                              /* create_font */
-    NULL,                              /* free_font */
-    close_display,                     /* close_display */
-    NULL,                              /* wire_to_event */
-    NULL,                              /* event_to_wire */
-    NULL,                              /* error */
-    NULL,                              /* error_string */
-};
-
-static XEXT_GENERATE_FIND_DISPLAY (find_display, xf86dri_info, 
-                                  xf86dri_extension_name, 
-                                  &xf86dri_extension_hooks, 
-                                  0, NULL)
-
-static XEXT_GENERATE_CLOSE_DISPLAY (close_display, xf86dri_info)
-
-
-/*****************************************************************************
- *                                                                           *
- *                 public XFree86-DRI Extension routines                    *
- *                                                                           *
- *****************************************************************************/
-
-#if 0
-#include <stdio.h>
-#define TRACE(msg)  fprintf(stderr,"XF86DRI%s\n", msg);
-#else
-#define TRACE(msg)
-#endif
-
-#define PUBLIC
-
-PUBLIC Bool XF86DRIQueryExtension (dpy, event_basep, error_basep)
-    Display *dpy;
-    int *event_basep, *error_basep;
-{
-    XExtDisplayInfo *info = find_display (dpy);
-
-    TRACE("QueryExtension...");
-    if (XextHasExtension(info)) {
-       *event_basep = info->codes->first_event;
-       *error_basep = info->codes->first_error;
-        TRACE("QueryExtension... return True");
-       return True;
-    } else {
-        TRACE("QueryExtension... return False");
-       return False;
-    }
-}
-
-PUBLIC Bool XF86DRIQueryVersion(dpy, majorVersion, minorVersion, patchVersion)
-    Display* dpy;
-    int* majorVersion; 
-    int* minorVersion;
-    int* patchVersion;
-{
-    XExtDisplayInfo *info = find_display (dpy);
-    xXF86DRIQueryVersionReply rep;
-    xXF86DRIQueryVersionReq *req;
-
-    TRACE("QueryVersion...");
-    XF86DRICheckExtension (dpy, info, False);
-
-    LockDisplay(dpy);
-    GetReq(XF86DRIQueryVersion, req);
-    req->reqType = info->codes->major_opcode;
-    req->driReqType = X_XF86DRIQueryVersion;
-    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
-       UnlockDisplay(dpy);
-       SyncHandle();
-        TRACE("QueryVersion... return False");
-       return False;
-    }
-    *majorVersion = rep.majorVersion;
-    *minorVersion = rep.minorVersion;
-    *patchVersion = rep.patchVersion;
-    UnlockDisplay(dpy);
-    SyncHandle();
-    TRACE("QueryVersion... return True");
-    return True;
-}
-
-PUBLIC Bool XF86DRIQueryDirectRenderingCapable(dpy, screen, isCapable)
-    Display* dpy;
-    int screen;
-    Bool* isCapable;
-{
-    XExtDisplayInfo *info = find_display (dpy);
-    xXF86DRIQueryDirectRenderingCapableReply rep;
-    xXF86DRIQueryDirectRenderingCapableReq *req;
-
-    TRACE("QueryDirectRenderingCapable...");
-    XF86DRICheckExtension (dpy, info, False);
-
-    LockDisplay(dpy);
-    GetReq(XF86DRIQueryDirectRenderingCapable, req);
-    req->reqType = info->codes->major_opcode;
-    req->driReqType = X_XF86DRIQueryDirectRenderingCapable;
-    req->screen = screen;
-    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
-       UnlockDisplay(dpy);
-       SyncHandle();
-        TRACE("QueryDirectRenderingCapable... return False");
-       return False;
-    }
-    *isCapable = rep.isCapable;
-    UnlockDisplay(dpy);
-    SyncHandle();
-    TRACE("QueryDirectRenderingCapable... return True");
-    return True;
-}
-
-PUBLIC Bool XF86DRIOpenConnection(dpy, screen, hSAREA, busIdString)
-    Display* dpy;
-    int screen;
-    drm_handle_t * hSAREA;
-    char **busIdString;
-{
-    XExtDisplayInfo *info = find_display (dpy);
-    xXF86DRIOpenConnectionReply rep;
-    xXF86DRIOpenConnectionReq *req;
-
-    TRACE("OpenConnection...");
-    XF86DRICheckExtension (dpy, info, False);
-
-    LockDisplay(dpy);
-    GetReq(XF86DRIOpenConnection, req);
-    req->reqType = info->codes->major_opcode;
-    req->driReqType = X_XF86DRIOpenConnection;
-    req->screen = screen;
-    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
-       UnlockDisplay(dpy);
-       SyncHandle();
-        TRACE("OpenConnection... return False");
-       return False;
-    }
-
-    *hSAREA = rep.hSAREALow;
-    if (sizeof(drm_handle_t) == 8) {
-       int shift = 32; /* var to prevent warning on next line */
-       *hSAREA |= ((drm_handle_t) rep.hSAREAHigh) << shift;
-    }
-
-    if (rep.length) {
-        if (!(*busIdString = (char *)Xcalloc(rep.busIdStringLength + 1, 1))) {
-            _XEatData(dpy, ((rep.busIdStringLength+3) & ~3));
-            UnlockDisplay(dpy);
-            SyncHandle();
-            TRACE("OpenConnection... return False");
-            return False;
-        }
-       _XReadPad(dpy, *busIdString, rep.busIdStringLength);
-    } else {
-        *busIdString = NULL;
-    }
-    UnlockDisplay(dpy);
-    SyncHandle();
-    TRACE("OpenConnection... return True");
-    return True;
-}
-
-PUBLIC Bool XF86DRIAuthConnection(dpy, screen, magic)
-    Display* dpy;
-    int screen;
-    drm_magic_t magic;
-{
-    XExtDisplayInfo *info = find_display (dpy);
-    xXF86DRIAuthConnectionReq *req;
-    xXF86DRIAuthConnectionReply rep;
-
-    TRACE("AuthConnection...");
-    XF86DRICheckExtension (dpy, info, False);
-
-    LockDisplay(dpy);
-    GetReq(XF86DRIAuthConnection, req);
-    req->reqType = info->codes->major_opcode;
-    req->driReqType = X_XF86DRIAuthConnection;
-    req->screen = screen;
-    req->magic = magic;
-    rep.authenticated = 0;
-    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse) || !rep.authenticated) {
-       UnlockDisplay(dpy);
-       SyncHandle();
-        TRACE("AuthConnection... return False");
-       return False;
-    }
-    UnlockDisplay(dpy);
-    SyncHandle();
-    TRACE("AuthConnection... return True");
-    return True;
-}
-
-PUBLIC Bool XF86DRICloseConnection(dpy, screen)
-    Display* dpy;
-    int screen;
-{
-    XExtDisplayInfo *info = find_display (dpy);
-    xXF86DRICloseConnectionReq *req;
-
-    TRACE("CloseConnection...");
-
-    XF86DRICheckExtension (dpy, info, False);
-
-    LockDisplay(dpy);
-    GetReq(XF86DRICloseConnection, req);
-    req->reqType = info->codes->major_opcode;
-    req->driReqType = X_XF86DRICloseConnection;
-    req->screen = screen;
-    UnlockDisplay(dpy);
-    SyncHandle();
-    TRACE("CloseConnection... return True");
-    return True;
-}
-
-PUBLIC Bool XF86DRIGetClientDriverName(dpy, screen, ddxDriverMajorVersion, 
-       ddxDriverMinorVersion, ddxDriverPatchVersion, clientDriverName)
-    Display* dpy;
-    int screen;
-    int* ddxDriverMajorVersion;
-    int* ddxDriverMinorVersion;
-    int* ddxDriverPatchVersion;
-    char** clientDriverName;
-{
-    XExtDisplayInfo *info = find_display (dpy);
-    xXF86DRIGetClientDriverNameReply rep;
-    xXF86DRIGetClientDriverNameReq *req;
-
-    TRACE("GetClientDriverName...");
-    XF86DRICheckExtension (dpy, info, False);
-
-    LockDisplay(dpy);
-    GetReq(XF86DRIGetClientDriverName, req);
-    req->reqType = info->codes->major_opcode;
-    req->driReqType = X_XF86DRIGetClientDriverName;
-    req->screen = screen;
-    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
-       UnlockDisplay(dpy);
-       SyncHandle();
-        TRACE("GetClientDriverName... return False");
-       return False;
-    }
-
-    *ddxDriverMajorVersion = rep.ddxDriverMajorVersion;
-    *ddxDriverMinorVersion = rep.ddxDriverMinorVersion;
-    *ddxDriverPatchVersion = rep.ddxDriverPatchVersion;
-
-    if (rep.length) {
-        if (!(*clientDriverName = (char *)Xcalloc(rep.clientDriverNameLength + 1, 1))) {
-            _XEatData(dpy, ((rep.clientDriverNameLength+3) & ~3));
-            UnlockDisplay(dpy);
-            SyncHandle();
-            TRACE("GetClientDriverName... return False");
-            return False;
-        }
-       _XReadPad(dpy, *clientDriverName, rep.clientDriverNameLength);
-    } else {
-        *clientDriverName = NULL;
-    }
-    UnlockDisplay(dpy);
-    SyncHandle();
-    TRACE("GetClientDriverName... return True");
-    return True;
-}
-
-PUBLIC Bool XF86DRICreateContextWithConfig(dpy, screen, configID, context,
-       hHWContext)
-    Display* dpy;
-    int screen;
-    int configID;
-    XID* context;
-    drm_context_t * hHWContext;
-{
-    XExtDisplayInfo *info = find_display (dpy);
-    xXF86DRICreateContextReply rep;
-    xXF86DRICreateContextReq *req;
-
-    TRACE("CreateContext...");
-    XF86DRICheckExtension (dpy, info, False);
-
-    LockDisplay(dpy);
-    GetReq(XF86DRICreateContext, req);
-    req->reqType = info->codes->major_opcode;
-    req->driReqType = X_XF86DRICreateContext;
-    req->visual = configID;
-    req->screen = screen;
-    *context = XAllocID(dpy);
-    req->context = *context;
-    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
-       UnlockDisplay(dpy);
-       SyncHandle();
-        TRACE("CreateContext... return False");
-       return False;
-    }
-    *hHWContext = rep.hHWContext;
-    UnlockDisplay(dpy);
-    SyncHandle();
-    TRACE("CreateContext... return True");
-    return True;
-}
-
-PUBLIC Bool XF86DRICreateContext(dpy, screen, visual, context, hHWContext)
-    Display* dpy;
-    int screen;
-    Visual* visual;
-    XID* context;
-    drm_context_t * hHWContext;
-{
-    return XF86DRICreateContextWithConfig( dpy, screen, visual->visualid,
-                                          context, hHWContext );
-}
-
-PUBLIC Bool XF86DRIDestroyContext( Display * ndpy, int screen, 
-    XID context )
-{
-    Display * const dpy = (Display *) ndpy;
-    XExtDisplayInfo *info = find_display (dpy);
-    xXF86DRIDestroyContextReq *req;
-
-    TRACE("DestroyContext...");
-    XF86DRICheckExtension (dpy, info, False);
-
-    LockDisplay(dpy);
-    GetReq(XF86DRIDestroyContext, req);
-    req->reqType = info->codes->major_opcode;
-    req->driReqType = X_XF86DRIDestroyContext;
-    req->screen = screen;
-    req->context = context;
-    UnlockDisplay(dpy);
-    SyncHandle();
-    TRACE("DestroyContext... return True");
-    return True;
-}
-
-PUBLIC Bool XF86DRICreateDrawable( Display * ndpy, int screen, 
-    Drawable drawable, drm_drawable_t * hHWDrawable )
-{
-    Display * const dpy = (Display *) ndpy;
-    XExtDisplayInfo *info = find_display (dpy);
-    xXF86DRICreateDrawableReply rep;
-    xXF86DRICreateDrawableReq *req;
-
-    TRACE("CreateDrawable...");
-    XF86DRICheckExtension (dpy, info, False);
-
-    LockDisplay(dpy);
-    GetReq(XF86DRICreateDrawable, req);
-    req->reqType = info->codes->major_opcode;
-    req->driReqType = X_XF86DRICreateDrawable;
-    req->screen = screen;
-    req->drawable = drawable;
-    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
-       UnlockDisplay(dpy);
-       SyncHandle();
-        TRACE("CreateDrawable... return False");
-       return False;
-    }
-    *hHWDrawable = rep.hHWDrawable;
-    UnlockDisplay(dpy);
-    SyncHandle();
-    TRACE("CreateDrawable... return True");
-    return True;
-}
-
-PUBLIC Bool XF86DRIDestroyDrawable( Display * ndpy, int screen,
-    Drawable drawable )
-{
-    Display * const dpy = (Display *) ndpy;
-    XExtDisplayInfo *info = find_display (dpy);
-    xXF86DRIDestroyDrawableReq *req;
-
-    TRACE("DestroyDrawable...");
-    XF86DRICheckExtension (dpy, info, False);
-
-    LockDisplay(dpy);
-    GetReq(XF86DRIDestroyDrawable, req);
-    req->reqType = info->codes->major_opcode;
-    req->driReqType = X_XF86DRIDestroyDrawable;
-    req->screen = screen;
-    req->drawable = drawable;
-    UnlockDisplay(dpy);
-    SyncHandle();
-    TRACE("DestroyDrawable... return True");
-    return True;
-}
-
-PUBLIC Bool XF86DRIGetDrawableInfo(Display* dpy, int screen, Drawable drawable,
-    unsigned int* index, unsigned int* stamp,
-    int* X, int* Y, int* W, int* H,
-    int* numClipRects, drm_clip_rect_t ** pClipRects,
-    int* backX, int* backY,
-    int* numBackClipRects, drm_clip_rect_t ** pBackClipRects )
-{
-    XExtDisplayInfo *info = find_display (dpy);
-    xXF86DRIGetDrawableInfoReply rep;
-    xXF86DRIGetDrawableInfoReq *req;
-    int total_rects;
-
-    TRACE("GetDrawableInfo...");
-    XF86DRICheckExtension (dpy, info, False);
-
-    LockDisplay(dpy);
-    GetReq(XF86DRIGetDrawableInfo, req);
-    req->reqType = info->codes->major_opcode;
-    req->driReqType = X_XF86DRIGetDrawableInfo;
-    req->screen = screen;
-    req->drawable = drawable;
-
-    if (!_XReply(dpy, (xReply *)&rep, 1, xFalse)) 
-    {
-       UnlockDisplay(dpy);
-       SyncHandle();
-        TRACE("GetDrawableInfo... return False");
-       return False;
-    }
-    *index = rep.drawableTableIndex;
-    *stamp = rep.drawableTableStamp;
-    *X = (int)rep.drawableX;
-    *Y = (int)rep.drawableY;
-    *W = (int)rep.drawableWidth;
-    *H = (int)rep.drawableHeight;
-    *numClipRects = rep.numClipRects;
-    total_rects = *numClipRects;
-
-    *backX = rep.backX;
-    *backY = rep.backY;
-    *numBackClipRects = rep.numBackClipRects;
-    total_rects += *numBackClipRects;
-
-#if 0
-    /* Because of the fix in Xserver/GL/dri/xf86dri.c, this check breaks
-     * backwards compatibility (Because of the >> 2 shift) but the fix
-     * enables multi-threaded apps to work.
-     */
-    if (rep.length !=  ((((SIZEOF(xXF86DRIGetDrawableInfoReply) - 
-                      SIZEOF(xGenericReply) + 
-                      total_rects * sizeof(drm_clip_rect_t)) + 3) & ~3) >> 2)) {
-        _XEatData(dpy, rep.length);
-       UnlockDisplay(dpy);
-       SyncHandle();
-        TRACE("GetDrawableInfo... return False");
-        return False;
-    }
-#endif
-
-    if (*numClipRects) {
-       int len = sizeof(drm_clip_rect_t) * (*numClipRects);
-
-       *pClipRects = (drm_clip_rect_t *)Xcalloc(len, 1);
-       if (*pClipRects) 
-         _XRead(dpy, (char*)*pClipRects, len);
-    } else {
-        *pClipRects = NULL;
-    }
-
-    if (*numBackClipRects) {
-       int len = sizeof(drm_clip_rect_t) * (*numBackClipRects);
-
-       *pBackClipRects = (drm_clip_rect_t *)Xcalloc(len, 1);
-       if (*pBackClipRects) 
-         _XRead(dpy, (char*)*pBackClipRects, len);
-    } else {
-        *pBackClipRects = NULL;
-    }
-
-    UnlockDisplay(dpy);
-    SyncHandle();
-    TRACE("GetDrawableInfo... return True");
-    return True;
-}
-
-PUBLIC Bool XF86DRIGetDeviceInfo(dpy, screen, hFrameBuffer, 
-       fbOrigin, fbSize, fbStride, devPrivateSize, pDevPrivate)
-    Display* dpy;
-    int screen;
-    drm_handle_t * hFrameBuffer;
-    int* fbOrigin;
-    int* fbSize;
-    int* fbStride;
-    int* devPrivateSize;
-    void** pDevPrivate;
-{
-    XExtDisplayInfo *info = find_display (dpy);
-    xXF86DRIGetDeviceInfoReply rep;
-    xXF86DRIGetDeviceInfoReq *req;
-
-    TRACE("GetDeviceInfo...");
-    XF86DRICheckExtension (dpy, info, False);
-
-    LockDisplay(dpy);
-    GetReq(XF86DRIGetDeviceInfo, req);
-    req->reqType = info->codes->major_opcode;
-    req->driReqType = X_XF86DRIGetDeviceInfo;
-    req->screen = screen;
-    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
-       UnlockDisplay(dpy);
-       SyncHandle();
-        TRACE("GetDeviceInfo... return False");
-       return False;
-    }
-
-    *hFrameBuffer = rep.hFrameBufferLow;
-    if (sizeof(drm_handle_t) == 8) {
-       int shift = 32; /* var to prevent warning on next line */
-       *hFrameBuffer |= ((drm_handle_t) rep.hFrameBufferHigh) << shift;
-    }
-
-    *fbOrigin = rep.framebufferOrigin;
-    *fbSize = rep.framebufferSize;
-    *fbStride = rep.framebufferStride;
-    *devPrivateSize = rep.devPrivateSize;
-
-    if (rep.length) {
-        if (!(*pDevPrivate = (void *)Xcalloc(rep.devPrivateSize, 1))) {
-            _XEatData(dpy, ((rep.devPrivateSize+3) & ~3));
-            UnlockDisplay(dpy);
-            SyncHandle();
-            TRACE("GetDeviceInfo... return False");
-            return False;
-        }
-       _XRead(dpy, (char*)*pDevPrivate, rep.devPrivateSize);
-    } else {
-        *pDevPrivate = NULL;
-    }
-
-    UnlockDisplay(dpy);
-    SyncHandle();
-    TRACE("GetDeviceInfo... return True");
-    return True;
-}
-
-PUBLIC Bool XF86DRIOpenFullScreen(dpy, screen, drawable)
-    Display* dpy;
-    int screen;
-    Drawable drawable;
-{
-    /* This function and the underlying X protocol are deprecated.
-     */
-    (void) dpy;
-    (void) screen;
-    (void) drawable;
-    return False;
-}
-
-PUBLIC Bool XF86DRICloseFullScreen(dpy, screen, drawable)
-    Display* dpy;
-    int screen;
-    Drawable drawable;
-{
-    /* This function and the underlying X protocol are deprecated.
-     */
-    (void) dpy;
-    (void) screen;
-    (void) drawable;
-    return True;
-}
-
diff --git a/src/driclient/src/driclient.c b/src/driclient/src/driclient.c
deleted file mode 100644 (file)
index dc2189a..0000000
+++ /dev/null
@@ -1,310 +0,0 @@
-#include "driclient.h"
-#include <assert.h>
-#include <stdlib.h>
-
-int driCreateScreen(Display *display, int screen, dri_screen_t **dri_screen, dri_framebuffer_t *dri_framebuf)
-{
-       int             evbase, errbase;
-       char            *driver_name;
-       int             newly_opened;
-       drm_magic_t     magic;
-       drmVersionPtr   drm_version;
-       drm_handle_t    sarea_handle;
-       char            *bus_id;
-       dri_screen_t    *dri_scrn;
-
-       assert(display);
-       assert(dri_screen);
-
-       if (!XF86DRIQueryExtension(display, &evbase, &errbase))
-               return 1;
-
-       dri_scrn = calloc(1, sizeof(dri_screen_t));
-
-       if (!dri_scrn)
-               return 1;
-
-       if (!XF86DRIQueryVersion(display, &dri_scrn->dri.major, &dri_scrn->dri.minor, &dri_scrn->dri.patch))
-               goto free_screen;
-
-       dri_scrn->display = display;
-       dri_scrn->num = screen;
-       dri_scrn->draw_lock_id = 1;
-
-       if (!XF86DRIOpenConnection(display, screen, &sarea_handle, &bus_id))
-               goto free_screen;
-
-       dri_scrn->fd = -1;
-       dri_scrn->fd = drmOpenOnce(NULL, bus_id, &newly_opened);
-       XFree(bus_id);
-
-       if (dri_scrn->fd < 0)
-               goto close_connection;
-
-       if (drmGetMagic(dri_scrn->fd, &magic))
-               goto close_drm;
-
-       drm_version = drmGetVersion(dri_scrn->fd);
-
-       if (!drm_version)
-               goto close_drm;
-
-       dri_scrn->drm.major = drm_version->version_major;
-       dri_scrn->drm.minor = drm_version->version_minor;
-       dri_scrn->drm.patch = drm_version->version_patchlevel;
-       drmFreeVersion(drm_version);
-
-       if (!XF86DRIAuthConnection(display, screen, magic))
-               goto close_drm;
-
-       if (!XF86DRIGetClientDriverName
-       (
-               display,
-               screen,
-               &dri_scrn->ddx.major,
-               &dri_scrn->ddx.minor,
-               &dri_scrn->ddx.patch,
-               &driver_name
-       ))
-               goto close_drm;
-
-       if (drmMap(dri_scrn->fd, sarea_handle, SAREA_MAX, (drmAddress)&dri_scrn->sarea))
-               goto close_drm;
-
-       dri_scrn->drawable_hash = drmHashCreate();
-
-       if (!dri_scrn->drawable_hash)
-               goto unmap_sarea;
-
-       if (dri_framebuf)
-       {
-               if (!XF86DRIGetDeviceInfo
-               (
-                       display,
-                       screen, &dri_framebuf->drm_handle,
-                       &dri_framebuf->base,
-                       &dri_framebuf->size,
-                       &dri_framebuf->stride,
-                       &dri_framebuf->private_size,
-                       &dri_framebuf->private
-               ))
-                       goto destroy_hash;
-       }
-
-       *dri_screen = dri_scrn;
-
-       return 0;
-
-destroy_hash:
-       drmHashDestroy(dri_scrn->drawable_hash);
-unmap_sarea:
-       drmUnmap(dri_scrn->sarea, SAREA_MAX);
-close_drm:
-       drmCloseOnce(dri_scrn->fd);
-close_connection:
-       XF86DRICloseConnection(display, screen);
-free_screen:
-       free(dri_scrn);
-
-       return 1;
-}
-
-int driDestroyScreen(dri_screen_t *dri_screen)
-{
-       Drawable        draw;
-       dri_drawable_t  *dri_draw;
-
-       assert(dri_screen);
-
-       if (drmHashFirst(dri_screen->drawable_hash, &draw, (void**)&dri_draw))
-       {
-               dri_draw->refcount = 1;
-               driDestroyDrawable(dri_draw);
-
-               while (drmHashNext(dri_screen->drawable_hash, &draw, (void**)&dri_draw))
-               {
-                       dri_draw->refcount = 1;
-                       driDestroyDrawable(dri_draw);
-               }
-       }
-
-       drmHashDestroy(dri_screen->drawable_hash);
-       drmUnmap(dri_screen->sarea, SAREA_MAX);
-       drmCloseOnce(dri_screen->fd);
-       XF86DRICloseConnection(dri_screen->display, dri_screen->num);
-       free(dri_screen);
-
-       return 0;
-}
-
-int driCreateDrawable(dri_screen_t *dri_screen, Drawable drawable, dri_drawable_t **dri_drawable)
-{
-       int             evbase, errbase;
-       dri_drawable_t  *dri_draw;
-
-       assert(dri_screen);
-       assert(dri_drawable);
-
-       if (!XF86DRIQueryExtension(dri_screen->display, &evbase, &errbase))
-               return 1;
-
-       if (!drmHashLookup(dri_screen->drawable_hash, drawable, (void**)dri_drawable))
-       {
-               /* Found */
-               (*dri_drawable)->refcount++;
-               return 0;
-       }
-
-       dri_draw = calloc(1, sizeof(dri_drawable_t));
-
-       if (!dri_draw)
-               return 1;
-
-       if (!XF86DRICreateDrawable(dri_screen->display, 0, drawable, &dri_draw->drm_drawable))
-       {
-               free(dri_draw);
-               return 1;
-       }
-
-       dri_draw->x_drawable = drawable;
-       dri_draw->sarea_index = 0;
-       dri_draw->sarea_stamp = NULL;
-       dri_draw->last_sarea_stamp = 0;
-       dri_draw->dri_screen = dri_screen;
-       dri_draw->refcount = 1;
-
-       if (drmHashInsert(dri_screen->drawable_hash, drawable, dri_draw))
-       {
-               XF86DRIDestroyDrawable(dri_screen->display, dri_screen->num, drawable);
-               free(dri_draw);
-               return 1;
-       }
-
-       if (!dri_draw->sarea_stamp || *dri_draw->sarea_stamp != dri_draw->last_sarea_stamp)
-       {
-               DRM_SPINLOCK(&dri_screen->sarea->drawable_lock, dri_screen->draw_lock_id);
-
-               if (driUpdateDrawableInfo(dri_draw))
-               {
-                       XF86DRIDestroyDrawable(dri_screen->display, dri_screen->num, drawable);
-                       free(dri_draw);
-                       DRM_SPINUNLOCK(&dri_screen->sarea->drawable_lock, dri_screen->draw_lock_id);
-                       return 1;
-               }
-
-               DRM_SPINUNLOCK(&dri_screen->sarea->drawable_lock, dri_screen->draw_lock_id);
-       }
-
-       *dri_drawable = dri_draw;
-
-       return 0;
-}
-
-int driUpdateDrawableInfo(dri_drawable_t *dri_drawable)
-{
-       assert(dri_drawable);
-
-       if (dri_drawable->cliprects)
-       {
-               XFree(dri_drawable->cliprects);
-               dri_drawable->cliprects = NULL;
-       }
-       if (dri_drawable->back_cliprects)
-       {
-               XFree(dri_drawable->back_cliprects);
-               dri_drawable->back_cliprects = NULL;
-       }
-
-       DRM_SPINUNLOCK(&dri_drawable->dri_screen->sarea->drawable_lock, dri_drawable->dri_screen->draw_lock_id);
-
-       if (!XF86DRIGetDrawableInfo
-       (
-               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->num_cliprects,
-               &dri_drawable->cliprects,
-               &dri_drawable->back_x,
-               &dri_drawable->back_y,
-               &dri_drawable->num_back_cliprects,
-               &dri_drawable->back_cliprects
-       ))
-       {
-               dri_drawable->sarea_stamp = &dri_drawable->last_sarea_stamp;
-               dri_drawable->num_cliprects = 0;
-               dri_drawable->cliprects = NULL;
-               dri_drawable->num_back_cliprects = 0;
-               dri_drawable->back_cliprects = 0;
-
-               return 1;
-       }
-       else
-               dri_drawable->sarea_stamp = &dri_drawable->dri_screen->sarea->drawableTable[dri_drawable->sarea_index].stamp;
-
-       DRM_SPINLOCK(&dri_drawable->dri_screen->sarea->drawable_lock, dri_drawable->dri_screen->draw_lock_id);
-
-       return 0;
-}
-
-int driDestroyDrawable(dri_drawable_t *dri_drawable)
-{
-       assert(dri_drawable);
-
-       if (--dri_drawable->refcount == 0)
-       {
-               if (dri_drawable->cliprects)
-                       XFree(dri_drawable->cliprects);
-               if (dri_drawable->back_cliprects)
-                       XFree(dri_drawable->back_cliprects);
-               drmHashDelete(dri_drawable->dri_screen->drawable_hash, dri_drawable->x_drawable);
-               XF86DRIDestroyDrawable(dri_drawable->dri_screen->display, dri_drawable->dri_screen->num, dri_drawable->x_drawable);
-               free(dri_drawable);
-       }
-
-       return 0;
-}
-
-int driCreateContext(dri_screen_t *dri_screen, Visual *visual, dri_context_t **dri_context)
-{
-       int             evbase, errbase;
-       dri_context_t   *dri_ctx;
-
-       assert(dri_screen);
-       assert(visual);
-       assert(dri_context);
-
-       if (!XF86DRIQueryExtension(dri_screen->display, &evbase, &errbase))
-               return 1;
-
-       dri_ctx = calloc(1, sizeof(dri_context_t));
-
-       if (!dri_ctx)
-               return 1;
-
-       if (!XF86DRICreateContext(dri_screen->display, dri_screen->num, visual, &dri_ctx->id, &dri_ctx->drm_context))
-       {
-               free(dri_ctx);
-               return 1;
-       }
-
-       dri_ctx->dri_screen = dri_screen;
-       *dri_context = dri_ctx;
-
-       return 0;
-}
-
-int driDestroyContext(dri_context_t *dri_context)
-{
-       assert(dri_context);
-
-       XF86DRIDestroyContext(dri_context->dri_screen->display, dri_context->dri_screen->num, dri_context->id);
-       free(dri_context);
-
-       return 0;
-}
diff --git a/src/driclient/src/xf86dristr.h b/src/driclient/src/xf86dristr.h
deleted file mode 100644 (file)
index b834bd1..0000000
+++ /dev/null
@@ -1,342 +0,0 @@
-/**************************************************************************
-
-Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
-Copyright 2000 VA Linux Systems, 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 PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
-ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-/*
- * Authors:
- *   Kevin E. Martin <martin@valinux.com>
- *   Jens Owen <jens@tungstengraphics.com>
- *   Rickard E. (Rik) Fiath <faith@valinux.com>
- *
- */
-
-#ifndef _XF86DRISTR_H_
-#define _XF86DRISTR_H_
-
-#include "xf86dri.h"
-
-#define XF86DRINAME "XFree86-DRI"
-
-/* The DRI version number.  This was originally set to be the same of the
- * XFree86 version number.  However, this version is really indepedent of
- * the XFree86 version.
- *
- * Version History:
- *    4.0.0: Original
- *    4.0.1: Patch to bump clipstamp when windows are destroyed, 28 May 02
- *    4.1.0: Add transition from single to multi in DRMInfo rec, 24 Jun 02
- */
-#define XF86DRI_MAJOR_VERSION  4
-#define XF86DRI_MINOR_VERSION  1
-#define XF86DRI_PATCH_VERSION  0
-
-typedef struct _XF86DRIQueryVersion {
-    CARD8      reqType;                /* always DRIReqCode */
-    CARD8      driReqType;             /* always X_DRIQueryVersion */
-    CARD16     length B16;
-} xXF86DRIQueryVersionReq;
-#define sz_xXF86DRIQueryVersionReq     4
-
-typedef struct {
-    BYTE       type;                   /* X_Reply */
-    BOOL       pad1;
-    CARD16     sequenceNumber B16;
-    CARD32     length B32;
-    CARD16     majorVersion B16;       /* major version of DRI protocol */
-    CARD16     minorVersion B16;       /* minor version of DRI protocol */
-    CARD32     patchVersion B32;       /* patch version of DRI protocol */
-    CARD32     pad3 B32;
-    CARD32     pad4 B32;
-    CARD32     pad5 B32;
-    CARD32     pad6 B32;
-} xXF86DRIQueryVersionReply;
-#define sz_xXF86DRIQueryVersionReply   32
-
-typedef struct _XF86DRIQueryDirectRenderingCapable {
-    CARD8      reqType;                /* always DRIReqCode */
-    CARD8      driReqType;             /* X_DRIQueryDirectRenderingCapable */
-    CARD16     length B16;
-    CARD32     screen B32;
-} xXF86DRIQueryDirectRenderingCapableReq;
-#define sz_xXF86DRIQueryDirectRenderingCapableReq      8
-
-typedef struct {
-    BYTE       type;                   /* X_Reply */
-    BOOL       pad1;
-    CARD16     sequenceNumber B16;
-    CARD32     length B32;
-    BOOL       isCapable;
-    BOOL       pad2;
-    BOOL       pad3;
-    BOOL       pad4;
-    CARD32     pad5 B32;
-    CARD32     pad6 B32;
-    CARD32     pad7 B32;
-    CARD32     pad8 B32;
-    CARD32     pad9 B32;
-} xXF86DRIQueryDirectRenderingCapableReply;
-#define sz_xXF86DRIQueryDirectRenderingCapableReply    32
-
-typedef struct _XF86DRIOpenConnection {
-    CARD8      reqType;                /* always DRIReqCode */
-    CARD8      driReqType;             /* always X_DRIOpenConnection */
-    CARD16     length B16;
-    CARD32     screen B32;
-} xXF86DRIOpenConnectionReq;
-#define sz_xXF86DRIOpenConnectionReq   8
-
-typedef struct {
-    BYTE       type;                   /* X_Reply */
-    BOOL       pad1;
-    CARD16     sequenceNumber B16;
-    CARD32     length B32;
-    CARD32     hSAREALow B32;
-    CARD32     hSAREAHigh B32;
-    CARD32     busIdStringLength B32;
-    CARD32     pad6 B32;
-    CARD32     pad7 B32;
-    CARD32     pad8 B32;
-} xXF86DRIOpenConnectionReply;
-#define sz_xXF86DRIOpenConnectionReply 32
-
-typedef struct _XF86DRIAuthConnection {
-    CARD8      reqType;                /* always DRIReqCode */
-    CARD8      driReqType;             /* always X_DRICloseConnection */
-    CARD16     length B16;
-    CARD32     screen B32;
-    CARD32      magic B32;
-} xXF86DRIAuthConnectionReq;
-#define sz_xXF86DRIAuthConnectionReq   12
-
-typedef struct {
-    BYTE        type;
-    BOOL        pad1;
-    CARD16      sequenceNumber B16;
-    CARD32      length B32;
-    CARD32      authenticated B32;
-    CARD32      pad2 B32;
-    CARD32      pad3 B32;
-    CARD32      pad4 B32;
-    CARD32      pad5 B32;
-    CARD32      pad6 B32;
-} xXF86DRIAuthConnectionReply;
-#define zx_xXF86DRIAuthConnectionReply  32
-
-typedef struct _XF86DRICloseConnection {
-    CARD8      reqType;                /* always DRIReqCode */
-    CARD8      driReqType;             /* always X_DRICloseConnection */
-    CARD16     length B16;
-    CARD32     screen B32;
-} xXF86DRICloseConnectionReq;
-#define sz_xXF86DRICloseConnectionReq  8
-
-typedef struct _XF86DRIGetClientDriverName {
-    CARD8      reqType;                /* always DRIReqCode */
-    CARD8      driReqType;             /* always X_DRIGetClientDriverName */
-    CARD16     length B16;
-    CARD32     screen B32;
-} xXF86DRIGetClientDriverNameReq;
-#define sz_xXF86DRIGetClientDriverNameReq      8
-
-typedef struct {
-    BYTE       type;                   /* X_Reply */
-    BOOL       pad1;
-    CARD16     sequenceNumber B16;
-    CARD32     length B32;
-    CARD32     ddxDriverMajorVersion B32;
-    CARD32     ddxDriverMinorVersion B32;
-    CARD32     ddxDriverPatchVersion B32;
-    CARD32     clientDriverNameLength B32;
-    CARD32     pad5 B32;
-    CARD32     pad6 B32;
-} xXF86DRIGetClientDriverNameReply;
-#define sz_xXF86DRIGetClientDriverNameReply    32
-
-typedef struct _XF86DRICreateContext {
-    CARD8      reqType;                /* always DRIReqCode */
-    CARD8      driReqType;             /* always X_DRICreateContext */
-    CARD16     length B16;
-    CARD32     screen B32;
-    CARD32     visual B32;
-    CARD32     context B32;
-} xXF86DRICreateContextReq;
-#define sz_xXF86DRICreateContextReq    16
-
-typedef struct {
-    BYTE       type;                   /* X_Reply */
-    BOOL       pad1;
-    CARD16     sequenceNumber B16;
-    CARD32     length B32;
-    CARD32     hHWContext B32;
-    CARD32     pad2 B32;
-    CARD32     pad3 B32;
-    CARD32     pad4 B32;
-    CARD32     pad5 B32;
-    CARD32     pad6 B32;
-} xXF86DRICreateContextReply;
-#define sz_xXF86DRICreateContextReply  32
-
-typedef struct _XF86DRIDestroyContext {
-    CARD8      reqType;                /* always DRIReqCode */
-    CARD8      driReqType;             /* always X_DRIDestroyContext */
-    CARD16     length B16;
-    CARD32     screen B32;
-    CARD32     context B32;
-} xXF86DRIDestroyContextReq;
-#define sz_xXF86DRIDestroyContextReq   12
-
-typedef struct _XF86DRICreateDrawable {
-    CARD8      reqType;                /* always DRIReqCode */
-    CARD8      driReqType;             /* always X_DRICreateDrawable */
-    CARD16     length B16;
-    CARD32     screen B32;
-    CARD32     drawable B32;
-} xXF86DRICreateDrawableReq;
-#define sz_xXF86DRICreateDrawableReq   12
-
-typedef struct {
-    BYTE       type;                   /* X_Reply */
-    BOOL       pad1;
-    CARD16     sequenceNumber B16;
-    CARD32     length B32;
-    CARD32     hHWDrawable B32;
-    CARD32     pad2 B32;
-    CARD32     pad3 B32;
-    CARD32     pad4 B32;
-    CARD32     pad5 B32;
-    CARD32     pad6 B32;
-} xXF86DRICreateDrawableReply;
-#define sz_xXF86DRICreateDrawableReply 32
-
-typedef struct _XF86DRIDestroyDrawable {
-    CARD8      reqType;                /* always DRIReqCode */
-    CARD8      driReqType;             /* always X_DRIDestroyDrawable */
-    CARD16     length B16;
-    CARD32     screen B32;
-    CARD32     drawable B32;
-} xXF86DRIDestroyDrawableReq;
-#define sz_xXF86DRIDestroyDrawableReq  12
-
-typedef struct _XF86DRIGetDrawableInfo {
-    CARD8      reqType;                /* always DRIReqCode */
-    CARD8      driReqType;             /* always X_DRIGetDrawableInfo */
-    CARD16     length B16;
-    CARD32     screen B32;
-    CARD32     drawable B32;
-} xXF86DRIGetDrawableInfoReq;
-#define sz_xXF86DRIGetDrawableInfoReq  12
-
-typedef struct {
-    BYTE       type;                   /* X_Reply */
-    BOOL       pad1;
-    CARD16     sequenceNumber B16;
-    CARD32     length B32;
-    CARD32     drawableTableIndex B32;
-    CARD32     drawableTableStamp B32;
-    INT16      drawableX B16;
-    INT16      drawableY B16;
-    INT16      drawableWidth B16;
-    INT16      drawableHeight B16;
-    CARD32     numClipRects B32;
-    INT16       backX B16;
-    INT16       backY B16;
-    CARD32      numBackClipRects B32;
-} xXF86DRIGetDrawableInfoReply;
-
-#define sz_xXF86DRIGetDrawableInfoReply        36
-
-
-typedef struct _XF86DRIGetDeviceInfo {
-    CARD8      reqType;                /* always DRIReqCode */
-    CARD8      driReqType;             /* always X_DRIGetDeviceInfo */
-    CARD16     length B16;
-    CARD32     screen B32;
-} xXF86DRIGetDeviceInfoReq;
-#define sz_xXF86DRIGetDeviceInfoReq    8
-
-typedef struct {
-    BYTE       type;                   /* X_Reply */
-    BOOL       pad1;
-    CARD16     sequenceNumber B16;
-    CARD32     length B32;
-    CARD32     hFrameBufferLow B32;
-    CARD32     hFrameBufferHigh B32;
-    CARD32     framebufferOrigin B32;
-    CARD32     framebufferSize B32;
-    CARD32     framebufferStride B32;
-    CARD32     devPrivateSize B32;
-} xXF86DRIGetDeviceInfoReply;
-#define sz_xXF86DRIGetDeviceInfoReply  32
-
-typedef struct _XF86DRIOpenFullScreen {
-    CARD8       reqType;       /* always DRIReqCode */
-    CARD8       driReqType;    /* always X_DRIOpenFullScreen */
-    CARD16      length B16;
-    CARD32      screen B32;
-    CARD32      drawable B32;
-} xXF86DRIOpenFullScreenReq;
-#define sz_xXF86DRIOpenFullScreenReq    12
-
-typedef struct {
-    BYTE        type;
-    BOOL        pad1;
-    CARD16      sequenceNumber B16;
-    CARD32      length B32;
-    CARD32      isFullScreen B32;
-    CARD32      pad2 B32;
-    CARD32      pad3 B32;
-    CARD32      pad4 B32;
-    CARD32      pad5 B32;
-    CARD32      pad6 B32;
-} xXF86DRIOpenFullScreenReply;
-#define sz_xXF86DRIOpenFullScreenReply  32
-
-typedef struct _XF86DRICloseFullScreen {
-    CARD8       reqType;       /* always DRIReqCode */
-    CARD8       driReqType;    /* always X_DRICloseFullScreen */
-    CARD16      length B16;
-    CARD32      screen B32;
-    CARD32      drawable B32;
-} xXF86DRICloseFullScreenReq;
-#define sz_xXF86DRICloseFullScreenReq   12
-
-typedef struct {
-    BYTE        type;
-    BOOL        pad1;
-    CARD16      sequenceNumber B16;
-    CARD32      length B32;
-    CARD32      pad2 B32;
-    CARD32      pad3 B32;
-    CARD32      pad4 B32;
-    CARD32      pad5 B32;
-    CARD32      pad6 B32;
-    CARD32      pad7 B32;
-} xXF86DRICloseFullScreenReply;
-#define sz_xXF86DRICloseFullScreenReply  32
-
-
-#endif /* _XF86DRISTR_H_ */
index 7d7d700eacd2602f4e95ed53e4436bca608c763c..e40f546929df94c6124bab09c0abc7fdc855acf1 100644 (file)
@@ -143,14 +143,13 @@ C_SOURCES = \
        util/u_transfer.c \
        util/u_resource.c \
        util/u_upload_mgr.c \
-       util/u_vbuf_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 \
+       util/u_vbuf_mgr.c \
+       vl/vl_bitstream_parser.c \
+       vl/vl_mpeg12_mc_renderer.c \
+       vl/vl_compositor.c \
+       vl/vl_csc.c \
+        vl/vl_idct.c \
+        vl/vl_vertex_buffers.c
 
 GALLIVM_SOURCES = \
         gallivm/lp_bld_arit.c \
@@ -221,3 +220,4 @@ util/u_format_table.c: util/u_format_table.py util/u_format_pack.py util/u_forma
 
 util/u_half.c: util/u_half.py
        $(PYTHON2) util/u_half.py > $@
+# DO NOT DELETE
index 0ec6307161555614b562321e23f041349b9380c4..11024d4192356bbe260628a3c0d9b2fd64bc0877 100644 (file)
@@ -191,12 +191,10 @@ source = [
     'util/u_transfer.c',
     'util/u_upload_mgr.c',
     'util/u_vbuf_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',
 ]
 
 if env['llvm']:
index 26a0eebc54483b724b1453becfa625c7d3e1b2b3..0ae15c9cc0a50f47c8169127919da1188dc996e4 100644 (file)
@@ -237,3 +237,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
index ab8bf29c97b9eb665688fc4833cf64594f8c86e6..64ea0b35347b81f51d7dc273220ad3a34c9f1f49 100644 (file)
@@ -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) {}
index dc9632346d15839178274277e57fbe138c654b79..9f2365a52662e3da093152bdd6916a07c8049328 100644 (file)
@@ -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/auxiliary/util/u_video.h b/src/gallium/auxiliary/util/u_video.h
new file mode 100644 (file)
index 0000000..78cceb6
--- /dev/null
@@ -0,0 +1,71 @@
+/**************************************************************************
+ *
+ * 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 U_VIDEO_H
+#define U_VIDEO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <pipe/p_defines.h>
+
+/* u_reduce_video_profile() needs these */
+#include <pipe/p_compiler.h>
+#include <util/u_debug.h>
+
+static INLINE enum pipe_video_codec
+u_reduce_video_profile(enum pipe_video_profile profile)
+{
+   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;
+   }
+}
+
+#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 (file)
index 0000000..f07b344
--- /dev/null
@@ -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 (file)
index 0000000..eeb51dd
--- /dev/null
@@ -0,0 +1,67 @@
+/**************************************************************************
+ * 
+ * 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;
+};
+
+inline void endian_swap_ushort(unsigned short *x);
+inline void endian_swap_uint(unsigned int *x);
+inline void endian_swap_ulonglong(unsigned long long *x);
+
+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 (file)
index 0000000..d1ba5fa
--- /dev/null
@@ -0,0 +1,640 @@
+/**************************************************************************
+ *
+ * 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 "util/u_draw.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_draw.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;
+
+   memset(&sampler, 0, sizeof(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_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.buffer_offset = 0;
+   /* XXX: Create with DYNAMIC or STREAM */
+   c->vertex_buf.buffer = pipe_buffer_create
+   (
+      c->pipe->screen,
+      PIPE_BIND_VERTEX_BUFFER,
+      PIPE_USAGE_STATIC,
+      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,
+      PIPE_USAGE_STATIC,
+      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, 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);
+
+      util_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, buf_transfer);
+}
diff --git a/src/gallium/auxiliary/vl/vl_compositor.h b/src/gallium/auxiliary/vl/vl_compositor.h
new file mode 100644 (file)
index 0000000..820c9ef
--- /dev/null
@@ -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 (file)
index 0000000..5ecc43a
--- /dev/null
@@ -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 (file)
index 0000000..722ca35
--- /dev/null
@@ -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_idct.c b/src/gallium/auxiliary/vl/vl_idct.c
new file mode 100644 (file)
index 0000000..89463a5
--- /dev/null
@@ -0,0 +1,766 @@
+/**************************************************************************
+ *
+ * Copyright 2010 Christian König
+ * 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_idct.h"
+#include "vl_vertex_buffers.h"
+#include "util/u_draw.h"
+#include <assert.h>
+#include <pipe/p_context.h>
+#include <pipe/p_screen.h>
+#include <util/u_inlines.h>
+#include <util/u_sampler.h>
+#include <util/u_format.h>
+#include <tgsi/tgsi_ureg.h>
+#include "vl_types.h"
+
+#define BLOCK_WIDTH 8
+#define BLOCK_HEIGHT 8
+
+#define SCALE_FACTOR_16_TO_9 (32768.0f / 256.0f)
+
+#define NR_RENDER_TARGETS 4
+
+enum VS_INPUT
+{
+   VS_I_RECT,
+   VS_I_VPOS,
+
+   NUM_VS_INPUTS
+};
+
+enum VS_OUTPUT
+{
+   VS_O_VPOS,
+   VS_O_L_ADDR0,
+   VS_O_L_ADDR1,
+   VS_O_R_ADDR0,
+   VS_O_R_ADDR1
+};
+
+static const float const_matrix[8][8] = {
+   {  0.3535530f,  0.3535530f,  0.3535530f,  0.3535530f,  0.3535530f,  0.3535530f,  0.353553f,  0.3535530f },
+   {  0.4903930f,  0.4157350f,  0.2777850f,  0.0975451f, -0.0975452f, -0.2777850f, -0.415735f, -0.4903930f },
+   {  0.4619400f,  0.1913420f, -0.1913420f, -0.4619400f, -0.4619400f, -0.1913420f,  0.191342f,  0.4619400f },
+   {  0.4157350f, -0.0975452f, -0.4903930f, -0.2777850f,  0.2777850f,  0.4903930f,  0.097545f, -0.4157350f },
+   {  0.3535530f, -0.3535530f, -0.3535530f,  0.3535540f,  0.3535530f, -0.3535540f, -0.353553f,  0.3535530f },
+   {  0.2777850f, -0.4903930f,  0.0975452f,  0.4157350f, -0.4157350f, -0.0975451f,  0.490393f, -0.2777850f },
+   {  0.1913420f, -0.4619400f,  0.4619400f, -0.1913420f, -0.1913410f,  0.4619400f, -0.461940f,  0.1913420f },
+   {  0.0975451f, -0.2777850f,  0.4157350f, -0.4903930f,  0.4903930f, -0.4157350f,  0.277786f, -0.0975458f }
+};
+
+static void
+calc_addr(struct ureg_program *shader, struct ureg_dst addr[2],
+          struct ureg_src tc, struct ureg_src start, bool right_side,
+          bool transposed, float size)
+{
+   unsigned wm_start = (right_side == transposed) ? TGSI_WRITEMASK_X : TGSI_WRITEMASK_Y;
+   unsigned sw_start = right_side ? TGSI_SWIZZLE_Y : TGSI_SWIZZLE_X;
+
+   unsigned wm_tc = (right_side == transposed) ? TGSI_WRITEMASK_Y : TGSI_WRITEMASK_X;
+   unsigned sw_tc = right_side ? TGSI_SWIZZLE_X : TGSI_SWIZZLE_Y;
+
+   /*
+    * addr[0..1].(start) = right_side ? start.x : tc.x
+    * addr[0..1].(tc) = right_side ? tc.y : start.y
+    * addr[0..1].z = tc.z
+    * addr[1].(start) += 1.0f / scale
+    */
+   ureg_MOV(shader, ureg_writemask(addr[0], wm_start), ureg_scalar(start, sw_start));
+   ureg_MOV(shader, ureg_writemask(addr[0], wm_tc), ureg_scalar(tc, sw_tc));
+   ureg_MOV(shader, ureg_writemask(addr[0], TGSI_WRITEMASK_Z), tc);
+
+   ureg_ADD(shader, ureg_writemask(addr[1], wm_start), ureg_scalar(start, sw_start), ureg_imm1f(shader, 1.0f / size));
+   ureg_MOV(shader, ureg_writemask(addr[1], wm_tc), ureg_scalar(tc, sw_tc));
+   ureg_MOV(shader, ureg_writemask(addr[1], TGSI_WRITEMASK_Z), tc);
+}
+
+static void *
+create_vert_shader(struct vl_idct *idct, bool matrix_stage)
+{
+   struct ureg_program *shader;
+   struct ureg_src scale;
+   struct ureg_src vrect, vpos;
+   struct ureg_dst t_tex, t_start;
+   struct ureg_dst o_vpos, o_l_addr[2], o_r_addr[2];
+
+   shader = ureg_create(TGSI_PROCESSOR_VERTEX);
+   if (!shader)
+      return NULL;
+
+   t_tex = ureg_DECL_temporary(shader);
+   t_start = ureg_DECL_temporary(shader);
+
+   vrect = ureg_DECL_vs_input(shader, VS_I_RECT);
+   vpos = ureg_DECL_vs_input(shader, VS_I_VPOS);
+
+   o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, VS_O_VPOS);
+
+   o_l_addr[0] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_L_ADDR0);
+   o_l_addr[1] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_L_ADDR1);
+
+   o_r_addr[0] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_R_ADDR0);
+   o_r_addr[1] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_R_ADDR1);
+
+   /*
+    * scale = (BLOCK_WIDTH, BLOCK_HEIGHT) / (dst.width, dst.height)
+    *
+    * t_vpos = vpos + vrect
+    * o_vpos.xy = t_vpos * scale
+    * o_vpos.zw = vpos
+    *
+    * o_l_addr = calc_addr(...)
+    * o_r_addr = calc_addr(...)
+    *
+    */
+   scale = ureg_imm2f(shader,
+      (float)BLOCK_WIDTH / idct->buffer_width,
+      (float)BLOCK_HEIGHT / idct->buffer_height);
+
+   ureg_ADD(shader, ureg_writemask(t_tex, TGSI_WRITEMASK_XY), vpos, vrect);
+   ureg_MUL(shader, ureg_writemask(t_tex, TGSI_WRITEMASK_XY), ureg_src(t_tex), scale);
+   ureg_MUL(shader, ureg_writemask(t_tex, TGSI_WRITEMASK_Z),
+      ureg_scalar(vrect, TGSI_SWIZZLE_X),
+      ureg_imm1f(shader, BLOCK_WIDTH / NR_RENDER_TARGETS));
+
+   ureg_MOV(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_XY), ureg_src(t_tex));
+   ureg_MOV(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_ZW), vpos);
+
+   ureg_MUL(shader, ureg_writemask(t_start, TGSI_WRITEMASK_XY), vpos, scale);
+
+   if(matrix_stage) {
+      calc_addr(shader, o_l_addr, ureg_src(t_tex), ureg_src(t_start), false, false, idct->buffer_width / 4);
+      calc_addr(shader, o_r_addr, vrect, ureg_imm1f(shader, 0.0f), true, true, BLOCK_WIDTH / 4);
+   } else {
+      calc_addr(shader, o_l_addr, vrect, ureg_imm1f(shader, 0.0f), false, false, BLOCK_WIDTH / 4);
+      calc_addr(shader, o_r_addr, ureg_src(t_tex), ureg_src(t_start), true, false, idct->buffer_height / 4);
+   }
+
+   ureg_release_temporary(shader, t_tex);
+   ureg_release_temporary(shader, t_start);
+
+   ureg_END(shader);
+
+   return ureg_create_shader_and_destroy(shader, idct->pipe);
+}
+
+static void
+increment_addr(struct ureg_program *shader, struct ureg_dst daddr[2],
+               struct ureg_src saddr[2], bool right_side, bool transposed,
+               int pos, float size)
+{
+   unsigned wm_start = (right_side == transposed) ? TGSI_WRITEMASK_X : TGSI_WRITEMASK_Y;
+   unsigned wm_tc = (right_side == transposed) ? TGSI_WRITEMASK_Y : TGSI_WRITEMASK_X;
+
+   /*
+    * daddr[0..1].(start) = saddr[0..1].(start)
+    * daddr[0..1].(tc) = saddr[0..1].(tc)
+    */
+
+   ureg_MOV(shader, ureg_writemask(daddr[0], wm_start), saddr[0]);
+   ureg_ADD(shader, ureg_writemask(daddr[0], wm_tc), saddr[0], ureg_imm1f(shader, pos / size));
+   ureg_MOV(shader, ureg_writemask(daddr[1], wm_start), saddr[1]);
+   ureg_ADD(shader, ureg_writemask(daddr[1], wm_tc), saddr[1], ureg_imm1f(shader, pos / size));
+}
+
+static void
+fetch_four(struct ureg_program *shader, struct ureg_dst m[2], struct ureg_src addr[2], struct ureg_src sampler)
+{
+   ureg_TEX(shader, m[0], TGSI_TEXTURE_3D, addr[0], sampler);
+   ureg_TEX(shader, m[1], TGSI_TEXTURE_3D, addr[1], sampler);
+}
+
+static void
+matrix_mul(struct ureg_program *shader, struct ureg_dst dst, struct ureg_dst l[2], struct ureg_dst r[2])
+{
+   struct ureg_dst tmp;
+
+   tmp = ureg_DECL_temporary(shader);
+
+   /*
+    * tmp.xy = dot4(m[0][0..1], m[1][0..1])
+    * dst = tmp.x + tmp.y
+    */
+   ureg_DP4(shader, ureg_writemask(tmp, TGSI_WRITEMASK_X), ureg_src(l[0]), ureg_src(r[0]));
+   ureg_DP4(shader, ureg_writemask(tmp, TGSI_WRITEMASK_Y), ureg_src(l[1]), ureg_src(r[1]));
+   ureg_ADD(shader, dst,
+      ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_X),
+      ureg_scalar(ureg_src(tmp), TGSI_SWIZZLE_Y));
+
+   ureg_release_temporary(shader, tmp);
+}
+
+static void *
+create_matrix_frag_shader(struct vl_idct *idct)
+{
+   struct ureg_program *shader;
+
+   struct ureg_src l_addr[2], r_addr[2];
+
+   struct ureg_dst l[4][2], r[2];
+   struct ureg_dst fragment[NR_RENDER_TARGETS];
+
+   unsigned i, j;
+
+   shader = ureg_create(TGSI_PROCESSOR_FRAGMENT);
+   if (!shader)
+      return NULL;
+
+   l_addr[0] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_L_ADDR0, TGSI_INTERPOLATE_LINEAR);
+   l_addr[1] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_L_ADDR1, TGSI_INTERPOLATE_LINEAR);
+
+   r_addr[0] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_R_ADDR0, TGSI_INTERPOLATE_LINEAR);
+   r_addr[1] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_R_ADDR1, TGSI_INTERPOLATE_LINEAR);
+
+   for (i = 0; i < NR_RENDER_TARGETS; ++i)
+       fragment[i] = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, i);
+
+   for (i = 0; i < 4; ++i) {
+      l[i][0] = ureg_DECL_temporary(shader);
+      l[i][1] = ureg_DECL_temporary(shader);
+   }
+
+   r[0] = ureg_DECL_temporary(shader);
+   r[1] = ureg_DECL_temporary(shader);
+
+   for (i = 1; i < 4; ++i) {
+      increment_addr(shader, l[i], l_addr, false, false, i, idct->buffer_height);
+   }
+
+   for (i = 0; i < 4; ++i) {
+      struct ureg_src s_addr[2];
+      s_addr[0] = i == 0 ? l_addr[0] : ureg_src(l[i][0]);
+      s_addr[1] = i == 0 ? l_addr[1] : ureg_src(l[i][1]);
+      fetch_four(shader, l[i], s_addr, ureg_DECL_sampler(shader, 1));
+   }
+
+   for (i = 0; i < NR_RENDER_TARGETS; ++i) {
+      if(i > 0)
+         increment_addr(shader, r, r_addr, true, true, i, BLOCK_HEIGHT);
+
+      struct ureg_src s_addr[2] = { ureg_src(r[0]), ureg_src(r[1]) };
+      s_addr[0] = i == 0 ? r_addr[0] : ureg_src(r[0]);
+      s_addr[1] = i == 0 ? r_addr[1] : ureg_src(r[1]);
+      fetch_four(shader, r, s_addr, ureg_DECL_sampler(shader, 0));
+
+      for (j = 0; j < 4; ++j) {
+         matrix_mul(shader, ureg_writemask(fragment[i], TGSI_WRITEMASK_X << j), l[j], r);
+      }
+   }
+
+   for (i = 0; i < 4; ++i) {
+      ureg_release_temporary(shader, l[i][0]);
+      ureg_release_temporary(shader, l[i][1]);
+   }
+   ureg_release_temporary(shader, r[0]);
+   ureg_release_temporary(shader, r[1]);
+
+   ureg_END(shader);
+
+   return ureg_create_shader_and_destroy(shader, idct->pipe);
+}
+
+static void *
+create_transpose_frag_shader(struct vl_idct *idct)
+{
+   struct ureg_program *shader;
+
+   struct ureg_src l_addr[2], r_addr[2];
+
+   struct ureg_dst l[2], r[2];
+   struct ureg_dst fragment;
+
+   shader = ureg_create(TGSI_PROCESSOR_FRAGMENT);
+   if (!shader)
+      return NULL;
+
+   l_addr[0] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_L_ADDR0, TGSI_INTERPOLATE_LINEAR);
+   l_addr[1] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_L_ADDR1, TGSI_INTERPOLATE_LINEAR);
+
+   r_addr[0] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_R_ADDR0, TGSI_INTERPOLATE_LINEAR);
+   r_addr[1] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_R_ADDR1, TGSI_INTERPOLATE_LINEAR);
+
+   l[0] = ureg_DECL_temporary(shader);
+   l[1] = ureg_DECL_temporary(shader);
+   r[0] = ureg_DECL_temporary(shader);
+   r[1] = ureg_DECL_temporary(shader);
+
+   fetch_four(shader, l, l_addr, ureg_DECL_sampler(shader, 0));
+   fetch_four(shader, r, r_addr, ureg_DECL_sampler(shader, 1));
+
+   fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0);
+
+   matrix_mul(shader, ureg_writemask(fragment, TGSI_WRITEMASK_X), l, r);
+
+   ureg_release_temporary(shader, l[0]);
+   ureg_release_temporary(shader, l[1]);
+   ureg_release_temporary(shader, r[0]);
+   ureg_release_temporary(shader, r[1]);
+
+   ureg_END(shader);
+
+   return ureg_create_shader_and_destroy(shader, idct->pipe);
+}
+
+static bool
+init_shaders(struct vl_idct *idct)
+{
+   idct->matrix_vs = create_vert_shader(idct, true);
+   idct->matrix_fs = create_matrix_frag_shader(idct);
+
+   idct->transpose_vs = create_vert_shader(idct, false);
+   idct->transpose_fs = create_transpose_frag_shader(idct);
+
+   return
+      idct->matrix_vs != NULL &&
+      idct->matrix_fs != NULL &&
+      idct->transpose_vs != NULL &&
+      idct->transpose_fs != NULL;
+}
+
+static void
+cleanup_shaders(struct vl_idct *idct)
+{
+   idct->pipe->delete_vs_state(idct->pipe, idct->matrix_vs);
+   idct->pipe->delete_fs_state(idct->pipe, idct->matrix_fs);
+   idct->pipe->delete_vs_state(idct->pipe, idct->transpose_vs);
+   idct->pipe->delete_fs_state(idct->pipe, idct->transpose_fs);
+}
+
+static bool
+init_state(struct vl_idct *idct)
+{
+   struct pipe_vertex_element vertex_elems[NUM_VS_INPUTS];
+   struct pipe_sampler_state sampler;
+   struct pipe_rasterizer_state rs_state;
+   unsigned i;
+
+   assert(idct);
+
+   idct->quad = vl_vb_upload_quads(idct->pipe, idct->max_blocks);
+
+   if(idct->quad.buffer == NULL)
+      return false;
+
+   for (i = 0; i < 4; ++i) {
+      memset(&sampler, 0, sizeof(sampler));
+      sampler.wrap_s = PIPE_TEX_WRAP_REPEAT;
+      sampler.wrap_t = PIPE_TEX_WRAP_REPEAT;
+      sampler.wrap_r = PIPE_TEX_WRAP_REPEAT;
+      sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST;
+      sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
+      sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
+      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[0] = ; */
+      /*sampler.max_anisotropy = ; */
+      idct->samplers.all[i] = idct->pipe->create_sampler_state(idct->pipe, &sampler);
+   }
+
+   memset(&rs_state, 0, sizeof(rs_state));
+   /*rs_state.sprite_coord_enable */
+   rs_state.sprite_coord_mode = PIPE_SPRITE_COORD_UPPER_LEFT;
+   rs_state.point_quad_rasterization = true;
+   rs_state.point_size = BLOCK_WIDTH;
+   rs_state.gl_rasterization_rules = false;
+   idct->rs_state = idct->pipe->create_rasterizer_state(idct->pipe, &rs_state);
+
+   vertex_elems[VS_I_RECT] = vl_vb_get_quad_vertex_element();
+
+   /* Pos element */
+   vertex_elems[VS_I_VPOS].src_format = PIPE_FORMAT_R16G16_SSCALED;
+
+   idct->vertex_buffer_stride = vl_vb_element_helper(&vertex_elems[VS_I_VPOS], 1, 1);
+   idct->vertex_elems_state = idct->pipe->create_vertex_elements_state(idct->pipe, 2, vertex_elems);
+
+   return true;
+}
+
+static void
+cleanup_state(struct vl_idct *idct)
+{
+   unsigned i;
+
+   for (i = 0; i < 4; ++i)
+      idct->pipe->delete_sampler_state(idct->pipe, idct->samplers.all[i]);
+
+   idct->pipe->delete_rasterizer_state(idct->pipe, idct->rs_state);
+   idct->pipe->delete_vertex_elements_state(idct->pipe, idct->vertex_elems_state);
+}
+
+static bool
+init_textures(struct vl_idct *idct, struct vl_idct_buffer *buffer)
+{
+   struct pipe_resource template;
+   struct pipe_sampler_view sampler_view;
+   unsigned i;
+
+   assert(idct && buffer);
+
+   /* create textures */
+   memset(&template, 0, sizeof(struct pipe_resource));
+   template.last_level = 0;
+   template.bind = PIPE_BIND_SAMPLER_VIEW;
+   template.flags = 0;
+
+   template.target = PIPE_TEXTURE_2D;
+   template.format = PIPE_FORMAT_R16G16B16A16_SNORM;
+   template.width0 = idct->buffer_width / 4;
+   template.height0 = idct->buffer_height;
+   template.depth0 = 1;
+   template.array_size = 1;
+   template.usage = PIPE_USAGE_STREAM;
+   buffer->textures.individual.source = idct->pipe->screen->resource_create(idct->pipe->screen, &template);
+
+   template.target = PIPE_TEXTURE_3D;
+   template.format = PIPE_FORMAT_R16G16B16A16_SNORM;
+   template.width0 = idct->buffer_width / NR_RENDER_TARGETS;
+   template.height0 = idct->buffer_height / 4;
+   template.depth0 = NR_RENDER_TARGETS;
+   template.usage = PIPE_USAGE_STATIC;
+   buffer->textures.individual.intermediate = idct->pipe->screen->resource_create(idct->pipe->screen, &template);
+
+   for (i = 0; i < 4; ++i) {
+      if(buffer->textures.all[i] == NULL)
+         return false; /* a texture failed to allocate */
+
+      u_sampler_view_default_template(&sampler_view, buffer->textures.all[i], buffer->textures.all[i]->format);
+      buffer->sampler_views.all[i] = idct->pipe->create_sampler_view(idct->pipe, buffer->textures.all[i], &sampler_view);
+   }
+
+   return true;
+}
+
+static void
+cleanup_textures(struct vl_idct *idct, struct vl_idct_buffer *buffer)
+{
+   unsigned i;
+
+   assert(idct && buffer);
+
+   for (i = 0; i < 4; ++i) {
+      pipe_sampler_view_reference(&buffer->sampler_views.all[i], NULL);
+      pipe_resource_reference(&buffer->textures.all[i], NULL);
+   }
+}
+
+static bool
+init_vertex_buffers(struct vl_idct *idct, struct vl_idct_buffer *buffer)
+{
+   assert(idct && buffer);
+
+   buffer->vertex_bufs.individual.quad.stride = idct->quad.stride;
+   buffer->vertex_bufs.individual.quad.buffer_offset = idct->quad.buffer_offset;
+   pipe_resource_reference(&buffer->vertex_bufs.individual.quad.buffer, idct->quad.buffer);
+
+   buffer->vertex_bufs.individual.pos = vl_vb_init(
+      &buffer->blocks, idct->pipe, idct->max_blocks,
+      idct->vertex_buffer_stride);
+
+   if(buffer->vertex_bufs.individual.pos.buffer == NULL)
+      return false;
+
+   return true;
+}
+
+static void
+cleanup_vertex_buffers(struct vl_idct *idct, struct vl_idct_buffer *buffer)
+{
+   assert(idct && buffer);
+
+   pipe_resource_reference(&buffer->vertex_bufs.individual.quad.buffer, NULL);
+   pipe_resource_reference(&buffer->vertex_bufs.individual.pos.buffer, NULL);
+
+   vl_vb_cleanup(&buffer->blocks);
+}
+
+struct pipe_resource *
+vl_idct_upload_matrix(struct pipe_context *pipe)
+{
+   struct pipe_resource template, *matrix;
+   struct pipe_transfer *buf_transfer;
+   unsigned i, j, pitch;
+   float *f;
+
+   struct pipe_box rect =
+   {
+      0, 0, 0,
+      BLOCK_WIDTH / 4,
+      BLOCK_HEIGHT,
+      1
+   };
+
+   memset(&template, 0, sizeof(struct pipe_resource));
+   template.target = PIPE_TEXTURE_2D;
+   template.format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+   template.last_level = 0;
+   template.width0 = 2;
+   template.height0 = 8;
+   template.depth0 = 1;
+   template.array_size = 1;
+   template.usage = PIPE_USAGE_IMMUTABLE;
+   template.bind = PIPE_BIND_SAMPLER_VIEW;
+   template.flags = 0;
+
+   matrix = pipe->screen->resource_create(pipe->screen, &template);
+
+   /* matrix */
+   buf_transfer = pipe->get_transfer
+   (
+      pipe, matrix,
+      0, PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD,
+      &rect
+   );
+   pitch = buf_transfer->stride / sizeof(float);
+
+   f = pipe->transfer_map(pipe, buf_transfer);
+   for(i = 0; i < BLOCK_HEIGHT; ++i)
+      for(j = 0; j < BLOCK_WIDTH; ++j)
+         // transpose and scale
+         f[i * pitch + j] = const_matrix[j][i] * sqrtf(SCALE_FACTOR_16_TO_9);
+
+   pipe->transfer_unmap(pipe, buf_transfer);
+   pipe->transfer_destroy(pipe, buf_transfer);
+
+   return matrix;
+}
+
+bool vl_idct_init(struct vl_idct *idct, struct pipe_context *pipe,
+                  unsigned buffer_width, unsigned buffer_height,
+                  struct pipe_resource *matrix)
+{
+   assert(idct && pipe && matrix);
+
+   idct->pipe = pipe;
+   idct->buffer_width = buffer_width;
+   idct->buffer_height = buffer_height;
+   pipe_resource_reference(&idct->matrix, matrix);
+
+   idct->max_blocks =
+      align(buffer_width, BLOCK_WIDTH) / BLOCK_WIDTH *
+      align(buffer_height, BLOCK_HEIGHT) / BLOCK_HEIGHT;
+
+   if(!init_shaders(idct))
+      return false;
+
+   if(!init_state(idct)) {
+      cleanup_shaders(idct);
+      return false;
+   }
+
+   return true;
+}
+
+void
+vl_idct_cleanup(struct vl_idct *idct)
+{
+   cleanup_shaders(idct);
+   cleanup_state(idct);
+
+   pipe_resource_reference(&idct->matrix, NULL);
+}
+
+bool
+vl_idct_init_buffer(struct vl_idct *idct, struct vl_idct_buffer *buffer, struct pipe_resource *dst)
+{
+   struct pipe_surface template;
+
+   unsigned i;
+
+   assert(buffer);
+   assert(idct);
+   assert(dst);
+
+   pipe_resource_reference(&buffer->textures.individual.matrix, idct->matrix);
+   pipe_resource_reference(&buffer->textures.individual.transpose, idct->matrix);
+   pipe_resource_reference(&buffer->destination, dst);
+
+   if (!init_textures(idct, buffer))
+      return false;
+
+   if (!init_vertex_buffers(idct, buffer))
+      return false;
+
+   /* init state */
+   buffer->viewport[0].scale[0] = buffer->textures.individual.intermediate->width0;
+   buffer->viewport[0].scale[1] = buffer->textures.individual.intermediate->height0;
+
+   buffer->viewport[1].scale[0] = buffer->destination->width0;
+   buffer->viewport[1].scale[1] = buffer->destination->height0;
+
+   buffer->fb_state[0].width = buffer->textures.individual.intermediate->width0;
+   buffer->fb_state[0].height = buffer->textures.individual.intermediate->height0;
+
+   buffer->fb_state[0].nr_cbufs = NR_RENDER_TARGETS;
+   for(i = 0; i < NR_RENDER_TARGETS; ++i) {
+      memset(&template, 0, sizeof(template));
+      template.format = buffer->textures.individual.intermediate->format;
+      template.u.tex.first_layer = i;
+      template.u.tex.last_layer = i;
+      template.usage = PIPE_BIND_RENDER_TARGET;
+      buffer->fb_state[0].cbufs[i] = idct->pipe->create_surface(
+         idct->pipe, buffer->textures.individual.intermediate,
+         &template);
+   }
+
+   buffer->fb_state[1].width = buffer->destination->width0;
+   buffer->fb_state[1].height = buffer->destination->height0;
+
+   buffer->fb_state[1].nr_cbufs = 1;
+
+   memset(&template, 0, sizeof(template));
+   template.format = buffer->destination->format;
+   template.usage = PIPE_BIND_RENDER_TARGET;
+   buffer->fb_state[1].cbufs[0] = idct->pipe->create_surface(
+      idct->pipe, buffer->destination, &template);
+
+   for(i = 0; i < 2; ++i) {
+      buffer->viewport[i].scale[2] = 1;
+      buffer->viewport[i].scale[3] = 1;
+      buffer->viewport[i].translate[0] = 0;
+      buffer->viewport[i].translate[1] = 0;
+      buffer->viewport[i].translate[2] = 0;
+      buffer->viewport[i].translate[3] = 0;
+
+      buffer->fb_state[i].zsbuf = NULL;
+   }
+
+   return true;
+}
+
+void
+vl_idct_cleanup_buffer(struct vl_idct *idct, struct vl_idct_buffer *buffer)
+{
+   unsigned i;
+
+   assert(buffer);
+
+   for(i = 0; i < NR_RENDER_TARGETS; ++i) {
+      idct->pipe->surface_destroy(idct->pipe, buffer->fb_state[0].cbufs[i]);
+   }
+
+   idct->pipe->surface_destroy(idct->pipe, buffer->fb_state[1].cbufs[0]);
+
+   cleanup_textures(idct, buffer);
+   cleanup_vertex_buffers(idct, buffer);
+}
+
+void
+vl_idct_map_buffers(struct vl_idct *idct, struct vl_idct_buffer *buffer)
+{
+   assert(idct);
+
+   struct pipe_box rect =
+   {
+      0, 0, 0,
+      buffer->textures.individual.source->width0,
+      buffer->textures.individual.source->height0,
+      1
+   };
+
+   buffer->tex_transfer = idct->pipe->get_transfer
+   (
+      idct->pipe, buffer->textures.individual.source,
+      0, PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD,
+      &rect
+   );
+
+   buffer->texels = idct->pipe->transfer_map(idct->pipe, buffer->tex_transfer);
+
+   vl_vb_map(&buffer->blocks, idct->pipe);
+}
+
+void
+vl_idct_add_block(struct vl_idct_buffer *buffer, unsigned x, unsigned y, short *block)
+{
+   struct vertex2s v;
+   unsigned tex_pitch;
+   short *texels;
+
+   unsigned i;
+
+   assert(buffer);
+
+   tex_pitch = buffer->tex_transfer->stride / sizeof(short);
+   texels = buffer->texels + y * tex_pitch * BLOCK_HEIGHT + x * BLOCK_WIDTH;
+
+   for (i = 0; i < BLOCK_HEIGHT; ++i)
+      memcpy(texels + i * tex_pitch, block + i * BLOCK_WIDTH, BLOCK_WIDTH * sizeof(short));
+
+   v.x = x;
+   v.y = y;
+   vl_vb_add_block(&buffer->blocks, &v);
+}
+
+void
+vl_idct_unmap_buffers(struct vl_idct *idct, struct vl_idct_buffer *buffer)
+{
+   assert(idct && buffer);
+
+   idct->pipe->transfer_unmap(idct->pipe, buffer->tex_transfer);
+   idct->pipe->transfer_destroy(idct->pipe, buffer->tex_transfer);
+   vl_vb_unmap(&buffer->blocks, idct->pipe);
+}
+
+void
+vl_idct_flush(struct vl_idct *idct, struct vl_idct_buffer *buffer)
+{
+   unsigned num_verts;
+
+   assert(idct);
+
+   num_verts = vl_vb_restart(&buffer->blocks);
+
+   if(num_verts > 0) {
+
+      idct->pipe->bind_rasterizer_state(idct->pipe, idct->rs_state);
+      idct->pipe->set_vertex_buffers(idct->pipe, 2, buffer->vertex_bufs.all);
+      idct->pipe->bind_vertex_elements_state(idct->pipe, idct->vertex_elems_state);
+
+      /* first stage */
+      idct->pipe->set_framebuffer_state(idct->pipe, &buffer->fb_state[0]);
+      idct->pipe->set_viewport_state(idct->pipe, &buffer->viewport[0]);
+      idct->pipe->set_fragment_sampler_views(idct->pipe, 2, buffer->sampler_views.stage[0]);
+      idct->pipe->bind_fragment_sampler_states(idct->pipe, 2, idct->samplers.stage[0]);
+      idct->pipe->bind_vs_state(idct->pipe, idct->matrix_vs);
+      idct->pipe->bind_fs_state(idct->pipe, idct->matrix_fs);
+      util_draw_arrays(idct->pipe, PIPE_PRIM_QUADS, 0, num_verts);
+
+      /* second stage */
+      idct->pipe->set_framebuffer_state(idct->pipe, &buffer->fb_state[1]);
+      idct->pipe->set_viewport_state(idct->pipe, &buffer->viewport[1]);
+      idct->pipe->set_fragment_sampler_views(idct->pipe, 2, buffer->sampler_views.stage[1]);
+      idct->pipe->bind_fragment_sampler_states(idct->pipe, 2, idct->samplers.stage[1]);
+      idct->pipe->bind_vs_state(idct->pipe, idct->transpose_vs);
+      idct->pipe->bind_fs_state(idct->pipe, idct->transpose_fs);
+      util_draw_arrays(idct->pipe, PIPE_PRIM_QUADS, 0, num_verts);
+   }
+}
diff --git a/src/gallium/auxiliary/vl/vl_idct.h b/src/gallium/auxiliary/vl/vl_idct.h
new file mode 100644 (file)
index 0000000..fcba75a
--- /dev/null
@@ -0,0 +1,124 @@
+/**************************************************************************
+ *
+ * Copyright 2010 Christian König
+ * 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_idct_h
+#define vl_idct_h
+
+#include <pipe/p_state.h>
+#include "vl_vertex_buffers.h"
+
+struct vl_idct
+{
+   struct pipe_context *pipe;
+
+   unsigned buffer_width;
+   unsigned buffer_height;
+
+   unsigned max_blocks;
+
+   void *rs_state;
+   void *vertex_elems_state;
+
+   union
+   {
+      void *all[4];
+      void *stage[2][2];
+      struct {
+         void *matrix, *source;
+         void *transpose, *intermediate;
+      } individual;
+   } samplers;
+
+   void *matrix_vs, *transpose_vs;
+   void *matrix_fs, *transpose_fs;
+
+   struct pipe_resource *matrix;
+   struct pipe_vertex_buffer quad;
+
+   unsigned vertex_buffer_stride;
+};
+
+struct vl_idct_buffer
+{
+   struct pipe_viewport_state viewport[2];
+   struct pipe_framebuffer_state fb_state[2];
+
+   struct pipe_resource *destination;
+
+   union
+   {
+      struct pipe_sampler_view *all[4];
+      struct pipe_sampler_view *stage[2][2];
+      struct {
+         struct pipe_sampler_view *matrix, *source;
+         struct pipe_sampler_view *transpose, *intermediate;
+      } individual;
+   } sampler_views;
+
+   union
+   {
+      struct pipe_resource *all[4];
+      struct pipe_resource *stage[2][2];
+      struct {
+         struct pipe_resource *matrix, *source;
+         struct pipe_resource *transpose, *intermediate;
+      } individual;
+   } textures;
+
+   union
+   {
+      struct pipe_vertex_buffer all[2];
+      struct { struct pipe_vertex_buffer quad, pos; } individual;
+   } vertex_bufs;
+
+   struct vl_vertex_buffer blocks;
+
+   struct pipe_transfer *tex_transfer;
+   short *texels;
+};
+
+struct pipe_resource *vl_idct_upload_matrix(struct pipe_context *pipe);
+
+bool vl_idct_init(struct vl_idct *idct, struct pipe_context *pipe, 
+                  unsigned buffer_width, unsigned buffer_height, 
+                  struct pipe_resource *matrix);
+
+void vl_idct_cleanup(struct vl_idct *idct);
+
+bool vl_idct_init_buffer(struct vl_idct *idct, struct vl_idct_buffer *buffer, struct pipe_resource *dst);
+
+void vl_idct_cleanup_buffer(struct vl_idct *idct, struct vl_idct_buffer *buffer);
+
+void vl_idct_map_buffers(struct vl_idct *idct, struct vl_idct_buffer *buffer);
+
+void vl_idct_add_block(struct vl_idct_buffer *buffer, unsigned x, unsigned y, short *block);
+
+void vl_idct_unmap_buffers(struct vl_idct *idct, struct vl_idct_buffer *buffer);
+
+void vl_idct_flush(struct vl_idct *idct, struct vl_idct_buffer *buffer);
+
+#endif
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 (file)
index 0000000..484e781
--- /dev/null
@@ -0,0 +1,1093 @@
+/**************************************************************************
+ *
+ * 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 "util/u_draw.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 <util/u_draw.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
+
+struct vertex_stream
+{
+   struct vertex2s pos;
+   struct vertex2s mv[4];
+   struct {
+      int8_t y;
+      int8_t cr;
+      int8_t cb;
+      int8_t flag;
+   } eb[2][2];
+};
+
+enum VS_INPUT
+{
+   VS_I_RECT,
+   VS_I_VPOS,
+   VS_I_MV0,
+   VS_I_MV1,
+   VS_I_MV2,
+   VS_I_MV3,
+   VS_I_EB_0_0,
+   VS_I_EB_0_1,
+   VS_I_EB_1_0,
+   VS_I_EB_1_1,
+
+   NUM_VS_INPUTS
+};
+
+enum VS_OUTPUT
+{
+   VS_O_VPOS,
+   VS_O_LINE,
+   VS_O_TEX0,
+   VS_O_TEX1,
+   VS_O_TEX2,
+   VS_O_EB_0,
+   VS_O_EB_1,
+   VS_O_INFO,
+   VS_O_MV0,
+   VS_O_MV1,
+   VS_O_MV2,
+   VS_O_MV3
+};
+
+static const unsigned const_empty_block_mask_420[3][2][2] = {
+        { { 0x20, 0x10 },  { 0x08, 0x04 } },
+        { { 0x02, 0x02 },  { 0x02, 0x02 } },
+        { { 0x01, 0x01 },  { 0x01, 0x01 } }
+};
+
+static void *
+create_vert_shader(struct vl_mpeg12_mc_renderer *r)
+{
+   struct ureg_program *shader;
+   struct ureg_src block_scale, mv_scale;
+   struct ureg_src vrect, vpos, eb[2][2], vmv[4];
+   struct ureg_dst t_vpos, t_vtex, t_vmv;
+   struct ureg_dst o_vpos, o_line, o_vtex[3], o_eb[2], o_vmv[4], o_info;
+   unsigned i, label;
+
+   shader = ureg_create(TGSI_PROCESSOR_VERTEX);
+   if (!shader)
+      return NULL;
+
+   t_vpos = ureg_DECL_temporary(shader);
+   t_vtex = ureg_DECL_temporary(shader);
+   t_vmv = ureg_DECL_temporary(shader);
+
+   vrect = ureg_DECL_vs_input(shader, VS_I_RECT);
+   vpos = ureg_DECL_vs_input(shader, VS_I_VPOS);
+   eb[0][0] = ureg_DECL_vs_input(shader, VS_I_EB_0_0);
+   eb[1][0] = ureg_DECL_vs_input(shader, VS_I_EB_1_0);
+   eb[0][1] = ureg_DECL_vs_input(shader, VS_I_EB_0_1);
+   eb[1][1] = ureg_DECL_vs_input(shader, VS_I_EB_1_1);
+
+   o_vpos = ureg_DECL_output(shader, TGSI_SEMANTIC_POSITION, VS_O_VPOS);
+   o_line = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_LINE);
+   o_vtex[0] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_TEX0);
+   o_vtex[1] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_TEX1);
+   o_vtex[2] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_TEX2);
+   o_eb[0] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_EB_0);
+   o_eb[1] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_EB_1);
+   o_info = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_INFO);
+
+   for (i = 0; i < 4; ++i) {
+     vmv[i] = ureg_DECL_vs_input(shader, VS_I_MV0 + i);
+     o_vmv[i] = ureg_DECL_output(shader, TGSI_SEMANTIC_GENERIC, VS_O_MV0 + i);
+   }
+
+   /*
+    * block_scale = (MACROBLOCK_WIDTH, MACROBLOCK_HEIGHT) / (dst.width, dst.height)
+    * mv_scale = 0.5 / (dst.width, dst.height);
+    *
+    * t_vpos = (vpos + vrect) * block_scale
+    * o_vpos.xy = t_vpos
+    * o_vpos.zw = vpos
+    *
+    * o_eb[0..1] = vrect.x ? eb[0..1][1] : eb[0..1][0]
+    *
+    * o_frame_pred = frame_pred
+    * o_info.x = ref_frames
+    * o_info.y = ref_frames > 0
+    * o_info.z = bkwd_pred
+    *
+    * // Apply motion vectors
+    * o_vmv[0..count] = t_vpos + vmv[0..count] * mv_scale
+    *
+    * o_line.xy = vrect * 8
+    * o_line.z = interlaced
+    *
+    * if(eb[0][0].w) { //interlaced
+    *    t_vtex.x = vrect.x
+    *    t_vtex.y = vrect.y * 0.5
+    *    t_vtex += vpos
+    *
+    *    o_vtex[0].xy = t_vtex * block_scale
+    *
+    *    t_vtex.y += 0.5
+    *    o_vtex[1].xy = t_vtex * block_scale
+    * } else {
+    *    o_vtex[0..1].xy = t_vpos
+    * }
+    * o_vtex[2].xy = t_vpos
+    *
+    */
+   block_scale = ureg_imm2f(shader,
+      (float)MACROBLOCK_WIDTH / r->buffer_width,
+      (float)MACROBLOCK_HEIGHT / r->buffer_height);
+
+   mv_scale = ureg_imm2f(shader,
+      0.5f / r->buffer_width,
+      0.5f / r->buffer_height);
+
+   ureg_ADD(shader, ureg_writemask(t_vpos, TGSI_WRITEMASK_XY), vpos, vrect);
+   ureg_MUL(shader, ureg_writemask(t_vpos, TGSI_WRITEMASK_XY), ureg_src(t_vpos), block_scale);
+   ureg_MOV(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_XY), ureg_src(t_vpos));
+   ureg_MOV(shader, ureg_writemask(o_vpos, TGSI_WRITEMASK_ZW), vpos);
+
+   ureg_CMP(shader, ureg_writemask(o_eb[0], TGSI_WRITEMASK_XYZ),
+            ureg_negate(ureg_scalar(vrect, TGSI_SWIZZLE_X)),
+            eb[0][1], eb[0][0]);
+   ureg_CMP(shader, ureg_writemask(o_eb[1], TGSI_WRITEMASK_XYZ),
+            ureg_negate(ureg_scalar(vrect, TGSI_SWIZZLE_X)),
+            eb[1][1], eb[1][0]);
+
+   ureg_MOV(shader, ureg_writemask(o_info, TGSI_WRITEMASK_X),
+            ureg_scalar(eb[1][1], TGSI_SWIZZLE_W));
+   ureg_SGE(shader, ureg_writemask(o_info, TGSI_WRITEMASK_Y),
+      ureg_scalar(eb[1][1], TGSI_SWIZZLE_W), ureg_imm1f(shader, 0.0f));
+   ureg_MOV(shader, ureg_writemask(o_info, TGSI_WRITEMASK_Z),
+            ureg_scalar(eb[1][0], TGSI_SWIZZLE_W));
+
+   ureg_MAD(shader, ureg_writemask(o_vmv[0], TGSI_WRITEMASK_XY), mv_scale, vmv[0], ureg_src(t_vpos));
+   ureg_MAD(shader, ureg_writemask(o_vmv[2], TGSI_WRITEMASK_XY), mv_scale, vmv[2], ureg_src(t_vpos));
+
+   ureg_CMP(shader, ureg_writemask(t_vmv, TGSI_WRITEMASK_XY),
+            ureg_negate(ureg_scalar(eb[0][1], TGSI_SWIZZLE_W)),
+            vmv[0], vmv[1]);
+   ureg_MAD(shader, ureg_writemask(o_vmv[1], TGSI_WRITEMASK_XY), mv_scale, ureg_src(t_vmv), ureg_src(t_vpos));
+
+   ureg_CMP(shader, ureg_writemask(t_vmv, TGSI_WRITEMASK_XY),
+            ureg_negate(ureg_scalar(eb[0][1], TGSI_SWIZZLE_W)),
+            vmv[2], vmv[3]);
+   ureg_MAD(shader, ureg_writemask(o_vmv[3], TGSI_WRITEMASK_XY), mv_scale, ureg_src(t_vmv), ureg_src(t_vpos));
+
+   ureg_MOV(shader, ureg_writemask(o_vtex[0], TGSI_WRITEMASK_XY), ureg_src(t_vpos));
+   ureg_MOV(shader, ureg_writemask(o_vtex[1], TGSI_WRITEMASK_XY), ureg_src(t_vpos));
+   ureg_MOV(shader, ureg_writemask(o_vtex[2], TGSI_WRITEMASK_XY), ureg_src(t_vpos));
+
+   ureg_MOV(shader, ureg_writemask(o_line, TGSI_WRITEMASK_X), ureg_scalar(vrect, TGSI_SWIZZLE_Y));
+   ureg_MUL(shader, ureg_writemask(o_line, TGSI_WRITEMASK_Y),
+      vrect, ureg_imm1f(shader, MACROBLOCK_HEIGHT / 2));
+
+   ureg_IF(shader, ureg_scalar(eb[0][0], TGSI_SWIZZLE_W), &label);
+
+      ureg_MOV(shader, ureg_writemask(t_vtex, TGSI_WRITEMASK_X), vrect);
+      ureg_MUL(shader, ureg_writemask(t_vtex, TGSI_WRITEMASK_Y), vrect, ureg_imm1f(shader, 0.5f));
+      ureg_ADD(shader, ureg_writemask(t_vtex, TGSI_WRITEMASK_XY), vpos, ureg_src(t_vtex));
+      ureg_MUL(shader, ureg_writemask(o_vtex[0], TGSI_WRITEMASK_XY), ureg_src(t_vtex), block_scale);
+      ureg_ADD(shader, ureg_writemask(t_vtex, TGSI_WRITEMASK_Y), ureg_src(t_vtex), ureg_imm1f(shader, 0.5f));
+      ureg_MUL(shader, ureg_writemask(o_vtex[1], TGSI_WRITEMASK_XY), ureg_src(t_vtex), block_scale);
+
+      ureg_MUL(shader, ureg_writemask(o_line, TGSI_WRITEMASK_X),
+         ureg_scalar(vrect, TGSI_SWIZZLE_Y),
+         ureg_imm1f(shader, MACROBLOCK_HEIGHT / 2));
+
+   ureg_fixup_label(shader, label, ureg_get_instruction_number(shader));
+   ureg_ENDIF(shader);
+
+   ureg_release_temporary(shader, t_vtex);
+   ureg_release_temporary(shader, t_vpos);
+   ureg_release_temporary(shader, t_vmv);
+
+   ureg_END(shader);
+
+   return ureg_create_shader_and_destroy(shader, r->pipe);
+}
+
+static struct ureg_dst
+calc_field(struct ureg_program *shader)
+{
+   struct ureg_dst tmp;
+   struct ureg_src line;
+
+   tmp = ureg_DECL_temporary(shader);
+
+   line = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_LINE, TGSI_INTERPOLATE_LINEAR);
+
+   /*
+    * line.x going from 0 to 1 if not interlaced
+    * line.x going from 0 to 8 in steps of 0.5 if interlaced
+    * line.y going from 0 to 8 in steps of 0.5
+    *
+    * tmp.xy = fraction(line)
+    * tmp.xy = tmp.xy >= 0.5 ? 1 : 0
+    */
+   ureg_FRC(shader, ureg_writemask(tmp, TGSI_WRITEMASK_XY), line);
+   ureg_SGE(shader, ureg_writemask(tmp, TGSI_WRITEMASK_XY), ureg_src(tmp), ureg_imm1f(shader, 0.5f));
+
+   return tmp;
+}
+
+static struct ureg_dst
+fetch_ycbcr(struct vl_mpeg12_mc_renderer *r, struct ureg_program *shader, struct ureg_dst field)
+{
+   struct ureg_src tc[3], sampler[3], eb[2];
+   struct ureg_dst texel, t_tc, t_eb_info;
+   unsigned i, label;
+
+   texel = ureg_DECL_temporary(shader);
+   t_tc = ureg_DECL_temporary(shader);
+   t_eb_info = ureg_DECL_temporary(shader);
+
+   tc[0] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_TEX0, TGSI_INTERPOLATE_LINEAR);
+   tc[1] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_TEX1, TGSI_INTERPOLATE_LINEAR);
+   tc[2] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_TEX2, TGSI_INTERPOLATE_LINEAR);
+
+   eb[0] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_EB_0, TGSI_INTERPOLATE_CONSTANT);
+   eb[1] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_EB_1, TGSI_INTERPOLATE_CONSTANT);
+
+   for (i = 0; i < 3; ++i)  {
+      sampler[i] = ureg_DECL_sampler(shader, i);
+   }
+
+   /*
+    * texel.y  = tex(field.y ? tc[1] : tc[0], sampler[0])
+    * texel.cb = tex(tc[2], sampler[1])
+    * texel.cr = tex(tc[2], sampler[2])
+    */
+
+   ureg_CMP(shader, ureg_writemask(t_tc, TGSI_WRITEMASK_XY),
+            ureg_negate(ureg_scalar(ureg_src(field), TGSI_SWIZZLE_X)),
+            tc[1], tc[0]);
+
+   ureg_CMP(shader, ureg_writemask(t_eb_info, TGSI_WRITEMASK_XYZ),
+            ureg_negate(ureg_scalar(ureg_src(field), TGSI_SWIZZLE_X)),
+            eb[1], eb[0]);
+
+   /* r600g is ignoring TGSI_INTERPOLATE_CONSTANT, just workaround this */
+   ureg_SLT(shader, ureg_writemask(t_eb_info, TGSI_WRITEMASK_XYZ), ureg_src(t_eb_info), ureg_imm1f(shader, 0.5f));
+
+   ureg_MOV(shader, ureg_writemask(texel, TGSI_WRITEMASK_XYZ), ureg_imm1f(shader, 0.0f));
+   for (i = 0; i < 3; ++i) {
+      ureg_IF(shader, ureg_scalar(ureg_src(t_eb_info), TGSI_SWIZZLE_X + i), &label);
+
+         /* Nouveau can't writemask tex dst regs (yet?), so this won't work anymore on nvidia hardware */
+         if(i==0 || r->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_444) {
+            ureg_TEX(shader, ureg_writemask(texel, TGSI_WRITEMASK_X << i), TGSI_TEXTURE_3D, ureg_src(t_tc), sampler[i]);
+         } else {
+            ureg_TEX(shader, ureg_writemask(texel, TGSI_WRITEMASK_X << i), TGSI_TEXTURE_3D, tc[2], sampler[i]);
+         }
+
+      ureg_fixup_label(shader, label, ureg_get_instruction_number(shader));
+      ureg_ENDIF(shader);
+   }
+
+   ureg_release_temporary(shader, t_tc);
+   ureg_release_temporary(shader, t_eb_info);
+
+   return texel;
+}
+
+static struct ureg_dst
+fetch_ref(struct ureg_program *shader, struct ureg_dst field)
+{
+   struct ureg_src info;
+   struct ureg_src tc[4], sampler[2];
+   struct ureg_dst ref[2], result;
+   unsigned i, intra_label, bi_label, label;
+
+   info = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_INFO, TGSI_INTERPOLATE_CONSTANT);
+
+   for (i = 0; i < 4; ++i)
+      tc[i] = ureg_DECL_fs_input(shader, TGSI_SEMANTIC_GENERIC, VS_O_MV0 + i, TGSI_INTERPOLATE_LINEAR);
+
+   for (i = 0; i < 2; ++i) {
+      sampler[i] = ureg_DECL_sampler(shader, i + 3);
+      ref[i] = ureg_DECL_temporary(shader);
+   }
+
+   result = ureg_DECL_temporary(shader);
+
+   ureg_MOV(shader, ureg_writemask(result, TGSI_WRITEMASK_XYZ), ureg_imm1f(shader, 0.5f));
+
+   ureg_IF(shader, ureg_scalar(info, TGSI_SWIZZLE_Y), &intra_label);
+      ureg_CMP(shader, ureg_writemask(ref[0], TGSI_WRITEMASK_XY),
+               ureg_negate(ureg_scalar(ureg_src(field), TGSI_SWIZZLE_Y)),
+               tc[1], tc[0]);
+
+      ureg_IF(shader, ureg_scalar(info, TGSI_SWIZZLE_X), &bi_label);
+
+         /*
+          * result = tex(field.z ? tc[1] : tc[0], sampler[bkwd_pred ? 1 : 0])
+          */
+         ureg_IF(shader, ureg_scalar(info, TGSI_SWIZZLE_Z), &label);
+            ureg_TEX(shader, result, TGSI_TEXTURE_2D, ureg_src(ref[0]), sampler[1]);
+         ureg_fixup_label(shader, label, ureg_get_instruction_number(shader));
+         ureg_ELSE(shader, &label);
+            ureg_TEX(shader, result, TGSI_TEXTURE_2D, ureg_src(ref[0]), sampler[0]);
+         ureg_fixup_label(shader, label, ureg_get_instruction_number(shader));
+         ureg_ENDIF(shader);
+
+      ureg_fixup_label(shader, bi_label, ureg_get_instruction_number(shader));
+      ureg_ELSE(shader, &bi_label);
+
+         /*
+          * if (field.z)
+          *    ref[0..1] = tex(tc[0..1], sampler[0..1])
+          * else
+          *    ref[0..1] = tex(tc[2..3], sampler[0..1])
+          */
+         ureg_CMP(shader, ureg_writemask(ref[1], TGSI_WRITEMASK_XY),
+            ureg_negate(ureg_scalar(ureg_src(field), TGSI_SWIZZLE_Y)),
+            tc[3], tc[2]);
+         ureg_TEX(shader, ref[0], TGSI_TEXTURE_2D, ureg_src(ref[0]), sampler[0]);
+         ureg_TEX(shader, ref[1], TGSI_TEXTURE_2D, ureg_src(ref[1]), sampler[1]);
+
+         ureg_LRP(shader, ureg_writemask(result, TGSI_WRITEMASK_XYZ), ureg_imm1f(shader, 0.5f),
+            ureg_src(ref[0]), ureg_src(ref[1]));
+
+      ureg_fixup_label(shader, bi_label, ureg_get_instruction_number(shader));
+      ureg_ENDIF(shader);
+   ureg_fixup_label(shader, intra_label, ureg_get_instruction_number(shader));
+   ureg_ENDIF(shader);
+
+   for (i = 0; i < 2; ++i)
+      ureg_release_temporary(shader, ref[i]);
+
+   return result;
+}
+
+static void *
+create_frag_shader(struct vl_mpeg12_mc_renderer *r)
+{
+   struct ureg_program *shader;
+   struct ureg_dst result;
+   struct ureg_dst field, texel;
+   struct ureg_dst fragment;
+
+   shader = ureg_create(TGSI_PROCESSOR_FRAGMENT);
+   if (!shader)
+      return NULL;
+
+   fragment = ureg_DECL_output(shader, TGSI_SEMANTIC_COLOR, 0);
+
+   field = calc_field(shader);
+   texel = fetch_ycbcr(r, shader, field);
+
+   result = fetch_ref(shader, field);
+
+   ureg_ADD(shader, ureg_writemask(fragment, TGSI_WRITEMASK_XYZ), ureg_src(texel), ureg_src(result));
+
+   ureg_release_temporary(shader, field);
+   ureg_release_temporary(shader, texel);
+   ureg_release_temporary(shader, result);
+   ureg_END(shader);
+
+   return ureg_create_shader_and_destroy(shader, r->pipe);
+}
+
+static bool
+init_pipe_state(struct vl_mpeg12_mc_renderer *r)
+{
+   struct pipe_sampler_state sampler;
+   struct pipe_rasterizer_state rs_state;
+   unsigned filters[5];
+   unsigned i;
+
+   assert(r);
+
+   r->viewport.scale[0] = r->buffer_width;
+   r->viewport.scale[1] = r->buffer_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->buffer_width;
+   r->fb_state.height = r->buffer_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 || true) { //TODO
+      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) {
+      memset(&sampler, 0, sizeof(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_BORDER;
+      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[0] = 0.0f;
+      sampler.border_color[1] = 0.0f;
+      sampler.border_color[2] = 0.0f;
+      sampler.border_color[3] = 0.0f;
+      /*sampler.max_anisotropy = ; */
+      r->samplers.all[i] = r->pipe->create_sampler_state(r->pipe, &sampler);
+   }
+
+   memset(&rs_state, 0, sizeof(rs_state));
+   /*rs_state.sprite_coord_enable */
+   rs_state.sprite_coord_mode = PIPE_SPRITE_COORD_UPPER_LEFT;
+   rs_state.point_quad_rasterization = true;
+   rs_state.point_size = BLOCK_WIDTH;
+   rs_state.gl_rasterization_rules = true;
+   r->rs_state = r->pipe->create_rasterizer_state(r->pipe, &rs_state);
+
+   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]);
+
+   r->pipe->delete_rasterizer_state(r->pipe, r->rs_state);
+}
+
+static bool
+init_buffers(struct vl_mpeg12_mc_renderer *r)
+{
+   struct pipe_resource *idct_matrix;
+   struct pipe_vertex_element vertex_elems[NUM_VS_INPUTS];
+
+   const unsigned mbw =
+      align(r->buffer_width, MACROBLOCK_WIDTH) / MACROBLOCK_WIDTH;
+   const unsigned mbh =
+      align(r->buffer_height, MACROBLOCK_HEIGHT) / MACROBLOCK_HEIGHT;
+
+   unsigned i, chroma_width, chroma_height;
+
+   assert(r);
+
+   r->macroblocks_per_batch =
+      mbw * (r->bufmode == VL_MPEG12_MC_RENDERER_BUFFER_PICTURE ? mbh : 1);
+
+   if (!(idct_matrix = vl_idct_upload_matrix(r->pipe)))
+      return false;
+
+   if (!vl_idct_init(&r->idct_luma, r->pipe, r->buffer_width, r->buffer_height, idct_matrix))
+      return false;
+
+   if (r->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420) {
+      chroma_width = r->buffer_width / 2;
+      chroma_height = r->buffer_height / 2;
+   } else if (r->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_422) {
+      chroma_width = r->buffer_width;
+      chroma_height = r->buffer_height / 2;
+   } else {
+      chroma_width = r->buffer_width;
+      chroma_height = r->buffer_height;
+   }
+
+   if(!vl_idct_init(&r->idct_chroma, r->pipe, chroma_width, chroma_height, idct_matrix))
+      return false;
+
+   memset(&vertex_elems, 0, sizeof(vertex_elems));
+
+   vertex_elems[VS_I_RECT] = vl_vb_get_quad_vertex_element();
+   r->quad = vl_vb_upload_quads(r->pipe, r->macroblocks_per_batch);
+
+   /* Position element */
+   vertex_elems[VS_I_VPOS].src_format = PIPE_FORMAT_R16G16_SSCALED;
+
+   for (i = 0; i < 4; ++i)
+      /* motion vector 0..4 element */
+      vertex_elems[VS_I_MV0 + i].src_format = PIPE_FORMAT_R16G16_SSCALED;
+
+   /* y, cr, cb empty block element top left block */
+   vertex_elems[VS_I_EB_0_0].src_format = PIPE_FORMAT_R8G8B8A8_SSCALED;
+
+   /* y, cr, cb empty block element top right block */
+   vertex_elems[VS_I_EB_0_1].src_format = PIPE_FORMAT_R8G8B8A8_SSCALED;
+
+   /* y, cr, cb empty block element bottom left block */
+   vertex_elems[VS_I_EB_1_0].src_format = PIPE_FORMAT_R8G8B8A8_SSCALED;
+
+   /* y, cr, cb empty block element bottom right block */
+   vertex_elems[VS_I_EB_1_1].src_format = PIPE_FORMAT_R8G8B8A8_SSCALED;
+
+   r->vertex_stream_stride = vl_vb_element_helper(&vertex_elems[VS_I_VPOS], 9, 1);
+
+   r->vertex_elems_state = r->pipe->create_vertex_elements_state(
+      r->pipe, NUM_VS_INPUTS, vertex_elems);
+
+   if (r->vertex_elems_state == NULL)
+      return false;
+
+   r->vs = create_vert_shader(r);
+   r->fs = create_frag_shader(r);
+
+   if (r->vs == NULL || r->fs == NULL)
+      return false;
+
+   return true;
+}
+
+static void
+cleanup_buffers(struct vl_mpeg12_mc_renderer *r)
+{
+   assert(r);
+
+   r->pipe->delete_vs_state(r->pipe, r->vs);
+   r->pipe->delete_fs_state(r->pipe, r->fs);
+
+   vl_idct_cleanup(&r->idct_luma);
+   vl_idct_cleanup(&r->idct_chroma);
+
+   r->pipe->delete_vertex_elements_state(r->pipe, r->vertex_elems_state);
+}
+
+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
+get_motion_vectors(struct pipe_mpeg12_macroblock *mb, struct vertex2s mv[4])
+{
+   switch (mb->mb_type) {
+      case PIPE_MPEG12_MACROBLOCK_TYPE_BI:
+      {
+         if (mb->mo_type == PIPE_MPEG12_MOTION_TYPE_FRAME) {
+            mv[2].x = mb->pmv[0][1][0];
+            mv[2].y = mb->pmv[0][1][1];
+
+         } else {
+            mv[2].x = mb->pmv[0][1][0];
+            mv[2].y = mb->pmv[0][1][1] - (mb->pmv[0][1][1] % 4);
+
+            mv[3].x = mb->pmv[1][1][0];
+            mv[3].y = mb->pmv[1][1][1] - (mb->pmv[1][1][1] % 4);
+
+            if(mb->mvfs[0][1]) mv[2].y += 2;
+            if(!mb->mvfs[1][1]) mv[3].y -= 2;
+         }
+
+         /* fall-through */
+      }
+      case PIPE_MPEG12_MACROBLOCK_TYPE_FWD:
+      case PIPE_MPEG12_MACROBLOCK_TYPE_BKWD:
+      {
+         if (mb->mb_type == PIPE_MPEG12_MACROBLOCK_TYPE_BKWD) {
+
+            if (mb->mo_type == PIPE_MPEG12_MOTION_TYPE_FRAME) {
+               mv[0].x = mb->pmv[0][1][0];
+               mv[0].y = mb->pmv[0][1][1];
+
+            } else {
+               mv[0].x = mb->pmv[0][1][0];
+               mv[0].y = mb->pmv[0][1][1] - (mb->pmv[0][1][1] % 4);
+
+               mv[1].x = mb->pmv[1][1][0];
+               mv[1].y = mb->pmv[1][1][1] - (mb->pmv[1][1][1] % 4);
+
+               if(mb->mvfs[0][1]) mv[0].y += 2;
+               if(!mb->mvfs[1][1]) mv[1].y -= 2;
+            }
+
+         } else {
+
+            if (mb->mo_type == PIPE_MPEG12_MOTION_TYPE_FRAME) {
+               mv[0].x = mb->pmv[0][0][0];
+               mv[0].y = mb->pmv[0][0][1];
+
+            } else {
+               mv[0].x = mb->pmv[0][0][0];
+               mv[0].y = mb->pmv[0][0][1] - (mb->pmv[0][0][1] % 4);
+
+               mv[1].x = mb->pmv[1][0][0];
+               mv[1].y = mb->pmv[1][0][1] - (mb->pmv[1][0][1] % 4);
+
+               if(mb->mvfs[0][0]) mv[0].y += 2;
+               if(!mb->mvfs[1][0]) mv[1].y -= 2;
+            }
+         }
+      }
+      default:
+         break;
+   }
+}
+
+static void
+grab_vectors(struct vl_mpeg12_mc_renderer *r,
+             struct vl_mpeg12_mc_buffer *buffer,
+             struct pipe_mpeg12_macroblock *mb)
+{
+   struct vertex_stream stream;
+
+   unsigned i, j;
+
+   assert(r);
+   assert(mb);
+
+   stream.pos.x = mb->mbx;
+   stream.pos.y = mb->mby;
+   for ( i = 0; i < 2; ++i) {
+      for ( j = 0; j < 2; ++j) {
+         stream.eb[i][j].y = !(mb->cbp & (*r->empty_block_mask)[0][i][j]);
+         stream.eb[i][j].cr = !(mb->cbp & (*r->empty_block_mask)[1][i][j]);
+         stream.eb[i][j].cb = !(mb->cbp & (*r->empty_block_mask)[2][i][j]);
+      }
+   }
+   stream.eb[0][0].flag = mb->dct_type == PIPE_MPEG12_DCT_TYPE_FIELD;
+   stream.eb[0][1].flag = mb->mo_type == PIPE_MPEG12_MOTION_TYPE_FRAME;
+   stream.eb[1][0].flag = mb->mb_type == PIPE_MPEG12_MACROBLOCK_TYPE_BKWD;
+   switch (mb->mb_type) {
+      case PIPE_MPEG12_MACROBLOCK_TYPE_INTRA:
+         stream.eb[1][1].flag = -1;
+         break;
+
+      case PIPE_MPEG12_MACROBLOCK_TYPE_FWD:
+      case PIPE_MPEG12_MACROBLOCK_TYPE_BKWD:
+         stream.eb[1][1].flag = 1;
+         break;
+
+      case PIPE_MPEG12_MACROBLOCK_TYPE_BI:
+         stream.eb[1][1].flag = 0;
+         break;
+
+      default:
+         assert(0);
+   }
+
+   get_motion_vectors(mb, stream.mv);
+   vl_vb_add_block(&buffer->vertex_stream, &stream);
+}
+
+static void
+grab_blocks(struct vl_mpeg12_mc_renderer *r,
+            struct vl_mpeg12_mc_buffer *buffer,
+            unsigned mbx, unsigned mby,
+            unsigned cbp, short *blocks)
+{
+   unsigned tb = 0;
+   unsigned x, y;
+
+   assert(r);
+   assert(blocks);
+
+   for (y = 0; y < 2; ++y) {
+      for (x = 0; x < 2; ++x, ++tb) {
+         if (cbp & (*r->empty_block_mask)[0][y][x]) {
+            vl_idct_add_block(&buffer->idct_y, mbx * 2 + x, mby * 2 + y, blocks);
+            blocks += BLOCK_WIDTH * BLOCK_HEIGHT;
+         }
+      }
+   }
+
+   /* TODO: Implement 422, 444 */
+   assert(r->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420);
+
+   for (tb = 1; tb < 3; ++tb) {
+      if (cbp & (*r->empty_block_mask)[tb][0][0]) {
+         if(tb == 1)
+            vl_idct_add_block(&buffer->idct_cb, mbx, mby, blocks);
+         else
+            vl_idct_add_block(&buffer->idct_cr, mbx, mby, blocks);
+         blocks += BLOCK_WIDTH * BLOCK_HEIGHT;
+      }
+   }
+}
+
+static void
+grab_macroblock(struct vl_mpeg12_mc_renderer *r,
+                struct vl_mpeg12_mc_buffer *buffer,
+                struct pipe_mpeg12_macroblock *mb)
+{
+   assert(r);
+   assert(mb);
+   assert(mb->blocks);
+   assert(buffer->num_macroblocks < r->macroblocks_per_batch);
+
+   grab_vectors(r, buffer, mb);
+   grab_blocks(r, buffer, mb->mbx, mb->mby, mb->cbp, mb->blocks);
+
+   ++buffer->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 buffer_width,
+                           unsigned buffer_height,
+                           enum pipe_video_chroma_format chroma_format,
+                           enum VL_MPEG12_MC_RENDERER_BUFFER_MODE bufmode)
+{
+   assert(renderer);
+   assert(pipe);
+
+   /* TODO: Implement other policies */
+   assert(bufmode == VL_MPEG12_MC_RENDERER_BUFFER_PICTURE);
+
+   memset(renderer, 0, sizeof(struct vl_mpeg12_mc_renderer));
+
+   renderer->pipe = pipe;
+   renderer->buffer_width = buffer_width;
+   renderer->buffer_height = buffer_height;
+   renderer->chroma_format = chroma_format;
+   renderer->bufmode = bufmode;
+
+   /* TODO: Implement 422, 444 */
+   assert(chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420);
+   renderer->empty_block_mask = &const_empty_block_mask_420;
+
+   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))
+      goto error_pipe_state;
+
+   if (!init_buffers(renderer))
+      goto error_buffers;
+
+   return true;
+
+error_buffers:
+   cleanup_pipe_state(renderer);
+
+error_pipe_state:
+   util_delete_keymap(renderer->texview_map, renderer->pipe);
+   return false;
+}
+
+void
+vl_mpeg12_mc_renderer_cleanup(struct vl_mpeg12_mc_renderer *renderer)
+{
+   assert(renderer);
+
+   util_delete_keymap(renderer->texview_map, renderer->pipe);
+   cleanup_pipe_state(renderer);
+   cleanup_buffers(renderer);
+}
+
+bool
+vl_mpeg12_mc_init_buffer(struct vl_mpeg12_mc_renderer *renderer, struct vl_mpeg12_mc_buffer *buffer)
+{
+   struct pipe_resource template;
+   struct pipe_sampler_view sampler_view;
+
+   unsigned i;
+
+   assert(renderer && buffer);
+
+   buffer->surface = NULL;
+   buffer->past = NULL;
+   buffer->future = NULL;
+   buffer->num_macroblocks = 0;
+
+   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 = renderer->buffer_width;
+   template.height0 = renderer->buffer_height;
+   template.depth0 = 1;
+   template.array_size = 1;
+   template.usage = PIPE_USAGE_STATIC;
+   template.bind = PIPE_BIND_SAMPLER_VIEW;
+   template.flags = 0;
+
+   buffer->textures.individual.y = renderer->pipe->screen->resource_create(renderer->pipe->screen, &template);
+
+   if (!vl_idct_init_buffer(&renderer->idct_luma, &buffer->idct_y, buffer->textures.individual.y))
+      return false;
+
+   if (renderer->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_420) {
+      template.width0 = renderer->buffer_width / 2;
+      template.height0 = renderer->buffer_height / 2;
+   }
+   else if (renderer->chroma_format == PIPE_VIDEO_CHROMA_FORMAT_422)
+      template.height0 = renderer->buffer_height / 2;
+
+   buffer->textures.individual.cb =
+      renderer->pipe->screen->resource_create(renderer->pipe->screen, &template);
+   buffer->textures.individual.cr =
+      renderer->pipe->screen->resource_create(renderer->pipe->screen, &template);
+
+   if (!vl_idct_init_buffer(&renderer->idct_chroma, &buffer->idct_cb, buffer->textures.individual.cb))
+      return false;
+
+   if (!vl_idct_init_buffer(&renderer->idct_chroma, &buffer->idct_cr, buffer->textures.individual.cr))
+      return false;
+
+   for (i = 0; i < 3; ++i) {
+      u_sampler_view_default_template(&sampler_view,
+                                      buffer->textures.all[i],
+                                      buffer->textures.all[i]->format);
+      sampler_view.swizzle_r = i == 0 ? PIPE_SWIZZLE_RED : PIPE_SWIZZLE_ZERO;
+      sampler_view.swizzle_g = i == 1 ? PIPE_SWIZZLE_RED : PIPE_SWIZZLE_ZERO;
+      sampler_view.swizzle_b = i == 2 ? PIPE_SWIZZLE_RED : PIPE_SWIZZLE_ZERO;
+      sampler_view.swizzle_a = PIPE_SWIZZLE_ONE;
+      buffer->sampler_views.all[i] = renderer->pipe->create_sampler_view(
+         renderer->pipe, buffer->textures.all[i], &sampler_view);
+   }
+
+   buffer->vertex_bufs.individual.quad.stride = renderer->quad.stride;
+   buffer->vertex_bufs.individual.quad.buffer_offset = renderer->quad.buffer_offset;
+   pipe_resource_reference(&buffer->vertex_bufs.individual.quad.buffer, renderer->quad.buffer);
+
+   buffer->vertex_bufs.individual.stream = vl_vb_init(
+      &buffer->vertex_stream, renderer->pipe, renderer->macroblocks_per_batch,
+      renderer->vertex_stream_stride);
+
+   return true;
+}
+
+void
+vl_mpeg12_mc_cleanup_buffer(struct vl_mpeg12_mc_renderer *renderer, struct vl_mpeg12_mc_buffer *buffer)
+{
+   unsigned i;
+
+   assert(renderer && buffer);
+
+   for (i = 0; i < 3; ++i) {
+      pipe_sampler_view_reference(&buffer->sampler_views.all[i], NULL);
+      pipe_resource_reference(&buffer->vertex_bufs.all[i].buffer, NULL);
+      pipe_resource_reference(&buffer->textures.all[i], NULL);
+   }
+
+   pipe_resource_reference(&buffer->vertex_bufs.individual.quad.buffer, NULL);
+   vl_vb_cleanup(&buffer->vertex_stream);
+
+   vl_idct_cleanup_buffer(&renderer->idct_luma, &buffer->idct_y);
+   vl_idct_cleanup_buffer(&renderer->idct_chroma, &buffer->idct_cb);
+   vl_idct_cleanup_buffer(&renderer->idct_chroma, &buffer->idct_cr);
+
+   pipe_surface_reference(&buffer->surface, NULL);
+   pipe_surface_reference(&buffer->past, NULL);
+   pipe_surface_reference(&buffer->future, NULL);
+}
+
+void
+vl_mpeg12_mc_map_buffer(struct vl_mpeg12_mc_renderer *renderer, struct vl_mpeg12_mc_buffer *buffer)
+{
+   assert(renderer && buffer);
+
+   vl_idct_map_buffers(&renderer->idct_luma, &buffer->idct_y);
+   vl_idct_map_buffers(&renderer->idct_chroma, &buffer->idct_cr);
+   vl_idct_map_buffers(&renderer->idct_chroma, &buffer->idct_cb);
+
+   vl_vb_map(&buffer->vertex_stream, renderer->pipe);
+}
+
+void
+vl_mpeg12_mc_renderer_render_macroblocks(struct vl_mpeg12_mc_renderer *renderer,
+                                         struct vl_mpeg12_mc_buffer *buffer,
+                                         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)
+{
+   assert(renderer && buffer);
+   assert(surface);
+   assert(num_macroblocks);
+   assert(mpeg12_macroblocks);
+
+   if (surface != buffer->surface) {
+      pipe_surface_reference(&buffer->surface, surface);
+      pipe_surface_reference(&buffer->past, past);
+      pipe_surface_reference(&buffer->future, future);
+      buffer->fence = fence;
+   } else {
+      /* If the surface we're rendering hasn't changed the ref frames shouldn't change. */
+      assert(buffer->past == past);
+      assert(buffer->future == future);
+   }
+
+   while (num_macroblocks) {
+      unsigned left_in_batch = renderer->macroblocks_per_batch - buffer->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, buffer, &mpeg12_macroblocks[i]);
+      }
+
+      num_macroblocks -= num_to_submit;
+
+      if (buffer->num_macroblocks == renderer->macroblocks_per_batch) {
+         vl_mpeg12_mc_unmap_buffer(renderer, buffer);
+         vl_mpeg12_mc_renderer_flush(renderer, buffer);
+         pipe_surface_reference(&buffer->surface, surface);
+         pipe_surface_reference(&buffer->past, past);
+         pipe_surface_reference(&buffer->future, future);
+         vl_mpeg12_mc_map_buffer(renderer, buffer);
+      }
+   }
+}
+
+void
+vl_mpeg12_mc_unmap_buffer(struct vl_mpeg12_mc_renderer *renderer, struct vl_mpeg12_mc_buffer *buffer)
+{
+   assert(renderer && buffer);
+
+   vl_idct_unmap_buffers(&renderer->idct_luma, &buffer->idct_y);
+   vl_idct_unmap_buffers(&renderer->idct_chroma, &buffer->idct_cr);
+   vl_idct_unmap_buffers(&renderer->idct_chroma, &buffer->idct_cb);
+
+   vl_vb_unmap(&buffer->vertex_stream, renderer->pipe);
+}
+
+void
+vl_mpeg12_mc_renderer_flush(struct vl_mpeg12_mc_renderer *renderer, struct vl_mpeg12_mc_buffer *buffer)
+{
+   assert(renderer && buffer);
+   assert(buffer->num_macroblocks <= renderer->macroblocks_per_batch);
+
+   if (buffer->num_macroblocks == 0)
+      return;
+
+   vl_idct_flush(&renderer->idct_luma, &buffer->idct_y);
+   vl_idct_flush(&renderer->idct_chroma, &buffer->idct_cr);
+   vl_idct_flush(&renderer->idct_chroma, &buffer->idct_cb);
+
+   vl_vb_restart(&buffer->vertex_stream);
+
+   renderer->fb_state.cbufs[0] = buffer->surface;
+   renderer->pipe->bind_rasterizer_state(renderer->pipe, renderer->rs_state);
+   renderer->pipe->set_framebuffer_state(renderer->pipe, &renderer->fb_state);
+   renderer->pipe->set_viewport_state(renderer->pipe, &renderer->viewport);
+   renderer->pipe->set_vertex_buffers(renderer->pipe, 2, buffer->vertex_bufs.all);
+   renderer->pipe->bind_vertex_elements_state(renderer->pipe, renderer->vertex_elems_state);
+
+   if (buffer->past) {
+      buffer->textures.individual.ref[0] = buffer->past->texture;
+      buffer->sampler_views.individual.ref[0] = find_or_create_sampler_view(renderer, buffer->past);
+   } else {
+      buffer->textures.individual.ref[0] = buffer->surface->texture;
+      buffer->sampler_views.individual.ref[0] = find_or_create_sampler_view(renderer, buffer->surface);
+   }
+
+   if (buffer->future) {
+      buffer->textures.individual.ref[1] = buffer->future->texture;
+      buffer->sampler_views.individual.ref[1] = find_or_create_sampler_view(renderer, buffer->future);
+   } else {
+      buffer->textures.individual.ref[1] = buffer->surface->texture;
+      buffer->sampler_views.individual.ref[1] = find_or_create_sampler_view(renderer, buffer->surface);
+   }
+
+   renderer->pipe->set_fragment_sampler_views(renderer->pipe, 5, buffer->sampler_views.all);
+   renderer->pipe->bind_fragment_sampler_states(renderer->pipe, 5, renderer->samplers.all);
+
+   renderer->pipe->bind_vs_state(renderer->pipe, renderer->vs);
+   renderer->pipe->bind_fs_state(renderer->pipe, renderer->fs);
+   util_draw_arrays(renderer->pipe, PIPE_PRIM_QUADS, 0, buffer->num_macroblocks * 4);
+
+   renderer->pipe->flush(renderer->pipe, PIPE_FLUSH_RENDER_CACHE, buffer->fence);
+
+   /* Next time we get this surface it may have new ref frames */
+   pipe_surface_reference(&buffer->surface, NULL);
+   pipe_surface_reference(&buffer->past, NULL);
+   pipe_surface_reference(&buffer->future, NULL);
+
+   buffer->num_macroblocks = 0;
+}
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 (file)
index 0000000..76d6e25
--- /dev/null
@@ -0,0 +1,141 @@
+/**************************************************************************
+ *
+ * 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"
+#include "vl_idct.h"
+#include "vl_vertex_buffers.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 */
+};
+
+struct vl_mpeg12_mc_renderer
+{
+   struct pipe_context *pipe;
+   unsigned buffer_width;
+   unsigned buffer_height;
+   enum pipe_video_chroma_format chroma_format;
+   const unsigned (*empty_block_mask)[3][2][2];
+   enum VL_MPEG12_MC_RENDERER_BUFFER_MODE bufmode;
+   unsigned macroblocks_per_batch;
+
+   unsigned vertex_stream_stride;
+
+   struct pipe_viewport_state viewport;
+   struct pipe_framebuffer_state fb_state;
+
+   struct vl_idct idct_luma, idct_chroma;
+
+   void *vertex_elems_state;
+   void *rs_state;
+
+   void *vs, *fs;
+
+   struct pipe_vertex_buffer quad;
+
+   union
+   {
+      void *all[5];
+      struct { void *y, *cb, *cr, *ref[2]; } individual;
+   } samplers;
+
+   struct keymap *texview_map;
+};
+
+struct vl_mpeg12_mc_buffer
+{
+   struct vl_idct_buffer idct_y, idct_cb, idct_cr;
+
+   struct vl_vertex_buffer vertex_stream;
+
+   union
+   {
+      struct pipe_sampler_view *all[5];
+      struct { struct pipe_sampler_view *y, *cb, *cr, *ref[2]; } individual;
+   } sampler_views;
+
+   union
+   {
+      struct pipe_resource *all[5];
+      struct { struct pipe_resource *y, *cb, *cr, *ref[2]; } individual;
+   } textures;
+
+   union
+   {
+      struct pipe_vertex_buffer all[2];
+      struct {
+         struct pipe_vertex_buffer quad, stream;
+      } individual;
+   } vertex_bufs;
+
+   struct pipe_surface *surface, *past, *future;
+   struct pipe_fence_handle **fence;
+   unsigned num_macroblocks;
+};
+
+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);
+
+void vl_mpeg12_mc_renderer_cleanup(struct vl_mpeg12_mc_renderer *renderer);
+
+bool vl_mpeg12_mc_init_buffer(struct vl_mpeg12_mc_renderer *renderer, struct vl_mpeg12_mc_buffer *buffer);
+
+void vl_mpeg12_mc_cleanup_buffer(struct vl_mpeg12_mc_renderer *renderer, struct vl_mpeg12_mc_buffer *buffer);
+
+void vl_mpeg12_mc_map_buffer(struct vl_mpeg12_mc_renderer *renderer, struct vl_mpeg12_mc_buffer *buffer);
+
+void vl_mpeg12_mc_renderer_render_macroblocks(struct vl_mpeg12_mc_renderer *renderer,
+                                              struct vl_mpeg12_mc_buffer *buffer,
+                                              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);
+
+void vl_mpeg12_mc_unmap_buffer(struct vl_mpeg12_mc_renderer *renderer, struct vl_mpeg12_mc_buffer *buffer);
+
+void vl_mpeg12_mc_renderer_flush(struct vl_mpeg12_mc_renderer *renderer, struct vl_mpeg12_mc_buffer *buffer);
+
+#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 (file)
index 0000000..9c745d7
--- /dev/null
@@ -0,0 +1,51 @@
+/**************************************************************************
+ *
+ * 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 vertex2s
+{
+   short x, y;
+};
+
+struct vertex4f
+{
+   float x, y, z, w;
+};
+
+struct quadf
+{
+   struct vertex2f bl, tl, tr, br;
+};
+
+#endif /* vl_types_h */
diff --git a/src/gallium/auxiliary/vl/vl_vertex_buffers.c b/src/gallium/auxiliary/vl/vl_vertex_buffers.c
new file mode 100644 (file)
index 0000000..552a045
--- /dev/null
@@ -0,0 +1,183 @@
+/**************************************************************************
+ *
+ * Copyright 2010 Christian König
+ * 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 <pipe/p_context.h>
+#include <pipe/p_screen.h>
+#include <util/u_memory.h>
+#include <util/u_inlines.h>
+#include <util/u_format.h>
+#include "vl_vertex_buffers.h"
+#include "vl_types.h"
+
+/* vertices for a quad covering a block */
+static const struct quadf const_quad = {
+   {0.0f, 1.0f}, {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}
+};
+
+struct pipe_vertex_buffer
+vl_vb_upload_quads(struct pipe_context *pipe, unsigned max_blocks)
+{
+   struct pipe_vertex_buffer quad;
+   struct pipe_transfer *buf_transfer;
+   struct quadf *v;
+
+   unsigned i;
+
+   assert(pipe);
+   assert(max_blocks);
+
+   /* create buffer */
+   quad.stride = sizeof(struct vertex2f);
+   quad.buffer_offset = 0;
+   quad.buffer = pipe_buffer_create
+   (
+      pipe->screen,
+      PIPE_BIND_VERTEX_BUFFER,
+      PIPE_USAGE_STATIC,
+      sizeof(struct vertex2f) * 4 * max_blocks
+   );
+
+   if(!quad.buffer)
+      return quad;
+
+   /* and fill it */
+   v = pipe_buffer_map
+   (
+      pipe,
+      quad.buffer,
+      PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD,
+      &buf_transfer
+   );
+
+   for ( i = 0; i < max_blocks; ++i)
+     memcpy(v + i, &const_quad, sizeof(const_quad));
+
+   pipe_buffer_unmap(pipe, buf_transfer);
+
+   return quad;
+}
+
+struct pipe_vertex_element
+vl_vb_get_quad_vertex_element(void)
+{
+   struct pipe_vertex_element element;
+
+   /* setup rectangle element */
+   element.src_offset = 0;
+   element.instance_divisor = 0;
+   element.vertex_buffer_index = 0;
+   element.src_format = PIPE_FORMAT_R32G32_FLOAT;
+
+   return element;
+}
+
+unsigned
+vl_vb_element_helper(struct pipe_vertex_element* elements, unsigned num_elements,
+                              unsigned vertex_buffer_index)
+{
+   unsigned i, offset = 0;
+
+   assert(elements && num_elements);
+
+   for ( i = 0; i < num_elements; ++i ) {
+      elements[i].src_offset = offset;
+      elements[i].instance_divisor = 0;
+      elements[i].vertex_buffer_index = vertex_buffer_index;
+      offset += util_format_get_blocksize(elements[i].src_format);
+   }
+
+   return offset;
+}
+
+struct pipe_vertex_buffer
+vl_vb_init(struct vl_vertex_buffer *buffer, struct pipe_context *pipe,
+           unsigned max_blocks, unsigned stride)
+{
+   struct pipe_vertex_buffer buf;
+
+   assert(buffer);
+
+   buffer->num_verts = 0;
+   buffer->stride = stride;
+
+   buf.stride = stride;
+   buf.buffer_offset = 0;
+   buf.buffer = pipe_buffer_create
+   (
+      pipe->screen,
+      PIPE_BIND_VERTEX_BUFFER,
+      PIPE_USAGE_STREAM,
+      stride * 4 * max_blocks
+   );
+
+   pipe_resource_reference(&buffer->resource, buf.buffer);
+
+   vl_vb_map(buffer, pipe);
+
+   return buf;
+}
+
+void
+vl_vb_map(struct vl_vertex_buffer *buffer, struct pipe_context *pipe)
+{
+   assert(buffer && pipe);
+
+   buffer->vectors = pipe_buffer_map
+   (
+      pipe,
+      buffer->resource,
+      PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD,
+      &buffer->transfer
+   );
+}
+
+void
+vl_vb_unmap(struct vl_vertex_buffer *buffer, struct pipe_context *pipe)
+{
+   assert(buffer && pipe);
+
+   pipe_buffer_unmap(pipe, buffer->transfer);
+}
+
+unsigned
+vl_vb_restart(struct vl_vertex_buffer *buffer)
+{
+   assert(buffer);
+
+   unsigned todo = buffer->num_verts;
+   buffer->num_verts = 0;
+   return todo;
+}
+
+void
+vl_vb_cleanup(struct vl_vertex_buffer *buffer)
+{
+   assert(buffer);
+
+   pipe_resource_reference(&buffer->resource, NULL);
+}
diff --git a/src/gallium/auxiliary/vl/vl_vertex_buffers.h b/src/gallium/auxiliary/vl/vl_vertex_buffers.h
new file mode 100644 (file)
index 0000000..b8e8766
--- /dev/null
@@ -0,0 +1,78 @@
+/**************************************************************************
+ *
+ * Copyright 2010 Christian König
+ * 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_vertex_buffers_h
+#define vl_vertex_buffers_h
+
+#include <assert.h>
+#include <pipe/p_state.h>
+#include "vl_types.h"
+
+struct vl_vertex_buffer
+{
+   unsigned num_verts;
+   unsigned stride;
+   struct pipe_resource *resource;
+   struct pipe_transfer *transfer;
+   void *vectors;
+};
+
+struct pipe_vertex_buffer vl_vb_upload_quads(struct pipe_context *pipe, unsigned max_blocks);
+
+struct pipe_vertex_element vl_vb_get_quad_vertex_element(void);
+
+unsigned vl_vb_element_helper(struct pipe_vertex_element* elements, unsigned num_elements,
+                              unsigned vertex_buffer_index);
+
+struct pipe_vertex_buffer vl_vb_init(struct vl_vertex_buffer *buffer,
+                                     struct pipe_context *pipe,
+                                     unsigned max_blocks, unsigned stride);
+
+void vl_vb_map(struct vl_vertex_buffer *buffer, struct pipe_context *pipe);
+
+static inline void
+vl_vb_add_block(struct vl_vertex_buffer *buffer, void *elements)
+{
+   void *pos;
+   unsigned i;
+
+   assert(buffer);
+
+   pos = buffer->vectors + buffer->num_verts * buffer->stride;
+   for(i = 0; i < 4; ++i) {
+      memcpy(pos, elements, buffer->stride);
+      pos += buffer->stride;
+      buffer->num_verts++;
+   }
+}
+
+void vl_vb_unmap(struct vl_vertex_buffer *buffer, struct pipe_context *pipe);
+
+unsigned vl_vb_restart(struct vl_vertex_buffer *buffer);
+
+void vl_vb_cleanup(struct vl_vertex_buffer *buffer);
+
+#endif
diff --git a/src/gallium/drivers/nv40/nv40_video_context.c b/src/gallium/drivers/nv40/nv40_video_context.c
new file mode 100644 (file)
index 0000000..e6e57ee
--- /dev/null
@@ -0,0 +1,47 @@
+/**************************************************************************
+ *
+ * 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,
+                             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 (file)
index 0000000..64196ca
--- /dev/null
@@ -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
index a3b76ac61b101e39860e1854f1bbabe2f531dfbd..cd37f0111e28b05f9f00e7121799a488a9740183 100644 (file)
@@ -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 = \
        $(LIBDRM_CFLAGS) \
index aa1e9567d313c8591f67e25a8244a93c97ce549a..15db574a1d08e95c173bbcac2acc062218665c0b 100644 (file)
@@ -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"
@@ -455,6 +456,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:
index 8fafca1950ccb5bc4116373dd881ef18899b7a87..15e1cbb1986703cf6202f5ca6ef76fe47b14191a 100644 (file)
@@ -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 (file)
index 0000000..58e1c0b
--- /dev/null
@@ -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 "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,
+                             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 (file)
index 0000000..6619427
--- /dev/null
@@ -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 (file)
index 0000000..9fe6d6f
--- /dev/null
@@ -0,0 +1,328 @@
+/*
+ * 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:
+ *   CooperYuan <cooper.yuan@amd.com>, <cooperyuan@gmail.com>
+ */
+
+#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,
+                                   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 (file)
index 0000000..a8210ba
--- /dev/null
@@ -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:
+ *   CooperYuan <cooper.yuan@amd.com>, <cooperyuan@gmail.com>
+ */
+
+#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
index a484f38e9f12fcbf795e35cf8332d612bb699e4d..436de9c4dbde0d46318a59d81402e5f8f804e44d 100644 (file)
@@ -17,6 +17,7 @@ C_SOURCES = \
        r600_shader.c \
        r600_state.c \
        r600_texture.c \
+       r600_video_context.c \
        r700_asm.c \
        evergreen_state.c \
        eg_asm.c \
index 80c5de39750bc441269328854ed9bc5635aecb34..4f86e3b4c38d0fbf721c62a06ff0d1c060d379f7 100644 (file)
 int eg_bc_cf_build(struct r600_bc *bc, struct r600_bc_cf *cf)
 {
        unsigned id = cf->id;
+       unsigned end_of_program = bc->cf.prev == &cf->list;
 
        switch (cf->inst) {
        case (EG_V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3):
        case (EG_V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP_AFTER << 3):
        case (EG_V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP2_AFTER << 3):
        case (EG_V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE << 3):
+               assert(!end_of_program);
                bc->bytecode[id++] = S_SQ_CF_ALU_WORD0_ADDR(cf->addr >> 1) |
                        S_SQ_CF_ALU_WORD0_KCACHE_MODE0(cf->kcache[0].mode) |
                        S_SQ_CF_ALU_WORD0_KCACHE_BANK0(cf->kcache[0].bank) |
@@ -46,15 +48,16 @@ int eg_bc_cf_build(struct r600_bc *bc, struct r600_bc_cf *cf)
                        S_SQ_CF_ALU_WORD1_KCACHE_MODE1(cf->kcache[1].mode) |
                        S_SQ_CF_ALU_WORD1_KCACHE_ADDR0(cf->kcache[0].addr) |
                        S_SQ_CF_ALU_WORD1_KCACHE_ADDR1(cf->kcache[1].addr) |
-                                       S_SQ_CF_ALU_WORD1_BARRIER(1) |
-                                       S_SQ_CF_ALU_WORD1_COUNT((cf->ndw / 2) - 1);
+                       S_SQ_CF_ALU_WORD1_BARRIER(cf->barrier) |
+                       S_SQ_CF_ALU_WORD1_COUNT((cf->ndw / 2) - 1);
                break;
        case EG_V_SQ_CF_WORD1_SQ_CF_INST_TEX:
        case EG_V_SQ_CF_WORD1_SQ_CF_INST_VTX:
                bc->bytecode[id++] = S_SQ_CF_WORD0_ADDR(cf->addr >> 1);
                bc->bytecode[id++] = S_SQ_CF_WORD1_CF_INST(cf->inst) |
-                                       S_SQ_CF_WORD1_BARRIER(1) |
-                                       S_SQ_CF_WORD1_COUNT((cf->ndw / 4) - 1);
+                       S_SQ_CF_WORD1_BARRIER(cf->barrier) |
+                       S_SQ_CF_WORD1_COUNT((cf->ndw / 4) - 1) |
+                       S_SQ_CF_WORD1_END_OF_PROGRAM(end_of_program);
                break;
        case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT:
        case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE:
@@ -67,9 +70,9 @@ int eg_bc_cf_build(struct r600_bc *bc, struct r600_bc_cf *cf)
                        S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_Y(cf->output.swizzle_y) |
                        S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_Z(cf->output.swizzle_z) |
                        S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_W(cf->output.swizzle_w) |
-                       S_SQ_CF_ALLOC_EXPORT_WORD1_BARRIER(cf->output.barrier) |
-                       S_SQ_CF_ALLOC_EXPORT_WORD1_CF_INST(cf->output.inst) |
-                       S_SQ_CF_ALLOC_EXPORT_WORD1_END_OF_PROGRAM(cf->output.end_of_program);
+                       S_SQ_CF_ALLOC_EXPORT_WORD1_BARRIER(cf->barrier) |
+                       S_SQ_CF_ALLOC_EXPORT_WORD1_CF_INST(cf->inst) |
+                       S_SQ_CF_ALLOC_EXPORT_WORD1_END_OF_PROGRAM(end_of_program);
                break;
        case EG_V_SQ_CF_WORD1_SQ_CF_INST_JUMP:
        case EG_V_SQ_CF_WORD1_SQ_CF_INST_ELSE:
@@ -82,9 +85,10 @@ int eg_bc_cf_build(struct r600_bc *bc, struct r600_bc_cf *cf)
        case EG_V_SQ_CF_WORD1_SQ_CF_INST_RETURN:
                bc->bytecode[id++] = S_SQ_CF_WORD0_ADDR(cf->cf_addr >> 1);
                bc->bytecode[id++] = S_SQ_CF_WORD1_CF_INST(cf->inst) |
-                                       S_SQ_CF_WORD1_BARRIER(1) |
-                                       S_SQ_CF_WORD1_COND(cf->cond) |
-                                       S_SQ_CF_WORD1_POP_COUNT(cf->pop_count);
+                       S_SQ_CF_WORD1_BARRIER(cf->barrier) |
+                       S_SQ_CF_WORD1_COND(cf->cond) |
+                       S_SQ_CF_WORD1_POP_COUNT(cf->pop_count) |
+                       S_SQ_CF_WORD1_END_OF_PROGRAM(end_of_program);
 
                break;
        default:
index de796188fdec8f71f371d2463de3ac7bee2e65de..1393df8875730e162231ae5adec6c6ffd42009de 100644 (file)
@@ -35,6 +35,9 @@
 #define NUM_OF_CYCLES 3
 #define NUM_OF_COMPONENTS 4
 
+#define PREV_ALU(alu) LIST_ENTRY(struct r600_bc_alu, alu->list.prev, list)
+#define NEXT_ALU(alu) LIST_ENTRY(struct r600_bc_alu, alu->list.next, list)
+
 static inline unsigned int r600_bc_get_num_operands(struct r600_bc *bc, struct r600_bc_alu *alu)
 {
        if(alu->is_op3)
@@ -156,6 +159,7 @@ static struct r600_bc_cf *r600_bc_cf(void)
        LIST_INITHEAD(&cf->alu);
        LIST_INITHEAD(&cf->vtx);
        LIST_INITHEAD(&cf->tex);
+       cf->barrier = 1;
        return cf;
 }
 
@@ -244,13 +248,49 @@ static int r600_bc_add_cf(struct r600_bc *bc)
        return 0;
 }
 
+static void r600_bc_remove_cf(struct r600_bc *bc, struct r600_bc_cf *cf)
+{
+       struct r600_bc_cf *other;
+       LIST_FOR_EACH_ENTRY(other, &bc->cf, list) {
+               if (other->id > cf->id)
+                       other->id -= 2;
+               if (other->cf_addr > cf->id)
+                       other->cf_addr -= 2;
+       }
+       LIST_DEL(&cf->list);
+       free(cf);
+}
+
+static void r600_bc_move_cf(struct r600_bc *bc, struct r600_bc_cf *cf, struct r600_bc_cf *next)
+{
+       struct r600_bc_cf *prev = LIST_ENTRY(struct r600_bc_cf, next->list.prev, list);
+       unsigned old_id = cf->id;
+       unsigned new_id = next->list.prev == &bc->cf ? 0 : prev->id + 2;
+       struct r600_bc_cf *other;
+
+       if (prev == cf || next == cf)
+               return; /* position hasn't changed */
+
+       LIST_DEL(&cf->list);
+       LIST_FOR_EACH_ENTRY(other, &bc->cf, list) {
+               if (other->id > old_id)
+                       other->id -= 2;
+               if (other->id >= new_id)
+                       other->id += 2;
+               if (other->cf_addr > old_id)
+                       other->cf_addr -= 2;
+               if (other->cf_addr > new_id)
+                       other->cf_addr += 2;
+       }
+       cf->id = new_id;
+       LIST_ADD(&cf->list, &prev->list);
+}
+
 int r600_bc_add_output(struct r600_bc *bc, const struct r600_bc_output *output)
 {
        int r;
 
-       if (bc->cf_last && (bc->cf_last->inst == output->inst ||
-               (bc->cf_last->inst == BC_INST(bc, V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT) &&
-               output->inst == BC_INST(bc, V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE))) &&
+       if (bc->cf_last && bc->cf_last->inst == BC_INST(bc, V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT) &&
                output->type == bc->cf_last->output.type &&
                output->elem_size == bc->cf_last->output.elem_size &&
                output->swizzle_x == bc->cf_last->output.swizzle_x &&
@@ -262,8 +302,6 @@ int r600_bc_add_output(struct r600_bc *bc, const struct r600_bc_output *output)
                if ((output->gpr + output->burst_count) == bc->cf_last->output.gpr &&
                        (output->array_base + output->burst_count) == bc->cf_last->output.array_base) {
 
-                       bc->cf_last->output.end_of_program |= output->end_of_program;
-                       bc->cf_last->output.inst = output->inst;
                        bc->cf_last->output.gpr = output->gpr;
                        bc->cf_last->output.array_base = output->array_base;
                        bc->cf_last->output.burst_count += output->burst_count;
@@ -272,8 +310,6 @@ int r600_bc_add_output(struct r600_bc *bc, const struct r600_bc_output *output)
                } else if (output->gpr == (bc->cf_last->output.gpr + bc->cf_last->output.burst_count) &&
                        output->array_base == (bc->cf_last->output.array_base + bc->cf_last->output.burst_count)) {
 
-                       bc->cf_last->output.end_of_program |= output->end_of_program;
-                       bc->cf_last->output.inst = output->inst;
                        bc->cf_last->output.burst_count += output->burst_count;
                        return 0;
                }
@@ -282,28 +318,19 @@ int r600_bc_add_output(struct r600_bc *bc, const struct r600_bc_output *output)
        r = r600_bc_add_cf(bc);
        if (r)
                return r;
-       bc->cf_last->inst = output->inst;
+       bc->cf_last->inst = BC_INST(bc, V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT);
        memcpy(&bc->cf_last->output, output, sizeof(struct r600_bc_output));
+       bc->cf_last->output.burst_count = 1;
        return 0;
 }
 
-/* alu instructions that can ony exits once per group */
-static int is_alu_once_inst(struct r600_bc *bc, struct r600_bc_alu *alu)
+/* alu predicate instructions */
+static int is_alu_pred_inst(struct r600_bc *bc, struct r600_bc_alu *alu)
 {
        switch (bc->chiprev) {
        case CHIPREV_R600:
        case CHIPREV_R700:
                return !alu->is_op3 && (
-                       alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLE ||
-                       alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT ||
-                       alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE ||
-                       alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLNE ||
-                       alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT_UINT ||
-                       alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE_UINT ||
-                       alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLE_INT ||
-                       alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT_INT ||
-                       alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE_INT ||
-                       alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLNE_INT ||
                        alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_UINT ||
                        alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_UINT ||
                        alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE ||
@@ -331,16 +358,6 @@ static int is_alu_once_inst(struct r600_bc *bc, struct r600_bc_alu *alu)
        case CHIPREV_EVERGREEN:
        default:
                return !alu->is_op3 && (
-                       alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLE ||
-                       alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT ||
-                       alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE ||
-                       alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLNE ||
-                       alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT_UINT ||
-                       alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE_UINT ||
-                       alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLE_INT ||
-                       alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT_INT ||
-                       alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE_INT ||
-                       alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLNE_INT ||
                        alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGT_UINT ||
                        alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETGE_UINT ||
                        alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_PRED_SETE ||
@@ -368,6 +385,46 @@ static int is_alu_once_inst(struct r600_bc *bc, struct r600_bc_alu *alu)
        }
 }
 
+/* alu kill instructions */
+static int is_alu_kill_inst(struct r600_bc *bc, struct r600_bc_alu *alu)
+{
+       switch (bc->chiprev) {
+       case CHIPREV_R600:
+       case CHIPREV_R700:
+               return !alu->is_op3 && (
+                       alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLE ||
+                       alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT ||
+                       alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE ||
+                       alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLNE ||
+                       alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT_UINT ||
+                       alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE_UINT ||
+                       alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLE_INT ||
+                       alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT_INT ||
+                       alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE_INT ||
+                       alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLNE_INT);
+       case CHIPREV_EVERGREEN:
+       default:
+               return !alu->is_op3 && (
+                       alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLE ||
+                       alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT ||
+                       alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE ||
+                       alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLNE ||
+                       alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT_UINT ||
+                       alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE_UINT ||
+                       alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLE_INT ||
+                       alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGT_INT ||
+                       alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLGE_INT ||
+                       alu->inst == EG_V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_KILLNE_INT);
+       }
+}
+
+/* alu instructions that can ony exits once per group */
+static int is_alu_once_inst(struct r600_bc *bc, struct r600_bc_alu *alu)
+{
+       return is_alu_kill_inst(bc, alu) ||
+               is_alu_pred_inst(bc, alu);
+}
+
 static int is_alu_reduction_inst(struct r600_bc *bc, struct r600_bc_alu *alu)
 {
        switch (bc->chiprev) {
@@ -1243,6 +1300,16 @@ int r600_bc_add_alu(struct r600_bc *bc, const struct r600_bc_alu *alu)
        return r600_bc_add_alu_type(bc, alu, BC_INST(bc, V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU));
 }
 
+static void r600_bc_remove_alu(struct r600_bc_cf *cf, struct r600_bc_alu *alu)
+{
+       if (alu->last && alu->list.prev != &cf->alu) {
+               PREV_ALU(alu)->last = 1;
+       }
+       LIST_DEL(&alu->list);
+       free(alu);
+       cf->ndw -= 2;
+}
+
 int r600_bc_add_vtx(struct r600_bc *bc, const struct r600_bc_vtx *vtx)
 {
        struct r600_bc_vtx *nvtx = r600_bc_vtx();
@@ -1451,16 +1518,63 @@ static int r600_bc_alu_build(struct r600_bc *bc, struct r600_bc_alu *alu, unsign
        return 0;
 }
 
-/* common for r600/r700 - eg in eg_asm.c */
-static int r600_bc_cf_build(struct r600_bc *bc, struct r600_bc_cf *cf)
+enum cf_class
+{
+       CF_CLASS_ALU,
+       CF_CLASS_TEXTURE,
+       CF_CLASS_VERTEX,
+       CF_CLASS_EXPORT,
+       CF_CLASS_OTHER
+};
+static enum cf_class r600_bc_cf_class(struct r600_bc_cf *cf)
 {
-       unsigned id = cf->id;
-
        switch (cf->inst) {
        case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3):
-       case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE << 3):
        case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP_AFTER << 3):
        case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP2_AFTER << 3):
+       case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE << 3):
+               return CF_CLASS_ALU;
+
+       case V_SQ_CF_WORD1_SQ_CF_INST_TEX:
+               return CF_CLASS_TEXTURE;
+
+       case V_SQ_CF_WORD1_SQ_CF_INST_VTX:
+       case V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC:
+               return CF_CLASS_VERTEX;
+
+       case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT:
+       case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE:
+       case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT:
+       case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE:
+               return CF_CLASS_EXPORT;
+
+       case V_SQ_CF_WORD1_SQ_CF_INST_JUMP:
+       case V_SQ_CF_WORD1_SQ_CF_INST_ELSE:
+       case V_SQ_CF_WORD1_SQ_CF_INST_POP:
+       case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_START_NO_AL:
+       case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_END:
+       case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_CONTINUE:
+       case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_BREAK:
+       case V_SQ_CF_WORD1_SQ_CF_INST_CALL_FS:
+       case V_SQ_CF_WORD1_SQ_CF_INST_RETURN:
+               return CF_CLASS_OTHER;
+
+       default:
+               R600_ERR("unsupported CF instruction (0x%X)\n", cf->inst);
+               return -EINVAL;
+       }
+}
+
+/* common for r600/r700 - eg in eg_asm.c */
+static int r600_bc_cf_build(struct r600_bc *bc, struct r600_bc_cf *cf)
+{
+       unsigned id = cf->id;
+       unsigned end_of_program = bc->cf.prev == &cf->list;
+
+       switch (r600_bc_cf_class(cf)) {
+       case CF_CLASS_ALU:
+               assert(!end_of_program);
                bc->bytecode[id++] = S_SQ_CF_ALU_WORD0_ADDR(cf->addr >> 1) |
                        S_SQ_CF_ALU_WORD0_KCACHE_MODE0(cf->kcache[0].mode) |
                        S_SQ_CF_ALU_WORD0_KCACHE_BANK0(cf->kcache[0].bank) |
@@ -1470,20 +1584,19 @@ static int r600_bc_cf_build(struct r600_bc *bc, struct r600_bc_cf *cf)
                        S_SQ_CF_ALU_WORD1_KCACHE_MODE1(cf->kcache[1].mode) |
                        S_SQ_CF_ALU_WORD1_KCACHE_ADDR0(cf->kcache[0].addr) |
                        S_SQ_CF_ALU_WORD1_KCACHE_ADDR1(cf->kcache[1].addr) |
-                                       S_SQ_CF_ALU_WORD1_BARRIER(1) |
-                                       S_SQ_CF_ALU_WORD1_USES_WATERFALL(bc->chiprev == CHIPREV_R600 ? cf->r6xx_uses_waterfall : 0) |
-                                       S_SQ_CF_ALU_WORD1_COUNT((cf->ndw / 2) - 1);
+                       S_SQ_CF_ALU_WORD1_BARRIER(cf->barrier) |
+                       S_SQ_CF_ALU_WORD1_USES_WATERFALL(bc->chiprev == CHIPREV_R600 ? cf->r6xx_uses_waterfall : 0) |
+                       S_SQ_CF_ALU_WORD1_COUNT((cf->ndw / 2) - 1);
                break;
-       case V_SQ_CF_WORD1_SQ_CF_INST_TEX:
-       case V_SQ_CF_WORD1_SQ_CF_INST_VTX:
-       case V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC:
+       case CF_CLASS_TEXTURE:
+       case CF_CLASS_VERTEX:
                bc->bytecode[id++] = S_SQ_CF_WORD0_ADDR(cf->addr >> 1);
                bc->bytecode[id++] = S_SQ_CF_WORD1_CF_INST(cf->inst) |
-                                       S_SQ_CF_WORD1_BARRIER(1) |
-                                       S_SQ_CF_WORD1_COUNT((cf->ndw / 4) - 1);
+                       S_SQ_CF_WORD1_BARRIER(cf->barrier) |
+                       S_SQ_CF_WORD1_COUNT((cf->ndw / 4) - 1) |
+                       S_SQ_CF_WORD1_END_OF_PROGRAM(end_of_program);
                break;
-       case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT:
-       case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE:
+       case CF_CLASS_EXPORT:
                bc->bytecode[id++] = S_SQ_CF_ALLOC_EXPORT_WORD0_RW_GPR(cf->output.gpr) |
                        S_SQ_CF_ALLOC_EXPORT_WORD0_ELEM_SIZE(cf->output.elem_size) |
                        S_SQ_CF_ALLOC_EXPORT_WORD0_ARRAY_BASE(cf->output.array_base) |
@@ -1493,24 +1606,17 @@ static int r600_bc_cf_build(struct r600_bc *bc, struct r600_bc_cf *cf)
                        S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_Y(cf->output.swizzle_y) |
                        S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_Z(cf->output.swizzle_z) |
                        S_SQ_CF_ALLOC_EXPORT_WORD1_SWIZ_SEL_W(cf->output.swizzle_w) |
-                       S_SQ_CF_ALLOC_EXPORT_WORD1_BARRIER(cf->output.barrier) |
-                       S_SQ_CF_ALLOC_EXPORT_WORD1_CF_INST(cf->output.inst) |
-                       S_SQ_CF_ALLOC_EXPORT_WORD1_END_OF_PROGRAM(cf->output.end_of_program);
+                       S_SQ_CF_ALLOC_EXPORT_WORD1_BARRIER(cf->barrier) |
+                       S_SQ_CF_ALLOC_EXPORT_WORD1_CF_INST(cf->inst) |
+                       S_SQ_CF_ALLOC_EXPORT_WORD1_END_OF_PROGRAM(end_of_program);
                break;
-       case V_SQ_CF_WORD1_SQ_CF_INST_JUMP:
-       case V_SQ_CF_WORD1_SQ_CF_INST_ELSE:
-       case V_SQ_CF_WORD1_SQ_CF_INST_POP:
-       case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_START_NO_AL:
-       case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_END:
-       case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_CONTINUE:
-       case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_BREAK:
-       case V_SQ_CF_WORD1_SQ_CF_INST_CALL_FS:
-       case V_SQ_CF_WORD1_SQ_CF_INST_RETURN:
+       case CF_CLASS_OTHER:
                bc->bytecode[id++] = S_SQ_CF_WORD0_ADDR(cf->cf_addr >> 1);
                bc->bytecode[id++] = S_SQ_CF_WORD1_CF_INST(cf->inst) |
-                                       S_SQ_CF_WORD1_BARRIER(1) |
-                                       S_SQ_CF_WORD1_COND(cf->cond) |
-                                       S_SQ_CF_WORD1_POP_COUNT(cf->pop_count);
+                       S_SQ_CF_WORD1_BARRIER(cf->barrier) |
+                       S_SQ_CF_WORD1_COND(cf->cond) |
+                       S_SQ_CF_WORD1_POP_COUNT(cf->pop_count) |
+                       S_SQ_CF_WORD1_END_OF_PROGRAM(end_of_program);
 
                break;
        default:
@@ -1520,12 +1626,819 @@ static int r600_bc_cf_build(struct r600_bc *bc, struct r600_bc_cf *cf)
        return 0;
 }
 
+struct gpr_usage_range {
+       int     replacement;
+       int     rel_block;
+       int     start;
+       int     end;
+};
+
+struct gpr_usage {
+       unsigned                channels:4;
+       int                     first_write;
+       int                     last_write[4];
+       unsigned                nranges;
+       struct gpr_usage_range  *ranges;
+};
+
+static struct gpr_usage_range* last_gpr_usage_range(struct gpr_usage *usage)
+{
+       if (usage->nranges)
+               return usage->ranges + usage->nranges - 1;
+       else
+               return NULL;
+}
+
+static struct gpr_usage_range* add_gpr_usage_range(struct gpr_usage *usage)
+{
+       struct gpr_usage_range *range;
+
+       usage->nranges++;
+       usage->ranges = realloc(usage->ranges, usage->nranges * sizeof(struct gpr_usage_range));
+       if (!usage->ranges)
+               return NULL;
+
+       range = last_gpr_usage_range(usage);
+       range->replacement = -1; /* no prefered replacement */
+       range->rel_block = -1;
+       range->start = -1;
+       range->end = -1;
+
+       return range;
+}
+
+static void notice_gpr_read(struct gpr_usage *usage, int id, unsigned chan)
+{
+       struct gpr_usage_range* range;
+
+        usage->channels |= 1 << chan;
+        usage->first_write = -1;
+        if (!usage->nranges) {
+               range = add_gpr_usage_range(usage);
+        } else
+               range = last_gpr_usage_range(usage);
+
+        if (range && range->end < id)
+               range->end = id;
+}
+
+static void notice_gpr_rel_read(struct r600_bc *bc, struct gpr_usage usage[128],
+                               int id, unsigned gpr, unsigned chan)
+{
+       unsigned i;
+       for (i = gpr; i < bc->ngpr; ++i)
+               notice_gpr_read(&usage[i], id, chan);
+
+       last_gpr_usage_range(&usage[gpr])->rel_block = bc->ngpr - gpr;
+}
+
+static void notice_gpr_last_write(struct gpr_usage *usage, int id, unsigned chan)
+{
+        usage->last_write[chan] = id;
+}
+
+static void notice_gpr_write(struct gpr_usage *usage, int id, unsigned chan,
+                               int predicate, int prefered_replacement)
+{
+       struct gpr_usage_range* last_range = last_gpr_usage_range(usage);
+       int start = usage->first_write != -1 ? usage->first_write : id;
+       usage->channels &= ~(1 << chan);
+       if (usage->channels) {
+               if (usage->first_write == -1)
+                       usage->first_write = id;
+       } else if (!last_range || (last_range->start != start && !predicate)) {
+               usage->first_write = start;
+               struct gpr_usage_range* range = add_gpr_usage_range(usage);
+               range->replacement = prefered_replacement;
+                range->start = start;
+        } else if (last_range->start == start && prefered_replacement != -1) {
+               last_range->replacement = prefered_replacement;
+        }
+        notice_gpr_last_write(usage, id, chan);
+}
+
+static void notice_gpr_rel_last_write(struct gpr_usage usage[128], int id, unsigned chan)
+{
+       unsigned i;
+       for (i = 0; i < 128; ++i)
+               notice_gpr_last_write(&usage[i], id, chan);
+}
+
+static void notice_gpr_rel_write(struct gpr_usage usage[128], int id, unsigned chan)
+{
+       unsigned i;
+       for (i = 0; i < 128; ++i)
+               notice_gpr_write(&usage[i], id, chan, 1, -1);
+}
+
+static void notice_alu_src_gprs(struct r600_bc *bc, struct r600_bc_alu *alu,
+                                struct gpr_usage usage[128], int id)
+{
+       unsigned src, num_src;
+
+       num_src = r600_bc_get_num_operands(bc, alu);
+       for (src = 0; src < num_src; ++src) {
+               // constants doesn't matter
+               if (!is_gpr(alu->src[src].sel))
+                       continue;
+
+               if (alu->src[src].rel)
+                       notice_gpr_rel_read(bc, usage, id, alu->src[src].sel, alu->src[src].chan);
+               else
+                       notice_gpr_read(&usage[alu->src[src].sel], id, alu->src[src].chan);
+       }
+}
+
+static void notice_alu_dst_gprs(struct r600_bc_alu *alu_first, struct gpr_usage usage[128],
+                               int id, int predicate)
+{
+       struct r600_bc_alu *alu;
+       for (alu = alu_first; alu; alu = LIST_ENTRY(struct r600_bc_alu, alu->list.next, list)) {
+               if (alu->dst.write) {
+                       if (alu->dst.rel)
+                               notice_gpr_rel_write(usage, id, alu->dst.chan);
+                       else if (alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV && is_gpr(alu->src[0].sel))
+                               notice_gpr_write(&usage[alu->dst.sel], id, alu->dst.chan,
+                                               predicate, alu->src[0].sel);
+                       else
+                               notice_gpr_write(&usage[alu->dst.sel], id, alu->dst.chan, predicate, -1);
+               }
+
+               if (alu->last)
+                       break;
+       }
+}
+
+static void notice_tex_gprs(struct r600_bc *bc, struct r600_bc_tex *tex,
+                               struct gpr_usage usage[128],
+                               int id, int predicate)
+{
+       if (tex->src_rel) {
+                if (tex->src_sel_x < 4)
+                       notice_gpr_rel_read(bc, usage, id, tex->src_gpr, tex->src_sel_x);
+               if (tex->src_sel_y < 4)
+                       notice_gpr_rel_read(bc, usage, id, tex->src_gpr, tex->src_sel_y);
+               if (tex->src_sel_z < 4)
+                       notice_gpr_rel_read(bc, usage, id, tex->src_gpr, tex->src_sel_z);
+               if (tex->src_sel_w < 4)
+                       notice_gpr_rel_read(bc, usage, id, tex->src_gpr, tex->src_sel_w);
+        } else {
+               if (tex->src_sel_x < 4)
+                       notice_gpr_read(&usage[tex->src_gpr], id, tex->src_sel_x);
+               if (tex->src_sel_y < 4)
+                       notice_gpr_read(&usage[tex->src_gpr], id, tex->src_sel_y);
+               if (tex->src_sel_z < 4)
+                       notice_gpr_read(&usage[tex->src_gpr], id, tex->src_sel_z);
+               if (tex->src_sel_w < 4)
+                       notice_gpr_read(&usage[tex->src_gpr], id, tex->src_sel_w);
+       }
+       if (tex->dst_rel) {
+               if (tex->dst_sel_x != 7)
+                       notice_gpr_rel_write(usage, id, 0);
+               if (tex->dst_sel_y != 7)
+                       notice_gpr_rel_write(usage, id, 1);
+               if (tex->dst_sel_z != 7)
+                       notice_gpr_rel_write(usage, id, 2);
+               if (tex->dst_sel_w != 7)
+                       notice_gpr_rel_write(usage, id, 3);
+       } else {
+               if (tex->dst_sel_x != 7)
+                       notice_gpr_write(&usage[tex->dst_gpr], id, 0, predicate, -1);
+               if (tex->dst_sel_y != 7)
+                       notice_gpr_write(&usage[tex->dst_gpr], id, 1, predicate, -1);
+               if (tex->dst_sel_z != 7)
+                       notice_gpr_write(&usage[tex->dst_gpr], id, 2, predicate, -1);
+               if (tex->dst_sel_w != 7)
+                       notice_gpr_write(&usage[tex->dst_gpr], id, 3, predicate, -1);
+       }
+}
+
+static void notice_vtx_gprs(struct r600_bc_vtx *vtx, struct gpr_usage usage[128],
+                               int id, int predicate)
+{
+       notice_gpr_read(&usage[vtx->src_gpr], id, vtx->src_sel_x);
+
+       if (vtx->dst_sel_x != 7)
+               notice_gpr_write(&usage[vtx->dst_gpr], id, 0, predicate, -1);
+       if (vtx->dst_sel_y != 7)
+               notice_gpr_write(&usage[vtx->dst_gpr], id, 1, predicate, -1);
+       if (vtx->dst_sel_z != 7)
+               notice_gpr_write(&usage[vtx->dst_gpr], id, 2, predicate, -1);
+       if (vtx->dst_sel_w != 7)
+               notice_gpr_write(&usage[vtx->dst_gpr], id, 3, predicate, -1);
+}
+
+static void notice_export_gprs(struct r600_bc_cf *cf, struct gpr_usage usage[128],
+                               struct r600_bc_cf *export_cf[128], int export_remap[128])
+{
+       //TODO handle other memory operations
+       struct gpr_usage *output = &usage[cf->output.gpr];
+       int id = MAX4(output->last_write[0], output->last_write[1],
+               output->last_write[2], output->last_write[3]);
+       id += 0x100;
+       id &= ~0xFF;
+
+       export_cf[cf->output.gpr] = cf;
+       export_remap[cf->output.gpr] = id;
+       if (cf->output.swizzle_x < 4)
+               notice_gpr_read(output, id, cf->output.swizzle_x);
+       if (cf->output.swizzle_y < 4)
+               notice_gpr_read(output, id, cf->output.swizzle_y);
+       if (cf->output.swizzle_z < 4)
+               notice_gpr_read(output, id, cf->output.swizzle_z);
+       if (cf->output.swizzle_w < 4)
+               notice_gpr_read(output, id, cf->output.swizzle_w);
+}
+
+static struct gpr_usage_range *find_src_range(struct gpr_usage *usage, int id)
+{
+       unsigned i;
+       for (i = 0; i < usage->nranges; ++i) {
+               struct gpr_usage_range* range = &usage->ranges[i];
+
+               if (range->start < id && id <= range->end)
+                       return range;
+       }
+       return NULL;
+}
+
+static struct gpr_usage_range *find_dst_range(struct gpr_usage *usage, int id)
+{
+       unsigned i;
+       for (i = 0; i < usage->nranges; ++i) {
+               struct gpr_usage_range* range = &usage->ranges[i];
+               int end = range->end;
+
+               if (range->start <= id && (id < end || end == -1))
+                       return range;
+       }
+       return NULL;
+}
+
+static int is_barrier_needed(struct gpr_usage *usage, int id, unsigned chan, int last_barrier)
+{
+       if (usage->last_write[chan] != (id & ~0xFF))
+               return usage->last_write[chan] >= last_barrier;
+       else
+               return 0;
+}
+
+static int is_intersection(struct gpr_usage_range* a, struct gpr_usage_range* b)
+{
+       return a->start <= b->end && b->start < a->end;
+}
+
+static int rate_replacement(struct gpr_usage usage[128], unsigned current, unsigned gpr,
+                               struct gpr_usage_range* range)
+{
+       int max_gpr = gpr + MAX2(range->rel_block, 1);
+       int best_start = 0x3FFFFFFF, best_end = 0x3FFFFFFF;
+       unsigned i;
+
+       for (; gpr < max_gpr; ++gpr) {
+
+               if (gpr >= 128) /* relative gpr block won't fit into clause temporaries */
+                       return -1; /* forget it */
+
+               if (gpr == current) /* ignore ranges of to be replaced register */
+                       continue;
+
+               for (i = 0; i < usage[gpr].nranges; ++i) {
+                       if (usage[gpr].ranges[i].replacement < gpr)
+                               continue; /* ignore already remapped ranges */
+
+                       if (is_intersection(&usage[gpr].ranges[i], range))
+                               return -1; /* forget it if usages overlap */
+
+                       if (range->start >= usage[gpr].ranges[i].end)
+                               best_start = MIN2(best_start, range->start - usage[gpr].ranges[i].end);
+
+                       if (range->end != -1 && range->end <= usage[gpr].ranges[i].start)
+                               best_end = MIN2(best_end, usage[gpr].ranges[i].start - range->end);
+               }
+       }
+       return best_start + best_end;
+}
+
+static void find_replacement(struct gpr_usage usage[128], unsigned current,
+                               struct gpr_usage_range *range)
+{
+       unsigned i, j;
+       int best_gpr = -1, best_rate = 0x7FFFFFFF;
+
+       if (range->replacement == current) 
+               return; /* register prefers to be not remapped */
+
+       if (range->replacement != -1 && range->replacement <= current) {
+               struct gpr_usage_range *other = find_src_range(&usage[range->replacement], range->start);
+               if (other && other->replacement != -1)
+                       range->replacement = other->replacement;
+       }
+
+       if (range->replacement != -1 && range->replacement < current) {
+               int rate = rate_replacement(usage, current, range->replacement, range);
+
+               /* check if prefered replacement can be used */
+               if (rate != -1) {
+                       best_rate = rate;
+                       best_gpr = range->replacement;
+               }
+       }
+
+       if (best_gpr == -1 && (range->start & ~0xFF) == (range->end & ~0xFF)) {
+               /* register is just used inside one ALU clause */
+               /* try to use clause temporaries for it */
+               for (i = 127; i > 123; --i) {
+                       int rate = rate_replacement(usage, current, i, range);
+
+                       if (rate == -1) /* can't be used because ranges overlap */
+                               continue;
+
+                       if (rate < best_rate) {
+                               best_rate = rate;
+                               best_gpr = i;
+
+                               /* can't get better than this */
+                               if (rate == 0)
+                                       break;
+                       }
+               }
+       }
+
+       if (best_gpr == -1) {
+               for (i = 0; i < current; ++i) {
+                       int rate = rate_replacement(usage, current, i, range);
+
+                       if (rate == -1) /* can't be used because ranges overlap */
+                               continue;
+
+                       if (rate < best_rate) {
+                               best_rate = rate;
+                               best_gpr = i;
+
+                               /* can't get better than this */
+                               if (rate == 0)
+                                       break;
+                       }
+               }
+       }
+
+       if (best_gpr != -1) {
+               struct gpr_usage_range *reservation = add_gpr_usage_range(&usage[best_gpr]);
+               reservation->replacement = best_gpr;
+               reservation->rel_block = -1;
+               reservation->start = range->start;
+               reservation->end = range->end;
+       } else
+               best_gpr = current;
+
+       range->replacement = best_gpr;
+       if (range->rel_block == -1)
+               return; /* no relative block to handle we are done here */
+
+       /* set prefered register for the whole relative register block */
+       for (i = current + 1, ++best_gpr; i < current + range->rel_block; ++i, ++best_gpr) {
+               for (j = 0; j < usage[i].nranges; ++j) {
+                       if (is_intersection(&usage[i].ranges[j], range))
+                               usage[i].ranges[j].replacement = best_gpr;
+               }
+       }
+}
+
+static void replace_alu_gprs(struct r600_bc *bc, struct r600_bc_alu *alu, struct gpr_usage usage[128],
+                               int id, int last_barrier, unsigned *barrier)
+{
+       struct gpr_usage *cur_usage;
+       struct gpr_usage_range *range;
+       unsigned src, num_src;
+
+       num_src = r600_bc_get_num_operands(bc, alu);
+       for (src = 0; src < num_src; ++src) {
+               // constants doesn't matter
+               if (!is_gpr(alu->src[src].sel))
+                       continue;
+
+               cur_usage = &usage[alu->src[src].sel];
+               range = find_src_range(cur_usage, id);
+               alu->src[src].sel = range->replacement;
+
+               *barrier |= is_barrier_needed(cur_usage, id, alu->src[src].chan, last_barrier);
+       }
+
+       if (alu->dst.write) {
+               cur_usage = &usage[alu->dst.sel];
+               range = find_dst_range(cur_usage, id);
+               if (!range || range->replacement == -1) {
+                       if (!alu->is_op3)
+                               alu->dst.write = 0;
+                       else
+                               /*TODO: really check that register 123 is useable */
+                               alu->dst.sel = 123;
+               } else {
+                       alu->dst.sel = range->replacement;
+                       *barrier |= is_barrier_needed(cur_usage, id, alu->dst.chan, last_barrier);
+               }
+       }
+       if (alu->dst.write) {
+               if (alu->dst.rel)
+                       notice_gpr_rel_last_write(usage, id, alu->dst.chan);
+               else
+                       notice_gpr_last_write(cur_usage, id, alu->dst.chan);
+       }
+}
+
+static void replace_tex_gprs(struct r600_bc_tex *tex, struct gpr_usage usage[128],
+                               int id, int last_barrier, unsigned *barrier)
+{
+       struct gpr_usage *cur_usage = &usage[tex->src_gpr];
+       struct gpr_usage_range *range = find_src_range(cur_usage, id);
+
+       if (tex->src_rel) {
+               *barrier = 1;
+        } else {
+               if (tex->src_sel_x < 4)
+                       *barrier |= is_barrier_needed(cur_usage, id, tex->src_sel_x, last_barrier);
+               if (tex->src_sel_y < 4)
+                       *barrier |= is_barrier_needed(cur_usage, id, tex->src_sel_y, last_barrier);
+               if (tex->src_sel_z < 4)
+                       *barrier |= is_barrier_needed(cur_usage, id, tex->src_sel_z, last_barrier);
+               if (tex->src_sel_w < 4)
+                       *barrier |= is_barrier_needed(cur_usage, id, tex->src_sel_w, last_barrier);
+       }
+       tex->src_gpr = range->replacement;
+
+       cur_usage = &usage[tex->dst_gpr];
+
+       range = find_dst_range(cur_usage, id);
+       if (range) {
+               tex->dst_gpr = range->replacement;
+
+               if (tex->dst_rel) {
+                       if (tex->dst_sel_x != 7)
+                               notice_gpr_rel_last_write(usage, id, tex->dst_sel_x);
+                       if (tex->dst_sel_y != 7)
+                               notice_gpr_rel_last_write(usage, id, tex->dst_sel_y);
+                       if (tex->dst_sel_z != 7)
+                               notice_gpr_rel_last_write(usage, id, tex->dst_sel_z);
+                       if (tex->dst_sel_w != 7)
+                               notice_gpr_rel_last_write(usage, id, tex->dst_sel_w);
+               } else {
+                       if (tex->dst_sel_x != 7)
+                               notice_gpr_last_write(cur_usage, id, tex->dst_sel_x);
+                       if (tex->dst_sel_y != 7)
+                               notice_gpr_last_write(cur_usage, id, tex->dst_sel_y);
+                       if (tex->dst_sel_z != 7)
+                               notice_gpr_last_write(cur_usage, id, tex->dst_sel_z);
+                       if (tex->dst_sel_w != 7)
+                               notice_gpr_last_write(cur_usage, id, tex->dst_sel_w);
+               }
+       } else {
+               tex->dst_gpr = 123;
+       }
+}
+
+static void replace_vtx_gprs(struct r600_bc_vtx *vtx, struct gpr_usage usage[128],
+                               int id, int last_barrier, unsigned *barrier)
+{
+       struct gpr_usage *cur_usage = &usage[vtx->src_gpr];
+       struct gpr_usage_range *range = find_src_range(cur_usage, id);
+
+       *barrier |= is_barrier_needed(cur_usage, id, vtx->src_sel_x, last_barrier);
+
+       vtx->src_gpr = range->replacement;
+
+       cur_usage = &usage[vtx->dst_gpr];
+       range = find_dst_range(cur_usage, id);
+       if (range) {
+               vtx->dst_gpr = range->replacement;
+
+               if (vtx->dst_sel_x != 7)
+                       notice_gpr_last_write(cur_usage, id, vtx->dst_sel_x);
+               if (vtx->dst_sel_y != 7)
+                       notice_gpr_last_write(cur_usage, id, vtx->dst_sel_y);
+               if (vtx->dst_sel_z != 7)
+                       notice_gpr_last_write(cur_usage, id, vtx->dst_sel_z);
+               if (vtx->dst_sel_w != 7)
+                       notice_gpr_last_write(cur_usage, id, vtx->dst_sel_w);
+       } else {
+               vtx->dst_gpr = 123;
+       }
+}
+
+static void replace_export_gprs(struct r600_bc_cf *cf, struct gpr_usage usage[128],
+                               int id, int last_barrier)
+{
+       //TODO handle other memory operations
+       struct gpr_usage *cur_usage = &usage[cf->output.gpr];
+       struct gpr_usage_range *range = find_src_range(cur_usage, id);
+
+       cf->barrier = 0;
+       if (cf->output.swizzle_x < 4)
+               cf->barrier |= is_barrier_needed(cur_usage, -1, cf->output.swizzle_x, last_barrier);
+       if (cf->output.swizzle_y < 4)
+               cf->barrier |= is_barrier_needed(cur_usage, -1, cf->output.swizzle_y, last_barrier);
+       if (cf->output.swizzle_z < 4)
+               cf->barrier |= is_barrier_needed(cur_usage, -1, cf->output.swizzle_z, last_barrier);
+       if (cf->output.swizzle_w < 4)
+               cf->barrier |= is_barrier_needed(cur_usage, -1, cf->output.swizzle_w, last_barrier);
+
+       cf->output.gpr = range->replacement;
+}
+
+static void optimize_alu_inst(struct r600_bc *bc, struct r600_bc_cf *cf, struct r600_bc_alu *alu)
+{
+       struct r600_bc_alu *alu_next;
+       unsigned chan;
+       unsigned src, num_src;
+
+       /* check if a MOV could be optimized away */
+       if (alu->inst == V_SQ_ALU_WORD1_OP2_SQ_OP2_INST_MOV) {
+
+               /* destination equals source? */
+               if (alu->dst.sel != alu->src[0].sel ||
+                       alu->dst.chan != alu->src[0].chan)
+                       return;
+
+               /* any special handling for the source? */
+               if (alu->src[0].rel || alu->src[0].neg || alu->src[0].abs)
+                       return;
+
+               /* any special handling for destination? */
+               if (alu->dst.rel || alu->dst.clamp)
+                       return;
+
+               /* ok find next instruction group and check if ps/pv is used */
+               for (alu_next = alu; !alu_next->last; alu_next = NEXT_ALU(alu_next));
+
+               if (alu_next->list.next != &cf->alu) {
+                       chan = is_alu_reduction_inst(bc, alu) ? 0 : alu->dst.chan;
+                       for (alu_next = NEXT_ALU(alu_next); alu_next; alu_next = NEXT_ALU(alu_next)) {
+                               num_src = r600_bc_get_num_operands(bc, alu_next);
+                               for (src = 0; src < num_src; ++src) {
+                                       if (alu_next->src[src].sel == V_SQ_ALU_SRC_PV &&
+                                               alu_next->src[src].chan == chan)
+                                               return;
+
+                                       if (alu_next->src[src].sel == V_SQ_ALU_SRC_PS)
+                                               return;
+                               }
+
+                               if (alu_next->last)
+                                       break;
+                       }
+               }
+
+               r600_bc_remove_alu(cf, alu);
+       }
+}
+
+static void optimize_export_inst(struct r600_bc *bc, struct r600_bc_cf *cf)
+{
+       struct r600_bc_cf *prev = LIST_ENTRY(struct r600_bc_cf, cf->list.prev, list);
+       if (&prev->list == &bc->cf ||
+               prev->inst != cf->inst ||
+               prev->output.type != cf->output.type ||
+               prev->output.elem_size != cf->output.elem_size ||
+               prev->output.swizzle_x != cf->output.swizzle_x ||
+               prev->output.swizzle_y != cf->output.swizzle_y ||
+               prev->output.swizzle_z != cf->output.swizzle_z ||
+               prev->output.swizzle_w != cf->output.swizzle_w)
+               return;
+
+       if ((prev->output.burst_count + cf->output.burst_count) > 16)
+               return;
+
+       if ((prev->output.gpr + prev->output.burst_count) == cf->output.gpr &&
+               (prev->output.array_base + prev->output.burst_count) == cf->output.array_base) {
+
+               prev->output.burst_count += cf->output.burst_count;
+               r600_bc_remove_cf(bc, cf);
+
+       } else if (prev->output.gpr == (cf->output.gpr + cf->output.burst_count) &&
+               prev->output.array_base == (cf->output.array_base + cf->output.burst_count)) {
+
+               cf->output.burst_count += prev->output.burst_count;
+               r600_bc_remove_cf(bc, prev);
+       }
+}
+
+static void r600_bc_optimize(struct r600_bc *bc)
+{
+       struct r600_bc_cf *cf, *next_cf;
+       struct r600_bc_alu *first, *next_alu;
+       struct r600_bc_alu *alu;
+       struct r600_bc_vtx *vtx;
+       struct r600_bc_tex *tex;
+       struct gpr_usage usage[128];
+
+       /* assume that each gpr is exported only once */
+       struct r600_bc_cf *export_cf[128] = { NULL };
+       int export_remap[128];
+
+       int id, cond_start, barrier[bc->nstack];
+       unsigned i, j, stack, predicate, old_stack;
+
+       memset(&usage, 0, sizeof(usage));
+       for (i = 0; i < 128; ++i) {
+               usage[i].first_write = -1;
+               usage[i].last_write[0] = -1;
+               usage[i].last_write[1] = -1;
+               usage[i].last_write[2] = -1;
+               usage[i].last_write[3] = -1;
+       }
+
+       /* first gather some informations about the gpr usage */
+       id = 0; stack = 0;
+       LIST_FOR_EACH_ENTRY(cf, &bc->cf, list) {
+               old_stack = stack;
+               if (stack == 0)
+                       cond_start = stack;
+
+               switch (r600_bc_cf_class(cf)) {
+               case CF_CLASS_ALU:
+                       predicate = 0;
+                       first = NULL;
+                       LIST_FOR_EACH_ENTRY(alu, &cf->alu, list) {
+                               if (!first)
+                                       first = alu;
+                               notice_alu_src_gprs(bc, alu, usage, id);
+                               if (alu->last) {
+                                       notice_alu_dst_gprs(first, usage, id, predicate || stack > 0);
+                                       first = NULL;
+                                       ++id;
+                               }
+                               if (is_alu_pred_inst(bc, alu))
+                                       predicate++;
+                       }
+                       if (cf->inst == V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE << 3)
+                               stack += predicate;
+                       else if (cf->inst == V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP_AFTER << 3)
+                               stack -= 1;
+                       else if (cf->inst == V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP2_AFTER << 3)
+                               stack -= 2;
+                       break;
+               case CF_CLASS_TEXTURE:
+                       LIST_FOR_EACH_ENTRY(tex, &cf->tex, list) {
+                               notice_tex_gprs(bc, tex, usage, id++, stack > 0);
+                       }
+                       break;
+               case CF_CLASS_VERTEX:
+                       LIST_FOR_EACH_ENTRY(vtx, &cf->vtx, list) {
+                               notice_vtx_gprs(vtx, usage, id++, stack > 0);
+                       }
+                       break;
+               case CF_CLASS_EXPORT:
+                       notice_export_gprs(cf, usage, export_cf, export_remap);
+                       continue; // don't increment id
+               case CF_CLASS_OTHER:
+                       switch (cf->inst) {
+                       case V_SQ_CF_WORD1_SQ_CF_INST_JUMP:
+                       case V_SQ_CF_WORD1_SQ_CF_INST_ELSE:
+                       case V_SQ_CF_WORD1_SQ_CF_INST_CALL_FS:
+                               break;
+
+                       case V_SQ_CF_WORD1_SQ_CF_INST_POP:
+                               stack -= cf->pop_count;
+                               break;
+
+                       default:
+                               // TODO implement loop handling
+                               goto out;
+                       }
+               }
+
+               /* extend last_write after conditional block */
+               if (stack == 0 && old_stack != 0)
+                       for (i = 0; i < 128; ++i)
+                               for (j = 0; j < 4; ++j)
+                                       if (usage[i].last_write[j] >= cond_start)
+                                               usage[i].last_write[j] = id;
+
+               id += 0x100;
+               id &= ~0xFF;
+       }
+       assert(stack == 0);
+
+       /* try to optimize gpr usage */
+       for (i = 0; i < 124; ++i) {
+               for (j = 0; j < usage[i].nranges; ++j) {
+                       struct gpr_usage_range *range = &usage[i].ranges[j];
+                       if (range->start == -1)
+                               /* can't rearange shader inputs */
+                               range->replacement = i;
+                       else if (range->end == -1)
+                               /* gpr isn't used any more after this instruction */
+                               range->replacement = -1;
+                       else
+                               find_replacement(usage, i, range);
+
+                       if (range->replacement == i)
+                               bc->ngpr = i;
+                       else if (range->replacement < i && range->replacement > bc->ngpr)
+                               bc->ngpr = range->replacement;
+               }
+       }
+       bc->ngpr++;
+
+       /* apply the changes */
+       for (i = 0; i < 128; ++i) {
+               usage[i].last_write[0] = -1;
+               usage[i].last_write[1] = -1;
+               usage[i].last_write[2] = -1;
+               usage[i].last_write[3] = -1;
+       }
+       barrier[0] = 0;
+       id = 0; stack = 0;
+       LIST_FOR_EACH_ENTRY_SAFE(cf, next_cf, &bc->cf, list) {
+               old_stack = stack;
+               switch (r600_bc_cf_class(cf)) {
+               case CF_CLASS_ALU:
+                       predicate = 0;
+                       first = NULL;
+                       cf->barrier = 0;
+                       LIST_FOR_EACH_ENTRY_SAFE(alu, next_alu, &cf->alu, list) {
+                               replace_alu_gprs(bc, alu, usage, id, barrier[stack], &cf->barrier);
+                               if (alu->last)
+                                       ++id;
+
+                               if (is_alu_pred_inst(bc, alu))
+                                       predicate++;
+
+                               if (cf->inst == V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3)
+                                       optimize_alu_inst(bc, cf, alu);
+                       }
+                       if (cf->inst == V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE << 3)
+                               stack += predicate;
+                       else if (cf->inst == V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP_AFTER << 3)
+                               stack -= 1;
+                       else if (cf->inst == V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP2_AFTER << 3)
+                               stack -= 2;
+                       if (LIST_IS_EMPTY(&cf->alu)) {
+                               r600_bc_remove_cf(bc, cf);
+                               cf = NULL;
+                       }
+                       break;
+               case CF_CLASS_TEXTURE:
+                       cf->barrier = 0;
+                       LIST_FOR_EACH_ENTRY(tex, &cf->tex, list) {
+                               replace_tex_gprs(tex, usage, id++, barrier[stack], &cf->barrier);
+                       }
+                       break;
+               case CF_CLASS_VERTEX:
+                       cf->barrier = 0;
+                       LIST_FOR_EACH_ENTRY(vtx, &cf->vtx, list) {
+                               replace_vtx_gprs(vtx, usage, id++, barrier[stack], &cf->barrier);
+                       }
+                       break;
+               case CF_CLASS_EXPORT:
+                       continue; // don't increment id
+               case CF_CLASS_OTHER:
+                       if (cf->inst == V_SQ_CF_WORD1_SQ_CF_INST_POP) {
+                               cf->barrier = 0;
+                               stack -= cf->pop_count;
+                       }
+                       break;
+               }
+
+               id &= ~0xFF;
+               if (cf && cf->barrier)
+                       barrier[old_stack] = id;
+
+               for (i = old_stack + 1; i <= stack; ++i)
+                       barrier[i] = barrier[old_stack];
+
+               id += 0x100;
+               if (stack != 0) /* ensure exports are placed outside of conditional blocks */
+                       continue;
+
+               for (i = 0; i < 128; ++i) {
+                       if (!export_cf[i] || id < export_remap[i])
+                               continue;
+
+                       r600_bc_move_cf(bc, export_cf[i], next_cf);
+                       replace_export_gprs(export_cf[i], usage, export_remap[i], barrier[stack]);
+                       if (export_cf[i]->barrier)
+                               barrier[stack] = id - 1;
+                       next_cf = LIST_ENTRY(struct r600_bc_cf, export_cf[i]->list.next, list);
+                       optimize_export_inst(bc, export_cf[i]);
+                       export_cf[i] = NULL;
+               }
+       }
+       assert(stack == 0);
+
+out:
+       for (i = 0; i < 128; ++i) {
+               free(usage[i].ranges);
+       }
+}
+
 int r600_bc_build(struct r600_bc *bc)
 {
        struct r600_bc_cf *cf;
        struct r600_bc_alu *alu;
        struct r600_bc_vtx *vtx;
        struct r600_bc_tex *tex;
+       struct r600_bc_cf *exports[4] = { NULL };
        uint32_t literal[4];
        unsigned nliteral;
        unsigned addr;
@@ -1537,37 +2450,26 @@ int r600_bc_build(struct r600_bc *bc)
                bc->nstack = 1;
        }
 
+       //r600_bc_optimize(bc);
+
        /* first path compute addr of each CF block */
        /* addr start after all the CF instructions */
-       addr = bc->cf_last->id + 2;
+       addr = LIST_ENTRY(struct r600_bc_cf, bc->cf.prev, list)->id + 2;
        LIST_FOR_EACH_ENTRY(cf, &bc->cf, list) {
-               switch (cf->inst) {
-               case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3):
-               case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP_AFTER << 3):
-               case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP2_AFTER << 3):
-               case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE << 3):
+               switch (r600_bc_cf_class(cf)) {
+               case CF_CLASS_ALU:
                        break;
-               case V_SQ_CF_WORD1_SQ_CF_INST_TEX:
-               case V_SQ_CF_WORD1_SQ_CF_INST_VTX:
-               case V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC:
+               case CF_CLASS_TEXTURE:
+               case CF_CLASS_VERTEX:
                        /* fetch node need to be 16 bytes aligned*/
                        addr += 3;
                        addr &= 0xFFFFFFFCUL;
                        break;
-               case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT:
-               case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE:
-               case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT:
-               case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE:
+               case CF_CLASS_EXPORT:
+                       if (cf->inst == BC_INST(bc, V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT))
+                               exports[cf->output.type] = cf;
                        break;
-               case V_SQ_CF_WORD1_SQ_CF_INST_JUMP:
-               case V_SQ_CF_WORD1_SQ_CF_INST_ELSE:
-               case V_SQ_CF_WORD1_SQ_CF_INST_POP:
-               case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_START_NO_AL:
-               case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_END:
-               case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_CONTINUE:
-               case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_BREAK:
-               case V_SQ_CF_WORD1_SQ_CF_INST_CALL_FS:
-               case V_SQ_CF_WORD1_SQ_CF_INST_RETURN:
+               case CF_CLASS_OTHER:
                        break;
                default:
                        R600_ERR("unsupported CF instruction (0x%X)\n", cf->inst);
@@ -1577,6 +2479,14 @@ int r600_bc_build(struct r600_bc *bc)
                addr += cf->ndw;
                bc->ndw = cf->addr + cf->ndw;
        }
+
+       /* set export done on last export of each type */
+       for (i = 0; i < 4; ++i) {
+               if (exports[i]) {
+                       exports[i]->inst = BC_INST(bc, V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE);
+               }
+       }
+
        free(bc->bytecode);
        bc->bytecode = calloc(1, bc->ndw * 4);
        if (bc->bytecode == NULL)
@@ -1589,11 +2499,8 @@ int r600_bc_build(struct r600_bc *bc)
                        r = r600_bc_cf_build(bc, cf);
                if (r)
                        return r;
-               switch (cf->inst) {
-               case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3):
-               case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP_AFTER << 3):
-               case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP2_AFTER << 3):
-               case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE << 3):
+               switch (r600_bc_cf_class(cf)) {
+               case CF_CLASS_ALU:
                        nliteral = 0;
                        memset(literal, 0, sizeof(literal));
                        LIST_FOR_EACH_ENTRY(alu, &cf->alu, list) {
@@ -1625,8 +2532,7 @@ int r600_bc_build(struct r600_bc *bc)
                                }
                        }
                        break;
-               case V_SQ_CF_WORD1_SQ_CF_INST_VTX:
-               case V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC:
+               case CF_CLASS_VERTEX:
                        LIST_FOR_EACH_ENTRY(vtx, &cf->vtx, list) {
                                r = r600_bc_vtx_build(bc, vtx, addr);
                                if (r)
@@ -1634,7 +2540,7 @@ int r600_bc_build(struct r600_bc *bc)
                                addr += 4;
                        }
                        break;
-               case V_SQ_CF_WORD1_SQ_CF_INST_TEX:
+               case CF_CLASS_TEXTURE:
                        LIST_FOR_EACH_ENTRY(tex, &cf->tex, list) {
                                r = r600_bc_tex_build(bc, tex, addr);
                                if (r)
@@ -1642,19 +2548,8 @@ int r600_bc_build(struct r600_bc *bc)
                                addr += 4;
                        }
                        break;
-               case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT:
-               case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE:
-               case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT:
-               case EG_V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE:
-               case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_START_NO_AL:
-               case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_END:
-               case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_CONTINUE:
-               case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_BREAK:
-               case V_SQ_CF_WORD1_SQ_CF_INST_JUMP:
-               case V_SQ_CF_WORD1_SQ_CF_INST_ELSE:
-               case V_SQ_CF_WORD1_SQ_CF_INST_POP:
-               case V_SQ_CF_WORD1_SQ_CF_INST_CALL_FS:
-               case V_SQ_CF_WORD1_SQ_CF_INST_RETURN:
+               case CF_CLASS_EXPORT:
+               case CF_CLASS_OTHER:
                        break;
                default:
                        R600_ERR("unsupported CF instruction (0x%X)\n", cf->inst);
@@ -1730,13 +2625,10 @@ void r600_bc_dump(struct r600_bc *bc)
        LIST_FOR_EACH_ENTRY(cf, &bc->cf, list) {
                id = cf->id;
 
-               switch (cf->inst) {
-               case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU << 3):
-               case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP_AFTER << 3):
-               case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_POP2_AFTER << 3):
-               case (V_SQ_CF_ALU_WORD1_SQ_CF_INST_ALU_PUSH_BEFORE << 3):
+               switch (r600_bc_cf_class(cf)) {
+               case CF_CLASS_ALU:
                        fprintf(stderr, "%04d %08X ALU ", id, bc->bytecode[id]);
-                       fprintf(stderr, "ADDR:%d ", cf->addr);
+                       fprintf(stderr, "ADDR:%04d ", cf->addr);
                        fprintf(stderr, "KCACHE_MODE0:%X ", cf->kcache[0].mode);
                        fprintf(stderr, "KCACHE_BANK0:%X ", cf->kcache[0].bank);
                        fprintf(stderr, "KCACHE_BANK1:%X\n", cf->kcache[1].bank);
@@ -1746,22 +2638,22 @@ void r600_bc_dump(struct r600_bc *bc)
                        fprintf(stderr, "KCACHE_MODE1:%X ", cf->kcache[1].mode);
                        fprintf(stderr, "KCACHE_ADDR0:%X ", cf->kcache[0].addr);
                        fprintf(stderr, "KCACHE_ADDR1:%X ", cf->kcache[1].addr);
+                       fprintf(stderr, "BARRIER:%d ", cf->barrier);
                        fprintf(stderr, "COUNT:%d\n", cf->ndw / 2);
                        break;
-               case V_SQ_CF_WORD1_SQ_CF_INST_TEX:
-               case V_SQ_CF_WORD1_SQ_CF_INST_VTX:
-               case V_SQ_CF_WORD1_SQ_CF_INST_VTX_TC:
+               case CF_CLASS_TEXTURE:
+               case CF_CLASS_VERTEX:
                        fprintf(stderr, "%04d %08X TEX/VTX ", id, bc->bytecode[id]);
-                       fprintf(stderr, "ADDR:%d\n", cf->addr);
+                       fprintf(stderr, "ADDR:%04d\n", cf->addr);
                        id++;
                        fprintf(stderr, "%04d %08X TEX/VTX ", id, bc->bytecode[id]);
                        fprintf(stderr, "INST:%d ", cf->inst);
+                       fprintf(stderr, "BARRIER:%d ", cf->barrier);
                        fprintf(stderr, "COUNT:%d\n", cf->ndw / 4);
                        break;
-               case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT:
-               case V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE:
+               case CF_CLASS_EXPORT:
                        fprintf(stderr, "%04d %08X EXPORT ", id, bc->bytecode[id]);
-                       fprintf(stderr, "GPR:%X ", cf->output.gpr);
+                       fprintf(stderr, "GPR:%d ", cf->output.gpr);
                        fprintf(stderr, "ELEM_SIZE:%X ", cf->output.elem_size);
                        fprintf(stderr, "ARRAY_BASE:%X ", cf->output.array_base);
                        fprintf(stderr, "TYPE:%X\n", cf->output.type);
@@ -1771,26 +2663,18 @@ void r600_bc_dump(struct r600_bc *bc)
                        fprintf(stderr, "SWIZ_Y:%X ", cf->output.swizzle_y);
                        fprintf(stderr, "SWIZ_Z:%X ", cf->output.swizzle_z);
                        fprintf(stderr, "SWIZ_W:%X ", cf->output.swizzle_w);
-                       fprintf(stderr, "BARRIER:%X ", cf->output.barrier);
-                       fprintf(stderr, "INST:%d ", cf->output.inst);
-                       fprintf(stderr, "BURST_COUNT:%d ", cf->output.burst_count);
-                       fprintf(stderr, "EOP:%X\n", cf->output.end_of_program);
+                       fprintf(stderr, "BARRIER:%d ", cf->barrier);
+                       fprintf(stderr, "INST:%d ", cf->inst);
+                       fprintf(stderr, "BURST_COUNT:%d\n", cf->output.burst_count);
                        break;
-               case V_SQ_CF_WORD1_SQ_CF_INST_JUMP:
-               case V_SQ_CF_WORD1_SQ_CF_INST_ELSE:
-               case V_SQ_CF_WORD1_SQ_CF_INST_POP:
-               case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_START_NO_AL:
-               case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_END:
-               case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_CONTINUE:
-               case V_SQ_CF_WORD1_SQ_CF_INST_LOOP_BREAK:
-               case V_SQ_CF_WORD1_SQ_CF_INST_CALL_FS:
-               case V_SQ_CF_WORD1_SQ_CF_INST_RETURN:
+               case CF_CLASS_OTHER:
                        fprintf(stderr, "%04d %08X CF ", id, bc->bytecode[id]);
-                       fprintf(stderr, "ADDR:%d\n", cf->cf_addr);
+                       fprintf(stderr, "ADDR:%04d\n", cf->cf_addr);
                        id++;
                        fprintf(stderr, "%04d %08X CF ", id, bc->bytecode[id]);
                        fprintf(stderr, "INST:%d ", cf->inst);
                        fprintf(stderr, "COND:%X ", cf->cond);
+                       fprintf(stderr, "BARRIER:%d ", cf->barrier);
                        fprintf(stderr, "POP_COUNT:%X\n", cf->pop_count);
                        break;
                }
index 921d0d984546e73a7f0c80c0d9cdae6738608306..453c29790c158b68309f7b73b64a983ddef60aa7 100644 (file)
@@ -108,8 +108,6 @@ struct r600_bc_vtx {
 struct r600_bc_output {
        unsigned                        array_base;
        unsigned                        type;
-       unsigned                        end_of_program;
-       unsigned                        inst;
        unsigned                        elem_size;
        unsigned                        gpr;
        unsigned                        swizzle_x;
@@ -117,7 +115,6 @@ struct r600_bc_output {
        unsigned                        swizzle_z;
        unsigned                        swizzle_w;
        unsigned                        burst_count;
-       unsigned                        barrier;
 };
 
 struct r600_bc_kcache {
@@ -135,6 +132,7 @@ struct r600_bc_cf {
        unsigned                        cond;
        unsigned                        pop_count;
        unsigned                        cf_addr; /* control flow addr */
+       unsigned                        barrier;
        struct r600_bc_kcache           kcache[2];
        unsigned                        r6xx_uses_waterfall;
        struct list_head                alu;
index 62d108f3518f7467caa4825d699d0c5c06a540a6..34094001b755f77162bfba7a37e66d267dc8ff5e 100644 (file)
@@ -44,6 +44,7 @@
 #include "r600_shader.h"
 #include "r600_pipe.h"
 #include "r600_state_inlines.h"
+#include "r600_video_context.h"
 
 /*
  * pipe_context
@@ -503,6 +504,7 @@ struct pipe_screen *r600_screen_create(struct radeon *radeon)
        rscreen->screen.get_paramf = r600_get_paramf;
        rscreen->screen.is_format_supported = r600_is_format_supported;
        rscreen->screen.context_create = r600_create_context;
+       rscreen->screen.video_context_create = r600_video_create;
        r600_init_screen_resource_functions(&rscreen->screen);
 
        rscreen->tiling_info = r600_get_tiling_info(radeon);
index 13ccc3fdc1fbabcba518295f3f793124666987c1..240c8f1ffd086c8d31143913d892086ea01b5860 100644 (file)
@@ -685,7 +685,7 @@ static int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_sh
        struct tgsi_full_property *property;
        struct r600_shader_ctx ctx;
        struct r600_bc_output output[32];
-       unsigned output_done, noutput;
+       unsigned noutput;
        unsigned opcode;
        int i, r = 0, pos0;
 
@@ -819,10 +819,8 @@ static int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_sh
                output[i].swizzle_z = 2;
                output[i].swizzle_w = 3;
                output[i].burst_count = 1;
-               output[i].barrier = 1;
                output[i].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PARAM;
                output[i].array_base = i - pos0;
-               output[i].inst = BC_INST(ctx.bc, V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT);
                switch (ctx.type) {
                case TGSI_PROCESSOR_VERTEX:
                        if (shader->output[i].name == TGSI_SEMANTIC_POSITION) {
@@ -883,10 +881,8 @@ static int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_sh
                        output[i].swizzle_z = 2;
                        output[i].swizzle_w = 3;
                        output[i].burst_count = 1;
-                       output[i].barrier = 1;
                        output[i].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PARAM;
                        output[i].array_base = 0;
-                       output[i].inst = BC_INST(ctx.bc, V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT);
                        noutput++;
                }
        }
@@ -900,22 +896,10 @@ static int r600_shader_from_tgsi(const struct tgsi_token *tokens, struct r600_sh
                output[0].swizzle_z = 7;
                output[0].swizzle_w = 7;
                output[0].burst_count = 1;
-               output[0].barrier = 1;
                output[0].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL;
                output[0].array_base = 0;
-               output[0].inst = BC_INST(ctx.bc, V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT);
                noutput++;
        }
-       /* set export done on last export of each type */
-       for (i = noutput - 1, output_done = 0; i >= 0; i--) {
-               if (i == (noutput - 1)) {
-                       output[i].end_of_program = 1;
-               }
-               if (!(output_done & (1 << output[i].type))) {
-                       output_done |= (1 << output[i].type);
-                       output[i].inst = BC_INST(ctx.bc, V_SQ_CF_ALLOC_EXPORT_WORD1_SQ_CF_INST_EXPORT_DONE);
-               }
-       }
        /* add output to bytecode */
        for (i = 0; i < noutput; i++) {
                r = r600_bc_add_output(ctx.bc, &output[i]);
index c365979e43979f2f7ae4e9d248df22938e7239ff..576067ae81e215861d30927b73c14e001c1665e7 100644 (file)
@@ -730,6 +730,17 @@ static void r600_cb(struct r600_pipe_context *rctx, struct r600_pipe_state *rsta
        desc = util_format_description(surf->base.format);
        if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB)
                ntype = V_0280A0_NUMBER_SRGB;
+        else if (desc->layout == UTIL_FORMAT_LAYOUT_PLAIN) {
+               switch(desc->channel[0].type) {
+               case UTIL_FORMAT_TYPE_UNSIGNED:
+                       ntype = V_0280A0_NUMBER_UNORM;
+                       break;
+
+               case UTIL_FORMAT_TYPE_SIGNED:
+                       ntype = V_0280A0_NUMBER_SNORM;
+                       break;
+               }
+       }
 
        for (i = 0; i < 4; i++) {
                if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) {
index 29e12f1d468e68a24b798a63bcbb86f078a73e3f..3dd54f45202c50253566dbbb56a76aa83178af8f 100644 (file)
@@ -319,6 +319,7 @@ static inline uint32_t r600_translate_colorswap(enum pipe_format format)
                return V_0280A0_SWAP_STD;
 
        case PIPE_FORMAT_R16_UNORM:
+       case PIPE_FORMAT_R16_SNORM:
                return V_0280A0_SWAP_STD;
 
                /* 32-bit buffers. */
@@ -417,6 +418,7 @@ static INLINE uint32_t r600_translate_colorformat(enum pipe_format format)
                return V_0280A0_COLOR_8_8;
 
        case PIPE_FORMAT_R16_UNORM:
+       case PIPE_FORMAT_R16_SNORM:
                return V_0280A0_COLOR_16;
 
                /* 32-bit buffers. */
@@ -449,8 +451,8 @@ static INLINE uint32_t r600_translate_colorformat(enum pipe_format format)
        case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
                return V_0280A0_COLOR_24_8;
 
-       case PIPE_FORMAT_R32_FLOAT:
-               return V_0280A0_COLOR_32_FLOAT;
+       //case PIPE_FORMAT_R32_FLOAT:
+       //      return V_0280A0_COLOR_32_FLOAT;
 
        case PIPE_FORMAT_R16G16_FLOAT:
                return V_0280A0_COLOR_16_16_FLOAT;
index 095558d0337bacd9aa5b69ffb58b8bee88033e9b..03af367401d9b8c411072f42bc3b94bfa67d4e36 100644 (file)
@@ -294,7 +294,7 @@ static boolean permit_hardware_blit(struct pipe_screen *screen,
        /* hackaround for S3TC */
        if (util_format_is_s3tc(res->format))
                return TRUE;
-           
+
        if (!screen->is_format_supported(screen,
                                res->format,
                                res->target,
diff --git a/src/gallium/drivers/r600/r600_video_context.c b/src/gallium/drivers/r600/r600_video_context.c
new file mode 100644 (file)
index 0000000..b3885db
--- /dev/null
@@ -0,0 +1,21 @@
+#include "r600_video_context.h"
+#include <softpipe/sp_video_context.h>
+
+struct pipe_video_context *
+r600_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,
+                             true,
+                             PIPE_FORMAT_VUYX);
+}
diff --git a/src/gallium/drivers/r600/r600_video_context.h b/src/gallium/drivers/r600/r600_video_context.h
new file mode 100644 (file)
index 0000000..bda33a0
--- /dev/null
@@ -0,0 +1,11 @@
+#ifndef __R600_VIDEO_CONTEXT_H__
+#define __R600_VIDEO_CONTEXT_H__
+
+#include <pipe/p_video_context.h>
+
+struct pipe_video_context *
+r600_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
index 28953582f0a4bf36dfd72b3e1df64ce0daded59a..8876bd163986febd5106778725061da337207d0f 100644 (file)
@@ -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
index ea10e8a9f986f5cbb7bd0933aaf1990abf4e3cfa..9b2abdfd7f11caa0e18fdc2b84ef12e86b49c1b3 100644 (file)
@@ -35,6 +35,7 @@ softpipe = env.ConvenienceLibrary(
                'sp_tex_tile_cache.c',
                'sp_texture.c',
                'sp_tile_cache.c',
+               'sp_video_context.c',
        ])
 
 env.Alias('softpipe', softpipe)
index 6d47fb9628032431a1b89f67974444ba8b42d9db..a06817c573527f677737f7f9a4cf9f044f99c63d 100644 (file)
@@ -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"
 
@@ -310,6 +311,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();
 
index 5603110eeb339b59816a9245b142c1a7d67c1c59..533d6252e259b5ae2cbffd2956e46f989698e3c3 100644 (file)
@@ -79,7 +79,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 (file)
index 0000000..daebbc5
--- /dev/null
@@ -0,0 +1,648 @@
+/**************************************************************************
+ *
+ * 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_keymap.h>
+#include <util/u_rect.h>
+#include <util/u_video.h>
+#include <util/u_surface.h>
+#include "sp_public.h"
+#include "sp_texture.h"
+
+#define NUM_BUFFERS 2
+
+static void
+flush_buffer(struct sp_mpeg12_context *ctx)
+{
+   assert(ctx);
+
+   if(ctx->mc_buffer != NULL) {
+
+      vl_mpeg12_mc_unmap_buffer(&ctx->mc_renderer, ctx->mc_buffer);
+      vl_mpeg12_mc_renderer_flush(&ctx->mc_renderer, ctx->mc_buffer);
+
+      ctx->mc_buffer = NULL;
+   }
+}
+
+static void
+rotate_buffer(struct sp_mpeg12_context *ctx)
+{
+   static unsigned key = 0;
+   struct vl_mpeg12_mc_buffer *buffer;
+
+   assert(ctx);
+
+   flush_buffer(ctx);
+
+   buffer = (struct vl_mpeg12_mc_buffer*)util_keymap_lookup(ctx->buffer_map, &key);
+   if (!buffer) {
+      boolean added_to_map;
+
+      buffer = CALLOC_STRUCT(vl_mpeg12_mc_buffer);
+      if (buffer == NULL)
+         return;
+
+      if(!vl_mpeg12_mc_init_buffer(&ctx->mc_renderer, buffer)) {
+         FREE(buffer);
+         return;
+      }
+
+      added_to_map = util_keymap_insert(ctx->buffer_map, &key, buffer, ctx);
+      assert(added_to_map);
+   }
+   ++key;
+   key %= NUM_BUFFERS;
+   ctx->mc_buffer = buffer;
+
+   vl_mpeg12_mc_map_buffer(&ctx->mc_renderer, ctx->mc_buffer);
+}
+
+static void
+delete_buffer(const struct keymap *map,
+              const void *key, void *data,
+              void *user)
+{
+   struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)user;
+   struct vl_mpeg12_mc_buffer *buf = (struct vl_mpeg12_mc_buffer*)data;
+
+   assert(map);
+   assert(key);
+   assert(data);
+   assert(user);
+
+   vl_mpeg12_mc_cleanup_buffer(&ctx->mc_renderer, buf);
+}
+
+static void
+sp_mpeg12_destroy(struct pipe_video_context *vpipe)
+{
+   struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
+
+   assert(vpipe);
+
+   flush_buffer(ctx);
+
+   /* 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);
+   util_delete_keymap(ctx->buffer_map, ctx);
+   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 struct pipe_surface *
+sp_mpeg12_create_surface(struct pipe_video_context *vpipe,
+                         struct pipe_resource *resource,
+                         const struct pipe_surface *templat)
+{
+   struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
+
+   assert(vpipe);
+
+   return ctx->pipe->create_surface(ctx->pipe, resource, templat);
+}
+
+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, format, PIPE_TEXTURE_2D,
+                                                 0, 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);
+   assert(ctx->mc_buffer);
+
+   vl_mpeg12_mc_renderer_render_macroblocks(&ctx->mc_renderer,
+                                            ctx->mc_buffer,
+                                            ctx->decode_target,
+                                            past, future, num_macroblocks,
+                                            mpeg12_macroblocks, fence);
+}
+
+static void
+sp_mpeg12_clear_render_target(struct pipe_video_context *vpipe,
+                       struct pipe_surface *dst,
+                       unsigned dstx, unsigned dsty,
+                       unsigned width, unsigned height)
+{
+   struct sp_mpeg12_context *ctx = (struct sp_mpeg12_context*)vpipe;
+   float rgba[4] = { 0, 0, 0, 0 };
+
+   assert(vpipe);
+   assert(dst);
+
+   if (ctx->pipe->clear_render_target)
+      ctx->pipe->clear_render_target(ctx->pipe, dst, rgba, dstx, dsty, width, height);
+   else
+      util_clear_render_target(ctx->pipe, dst, rgba, dstx, dsty, width, height);
+}
+
+static void
+sp_mpeg12_resource_copy_region(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);
+
+   struct pipe_box box;
+   box.x = srcx;
+   box.y = srcy;
+   box.z = 0;
+   box.width = width;
+   box.height = height;
+
+   if (ctx->pipe->resource_copy_region)
+      ctx->pipe->resource_copy_region(ctx->pipe, dst->texture, dst->u.tex.level,
+                                      dstx, dsty, dst->u.tex.first_layer,
+                                      src->texture, src->u.tex.level, &box);
+   else
+      util_resource_copy_region(ctx->pipe, dst->texture, dst->u.tex.level,
+                                dstx, dsty, dst->u.tex.first_layer,
+                                src->texture, src->u.tex.level, &box);
+}
+
+static struct pipe_transfer*
+sp_mpeg12_get_transfer(struct pipe_video_context *vpipe,
+                       struct pipe_resource *resource,
+                       unsigned level,
+                       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, level, 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,
+                                unsigned level,
+                                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, level, 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);
+
+   flush_buffer(ctx);
+
+   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);
+
+   if (ctx->decode_target != dt || ctx->mc_buffer == NULL) {
+      rotate_buffer(ctx);
+
+      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);
+
+   memset(&rast, 0, sizeof rast);
+   rast.flatshade = 1;
+   rast.flatshade_first = 0;
+   rast.light_twoside = 0;
+   rast.front_ccw = 1;
+   rast.cull_face = PIPE_FACE_NONE;
+   rast.fill_back = PIPE_POLYGON_MODE_FILL;
+   rast.fill_front = PIPE_POLYGON_MODE_FILL;
+   rast.offset_point = 0;
+   rast.offset_line = 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_per_vertex = 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);
+
+   memset(&blend, 0, sizeof blend);
+
+   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);
+
+   memset(&dsa, 0, sizeof dsa);
+   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,
+                 bool pot_buffers,
+                 enum pipe_format decode_format)
+{
+   unsigned buffer_width, buffer_height;
+   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;
+
+   /* TODO: Non-pot buffers untested, probably doesn't work without changes to texcoord generation, vert shader, etc */
+   assert(pot_buffers);
+
+   buffer_width = pot_buffers ? util_next_power_of_two(width) : width; 
+   buffer_height = pot_buffers ? util_next_power_of_two(height) : height; 
+
+   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.create_surface = sp_mpeg12_create_surface;
+   ctx->base.decode_macroblocks = sp_mpeg12_decode_macroblocks;
+   ctx->base.render_picture = sp_mpeg12_render_picture;
+   ctx->base.clear_render_target = sp_mpeg12_clear_render_target;
+   ctx->base.resource_copy_region = sp_mpeg12_resource_copy_region;
+   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,
+                                   buffer_width, buffer_height, chroma_format,
+                                   bufmode)) {
+      ctx->pipe->destroy(ctx->pipe);
+      FREE(ctx);
+      return NULL;
+   }
+
+   ctx->buffer_map = util_new_keymap(sizeof(unsigned), -1, delete_buffer);
+   if (!ctx->buffer_map) {
+      vl_mpeg12_mc_renderer_cleanup(&ctx->mc_renderer);
+      ctx->pipe->destroy(ctx->pipe);
+      FREE(ctx);
+      return NULL;
+   }
+
+   if (!vl_compositor_init(&ctx->compositor, ctx->pipe)) {
+      util_delete_keymap(ctx->buffer_map, ctx);
+      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);
+      util_delete_keymap(ctx->buffer_map, ctx);
+      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 */
+   return sp_video_create_ex(pipe, profile,
+                             chroma_format,
+                             width, height,
+                             VL_MPEG12_MC_RENDERER_BUFFER_PICTURE,
+                             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,
+                   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,
+                                 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 (file)
index 0000000..9b60bad
--- /dev/null
@@ -0,0 +1,70 @@
+/**************************************************************************
+ *
+ * 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 keymap *buffer_map;
+   struct vl_mpeg12_mc_buffer *mc_buffer;
+   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,
+                   bool pot_buffers,
+                   enum pipe_format decode_format);
+
+#endif /* SP_VIDEO_CONTEXT_H */
index 81da4b864487713577ea7a275cdd393cf15717c9..8cf738fa2c081bc76068c9696a42e224eaa6508c 100644 (file)
@@ -512,6 +512,32 @@ 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
  */
@@ -526,6 +552,7 @@ struct pipe_query_data_timestamp_disjoint
    boolean  disjoint;
 };
 
+
 #ifdef __cplusplus
 }
 #endif
index c8904d4f16b2a629264c43fe2a776c7dda697646..e2cc32222de0fb5b6a596afb01a10100c418f8d1 100644 (file)
@@ -196,19 +196,37 @@ 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,
+
    /* some stencil samplers formats */
-   PIPE_FORMAT_X24S8_USCALED           = 136,
-   PIPE_FORMAT_S8X24_USCALED           = 137,
-   PIPE_FORMAT_X32_S8X24_USCALED       = 138,
+   PIPE_FORMAT_X24S8_USCALED           = 143,
+   PIPE_FORMAT_S8X24_USCALED           = 144,
+   PIPE_FORMAT_X32_S8X24_USCALED       = 145,
 
-   PIPE_FORMAT_B2G3R3_UNORM            = 139,
-   PIPE_FORMAT_L16A16_UNORM            = 140,
-   PIPE_FORMAT_A16_UNORM               = 141,
-   PIPE_FORMAT_I16_UNORM               = 142,
+   PIPE_FORMAT_B2G3R3_UNORM            = 146,
+   PIPE_FORMAT_L16A16_UNORM            = 147,
+   PIPE_FORMAT_A16_UNORM               = 148,
+   PIPE_FORMAT_I16_UNORM               = 149,
 
    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
 }
index 850eb84a3c8f59728908ad076bc7fc7d988fe9e6..2a6acecb7264a90b8a093b2c1ac56ae7cb9c2718 100644 (file)
@@ -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 (file)
index 0000000..73f03d5
--- /dev/null
@@ -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.
+ *
+ **************************************************************************/
+
+#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);
+
+   struct pipe_surface *(*create_surface)(struct pipe_video_context *vpipe,
+                                          struct pipe_resource *resource,
+                                          const struct pipe_surface *templat);
+
+   /**
+    * 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 (*clear_render_target)(struct pipe_video_context *vpipe,
+                               struct pipe_surface *dst,
+                               unsigned dstx, unsigned dsty,
+                               const float *rgba,
+                               unsigned width, unsigned height);
+
+   void (*resource_copy_region)(struct pipe_video_context *vpipe,
+                                struct pipe_resource *dst,
+                                unsigned dstx, unsigned dsty, unsigned dstz,
+                                struct pipe_resource *src,
+                                unsigned srcx, unsigned srcy, unsigned srcz,
+                                unsigned width, unsigned height);
+
+   struct pipe_transfer *(*get_transfer)(struct pipe_video_context *vpipe,
+                                         struct pipe_resource *resource,
+                                         unsigned level,
+                                         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,
+                                 unsigned level,
+                                 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 (file)
index 0000000..1cb555b
--- /dev/null
@@ -0,0 +1,134 @@
+/**************************************************************************
+ *
+ * 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];
+   bool mvfs[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/va/Makefile b/src/gallium/state_trackers/va/Makefile
new file mode 100644 (file)
index 0000000..dd303eb
--- /dev/null
@@ -0,0 +1,28 @@
+TOP = ../../../..
+include $(TOP)/configs/current
+
+LIBNAME = vatracker
+
+VA_MAJOR = 0
+VA_MINOR = 3
+LIBRARY_DEFINES = -DVER_MAJOR=$(VA_MAJOR) -DVER_MINOR=$(VA_MINOR) $(STATE_TRACKER_DEFINES)
+
+LIBRARY_INCLUDES = \
+       $(shell pkg-config --cflags-only-I va) \
+       -I$(TOP)/src/gallium/winsys/g3dvl
+
+C_SOURCES = htab.c \
+           ftab.c \
+           va_context.c \
+           va_image.c \
+           va_subpicture.c \
+           va_buffer.c \
+           va_config.c \
+            va_picture.c \
+            va_surface.c \
+           va_display.c
+           
+
+
+include ../../Makefile.template
+
diff --git a/src/gallium/state_trackers/va/ftab.c b/src/gallium/state_trackers/va/ftab.c
new file mode 100644 (file)
index 0000000..999287e
--- /dev/null
@@ -0,0 +1,136 @@
+/**************************************************************************
+ *
+ * Copyright 2010 Thomas Balling Sørensen & Orasanu Lucian.
+ * 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 <va/va.h>
+#include <va/va_backend.h>
+#include "va_private.h"
+
+struct VADriverVTable vlVaGetVtable();
+
+static struct VADriverVTable vtable =
+{
+       &vlVaTerminate, /* VAStatus (*vaTerminate) ( VADriverContextP ctx ); */
+       &vlVaQueryConfigProfiles, /* VAStatus (*vaQueryConfigProfiles) ( VADriverContextP ctx, VAProfile *profile_list,int *num_profiles); */
+       &vlVaQueryConfigEntrypoints, /* VAStatus (*vaQueryConfigEntrypoints) ( VADriverContextP ctx,    VAProfile profile, VAEntrypoint  *entrypoint_list, int *num_entrypoints ); */
+       &vlVaGetConfigAttributes, /* VAStatus (*vaGetConfigAttributes) ( VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoint, VAConfigAttrib *attrib_list, int num_attribs ); */
+       &vlVaCreateConfig, /* VAStatus (*vaCreateConfig) ( VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoint,    VAConfigAttrib *attrib_list, int num_attribs, VAConfigID *config_id); */
+       &vlVaDestroyConfig, /* VAStatus (*vaDestroyConfig) ( VADriverContextP ctx, VAConfigID config_id); */
+       &vlVaQueryConfigAttributes, /* VAStatus (*vaQueryConfigAttributes) ( VADriverContextP ctx, VAConfigID config_id, VAProfile *profile, VAEntrypoint *entrypoint, VAConfigAttrib *attrib_list, int *num_attribs); */
+       &vlVaCreateSurfaces, /* VAStatus (*vaCreateSurfaces) ( VADriverContextP ctx,int width,int height,int format,int num_surfaces,VASurfaceID *surfaces); */
+       &vlVaDestroySurfaces, /* VAStatus (*vaDestroySurfaces) ( VADriverContextP ctx, VASurfaceID *surface_list, int num_surfaces ); */
+       &vlVaCreateContext, /* VAStatus (*vaCreateContext) (VADriverContextP ctx,VAConfigID config_id,int picture_width,int picture_height,int flag,VASurfaceID *render_targets,int num_render_targets,VAContextID *context); */
+       &vlVaDestroyContext, /* VAStatus (*vaDestroyContext) (VADriverContextP ctx,VAContextID context); */
+       &vlVaCreateBuffer, /* VAStatus (*vaCreateBuffer) (VADriverContextP ctx,VAContextID context,VABufferType type,unsigned int size,unsigned int num_elements,void *data,VABufferID *buf_id); */
+       &vlVaBufferSetNumElements, /* VAStatus (*vaBufferSetNumElements) (VADriverContextP ctx,VABufferID buf_id,unsigned int num_elements); */
+       &vlVaMapBuffer, /* VAStatus (*vaMapBuffer) (VADriverContextP ctx,VABufferID buf_id,void **pbuf); */
+       &vlVaUnmapBuffer, /* VAStatus (*vaUnmapBuffer) (VADriverContextP ctx,VABufferID buf_id); */
+       &vlVaDestroyBuffer, /* VAStatus (*vaDestroyBuffer) (VADriverContextP ctx,VABufferID buffer_id); */
+       &vlVaBeginPicture, /* VAStatus (*vaBeginPicture) (VADriverContextP ctx,VAContextID context,VASurfaceID render_target); */
+       &vlVaRenderPicture, /* VAStatus (*vaRenderPicture) (VADriverContextP ctx,VAContextID context,VABufferID *buffers,int num_buffers); */
+       &vlVaEndPicture, /* VAStatus (*vaEndPicture) (VADriverContextP ctx,VAContextID context); */
+       &vlVaSyncSurface, /* VAStatus (*vaSyncSurface) (VADriverContextP ctx,VASurfaceID render_target); */
+       &vlVaQuerySurfaceStatus, /* VAStatus (*vaQuerySurfaceStatus) (VADriverContextP ctx,VASurfaceID render_target,VASurfaceStatus *status); */
+       &vlVaPutSurface, /* VAStatus (*vaPutSurface) (
+               VADriverContextP ctx,
+               VASurfaceID surface,
+               void* draw,
+               short srcx,
+               short srcy,
+               unsigned short srcw,
+               unsigned short srch,
+               short destx,
+               short desty,
+               unsigned short destw,
+               unsigned short desth,
+               VARectangle *cliprects,
+               unsigned int number_cliprects,
+               unsigned int flags); */
+       &vlVaQueryImageFormats, /* VAStatus (*vaQueryImageFormats) ( VADriverContextP ctx, VAImageFormat *format_list,int *num_formats); */
+       &vlVaCreateImage, /* VAStatus (*vaCreateImage) (VADriverContextP ctx,VAImageFormat *format,int width,int height,VAImage *image); */
+       &vlVaDeriveImage, /* VAStatus (*vaDeriveImage) (VADriverContextP ctx,VASurfaceID surface,VAImage *image); */
+       &vlVaDestroyImage, /* VAStatus (*vaDestroyImage) (VADriverContextP ctx,VAImageID image); */
+       &vlVaSetImagePalette, /* VAStatus (*vaSetImagePalette) (VADriverContextP ctx,VAImageID image, unsigned char *palette); */
+       &vlVaGetImage, /* VAStatus (*vaGetImage) (VADriverContextP ctx,VASurfaceID surface,int x,int y,unsigned int width,unsigned int height,VAImageID image); */
+       &vlVaPutImage, /* VAStatus (*vaPutImage) (
+               VADriverContextP ctx,
+               VASurfaceID surface,
+               VAImageID image,
+               int src_x,
+               int src_y,
+               unsigned int src_width,
+               unsigned int src_height,
+               int dest_x,
+               int dest_y,
+               unsigned int dest_width,
+               unsigned int dest_height
+       ); */
+       &vlVaQuerySubpictureFormats,    /* VAStatus (*vaQuerySubpictureFormats) (VADriverContextP ctx,VAImageFormat *format_list,unsigned int *flags,unsigned int *num_formats); */
+       &vlVaCreateSubpicture, /* VAStatus (*vaCreateSubpicture) (VADriverContextP ctx,VAImageID image,VASubpictureID *subpicture); */
+       &vlVaDestroySubpicture, /* VAStatus (*vaDestroySubpicture) (VADriverContextP ctx,VASubpictureID subpicture); */
+       &vlVaSubpictureImage, /* VAStatus (*vaSetSubpictureImage) (VADriverContextP ctx,VASubpictureID subpicture,VAImageID image); */
+       &vlVaSetSubpictureChromakey, /* VAStatus (*vaSetSubpictureChromakey) (VADriverContextP ctx,VASubpictureID subpicture,unsigned int chromakey_min,unsigned int chromakey_max,unsigned int chromakey_mask); */
+       &vlVaSetSubpictureGlobalAlpha, /* VAStatus (*vaSetSubpictureGlobalAlpha) (VADriverContextP ctx,VASubpictureID subpicture,float global_alpha); */
+       &vlVaAssociateSubpicture, /* VAStatus (*vaAssociateSubpicture) (
+               VADriverContextP ctx,
+               VASubpictureID subpicture,
+               VASurfaceID *target_surfaces,
+               int num_surfaces,
+               short src_x,
+               short src_y,
+               unsigned short src_width,
+               unsigned short src_height,
+               short dest_x,
+               short dest_y,
+               unsigned short dest_width,
+               unsigned short dest_height,
+               unsigned int flags); */
+       &vlVaDeassociateSubpicture, /* VAStatus (*vaDeassociateSubpicture) (VADriverContextP ctx,VASubpictureID subpicture,VASurfaceID *target_surfaces,int num_surfaces); */
+       &vlVaQueryDisplayAttributes, /* VAStatus (*vaQueryDisplayAttributes) (VADriverContextP ctx,VADisplayAttribute *attr_list,int *num_attributes); */
+       &vlVaGetDisplayAttributes, /* VAStatus (*vaGetDisplayAttributes) (VADriverContextP ctx,VADisplayAttribute *attr_list,int num_attributes); */
+       &vlVaSetDisplayAttributes, /* VAStatus (*vaSetDisplayAttributes) (VADriverContextP ctx,VADisplayAttribute *attr_list,int num_attributes); */
+       &vlVaBufferInfo, /* VAStatus (*vaBufferInfo) (VADriverContextP ctx,VAContextID context,VABufferID buf_id,VABufferType *type,unsigned int *size,unsigned int *num_elements); */
+       &vlVaLockSurface, /* VAStatus (*vaLockSurface) (
+               VADriverContextP ctx,
+                VASurfaceID surface,
+                unsigned int *fourcc,
+                unsigned int *luma_stride,
+                unsigned int *chroma_u_stride,
+                unsigned int *chroma_v_stride,
+                unsigned int *luma_offset,
+                unsigned int *chroma_u_offset,
+                unsigned int *chroma_v_offset,
+                unsigned int *buffer_name,
+                void **buffer); */
+       &vlVaUnlockSurface, /* VAStatus (*vaUnlockSurface) (VADriverContextP ctx,VASurfaceID surface); */
+       NULL /* struct VADriverVTableGLX *glx; "Optional" */
+};
+
+struct VADriverVTable vlVaGetVtable()
+{
+       return vtable;
+}
diff --git a/src/gallium/state_trackers/va/htab.c b/src/gallium/state_trackers/va/htab.c
new file mode 100644 (file)
index 0000000..2187507
--- /dev/null
@@ -0,0 +1,99 @@
+/**************************************************************************
+ *
+ * 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 "va_private.h"
+
+boolean vlCreateHTAB(void);
+void vlDestroyHTAB(void);
+vlHandle vlAddDataHTAB(void *data);
+void* vlGetDataHTAB(vlHandle handle);
+
+#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/va/va_buffer.c b/src/gallium/state_trackers/va/va_buffer.c
new file mode 100644 (file)
index 0000000..7608a42
--- /dev/null
@@ -0,0 +1,96 @@
+/**************************************************************************
+ *
+ * Copyright 2010 Thomas Balling Sørensen & Orasanu Lucian.
+ * 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 <va/va.h>
+#include <va/va_backend.h>
+#include "va_private.h"
+
+
+VAStatus vlVaCreateBuffer(             VADriverContextP ctx,
+                                VAContextID context,
+                                VABufferType type,
+                                unsigned int size,
+                                unsigned int num_elements,
+                                void *data,
+                                VABufferID *buf_id)
+{
+       if (!ctx)
+               return VA_STATUS_ERROR_INVALID_CONTEXT;
+
+       return VA_STATUS_ERROR_UNIMPLEMENTED;
+}
+
+VAStatus vlVaBufferSetNumElements(     VADriverContextP ctx,
+                                    VABufferID buf_id,
+                                    unsigned int num_elements)
+{
+       if (!ctx)
+               return VA_STATUS_ERROR_INVALID_CONTEXT;
+
+       return VA_STATUS_ERROR_UNIMPLEMENTED;
+}
+
+VAStatus vlVaMapBuffer(                        VADriverContextP ctx,
+                                VABufferID buf_id,
+                                void **pbuff)
+{
+       if (!ctx)
+               return VA_STATUS_ERROR_INVALID_CONTEXT;
+
+       return VA_STATUS_ERROR_UNIMPLEMENTED;
+}
+
+VAStatus vlVaUnmapBuffer(              VADriverContextP ctx,
+                                VABufferID buf_id)
+{
+       if (!ctx)
+               return VA_STATUS_ERROR_INVALID_CONTEXT;
+
+       return VA_STATUS_ERROR_UNIMPLEMENTED;
+}
+
+VAStatus vlVaDestroyBuffer(            VADriverContextP ctx,
+                                    VABufferID buffer_id)
+{
+       if (!ctx)
+               return VA_STATUS_ERROR_INVALID_CONTEXT;
+
+       return VA_STATUS_ERROR_UNIMPLEMENTED;
+}
+
+VAStatus vlVaBufferInfo(               VADriverContextP ctx,
+                                VAContextID context,
+                                VABufferID buf_id,
+                                VABufferType *type,
+                                unsigned int *size,
+                                unsigned int *num_elements)
+{
+       if (!ctx)
+               return VA_STATUS_ERROR_INVALID_CONTEXT;
+
+       return VA_STATUS_ERROR_UNIMPLEMENTED;
+}
diff --git a/src/gallium/state_trackers/va/va_config.c b/src/gallium/state_trackers/va/va_config.c
new file mode 100644 (file)
index 0000000..1589abf
--- /dev/null
@@ -0,0 +1,131 @@
+/**************************************************************************
+ *
+ * Copyright 2010 Thomas Balling Sørensen & Orasanu Lucian.
+ * 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 <va/va.h>
+#include <va/va_backend.h>
+#include <util/u_debug.h>
+#include "va_private.h"
+
+VAStatus vlVaQueryConfigProfiles(       VADriverContextP ctx,
+                                   VAProfile *profile_list,
+                                   int *num_profiles)
+{
+       if (!ctx)
+               return VA_STATUS_ERROR_INVALID_CONTEXT;
+
+       int i = 0;
+
+    profile_list[i++] = VAProfileMPEG2Simple;
+       *num_profiles = i;
+
+       return VA_STATUS_SUCCESS;
+}
+
+
+VAStatus vlVaQueryConfigEntrypoints(       VADriverContextP ctx,
+                                      VAProfile profile,
+                                      VAEntrypoint *entrypoint_list,
+                                      int *num_entrypoints)
+{
+       if (!ctx)
+               return VA_STATUS_ERROR_INVALID_CONTEXT;
+               
+       VAStatus vaStatus = VA_STATUS_SUCCESS;
+
+    switch (profile) {
+    case VAProfileMPEG2Simple:
+    case VAProfileMPEG2Main:
+               VA_INFO("Using profile %08x\n",profile);
+        *num_entrypoints = 1;
+        entrypoint_list[0] = VAEntrypointMoComp;
+        break;
+
+    case VAProfileH264Baseline:
+    case VAProfileH264Main:
+    case VAProfileH264High:
+        vaStatus = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
+        *num_entrypoints = 0;
+        break;
+
+    default:
+               VA_ERROR("Unsupported profile %08x\n",profile);
+        vaStatus = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
+        *num_entrypoints = 0;
+        break;
+    }
+
+    return vaStatus;
+}
+
+
+VAStatus vlVaGetConfigAttributes(       VADriverContextP ctx,
+                                        VAProfile profile,
+                                        VAEntrypoint entrypoint,
+                                        VAConfigAttrib *attrib_list,
+                                        int num_attribs)
+{
+       if (!ctx)
+               return VA_STATUS_ERROR_INVALID_CONTEXT;
+
+       return VA_STATUS_ERROR_UNIMPLEMENTED;
+}
+
+VAStatus vlVaCreateConfig(       VADriverContextP ctx,
+                                 VAProfile profile,
+                                 VAEntrypoint entrypoint,
+                                 VAConfigAttrib *attrib_list,
+                                 int num_attribs,
+                                 VAConfigID *config_id)
+{
+       if (!ctx)
+               return VA_STATUS_ERROR_INVALID_CONTEXT;
+
+       return VA_STATUS_ERROR_UNIMPLEMENTED;
+}
+
+VAStatus vlVaDestroyConfig(       VADriverContextP ctx,
+                                  VAConfigID config_id)
+{
+       if (!ctx)
+               return VA_STATUS_ERROR_INVALID_CONTEXT;
+
+       return VA_STATUS_ERROR_UNIMPLEMENTED;
+}
+
+VAStatus vlVaQueryConfigAttributes(       VADriverContextP ctx,
+        VAConfigID config_id,
+        VAProfile *profile,
+        VAEntrypoint *entrypoint,
+        VAConfigAttrib *attrib_list,
+        int *num_attribs)
+{
+       if (!ctx)
+               return VA_STATUS_ERROR_INVALID_CONTEXT;
+
+       return VA_STATUS_ERROR_UNIMPLEMENTED;
+}
+
diff --git a/src/gallium/state_trackers/va/va_context.c b/src/gallium/state_trackers/va/va_context.c
new file mode 100644 (file)
index 0000000..cdb20cc
--- /dev/null
@@ -0,0 +1,107 @@
+/**************************************************************************
+ *
+ * Copyright 2010 Thomas Balling Sørensen & Orasanu Lucian.
+ * 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 <pipe/p_compiler.h>
+#include <pipe/p_video_context.h>
+#include <pipe/p_screen.h>
+#include <vl_winsys.h>
+#include <util/u_debug.h>
+#include <util/u_memory.h>
+#include <va/va.h>
+#include <va/va_backend.h>
+#include "va_private.h"
+
+//struct VADriverVTable vlVaGetVtable();
+
+PUBLIC
+VAStatus __vaDriverInit_0_31 (VADriverContextP ctx)
+{
+       vlVaDriverContextPriv *driver_context = NULL;
+       
+       if (!ctx)
+               return VA_STATUS_ERROR_INVALID_CONTEXT;
+               
+               
+       /* Create private driver context */
+       driver_context = CALLOC(1,sizeof(vlVaDriverContextPriv));
+       if (!driver_context)
+               return VA_STATUS_ERROR_ALLOCATION_FAILED;
+               
+    driver_context->vscreen = vl_screen_create(ctx->native_dpy, ctx->x11_screen);
+       if (!driver_context->vscreen)
+       {
+               FREE(driver_context);
+               return VA_STATUS_ERROR_ALLOCATION_FAILED;
+       }
+               
+       ctx->str_vendor = "mesa gallium vaapi";
+       ctx->vtable = vlVaGetVtable();
+       ctx->max_attributes = 1;
+       ctx->max_display_attributes = 1;
+       ctx->max_entrypoints = VA_MAX_ENTRYPOINTS;
+       ctx->max_image_formats = VA_MAX_IMAGE_FORMATS_SUPPORTED;
+       ctx->max_profiles = 1;
+       ctx->max_subpic_formats = VA_MAX_SUBPIC_FORMATS_SUPPORTED;
+       ctx->version_major = 3;
+       ctx->version_minor = 1;
+       ctx->pDriverData = (void *)driver_context;
+
+       VA_INFO("vl_screen_pointer %p\n",ctx->native_dpy);
+
+       return VA_STATUS_SUCCESS;
+}
+
+VAStatus vlVaCreateContext(       VADriverContextP ctx,
+                                  VAConfigID config_id,
+                                  int picture_width,
+                                  int picture_height,
+                                  int flag,
+                                  VASurfaceID *render_targets,
+                                  int num_render_targets,
+                                  VAContextID *conext)
+{
+       if (!ctx)
+               return VA_STATUS_ERROR_INVALID_CONTEXT;
+
+       return VA_STATUS_ERROR_UNIMPLEMENTED;
+}
+
+VAStatus vlVaDestroyContext(       VADriverContextP ctx,
+                                   VAContextID context)
+{
+       if (!ctx)
+               return VA_STATUS_ERROR_INVALID_CONTEXT;
+
+       return VA_STATUS_ERROR_UNIMPLEMENTED;
+}
+
+VAStatus vlVaTerminate(       VADriverContextP ctx)
+{
+       if (!ctx)
+               return VA_STATUS_ERROR_INVALID_CONTEXT;
+       return VA_STATUS_ERROR_UNIMPLEMENTED;
+}
diff --git a/src/gallium/state_trackers/va/va_display.c b/src/gallium/state_trackers/va/va_display.c
new file mode 100644 (file)
index 0000000..1aaaf7c
--- /dev/null
@@ -0,0 +1,70 @@
+/**************************************************************************
+ *
+ * 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 <va/va.h>
+ #include <va/va_backend.h>
+ #include "va_private.h"
+
+
+VAStatus  vlVaQueryDisplayAttributes(          VADriverContextP ctx,
+                                                               VADisplayAttribute *attr_list,
+                                                               int *num_attributes)
+{
+        if (!ctx)
+                return VA_STATUS_ERROR_INVALID_CONTEXT;
+
+               if (!(attr_list && num_attributes))
+                       return VA_STATUS_ERROR_UNKNOWN;
+
+        *num_attributes = 0;
+
+               return VA_STATUS_SUCCESS;
+}
+
+VAStatus  vlVaGetDisplayAttributes(            VADriverContextP ctx,
+                                                               VADisplayAttribute *attr_list,
+                                                               int num_attributes)
+{
+        if (!ctx)
+                return VA_STATUS_ERROR_INVALID_CONTEXT;
+
+
+        return VA_STATUS_ERROR_UNIMPLEMENTED;
+}
+
+VAStatus  vlVaSetDisplayAttributes(            VADriverContextP ctx,
+                                                               VADisplayAttribute *attr_list,
+                                                               int num_attributes)
+{
+        if (!ctx)
+                return VA_STATUS_ERROR_INVALID_CONTEXT;
+
+
+        return VA_STATUS_ERROR_UNIMPLEMENTED;
+}
+
+
diff --git a/src/gallium/state_trackers/va/va_image.c b/src/gallium/state_trackers/va/va_image.c
new file mode 100644 (file)
index 0000000..8d20bfa
--- /dev/null
@@ -0,0 +1,178 @@
+/**************************************************************************
+ *
+ * Copyright 2010 Thomas Balling Sørensen & Orasanu Lucian.
+ * 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_memory.h>
+#include <util/u_format.h>
+#include <util/u_debug.h>
+#include <pipe/p_format.h>
+#include <va/va.h>
+#include <va/va_backend.h>
+#include "va_private.h"
+
+typedef struct  {
+       enum pipe_format pipe_format;
+       VAImageFormat       va_format;
+} va_image_formats_supported_t;
+
+static const va_image_formats_supported_t va_image_formats_supported[VA_MAX_IMAGE_FORMATS_SUPPORTED] = 
+{
+       { PIPE_FORMAT_B8G8R8A8_UNORM,
+      { VA_FOURCC('B','G','R','A'), VA_LSB_FIRST, 32, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }},
+    { PIPE_FORMAT_R8G8B8A8_UNORM, 
+         { VA_FOURCC_RGBA, VA_LSB_FIRST, 32, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 }}
+};
+
+boolean vlCreateHTAB(void);
+void vlDestroyHTAB(void);
+vlHandle vlAddDataHTAB(void *data);
+void* vlGetDataHTAB(vlHandle handle);
+
+VAStatus
+vlVaQueryImageFormats (        VADriverContextP ctx,
+                            VAImageFormat *format_list,
+                            int *num_formats)
+{
+       if (!ctx)
+               return VA_STATUS_ERROR_INVALID_CONTEXT;
+
+       if (!(format_list && num_formats))
+               return VA_STATUS_ERROR_UNKNOWN;
+               
+       int n = 0;
+       
+       num_formats[0] = VA_MAX_IMAGE_FORMATS_SUPPORTED;
+       
+       /* Query supported formats */
+       for (n = 0; n < VA_MAX_IMAGE_FORMATS_SUPPORTED; n++)
+       {
+               format_list[n] = va_image_formats_supported[n].va_format;
+       }
+
+       return VA_STATUS_SUCCESS;
+}
+
+VAStatus vlVaCreateImage(      VADriverContextP ctx,
+                            VAImageFormat *format,
+                            int width,
+                            int height,
+                            VAImage *image)
+{
+       if (!ctx)
+               return VA_STATUS_ERROR_INVALID_CONTEXT;
+
+       if(!format)
+               return VA_STATUS_ERROR_UNKNOWN;
+               
+       if (!(width && height))
+               return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT;
+               
+       if (!vlCreateHTAB())
+               return VA_STATUS_ERROR_UNKNOWN; 
+               
+       switch (format->fourcc) {
+       case VA_FOURCC('B','G','R','A'):
+               VA_INFO("Creating BGRA image of size %dx%d\n",width,height);
+       break;
+       case VA_FOURCC_RGBA:
+               VA_INFO("Creating RGBA image of size %dx%d\n",width,height);
+       break;
+       default:
+               VA_ERROR("Couldn't create image of type %0x08\n",format->fourcc);
+               return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
+       break;
+       }
+               
+       VA_INFO("Image %p created successfully\n",format);
+       
+       return VA_STATUS_SUCCESS;
+}
+
+VAStatus vlVaDeriveImage(      VADriverContextP ctx,
+                            VASurfaceID surface,
+                            VAImage *image)
+{
+       if (!ctx)
+               return VA_STATUS_ERROR_INVALID_CONTEXT;
+
+
+       return VA_STATUS_ERROR_UNIMPLEMENTED;
+}
+
+VAStatus vlVaDestroyImage(     VADriverContextP ctx,
+                            VAImageID image)
+{
+       if (!ctx)
+               return VA_STATUS_ERROR_INVALID_CONTEXT;
+
+
+       return VA_STATUS_ERROR_UNIMPLEMENTED;
+}
+
+VAStatus vlVaSetImagePalette(  VADriverContextP ctx,
+                            VAImageID image,
+                            unsigned char *palette)
+{
+       if (!ctx)
+               return VA_STATUS_ERROR_INVALID_CONTEXT;
+
+
+       return VA_STATUS_ERROR_UNIMPLEMENTED;
+}
+
+VAStatus vlVaGetImage(         VADriverContextP ctx,
+                            VASurfaceID surface,
+                            int x,
+                            int y,
+                            unsigned int width,
+                            unsigned int height,
+                            VAImageID image)
+{
+       if (!ctx)
+               return VA_STATUS_ERROR_INVALID_CONTEXT;
+
+
+       return VA_STATUS_ERROR_UNIMPLEMENTED;
+}
+
+VAStatus vlVaPutImage(         VADriverContextP ctx,
+                            VASurfaceID surface,
+                            VAImageID image,
+                            int src_x,
+                            int src_y,
+                            unsigned int src_width,
+                            unsigned int src_height,
+                            int dest_x,
+                            int dest_y,
+                            unsigned int dest_width,
+                            unsigned int dest_height)
+{
+       if (!ctx)
+               return VA_STATUS_ERROR_INVALID_CONTEXT;
+
+
+       return VA_STATUS_ERROR_UNIMPLEMENTED;
+}
diff --git a/src/gallium/state_trackers/va/va_picture.c b/src/gallium/state_trackers/va/va_picture.c
new file mode 100644 (file)
index 0000000..3603dfb
--- /dev/null
@@ -0,0 +1,61 @@
+/**************************************************************************
+ *
+ * Copyright 2010 Thomas Balling Sørensen & Orasanu Lucian.
+ * 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 <va/va.h>
+#include <va/va_backend.h>
+#include <util/u_debug.h>
+#include "va_private.h"
+
+VAStatus vlVaBeginPicture(       VADriverContextP ctx,
+                                 VAContextID context,
+                                 VASurfaceID render_target)
+{
+       if (!ctx)
+               return VA_STATUS_ERROR_INVALID_CONTEXT;
+
+       return VA_STATUS_ERROR_UNIMPLEMENTED;
+}
+
+VAStatus vlVaRenderPicture(       VADriverContextP ctx,
+                                  VAContextID context,
+                                  VABufferID *buffers,
+                                  int num_buffers)
+{
+       if (!ctx)
+               return VA_STATUS_ERROR_INVALID_CONTEXT;
+
+       return VA_STATUS_ERROR_UNIMPLEMENTED;
+}
+
+VAStatus vlVaEndPicture(       VADriverContextP ctx,
+                               VAContextID context)
+{
+       if (!ctx)
+               return VA_STATUS_ERROR_INVALID_CONTEXT;
+
+       return VA_STATUS_ERROR_UNIMPLEMENTED;
+}
diff --git a/src/gallium/state_trackers/va/va_private.h b/src/gallium/state_trackers/va/va_private.h
new file mode 100644 (file)
index 0000000..625c6cd
--- /dev/null
@@ -0,0 +1,159 @@
+/**************************************************************************
+ *
+ * Copyright 2010 Thomas Balling Sørensen & Orasanu Lucian.
+ * 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 VA_PRIVATE_H
+#define VA_PRIVATE_H
+
+#include <va/va.h>
+#include <va/va_backend.h>
+#include <pipe/p_format.h>
+#include <pipe/p_state.h>
+
+#define VA_DEBUG(_str,...) debug_printf("[Gallium VA backend]: " _str,__VA_ARGS__)
+#define VA_INFO(_str,...) VA_DEBUG("INFO: " _str,__VA_ARGS__)
+#define VA_WARNING(_str,...) VA_DEBUG("WARNING: " _str,__VA_ARGS__)
+#define VA_ERROR(_str,...) VA_DEBUG("ERROR: " _str,__VA_ARGS__)
+
+#define VA_MAX_IMAGE_FORMATS_SUPPORTED 2
+#define VA_MAX_SUBPIC_FORMATS_SUPPORTED 2
+#define VA_MAX_ENTRYPOINTS 1
+
+#define VL_HANDLES
+
+typedef unsigned int vlHandle;
+
+typedef struct {
+       struct vl_screen *vscreen;
+       struct pipe_surface *backbuffer;
+} vlVaDriverContextPriv;
+
+typedef struct {
+       unsigned int width;
+       unsigned int height;
+       enum pipe_video_chroma_format format;
+       VADriverContextP ctx;
+} vlVaSurfacePriv;
+
+// Public functions:
+VAStatus __vaDriverInit_0_31 (VADriverContextP ctx);
+
+// Private functions:
+struct VADriverVTable vlVaGetVtable();
+
+
+// Vtable functions:
+VAStatus vlVaTerminate (VADriverContextP ctx);
+VAStatus vlVaQueryConfigProfiles (VADriverContextP ctx, VAProfile *profile_list,int *num_profiles);
+VAStatus vlVaQueryConfigEntrypoints (VADriverContextP ctx, VAProfile profile, VAEntrypoint  *entrypoint_list, int *num_entrypoints);
+VAStatus vlVaGetConfigAttributes (VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoint, VAConfigAttrib *attrib_list, int num_attribs);
+VAStatus vlVaCreateConfig (VADriverContextP ctx, VAProfile profile, VAEntrypoint entrypoint, VAConfigAttrib *attrib_list, int num_attribs, VAConfigID *config_id);
+VAStatus vlVaDestroyConfig (VADriverContextP ctx, VAConfigID config_id);
+VAStatus vlVaQueryConfigAttributes (VADriverContextP ctx, VAConfigID config_id, VAProfile *profile, VAEntrypoint *entrypoint, VAConfigAttrib *attrib_list, int *num_attribs);
+VAStatus vlVaCreateSurfaces (VADriverContextP ctx,int width,int height,int format,int num_surfaces,VASurfaceID *surfaces);
+VAStatus vlVaDestroySurfaces (VADriverContextP ctx, VASurfaceID *surface_list, int num_surfaces);
+VAStatus vlVaCreateContext (VADriverContextP ctx,VAConfigID config_id,int picture_width,int picture_height,int flag,VASurfaceID *render_targets,int num_render_targets,VAContextID *context);
+VAStatus vlVaDestroyContext (VADriverContextP ctx,VAContextID context);
+VAStatus vlVaCreateBuffer (VADriverContextP ctx,VAContextID context,VABufferType type,unsigned int size,unsigned int num_elements,void *data,VABufferID *buf_id);
+VAStatus vlVaBufferSetNumElements (VADriverContextP ctx,VABufferID buf_id,unsigned int num_elements);
+VAStatus vlVaMapBuffer (VADriverContextP ctx,VABufferID buf_id,void **pbuf);
+VAStatus vlVaUnmapBuffer (VADriverContextP ctx,VABufferID buf_id);
+VAStatus vlVaDestroyBuffer (VADriverContextP ctx,VABufferID buffer_id);
+VAStatus vlVaBeginPicture (VADriverContextP ctx,VAContextID context,VASurfaceID render_target);
+VAStatus vlVaRenderPicture (VADriverContextP ctx,VAContextID context,VABufferID *buffers,int num_buffers);
+VAStatus vlVaEndPicture (VADriverContextP ctx,VAContextID context);
+VAStatus vlVaSyncSurface (VADriverContextP ctx,VASurfaceID render_target);
+VAStatus vlVaQuerySurfaceStatus (VADriverContextP ctx,VASurfaceID render_target,VASurfaceStatus *status);
+VAStatus vlVaPutSurface (VADriverContextP ctx,
+                         VASurfaceID surface,
+                         void* draw,
+                         short srcx,
+                         short srcy,
+                         unsigned short srcw,
+                         unsigned short srch,
+                         short destx,
+                         short desty,
+                         unsigned short destw,
+                         unsigned short desth,
+                         VARectangle *cliprects,
+                         unsigned int number_cliprects,
+                         unsigned int flags);
+VAStatus vlVaQueryImageFormats (VADriverContextP ctx,VAImageFormat *format_list,int *num_formats);
+VAStatus vlVaQuerySubpictureFormats(VADriverContextP ctx,VAImageFormat *format_list,unsigned int *flags,unsigned int *num_formats);
+VAStatus vlVaCreateImage(VADriverContextP ctx,VAImageFormat *format,int width,int height,VAImage *image);
+VAStatus vlVaDeriveImage(VADriverContextP ctx,VASurfaceID surface,VAImage *image);
+VAStatus vlVaDestroyImage(VADriverContextP ctx,VAImageID image);
+VAStatus vlVaSetImagePalette(VADriverContextP ctx,VAImageID image, unsigned char *palette);
+VAStatus vlVaGetImage(VADriverContextP ctx,VASurfaceID surface,int x,int y,unsigned int width,unsigned int height,VAImageID image);
+VAStatus vlVaPutImage(VADriverContextP ctx,
+                      VASurfaceID surface,
+                      VAImageID image,
+                      int src_x,
+                      int src_y,
+                      unsigned int src_width,
+                      unsigned int src_height,
+                      int dest_x,
+                      int dest_y,
+                      unsigned int dest_width,
+                      unsigned int dest_height);
+VAStatus vlVaQuerySubpictureFormats(VADriverContextP ctx,VAImageFormat *format_list,unsigned int *flags,unsigned int *num_formats);
+VAStatus vlVaCreateSubpicture(VADriverContextP ctx,VAImageID image,VASubpictureID *subpicture);
+VAStatus vlVaDestroySubpicture(VADriverContextP ctx,VASubpictureID subpicture);
+VAStatus vlVaSubpictureImage(VADriverContextP ctx,VASubpictureID subpicture,VAImageID image);
+VAStatus vlVaSetSubpictureChromakey(VADriverContextP ctx,VASubpictureID subpicture,unsigned int chromakey_min,unsigned int chromakey_max,unsigned int chromakey_mask);
+VAStatus vlVaSetSubpictureGlobalAlpha(VADriverContextP ctx,VASubpictureID subpicture,float global_alpha);
+VAStatus vlVaAssociateSubpicture(VADriverContextP ctx,
+                                 VASubpictureID subpicture,
+                                 VASurfaceID *target_surfaces,
+                                 int num_surfaces,
+                                 short src_x,
+                                 short src_y,
+                                 unsigned short src_width,
+                                 unsigned short src_height,
+                                 short dest_x,
+                                 short dest_y,
+                                 unsigned short dest_width,
+                                 unsigned short dest_height,
+                                 unsigned int flags);
+VAStatus vlVaDeassociateSubpicture(VADriverContextP ctx,VASubpictureID subpicture,VASurfaceID *target_surfaces,int num_surfaces);
+VAStatus vlVaQueryDisplayAttributes(VADriverContextP ctx,VADisplayAttribute *attr_list,int *num_attributes);
+VAStatus vlVaGetDisplayAttributes(VADriverContextP ctx,VADisplayAttribute *attr_list,int num_attributes);
+VAStatus vlVaSetDisplayAttributes(VADriverContextP ctx,VADisplayAttribute *attr_list,int num_attributes);
+VAStatus vlVaBufferInfo(VADriverContextP ctx,VAContextID context,VABufferID buf_id,VABufferType *type,unsigned int *size,unsigned int *num_elements);
+VAStatus vlVaLockSurface(VADriverContextP ctx,
+                         VASurfaceID surface,
+                         unsigned int *fourcc,
+                         unsigned int *luma_stride,
+                         unsigned int *chroma_u_stride,
+                         unsigned int *chroma_v_stride,
+                         unsigned int *luma_offset,
+                         unsigned int *chroma_u_offset,
+                         unsigned int *chroma_v_offset,
+                         unsigned int *buffer_name,
+                         void **buffer);
+VAStatus vlVaUnlockSurface(VADriverContextP ctx,VASurfaceID surface);
+
+#endif //VA_PRIVATE_H
diff --git a/src/gallium/state_trackers/va/va_subpicture.c b/src/gallium/state_trackers/va/va_subpicture.c
new file mode 100644 (file)
index 0000000..910e5bd
--- /dev/null
@@ -0,0 +1,157 @@
+/**************************************************************************
+ *
+ * Copyright 2010 Thomas Balling Sørensen & Orasanu Lucian.
+ * 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 <va/va.h>
+#include <va/va_backend.h>
+#include <pipe/p_format.h>
+#include "va_private.h"
+
+
+typedef struct  {
+       enum pipe_format        pipe_format;
+       VAImageFormat       va_format;
+    unsigned int        va_flags;
+} va_subpicture_formats_supported_t;
+
+static const va_subpicture_formats_supported_t va_subpicture_formats_supported[VA_MAX_SUBPIC_FORMATS_SUPPORTED + 1] = 
+{
+       { PIPE_FORMAT_B8G8R8A8_UNORM,
+      { VA_FOURCC('B','G','R','A'), VA_LSB_FIRST, 32, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 },
+      0 },
+    { PIPE_FORMAT_R8G8B8A8_UNORM, 
+         { VA_FOURCC_RGBA, VA_LSB_FIRST, 32, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 },
+      0 }
+};
+
+VAStatus
+vlVaQuerySubpictureFormats(            VADriverContextP ctx,
+                                VAImageFormat *format_list,
+                                unsigned int *flags,
+                                unsigned int *num_formats)
+{
+       if (!ctx)
+               return VA_STATUS_ERROR_INVALID_CONTEXT;
+               
+       if (!(format_list && flags && num_formats))
+               return VA_STATUS_ERROR_UNKNOWN;
+               
+       num_formats[0] = VA_MAX_SUBPIC_FORMATS_SUPPORTED;
+               
+       int n = 0;
+       /* Query supported formats */
+       for (n = 0; n < VA_MAX_SUBPIC_FORMATS_SUPPORTED ; n++)
+       {
+               const va_subpicture_formats_supported_t * const format_map = &va_subpicture_formats_supported[n];
+               flags[n] = format_map->va_flags;
+               format_list[n] = format_map->va_format;
+       }
+
+       return VA_STATUS_SUCCESS;
+}
+
+
+VAStatus vlVaCreateSubpicture(         VADriverContextP ctx,
+                                    VAImageID image,
+                                    VASubpictureID *subpicture)
+{
+       if (!ctx)
+               return VA_STATUS_ERROR_INVALID_CONTEXT;
+
+       return VA_STATUS_ERROR_UNIMPLEMENTED;
+}
+
+VAStatus vlVaDestroySubpicture(                VADriverContextP ctx,
+                                    VASubpictureID subpicture)
+{
+       if (!ctx)
+               return VA_STATUS_ERROR_INVALID_CONTEXT;
+
+       return VA_STATUS_ERROR_UNIMPLEMENTED;
+}
+
+VAStatus vlVaSubpictureImage(          VADriverContextP ctx,
+                                    VASubpictureID subpicture,
+                                    VAImageID image)
+{
+       if (!ctx)
+               return VA_STATUS_ERROR_INVALID_CONTEXT;
+
+       return VA_STATUS_ERROR_UNIMPLEMENTED;
+}
+
+VAStatus vlVaSetSubpictureChromakey(   VADriverContextP ctx,
+                                        VASubpictureID subpicture,
+                                        unsigned int chromakey_min,
+                                        unsigned int chromakey_max,
+                                        unsigned int chromakey_mask)
+{
+       if (!ctx)
+               return VA_STATUS_ERROR_INVALID_CONTEXT;
+
+       return VA_STATUS_ERROR_UNIMPLEMENTED;
+}
+
+VAStatus vlVaSetSubpictureGlobalAlpha( VADriverContextP ctx,
+                                        VASubpictureID subpicture,
+                                        float global_alpha)
+{
+       if (!ctx)
+               return VA_STATUS_ERROR_INVALID_CONTEXT;
+
+       return VA_STATUS_ERROR_UNIMPLEMENTED;
+}
+
+VAStatus vlVaAssociateSubpicture(      VADriverContextP ctx,
+                                    VASubpictureID subpicture,
+                                    VASurfaceID *target_surfaces,
+                                    int num_surfaces,
+                                    short src_x,
+                                    short src_y,
+                                    unsigned short src_width,
+                                    unsigned short src_height,
+                                    short dest_x,
+                                    short dest_y,
+                                    unsigned short dest_width,
+                                    unsigned short dest_height,
+                                    unsigned int flags)
+{
+       if (!ctx)
+               return VA_STATUS_ERROR_INVALID_CONTEXT;
+
+       return VA_STATUS_ERROR_UNIMPLEMENTED;
+}
+
+VAStatus vlVaDeassociateSubpicture(    VADriverContextP ctx,
+                                    VASubpictureID subpicture,
+                                    VASurfaceID *target_surfaces,
+                                    int num_surfaces)
+{
+       if (!ctx)
+               return VA_STATUS_ERROR_INVALID_CONTEXT;
+
+       return VA_STATUS_ERROR_UNIMPLEMENTED;
+}
diff --git a/src/gallium/state_trackers/va/va_surface.c b/src/gallium/state_trackers/va/va_surface.c
new file mode 100644 (file)
index 0000000..a86c806
--- /dev/null
@@ -0,0 +1,167 @@
+/**************************************************************************
+ *
+       * Copyright 2010 Thomas Balling Sørensen & Orasanu Lucian.
+ * 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 <va/va.h>
+#include <va/va_backend.h>
+#include <util/u_debug.h>
+#include <util/u_memory.h>
+#include "va_private.h"
+
+boolean vlCreateHTAB(void);
+void vlDestroyHTAB(void);
+vlHandle vlAddDataHTAB(void *data);
+void* vlGetDataHTAB(vlHandle handle);
+
+static enum pipe_video_chroma_format VaRTFormatToPipe(unsigned int va_type)
+{
+   switch (va_type) {
+      case VA_RT_FORMAT_YUV420:
+         return PIPE_VIDEO_CHROMA_FORMAT_420;
+      case VA_RT_FORMAT_YUV422:
+         return PIPE_VIDEO_CHROMA_FORMAT_422;
+      case VA_RT_FORMAT_YUV444:
+         return PIPE_VIDEO_CHROMA_FORMAT_444;
+      default:
+         assert(0);
+   }
+
+   return -1;
+}
+
+VAStatus vlVaCreateSurfaces(       VADriverContextP ctx,
+                                   int width,
+                                   int height,
+                                   int format,
+                                   int num_surfaces,
+                                   VASurfaceID *surfaces)
+{
+       if (!ctx)
+               return VA_STATUS_ERROR_INVALID_CONTEXT;
+
+    /* We only support one format */
+    if (VA_RT_FORMAT_YUV420 != format)
+        return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
+               
+       if (!(width && height))
+               return VA_STATUS_ERROR_INVALID_IMAGE_FORMAT;
+               
+       if (!vlCreateHTAB())
+               return VA_STATUS_ERROR_UNKNOWN; 
+               
+       vlVaSurfacePriv *va_surface = (vlVaSurfacePriv *)CALLOC(num_surfaces,sizeof(vlVaSurfacePriv));
+       if (!va_surface)
+               return VA_STATUS_ERROR_ALLOCATION_FAILED;
+               
+       int n = 0;
+       for (n = 0; n < num_surfaces; n++)
+       {
+               va_surface[n].width = width;
+               va_surface[n].height = height;
+               va_surface[n].format = VaRTFormatToPipe(format);
+               va_surface[n].ctx = ctx;
+               surfaces[n] = (VASurfaceID *)vlAddDataHTAB((void *)(va_surface + n));
+       }
+
+       return VA_STATUS_SUCCESS;
+}
+
+VAStatus vlVaDestroySurfaces(       VADriverContextP ctx,
+                                    VASurfaceID *surface_list,
+                                    int num_surfaces)
+{
+       if (!ctx)
+               return VA_STATUS_ERROR_INVALID_CONTEXT;
+
+       return VA_STATUS_ERROR_UNIMPLEMENTED;
+}
+
+VAStatus vlVaSyncSurface(       VADriverContextP ctx,
+                                VASurfaceID render_target)
+{
+       if (!ctx)
+               return VA_STATUS_ERROR_INVALID_CONTEXT;
+
+       return VA_STATUS_ERROR_UNIMPLEMENTED;
+}
+
+VAStatus vlVaQuerySurfaceStatus(       VADriverContextP ctx,
+                                       VASurfaceID render_target,
+                                       VASurfaceStatus *status)
+{
+       if (!ctx)
+               return VA_STATUS_ERROR_INVALID_CONTEXT;
+
+       return VA_STATUS_ERROR_UNIMPLEMENTED;
+}
+
+VAStatus vlVaPutSurface(       VADriverContextP ctx,
+                               VASurfaceID surface,
+                               void* draw,
+                               short srcx,
+                               short srcy,
+                               unsigned short srcw,
+                               unsigned short srch,
+                               short destx,
+                               short desty,
+                               unsigned short destw,
+                               unsigned short desth,
+                               VARectangle *cliprects,
+                               unsigned int number_cliprects,
+                               unsigned int flags)
+{
+       if (!ctx)
+               return VA_STATUS_ERROR_INVALID_CONTEXT;
+
+       return VA_STATUS_ERROR_UNIMPLEMENTED;
+}
+
+VAStatus vlVaLockSurface(      VADriverContextP ctx,
+                            VASurfaceID surface,
+                            unsigned int *fourcc,
+                            unsigned int *luma_stride,
+                            unsigned int *chroma_u_stride,
+                            unsigned int *chroma_v_stride,
+                            unsigned int *luma_offset,
+                            unsigned int *chroma_u_offset,
+                            unsigned int *chroma_v_offset,
+                            unsigned int *buffer_name,
+                            void **buffer)
+{
+       if (!ctx)
+               return VA_STATUS_ERROR_INVALID_CONTEXT;
+
+       return VA_STATUS_ERROR_UNIMPLEMENTED;
+}
+
+VAStatus vlVaUnlockSurface(    VADriverContextP ctx,
+                            VASurfaceID surface)
+{
+       if (!ctx)
+               return VA_STATUS_ERROR_INVALID_CONTEXT;
+
+       return VA_STATUS_ERROR_UNIMPLEMENTED;
+}
diff --git a/src/gallium/state_trackers/vdpau/Makefile b/src/gallium/state_trackers/vdpau/Makefile
new file mode 100644 (file)
index 0000000..0e68d4f
--- /dev/null
@@ -0,0 +1,29 @@
+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 \
+           preemption.c \
+           mixer.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 (file)
index 0000000..f1a9d9a
--- /dev/null
@@ -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 (file)
index 0000000..e69de29
diff --git a/src/gallium/state_trackers/vdpau/decode.c b/src/gallium/state_trackers/vdpau/decode.c
new file mode 100644 (file)
index 0000000..5d3674c
--- /dev/null
@@ -0,0 +1,309 @@
+/**************************************************************************
+ *
+ * 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 
+)
+{
+       enum pipe_video_profile p_profile = PIPE_VIDEO_PROFILE_UNKNOWN;
+       VdpStatus ret = VDP_STATUS_OK;
+       vlVdpDecoder *vldecoder = NULL;
+       
+       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->height = height;
+       vldecoder->width = width;
+       vldecoder->device = dev;
+       vldecoder->vctx = NULL;
+               
+       *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
+)
+{
+       debug_printf("[VDPAU] Destroying decoder\n");
+       vlVdpDecoder *vldecoder;
+       
+       vldecoder = (vlVdpDecoder *)vlGetDataHTAB(decoder);
+       if (!vldecoder)  {
+      return VDP_STATUS_INVALID_HANDLE;
+       }
+       
+       if (vldecoder->vctx)
+       {
+               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 *vctx;
+       
+       debug_printf("[VDPAU] Creating surface\n");
+               
+       if(!(vldecoder && vlsurf))
+               return VDP_STATUS_INVALID_POINTER;
+               
+       vctx = vldecoder->vctx->vpipe;
+               
+       memset(&tmplt, 0, sizeof(struct pipe_resource));
+       tmplt.target = PIPE_TEXTURE_2D;
+       tmplt.format = vctx->get_param(vctx,PIPE_CAP_DECODE_TARGET_PREFERRED_FORMAT);
+       tmplt.last_level = 0;
+
+       if (vctx->is_format_supported(vctx, 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(vctx->is_format_supported(vctx, 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 = vctx->screen->resource_create(vctx->screen, &tmplt);
+       
+       vlsurf->psurface = vctx->screen->get_tex_surface(vctx->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;
+       debug_printf("[VDPAU] Done creating surface\n");
+       
+       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;
+       
+       debug_printf("[VDPAU] Decoding MPEG2\n");
+
+       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);
+
+       vpipe = vldecoder->vctx->vpipe;
+
+       if (vlVdpMPEG2BitstreamToMacroblock(vpipe->screen, bitstream_buffers, bitstream_buffer_count,
+                     &num_macroblocks, &pipe_macroblocks))
+                                        {
+                                                debug_printf("[VDPAU] Error in frame-header. Skipping.\n");
+                                                
+                                                ret = VDP_STATUS_OK;
+                                                goto skip_frame;
+                                        }
+               
+       vpipe->set_decode_target(vpipe,t_surf);
+       vpipe->decode_macroblocks(vpipe, p_surf, f_surf, num_macroblocks, (struct pipe_macroblock *)pipe_macroblocks, NULL);
+       
+       skip_frame:
+       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;
+               
+       /* Test doesn't make sence */
+       /*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->chroma_format, vldecoder->width, vldecoder->height);
+       if (!vldecoder->vctx)
+               return VDP_STATUS_RESOURCES;
+               
+    // 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;
+}
+
+VdpStatus 
+vlVdpGenerateCSCMatrix(
+       VdpProcamp *procamp, 
+       VdpColorStandard standard,
+       VdpCSCMatrix *csc_matrix)
+{
+       debug_printf("[VDPAU] Generating CSCMatrix\n");
+       if (!(csc_matrix && procamp))
+               return VDP_STATUS_INVALID_POINTER;
+               
+       return VDP_STATUS_OK;
+}
\ No newline at end of file
diff --git a/src/gallium/state_trackers/vdpau/device.c b/src/gallium/state_trackers/vdpau/device.c
new file mode 100644 (file)
index 0000000..496e2b8
--- /dev/null
@@ -0,0 +1,198 @@
+/**************************************************************************
+ *
+ * Copyright 2010 Younes Manton og 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 <pipe/p_compiler.h>
+#include <pipe/p_video_context.h>
+#include <vl_winsys.h>
+#include <util/u_memory.h>
+#include <util/u_debug.h>
+#include "vdpau_private.h"
+
+
+PUBLIC VdpStatus
+vdp_imp_device_create_x11(Display *display, int screen, VdpDevice *device, VdpGetProcAddress **get_proc_address)
+{
+   VdpStatus    ret;
+   vlVdpDevice *dev = 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;
+   dev->vscreen = vl_screen_create(display, screen);
+   if (!dev->vscreen)
+          {
+      ret = VDP_STATUS_RESOURCES;
+      goto no_vscreen;
+   }
+
+   *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:
+   /* Destroy vscreen */
+no_vscreen:
+   FREE(dev);
+no_dev:
+   vlDestroyHTAB();
+no_htab:
+   return ret;
+}
+
+PUBLIC VdpStatus 
+vlVdpPresentationQueueTargetCreateX11(VdpDevice device, Drawable drawable,VdpPresentationQueueTarget *target)
+{
+   VdpStatus    ret;
+   vlVdpPresentationQueueTarget *pqt = NULL;
+   
+   debug_printf("[VDPAU] Creating PresentationQueueTarget\n");
+
+   if (!drawable)
+      return VDP_STATUS_INVALID_HANDLE;
+         
+   vlVdpDevice *dev = vlGetDataHTAB(device);
+   if (!dev)
+      return VDP_STATUS_INVALID_HANDLE;
+
+   pqt = CALLOC(1, sizeof(vlVdpPresentationQueue));
+   if (!pqt)
+      return VDP_STATUS_RESOURCES;
+   
+   pqt->device = dev;
+   pqt->drawable = drawable;
+         
+       *target = vlAddDataHTAB(pqt);
+   if (*target == 0) {
+      ret = VDP_STATUS_ERROR;
+      goto no_handle;
+   }
+
+
+       return VDP_STATUS_OK;
+    no_handle:
+    FREE(dev);
+       return ret;
+}
+
+VdpStatus 
+vlVdpDeviceDestroy(VdpDevice device)
+{
+   debug_printf("[VDPAU] Destroying destroy\n");
+       
+   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 (file)
index 0000000..de08b81
--- /dev/null
@@ -0,0 +1,122 @@
+/**************************************************************************
+ *
+ * Copyright 2010 Younes Manton & 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 <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 */
+   0x55,                                       /* DUMMY */
+   &vlVdpGetInformationString, /* VDP_FUNC_ID_GET_INFORMATION_STRING */
+   &vlVdpDeviceDestroy, /* VDP_FUNC_ID_DEVICE_DESTROY */
+   &vlVdpGenerateCSCMatrix, /* 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 */
+   0x2, /* 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 */
+   0x3, /* VDP_FUNC_ID_OUTPUT_SURFACE_DESTROY */
+   0x4, /* VDP_FUNC_ID_OUTPUT_SURFACE_GET_PARAMETERS */
+   0x5, /* VDP_FUNC_ID_OUTPUT_SURFACE_GET_BITS_NATIVE */
+   0x6, /* VDP_FUNC_ID_OUTPUT_SURFACE_PUT_BITS_NATIVE */
+   0x7, /* VDP_FUNC_ID_OUTPUT_SURFACE_PUT_BITS_INDEXED */
+   0x8, /* 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 */
+   0x55,       /* DUMMY */
+   0x55,       /* DUMMY */
+   0x55,       /* DUMMY */
+   0x9, /* VDP_FUNC_ID_OUTPUT_SURFACE_RENDER_OUTPUT_SURFACE */
+   0x10, /* VDP_FUNC_ID_OUTPUT_SURFACE_RENDER_BITMAP_SURFACE */
+   0x11, /* 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 */
+   0x12, /* 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 */
+   &vlVdpVideoMixerCreate, /* VDP_FUNC_ID_VIDEO_MIXER_CREATE */
+   &vlVdpVideoMixerSetFeatureEnables, /* VDP_FUNC_ID_VIDEO_MIXER_SET_FEATURE_ENABLES */
+   &vlVdpVideoMixerSetAttributeValues, /* VDP_FUNC_ID_VIDEO_MIXER_SET_ATTRIBUTE_VALUES */
+   0x16, /* VDP_FUNC_ID_VIDEO_MIXER_GET_FEATURE_SUPPORT */
+   0x17, /* VDP_FUNC_ID_VIDEO_MIXER_GET_FEATURE_ENABLES */
+   0x18, /* VDP_FUNC_ID_VIDEO_MIXER_GET_PARAMETER_VALUES */
+   0x19, /* VDP_FUNC_ID_VIDEO_MIXER_GET_ATTRIBUTE_VALUES */
+   0x20, /* VDP_FUNC_ID_VIDEO_MIXER_DESTROY */
+   &vlVdpVideoMixerRender, /* 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 */
+   0x55,       /* DUMMY */
+   0x55,       /* DUMMY */
+   &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 */
+   &vlVdpPreemptionCallbackRegister  /* VDP_FUNC_ID_PREEMPTION_CALLBACK_REGISTER */
+};
+
+static void* ftab_winsys[1] =
+{
+   &vlVdpPresentationQueueTargetCreateX11  /* 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/htab.c b/src/gallium/state_trackers/vdpau/htab.c
new file mode 100644 (file)
index 0000000..0c95805
--- /dev/null
@@ -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 (file)
index 0000000..124125e
--- /dev/null
@@ -0,0 +1,140 @@
+/**************************************************************************
+ *
+ * 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 <util/u_memory.h>
+  #include <util/u_debug.h>
+  #include "vdpau_private.h"
+
+ VdpStatus     
+ vlVdpVideoMixerCreate (VdpDevice device, 
+                                               uint32_t feature_count, 
+                                               VdpVideoMixerFeature const *features, 
+                                               uint32_t parameter_count, 
+                                               VdpVideoMixerParameter const *parameters, 
+                                               void const *const *parameter_values, 
+                                               VdpVideoMixer *mixer)
+{
+       VdpStatus ret;
+       vlVdpVideoMixer *vmixer = NULL;
+       
+       debug_printf("[VDPAU] Creating VideoMixer\n");
+       
+       vlVdpDevice *dev = vlGetDataHTAB(device);
+       if (!dev)
+      return VDP_STATUS_INVALID_HANDLE;
+         
+       vmixer = CALLOC(1, sizeof(vlVdpVideoMixer));
+       if (!vmixer)
+      return VDP_STATUS_RESOURCES;
+         
+       vmixer->device = dev;
+         /*
+          * TODO: Handle features and parameters
+          * */
+         
+       *mixer = vlAddDataHTAB(vmixer);
+    if (*mixer == 0) {
+      ret = VDP_STATUS_ERROR;
+      goto no_handle;
+    }
+   
+   
+   return VDP_STATUS_OK;
+   no_handle:
+   return ret;
+}
+
+VdpStatus
+vlVdpVideoMixerSetFeatureEnables (
+                       VdpVideoMixer mixer, 
+                       uint32_t feature_count, 
+                       VdpVideoMixerFeature const *features, 
+                       VdpBool const *feature_enables)
+{
+       debug_printf("[VDPAU] Setting VideoMixer features\n");
+       
+       if (!(features && feature_enables))     
+               return VDP_STATUS_INVALID_POINTER;
+       
+       vlVdpVideoMixer *vmixer = vlGetDataHTAB(mixer);
+       if (!vmixer)
+               return VDP_STATUS_INVALID_HANDLE;
+               
+       /*
+          * TODO: Set features
+          * */
+       
+       
+       return VDP_STATUS_OK;
+}
+
+VdpStatus vlVdpVideoMixerRender (
+               VdpVideoMixer mixer, 
+               VdpOutputSurface background_surface, 
+               VdpRect const *background_source_rect, 
+               VdpVideoMixerPictureStructure current_picture_structure, 
+               uint32_t video_surface_past_count, 
+               VdpVideoSurface const *video_surface_past, 
+               VdpVideoSurface video_surface_current, 
+               uint32_t video_surface_future_count, 
+               VdpVideoSurface const *video_surface_future, 
+               VdpRect const *video_source_rect, 
+               VdpOutputSurface destination_surface, 
+               VdpRect const *destination_rect, 
+               VdpRect const *destination_video_rect, 
+               uint32_t layer_count, 
+               VdpLayer const *layers)
+{
+       if (!(background_source_rect && video_surface_past && video_surface_future && video_source_rect && destination_rect && destination_video_rect && layers))       
+               return VDP_STATUS_INVALID_POINTER;
+
+       return VDP_STATUS_NO_IMPLEMENTATION;
+}
+
+VdpStatus
+vlVdpVideoMixerSetAttributeValues (
+               VdpVideoMixer mixer, 
+               uint32_t attribute_count, 
+               VdpVideoMixerAttribute const *attributes, 
+               void const *const *attribute_values)
+{
+       if (!(attributes && attribute_values))  
+               return VDP_STATUS_INVALID_POINTER;
+       
+       vlVdpVideoMixer *vmixer = vlGetDataHTAB(mixer);
+       if (!vmixer)
+               return VDP_STATUS_INVALID_HANDLE;
+               
+       /*
+        * TODO: Implement the function
+        * 
+        * */
+       
+       return VDP_STATUS_OK;
+}
\ No newline at end of file
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 (file)
index 0000000..9093658
--- /dev/null
@@ -0,0 +1,149 @@
+/**************************************************************************
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include "mpeg2_bitstream_parser.h"
+
+int
+vlVdpMPEG2NextStartCode(struct vdpMPEG2BitstreamParser *parser)
+{
+       uint32_t integer = 0xffffff00;
+       uint8_t * ptr_read = parser->ptr_bitstream;
+       int8_t * bytes_to_end;
+               
+       bytes_to_end = parser->ptr_bitstream_end - parser->ptr_bitstream;
+               
+       /* Read byte after byte, until startcode is found */
+       while(integer != 0x00000100)
+       {
+               if (bytes_to_end <= 0)
+               {
+                       parser->state = MPEG2_BITSTREAM_DONE;
+                       parser->code = 0;
+                       return 0;
+               }
+               integer = ( integer | *ptr_read++ ) << 8;
+               bytes_to_end--; 
+       }
+       parser->ptr_bitstream = ptr_read;
+       parser->code = parser->ptr_bitstream;
+       /* start_code found. rewind cursor a byte */
+       //parser->cursor -= 8;
+       
+       return 0;
+}
+
+int
+vlVdpMPEG2BitstreamToMacroblock (
+                 struct pipe_screen *screen,
+                 VdpBitstreamBuffer const *bitstream_buffers,
+                 uint32_t bitstream_buffer_count,
+          unsigned int *num_macroblocks,
+          struct pipe_mpeg12_macroblock **pipe_macroblocks)
+{
+       bool b_header_done = false;
+       struct vdpMPEG2BitstreamParser parser;
+       
+       #if(1)
+       FILE *fp;
+   
+      if ((fp = fopen("binout", "w"))==NULL) {
+        printf("Cannot open file.\n");
+        exit(1);
+      }
+       fwrite(bitstream_buffers[0].bitstream, 1, bitstream_buffers[0].bitstream_bytes, fp);
+       fclose(fp);
+       
+       #endif
+       
+       
+       debug_printf("[VDPAU] Starting decoding MPEG2 stream\n");
+       
+       num_macroblocks[0] = 0;
+       
+       memset(&parser,0,sizeof(parser));
+       parser.state = MPEG2_HEADER_START_CODE;
+       parser.ptr_bitstream = (unsigned char *)bitstream_buffers[0].bitstream;
+       parser.ptr_bitstream_end = parser.ptr_bitstream + bitstream_buffers[0].bitstream_bytes;
+       
+       /* Main header parser loop */
+       while(!b_header_done)
+       {
+               switch (parser.state)
+               {
+               case MPEG2_SEEK_HEADER:
+                       if (vlVdpMPEG2NextStartCode(&parser))
+                               exit(1);
+                       break;
+                       /* Start_code found */
+                       switch (parser.code)
+                       {
+                               /* sequence_header_code */
+                               case 0xB3:
+                               debug_printf("[VDPAU][Bitstream parser] Sequence header code found\n");
+                               
+                               /* We dont need to read this, because we already have this information */
+                               break;
+                               case 0xB5:
+                               debug_printf("[VDPAU][Bitstream parser] Extension start code found\n");
+                               //exit(1);
+                               break;
+                               
+                               case 0xB8:
+                               debug_printf("[VDPAU][Bitstream parser] Extension start code found\n");
+                               //exit(1);
+                               break;
+                               
+                       }
+               
+               break;
+               case MPEG2_BITSTREAM_DONE:
+                       if (parser.cur_bitstream < bitstream_buffer_count - 1)
+                       {
+                               debug_printf("[VDPAU][Bitstream parser] Done parsing current bitstream. Moving to the next\n");
+                               parser.cur_bitstream++;
+                               parser.ptr_bitstream = (unsigned char *)bitstream_buffers[parser.cur_bitstream].bitstream;
+                               parser.ptr_bitstream_end = parser.ptr_bitstream + bitstream_buffers[parser.cur_bitstream].bitstream_bytes; 
+                               parser.state = MPEG2_HEADER_START_CODE;
+                       }
+                       else
+                       {
+                               debug_printf("[VDPAU][Bitstream parser] Done with frame\n");
+                               exit(0);
+                               // return 0;
+                       }
+               break;
+               
+               }
+               
+               
+       }
+       
+
+       return 0;
+}
+
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 (file)
index 0000000..25f3516
--- /dev/null
@@ -0,0 +1,65 @@
+/**************************************************************************
+ *
+ * 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"
+
+enum vdpMPEG2States
+{
+       MPEG2_SEEK_HEADER,
+       MPEG2_HEADER_DONE,
+       MPEG2_BITSTREAM_DONE,
+       MPEG2_HEADER_START_CODE
+};
+
+
+struct vdpMPEG2BitstreamParser
+{
+       enum vdpMPEG2States state;
+       uint32_t cur_bitstream;
+       const uint8_t *ptr_bitstream_end;
+       const uint8_t *ptr_bitstream;
+       uint8_t code;
+       
+       /* The decoded bitstream goes here: */
+       /* Sequence_header_info */
+       uint32_t horizontal_size_value;
+};
+
+int
+vlVdpMPEG2BitstreamToMacroblock(struct pipe_screen *screen,
+                  VdpBitstreamBuffer const *bitstream_buffers,
+                                 uint32_t bitstream_buffer_count,
+                  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 (file)
index 0000000..20097ea
--- /dev/null
@@ -0,0 +1,64 @@
+/**************************************************************************
+ *
+ * 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>
+#include <util/u_memory.h>
+
+VdpStatus
+vlVdpOutputSurfaceCreate (     VdpDevice  device, 
+                                                       VdpRGBAFormat  rgba_format, 
+                                                       uint32_t width, uint32_t height, 
+                                                       VdpOutputSurface  *surface)
+{
+       vlVdpOutputSurface *vlsurface = NULL;
+       
+       debug_printf("[VDPAU] Creating output surface\n");
+       if (!(width && height))
+               return VDP_STATUS_INVALID_SIZE;
+               
+       vlVdpDevice *dev = vlGetDataHTAB(device);
+       if (!dev)
+      return VDP_STATUS_INVALID_HANDLE;
+         
+       vlsurface = CALLOC(1, sizeof(vlVdpOutputSurface));
+    if (!vlsurface)
+      return VDP_STATUS_RESOURCES;
+         
+       vlsurface->width = width;
+       vlsurface->height = height;
+       vlsurface->format = FormatRGBAToPipe(rgba_format);
+         
+       *surface = vlAddDataHTAB(vlsurface);
+   if (*surface == 0) {
+      FREE(dev);
+         return VDP_STATUS_ERROR;
+   }
+       
+       return VDP_STATUS_OK;
+}
\ 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 (file)
index 0000000..4572bdc
--- /dev/null
@@ -0,0 +1,39 @@
+/**************************************************************************
+ *
+ * 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>
+ void vlVdpPreemptionCallback (VdpDevice device, void *context)
+ {
+        /* TODO: Implement preemption */
+ }
+ VdpStatus vlVdpPreemptionCallbackRegister (VdpDevice device, VdpPreemptionCallback callback, void *context)
+ {
+        
+        return VDP_STATUS_OK;
+ }
\ No newline at end of file
diff --git a/src/gallium/state_trackers/vdpau/presentation.c b/src/gallium/state_trackers/vdpau/presentation.c
new file mode 100644 (file)
index 0000000..5f545d0
--- /dev/null
@@ -0,0 +1,149 @@
+/**************************************************************************
+ *
+ * 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>
+#include <util/u_memory.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 PresentationQueue\n");
+       VdpStatus    ret;
+       vlVdpPresentationQueue *pq = NULL;
+       
+       if (!presentation_queue)
+               return VDP_STATUS_INVALID_POINTER;
+         
+   vlVdpDevice *dev = vlGetDataHTAB(device);
+   if (!dev)
+      return VDP_STATUS_INVALID_HANDLE;
+
+   vlVdpPresentationQueueTarget *pqt = vlGetDataHTAB(presentation_queue_target);
+   if (!pqt)
+          return VDP_STATUS_INVALID_HANDLE;
+          
+       if (dev != pqt->device)
+               return VDP_STATUS_HANDLE_DEVICE_MISMATCH;
+
+   pq = CALLOC(1, sizeof(vlVdpPresentationQueue));
+   if (!pq)
+      return VDP_STATUS_RESOURCES;
+         
+       *presentation_queue = vlAddDataHTAB(pq);
+   if (*presentation_queue == 0) {
+      ret = VDP_STATUS_ERROR;
+      goto no_handle;
+   }
+
+
+       return VDP_STATUS_OK;
+    no_handle:
+    FREE(pq);
+       return ret;
+}
+
+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 (file)
index 0000000..a3a8500
--- /dev/null
@@ -0,0 +1,282 @@
+/**************************************************************************
+ *
+ * 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,
+                                                                  1,
+                                   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/surface.c b/src/gallium/state_trackers/vdpau/surface.c
new file mode 100644 (file)
index 0000000..9b6dac9
--- /dev/null
@@ -0,0 +1,193 @@
+/**************************************************************************
+ *
+ * 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>
+
+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 = TypeToPipe(chroma_type);
+ p_surf->device = dev;
+ p_surf->width = width;
+ p_surf->height = height;
+
+ *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 (file)
index 0000000..1deea3a
--- /dev/null
@@ -0,0 +1,278 @@
+/**************************************************************************
+ *
+ * Copyright 2010 Younes Manton & 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 VDPAU_PRIVATE_H
+#define VDPAU_PRIVATE_H
+
+
+#include <vdpau/vdpau.h>
+#include <vdpau/vdpau_x11.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 enum pipe_format FormatRGBAToPipe(VdpRGBAFormat vdpau_format)
+{
+   switch (vdpau_format) {
+      case VDP_RGBA_FORMAT_A8:
+         return PIPE_FORMAT_A8_UNORM;
+      case VDP_RGBA_FORMAT_B10G10R10A2:
+         return PIPE_FORMAT_B10G10R10A2_UNORM;
+      case VDP_RGBA_FORMAT_B8G8R8A8:
+         return PIPE_FORMAT_B8G8R8A8_UNORM;
+      case VDP_RGBA_FORMAT_R10G10B10A2:
+         return PIPE_FORMAT_R10G10B10A2_UNORM;
+      case VDP_RGBA_FORMAT_R8G8B8A8:
+         return PIPE_FORMAT_R8G8B8A8_UNORM;
+      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
+{
+   Display *display;
+   int screen;
+   struct vl_screen *vscreen;
+} vlVdpDevice;
+
+typedef struct
+{
+   vlVdpDevice *device;
+   Drawable drawable;
+} vlVdpPresentationQueueTarget;
+
+typedef struct
+{
+   vlVdpDevice *device;
+   Drawable drawable;
+} vlVdpPresentationQueue;
+
+typedef struct
+{
+       vlVdpDevice *device;
+} vlVdpVideoMixer;
+
+typedef struct
+{
+   vlVdpDevice *device;
+   uint32_t width;
+   uint32_t height;
+   uint32_t pitch;
+   struct pipe_surface *psurface;
+   enum pipe_video_chroma_format chroma_format;
+   uint8_t *data;
+} vlVdpSurface;
+
+typedef struct
+{
+   vlVdpDevice *device;
+   uint32_t width;
+   uint32_t height;
+   enum pipe_format format;
+} vlVdpOutputSurface;
+
+typedef struct
+{
+       vlVdpDevice *device;
+    struct vl_context *vctx;
+       enum pipe_video_chroma_format chroma_format;
+       enum pipe_video_profile profile;
+       uint32_t width;
+       uint32_t height;
+} 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);
+
+/* Public functions */
+VdpDeviceCreateX11 vdp_imp_device_create_x11;
+VdpPresentationQueueTargetCreateX11 vlVdpPresentationQueueTargetCreateX11;
+
+/* Internal function pointers */
+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;
+VdpPreemptionCallback vlVdpPreemptionCallback;
+VdpPreemptionCallbackRegister vlVdpPreemptionCallbackRegister;
+VdpVideoMixerSetFeatureEnables vlVdpVideoMixerSetFeatureEnables;
+VdpVideoMixerCreate vlVdpVideoMixerCreate;
+VdpVideoMixerRender vlVdpVideoMixerRender;
+VdpVideoMixerSetAttributeValues vlVdpVideoMixerSetAttributeValues;
+VdpGenerateCSCMatrix vlVdpGenerateCSCMatrix;
+
+
+#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 (file)
index 0000000..126dc6d
--- /dev/null
@@ -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 (file)
index 0000000..d23d863
--- /dev/null
@@ -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 (file)
index 0000000..c7da7a8
--- /dev/null
@@ -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 (file)
index 0000000..06a1633
--- /dev/null
@@ -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_IDCT | XVMC_MOCOMP | XVMC_MPEG_2)) {
+      XVMC_MSG(XVMC_ERR, "[XvMC] Cannot decode requested surface type. Non-MPEG2/Mocomp/iDCT acceleration unsupported.\n");
+      return BadImplementation;
+   }
+   if (surface_flags & XVMC_INTRA_UNSIGNED) {
+      XVMC_MSG(XVMC_ERR, "[XvMC] Cannot decode requested surface type. Unsigned 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 (file)
index 0000000..78de154
--- /dev/null
@@ -0,0 +1,453 @@
+/**************************************************************************
+ *
+ * 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;
+   struct pipe_surface surf_template;
+   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.array_size = 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);
+
+   memset(&surf_template, 0, sizeof(surf_template));
+   surf_template.format = tex->format;
+   surf_template.usage = PIPE_BIND_SAMPLER_VIEW;
+   subpicture_priv->sfc = vpipe->create_surface(vpipe, tex, &surf_template);
+   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;
+   unsigned int tmp_color;
+   float color_f[4];
+
+   assert(dpy);
+
+   if (!subpicture)
+      return XvMCBadSubpicture;
+
+   /* Convert color to float */
+   util_format_read_4f(PIPE_FORMAT_B8G8R8A8_UNORM,
+                    color_f, 1,
+                    &color, 4,
+                    0, 0, 1, 1);
+
+   subpicture_priv = subpicture->privData;
+   context_priv = subpicture_priv->context->privData;
+   /* TODO: Assert clear rect is within bounds? Or clip? */
+   context_priv->vctx->vpipe->clear_render_target(context_priv->vctx->vpipe,
+                                           subpicture_priv->sfc, x, y,
+                                                                                  color_f,
+                                           width, height);
+
+   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};
+
+   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,
+                              0, 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 (file)
index 0000000..c90ad40
--- /dev/null
@@ -0,0 +1,527 @@
+/**************************************************************************
+ *
+ * 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 <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, unsigned int xvmc_picture_structure)
+{
+   switch (xvmc_motion_type) {
+      case XVMC_PREDICTION_FRAME:
+         if (xvmc_picture_structure == XVMC_FRAME_PICTURE)
+            return PIPE_MPEG12_MOTION_TYPE_FRAME;
+         else
+            return PIPE_MPEG12_MOTION_TYPE_16x8;
+         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 picture structure 0x%08X).\n", xvmc_motion_type, xvmc_picture_structure);
+
+   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.array_size = 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,
+                  unsigned int xvmc_picture_structure,
+                  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_picture_structure);
+      /* 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->mvfs[0][0] = xvmc_mb->motion_vertical_field_select & XVMC_SELECT_FIRST_FORWARD;
+      pipe_macroblocks->mvfs[0][1] = xvmc_mb->motion_vertical_field_select & XVMC_SELECT_FIRST_BACKWARD;
+      pipe_macroblocks->mvfs[1][0] = xvmc_mb->motion_vertical_field_select & XVMC_SELECT_SECOND_FORWARD;
+      pipe_macroblocks->mvfs[1][1] = xvmc_mb->motion_vertical_field_select & XVMC_SELECT_SECOND_BACKWARD;
+
+      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 surf_template;
+   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.array_size = 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;
+   }
+
+   memset(&surf_template, 0, sizeof(surf_template));
+   surf_template.format = vsfc_tex->format;
+   surf_template.usage = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
+   vsfc = vpipe->create_surface(vpipe, vsfc_tex, &surf_template);
+   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, picture_structure, 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)
+{
+   static int dump_window = -1;
+
+   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, 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->texture,
+      0, 0,
+      vl_contextprivate_get(context_priv->vctx, drawable_surface)
+   );
+
+   pipe_surface_reference(&drawable_surface, NULL);
+
+   if(dump_window == -1) {
+      dump_window = debug_get_num_option("XVMC_DUMP", 0);
+   }
+
+   if(dump_window) {
+      static unsigned int framenum = 0;
+      char cmd[256];
+      sprintf(cmd, "xwd -id %d -out xvmc_frame_%08d.xwd", (int)drawable, ++framenum);
+      system(cmd);
+   }
+
+   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 (file)
index 0000000..9a8e05d
--- /dev/null
@@ -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 (file)
index 0000000..88b0376
--- /dev/null
@@ -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 (file)
index 0000000..994e3ca
--- /dev/null
@@ -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 (file)
index 0000000..3da957c
--- /dev/null
@@ -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 (file)
index 0000000..6058783
--- /dev/null
@@ -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 (file)
index 0000000..20d0907
--- /dev/null
@@ -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 (file)
index 0000000..b65eb26
--- /dev/null
@@ -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 (file)
index 0000000..142c09b
--- /dev/null
@@ -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 (file)
index 0000000..0438e52
--- /dev/null
@@ -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 (file)
index 0000000..bf94d85
--- /dev/null
@@ -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 (file)
index 0000000..1e2dfb4
--- /dev/null
@@ -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.va b/src/gallium/targets/Makefile.va
new file mode 100644 (file)
index 0000000..efb0a59
--- /dev/null
@@ -0,0 +1,62 @@
+# This makefile template is used to build "driver"_drv_video.so
+
+LIBNAME = lib$(LIBBASENAME).so
+VA_LIB_GLOB= lib$(LIBBASENAME).*so*
+VA_MAJOR = 0
+VA_MINOR = 3
+INCLUDES = -I$(TOP)/src/gallium/include \
+          -I$(TOP)/src/gallium/drivers \
+          -I$(TOP)/src/gallium/auxiliary \
+          -I$(TOP)/src/gallium/winsys \
+          -I$(TOP)/src/gallium/winsys/g3dvl \
+          $(DRIVER_INCLUDES)
+DEFINES = -DGALLIUM_TRACE -DVER_MAJOR=$(VA_MAJOR) -DVER_MINOR=$(VA_MINOR) $(DRIVER_DEFINES)
+LIBS = $(EXTRA_LIB_PATH) $(DRIVER_LIBS) -lva -lXext -lX11 -lm
+STATE_TRACKER_LIB = $(TOP)/src/gallium/state_trackers/va/libvatracker.a
+
+# XXX: Hack, VA public funcs aren't exported
+OBJECTS = $(C_SOURCES:.c=.o) \
+         $(ASM_SOURCES:.S=.o) \
+         $(TOP)/src/gallium/state_trackers/va/*.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 $(VA_MAJOR) -minor $(VA_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)$(VA_LIB_INSTALL_DIR)
+       $(MINSTALL) -m 755 $(TOP)/$(LIB_DIR)/gallium/$(VA_LIB_GLOB) $(DESTDIR)$(VA_LIB_INSTALL_DIR)
+
+include depend
diff --git a/src/gallium/targets/Makefile.vdpau b/src/gallium/targets/Makefile.vdpau
new file mode 100644 (file)
index 0000000..2accbeb
--- /dev/null
@@ -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 (file)
index 0000000..6abe7f6
--- /dev/null
@@ -0,0 +1,62 @@
+# This makefile template is used to build libXvMCg3dvl.so
+
+LIBNAME = lib$(LIBBASENAME).so
+LIB_GLOB=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 \
+          -I$(TOP)/src/gallium/winsys/g3dvl \
+          $(DRIVER_INCLUDES)
+DEFINES = -DGALLIUM_TRACE $(DRIVER_DEFINES)
+LIBS = $(EXTRA_LIB_PATH) $(DRIVER_LIBS) -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: default
+       $(INSTALL) -d $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR)
+       $(MINSTALL) -m 755 $(TOP)/$(LIB_DIR)/gallium/$(LIB_GLOB) $(DESTDIR)$(INSTALL_DIR)/$(LIB_DIR)
+
+include depend
index eb1ee859a00389a594b18c1b5ded32fcec1332ca..26c927e0a812fd04d0fee055879f75e666fd7922 100644 (file)
@@ -11,6 +11,7 @@ PIPE_DRIVERS = \
        $(TOP)/src/gallium/drivers/nvfx/libnvfx.a \
        $(TOP)/src/gallium/drivers/nv50/libnv50.a \
        $(TOP)/src/gallium/drivers/nvc0/libnvc0.a \
+       $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
        $(TOP)/src/gallium/drivers/nouveau/libnouveau.a
 
 C_SOURCES = \
diff --git a/src/gallium/targets/va-r600/Makefile b/src/gallium/targets/va-r600/Makefile
new file mode 100644 (file)
index 0000000..03ca8ed
--- /dev/null
@@ -0,0 +1,26 @@
+TOP = ../../../..
+include $(TOP)/configs/current
+
+LIBBASENAME = r600_drv_video
+
+DRIVER_DEFINES = -DGALLIUM_SOFTPIPE
+DRIVER_INCLUDES =
+
+PIPE_DRIVERS = \
+       $(TOP)/src/gallium/drivers/r600/libr600.a \
+       $(TOP)/src/gallium/winsys/g3dvl/dri/libvldri.a \
+        $(TOP)/src/gallium/winsys/r600/drm/libr600winsys.a \
+       $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
+        $(TOP)/src/gallium/drivers/trace/libtrace.a \
+       $(TOP)/src/gallium/auxiliary/libgallium.a
+
+C_SOURCES = \
+       target.c \
+       $(COMMON_GALLIUM_SOURCES) \
+       $(DRIVER_SOURCES)
+
+DRIVER_LIBS = $(shell pkg-config libdrm_radeon --libs) -lXfixes
+
+include ../Makefile.va
+
+symlinks:
diff --git a/src/gallium/targets/va-r600/target.c b/src/gallium/targets/va-r600/target.c
new file mode 100644 (file)
index 0000000..8753e2b
--- /dev/null
@@ -0,0 +1,24 @@
+#include "state_tracker/drm_driver.h"
+#include "target-helpers/inline_debug_helper.h"
+#include "r600/drm/r600_drm_public.h"
+#include "r600/r600_public.h"
+
+static struct pipe_screen *create_screen(int fd)
+{
+   struct radeon *radeon;
+   struct pipe_screen *screen;
+
+   radeon = r600_drm_winsys_create(fd);
+   if (!radeon)
+      return NULL;
+
+   screen = r600_screen_create(radeon);
+   if (!screen)
+      return NULL;
+
+   screen = debug_screen_wrap(screen);
+
+   return screen;
+}
+
+DRM_DRIVER_DESCRIPTOR("r600", "radeon", create_screen)
diff --git a/src/gallium/targets/va-softpipe/Makefile b/src/gallium/targets/va-softpipe/Makefile
new file mode 100644 (file)
index 0000000..a58df36
--- /dev/null
@@ -0,0 +1,21 @@
+TOP = ../../../..
+include $(TOP)/configs/current
+
+LIBBASENAME = softpipe_drv_video
+
+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.va
+
+symlinks:
diff --git a/src/gallium/targets/vdpau-softpipe/Makefile b/src/gallium/targets/vdpau-softpipe/Makefile
new file mode 100644 (file)
index 0000000..29dea50
--- /dev/null
@@ -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 (file)
index 0000000..4384eea
--- /dev/null
@@ -0,0 +1,23 @@
+TOP = ../../../..
+include $(TOP)/configs/current
+
+LIBBASENAME = XvMCnouveau
+
+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-r600/Makefile b/src/gallium/targets/xvmc-r600/Makefile
new file mode 100644 (file)
index 0000000..62e47b5
--- /dev/null
@@ -0,0 +1,23 @@
+TOP = ../../../..
+include $(TOP)/configs/current
+
+LIBBASENAME = XvMCr600
+
+PIPE_DRIVERS = \
+        $(TOP)/src/gallium/drivers/r600/libr600.a \
+       $(TOP)/src/gallium/winsys/g3dvl/dri/libvldri.a \
+        $(TOP)/src/gallium/winsys/r600/drm/libr600winsys.a \
+       $(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
+        $(TOP)/src/gallium/drivers/trace/libtrace.a \
+       $(TOP)/src/gallium/auxiliary/libgallium.a
+
+C_SOURCES = \
+       target.c \
+       $(COMMON_GALLIUM_SOURCES) \
+       $(DRIVER_SOURCES)
+
+DRIVER_LIBS = $(shell pkg-config libdrm_radeon --libs) -lXfixes
+
+include ../Makefile.xvmc
+
+symlinks:
diff --git a/src/gallium/targets/xvmc-r600/target.c b/src/gallium/targets/xvmc-r600/target.c
new file mode 100644 (file)
index 0000000..8753e2b
--- /dev/null
@@ -0,0 +1,24 @@
+#include "state_tracker/drm_driver.h"
+#include "target-helpers/inline_debug_helper.h"
+#include "r600/drm/r600_drm_public.h"
+#include "r600/r600_public.h"
+
+static struct pipe_screen *create_screen(int fd)
+{
+   struct radeon *radeon;
+   struct pipe_screen *screen;
+
+   radeon = r600_drm_winsys_create(fd);
+   if (!radeon)
+      return NULL;
+
+   screen = r600_screen_create(radeon);
+   if (!screen)
+      return NULL;
+
+   screen = debug_screen_wrap(screen);
+
+   return screen;
+}
+
+DRM_DRIVER_DESCRIPTOR("r600", "radeon", create_screen)
diff --git a/src/gallium/targets/xvmc-softpipe/Makefile b/src/gallium/targets/xvmc-softpipe/Makefile
new file mode 100644 (file)
index 0000000..5b60bed
--- /dev/null
@@ -0,0 +1,21 @@
+TOP = ../../../..
+include $(TOP)/configs/current
+
+LIBBASENAME = XvMCsoftpipe
+
+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 (file)
index 822cd11..0000000
+++ /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 <jrfonseca@tungstengraphics.com>
diff --git a/src/gallium/tests/python/retrace/format.py b/src/gallium/tests/python/retrace/format.py
deleted file mode 100755 (executable)
index a4285bf..0000000
+++ /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 (executable)
index d4a079f..0000000
+++ /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 (executable)
index b08d368..0000000
+++ /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 (executable)
index bd47c9a..0000000
+++ /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 (file)
index 936c0b3..0000000
+++ /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 (file)
index 6d17c88..0000000
+++ /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 (file)
index 0dbbaee..0000000
+++ /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 (executable)
index d8cf84d..0000000
+++ /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 (file)
index e33609d..0000000
+++ /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 (file)
index 103d749..0000000
+++ /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 (file)
index bcb9420..0000000
+++ /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 (file)
index 85fb9ea..0000000
+++ /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 (file)
index b528197..0000000
+++ /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 (file)
index d59df76..0000000
+++ /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 (file)
index fbb20fa..0000000
+++ /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 (file)
index b511288..0000000
+++ /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 (file)
index 99a2f96..0000000
+++ /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 (file)
index a54c262..0000000
+++ /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 (file)
index 5f5b4be..0000000
+++ /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 (file)
index 6323c47..0000000
+++ /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 (file)
index 740809d..0000000
+++ /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 (file)
index 413b9dc..0000000
+++ /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 (file)
index b69f213..0000000
+++ /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 (file)
index df284f4..0000000
+++ /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 (file)
index 64af72f..0000000
+++ /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 (file)
index bdd0b00..0000000
+++ /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 (file)
index f4b611b..0000000
+++ /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 (file)
index d1e9b0b..0000000
+++ /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 (file)
index 1f33fac..0000000
+++ /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 (file)
index d58b788..0000000
+++ /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 (file)
index ecd1924..0000000
+++ /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 (file)
index c2d99dd..0000000
+++ /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 (file)
index a08ab6d..0000000
+++ /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 (file)
index 6110647..0000000
+++ /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 (file)
index 673fca1..0000000
+++ /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 (file)
index 6ec8b11..0000000
+++ /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 (file)
index ef65a9c..0000000
+++ /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 (file)
index e33609d..0000000
+++ /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 (file)
index 05e40db..0000000
+++ /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 (executable)
index 23f3d2a..0000000
+++ /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 (executable)
index 0c1bcda..0000000
+++ /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 (file)
index af6cded..0000000
+++ /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 (file)
index 2ed6341..0000000
+++ /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 (file)
index bb3039f..0000000
+++ /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 (file)
index 655e8a9..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-Import('*')
-
-env = env.Clone()
-
-env.Prepend(LIBS = [gallium])
-
-if env['platform'] in ('freebsd8', 'sunos5'):
-    env.Append(LIBS = ['m'])
-
-if env['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/pipe_barrier_test.c b/src/gallium/tests/unit/pipe_barrier_test.c
deleted file mode 100644 (file)
index f5d72b0..0000000
+++ /dev/null
@@ -1,86 +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.
- *
- **************************************************************************/
-
-
-/*
- *  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
-
-static pipe_thread threads[NUM_THREADS];
-static pipe_barrier barrier;
-static int thread_ids[NUM_THREADS];
-
-
-static PIPE_THREAD_ROUTINE(thread_function, thread_data)
-{
-   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]);
-   }
-
-   pipe_barrier_destroy(&barrier);
-
-   printf("pipe_barrier_test exiting\n");
-
-   return 0;
-}
diff --git a/src/gallium/tests/unit/u_cache_test.c b/src/gallium/tests/unit/u_cache_test.c
deleted file mode 100644 (file)
index 0b62a76..0000000
+++ /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 (file)
index ba0dd17..0000000
+++ /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 (file)
index 00bda7f..0000000
+++ /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 (file)
index 0000000..6c793e0
--- /dev/null
@@ -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 (file)
index 0000000..b270e78
--- /dev/null
@@ -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/gallium/winsys/g3dvl/dri/XF86dri.c b/src/gallium/winsys/g3dvl/dri/XF86dri.c
new file mode 100644 (file)
index 0000000..831a760
--- /dev/null
@@ -0,0 +1,618 @@
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+Copyright 2000 VA Linux Systems, 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 PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ *   Kevin E. Martin <martin@valinux.com>
+ *   Jens Owen <jens@tungstengraphics.com>
+ *   Rickard E. (Rik) Faith <faith@valinux.com>
+ *
+ */
+
+/* THIS IS NOT AN X CONSORTIUM STANDARD */
+
+#include <X11/Xlibint.h>
+#include <X11/extensions/Xext.h>
+#include <X11/extensions/extutil.h>
+#include "xf86dristr.h"
+
+static XExtensionInfo _xf86dri_info_data;
+static XExtensionInfo *xf86dri_info = &_xf86dri_info_data;
+static char xf86dri_extension_name[] = XF86DRINAME;
+
+#define XF86DRICheckExtension(dpy,i,val) \
+  XextCheckExtension (dpy, i, xf86dri_extension_name, val)
+
+/*****************************************************************************
+ *                                                                           *
+ *                        private utility routines                          *
+ *                                                                           *
+ *****************************************************************************/
+
+static int close_display(Display *dpy, XExtCodes *extCodes);
+static /* const */ XExtensionHooks xf86dri_extension_hooks = {
+    NULL,                              /* create_gc */
+    NULL,                              /* copy_gc */
+    NULL,                              /* flush_gc */
+    NULL,                              /* free_gc */
+    NULL,                              /* create_font */
+    NULL,                              /* free_font */
+    close_display,                     /* close_display */
+    NULL,                              /* wire_to_event */
+    NULL,                              /* event_to_wire */
+    NULL,                              /* error */
+    NULL,                              /* error_string */
+};
+
+static XEXT_GENERATE_FIND_DISPLAY (find_display, xf86dri_info, 
+                                  xf86dri_extension_name, 
+                                  &xf86dri_extension_hooks, 
+                                  0, NULL)
+
+static XEXT_GENERATE_CLOSE_DISPLAY (close_display, xf86dri_info)
+
+
+/*****************************************************************************
+ *                                                                           *
+ *                 public XFree86-DRI Extension routines                    *
+ *                                                                           *
+ *****************************************************************************/
+
+#if 0
+#include <stdio.h>
+#define TRACE(msg)  fprintf(stderr,"XF86DRI%s\n", msg);
+#else
+#define TRACE(msg)
+#endif
+
+#define PUBLIC
+
+PUBLIC Bool XF86DRIQueryExtension (dpy, event_basep, error_basep)
+    Display *dpy;
+    int *event_basep, *error_basep;
+{
+    XExtDisplayInfo *info = find_display (dpy);
+
+    TRACE("QueryExtension...");
+    if (XextHasExtension(info)) {
+       *event_basep = info->codes->first_event;
+       *error_basep = info->codes->first_error;
+        TRACE("QueryExtension... return True");
+       return True;
+    } else {
+        TRACE("QueryExtension... return False");
+       return False;
+    }
+}
+
+PUBLIC Bool XF86DRIQueryVersion(dpy, majorVersion, minorVersion, patchVersion)
+    Display* dpy;
+    int* majorVersion; 
+    int* minorVersion;
+    int* patchVersion;
+{
+    XExtDisplayInfo *info = find_display (dpy);
+    xXF86DRIQueryVersionReply rep;
+    xXF86DRIQueryVersionReq *req;
+
+    TRACE("QueryVersion...");
+    XF86DRICheckExtension (dpy, info, False);
+
+    LockDisplay(dpy);
+    GetReq(XF86DRIQueryVersion, req);
+    req->reqType = info->codes->major_opcode;
+    req->driReqType = X_XF86DRIQueryVersion;
+    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+       UnlockDisplay(dpy);
+       SyncHandle();
+        TRACE("QueryVersion... return False");
+       return False;
+    }
+    *majorVersion = rep.majorVersion;
+    *minorVersion = rep.minorVersion;
+    *patchVersion = rep.patchVersion;
+    UnlockDisplay(dpy);
+    SyncHandle();
+    TRACE("QueryVersion... return True");
+    return True;
+}
+
+PUBLIC Bool XF86DRIQueryDirectRenderingCapable(dpy, screen, isCapable)
+    Display* dpy;
+    int screen;
+    Bool* isCapable;
+{
+    XExtDisplayInfo *info = find_display (dpy);
+    xXF86DRIQueryDirectRenderingCapableReply rep;
+    xXF86DRIQueryDirectRenderingCapableReq *req;
+
+    TRACE("QueryDirectRenderingCapable...");
+    XF86DRICheckExtension (dpy, info, False);
+
+    LockDisplay(dpy);
+    GetReq(XF86DRIQueryDirectRenderingCapable, req);
+    req->reqType = info->codes->major_opcode;
+    req->driReqType = X_XF86DRIQueryDirectRenderingCapable;
+    req->screen = screen;
+    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+       UnlockDisplay(dpy);
+       SyncHandle();
+        TRACE("QueryDirectRenderingCapable... return False");
+       return False;
+    }
+    *isCapable = rep.isCapable;
+    UnlockDisplay(dpy);
+    SyncHandle();
+    TRACE("QueryDirectRenderingCapable... return True");
+    return True;
+}
+
+PUBLIC Bool XF86DRIOpenConnection(dpy, screen, hSAREA, busIdString)
+    Display* dpy;
+    int screen;
+    drm_handle_t * hSAREA;
+    char **busIdString;
+{
+    XExtDisplayInfo *info = find_display (dpy);
+    xXF86DRIOpenConnectionReply rep;
+    xXF86DRIOpenConnectionReq *req;
+
+    TRACE("OpenConnection...");
+    XF86DRICheckExtension (dpy, info, False);
+
+    LockDisplay(dpy);
+    GetReq(XF86DRIOpenConnection, req);
+    req->reqType = info->codes->major_opcode;
+    req->driReqType = X_XF86DRIOpenConnection;
+    req->screen = screen;
+    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+       UnlockDisplay(dpy);
+       SyncHandle();
+        TRACE("OpenConnection... return False");
+       return False;
+    }
+
+    *hSAREA = rep.hSAREALow;
+    if (sizeof(drm_handle_t) == 8) {
+       int shift = 32; /* var to prevent warning on next line */
+       *hSAREA |= ((drm_handle_t) rep.hSAREAHigh) << shift;
+    }
+
+    if (rep.length) {
+        if (!(*busIdString = (char *)Xcalloc(rep.busIdStringLength + 1, 1))) {
+            _XEatData(dpy, ((rep.busIdStringLength+3) & ~3));
+            UnlockDisplay(dpy);
+            SyncHandle();
+            TRACE("OpenConnection... return False");
+            return False;
+        }
+       _XReadPad(dpy, *busIdString, rep.busIdStringLength);
+    } else {
+        *busIdString = NULL;
+    }
+    UnlockDisplay(dpy);
+    SyncHandle();
+    TRACE("OpenConnection... return True");
+    return True;
+}
+
+PUBLIC Bool XF86DRIAuthConnection(dpy, screen, magic)
+    Display* dpy;
+    int screen;
+    drm_magic_t magic;
+{
+    XExtDisplayInfo *info = find_display (dpy);
+    xXF86DRIAuthConnectionReq *req;
+    xXF86DRIAuthConnectionReply rep;
+
+    TRACE("AuthConnection...");
+    XF86DRICheckExtension (dpy, info, False);
+
+    LockDisplay(dpy);
+    GetReq(XF86DRIAuthConnection, req);
+    req->reqType = info->codes->major_opcode;
+    req->driReqType = X_XF86DRIAuthConnection;
+    req->screen = screen;
+    req->magic = magic;
+    rep.authenticated = 0;
+    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse) || !rep.authenticated) {
+       UnlockDisplay(dpy);
+       SyncHandle();
+        TRACE("AuthConnection... return False");
+       return False;
+    }
+    UnlockDisplay(dpy);
+    SyncHandle();
+    TRACE("AuthConnection... return True");
+    return True;
+}
+
+PUBLIC Bool XF86DRICloseConnection(dpy, screen)
+    Display* dpy;
+    int screen;
+{
+    XExtDisplayInfo *info = find_display (dpy);
+    xXF86DRICloseConnectionReq *req;
+
+    TRACE("CloseConnection...");
+
+    XF86DRICheckExtension (dpy, info, False);
+
+    LockDisplay(dpy);
+    GetReq(XF86DRICloseConnection, req);
+    req->reqType = info->codes->major_opcode;
+    req->driReqType = X_XF86DRICloseConnection;
+    req->screen = screen;
+    UnlockDisplay(dpy);
+    SyncHandle();
+    TRACE("CloseConnection... return True");
+    return True;
+}
+
+PUBLIC Bool XF86DRIGetClientDriverName(dpy, screen, ddxDriverMajorVersion, 
+       ddxDriverMinorVersion, ddxDriverPatchVersion, clientDriverName)
+    Display* dpy;
+    int screen;
+    int* ddxDriverMajorVersion;
+    int* ddxDriverMinorVersion;
+    int* ddxDriverPatchVersion;
+    char** clientDriverName;
+{
+    XExtDisplayInfo *info = find_display (dpy);
+    xXF86DRIGetClientDriverNameReply rep;
+    xXF86DRIGetClientDriverNameReq *req;
+
+    TRACE("GetClientDriverName...");
+    XF86DRICheckExtension (dpy, info, False);
+
+    LockDisplay(dpy);
+    GetReq(XF86DRIGetClientDriverName, req);
+    req->reqType = info->codes->major_opcode;
+    req->driReqType = X_XF86DRIGetClientDriverName;
+    req->screen = screen;
+    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+       UnlockDisplay(dpy);
+       SyncHandle();
+        TRACE("GetClientDriverName... return False");
+       return False;
+    }
+
+    *ddxDriverMajorVersion = rep.ddxDriverMajorVersion;
+    *ddxDriverMinorVersion = rep.ddxDriverMinorVersion;
+    *ddxDriverPatchVersion = rep.ddxDriverPatchVersion;
+
+    if (rep.length) {
+        if (!(*clientDriverName = (char *)Xcalloc(rep.clientDriverNameLength + 1, 1))) {
+            _XEatData(dpy, ((rep.clientDriverNameLength+3) & ~3));
+            UnlockDisplay(dpy);
+            SyncHandle();
+            TRACE("GetClientDriverName... return False");
+            return False;
+        }
+       _XReadPad(dpy, *clientDriverName, rep.clientDriverNameLength);
+    } else {
+        *clientDriverName = NULL;
+    }
+    UnlockDisplay(dpy);
+    SyncHandle();
+    TRACE("GetClientDriverName... return True");
+    return True;
+}
+
+PUBLIC Bool XF86DRICreateContextWithConfig(dpy, screen, configID, context,
+       hHWContext)
+    Display* dpy;
+    int screen;
+    int configID;
+    XID* context;
+    drm_context_t * hHWContext;
+{
+    XExtDisplayInfo *info = find_display (dpy);
+    xXF86DRICreateContextReply rep;
+    xXF86DRICreateContextReq *req;
+
+    TRACE("CreateContext...");
+    XF86DRICheckExtension (dpy, info, False);
+
+    LockDisplay(dpy);
+    GetReq(XF86DRICreateContext, req);
+    req->reqType = info->codes->major_opcode;
+    req->driReqType = X_XF86DRICreateContext;
+    req->visual = configID;
+    req->screen = screen;
+    *context = XAllocID(dpy);
+    req->context = *context;
+    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+       UnlockDisplay(dpy);
+       SyncHandle();
+        TRACE("CreateContext... return False");
+       return False;
+    }
+    *hHWContext = rep.hHWContext;
+    UnlockDisplay(dpy);
+    SyncHandle();
+    TRACE("CreateContext... return True");
+    return True;
+}
+
+PUBLIC Bool XF86DRICreateContext(dpy, screen, visual, context, hHWContext)
+    Display* dpy;
+    int screen;
+    Visual* visual;
+    XID* context;
+    drm_context_t * hHWContext;
+{
+    return XF86DRICreateContextWithConfig( dpy, screen, visual->visualid,
+                                          context, hHWContext );
+}
+
+PUBLIC Bool XF86DRIDestroyContext( Display * ndpy, int screen, 
+    XID context )
+{
+    Display * const dpy = (Display *) ndpy;
+    XExtDisplayInfo *info = find_display (dpy);
+    xXF86DRIDestroyContextReq *req;
+
+    TRACE("DestroyContext...");
+    XF86DRICheckExtension (dpy, info, False);
+
+    LockDisplay(dpy);
+    GetReq(XF86DRIDestroyContext, req);
+    req->reqType = info->codes->major_opcode;
+    req->driReqType = X_XF86DRIDestroyContext;
+    req->screen = screen;
+    req->context = context;
+    UnlockDisplay(dpy);
+    SyncHandle();
+    TRACE("DestroyContext... return True");
+    return True;
+}
+
+PUBLIC Bool XF86DRICreateDrawable( Display * ndpy, int screen, 
+    Drawable drawable, drm_drawable_t * hHWDrawable )
+{
+    Display * const dpy = (Display *) ndpy;
+    XExtDisplayInfo *info = find_display (dpy);
+    xXF86DRICreateDrawableReply rep;
+    xXF86DRICreateDrawableReq *req;
+
+    TRACE("CreateDrawable...");
+    XF86DRICheckExtension (dpy, info, False);
+
+    LockDisplay(dpy);
+    GetReq(XF86DRICreateDrawable, req);
+    req->reqType = info->codes->major_opcode;
+    req->driReqType = X_XF86DRICreateDrawable;
+    req->screen = screen;
+    req->drawable = drawable;
+    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+       UnlockDisplay(dpy);
+       SyncHandle();
+        TRACE("CreateDrawable... return False");
+       return False;
+    }
+    *hHWDrawable = rep.hHWDrawable;
+    UnlockDisplay(dpy);
+    SyncHandle();
+    TRACE("CreateDrawable... return True");
+    return True;
+}
+
+PUBLIC Bool XF86DRIDestroyDrawable( Display * ndpy, int screen,
+    Drawable drawable )
+{
+    Display * const dpy = (Display *) ndpy;
+    XExtDisplayInfo *info = find_display (dpy);
+    xXF86DRIDestroyDrawableReq *req;
+
+    TRACE("DestroyDrawable...");
+    XF86DRICheckExtension (dpy, info, False);
+
+    LockDisplay(dpy);
+    GetReq(XF86DRIDestroyDrawable, req);
+    req->reqType = info->codes->major_opcode;
+    req->driReqType = X_XF86DRIDestroyDrawable;
+    req->screen = screen;
+    req->drawable = drawable;
+    UnlockDisplay(dpy);
+    SyncHandle();
+    TRACE("DestroyDrawable... return True");
+    return True;
+}
+
+PUBLIC Bool XF86DRIGetDrawableInfo(Display* dpy, int screen, Drawable drawable,
+    unsigned int* index, unsigned int* stamp,
+    int* X, int* Y, int* W, int* H,
+    int* numClipRects, drm_clip_rect_t ** pClipRects,
+    int* backX, int* backY,
+    int* numBackClipRects, drm_clip_rect_t ** pBackClipRects )
+{
+    XExtDisplayInfo *info = find_display (dpy);
+    xXF86DRIGetDrawableInfoReply rep;
+    xXF86DRIGetDrawableInfoReq *req;
+    int total_rects;
+
+    TRACE("GetDrawableInfo...");
+    XF86DRICheckExtension (dpy, info, False);
+
+    LockDisplay(dpy);
+    GetReq(XF86DRIGetDrawableInfo, req);
+    req->reqType = info->codes->major_opcode;
+    req->driReqType = X_XF86DRIGetDrawableInfo;
+    req->screen = screen;
+    req->drawable = drawable;
+
+    if (!_XReply(dpy, (xReply *)&rep, 1, xFalse)) 
+    {
+       UnlockDisplay(dpy);
+       SyncHandle();
+        TRACE("GetDrawableInfo... return False");
+       return False;
+    }
+    *index = rep.drawableTableIndex;
+    *stamp = rep.drawableTableStamp;
+    *X = (int)rep.drawableX;
+    *Y = (int)rep.drawableY;
+    *W = (int)rep.drawableWidth;
+    *H = (int)rep.drawableHeight;
+    *numClipRects = rep.numClipRects;
+    total_rects = *numClipRects;
+
+    *backX = rep.backX;
+    *backY = rep.backY;
+    *numBackClipRects = rep.numBackClipRects;
+    total_rects += *numBackClipRects;
+
+#if 0
+    /* Because of the fix in Xserver/GL/dri/xf86dri.c, this check breaks
+     * backwards compatibility (Because of the >> 2 shift) but the fix
+     * enables multi-threaded apps to work.
+     */
+    if (rep.length !=  ((((SIZEOF(xXF86DRIGetDrawableInfoReply) - 
+                      SIZEOF(xGenericReply) + 
+                      total_rects * sizeof(drm_clip_rect_t)) + 3) & ~3) >> 2)) {
+        _XEatData(dpy, rep.length);
+       UnlockDisplay(dpy);
+       SyncHandle();
+        TRACE("GetDrawableInfo... return False");
+        return False;
+    }
+#endif
+
+    if (*numClipRects) {
+       int len = sizeof(drm_clip_rect_t) * (*numClipRects);
+
+       *pClipRects = (drm_clip_rect_t *)Xcalloc(len, 1);
+       if (*pClipRects) 
+         _XRead(dpy, (char*)*pClipRects, len);
+    } else {
+        *pClipRects = NULL;
+    }
+
+    if (*numBackClipRects) {
+       int len = sizeof(drm_clip_rect_t) * (*numBackClipRects);
+
+       *pBackClipRects = (drm_clip_rect_t *)Xcalloc(len, 1);
+       if (*pBackClipRects) 
+         _XRead(dpy, (char*)*pBackClipRects, len);
+    } else {
+        *pBackClipRects = NULL;
+    }
+
+    UnlockDisplay(dpy);
+    SyncHandle();
+    TRACE("GetDrawableInfo... return True");
+    return True;
+}
+
+PUBLIC Bool XF86DRIGetDeviceInfo(dpy, screen, hFrameBuffer, 
+       fbOrigin, fbSize, fbStride, devPrivateSize, pDevPrivate)
+    Display* dpy;
+    int screen;
+    drm_handle_t * hFrameBuffer;
+    int* fbOrigin;
+    int* fbSize;
+    int* fbStride;
+    int* devPrivateSize;
+    void** pDevPrivate;
+{
+    XExtDisplayInfo *info = find_display (dpy);
+    xXF86DRIGetDeviceInfoReply rep;
+    xXF86DRIGetDeviceInfoReq *req;
+
+    TRACE("GetDeviceInfo...");
+    XF86DRICheckExtension (dpy, info, False);
+
+    LockDisplay(dpy);
+    GetReq(XF86DRIGetDeviceInfo, req);
+    req->reqType = info->codes->major_opcode;
+    req->driReqType = X_XF86DRIGetDeviceInfo;
+    req->screen = screen;
+    if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
+       UnlockDisplay(dpy);
+       SyncHandle();
+        TRACE("GetDeviceInfo... return False");
+       return False;
+    }
+
+    *hFrameBuffer = rep.hFrameBufferLow;
+    if (sizeof(drm_handle_t) == 8) {
+       int shift = 32; /* var to prevent warning on next line */
+       *hFrameBuffer |= ((drm_handle_t) rep.hFrameBufferHigh) << shift;
+    }
+
+    *fbOrigin = rep.framebufferOrigin;
+    *fbSize = rep.framebufferSize;
+    *fbStride = rep.framebufferStride;
+    *devPrivateSize = rep.devPrivateSize;
+
+    if (rep.length) {
+        if (!(*pDevPrivate = (void *)Xcalloc(rep.devPrivateSize, 1))) {
+            _XEatData(dpy, ((rep.devPrivateSize+3) & ~3));
+            UnlockDisplay(dpy);
+            SyncHandle();
+            TRACE("GetDeviceInfo... return False");
+            return False;
+        }
+       _XRead(dpy, (char*)*pDevPrivate, rep.devPrivateSize);
+    } else {
+        *pDevPrivate = NULL;
+    }
+
+    UnlockDisplay(dpy);
+    SyncHandle();
+    TRACE("GetDeviceInfo... return True");
+    return True;
+}
+
+PUBLIC Bool XF86DRIOpenFullScreen(dpy, screen, drawable)
+    Display* dpy;
+    int screen;
+    Drawable drawable;
+{
+    /* This function and the underlying X protocol are deprecated.
+     */
+    (void) dpy;
+    (void) screen;
+    (void) drawable;
+    return False;
+}
+
+PUBLIC Bool XF86DRICloseFullScreen(dpy, screen, drawable)
+    Display* dpy;
+    int screen;
+    Drawable drawable;
+{
+    /* This function and the underlying X protocol are deprecated.
+     */
+    (void) dpy;
+    (void) screen;
+    (void) drawable;
+    return True;
+}
+
diff --git a/src/gallium/winsys/g3dvl/dri/dri2.c b/src/gallium/winsys/g3dvl/dri/dri2.c
new file mode 100644 (file)
index 0000000..23fb778
--- /dev/null
@@ -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 (krh@redhat.com)
+ */
+
+
+#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 (file)
index 0000000..114e9f8
--- /dev/null
@@ -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 (krh@redhat.com)
+ */
+
+#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 (file)
index 0000000..8588ddd
--- /dev/null
@@ -0,0 +1,282 @@
+/**************************************************************************
+ *
+ * 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_driver.h>
+#include <X11/Xlibint.h>
+
+struct vl_dri_screen
+{
+   struct vl_screen base;
+   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_context *vctx, 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(vctx);
+
+   struct vl_dri_screen *vl_dri_scrn = (struct vl_dri_screen*)vctx->vscreen;
+   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;
+      struct pipe_surface surf_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) {
+         memset(&surf_template, 0, sizeof(surf_template));
+         surf_template.format = front_tex->format;
+         surf_template.usage = PIPE_BIND_RENDER_TARGET;
+         front_surf = vctx->vpipe->create_surface(vctx->vpipe, front_tex, &surf_template);
+      }
+      pipe_resource_reference(&front_tex, NULL);
+      Xfree(dri2_front);
+   }
+
+   return front_surf;
+}
+
+static void
+vl_dri2_flush_frontbuffer(struct pipe_screen *screen,
+                          struct pipe_resource *resource,
+                          unsigned level, unsigned layer,
+                          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(resource);
+   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_context *vctx, Drawable drawable)
+{
+   assert(vctx);
+
+   struct vl_dri_screen *vl_dri_scrn = (struct vl_dri_screen*)vctx->vscreen;
+   assert(vl_dri_scrn);
+
+   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(vctx, 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;
+
+   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->base.pscreen = driver_descriptor.create_screen(vl_dri_scrn->dri_screen->fd);
+
+   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:
+   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);
+   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/gallium/winsys/g3dvl/dri/driclient.c b/src/gallium/winsys/g3dvl/dri/driclient.c
new file mode 100644 (file)
index 0000000..90e48a7
--- /dev/null
@@ -0,0 +1,388 @@
+#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)
+{
+       int             evbase, errbase;
+       char            *driver_name;
+       int             newly_opened;
+       drm_magic_t     magic;
+       drmVersionPtr   drm_version;
+       drm_handle_t    sarea_handle;
+       char            *bus_id;
+       dri_screen_t    *dri_scrn;
+
+       assert(display);
+       assert(dri_screen);
+
+       if (!XF86DRIQueryExtension(display, &evbase, &errbase))
+               return 1;
+
+       dri_scrn = calloc(1, sizeof(dri_screen_t));
+
+       if (!dri_scrn)
+               return 1;
+
+       if (!XF86DRIQueryVersion(display, &dri_scrn->dri.major, &dri_scrn->dri.minor, &dri_scrn->dri.patch))
+               goto free_screen;
+
+       dri_scrn->display = display;
+       dri_scrn->num = screen;
+       dri_scrn->draw_lock_id = 1;
+
+       if (!XF86DRIOpenConnection(display, screen, &sarea_handle, &bus_id))
+               goto free_screen;
+
+       dri_scrn->fd = -1;
+       dri_scrn->fd = drmOpenOnce(NULL, bus_id, &newly_opened);
+       XFree(bus_id);
+
+       if (dri_scrn->fd < 0)
+               goto close_connection;
+
+       if (drmGetMagic(dri_scrn->fd, &magic))
+               goto close_drm;
+
+       drm_version = drmGetVersion(dri_scrn->fd);
+
+       if (!drm_version)
+               goto close_drm;
+
+       dri_scrn->drm.major = drm_version->version_major;
+       dri_scrn->drm.minor = drm_version->version_minor;
+       dri_scrn->drm.patch = drm_version->version_patchlevel;
+       drmFreeVersion(drm_version);
+
+       if (!XF86DRIAuthConnection(display, screen, magic))
+               goto close_drm;
+
+       if (!XF86DRIGetClientDriverName
+       (
+               display,
+               screen,
+               &dri_scrn->ddx.major,
+               &dri_scrn->ddx.minor,
+               &dri_scrn->ddx.patch,
+               &driver_name
+       ))
+               goto close_drm;
+
+       if (drmMap(dri_scrn->fd, sarea_handle, SAREA_MAX, (drmAddress)&dri_scrn->sarea))
+               goto close_drm;
+
+       dri_scrn->drawable_hash = drmHashCreate();
+
+       if (!dri_scrn->drawable_hash)
+               goto unmap_sarea;
+
+       if (dri_framebuf)
+       {
+               if (!XF86DRIGetDeviceInfo
+               (
+                       display,
+                       screen, &dri_framebuf->drm_handle,
+                       &dri_framebuf->base,
+                       &dri_framebuf->size,
+                       &dri_framebuf->stride,
+                       &dri_framebuf->private_size,
+                       &dri_framebuf->private
+               ))
+                       goto destroy_hash;
+       }
+
+       *dri_screen = dri_scrn;
+
+       return 0;
+
+destroy_hash:
+       drmHashDestroy(dri_scrn->drawable_hash);
+unmap_sarea:
+       drmUnmap(dri_scrn->sarea, SAREA_MAX);
+close_drm:
+       drmCloseOnce(dri_scrn->fd);
+close_connection:
+       XF86DRICloseConnection(display, screen);
+free_screen:
+       free(dri_scrn);
+
+       return 1;
+}
+
+int driDestroyScreen(dri_screen_t *dri_screen)
+{
+       Drawable        draw;
+       dri_drawable_t  *dri_draw;
+
+       assert(dri_screen);
+
+       if (drmHashFirst(dri_screen->drawable_hash, &draw, (void**)&dri_draw))
+       {
+               dri_draw->refcount = 1;
+               driDestroyDrawable(dri_draw);
+
+               while (drmHashNext(dri_screen->drawable_hash, &draw, (void**)&dri_draw))
+               {
+                       dri_draw->refcount = 1;
+                       driDestroyDrawable(dri_draw);
+               }
+       }
+
+       drmHashDestroy(dri_screen->drawable_hash);
+       drmUnmap(dri_screen->sarea, SAREA_MAX);
+       drmCloseOnce(dri_screen->fd);
+       XF86DRICloseConnection(dri_screen->display, dri_screen->num);
+       free(dri_screen);
+
+       return 0;
+}
+
+int driCreateDrawable(dri_screen_t *dri_screen, Drawable drawable, dri_drawable_t **dri_drawable)
+{
+       int             evbase, errbase;
+       dri_drawable_t  *dri_draw;
+
+       assert(dri_screen);
+       assert(dri_drawable);
+
+       if (!XF86DRIQueryExtension(dri_screen->display, &evbase, &errbase))
+               return 1;
+
+       if (!drmHashLookup(dri_screen->drawable_hash, drawable, (void**)dri_drawable))
+       {
+               /* Found */
+               (*dri_drawable)->refcount++;
+               return 0;
+       }
+
+       dri_draw = calloc(1, sizeof(dri_drawable_t));
+
+       if (!dri_draw)
+               return 1;
+
+       if (!XF86DRICreateDrawable(dri_screen->display, 0, drawable, &dri_draw->drm_drawable))
+       {
+               free(dri_draw);
+               return 1;
+       }
+
+       dri_draw->x_drawable = drawable;
+       dri_draw->sarea_index = 0;
+       dri_draw->sarea_stamp = NULL;
+       dri_draw->last_sarea_stamp = 0;
+       dri_draw->dri_screen = dri_screen;
+       dri_draw->refcount = 1;
+
+       if (drmHashInsert(dri_screen->drawable_hash, drawable, dri_draw))
+       {
+               XF86DRIDestroyDrawable(dri_screen->display, dri_screen->num, drawable);
+               free(dri_draw);
+               return 1;
+       }
+
+       if (!dri_draw->sarea_stamp || *dri_draw->sarea_stamp != dri_draw->last_sarea_stamp)
+       {
+               DRM_SPINLOCK(&dri_screen->sarea->drawable_lock, dri_screen->draw_lock_id);
+
+               if (driUpdateDrawableInfo(dri_draw))
+               {
+                       XF86DRIDestroyDrawable(dri_screen->display, dri_screen->num, drawable);
+                       free(dri_draw);
+                       DRM_SPINUNLOCK(&dri_screen->sarea->drawable_lock, dri_screen->draw_lock_id);
+                       return 1;
+               }
+
+               DRM_SPINUNLOCK(&dri_screen->sarea->drawable_lock, dri_screen->draw_lock_id);
+       }
+
+       *dri_drawable = dri_draw;
+
+       return 0;
+}
+
+int driUpdateDrawableInfo(dri_drawable_t *dri_drawable)
+{
+       assert(dri_drawable);
+
+       if (dri_drawable->cliprects)
+       {
+               XFree(dri_drawable->cliprects);
+               dri_drawable->cliprects = NULL;
+       }
+       if (dri_drawable->back_cliprects)
+       {
+               XFree(dri_drawable->back_cliprects);
+               dri_drawable->back_cliprects = NULL;
+       }
+
+       DRM_SPINUNLOCK(&dri_drawable->dri_screen->sarea->drawable_lock, dri_drawable->dri_screen->draw_lock_id);
+
+       if (!XF86DRIGetDrawableInfo
+       (
+               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->num_cliprects,
+               &dri_drawable->cliprects,
+               &dri_drawable->back_x,
+               &dri_drawable->back_y,
+               &dri_drawable->num_back_cliprects,
+               &dri_drawable->back_cliprects
+       ))
+       {
+               dri_drawable->sarea_stamp = &dri_drawable->last_sarea_stamp;
+               dri_drawable->num_cliprects = 0;
+               dri_drawable->cliprects = NULL;
+               dri_drawable->num_back_cliprects = 0;
+               dri_drawable->back_cliprects = 0;
+
+               return 1;
+       }
+       else
+               dri_drawable->sarea_stamp = &dri_drawable->dri_screen->sarea->drawableTable[dri_drawable->sarea_index].stamp;
+
+       DRM_SPINLOCK(&dri_drawable->dri_screen->sarea->drawable_lock, dri_drawable->dri_screen->draw_lock_id);
+
+       return 0;
+}
+
+int driDestroyDrawable(dri_drawable_t *dri_drawable)
+{
+       assert(dri_drawable);
+
+       if (--dri_drawable->refcount == 0)
+       {
+               if (dri_drawable->cliprects)
+                       XFree(dri_drawable->cliprects);
+               if (dri_drawable->back_cliprects)
+                       XFree(dri_drawable->back_cliprects);
+               drmHashDelete(dri_drawable->dri_screen->drawable_hash, dri_drawable->x_drawable);
+               XF86DRIDestroyDrawable(dri_drawable->dri_screen->display, dri_drawable->dri_screen->num, dri_drawable->x_drawable);
+               free(dri_drawable);
+       }
+
+       return 0;
+}
+
+int driCreateContext(dri_screen_t *dri_screen, Visual *visual, dri_context_t **dri_context)
+{
+       int             evbase, errbase;
+       dri_context_t   *dri_ctx;
+
+       assert(dri_screen);
+       assert(visual);
+       assert(dri_context);
+
+       if (!XF86DRIQueryExtension(dri_screen->display, &evbase, &errbase))
+               return 1;
+
+       dri_ctx = calloc(1, sizeof(dri_context_t));
+
+       if (!dri_ctx)
+               return 1;
+
+       if (!XF86DRICreateContext(dri_screen->display, dri_screen->num, visual, &dri_ctx->id, &dri_ctx->drm_context))
+       {
+               free(dri_ctx);
+               return 1;
+       }
+
+       dri_ctx->dri_screen = dri_screen;
+       *dri_context = dri_ctx;
+
+       return 0;
+}
+
+int driDestroyContext(dri_context_t *dri_context)
+{
+       assert(dri_context);
+
+       XF86DRIDestroyContext(dri_context->dri_screen->display, dri_context->dri_screen->num, dri_context->id);
+       free(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/gallium/winsys/g3dvl/dri/driclient.h b/src/gallium/winsys/g3dvl/dri/driclient.h
new file mode 100644 (file)
index 0000000..4e4fd36
--- /dev/null
@@ -0,0 +1,117 @@
+#ifndef driclient_h
+#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 */
+
+typedef struct dri_version
+{
+       int major;
+       int minor;
+       int patch;
+} dri_version_t;
+
+typedef struct dri_screen
+{
+       Display                 *display;
+       unsigned int            num;
+       dri_version_t           ddx, dri, drm;
+       int                     draw_lock_id;
+       int                     fd;
+       drm_sarea_t             *sarea;
+       void                    *drawable_hash;
+       void                    *private;
+} dri_screen_t;
+
+struct dri_context;
+
+typedef struct dri_drawable
+{
+       drm_drawable_t          drm_drawable;
+       Drawable                x_drawable;
+       unsigned int            sarea_index;
+       unsigned int            *sarea_stamp;
+       unsigned int            last_sarea_stamp;
+       int                     x, y, w, h;
+       int                     back_x, back_y;
+       int                     num_cliprects, num_back_cliprects;
+       drm_clip_rect_t         *cliprects, *back_cliprects;
+       dri_screen_t            *dri_screen;
+       unsigned int            refcount;
+       void                    *private;
+} dri_drawable_t;
+
+typedef struct dri_context
+{
+       XID                     id;
+       drm_context_t           drm_context;
+       dri_screen_t            *dri_screen;
+       void                    *private;
+} dri_context_t;
+
+typedef struct dri_framebuffer
+{
+       drm_handle_t            drm_handle;
+       int                     base, size, stride;
+       int                     private_size;
+       void                    *private;
+} dri_framebuffer_t;
+
+int driCreateScreen(Display *display, int screen, dri_screen_t **dri_screen, dri_framebuffer_t *dri_framebuf);
+int driDestroyScreen(dri_screen_t *dri_screen);
+int driCreateDrawable(dri_screen_t *dri_screen, Drawable drawable, dri_drawable_t **dri_drawable);
+int driUpdateDrawableInfo(dri_drawable_t *dri_drawable);
+int driDestroyDrawable(dri_drawable_t *dri_drawable);
+int driCreateContext(dri_screen_t *dri_screen, Visual *visual, dri_context_t **dri_context);
+int driDestroyContext(dri_context_t *dri_context);
+
+#define DRI_VALIDATE_DRAWABLE_INFO_ONCE(dri_drawable)                                  \
+do                                                                                     \
+{                                                                                      \
+       if (*(dri_drawable->sarea_stamp) != dri_drawable->last_sarea_stamp)             \
+               driUpdateDrawableInfo(dri_drawable);                                    \
+} while (0)
+
+#define DRI_VALIDATE_DRAWABLE_INFO(dri_screen, dri_drawable)                                   \
+do                                                                                             \
+{                                                                                              \
+       while (*(dri_drawable->sarea_stamp) != dri_drawable->last_sarea_stamp)                  \
+       {                                                                                       \
+               register unsigned int hwContext = dri_screen->sarea->lock.lock &                \
+               ~(DRM_LOCK_HELD | DRM_LOCK_CONT);                                               \
+               DRM_UNLOCK(dri_screen->fd, &dri_screen->sarea->lock, hwContext);                \
+                                                                                               \
+               DRM_SPINLOCK(&dri_screen->sarea->drawable_lock, dri_screen->draw_lock_id);      \
+               DRI_VALIDATE_DRAWABLE_INFO_ONCE(dri_drawable);                                  \
+               DRM_SPINUNLOCK(&dri_screen->sarea->drawable_lock, dri_screen->draw_lock_id);    \
+                                                                                               \
+               DRM_LIGHT_LOCK(dri_screen->fd, &dri_screen->sarea->lock, hwContext);            \
+       }                                                                                       \
+} 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/gallium/winsys/g3dvl/dri/xf86dri.h b/src/gallium/winsys/g3dvl/dri/xf86dri.h
new file mode 100644 (file)
index 0000000..baf80a7
--- /dev/null
@@ -0,0 +1,119 @@
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+Copyright 2000 VA Linux Systems, 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 PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/**
+ * \file xf86dri.h
+ * Protocol numbers and function prototypes for DRI X protocol.
+ *
+ * \author Kevin E. Martin <martin@valinux.com>
+ * \author Jens Owen <jens@tungstengraphics.com>
+ * \author Rickard E. (Rik) Faith <faith@valinux.com>
+ */
+
+#ifndef _XF86DRI_H_
+#define _XF86DRI_H_
+
+#include <X11/Xfuncproto.h>
+#include <xf86drm.h>
+
+#define X_XF86DRIQueryVersion                  0
+#define X_XF86DRIQueryDirectRenderingCapable   1
+#define X_XF86DRIOpenConnection                        2
+#define X_XF86DRICloseConnection               3
+#define X_XF86DRIGetClientDriverName           4
+#define X_XF86DRICreateContext                 5
+#define X_XF86DRIDestroyContext                        6
+#define X_XF86DRICreateDrawable                        7
+#define X_XF86DRIDestroyDrawable               8
+#define X_XF86DRIGetDrawableInfo               9
+#define X_XF86DRIGetDeviceInfo                 10
+#define X_XF86DRIAuthConnection                 11
+#define X_XF86DRIOpenFullScreen                 12   /* Deprecated */
+#define X_XF86DRICloseFullScreen                13   /* Deprecated */
+
+#define XF86DRINumberEvents            0
+
+#define XF86DRIClientNotLocal          0
+#define XF86DRIOperationNotSupported   1
+#define XF86DRINumberErrors            (XF86DRIOperationNotSupported + 1)
+
+#ifndef _XF86DRI_SERVER_
+
+_XFUNCPROTOBEGIN
+
+Bool XF86DRIQueryExtension( Display *dpy, int *event_base, int *error_base );
+
+Bool XF86DRIQueryVersion( Display *dpy, int *majorVersion, int *minorVersion,
+    int *patchVersion );
+
+Bool XF86DRIQueryDirectRenderingCapable( Display *dpy, int screen,
+    Bool *isCapable );
+
+Bool XF86DRIOpenConnection( Display *dpy, int screen, drm_handle_t *hSAREA,
+    char **busIDString );
+
+Bool XF86DRIAuthConnection( Display *dpy, int screen, drm_magic_t magic );
+
+Bool XF86DRICloseConnection( Display *dpy, int screen );
+
+Bool XF86DRIGetClientDriverName( Display *dpy, int screen,
+    int *ddxDriverMajorVersion, int *ddxDriverMinorVersion,
+    int *ddxDriverPatchVersion, char **clientDriverName );
+
+Bool XF86DRICreateContext( Display *dpy, int screen, Visual *visual,
+    XID *ptr_to_returned_context_id, drm_context_t *hHWContext );
+
+Bool XF86DRICreateContextWithConfig( Display *dpy, int screen, int configID,
+    XID *ptr_to_returned_context_id, drm_context_t *hHWContext );
+
+Bool XF86DRIDestroyContext( Display *dpy, int screen,
+    XID context_id );
+
+Bool XF86DRICreateDrawable( Display *dpy, int screen,
+    Drawable drawable, drm_drawable_t *hHWDrawable );
+
+Bool XF86DRIDestroyDrawable( Display *dpy, int screen, 
+    Drawable drawable);
+
+Bool XF86DRIGetDrawableInfo( Display *dpy, int screen, Drawable drawable,
+    unsigned int *index, unsigned int *stamp, 
+    int *X, int *Y, int *W, int *H,
+    int *numClipRects, drm_clip_rect_t ** pClipRects,
+    int *backX, int *backY,
+    int *numBackClipRects, drm_clip_rect_t **pBackClipRects );
+
+Bool XF86DRIGetDeviceInfo( Display *dpy, int screen,
+    drm_handle_t *hFrameBuffer, int *fbOrigin, int *fbSize,
+    int *fbStride, int *devPrivateSize, void **pDevPrivate );
+
+_XFUNCPROTOEND
+
+#endif /* _XF86DRI_SERVER_ */
+
+#endif /* _XF86DRI_H_ */
+
diff --git a/src/gallium/winsys/g3dvl/dri/xf86dristr.h b/src/gallium/winsys/g3dvl/dri/xf86dristr.h
new file mode 100644 (file)
index 0000000..b834bd1
--- /dev/null
@@ -0,0 +1,342 @@
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+Copyright 2000 VA Linux Systems, 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 PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ *   Kevin E. Martin <martin@valinux.com>
+ *   Jens Owen <jens@tungstengraphics.com>
+ *   Rickard E. (Rik) Fiath <faith@valinux.com>
+ *
+ */
+
+#ifndef _XF86DRISTR_H_
+#define _XF86DRISTR_H_
+
+#include "xf86dri.h"
+
+#define XF86DRINAME "XFree86-DRI"
+
+/* The DRI version number.  This was originally set to be the same of the
+ * XFree86 version number.  However, this version is really indepedent of
+ * the XFree86 version.
+ *
+ * Version History:
+ *    4.0.0: Original
+ *    4.0.1: Patch to bump clipstamp when windows are destroyed, 28 May 02
+ *    4.1.0: Add transition from single to multi in DRMInfo rec, 24 Jun 02
+ */
+#define XF86DRI_MAJOR_VERSION  4
+#define XF86DRI_MINOR_VERSION  1
+#define XF86DRI_PATCH_VERSION  0
+
+typedef struct _XF86DRIQueryVersion {
+    CARD8      reqType;                /* always DRIReqCode */
+    CARD8      driReqType;             /* always X_DRIQueryVersion */
+    CARD16     length B16;
+} xXF86DRIQueryVersionReq;
+#define sz_xXF86DRIQueryVersionReq     4
+
+typedef struct {
+    BYTE       type;                   /* X_Reply */
+    BOOL       pad1;
+    CARD16     sequenceNumber B16;
+    CARD32     length B32;
+    CARD16     majorVersion B16;       /* major version of DRI protocol */
+    CARD16     minorVersion B16;       /* minor version of DRI protocol */
+    CARD32     patchVersion B32;       /* patch version of DRI protocol */
+    CARD32     pad3 B32;
+    CARD32     pad4 B32;
+    CARD32     pad5 B32;
+    CARD32     pad6 B32;
+} xXF86DRIQueryVersionReply;
+#define sz_xXF86DRIQueryVersionReply   32
+
+typedef struct _XF86DRIQueryDirectRenderingCapable {
+    CARD8      reqType;                /* always DRIReqCode */
+    CARD8      driReqType;             /* X_DRIQueryDirectRenderingCapable */
+    CARD16     length B16;
+    CARD32     screen B32;
+} xXF86DRIQueryDirectRenderingCapableReq;
+#define sz_xXF86DRIQueryDirectRenderingCapableReq      8
+
+typedef struct {
+    BYTE       type;                   /* X_Reply */
+    BOOL       pad1;
+    CARD16     sequenceNumber B16;
+    CARD32     length B32;
+    BOOL       isCapable;
+    BOOL       pad2;
+    BOOL       pad3;
+    BOOL       pad4;
+    CARD32     pad5 B32;
+    CARD32     pad6 B32;
+    CARD32     pad7 B32;
+    CARD32     pad8 B32;
+    CARD32     pad9 B32;
+} xXF86DRIQueryDirectRenderingCapableReply;
+#define sz_xXF86DRIQueryDirectRenderingCapableReply    32
+
+typedef struct _XF86DRIOpenConnection {
+    CARD8      reqType;                /* always DRIReqCode */
+    CARD8      driReqType;             /* always X_DRIOpenConnection */
+    CARD16     length B16;
+    CARD32     screen B32;
+} xXF86DRIOpenConnectionReq;
+#define sz_xXF86DRIOpenConnectionReq   8
+
+typedef struct {
+    BYTE       type;                   /* X_Reply */
+    BOOL       pad1;
+    CARD16     sequenceNumber B16;
+    CARD32     length B32;
+    CARD32     hSAREALow B32;
+    CARD32     hSAREAHigh B32;
+    CARD32     busIdStringLength B32;
+    CARD32     pad6 B32;
+    CARD32     pad7 B32;
+    CARD32     pad8 B32;
+} xXF86DRIOpenConnectionReply;
+#define sz_xXF86DRIOpenConnectionReply 32
+
+typedef struct _XF86DRIAuthConnection {
+    CARD8      reqType;                /* always DRIReqCode */
+    CARD8      driReqType;             /* always X_DRICloseConnection */
+    CARD16     length B16;
+    CARD32     screen B32;
+    CARD32      magic B32;
+} xXF86DRIAuthConnectionReq;
+#define sz_xXF86DRIAuthConnectionReq   12
+
+typedef struct {
+    BYTE        type;
+    BOOL        pad1;
+    CARD16      sequenceNumber B16;
+    CARD32      length B32;
+    CARD32      authenticated B32;
+    CARD32      pad2 B32;
+    CARD32      pad3 B32;
+    CARD32      pad4 B32;
+    CARD32      pad5 B32;
+    CARD32      pad6 B32;
+} xXF86DRIAuthConnectionReply;
+#define zx_xXF86DRIAuthConnectionReply  32
+
+typedef struct _XF86DRICloseConnection {
+    CARD8      reqType;                /* always DRIReqCode */
+    CARD8      driReqType;             /* always X_DRICloseConnection */
+    CARD16     length B16;
+    CARD32     screen B32;
+} xXF86DRICloseConnectionReq;
+#define sz_xXF86DRICloseConnectionReq  8
+
+typedef struct _XF86DRIGetClientDriverName {
+    CARD8      reqType;                /* always DRIReqCode */
+    CARD8      driReqType;             /* always X_DRIGetClientDriverName */
+    CARD16     length B16;
+    CARD32     screen B32;
+} xXF86DRIGetClientDriverNameReq;
+#define sz_xXF86DRIGetClientDriverNameReq      8
+
+typedef struct {
+    BYTE       type;                   /* X_Reply */
+    BOOL       pad1;
+    CARD16     sequenceNumber B16;
+    CARD32     length B32;
+    CARD32     ddxDriverMajorVersion B32;
+    CARD32     ddxDriverMinorVersion B32;
+    CARD32     ddxDriverPatchVersion B32;
+    CARD32     clientDriverNameLength B32;
+    CARD32     pad5 B32;
+    CARD32     pad6 B32;
+} xXF86DRIGetClientDriverNameReply;
+#define sz_xXF86DRIGetClientDriverNameReply    32
+
+typedef struct _XF86DRICreateContext {
+    CARD8      reqType;                /* always DRIReqCode */
+    CARD8      driReqType;             /* always X_DRICreateContext */
+    CARD16     length B16;
+    CARD32     screen B32;
+    CARD32     visual B32;
+    CARD32     context B32;
+} xXF86DRICreateContextReq;
+#define sz_xXF86DRICreateContextReq    16
+
+typedef struct {
+    BYTE       type;                   /* X_Reply */
+    BOOL       pad1;
+    CARD16     sequenceNumber B16;
+    CARD32     length B32;
+    CARD32     hHWContext B32;
+    CARD32     pad2 B32;
+    CARD32     pad3 B32;
+    CARD32     pad4 B32;
+    CARD32     pad5 B32;
+    CARD32     pad6 B32;
+} xXF86DRICreateContextReply;
+#define sz_xXF86DRICreateContextReply  32
+
+typedef struct _XF86DRIDestroyContext {
+    CARD8      reqType;                /* always DRIReqCode */
+    CARD8      driReqType;             /* always X_DRIDestroyContext */
+    CARD16     length B16;
+    CARD32     screen B32;
+    CARD32     context B32;
+} xXF86DRIDestroyContextReq;
+#define sz_xXF86DRIDestroyContextReq   12
+
+typedef struct _XF86DRICreateDrawable {
+    CARD8      reqType;                /* always DRIReqCode */
+    CARD8      driReqType;             /* always X_DRICreateDrawable */
+    CARD16     length B16;
+    CARD32     screen B32;
+    CARD32     drawable B32;
+} xXF86DRICreateDrawableReq;
+#define sz_xXF86DRICreateDrawableReq   12
+
+typedef struct {
+    BYTE       type;                   /* X_Reply */
+    BOOL       pad1;
+    CARD16     sequenceNumber B16;
+    CARD32     length B32;
+    CARD32     hHWDrawable B32;
+    CARD32     pad2 B32;
+    CARD32     pad3 B32;
+    CARD32     pad4 B32;
+    CARD32     pad5 B32;
+    CARD32     pad6 B32;
+} xXF86DRICreateDrawableReply;
+#define sz_xXF86DRICreateDrawableReply 32
+
+typedef struct _XF86DRIDestroyDrawable {
+    CARD8      reqType;                /* always DRIReqCode */
+    CARD8      driReqType;             /* always X_DRIDestroyDrawable */
+    CARD16     length B16;
+    CARD32     screen B32;
+    CARD32     drawable B32;
+} xXF86DRIDestroyDrawableReq;
+#define sz_xXF86DRIDestroyDrawableReq  12
+
+typedef struct _XF86DRIGetDrawableInfo {
+    CARD8      reqType;                /* always DRIReqCode */
+    CARD8      driReqType;             /* always X_DRIGetDrawableInfo */
+    CARD16     length B16;
+    CARD32     screen B32;
+    CARD32     drawable B32;
+} xXF86DRIGetDrawableInfoReq;
+#define sz_xXF86DRIGetDrawableInfoReq  12
+
+typedef struct {
+    BYTE       type;                   /* X_Reply */
+    BOOL       pad1;
+    CARD16     sequenceNumber B16;
+    CARD32     length B32;
+    CARD32     drawableTableIndex B32;
+    CARD32     drawableTableStamp B32;
+    INT16      drawableX B16;
+    INT16      drawableY B16;
+    INT16      drawableWidth B16;
+    INT16      drawableHeight B16;
+    CARD32     numClipRects B32;
+    INT16       backX B16;
+    INT16       backY B16;
+    CARD32      numBackClipRects B32;
+} xXF86DRIGetDrawableInfoReply;
+
+#define sz_xXF86DRIGetDrawableInfoReply        36
+
+
+typedef struct _XF86DRIGetDeviceInfo {
+    CARD8      reqType;                /* always DRIReqCode */
+    CARD8      driReqType;             /* always X_DRIGetDeviceInfo */
+    CARD16     length B16;
+    CARD32     screen B32;
+} xXF86DRIGetDeviceInfoReq;
+#define sz_xXF86DRIGetDeviceInfoReq    8
+
+typedef struct {
+    BYTE       type;                   /* X_Reply */
+    BOOL       pad1;
+    CARD16     sequenceNumber B16;
+    CARD32     length B32;
+    CARD32     hFrameBufferLow B32;
+    CARD32     hFrameBufferHigh B32;
+    CARD32     framebufferOrigin B32;
+    CARD32     framebufferSize B32;
+    CARD32     framebufferStride B32;
+    CARD32     devPrivateSize B32;
+} xXF86DRIGetDeviceInfoReply;
+#define sz_xXF86DRIGetDeviceInfoReply  32
+
+typedef struct _XF86DRIOpenFullScreen {
+    CARD8       reqType;       /* always DRIReqCode */
+    CARD8       driReqType;    /* always X_DRIOpenFullScreen */
+    CARD16      length B16;
+    CARD32      screen B32;
+    CARD32      drawable B32;
+} xXF86DRIOpenFullScreenReq;
+#define sz_xXF86DRIOpenFullScreenReq    12
+
+typedef struct {
+    BYTE        type;
+    BOOL        pad1;
+    CARD16      sequenceNumber B16;
+    CARD32      length B32;
+    CARD32      isFullScreen B32;
+    CARD32      pad2 B32;
+    CARD32      pad3 B32;
+    CARD32      pad4 B32;
+    CARD32      pad5 B32;
+    CARD32      pad6 B32;
+} xXF86DRIOpenFullScreenReply;
+#define sz_xXF86DRIOpenFullScreenReply  32
+
+typedef struct _XF86DRICloseFullScreen {
+    CARD8       reqType;       /* always DRIReqCode */
+    CARD8       driReqType;    /* always X_DRICloseFullScreen */
+    CARD16      length B16;
+    CARD32      screen B32;
+    CARD32      drawable B32;
+} xXF86DRICloseFullScreenReq;
+#define sz_xXF86DRICloseFullScreenReq   12
+
+typedef struct {
+    BYTE        type;
+    BOOL        pad1;
+    CARD16      sequenceNumber B16;
+    CARD32      length B32;
+    CARD32      pad2 B32;
+    CARD32      pad3 B32;
+    CARD32      pad4 B32;
+    CARD32      pad5 B32;
+    CARD32      pad6 B32;
+    CARD32      pad7 B32;
+} xXF86DRICloseFullScreenReply;
+#define sz_xXF86DRICloseFullScreenReply  32
+
+
+#endif /* _XF86DRISTR_H_ */
diff --git a/src/gallium/winsys/g3dvl/drm/Makefile b/src/gallium/winsys/g3dvl/drm/Makefile
new file mode 100644 (file)
index 0000000..0711f44
--- /dev/null
@@ -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 (file)
index 0000000..2b79dee
--- /dev/null
@@ -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 (file)
index 0000000..5c55186
--- /dev/null
@@ -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 (file)
index 0000000..0f7fd1c
--- /dev/null
@@ -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 (file)
index 0000000..58f5488
--- /dev/null
@@ -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_context *vctx, 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 (file)
index 0000000..cc80583
--- /dev/null
@@ -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;
+   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);
+}
index edd774e0e0052758a2a623a13230ddb6074b570c..06e8f6910f339ed49e439f9c9f52c1a9433cc231 100644 (file)
@@ -63,12 +63,25 @@ struct r600_bo *r600_bo(struct radeon *radeon,
         * and are used for uploads and downloads from regular
         * resources.  We generate them internally for some transfers.
         */
-       if (usage == PIPE_USAGE_STAGING)
-               bo->domains = RADEON_GEM_DOMAIN_CPU | RADEON_GEM_DOMAIN_GTT;
-       else
-               bo->domains = (RADEON_GEM_DOMAIN_CPU |
+       switch (usage) {
+        case PIPE_USAGE_DEFAULT:
+               bo->domains = RADEON_GEM_DOMAIN_CPU |
                                RADEON_GEM_DOMAIN_GTT |
-                               RADEON_GEM_DOMAIN_VRAM);
+                               RADEON_GEM_DOMAIN_VRAM;
+                break;
+
+        case PIPE_USAGE_DYNAMIC:
+        case PIPE_USAGE_STREAM:
+        case PIPE_USAGE_STAGING:
+               bo->domains = RADEON_GEM_DOMAIN_CPU |
+                                RADEON_GEM_DOMAIN_GTT;
+               break;
+
+        case PIPE_USAGE_STATIC:
+        case PIPE_USAGE_IMMUTABLE:
+               bo->domains = RADEON_GEM_DOMAIN_VRAM;
+               break;
+        }
 
        pipe_reference_init(&bo->reference, 1);
        return bo;