From a97794e871281ac4a8184e65f988bb6d37250500 Mon Sep 17 00:00:00 2001
From: Frank Binns <frank.binns@imgtec.com>
Date: Tue, 14 Apr 2020 09:47:46 +0100
Subject: [PATCH] Add pvr dri driver

---
 meson.build                               |  19 +-
 meson_options.txt                         |   2 +-
 src/mesa/drivers/dri/meson.build          |   5 +
 src/mesa/drivers/dri/pvr/dri_support.h    | 581 +++++++++++++++
 src/mesa/drivers/dri/pvr/img_drm_fourcc.h | 113 +++
 src/mesa/drivers/dri/pvr/imgpixfmts.h     | 307 ++++++++
 src/mesa/drivers/dri/pvr/imgyuv.h         |  58 ++
 src/mesa/drivers/dri/pvr/mesa_context.c   | 208 ++++++
 src/mesa/drivers/dri/pvr/meson.build      |  48 ++
 src/mesa/drivers/dri/pvr/pvrcb.c          | 328 +++++++++
 src/mesa/drivers/dri/pvr/pvrcompat.c      | 838 ++++++++++++++++++++++
 src/mesa/drivers/dri/pvr/pvrdri.c         | 613 ++++++++++++++++
 src/mesa/drivers/dri/pvr/pvrdri.h         | 188 +++++
 src/mesa/drivers/dri/pvr/pvrdri_support.h | 206 ++++++
 src/mesa/drivers/dri/pvr/pvrext.c         | 704 ++++++++++++++++++
 src/mesa/drivers/dri/pvr/pvrmesa.h        |  36 +
 src/mesa/drivers/dri/pvr/pvrutil.c        | 239 ++++++
 src/meson.build                           |   1 +
 18 files changed, 4485 insertions(+), 9 deletions(-)
 create mode 100644 src/mesa/drivers/dri/pvr/dri_support.h
 create mode 100644 src/mesa/drivers/dri/pvr/img_drm_fourcc.h
 create mode 100644 src/mesa/drivers/dri/pvr/imgpixfmts.h
 create mode 100644 src/mesa/drivers/dri/pvr/imgyuv.h
 create mode 100644 src/mesa/drivers/dri/pvr/mesa_context.c
 create mode 100644 src/mesa/drivers/dri/pvr/meson.build
 create mode 100644 src/mesa/drivers/dri/pvr/pvrcb.c
 create mode 100644 src/mesa/drivers/dri/pvr/pvrcompat.c
 create mode 100644 src/mesa/drivers/dri/pvr/pvrdri.c
 create mode 100644 src/mesa/drivers/dri/pvr/pvrdri.h
 create mode 100644 src/mesa/drivers/dri/pvr/pvrdri_support.h
 create mode 100644 src/mesa/drivers/dri/pvr/pvrext.c
 create mode 100644 src/mesa/drivers/dri/pvr/pvrmesa.h
 create mode 100644 src/mesa/drivers/dri/pvr/pvrutil.c

diff --git a/meson.build b/meson.build
index 155db28..968b4f5 100644
--- a/meson.build
+++ b/meson.build
@@ -171,11 +171,11 @@ if dri_drivers.contains('auto')
   if system_has_kms_drm
     # TODO: PPC, Sparc
     if ['x86', 'x86_64'].contains(host_machine.cpu_family())
-      dri_drivers = ['i915', 'i965', 'r100', 'r200', 'nouveau']
+      dri_drivers = ['i915', 'i965', 'r100', 'r200', 'nouveau', 'pvr']
     elif ['arm', 'aarch64'].contains(host_machine.cpu_family())
-      dri_drivers = []
+      dri_drivers = ['pvr']
     elif ['mips', 'mips64', 'riscv32', 'riscv64'].contains(host_machine.cpu_family())
-      dri_drivers = ['r100', 'r200', 'nouveau']
+      dri_drivers = ['r100', 'r200', 'nouveau', 'pvr']
     else
       error('Unknown architecture @0@. Please pass -Ddri-drivers to set driver options. Patches gladly accepted to fix this.'.format(
             host_machine.cpu_family()))
@@ -194,6 +194,7 @@ with_dri_i965 = dri_drivers.contains('i965')
 with_dri_r100 = dri_drivers.contains('r100')
 with_dri_r200 = dri_drivers.contains('r200')
 with_dri_nouveau = dri_drivers.contains('nouveau')
+with_dri_pvr = dri_drivers.contains('pvr')
 
 with_dri = dri_drivers.length() != 0
 
@@ -1516,14 +1517,16 @@ _drm_amdgpu_ver = '2.4.107'
 _drm_radeon_ver = '2.4.71'
 _drm_nouveau_ver = '2.4.102'
 _drm_intel_ver = '2.4.75'
+_drm_pvr_ver = '2.4.60'
 _drm_ver = '2.4.81'
 
 _libdrm_checks = [
-  ['intel', with_dri_i915 or with_gallium_i915],
-  ['amdgpu', (with_amd_vk and not with_platform_windows) or with_gallium_radeonsi],
+  ['intel', with_dri_i915 or with_gallium_i915, true],
+  ['amdgpu', (with_amd_vk and not with_platform_windows) or with_gallium_radeonsi, true],
   ['radeon', (with_gallium_radeonsi or with_dri_r100 or with_dri_r200 or
-              with_gallium_r300 or with_gallium_r600)],
-  ['nouveau', (with_gallium_nouveau or with_dri_nouveau)],
+              with_gallium_r300 or with_gallium_r600), true],
+  ['nouveau', (with_gallium_nouveau or with_dri_nouveau), true],
+  ['pvr', with_dri_pvr, false],
 ]
 
 # VC4 only needs core libdrm support of this version, not a libdrm_vc4
@@ -1553,7 +1556,7 @@ endif
 
 # Then get each libdrm module
 foreach d : _libdrm_checks
-  if d[1]
+  if d[1] and d[2]
     set_variable(
       'dep_libdrm_' + d[0],
       dependency('libdrm_' + d[0], version : '>=' + _drm_ver)
diff --git a/meson_options.txt b/meson_options.txt
index 29c402c..dac7910 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -55,7 +55,7 @@ option(
   'dri-drivers',
   type : 'array',
   value : ['auto'],
-  choices : ['auto', 'i915', 'i965', 'r100', 'r200', 'nouveau'],
+  choices : ['auto', 'i915', 'i965', 'r100', 'r200', 'nouveau', 'pvr'],
   description : 'List of dri drivers to build. If this is set to auto all drivers applicable to the target OS/architecture will be built'
 )
 option(
diff --git a/src/mesa/drivers/dri/meson.build b/src/mesa/drivers/dri/meson.build
index 239ca96..88a973b 100644
--- a/src/mesa/drivers/dri/meson.build
+++ b/src/mesa/drivers/dri/meson.build
@@ -48,6 +48,11 @@ if with_dri_nouveau
   _dri_drivers += libnouveau_vieux
   _dri_link += 'nouveau_vieux_dri.so'
 endif
+if with_dri_pvr
+  subdir('pvr')
+  _dri_drivers += libpvr
+  _dri_link += 'pvr_dri.so'
+endif
 
 if _dri_drivers != []
   libmesa_dri_drivers = shared_library(
diff --git a/src/mesa/drivers/dri/pvr/dri_support.h b/src/mesa/drivers/dri/pvr/dri_support.h
new file mode 100644
index 0000000..6314104
--- /dev/null
+++ b/src/mesa/drivers/dri/pvr/dri_support.h
@@ -0,0 +1,581 @@
+/* -*- mode: c; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* vi: set ts=8 sw=8 sts=8: */
+/*************************************************************************/ /*!
+@File
+@Title          PVR DRI interface definition
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        MIT
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(__PVRDRIIFCE_H__)
+#define __PVRDRIIFCE_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+
+/* API type. */
+typedef enum
+{
+	PVRDRI_API_NONE = 0,
+	PVRDRI_API_GLES1 = 2,
+	PVRDRI_API_GLES2 = 3,
+	PVRDRI_API_CL = 4,
+	PVRDRI_API_GL_COMPAT = 5,
+	PVRDRI_API_GL_CORE = 6,
+} PVRDRIAPIType;
+
+typedef enum
+{
+	PVRDRI_CONFIG_ATTRIB_INVALID = 0,
+	PVRDRI_CONFIG_ATTRIB_RENDERABLE_TYPE = 1,
+	PVRDRI_CONFIG_ATTRIB_RGB_MODE = 2,
+	PVRDRI_CONFIG_ATTRIB_DOUBLE_BUFFER_MODE = 3,
+	PVRDRI_CONFIG_ATTRIB_RED_BITS = 4,
+	PVRDRI_CONFIG_ATTRIB_GREEN_BITS = 5,
+	PVRDRI_CONFIG_ATTRIB_BLUE_BITS = 6,
+	PVRDRI_CONFIG_ATTRIB_ALPHA_BITS = 7,
+	PVRDRI_CONFIG_ATTRIB_RGB_BITS = 8,
+	PVRDRI_CONFIG_ATTRIB_DEPTH_BITS = 9,
+	PVRDRI_CONFIG_ATTRIB_STENCIL_BITS = 10,
+	PVRDRI_CONFIG_ATTRIB_SAMPLE_BUFFERS = 11,
+	PVRDRI_CONFIG_ATTRIB_SAMPLES = 12,
+	PVRDRI_CONFIG_ATTRIB_BIND_TO_TEXTURE_RGB = 13,
+	PVRDRI_CONFIG_ATTRIB_BIND_TO_TEXTURE_RGBA = 14,
+	PVRDRI_CONFIG_ATTRIB_YUV_ORDER = 15,
+	PVRDRI_CONFIG_ATTRIB_YUV_NUM_OF_PLANES = 16,
+	PVRDRI_CONFIG_ATTRIB_YUV_SUBSAMPLE = 17,
+	PVRDRI_CONFIG_ATTRIB_YUV_DEPTH_RANGE = 18,
+	PVRDRI_CONFIG_ATTRIB_YUV_CSC_STANDARD = 19,
+	PVRDRI_CONFIG_ATTRIB_YUV_PLANE_BPP = 20,
+	PVRDRI_CONFIG_ATTRIB_RED_MASK = 21,
+	PVRDRI_CONFIG_ATTRIB_GREEN_MASK = 22,
+	PVRDRI_CONFIG_ATTRIB_BLUE_MASK = 23,
+	PVRDRI_CONFIG_ATTRIB_ALPHA_MASK = 24,
+	PVRDRI_CONFIG_ATTRIB_SRGB_CAPABLE = 25
+} PVRDRIConfigAttrib;
+
+/* EGL_RENDERABLE_TYPE mask bits */
+#define PVRDRI_API_BIT_GLES		0x0001
+#define PVRDRI_API_BIT_GLES2		0x0004
+#define PVRDRI_API_BIT_GL		0x0008
+#define PVRDRI_API_BIT_GLES3		0x0040
+
+/* Mesa config formats. These need not match their MESA_FORMAT counterparts */
+#define	PVRDRI_MESA_FORMAT_NONE			0
+#define PVRDRI_MESA_FORMAT_B8G8R8A8_UNORM	1
+#define PVRDRI_MESA_FORMAT_B8G8R8X8_UNORM	2
+#define PVRDRI_MESA_FORMAT_B5G6R5_UNORM		3
+#define PVRDRI_MESA_FORMAT_R8G8B8A8_UNORM	4
+#define PVRDRI_MESA_FORMAT_R8G8B8X8_UNORM	5
+#define PVRDRI_MESA_FORMAT_YCBCR		6
+#define PVRDRI_MESA_FORMAT_YUV420_2PLANE	7
+#define PVRDRI_MESA_FORMAT_YVU420_2PLANE	8
+#define PVRDRI_MESA_FORMAT_B8G8R8A8_SRGB	9
+#define PVRDRI_MESA_FORMAT_R8G8B8A8_SRGB	10
+
+typedef struct __DRIimageRec __DRIimage;
+
+typedef struct PVRDRIConfigRec PVRDRIConfig;
+
+/* The PVRDRI_GL defines match their EGL_GL counterparts */
+#define PVRDRI_GL_RENDERBUFFER			0x30B9
+#define PVRDRI_GL_TEXTURE_2D			0x30B1
+#define PVRDRI_GL_TEXTURE_3D			0x30B2
+#define PVRDRI_GL_TEXTURE_CUBE_MAP_POSITIVE_X	0x30B3
+#define PVRDRI_GL_TEXTURE_CUBE_MAP_NEGATIVE_X	0x30B4
+#define PVRDRI_GL_TEXTURE_CUBE_MAP_POSITIVE_Y	0x30B5
+#define PVRDRI_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y	0x30B6
+#define PVRDRI_GL_TEXTURE_CUBE_MAP_POSITIVE_Z	0x30B7
+#define PVRDRI_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z	0x30B8
+
+struct __DRIscreenRec;
+struct __DRIcontextRec;
+struct __DRIdrawableRec;
+
+struct __DRIconfigRec;
+
+struct DRISUPScreen;
+struct DRISUPContext;
+struct DRISUPDrawable;
+struct DRISUPBuffer;
+
+struct PVRDRIContextConfig
+{
+	unsigned int uMajorVersion;
+	unsigned int uMinorVersion;
+	uint32_t uFlags;
+
+	int iResetStrategy;
+	unsigned int uPriority;
+	int iReleaseBehavior;
+};
+
+/*
+ * PVR DRI Support interface V2.
+ * This structure may change over time, as older interfaces become obsolete.
+ * For example, the v0 interface may be removed if superseded by newer
+ * interfaces.
+ */
+struct  PVRDRISupportInterfaceV2
+{
+	struct
+	{
+		struct DRISUPScreen *(*CreateScreen)
+			(struct __DRIscreenRec *psDRIScreen,
+			 int iFD,
+			 bool bUseInvalidate,
+			 void *pvLoaderPrivate,
+			 const struct __DRIconfigRec ***pppsConfigs,
+			 int *piMaxGLES1Version,
+			 int *piMaxGLES2Version);
+
+		void (*DestroyScreen)
+			(struct DRISUPScreen *psDRISUPScreen);
+
+		unsigned int (*CreateContext)
+			(PVRDRIAPIType eAPI,
+			 PVRDRIConfig *psPVRDRIConfig,
+			 struct PVRDRIContextConfig *psCtxConfig,
+			 struct __DRIcontextRec *psDRIContext,
+			 struct DRISUPContext *psDRISUPSharedContext,
+			 struct DRISUPScreen *psDRISUPScreen,
+			 struct DRISUPContext **ppsDRISUPContext);
+
+		void (*DestroyContext)
+			(struct DRISUPContext *psDRISUPContext);
+
+		struct DRISUPDrawable *(*CreateDrawable)
+			(struct __DRIdrawableRec *psDRIDrawable,
+			 struct DRISUPScreen *psDRISUPDrawable,
+			 void *pvLoaderPrivate,
+			 PVRDRIConfig *psPVRDRIConfig);
+
+		void (*DestroyDrawable)
+			(struct DRISUPDrawable *psDRISUPDrawable);
+
+		bool (*MakeCurrent)
+			(struct DRISUPContext *psDRISUPContext,
+			 struct DRISUPDrawable *psDRISUPWrite,
+			 struct DRISUPDrawable *psDRISUPRead);
+
+		bool (*UnbindContext)
+			(struct DRISUPContext *psDRISUPContext);
+
+		struct DRISUPBuffer *(*AllocateBuffer)
+			(struct DRISUPScreen *psDRISUPScreen,
+			 unsigned int uAttachment,
+			 unsigned int uFormat,
+			 int iWidth,
+			 int iHeight,
+			 unsigned int *puName,
+			 unsigned int *puPitch,
+			 unsigned int *puCPP,
+			 unsigned int *puFlags);
+
+		void (*ReleaseBuffer)
+			(struct DRISUPScreen *psDRISUPScreen,
+			 struct DRISUPBuffer *psDRISUPBuffer);
+
+		/* Functions to support the DRI TexBuffer extension */
+		void (*SetTexBuffer2)
+			(struct DRISUPContext *psDRISUPContext,
+			 int iTarget,
+			 int iFormat,
+			 struct DRISUPDrawable *psDRISUPDrawable);
+
+		void (*ReleaseTexBuffer)
+			(struct DRISUPContext *psDRISUPContext,
+			 int iTarget,
+			 struct DRISUPDrawable *psDRISUPDrawable);
+
+		/* Functions to support the DRI Flush extension */
+		void (*Flush)
+			(struct DRISUPDrawable *psDRISUPDrawable);
+
+		void (*Invalidate)
+			(struct DRISUPDrawable *psDRISUPDrawable);
+
+		void (*FlushWithFlags)
+			(struct DRISUPContext *psDRISUPContext,
+			 struct DRISUPDrawable *psDRISUPDrawable,
+			 unsigned int uFlags,
+			 unsigned int uThrottleReason);
+
+		/* Functions to support the DRI Image extension */
+		__DRIimage *(*CreateImageFromName)
+			(struct DRISUPScreen *psDRISUPScreen,
+			 int iWidth,
+			 int iHeight,
+			 int iFourCC,
+			 int iName,
+			 int iPitch,
+			 void *pvLoaderPrivate);
+
+		__DRIimage *(*CreateImageFromRenderbuffer)
+			(struct DRISUPContext *psDRISUPContext,
+			int iRenderBuffer,
+			void *pvLoaderPrivate);
+
+		void (*DestroyImage)
+			(__DRIimage *psImage);
+
+		__DRIimage *(*CreateImage)
+			(struct DRISUPScreen *psDRISUPScreen,
+			 int iWidth,
+			 int iHeight,
+			 int iFourCC,
+			 unsigned int uUse,
+			 void *pvLoaderPrivate);
+
+		bool (*QueryImage)
+			(__DRIimage *psImage,
+			 int iAttrib,
+			 int *iValue);
+
+		__DRIimage *(*DupImage)
+			(__DRIimage *psImage,
+			 void *pvLoaderPrivate);
+
+		bool (*ValidateImageUsage)
+			(__DRIimage *psImage,
+			 unsigned int uUse);
+
+		__DRIimage *(*CreateImageFromNames)
+			(struct DRISUPScreen *psDRISUPScreen,
+			 int iWidth,
+			 int iHeight,
+			 int iFourCC,
+			 int *piNames,
+			 int iNumNames,
+			 int *piStrides,
+			 int *piOffsets,
+			 void *pvLoaderPrivate);
+			 __DRIimage *(*FromPlanar)(__DRIimage *psImage,
+			 int iPlane,
+			 void *pvLoaderPrivate);
+
+		__DRIimage *(*CreateImageFromTexture)
+			(struct DRISUPContext *psDRISUPContext,
+			 int iTarget,
+			 unsigned int uTexture,
+			 int iDepth,
+			 int iLevel,
+			 unsigned int *puError,
+			 void *pvLoaderPrivate);
+
+		__DRIimage *(*CreateImageFromFDs)
+			(struct DRISUPScreen *psDRISUPcreen,
+			 int iWidth,
+			 int iHeight,
+			 int iFourCC,
+			 int *piFDs,
+			 int iNumFDs,
+			 int *piStrides,
+			 int *piOffsets,
+			 void *pvLoaderPrivate);
+
+		__DRIimage *(*CreateImageFromDMABufs)
+			(struct DRISUPScreen *psDRISUPScreen,
+			 int iWidth,
+			 int iHeight,
+			 int iFourCC,
+			 int *piFDs,
+			 int iNumFDs,
+			 int *piStrides,
+			 int *piOffsets,
+			 unsigned int uColorSpace,
+			 unsigned int uSampleRange,
+			 unsigned int uHorizSiting,
+			 unsigned int uVertSiting,
+			 unsigned int *puError,
+			 void *pvLoaderPrivate);
+
+		int (*GetImageCapabilities)
+			(struct DRISUPScreen *psDRISUPScreen);
+
+		void (*BlitImage)
+			(struct DRISUPContext *psDRISUPContext,
+			 __DRIimage *psDst,
+			 __DRIimage *psSrc,
+			 int iDstX0,
+			 int iDstY0,
+			 int iDstWidth,
+			 int iDstHeight,
+			 int iSrcX0, int
+			 iSrcY0,
+			 int iSrcWidth,
+			 int iSrcHeight,
+			 int iFlushFlag);
+
+		void *(*MapImage)
+			(struct DRISUPContext *psDRISUPContext,
+			 __DRIimage *psImage,
+			 int iX0,
+			 int iY0,
+			 int iWidth,
+			 int iHeight,
+			 unsigned int uFlags,
+			 int *piStride,
+			 void **ppvData);
+
+		void (*UnmapImage)
+			(struct DRISUPContext *psDRISUPContext,
+			 __DRIimage *psImage,
+			 void *pvData);
+
+		__DRIimage *(*CreateImageWithModifiers)
+			(struct DRISUPScreen *psDRISUPScreen,
+			 int iWidth,
+			 int iHeight,
+			 int iFourCC,
+			 const uint64_t *puModifiers,
+			 const unsigned int uModifierCount,
+			 void *pvLoaderPrivate);
+
+		__DRIimage *(*CreateImageFromDMABufs2)
+			(struct DRISUPScreen *psDRISUPScreen,
+			 int iWidth,
+			 int iHeight,
+			 int iFourCC,
+			 uint64_t uModifier,
+			 int *piFDs,
+			 int iNumFDs,
+			 int *piStrides,
+			 int *piOffsets,
+			 unsigned int uColorSpace,
+			 unsigned int uSampleRange,
+			 unsigned int uHorizSiting,
+			 unsigned int uVertSiting,
+			 unsigned int *puError,
+			 void *pvLoaderPrivate);
+
+		bool (*QueryDMABufFormats)
+			(struct DRISUPScreen *psDRISUPScreen,
+			 int iMax,
+			 int *piFormats,
+			 int *piCount);
+
+		bool (*QueryDMABufModifiers)
+			(struct DRISUPScreen *psDRISUPScreen,
+			 int iFourCC,
+			 int iMax,
+			 uint64_t *puModifiers,
+			 unsigned int *piExternalOnly,
+			 int *piCount);
+
+		bool (*QueryDMABufFormatModifierAttribs)
+			(struct DRISUPScreen *psDRISUPScreen,
+			 uint32_t uFourcc,
+			 uint64_t uModifier,
+			 int iAttrib,
+			 uint64_t *puValue);
+
+		__DRIimage *(*CreateImageFromRenderBuffer2)
+			(struct DRISUPContext *psDRISUPContext,
+			 int iRenderBuffer,
+			 void *pvLoaderPrivate,
+			 unsigned int *puError);
+
+		__DRIimage *(*CreateImageFromBuffer)
+			(struct DRISUPContext *psDRISUPContext,
+			 int iTarget,
+			 void *pvBuffer,
+			 unsigned int *puError,
+			 void *pvLoaderPrivate);
+
+		/* Functions to support the DRI Renderer Query extension */
+		int (*QueryRendererInteger)
+			(struct DRISUPScreen *psDRISUPScreen,
+			 int iAttribute,
+			 unsigned int *puValue);
+
+		int (*QueryRendererString)
+			(struct DRISUPScreen *psDRISUPScreen,
+			 int iAttribute,
+			 const char **ppszValue);
+
+		/* Functions to support the DRI Fence extension */
+		void *(*CreateFence)
+			(struct DRISUPContext *psDRISUPContext);
+
+		void (*DestroyFence)
+			(struct DRISUPScreen *psDRISUPScreen,
+			 void *pvFence);
+
+		bool (*ClientWaitSync)
+			(struct DRISUPContext *psDRISUPContext,
+			 void *pvFence,
+			 unsigned int uFlags,
+			 uint64_t uTimeout);
+
+		void (*ServerWaitSync)
+			(struct DRISUPContext *psDRISUPContext,
+			 void *pvFence,
+			 unsigned int uFlags);
+
+		unsigned int (*GetFenceCapabilities)
+			(struct DRISUPScreen *psDRISUPScreen);
+
+		void *(*CreateFenceFD)
+			(struct DRISUPContext *psDRISUPContext,
+			 int iFD);
+
+		int (*GetFenceFD)
+			(struct DRISUPScreen *psDRISUPScreen,
+			 void *pvFence);
+
+		unsigned int (*GetNumAPIProcs)
+			(struct DRISUPScreen *psDRISUPScreen,
+			 PVRDRIAPIType eAPI);
+
+		const char *(*GetAPIProcName)
+			(struct DRISUPScreen *psDRISUPScreen,
+			 PVRDRIAPIType eAPI,
+			 unsigned int uIndex);
+
+		void *(*GetAPIProcAddress)
+			(struct DRISUPScreen *psDRISUPScreen,
+			 PVRDRIAPIType eAPI,
+			 unsigned int uIndex);
+
+		void (*SetDamageRegion)
+			(struct DRISUPDrawable *psDRISUPDrawable,
+			 unsigned int uNRects,
+			 int *piRects);
+	} v0;
+	/* The v1 interface is an extension of v0, so v0 is required as well */
+	struct {
+		void *(*GetFenceFromCLEvent)
+			(struct DRISUPScreen *psDRISUPScreen,
+			 intptr_t iCLEvent);
+	} v1;
+	/* The v2 interface is an extension of v1, so v1 is required as well */
+	struct {
+		int (*GetAPIVersion)
+			(struct DRISUPScreen *psDRISUPScreen,
+			 PVRDRIAPIType eAPI);
+	} v2;
+	/*
+	 * The v3 interface has no additional entry points. It indicates that
+	 * OpenCL event based fences are available, provided the DDK is built
+	 * with OpenCL support.
+	 */
+	/* The v4 interface is an extension of v3, so v3 is required as well */
+	struct {
+		bool (*HaveGetFenceFromCLEvent)(void);
+	} v4;
+};
+
+struct PVRDRIImageList {
+	uint32_t uImageMask;
+	__DRIimage *psBack;
+	__DRIimage *psFront;
+	__DRIimage *psPrev;
+};
+
+/*
+ * PVR DRI Support callback interface V2.
+ * This structure may change over time, as older interfaces become obsolete.
+ * For example, the v0 interface may be removed if superseded by newer
+ * interfaces.
+ */
+struct PVRDRICallbacksV2
+{
+	struct {
+		bool (*RegisterSupportInterface)
+			(const void *psInterface,
+			 unsigned int uVersion,
+			 unsigned int uMinVersion);
+
+		int (*GetBuffers)
+			(struct __DRIdrawableRec *psDRIDrawable,
+			 unsigned int uFourCC,
+			 uint32_t *puStamp,
+			 void *pvLoaderPrivate,
+			 uint32_t uBufferMask,
+			 struct PVRDRIImageList *psImageList);
+
+		bool (*CreateConfigs)
+			(struct __DRIconfigRec ***pppsConfigs,
+			 struct __DRIscreenRec *psDRIScreen,
+			 int iPVRDRIMesaFormat,
+			 const uint8_t *puDepthBits,
+			 const uint8_t *puStencilBits,
+			 unsigned int uNumDepthStencilBits,
+			 const unsigned int *puDBModes,
+			 unsigned int uNumDBModes,
+			 const uint8_t *puMSAASamples,
+			 unsigned int uNumMSAAModes,
+			 bool bEnableAccum,
+			 bool bColorDepthMatch,
+			 bool bMutableRenderBuffer,
+			 int iYUVDepthRange,
+			 int iYUVCSCStandard,
+			 uint32_t uMaxPbufferWidth,
+			 uint32_t uMaxPbufferHeight);
+
+		struct __DRIconfigRec **(*ConcatConfigs)
+			(struct __DRIscreenRec *psDRIScreen,
+			 struct __DRIconfigRec **ppsConfigA,
+			 struct __DRIconfigRec **ppsConfigB);
+
+		bool (*ConfigQuery)
+			(const PVRDRIConfig *psConfig,
+			 PVRDRIConfigAttrib eConfigAttrib,
+			 unsigned int *puValueOut);
+
+		__DRIimage *(*LookupEGLImage)
+			(struct __DRIscreenRec *psDRIScreen,
+			 void *pvImage,
+			 void *pvLoaderPrivate);
+
+		unsigned int (*GetCapability)
+			(struct __DRIscreenRec *psDRIScreen,
+			 unsigned int uCapability);
+	} v0;
+	/* The v1 interface is an extension of v0, so v0 is required as well */
+	struct {
+		void (*FlushFrontBuffer)
+			(struct __DRIdrawableRec *psDRIDrawable,
+			 void *pvLoaderPrivate);
+	} v1;
+	/* The v2 interface is an extension of v1, so v1 is required as well */
+	struct {
+		int (*GetDisplayFD)
+			(struct __DRIscreenRec *psDRIScreen,
+			 void *pvLoaderPrivate);
+	} v2;
+	/* The v3 interface is an extension of v2, so v2 is required as well */
+	struct {
+		void *(*DrawableGetReferenceHandle)
+			(struct __DRIdrawableRec *psDRIDrawable);
+
+		void (*DrawableAddReference)
+			(void *pvReferenceHandle);
+
+		void (*DrawableRemoveReference)
+			(void *pvReferenceHandle);
+	} v3;
+};
+
+#endif /* defined(__PVRDRIIFCE_H__) */
diff --git a/src/mesa/drivers/dri/pvr/img_drm_fourcc.h b/src/mesa/drivers/dri/pvr/img_drm_fourcc.h
new file mode 100644
index 0000000..8d570ff
--- /dev/null
+++ b/src/mesa/drivers/dri/pvr/img_drm_fourcc.h
@@ -0,0 +1,113 @@
+/*************************************************************************/ /*!
+@File
+@Title          Wrapper around drm_fourcc.h
+@Description    FourCCs and DRM framebuffer modifiers that are not in the
+                Kernel's and libdrm's drm_fourcc.h can be added here.
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        MIT
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/ /**************************************************************************/
+
+#ifndef IMG_DRM_FOURCC_H
+#define IMG_DRM_FOURCC_H
+
+#if defined(__KERNEL__)
+#include <drm/drm_fourcc.h>
+#else
+/*
+ * Include types.h to workaround versions of libdrm older than 2.4.68
+ * not including the correct headers.
+ */
+#include <linux/types.h>
+
+#include <drm_fourcc.h>
+#endif
+
+/*
+ * Don't get too inspired by this example :)
+ * ADF doesn't support DRM modifiers, so the memory layout had to be
+ * included in the fourcc name, but the proper way to specify information
+ * additional to pixel formats is to use DRM modifiers.
+ *
+ * See upstream drm_fourcc.h for the proper naming convention.
+ */
+#ifndef DRM_FORMAT_BGRA8888_DIRECT_16x4
+#define DRM_FORMAT_BGRA8888_DIRECT_16x4 fourcc_code('I', 'M', 'G', '0')
+#endif
+
+/*
+ * Upstream doesn't have a floating point format yet, so let's make one
+ * up.
+ * Note: The kernel's core DRM needs to know about this format,
+ * otherwise it won't be supported and should not be exposed by our
+ * kernel modules either.
+ * Refer to the provided kernel patch adding this format.
+ */
+#if !defined(__KERNEL__)
+#define DRM_FORMAT_ABGR16_IMG fourcc_code('I', 'M', 'G', '1')
+#endif
+
+/*
+ * Upstream does not have a packed 10 Bits Per Channel YVU format yet,
+ * so let`s make one up.
+ * Note: at the moment this format is not intended to be used with
+ *       a framebuffer, so the kernels core DRM doesn`t need to know
+ *       about this format. This means that the kernel doesn`t need
+ *       to be patched.
+ */
+#if !defined(__KERNEL__)
+#define DRM_FORMAT_YVU444_PACK10_IMG fourcc_code('I', 'M', 'G', '2')
+#define DRM_FORMAT_YUV422_2PLANE_PACK10_IMG fourcc_code('I', 'M', 'G', '3')
+#define DRM_FORMAT_YUV420_2PLANE_PACK10_IMG fourcc_code('I', 'M', 'G', '4')
+#endif
+
+/*
+ * Value chosen in the middle of 255 pool to minimise the chance of hitting
+ * the same value potentially defined by other vendors in the drm_fourcc.h
+ */
+#define DRM_FORMAT_MOD_VENDOR_PVR 0x92
+
+#ifndef DRM_FORMAT_MOD_VENDOR_NONE
+#define DRM_FORMAT_MOD_VENDOR_NONE 0
+#endif
+
+#ifndef DRM_FORMAT_RESERVED
+#define DRM_FORMAT_RESERVED ((1ULL << 56) - 1)
+#endif
+
+#ifndef fourcc_mod_code
+#define fourcc_mod_code(vendor, val) \
+	((((__u64)DRM_FORMAT_MOD_VENDOR_## vendor) << 56) | (val & 0x00ffffffffffffffULL))
+#endif
+
+#ifndef DRM_FORMAT_MOD_INVALID
+#define DRM_FORMAT_MOD_INVALID fourcc_mod_code(NONE, DRM_FORMAT_RESERVED)
+#endif
+
+#ifndef DRM_FORMAT_MOD_LINEAR
+#define DRM_FORMAT_MOD_LINEAR fourcc_mod_code(NONE, 0)
+#endif
+
+#define DRM_FORMAT_MOD_PVR_FBCDC_8x8_V7      fourcc_mod_code(PVR, 6)
+#define DRM_FORMAT_MOD_PVR_FBCDC_16x4_V7     fourcc_mod_code(PVR, 12)
+
+#endif /* IMG_DRM_FOURCC_H */
diff --git a/src/mesa/drivers/dri/pvr/imgpixfmts.h b/src/mesa/drivers/dri/pvr/imgpixfmts.h
new file mode 100644
index 0000000..da12a0f
--- /dev/null
+++ b/src/mesa/drivers/dri/pvr/imgpixfmts.h
@@ -0,0 +1,307 @@
+/*************************************************************************/ /*!
+@File           imgpixfmts.h
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        MIT
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/ /**************************************************************************/
+
+/******************************************************************************
+ **
+ ** WARNING: File is autogenerated by parsesystable.py - DO NOT EDIT.
+ ** Use fmts_systable.txt to add new formats.
+ **
+ *****************************************************************************/
+
+#if !defined(IMGPIXFMTS_H)
+#define IMGPIXFMTS_H
+
+typedef enum _IMG_PIXFMT_
+{
+	IMG_PIXFMT_UNKNOWN = 0,
+	IMG_PIXFMT_RESERVED_1 = 1,
+	IMG_PIXFMT_RESERVED_2 = 2,
+	IMG_PIXFMT_RESERVED_3 = 3,
+	IMG_PIXFMT_RESERVED_4 = 4,
+	IMG_PIXFMT_RESERVED_5 = 5,
+	IMG_PIXFMT_RESERVED_6 = 6,
+	IMG_PIXFMT_RESERVED_7 = 7,
+	IMG_PIXFMT_RESERVED_8 = 8,
+	IMG_PIXFMT_RESERVED_9 = 9,
+	IMG_PIXFMT_RESERVED_10 = 10,
+	IMG_PIXFMT_RESERVED_11 = 11,
+	IMG_PIXFMT_RESERVED_12 = 12,
+	IMG_PIXFMT_RESERVED_13 = 13,
+	IMG_PIXFMT_RESERVED_14 = 14,
+	IMG_PIXFMT_RESERVED_15 = 15,
+	IMG_PIXFMT_RESERVED_16 = 16,
+	IMG_PIXFMT_RESERVED_17 = 17,
+	IMG_PIXFMT_RESERVED_18 = 18,
+	IMG_PIXFMT_RESERVED_19 = 19,
+	IMG_PIXFMT_RESERVED_20 = 20,
+	IMG_PIXFMT_RESERVED_21 = 21,
+	IMG_PIXFMT_RESERVED_22 = 22,
+	IMG_PIXFMT_RESERVED_23 = 23,
+	IMG_PIXFMT_RESERVED_24 = 24,
+	IMG_PIXFMT_R10G10B10A2_UNORM = 25,
+	IMG_PIXFMT_RESERVED_26 = 26,
+	IMG_PIXFMT_RESERVED_27 = 27,
+	IMG_PIXFMT_B10G10R10A2_UNORM = 28,
+	IMG_PIXFMT_RESERVED_29 = 29,
+	IMG_PIXFMT_RESERVED_30 = 30,
+	IMG_PIXFMT_RESERVED_31 = 31,
+	IMG_PIXFMT_R8G8B8A8_UNORM = 32,
+	IMG_PIXFMT_R8G8B8A8_UNORM_SRGB = 33,
+	IMG_PIXFMT_RESERVED_34 = 34,
+	IMG_PIXFMT_RESERVED_35 = 35,
+	IMG_PIXFMT_RESERVED_36 = 36,
+	IMG_PIXFMT_R8G8B8X8_UNORM = 37,
+	IMG_PIXFMT_RESERVED_38 = 38,
+	IMG_PIXFMT_RESERVED_39 = 39,
+	IMG_PIXFMT_RESERVED_40 = 40,
+	IMG_PIXFMT_RESERVED_41 = 41,
+	IMG_PIXFMT_RESERVED_42 = 42,
+	IMG_PIXFMT_RESERVED_43 = 43,
+	IMG_PIXFMT_RESERVED_44 = 44,
+	IMG_PIXFMT_RESERVED_45 = 45,
+	IMG_PIXFMT_RESERVED_46 = 46,
+	IMG_PIXFMT_RESERVED_47 = 47,
+	IMG_PIXFMT_RESERVED_48 = 48,
+	IMG_PIXFMT_RESERVED_49 = 49,
+	IMG_PIXFMT_RESERVED_50 = 50,
+	IMG_PIXFMT_D32_FLOAT = 51,
+	IMG_PIXFMT_RESERVED_52 = 52,
+	IMG_PIXFMT_RESERVED_53 = 53,
+	IMG_PIXFMT_RESERVED_54 = 54,
+	IMG_PIXFMT_RESERVED_55 = 55,
+	IMG_PIXFMT_RESERVED_56 = 56,
+	IMG_PIXFMT_RESERVED_57 = 57,
+	IMG_PIXFMT_D24_UNORM_X8_TYPELESS = 58,
+	IMG_PIXFMT_RESERVED_59 = 59,
+	IMG_PIXFMT_RESERVED_60 = 60,
+	IMG_PIXFMT_RESERVED_61 = 61,
+	IMG_PIXFMT_R8G8_UNORM = 62,
+	IMG_PIXFMT_RESERVED_63 = 63,
+	IMG_PIXFMT_RESERVED_64 = 64,
+	IMG_PIXFMT_RESERVED_65 = 65,
+	IMG_PIXFMT_RESERVED_66 = 66,
+	IMG_PIXFMT_RESERVED_67 = 67,
+	IMG_PIXFMT_RESERVED_68 = 68,
+	IMG_PIXFMT_D16_UNORM = 69,
+	IMG_PIXFMT_RESERVED_70 = 70,
+	IMG_PIXFMT_RESERVED_71 = 71,
+	IMG_PIXFMT_RESERVED_72 = 72,
+	IMG_PIXFMT_RESERVED_73 = 73,
+	IMG_PIXFMT_RESERVED_74 = 74,
+	IMG_PIXFMT_RESERVED_75 = 75,
+	IMG_PIXFMT_R8_UNORM = 76,
+	IMG_PIXFMT_RESERVED_77 = 77,
+	IMG_PIXFMT_RESERVED_78 = 78,
+	IMG_PIXFMT_RESERVED_79 = 79,
+	IMG_PIXFMT_RESERVED_80 = 80,
+	IMG_PIXFMT_S8_UINT = 81,
+	IMG_PIXFMT_RESERVED_82 = 82,
+	IMG_PIXFMT_RESERVED_83 = 83,
+	IMG_PIXFMT_RESERVED_84 = 84,
+	IMG_PIXFMT_B5G6R5_UNORM = 85,
+	IMG_PIXFMT_R5G6B5_UNORM = 86,
+	IMG_PIXFMT_B5G5R5A1_UNORM = 87,
+	IMG_PIXFMT_B5G5R5X1_UNORM = 88,
+	IMG_PIXFMT_B8G8R8A8_UNORM = 89,
+	IMG_PIXFMT_B8G8R8X8_UNORM = 90,
+	IMG_PIXFMT_B8G8R8A8_UINT = 91,
+	IMG_PIXFMT_B8G8R8A8_SNORM = 92,
+	IMG_PIXFMT_B8G8R8A8_SINT = 93,
+	IMG_PIXFMT_B8G8R8A8_UNORM_SRGB = 94,
+	IMG_PIXFMT_RESERVED_95 = 95,
+	IMG_PIXFMT_RESERVED_96 = 96,
+	IMG_PIXFMT_RESERVED_97 = 97,
+	IMG_PIXFMT_RESERVED_98 = 98,
+	IMG_PIXFMT_RESERVED_99 = 99,
+	IMG_PIXFMT_RESERVED_100 = 100,
+	IMG_PIXFMT_RESERVED_101 = 101,
+	IMG_PIXFMT_RESERVED_102 = 102,
+	IMG_PIXFMT_RESERVED_103 = 103,
+	IMG_PIXFMT_RESERVED_104 = 104,
+	IMG_PIXFMT_RESERVED_105 = 105,
+	IMG_PIXFMT_RESERVED_106 = 106,
+	IMG_PIXFMT_RESERVED_107 = 107,
+	IMG_PIXFMT_RESERVED_108 = 108,
+	IMG_PIXFMT_RESERVED_109 = 109,
+	IMG_PIXFMT_RESERVED_110 = 110,
+	IMG_PIXFMT_RESERVED_111 = 111,
+	IMG_PIXFMT_RESERVED_112 = 112,
+	IMG_PIXFMT_RESERVED_113 = 113,
+	IMG_PIXFMT_RESERVED_114 = 114,
+	IMG_PIXFMT_RESERVED_115 = 115,
+	IMG_PIXFMT_RESERVED_116 = 116,
+	IMG_PIXFMT_RESERVED_117 = 117,
+	IMG_PIXFMT_RESERVED_118 = 118,
+	IMG_PIXFMT_RESERVED_119 = 119,
+	IMG_PIXFMT_RESERVED_120 = 120,
+	IMG_PIXFMT_RESERVED_121 = 121,
+	IMG_PIXFMT_RESERVED_122 = 122,
+	IMG_PIXFMT_RESERVED_123 = 123,
+	IMG_PIXFMT_RESERVED_124 = 124,
+	IMG_PIXFMT_RESERVED_125 = 125,
+	IMG_PIXFMT_RESERVED_126 = 126,
+	IMG_PIXFMT_RESERVED_127 = 127,
+	IMG_PIXFMT_RESERVED_128 = 128,
+	IMG_PIXFMT_RESERVED_129 = 129,
+	IMG_PIXFMT_RESERVED_130 = 130,
+	IMG_PIXFMT_RESERVED_131 = 131,
+	IMG_PIXFMT_RESERVED_132 = 132,
+	IMG_PIXFMT_RESERVED_133 = 133,
+	IMG_PIXFMT_RESERVED_134 = 134,
+	IMG_PIXFMT_RESERVED_135 = 135,
+	IMG_PIXFMT_L8_UNORM = 136,
+	IMG_PIXFMT_RESERVED_137 = 137,
+	IMG_PIXFMT_L8A8_UNORM = 138,
+	IMG_PIXFMT_RESERVED_139 = 139,
+	IMG_PIXFMT_RESERVED_140 = 140,
+	IMG_PIXFMT_RESERVED_141 = 141,
+	IMG_PIXFMT_RESERVED_142 = 142,
+	IMG_PIXFMT_RESERVED_143 = 143,
+	IMG_PIXFMT_RESERVED_144 = 144,
+	IMG_PIXFMT_B4G4R4A4_UNORM = 145,
+	IMG_PIXFMT_RESERVED_146 = 146,
+	IMG_PIXFMT_RESERVED_147 = 147,
+	IMG_PIXFMT_RESERVED_148 = 148,
+	IMG_PIXFMT_RESERVED_149 = 149,
+	IMG_PIXFMT_RESERVED_150 = 150,
+	IMG_PIXFMT_RESERVED_151 = 151,
+	IMG_PIXFMT_RESERVED_152 = 152,
+	IMG_PIXFMT_RESERVED_153 = 153,
+	IMG_PIXFMT_RESERVED_154 = 154,
+	IMG_PIXFMT_RESERVED_155 = 155,
+	IMG_PIXFMT_RESERVED_156 = 156,
+	IMG_PIXFMT_RESERVED_157 = 157,
+	IMG_PIXFMT_RESERVED_158 = 158,
+	IMG_PIXFMT_RESERVED_159 = 159,
+	IMG_PIXFMT_R8G8B8_UNORM = 160,
+	IMG_PIXFMT_R8G8B8_UNORM_SRGB = 161,
+	IMG_PIXFMT_RESERVED_162 = 162,
+	IMG_PIXFMT_RESERVED_163 = 163,
+	IMG_PIXFMT_RESERVED_164 = 164,
+	IMG_PIXFMT_RESERVED_165 = 165,
+	IMG_PIXFMT_RESERVED_166 = 166,
+	IMG_PIXFMT_RESERVED_167 = 167,
+	IMG_PIXFMT_RESERVED_168 = 168,
+	IMG_PIXFMT_RESERVED_169 = 169,
+	IMG_PIXFMT_RESERVED_170 = 170,
+	IMG_PIXFMT_UYVY = 171,
+	IMG_PIXFMT_VYUY = 172,
+	IMG_PIXFMT_YUYV = 173,
+	IMG_PIXFMT_YVYU = 174,
+	IMG_PIXFMT_YVU420_2PLANE = 175,
+	IMG_PIXFMT_YUV420_2PLANE = 176,
+	IMG_PIXFMT_YVU420_2PLANE_MACRO_BLOCK = 177,
+	IMG_PIXFMT_YUV420_3PLANE = 178,
+	IMG_PIXFMT_YVU420_3PLANE = 179,
+	IMG_PIXFMT_RESERVED_180 = 180,
+	IMG_PIXFMT_RESERVED_181 = 181,
+	IMG_PIXFMT_RESERVED_182 = 182,
+	IMG_PIXFMT_RESERVED_183 = 183,
+	IMG_PIXFMT_RESERVED_184 = 184,
+	IMG_PIXFMT_RESERVED_185 = 185,
+	IMG_PIXFMT_RESERVED_186 = 186,
+	IMG_PIXFMT_RESERVED_187 = 187,
+	IMG_PIXFMT_RESERVED_188 = 188,
+	IMG_PIXFMT_RESERVED_189 = 189,
+	IMG_PIXFMT_RESERVED_190 = 190,
+	IMG_PIXFMT_RESERVED_191 = 191,
+	IMG_PIXFMT_RESERVED_192 = 192,
+	IMG_PIXFMT_RESERVED_193 = 193,
+	IMG_PIXFMT_RESERVED_194 = 194,
+	IMG_PIXFMT_RESERVED_195 = 195,
+	IMG_PIXFMT_RESERVED_196 = 196,
+	IMG_PIXFMT_RESERVED_197 = 197,
+	IMG_PIXFMT_RESERVED_198 = 198,
+	IMG_PIXFMT_RESERVED_199 = 199,
+	IMG_PIXFMT_RESERVED_200 = 200,
+	IMG_PIXFMT_YVU8_422_2PLANE_PACK8 = 201,
+	IMG_PIXFMT_RESERVED_202 = 202,
+	IMG_PIXFMT_YVU10_444_1PLANE_PACK10 = 203,
+	IMG_PIXFMT_RESERVED_204 = 204,
+	IMG_PIXFMT_RESERVED_205 = 205,
+	IMG_PIXFMT_RESERVED_206 = 206,
+	IMG_PIXFMT_YUV8_422_2PLANE_PACK8 = 207,
+	IMG_PIXFMT_YUV8_444_3PLANE_PACK8 = 208,
+	IMG_PIXFMT_RESERVED_209 = 209,
+	IMG_PIXFMT_RESERVED_210 = 210,
+	IMG_PIXFMT_RESERVED_211 = 211,
+	IMG_PIXFMT_RESERVED_212 = 212,
+	IMG_PIXFMT_RESERVED_213 = 213,
+	IMG_PIXFMT_RESERVED_214 = 214,
+	IMG_PIXFMT_RESERVED_215 = 215,
+	IMG_PIXFMT_RESERVED_216 = 216,
+	IMG_PIXFMT_RESERVED_217 = 217,
+	IMG_PIXFMT_RESERVED_218 = 218,
+	IMG_PIXFMT_RESERVED_219 = 219,
+	IMG_PIXFMT_RESERVED_220 = 220,
+	IMG_PIXFMT_RESERVED_221 = 221,
+	IMG_PIXFMT_RESERVED_222 = 222,
+	IMG_PIXFMT_RESERVED_223 = 223,
+	IMG_PIXFMT_RESERVED_224 = 224,
+	IMG_PIXFMT_RESERVED_225 = 225,
+	IMG_PIXFMT_RESERVED_226 = 226,
+	IMG_PIXFMT_RESERVED_227 = 227,
+	IMG_PIXFMT_RESERVED_228 = 228,
+	IMG_PIXFMT_RESERVED_229 = 229,
+	IMG_PIXFMT_RESERVED_230 = 230,
+	IMG_PIXFMT_RESERVED_231 = 231,
+	IMG_PIXFMT_RESERVED_232 = 232,
+	IMG_PIXFMT_RESERVED_233 = 233,
+	IMG_PIXFMT_RESERVED_234 = 234,
+	IMG_PIXFMT_RESERVED_235 = 235,
+	IMG_PIXFMT_RESERVED_236 = 236,
+	IMG_PIXFMT_RESERVED_237 = 237,
+	IMG_PIXFMT_RESERVED_238 = 238,
+	IMG_PIXFMT_RESERVED_239 = 239,
+	IMG_PIXFMT_RESERVED_240 = 240,
+	IMG_PIXFMT_RESERVED_241 = 241,
+	IMG_PIXFMT_RESERVED_242 = 242,
+	IMG_PIXFMT_RESERVED_243 = 243,
+	IMG_PIXFMT_RESERVED_244 = 244,
+	IMG_PIXFMT_YVU8_420_2PLANE_PACK8_P = 245,
+	IMG_PIXFMT_RESERVED_246 = 246,
+	IMG_PIXFMT_RESERVED_247 = 247,
+	IMG_PIXFMT_RESERVED_248 = 248,
+	IMG_PIXFMT_YUV8_420_2PLANE_PACK8_P = 249,
+	IMG_PIXFMT_RESERVED_250 = 250,
+	IMG_PIXFMT_RESERVED_251 = 251,
+	IMG_PIXFMT_UYVY10_422_1PLANE_PACK10_CUST1 = 252,
+	IMG_PIXFMT_RESERVED_253 = 253,
+	IMG_PIXFMT_RESERVED_254 = 254,
+	IMG_PIXFMT_RESERVED_255 = 255,
+	IMG_PIXFMT_RESERVED_256 = 256,
+	IMG_PIXFMT_RESERVED_257 = 257,
+	IMG_PIXFMT_RESERVED_258 = 258,
+	IMG_PIXFMT_RESERVED_259 = 259,
+	IMG_PIXFMT_RESERVED_260 = 260,
+	IMG_PIXFMT_RESERVED_261 = 261,
+	IMG_PIXFMT_RESERVED_262 = 262,
+	IMG_PIXFMT_RESERVED_263 = 263,
+	IMG_PIXFMT_RESERVED_264 = 264,
+#define IMG_PIXFMT_ENUM_COUNT 265
+} IMG_PIXFMT;
+
+#endif /* IMGPIXFMTS_H */
diff --git a/src/mesa/drivers/dri/pvr/imgyuv.h b/src/mesa/drivers/dri/pvr/imgyuv.h
new file mode 100644
index 0000000..7ae8fd1
--- /dev/null
+++ b/src/mesa/drivers/dri/pvr/imgyuv.h
@@ -0,0 +1,58 @@
+/*************************************************************************/ /*!
+@File
+@Title          YUV defines
+@Copyright      Copyright (c) Imagination Technologies Ltd. All Rights Reserved
+@License        MIT
+
+The contents of this file are subject to the MIT license as set out below.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/ /**************************************************************************/
+
+#if !defined(IMGYUV_H)
+#define IMGYUV_H
+
+typedef enum
+{
+	IMG_COLORSPACE_UNDEFINED = 0,
+	IMG_COLORSPACE_BT601_CONFORMANT_RANGE = 1,
+	IMG_COLORSPACE_BT601_FULL_RANGE = 2,
+	IMG_COLORSPACE_BT709_CONFORMANT_RANGE = 3,
+	IMG_COLORSPACE_BT709_FULL_RANGE = 4,
+	IMG_COLORSPACE_BT2020_CONFORMANT_RANGE = 5,
+	IMG_COLORSPACE_BT2020_FULL_RANGE = 6,
+	IMG_COLORSPACE_BT601_CONFORMANT_RANGE_INVERSE = 7,
+	IMG_COLORSPACE_BT601_FULL_RANGE_INVERSE = 8,
+	IMG_COLORSPACE_BT709_CONFORMANT_RANGE_INVERSE = 9,
+	IMG_COLORSPACE_BT709_FULL_RANGE_INVERSE = 10,
+	IMG_COLORSPACE_BT2020_CONFORMANT_RANGE_INVERSE = 11,
+	IMG_COLORSPACE_BT2020_FULL_RANGE_INVERSE = 12
+} IMG_YUV_COLORSPACE;
+
+typedef enum
+{
+	IMG_CHROMA_INTERP_UNDEFINED = 0,
+	IMG_CHROMA_INTERP_ZERO = 1,
+	IMG_CHROMA_INTERP_QUARTER = 2,
+	IMG_CHROMA_INTERP_HALF = 3,
+	IMG_CHROMA_INTERP_THREEQUARTERS = 4
+} IMG_YUV_CHROMA_INTERP;
+
+
+#endif /* IMGYUV_H */
diff --git a/src/mesa/drivers/dri/pvr/mesa_context.c b/src/mesa/drivers/dri/pvr/mesa_context.c
new file mode 100644
index 0000000..d36bae5
--- /dev/null
+++ b/src/mesa/drivers/dri/pvr/mesa_context.c
@@ -0,0 +1,208 @@
+/**
+ * \file context.c
+ * Mesa context/visual/framebuffer management functions.
+ * \author Brian Paul
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  7.1
+ *
+ * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
+ *
+ * The contents of this file are subject to the MIT license as set out below.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <stdlib.h>
+#include <assert.h>
+
+#include "main/version.h"
+#include "main/errors.h"
+
+#include "dri_support.h"
+#include "dri_util.h"
+#include "glapi.h"
+#include "dispatch.h"
+#include "pvrmesa.h"
+
+/**
+ * This is the default function we plug into all dispatch table slots This
+ * helps prevents a segfault when someone calls a GL function without first
+ * checking if the extension is supported.
+ */
+static int
+generic_nop(void)
+{
+   _mesa_warning(NULL, "User called no-op dispatch function (an unsupported extension function?)");
+
+   return 0;
+}
+
+/**
+ * Allocate and initialise a new dispatch table.
+ */
+static struct _glapi_table *
+pvrdri_alloc_dispatch_table(void)
+{
+   unsigned int numEntries = _glapi_get_dispatch_table_size();
+   _glapi_proc *table;
+
+   table = malloc(numEntries * sizeof(_glapi_proc));
+   if (table)
+      for (unsigned int i = 0; i < numEntries; i++)
+         table[i] = (_glapi_proc) generic_nop;
+
+   return (struct _glapi_table *) table;
+}
+
+/**
+ * Return a pointer to the pointer to the dispatch table of an API in
+ * PVRDRIScreen.
+ */
+static struct _glapi_table **
+pvrdri_get_dispatch_table_ptr(PVRDRIScreen *psPVRScreen, PVRDRIAPIType eAPI)
+{
+   switch (eAPI) {
+   case PVRDRI_API_GLES1:
+      return &psPVRScreen->psOGLES1Dispatch;
+   case PVRDRI_API_GLES2:
+      return &psPVRScreen->psOGLES2Dispatch;
+   case PVRDRI_API_GL_COMPAT:
+   case PVRDRI_API_GL_CORE:
+      return &psPVRScreen->psOGLDispatch;
+   default:
+      return NULL;
+   }
+}
+
+/**
+ * Return a pointer to the dispatch table of an API.
+ */
+static struct _glapi_table *
+pvrdri_get_dispatch_table(PVRDRIScreen *psPVRScreen, PVRDRIAPIType eAPI)
+{
+   struct _glapi_table **ppsTable =
+      pvrdri_get_dispatch_table_ptr(psPVRScreen, eAPI);
+
+   return ppsTable ? *ppsTable : NULL;
+}
+
+/**
+ * Free all dispatch tables.
+ */
+void
+pvrdri_free_dispatch_tables(PVRDRIScreen *psPVRScreen)
+{
+   if (psPVRScreen->psOGLES1Dispatch != NULL) {
+      free(psPVRScreen->psOGLES1Dispatch);
+      psPVRScreen->psOGLES1Dispatch = NULL;
+   }
+
+   if (psPVRScreen->psOGLES2Dispatch != NULL) {
+      free(psPVRScreen->psOGLES2Dispatch);
+      psPVRScreen->psOGLES2Dispatch = NULL;
+   }
+
+   if (psPVRScreen->psOGLDispatch != NULL) {
+      free(psPVRScreen->psOGLDispatch);
+      psPVRScreen->psOGLDispatch = NULL;
+   }
+}
+
+static void
+pvrdri_add_mesa_dispatch(struct _glapi_table *psTable, PVRDRIAPIType eAPI,
+                         struct DRISUPScreen *psDRISUPScreen,
+                         unsigned int uIdx)
+{
+   const char *asFunc[] = { NULL, NULL };
+   int iOffset;
+   const char *psFunc;
+   _glapi_proc pfFunc;
+
+   pfFunc = DRISUPGetAPIProcAddress(psDRISUPScreen, eAPI, uIdx);
+   if (pfFunc == NULL)
+      return;
+
+   psFunc = DRISUPGetAPIProcName(psDRISUPScreen, eAPI, uIdx);
+   assert(psFunc != NULL);
+
+   asFunc[0] = psFunc;
+   iOffset = _glapi_add_dispatch(asFunc, "");
+   if (iOffset == -1) {
+      _mesa_warning(NULL, "Couldn't add %s to the Mesa dispatch table",
+                    psFunc);
+   } else {
+      SET_by_offset(psTable, iOffset, pfFunc);
+   }
+}
+
+static void
+pvrdri_set_mesa_dispatch(struct _glapi_table *psTable, PVRDRIAPIType eAPI,
+                         struct DRISUPScreen *psDRISUPScreen,
+                         unsigned int uNumFuncs)
+{
+   for (unsigned int i = 0; i < uNumFuncs; i++)
+      pvrdri_add_mesa_dispatch(psTable, eAPI, psDRISUPScreen, i);
+}
+
+bool
+pvrdri_create_dispatch_table(PVRDRIScreen *psPVRScreen, PVRDRIAPIType eAPI)
+{
+   struct DRISUPScreen *psDRISUPScreen = psPVRScreen->psDRISUPScreen;
+   struct _glapi_table **ppsTable;
+   unsigned int uNumFuncs;
+
+   ppsTable = pvrdri_get_dispatch_table_ptr(psPVRScreen, eAPI);
+   if (ppsTable == NULL)
+      return false;
+
+   if (*ppsTable != NULL)
+      return true;
+
+   uNumFuncs = DRISUPGetNumAPIProcs(psDRISUPScreen, eAPI);
+   if (!uNumFuncs)
+      return false;
+
+   *ppsTable = pvrdri_alloc_dispatch_table();
+   if (*ppsTable == NULL)
+      return false;
+
+   pvrdri_set_mesa_dispatch(*ppsTable, eAPI, psDRISUPScreen, uNumFuncs);
+
+   return true;
+}
+
+void
+pvrdri_set_null_dispatch_table(void)
+{
+   _glapi_set_dispatch(NULL);
+}
+
+void
+pvrdri_set_dispatch_table(PVRDRIContext *psPVRContext)
+{
+   struct _glapi_table *psTable;
+
+   psTable = pvrdri_get_dispatch_table(psPVRContext->psPVRScreen,
+                                       psPVRContext->eAPI);
+
+   _glapi_set_dispatch(psTable);
+}
diff --git a/src/mesa/drivers/dri/pvr/meson.build b/src/mesa/drivers/dri/pvr/meson.build
new file mode 100644
index 0000000..59cccf8
--- /dev/null
+++ b/src/mesa/drivers/dri/pvr/meson.build
@@ -0,0 +1,48 @@
+# Copyright (c) Imagination Technologies Ltd.
+#
+# The contents of this file are subject to the MIT license as set out below.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+files_pvr = files(
+  'mesa_context.c',
+  'pvrcb.c',
+  'pvrcompat.c',
+  'pvrdri.c',
+  'pvrext.c',
+  'pvrutil.c',
+)
+
+dep_libpvr = [
+  dep_libdrm,
+]
+
+if with_platform_tizen
+  dep_libpvr += dep_dlog
+endif
+
+libpvr = static_library(
+  'pvr',
+  [files_pvr, main_dispatch_h],
+  include_directories : [inc_include, inc_src, inc_mapi, inc_mesa,
+                         inc_dri_common, inc_util, inc_pvr],
+  c_args : [no_override_init_args],
+  gnu_symbol_visibility : 'hidden',
+  dependencies : [dep_libpvr],
+)
diff --git a/src/mesa/drivers/dri/pvr/pvrcb.c b/src/mesa/drivers/dri/pvr/pvrcb.c
new file mode 100644
index 0000000..ea8911c
--- /dev/null
+++ b/src/mesa/drivers/dri/pvr/pvrcb.c
@@ -0,0 +1,328 @@
+/*
+ * Copyright (c) Imagination Technologies Ltd.
+ *
+ * The contents of this file are subject to the MIT license as set out below.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <assert.h>
+
+#include "utils.h"
+#include "pvrdri.h"
+
+int
+MODSUPGetBuffers(__DRIdrawable *psDRIDrawable, unsigned int uFourCC,
+                 uint32_t *puStamp, void *pvLoaderPrivate,
+                 uint32_t uBufferMask, struct PVRDRIImageList *psImageList)
+{
+   PVRDRIDrawable *psPVRDrawable = psDRIDrawable->driverPrivate;
+   __DRIscreen *psDRIScreen = psDRIDrawable->driScreenPriv;
+   struct __DRIimageList sDRIList;
+   int res;
+
+#if !defined(DRI_IMAGE_HAS_BUFFER_PREV)
+   uBufferMask &= ~PVRDRI_IMAGE_BUFFER_PREV;
+#endif
+
+   if (psPVRDrawable->uFourCC != uFourCC) {
+      psPVRDrawable->uDRIFormat = PVRDRIFourCCToDRIFormat(uFourCC);
+      psPVRDrawable->uFourCC = uFourCC;
+   }
+
+   res = psDRIScreen->image.loader->getBuffers(psDRIDrawable,
+                                               psPVRDrawable->uDRIFormat,
+                                               puStamp,
+                                               pvLoaderPrivate,
+                                               uBufferMask, &sDRIList);
+
+   if (res) {
+      psImageList->uImageMask = sDRIList.image_mask;
+      psImageList->psBack = sDRIList.back;
+      psImageList->psFront = sDRIList.front;
+      psImageList->psPrev = sDRIList.prev;
+   }
+
+   return res;
+}
+
+bool
+MODSUPCreateConfigs(__DRIconfig ***pppsConfigs, __DRIscreen *psDRIScreen,
+                    int iPVRDRIMesaFormat, const uint8_t *puDepthBits,
+                    const uint8_t *puStencilBits,
+                    unsigned int uNumDepthStencilBits,
+                    const unsigned int *puDBModes, unsigned int uNumDBModes,
+                    const uint8_t *puMSAASamples, unsigned int uNumMSAAModes,
+                    bool bEnableAccum, bool bColorDepthMatch,
+                    UNUSED bool bMutableRenderBuffer,
+                    int iYUVDepthRange, int iYUVCSCStandard,
+                    uint32_t uMaxPbufferWidth, uint32_t uMaxPbufferHeight)
+{
+   __DRIconfig **ppsConfigs;
+   mesa_format eFormat = PVRDRIMesaFormatToMesaFormat(iPVRDRIMesaFormat);
+   unsigned int i;
+
+   (void) psDRIScreen;
+
+   switch (eFormat) {
+   case MESA_FORMAT_NONE:
+      __driUtilMessage("%s: Unknown PVR DRI format: %u",
+                       __func__, iPVRDRIMesaFormat);
+      return false;
+   default:
+      break;
+   }
+
+   /*
+    * The double buffered modes array argument for driCreateConfigs has
+    * entries of type GLenum.
+    */
+   static_assert(sizeof(GLenum) == sizeof(unsigned int),
+                 "Size mismatch between GLenum and unsigned int");
+
+   ppsConfigs = driCreateConfigs(eFormat, puDepthBits, puStencilBits,
+                                 uNumDepthStencilBits, (GLenum *) puDBModes,
+                                 uNumDBModes, puMSAASamples, uNumMSAAModes,
+                                 bEnableAccum, bColorDepthMatch,
+                                 iYUVDepthRange, iYUVCSCStandard);
+   if (!ppsConfigs)
+      return false;
+
+   for (i = 0; ppsConfigs[i]; i++) {
+      ppsConfigs[i]->modes.maxPbufferWidth = uMaxPbufferWidth;
+      ppsConfigs[i]->modes.maxPbufferHeight = uMaxPbufferHeight;
+      ppsConfigs[i]->modes.maxPbufferPixels =
+         uMaxPbufferWidth * uMaxPbufferHeight;
+   }
+
+   *pppsConfigs = ppsConfigs;
+
+   return true;
+}
+
+__DRIconfig **
+MODSUPConcatConfigs(__DRIscreen *psDRIScreen,
+                    __DRIconfig **ppsConfigA, __DRIconfig **ppsConfigB)
+{
+   (void) psDRIScreen;
+
+   return driConcatConfigs(ppsConfigA, ppsConfigB);
+}
+
+struct __DRIimageRec *
+MODSUPLookupEGLImage(__DRIscreen *psDRIScreen, void *pvImage,
+                     void *pvLoaderPrivate)
+{
+   return psDRIScreen->dri2.image->lookupEGLImage(psDRIScreen,
+                                                  pvImage,
+                                                  pvLoaderPrivate);
+}
+
+
+unsigned int
+MODSUPGetCapability(__DRIscreen *psDRIScreen, unsigned int uCapability)
+{
+   if (psDRIScreen->image.loader->base.version >= 2 &&
+       psDRIScreen->image.loader->getCapability) {
+      enum dri_loader_cap eCapability =
+         (enum dri_loader_cap) uCapability;
+
+      return psDRIScreen->image.loader->getCapability(
+         psDRIScreen->loaderPrivate,
+         eCapability);
+   }
+
+   return 0;
+}
+
+int
+MODSUPGetDisplayFD(__DRIscreen *psDRIScreen, void *pvLoaderPrivate)
+{
+#if __DRI_IMAGE_LOADER_VERSION >= 5
+   if (psDRIScreen->image.loader->base.version >= 5 &&
+       psDRIScreen->image.loader->getDisplayFD)
+      return psDRIScreen->image.loader->getDisplayFD(pvLoaderPrivate);
+#else
+   (void) psDRIScreen;
+   (void) pvLoaderPrivate;
+#endif
+
+   return -1;
+}
+
+static bool
+PVRDRIConfigQueryUnsigned(const PVRDRIConfig *psConfig,
+                          PVRDRIConfigAttrib eConfigAttrib,
+                          unsigned int *puValueOut)
+{
+   if (!psConfig || !puValueOut)
+      return false;
+
+   switch (eConfigAttrib) {
+   case PVRDRI_CONFIG_ATTRIB_RENDERABLE_TYPE:
+      *puValueOut = psConfig->iSupportedAPIs;
+      return true;
+   case PVRDRI_CONFIG_ATTRIB_RGB_MODE:
+      *puValueOut = psConfig->sGLMode.rgbMode;
+      return true;
+   case PVRDRI_CONFIG_ATTRIB_DOUBLE_BUFFER_MODE:
+      *puValueOut = psConfig->sGLMode.doubleBufferMode;
+      return true;
+   case PVRDRI_CONFIG_ATTRIB_RED_BITS:
+      *puValueOut = psConfig->sGLMode.redBits;
+      return true;
+   case PVRDRI_CONFIG_ATTRIB_GREEN_BITS:
+      *puValueOut = psConfig->sGLMode.greenBits;
+      return true;
+   case PVRDRI_CONFIG_ATTRIB_BLUE_BITS:
+      *puValueOut = psConfig->sGLMode.blueBits;
+      return true;
+   case PVRDRI_CONFIG_ATTRIB_ALPHA_BITS:
+      *puValueOut = psConfig->sGLMode.alphaBits;
+      return true;
+   case PVRDRI_CONFIG_ATTRIB_RGB_BITS:
+      *puValueOut = psConfig->sGLMode.rgbBits;
+      return true;
+   case PVRDRI_CONFIG_ATTRIB_DEPTH_BITS:
+      *puValueOut = psConfig->sGLMode.depthBits;
+      return true;
+   case PVRDRI_CONFIG_ATTRIB_STENCIL_BITS:
+      *puValueOut = psConfig->sGLMode.stencilBits;
+      return true;
+   case PVRDRI_CONFIG_ATTRIB_SAMPLE_BUFFERS:
+      *puValueOut = !!psConfig->sGLMode.samples;
+      return true;
+   case PVRDRI_CONFIG_ATTRIB_SAMPLES:
+      *puValueOut = psConfig->sGLMode.samples;
+      return true;
+   case PVRDRI_CONFIG_ATTRIB_BIND_TO_TEXTURE_RGB:
+      *puValueOut = GL_TRUE;
+      return true;
+   case PVRDRI_CONFIG_ATTRIB_BIND_TO_TEXTURE_RGBA:
+      *puValueOut = GL_TRUE;
+      return true;
+#if defined(__DRI_ATTRIB_YUV_BIT)
+   case PVRDRI_CONFIG_ATTRIB_YUV_ORDER:
+      *puValueOut = psConfig->sGLMode.YUVOrder;
+      return true;
+   case PVRDRI_CONFIG_ATTRIB_YUV_NUM_OF_PLANES:
+      *puValueOut = psConfig->sGLMode.YUVNumberOfPlanes;
+      return true;
+   case PVRDRI_CONFIG_ATTRIB_YUV_SUBSAMPLE:
+      *puValueOut = psConfig->sGLMode.YUVSubsample;
+      return true;
+   case PVRDRI_CONFIG_ATTRIB_YUV_DEPTH_RANGE:
+      *puValueOut = psConfig->sGLMode.YUVDepthRange;
+      return true;
+   case PVRDRI_CONFIG_ATTRIB_YUV_CSC_STANDARD:
+      *puValueOut = psConfig->sGLMode.YUVCSCStandard;
+      return true;
+   case PVRDRI_CONFIG_ATTRIB_YUV_PLANE_BPP:
+      *puValueOut = psConfig->sGLMode.YUVPlaneBPP;
+      return true;
+#endif
+#if !defined(__DRI_ATTRIB_YUV_BIT)
+   case PVRDRI_CONFIG_ATTRIB_YUV_ORDER:
+   case PVRDRI_CONFIG_ATTRIB_YUV_NUM_OF_PLANES:
+   case PVRDRI_CONFIG_ATTRIB_YUV_SUBSAMPLE:
+   case PVRDRI_CONFIG_ATTRIB_YUV_DEPTH_RANGE:
+   case PVRDRI_CONFIG_ATTRIB_YUV_CSC_STANDARD:
+   case PVRDRI_CONFIG_ATTRIB_YUV_PLANE_BPP:
+      return false;
+#endif
+   case PVRDRI_CONFIG_ATTRIB_RED_MASK:
+      *puValueOut = psConfig->sGLMode.redMask;
+      return true;
+   case PVRDRI_CONFIG_ATTRIB_GREEN_MASK:
+      *puValueOut = psConfig->sGLMode.greenMask;
+      return true;
+   case PVRDRI_CONFIG_ATTRIB_BLUE_MASK:
+      *puValueOut = psConfig->sGLMode.blueMask;
+      return true;
+   case PVRDRI_CONFIG_ATTRIB_ALPHA_MASK:
+      *puValueOut = psConfig->sGLMode.alphaMask;
+      return true;
+   case PVRDRI_CONFIG_ATTRIB_SRGB_CAPABLE:
+      *puValueOut = psConfig->sGLMode.sRGBCapable;
+      return true;
+   case PVRDRI_CONFIG_ATTRIB_INVALID:
+      errorMessage("%s: Invalid attribute", __func__);
+      assert(0);
+      return false;
+   default:
+      return false;
+   }
+}
+
+bool
+PVRDRIConfigQuery(const PVRDRIConfig *psConfig,
+                  PVRDRIConfigAttrib eConfigAttrib, int *piValueOut)
+{
+   bool bRes;
+   unsigned int uValue;
+
+   bRes = PVRDRIConfigQueryUnsigned(psConfig, eConfigAttrib, &uValue);
+   if (bRes)
+      *piValueOut = (int) uValue;
+
+   return bRes;
+}
+
+bool
+MODSUPConfigQuery(const PVRDRIConfig *psConfig,
+                  PVRDRIConfigAttrib eConfigAttrib, unsigned int *puValueOut)
+{
+   return PVRDRIConfigQueryUnsigned(psConfig, eConfigAttrib, puValueOut);
+}
+
+void
+MODSUPFlushFrontBuffer(struct __DRIdrawableRec *psDRIDrawable,
+                       void *pvLoaderPrivate)
+{
+   PVRDRIDrawable *psPVRDrawable = psDRIDrawable->driverPrivate;
+   __DRIscreen *psDRIScreen = psDRIDrawable->driScreenPriv;
+
+   if (!psPVRDrawable->sConfig.sGLMode.doubleBufferMode)
+      psDRIScreen->image.loader->flushFrontBuffer(psDRIDrawable,
+                                                  pvLoaderPrivate);
+}
+
+void *
+MODSUPDrawableGetReferenceHandle(struct __DRIdrawableRec *psDRIDrawable)
+{
+   PVRDRIDrawable *psPVRDrawable = psDRIDrawable->driverPrivate;
+
+   return psPVRDrawable;
+}
+
+void
+MODSUPDrawableAddReference(void *pvReferenceHandle)
+{
+   PVRDRIDrawable *psPVRDrawable = pvReferenceHandle;
+
+   PVRDRIDrawableAddReference(psPVRDrawable);
+}
+
+void
+MODSUPDrawableRemoveReference(void *pvReferenceHandle)
+{
+   PVRDRIDrawable *psPVRDrawable = pvReferenceHandle;
+
+   PVRDRIDrawableRemoveReference(psPVRDrawable);
+}
diff --git a/src/mesa/drivers/dri/pvr/pvrcompat.c b/src/mesa/drivers/dri/pvr/pvrcompat.c
new file mode 100644
index 0000000..23a57dd
--- /dev/null
+++ b/src/mesa/drivers/dri/pvr/pvrcompat.c
@@ -0,0 +1,838 @@
+/*
+ * Copyright (c) Imagination Technologies Ltd.
+ *
+ * The contents of this file are subject to the MIT license as set out below.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dlfcn.h>
+#include <pthread.h>
+#include <assert.h>
+
+#include <drm_fourcc.h>
+
+#include "pvrdri.h"
+
+#ifndef DRM_FORMAT_MOD_INVALID
+#define DRM_FORMAT_MOD_INVALID ((1ULL << 56) - 1)
+#endif
+
+#define _MAKESTRING(x) # x
+#define MAKESTRING(x) _MAKESTRING(x)
+
+#define PVRDRI_SUPPORT_LIB "libpvr_dri_support.so"
+
+static void *gpvSupLib;
+static int giSupLibRef;
+
+static struct PVRDRISupportInterfaceV2 gsSupV2;
+
+static pthread_mutex_t gsCompatLock = PTHREAD_MUTEX_INITIALIZER;
+
+/* Lookup a function, and set the pointer to the function address */
+#define LookupFunc(func, ptr)                   \
+   do {                                         \
+      ptr = dlsym(gpvSupLib, MAKESTRING(func)); \
+   } while(0)
+
+/* Call a function via the DRI Support interface structure */
+#define CallFuncV2(field, ...)                  \
+   do {                                         \
+      if (gsSupV2.field)                        \
+         return gsSupV2.field(__VA_ARGS__);     \
+   } while(0)
+
+/* Calculate the start of the PVRDRISupportInterfaceV2 structure */
+#define PVRDRIInterfaceV2Start(field)                   \
+   (offsetof(struct PVRDRISupportInterfaceV2, field))
+
+/* Calculate the end of the PVRDRISupportInterfaceV2 structure */
+#define PVRDRIInterfaceV2End(field)                             \
+   (offsetof(struct PVRDRISupportInterfaceV2, field) +          \
+    sizeof((struct PVRDRISupportInterfaceV2 *)0)->field)
+
+static void
+CompatLock(void)
+{
+   int ret;
+
+   ret = pthread_mutex_lock(&gsCompatLock);
+   if (ret) {
+      errorMessage("%s: Failed to lock mutex (%d)", __func__, ret);
+      abort();
+   }
+}
+
+static void
+CompatUnlock(void)
+{
+   int ret;
+
+   ret = pthread_mutex_unlock(&gsCompatLock);
+   if (ret) {
+      errorMessage("%s: Failed to unlock mutex (%d)", __func__, ret);
+      abort();
+   }
+}
+
+static void *
+LoadLib(const char *path)
+{
+   void *handle;
+
+   /* Clear the error */
+   (void) dlerror();
+
+   handle = dlopen(path, RTLD_NOW);
+   if (handle) {
+      __driUtilMessage("Loaded %s", path);
+   } else {
+      const char *error;
+
+      error = dlerror();
+      if (!error)
+         error = "unknown error";
+
+      errorMessage("%s: Couldn't load %s: %s", __func__, path, error);
+   }
+
+   return handle;
+}
+
+static void
+UnloadLib(void *handle, const char *name)
+{
+   if (!handle)
+      return;
+
+   /* Clear the error */
+   (void) dlerror();
+
+   if (dlclose(handle)) {
+      const char *error;
+
+      error = dlerror();
+      if (!error)
+         error = "unknown error";
+
+      errorMessage("%s: Couldn't unload %s: %s", __func__, name, error);
+   } else {
+      __driUtilMessage("Unloaded %s", name);
+   }
+}
+
+static bool
+LoadSupportLib(void)
+{
+   gpvSupLib = LoadLib(PVRDRI_SUPPORT_LIB);
+
+   return gpvSupLib != NULL;
+}
+
+static void
+UnloadSupportLib(void)
+{
+   UnloadLib(gpvSupLib, PVRDRI_SUPPORT_LIB);
+   gpvSupLib = NULL;
+}
+
+static void
+CompatDeinit(void)
+{
+   UnloadSupportLib();
+   memset(&gsSupV2, 0, sizeof(gsSupV2));
+}
+
+bool
+PVRDRICompatInit(const struct PVRDRICallbacksV2 *psCallbacksV2,
+                 unsigned int uVersionV2, unsigned int uMinVersionV2)
+{
+   bool (*pfRegisterVersionedCallbacksV2)(const void *pvCallbacks,
+                                          unsigned int uVersion,
+                                          unsigned int uMinVersion);
+   bool res;
+
+   CompatLock();
+   res = (giSupLibRef++ != 0);
+   if (res)
+      goto Exit;
+
+   res = LoadSupportLib();
+   if (!res)
+      goto Exit;
+
+   LookupFunc(PVRDRIRegisterVersionedCallbacksV2,
+              pfRegisterVersionedCallbacksV2);
+
+   res = (pfRegisterVersionedCallbacksV2 != NULL);
+   if (!res)
+      goto Exit;
+
+   res = pfRegisterVersionedCallbacksV2(psCallbacksV2,
+                                        uVersionV2, uMinVersionV2);
+
+Exit:
+   if (!res) {
+      CompatDeinit();
+      giSupLibRef--;
+   }
+   CompatUnlock();
+
+   return res;
+}
+
+void
+PVRDRICompatDeinit(void)
+{
+   CompatLock();
+   if (--giSupLibRef == 0)
+      CompatDeinit();
+   CompatUnlock();
+}
+
+bool
+MODSUPRegisterSupportInterfaceV2(const void *pvInterface,
+                                 unsigned int uVersion,
+                                 unsigned int uMinVersion)
+{
+   size_t uStart, uEnd;
+
+   memset(&gsSupV2, 0, sizeof(gsSupV2));
+
+   if (uVersion < uMinVersion)
+      return false;
+
+   /*
+    * Minimum versions we support. To prevent the accumulation of old unused
+    * interfaces in the PVRDRIInterfaceV2 structure, the caller specifies the
+    * minimum version it supports. This will be pointed to be the psInterface
+    * argument. Assuming we support that version, we must copy the structure
+    * passed to us into the correct place in our version of the interface
+    * structure.
+    */
+   switch (uMinVersion) {
+   case 0:
+      uStart = PVRDRIInterfaceV2Start(v0);
+      break;
+   case 1:
+   case 2:
+   case 3:
+   case 4:
+      /* These versions require version 0 */
+      return false;
+   default:
+      return false;
+   }
+
+   /* The "default" case should be associated with the latest version */
+   switch (uVersion) {
+   default:
+   case 4:
+      /* This version is an extension of versions 0 to 3 */
+      if (uMinVersion > 0)
+         return false;
+
+      uEnd = PVRDRIInterfaceV2End(v4);
+      break;
+   case 3:
+      /*
+       * This version is an extension of version 2, with no new
+       * entry points.
+       */
+   case 2:
+      /* This version is an extension of versions 0 and 1 */
+      if (uMinVersion > 0)
+         return false;
+
+      uEnd = PVRDRIInterfaceV2End(v2);
+      break;
+   case 1:
+      /* This version is an extension of version 0 */
+      if (uMinVersion > 0)
+         return false;
+
+      uEnd = PVRDRIInterfaceV2End(v1);
+      break;
+   case 0:
+      uEnd = PVRDRIInterfaceV2End(v0);
+      break;
+   }
+
+   memcpy(((char *) &gsSupV2) + uStart, pvInterface, uEnd - uStart);
+
+   PVRDRIAdjustExtensions(uVersion, uMinVersion);
+
+   return true;
+}
+
+struct DRISUPScreen *
+DRISUPCreateScreen(struct __DRIscreenRec *psDRIScreen, int iFD,
+                   bool bUseInvalidate, void *pvLoaderPrivate,
+                   const struct __DRIconfigRec ***pppsConfigs,
+                   int *piMaxGLES1Version, int *piMaxGLES2Version)
+{
+   CallFuncV2(v0.CreateScreen,
+              psDRIScreen, iFD, bUseInvalidate, pvLoaderPrivate, pppsConfigs,
+              piMaxGLES1Version, piMaxGLES2Version);
+
+   return NULL;
+}
+
+void
+DRISUPDestroyScreen(struct DRISUPScreen *psDRISUPScreen)
+{
+   CallFuncV2(v0.DestroyScreen,
+              psDRISUPScreen);
+}
+
+unsigned int
+DRISUPCreateContext(PVRDRIAPIType eAPI, PVRDRIConfig *psPVRDRIConfig,
+                    struct PVRDRIContextConfig *psCtxConfig,
+                    struct __DRIcontextRec *psDRIContext,
+                    struct DRISUPContext *psDRISUPSharedContext,
+                    struct DRISUPScreen *psDRISUPScreen,
+                    struct DRISUPContext **ppsDRISUPContext)
+{
+   CallFuncV2(v0.CreateContext,
+              eAPI, psPVRDRIConfig, psCtxConfig, psDRIContext,
+              psDRISUPSharedContext, psDRISUPScreen, ppsDRISUPContext);
+
+   return __DRI_CTX_ERROR_BAD_API;
+}
+
+void
+DRISUPDestroyContext(struct DRISUPContext *psDRISUPContext)
+{
+   CallFuncV2(v0.DestroyContext,
+              psDRISUPContext);
+}
+
+struct DRISUPDrawable *
+DRISUPCreateDrawable(struct __DRIdrawableRec *psDRIDrawable,
+                     struct DRISUPScreen *psDRISUPScreen,
+                     void *pvLoaderPrivate, PVRDRIConfig *psPVRDRIConfig)
+{
+   CallFuncV2(v0.CreateDrawable,
+              psDRIDrawable, psDRISUPScreen, pvLoaderPrivate, psPVRDRIConfig);
+
+   return NULL;
+}
+
+void
+DRISUPDestroyDrawable(struct DRISUPDrawable *psDRISUPDrawable)
+{
+   CallFuncV2(v0.DestroyDrawable,
+              psDRISUPDrawable);
+}
+
+bool
+DRISUPMakeCurrent(struct DRISUPContext *psDRISUPContext,
+                  struct DRISUPDrawable *psDRISUPWrite,
+                  struct DRISUPDrawable *psDRISUPRead)
+{
+   CallFuncV2(v0.MakeCurrent,
+              psDRISUPContext, psDRISUPWrite, psDRISUPRead);
+
+   return false;
+}
+
+bool
+DRISUPUnbindContext(struct DRISUPContext *psDRISUPContext)
+{
+   CallFuncV2(v0.UnbindContext,
+              psDRISUPContext);
+
+   return false;
+}
+
+struct DRISUPBuffer *
+DRISUPAllocateBuffer(struct DRISUPScreen *psDRISUPScreen,
+                     unsigned int uAttachment, unsigned int uFormat,
+                     int iWidth, int iHeight, unsigned int *puName,
+                     unsigned int *puPitch, unsigned int *puCPP,
+                     unsigned int *puFlags)
+{
+   CallFuncV2(v0.AllocateBuffer,
+              psDRISUPScreen, uAttachment, uFormat, iWidth, iHeight, puName,
+              puPitch, puCPP, puFlags);
+
+   return NULL;
+}
+
+void
+DRISUPReleaseBuffer(struct DRISUPScreen *psDRISUPScreen,
+                    struct DRISUPBuffer *psDRISUPBuffer)
+{
+   CallFuncV2(v0.ReleaseBuffer,
+              psDRISUPScreen, psDRISUPBuffer);
+}
+
+void
+DRISUPSetTexBuffer2(struct DRISUPContext *psDRISUPContext, int iTarget,
+                    int iFormat, struct DRISUPDrawable *psDRISUPDrawable)
+{
+   CallFuncV2(v0.SetTexBuffer2,
+              psDRISUPContext, iTarget, iFormat, psDRISUPDrawable);
+}
+
+void
+DRISUPReleaseTexBuffer(struct DRISUPContext *psDRISUPContext, int iTarget,
+                       struct DRISUPDrawable *psDRISUPDrawable)
+{
+   CallFuncV2(v0.ReleaseTexBuffer,
+              psDRISUPContext, iTarget, psDRISUPDrawable);
+}
+
+void
+DRISUPFlush(struct DRISUPDrawable *psDRISUPDrawable)
+{
+   CallFuncV2(v0.Flush,
+              psDRISUPDrawable);
+}
+
+void
+DRISUPInvalidate(struct DRISUPDrawable *psDRISUPDrawable)
+{
+   CallFuncV2(v0.Invalidate,
+              psDRISUPDrawable);
+}
+
+void
+DRISUPFlushWithFlags(struct DRISUPContext *psDRISUPContext,
+                     struct DRISUPDrawable *psDRISUPDrawable,
+                     unsigned int uFlags, unsigned int uThrottleReason)
+{
+   CallFuncV2(v0.FlushWithFlags,
+              psDRISUPContext, psDRISUPDrawable, uFlags, uThrottleReason);
+}
+
+__DRIimage *
+DRISUPCreateImageFromName(struct DRISUPScreen *psDRISUPScreen,
+                          int iWidth, int iHeight, int iFourCC, int iName,
+                          int iPitch, void *pvLoaderPrivate)
+{
+   CallFuncV2(v0.CreateImageFromName,
+              psDRISUPScreen, iWidth, iHeight, iFourCC, iName, iPitch,
+              pvLoaderPrivate);
+
+   return NULL;
+}
+
+__DRIimage *
+DRISUPCreateImageFromRenderbuffer(struct DRISUPContext *psDRISUPContext,
+                                  int iRenderBuffer, void *pvLoaderPrivate)
+{
+   CallFuncV2(v0.CreateImageFromRenderbuffer,
+              psDRISUPContext, iRenderBuffer, pvLoaderPrivate);
+
+   return NULL;
+}
+
+void
+DRISUPDestroyImage(__DRIimage *psImage)
+{
+   CallFuncV2(v0.DestroyImage, psImage);
+}
+
+__DRIimage *
+DRISUPCreateImage(struct DRISUPScreen *psDRISUPScreen,
+                  int iWidth, int iHeight, int iFourCC, unsigned int uUse,
+                  void *pvLoaderPrivate)
+{
+   CallFuncV2(v0.CreateImage,
+              psDRISUPScreen, iWidth, iHeight, iFourCC, uUse, pvLoaderPrivate);
+
+   return NULL;
+}
+
+bool
+DRISUPQueryImage(__DRIimage *psImage, int iAttrib, int *piValue)
+{
+   CallFuncV2(v0.QueryImage,
+              psImage, iAttrib, piValue);
+
+   return false;
+}
+
+__DRIimage *
+DRISUPDupImage(__DRIimage *psImage, void *pvLoaderPrivate)
+{
+   CallFuncV2(v0.DupImage,
+              psImage, pvLoaderPrivate);
+
+   return NULL;
+}
+
+bool
+DRISUPValidateImageUsage(__DRIimage *psImage, unsigned int uUse)
+{
+   CallFuncV2(v0.ValidateImageUsage,
+              psImage, uUse);
+
+   return false;
+}
+
+__DRIimage *
+DRISUPCreateImageFromNames(struct DRISUPScreen *psDRISUPScreen,
+                           int iWidth, int iHeight, int iFourCC,
+                           int *piNames, int iNumNames,
+                           int *piStrides, int *piOffsets,
+                           void *pvLoaderPrivate)
+{
+   CallFuncV2(v0.CreateImageFromNames,
+              psDRISUPScreen, iWidth, iHeight, iFourCC, piNames, iNumNames,
+              piStrides, piOffsets, pvLoaderPrivate);
+
+   return NULL;
+}
+
+__DRIimage *
+DRISUPFromPlanar(__DRIimage *psImage, int iPlane, void *pvLoaderPrivate)
+{
+   CallFuncV2(v0.FromPlanar,
+              psImage, iPlane, pvLoaderPrivate);
+
+   return NULL;
+}
+
+__DRIimage *
+DRISUPCreateImageFromTexture(struct DRISUPContext *psDRISUPContext,
+                             int iTarget, unsigned int uTexture, int iDepth,
+                             int iLevel, unsigned int *puError,
+                             void *pvLoaderPrivate)
+{
+   CallFuncV2(v0.CreateImageFromTexture,
+              psDRISUPContext, iTarget, uTexture, iDepth, iLevel, puError,
+              pvLoaderPrivate);
+
+   return NULL;
+}
+
+__DRIimage *
+DRISUPCreateImageFromFDs(struct DRISUPScreen *psDRISUPcreen,
+                         int iWidth, int iHeight, int iFourCC,
+                         int *piFDs, int iNumFDs, int *piStrides,
+                         int *piOffsets, void *pvLoaderPrivate)
+{
+   CallFuncV2(v0.CreateImageFromFDs,
+              psDRISUPcreen, iWidth, iHeight, iFourCC, piFDs, iNumFDs,
+              piStrides, piOffsets, pvLoaderPrivate);
+
+   return NULL;
+}
+
+__DRIimage *
+DRISUPCreateImageFromDmaBufs(struct DRISUPScreen *psDRISUPScreen,
+                             int iWidth, int iHeight, int iFourCC,
+                             int *piFDs, int iNumFDs,
+                             int *piStrides, int *piOffsets,
+                             unsigned int uColorSpace,
+                             unsigned int uSampleRange,
+                             unsigned int uHorizSiting,
+                             unsigned int uVertSiting,
+                             unsigned int *puError,
+                             void *pvLoaderPrivate)
+{
+   CallFuncV2(v0.CreateImageFromDMABufs,
+              psDRISUPScreen, iWidth, iHeight, iFourCC, piFDs, iNumFDs,
+              piStrides, piOffsets, uColorSpace, uSampleRange,
+              uHorizSiting, uVertSiting, puError, pvLoaderPrivate);
+
+   return NULL;
+}
+
+int
+DRISUPGetImageCapabilities(struct DRISUPScreen *psDRISUPScreen)
+{
+   CallFuncV2(v0.GetImageCapabilities,
+              psDRISUPScreen);
+
+   return 0;
+}
+
+void
+DRISUPBlitImage(struct DRISUPContext *psDRISUPContext,
+                __DRIimage *psDst, __DRIimage *psSrc, int iDstX0, int iDstY0,
+                int iDstWidth, int iDstHeight, int iSrcX0, int iSrcY0,
+                int iSrcWidth, int iSrcHeight, int iFlushFlag)
+{
+   CallFuncV2(v0.BlitImage,
+              psDRISUPContext, psDst, psSrc, iDstX0, iDstY0,
+              iDstWidth, iDstHeight, iSrcX0, iSrcY0,
+              iSrcWidth, iSrcHeight, iFlushFlag);
+}
+
+void *
+DRISUPMapImage(struct DRISUPContext *psDRISUPContext, __DRIimage* psImage,
+               int iX0, int iY0, int iWidth, int iHeight, unsigned int uFlags,
+               int *piStride, void **ppvData)
+{
+   CallFuncV2(v0.MapImage,
+              psDRISUPContext, psImage, iX0, iY0, iWidth, iHeight, uFlags,
+              piStride, ppvData);
+
+   return NULL;
+}
+
+void
+DRISUPUnmapImage(struct DRISUPContext *psDRISUPContext, __DRIimage *psImage,
+                 void *pvData)
+{
+   CallFuncV2(v0.UnmapImage,
+              psDRISUPContext, psImage, pvData);
+}
+
+__DRIimage *
+DRISUPCreateImageWithModifiers(struct DRISUPScreen *psDRISUPScreen,
+                               int iWidth, int iHeight, int iFourCC,
+                               const uint64_t *puModifiers,
+                               const unsigned int uModifierCount,
+                               void *pvLoaderPrivate)
+{
+   CallFuncV2(v0.CreateImageWithModifiers,
+              psDRISUPScreen, iWidth, iHeight, iFourCC, puModifiers,
+              uModifierCount, pvLoaderPrivate);
+
+   return NULL;
+}
+
+__DRIimage *
+DRISUPCreateImageFromDMABufs2(struct DRISUPScreen *psDRISUPScreen,
+                              int iWidth, int iHeight, int iFourCC,
+                              uint64_t uModifier, int *piFDs, int iNumFDs,
+                              int *piStrides, int *piOffsets,
+                              unsigned int uColorSpace,
+                              unsigned int uSampleRange,
+                              unsigned int uHorizSiting,
+                              unsigned int uVertSiting,
+                              unsigned int *puError, void *pvLoaderPrivate)
+{
+   CallFuncV2(v0.CreateImageFromDMABufs2,
+              psDRISUPScreen, iWidth, iHeight, iFourCC, uModifier,
+              piFDs, iNumFDs, piStrides, piOffsets, uColorSpace, uSampleRange,
+              uHorizSiting, uVertSiting, puError, pvLoaderPrivate);
+
+   return NULL;
+}
+
+bool
+DRISUPQueryDMABufFormats(struct DRISUPScreen *psDRISUPScreen, int iMax,
+                         int *piFormats, int *piCount)
+{
+   CallFuncV2(v0.QueryDMABufFormats,
+              psDRISUPScreen, iMax, piFormats, piCount);
+
+   return false;
+}
+
+bool
+DRISUPQueryDMABufModifiers(struct DRISUPScreen *psDRISUPScreen, int iFourCC,
+                           int iMax, uint64_t *puModifiers,
+                           unsigned int *piExternalOnly, int *piCount)
+{
+   CallFuncV2(v0.QueryDMABufModifiers,
+              psDRISUPScreen, iFourCC, iMax, puModifiers, piExternalOnly,
+              piCount);
+
+   return false;
+}
+
+bool
+DRISUPQueryDMABufFormatModifierAttribs(struct DRISUPScreen *psDRISUPScreen,
+                                       uint32_t iFourCC, uint64_t uModifier,
+                                       int iAttrib, uint64_t *puValue)
+{
+   CallFuncV2(v0.QueryDMABufFormatModifierAttribs,
+              psDRISUPScreen, iFourCC, uModifier, iAttrib, puValue);
+
+   return false;
+}
+
+__DRIimage *
+DRISUPCreateImageFromRenderBuffer2(struct DRISUPContext *psDRISUPContext,
+                                   int iRenderBuffer, void *pvLoaderPrivate,
+                                   unsigned int *puError)
+{
+   CallFuncV2(v0.CreateImageFromRenderBuffer2,
+              psDRISUPContext, iRenderBuffer, pvLoaderPrivate, puError);
+
+   return NULL;
+}
+
+__DRIimage *
+DRISUPCreateImageFromBuffer(struct DRISUPContext *psDRISUPContext,
+                            int iTarget, void *pvBuffer,
+                            unsigned int *puError, void *pvLoaderPrivate)
+{
+   CallFuncV2(v0.CreateImageFromBuffer,
+              psDRISUPContext, iTarget, pvBuffer, puError, pvLoaderPrivate);
+
+   return NULL;
+}
+
+int
+DRISUPQueryRendererInteger(struct DRISUPScreen *psDRISUPScreen,
+                           int iAttribute, unsigned int *puValue)
+{
+   CallFuncV2(v0.QueryRendererInteger,
+              psDRISUPScreen, iAttribute, puValue);
+
+   return -1;
+}
+
+int
+DRISUPQueryRendererString(struct DRISUPScreen *psDRISUPScreen,
+                          int iAttribute, const char **ppszValue)
+{
+   CallFuncV2(v0.QueryRendererString,
+              psDRISUPScreen, iAttribute, ppszValue);
+
+   return -1;
+}
+
+void *
+DRISUPCreateFence(struct DRISUPContext *psDRISUPContext)
+{
+   CallFuncV2(v0.CreateFence,
+              psDRISUPContext);
+
+   return NULL;
+}
+
+void
+DRISUPDestroyFence(struct DRISUPScreen *psDRISUPScreen, void *pvFence)
+{
+   CallFuncV2(v0.DestroyFence,
+              psDRISUPScreen, pvFence);
+}
+
+bool
+DRISUPClientWaitSync(struct DRISUPContext *psDRISUPContext, void *pvFence,
+                     unsigned int uFlags, uint64_t uTimeout)
+{
+   CallFuncV2(v0.ClientWaitSync,
+              psDRISUPContext, pvFence, uFlags, uTimeout);
+
+   return false;
+}
+
+void
+DRISUPServerWaitSync(struct DRISUPContext *psDRISUPContext, void *pvFence,
+                     unsigned int uFlags)
+{
+   CallFuncV2(v0.ServerWaitSync,
+              psDRISUPContext, pvFence, uFlags);
+}
+
+unsigned int
+DRISUPGetFenceCapabilities(struct DRISUPScreen *psDRISUPScreen)
+{
+   CallFuncV2(v0.GetFenceCapabilities,
+              psDRISUPScreen);
+
+   return 0;
+}
+
+void *
+DRISUPCreateFenceFD(struct DRISUPContext *psDRISUPContext, int iFD)
+{
+   CallFuncV2(v0.CreateFenceFD,
+              psDRISUPContext, iFD);
+
+   return NULL;
+}
+
+int
+DRISUPGetFenceFD(struct DRISUPScreen *psDRISUPScreen, void *pvFence)
+{
+   CallFuncV2(v0.GetFenceFD,
+              psDRISUPScreen, pvFence);
+
+   return -1;
+}
+
+void *
+DRISUPGetFenceFromCLEvent(struct DRISUPScreen *psDRISUPScreen,
+                          intptr_t iCLEvent)
+{
+   CallFuncV2(v1.GetFenceFromCLEvent,
+              psDRISUPScreen, iCLEvent);
+
+   return NULL;
+}
+
+int
+DRISUPGetAPIVersion(struct DRISUPScreen *psDRISUPScreen,
+                    PVRDRIAPIType eAPI)
+{
+   CallFuncV2(v2.GetAPIVersion,
+              psDRISUPScreen, eAPI);
+
+   return 0;
+}
+
+unsigned int
+DRISUPGetNumAPIProcs(struct DRISUPScreen *psDRISUPScreen,
+                     PVRDRIAPIType eAPI)
+{
+   CallFuncV2(v0.GetNumAPIProcs,
+              psDRISUPScreen, eAPI);
+
+   return 0;
+}
+
+const char *
+DRISUPGetAPIProcName(struct DRISUPScreen *psDRISUPScreen, PVRDRIAPIType eAPI,
+                     unsigned int uIndex)
+{
+   CallFuncV2(v0.GetAPIProcName,
+              psDRISUPScreen, eAPI, uIndex);
+
+   return NULL;
+}
+
+void *
+DRISUPGetAPIProcAddress(struct DRISUPScreen *psDRISUPScreen,
+                        PVRDRIAPIType eAPI, unsigned int uIndex)
+{
+   CallFuncV2(v0.GetAPIProcAddress,
+              psDRISUPScreen, eAPI, uIndex);
+
+   return NULL;
+}
+
+void
+DRISUPSetDamageRegion(struct DRISUPDrawable *psDRISUPDrawable,
+                      unsigned int uNRects, int *piRects)
+{
+   CallFuncV2(v0.SetDamageRegion,
+              psDRISUPDrawable, uNRects, piRects);
+}
+
+bool
+DRISUPHaveGetFenceFromCLEvent(void)
+{
+   CallFuncV2(v4.HaveGetFenceFromCLEvent);
+
+   return true;
+}
diff --git a/src/mesa/drivers/dri/pvr/pvrdri.c b/src/mesa/drivers/dri/pvr/pvrdri.c
new file mode 100644
index 0000000..ab941f7
--- /dev/null
+++ b/src/mesa/drivers/dri/pvr/pvrdri.c
@@ -0,0 +1,613 @@
+/*
+ * Copyright (c) Imagination Technologies Ltd.
+ *
+ * The contents of this file are subject to the MIT license as set out below.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <string.h>
+#include <assert.h>
+
+#include "util/u_atomic.h"
+#include "utils.h"
+
+#include "pvrdri.h"
+#include "pvrmesa.h"
+
+#define PVR_IMAGE_LOADER_VER_MIN 1
+
+struct PVRBuffer {
+   __DRIbuffer sDRIBuffer;
+   struct DRISUPBuffer *psDRISUPBuffer;
+};
+
+/*************************************************************************//*!
+ Local functions
+ *//**************************************************************************/
+
+static bool
+PVRLoaderIsSupported(__DRIscreen *psDRIScreen)
+{
+   if (psDRIScreen->image.loader) {
+      if (psDRIScreen->image.loader->base.version < PVR_IMAGE_LOADER_VER_MIN) {
+         __driUtilMessage("%s: Image loader extension version %d but need %d",
+                          __func__, psDRIScreen->image.loader->base.version,
+                          PVR_IMAGE_LOADER_VER_MIN);
+         return false;
+      } else if (!psDRIScreen->image.loader->getBuffers) {
+         __driUtilMessage("%s: Image loader extension missing support for getBuffers",
+                          __func__);
+         return false;
+      }
+   } else {
+      __driUtilMessage("%s: Image loader extension required", __func__);
+      return false;
+   }
+
+   return true;
+}
+
+static inline struct DRISUPContext *
+getSharedContextImpl(void *pvSharedContextPrivate)
+{
+   if (pvSharedContextPrivate == NULL)
+      return NULL;
+
+   return ((PVRDRIContext *) pvSharedContextPrivate)->psDRISUPContext;
+}
+
+static void
+PVRDRIScreenAddReference(PVRDRIScreen *psPVRScreen)
+{
+   int iRefCount = p_atomic_inc_return(&psPVRScreen->iRefCount);
+
+   (void) iRefCount;
+   assert(iRefCount > 1);
+}
+
+static void
+PVRDRIScreenRemoveReference(PVRDRIScreen *psPVRScreen)
+{
+   int iRefCount = p_atomic_dec_return(&psPVRScreen->iRefCount);
+
+   assert(iRefCount >= 0);
+
+   if (iRefCount != 0)
+      return;
+
+   pvrdri_free_dispatch_tables(psPVRScreen);
+   DRISUPDestroyScreen(psPVRScreen->psDRISUPScreen);
+   PVRDRICompatDeinit();
+   free(psPVRScreen);
+}
+
+void
+PVRDRIDrawableAddReference(PVRDRIDrawable *psPVRDrawable)
+{
+   int iRefCount = p_atomic_inc_return(&psPVRDrawable->iRefCount);
+
+   (void) iRefCount;
+   assert(iRefCount > 1);
+}
+
+void
+PVRDRIDrawableRemoveReference(PVRDRIDrawable *psPVRDrawable)
+{
+   int iRefCount = p_atomic_dec_return(&psPVRDrawable->iRefCount);
+
+   assert(iRefCount >= 0);
+
+   if (iRefCount != 0)
+      return;
+
+   DRISUPDestroyDrawable(psPVRDrawable->psDRISUPDrawable);
+
+#if defined(DEBUG)
+   p_atomic_dec(&psPVRDrawable->psPVRScreen->iDrawableAlloc);
+#endif
+
+   PVRDRIScreenRemoveReference(psPVRDrawable->psPVRScreen);
+   free(psPVRDrawable);
+}
+
+static void
+PVRScreenPrintExtensions(__DRIscreen *psDRIScreen)
+{
+   /* Don't attempt to print anything if LIBGL_DEBUG isn't in the environment */
+   if (getenv("LIBGL_DEBUG") == NULL)
+      return;
+
+   if (psDRIScreen->extensions) {
+      const __DRIextension *psScreenExtensionVersionInfo =
+         PVRDRIScreenExtensionVersionInfo();
+      int i;
+      int j;
+
+      __driUtilMessage("Supported screen extensions:");
+
+      for (i = 0; psDRIScreen->extensions[i]; i++) {
+         for (j = 0; psScreenExtensionVersionInfo[j].name; j++) {
+            if (strcmp(psDRIScreen->extensions[i]->name,
+                       psScreenExtensionVersionInfo[j].name) == 0) {
+               __driUtilMessage("\t%s (supported version: %u - max version: %u)",
+                                psDRIScreen->extensions[i]->name,
+                                psDRIScreen->extensions[i]->version,
+                                psScreenExtensionVersionInfo[j].version);
+               break;
+            }
+         }
+
+         if (psScreenExtensionVersionInfo[j].name == NULL) {
+            __driUtilMessage("\t%s (supported version: %u - max version: unknown)",
+                             psDRIScreen->extensions[i]->name,
+                             psDRIScreen->extensions[i]->version);
+         }
+      }
+   } else {
+      __driUtilMessage("No screen extensions found");
+   }
+}
+
+/*************************************************************************//*!
+ Mesa driver API functions
+ *//**************************************************************************/
+
+static const __DRIconfig **
+PVRDRIInitScreen(__DRIscreen *psDRIScreen)
+{
+   PVRDRIScreen *psPVRScreen;
+   const __DRIconfig **ppsConfigs;
+   int iMaxGLES1Version, iMaxGLES2Version;
+   const struct PVRDRICallbacksV2 sDRICallbacksV2 = {
+      /* Version 0 callbacks */
+      .v0.RegisterSupportInterface = MODSUPRegisterSupportInterfaceV2,
+      .v0.GetBuffers = MODSUPGetBuffers,
+      .v0.CreateConfigs = MODSUPCreateConfigs,
+      .v0.ConcatConfigs = MODSUPConcatConfigs,
+      .v0.ConfigQuery = MODSUPConfigQuery,
+      .v0.LookupEGLImage = MODSUPLookupEGLImage,
+      .v0.GetCapability = MODSUPGetCapability,
+      /* Version 1 callbacks */
+      .v1.FlushFrontBuffer = MODSUPFlushFrontBuffer,
+      /* Version 2 callbacks */
+      .v2.GetDisplayFD = MODSUPGetDisplayFD,
+      /* Version 3 callbacks */
+      .v3.DrawableGetReferenceHandle = MODSUPDrawableGetReferenceHandle,
+      .v3.DrawableAddReference = MODSUPDrawableAddReference,
+      .v3.DrawableRemoveReference = MODSUPDrawableRemoveReference,
+   };
+
+   if (!PVRLoaderIsSupported(psDRIScreen))
+      return NULL;
+
+   if (!PVRDRICompatInit(&sDRICallbacksV2, 3, 0))
+      return NULL;
+
+   psPVRScreen = calloc(1, sizeof(*psPVRScreen));
+   if (psPVRScreen == NULL) {
+      __driUtilMessage("%s: Couldn't allocate PVRDRIScreen", __func__);
+      goto ErrorCompatDeinit;
+   }
+
+   psDRIScreen->driverPrivate = psPVRScreen;
+   psPVRScreen->psDRIScreen = psDRIScreen;
+   psPVRScreen->iRefCount = 1;
+
+   psPVRScreen->psDRISUPScreen =
+      DRISUPCreateScreen(psDRIScreen, psDRIScreen->fd,
+                         psDRIScreen->dri2.useInvalidate != NULL,
+                         psDRIScreen->loaderPrivate,
+                         &ppsConfigs, &iMaxGLES1Version, &iMaxGLES2Version);
+   if (!psPVRScreen->psDRISUPScreen)
+      goto ErrorScreenFree;
+
+   psDRIScreen->max_gl_es1_version = iMaxGLES1Version;
+   psDRIScreen->max_gl_es2_version = iMaxGLES2Version;
+
+   psDRIScreen->max_gl_compat_version =
+      DRISUPGetAPIVersion(psPVRScreen->psDRISUPScreen, PVRDRI_API_GL_COMPAT);
+   psDRIScreen->max_gl_core_version =
+      DRISUPGetAPIVersion(psPVRScreen->psDRISUPScreen, PVRDRI_API_GL_CORE);
+
+   psDRIScreen->extensions = PVRDRIScreenExtensions();
+
+   PVRScreenPrintExtensions(psDRIScreen);
+
+   return ppsConfigs;
+
+ErrorScreenFree:
+   psDRIScreen->driverPrivate = NULL;
+   free(psPVRScreen);
+
+ErrorCompatDeinit:
+   PVRDRICompatDeinit();
+
+   return NULL;
+}
+
+static void
+PVRDRIDestroyScreen(__DRIscreen *psDRIScreen)
+{
+   PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate;
+
+#if defined(DEBUG)
+   if (psPVRScreen->iBufferAlloc != 0 ||
+       psPVRScreen->iDrawableAlloc != 0 ||
+       psPVRScreen->iContextAlloc != 0) {
+      errorMessage("%s: Outstanding allocations: Contexts: %d Drawables: %d Buffers: %d",
+                   __func__, psPVRScreen->iContextAlloc,
+                   psPVRScreen->iDrawableAlloc, psPVRScreen->iBufferAlloc);
+
+      if (psPVRScreen->iRefCount > 1) {
+         errorMessage("%s: PVRDRIScreen resources will not be freed until its %d references are removed",
+                      __func__, psPVRScreen->iRefCount - 1);
+      }
+   }
+#endif
+
+   PVRDRIScreenRemoveReference(psPVRScreen);
+}
+
+static int
+PVRDRIScreenSupportedAPIs(PVRDRIScreen *psPVRScreen)
+{
+   unsigned int api_mask = psPVRScreen->psDRIScreen->api_mask;
+   int supported = 0;
+
+   if ((api_mask & (1 << __DRI_API_GLES)) != 0)
+      supported |= PVRDRI_API_BIT_GLES;
+
+   if ((api_mask & (1 << __DRI_API_GLES2)) != 0)
+      supported |= PVRDRI_API_BIT_GLES2;
+
+   if ((api_mask & (1 << __DRI_API_GLES3)) != 0)
+      supported |= PVRDRI_API_BIT_GLES3;
+
+   if ((api_mask & (1 << __DRI_API_OPENGL)) != 0)
+      supported |= PVRDRI_API_BIT_GL;
+
+   if ((api_mask & (1 << __DRI_API_OPENGL_CORE)) != 0)
+      supported |= PVRDRI_API_BIT_GL;
+
+   return supported;
+}
+
+static GLboolean
+PVRDRICreateContext(gl_api eMesaAPI, const struct gl_config *psGLMode,
+                    __DRIcontext *psDRIContext,
+                    const struct __DriverContextConfig *psCtxConfig,
+                    unsigned int *puError, void *pvSharedContextPrivate)
+{
+   __DRIscreen *psDRIScreen = psDRIContext->driScreenPriv;
+   PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate;
+   PVRDRIContext *psPVRContext;
+   struct DRISUPContext *psDRISUPContext;
+   struct DRISUPContext *psDRISUPSharedContext;
+   struct PVRDRIContextConfig sCtxConfig;
+   PVRDRIAPIType eAPI;
+
+   psDRISUPSharedContext = getSharedContextImpl(pvSharedContextPrivate);
+
+   sCtxConfig.uMajorVersion = psCtxConfig->major_version;
+   sCtxConfig.uMinorVersion = psCtxConfig->minor_version;
+   sCtxConfig.uFlags = psCtxConfig->flags;
+   sCtxConfig.iResetStrategy = __DRI_CTX_RESET_NO_NOTIFICATION;
+   sCtxConfig.uPriority = __DRI_CTX_PRIORITY_MEDIUM;
+   sCtxConfig.iReleaseBehavior = __DRI_CTX_RELEASE_BEHAVIOR_FLUSH;
+
+   psPVRContext = calloc(1, sizeof(*psPVRContext));
+   if (psPVRContext == NULL) {
+      __driUtilMessage("%s: Couldn't allocate PVRDRIContext", __func__);
+      *puError = __DRI_CTX_ERROR_NO_MEMORY;
+      return GL_FALSE;
+   }
+
+   psPVRContext->psDRIContext = psDRIContext;
+   psPVRContext->psPVRScreen = psPVRScreen;
+
+   if (psGLMode)
+      psPVRContext->sConfig.sGLMode = *psGLMode;
+
+   switch (eMesaAPI) {
+   case API_OPENGLES:
+      eAPI = PVRDRI_API_GLES1;
+      break;
+   case API_OPENGLES2:
+      eAPI = PVRDRI_API_GLES2;
+      break;
+   case API_OPENGL_COMPAT:
+      eAPI = PVRDRI_API_GL_COMPAT;
+      break;
+   case API_OPENGL_CORE:
+      eAPI = PVRDRI_API_GL_CORE;
+      break;
+   default:
+      __driUtilMessage("%s: Unsupported API: %d",
+                       __func__, (int) eMesaAPI);
+      *puError = __DRI_CTX_ERROR_BAD_API;
+      goto ErrorContextFree;
+   }
+   psPVRContext->eAPI = eAPI;
+
+   if ((psCtxConfig->attribute_mask &
+        __DRIVER_CONTEXT_ATTRIB_RESET_STRATEGY) != 0) {
+      sCtxConfig.iResetStrategy = psCtxConfig->reset_strategy;
+   }
+
+   if ((psCtxConfig->attribute_mask &
+        __DRIVER_CONTEXT_ATTRIB_RELEASE_BEHAVIOR) != 0) {
+      sCtxConfig.iReleaseBehavior = psCtxConfig->release_behavior;
+   }
+
+   if ((psCtxConfig->attribute_mask &
+        __DRIVER_CONTEXT_ATTRIB_PRIORITY) != 0) {
+      sCtxConfig.uPriority = psCtxConfig->priority;
+   }
+
+   *puError = DRISUPCreateContext(eAPI, &psPVRContext->sConfig, &sCtxConfig,
+                                  psDRIContext, psDRISUPSharedContext,
+                                  psPVRScreen->psDRISUPScreen,
+                                  &psDRISUPContext);
+   if (*puError != __DRI_CTX_ERROR_SUCCESS)
+      goto ErrorContextFree;
+
+   psPVRContext->psDRISUPContext = psDRISUPContext;
+
+   if (!pvrdri_create_dispatch_table(psPVRScreen, eAPI)) {
+      __driUtilMessage("%s: Couldn't create dispatch table", __func__);
+      *puError = __DRI_CTX_ERROR_BAD_API;
+      goto ErrorContextDestroy;
+   }
+#if defined(DEBUG)
+   p_atomic_inc(&psPVRScreen->iContextAlloc);
+#endif
+
+   psDRIContext->driverPrivate = (void *) psPVRContext;
+   PVRDRIScreenAddReference(psPVRScreen);
+
+   *puError = __DRI_CTX_ERROR_SUCCESS;
+
+   return GL_TRUE;
+
+ErrorContextDestroy:
+   DRISUPDestroyContext(psPVRContext->psDRISUPContext);
+
+ErrorContextFree:
+   free(psPVRContext);
+
+   return GL_FALSE;
+}
+
+static void
+PVRDRIDestroyContext(__DRIcontext *psDRIContext)
+{
+   PVRDRIContext *psPVRContext = psDRIContext->driverPrivate;
+   PVRDRIScreen *psPVRScreen = psPVRContext->psPVRScreen;
+
+   DRISUPDestroyContext(psPVRContext->psDRISUPContext);
+
+#if defined(DEBUG)
+   p_atomic_dec(&psPVRScreen->iContextAlloc);
+#endif
+
+   PVRDRIScreenRemoveReference(psPVRScreen);
+   free(psPVRContext);
+}
+
+static GLboolean
+PVRDRICreateBuffer(__DRIscreen *psDRIScreen, __DRIdrawable *psDRIDrawable,
+                   const struct gl_config *psGLMode, GLboolean bIsPixmap)
+{
+   PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate;
+   PVRDRIDrawable *psPVRDrawable = NULL;
+
+   /* No known callers ever set this to true */
+   if (bIsPixmap)
+      return GL_FALSE;
+
+   if (!psGLMode) {
+      __driUtilMessage("%s: Invalid GL config", __func__);
+      return GL_FALSE;
+   }
+
+   psPVRDrawable = calloc(1, sizeof(*psPVRDrawable));
+   if (!psPVRDrawable) {
+      __driUtilMessage("%s: Couldn't allocate PVR drawable", __func__);
+      goto ErrorDrawableFree;
+   }
+
+   psDRIDrawable->driverPrivate = (void *) psPVRDrawable;
+   psPVRDrawable->iRefCount = 1;
+   psPVRDrawable->psDRIDrawable = psDRIDrawable;
+   psPVRDrawable->psPVRScreen = psPVRScreen;
+   psPVRDrawable->sConfig.sGLMode = *psGLMode;
+   psPVRDrawable->sConfig.iSupportedAPIs =
+      PVRDRIScreenSupportedAPIs(psPVRScreen);
+
+   psPVRDrawable->psDRISUPDrawable =
+      DRISUPCreateDrawable(psDRIDrawable, psPVRScreen->psDRISUPScreen,
+                           psDRIDrawable->loaderPrivate,
+                           &psPVRDrawable->sConfig);
+   if (!psPVRDrawable->psDRISUPDrawable) {
+      __driUtilMessage("%s: Couldn't create DRI Support drawable",
+                       __func__);
+      goto ErrorDrawableFree;
+   }
+
+   /* Initialisation is completed in MakeCurrent */
+#if defined(DEBUG)
+   p_atomic_inc(&psPVRScreen->iDrawableAlloc);
+#endif
+   PVRDRIScreenAddReference(psPVRScreen);
+   return GL_TRUE;
+
+ErrorDrawableFree:
+   DRISUPDestroyDrawable(psPVRDrawable->psDRISUPDrawable);
+   free(psPVRDrawable);
+   psDRIDrawable->driverPrivate = NULL;
+
+   return GL_FALSE;
+}
+
+static void
+PVRDRIDestroyBuffer(__DRIdrawable *psDRIDrawable)
+{
+   PVRDRIDrawable *psPVRDrawable = psDRIDrawable->driverPrivate;
+
+   PVRDRIDrawableRemoveReference(psPVRDrawable);
+}
+
+static GLboolean
+PVRDRIMakeCurrent(__DRIcontext *psDRIContext,
+                  __DRIdrawable *psDRIWrite, __DRIdrawable *psDRIRead)
+{
+   PVRDRIContext *psPVRContext = psDRIContext->driverPrivate;
+   struct DRISUPDrawable *psDRISUPWrite;
+   struct DRISUPDrawable *psDRISUPRead;
+
+   if (psDRIWrite) {
+      PVRDRIDrawable *psPVRWrite = psDRIWrite->driverPrivate;
+
+      psDRISUPWrite = psPVRWrite->psDRISUPDrawable;
+   } else {
+      psDRISUPWrite = NULL;
+   }
+
+   if (psDRIRead) {
+      PVRDRIDrawable *psPVRRead = psDRIRead->driverPrivate;
+
+      psDRISUPRead = psPVRRead->psDRISUPDrawable;
+   } else {
+      psDRISUPRead = NULL;
+   }
+
+   if (!DRISUPMakeCurrent(psPVRContext->psDRISUPContext,
+                          psDRISUPWrite, psDRISUPRead))
+      goto ErrorUnlock;
+
+   pvrdri_set_dispatch_table(psPVRContext);
+
+   return GL_TRUE;
+
+ErrorUnlock:
+   return GL_FALSE;
+}
+
+static GLboolean
+PVRDRIUnbindContext(__DRIcontext *psDRIContext)
+{
+   PVRDRIContext *psPVRContext = psDRIContext->driverPrivate;
+
+   pvrdri_set_null_dispatch_table();
+   DRISUPUnbindContext(psPVRContext->psDRISUPContext);
+
+   return GL_TRUE;
+}
+
+static __DRIbuffer *
+PVRDRIAllocateBuffer(__DRIscreen *psDRIScreen, unsigned int uAttachment,
+                     unsigned int uFormat, int iWidth, int iHeight)
+{
+   PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate;
+   struct PVRBuffer *psBuffer;
+
+   psBuffer = calloc(1, sizeof(*psBuffer));
+   if (psBuffer == NULL) {
+      __driUtilMessage("%s: Failed to allocate buffer", __func__);
+      return NULL;
+   }
+
+   psBuffer->psDRISUPBuffer =
+      DRISUPAllocateBuffer(psPVRScreen->psDRISUPScreen, uAttachment, uFormat,
+                           iWidth, iHeight, &psBuffer->sDRIBuffer.name,
+                           &psBuffer->sDRIBuffer.pitch,
+                           &psBuffer->sDRIBuffer.cpp,
+                           &psBuffer->sDRIBuffer.flags);
+   if (!psBuffer->psDRISUPBuffer) {
+      __driUtilMessage("%s: Failed to create DRI Support buffer", __func__);
+      goto ErrorFreeDRIBuffer;
+   }
+
+   psBuffer->sDRIBuffer.attachment = uAttachment;
+
+#if defined(DEBUG)
+   p_atomic_inc(&psPVRScreen->iBufferAlloc);
+#endif
+
+   return &psBuffer->sDRIBuffer;
+
+ErrorFreeDRIBuffer:
+   free(psBuffer);
+
+   return NULL;
+}
+
+static void
+PVRDRIReleaseBuffer(__DRIscreen *psDRIScreen, __DRIbuffer *psDRIBuffer)
+{
+   struct PVRBuffer *psPVRBuffer = (struct PVRBuffer *) psDRIBuffer;
+   PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate;
+
+   DRISUPReleaseBuffer(psPVRScreen->psDRISUPScreen,
+                       psPVRBuffer->psDRISUPBuffer);
+
+#if defined(DEBUG)
+   p_atomic_dec(&psPVRScreen->iBufferAlloc);
+#endif
+
+   free(psPVRBuffer);
+}
+
+static const struct __DriverAPIRec pvr_driver_api = {
+   .InitScreen = PVRDRIInitScreen,
+   .DestroyScreen = PVRDRIDestroyScreen,
+   .CreateContext = PVRDRICreateContext,
+   .DestroyContext = PVRDRIDestroyContext,
+   .CreateBuffer = PVRDRICreateBuffer,
+   .DestroyBuffer = PVRDRIDestroyBuffer,
+   .SwapBuffers = NULL,
+   .MakeCurrent = PVRDRIMakeCurrent,
+   .UnbindContext = PVRDRIUnbindContext,
+   .AllocateBuffer = PVRDRIAllocateBuffer,
+   .ReleaseBuffer = PVRDRIReleaseBuffer,
+};
+
+static const struct __DRIDriverVtableExtensionRec pvr_vtable = {
+   .base = {__DRI_DRIVER_VTABLE, 1},
+   .vtable = &pvr_driver_api,
+};
+
+static const __DRIextension *pvr_driver_extensions[] = {
+   &driCoreExtension.base,
+   &driImageDriverExtension.base,
+   &driDRI2Extension.base,
+   &pvr_vtable.base,
+   NULL
+};
+
+const __DRIextension **__driDriverGetExtensions_pvr(void);
+
+PUBLIC const __DRIextension **
+__driDriverGetExtensions_pvr(void)
+{
+   globalDriverAPI = &pvr_driver_api;
+
+   return pvr_driver_extensions;
+}
diff --git a/src/mesa/drivers/dri/pvr/pvrdri.h b/src/mesa/drivers/dri/pvr/pvrdri.h
new file mode 100644
index 0000000..fd465bf
--- /dev/null
+++ b/src/mesa/drivers/dri/pvr/pvrdri.h
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) Imagination Technologies Ltd.
+ *
+ * The contents of this file are subject to the MIT license as set out below.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#if !defined(__PVRDRI_H__)
+#define __PVRDRI_H__
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <inttypes.h>
+
+#include <glapi/glapi.h>
+
+#include "main/mtypes.h"
+#include "util/macros.h"
+#include "dri_util.h"
+#include "pvrdri_support.h"
+
+struct PVRDRIConfigRec {
+   struct gl_config sGLMode;
+   int iSupportedAPIs;
+};
+
+/* PVR screen data */
+typedef struct PVRDRIScreen_TAG {
+   /* DRI screen structure pointer */
+   __DRIscreen *psDRIScreen;
+
+   /* Opaque PVR DRI Support screen structure pointer */
+   struct DRISUPScreen *psDRISUPScreen;
+
+   /* Reference count */
+   int iRefCount;
+
+#if defined(DEBUG)
+   /* Counters of outstanding allocations */
+   int iContextAlloc;
+   int iDrawableAlloc;
+   int iBufferAlloc;
+#endif
+
+   /* PVR OGLES 1 dispatch table */
+   struct _glapi_table *psOGLES1Dispatch;
+   /* PVR OGLES 2/3 dispatch table */
+   struct _glapi_table *psOGLES2Dispatch;
+   /* PVR OGL dispatch table */
+   struct _glapi_table *psOGLDispatch;
+} PVRDRIScreen;
+
+/* PVR context data */
+typedef struct PVRDRIContext_TAG {
+   /* Pointer to DRI context */
+   __DRIcontext *psDRIContext;
+
+   /* Opaque PVR DRI Support context structure pointer */
+   struct DRISUPContext *psDRISUPContext;
+
+   /* Pointer to PVRDRIScreen structure */
+   PVRDRIScreen *psPVRScreen;
+
+   /* GL config */
+   PVRDRIConfig sConfig;
+
+   /* API */
+   PVRDRIAPIType eAPI;
+} PVRDRIContext;
+
+/* PVR drawable data */
+typedef struct PVRDRIDrawable_TAG {
+   PVRDRIScreen *psPVRScreen;
+   __DRIdrawable *psDRIDrawable;
+   int iRefCount;
+   PVRDRIConfig sConfig;
+   struct DRISUPDrawable *psDRISUPDrawable;
+   unsigned int uFourCC;
+   unsigned int uDRIFormat;
+} PVRDRIDrawable;
+
+/*************************************************************************//*!
+ pvrdri.c
+ *//**************************************************************************/
+void PVRDRIDrawableAddReference(PVRDRIDrawable *psPVRDrawable);
+void PVRDRIDrawableRemoveReference(PVRDRIDrawable *psPVRDrawable);
+
+/*************************************************************************//*!
+ pvrutil.c
+ *//**************************************************************************/
+
+void PRINTFLIKE(1, 2) __driUtilMessage(const char *f, ...);
+void PRINTFLIKE(1, 2) errorMessage(const char *f, ...);
+
+mesa_format PVRDRIMesaFormatToMesaFormat(int pvrdri_mesa_format);
+int PVRDRIFormatToFourCC(int dri_format);
+int PVRDRIFourCCToDRIFormat(int iFourCC);
+
+/*************************************************************************//*!
+ pvrext.c
+ *//**************************************************************************/
+
+const __DRIextension **PVRDRIScreenExtensions(void);
+const __DRIextension *PVRDRIScreenExtensionVersionInfo(void);
+
+void PVRDRIAdjustExtensions(unsigned int uVersion, unsigned int uMinVersion);
+
+/*************************************************************************//*!
+ pvrcompat.c
+ *//**************************************************************************/
+
+bool PVRDRICompatInit(const struct PVRDRICallbacksV2 *psCallbacksV2,
+                      unsigned int uVersionV2, unsigned int uMinVersionV2);
+void PVRDRICompatDeinit(void);
+
+bool MODSUPRegisterSupportInterfaceV2(const void *pvInterface,
+                                      unsigned int uVersion,
+                                      unsigned int uMinVersion);
+
+/*************************************************************************//*!
+ pvrcb.c
+ *//**************************************************************************/
+
+int MODSUPGetBuffers(struct __DRIdrawableRec *psDRIDrawable,
+                     unsigned int uFourCC, uint32_t *puStamp,
+                     void *pvLoaderPrivate, uint32_t uBufferMask,
+                     struct PVRDRIImageList *psImageList);
+
+bool MODSUPCreateConfigs(struct __DRIconfigRec ***psConfigs,
+                         struct __DRIscreenRec *psDRIScreen,
+                         int iPVRDRIMesaFormat, const uint8_t *puDepthBits,
+                         const uint8_t *puStencilBits,
+                         unsigned int uNumDepthStencilBits,
+                         const unsigned int *puDBModes,
+                         unsigned int uNumDBModes,
+                         const uint8_t *puMSAASamples,
+                         unsigned int uNumMSAAModes, bool bEnableAccum,
+                         bool bColorDepthMatch, bool bMutableRenderBuffer,
+                         int iYUVDepthRange, int iYUVCSCStandard,
+                         uint32_t uMaxPbufferWidth, uint32_t uMaxPbufferHeight);
+
+struct __DRIconfigRec **MODSUPConcatConfigs(struct __DRIscreenRec *psDRIScreen,
+                                            struct __DRIconfigRec **ppsConfigA,
+                                            struct __DRIconfigRec **ppsConfigB);
+
+__DRIimage *MODSUPLookupEGLImage(struct __DRIscreenRec *psDRIScreen,
+                                 void *pvImage, void *pvLoaderPrivate);
+
+unsigned int MODSUPGetCapability(struct __DRIscreenRec *psDRIScreen,
+                                 unsigned int uCapability);
+
+int MODSUPGetDisplayFD(struct __DRIscreenRec *psDRIScreen,
+                       void *pvLoaderPrivate);
+
+bool PVRDRIConfigQuery(const PVRDRIConfig *psConfig,
+                       PVRDRIConfigAttrib eConfigAttrib, int *piValueOut);
+
+bool MODSUPConfigQuery(const PVRDRIConfig *psConfig,
+                       PVRDRIConfigAttrib eConfigAttrib,
+                       unsigned int *puValueOut);
+
+void MODSUPFlushFrontBuffer(struct __DRIdrawableRec *psDRIDrawable,
+                            void *pvLoaderPrivate);
+
+void *MODSUPDrawableGetReferenceHandle(struct __DRIdrawableRec *psDRIDrawable);
+
+void MODSUPDrawableAddReference(void *pvReferenceHandle);
+
+void MODSUPDrawableRemoveReference(void *pvReferenceHandle);
+
+#endif /* defined(__PVRDRI_H__) */
diff --git a/src/mesa/drivers/dri/pvr/pvrdri_support.h b/src/mesa/drivers/dri/pvr/pvrdri_support.h
new file mode 100644
index 0000000..58ea350
--- /dev/null
+++ b/src/mesa/drivers/dri/pvr/pvrdri_support.h
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) Imagination Technologies Ltd.
+ *
+ * The contents of this file are subject to the MIT license as set out below.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#if !defined(__PVRDRI_SUPPORT_H__)
+#define __PVRDRI_SUPPORT_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "dri_support.h"
+
+struct DRISUPScreen *DRISUPCreateScreen(struct __DRIscreenRec *psDRIScreen,
+                                        int iFD, bool bUseInvalidate,
+                                        void *pvLoaderPrivate,
+                                        const struct __DRIconfigRec ***pppsConfigs,
+                                        int *piMaxGLES1Version,
+                                        int *piMaxGLES2Version);
+void DRISUPDestroyScreen(struct DRISUPScreen *psDRISUPScreen);
+
+unsigned int DRISUPCreateContext(PVRDRIAPIType eAPI,
+                                 PVRDRIConfig *psPVRDRIConfig,
+                                 struct PVRDRIContextConfig *psCtxConfig,
+                                 struct __DRIcontextRec *psDRIContext,
+                                 struct DRISUPContext *psDRISUPSharedContext,
+                                 struct DRISUPScreen *psDRISUPScreen,
+                                 struct DRISUPContext **ppsDRISUPContext);
+void DRISUPDestroyContext(struct DRISUPContext *psDRISUPContext);
+
+struct DRISUPDrawable *DRISUPCreateDrawable(struct __DRIdrawableRec *psDRIDrawable,
+                                            struct DRISUPScreen *psDRISUPScreen,
+                                            void *pvLoaderPrivate,
+                                            PVRDRIConfig *psPVRDRIConfig);
+void DRISUPDestroyDrawable(struct DRISUPDrawable *psDRISUPDrawable);
+
+bool DRISUPMakeCurrent(struct DRISUPContext *psDRISUPContext,
+                       struct DRISUPDrawable *psDRISUPWrite,
+                       struct DRISUPDrawable *psDRISUPRead);
+bool DRISUPUnbindContext(struct DRISUPContext *psDRISUPContext);
+
+struct DRISUPBuffer *DRISUPAllocateBuffer(struct DRISUPScreen *psDRISUPScreen,
+                                          unsigned int uAttchment,
+                                          unsigned int uFormat,
+                                          int iWidth, int iHeight,
+                                          unsigned int *puName,
+                                          unsigned int *puPitch,
+                                          unsigned int *puCPP,
+                                          unsigned int *puFlags);
+void DRISUPReleaseBuffer(struct DRISUPScreen *psDRISUPScreen,
+                         struct DRISUPBuffer *psDRISUPBuffer);
+void DRISUPSetTexBuffer2(struct DRISUPContext *psDRISUPContext,
+                         int iTarget, int iFormat,
+                         struct DRISUPDrawable *psDRISUPDrawable);
+void DRISUPReleaseTexBuffer(struct DRISUPContext *psDRISUPContext,
+                            int iTarget,
+                            struct DRISUPDrawable *psDRISUPDrawable);
+
+void DRISUPFlush(struct DRISUPDrawable *psDRISUPDrawable);
+void DRISUPInvalidate(struct DRISUPDrawable *psDRISUPDrawable);
+void DRISUPFlushWithFlags(struct DRISUPContext *psDRISUPContext,
+                          struct DRISUPDrawable *psDRISUPDrawable,
+                          unsigned int uFlags, unsigned int uThrottleReason);
+
+__DRIimage *DRISUPCreateImageFromName(struct DRISUPScreen *psDRISUPScreen,
+                                      int iWidth, int iHeight, int iFourCC,
+                                      int iName, int iPitch,
+                                      void *pvLoaderPrivate);
+__DRIimage *DRISUPCreateImageFromRenderbuffer(struct DRISUPContext *psDRISUPContext,
+                                              int iRenderBuffer,
+                                              void *pvLoaderPrivate);
+void DRISUPDestroyImage(__DRIimage *psImage);
+__DRIimage *DRISUPCreateImage(struct DRISUPScreen *psDRISUPScreen,
+                              int iWidth, int iHeight, int iFourCC,
+                              unsigned int uUse, void *pvLoaderPrivate);
+bool DRISUPQueryImage(__DRIimage *psImage, int iAttrib, int *piValue);
+__DRIimage *DRISUPDupImage(__DRIimage *psImage, void *pvLoaderPrivate);
+bool DRISUPValidateImageUsage(__DRIimage *psImage, unsigned int uUse);
+__DRIimage *DRISUPCreateImageFromNames(struct DRISUPScreen *psDRISUPScreen,
+                                       int iWidth, int iHeight, int iFourCC,
+                                       int *piNames, int iNumNames,
+                                       int *piStrides, int *piOffsets,
+                                       void *pvLoaderPrivate);
+__DRIimage *DRISUPFromPlanar(__DRIimage *psImage, int iPlane,
+                             void *pvLoaderPrivate);
+__DRIimage *DRISUPCreateImageFromTexture(struct DRISUPContext *psDRISUPContext,
+                                         int iTarget, unsigned int uTexture,
+                                         int iDepth, int iLevel,
+                                         unsigned int *puError,
+                                         void *pvLoaderPrivate);
+__DRIimage *DRISUPCreateImageFromFDs(struct DRISUPScreen *psDRISUPcreen,
+                                     int iWidth, int iHeight, int iFourCC,
+                                     int *piFDs, int iNumFDs,
+                                     int *piStrides, int *piOffsets,
+                                     void *pvLoaderPrivate);
+__DRIimage *DRISUPCreateImageFromDmaBufs(struct DRISUPScreen *psDRISUPScreen,
+                                         int iWidth, int iHeight, int iFourCC,
+                                         int *piFDs, int iNumFDs,
+                                         int *piStrides, int *piOffsets,
+                                         unsigned int uColorSpace,
+                                         unsigned int uSampleRange,
+                                         unsigned int uHorizSiting,
+                                         unsigned int uVertSiting,
+                                         unsigned int *puError,
+                                         void *pvLoaderPrivate);
+int DRISUPGetImageCapabilities(struct DRISUPScreen *psDRISUPScreen);
+void DRISUPBlitImage(struct DRISUPContext *psDRISUPContext,
+                     __DRIimage *psDst, __DRIimage *psSrc,
+                     int iDstX0, int iDstY0, int iDstWidth, int iDstHeight,
+                     int iSrcX0, int iSrcY0, int iSrcWidth, int iSrcHeight,
+                     int iFlushFlag);
+void *DRISUPMapImage(struct DRISUPContext *psDRISUPContext,
+                     __DRIimage *psImage,
+                     int iX0, int iY0, int iWidth, int iHeight,
+                     unsigned int uFlags, int *piStride, void **ppvData);
+void DRISUPUnmapImage(struct DRISUPContext *psDRISUPContext,
+                      __DRIimage *psImage, void *pvData);
+__DRIimage *DRISUPCreateImageWithModifiers(struct DRISUPScreen *psDRISUPScreen,
+                                           int iWidth, int iHeight, int iFourCC,
+                                           const uint64_t *puModifiers,
+                                           const unsigned int uModifierCount,
+                                           void *pvLoaderPrivate);
+__DRIimage *DRISUPCreateImageFromDMABufs2(struct DRISUPScreen *psDRISUPScreen,
+                                          int iWidth, int iHeight,
+                                          int iFourCC, uint64_t uModifier,
+                                          int *piFDs, int iNumFDs,
+                                          int *piStrides, int *piOffsets,
+                                          unsigned int uColorSpace,
+                                          unsigned int uSampleRange,
+                                          unsigned int uHorizSiting,
+                                          unsigned int uVertSiting,
+                                          unsigned int *puError,
+                                          void *pvLoaderPrivate);
+
+bool DRISUPQueryDMABufFormats(struct DRISUPScreen *psDRISUPScreen, int iMax,
+                              int *piFormats, int *piCount);
+bool DRISUPQueryDMABufModifiers(struct DRISUPScreen *psDRISUPScreen,
+                                int iFourCC, int iMax, uint64_t *puModifiers,
+                                unsigned int *piExternalOnly, int *piCount);
+bool DRISUPQueryDMABufFormatModifierAttribs(struct DRISUPScreen *psDRISUPScreen,
+                                            uint32_t uFourcc,
+                                            uint64_t uModifier,
+                                            int iAttrib, uint64_t *puValue);
+
+__DRIimage *DRISUPCreateImageFromRenderBuffer2(struct DRISUPContext *psDRISUPContext,
+                                               int iRenderBuffer,
+                                               void *pvLoaderPrivate,
+                                               unsigned int *puError);
+
+__DRIimage *DRISUPCreateImageFromBuffer(struct DRISUPContext *psDRISUPContext,
+                                        int iTarget, void *pvBuffer,
+                                        unsigned int *puError,
+                                        void *pvLoaderPrivate);
+
+int DRISUPQueryRendererInteger(struct DRISUPScreen *psDRISUPScreen,
+                               int iAttribute, unsigned int *puValue);
+int DRISUPQueryRendererString(struct DRISUPScreen *psDRISUPScreen,
+                              int iAttribute, const char **ppszValue);
+
+void *DRISUPCreateFence(struct DRISUPContext *psDRISUPContext);
+void DRISUPDestroyFence(struct DRISUPScreen *psDRISUPScreen, void *pvFence);
+bool DRISUPClientWaitSync(struct DRISUPContext *psDRISUPContext,
+                          void *pvFence, unsigned int uFlags,
+                          uint64_t uTimeout);
+void DRISUPServerWaitSync(struct DRISUPContext *psDRISUPContext,
+                          void *pvFence, unsigned int uFlags);
+unsigned int DRISUPGetFenceCapabilities(struct DRISUPScreen *psDRISUPScreen);
+void *DRISUPCreateFenceFD(struct DRISUPContext *psDRISUPContext, int iFD);
+int DRISUPGetFenceFD(struct DRISUPScreen *psDRISUPScreen, void *pvFence);
+void *DRISUPGetFenceFromCLEvent(struct DRISUPScreen *psDRISUPScreen,
+                                intptr_t iCLEvent);
+int DRISUPGetAPIVersion(struct DRISUPScreen *psDRISUPScreen,
+                        PVRDRIAPIType eAPI);
+
+unsigned int DRISUPGetNumAPIProcs(struct DRISUPScreen *psDRISUPScreen,
+                                  PVRDRIAPIType eAPI);
+const char *DRISUPGetAPIProcName(struct DRISUPScreen *psDRISUPScreen,
+                                 PVRDRIAPIType eAPI, unsigned int uIndex);
+void *DRISUPGetAPIProcAddress(struct DRISUPScreen *psDRISUPScreen,
+                              PVRDRIAPIType eAPI, unsigned int uIndex);
+
+void DRISUPSetDamageRegion(struct DRISUPDrawable *psDRISUPDrawable,
+                           unsigned int uNRects, int *piRects);
+
+bool DRISUPHaveGetFenceFromCLEvent(void);
+
+#endif /* defined(__PVRDRI_SUPPORT_H__) */
diff --git a/src/mesa/drivers/dri/pvr/pvrext.c b/src/mesa/drivers/dri/pvr/pvrext.c
new file mode 100644
index 0000000..4783996
--- /dev/null
+++ b/src/mesa/drivers/dri/pvr/pvrext.c
@@ -0,0 +1,704 @@
+/*
+ * Copyright (c) Imagination Technologies Ltd.
+ *
+ * The contents of this file are subject to the MIT license as set out below.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/*
+ * EXTENSION SUPPORT
+ *
+ * As the driver supports a range of Mesa versions it can be the case that it
+ * needs to support different extensions and extension versions depending on
+ * the version of Mesa that it's built against. As a guide the following rules
+ * should be followed:
+ *
+ * 1) If an extension appears in some supported versions of Mesa but not others
+ *    then it should be protected by the extension define, e.g.:
+ *    #if defined(__DRI_IMAGE)
+ *    <code>
+ *    #endif
+ *
+ *    However, if it appears in all versions then there's no need for it to
+ *    be protected.
+ *
+ * 2) Each driver supported extension should have a define for the maximum
+ *    version supported by the driver. This should be used when initialising
+ *    the corresponding extension structure. The Mesa extension version define
+ *    should *NOT* be used.
+ *
+ * 3) If the driver supports a range of versions for a given extension then
+ *    it should protect the extension code based on the Mesa extension version
+ *    define. For example, if the driver has to support versions 7 to 8 of the
+ *    __DRI_IMAGE extension then any fields, in the __DRIimageExtension
+ *    structure, that appear in version 8 but not 7 should be protected as
+ *    follows:
+ *    #if (__DRI_IMAGE_VERSION >= 8)
+ *    .createImageFromDmaBufs = PVRDRICreateImageFromDmaBufs,
+ *    #endif
+ *
+ *    Obviously any other associated code should also be protected in the same
+ *    way.
+ */
+
+#include "dri_util.h"
+#include "utils.h"
+
+#include "dri_support.h"
+#include "pvrdri.h"
+
+#include "EGL/egl.h"
+#include "EGL/eglext.h"
+#include "EGL/eglmesaext.h"
+
+/* Maximum version numbers for each supported extension */
+#define PVR_DRI_TEX_BUFFER_VERSION      3
+#define PVR_DRI2_FLUSH_VERSION          4
+#define PVR_DRI_IMAGE_VERSION           17
+#define PVR_DRI2_ROBUSTNESS_VERSION     1
+#define PVR_DRI2_FENCE_VERSION          2
+#define PVR_DRI2_RENDERER_QUERY_VERSION 1
+#define PVR_DRI2_BUFFER_DAMAGE_VERSION  1
+
+static void
+PVRDRIExtSetTexBuffer(__DRIcontext *psDRIContext, GLint iTarget,
+                      GLint iFormat, __DRIdrawable *psDRIDrawable)
+{
+   PVRDRIDrawable *psPVRDrawable = psDRIDrawable->driverPrivate;
+   PVRDRIContext *psPVRContext = psDRIContext->driverPrivate;
+
+   DRISUPSetTexBuffer2(psPVRContext->psDRISUPContext,
+                       iTarget, iFormat, psPVRDrawable->psDRISUPDrawable);
+}
+
+static void
+PVRDRIExtReleaseTexBuffer(__DRIcontext *psDRIContext, GLint iTarget,
+                          __DRIdrawable *psDRIDrawable)
+{
+   PVRDRIDrawable *psPVRDrawable = psDRIDrawable->driverPrivate;
+   PVRDRIContext *psPVRContext = psDRIContext->driverPrivate;
+
+   DRISUPReleaseTexBuffer(psPVRContext->psDRISUPContext,
+                          iTarget, psPVRDrawable->psDRISUPDrawable);
+
+}
+
+static __DRItexBufferExtension pvrDRITexBufferExtension = {
+   .base = {
+      .name = __DRI_TEX_BUFFER,
+      .version = PVR_DRI_TEX_BUFFER_VERSION,
+   },
+   .setTexBuffer = NULL,
+   .setTexBuffer2 = PVRDRIExtSetTexBuffer,
+   .releaseTexBuffer = PVRDRIExtReleaseTexBuffer,
+};
+
+static void
+PVRDRI2Flush(__DRIdrawable *psDRIDrawable)
+{
+   PVRDRIDrawable *psPVRDrawable = psDRIDrawable->driverPrivate;
+
+   DRISUPFlush(psPVRDrawable->psDRISUPDrawable);
+}
+
+static void
+PVRDRI2Invalidate(__DRIdrawable *psDRIDrawable)
+{
+   PVRDRIDrawable *psPVRDrawable = psDRIDrawable->driverPrivate;
+
+   DRISUPInvalidate(psPVRDrawable->psDRISUPDrawable);
+}
+
+static void
+PVRDRI2FlushWithFlags(__DRIcontext *psDRIContext,
+                      __DRIdrawable *psDRIDrawable,
+                      unsigned int uFlags,
+                      enum __DRI2throttleReason eThrottleReason)
+{
+   PVRDRIContext *psPVRContext = psDRIContext->driverPrivate;
+   struct DRISUPDrawable *psDRISUPDrawable;
+
+   if ((uFlags & __DRI2_FLUSH_DRAWABLE) != 0) {
+      PVRDRIDrawable *psPVRDrawable = psDRIDrawable->driverPrivate;
+
+      psDRISUPDrawable = psPVRDrawable->psDRISUPDrawable;
+   } else {
+      psDRISUPDrawable = NULL;
+   }
+
+   DRISUPFlushWithFlags(psPVRContext->psDRISUPContext, psDRISUPDrawable,
+                        uFlags, (unsigned int) eThrottleReason);
+}
+
+static __DRI2flushExtension pvrDRI2FlushExtension = {
+   .base = {
+      .name = __DRI2_FLUSH,
+      .version = PVR_DRI2_FLUSH_VERSION,
+   },
+   .flush = PVRDRI2Flush,
+   .invalidate = PVRDRI2Invalidate,
+   .flush_with_flags = PVRDRI2FlushWithFlags,
+};
+
+static __DRIimage *
+PVRDRICreateImageFromName(__DRIscreen *psDRIScreen, int iWidth, int iHeight,
+                          int iFormat, int iName, int iPitch,
+                          void *pvLoaderPrivate)
+{
+   PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate;
+   int iFourCC = PVRDRIFormatToFourCC(iFormat);
+
+   return DRISUPCreateImageFromName(psPVRScreen->psDRISUPScreen,
+                                    iWidth, iHeight, iFourCC, iName, iPitch,
+                                    pvLoaderPrivate);
+}
+
+static __DRIimage *
+PVRDRICreateImageFromRenderbuffer(__DRIcontext *psDRIContext,
+                                  int iRenderBuffer, void *pvLoaderPrivate)
+{
+   PVRDRIContext *psPVRContext = psDRIContext->driverPrivate;
+
+   return DRISUPCreateImageFromRenderbuffer(psPVRContext->psDRISUPContext,
+                                            iRenderBuffer, pvLoaderPrivate);
+}
+
+static void
+PVRDRIDestroyImage(__DRIimage *psImage)
+{
+   DRISUPDestroyImage(psImage);
+}
+
+static __DRIimage *
+PVRDRICreateImage(__DRIscreen *psDRIScreen, int iWidth, int iHeight,
+                  int iFormat, unsigned int uUse, void *pvLoaderPrivate)
+{
+   PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate;
+   int iFourCC = PVRDRIFormatToFourCC(iFormat);
+
+   return DRISUPCreateImage(psPVRScreen->psDRISUPScreen, iWidth, iHeight,
+                            iFourCC, uUse, pvLoaderPrivate);
+}
+
+static GLboolean
+PVRDRIQueryImage(__DRIimage *psImage, int iAttrib, int *piValue)
+{
+   int iFourCC;
+
+   switch (iAttrib) {
+   case __DRI_IMAGE_ATTRIB_FORMAT:
+      if (DRISUPQueryImage(psImage,
+                           __DRI_IMAGE_ATTRIB_FOURCC, &iFourCC)) {
+         *piValue = PVRDRIFourCCToDRIFormat(iFourCC);
+         return GL_TRUE;
+      }
+      return GL_FALSE;
+   default:
+      return DRISUPQueryImage(psImage, iAttrib, piValue);
+   }
+
+}
+
+static __DRIimage *
+PVRDRIDupImage(__DRIimage *psImage, void *pvLoaderPrivate)
+{
+   return DRISUPDupImage(psImage, pvLoaderPrivate);
+}
+
+static GLboolean
+PVRDRIValidateImageUsage(__DRIimage *psImage, unsigned int uUse)
+{
+   return DRISUPValidateImageUsage(psImage, uUse);
+}
+
+static __DRIimage *
+PVRDRICreateImageFromNames(__DRIscreen *psDRIScreen, int iWidth, int iHeight,
+                           int iFourCC, int *piNames, int iNumNames,
+                           int *piStrides, int *piOffsets,
+                           void *pvLoaderPrivate)
+{
+   PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate;
+
+   return DRISUPCreateImageFromNames(psPVRScreen->psDRISUPScreen,
+                                     iWidth, iHeight, iFourCC,
+                                     piNames, iNumNames,
+                                     piStrides, piOffsets, pvLoaderPrivate);
+}
+
+static __DRIimage *
+PVRDRIFromPlanar(__DRIimage *psImage, int iPlane, void *pvLoaderPrivate)
+{
+   return DRISUPFromPlanar(psImage, iPlane, pvLoaderPrivate);
+}
+
+static __DRIimage *
+PVRDRICreateImageFromTexture(__DRIcontext *psDRIContext, int iTarget,
+                             unsigned int uTexture, int iDepth, int iLevel,
+                             unsigned int *puError, void *pvLoaderPrivate)
+{
+   PVRDRIContext *psPVRContext = psDRIContext->driverPrivate;
+   int iEGLTarget;
+
+   switch (iTarget) {
+   case GL_TEXTURE_2D:
+      iEGLTarget = PVRDRI_GL_TEXTURE_2D;
+      break;
+   case GL_TEXTURE_3D:
+      iEGLTarget = PVRDRI_GL_TEXTURE_3D;
+      break;
+   case GL_TEXTURE_CUBE_MAP:
+      iEGLTarget = PVRDRI_GL_TEXTURE_CUBE_MAP_POSITIVE_X;
+      break;
+   default:
+      errorMessage("%s: GL Target %d is not supported",
+                   __func__, iTarget);
+      *puError = __DRI_IMAGE_ERROR_BAD_PARAMETER;
+      return NULL;
+   }
+
+   return DRISUPCreateImageFromTexture(psPVRContext->psDRISUPContext,
+                                       iEGLTarget, uTexture, iDepth, iLevel,
+                                       puError, pvLoaderPrivate);
+}
+
+static __DRIimage *
+PVRDRICreateImageFromFds(__DRIscreen *psDRIScreen, int iWidth, int iHeight,
+                         int iFourCC, int *piFDs, int iNumFDs,
+                         int *piStrides, int *piOffsets,
+                         void *pvLoaderPrivate)
+{
+   PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate;
+
+   return DRISUPCreateImageFromFDs(psPVRScreen->psDRISUPScreen,
+                                   iWidth, iHeight, iFourCC, piFDs, iNumFDs,
+                                   piStrides, piOffsets, pvLoaderPrivate);
+}
+
+static __DRIimage *
+PVRDRICreateImageFromDmaBufs(__DRIscreen *psDRIScreen,
+                             int iWidth, int iHeight, int iFourCC,
+                             int *piFDs, int iNumFDs,
+                             int *piStrides, int *piOffsets,
+                             enum __DRIYUVColorSpace eColorSpace,
+                             enum __DRISampleRange eSampleRange,
+                             enum __DRIChromaSiting eHorizSiting,
+                             enum __DRIChromaSiting eVertSiting,
+                             unsigned int *puError, void *pvLoaderPrivate)
+{
+   PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate;
+
+   return DRISUPCreateImageFromDmaBufs(psPVRScreen->psDRISUPScreen,
+                                       iWidth, iHeight, iFourCC,
+                                       piFDs, iNumFDs, piStrides, piOffsets,
+                                       (unsigned int) eColorSpace,
+                                       (unsigned int) eSampleRange,
+                                       (unsigned int) eHorizSiting,
+                                       (unsigned int) eVertSiting,
+                                       puError, pvLoaderPrivate);
+}
+
+static void
+PVRDRIBlitImage(__DRIcontext *psDRIContext,
+                __DRIimage *psDst, __DRIimage *psSrc,
+                int iDstX0, int iDstY0, int iDstWidth, int iDstHeight,
+                int iSrcX0, int iSrcY0, int iSrcWidth, int iSrcHeight,
+                int iFlushFlag)
+{
+   PVRDRIContext *psPVRContext = psDRIContext->driverPrivate;
+
+   return DRISUPBlitImage(psPVRContext->psDRISUPContext,
+                          psDst, psSrc,
+                          iDstX0, iDstY0, iDstWidth, iDstHeight,
+                          iSrcX0, iSrcY0, iSrcWidth, iSrcHeight,
+                          iFlushFlag);
+}
+
+static int
+PVRDRIGetCapabilities(__DRIscreen *psDRIScreen)
+{
+   PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate;
+
+   return DRISUPGetImageCapabilities(psPVRScreen->psDRISUPScreen);
+}
+
+static void *
+PVRDRIMapImage(__DRIcontext *psDRIContext, __DRIimage *psImage,
+               int iX0, int iY0, int iWidth, int iHeight,
+               unsigned int iFlags, int *piStride, void **ppvData)
+{
+   PVRDRIContext *psPVRContext = psDRIContext->driverPrivate;
+
+   return DRISUPMapImage(psPVRContext->psDRISUPContext, psImage,
+                         iX0, iY0, iWidth, iHeight, iFlags, piStride,
+                         ppvData);
+}
+
+static void
+PVRDRIUnmapImage(__DRIcontext *psDRIContext, __DRIimage *psImage,
+                 void *pvData)
+{
+   PVRDRIContext *psPVRContext = psDRIContext->driverPrivate;
+
+   return DRISUPUnmapImage(psPVRContext->psDRISUPContext, psImage, pvData);
+}
+
+static __DRIimage *
+PVRDRICreateImageWithModifiers(__DRIscreen *psDRIScreen,
+                               int iWidth, int iHeight, int iFormat,
+                               const uint64_t *puModifiers,
+                               const unsigned int uModifierCount,
+                               void *pvLoaderPrivate)
+{
+   PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate;
+   int iFourCC = PVRDRIFormatToFourCC(iFormat);
+
+   return DRISUPCreateImageWithModifiers(psPVRScreen->psDRISUPScreen,
+                                         iWidth, iHeight, iFourCC,
+                                         puModifiers, uModifierCount,
+                                         pvLoaderPrivate);
+}
+
+static __DRIimage *
+PVRDRICreateImageFromDmaBufs2(__DRIscreen *psDRIScreen,
+                              int iWidth, int iHeight,
+                              int iFourCC, uint64_t uModifier,
+                              int *piFDs, int iNumFDs,
+                              int *piStrides, int *piOffsets,
+                              enum __DRIYUVColorSpace eColorSpace,
+                              enum __DRISampleRange eSampleRange,
+                              enum __DRIChromaSiting eHorizSiting,
+                              enum __DRIChromaSiting eVertSiting,
+                              unsigned int *puError, void *pvLoaderPrivate)
+{
+   PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate;
+
+   return DRISUPCreateImageFromDMABufs2(psPVRScreen->psDRISUPScreen,
+                                        iWidth, iHeight, iFourCC, uModifier,
+                                        piFDs, iNumFDs, piStrides, piOffsets,
+                                        (unsigned int) eColorSpace,
+                                        (unsigned int) eSampleRange,
+                                        (unsigned int) eHorizSiting,
+                                        (unsigned int) eVertSiting,
+                                        puError, pvLoaderPrivate);
+}
+
+static GLboolean
+PVRDRIQueryDmaBufFormats(__DRIscreen *psDRIScreen, int iMax,
+                         int *piFormats, int *piCount)
+{
+   PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate;
+
+   return DRISUPQueryDMABufFormats(psPVRScreen->psDRISUPScreen, iMax,
+                                   piFormats, piCount);
+}
+
+static GLboolean
+PVRDRIQueryDmaBufModifiers(__DRIscreen *psDRIScreen, int iFourCC, int iMax,
+                           uint64_t *puModifiers,
+                           unsigned int *puExternalOnly, int *piCount)
+{
+   PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate;
+
+   return DRISUPQueryDMABufModifiers(psPVRScreen->psDRISUPScreen, iFourCC,
+                                     iMax,
+                                     puModifiers, puExternalOnly, piCount);
+}
+
+static GLboolean
+PVRDRIQueryDmaBufFormatModifierAttribs(__DRIscreen *psDRIScreen,
+                                       uint32_t uFourCC, uint64_t uModifier,
+                                       int iAttrib, uint64_t *puValue)
+{
+   PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate;
+   struct DRISUPScreen *psDRISUPScreen = psPVRScreen->psDRISUPScreen;
+
+   return DRISUPQueryDMABufFormatModifierAttribs(psDRISUPScreen, uFourCC,
+                                                 uModifier, iAttrib, puValue);
+}
+
+static __DRIimage *
+PVRDRICreateImageFromRenderbuffer2(__DRIcontext *psDRIContext,
+                                   int iRenderBuffer, void *pvLoaderPrivate,
+                                   unsigned int *puError)
+{
+   PVRDRIContext *psPVRContext = psDRIContext->driverPrivate;
+   struct DRISUPContext *psDRISUPContext = psPVRContext->psDRISUPContext;
+
+   return DRISUPCreateImageFromRenderBuffer2(psDRISUPContext, iRenderBuffer,
+                                             pvLoaderPrivate, puError);
+}
+
+#if defined(EGL_IMG_cl_image)
+static __DRIimage *
+PVRDRICreateImageFromBuffer(__DRIcontext *psDRIContext, int iTarget,
+                            void *pvBuffer, unsigned int *puError,
+                            void *pvLoaderPrivate)
+{
+   PVRDRIContext *psPVRContext = psDRIContext->driverPrivate;
+
+   return DRISUPCreateImageFromBuffer(psPVRContext->psDRISUPContext, iTarget,
+                                      pvBuffer, puError, pvLoaderPrivate);
+}
+#endif
+
+static __DRIimageExtension pvrDRIImage = {
+   .base = {
+      .name = __DRI_IMAGE,
+      .version = PVR_DRI_IMAGE_VERSION,
+   },
+   .createImageFromName = PVRDRICreateImageFromName,
+   .createImageFromRenderbuffer = PVRDRICreateImageFromRenderbuffer,
+   .destroyImage = PVRDRIDestroyImage,
+   .createImage = PVRDRICreateImage,
+   .queryImage = PVRDRIQueryImage,
+   .dupImage = PVRDRIDupImage,
+   .validateUsage = PVRDRIValidateImageUsage,
+   .createImageFromNames = PVRDRICreateImageFromNames,
+   .fromPlanar = PVRDRIFromPlanar,
+   .createImageFromTexture = PVRDRICreateImageFromTexture,
+   .createImageFromFds = PVRDRICreateImageFromFds,
+   .createImageFromDmaBufs = PVRDRICreateImageFromDmaBufs,
+   .blitImage = PVRDRIBlitImage,
+   .getCapabilities = PVRDRIGetCapabilities,
+   .mapImage = PVRDRIMapImage,
+   .unmapImage = PVRDRIUnmapImage,
+   .createImageWithModifiers = PVRDRICreateImageWithModifiers,
+   .createImageFromDmaBufs2 = PVRDRICreateImageFromDmaBufs2,
+   .queryDmaBufFormats = PVRDRIQueryDmaBufFormats,
+   .queryDmaBufModifiers = PVRDRIQueryDmaBufModifiers,
+   .queryDmaBufFormatModifierAttribs =
+   PVRDRIQueryDmaBufFormatModifierAttribs,
+   .createImageFromRenderbuffer2 = PVRDRICreateImageFromRenderbuffer2,
+#if defined(EGL_IMG_cl_image)
+   .createImageFromBuffer = PVRDRICreateImageFromBuffer,
+#endif
+};
+
+static __DRIrobustnessExtension pvrDRIRobustness = {
+   .base = {
+      .name = __DRI2_ROBUSTNESS,
+      .version = PVR_DRI2_ROBUSTNESS_VERSION,
+   }
+};
+
+static int
+PVRDRIQueryRendererInteger(__DRIscreen *psDRIScreen, int iAttribute,
+                           unsigned int *puValue)
+{
+   PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate;
+   int res;
+
+   res = DRISUPQueryRendererInteger(psPVRScreen->psDRISUPScreen,
+                                    iAttribute, puValue);
+   if (res == -1)
+      return driQueryRendererIntegerCommon(psDRIScreen, iAttribute, puValue);
+
+   return res;
+}
+
+static int
+PVRDRIQueryRendererString(__DRIscreen *psDRIScreen, int iAttribute,
+                          const char **ppszValue)
+{
+   PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate;
+
+   return DRISUPQueryRendererString(psPVRScreen->psDRISUPScreen, iAttribute,
+                                    ppszValue);
+}
+
+static const __DRI2rendererQueryExtension pvrDRIRendererQueryExtension = {
+   .base = {
+      .name = __DRI2_RENDERER_QUERY,
+      .version = PVR_DRI2_RENDERER_QUERY_VERSION,
+   },
+   .queryInteger = PVRDRIQueryRendererInteger,
+   .queryString = PVRDRIQueryRendererString,
+};
+
+
+static void *
+PVRDRICreateFenceEXT(__DRIcontext *psDRIContext)
+{
+   PVRDRIContext *psPVRContext = psDRIContext->driverPrivate;
+
+   return DRISUPCreateFence(psPVRContext->psDRISUPContext);
+}
+
+static void
+PVRDRIDestroyFenceEXT(__DRIscreen *psDRIScreen, void *pvFence)
+{
+   PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate;
+
+   return DRISUPDestroyFence(psPVRScreen->psDRISUPScreen, pvFence);
+}
+
+static GLboolean
+PVRDRIClientWaitSyncEXT(__DRIcontext *psDRIContext, void *pvFence,
+                        unsigned int uFlags, uint64_t uTimeout)
+{
+   struct DRISUPContext *psDRISUPContext;
+
+   if (psDRIContext) {
+      PVRDRIContext *psPVRContext = psDRIContext->driverPrivate;
+
+      psDRISUPContext = psPVRContext->psDRISUPContext;
+   } else {
+      psDRISUPContext = NULL;
+   }
+
+   return DRISUPClientWaitSync(psDRISUPContext, pvFence, uFlags, uTimeout);
+}
+
+static void
+PVRDRIServerWaitSyncEXT(__DRIcontext *psDRIContext, void *pvFence,
+                        unsigned int uFlags)
+{
+   PVRDRIContext *psPVRContext = psDRIContext->driverPrivate;
+
+   return DRISUPServerWaitSync(psPVRContext->psDRISUPContext, pvFence, uFlags);
+}
+
+static unsigned int
+PVRDRIGetFenceCapabilitiesEXT(__DRIscreen *psDRIScreen)
+{
+   PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate;
+
+   return DRISUPGetFenceCapabilities(psPVRScreen->psDRISUPScreen);
+}
+
+static void *
+PVRDRICreateFenceFdEXT(__DRIcontext *psDRIContext, int iFD)
+{
+   PVRDRIContext *psPVRContext = psDRIContext->driverPrivate;
+
+   return DRISUPCreateFenceFD(psPVRContext->psDRISUPContext, iFD);
+}
+
+static int
+PVRDRIGetFenceFdEXT(__DRIscreen *psDRIScreen, void *pvFence)
+{
+   PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate;
+
+   return DRISUPGetFenceFD(psPVRScreen->psDRISUPScreen, pvFence);
+}
+
+static void *
+PVRDRIGetFenceFromClEventEXT(__DRIscreen *psDRIScreen, intptr_t iClEvent)
+{
+   PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate;
+
+   return DRISUPGetFenceFromCLEvent(psPVRScreen->psDRISUPScreen, iClEvent);
+}
+
+__DRI2fenceExtension pvrDRIFenceExtension = {
+   .base = {
+      .name = __DRI2_FENCE,
+      .version = PVR_DRI2_FENCE_VERSION,
+   },
+   .create_fence = PVRDRICreateFenceEXT,
+   .get_fence_from_cl_event = PVRDRIGetFenceFromClEventEXT,
+   .destroy_fence = PVRDRIDestroyFenceEXT,
+   .client_wait_sync = PVRDRIClientWaitSyncEXT,
+   .server_wait_sync = PVRDRIServerWaitSyncEXT,
+   .get_capabilities = PVRDRIGetFenceCapabilitiesEXT,
+   .create_fence_fd = PVRDRICreateFenceFdEXT,
+   .get_fence_fd = PVRDRIGetFenceFdEXT,
+};
+
+static void
+PVRDRISetDamageRegion(__DRIdrawable *psDRIDrawable,
+                      unsigned int uNRects, int *piRects)
+{
+   PVRDRIDrawable *psPVRDrawable = psDRIDrawable->driverPrivate;
+
+   DRISUPSetDamageRegion(psPVRDrawable->psDRISUPDrawable, uNRects, piRects);
+}
+
+const __DRI2bufferDamageExtension pvrDRIbufferDamageExtension = {
+   .base = {
+      .name = __DRI2_BUFFER_DAMAGE,
+      .version = PVR_DRI2_BUFFER_DAMAGE_VERSION,
+   },
+   .set_damage_region = PVRDRISetDamageRegion,
+};
+
+/*
+ * Extension lists
+ *
+ * NOTE: When adding a new screen extension asScreenExtensionVersionInfo
+ *       should also be updated accordingly.
+ */
+static const __DRIextension *apsScreenExtensions[] = {
+   &pvrDRITexBufferExtension.base,
+   &pvrDRI2FlushExtension.base,
+   &pvrDRIImage.base,
+   &pvrDRIRobustness.base,
+   &pvrDRIRendererQueryExtension.base,
+   &pvrDRIFenceExtension.base,
+   &pvrDRIbufferDamageExtension.base,
+   &dri2ConfigQueryExtension.base,
+   NULL
+};
+
+static const __DRIextension asScreenExtensionVersionInfo[] = {
+   {.name = __DRI_TEX_BUFFER,.version = __DRI_TEX_BUFFER_VERSION},
+   {.name = __DRI2_FLUSH,.version = __DRI2_FLUSH_VERSION},
+   {.name = __DRI_IMAGE,.version = __DRI_IMAGE_VERSION},
+   {.name = __DRI2_ROBUSTNESS,.version = __DRI2_ROBUSTNESS_VERSION},
+   {.name = __DRI2_RENDERER_QUERY,.version = __DRI2_RENDERER_QUERY_VERSION},
+   {.name = __DRI2_FENCE,.version = __DRI2_FENCE_VERSION},
+   {.name = __DRI2_BUFFER_DAMAGE,.version = __DRI2_BUFFER_DAMAGE_VERSION},
+   {.name = __DRI2_CONFIG_QUERY,.version = __DRI2_CONFIG_QUERY_VERSION},
+   {.name = NULL,.version = 0},
+};
+
+const __DRIextension **
+PVRDRIScreenExtensions(void)
+{
+   return apsScreenExtensions;
+}
+
+const __DRIextension *
+PVRDRIScreenExtensionVersionInfo(void)
+{
+   return asScreenExtensionVersionInfo;
+}
+
+void
+PVRDRIAdjustExtensions(unsigned int uVersion, unsigned int uMinVersion)
+{
+   switch (uVersion) {
+   default:
+   case 4:
+      /* Is the KHR_cl_event2 EGL extension supported? */
+      if (!DRISUPHaveGetFenceFromCLEvent())
+         pvrDRIFenceExtension.get_fence_from_cl_event = NULL;
+
+      break;
+   case 3:
+      break;
+   case 2:
+   case 1:
+   case 0:
+      /* The KHR_cl_event2 EGL extension is not supported */
+      pvrDRIFenceExtension.get_fence_from_cl_event = NULL;
+      break;
+   }
+}
diff --git a/src/mesa/drivers/dri/pvr/pvrmesa.h b/src/mesa/drivers/dri/pvr/pvrmesa.h
new file mode 100644
index 0000000..5e1c9c1
--- /dev/null
+++ b/src/mesa/drivers/dri/pvr/pvrmesa.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) Imagination Technologies Ltd.
+ *
+ * The contents of this file are subject to the MIT license as set out below.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#if !defined(__PVRMESA_H__)
+#define __PVRMESA_H__
+
+#include "pvrdri.h"
+
+void pvrdri_free_dispatch_tables(PVRDRIScreen *psPVRScreen);
+bool pvrdri_create_dispatch_table(PVRDRIScreen *psPVRScreen,
+                                  PVRDRIAPIType eAPI);
+void pvrdri_set_null_dispatch_table(void);
+void pvrdri_set_dispatch_table(PVRDRIContext *psPVRContext);
+
+#endif /* !defined(__PVRMESA_H__) */
diff --git a/src/mesa/drivers/dri/pvr/pvrutil.c b/src/mesa/drivers/dri/pvr/pvrutil.c
new file mode 100644
index 0000000..945e18c
--- /dev/null
+++ b/src/mesa/drivers/dri/pvr/pvrutil.c
@@ -0,0 +1,239 @@
+/*
+ * Copyright (c) Imagination Technologies Ltd.
+ *
+ * The contents of this file are subject to the MIT license as set out below.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include "drm-uapi/drm_fourcc.h"
+
+#include "utils.h"
+#include "dri_util.h"
+#include "pvrdri.h"
+
+#define MESSAGE_LENGTH_MAX 1024
+
+/*
+ * Define before including android/log.h and dlog.h as this is used by these
+ * headers.
+ */
+#define LOG_TAG "PVR-MESA"
+
+#if defined(HAVE_ANDROID_PLATFORM)
+#include <android/log.h>
+#define err_printf(f, args...) ((void)__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, f, ##args))
+#define dbg_printf(f, args...) ((void)__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, f, ##args))
+#elif defined(HAVE_TIZEN_PLATFORM)
+#include <dlog.h>
+#define err_printf(f, args...) LOGE(f, ##args)
+#define dbg_printf(f, args...) LOGD(f, ##args)
+#else
+#define err_printf(f, args...) fprintf(stderr, f "\n", ##args)
+#define dbg_printf(f, args...) fprintf(stderr, "LibGL: " f "\n", ##args)
+#endif /* HAVE_ANDROID_PLATFORM */
+
+/* Standard error message */
+void PRINTFLIKE(1, 2)
+errorMessage(const char *f, ...)
+{
+   char message[MESSAGE_LENGTH_MAX];
+   va_list args;
+
+   va_start(args, f);
+   vsnprintf(message, sizeof message, f, args);
+   va_end(args);
+
+   err_printf("%s", message);
+}
+
+void PRINTFLIKE(1, 2)
+__driUtilMessage(const char *f, ...)
+{
+   char message[MESSAGE_LENGTH_MAX];
+   va_list args;
+
+   /*
+    * On Android and Tizen, always print messages; otherwise, only print if
+    * the environment variable LIBGL_DEBUG=verbose.
+    */
+#if !defined(HAVE_ANDROID_PLATFORM) && !defined(HAVE_TIZEN_PLATFORM)
+   char *ev = getenv("LIBGL_DEBUG");
+
+   if (!ev || strcmp(ev, "verbose") != 0)
+      return;
+#endif
+
+   va_start(args, f);
+   vsnprintf(message, sizeof message, f, args);
+   va_end(args);
+
+   dbg_printf("%s", message);
+}
+
+mesa_format
+PVRDRIMesaFormatToMesaFormat(int pvrdri_mesa_format)
+{
+   switch (pvrdri_mesa_format) {
+   case PVRDRI_MESA_FORMAT_NONE:
+      return MESA_FORMAT_NONE;
+   case PVRDRI_MESA_FORMAT_B8G8R8A8_UNORM:
+      return MESA_FORMAT_B8G8R8A8_UNORM;
+   case PVRDRI_MESA_FORMAT_B8G8R8X8_UNORM:
+      return MESA_FORMAT_B8G8R8X8_UNORM;
+   case PVRDRI_MESA_FORMAT_B5G6R5_UNORM:
+      return MESA_FORMAT_B5G6R5_UNORM;
+   case PVRDRI_MESA_FORMAT_R8G8B8A8_UNORM:
+      return MESA_FORMAT_R8G8B8A8_UNORM;
+   case PVRDRI_MESA_FORMAT_R8G8B8X8_UNORM:
+      return MESA_FORMAT_R8G8B8X8_UNORM;
+   case PVRDRI_MESA_FORMAT_YCBCR:
+      return MESA_FORMAT_YCBCR;
+   case PVRDRI_MESA_FORMAT_YUV420_2PLANE:
+      return MESA_FORMAT_YUV420_2PLANE;
+   case PVRDRI_MESA_FORMAT_YVU420_2PLANE:
+      return MESA_FORMAT_YVU420_2PLANE;
+   case PVRDRI_MESA_FORMAT_B8G8R8A8_SRGB:
+      return MESA_FORMAT_B8G8R8A8_SRGB;
+   case PVRDRI_MESA_FORMAT_R8G8B8A8_SRGB:
+      return MESA_FORMAT_R8G8B8A8_SRGB;
+   default:
+      __driUtilMessage("%s: Unknown format: %d", __func__, pvrdri_mesa_format);
+      break;
+   }
+
+   return MESA_FORMAT_NONE;
+}
+
+int
+PVRDRIFormatToFourCC(int dri_format)
+{
+   switch (dri_format) {
+   case __DRI_IMAGE_FORMAT_RGB565:
+      return DRM_FORMAT_RGB565;
+   case __DRI_IMAGE_FORMAT_XRGB8888:
+      return DRM_FORMAT_XRGB8888;
+   case __DRI_IMAGE_FORMAT_ARGB8888:
+      return DRM_FORMAT_ARGB8888;
+   case __DRI_IMAGE_FORMAT_ABGR8888:
+      return DRM_FORMAT_ABGR8888;
+   case __DRI_IMAGE_FORMAT_XBGR8888:
+      return DRM_FORMAT_XBGR8888;
+   case __DRI_IMAGE_FORMAT_R8:
+      return DRM_FORMAT_R8;
+   case __DRI_IMAGE_FORMAT_GR88:
+      return DRM_FORMAT_GR88;
+   case __DRI_IMAGE_FORMAT_NONE:
+      return 0;
+   case __DRI_IMAGE_FORMAT_XRGB2101010:
+      return DRM_FORMAT_XRGB2101010;
+   case __DRI_IMAGE_FORMAT_ARGB2101010:
+      return DRM_FORMAT_ARGB2101010;
+   case __DRI_IMAGE_FORMAT_SARGB8:
+      return __DRI_IMAGE_FOURCC_SARGB8888;
+   case __DRI_IMAGE_FORMAT_ARGB1555:
+      return DRM_FORMAT_ARGB1555;
+   case __DRI_IMAGE_FORMAT_R16:
+      return DRM_FORMAT_R16;
+   case __DRI_IMAGE_FORMAT_GR1616:
+      return DRM_FORMAT_GR1616;
+   case __DRI_IMAGE_FORMAT_YUYV:
+      return DRM_FORMAT_YUYV;
+   case __DRI_IMAGE_FORMAT_XBGR2101010:
+      return DRM_FORMAT_XBGR2101010;
+   case __DRI_IMAGE_FORMAT_ABGR2101010:
+      return DRM_FORMAT_ABGR2101010;
+   case __DRI_IMAGE_FORMAT_SABGR8:
+      return __DRI_IMAGE_FOURCC_SABGR8888;
+   case __DRI_IMAGE_FORMAT_UYVY:
+      return DRM_FORMAT_UYVY;
+   case __DRI_IMAGE_FORMAT_ARGB4444:
+      return DRM_FORMAT_ARGB4444;
+   case __DRI_IMAGE_FORMAT_YVU444_PACK10_IMG:
+      return DRM_FORMAT_YVU444_PACK10_IMG;
+   case __DRI_IMAGE_FORMAT_BGR888:
+      return DRM_FORMAT_BGR888;
+   default:
+      __driUtilMessage("%s: Unknown format: %d", __func__, dri_format);
+      break;
+   }
+
+   return 0;
+}
+
+int
+PVRDRIFourCCToDRIFormat(int iFourCC)
+{
+   switch (iFourCC) {
+   case 0:
+      return __DRI_IMAGE_FORMAT_NONE;
+   case DRM_FORMAT_RGB565:
+      return __DRI_IMAGE_FORMAT_RGB565;
+   case DRM_FORMAT_XRGB8888:
+      return __DRI_IMAGE_FORMAT_XRGB8888;
+   case DRM_FORMAT_ARGB8888:
+      return __DRI_IMAGE_FORMAT_ARGB8888;
+   case DRM_FORMAT_ABGR8888:
+      return __DRI_IMAGE_FORMAT_ABGR8888;
+   case DRM_FORMAT_XBGR8888:
+      return __DRI_IMAGE_FORMAT_XBGR8888;
+   case DRM_FORMAT_R8:
+      return __DRI_IMAGE_FORMAT_R8;
+   case DRM_FORMAT_GR88:
+      return __DRI_IMAGE_FORMAT_GR88;
+   case DRM_FORMAT_XRGB2101010:
+      return __DRI_IMAGE_FORMAT_XRGB2101010;
+   case DRM_FORMAT_ARGB2101010:
+      return __DRI_IMAGE_FORMAT_ARGB2101010;
+   case __DRI_IMAGE_FOURCC_SARGB8888:
+      return __DRI_IMAGE_FORMAT_SARGB8;
+   case DRM_FORMAT_ARGB1555:
+      return __DRI_IMAGE_FORMAT_ARGB1555;
+   case DRM_FORMAT_R16:
+      return __DRI_IMAGE_FORMAT_R16;
+   case DRM_FORMAT_GR1616:
+      return __DRI_IMAGE_FORMAT_GR1616;
+   case DRM_FORMAT_YUYV:
+      return __DRI_IMAGE_FORMAT_YUYV;
+   case DRM_FORMAT_XBGR2101010:
+      return __DRI_IMAGE_FORMAT_XBGR2101010;
+   case DRM_FORMAT_ABGR2101010:
+      return __DRI_IMAGE_FORMAT_ABGR2101010;
+   case __DRI_IMAGE_FOURCC_SABGR8888:
+      return __DRI_IMAGE_FORMAT_SABGR8;
+   case DRM_FORMAT_UYVY:
+      return __DRI_IMAGE_FORMAT_UYVY;
+   case DRM_FORMAT_ARGB4444:
+      return __DRI_IMAGE_FORMAT_ARGB4444;
+   case DRM_FORMAT_YVU444_PACK10_IMG:
+      return __DRI_IMAGE_FORMAT_YVU444_PACK10_IMG;
+   case DRM_FORMAT_BGR888:
+      return __DRI_IMAGE_FORMAT_BGR888;
+   default:
+      __driUtilMessage("%s: Unknown format: %d", __func__, iFourCC);
+      break;
+   }
+
+   return 0;
+}
diff --git a/src/meson.build b/src/meson.build
index acc7fe9..c3bab27 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -25,6 +25,7 @@ inc_gallium = include_directories('gallium/include')
 inc_gallium_aux = include_directories('gallium/auxiliary')
 inc_amd_common = include_directories('amd/common')
 inc_amd_common_llvm = include_directories('amd/llvm')
+inc_pvr = include_directories('mesa/main', 'mapi/glapi')
 inc_tool = include_directories('tool')
 pps_datasources = []
 pps_includes = []
