[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#656719: Please provide xvmc and vdpau Gallium3D video acceleration drivers



This patch provide xvmc/vdpau support for mesa-9.1.3 from debian unstable.

changes:
  * add libxvmc1-gallium-drivers and libvdpau1-gallium-drivers packages
    to provide xvmc and vdpau video acceleration for Nvidia and AMD
    Radeon chips.
  * backport radeon UVD support from upstream mesa sources (linux >= 3.10
    and latest radeon firmware files required)

Building were tested on i386 and amd64 architectures.

Mikhail Kshevetskiy

From 6f2808966e689e7b8560bc0af2f48db431d736bf Mon Sep 17 00:00:00 2001
From: Mikhail Kshevetskiy <mikhail.kshevetskiy@gmail.com>
Date: Sun, 9 Jun 2013 03:25:55 +0400
Subject: [PATCH] add xvmc/vdpau support, add UVD support for radeon

---
 debian/changelog                                   |   15 +
 debian/control                                     |   76 +
 debian/libvdpau1-gallium-drivers.install.in        |    1 +
 debian/libxvmc1-gallium-drivers.install.in         |    1 +
 ...n-winsys-add-uvd-ring-support-to-winsys-v3.diff |  112 +
 .../102-radeon-uvd-add-UVD-implementation-v5.diff  | 2262 ++++++++++++++++++++
 ...nable-detection-of-vdpau-and-xvmc-by-defau.diff |   38 +
 ...d-cleanup-disabling-tiling-on-pre-EG-asics.diff |   61 +
 ...deonsi-cleanup-disabling-tiling-for-UVD-v3.diff |   61 +
 ...106-radeon-uvd-stop-using-anonymous-unions.diff |  203 ++
 ...stop-advertising-MPEG4-on-UVD-2.x-chips-v2.diff |   85 +
 ...-vl-compositor-cleanup-background-clearing.diff |  156 ++
 ...buffer-use-2D_ARRAY-instead-of-3D-textures.diff |  340 +++
 ...vdpau-fix-background-handling-in-the-mixer.diff |   59 +
 ...-radeon-uvd-fix-quant-scan-order-for-mpeg2.diff |   42 +
 ...-Fix-build-failure-with-non-standard-libdr.diff |   33 +
 .../113-radeon-uvd-fix-some-MPEG4-artifacts.diff   |   76 +
 .../114-vl-buffers-fix-typo-in-function-name.diff  |  150 ++
 ...x-for-commit-7d2f2a0c890b1993532a45c8c392c.diff |  223 ++
 ...n-uvd-enable-interlaced-buffers-by-default.diff |   66 +
 .../117-st-xvmc-tests-Fix-build-failure-v2.diff    |   34 +
 ...au-fix-PresentationQueueQuerySurfaceStatus.diff |  107 +
 ...dpau-invalidate-the-handles-on-destruction.diff |   58 +
 ...remove-vlCreateHTAB-from-surface-functions.diff |   50 +
 ...-destroy-handle-table-only-when-it-s-empty.diff |   29 +
 debian/patches/series                              |   21 +
 debian/rules                                       |    3 +
 27 files changed, 4362 insertions(+)
 create mode 100644 debian/libvdpau1-gallium-drivers.install.in
 create mode 100644 debian/libxvmc1-gallium-drivers.install.in
 create mode 100644 debian/patches/101-radeon-winsys-add-uvd-ring-support-to-winsys-v3.diff
 create mode 100644 debian/patches/102-radeon-uvd-add-UVD-implementation-v5.diff
 create mode 100644 debian/patches/103-autoconf-enable-detection-of-vdpau-and-xvmc-by-defau.diff
 create mode 100644 debian/patches/104-r600-uvd-cleanup-disabling-tiling-on-pre-EG-asics.diff
 create mode 100644 debian/patches/105-radeonsi-cleanup-disabling-tiling-for-UVD-v3.diff
 create mode 100644 debian/patches/106-radeon-uvd-stop-using-anonymous-unions.diff
 create mode 100644 debian/patches/107-r600-uvd-stop-advertising-MPEG4-on-UVD-2.x-chips-v2.diff
 create mode 100644 debian/patches/108-vl-compositor-cleanup-background-clearing.diff
 create mode 100644 debian/patches/109-vl-buffer-use-2D_ARRAY-instead-of-3D-textures.diff
 create mode 100644 debian/patches/110-st-vdpau-fix-background-handling-in-the-mixer.diff
 create mode 100644 debian/patches/111-radeon-uvd-fix-quant-scan-order-for-mpeg2.diff
 create mode 100644 debian/patches/112-radeon-uvd-Fix-build-failure-with-non-standard-libdr.diff
 create mode 100644 debian/patches/113-radeon-uvd-fix-some-MPEG4-artifacts.diff
 create mode 100644 debian/patches/114-vl-buffers-fix-typo-in-function-name.diff
 create mode 100644 debian/patches/115-vl-idct-fix-for-commit-7d2f2a0c890b1993532a45c8c392c.diff
 create mode 100644 debian/patches/116-radeon-uvd-enable-interlaced-buffers-by-default.diff
 create mode 100644 debian/patches/117-st-xvmc-tests-Fix-build-failure-v2.diff
 create mode 100644 debian/patches/118-vl-vdpau-fix-PresentationQueueQuerySurfaceStatus.diff
 create mode 100644 debian/patches/119-st-vdpau-invalidate-the-handles-on-destruction.diff
 create mode 100644 debian/patches/120-st-vdpau-remove-vlCreateHTAB-from-surface-functions.diff
 create mode 100644 debian/patches/121-st-vdpau-destroy-handle-table-only-when-it-s-empty.diff

diff --git a/debian/changelog b/debian/changelog
index 2c81409..4fddb69 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,18 @@
+mesa (9.1.3-7) unstable; urgency=low
+
+  [ Mikhail Kshevetskiy ]
+
+  * debian: Add libxvmc1-gallium-drivers and libvdpau1-gallium-drivers
+    packages to provide xvmc and vdpau video acceleration for nouveau,
+    radeon and softpipe drivers.
+  * backport radeon UVD support from upstream mesa sources (linux >= 3.10
+    and latest radeon firmware files required). Cherry-pick commit bba0e116,
+    fa2f8cd7, ec28efda, 47dd97b4, eb41a133, bf7fc154, e18d2ec8, 2fb23750,
+    ccf1273f, bf6c4246, 75a2e4d3, 0ae61d1e, 10de99f0, 36755857, 16f22fd1,
+    4b4b8319, 5ff81cfd, e195d301, 8ea34fa0, f796b674, 5328c800.
+
+ -- Mikhail Kshevetskiy <mikhail.kshevetskiy@gmail.com>  Sun, 09 Jun 2013 02:14:05 +0400
+
 mesa (9.1.3-6) unstable; urgency=low
 
   * Team upload.
diff --git a/debian/control b/debian/control
index 04e5305..a965066 100644
--- a/debian/control
+++ b/debian/control
@@ -32,6 +32,8 @@ Build-Depends:
  bison,
  llvm-3.2-dev (>= 1:3.2repack-7~) [amd64 i386 kfreebsd-amd64 kfreebsd-i386 armhf],
  libwayland-dev (>= 1.0.2) [linux-any],
+ libxvmc-dev,
+ libvdpau-dev,
 Vcs-Git: git://git.debian.org/git/pkg-xorg/lib/mesa
 Vcs-Browser: http://git.debian.org/?p=pkg-xorg/lib/mesa.git
 Homepage: http://mesa3d.sourceforge.net/
@@ -776,4 +778,78 @@ Description: Mesa Off-screen rendering extension -- development files
  .
  For more information on OSmesa see the libosmesa6 package.
 
+Package: libvdpau1-gallium-drivers
+Section: libs
+Priority: optional
+Architecture: linux-any
+Depends:
+ ${shlibs:Depends},
+ ${misc:Depends},
+ linux-firmware-nonfree
+Recommends: libgl1-mesa-dri, libxvmc-mesa-drivers
+Multi-Arch: same
+Description: VDPAU Gallium3D video acceleration drivers
+ This package provide vdpau gallium drivers to accelerate video decoding
+ on r300/r600/radeonsi (AMD Radeon chips), nouveau (NVidia chips) and
+ softpipe.
+ .
+ Features:
+   r300:          MPEG1, MPEG2
+   r600/radeonsi: MPEG1, MPEG2, H264, VC1, MPEG4 (see note)
+   nouveau:       ???
+   softpipe:      ???
+ .
+ Recent MPlayer versions use the provided library automatically. But you
+ can manually use it using for example the following command line.
+ .
+ .    mplayer -vo vdpau -vc ffmpeg12vdpau example.mpeg2
+ .
+ Note: you'll need UVD support in your kernel to get H264/VC1/MPEG4
+       video decoding on AMD Radeon chips (linux >= 3.10 and latest
+       radeon firmware files required).
+ .
+ Beware that this is work in progress and might not work as expected.
+
+Package: libvdpau1-gallium-drivers-dbg
+Section: debug
+Priority: extra
+Architecture: linux-any
+Depends:
+ libvdpau1-gallium-drivers (= ${binary:Version}),
+ ${misc:Depends}
+Multi-Arch: same
+Description: debugging symbols for VDPAU Gallium3D video acceleration drivers
+ This package contains the debugging symbols for the VDPAU gallium drivers.
+
+Package: libxvmc1-gallium-drivers
+Section: libs
+Priority: optional
+Architecture: linux-any
+Depends:
+ libxvmc1,
+ ${shlibs:Depends},
+ ${misc:Depends},
+Recommends: libgl1-mesa-dri, libvdpau1-gallium-drivers
+Multi-Arch: same
+Description: XvMC Gallium3D video acceleration drivers
+ This package provide accelerated XvMC gallium drivers for
+ r300/r600/radeonsi (AMD Radeon chips), nouveau (NVidia chips) and
+ softpipe.
+ .
+ You have to edit `/etc/X11/XvMCConfig` and list your hardware specific
+ library in there, for example `libXvMCr600.so.1`.
+ .
+ Beware that this is work in progress and might not work as expected.
+
+Package: libxvmc1-gallium-drivers-dbg
+Section: debug
+Priority: extra
+Architecture: linux-any
+Depends:
+ libxvmc1-gallium-drivers (= ${binary:Version}),
+ ${misc:Depends}
+Multi-Arch: same
+Description: debugging symbols for XvMC Gallium3D video acceleration drivers
+ This package contains the debugging symbols for the XvMCV gallium libraries.
+
 # vim: tw=0
diff --git a/debian/libvdpau1-gallium-drivers.install.in b/debian/libvdpau1-gallium-drivers.install.in
new file mode 100644
index 0000000..ab8d553
--- /dev/null
+++ b/debian/libvdpau1-gallium-drivers.install.in
@@ -0,0 +1 @@
+dri/usr/lib/${DEB_HOST_MULTIARCH}/vdpau/libvdpau_*		usr/lib/${DEB_HOST_MULTIARCH}/vdpau
diff --git a/debian/libxvmc1-gallium-drivers.install.in b/debian/libxvmc1-gallium-drivers.install.in
new file mode 100644
index 0000000..f08bad2
--- /dev/null
+++ b/debian/libxvmc1-gallium-drivers.install.in
@@ -0,0 +1 @@
+dri/usr/lib/${DEB_HOST_MULTIARCH}/libXvMC*		usr/lib/${DEB_HOST_MULTIARCH}
diff --git a/debian/patches/101-radeon-winsys-add-uvd-ring-support-to-winsys-v3.diff b/debian/patches/101-radeon-winsys-add-uvd-ring-support-to-winsys-v3.diff
new file mode 100644
index 0000000..ab4c179
--- /dev/null
+++ b/debian/patches/101-radeon-winsys-add-uvd-ring-support-to-winsys-v3.diff
@@ -0,0 +1,112 @@
+From bba0e1161fc81be5ccd810f638ffff95f1490b0c Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
+Date: Mon, 8 Apr 2013 16:41:01 +0200
+Subject: [PATCH 01/17] radeon/winsys: add uvd ring support to winsys v3
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Separated from UVD patch for clarity.
+
+v2: sync with next tree for 3.10
+v3: as pointed out by Andreas Bool check for drm minor >= 32
+
+http://cgit.freedesktop.org/~agd5f/linux/log/?h=drm-next-3.10-wip
+
+Signed-off-by: Christian König <christian.koenig@amd.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+Reviewed-by: Andreas Boll <andreas.boll.dev@gmail.com>
+---
+ src/gallium/winsys/radeon/drm/radeon_drm_cs.c     |   11 +++++++++++
+ src/gallium/winsys/radeon/drm/radeon_drm_winsys.c |   17 +++++++++++++++++
+ src/gallium/winsys/radeon/drm/radeon_winsys.h     |    3 +++
+ 3 files changed, 31 insertions(+)
+
+diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c
+index 6a7115b..1699c87 100644
+--- a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c
++++ b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c
+@@ -94,6 +94,10 @@
+ #define RADEON_CS_RING_DMA          2
+ #endif
+ 
++#ifndef RADEON_CS_RING_UVD
++#define RADEON_CS_RING_UVD          3
++#endif
++
+ #ifndef RADEON_CS_END_OF_FRAME
+ #define RADEON_CS_END_OF_FRAME      0x04
+ #endif
+@@ -486,6 +490,13 @@ static void radeon_drm_cs_flush(struct radeon_winsys_cs *rcs, unsigned flags)
+                 cs->cst->flags[0] |= RADEON_CS_USE_VM;
+             }
+             break;
++
++        case RING_UVD:
++            cs->cst->flags[0] = 0;
++            cs->cst->flags[1] = RADEON_CS_RING_UVD;
++            cs->cst->cs.num_chunks = 3;
++            break;
++
+         default:
+         case RING_GFX:
+             cs->cst->flags[0] = 0;
+diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c
+index 62ba4b1..801ca43 100644
+--- a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c
++++ b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c
+@@ -90,6 +90,14 @@
+ #define RADEON_INFO_TIMESTAMP 0x11
+ #endif
+ 
++#ifndef RADEON_INFO_RING_WORKING
++#define RADEON_INFO_RING_WORKING 0x15
++#endif
++
++#ifndef RADEON_CS_RING_UVD
++#define RADEON_CS_RING_UVD	3
++#endif
++
+ static struct util_hash_table *fd_tab = NULL;
+ 
+ /* Enable/disable feature access for one command stream.
+@@ -323,6 +331,15 @@ static boolean do_winsys_init(struct radeon_drm_winsys *ws)
+         ws->info.r600_has_dma = TRUE;
+     }
+ 
++    /* Check for UVD */
++    ws->info.has_uvd = FALSE;
++    if (ws->info.drm_minor >= 32) {
++	uint32_t value = RADEON_CS_RING_UVD;
++        if (radeon_get_drm_value(ws->fd, RADEON_INFO_RING_WORKING,
++                                 "UVD Ring working", &value))
++            ws->info.has_uvd = value;
++    }
++
+     /* Get GEM info. */
+     retval = drmCommandWriteRead(ws->fd, DRM_RADEON_GEM_INFO,
+             &gem_info, sizeof(gem_info));
+diff --git a/src/gallium/winsys/radeon/drm/radeon_winsys.h b/src/gallium/winsys/radeon/drm/radeon_winsys.h
+index c57a87d..64b597c 100644
+--- a/src/gallium/winsys/radeon/drm/radeon_winsys.h
++++ b/src/gallium/winsys/radeon/drm/radeon_winsys.h
+@@ -142,6 +142,7 @@ enum chip_class {
+ enum ring_type {
+     RING_GFX = 0,
+     RING_DMA,
++    RING_UVD,
+     RING_LAST,
+ };
+ 
+@@ -165,6 +166,8 @@ struct radeon_info {
+     uint32_t                    drm_minor;
+     uint32_t                    drm_patchlevel;
+ 
++    boolean                     has_uvd;
++
+     uint32_t                    r300_num_gb_pipes;
+     uint32_t                    r300_num_z_pipes;
+ 
+-- 
+1.7.10.4
+
diff --git a/debian/patches/102-radeon-uvd-add-UVD-implementation-v5.diff b/debian/patches/102-radeon-uvd-add-UVD-implementation-v5.diff
new file mode 100644
index 0000000..d7533b4
--- /dev/null
+++ b/debian/patches/102-radeon-uvd-add-UVD-implementation-v5.diff
@@ -0,0 +1,2262 @@
+From fa2f8cd74dbd4ed8e1b7e11a2badf14a88efc373 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
+Date: Wed, 3 Apr 2013 10:18:35 +0200
+Subject: [PATCH 02/17] radeon/uvd: add UVD implementation v5
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Just everything you need for UVD with r600g and radeonsi.
+
+v2: move UVD code to radeon subdir, clean up build system additions,
+    remove an unused SI function, disable tiling on SI for now.
+v3: some minor indentation fix and rebased
+v4: dpb size calculation fixed
+v5: implement proper fall-back in case the kernel doesn't support UVD,
+    based on patches from Andreas Boll but cleaned up a bit more.
+
+Signed-off-by: Christian König <christian.koenig@amd.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+---
+ configure.ac                                  |    5 +-
+ docs/README.UVD                               |   13 +
+ src/gallium/drivers/Makefile.am               |   10 +-
+ src/gallium/drivers/r600/Makefile.am          |    4 +-
+ src/gallium/drivers/r600/Makefile.sources     |    3 +-
+ src/gallium/drivers/r600/r600_pipe.c          |   21 +-
+ src/gallium/drivers/r600/r600_pipe.h          |   12 +
+ src/gallium/drivers/r600/r600_uvd.c           |  178 ++++
+ src/gallium/drivers/radeon/Makefile.am        |   25 +-
+ src/gallium/drivers/radeon/Makefile.sources   |    7 +-
+ src/gallium/drivers/radeon/radeon_uvd.c       | 1111 +++++++++++++++++++++++++
+ src/gallium/drivers/radeon/radeon_uvd.h       |  377 +++++++++
+ src/gallium/drivers/radeonsi/Makefile.am      |    4 +-
+ src/gallium/drivers/radeonsi/Makefile.sources |    3 +-
+ src/gallium/drivers/radeonsi/radeonsi_pipe.c  |   21 +-
+ src/gallium/drivers/radeonsi/radeonsi_pipe.h  |   11 +
+ src/gallium/drivers/radeonsi/radeonsi_uvd.c   |  160 ++++
+ 17 files changed, 1941 insertions(+), 24 deletions(-)
+ create mode 100644 docs/README.UVD
+ create mode 100644 src/gallium/drivers/r600/r600_uvd.c
+ create mode 100644 src/gallium/drivers/radeon/radeon_uvd.c
+ create mode 100644 src/gallium/drivers/radeon/radeon_uvd.h
+ create mode 100644 src/gallium/drivers/radeonsi/radeonsi_uvd.c
+
+diff --git a/configure.ac b/configure.ac
+index b9fcb0b..5de16d0 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1802,6 +1802,7 @@ radeon_llvm_check() {
+     fi
+     AC_MSG_WARN([Please ensure you use the latest llvm tree from git://people.freedesktop.org/~tstellar/llvm master before submitting a bug])
+     LLVM_COMPONENTS="${LLVM_COMPONENTS} r600"
++    NEED_RADEON_LLVM=yes
+ }
+ 
+ dnl Gallium drivers
+@@ -1839,7 +1840,6 @@ if test "x$with_gallium_drivers" != x; then
+             GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS r600"
+             if test "x$enable_r600_llvm" = xyes -o "x$enable_opencl" = xyes; then
+                 radeon_llvm_check
+-                NEED_RADEON_GALLIUM=yes;
+                 R600_NEED_RADEON_GALLIUM=yes;
+                 LLVM_COMPONENTS="${LLVM_COMPONENTS} ipo bitreader asmparser"
+             fi
+@@ -1857,7 +1857,6 @@ if test "x$with_gallium_drivers" != x; then
+             gallium_require_drm_loader
+             GALLIUM_DRIVERS_DIRS="$GALLIUM_DRIVERS_DIRS radeonsi"
+             radeon_llvm_check
+-	    NEED_RADEON_GALLIUM=yes;
+             gallium_check_st "radeon/drm" "dri-radeonsi" "xorg-radeonsi" "" "" "vdpau-radeonsi" ""
+             ;;
+         xnouveau)
+@@ -1996,7 +1995,7 @@ done
+ AM_CONDITIONAL(HAVE_GALAHAD_GALLIUM, test x$HAVE_GALAHAD_GALLIUM = xyes)
+ AM_CONDITIONAL(HAVE_IDENTITY_GALLIUM, test x$HAVE_IDENTITY_GALLIUM = xyes)
+ AM_CONDITIONAL(HAVE_NOOP_GALLIUM, test x$HAVE_NOOP_GALLIUM = xyes)
+-AM_CONDITIONAL(NEED_RADEON_GALLIUM, test x$NEED_RADEON_GALLIUM = xyes)
++AM_CONDITIONAL(NEED_RADEON_LLVM, test x$NEED_RADEON_LLVM = xyes)
+ AM_CONDITIONAL(R600_NEED_RADEON_GALLIUM, test x$R600_NEED_RADEON_GALLIUM = xyes)
+ AM_CONDITIONAL(USE_R600_LLVM_COMPILER, test x$USE_R600_LLVM_COMPILER = xyes)
+ AM_CONDITIONAL(HAVE_LOADER_GALLIUM, test x$enable_gallium_loader = xyes)
+diff --git a/docs/README.UVD b/docs/README.UVD
+new file mode 100644
+index 0000000..36b467e
+--- /dev/null
++++ b/docs/README.UVD
+@@ -0,0 +1,13 @@
++The software may implement third party technologies (e.g. third party
++libraries) that are not licensed to you by AMD and for which you may need
++to obtain licenses from other parties.  Unless explicitly stated otherwise,
++these third party technologies are not licensed hereunder.  Such third
++party technologies include, but are not limited, to H.264, MPEG-2, MPEG-4,
++AVC, and VC-1.
++
++For MPEG-2 Encoding Products ANY USE OF THIS PRODUCT IN ANY MANNER OTHER
++THAN PERSONAL USE THAT COMPLIES WITH THE MPEG-2 STANDARD FOR ENCODING VIDEO
++INFORMATION FOR PACKAGED MEDIA IS EXPRESSLY PROHIBITED WITHOUT A LICENSE
++UNDER APPLICABLE PATENTS IN THE MPEG-2 PATENT PORTFOLIO, WHICH LICENSES IS
++AVAILABLE FROM MPEG LA, LLC, 6312 S. Fiddlers Green Circle, Suite 400E,
++Greenwood Village, Colorado 80111 U.S.A.
+diff --git a/src/gallium/drivers/Makefile.am b/src/gallium/drivers/Makefile.am
+index 3477fee..c4dc6bf 100644
+--- a/src/gallium/drivers/Makefile.am
++++ b/src/gallium/drivers/Makefile.am
+@@ -56,10 +56,18 @@ endif
+ 
+ ################################################################################
+ 
+-if NEED_RADEON_GALLIUM
++if HAVE_GALLIUM_R600
+ 
+ SUBDIRS += radeon
+ 
++else
++
++if HAVE_GALLIUM_RADEONSI
++
++SUBDIRS += radeon
++
++endif
++
+ endif
+ 
+ ################################################################################
+diff --git a/src/gallium/drivers/r600/Makefile.am b/src/gallium/drivers/r600/Makefile.am
+index 6f48b56..459aa18 100644
+--- a/src/gallium/drivers/r600/Makefile.am
++++ b/src/gallium/drivers/r600/Makefile.am
+@@ -13,13 +13,15 @@ AM_CFLAGS = \
+ libr600_la_SOURCES = \
+ 	$(C_SOURCES)
+ 
++libr600_la_LIBADD = ../radeon/libradeon.la
++
+ if R600_NEED_RADEON_GALLIUM
+ 
+ libr600_la_SOURCES += \
+ 	$(LLVM_C_SOURCES) \
+ 	$(LLVM_CXX_SOURCES)
+ 
+-libr600_la_LIBADD = ../radeon/libllvmradeon@VERSION@.la
++libr600_la_LIBADD += ../radeon/libllvmradeon@VERSION@.la
+ 
+ AM_CFLAGS += \
+ 	$(LLVM_CFLAGS) \
+diff --git a/src/gallium/drivers/r600/Makefile.sources b/src/gallium/drivers/r600/Makefile.sources
+index 0885ae5..c71f73b 100644
+--- a/src/gallium/drivers/r600/Makefile.sources
++++ b/src/gallium/drivers/r600/Makefile.sources
+@@ -16,7 +16,8 @@ C_SOURCES = \
+ 	r600_state_common.c \
+ 	evergreen_compute.c \
+ 	evergreen_compute_internal.c \
+-	compute_memory_pool.c
++	compute_memory_pool.c \
++	r600_uvd.c
+ 
+ LLVM_C_SOURCES = r600_llvm.c
+ LLVM_CXX_SOURCES = llvm_wrapper.cpp
+diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c
+index 80b859f..28e999f 100644
+--- a/src/gallium/drivers/r600/r600_pipe.c
++++ b/src/gallium/drivers/r600/r600_pipe.c
+@@ -34,6 +34,7 @@
+ #include "util/u_math.h"
+ #include "vl/vl_decoder.h"
+ #include "vl/vl_video_buffer.h"
++#include "radeon/radeon_uvd.h"
+ #include "os/os_time.h"
+ 
+ /*
+@@ -359,8 +360,13 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void
+ 	r600_init_surface_functions(rctx);
+ 
+ 
+-	rctx->context.create_video_decoder = vl_create_decoder;
+-	rctx->context.create_video_buffer = vl_video_buffer_create;
++	if (rscreen->info.has_uvd) {
++		rctx->context.create_video_decoder = r600_uvd_create_decoder;
++		rctx->context.create_video_buffer = r600_video_buffer_create;
++	} else {
++		rctx->context.create_video_decoder = vl_create_decoder;
++		rctx->context.create_video_buffer = vl_video_buffer_create;
++	}
+ 
+ 	r600_init_common_state_functions(rctx);
+ 
+@@ -1125,7 +1131,6 @@ struct pipe_screen *r600_screen_create(struct radeon_winsys *ws)
+ 	rscreen->screen.get_param = r600_get_param;
+ 	rscreen->screen.get_shader_param = r600_get_shader_param;
+ 	rscreen->screen.get_paramf = r600_get_paramf;
+-	rscreen->screen.get_video_param = r600_get_video_param;
+ 	rscreen->screen.get_compute_param = r600_get_compute_param;
+ 	rscreen->screen.get_timestamp = r600_get_timestamp;
+ 
+@@ -1136,11 +1141,19 @@ struct pipe_screen *r600_screen_create(struct radeon_winsys *ws)
+ 		rscreen->screen.is_format_supported = r600_is_format_supported;
+ 		rscreen->dma_blit = &r600_dma_blit;
+ 	}
+-	rscreen->screen.is_video_format_supported = vl_video_buffer_is_format_supported;
+ 	rscreen->screen.context_create = r600_create_context;
+ 	rscreen->screen.fence_reference = r600_fence_reference;
+ 	rscreen->screen.fence_signalled = r600_fence_signalled;
+ 	rscreen->screen.fence_finish = r600_fence_finish;
++
++	if (rscreen->info.has_uvd) {
++		rscreen->screen.get_video_param = ruvd_get_video_param;
++		rscreen->screen.is_video_format_supported = ruvd_is_format_supported;
++	} else {
++		rscreen->screen.get_video_param = r600_get_video_param;
++		rscreen->screen.is_video_format_supported = vl_video_buffer_is_format_supported;
++	}
++
+ 	r600_init_screen_resource_functions(&rscreen->screen);
+ 
+ 	util_format_s3tc_init();
+diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h
+index 1be4321..be4a155 100644
+--- a/src/gallium/drivers/r600/r600_pipe.h
++++ b/src/gallium/drivers/r600/r600_pipe.h
+@@ -746,6 +746,18 @@ unsigned r600_tex_mipfilter(unsigned filter);
+ unsigned r600_tex_compare(unsigned compare);
+ bool sampler_state_needs_border_color(const struct pipe_sampler_state *state);
+ 
++/* r600_uvd.c */
++struct pipe_video_decoder *r600_uvd_create_decoder(struct pipe_context *context,
++                                                   enum pipe_video_profile profile,
++                                                   enum pipe_video_entrypoint entrypoint,
++                                                   enum pipe_video_chroma_format chroma_format,
++                                                   unsigned width, unsigned height,
++						   unsigned max_references, bool expect_chunked_decode);
++
++struct pipe_video_buffer *r600_video_buffer_create(struct pipe_context *pipe,
++						   const struct pipe_video_buffer *tmpl);
++
++
+ /*
+  * Helpers for building command buffers
+  */
+diff --git a/src/gallium/drivers/r600/r600_uvd.c b/src/gallium/drivers/r600/r600_uvd.c
+new file mode 100644
+index 0000000..bdda7e1
+--- /dev/null
++++ b/src/gallium/drivers/r600/r600_uvd.c
+@@ -0,0 +1,178 @@
++/**************************************************************************
++ *
++ * Copyright 2011 Advanced Micro Devices, 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 THE COPYRIGHT HOLDER(S) OR AUTHOR(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:
++ *      Christian König <christian.koenig@amd.com>
++ *
++ */
++
++#include <sys/types.h>
++#include <assert.h>
++#include <errno.h>
++#include <unistd.h>
++
++#include "pipe/p_video_decoder.h"
++
++#include "util/u_memory.h"
++#include "util/u_video.h"
++
++#include "vl/vl_defines.h"
++#include "vl/vl_mpeg12_decoder.h"
++
++#include "r600_pipe.h"
++#include "radeon/radeon_uvd.h"
++#include "r600d.h"
++
++/**
++ * creates an video buffer with an UVD compatible memory layout
++ */
++struct pipe_video_buffer *r600_video_buffer_create(struct pipe_context *pipe,
++						   const struct pipe_video_buffer *tmpl)
++{
++	struct r600_context *ctx = (struct r600_context *)pipe;
++	struct r600_texture *resources[VL_NUM_COMPONENTS] = {};
++	struct radeon_surface* surfaces[VL_NUM_COMPONENTS] = {};
++	struct pb_buffer **pbs[VL_NUM_COMPONENTS] = {};
++	const enum pipe_format *resource_formats;
++	struct pipe_video_buffer template;
++	struct pipe_resource templ;
++	unsigned i, depth;
++
++	assert(pipe);
++
++	/* first create the needed resources as "normal" textures */
++	resource_formats = vl_video_buffer_formats(pipe->screen, tmpl->buffer_format);
++	if (!resource_formats)
++		return NULL;
++
++	depth = tmpl->interlaced ? 2 : 1;
++	template = *tmpl;
++	template.width = align(tmpl->width, VL_MACROBLOCK_WIDTH);
++	template.height = align(tmpl->height / depth, VL_MACROBLOCK_HEIGHT);
++
++	vl_vide_buffer_template(&templ, &template, resource_formats[0], depth, PIPE_USAGE_STATIC, 0);
++	resources[0] = (struct r600_texture *)
++		pipe->screen->resource_create(pipe->screen, &templ);
++	if (!resources[0])
++		goto error;
++
++	if (resource_formats[1] != PIPE_FORMAT_NONE) {
++		vl_vide_buffer_template(&templ, &template, resource_formats[1], depth, PIPE_USAGE_STATIC, 1);
++		resources[1] = (struct r600_texture *)
++			pipe->screen->resource_create(pipe->screen, &templ);
++		if (!resources[1])
++			goto error;
++	}
++
++	if (resource_formats[2] != PIPE_FORMAT_NONE) {
++		vl_vide_buffer_template(&templ, &template, resource_formats[2], depth, PIPE_USAGE_STATIC, 2);
++		resources[2] = (struct r600_texture *)
++			pipe->screen->resource_create(pipe->screen, &templ);
++		if (!resources[2])
++			goto error;
++	}
++
++	for (i = 0; i < VL_NUM_COMPONENTS; ++i) {
++		if (!resources[i])
++			continue;
++
++		pbs[i] = &resources[i]->resource.buf;
++		surfaces[i] = &resources[i]->surface;
++
++		if (ctx->chip_class < EVERGREEN) {
++			resources[i]->array_mode[0] = V_038000_ARRAY_LINEAR_ALIGNED;
++			resources[i]->surface.level[0].mode = RADEON_SURF_MODE_LINEAR_ALIGNED;
++		}
++	}
++
++	ruvd_join_surfaces(ctx->ws, templ.bind, pbs, surfaces);
++
++	for (i = 0; i < VL_NUM_COMPONENTS; ++i) {
++		if (!resources[i])
++			continue;
++
++		/* recreate the CS handle */
++		resources[i]->resource.cs_buf = ctx->ws->buffer_get_cs_handle(
++			resources[i]->resource.buf);
++	}
++
++	template.height *= depth;
++	return vl_video_buffer_create_ex2(pipe, &template, (struct pipe_resource **)resources);
++
++error:
++	for (i = 0; i < VL_NUM_COMPONENTS; ++i)
++		pipe_resource_reference((struct pipe_resource **)&resources[i], NULL);
++
++	return NULL;
++}
++
++/* hw encode the number of memory banks */
++static uint32_t eg_num_banks(uint32_t nbanks)
++{
++	switch (nbanks) {
++	case 2:
++		return 0;
++	case 4:
++		return 1;
++	case 8:
++	default:
++		return 2;
++	case 16:
++		return 3;
++	}
++}
++
++/* set the decoding target buffer offsets */
++static struct radeon_winsys_cs_handle* r600_uvd_set_dtb(struct ruvd_msg *msg, struct vl_video_buffer *buf)
++{
++	struct r600_screen *rscreen = (struct r600_screen*)buf->base.context->screen;
++	struct r600_texture *luma = (struct r600_texture *)buf->resources[0];
++	struct r600_texture *chroma = (struct r600_texture *)buf->resources[1];
++
++	msg->decode.dt_field_mode = buf->base.interlaced;
++	msg->decode.dt_surf_tile_config |= RUVD_NUM_BANKS(eg_num_banks(rscreen->tiling_info.num_banks));
++
++	ruvd_set_dt_surfaces(msg, &luma->surface, &chroma->surface);
++
++	return luma->resource.cs_buf;
++}
++
++/* create decoder */
++struct pipe_video_decoder *r600_uvd_create_decoder(struct pipe_context *context,
++						   enum pipe_video_profile profile,
++						   enum pipe_video_entrypoint entrypoint,
++						   enum pipe_video_chroma_format chroma_format,
++						   unsigned width, unsigned height,
++						   unsigned max_references, bool expect_chunked_decode)
++{
++	struct r600_context *ctx = (struct r600_context *)context;
++
++	return ruvd_create_decoder(context, profile, entrypoint, chroma_format,
++			 	   width, height, max_references, expect_chunked_decode,
++				   ctx->ws, r600_uvd_set_dtb);
++}
+diff --git a/src/gallium/drivers/radeon/Makefile.am b/src/gallium/drivers/radeon/Makefile.am
+index a3a7b74..d78a550 100644
+--- a/src/gallium/drivers/radeon/Makefile.am
++++ b/src/gallium/drivers/radeon/Makefile.am
+@@ -3,6 +3,15 @@ include $(top_srcdir)/src/gallium/Automake.inc
+ 
+ LIBGALLIUM_LIBS=
+ 
++noinst_LTLIBRARIES = libradeon.la
++
++AM_CFLAGS = $(GALLIUM_CFLAGS)
++
++libradeon_la_SOURCES = \
++	$(C_SOURCES)
++
++if NEED_RADEON_LLVM
++
+ if HAVE_GALLIUM_R600
+ if HAVE_GALLIUM_RADEONSI
+ lib_LTLIBRARIES = libllvmradeon@VERSION@.la
+@@ -10,25 +19,29 @@ libllvmradeon@VERSION@_la_LDFLAGS = -Wl, -shared -avoid-version \
+ 	$(LLVM_LDFLAGS)
+ LIBGALLIUM_LIBS += $(top_builddir)/src/gallium/auxiliary/libgallium.la
+ else
+-noinst_LTLIBRARIES = libllvmradeon@VERSION@.la
++noinst_LTLIBRARIES += libllvmradeon@VERSION@.la
+ endif
+ else
+-noinst_LTLIBRARIES = libllvmradeon@VERSION@.la
++noinst_LTLIBRARIES += libllvmradeon@VERSION@.la
+ endif
+ 
+-AM_CXXFLAGS = \
++libllvmradeon@VERSION@_la_CXXFLAGS = \
++	$(GALLIUM_CFLAGS) \
+ 	$(filter-out -DDEBUG, $(LLVM_CXXFLAGS)) \
+ 	$(DEFINES)
+ 
+-AM_CFLAGS = \
++libllvmradeon@VERSION@_la_CFLAGS = \
+ 	$(GALLIUM_CFLAGS) \
+ 	$(LLVM_CFLAGS)
+ 
+ libllvmradeon@VERSION@_la_SOURCES = \
+-	$(CPP_FILES) \
+-	$(C_FILES)
++	$(LLVM_CPP_FILES) \
++	$(LLVM_C_FILES)
++
+ 
+ libllvmradeon@VERSION@_la_LIBADD = \
+ 	$(LIBGALLIUM_LIBS) \
+ 	$(CLOCK_LIB) \
+ 	$(LLVM_LIBS)
++
++endif
+\ No newline at end of file
+diff --git a/src/gallium/drivers/radeon/Makefile.sources b/src/gallium/drivers/radeon/Makefile.sources
+index 39f9532..8977ce5 100644
+--- a/src/gallium/drivers/radeon/Makefile.sources
++++ b/src/gallium/drivers/radeon/Makefile.sources
+@@ -1,5 +1,8 @@
+-CPP_FILES := \
++C_SOURCES := \
++	radeon_uvd.c
++
++LLVM_CPP_FILES := \
+ 	radeon_llvm_emit.cpp
+ 
+-C_FILES := \
++LLVM_C_FILES := \
+ 	radeon_setup_tgsi_llvm.c
+diff --git a/src/gallium/drivers/radeon/radeon_uvd.c b/src/gallium/drivers/radeon/radeon_uvd.c
+new file mode 100644
+index 0000000..dae7880
+--- /dev/null
++++ b/src/gallium/drivers/radeon/radeon_uvd.c
+@@ -0,0 +1,1111 @@
++/**************************************************************************
++ *
++ * Copyright 2011 Advanced Micro Devices, 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 THE COPYRIGHT HOLDER(S) OR AUTHOR(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:
++ *	Christian König <christian.koenig@amd.com>
++ *
++ */
++
++#include <sys/types.h>
++#include <assert.h>
++#include <errno.h>
++#include <unistd.h>
++#include <stdio.h>
++
++#include "pipe/p_video_decoder.h"
++
++#include "util/u_memory.h"
++#include "util/u_video.h"
++
++#include "vl/vl_defines.h"
++#include "vl/vl_mpeg12_decoder.h"
++
++#include "../../winsys/radeon/drm/radeon_winsys.h"
++#include "radeon_uvd.h"
++
++#define RUVD_ERR(fmt, args...) \
++	fprintf(stderr, "EE %s:%d %s UVD - "fmt, __FILE__, __LINE__, __func__, ##args)
++
++#define NUM_BUFFERS 4
++
++#define NUM_MPEG2_REFS 6
++#define NUM_H264_REFS 17
++
++/* UVD buffer representation */
++struct ruvd_buffer
++{
++	struct pb_buffer*		buf;
++	struct radeon_winsys_cs_handle*	cs_handle;
++};
++
++/* UVD decoder representation */
++struct ruvd_decoder {
++	struct pipe_video_decoder	base;
++
++	ruvd_set_dtb			set_dtb;
++
++	unsigned			stream_handle;
++	unsigned			frame_number;
++
++	struct radeon_winsys*		ws;
++	struct radeon_winsys_cs*	cs;
++
++	unsigned			cur_buffer;
++
++	struct ruvd_buffer		msg_fb_buffers[NUM_BUFFERS];
++	struct ruvd_buffer		bs_buffers[NUM_BUFFERS];
++	void*				bs_ptr;
++	unsigned			bs_size;
++
++	struct ruvd_buffer		dpb;
++};
++
++/* generate an UVD stream handle */
++static unsigned alloc_stream_handle()
++{
++	static unsigned counter = 0;
++	unsigned stream_handle = 0;
++	unsigned pid = getpid();
++	int i;
++
++	for (i = 0; i < 32; ++i)
++		stream_handle |= ((pid >> i) & 1) << (31 - i);
++
++	stream_handle ^= ++counter;
++	return stream_handle;
++}
++
++/* flush IB to the hardware */
++static void flush(struct ruvd_decoder *dec)
++{
++	uint32_t *pm4 =	dec->cs->buf;
++
++	// align IB
++	while(dec->cs->cdw % 16)
++		pm4[dec->cs->cdw++] = RUVD_PKT2();
++
++	dec->ws->cs_flush(dec->cs, 0);
++}
++
++/* add a new set register command to the IB */
++static void set_reg(struct ruvd_decoder *dec, unsigned reg, uint32_t val)
++{
++	uint32_t *pm4 =	dec->cs->buf;
++	pm4[dec->cs->cdw++] = RUVD_PKT0(reg >> 2, 0);
++	pm4[dec->cs->cdw++] = val;
++}
++
++/* send a command to the VCPU through the GPCOM registers */
++static void send_cmd(struct ruvd_decoder *dec, unsigned cmd,
++		     struct radeon_winsys_cs_handle* cs_buf, uint32_t off,
++		     enum radeon_bo_usage usage, enum radeon_bo_domain domain)
++{
++	int reloc_idx;
++
++	reloc_idx = dec->ws->cs_add_reloc(dec->cs, cs_buf, usage, domain);
++	set_reg(dec, RUVD_GPCOM_VCPU_DATA0, off);
++	set_reg(dec, RUVD_GPCOM_VCPU_DATA1, reloc_idx * 4);
++	set_reg(dec, RUVD_GPCOM_VCPU_CMD, cmd << 1);
++}
++
++/* send a message command to the VCPU */
++static void send_msg(struct ruvd_decoder *dec, struct ruvd_msg *msg)
++{
++	struct ruvd_buffer* buf;
++	void *ptr;
++
++	/* grap a message buffer */
++	buf = &dec->msg_fb_buffers[dec->cur_buffer];
++
++	/* copy the message into it */
++	ptr = dec->ws->buffer_map(buf->cs_handle, dec->cs, PIPE_TRANSFER_WRITE);
++	if (!ptr)
++		return;
++
++	memcpy(ptr, msg, sizeof(*msg));
++	memset(ptr + sizeof(*msg), 0, buf->buf->size - sizeof(*msg));
++	dec->ws->buffer_unmap(buf->cs_handle);
++
++	/* and send it to the hardware */
++	send_cmd(dec, RUVD_CMD_MSG_BUFFER, buf->cs_handle, 0,
++		 RADEON_USAGE_READ, RADEON_DOMAIN_VRAM);
++}
++
++/* create a buffer in the winsys */
++static bool create_buffer(struct ruvd_decoder *dec,
++			  struct ruvd_buffer *buffer,
++			  unsigned size)
++{
++	buffer->buf = dec->ws->buffer_create(dec->ws, size, 4096, false,
++					     RADEON_DOMAIN_GTT | RADEON_DOMAIN_VRAM);
++	if (!buffer->buf)
++		return false;
++
++	buffer->cs_handle = dec->ws->buffer_get_cs_handle(buffer->buf);
++	if (!buffer->cs_handle)
++		return false;
++
++	return true;
++}
++
++/* destroy a buffer */
++static void destroy_buffer(struct ruvd_buffer *buffer)
++{
++	pb_reference(&buffer->buf, NULL);
++	buffer->cs_handle = NULL;
++}
++
++/* reallocate a buffer, preserving its content */
++static bool resize_buffer(struct ruvd_decoder *dec,
++			  struct ruvd_buffer *new_buf,
++			  unsigned new_size)
++{
++	unsigned bytes = MIN2(new_buf->buf->size, new_size);
++	struct ruvd_buffer old_buf = *new_buf;
++	void *src = NULL, *dst = NULL;
++
++	if (!create_buffer(dec, new_buf, new_size))
++		goto error;
++
++	src = dec->ws->buffer_map(old_buf.cs_handle, dec->cs, PIPE_TRANSFER_READ);
++	if (!src)
++		goto error;
++
++	dst = dec->ws->buffer_map(new_buf->cs_handle, dec->cs, PIPE_TRANSFER_WRITE);
++	if (!dst)
++		goto error;
++
++	memcpy(dst, src, bytes);
++	if (new_size > bytes) {
++		new_size -= bytes;
++		dst += bytes;
++		memset(dst, 0, new_size);
++	}
++	dec->ws->buffer_unmap(new_buf->cs_handle);
++	dec->ws->buffer_unmap(old_buf.cs_handle);
++	destroy_buffer(&old_buf);
++	return true;
++
++error:
++	if (src) dec->ws->buffer_unmap(old_buf.cs_handle);
++	destroy_buffer(new_buf);
++	*new_buf = old_buf;
++	return false;
++}
++
++/* clear the buffer with zeros */
++static void clear_buffer(struct ruvd_decoder *dec,
++			 struct ruvd_buffer* buffer)
++{
++	//TODO: let the GPU do the job
++	void *ptr = dec->ws->buffer_map(buffer->cs_handle, dec->cs,
++					PIPE_TRANSFER_WRITE);
++	if (!ptr)
++		return;
++
++	memset(ptr, 0, buffer->buf->size);
++	dec->ws->buffer_unmap(buffer->cs_handle);
++}
++
++/* cycle to the next set of buffers */
++static void next_buffer(struct ruvd_decoder *dec)
++{
++	++dec->cur_buffer;
++	dec->cur_buffer %= NUM_BUFFERS;
++}
++
++/* convert the profile into something UVD understands */
++static uint32_t profile2stream_type(enum pipe_video_profile profile)
++{
++	switch (u_reduce_video_profile(profile)) {
++	case PIPE_VIDEO_CODEC_MPEG4_AVC:
++		return RUVD_CODEC_H264;
++
++	case PIPE_VIDEO_CODEC_VC1:
++		return RUVD_CODEC_VC1;
++
++	case PIPE_VIDEO_CODEC_MPEG12:
++		return RUVD_CODEC_MPEG2;
++
++	case PIPE_VIDEO_CODEC_MPEG4:
++		return RUVD_CODEC_MPEG4;
++
++	default:
++		assert(0);
++		return 0;
++	}
++}
++
++/* calculate size of reference picture buffer */
++static unsigned calc_dpb_size(enum pipe_video_profile profile,
++			      unsigned width, unsigned height,
++			      unsigned max_references)
++{
++	unsigned width_in_mb, height_in_mb, image_size, dpb_size;
++
++	// always align them to MB size for dpb calculation
++	width = align(width, VL_MACROBLOCK_WIDTH);
++	height = align(height, VL_MACROBLOCK_HEIGHT);
++
++	// always one more for currently decoded picture
++	max_references += 1;
++
++	// aligned size of a single frame
++	image_size = width * height;
++	image_size += image_size / 2;
++	image_size = align(image_size, 1024);
++
++	// picture width & height in 16 pixel units
++	width_in_mb = width / VL_MACROBLOCK_WIDTH;
++	height_in_mb = align(height / VL_MACROBLOCK_HEIGHT, 2);
++
++	switch (u_reduce_video_profile(profile)) {
++	case PIPE_VIDEO_CODEC_MPEG4_AVC:
++		// the firmware seems to allways assume a minimum of ref frames
++		max_references = MAX2(NUM_H264_REFS, max_references);
++
++		// reference picture buffer
++		dpb_size = image_size * max_references;
++
++		// macroblock context buffer
++		dpb_size += width_in_mb * height_in_mb * max_references * 192;
++
++		// IT surface buffer
++		dpb_size += width_in_mb * height_in_mb * 32;
++		break;
++
++	case PIPE_VIDEO_CODEC_VC1:
++		// reference picture buffer
++		dpb_size = image_size * max_references;
++
++		// CONTEXT_BUFFER
++		dpb_size += width_in_mb * height_in_mb * 128;
++
++		// IT surface buffer
++		dpb_size += width_in_mb * 64;
++
++		// DB surface buffer
++		dpb_size += width_in_mb * 128;
++
++		// BP
++		dpb_size += align(MAX2(width_in_mb, height_in_mb) * 7 * 16, 64);
++		break;
++
++	case PIPE_VIDEO_CODEC_MPEG12:
++		// reference picture buffer, must be big enough for all frames
++		dpb_size = image_size * NUM_MPEG2_REFS;
++		break;
++
++	case PIPE_VIDEO_CODEC_MPEG4:
++		// reference picture buffer
++		dpb_size = image_size * max_references;
++
++		// CM
++		dpb_size += width_in_mb * height_in_mb * 64;
++
++		// IT surface buffer
++		dpb_size += align(width_in_mb * height_in_mb * 32, 64);
++		break;
++
++	default:
++		// something is missing here
++		assert(0);
++
++		// at least use a sane default value
++		dpb_size = 32 * 1024 * 1024;
++		break;
++	}
++	return dpb_size;
++}
++
++/* get h264 specific message bits */
++static struct ruvd_h264 get_h264_msg(struct ruvd_decoder *dec, struct pipe_h264_picture_desc *pic)
++{
++	struct ruvd_h264 result;
++
++	memset(&result, 0, sizeof(result));
++	switch (pic->base.profile) {
++	case PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE:
++		result.profile = RUVD_H264_PROFILE_BASELINE;
++		break;
++
++	case PIPE_VIDEO_PROFILE_MPEG4_AVC_MAIN:
++		result.profile = RUVD_H264_PROFILE_MAIN;
++		break;
++
++	case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH:
++		result.profile = RUVD_H264_PROFILE_HIGH;
++		break;
++
++	default:
++		assert(0);
++		break;
++	}
++	if (((dec->base.width * dec->base.height) >> 8) <= 1620)
++		result.level = 30;
++	else
++		result.level = 41;
++
++	result.sps_info_flags = 0;
++	result.sps_info_flags |= pic->direct_8x8_inference_flag << 0;
++	result.sps_info_flags |= pic->mb_adaptive_frame_field_flag << 1;
++	result.sps_info_flags |= pic->frame_mbs_only_flag << 2;
++	result.sps_info_flags |= pic->delta_pic_order_always_zero_flag << 3;
++
++	result.pps_info_flags = 0;
++	result.pps_info_flags |= pic->transform_8x8_mode_flag << 0;
++	result.pps_info_flags |= pic->redundant_pic_cnt_present_flag << 1;
++	result.pps_info_flags |= pic->constrained_intra_pred_flag << 2;
++	result.pps_info_flags |= pic->deblocking_filter_control_present_flag << 3;
++	result.pps_info_flags |= pic->weighted_bipred_idc << 4;
++	result.pps_info_flags |= pic->weighted_pred_flag << 6;
++	result.pps_info_flags |= pic->pic_order_present_flag << 7;
++	result.pps_info_flags |= pic->entropy_coding_mode_flag << 8;
++
++	result.chroma_format = 0x1;
++	result.bit_depth_luma_minus8 = 0;
++	result.bit_depth_chroma_minus8 = 0;
++
++	result.log2_max_frame_num_minus4 = pic->log2_max_frame_num_minus4;
++	result.pic_order_cnt_type = pic->pic_order_cnt_type;
++	result.log2_max_pic_order_cnt_lsb_minus4 = pic->log2_max_pic_order_cnt_lsb_minus4;
++	result.num_ref_frames = pic->num_ref_frames;
++	result.pic_init_qp_minus26 = pic->pic_init_qp_minus26;
++	result.chroma_qp_index_offset = pic->chroma_qp_index_offset;
++	result.second_chroma_qp_index_offset = pic->second_chroma_qp_index_offset;
++
++	result.num_slice_groups_minus1 = 0;
++	result.slice_group_map_type = 0;
++
++	result.num_ref_idx_l0_active_minus1 = pic->num_ref_idx_l0_active_minus1;
++	result.num_ref_idx_l1_active_minus1 = pic->num_ref_idx_l1_active_minus1;
++
++	result.slice_group_change_rate_minus1 = 0;
++
++	memcpy(result.scaling_list_4x4, pic->scaling_lists_4x4, 6*64);
++	memcpy(result.scaling_list_8x8, pic->scaling_lists_8x8, 2*64);
++
++	result.frame_num = pic->frame_num;
++	memcpy(result.frame_num_list, pic->frame_num_list, 4*16);
++	result.curr_field_order_cnt_list[0] = pic->field_order_cnt[0];
++	result.curr_field_order_cnt_list[1] = pic->field_order_cnt[1];
++	memcpy(result.field_order_cnt_list, pic->field_order_cnt_list, 4*16*2);
++
++	result.decoded_pic_idx = pic->frame_num;
++
++	return result;
++}
++
++/* get vc1 specific message bits */
++static struct ruvd_vc1 get_vc1_msg(struct pipe_vc1_picture_desc *pic)
++{
++	struct ruvd_vc1 result;
++
++	memset(&result, 0, sizeof(result));
++	switch(pic->base.profile) {
++	case PIPE_VIDEO_PROFILE_VC1_SIMPLE:
++		result.profile = RUVD_VC1_PROFILE_SIMPLE;
++		break;
++
++	case PIPE_VIDEO_PROFILE_VC1_MAIN:
++		result.profile = RUVD_VC1_PROFILE_MAIN;
++		break;
++		
++	case PIPE_VIDEO_PROFILE_VC1_ADVANCED:
++		result.profile = RUVD_VC1_PROFILE_ADVANCED;
++		break;
++	default:
++		assert(0);
++	}
++
++	if (pic->base.profile == PIPE_VIDEO_PROFILE_VC1_ADVANCED) {
++		result.level = 0;
++
++		result.sps_info_flags |= pic->postprocflag << 7;
++		result.sps_info_flags |= pic->pulldown << 6;
++		result.sps_info_flags |= pic->interlace << 5;
++		result.sps_info_flags |= pic->tfcntrflag << 4;
++		result.sps_info_flags |= pic->psf << 1;
++
++		result.pps_info_flags |= pic->panscan_flag << 7;
++		result.pps_info_flags |= pic->refdist_flag << 6;
++		result.pps_info_flags |= pic->extended_dmv << 8;
++		result.pps_info_flags |= pic->range_mapy_flag << 31;
++		result.pps_info_flags |= pic->range_mapy << 28;
++		result.pps_info_flags |= pic->range_mapuv_flag << 27;
++		result.pps_info_flags |= pic->range_mapuv << 24;
++
++	} else {
++		result.level = 0;
++		result.pps_info_flags |= pic->multires << 21;
++		result.pps_info_flags |= pic->syncmarker << 20;
++		result.pps_info_flags |= pic->rangered << 19;
++		result.pps_info_flags |= pic->maxbframes << 16;
++	}
++
++	result.sps_info_flags |= pic->finterpflag << 3;
++	//(((unsigned int)(pPicParams->advance.reserved1))        << SPS_INFO_VC1_RESERVED_SHIFT)
++
++	result.pps_info_flags |= pic->loopfilter << 5;
++	result.pps_info_flags |= pic->fastuvmc << 4;
++	result.pps_info_flags |= pic->extended_mv << 3;
++	result.pps_info_flags |= pic->dquant << 1;
++	result.pps_info_flags |= pic->vstransform << 0;
++	result.pps_info_flags |= pic->overlap << 11;
++	result.pps_info_flags |= pic->quantizer << 9;
++
++
++#if 0
++uint32_t 	slice_count
++uint8_t 	picture_type
++uint8_t 	frame_coding_mode
++uint8_t 	deblockEnable
++uint8_t 	pquant
++#endif
++
++        result.chroma_format  = 1;
++	return result;
++}
++
++/* extract the frame number from a referenced video buffer */
++static uint32_t get_ref_pic_idx(struct ruvd_decoder *dec, struct pipe_video_buffer *ref)
++{
++	uint32_t min = dec->frame_number - NUM_MPEG2_REFS;
++	uint32_t max = dec->frame_number - 1;
++	uintptr_t frame;
++
++	/* seems to be the most sane fallback */
++	if (!ref)
++		return max;
++
++	/* get the frame number from the associated data */
++	frame = (uintptr_t)vl_video_buffer_get_associated_data(ref, &dec->base);
++
++	/* limit the frame number to a valid range */
++	return MAX2(MIN2(frame, max), min);
++}
++
++/* get mpeg2 specific msg bits */
++static struct ruvd_mpeg2 get_mpeg2_msg(struct ruvd_decoder *dec,
++				       struct pipe_mpeg12_picture_desc *pic)
++{
++	struct ruvd_mpeg2 result;
++	unsigned i;
++
++	memset(&result, 0, sizeof(result));
++	result.decoded_pic_idx = dec->frame_number;
++	for (i = 0; i < 2; ++i)
++		result.ref_pic_idx[i] = get_ref_pic_idx(dec, pic->ref[i]);
++
++	result.load_intra_quantiser_matrix = 1;
++	result.load_nonintra_quantiser_matrix = 1;
++	memcpy(&result.intra_quantiser_matrix, pic->intra_matrix, 64);
++	memcpy(&result.nonintra_quantiser_matrix, pic->non_intra_matrix, 64);
++
++	result.profile_and_level_indication = 0;
++	result.chroma_format = 0x1;
++
++	result.picture_coding_type = pic->picture_coding_type;
++	result.f_code[0][0] = pic->f_code[0][0] + 1;
++	result.f_code[0][1] = pic->f_code[0][1] + 1;
++	result.f_code[1][0] = pic->f_code[1][0] + 1;
++	result.f_code[1][1] = pic->f_code[1][1] + 1;
++	result.intra_dc_precision = pic->intra_dc_precision;
++	result.pic_structure = pic->picture_structure;
++	result.top_field_first = pic->top_field_first;
++	result.frame_pred_frame_dct = pic->frame_pred_frame_dct;
++	result.concealment_motion_vectors = pic->concealment_motion_vectors;
++	result.q_scale_type = pic->q_scale_type;
++	result.intra_vlc_format = pic->intra_vlc_format;
++	result.alternate_scan = pic->alternate_scan;
++
++	return result;
++}
++
++/* get mpeg4 specific msg bits */
++static struct ruvd_mpeg4 get_mpeg4_msg(struct ruvd_decoder *dec,
++				       struct pipe_mpeg4_picture_desc *pic)
++{
++	struct ruvd_mpeg4 result;
++	unsigned i;
++	memset(&result, 0, sizeof(result));
++	result.decoded_pic_idx = dec->frame_number;
++	for (i = 0; i < 2; ++i)
++		result.ref_pic_idx[i] = get_ref_pic_idx(dec, pic->ref[i]);
++
++	result.video_object_layer_width = dec->base.width;
++        result.video_object_layer_height = dec->base.height;
++
++	result.vop_time_increment_resolution = pic->vop_time_increment_resolution;
++	result.quant_type = pic->quant_type;
++
++	result.flags |= pic->short_video_header << 0;
++	//result.flags |= obmc_disable << 1;
++	result.flags |= pic->interlaced << 2;
++        result.flags |= 1 << 3; // load_intra_quant_mat
++	result.flags |= 1 << 4; // load_nonintra_quant_mat
++	result.flags |= pic->quarter_sample << 5;
++	//result.flags |= complexity_estimation_disable << 6
++	result.flags |= pic->resync_marker_disable << 7;
++	//result.flags |= data_partitioned << 8;
++	//result.flags |= reversible_vlc << 9;
++	//result.flags |= newpred_enable << 10;
++	//result.flags |= reduced_resolution_vop_enable << 11;
++	//result.flags |= scalability << 12;
++	//result.flags |= is_object_layer_identifier << 13;
++	//result.flags |= fixed_vop_rate << 14;
++	//result.flags |= newpred_segment_type << 15;
++
++	memcpy(&result.intra_quant_mat, pic->intra_matrix, 64);
++	memcpy(&result.nonintra_quant_mat, pic->non_intra_matrix, 64);
++
++	/*
++	int32_t 	trd [2]
++	int32_t 	trb [2]
++	uint8_t 	vop_coding_type
++	uint8_t 	vop_fcode_forward
++	uint8_t 	vop_fcode_backward
++	uint8_t 	rounding_control
++	uint8_t 	alternate_vertical_scan_flag
++	uint8_t 	top_field_first
++	*/
++
++	return result;
++}
++
++/**
++ * destroy this video decoder
++ */
++static void ruvd_destroy(struct pipe_video_decoder *decoder)
++{
++	struct ruvd_decoder *dec = (struct ruvd_decoder*)decoder;
++	struct ruvd_msg msg;
++	unsigned i;
++
++	assert(decoder);
++
++	memset(&msg, 0, sizeof(msg));
++	msg.size = sizeof(msg);
++	msg.msg_type = RUVD_MSG_DESTROY;
++	msg.stream_handle = dec->stream_handle;
++	send_msg(dec, &msg);
++
++	flush(dec);
++
++	dec->ws->cs_destroy(dec->cs);
++
++	for (i = 0; i < NUM_BUFFERS; ++i) {
++		destroy_buffer(&dec->msg_fb_buffers[i]);
++		destroy_buffer(&dec->bs_buffers[i]);
++	}
++
++	destroy_buffer(&dec->dpb);
++
++	FREE(dec);
++}
++
++/* free associated data in the video buffer callback */
++static void ruvd_destroy_associated_data(void *data)
++{
++	/* NOOP, since we only use an intptr */
++}
++
++/**
++ * start decoding of a new frame
++ */
++static void ruvd_begin_frame(struct pipe_video_decoder *decoder,
++			     struct pipe_video_buffer *target,
++			     struct pipe_picture_desc *picture)
++{
++	struct ruvd_decoder *dec = (struct ruvd_decoder*)decoder;
++	uintptr_t frame;
++
++	assert(decoder);
++
++	frame = ++dec->frame_number;
++	vl_video_buffer_set_associated_data(target, decoder, (void *)frame,
++					    &ruvd_destroy_associated_data);
++
++	dec->bs_size = 0;
++	dec->bs_ptr = dec->ws->buffer_map(
++		dec->bs_buffers[dec->cur_buffer].cs_handle,
++		dec->cs, PIPE_TRANSFER_WRITE);
++}
++
++/**
++ * decode a macroblock
++ */
++static void ruvd_decode_macroblock(struct pipe_video_decoder *decoder,
++				   struct pipe_video_buffer *target,
++				   struct pipe_picture_desc *picture,
++				   const struct pipe_macroblock *macroblocks,
++				   unsigned num_macroblocks)
++{
++	/* not supported (yet) */
++	assert(0);
++}
++
++/**
++ * decode a bitstream
++ */
++static void ruvd_decode_bitstream(struct pipe_video_decoder *decoder,
++				  struct pipe_video_buffer *target,
++				  struct pipe_picture_desc *picture,
++				  unsigned num_buffers,
++				  const void * const *buffers,
++				  const unsigned *sizes)
++{
++	struct ruvd_decoder *dec = (struct ruvd_decoder*)decoder;
++	unsigned i;
++
++	assert(decoder);
++
++	if (!dec->bs_ptr)
++		return;
++
++	for (i = 0; i < num_buffers; ++i) {
++		struct ruvd_buffer *buf = &dec->bs_buffers[dec->cur_buffer];
++		unsigned new_size = dec->bs_size + sizes[i];
++
++		if (new_size > buf->buf->size) {
++			dec->ws->buffer_unmap(buf->cs_handle);
++			if (!resize_buffer(dec, buf, new_size)) {
++				RUVD_ERR("Can't resize bitstream buffer!");
++				return;
++			}
++
++			dec->bs_ptr = dec->ws->buffer_map(buf->cs_handle, dec->cs,
++							  PIPE_TRANSFER_WRITE);
++			if (!dec->bs_ptr)
++				return;
++
++			dec->bs_ptr += dec->bs_size;
++		}
++
++		memcpy(dec->bs_ptr, buffers[i], sizes[i]);
++		dec->bs_size += sizes[i];
++		dec->bs_ptr += sizes[i];
++	}
++}
++
++/**
++ * end decoding of the current frame
++ */
++static void ruvd_end_frame(struct pipe_video_decoder *decoder,
++			   struct pipe_video_buffer *target,
++			   struct pipe_picture_desc *picture)
++{
++	struct ruvd_decoder *dec = (struct ruvd_decoder*)decoder;
++	struct radeon_winsys_cs_handle *dt;
++	struct ruvd_buffer *msg_fb_buf, *bs_buf;
++	struct ruvd_msg msg;
++	unsigned bs_size;
++
++	assert(decoder);
++
++	if (!dec->bs_ptr)
++		return;
++
++	msg_fb_buf = &dec->msg_fb_buffers[dec->cur_buffer];
++	bs_buf = &dec->bs_buffers[dec->cur_buffer];
++
++	bs_size = align(dec->bs_size, 128);
++	memset(dec->bs_ptr, 0, bs_size - dec->bs_size);
++	dec->ws->buffer_unmap(bs_buf->cs_handle);
++
++	memset(&msg, 0, sizeof(msg));
++	msg.size = sizeof(msg);
++	msg.msg_type = RUVD_MSG_DECODE;
++	msg.stream_handle = dec->stream_handle;
++	msg.status_report_feedback_number = dec->frame_number;
++
++	msg.decode.stream_type = profile2stream_type(dec->base.profile);
++	msg.decode.decode_flags = 0x1;
++	msg.decode.width_in_samples = dec->base.width;
++	msg.decode.height_in_samples = dec->base.height;
++
++	msg.decode.dpb_size = dec->dpb.buf->size;
++	msg.decode.bsd_size = bs_size;
++
++	dt = dec->set_dtb(&msg, (struct vl_video_buffer *)target);
++
++	switch (u_reduce_video_profile(picture->profile)) {
++	case PIPE_VIDEO_CODEC_MPEG4_AVC:
++		msg.decode.h264 = get_h264_msg(dec, (struct pipe_h264_picture_desc*)picture);
++		break;
++
++	case PIPE_VIDEO_CODEC_VC1:
++		msg.decode.vc1 = get_vc1_msg((struct pipe_vc1_picture_desc*)picture);
++		break;
++
++	case PIPE_VIDEO_CODEC_MPEG12:
++		msg.decode.mpeg2 = get_mpeg2_msg(dec, (struct pipe_mpeg12_picture_desc*)picture);
++		break;
++
++	case PIPE_VIDEO_CODEC_MPEG4:
++		msg.decode.mpeg4 = get_mpeg4_msg(dec, (struct pipe_mpeg4_picture_desc*)picture);
++		break;
++
++	default:
++		assert(0);
++		return;
++	}
++
++	msg.decode.db_surf_tile_config = msg.decode.dt_surf_tile_config;
++	msg.decode.extension_support = 0x1;
++
++	send_msg(dec, &msg);
++	send_cmd(dec, RUVD_CMD_DPB_BUFFER, dec->dpb.cs_handle, 0,
++		 RADEON_USAGE_READWRITE, RADEON_DOMAIN_VRAM);
++	send_cmd(dec, RUVD_CMD_BITSTREAM_BUFFER, bs_buf->cs_handle,
++		 0, RADEON_USAGE_READ, RADEON_DOMAIN_GTT);
++	send_cmd(dec, RUVD_CMD_DECODING_TARGET_BUFFER, dt, 0,
++		 RADEON_USAGE_WRITE, RADEON_DOMAIN_VRAM);
++	send_cmd(dec, RUVD_CMD_FEEDBACK_BUFFER, msg_fb_buf->cs_handle,
++		 0x1000, RADEON_USAGE_WRITE, RADEON_DOMAIN_VRAM);
++	set_reg(dec, RUVD_ENGINE_CNTL, 1);
++
++	flush(dec);
++	next_buffer(dec);
++}
++
++/**
++ * flush any outstanding command buffers to the hardware
++ */
++static void ruvd_flush(struct pipe_video_decoder *decoder)
++{
++}
++
++/**
++ * create and UVD decoder
++ */
++struct pipe_video_decoder *ruvd_create_decoder(struct pipe_context *context,
++					       enum pipe_video_profile profile,
++					       enum pipe_video_entrypoint entrypoint,
++					       enum pipe_video_chroma_format chroma_format,
++					       unsigned width, unsigned height,
++					       unsigned max_references, bool expect_chunked_decode,
++					       struct radeon_winsys* ws,
++					       ruvd_set_dtb set_dtb)
++{
++	unsigned dpb_size = calc_dpb_size(profile, width, height, max_references);
++	struct ruvd_decoder *dec;
++	struct ruvd_msg msg;
++	int i;
++
++	switch(u_reduce_video_profile(profile)) {
++	case PIPE_VIDEO_CODEC_MPEG12:
++		if (entrypoint > PIPE_VIDEO_ENTRYPOINT_BITSTREAM)
++			return vl_create_mpeg12_decoder(context, profile, entrypoint,
++							chroma_format, width,
++							height, max_references, expect_chunked_decode);
++
++		/* fall through */
++	case PIPE_VIDEO_CODEC_MPEG4:
++	case PIPE_VIDEO_CODEC_MPEG4_AVC:
++		width = align(width, VL_MACROBLOCK_WIDTH);
++		height = align(height, VL_MACROBLOCK_HEIGHT);
++		break;
++
++	default:
++		break;
++	}
++
++
++	dec = CALLOC_STRUCT(ruvd_decoder);
++
++	if (!dec)
++		return NULL;
++
++	dec->base.context = context;
++	dec->base.profile = profile;
++	dec->base.entrypoint = entrypoint;
++	dec->base.chroma_format = chroma_format;
++	dec->base.width = width;
++	dec->base.height = height;
++
++	dec->base.destroy = ruvd_destroy;
++	dec->base.begin_frame = ruvd_begin_frame;
++	dec->base.decode_macroblock = ruvd_decode_macroblock;
++	dec->base.decode_bitstream = ruvd_decode_bitstream;
++	dec->base.end_frame = ruvd_end_frame;
++	dec->base.flush = ruvd_flush;
++
++	dec->set_dtb = set_dtb;
++	dec->stream_handle = alloc_stream_handle();
++	dec->ws = ws;
++	dec->cs = ws->cs_create(ws, RING_UVD);
++	if (!dec->cs) {
++		RUVD_ERR("Can't get command submission context.\n");
++		goto error;
++	}
++
++	for (i = 0; i < NUM_BUFFERS; ++i) {
++		unsigned msg_fb_size = align(sizeof(struct ruvd_msg), 0x1000) + 0x1000;
++		if (!create_buffer(dec, &dec->msg_fb_buffers[i], msg_fb_size)) {
++			RUVD_ERR("Can't allocated message buffers.\n");
++			goto error;
++		}
++
++		if (!create_buffer(dec, &dec->bs_buffers[i], 4096)) {
++			RUVD_ERR("Can't allocated bitstream buffers.\n");
++			goto error;
++		}
++
++		clear_buffer(dec, &dec->msg_fb_buffers[i]);
++		clear_buffer(dec, &dec->bs_buffers[i]);
++	}
++
++	if (!create_buffer(dec, &dec->dpb, dpb_size)) {
++		RUVD_ERR("Can't allocated dpb.\n");
++		goto error;
++	}
++
++	clear_buffer(dec, &dec->dpb);
++
++	memset(&msg, 0, sizeof(msg));
++	msg.size = sizeof(msg);
++	msg.msg_type = RUVD_MSG_CREATE;
++	msg.stream_handle = dec->stream_handle;
++	msg.create.stream_type = profile2stream_type(dec->base.profile);
++	msg.create.width_in_samples = dec->base.width;
++	msg.create.height_in_samples = dec->base.height;
++	msg.create.dpb_size = dec->dpb.buf->size;
++	send_msg(dec, &msg);
++	flush(dec);
++	next_buffer(dec);
++
++	return &dec->base;
++
++error:
++	if (dec->cs) dec->ws->cs_destroy(dec->cs);
++
++	for (i = 0; i < NUM_BUFFERS; ++i) {
++		destroy_buffer(&dec->msg_fb_buffers[i]);
++		destroy_buffer(&dec->bs_buffers[i]);
++	}
++
++	destroy_buffer(&dec->dpb);
++
++	FREE(dec);
++
++	return NULL;
++}
++
++/**
++ * join surfaces into the same buffer with identical tiling params
++ * sumup their sizes and replace the backend buffers with a single bo
++ */
++void ruvd_join_surfaces(struct radeon_winsys* ws, unsigned bind,
++			struct pb_buffer** buffers[VL_NUM_COMPONENTS],
++			struct radeon_surface *surfaces[VL_NUM_COMPONENTS])
++{
++	unsigned best_tiling, best_wh, off;
++	unsigned size, alignment;
++	struct pb_buffer *pb;
++	unsigned i, j;
++
++	for (i = 0, best_tiling = 0, best_wh = ~0; i < VL_NUM_COMPONENTS; ++i) {
++		unsigned wh;
++
++		if (!surfaces[i])
++			continue;
++
++		/* choose the smallest bank w/h for now */
++		wh = surfaces[i]->bankw * surfaces[i]->bankh;
++		if (wh < best_wh) {
++			best_wh = wh;
++			best_tiling = i;
++		}
++	}
++
++	for (i = 0, off = 0; i < VL_NUM_COMPONENTS; ++i) {
++		if (!surfaces[i])
++			continue;
++
++		/* copy the tiling parameters */
++		surfaces[i]->bankw = surfaces[best_tiling]->bankw;
++		surfaces[i]->bankh = surfaces[best_tiling]->bankh;
++		surfaces[i]->mtilea = surfaces[best_tiling]->mtilea;
++		surfaces[i]->tile_split = surfaces[best_tiling]->tile_split;
++
++		/* adjust the texture layer offsets */
++		off = align(off, surfaces[i]->bo_alignment);
++		for (j = 0; j < Elements(surfaces[i]->level); ++j)
++			surfaces[i]->level[j].offset += off;
++		off += surfaces[i]->bo_size;
++	}
++
++	for (i = 0, size = 0, alignment = 0; i < VL_NUM_COMPONENTS; ++i) {
++		if (!buffers[i] || !*buffers[i])
++			continue;
++
++		size = align(size, (*buffers[i])->alignment);
++		size += (*buffers[i])->size;
++		alignment = MAX2(alignment, (*buffers[i])->alignment * 1);
++	}
++
++	if (!size)
++		return;
++
++	/* TODO: 2D tiling workaround */
++	alignment *= 2;
++
++	pb = ws->buffer_create(ws, size, alignment, bind, RADEON_DOMAIN_VRAM);
++	if (!pb)
++		return;
++
++	for (i = 0; i < VL_NUM_COMPONENTS; ++i) {
++		if (!buffers[i] || !*buffers[i])
++			continue;
++
++		pb_reference(buffers[i], pb);
++	}
++
++	pb_reference(&pb, NULL);
++}
++
++/* calculate top/bottom offset */
++static unsigned texture_offset(struct radeon_surface *surface, unsigned layer)
++{
++	return surface->level[0].offset +
++		layer * surface->level[0].slice_size;
++}
++
++/* hw encode the aspect of macro tiles */
++static unsigned macro_tile_aspect(unsigned macro_tile_aspect)
++{
++	switch (macro_tile_aspect) {
++	default:
++	case 1: macro_tile_aspect = 0;  break;
++	case 2: macro_tile_aspect = 1;  break;
++	case 4: macro_tile_aspect = 2;  break;
++	case 8: macro_tile_aspect = 3;  break;
++	}
++	return macro_tile_aspect;
++}
++
++/* hw encode the bank width and height */
++static unsigned bank_wh(unsigned bankwh)
++{
++	switch (bankwh) {
++	default:
++	case 1: bankwh = 0;     break;
++	case 2: bankwh = 1;     break;
++	case 4: bankwh = 2;     break;
++	case 8: bankwh = 3;     break;
++	}
++	return bankwh;
++}
++
++/**
++ * fill decoding target field from the luma and chroma surfaces
++ */
++void ruvd_set_dt_surfaces(struct ruvd_msg *msg, struct radeon_surface *luma,
++			  struct radeon_surface *chroma)
++{
++	msg->decode.dt_pitch = luma->level[0].pitch_bytes;
++	switch (luma->level[0].mode) {
++	case RADEON_SURF_MODE_LINEAR_ALIGNED:
++		msg->decode.dt_tiling_mode = RUVD_TILE_LINEAR;
++		msg->decode.dt_array_mode = RUVD_ARRAY_MODE_LINEAR;
++		break;
++	case RADEON_SURF_MODE_1D:
++		msg->decode.dt_tiling_mode = RUVD_TILE_8X8;
++		msg->decode.dt_array_mode = RUVD_ARRAY_MODE_1D_THIN;
++		break;
++	case RADEON_SURF_MODE_2D:
++		msg->decode.dt_tiling_mode = RUVD_TILE_8X8;
++		msg->decode.dt_array_mode = RUVD_ARRAY_MODE_2D_THIN;
++		break;
++	default:
++		assert(0);
++		break;
++	}
++
++	msg->decode.dt_luma_top_offset = texture_offset(luma, 0);
++	msg->decode.dt_chroma_top_offset = texture_offset(chroma, 0);
++	if (msg->decode.dt_field_mode) {
++		msg->decode.dt_luma_bottom_offset = texture_offset(luma, 1);
++		msg->decode.dt_chroma_bottom_offset = texture_offset(chroma, 1);
++	} else {
++		msg->decode.dt_luma_bottom_offset = msg->decode.dt_luma_top_offset;
++		msg->decode.dt_chroma_bottom_offset = msg->decode.dt_chroma_top_offset;
++	}
++
++	assert(luma->bankw == chroma->bankw);
++	assert(luma->bankh == chroma->bankh);
++	assert(luma->mtilea == chroma->mtilea);
++
++	msg->decode.dt_surf_tile_config |= RUVD_BANK_WIDTH(bank_wh(luma->bankw));
++	msg->decode.dt_surf_tile_config |= RUVD_BANK_HEIGHT(bank_wh(luma->bankh));
++	msg->decode.dt_surf_tile_config |= RUVD_MACRO_TILE_ASPECT_RATIO(macro_tile_aspect(luma->mtilea));
++}
++
++int ruvd_get_video_param(struct pipe_screen *screen,
++			 enum pipe_video_profile profile,
++			 enum pipe_video_cap param)
++{
++	switch (param) {
++	case PIPE_VIDEO_CAP_SUPPORTED:
++		switch (u_reduce_video_profile(profile)) {
++		case PIPE_VIDEO_CODEC_MPEG12:
++		case PIPE_VIDEO_CODEC_MPEG4:
++			/* TODO not all hw families support MPEG4 */
++		case PIPE_VIDEO_CODEC_MPEG4_AVC:
++		case PIPE_VIDEO_CODEC_VC1:
++			return true;
++		default:
++			return false;
++		}
++	case PIPE_VIDEO_CAP_NPOT_TEXTURES:
++		return 1;
++	case PIPE_VIDEO_CAP_MAX_WIDTH:
++		return 2048;
++	case PIPE_VIDEO_CAP_MAX_HEIGHT:
++		return 1152;
++	case PIPE_VIDEO_CAP_PREFERED_FORMAT:
++		return PIPE_FORMAT_NV12;
++	case PIPE_VIDEO_CAP_PREFERS_INTERLACED:
++		return false;
++	case PIPE_VIDEO_CAP_SUPPORTS_INTERLACED:
++		return false; /* TODO: enable this */
++	case PIPE_VIDEO_CAP_SUPPORTS_PROGRESSIVE:
++		return true;
++	default:
++		return 0;
++	}
++}
++
++boolean ruvd_is_format_supported(struct pipe_screen *screen,
++				 enum pipe_format format,
++				 enum pipe_video_profile profile)
++{
++	/* we can only handle this one anyway */
++	return format == PIPE_FORMAT_NV12;
++}
+diff --git a/src/gallium/drivers/radeon/radeon_uvd.h b/src/gallium/drivers/radeon/radeon_uvd.h
+new file mode 100644
+index 0000000..b6bceae
+--- /dev/null
++++ b/src/gallium/drivers/radeon/radeon_uvd.h
+@@ -0,0 +1,377 @@
++/**************************************************************************
++ *
++ * Copyright 2011 Advanced Micro Devices, 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 THE COPYRIGHT HOLDER(S) OR AUTHOR(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:
++ *      Christian König <christian.koenig@amd.com>
++ *
++ */
++
++#ifndef RADEON_UVD_H
++#define RADEON_UVD_H
++
++/* UVD uses PM4 packet type 0 and 2 */
++#define RUVD_PKT_TYPE_S(x)		(((x) & 0x3) << 30)
++#define RUVD_PKT_TYPE_G(x)		(((x) >> 30) & 0x3)
++#define RUVD_PKT_TYPE_C			0x3FFFFFFF
++#define RUVD_PKT_COUNT_S(x)		(((x) & 0x3FFF) << 16)
++#define RUVD_PKT_COUNT_G(x)		(((x) >> 16) & 0x3FFF)
++#define RUVD_PKT_COUNT_C		0xC000FFFF
++#define RUVD_PKT0_BASE_INDEX_S(x)	(((x) & 0xFFFF) << 0)
++#define RUVD_PKT0_BASE_INDEX_G(x)	(((x) >> 0) & 0xFFFF)
++#define RUVD_PKT0_BASE_INDEX_C		0xFFFF0000
++#define RUVD_PKT0(index, count)		(RUVD_PKT_TYPE_S(0) | RUVD_PKT0_BASE_INDEX_S(index) | RUVD_PKT_COUNT_S(count))
++#define RUVD_PKT2()			(RUVD_PKT_TYPE_S(2))
++
++/* registers involved with UVD */
++#define RUVD_GPCOM_VCPU_CMD		0xEF0C
++#define RUVD_GPCOM_VCPU_DATA0		0xEF10
++#define RUVD_GPCOM_VCPU_DATA1		0xEF14
++#define RUVD_ENGINE_CNTL		0xEF18
++
++/* UVD commands to VCPU */
++#define RUVD_CMD_MSG_BUFFER		0x00000000
++#define RUVD_CMD_DPB_BUFFER		0x00000001
++#define RUVD_CMD_DECODING_TARGET_BUFFER	0x00000002
++#define RUVD_CMD_FEEDBACK_BUFFER	0x00000003
++#define RUVD_CMD_BITSTREAM_BUFFER	0x00000100
++
++/* UVD message types */
++#define RUVD_MSG_CREATE		0
++#define RUVD_MSG_DECODE		1
++#define RUVD_MSG_DESTROY	2
++
++/* UVD stream types */
++#define RUVD_CODEC_H264		0x00000000
++#define RUVD_CODEC_VC1		0x00000001
++#define RUVD_CODEC_MPEG2	0x00000003
++#define RUVD_CODEC_MPEG4	0x00000004
++
++/* UVD decode target buffer tiling mode */
++#define RUVD_TILE_LINEAR	0x00000000
++#define RUVD_TILE_8X4		0x00000001
++#define RUVD_TILE_8X8		0x00000002
++#define RUVD_TILE_32AS8		0x00000003
++
++/* UVD decode target buffer array mode */
++#define RUVD_ARRAY_MODE_LINEAR				0x00000000
++#define RUVD_ARRAY_MODE_MACRO_LINEAR_MICRO_TILED	0x00000001
++#define RUVD_ARRAY_MODE_1D_THIN				0x00000002
++#define RUVD_ARRAY_MODE_2D_THIN				0x00000004
++#define RUVD_ARRAY_MODE_MACRO_TILED_MICRO_LINEAR	0x00000004
++#define RUVD_ARRAY_MODE_MACRO_TILED_MICRO_TILED		0x00000005
++
++/* UVD tile config */
++#define RUVD_BANK_WIDTH(x)		((x) << 0)
++#define RUVD_BANK_HEIGHT(x)		((x) << 3)
++#define RUVD_MACRO_TILE_ASPECT_RATIO(x)	((x) << 6)
++#define RUVD_NUM_BANKS(x)		((x) << 9)
++
++/* H.264 profile definitions */
++#define RUVD_H264_PROFILE_BASELINE	0x00000000
++#define RUVD_H264_PROFILE_MAIN		0x00000001
++#define RUVD_H264_PROFILE_HIGH		0x00000002
++#define RUVD_H264_PROFILE_STEREO_HIGH	0x00000003
++#define RUVD_H264_PROFILE_MVC		0x00000004
++
++/* VC-1 profile definitions */
++#define RUVD_VC1_PROFILE_SIMPLE		0x00000000
++#define RUVD_VC1_PROFILE_MAIN		0x00000001
++#define RUVD_VC1_PROFILE_ADVANCED	0x00000002
++
++struct ruvd_mvc_element {
++	uint16_t	viewOrderIndex;
++	uint16_t	viewId;
++	uint16_t	numOfAnchorRefsInL0;
++	uint16_t	viewIdOfAnchorRefsInL0[15];
++	uint16_t	numOfAnchorRefsInL1;
++	uint16_t	viewIdOfAnchorRefsInL1[15];
++	uint16_t	numOfNonAnchorRefsInL0;
++	uint16_t	viewIdOfNonAnchorRefsInL0[15];
++	uint16_t	numOfNonAnchorRefsInL1;
++	uint16_t	viewIdOfNonAnchorRefsInL1[15];
++};
++
++struct ruvd_h264 {
++	uint32_t	profile;
++	uint32_t	level;
++
++	uint32_t	sps_info_flags;
++	uint32_t	pps_info_flags;
++	uint8_t		chroma_format;
++	uint8_t		bit_depth_luma_minus8;
++	uint8_t		bit_depth_chroma_minus8;
++	uint8_t		log2_max_frame_num_minus4;
++
++	uint8_t		pic_order_cnt_type;
++	uint8_t		log2_max_pic_order_cnt_lsb_minus4;
++	uint8_t		num_ref_frames;
++	uint8_t		reserved_8bit;
++
++	int8_t		pic_init_qp_minus26;
++	int8_t		pic_init_qs_minus26;
++	int8_t		chroma_qp_index_offset;
++	int8_t		second_chroma_qp_index_offset;
++
++	uint8_t		num_slice_groups_minus1;
++	uint8_t		slice_group_map_type;
++	uint8_t		num_ref_idx_l0_active_minus1;
++	uint8_t		num_ref_idx_l1_active_minus1;
++
++	uint16_t	slice_group_change_rate_minus1;
++	uint16_t	reserved_16bit_1;
++
++	uint8_t		scaling_list_4x4[6][16];
++	uint8_t		scaling_list_8x8[2][64];
++
++	uint32_t	frame_num;
++	uint32_t	frame_num_list[16];
++	int32_t		curr_field_order_cnt_list[2];
++	int32_t		field_order_cnt_list[16][2];
++
++	uint32_t	decoded_pic_idx;
++
++	uint32_t	curr_pic_ref_frame_num;
++
++	uint8_t		ref_frame_list[16];
++
++	uint32_t	reserved[122];
++
++	struct {
++		uint32_t			numViews;
++		uint32_t			viewId0;
++		struct ruvd_mvc_element	mvcElements[1];
++	} mvc;
++};
++
++struct ruvd_vc1 {
++	uint32_t	profile;
++	uint32_t	level;
++	uint32_t	sps_info_flags;
++	uint32_t	pps_info_flags;
++	uint32_t	pic_structure;
++	uint32_t	chroma_format;
++};
++
++struct ruvd_mpeg2 {
++	uint32_t	decoded_pic_idx;
++	uint32_t	ref_pic_idx[2];
++
++	uint8_t		load_intra_quantiser_matrix;
++	uint8_t		load_nonintra_quantiser_matrix;
++	uint8_t		reserved_quantiser_alignement[2];
++	uint8_t		intra_quantiser_matrix[64];
++	uint8_t		nonintra_quantiser_matrix[64];
++
++	uint8_t		profile_and_level_indication;
++	uint8_t		chroma_format;
++
++	uint8_t		picture_coding_type;
++
++	uint8_t		reserved_1;
++
++	uint8_t		f_code[2][2];
++	uint8_t		intra_dc_precision;
++	uint8_t		pic_structure;
++	uint8_t		top_field_first;
++	uint8_t		frame_pred_frame_dct;
++	uint8_t		concealment_motion_vectors;
++	uint8_t		q_scale_type;
++	uint8_t		intra_vlc_format;
++	uint8_t		alternate_scan;
++};
++
++struct ruvd_mpeg4
++{
++	uint32_t	decoded_pic_idx;
++	uint32_t	ref_pic_idx[2];
++
++	uint32_t	variant_type;
++	uint8_t		profile_and_level_indication;
++
++	uint8_t		video_object_layer_verid;
++	uint8_t		video_object_layer_shape;
++
++	uint8_t		reserved_1;
++
++	uint16_t	video_object_layer_width;
++	uint16_t	video_object_layer_height;
++
++	uint16_t	vop_time_increment_resolution;
++
++	uint16_t	reserved_2;
++
++	uint32_t	flags;
++
++	uint8_t		quant_type;
++
++	uint8_t		reserved_3[3];
++
++	uint8_t		intra_quant_mat[64];
++	uint8_t		nonintra_quant_mat[64];
++
++	struct {
++		uint8_t		sprite_enable;
++
++		uint8_t		reserved_4[3];
++
++		uint16_t	sprite_width;
++		uint16_t	sprite_height;
++		int16_t		sprite_left_coordinate;
++		int16_t		sprite_top_coordinate;
++
++		uint8_t		no_of_sprite_warping_points;
++		uint8_t		sprite_warping_accuracy;
++		uint8_t		sprite_brightness_change;
++		uint8_t		low_latency_sprite_enable;
++	} sprite_config;
++
++	struct {
++		uint32_t	flags;
++		uint8_t		vol_mode;
++		uint8_t		reserved_5[3];
++	} divx_311_config;
++};
++
++/* message between driver and hardware */
++struct ruvd_msg {
++
++	uint32_t	size;
++	uint32_t	msg_type;
++	uint32_t	stream_handle;
++	uint32_t	status_report_feedback_number;
++
++	union {
++		struct {
++			uint32_t	stream_type;
++			uint32_t	session_flags;
++			uint32_t	asic_id;
++			uint32_t	width_in_samples;
++			uint32_t	height_in_samples;
++			uint32_t	dpb_buffer;
++			uint32_t	dpb_size;
++			uint32_t	dpb_model;
++			uint32_t	version_info;
++		} create;
++
++		struct {
++			uint32_t	stream_type;
++			uint32_t	decode_flags;
++			uint32_t	width_in_samples;
++			uint32_t	height_in_samples;
++
++			uint32_t	dpb_buffer;
++			uint32_t	dpb_size;
++			uint32_t	dpb_model;
++			uint32_t	dpb_reserved;
++
++			uint32_t	db_offset_alignment;
++			uint32_t	db_pitch;
++			uint32_t	db_tiling_mode;
++			uint32_t	db_array_mode;
++			uint32_t	db_field_mode;
++			uint32_t	db_surf_tile_config;
++			uint32_t	db_aligned_height;
++			uint32_t	db_reserved;
++
++			uint32_t	use_addr_macro;
++
++			uint32_t	bsd_buffer;
++			uint32_t	bsd_size;
++
++			uint32_t	pic_param_buffer;
++			uint32_t	pic_param_size;
++			uint32_t	mb_cntl_buffer;
++			uint32_t	mb_cntl_size;
++
++			uint32_t	dt_buffer;
++			uint32_t	dt_pitch;
++			uint32_t	dt_tiling_mode;
++			uint32_t	dt_array_mode;
++			uint32_t	dt_field_mode;
++			uint32_t	dt_luma_top_offset;
++			uint32_t	dt_luma_bottom_offset;
++			uint32_t	dt_chroma_top_offset;
++			uint32_t	dt_chroma_bottom_offset;
++			uint32_t	dt_surf_tile_config;
++			uint32_t	dt_reserved[3];
++
++			uint32_t	reserved[16];
++
++			union {
++				struct ruvd_h264	h264;
++				struct ruvd_vc1		vc1;
++				struct ruvd_mpeg2	mpeg2;
++				struct ruvd_mpeg4	mpeg4;
++
++				uint32_t codec_info[768];
++			} ;
++
++			uint8_t		extension_support;
++			uint8_t		reserved_8bit_1;
++			uint8_t		reserved_8bit_2;
++			uint8_t		reserved_8bit_3;
++			uint32_t	extension_reserved[64];
++		} decode;
++	};
++};
++
++/* driver dependent callback */
++typedef struct radeon_winsys_cs_handle* (*ruvd_set_dtb)
++(struct ruvd_msg* msg, struct vl_video_buffer *vb);
++
++/* create an UVD decode */
++struct pipe_video_decoder *ruvd_create_decoder(struct pipe_context *context,
++					       enum pipe_video_profile profile,
++					       enum pipe_video_entrypoint entrypoint,
++					       enum pipe_video_chroma_format chroma_format,
++					       unsigned width, unsigned height,
++					       unsigned max_references, bool expect_chunked_decode,
++					       struct radeon_winsys* ws,
++					       ruvd_set_dtb set_dtb);
++
++/* join surfaces into the same buffer with identical tiling params
++   sumup their sizes and replace the backend buffers with a single bo */
++void ruvd_join_surfaces(struct radeon_winsys* ws, unsigned bind,
++			struct pb_buffer** buffers[VL_NUM_COMPONENTS],
++			struct radeon_surface *surfaces[VL_NUM_COMPONENTS]);
++
++/* fill decoding target field from the luma and chroma surfaces */
++void ruvd_set_dt_surfaces(struct ruvd_msg *msg, struct radeon_surface *luma,
++			  struct radeon_surface *chroma);
++
++/* returns supported codecs and other parameters */
++int ruvd_get_video_param(struct pipe_screen *screen,
++			 enum pipe_video_profile profile,
++			 enum pipe_video_cap param);
++
++/* the hardware only supports NV12 */
++boolean ruvd_is_format_supported(struct pipe_screen *screen,
++				 enum pipe_format format,
++				 enum pipe_video_profile profile);
++
++#endif
+diff --git a/src/gallium/drivers/radeonsi/Makefile.am b/src/gallium/drivers/radeonsi/Makefile.am
+index e771d31..df2870e 100644
+--- a/src/gallium/drivers/radeonsi/Makefile.am
++++ b/src/gallium/drivers/radeonsi/Makefile.am
+@@ -33,4 +33,6 @@ AM_CPPFLAGS = \
+ AM_CFLAGS = $(LLVM_CFLAGS)
+ 
+ libradeonsi_la_SOURCES = $(C_SOURCES)
+-libradeonsi_la_LIBADD = ../radeon/libllvmradeon@VERSION@.la
++libradeonsi_la_LIBADD = \
++	../radeon/libradeon.la \
++	../radeon/libllvmradeon@VERSION@.la
+diff --git a/src/gallium/drivers/radeonsi/Makefile.sources b/src/gallium/drivers/radeonsi/Makefile.sources
+index 65da1ac..a6fddb4 100644
+--- a/src/gallium/drivers/radeonsi/Makefile.sources
++++ b/src/gallium/drivers/radeonsi/Makefile.sources
+@@ -12,4 +12,5 @@ C_SOURCES := \
+ 	si_state.c \
+ 	si_state_streamout.c \
+ 	si_state_draw.c \
+-	si_commands.c
++	si_commands.c \
++	radeonsi_uvd.c
+diff --git a/src/gallium/drivers/radeonsi/radeonsi_pipe.c b/src/gallium/drivers/radeonsi/radeonsi_pipe.c
+index 74bea25..8ac83f3 100644
+--- a/src/gallium/drivers/radeonsi/radeonsi_pipe.c
++++ b/src/gallium/drivers/radeonsi/radeonsi_pipe.c
+@@ -43,6 +43,8 @@
+ #include "vl/vl_video_buffer.h"
+ #include "os/os_time.h"
+ #include "pipebuffer/pb_buffer.h"
++#include "radeonsi_pipe.h"
++#include "radeon/radeon_uvd.h"
+ #include "r600.h"
+ #include "sid.h"
+ #include "r600_resource.h"
+@@ -218,8 +220,13 @@ static struct pipe_context *r600_create_context(struct pipe_screen *screen, void
+ 	r600_init_context_resource_functions(rctx);
+ 	si_init_surface_functions(rctx);
+ 
+-	rctx->context.create_video_decoder = vl_create_decoder;
+-	rctx->context.create_video_buffer = vl_video_buffer_create;
++	if (rscreen->info.has_uvd) {
++		rctx->context.create_video_decoder = radeonsi_uvd_create_decoder;
++		rctx->context.create_video_buffer = radeonsi_video_buffer_create;
++	} else {
++		rctx->context.create_video_decoder = vl_create_decoder;
++		rctx->context.create_video_buffer = vl_video_buffer_create;
++	}
+ 
+ 	switch (rctx->chip_class) {
+ 	case TAHITI:
+@@ -704,15 +711,21 @@ struct pipe_screen *radeonsi_screen_create(struct radeon_winsys *ws)
+ 	rscreen->screen.get_param = r600_get_param;
+ 	rscreen->screen.get_shader_param = r600_get_shader_param;
+ 	rscreen->screen.get_paramf = r600_get_paramf;
+-	rscreen->screen.get_video_param = r600_get_video_param;
+ 	rscreen->screen.is_format_supported = si_is_format_supported;
+-	rscreen->screen.is_video_format_supported = vl_video_buffer_is_format_supported;
+ 	rscreen->screen.context_create = r600_create_context;
+ 	rscreen->screen.fence_reference = r600_fence_reference;
+ 	rscreen->screen.fence_signalled = r600_fence_signalled;
+ 	rscreen->screen.fence_finish = r600_fence_finish;
+ 	r600_init_screen_resource_functions(&rscreen->screen);
+ 
++	if (rscreen->info.has_uvd) {
++		rscreen->screen.get_video_param = ruvd_get_video_param;
++		rscreen->screen.is_video_format_supported = ruvd_is_format_supported;
++	} else {
++		rscreen->screen.get_video_param = r600_get_video_param;
++		rscreen->screen.is_video_format_supported = vl_video_buffer_is_format_supported;
++	}
++
+ 	util_format_s3tc_init();
+ 
+ 	rscreen->fences.bo = NULL;
+diff --git a/src/gallium/drivers/radeonsi/radeonsi_pipe.h b/src/gallium/drivers/radeonsi/radeonsi_pipe.h
+index 8c6d908..9a795d9 100644
+--- a/src/gallium/drivers/radeonsi/radeonsi_pipe.h
++++ b/src/gallium/drivers/radeonsi/radeonsi_pipe.h
+@@ -226,6 +226,17 @@ void r600_translate_index_buffer(struct r600_context *r600,
+ 				 struct pipe_index_buffer *ib,
+ 				 unsigned count);
+ 
++/* radeonsi_uvd.c */
++struct pipe_video_decoder *radeonsi_uvd_create_decoder(struct pipe_context *context,
++						       enum pipe_video_profile profile,
++						       enum pipe_video_entrypoint entrypoint,
++						       enum pipe_video_chroma_format chroma_format,
++						       unsigned width, unsigned height,
++						       unsigned max_references, bool expect_chunked_decode);
++
++struct pipe_video_buffer *radeonsi_video_buffer_create(struct pipe_context *pipe,
++						       const struct pipe_video_buffer *tmpl);
++
+ /*
+  * common helpers
+  */
+diff --git a/src/gallium/drivers/radeonsi/radeonsi_uvd.c b/src/gallium/drivers/radeonsi/radeonsi_uvd.c
+new file mode 100644
+index 0000000..d49c088
+--- /dev/null
++++ b/src/gallium/drivers/radeonsi/radeonsi_uvd.c
+@@ -0,0 +1,160 @@
++/**************************************************************************
++ *
++ * Copyright 2011 Advanced Micro Devices, 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 THE COPYRIGHT HOLDER(S) OR AUTHOR(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:
++ *      Christian König <christian.koenig@amd.com>
++ *
++ */
++
++#include <sys/types.h>
++#include <assert.h>
++#include <errno.h>
++#include <unistd.h>
++
++#include "pipe/p_video_decoder.h"
++
++#include "util/u_memory.h"
++#include "util/u_video.h"
++
++#include "vl/vl_defines.h"
++#include "vl/vl_mpeg12_decoder.h"
++
++#include "radeonsi_pipe.h"
++#include "radeon/radeon_uvd.h"
++#include "sid.h"
++
++/**
++ * creates an video buffer with an UVD compatible memory layout
++ */
++struct pipe_video_buffer *radeonsi_video_buffer_create(struct pipe_context *pipe,
++						       const struct pipe_video_buffer *tmpl)
++{
++	struct r600_context *ctx = (struct r600_context *)pipe;
++	struct r600_resource_texture *resources[VL_NUM_COMPONENTS] = {};
++	struct radeon_surface *surfaces[VL_NUM_COMPONENTS] = {};
++	struct pb_buffer **pbs[VL_NUM_COMPONENTS] = {};
++	const enum pipe_format *resource_formats;
++	struct pipe_video_buffer template;
++	struct pipe_resource templ;
++	unsigned i, depth;
++
++	assert(pipe);
++
++	/* first create the needed resources as "normal" textures */
++	resource_formats = vl_video_buffer_formats(pipe->screen, tmpl->buffer_format);
++	if (!resource_formats)
++		return NULL;
++
++	depth = tmpl->interlaced ? 2 : 1;
++	template = *tmpl;
++	template.width = align(tmpl->width, VL_MACROBLOCK_WIDTH);
++	template.height = align(tmpl->height / depth, VL_MACROBLOCK_HEIGHT);
++
++	vl_vide_buffer_template(&templ, &template, resource_formats[0], depth, PIPE_USAGE_STATIC, 0);
++	resources[0] = (struct r600_resource_texture *)
++		pipe->screen->resource_create(pipe->screen, &templ);
++	if (!resources[0])
++		goto error;
++
++	if (resource_formats[1] != PIPE_FORMAT_NONE) {
++		vl_vide_buffer_template(&templ, &template, resource_formats[1], depth, PIPE_USAGE_STATIC, 1);
++		resources[1] = (struct r600_resource_texture *)
++			pipe->screen->resource_create(pipe->screen, &templ);
++		if (!resources[1])
++			goto error;
++	}
++
++	if (resource_formats[2] != PIPE_FORMAT_NONE) {
++		vl_vide_buffer_template(&templ, &template, resource_formats[2], depth, PIPE_USAGE_STATIC, 2);
++		resources[2] = (struct r600_resource_texture *)
++			pipe->screen->resource_create(pipe->screen, &templ);
++		if (!resources[2])
++			goto error;
++	}
++
++	for (i = 0; i < VL_NUM_COMPONENTS; ++i) {
++		if (!resources[i])
++			continue;
++
++		surfaces[i] = & resources[i]->surface;
++		pbs[i] = &resources[i]->resource.buf;
++	}
++
++	ruvd_join_surfaces(ctx->ws, templ.bind, pbs, surfaces);
++
++	for (i = 0; i < VL_NUM_COMPONENTS; ++i) {
++		if (!resources[i])
++			continue;
++
++		/* recreate the CS handle */
++		resources[i]->resource.cs_buf = ctx->ws->buffer_get_cs_handle(
++			resources[i]->resource.buf);
++
++		/* TODO: tiling used to work with UVD on SI */
++		resources[i]->surface.level[0].mode = RADEON_SURF_MODE_LINEAR_ALIGNED;
++	}
++
++	template.height *= depth;
++	return vl_video_buffer_create_ex2(pipe, &template, (struct pipe_resource **)resources);
++
++error:
++	for (i = 0; i < VL_NUM_COMPONENTS; ++i)
++		pipe_resource_reference((struct pipe_resource **)&resources[i], NULL);
++
++	return NULL;
++}
++
++/* set the decoding target buffer offsets */
++static struct radeon_winsys_cs_handle* radeonsi_uvd_set_dtb(struct ruvd_msg *msg, struct vl_video_buffer *buf)
++{
++	struct r600_resource_texture *luma = (struct r600_resource_texture *)buf->resources[0];
++	struct r600_resource_texture *chroma = (struct r600_resource_texture *)buf->resources[1];
++
++	msg->decode.dt_field_mode = buf->base.interlaced;
++
++	ruvd_set_dt_surfaces(msg, &luma->surface, &chroma->surface);
++
++	return luma->resource.cs_buf;
++}
++
++/**
++ * creates an UVD compatible decoder
++ */
++struct pipe_video_decoder *radeonsi_uvd_create_decoder(struct pipe_context *context,
++						       enum pipe_video_profile profile,
++						       enum pipe_video_entrypoint entrypoint,
++						       enum pipe_video_chroma_format chroma_format,
++						       unsigned width, unsigned height,
++						       unsigned max_references, bool expect_chunked_decode)
++{
++	struct r600_context *ctx = (struct r600_context *)context;
++
++	return ruvd_create_decoder(context, profile, entrypoint, chroma_format,
++				   width, height, max_references, expect_chunked_decode,
++				   ctx->ws, radeonsi_uvd_set_dtb);
++}
+-- 
+1.7.10.4
+
diff --git a/debian/patches/103-autoconf-enable-detection-of-vdpau-and-xvmc-by-defau.diff b/debian/patches/103-autoconf-enable-detection-of-vdpau-and-xvmc-by-defau.diff
new file mode 100644
index 0000000..7e1d565
--- /dev/null
+++ b/debian/patches/103-autoconf-enable-detection-of-vdpau-and-xvmc-by-defau.diff
@@ -0,0 +1,38 @@
+From ec28efda3569f39056c3a6d0260092150bffaf11 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
+Date: Fri, 12 Apr 2013 10:25:18 +0200
+Subject: [PATCH 03/17] autoconf: enable detection of vdpau and xvmc by
+ default
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Since we now have UVD support we should enable them by default.
+
+Signed-off-by: Christian König <christian.koenig@amd.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+---
+ configure.ac |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index 5de16d0..42a778c 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1380,10 +1380,10 @@ dnl
+ dnl Gallium G3DVL configuration
+ dnl
+ AC_ARG_ENABLE([gallium-g3dvl],
+-    [AS_HELP_STRING([--enable-gallium-g3dvl],
+-        [build gallium g3dvl @<:@default=disabled@:>@])],
++    [AS_HELP_STRING([--disable-gallium-g3dvl],
++        [build gallium g3dvl @<:@default=enabled@:>@])],
+     [enable_gallium_g3dvl="$enableval"],
+-    [enable_gallium_g3dvl=no])
++    [enable_gallium_g3dvl=yes])
+ if test "x$enable_gallium_g3dvl" = xyes; then
+     if test "x$with_gallium_drivers" = x; then
+         AC_MSG_ERROR([cannot enable G3DVL without Gallium])
+-- 
+1.7.10.4
+
diff --git a/debian/patches/104-r600-uvd-cleanup-disabling-tiling-on-pre-EG-asics.diff b/debian/patches/104-r600-uvd-cleanup-disabling-tiling-on-pre-EG-asics.diff
new file mode 100644
index 0000000..826d791
--- /dev/null
+++ b/debian/patches/104-r600-uvd-cleanup-disabling-tiling-on-pre-EG-asics.diff
@@ -0,0 +1,61 @@
+From 47dd97b434590dfa6c9c3bc10e83621d85d78061 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
+Date: Fri, 12 Apr 2013 17:13:41 +0200
+Subject: [PATCH 04/17] r600/uvd: cleanup disabling tiling on pre EG asics
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Set transfer flag instead of fiddling with the tilling params directly.
+
+Signed-off-by: Christian König <christian.koenig@amd.com>
+---
+ src/gallium/drivers/r600/r600_uvd.c |   11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+diff --git a/src/gallium/drivers/r600/r600_uvd.c b/src/gallium/drivers/r600/r600_uvd.c
+index bdda7e1..dafddfa 100644
+--- a/src/gallium/drivers/r600/r600_uvd.c
++++ b/src/gallium/drivers/r600/r600_uvd.c
+@@ -76,6 +76,8 @@ struct pipe_video_buffer *r600_video_buffer_create(struct pipe_context *pipe,
+ 	template.height = align(tmpl->height / depth, VL_MACROBLOCK_HEIGHT);
+ 
+ 	vl_vide_buffer_template(&templ, &template, resource_formats[0], depth, PIPE_USAGE_STATIC, 0);
++	if (ctx->chip_class < EVERGREEN)
++		templ.flags = R600_RESOURCE_FLAG_TRANSFER;
+ 	resources[0] = (struct r600_texture *)
+ 		pipe->screen->resource_create(pipe->screen, &templ);
+ 	if (!resources[0])
+@@ -83,6 +85,8 @@ struct pipe_video_buffer *r600_video_buffer_create(struct pipe_context *pipe,
+ 
+ 	if (resource_formats[1] != PIPE_FORMAT_NONE) {
+ 		vl_vide_buffer_template(&templ, &template, resource_formats[1], depth, PIPE_USAGE_STATIC, 1);
++		if (ctx->chip_class < EVERGREEN)
++			templ.flags = R600_RESOURCE_FLAG_TRANSFER;
+ 		resources[1] = (struct r600_texture *)
+ 			pipe->screen->resource_create(pipe->screen, &templ);
+ 		if (!resources[1])
+@@ -91,6 +95,8 @@ struct pipe_video_buffer *r600_video_buffer_create(struct pipe_context *pipe,
+ 
+ 	if (resource_formats[2] != PIPE_FORMAT_NONE) {
+ 		vl_vide_buffer_template(&templ, &template, resource_formats[2], depth, PIPE_USAGE_STATIC, 2);
++		if (ctx->chip_class < EVERGREEN)
++			templ.flags = R600_RESOURCE_FLAG_TRANSFER;
+ 		resources[2] = (struct r600_texture *)
+ 			pipe->screen->resource_create(pipe->screen, &templ);
+ 		if (!resources[2])
+@@ -103,11 +109,6 @@ struct pipe_video_buffer *r600_video_buffer_create(struct pipe_context *pipe,
+ 
+ 		pbs[i] = &resources[i]->resource.buf;
+ 		surfaces[i] = &resources[i]->surface;
+-
+-		if (ctx->chip_class < EVERGREEN) {
+-			resources[i]->array_mode[0] = V_038000_ARRAY_LINEAR_ALIGNED;
+-			resources[i]->surface.level[0].mode = RADEON_SURF_MODE_LINEAR_ALIGNED;
+-		}
+ 	}
+ 
+ 	ruvd_join_surfaces(ctx->ws, templ.bind, pbs, surfaces);
+-- 
+1.7.10.4
+
diff --git a/debian/patches/105-radeonsi-cleanup-disabling-tiling-for-UVD-v3.diff b/debian/patches/105-radeonsi-cleanup-disabling-tiling-for-UVD-v3.diff
new file mode 100644
index 0000000..785a4c1
--- /dev/null
+++ b/debian/patches/105-radeonsi-cleanup-disabling-tiling-for-UVD-v3.diff
@@ -0,0 +1,61 @@
+From eb41a13386ca429fdea2e380a26a503df4147797 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
+Date: Sat, 20 Apr 2013 13:19:33 +0200
+Subject: [PATCH 05/17] radeonsi: cleanup disabling tiling for UVD v3
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Should fix: https://bugs.freedesktop.org/show_bug.cgi?id=63702
+
+v2: add a comment that this is just a workaround
+v3: fix typo in comment
+
+Signed-off-by: Christian König <christian.koenig@amd.com>
+Reviewed-by: Michel Dänzer <michel.daenzer@amd.com>
+---
+ src/gallium/drivers/radeonsi/radeonsi_uvd.c |    7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/src/gallium/drivers/radeonsi/radeonsi_uvd.c b/src/gallium/drivers/radeonsi/radeonsi_uvd.c
+index d49c088..3aec098 100644
+--- a/src/gallium/drivers/radeonsi/radeonsi_uvd.c
++++ b/src/gallium/drivers/radeonsi/radeonsi_uvd.c
+@@ -76,6 +76,8 @@ struct pipe_video_buffer *radeonsi_video_buffer_create(struct pipe_context *pipe
+ 	template.height = align(tmpl->height / depth, VL_MACROBLOCK_HEIGHT);
+ 
+ 	vl_vide_buffer_template(&templ, &template, resource_formats[0], depth, PIPE_USAGE_STATIC, 0);
++	/* TODO: Setting the transfer flag is only a workaround till we get tiling working */
++	templ.flags = R600_RESOURCE_FLAG_TRANSFER;
+ 	resources[0] = (struct r600_resource_texture *)
+ 		pipe->screen->resource_create(pipe->screen, &templ);
+ 	if (!resources[0])
+@@ -83,6 +85,7 @@ struct pipe_video_buffer *radeonsi_video_buffer_create(struct pipe_context *pipe
+ 
+ 	if (resource_formats[1] != PIPE_FORMAT_NONE) {
+ 		vl_vide_buffer_template(&templ, &template, resource_formats[1], depth, PIPE_USAGE_STATIC, 1);
++		templ.flags = R600_RESOURCE_FLAG_TRANSFER;
+ 		resources[1] = (struct r600_resource_texture *)
+ 			pipe->screen->resource_create(pipe->screen, &templ);
+ 		if (!resources[1])
+@@ -91,6 +94,7 @@ struct pipe_video_buffer *radeonsi_video_buffer_create(struct pipe_context *pipe
+ 
+ 	if (resource_formats[2] != PIPE_FORMAT_NONE) {
+ 		vl_vide_buffer_template(&templ, &template, resource_formats[2], depth, PIPE_USAGE_STATIC, 2);
++		templ.flags = R600_RESOURCE_FLAG_TRANSFER;
+ 		resources[2] = (struct r600_resource_texture *)
+ 			pipe->screen->resource_create(pipe->screen, &templ);
+ 		if (!resources[2])
+@@ -114,9 +118,6 @@ struct pipe_video_buffer *radeonsi_video_buffer_create(struct pipe_context *pipe
+ 		/* recreate the CS handle */
+ 		resources[i]->resource.cs_buf = ctx->ws->buffer_get_cs_handle(
+ 			resources[i]->resource.buf);
+-
+-		/* TODO: tiling used to work with UVD on SI */
+-		resources[i]->surface.level[0].mode = RADEON_SURF_MODE_LINEAR_ALIGNED;
+ 	}
+ 
+ 	template.height *= depth;
+-- 
+1.7.10.4
+
diff --git a/debian/patches/106-radeon-uvd-stop-using-anonymous-unions.diff b/debian/patches/106-radeon-uvd-stop-using-anonymous-unions.diff
new file mode 100644
index 0000000..b83c83c
--- /dev/null
+++ b/debian/patches/106-radeon-uvd-stop-using-anonymous-unions.diff
@@ -0,0 +1,203 @@
+From bf7fc15438db469561d67f937f36e0a7f069c2ef Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
+Date: Fri, 26 Apr 2013 11:16:19 +0200
+Subject: [PATCH 06/17] radeon/uvd: stop using anonymous unions
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Christian König <christian.koenig@amd.com>
+---
+ src/gallium/drivers/r600/r600_uvd.c         |    4 +-
+ src/gallium/drivers/radeon/radeon_uvd.c     |   66 +++++++++++++--------------
+ src/gallium/drivers/radeon/radeon_uvd.h     |    6 +--
+ src/gallium/drivers/radeonsi/radeonsi_uvd.c |    2 +-
+ 4 files changed, 39 insertions(+), 39 deletions(-)
+
+diff --git a/src/gallium/drivers/r600/r600_uvd.c b/src/gallium/drivers/r600/r600_uvd.c
+index dafddfa..c1de497 100644
+--- a/src/gallium/drivers/r600/r600_uvd.c
++++ b/src/gallium/drivers/r600/r600_uvd.c
+@@ -155,8 +155,8 @@ static struct radeon_winsys_cs_handle* r600_uvd_set_dtb(struct ruvd_msg *msg, st
+ 	struct r600_texture *luma = (struct r600_texture *)buf->resources[0];
+ 	struct r600_texture *chroma = (struct r600_texture *)buf->resources[1];
+ 
+-	msg->decode.dt_field_mode = buf->base.interlaced;
+-	msg->decode.dt_surf_tile_config |= RUVD_NUM_BANKS(eg_num_banks(rscreen->tiling_info.num_banks));
++	msg->body.decode.dt_field_mode = buf->base.interlaced;
++	msg->body.decode.dt_surf_tile_config |= RUVD_NUM_BANKS(eg_num_banks(rscreen->tiling_info.num_banks));
+ 
+ 	ruvd_set_dt_surfaces(msg, &luma->surface, &chroma->surface);
+ 
+diff --git a/src/gallium/drivers/radeon/radeon_uvd.c b/src/gallium/drivers/radeon/radeon_uvd.c
+index dae7880..64ef335 100644
+--- a/src/gallium/drivers/radeon/radeon_uvd.c
++++ b/src/gallium/drivers/radeon/radeon_uvd.c
+@@ -744,31 +744,31 @@ static void ruvd_end_frame(struct pipe_video_decoder *decoder,
+ 	msg.stream_handle = dec->stream_handle;
+ 	msg.status_report_feedback_number = dec->frame_number;
+ 
+-	msg.decode.stream_type = profile2stream_type(dec->base.profile);
+-	msg.decode.decode_flags = 0x1;
+-	msg.decode.width_in_samples = dec->base.width;
+-	msg.decode.height_in_samples = dec->base.height;
++	msg.body.decode.stream_type = profile2stream_type(dec->base.profile);
++	msg.body.decode.decode_flags = 0x1;
++	msg.body.decode.width_in_samples = dec->base.width;
++	msg.body.decode.height_in_samples = dec->base.height;
+ 
+-	msg.decode.dpb_size = dec->dpb.buf->size;
+-	msg.decode.bsd_size = bs_size;
++	msg.body.decode.dpb_size = dec->dpb.buf->size;
++	msg.body.decode.bsd_size = bs_size;
+ 
+ 	dt = dec->set_dtb(&msg, (struct vl_video_buffer *)target);
+ 
+ 	switch (u_reduce_video_profile(picture->profile)) {
+ 	case PIPE_VIDEO_CODEC_MPEG4_AVC:
+-		msg.decode.h264 = get_h264_msg(dec, (struct pipe_h264_picture_desc*)picture);
++		msg.body.decode.codec.h264 = get_h264_msg(dec, (struct pipe_h264_picture_desc*)picture);
+ 		break;
+ 
+ 	case PIPE_VIDEO_CODEC_VC1:
+-		msg.decode.vc1 = get_vc1_msg((struct pipe_vc1_picture_desc*)picture);
++		msg.body.decode.codec.vc1 = get_vc1_msg((struct pipe_vc1_picture_desc*)picture);
+ 		break;
+ 
+ 	case PIPE_VIDEO_CODEC_MPEG12:
+-		msg.decode.mpeg2 = get_mpeg2_msg(dec, (struct pipe_mpeg12_picture_desc*)picture);
++		msg.body.decode.codec.mpeg2 = get_mpeg2_msg(dec, (struct pipe_mpeg12_picture_desc*)picture);
+ 		break;
+ 
+ 	case PIPE_VIDEO_CODEC_MPEG4:
+-		msg.decode.mpeg4 = get_mpeg4_msg(dec, (struct pipe_mpeg4_picture_desc*)picture);
++		msg.body.decode.codec.mpeg4 = get_mpeg4_msg(dec, (struct pipe_mpeg4_picture_desc*)picture);
+ 		break;
+ 
+ 	default:
+@@ -776,8 +776,8 @@ static void ruvd_end_frame(struct pipe_video_decoder *decoder,
+ 		return;
+ 	}
+ 
+-	msg.decode.db_surf_tile_config = msg.decode.dt_surf_tile_config;
+-	msg.decode.extension_support = 0x1;
++	msg.body.decode.db_surf_tile_config = msg.body.decode.dt_surf_tile_config;
++	msg.body.decode.extension_support = 0x1;
+ 
+ 	send_msg(dec, &msg);
+ 	send_cmd(dec, RUVD_CMD_DPB_BUFFER, dec->dpb.cs_handle, 0,
+@@ -892,10 +892,10 @@ struct pipe_video_decoder *ruvd_create_decoder(struct pipe_context *context,
+ 	msg.size = sizeof(msg);
+ 	msg.msg_type = RUVD_MSG_CREATE;
+ 	msg.stream_handle = dec->stream_handle;
+-	msg.create.stream_type = profile2stream_type(dec->base.profile);
+-	msg.create.width_in_samples = dec->base.width;
+-	msg.create.height_in_samples = dec->base.height;
+-	msg.create.dpb_size = dec->dpb.buf->size;
++	msg.body.create.stream_type = profile2stream_type(dec->base.profile);
++	msg.body.create.width_in_samples = dec->base.width;
++	msg.body.create.height_in_samples = dec->base.height;
++	msg.body.create.dpb_size = dec->dpb.buf->size;
+ 	send_msg(dec, &msg);
+ 	flush(dec);
+ 	next_buffer(dec);
+@@ -1029,42 +1029,42 @@ static unsigned bank_wh(unsigned bankwh)
+ void ruvd_set_dt_surfaces(struct ruvd_msg *msg, struct radeon_surface *luma,
+ 			  struct radeon_surface *chroma)
+ {
+-	msg->decode.dt_pitch = luma->level[0].pitch_bytes;
++	msg->body.decode.dt_pitch = luma->level[0].pitch_bytes;
+ 	switch (luma->level[0].mode) {
+ 	case RADEON_SURF_MODE_LINEAR_ALIGNED:
+-		msg->decode.dt_tiling_mode = RUVD_TILE_LINEAR;
+-		msg->decode.dt_array_mode = RUVD_ARRAY_MODE_LINEAR;
++		msg->body.decode.dt_tiling_mode = RUVD_TILE_LINEAR;
++		msg->body.decode.dt_array_mode = RUVD_ARRAY_MODE_LINEAR;
+ 		break;
+ 	case RADEON_SURF_MODE_1D:
+-		msg->decode.dt_tiling_mode = RUVD_TILE_8X8;
+-		msg->decode.dt_array_mode = RUVD_ARRAY_MODE_1D_THIN;
++		msg->body.decode.dt_tiling_mode = RUVD_TILE_8X8;
++		msg->body.decode.dt_array_mode = RUVD_ARRAY_MODE_1D_THIN;
+ 		break;
+ 	case RADEON_SURF_MODE_2D:
+-		msg->decode.dt_tiling_mode = RUVD_TILE_8X8;
+-		msg->decode.dt_array_mode = RUVD_ARRAY_MODE_2D_THIN;
++		msg->body.decode.dt_tiling_mode = RUVD_TILE_8X8;
++		msg->body.decode.dt_array_mode = RUVD_ARRAY_MODE_2D_THIN;
+ 		break;
+ 	default:
+ 		assert(0);
+ 		break;
+ 	}
+ 
+-	msg->decode.dt_luma_top_offset = texture_offset(luma, 0);
+-	msg->decode.dt_chroma_top_offset = texture_offset(chroma, 0);
+-	if (msg->decode.dt_field_mode) {
+-		msg->decode.dt_luma_bottom_offset = texture_offset(luma, 1);
+-		msg->decode.dt_chroma_bottom_offset = texture_offset(chroma, 1);
++	msg->body.decode.dt_luma_top_offset = texture_offset(luma, 0);
++	msg->body.decode.dt_chroma_top_offset = texture_offset(chroma, 0);
++	if (msg->body.decode.dt_field_mode) {
++		msg->body.decode.dt_luma_bottom_offset = texture_offset(luma, 1);
++		msg->body.decode.dt_chroma_bottom_offset = texture_offset(chroma, 1);
+ 	} else {
+-		msg->decode.dt_luma_bottom_offset = msg->decode.dt_luma_top_offset;
+-		msg->decode.dt_chroma_bottom_offset = msg->decode.dt_chroma_top_offset;
++		msg->body.decode.dt_luma_bottom_offset = msg->body.decode.dt_luma_top_offset;
++		msg->body.decode.dt_chroma_bottom_offset = msg->body.decode.dt_chroma_top_offset;
+ 	}
+ 
+ 	assert(luma->bankw == chroma->bankw);
+ 	assert(luma->bankh == chroma->bankh);
+ 	assert(luma->mtilea == chroma->mtilea);
+ 
+-	msg->decode.dt_surf_tile_config |= RUVD_BANK_WIDTH(bank_wh(luma->bankw));
+-	msg->decode.dt_surf_tile_config |= RUVD_BANK_HEIGHT(bank_wh(luma->bankh));
+-	msg->decode.dt_surf_tile_config |= RUVD_MACRO_TILE_ASPECT_RATIO(macro_tile_aspect(luma->mtilea));
++	msg->body.decode.dt_surf_tile_config |= RUVD_BANK_WIDTH(bank_wh(luma->bankw));
++	msg->body.decode.dt_surf_tile_config |= RUVD_BANK_HEIGHT(bank_wh(luma->bankh));
++	msg->body.decode.dt_surf_tile_config |= RUVD_MACRO_TILE_ASPECT_RATIO(macro_tile_aspect(luma->mtilea));
+ }
+ 
+ int ruvd_get_video_param(struct pipe_screen *screen,
+diff --git a/src/gallium/drivers/radeon/radeon_uvd.h b/src/gallium/drivers/radeon/radeon_uvd.h
+index b6bceae..1e97425 100644
+--- a/src/gallium/drivers/radeon/radeon_uvd.h
++++ b/src/gallium/drivers/radeon/radeon_uvd.h
+@@ -328,8 +328,8 @@ struct ruvd_msg {
+ 				struct ruvd_mpeg2	mpeg2;
+ 				struct ruvd_mpeg4	mpeg4;
+ 
+-				uint32_t codec_info[768];
+-			} ;
++				uint32_t info[768];
++			} codec;
+ 
+ 			uint8_t		extension_support;
+ 			uint8_t		reserved_8bit_1;
+@@ -337,7 +337,7 @@ struct ruvd_msg {
+ 			uint8_t		reserved_8bit_3;
+ 			uint32_t	extension_reserved[64];
+ 		} decode;
+-	};
++	} body;
+ };
+ 
+ /* driver dependent callback */
+diff --git a/src/gallium/drivers/radeonsi/radeonsi_uvd.c b/src/gallium/drivers/radeonsi/radeonsi_uvd.c
+index 3aec098..1aaaac4 100644
+--- a/src/gallium/drivers/radeonsi/radeonsi_uvd.c
++++ b/src/gallium/drivers/radeonsi/radeonsi_uvd.c
+@@ -136,7 +136,7 @@ static struct radeon_winsys_cs_handle* radeonsi_uvd_set_dtb(struct ruvd_msg *msg
+ 	struct r600_resource_texture *luma = (struct r600_resource_texture *)buf->resources[0];
+ 	struct r600_resource_texture *chroma = (struct r600_resource_texture *)buf->resources[1];
+ 
+-	msg->decode.dt_field_mode = buf->base.interlaced;
++	msg->body.decode.dt_field_mode = buf->base.interlaced;
+ 
+ 	ruvd_set_dt_surfaces(msg, &luma->surface, &chroma->surface);
+ 
+-- 
+1.7.10.4
+
diff --git a/debian/patches/107-r600-uvd-stop-advertising-MPEG4-on-UVD-2.x-chips-v2.diff b/debian/patches/107-r600-uvd-stop-advertising-MPEG4-on-UVD-2.x-chips-v2.diff
new file mode 100644
index 0000000..3a94770
--- /dev/null
+++ b/debian/patches/107-r600-uvd-stop-advertising-MPEG4-on-UVD-2.x-chips-v2.diff
@@ -0,0 +1,85 @@
+From e18d2ec827987c4cd357746d1d7ab37a2d568cc7 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
+Date: Fri, 26 Apr 2013 11:49:55 +0200
+Subject: [PATCH 07/17] r600/uvd: stop advertising MPEG4 on UVD 2.x chips v2
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+That is just not supported by the hardware.
+
+v2: fix compare
+
+Signed-off-by: Christian König <christian.koenig@amd.com>
+Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
+---
+ src/gallium/drivers/r600/r600_pipe.c    |    2 +-
+ src/gallium/drivers/r600/r600_pipe.h    |    3 +++
+ src/gallium/drivers/r600/r600_uvd.c     |   14 ++++++++++++++
+ src/gallium/drivers/radeon/radeon_uvd.c |    1 -
+ 4 files changed, 18 insertions(+), 2 deletions(-)
+
+diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c
+index 28e999f..c27ae24 100644
+--- a/src/gallium/drivers/r600/r600_pipe.c
++++ b/src/gallium/drivers/r600/r600_pipe.c
+@@ -1147,7 +1147,7 @@ struct pipe_screen *r600_screen_create(struct radeon_winsys *ws)
+ 	rscreen->screen.fence_finish = r600_fence_finish;
+ 
+ 	if (rscreen->info.has_uvd) {
+-		rscreen->screen.get_video_param = ruvd_get_video_param;
++		rscreen->screen.get_video_param = r600_uvd_get_video_param;
+ 		rscreen->screen.is_video_format_supported = ruvd_is_format_supported;
+ 	} else {
+ 		rscreen->screen.get_video_param = r600_get_video_param;
+diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h
+index be4a155..f53d4ce 100644
+--- a/src/gallium/drivers/r600/r600_pipe.h
++++ b/src/gallium/drivers/r600/r600_pipe.h
+@@ -757,6 +757,9 @@ struct pipe_video_decoder *r600_uvd_create_decoder(struct pipe_context *context,
+ struct pipe_video_buffer *r600_video_buffer_create(struct pipe_context *pipe,
+ 						   const struct pipe_video_buffer *tmpl);
+ 
++int r600_uvd_get_video_param(struct pipe_screen *screen,
++			     enum pipe_video_profile profile,
++			     enum pipe_video_cap param);
+ 
+ /*
+  * Helpers for building command buffers
+diff --git a/src/gallium/drivers/r600/r600_uvd.c b/src/gallium/drivers/r600/r600_uvd.c
+index c1de497..c4c04a8 100644
+--- a/src/gallium/drivers/r600/r600_uvd.c
++++ b/src/gallium/drivers/r600/r600_uvd.c
+@@ -177,3 +177,17 @@ struct pipe_video_decoder *r600_uvd_create_decoder(struct pipe_context *context,
+ 			 	   width, height, max_references, expect_chunked_decode,
+ 				   ctx->ws, r600_uvd_set_dtb);
+ }
++
++int r600_uvd_get_video_param(struct pipe_screen *screen,
++			     enum pipe_video_profile profile,
++			     enum pipe_video_cap param)
++{
++	struct r600_screen *rscreen = (struct r600_screen *)screen;
++
++	/* No support for MPEG4 on UVD 2.x */
++	if (param == PIPE_VIDEO_CAP_SUPPORTED && rscreen->family < CHIP_CEDAR &&
++	    u_reduce_video_profile(profile) == PIPE_VIDEO_CODEC_MPEG4)
++		return false;
++
++	return ruvd_get_video_param(screen, profile, param);
++}
+diff --git a/src/gallium/drivers/radeon/radeon_uvd.c b/src/gallium/drivers/radeon/radeon_uvd.c
+index 64ef335..97b171f 100644
+--- a/src/gallium/drivers/radeon/radeon_uvd.c
++++ b/src/gallium/drivers/radeon/radeon_uvd.c
+@@ -1076,7 +1076,6 @@ int ruvd_get_video_param(struct pipe_screen *screen,
+ 		switch (u_reduce_video_profile(profile)) {
+ 		case PIPE_VIDEO_CODEC_MPEG12:
+ 		case PIPE_VIDEO_CODEC_MPEG4:
+-			/* TODO not all hw families support MPEG4 */
+ 		case PIPE_VIDEO_CODEC_MPEG4_AVC:
+ 		case PIPE_VIDEO_CODEC_VC1:
+ 			return true;
+-- 
+1.7.10.4
+
diff --git a/debian/patches/108-vl-compositor-cleanup-background-clearing.diff b/debian/patches/108-vl-compositor-cleanup-background-clearing.diff
new file mode 100644
index 0000000..767e2e7
--- /dev/null
+++ b/debian/patches/108-vl-compositor-cleanup-background-clearing.diff
@@ -0,0 +1,156 @@
+From 2fb23750877ec9ba6050726499caecfb0bfe3b43 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
+Date: Mon, 29 Apr 2013 17:43:04 +0200
+Subject: [PATCH 08/17] vl/compositor: cleanup background clearing
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add an extra parameter to specify if we should clear the render target.
+
+Signed-off-by: Christian König <christian.koenig@amd.com>
+---
+ src/gallium/auxiliary/vl/vl_compositor.c        |    7 ++++---
+ src/gallium/auxiliary/vl/vl_compositor.h        |    3 ++-
+ src/gallium/state_trackers/vdpau/device.c       |    2 +-
+ src/gallium/state_trackers/vdpau/mixer.c        |    2 +-
+ src/gallium/state_trackers/vdpau/output.c       |    9 +++++----
+ src/gallium/state_trackers/vdpau/presentation.c |    2 +-
+ src/gallium/state_trackers/xvmc/surface.c       |    2 +-
+ 7 files changed, 15 insertions(+), 12 deletions(-)
+
+diff --git a/src/gallium/auxiliary/vl/vl_compositor.c b/src/gallium/auxiliary/vl/vl_compositor.c
+index fecf3c9..0ffa431 100644
+--- a/src/gallium/auxiliary/vl/vl_compositor.c
++++ b/src/gallium/auxiliary/vl/vl_compositor.c
+@@ -985,7 +985,8 @@ void
+ vl_compositor_render(struct vl_compositor_state *s,
+                      struct vl_compositor       *c,
+                      struct pipe_surface        *dst_surface,
+-                     struct u_rect              *dirty_area)
++                     struct u_rect              *dirty_area,
++                     bool                        clear_dirty)
+ {
+    assert(c);
+    assert(dst_surface);
+@@ -1003,8 +1004,8 @@ vl_compositor_render(struct vl_compositor_state *s,
+ 
+    gen_vertex_data(c, s, dirty_area);
+ 
+-   if (dirty_area && (dirty_area->x0 < dirty_area->x1 ||
+-                      dirty_area->y0 < dirty_area->y1)) {
++   if (clear_dirty && dirty_area &&
++       (dirty_area->x0 < dirty_area->x1 || dirty_area->y0 < dirty_area->y1)) {
+ 
+       c->pipe->clear_render_target(c->pipe, dst_surface, &s->clear_color,
+                                    0, 0, dst_surface->width, dst_surface->height);
+diff --git a/src/gallium/auxiliary/vl/vl_compositor.h b/src/gallium/auxiliary/vl/vl_compositor.h
+index 6de6ca0..2a1f66c 100644
+--- a/src/gallium/auxiliary/vl/vl_compositor.h
++++ b/src/gallium/auxiliary/vl/vl_compositor.h
+@@ -224,7 +224,8 @@ void
+ vl_compositor_render(struct vl_compositor_state *state,
+                      struct vl_compositor       *compositor,
+                      struct pipe_surface        *dst_surface,
+-                     struct u_rect              *dirty_area);
++                     struct u_rect              *dirty_area,
++                     bool                        clear_dirty);
+ 
+ /**
+  * destroy this compositor
+diff --git a/src/gallium/state_trackers/vdpau/device.c b/src/gallium/state_trackers/vdpau/device.c
+index dd586f5..c530f43 100644
+--- a/src/gallium/state_trackers/vdpau/device.c
++++ b/src/gallium/state_trackers/vdpau/device.c
+@@ -279,7 +279,7 @@ vlVdpResolveDelayedRendering(vlVdpDevice *dev, struct pipe_surface *surface, str
+       dirty_area = &vlsurface->dirty_area;
+    }
+ 
+-   vl_compositor_render(cstate, &dev->compositor, surface, dirty_area);
++   vl_compositor_render(cstate, &dev->compositor, surface, dirty_area, true);
+ 
+    dev->delayed_rendering.surface = VDP_INVALID_HANDLE;
+    dev->delayed_rendering.cstate = NULL;
+diff --git a/src/gallium/state_trackers/vdpau/mixer.c b/src/gallium/state_trackers/vdpau/mixer.c
+index 81a5c29..1d2ae49 100644
+--- a/src/gallium/state_trackers/vdpau/mixer.c
++++ b/src/gallium/state_trackers/vdpau/mixer.c
+@@ -312,7 +312,7 @@ VdpStatus vlVdpVideoMixerRender(VdpVideoMixer mixer,
+    if (!vmixer->noise_reduction.filter && !vmixer->sharpness.filter)
+       vlVdpSave4DelayedRendering(vmixer->device, destination_surface, &vmixer->cstate);
+    else {
+-      vl_compositor_render(&vmixer->cstate, compositor, dst->surface, &dst->dirty_area);
++      vl_compositor_render(&vmixer->cstate, compositor, dst->surface, &dst->dirty_area, true);
+ 
+       /* applying the noise reduction after scaling is actually not very
+          clever, but currently we should avoid to copy around the image
+diff --git a/src/gallium/state_trackers/vdpau/output.c b/src/gallium/state_trackers/vdpau/output.c
+index a835126..e31fee7 100644
+--- a/src/gallium/state_trackers/vdpau/output.c
++++ b/src/gallium/state_trackers/vdpau/output.c
+@@ -381,7 +381,7 @@ vlVdpOutputSurfacePutBitsIndexed(VdpOutputSurface surface,
+    vl_compositor_clear_layers(cstate);
+    vl_compositor_set_palette_layer(cstate, compositor, 0, sv_idx, sv_tbl, NULL, NULL, false);
+    vl_compositor_set_layer_dst_area(cstate, 0, RectToPipe(destination_rect, &dst_rect));
+-   vl_compositor_render(cstate, compositor, vlsurface->surface, NULL);
++   vl_compositor_render(cstate, compositor, vlsurface->surface, &vlsurface->dirty_area, false);
+ 
+    pipe_sampler_view_reference(&sv_idx, NULL);
+    pipe_sampler_view_reference(&sv_tbl, NULL);
+@@ -487,7 +487,7 @@ vlVdpOutputSurfacePutBitsYCbCr(VdpOutputSurface surface,
+    vl_compositor_clear_layers(cstate);
+    vl_compositor_set_buffer_layer(cstate, compositor, 0, vbuffer, NULL, NULL, VL_COMPOSITOR_WEAVE);
+    vl_compositor_set_layer_dst_area(cstate, 0, RectToPipe(destination_rect, &dst_rect));
+-   vl_compositor_render(cstate, compositor, vlsurface->surface, NULL);
++   vl_compositor_render(cstate, compositor, vlsurface->surface, &vlsurface->dirty_area, false);
+ 
+    vbuffer->destroy(vbuffer);
+    pipe_mutex_unlock(vlsurface->device->mutex);
+@@ -657,7 +657,7 @@ vlVdpOutputSurfaceRenderOutputSurface(VdpOutputSurface destination_surface,
+                                 RectToPipe(source_rect, &src_rect), NULL,
+                                 ColorsToPipe(colors, flags, vlcolors));
+    vl_compositor_set_layer_dst_area(cstate, 0, RectToPipe(destination_rect, &dst_rect));
+-   vl_compositor_render(cstate, compositor, dst_vlsurface->surface, NULL);
++   vl_compositor_render(cstate, compositor, dst_vlsurface->surface, &dst_vlsurface->dirty_area, false);
+ 
+    context->delete_blend_state(context, blend);
+    pipe_mutex_unlock(dst_vlsurface->device->mutex);
+@@ -716,7 +716,8 @@ vlVdpOutputSurfaceRenderBitmapSurface(VdpOutputSurface destination_surface,
+                                 RectToPipe(source_rect, &src_rect), NULL,
+                                 ColorsToPipe(colors, flags, vlcolors));
+    vl_compositor_set_layer_dst_area(cstate, 0, RectToPipe(destination_rect, &dst_rect));
+-   vl_compositor_render(cstate, compositor, dst_vlsurface->surface, NULL);
++   vl_compositor_render(cstate, compositor, dst_vlsurface->surface, &dst_vlsurface->dirty_area, false);
++
+ 
+    context->delete_blend_state(context, blend);
+    pipe_mutex_unlock(dst_vlsurface->device->mutex);
+diff --git a/src/gallium/state_trackers/vdpau/presentation.c b/src/gallium/state_trackers/vdpau/presentation.c
+index 3dd7f05..a5466cd 100644
+--- a/src/gallium/state_trackers/vdpau/presentation.c
++++ b/src/gallium/state_trackers/vdpau/presentation.c
+@@ -264,7 +264,7 @@ vlVdpPresentationQueueDisplay(VdpPresentationQueue presentation_queue,
+       vl_compositor_clear_layers(cstate);
+       vl_compositor_set_rgba_layer(cstate, compositor, 0, surf->sampler_view, &src_rect, NULL, NULL);
+       vl_compositor_set_dst_clip(cstate, &dst_clip);
+-      vl_compositor_render(cstate, compositor, surf_draw, dirty_area);
++      vl_compositor_render(cstate, compositor, surf_draw, dirty_area, true);
+    }
+ 
+    vl_screen_set_next_timestamp(pq->device->vscreen, earliest_presentation_time);
+diff --git a/src/gallium/state_trackers/xvmc/surface.c b/src/gallium/state_trackers/xvmc/surface.c
+index 99d2d70..6a895aa 100644
+--- a/src/gallium/state_trackers/xvmc/surface.c
++++ b/src/gallium/state_trackers/xvmc/surface.c
+@@ -432,7 +432,7 @@ Status XvMCPutSurface(Display *dpy, XvMCSurface *surface, Drawable drawable,
+ 
+    vl_compositor_set_layer_dst_area(cstate, 0, &dst_rect);
+    vl_compositor_set_layer_dst_area(cstate, 1, &dst_rect);
+-   vl_compositor_render(cstate, compositor, surf, dirty_area);
++   vl_compositor_render(cstate, compositor, surf, dirty_area, true);
+ 
+    pipe->flush(pipe, &surface_priv->fence, 0);
+ 
+-- 
+1.7.10.4
+
diff --git a/debian/patches/109-vl-buffer-use-2D_ARRAY-instead-of-3D-textures.diff b/debian/patches/109-vl-buffer-use-2D_ARRAY-instead-of-3D-textures.diff
new file mode 100644
index 0000000..ace7821
--- /dev/null
+++ b/debian/patches/109-vl-buffer-use-2D_ARRAY-instead-of-3D-textures.diff
@@ -0,0 +1,340 @@
+From ccf1273f53d16f00629b9bb8175dba896662f679 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
+Date: Tue, 30 Apr 2013 14:40:40 +0200
+Subject: [PATCH 09/17] vl/buffer: use 2D_ARRAY instead of 3D textures
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Christian König <christian.koenig@amd.com>
+---
+ src/gallium/auxiliary/vl/vl_compositor.c    |   12 ++++++------
+ src/gallium/auxiliary/vl/vl_video_buffer.c  |   23 ++++++++++++-----------
+ src/gallium/auxiliary/vl/vl_video_buffer.h  |    7 ++++---
+ src/gallium/drivers/r600/r600_uvd.c         |   14 +++++++-------
+ src/gallium/drivers/radeonsi/radeonsi_uvd.c |   14 +++++++-------
+ src/gallium/state_trackers/vdpau/surface.c  |    8 ++++----
+ 6 files changed, 40 insertions(+), 38 deletions(-)
+
+diff --git a/src/gallium/auxiliary/vl/vl_compositor.c b/src/gallium/auxiliary/vl/vl_compositor.c
+index 0ffa431..97d30f3 100644
+--- a/src/gallium/auxiliary/vl/vl_compositor.c
++++ b/src/gallium/auxiliary/vl/vl_compositor.c
+@@ -152,7 +152,7 @@ create_frag_shader_video_buffer(struct vl_compositor *c)
+     * fragment = csc * texel
+     */
+    for (i = 0; i < 3; ++i)
+-      ureg_TEX(shader, ureg_writemask(texel, TGSI_WRITEMASK_X << i), TGSI_TEXTURE_3D, tc, sampler[i]);
++      ureg_TEX(shader, ureg_writemask(texel, TGSI_WRITEMASK_X << i), TGSI_TEXTURE_2D_ARRAY, tc, sampler[i]);
+ 
+    ureg_MOV(shader, ureg_writemask(texel, TGSI_WRITEMASK_W), ureg_imm1f(shader, 1.0f));
+ 
+@@ -207,7 +207,7 @@ create_frag_shader_weave(struct vl_compositor *c)
+                i_tc[i], ureg_imm1f(shader, 0.5f));
+       ureg_ROUND(shader, ureg_writemask(t_tc[i], TGSI_WRITEMASK_YZ), ureg_src(t_tc[i]));
+       ureg_MOV(shader, ureg_writemask(t_tc[i], TGSI_WRITEMASK_W),
+-               ureg_imm1f(shader, i ? -0.25f : 0.25f));
++               ureg_imm1f(shader, i ? 1.0f : 0.0f));
+       ureg_ADD(shader, ureg_writemask(t_tc[i], TGSI_WRITEMASK_YZ),
+                ureg_src(t_tc[i]), ureg_imm1f(shader, 0.5f));
+       ureg_MUL(shader, ureg_writemask(t_tc[i], TGSI_WRITEMASK_Y),
+@@ -227,7 +227,7 @@ create_frag_shader_weave(struct vl_compositor *c)
+             TGSI_SWIZZLE_X, j ? TGSI_SWIZZLE_Z : TGSI_SWIZZLE_Y, TGSI_SWIZZLE_W, TGSI_SWIZZLE_W);
+ 
+          ureg_TEX(shader, ureg_writemask(t_texel[i], TGSI_WRITEMASK_X << j),
+-                  TGSI_TEXTURE_3D, src, sampler[j]);
++                  TGSI_TEXTURE_2D_ARRAY, src, sampler[j]);
+       }
+ 
+    /* calculate linear interpolation factor
+@@ -557,7 +557,7 @@ static INLINE struct u_rect
+ default_rect(struct vl_compositor_layer *layer)
+ {
+    struct pipe_resource *res = layer->sampler_views[0]->texture;
+-   struct u_rect rect = { 0, res->width0, 0, res->height0 * res->depth0 };
++   struct u_rect rect = { 0, res->width0, 0, res->height0 * res->array_size };
+    return rect;
+ }
+ 
+@@ -901,14 +901,14 @@ vl_compositor_set_buffer_layer(struct vl_compositor_state *s,
+          break;
+ 
+       case VL_COMPOSITOR_BOB_TOP:
+-         s->layers[layer].zw.x = 0.25f;
++         s->layers[layer].zw.x = 0.0f;
+          s->layers[layer].src.tl.y += half_a_line;
+          s->layers[layer].src.br.y += half_a_line;
+          s->layers[layer].fs = c->fs_video_buffer;
+          break;
+ 
+       case VL_COMPOSITOR_BOB_BOTTOM:
+-         s->layers[layer].zw.x = 0.75f;
++         s->layers[layer].zw.x = 1.0f;
+          s->layers[layer].src.tl.y -= half_a_line;
+          s->layers[layer].src.br.y -= half_a_line;
+          s->layers[layer].fs = c->fs_video_buffer;
+diff --git a/src/gallium/auxiliary/vl/vl_video_buffer.c b/src/gallium/auxiliary/vl/vl_video_buffer.c
+index d61dab2..220c3ea 100644
+--- a/src/gallium/auxiliary/vl/vl_video_buffer.c
++++ b/src/gallium/auxiliary/vl/vl_video_buffer.c
+@@ -216,15 +216,16 @@ void
+ vl_vide_buffer_template(struct pipe_resource *templ,
+                         const struct pipe_video_buffer *tmpl,
+                         enum pipe_format resource_format,
+-                        unsigned depth, unsigned usage, unsigned plane)
++                        unsigned array_size, unsigned usage,
++                        unsigned plane)
+ {
+    memset(templ, 0, sizeof(*templ));
+-   templ->target = depth > 1 ? PIPE_TEXTURE_3D : PIPE_TEXTURE_2D;
++   templ->target = array_size > 1 ? PIPE_TEXTURE_2D_ARRAY : PIPE_TEXTURE_2D;
+    templ->format = resource_format;
+    templ->width0 = tmpl->width;
+    templ->height0 = tmpl->height;
+-   templ->depth0 = depth;
+-   templ->array_size = 1;
++   templ->depth0 = 1;
++   templ->array_size = array_size;
+    templ->bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
+    templ->usage = usage;
+ 
+@@ -349,15 +350,15 @@ vl_video_buffer_surfaces(struct pipe_video_buffer *buffer)
+    struct vl_video_buffer *buf = (struct vl_video_buffer *)buffer;
+    struct pipe_surface surf_templ;
+    struct pipe_context *pipe;
+-   unsigned i, j, depth, surf;
++   unsigned i, j, array_size, surf;
+ 
+    assert(buf);
+ 
+    pipe = buf->base.context;
+ 
+-   depth = buffer->interlaced ? 2 : 1;
++   array_size = buffer->interlaced ? 2 : 1;
+    for (i = 0, surf = 0; i < VL_NUM_COMPONENTS; ++i) {
+-      for (j = 0; j < depth; ++j, ++surf) {
++      for (j = 0; j < array_size; ++j, ++surf) {
+          assert(surf < (VL_NUM_COMPONENTS * 2));
+ 
+          if (!buf->resources[i]) {
+@@ -433,7 +434,7 @@ struct pipe_video_buffer *
+ vl_video_buffer_create_ex(struct pipe_context *pipe,
+                           const struct pipe_video_buffer *tmpl,
+                           const enum pipe_format resource_formats[VL_NUM_COMPONENTS],
+-                          unsigned depth, unsigned usage)
++                          unsigned array_size, unsigned usage)
+ {
+    struct pipe_resource res_tmpl;
+    struct pipe_resource *resources[VL_NUM_COMPONENTS];
+@@ -443,7 +444,7 @@ vl_video_buffer_create_ex(struct pipe_context *pipe,
+ 
+    memset(resources, 0, sizeof resources);
+ 
+-   vl_vide_buffer_template(&res_tmpl, tmpl, resource_formats[0], depth, usage, 0);
++   vl_vide_buffer_template(&res_tmpl, tmpl, resource_formats[0], array_size, usage, 0);
+    resources[0] = pipe->screen->resource_create(pipe->screen, &res_tmpl);
+    if (!resources[0])
+       goto error;
+@@ -453,7 +454,7 @@ vl_video_buffer_create_ex(struct pipe_context *pipe,
+       return vl_video_buffer_create_ex2(pipe, tmpl, resources);
+    }
+ 
+-   vl_vide_buffer_template(&res_tmpl, tmpl, resource_formats[1], depth, usage, 1);
++   vl_vide_buffer_template(&res_tmpl, tmpl, resource_formats[1], array_size, usage, 1);
+    resources[1] = pipe->screen->resource_create(pipe->screen, &res_tmpl);
+    if (!resources[1])
+       goto error;
+@@ -461,7 +462,7 @@ vl_video_buffer_create_ex(struct pipe_context *pipe,
+    if (resource_formats[2] == PIPE_FORMAT_NONE)
+       return vl_video_buffer_create_ex2(pipe, tmpl, resources);
+ 
+-   vl_vide_buffer_template(&res_tmpl, tmpl, resource_formats[2], depth, usage, 2);
++   vl_vide_buffer_template(&res_tmpl, tmpl, resource_formats[2], array_size, usage, 2);
+    resources[2] = pipe->screen->resource_create(pipe->screen, &res_tmpl);
+    if (!resources[2])
+       goto error;
+diff --git a/src/gallium/auxiliary/vl/vl_video_buffer.h b/src/gallium/auxiliary/vl/vl_video_buffer.h
+index 6e2f8b8..e666011 100644
+--- a/src/gallium/auxiliary/vl/vl_video_buffer.h
++++ b/src/gallium/auxiliary/vl/vl_video_buffer.h
+@@ -98,7 +98,8 @@ void
+ vl_vide_buffer_template(struct pipe_resource *templ,
+ 			const struct pipe_video_buffer *templat,
+                         enum pipe_format resource_format,
+-                        unsigned depth, unsigned usage, unsigned plane);
++                        unsigned array_size, unsigned usage,
++                        unsigned plane);
+ 
+ /**
+  * creates a video buffer, can be used as a standard implementation for pipe->create_video_buffer
+@@ -108,13 +109,13 @@ vl_video_buffer_create(struct pipe_context *pipe,
+                        const struct pipe_video_buffer *templat);
+ 
+ /**
+- * extended create function, gets depth, usage and formats for each plane seperately
++ * extended create function, gets array_size, usage and formats for each plane seperately
+  */
+ struct pipe_video_buffer *
+ vl_video_buffer_create_ex(struct pipe_context *pipe,
+                           const struct pipe_video_buffer *templat,
+                           const enum pipe_format resource_formats[VL_NUM_COMPONENTS],
+-                          unsigned depth, unsigned usage);
++                          unsigned array_size, unsigned usage);
+ 
+ /**
+  * even more extended create function, provide the pipe_resource for each plane
+diff --git a/src/gallium/drivers/r600/r600_uvd.c b/src/gallium/drivers/r600/r600_uvd.c
+index c4c04a8..9028238 100644
+--- a/src/gallium/drivers/r600/r600_uvd.c
++++ b/src/gallium/drivers/r600/r600_uvd.c
+@@ -61,7 +61,7 @@ struct pipe_video_buffer *r600_video_buffer_create(struct pipe_context *pipe,
+ 	const enum pipe_format *resource_formats;
+ 	struct pipe_video_buffer template;
+ 	struct pipe_resource templ;
+-	unsigned i, depth;
++	unsigned i, array_size;
+ 
+ 	assert(pipe);
+ 
+@@ -70,12 +70,12 @@ struct pipe_video_buffer *r600_video_buffer_create(struct pipe_context *pipe,
+ 	if (!resource_formats)
+ 		return NULL;
+ 
+-	depth = tmpl->interlaced ? 2 : 1;
++	array_size = tmpl->interlaced ? 2 : 1;
+ 	template = *tmpl;
+ 	template.width = align(tmpl->width, VL_MACROBLOCK_WIDTH);
+-	template.height = align(tmpl->height / depth, VL_MACROBLOCK_HEIGHT);
++	template.height = align(tmpl->height / array_size, VL_MACROBLOCK_HEIGHT);
+ 
+-	vl_vide_buffer_template(&templ, &template, resource_formats[0], depth, PIPE_USAGE_STATIC, 0);
++	vl_vide_buffer_template(&templ, &template, resource_formats[0], array_size, PIPE_USAGE_STATIC, 0);
+ 	if (ctx->chip_class < EVERGREEN)
+ 		templ.flags = R600_RESOURCE_FLAG_TRANSFER;
+ 	resources[0] = (struct r600_texture *)
+@@ -84,7 +84,7 @@ struct pipe_video_buffer *r600_video_buffer_create(struct pipe_context *pipe,
+ 		goto error;
+ 
+ 	if (resource_formats[1] != PIPE_FORMAT_NONE) {
+-		vl_vide_buffer_template(&templ, &template, resource_formats[1], depth, PIPE_USAGE_STATIC, 1);
++		vl_vide_buffer_template(&templ, &template, resource_formats[1], array_size, PIPE_USAGE_STATIC, 1);
+ 		if (ctx->chip_class < EVERGREEN)
+ 			templ.flags = R600_RESOURCE_FLAG_TRANSFER;
+ 		resources[1] = (struct r600_texture *)
+@@ -94,7 +94,7 @@ struct pipe_video_buffer *r600_video_buffer_create(struct pipe_context *pipe,
+ 	}
+ 
+ 	if (resource_formats[2] != PIPE_FORMAT_NONE) {
+-		vl_vide_buffer_template(&templ, &template, resource_formats[2], depth, PIPE_USAGE_STATIC, 2);
++		vl_vide_buffer_template(&templ, &template, resource_formats[2], array_size, PIPE_USAGE_STATIC, 2);
+ 		if (ctx->chip_class < EVERGREEN)
+ 			templ.flags = R600_RESOURCE_FLAG_TRANSFER;
+ 		resources[2] = (struct r600_texture *)
+@@ -122,7 +122,7 @@ struct pipe_video_buffer *r600_video_buffer_create(struct pipe_context *pipe,
+ 			resources[i]->resource.buf);
+ 	}
+ 
+-	template.height *= depth;
++	template.height *= array_size;
+ 	return vl_video_buffer_create_ex2(pipe, &template, (struct pipe_resource **)resources);
+ 
+ error:
+diff --git a/src/gallium/drivers/radeonsi/radeonsi_uvd.c b/src/gallium/drivers/radeonsi/radeonsi_uvd.c
+index 1aaaac4..04f672d 100644
+--- a/src/gallium/drivers/radeonsi/radeonsi_uvd.c
++++ b/src/gallium/drivers/radeonsi/radeonsi_uvd.c
+@@ -61,7 +61,7 @@ struct pipe_video_buffer *radeonsi_video_buffer_create(struct pipe_context *pipe
+ 	const enum pipe_format *resource_formats;
+ 	struct pipe_video_buffer template;
+ 	struct pipe_resource templ;
+-	unsigned i, depth;
++	unsigned i, array_size;
+ 
+ 	assert(pipe);
+ 
+@@ -70,12 +70,12 @@ struct pipe_video_buffer *radeonsi_video_buffer_create(struct pipe_context *pipe
+ 	if (!resource_formats)
+ 		return NULL;
+ 
+-	depth = tmpl->interlaced ? 2 : 1;
++	array_size = tmpl->interlaced ? 2 : 1;
+ 	template = *tmpl;
+ 	template.width = align(tmpl->width, VL_MACROBLOCK_WIDTH);
+-	template.height = align(tmpl->height / depth, VL_MACROBLOCK_HEIGHT);
++	template.height = align(tmpl->height / array_size, VL_MACROBLOCK_HEIGHT);
+ 
+-	vl_vide_buffer_template(&templ, &template, resource_formats[0], depth, PIPE_USAGE_STATIC, 0);
++	vl_vide_buffer_template(&templ, &template, resource_formats[0], array_size, PIPE_USAGE_STATIC, 0);
+ 	/* TODO: Setting the transfer flag is only a workaround till we get tiling working */
+ 	templ.flags = R600_RESOURCE_FLAG_TRANSFER;
+ 	resources[0] = (struct r600_resource_texture *)
+@@ -84,7 +84,7 @@ struct pipe_video_buffer *radeonsi_video_buffer_create(struct pipe_context *pipe
+ 		goto error;
+ 
+ 	if (resource_formats[1] != PIPE_FORMAT_NONE) {
+-		vl_vide_buffer_template(&templ, &template, resource_formats[1], depth, PIPE_USAGE_STATIC, 1);
++		vl_vide_buffer_template(&templ, &template, resource_formats[1], array_size, PIPE_USAGE_STATIC, 1);
+ 		templ.flags = R600_RESOURCE_FLAG_TRANSFER;
+ 		resources[1] = (struct r600_resource_texture *)
+ 			pipe->screen->resource_create(pipe->screen, &templ);
+@@ -93,7 +93,7 @@ struct pipe_video_buffer *radeonsi_video_buffer_create(struct pipe_context *pipe
+ 	}
+ 
+ 	if (resource_formats[2] != PIPE_FORMAT_NONE) {
+-		vl_vide_buffer_template(&templ, &template, resource_formats[2], depth, PIPE_USAGE_STATIC, 2);
++		vl_vide_buffer_template(&templ, &template, resource_formats[2], array_size, PIPE_USAGE_STATIC, 2);
+ 		templ.flags = R600_RESOURCE_FLAG_TRANSFER;
+ 		resources[2] = (struct r600_resource_texture *)
+ 			pipe->screen->resource_create(pipe->screen, &templ);
+@@ -120,7 +120,7 @@ struct pipe_video_buffer *radeonsi_video_buffer_create(struct pipe_context *pipe
+ 			resources[i]->resource.buf);
+ 	}
+ 
+-	template.height *= depth;
++	template.height *= array_size;
+ 	return vl_video_buffer_create_ex2(pipe, &template, (struct pipe_resource **)resources);
+ 
+ error:
+diff --git a/src/gallium/state_trackers/vdpau/surface.c b/src/gallium/state_trackers/vdpau/surface.c
+index 5c06f85..ad56125 100644
+--- a/src/gallium/state_trackers/vdpau/surface.c
++++ b/src/gallium/state_trackers/vdpau/surface.c
+@@ -228,7 +228,7 @@ vlVdpVideoSurfaceGetBitsYCbCr(VdpVideoSurface surface,
+ 
+       vlVdpVideoSurfaceSize(vlsurface, i, &width, &height);
+ 
+-      for (j = 0; j < sv->texture->depth0; ++j) {
++      for (j = 0; j < sv->texture->array_size; ++j) {
+          struct pipe_box box = {
+             0, 0, j,
+             width, height, 1
+@@ -244,7 +244,7 @@ vlVdpVideoSurfaceGetBitsYCbCr(VdpVideoSurface surface,
+          }
+ 
+          util_copy_rect(destination_data[i] + destination_pitches[i] * j, sv->texture->format,
+-                        destination_pitches[i] * sv->texture->depth0, 0, 0,
++                        destination_pitches[i] * sv->texture->array_size, 0, 0,
+                         box.width, box.height, map, transfer->stride, 0, 0);
+ 
+          pipe_transfer_unmap(pipe, transfer);
+@@ -315,7 +315,7 @@ vlVdpVideoSurfacePutBitsYCbCr(VdpVideoSurface surface,
+ 
+       vlVdpVideoSurfaceSize(p_surf, i, &width, &height);
+ 
+-      for (j = 0; j < sv->texture->depth0; ++j) {
++      for (j = 0; j < sv->texture->array_size; ++j) {
+          struct pipe_box dst_box = {
+             0, 0, j,
+             width, height, 1
+@@ -324,7 +324,7 @@ vlVdpVideoSurfacePutBitsYCbCr(VdpVideoSurface surface,
+          pipe->transfer_inline_write(pipe, sv->texture, 0,
+                                      PIPE_TRANSFER_WRITE, &dst_box,
+                                      source_data[i] + source_pitches[i] * j,
+-                                     source_pitches[i] * sv->texture->depth0,
++                                     source_pitches[i] * sv->texture->array_size,
+                                      0);
+       }
+    }
+-- 
+1.7.10.4
+
diff --git a/debian/patches/110-st-vdpau-fix-background-handling-in-the-mixer.diff b/debian/patches/110-st-vdpau-fix-background-handling-in-the-mixer.diff
new file mode 100644
index 0000000..c5fa7a2
--- /dev/null
+++ b/debian/patches/110-st-vdpau-fix-background-handling-in-the-mixer.diff
@@ -0,0 +1,59 @@
+From bf6c42466ea60efa7bc3060278f55b273cc0702f Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
+Date: Tue, 30 Apr 2013 14:55:14 +0200
+Subject: [PATCH 10/17] st/vdpau: fix background handling in the mixer
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Christian König <christian.koenig@amd.com>
+---
+ src/gallium/state_trackers/vdpau/mixer.c |   19 ++++++++++---------
+ 1 file changed, 10 insertions(+), 9 deletions(-)
+
+diff --git a/src/gallium/state_trackers/vdpau/mixer.c b/src/gallium/state_trackers/vdpau/mixer.c
+index 1d2ae49..26db5c8 100644
+--- a/src/gallium/state_trackers/vdpau/mixer.c
++++ b/src/gallium/state_trackers/vdpau/mixer.c
+@@ -221,7 +221,7 @@ VdpStatus vlVdpVideoMixerRender(VdpVideoMixer mixer,
+ 
+    vlVdpVideoMixer *vmixer;
+    vlVdpSurface *surf;
+-   vlVdpOutputSurface *dst;
++   vlVdpOutputSurface *dst, *bg = NULL;
+ 
+    struct vl_compositor *compositor;
+ 
+@@ -250,20 +250,21 @@ VdpStatus vlVdpVideoMixerRender(VdpVideoMixer mixer,
+    if (!dst)
+       return VDP_STATUS_INVALID_HANDLE;
+ 
+-   pipe_mutex_lock(vmixer->device->mutex);
+-   vlVdpResolveDelayedRendering(vmixer->device, NULL, NULL);
+    if (background_surface != VDP_INVALID_HANDLE) {
+-      vlVdpOutputSurface *bg = vlGetDataHTAB(background_surface);
+-      if (!bg) {
+-         pipe_mutex_unlock(vmixer->device->mutex);
++      bg = vlGetDataHTAB(background_surface);
++      if (!bg)
+          return VDP_STATUS_INVALID_HANDLE;
+-      }
+-      vl_compositor_set_rgba_layer(&vmixer->cstate, compositor, layer++, bg->sampler_view,
+-                                   RectToPipe(background_source_rect, &rect), NULL, NULL);
+    }
+ 
++   pipe_mutex_lock(vmixer->device->mutex);
++   vlVdpResolveDelayedRendering(vmixer->device, NULL, NULL);
++
+    vl_compositor_clear_layers(&vmixer->cstate);
+ 
++   if (bg)
++      vl_compositor_set_rgba_layer(&vmixer->cstate, compositor, layer++, bg->sampler_view,
++                                   RectToPipe(background_source_rect, &rect), NULL, NULL);
++
+    switch (current_picture_structure) {
+    case VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD:
+       deinterlace = VL_COMPOSITOR_BOB_TOP;
+-- 
+1.7.10.4
+
diff --git a/debian/patches/111-radeon-uvd-fix-quant-scan-order-for-mpeg2.diff b/debian/patches/111-radeon-uvd-fix-quant-scan-order-for-mpeg2.diff
new file mode 100644
index 0000000..f562da5
--- /dev/null
+++ b/debian/patches/111-radeon-uvd-fix-quant-scan-order-for-mpeg2.diff
@@ -0,0 +1,42 @@
+From 75a2e4d3c098c645cdcf617277e1cde763934322 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
+Date: Tue, 30 Apr 2013 19:38:24 +0200
+Subject: [PATCH 11/17] radeon/uvd: fix quant scan order for mpeg2
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Christian König <christian.koenig@amd.com>
+---
+ src/gallium/drivers/radeon/radeon_uvd.c |    8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/src/gallium/drivers/radeon/radeon_uvd.c b/src/gallium/drivers/radeon/radeon_uvd.c
+index 97b171f..b8fe819 100644
+--- a/src/gallium/drivers/radeon/radeon_uvd.c
++++ b/src/gallium/drivers/radeon/radeon_uvd.c
+@@ -514,6 +514,7 @@ static uint32_t get_ref_pic_idx(struct ruvd_decoder *dec, struct pipe_video_buff
+ static struct ruvd_mpeg2 get_mpeg2_msg(struct ruvd_decoder *dec,
+ 				       struct pipe_mpeg12_picture_desc *pic)
+ {
++	const int *zscan = pic->alternate_scan ? vl_zscan_alternate : vl_zscan_normal;
+ 	struct ruvd_mpeg2 result;
+ 	unsigned i;
+ 
+@@ -524,8 +525,11 @@ static struct ruvd_mpeg2 get_mpeg2_msg(struct ruvd_decoder *dec,
+ 
+ 	result.load_intra_quantiser_matrix = 1;
+ 	result.load_nonintra_quantiser_matrix = 1;
+-	memcpy(&result.intra_quantiser_matrix, pic->intra_matrix, 64);
+-	memcpy(&result.nonintra_quantiser_matrix, pic->non_intra_matrix, 64);
++
++	for (i = 0; i < 64; ++i) {
++		result.intra_quantiser_matrix[i] = pic->intra_matrix[zscan[i]];
++		result.nonintra_quantiser_matrix[i] = pic->non_intra_matrix[zscan[i]];
++	}
+ 
+ 	result.profile_and_level_indication = 0;
+ 	result.chroma_format = 0x1;
+-- 
+1.7.10.4
+
diff --git a/debian/patches/112-radeon-uvd-Fix-build-failure-with-non-standard-libdr.diff b/debian/patches/112-radeon-uvd-Fix-build-failure-with-non-standard-libdr.diff
new file mode 100644
index 0000000..0dc49a1
--- /dev/null
+++ b/debian/patches/112-radeon-uvd-Fix-build-failure-with-non-standard-libdr.diff
@@ -0,0 +1,33 @@
+From 0ae61d1eaf0c53e977cdfd20ea53bd700334ad17 Mon Sep 17 00:00:00 2001
+From: Lauri Kasanen <cand@gmx.com>
+Date: Wed, 1 May 2013 19:26:06 +0300
+Subject: [PATCH 12/17] radeon/uvd: Fix build failure with non-standard libdrm
+ installation prefix
+
+Without this patch, radeon_uvd failed to find the libdrm includes:
+
+In file included from radeon_uvd.c:48:
+../../winsys/radeon/drm/radeon_winsys.h:44:35: error:
+libdrm/radeon_surface.h: No such file or directory
+
+Signed-off-by: Lauri Kasanen <cand@gmx.com>
+---
+ src/gallium/drivers/radeon/Makefile.am |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/gallium/drivers/radeon/Makefile.am b/src/gallium/drivers/radeon/Makefile.am
+index d78a550..6cca331 100644
+--- a/src/gallium/drivers/radeon/Makefile.am
++++ b/src/gallium/drivers/radeon/Makefile.am
+@@ -5,7 +5,7 @@ LIBGALLIUM_LIBS=
+ 
+ noinst_LTLIBRARIES = libradeon.la
+ 
+-AM_CFLAGS = $(GALLIUM_CFLAGS)
++AM_CFLAGS = $(GALLIUM_CFLAGS) $(RADEON_CFLAGS)
+ 
+ libradeon_la_SOURCES = \
+ 	$(C_SOURCES)
+-- 
+1.7.10.4
+
diff --git a/debian/patches/113-radeon-uvd-fix-some-MPEG4-artifacts.diff b/debian/patches/113-radeon-uvd-fix-some-MPEG4-artifacts.diff
new file mode 100644
index 0000000..d71a870
--- /dev/null
+++ b/debian/patches/113-radeon-uvd-fix-some-MPEG4-artifacts.diff
@@ -0,0 +1,76 @@
+From 10de99f037692d2ee1fec3910a94c73b14952000 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
+Date: Wed, 1 May 2013 14:33:49 +0200
+Subject: [PATCH 13/17] radeon/uvd: fix some MPEG4 artifacts
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Still not perfect, but a step in the right direction.
+
+Signed-off-by: Christian König <christian.koenig@amd.com>
+---
+ src/gallium/drivers/radeon/radeon_uvd.c |   24 +++++++++++++++++-------
+ 1 file changed, 17 insertions(+), 7 deletions(-)
+
+diff --git a/src/gallium/drivers/radeon/radeon_uvd.c b/src/gallium/drivers/radeon/radeon_uvd.c
+index b8fe819..c018d57 100644
+--- a/src/gallium/drivers/radeon/radeon_uvd.c
++++ b/src/gallium/drivers/radeon/radeon_uvd.c
+@@ -557,16 +557,22 @@ static struct ruvd_mpeg4 get_mpeg4_msg(struct ruvd_decoder *dec,
+ {
+ 	struct ruvd_mpeg4 result;
+ 	unsigned i;
++
+ 	memset(&result, 0, sizeof(result));
+ 	result.decoded_pic_idx = dec->frame_number;
+ 	for (i = 0; i < 2; ++i)
+ 		result.ref_pic_idx[i] = get_ref_pic_idx(dec, pic->ref[i]);
+ 
++	result.variant_type = 0;
++	result.profile_and_level_indication = 0xF0; // ASP Level0
++
++	result.video_object_layer_verid = 0x5; // advanced simple
++	result.video_object_layer_shape = 0x0; // rectangular
++
+ 	result.video_object_layer_width = dec->base.width;
+-        result.video_object_layer_height = dec->base.height;
++	result.video_object_layer_height = dec->base.height;
+ 
+ 	result.vop_time_increment_resolution = pic->vop_time_increment_resolution;
+-	result.quant_type = pic->quant_type;
+ 
+ 	result.flags |= pic->short_video_header << 0;
+ 	//result.flags |= obmc_disable << 1;
+@@ -574,19 +580,23 @@ static struct ruvd_mpeg4 get_mpeg4_msg(struct ruvd_decoder *dec,
+         result.flags |= 1 << 3; // load_intra_quant_mat
+ 	result.flags |= 1 << 4; // load_nonintra_quant_mat
+ 	result.flags |= pic->quarter_sample << 5;
+-	//result.flags |= complexity_estimation_disable << 6
++	result.flags |= 1 << 6; // complexity_estimation_disable
+ 	result.flags |= pic->resync_marker_disable << 7;
+ 	//result.flags |= data_partitioned << 8;
+ 	//result.flags |= reversible_vlc << 9;
+-	//result.flags |= newpred_enable << 10;
+-	//result.flags |= reduced_resolution_vop_enable << 11;
++	result.flags |= 0 << 10; // newpred_enable
++	result.flags |= 0 << 11; // reduced_resolution_vop_enable
+ 	//result.flags |= scalability << 12;
+ 	//result.flags |= is_object_layer_identifier << 13;
+ 	//result.flags |= fixed_vop_rate << 14;
+ 	//result.flags |= newpred_segment_type << 15;
+ 
+-	memcpy(&result.intra_quant_mat, pic->intra_matrix, 64);
+-	memcpy(&result.nonintra_quant_mat, pic->non_intra_matrix, 64);
++	result.quant_type = pic->quant_type;
++
++	for (i = 0; i < 64; ++i) {
++		result.intra_quant_mat[i] = pic->intra_matrix[vl_zscan_normal[i]];
++		result.nonintra_quant_mat[i] = pic->non_intra_matrix[vl_zscan_normal[i]];
++	}
+ 
+ 	/*
+ 	int32_t 	trd [2]
+-- 
+1.7.10.4
+
diff --git a/debian/patches/114-vl-buffers-fix-typo-in-function-name.diff b/debian/patches/114-vl-buffers-fix-typo-in-function-name.diff
new file mode 100644
index 0000000..17461e7
--- /dev/null
+++ b/debian/patches/114-vl-buffers-fix-typo-in-function-name.diff
@@ -0,0 +1,150 @@
+From 367558575f3efb79e754f2232a19c86366f4a95d Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
+Date: Thu, 2 May 2013 15:42:24 +0200
+Subject: [PATCH 14/17] vl/buffers: fix typo in function name
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Christian König <christian.koenig@amd.com>
+---
+ src/gallium/auxiliary/vl/vl_video_buffer.c  |   16 ++++++++--------
+ src/gallium/auxiliary/vl/vl_video_buffer.h  |   10 +++++-----
+ src/gallium/drivers/r600/r600_uvd.c         |    6 +++---
+ src/gallium/drivers/radeonsi/radeonsi_uvd.c |    6 +++---
+ 4 files changed, 19 insertions(+), 19 deletions(-)
+
+diff --git a/src/gallium/auxiliary/vl/vl_video_buffer.c b/src/gallium/auxiliary/vl/vl_video_buffer.c
+index 220c3ea..fe33325 100644
+--- a/src/gallium/auxiliary/vl/vl_video_buffer.c
++++ b/src/gallium/auxiliary/vl/vl_video_buffer.c
+@@ -213,11 +213,11 @@ vl_video_buffer_get_associated_data(struct pipe_video_buffer *vbuf,
+ }
+ 
+ void
+-vl_vide_buffer_template(struct pipe_resource *templ,
+-                        const struct pipe_video_buffer *tmpl,
+-                        enum pipe_format resource_format,
+-                        unsigned array_size, unsigned usage,
+-                        unsigned plane)
++vl_video_buffer_template(struct pipe_resource *templ,
++                         const struct pipe_video_buffer *tmpl,
++                         enum pipe_format resource_format,
++                         unsigned array_size, unsigned usage,
++                         unsigned plane)
+ {
+    memset(templ, 0, sizeof(*templ));
+    templ->target = array_size > 1 ? PIPE_TEXTURE_2D_ARRAY : PIPE_TEXTURE_2D;
+@@ -444,7 +444,7 @@ vl_video_buffer_create_ex(struct pipe_context *pipe,
+ 
+    memset(resources, 0, sizeof resources);
+ 
+-   vl_vide_buffer_template(&res_tmpl, tmpl, resource_formats[0], array_size, usage, 0);
++   vl_video_buffer_template(&res_tmpl, tmpl, resource_formats[0], array_size, usage, 0);
+    resources[0] = pipe->screen->resource_create(pipe->screen, &res_tmpl);
+    if (!resources[0])
+       goto error;
+@@ -454,7 +454,7 @@ vl_video_buffer_create_ex(struct pipe_context *pipe,
+       return vl_video_buffer_create_ex2(pipe, tmpl, resources);
+    }
+ 
+-   vl_vide_buffer_template(&res_tmpl, tmpl, resource_formats[1], array_size, usage, 1);
++   vl_video_buffer_template(&res_tmpl, tmpl, resource_formats[1], array_size, usage, 1);
+    resources[1] = pipe->screen->resource_create(pipe->screen, &res_tmpl);
+    if (!resources[1])
+       goto error;
+@@ -462,7 +462,7 @@ vl_video_buffer_create_ex(struct pipe_context *pipe,
+    if (resource_formats[2] == PIPE_FORMAT_NONE)
+       return vl_video_buffer_create_ex2(pipe, tmpl, resources);
+ 
+-   vl_vide_buffer_template(&res_tmpl, tmpl, resource_formats[2], array_size, usage, 2);
++   vl_video_buffer_template(&res_tmpl, tmpl, resource_formats[2], array_size, usage, 2);
+    resources[2] = pipe->screen->resource_create(pipe->screen, &res_tmpl);
+    if (!resources[2])
+       goto error;
+diff --git a/src/gallium/auxiliary/vl/vl_video_buffer.h b/src/gallium/auxiliary/vl/vl_video_buffer.h
+index e666011..1285f52 100644
+--- a/src/gallium/auxiliary/vl/vl_video_buffer.h
++++ b/src/gallium/auxiliary/vl/vl_video_buffer.h
+@@ -95,11 +95,11 @@ vl_video_buffer_get_associated_data(struct pipe_video_buffer *vbuf,
+  * fill a resource template for the given plane
+  */
+ void
+-vl_vide_buffer_template(struct pipe_resource *templ,
+-			const struct pipe_video_buffer *templat,
+-                        enum pipe_format resource_format,
+-                        unsigned array_size, unsigned usage,
+-                        unsigned plane);
++vl_video_buffer_template(struct pipe_resource *templ,
++                         const struct pipe_video_buffer *templat,
++                         enum pipe_format resource_format,
++                         unsigned array_size, unsigned usage,
++                         unsigned plane);
+ 
+ /**
+  * creates a video buffer, can be used as a standard implementation for pipe->create_video_buffer
+diff --git a/src/gallium/drivers/r600/r600_uvd.c b/src/gallium/drivers/r600/r600_uvd.c
+index 9028238..a172467 100644
+--- a/src/gallium/drivers/r600/r600_uvd.c
++++ b/src/gallium/drivers/r600/r600_uvd.c
+@@ -75,7 +75,7 @@ struct pipe_video_buffer *r600_video_buffer_create(struct pipe_context *pipe,
+ 	template.width = align(tmpl->width, VL_MACROBLOCK_WIDTH);
+ 	template.height = align(tmpl->height / array_size, VL_MACROBLOCK_HEIGHT);
+ 
+-	vl_vide_buffer_template(&templ, &template, resource_formats[0], array_size, PIPE_USAGE_STATIC, 0);
++	vl_video_buffer_template(&templ, &template, resource_formats[0], array_size, PIPE_USAGE_STATIC, 0);
+ 	if (ctx->chip_class < EVERGREEN)
+ 		templ.flags = R600_RESOURCE_FLAG_TRANSFER;
+ 	resources[0] = (struct r600_texture *)
+@@ -84,7 +84,7 @@ struct pipe_video_buffer *r600_video_buffer_create(struct pipe_context *pipe,
+ 		goto error;
+ 
+ 	if (resource_formats[1] != PIPE_FORMAT_NONE) {
+-		vl_vide_buffer_template(&templ, &template, resource_formats[1], array_size, PIPE_USAGE_STATIC, 1);
++		vl_video_buffer_template(&templ, &template, resource_formats[1], array_size, PIPE_USAGE_STATIC, 1);
+ 		if (ctx->chip_class < EVERGREEN)
+ 			templ.flags = R600_RESOURCE_FLAG_TRANSFER;
+ 		resources[1] = (struct r600_texture *)
+@@ -94,7 +94,7 @@ struct pipe_video_buffer *r600_video_buffer_create(struct pipe_context *pipe,
+ 	}
+ 
+ 	if (resource_formats[2] != PIPE_FORMAT_NONE) {
+-		vl_vide_buffer_template(&templ, &template, resource_formats[2], array_size, PIPE_USAGE_STATIC, 2);
++		vl_video_buffer_template(&templ, &template, resource_formats[2], array_size, PIPE_USAGE_STATIC, 2);
+ 		if (ctx->chip_class < EVERGREEN)
+ 			templ.flags = R600_RESOURCE_FLAG_TRANSFER;
+ 		resources[2] = (struct r600_texture *)
+diff --git a/src/gallium/drivers/radeonsi/radeonsi_uvd.c b/src/gallium/drivers/radeonsi/radeonsi_uvd.c
+index 04f672d..a618a2b 100644
+--- a/src/gallium/drivers/radeonsi/radeonsi_uvd.c
++++ b/src/gallium/drivers/radeonsi/radeonsi_uvd.c
+@@ -75,7 +75,7 @@ struct pipe_video_buffer *radeonsi_video_buffer_create(struct pipe_context *pipe
+ 	template.width = align(tmpl->width, VL_MACROBLOCK_WIDTH);
+ 	template.height = align(tmpl->height / array_size, VL_MACROBLOCK_HEIGHT);
+ 
+-	vl_vide_buffer_template(&templ, &template, resource_formats[0], array_size, PIPE_USAGE_STATIC, 0);
++	vl_video_buffer_template(&templ, &template, resource_formats[0], array_size, PIPE_USAGE_STATIC, 0);
+ 	/* TODO: Setting the transfer flag is only a workaround till we get tiling working */
+ 	templ.flags = R600_RESOURCE_FLAG_TRANSFER;
+ 	resources[0] = (struct r600_resource_texture *)
+@@ -84,7 +84,7 @@ struct pipe_video_buffer *radeonsi_video_buffer_create(struct pipe_context *pipe
+ 		goto error;
+ 
+ 	if (resource_formats[1] != PIPE_FORMAT_NONE) {
+-		vl_vide_buffer_template(&templ, &template, resource_formats[1], array_size, PIPE_USAGE_STATIC, 1);
++		vl_video_buffer_template(&templ, &template, resource_formats[1], array_size, PIPE_USAGE_STATIC, 1);
+ 		templ.flags = R600_RESOURCE_FLAG_TRANSFER;
+ 		resources[1] = (struct r600_resource_texture *)
+ 			pipe->screen->resource_create(pipe->screen, &templ);
+@@ -93,7 +93,7 @@ struct pipe_video_buffer *radeonsi_video_buffer_create(struct pipe_context *pipe
+ 	}
+ 
+ 	if (resource_formats[2] != PIPE_FORMAT_NONE) {
+-		vl_vide_buffer_template(&templ, &template, resource_formats[2], array_size, PIPE_USAGE_STATIC, 2);
++		vl_video_buffer_template(&templ, &template, resource_formats[2], array_size, PIPE_USAGE_STATIC, 2);
+ 		templ.flags = R600_RESOURCE_FLAG_TRANSFER;
+ 		resources[2] = (struct r600_resource_texture *)
+ 			pipe->screen->resource_create(pipe->screen, &templ);
+-- 
+1.7.10.4
+
diff --git a/debian/patches/115-vl-idct-fix-for-commit-7d2f2a0c890b1993532a45c8c392c.diff b/debian/patches/115-vl-idct-fix-for-commit-7d2f2a0c890b1993532a45c8c392c.diff
new file mode 100644
index 0000000..3c5c4eb
--- /dev/null
+++ b/debian/patches/115-vl-idct-fix-for-commit-7d2f2a0c890b1993532a45c8c392c.diff
@@ -0,0 +1,223 @@
+From 16f22fd1a74bc6557cfcff7f6b2f683ab90daaa0 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
+Date: Thu, 2 May 2013 16:02:05 +0200
+Subject: [PATCH 15/17] vl/idct: fix for commit
+ 7d2f2a0c890b1993532a45c8c392c28950ddc06e
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+We still need the option for handling 3D textures as well.
+
+Should fix: https://bugs.freedesktop.org/show_bug.cgi?id=64143
+
+Signed-off-by: Christian König <christian.koenig@amd.com>
+---
+ src/gallium/auxiliary/vl/vl_mpeg12_decoder.c |    6 +++---
+ src/gallium/auxiliary/vl/vl_video_buffer.c   |   23 ++++++++++++++---------
+ src/gallium/auxiliary/vl/vl_video_buffer.h   |    8 ++++----
+ src/gallium/drivers/r600/r600_uvd.c          |    6 +++---
+ src/gallium/drivers/radeonsi/radeonsi_uvd.c  |    6 +++---
+ 5 files changed, 27 insertions(+), 22 deletions(-)
+
+diff --git a/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c b/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c
+index eb82b95..1eb9708 100644
+--- a/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c
++++ b/src/gallium/auxiliary/vl/vl_mpeg12_decoder.c
+@@ -902,7 +902,7 @@ init_idct(struct vl_mpeg12_decoder *dec, const struct format_config* format_conf
+    dec->idct_source = vl_video_buffer_create_ex
+    (
+       dec->base.context, &templat,
+-      formats, 1, PIPE_USAGE_STATIC
++      formats, 1, 1, PIPE_USAGE_STATIC
+    );
+ 
+    if (!dec->idct_source)
+@@ -916,7 +916,7 @@ init_idct(struct vl_mpeg12_decoder *dec, const struct format_config* format_conf
+    dec->mc_source = vl_video_buffer_create_ex
+    (
+       dec->base.context, &templat,
+-      formats, nr_of_idct_render_targets, PIPE_USAGE_STATIC
++      formats, nr_of_idct_render_targets, 1, PIPE_USAGE_STATIC
+    );
+ 
+    if (!dec->mc_source)
+@@ -967,7 +967,7 @@ init_mc_source_widthout_idct(struct vl_mpeg12_decoder *dec, const struct format_
+    dec->mc_source = vl_video_buffer_create_ex
+    (
+       dec->base.context, &templat,
+-      formats, 1, PIPE_USAGE_STATIC
++      formats, 1, 1, PIPE_USAGE_STATIC
+    );
+       
+    return dec->mc_source != NULL;
+diff --git a/src/gallium/auxiliary/vl/vl_video_buffer.c b/src/gallium/auxiliary/vl/vl_video_buffer.c
+index fe33325..6ef95e4 100644
+--- a/src/gallium/auxiliary/vl/vl_video_buffer.c
++++ b/src/gallium/auxiliary/vl/vl_video_buffer.c
+@@ -216,15 +216,20 @@ void
+ vl_video_buffer_template(struct pipe_resource *templ,
+                          const struct pipe_video_buffer *tmpl,
+                          enum pipe_format resource_format,
+-                         unsigned array_size, unsigned usage,
+-                         unsigned plane)
++                         unsigned depth, unsigned array_size,
++                         unsigned usage, unsigned plane)
+ {
+    memset(templ, 0, sizeof(*templ));
+-   templ->target = array_size > 1 ? PIPE_TEXTURE_2D_ARRAY : PIPE_TEXTURE_2D;
++   if (depth > 1)
++      templ->target = PIPE_TEXTURE_3D;
++   else if (array_size > 1)
++      templ->target = PIPE_TEXTURE_2D_ARRAY;
++   else
++      templ->target = PIPE_TEXTURE_2D;
+    templ->format = resource_format;
+    templ->width0 = tmpl->width;
+    templ->height0 = tmpl->height;
+-   templ->depth0 = 1;
++   templ->depth0 = depth;
+    templ->array_size = array_size;
+    templ->bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
+    templ->usage = usage;
+@@ -420,7 +425,7 @@ vl_video_buffer_create(struct pipe_context *pipe,
+    result = vl_video_buffer_create_ex
+    (
+       pipe, &templat, resource_formats,
+-      tmpl->interlaced ? 2 : 1, PIPE_USAGE_STATIC
++      1, tmpl->interlaced ? 2 : 1, PIPE_USAGE_STATIC
+    );
+ 
+ 
+@@ -434,7 +439,7 @@ struct pipe_video_buffer *
+ vl_video_buffer_create_ex(struct pipe_context *pipe,
+                           const struct pipe_video_buffer *tmpl,
+                           const enum pipe_format resource_formats[VL_NUM_COMPONENTS],
+-                          unsigned array_size, unsigned usage)
++                          unsigned depth, unsigned array_size, unsigned usage)
+ {
+    struct pipe_resource res_tmpl;
+    struct pipe_resource *resources[VL_NUM_COMPONENTS];
+@@ -444,7 +449,7 @@ vl_video_buffer_create_ex(struct pipe_context *pipe,
+ 
+    memset(resources, 0, sizeof resources);
+ 
+-   vl_video_buffer_template(&res_tmpl, tmpl, resource_formats[0], array_size, usage, 0);
++   vl_video_buffer_template(&res_tmpl, tmpl, resource_formats[0], depth, array_size, usage, 0);
+    resources[0] = pipe->screen->resource_create(pipe->screen, &res_tmpl);
+    if (!resources[0])
+       goto error;
+@@ -454,7 +459,7 @@ vl_video_buffer_create_ex(struct pipe_context *pipe,
+       return vl_video_buffer_create_ex2(pipe, tmpl, resources);
+    }
+ 
+-   vl_video_buffer_template(&res_tmpl, tmpl, resource_formats[1], array_size, usage, 1);
++   vl_video_buffer_template(&res_tmpl, tmpl, resource_formats[1], depth, array_size, usage, 1);
+    resources[1] = pipe->screen->resource_create(pipe->screen, &res_tmpl);
+    if (!resources[1])
+       goto error;
+@@ -462,7 +467,7 @@ vl_video_buffer_create_ex(struct pipe_context *pipe,
+    if (resource_formats[2] == PIPE_FORMAT_NONE)
+       return vl_video_buffer_create_ex2(pipe, tmpl, resources);
+ 
+-   vl_video_buffer_template(&res_tmpl, tmpl, resource_formats[2], array_size, usage, 2);
++   vl_video_buffer_template(&res_tmpl, tmpl, resource_formats[2], depth, array_size, usage, 2);
+    resources[2] = pipe->screen->resource_create(pipe->screen, &res_tmpl);
+    if (!resources[2])
+       goto error;
+diff --git a/src/gallium/auxiliary/vl/vl_video_buffer.h b/src/gallium/auxiliary/vl/vl_video_buffer.h
+index 1285f52..178f429 100644
+--- a/src/gallium/auxiliary/vl/vl_video_buffer.h
++++ b/src/gallium/auxiliary/vl/vl_video_buffer.h
+@@ -98,8 +98,8 @@ void
+ vl_video_buffer_template(struct pipe_resource *templ,
+                          const struct pipe_video_buffer *templat,
+                          enum pipe_format resource_format,
+-                         unsigned array_size, unsigned usage,
+-                         unsigned plane);
++                         unsigned depth, unsigned array_size,
++                         unsigned usage, unsigned plane);
+ 
+ /**
+  * creates a video buffer, can be used as a standard implementation for pipe->create_video_buffer
+@@ -109,13 +109,13 @@ vl_video_buffer_create(struct pipe_context *pipe,
+                        const struct pipe_video_buffer *templat);
+ 
+ /**
+- * extended create function, gets array_size, usage and formats for each plane seperately
++ * extended create function, gets depth, array_size, usage and formats for each plane seperately
+  */
+ struct pipe_video_buffer *
+ vl_video_buffer_create_ex(struct pipe_context *pipe,
+                           const struct pipe_video_buffer *templat,
+                           const enum pipe_format resource_formats[VL_NUM_COMPONENTS],
+-                          unsigned array_size, unsigned usage);
++                          unsigned depth, unsigned array_size, unsigned usage);
+ 
+ /**
+  * even more extended create function, provide the pipe_resource for each plane
+diff --git a/src/gallium/drivers/r600/r600_uvd.c b/src/gallium/drivers/r600/r600_uvd.c
+index a172467..9d8ae94 100644
+--- a/src/gallium/drivers/r600/r600_uvd.c
++++ b/src/gallium/drivers/r600/r600_uvd.c
+@@ -75,7 +75,7 @@ struct pipe_video_buffer *r600_video_buffer_create(struct pipe_context *pipe,
+ 	template.width = align(tmpl->width, VL_MACROBLOCK_WIDTH);
+ 	template.height = align(tmpl->height / array_size, VL_MACROBLOCK_HEIGHT);
+ 
+-	vl_video_buffer_template(&templ, &template, resource_formats[0], array_size, PIPE_USAGE_STATIC, 0);
++	vl_video_buffer_template(&templ, &template, resource_formats[0], 1, array_size, PIPE_USAGE_STATIC, 0);
+ 	if (ctx->chip_class < EVERGREEN)
+ 		templ.flags = R600_RESOURCE_FLAG_TRANSFER;
+ 	resources[0] = (struct r600_texture *)
+@@ -84,7 +84,7 @@ struct pipe_video_buffer *r600_video_buffer_create(struct pipe_context *pipe,
+ 		goto error;
+ 
+ 	if (resource_formats[1] != PIPE_FORMAT_NONE) {
+-		vl_video_buffer_template(&templ, &template, resource_formats[1], array_size, PIPE_USAGE_STATIC, 1);
++		vl_video_buffer_template(&templ, &template, resource_formats[1], 1, array_size, PIPE_USAGE_STATIC, 1);
+ 		if (ctx->chip_class < EVERGREEN)
+ 			templ.flags = R600_RESOURCE_FLAG_TRANSFER;
+ 		resources[1] = (struct r600_texture *)
+@@ -94,7 +94,7 @@ struct pipe_video_buffer *r600_video_buffer_create(struct pipe_context *pipe,
+ 	}
+ 
+ 	if (resource_formats[2] != PIPE_FORMAT_NONE) {
+-		vl_video_buffer_template(&templ, &template, resource_formats[2], array_size, PIPE_USAGE_STATIC, 2);
++		vl_video_buffer_template(&templ, &template, resource_formats[2], 1, array_size, PIPE_USAGE_STATIC, 2);
+ 		if (ctx->chip_class < EVERGREEN)
+ 			templ.flags = R600_RESOURCE_FLAG_TRANSFER;
+ 		resources[2] = (struct r600_texture *)
+diff --git a/src/gallium/drivers/radeonsi/radeonsi_uvd.c b/src/gallium/drivers/radeonsi/radeonsi_uvd.c
+index a618a2b..f6ab10d 100644
+--- a/src/gallium/drivers/radeonsi/radeonsi_uvd.c
++++ b/src/gallium/drivers/radeonsi/radeonsi_uvd.c
+@@ -75,7 +75,7 @@ struct pipe_video_buffer *radeonsi_video_buffer_create(struct pipe_context *pipe
+ 	template.width = align(tmpl->width, VL_MACROBLOCK_WIDTH);
+ 	template.height = align(tmpl->height / array_size, VL_MACROBLOCK_HEIGHT);
+ 
+-	vl_video_buffer_template(&templ, &template, resource_formats[0], array_size, PIPE_USAGE_STATIC, 0);
++	vl_video_buffer_template(&templ, &template, resource_formats[0], 1, array_size, PIPE_USAGE_STATIC, 0);
+ 	/* TODO: Setting the transfer flag is only a workaround till we get tiling working */
+ 	templ.flags = R600_RESOURCE_FLAG_TRANSFER;
+ 	resources[0] = (struct r600_resource_texture *)
+@@ -84,7 +84,7 @@ struct pipe_video_buffer *radeonsi_video_buffer_create(struct pipe_context *pipe
+ 		goto error;
+ 
+ 	if (resource_formats[1] != PIPE_FORMAT_NONE) {
+-		vl_video_buffer_template(&templ, &template, resource_formats[1], array_size, PIPE_USAGE_STATIC, 1);
++		vl_video_buffer_template(&templ, &template, resource_formats[1], 1, array_size, PIPE_USAGE_STATIC, 1);
+ 		templ.flags = R600_RESOURCE_FLAG_TRANSFER;
+ 		resources[1] = (struct r600_resource_texture *)
+ 			pipe->screen->resource_create(pipe->screen, &templ);
+@@ -93,7 +93,7 @@ struct pipe_video_buffer *radeonsi_video_buffer_create(struct pipe_context *pipe
+ 	}
+ 
+ 	if (resource_formats[2] != PIPE_FORMAT_NONE) {
+-		vl_video_buffer_template(&templ, &template, resource_formats[2], array_size, PIPE_USAGE_STATIC, 2);
++		vl_video_buffer_template(&templ, &template, resource_formats[2], 1, array_size, PIPE_USAGE_STATIC, 2);
+ 		templ.flags = R600_RESOURCE_FLAG_TRANSFER;
+ 		resources[2] = (struct r600_resource_texture *)
+ 			pipe->screen->resource_create(pipe->screen, &templ);
+-- 
+1.7.10.4
+
diff --git a/debian/patches/116-radeon-uvd-enable-interlaced-buffers-by-default.diff b/debian/patches/116-radeon-uvd-enable-interlaced-buffers-by-default.diff
new file mode 100644
index 0000000..30d6cd3
--- /dev/null
+++ b/debian/patches/116-radeon-uvd-enable-interlaced-buffers-by-default.diff
@@ -0,0 +1,66 @@
+From 4b4b8319099acaa50b7d2d7b9afd9f61f89bf20c Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
+Date: Thu, 2 May 2013 16:19:41 +0200
+Subject: [PATCH 16/17] radeon/uvd: enable interlaced buffers by default
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Kills tilling on UVD buffers, but we currently don't really need that.
+
+Signed-off-by: Christian König <christian.koenig@amd.com>
+---
+ src/gallium/drivers/r600/r600_uvd.c     |    6 +++---
+ src/gallium/drivers/radeon/radeon_uvd.c |    4 ++--
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/src/gallium/drivers/r600/r600_uvd.c b/src/gallium/drivers/r600/r600_uvd.c
+index 9d8ae94..6a3974c 100644
+--- a/src/gallium/drivers/r600/r600_uvd.c
++++ b/src/gallium/drivers/r600/r600_uvd.c
+@@ -76,7 +76,7 @@ struct pipe_video_buffer *r600_video_buffer_create(struct pipe_context *pipe,
+ 	template.height = align(tmpl->height / array_size, VL_MACROBLOCK_HEIGHT);
+ 
+ 	vl_video_buffer_template(&templ, &template, resource_formats[0], 1, array_size, PIPE_USAGE_STATIC, 0);
+-	if (ctx->chip_class < EVERGREEN)
++	if (ctx->chip_class < EVERGREEN || tmpl->interlaced)
+ 		templ.flags = R600_RESOURCE_FLAG_TRANSFER;
+ 	resources[0] = (struct r600_texture *)
+ 		pipe->screen->resource_create(pipe->screen, &templ);
+@@ -85,7 +85,7 @@ struct pipe_video_buffer *r600_video_buffer_create(struct pipe_context *pipe,
+ 
+ 	if (resource_formats[1] != PIPE_FORMAT_NONE) {
+ 		vl_video_buffer_template(&templ, &template, resource_formats[1], 1, array_size, PIPE_USAGE_STATIC, 1);
+-		if (ctx->chip_class < EVERGREEN)
++		if (ctx->chip_class < EVERGREEN || tmpl->interlaced)
+ 			templ.flags = R600_RESOURCE_FLAG_TRANSFER;
+ 		resources[1] = (struct r600_texture *)
+ 			pipe->screen->resource_create(pipe->screen, &templ);
+@@ -95,7 +95,7 @@ struct pipe_video_buffer *r600_video_buffer_create(struct pipe_context *pipe,
+ 
+ 	if (resource_formats[2] != PIPE_FORMAT_NONE) {
+ 		vl_video_buffer_template(&templ, &template, resource_formats[2], 1, array_size, PIPE_USAGE_STATIC, 2);
+-		if (ctx->chip_class < EVERGREEN)
++		if (ctx->chip_class < EVERGREEN || tmpl->interlaced)
+ 			templ.flags = R600_RESOURCE_FLAG_TRANSFER;
+ 		resources[2] = (struct r600_texture *)
+ 			pipe->screen->resource_create(pipe->screen, &templ);
+diff --git a/src/gallium/drivers/radeon/radeon_uvd.c b/src/gallium/drivers/radeon/radeon_uvd.c
+index c018d57..184a9a5 100644
+--- a/src/gallium/drivers/radeon/radeon_uvd.c
++++ b/src/gallium/drivers/radeon/radeon_uvd.c
+@@ -1105,9 +1105,9 @@ int ruvd_get_video_param(struct pipe_screen *screen,
+ 	case PIPE_VIDEO_CAP_PREFERED_FORMAT:
+ 		return PIPE_FORMAT_NV12;
+ 	case PIPE_VIDEO_CAP_PREFERS_INTERLACED:
+-		return false;
++		return true;
+ 	case PIPE_VIDEO_CAP_SUPPORTS_INTERLACED:
+-		return false; /* TODO: enable this */
++		return true;
+ 	case PIPE_VIDEO_CAP_SUPPORTS_PROGRESSIVE:
+ 		return true;
+ 	default:
+-- 
+1.7.10.4
+
diff --git a/debian/patches/117-st-xvmc-tests-Fix-build-failure-v2.diff b/debian/patches/117-st-xvmc-tests-Fix-build-failure-v2.diff
new file mode 100644
index 0000000..864c575
--- /dev/null
+++ b/debian/patches/117-st-xvmc-tests-Fix-build-failure-v2.diff
@@ -0,0 +1,34 @@
+From 5ff81cfd8640d02dc78d736cad5020d54ef7a0dc Mon Sep 17 00:00:00 2001
+From: Lauri Kasanen <cand@gmx.com>
+Date: Fri, 3 May 2013 11:48:53 +0300
+Subject: [PATCH] st/xvmc/tests: Fix build failure, v2
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+v2: Removed extra libs as requested by Matt Turner.
+
+Signed-off-by: Lauri Kasanen <cand@gmx.com>
+Reviewed-by: Christian König <christian.koenig@amd.com>
+Reviewed-by: Matt Turner <mattst88@gmail.com>
+Signed-off-by: Andreas Boll <andreas.boll.dev@gmail.com>
+---
+ src/gallium/state_trackers/xvmc/Makefile.am |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/gallium/state_trackers/xvmc/Makefile.am b/src/gallium/state_trackers/xvmc/Makefile.am
+index 8ac7406..008c50a 100644
+--- a/src/gallium/state_trackers/xvmc/Makefile.am
++++ b/src/gallium/state_trackers/xvmc/Makefile.am
+@@ -44,7 +44,7 @@ check_PROGRAMS = \
+ TESTS = $(check_PROGRAMS)
+ noinst_PROGRAMS = tests/xvmc_bench
+ 
+-TEST_LIBS = -lXvMCW -lXvMC -lXv -lX11
++TEST_LIBS = $(XVMC_LIBS) -lXvMCW
+ tests_test_context_SOURCES = tests/test_context.c tests/testlib.c
+ tests_test_context_LDADD = $(TEST_LIBS)
+ tests_test_surface_SOURCES = tests/test_surface.c tests/testlib.c
+-- 
+1.7.10.4
+
diff --git a/debian/patches/118-vl-vdpau-fix-PresentationQueueQuerySurfaceStatus.diff b/debian/patches/118-vl-vdpau-fix-PresentationQueueQuerySurfaceStatus.diff
new file mode 100644
index 0000000..dd769d1
--- /dev/null
+++ b/debian/patches/118-vl-vdpau-fix-PresentationQueueQuerySurfaceStatus.diff
@@ -0,0 +1,107 @@
+From e195d301aeb50a33cc20b208900164a97524bef4 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
+Date: Wed, 8 May 2013 17:03:01 +0200
+Subject: [PATCH] vl/vdpau: fix PresentationQueueQuerySurfaceStatus
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The last queued surface always keeps displaying.
+
+Fixing a problem with XBMC.
+
+Signed-off-by: Christian König <christian.koenig@amd.com>
+---
+ src/gallium/state_trackers/vdpau/presentation.c  |    8 ++++---
+ src/gallium/state_trackers/vdpau/vdpau_private.h |   28 +++++++++++-----------
+ 2 files changed, 19 insertions(+), 17 deletions(-)
+
+diff --git a/src/gallium/state_trackers/vdpau/presentation.c b/src/gallium/state_trackers/vdpau/presentation.c
+index a5466cd..c9f8ea7 100644
+--- a/src/gallium/state_trackers/vdpau/presentation.c
++++ b/src/gallium/state_trackers/vdpau/presentation.c
+@@ -238,8 +238,6 @@ vlVdpPresentationQueueDisplay(VdpPresentationQueue presentation_queue,
+    surf_templ.format = tex->format;
+    surf_draw = pipe->create_surface(pipe, tex, &surf_templ);
+ 
+-   surf->timestamp = (vlVdpTime)earliest_presentation_time;
+-
+    dst_clip.x0 = 0;
+    dst_clip.y0 = 0;
+    dst_clip.x1 = clip_width ? clip_width : surf_draw->width;
+@@ -276,6 +274,7 @@ vlVdpPresentationQueueDisplay(VdpPresentationQueue presentation_queue,
+ 
+    pipe->screen->fence_reference(pipe->screen, &surf->fence, NULL);
+    pipe->flush(pipe, &surf->fence, 0);
++   pq->last_surf = surf;
+ 
+    if (dump_window == -1) {
+       dump_window = debug_get_num_option("VDPAU_DUMP", 0);
+@@ -360,7 +359,10 @@ vlVdpPresentationQueueQuerySurfaceStatus(VdpPresentationQueue presentation_queue
+    *first_presentation_time = 0;
+ 
+    if (!surf->fence) {
+-      *status = VDP_PRESENTATION_QUEUE_STATUS_IDLE;
++      if (pq->last_surf == surf)
++         *status = VDP_PRESENTATION_QUEUE_STATUS_VISIBLE;
++      else
++         *status = VDP_PRESENTATION_QUEUE_STATUS_IDLE;
+    } else {
+       pipe_mutex_lock(pq->device->mutex);
+       screen = pq->device->vscreen->pscreen;
+diff --git a/src/gallium/state_trackers/vdpau/vdpau_private.h b/src/gallium/state_trackers/vdpau/vdpau_private.h
+index 918a6c2..716d218 100644
+--- a/src/gallium/state_trackers/vdpau/vdpau_private.h
++++ b/src/gallium/state_trackers/vdpau/vdpau_private.h
+@@ -323,19 +323,6 @@ typedef struct
+ typedef struct
+ {
+    vlVdpDevice *device;
+-   Drawable drawable;
+-} vlVdpPresentationQueueTarget;
+-
+-typedef struct
+-{
+-   vlVdpDevice *device;
+-   Drawable drawable;
+-   struct vl_compositor_state cstate;
+-} vlVdpPresentationQueue;
+-
+-typedef struct
+-{
+-   vlVdpDevice *device;
+    struct vl_compositor_state cstate;
+ 
+    struct {
+@@ -375,7 +362,6 @@ typedef uint64_t vlVdpTime;
+ 
+ typedef struct
+ {
+-   vlVdpTime timestamp;
+    vlVdpDevice *device;
+    struct pipe_surface *surface;
+    struct pipe_sampler_view *sampler_view;
+@@ -387,6 +373,20 @@ typedef struct
+ typedef struct
+ {
+    vlVdpDevice *device;
++   Drawable drawable;
++} vlVdpPresentationQueueTarget;
++
++typedef struct
++{
++   vlVdpDevice *device;
++   Drawable drawable;
++   struct vl_compositor_state cstate;
++   vlVdpOutputSurface *last_surf;
++} vlVdpPresentationQueue;
++
++typedef struct
++{
++   vlVdpDevice *device;
+    struct pipe_video_decoder *decoder;
+ } vlVdpDecoder;
+ 
+-- 
+1.7.10.4
+
diff --git a/debian/patches/119-st-vdpau-invalidate-the-handles-on-destruction.diff b/debian/patches/119-st-vdpau-invalidate-the-handles-on-destruction.diff
new file mode 100644
index 0000000..af242e8
--- /dev/null
+++ b/debian/patches/119-st-vdpau-invalidate-the-handles-on-destruction.diff
@@ -0,0 +1,58 @@
+From 8ea34fa0e8e2c5ac7583777cdb91f3abe8ce9f8c Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
+Date: Thu, 23 May 2013 19:17:19 +0200
+Subject: [PATCH 1/3] st/vdpau: invalidate the handles on destruction
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Fixes a problem with xbmc when switching channels.
+
+Signed-off-by: Christian König <christian.koenig@amd.com>
+---
+ src/gallium/state_trackers/vdpau/decode.c  |    1 +
+ src/gallium/state_trackers/vdpau/device.c  |    1 +
+ src/gallium/state_trackers/vdpau/surface.c |    2 ++
+ 3 files changed, 4 insertions(+)
+
+diff --git a/src/gallium/state_trackers/vdpau/decode.c b/src/gallium/state_trackers/vdpau/decode.c
+index 61b10e0..2ffd8dd 100644
+--- a/src/gallium/state_trackers/vdpau/decode.c
++++ b/src/gallium/state_trackers/vdpau/decode.c
+@@ -139,6 +139,7 @@ vlVdpDecoderDestroy(VdpDecoder decoder)
+    vldecoder->decoder->destroy(vldecoder->decoder);
+    pipe_mutex_unlock(vldecoder->device->mutex);
+ 
++   vlRemoveDataHTAB(decoder);
+    FREE(vldecoder);
+ 
+    return VDP_STATUS_OK;
+diff --git a/src/gallium/state_trackers/vdpau/device.c b/src/gallium/state_trackers/vdpau/device.c
+index c530f43..a829c27 100644
+--- a/src/gallium/state_trackers/vdpau/device.c
++++ b/src/gallium/state_trackers/vdpau/device.c
+@@ -166,6 +166,7 @@ vlVdpDeviceDestroy(VdpDevice device)
+    dev->context->destroy(dev->context);
+    vl_screen_destroy(dev->vscreen);
+ 
++   vlRemoveDataHTAB(device);
+    FREE(dev);
+    vlDestroyHTAB();
+ 
+diff --git a/src/gallium/state_trackers/vdpau/surface.c b/src/gallium/state_trackers/vdpau/surface.c
+index ad56125..135eb85 100644
+--- a/src/gallium/state_trackers/vdpau/surface.c
++++ b/src/gallium/state_trackers/vdpau/surface.c
+@@ -132,7 +132,9 @@ vlVdpVideoSurfaceDestroy(VdpVideoSurface surface)
+       p_surf->video_buffer->destroy(p_surf->video_buffer);
+    pipe_mutex_unlock(p_surf->device->mutex);
+ 
++   vlRemoveDataHTAB(surface);
+    FREE(p_surf);
++
+    return VDP_STATUS_OK;
+ }
+ 
+-- 
+1.7.10.4
+
diff --git a/debian/patches/120-st-vdpau-remove-vlCreateHTAB-from-surface-functions.diff b/debian/patches/120-st-vdpau-remove-vlCreateHTAB-from-surface-functions.diff
new file mode 100644
index 0000000..b8aff9f
--- /dev/null
+++ b/debian/patches/120-st-vdpau-remove-vlCreateHTAB-from-surface-functions.diff
@@ -0,0 +1,50 @@
+From f796b67431cfcadecfa983f9fc952dbee228cec0 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
+Date: Thu, 23 May 2013 19:28:57 +0200
+Subject: [PATCH 2/3] st/vdpau: remove vlCreateHTAB from surface functions
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Christian König <christian.koenig@amd.com>
+---
+ src/gallium/state_trackers/vdpau/surface.c |    9 ---------
+ 1 file changed, 9 deletions(-)
+
+diff --git a/src/gallium/state_trackers/vdpau/surface.c b/src/gallium/state_trackers/vdpau/surface.c
+index 135eb85..bd11fc3 100644
+--- a/src/gallium/state_trackers/vdpau/surface.c
++++ b/src/gallium/state_trackers/vdpau/surface.c
+@@ -54,11 +54,6 @@ vlVdpVideoSurfaceCreate(VdpDevice device, VdpChromaType chroma_type,
+       goto inv_size;
+    }
+ 
+-   if (!vlCreateHTAB()) {
+-      ret = VDP_STATUS_RESOURCES;
+-      goto no_htab;
+-   }
+-
+    p_surf = CALLOC(1, sizeof(vlVdpSurface));
+    if (!p_surf) {
+       ret = VDP_STATUS_RESOURCES;
+@@ -110,7 +105,6 @@ inv_device:
+    FREE(p_surf);
+ 
+ no_res:
+-no_htab:
+ inv_size:
+    return ret;
+ }
+@@ -272,9 +266,6 @@ vlVdpVideoSurfacePutBitsYCbCr(VdpVideoSurface surface,
+    struct pipe_sampler_view **sampler_views;
+    unsigned i, j;
+ 
+-   if (!vlCreateHTAB())
+-      return VDP_STATUS_RESOURCES;
+-
+    vlVdpSurface *p_surf = vlGetDataHTAB(surface);
+    if (!p_surf)
+       return VDP_STATUS_INVALID_HANDLE;
+-- 
+1.7.10.4
+
diff --git a/debian/patches/121-st-vdpau-destroy-handle-table-only-when-it-s-empty.diff b/debian/patches/121-st-vdpau-destroy-handle-table-only-when-it-s-empty.diff
new file mode 100644
index 0000000..5193ee7
--- /dev/null
+++ b/debian/patches/121-st-vdpau-destroy-handle-table-only-when-it-s-empty.diff
@@ -0,0 +1,29 @@
+From 5328c8001b26b5a341edaec3618919dd8a4de52f Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com>
+Date: Thu, 23 May 2013 19:31:08 +0200
+Subject: [PATCH 3/3] st/vdpau: destroy handle table only when it's empty
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Christian König <christian.koenig@amd.com>
+---
+ src/gallium/state_trackers/vdpau/htab.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/gallium/state_trackers/vdpau/htab.c b/src/gallium/state_trackers/vdpau/htab.c
+index 39ff7be..8b809f2 100644
+--- a/src/gallium/state_trackers/vdpau/htab.c
++++ b/src/gallium/state_trackers/vdpau/htab.c
+@@ -55,7 +55,7 @@ void vlDestroyHTAB(void)
+ {
+ #ifdef VL_HANDLES
+    pipe_mutex_lock(htab_lock);
+-   if (htab) {
++   if (htab && !handle_table_get_first_handle(htab)) {
+       handle_table_destroy(htab);
+       htab = NULL;
+    }
+-- 
+1.7.10.4
+
diff --git a/debian/patches/series b/debian/patches/series
index cf3211b..bdde67b 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -2,3 +2,24 @@
 06_kfreebsd-ftbfs.diff
 08-kfreebsd-gallium.diff
 #11-hurd-ftbfs-again.diff
+101-radeon-winsys-add-uvd-ring-support-to-winsys-v3.diff
+102-radeon-uvd-add-UVD-implementation-v5.diff
+103-autoconf-enable-detection-of-vdpau-and-xvmc-by-defau.diff
+104-r600-uvd-cleanup-disabling-tiling-on-pre-EG-asics.diff
+105-radeonsi-cleanup-disabling-tiling-for-UVD-v3.diff
+106-radeon-uvd-stop-using-anonymous-unions.diff
+107-r600-uvd-stop-advertising-MPEG4-on-UVD-2.x-chips-v2.diff
+108-vl-compositor-cleanup-background-clearing.diff
+109-vl-buffer-use-2D_ARRAY-instead-of-3D-textures.diff
+110-st-vdpau-fix-background-handling-in-the-mixer.diff
+111-radeon-uvd-fix-quant-scan-order-for-mpeg2.diff
+112-radeon-uvd-Fix-build-failure-with-non-standard-libdr.diff
+113-radeon-uvd-fix-some-MPEG4-artifacts.diff
+114-vl-buffers-fix-typo-in-function-name.diff
+115-vl-idct-fix-for-commit-7d2f2a0c890b1993532a45c8c392c.diff
+116-radeon-uvd-enable-interlaced-buffers-by-default.diff
+117-st-xvmc-tests-Fix-build-failure-v2.diff
+118-vl-vdpau-fix-PresentationQueueQuerySurfaceStatus.diff
+119-st-vdpau-invalidate-the-handles-on-destruction.diff
+120-st-vdpau-remove-vlCreateHTAB-from-surface-functions.diff
+121-st-vdpau-destroy-handle-table-only-when-it-s-empty.diff
diff --git a/debian/rules b/debian/rules
index 26dd735..ddfa0aa 100755
--- a/debian/rules
+++ b/debian/rules
@@ -135,6 +135,7 @@ confflags-swx11 = \
 	--enable-xlib-glx \
 	--disable-egl \
 	--disable-shared-glapi \
+	--disable-gallium-g3dvl \
 	CFLAGS="$(CFLAGS)" \
 	CXXFLAGS="$(CXXFLAGS)"
 
@@ -146,6 +147,7 @@ confflags-swx11-static = \
 	--enable-static \
 	--disable-egl \
 	--disable-shared-glapi \
+	--disable-gallium-g3dvl \
 	CFLAGS="$(CFLAGS)" \
 	CXXFLAGS="$(CXXFLAGS)"
 
@@ -155,6 +157,7 @@ confflags-swx11-i386-i686 = \
 	--with-gallium-drivers= \
 	--enable-xlib-glx \
 	--disable-egl \
+	--disable-gallium-g3dvl \
 	--libdir=/usr/lib/$(DEB_HOST_MULTIARCH)/i686/cmov \
 	CFLAGS="$(CFLAGS) -march=i686" \
 	CXXFLAGS="$(CXXFLAGS) -march=i686"
-- 
1.7.10.4


Reply to: