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: