blob: 92f23c89355184f588a20bc0b2c3fb2d19595271 [file] [log] [blame]
From e85a3db324dd8be32bb5d9028e2f90b0a1aab21d Mon Sep 17 00:00:00 2001
From: Frank Binns <frank.binns@imgtec.com>
Date: Wed, 3 Jul 2019 10:48:29 +0100
Subject: [PATCH 01/11] dri/pvr: Introduce PowerVR DRI driver.
Change-Id: Ied94552937389a736124347d2f068b7066eff198
---
configure.ac | 7 +
meson.build | 19 +-
meson_options.txt | 4 +-
src/mesa/drivers/dri/Makefile.am | 6 +
src/mesa/drivers/dri/meson.build | 3 +
src/mesa/drivers/dri/pvr/Makefile.am | 44 +
src/mesa/drivers/dri/pvr/Makefile.sources | 36 +
src/mesa/drivers/dri/pvr/dri_support.h | 969 ++++++++++++++
src/mesa/drivers/dri/pvr/img_drm_fourcc.h | 110 ++
src/mesa/drivers/dri/pvr/imgpixfmts.h | 80 ++
src/mesa/drivers/dri/pvr/imgyuv.h | 58 +
src/mesa/drivers/dri/pvr/mesa_context.c | 258 ++++
src/mesa/drivers/dri/pvr/meson.build | 48 +
src/mesa/drivers/dri/pvr/pvrcompat.c | 1383 ++++++++++++++++++++
src/mesa/drivers/dri/pvr/pvrdrawable.c | 542 ++++++++
src/mesa/drivers/dri/pvr/pvrdri.c | 1018 +++++++++++++++
src/mesa/drivers/dri/pvr/pvrdri.h | 388 ++++++
src/mesa/drivers/dri/pvr/pvrext.c | 440 +++++++
src/mesa/drivers/dri/pvr/pvrimage.c | 1420 +++++++++++++++++++++
src/mesa/drivers/dri/pvr/pvrimage.h | 131 ++
src/mesa/drivers/dri/pvr/pvrmesa.h | 41 +
src/mesa/drivers/dri/pvr/pvrutil.c | 1067 ++++++++++++++++
src/meson.build | 1 +
23 files changed, 8064 insertions(+), 9 deletions(-)
create mode 100644 src/mesa/drivers/dri/pvr/Makefile.am
create mode 100644 src/mesa/drivers/dri/pvr/Makefile.sources
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/pvrcompat.c
create mode 100644 src/mesa/drivers/dri/pvr/pvrdrawable.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/pvrext.c
create mode 100644 src/mesa/drivers/dri/pvr/pvrimage.c
create mode 100644 src/mesa/drivers/dri/pvr/pvrimage.h
create mode 100644 src/mesa/drivers/dri/pvr/pvrmesa.h
create mode 100644 src/mesa/drivers/dri/pvr/pvrutil.c
diff --git a/configure.ac b/configure.ac
index d169223094f..4d9053bddfa 100644
--- a/configure.ac
+++ b/configure.ac
@@ -89,6 +89,7 @@ LIBDRM_REQUIRED=2.4.75
LIBDRM_RADEON_REQUIRED=2.4.71
LIBDRM_AMDGPU_REQUIRED=2.4.97
LIBDRM_INTEL_REQUIRED=2.4.75
+LIBDRM_PVR_REQUIRED=2.4.60
LIBDRM_NVVIEUX_REQUIRED=2.4.66
LIBDRM_NOUVEAU_REQUIRED=2.4.66
LIBDRM_ETNAVIV_REQUIRED=2.4.89
@@ -2081,6 +2082,10 @@ if test -n "$with_dri_drivers"; then
HAVE_R200_DRI=yes
PKG_CHECK_MODULES([RADEON], [libdrm >= $LIBDRM_RADEON_REQUIRED libdrm_radeon >= $LIBDRM_RADEON_REQUIRED])
;;
+ xpvr)
+ HAVE_PVR_DRI=yes;
+ PKG_CHECK_MODULES([PVR], [libdrm >= $LIBDRM_PVR_REQUIRED])
+ ;;
xswrast)
HAVE_SWRAST_DRI=yes
;;
@@ -2993,6 +2998,7 @@ AM_CONDITIONAL(HAVE_I965_DRI, test x$HAVE_I965_DRI = xyes)
AM_CONDITIONAL(HAVE_NOUVEAU_DRI, test x$HAVE_NOUVEAU_DRI = xyes)
AM_CONDITIONAL(HAVE_R200_DRI, test x$HAVE_R200_DRI = xyes)
AM_CONDITIONAL(HAVE_RADEON_DRI, test x$HAVE_RADEON_DRI = xyes)
+AM_CONDITIONAL(HAVE_PVR_DRI, test x$HAVE_PVR_DRI = xyes)
AM_CONDITIONAL(HAVE_SWRAST_DRI, test x$HAVE_SWRAST_DRI = xyes)
AM_CONDITIONAL(HAVE_RADEON_VULKAN, test "x$HAVE_RADEON_VULKAN" = xyes)
@@ -3192,6 +3198,7 @@ AC_CONFIG_FILES([Makefile
src/mesa/drivers/dri/nouveau/Makefile
src/mesa/drivers/dri/r200/Makefile
src/mesa/drivers/dri/radeon/Makefile
+ src/mesa/drivers/dri/pvr/Makefile
src/mesa/drivers/dri/swrast/Makefile
src/mesa/drivers/osmesa/Makefile
src/mesa/drivers/osmesa/osmesa.pc
diff --git a/meson.build b/meson.build
index bfff862c3c8..648233f15ce 100644
--- a/meson.build
+++ b/meson.build
@@ -96,9 +96,9 @@ if _drivers.contains('auto')
if system_has_kms_drm
# TODO: PPC, Sparc
if ['x86', 'x86_64'].contains(host_machine.cpu_family())
- _drivers = ['i915', 'i965', 'r100', 'r200', 'nouveau']
+ _drivers = ['i915', 'i965', 'r100', 'r200', 'nouveau', 'pvr']
elif ['arm', 'aarch64'].contains(host_machine.cpu_family())
- _drivers = []
+ _drivers = ['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()))
@@ -118,6 +118,7 @@ with_dri_r100 = _drivers.contains('r100')
with_dri_r200 = _drivers.contains('r200')
with_dri_nouveau = _drivers.contains('nouveau')
with_dri_swrast = _drivers.contains('swrast')
+with_dri_pvr = _drivers.contains('pvr')
with_dri = _drivers.length() != 0 and _drivers != ['']
@@ -1118,15 +1119,17 @@ _drm_radeon_ver = '2.4.71'
_drm_nouveau_ver = '2.4.66'
_drm_etnaviv_ver = '2.4.89'
_drm_intel_ver = '2.4.75'
+_drm_pvr_ver = '2.4.60'
_drm_ver = '2.4.75'
_libdrm_checks = [
- ['intel', with_dri_i915 or with_gallium_i915],
- ['amdgpu', with_amd_vk or with_gallium_radeonsi],
+ ['intel', with_dri_i915 or with_gallium_i915, true],
+ ['amdgpu', with_amd_vk 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)],
- ['etnaviv', with_gallium_etnaviv],
+ with_gallium_r300 or with_gallium_r600), true],
+ ['nouveau', (with_gallium_nouveau or with_dri_nouveau), true],
+ ['etnaviv', with_gallium_etnaviv, true],
+ ['pvr', with_dri_pvr, false],
]
# VC4 only needs core libdrm support of this version, not a libdrm_vc4
@@ -1151,7 +1154,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 ccf70659ff7..0a2e80294f2 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -38,7 +38,9 @@ option(
'dri-drivers',
type : 'array',
value : ['auto'],
- choices : ['', 'auto', 'i915', 'i965', 'r100', 'r200', 'nouveau', 'swrast'],
+ choices : [
+ '', 'auto', 'i915', 'i965', 'r100', 'r200', 'nouveau', 'swrast', '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/Makefile.am b/src/mesa/drivers/dri/Makefile.am
index 3876d7c4192..15b0d5391d2 100644
--- a/src/mesa/drivers/dri/Makefile.am
+++ b/src/mesa/drivers/dri/Makefile.am
@@ -36,6 +36,12 @@ MEGADRIVERS_DEPS += radeon/libradeon_dri.la
MEGADRIVERS += radeon_dri.so
endif
+if HAVE_PVR_DRI
+SUBDIRS += pvr
+MEGADRIVERS_DEPS += pvr/libpvr_dri.la
+MEGADRIVERS += pvr_dri.so
+endif
+
if HAVE_SWRAST_DRI
SUBDIRS += swrast
MEGADRIVERS_DEPS += swrast/libswrast_dri.la
diff --git a/src/mesa/drivers/dri/meson.build b/src/mesa/drivers/dri/meson.build
index d98c823f5fe..27213f7f660 100644
--- a/src/mesa/drivers/dri/meson.build
+++ b/src/mesa/drivers/dri/meson.build
@@ -40,6 +40,9 @@ endif
if with_dri_nouveau
subdir('nouveau')
endif
+if with_dri_pvr
+ subdir('pvr')
+endif
if dri_drivers != []
libmesa_dri_drivers = shared_library(
diff --git a/src/mesa/drivers/dri/pvr/Makefile.am b/src/mesa/drivers/dri/pvr/Makefile.am
new file mode 100644
index 00000000000..681c13e6102
--- /dev/null
+++ b/src/mesa/drivers/dri/pvr/Makefile.am
@@ -0,0 +1,44 @@
+#
+# 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 Makefile.sources
+
+AM_CFLAGS = \
+ -I$(top_srcdir)/include \
+ -I$(top_srcdir)/src \
+ -I$(top_srcdir)/src/mapi \
+ -I$(top_srcdir)/src/mapi/glapi \
+ -I$(top_srcdir)/src/mesa \
+ -I$(top_srcdir)/src/mesa/main \
+ -I$(top_srcdir)/src/mesa/drivers/dri/common \
+ -I$(top_builddir)/src/mesa/main \
+ $(DEFINES) \
+ $(VISIBILITY_CFLAGS) \
+ $(PVR_CFLAGS)
+
+AM_CXXFLAGS = $(AM_CFLAGS)
+
+noinst_LTLIBRARIES = libpvr_dri.la
+libpvr_dri_la_SOURCES = $(pvr_FILES)
+libpvr_dri_la_LIBADD = $(PVR_LIBS)
diff --git a/src/mesa/drivers/dri/pvr/Makefile.sources b/src/mesa/drivers/dri/pvr/Makefile.sources
new file mode 100644
index 00000000000..6e0c8eb39f9
--- /dev/null
+++ b/src/mesa/drivers/dri/pvr/Makefile.sources
@@ -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.
+#
+
+pvr_INCLUDES = \
+ $(MESA_TOP)/src \
+ $(MESA_TOP)/src/mesa/drivers/dri/pvr
+
+pvr_FILES = \
+ mesa_context.c \
+ pvrcompat.c \
+ pvrdrawable.c \
+ pvrdri.c \
+ pvrext.c \
+ pvrimage.c \
+ pvrutil.c
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 00000000000..fc5a8c47410
--- /dev/null
+++ b/src/mesa/drivers/dri/pvr/dri_support.h
@@ -0,0 +1,969 @@
+/* -*- 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>
+
+#include "imgpixfmts.h"
+#include "imgyuv.h"
+
+typedef enum
+{
+ PVRDRI_DEVICE_TYPE_INVALID = 0,
+ PVRDRI_DEVICE_TYPE_UNKNOWN,
+ PVRDRI_DEVICE_TYPE_DISPLAY,
+ PVRDRI_DEVICE_TYPE_RENDER,
+} PVRDRIDeviceType;
+
+/* API type. */
+typedef enum
+{
+ PVRDRI_API_NONE = 0,
+ PVRDRI_API_GLES1 = 2,
+ PVRDRI_API_GLES2 = 3,
+ PVRDRI_API_CL = 4,
+} PVRDRIAPIType;
+
+/* API sub type. */
+typedef enum
+{
+ PVRDRI_API_SUB_NONE,
+} PVRDRIAPISubType;
+
+typedef enum
+{
+ PVRDRI_DRAWABLE_NONE = 0,
+ PVRDRI_DRAWABLE_WINDOW = 1,
+ PVRDRI_DRAWABLE_PIXMAP = 2,
+ PVRDRI_DRAWABLE_PBUFFER = 3,
+} PVRDRIDrawableType;
+
+typedef enum
+{
+ PVRDRI_IMAGE = 1,
+ PVRDRI_IMAGE_FROM_NAMES,
+ PVRDRI_IMAGE_FROM_EGLIMAGE,
+ PVRDRI_IMAGE_FROM_DMABUFS,
+ PVRDRI_IMAGE_SUBIMAGE,
+} PVRDRIImageType;
+
+typedef enum
+{
+ PVRDRI_EGLIMAGE_NONE = 0,
+ PVRDRI_EGLIMAGE_IMGEGL,
+ PVRDRI_EGLIMAGE_IMGOCL,
+} PVRDRIEGLImageType;
+
+typedef enum
+{
+ /* Since PVRDRICallbacks version 2 */
+ 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,
+} PVRDRIConfigAttrib;
+
+typedef enum
+{
+ /* Since PVRDRICallbacks version 2 */
+ PVRDRI_BUFFER_ATTRIB_INVALID = 0,
+ PVRDRI_BUFFER_ATTRIB_TYPE = 1,
+ PVRDRI_BUFFER_ATTRIB_WIDTH = 2,
+ PVRDRI_BUFFER_ATTRIB_HEIGHT = 3,
+ PVRDRI_BUFFER_ATTRIB_STRIDE = 4,
+ PVRDRI_BUFFER_ATTRIB_PIXEL_FORMAT = 5,
+} PVRDRIBufferAttrib;
+
+/* The context flags match their __DRI_CTX_FLAG and EGL_CONTEXT counterparts */
+#define PVRDRI_CONTEXT_FLAG_DEBUG 0x00000001
+#define PVRDRI_CONTEXT_FLAG_FORWARD_COMPATIBLE 0x00000002
+#define PVRDRI_CONTEXT_FLAG_ROBUST_BUFFER_ACCESS 0x00000004
+
+/* The context error codes match their __DRI_CTX_ERROR counterparts */
+#define PVRDRI_CONTEXT_ERROR_SUCCESS 0
+/* Out of memory */
+#define PVRDRI_CONTEXT_ERROR_NO_MEMORY 1
+/* Unsupported API */
+#define PVRDRI_CONTEXT_ERROR_BAD_API 2
+/* Unsupported version of API */
+#define PVRDRI_CONTEXT_ERROR_BAD_VERSION 3
+/* Unsupported context flag or combination of flags */
+#define PVRDRI_CONTEXT_ERROR_BAD_FLAG 4
+/* Unrecognised context attribute */
+#define PVRDRI_CONTEXT_ERROR_UNKNOWN_ATTRIBUTE 5
+/* Unrecognised context flag */
+#define PVRDRI_CONTEXT_ERROR_UNKNOWN_FLAG 6
+
+/*
+ * The context priority defines match their __DRI_CTX counterparts, and
+ * the context priority values used by the DDK.
+ */
+#define PVRDRI_CONTEXT_PRIORITY_LOW 0
+#define PVRDRI_CONTEXT_PRIORITY_MEDIUM 1
+#define PVRDRI_CONTEXT_PRIORITY_HIGH 2
+
+/* The image error flags match their __DRI_IMAGE_ERROR counterparts */
+#define PVRDRI_IMAGE_ERROR_SUCCESS 0
+#define PVRDRI_IMAGE_ERROR_BAD_ALLOC 1
+#define PVRDRI_IMAGE_ERROR_BAD_MATCH 2
+#define PVRDRI_IMAGE_ERROR_BAD_PARAMETER 3
+#define PVRDRI_IMAGE_ERROR_BAD_ACCESS 4
+
+/* The buffer flags match their __DRI_IMAGE_USE counterparts */
+#define PVDRI_BUFFER_USE_SHARE 0x0001
+#define PVDRI_BUFFER_USE_SCANOUT 0x0002
+#define PVDRI_BUFFER_USE_CURSOR 0x0004
+#define PVDRI_BUFFER_USE_LINEAR 0x0008
+
+/* EGL_RENDERABLE_TYPE mask bits */
+#define PVRDRI_API_BIT_GLES 0x0001
+#define PVRDRI_API_BIT_GLES2 0x0004
+#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
+
+/* The blit flags match their DRI counterparts */
+#define PVRDRI_BLIT_FLAG_FLUSH 0x0001
+#define PVRDRI_BLIT_FLAG_FINISH 0x0002
+
+/* The image mapping flags match their DRI counterparts */
+#define PVRDRI_IMAGE_TRANSFER_READ 0x1
+#define PVRDRI_IMAGE_TRANSFER_WRITE 0x2
+#define PVRDRI_IMAGE_TRANSFER_READ_WRITE \
+ (PVRDRI_IMAGE_TRANSFER_READ | PVRDRI_IMAGE_TRANSFER_WRITE)
+
+/* The YUV defines match their DRI counterparts */
+#define PVRDRI_YUV_ORDER_NONE 0x0
+#define PVRDRI_YUV_ORDER_YUV 0x1
+#define PVRDRI_YUV_ORDER_YVU 0x2
+#define PVRDRI_YUV_ORDER_YUYV 0x4
+#define PVRDRI_YUV_ORDER_UYVY 0x8
+#define PVRDRI_YUV_ORDER_YVYU 0x10
+#define PVRDRI_YUV_ORDER_VYUY 0x20
+#define PVRDRI_YUV_ORDER_AYUV 0x40
+
+#define PVRDRI_YUV_SUBSAMPLE_NONE 0x0
+#define PVRDRI_YUV_SUBSAMPLE_4_2_0 0x1
+#define PVRDRI_YUV_SUBSAMPLE_4_2_2 0x2
+#define PVRDRI_YUV_SUBSAMPLE_4_4_4 0x4
+
+#define PVRDRI_YUV_DEPTH_RANGE_NONE 0x0
+#define PVRDRI_YUV_DEPTH_RANGE_LIMITED 0x1
+#define PVRDRI_YUV_DEPTH_RANGE_FULL 0x2
+
+#define PVRDRI_YUV_CSC_STANDARD_NONE 0x0
+#define PVRDRI_YUV_CSC_STANDARD_601 0x1
+#define PVRDRI_YUV_CSC_STANDARD_709 0x2
+#define PVRDRI_YUV_CSC_STANDARD_2020 0x4
+
+#define PVRDRI_YUV_PLANE_BPP_NONE 0x0
+#define PVRDRI_YUV_PLANE_BPP_0 0x1
+#define PVRDRI_YUV_PLANE_BPP_8 0x2
+#define PVRDRI_YUV_PLANE_BPP_10 0x4
+
+/* Flags for PVRDRICallbacks.DrawableGetParametersV2 */
+/* Since callback interface version 2 */
+#define PVRDRI_GETPARAMS_FLAG_ALLOW_RECREATE 0x1
+/* Since callback interface version 3 */
+#define PVRDRI_GETPARAMS_FLAG_NO_UPDATE 0x2
+
+/*
+ * Capabilities that might be returned by PVRDRIInterface.GetFenceCapabilities.
+ * These match their _DRI_FENCE_CAP counterparts.
+ *
+ * Since PVRDRIInterface version 2.
+ */
+#define PVRDRI_FENCE_CAP_NATIVE_FD 0x1
+
+typedef struct
+{
+ IMG_PIXFMT ePixFormat;
+ uint32_t uiWidth;
+ uint32_t uiHeight;
+ uint32_t uiStrideInBytes;
+} PVRDRIBufferAttribs;
+
+typedef struct
+{
+ int sampleBuffers;
+ int samples;
+
+ int redBits;
+ int greenBits;
+ int blueBits;
+ int alphaBits;
+
+ int rgbBits;
+ int depthBits;
+ int stencilBits;
+
+ bool doubleBufferMode;
+
+ int bindToTextureRgb;
+ int bindToTextureRgba;
+} PVRDRIConfigInfo;
+
+typedef struct IMGEGLImageRec IMGEGLImage;
+typedef struct __DRIimageRec __DRIimage;
+
+/* PVRDRI interface opaque types */
+typedef struct PVRDRIScreenImplRec PVRDRIScreenImpl;
+typedef struct PVRDRIContextImplRec PVRDRIContextImpl;
+typedef struct PVRDRIDrawableImplRec PVRDRIDrawableImpl;
+typedef struct PVRDRIBufferImplRec PVRDRIBufferImpl;
+
+typedef struct PVRDRIDrawable_TAG PVRDRIDrawable;
+
+typedef void (*PVRDRIGLAPIProc)(void);
+
+/* Since PVRDRICallbacks version 2 */
+typedef struct PVRDRIConfigRec PVRDRIConfig;
+
+typedef struct {
+ /**********************************************************************
+ * Version 0 interface
+ **********************************************************************/
+
+ PVRDRIDeviceType (*GetDeviceTypeFromFd)(int iFd);
+
+ bool (*IsFirstScreen)(PVRDRIScreenImpl *psScreenImpl);
+
+ uint32_t (*PixFmtGetDepth)(IMG_PIXFMT eFmt);
+ uint32_t (*PixFmtGetBPP)(IMG_PIXFMT eFmt);
+ uint32_t (*PixFmtGetBlockSize)(IMG_PIXFMT eFmt);
+
+ /* ScreenImpl functions */
+ PVRDRIScreenImpl *(*CreateScreen)(int iFd);
+ void (*DestroyScreen)(PVRDRIScreenImpl *psScreenImpl);
+
+ int (*APIVersion)(PVRDRIAPIType eAPI,
+ PVRDRIAPISubType eAPISub,
+ PVRDRIScreenImpl *psScreenImpl);
+
+ void *(*EGLGetLibHandle)(PVRDRIAPIType eAPI,
+ PVRDRIScreenImpl *psScreenImpl);
+
+ PVRDRIGLAPIProc (*EGLGetProcAddress)(PVRDRIAPIType eAPI,
+ PVRDRIScreenImpl *psScreenImpl,
+ const char *psProcName);
+
+ bool (*EGLFlushBuffers)(PVRDRIAPIType eAPI,
+ PVRDRIScreenImpl *psScreenImpl,
+ PVRDRIContextImpl *psContextImpl,
+ PVRDRIDrawableImpl *psDrawableImpl,
+ bool bFlushAllSurfaces,
+ bool bSwapBuffers,
+ bool bWaitForHW);
+ /* EGLFreeResources is deprecated */
+ bool (*EGLFreeResources)(PVRDRIScreenImpl *psPVRScreenImpl);
+ void (*EGLMarkRendersurfaceInvalid)(PVRDRIAPIType eAPI,
+ PVRDRIScreenImpl *psScreenImpl,
+ PVRDRIContextImpl *psContextImpl);
+ /* EGLSetFrontBufferCallback is deprecated */
+ void (*EGLSetFrontBufferCallback)(PVRDRIAPIType eAPI,
+ PVRDRIScreenImpl *psScreenImpl,
+ PVRDRIDrawableImpl *psDrawableImpl,
+ void (*pfnCallback)(PVRDRIDrawable *));
+
+ /* Deprecated in version 1 (since 1.10) */
+ unsigned (*CreateContext)(PVRDRIContextImpl **ppsContextImpl,
+ PVRDRIAPIType eAPI,
+ PVRDRIAPISubType eAPISub,
+ PVRDRIScreenImpl *psScreenImpl,
+ const PVRDRIConfigInfo *psConfigInfo,
+ unsigned uMajorVersion,
+ unsigned uMinorVersion,
+ uint32_t uFlags,
+ bool bNotifyReset,
+ unsigned uPriority,
+ PVRDRIContextImpl *psSharedContextImpl);
+
+ void (*DestroyContext)(PVRDRIContextImpl *psContextImpl,
+ PVRDRIAPIType eAPI,
+ PVRDRIScreenImpl *psScreenImpl);
+
+ bool (*MakeCurrentGC)(PVRDRIAPIType eAPI,
+ PVRDRIScreenImpl *psScreenImpl,
+ PVRDRIContextImpl *psContextImpl,
+ PVRDRIDrawableImpl *psWriteImpl,
+ PVRDRIDrawableImpl *psReadImpl);
+
+ void (*MakeUnCurrentGC)(PVRDRIAPIType eAPI,
+ PVRDRIScreenImpl *psScreenImpl);
+
+ unsigned (*GetImageSource)(PVRDRIAPIType eAPI,
+ PVRDRIScreenImpl *psScreenImpl,
+ PVRDRIContextImpl *psContextImpl,
+ uint32_t uiTarget,
+ uintptr_t uiBuffer,
+ uint32_t uiLevel,
+ IMGEGLImage *psEGLImage);
+
+ bool (*BindTexImage)(PVRDRIAPIType eAPI,
+ PVRDRIScreenImpl *psScreenImpl,
+ PVRDRIContextImpl *psContextImpl,
+ PVRDRIDrawableImpl *psDrawableImpl);
+
+ void (*ReleaseTexImage)(PVRDRIAPIType eAPI,
+ PVRDRIScreenImpl *psScreenImpl,
+ PVRDRIContextImpl *psContextImpl,
+ PVRDRIDrawableImpl *psDrawableImpl);
+
+ /* Deprecated in version 1 (since 1.10) */
+ PVRDRIDrawableImpl *(*CreateDrawable)(PVRDRIDrawable *psPVRDrawable);
+
+ void (*DestroyDrawable)(PVRDRIDrawableImpl *psScreenImpl);
+ bool (*EGLDrawableCreate)(PVRDRIScreenImpl *psScreenImpl,
+ PVRDRIDrawableImpl *psDrawableImpl);
+ bool (*EGLDrawableRecreate)(PVRDRIScreenImpl *psScreenImpl,
+ PVRDRIDrawableImpl *psDrawableImpl);
+ bool (*EGLDrawableDestroy)(PVRDRIScreenImpl *psScreenImpl,
+ PVRDRIDrawableImpl *psDrawableImpl);
+ void (*EGLDrawableDestroyConfig)(PVRDRIDrawableImpl *psDrawableImpl);
+
+ /* Buffer functions */
+ PVRDRIBufferImpl *(*BufferCreate)(PVRDRIScreenImpl *psScreenImpl,
+ int iWidth,
+ int iHeight,
+ unsigned int uiBpp,
+ unsigned int uiUseFlags,
+ unsigned int *puiStride);
+
+ PVRDRIBufferImpl *(*BufferCreateWithModifiers)(PVRDRIScreenImpl *psScreenImpl,
+ int iWidth,
+ int iHeight,
+ int iFormat,
+ IMG_PIXFMT eIMGPixelFormat,
+ const uint64_t *puiModifiers,
+ unsigned int uiModifierCount,
+ unsigned int *puiStride);
+
+ PVRDRIBufferImpl *(*BufferCreateFromNames)(PVRDRIScreenImpl *psScreenImpl,
+ int iWidth,
+ int iHeight,
+ unsigned uiNumPlanes,
+ const int *piName,
+ const int *piStride,
+ const int *piOffset,
+ const unsigned int *puiWidthShift,
+ const unsigned int *puiHeightShift);
+
+ PVRDRIBufferImpl *(*BufferCreateFromName)(PVRDRIScreenImpl *psScreenImpl,
+ int iName,
+ int iWidth,
+ int iHeight,
+ int iStride,
+ int iOffset);
+
+ /* BufferCreateFromFds is deprecated */
+ PVRDRIBufferImpl *(*BufferCreateFromFds)(PVRDRIScreenImpl *psScreenImpl,
+ int iWidth,
+ int iHeight,
+ unsigned uiNumPlanes,
+ const int *piFd,
+ const int *piStride,
+ const int *piOffset,
+ const unsigned int *puiWidthShift,
+ const unsigned int *puiHeightShift);
+
+ PVRDRIBufferImpl *(*BufferCreateFromFdsWithModifier)(PVRDRIScreenImpl *psScreenImpl,
+ int iWidth,
+ int iHeight,
+ uint64_t uiModifier,
+ unsigned uiNumPlanes,
+ const int *piFd,
+ const int *piStride,
+ const int *piOffset,
+ const unsigned int *puiWidthShift,
+ const unsigned int *puiHeightShift);
+
+ PVRDRIBufferImpl *(*SubBufferCreate)(PVRDRIScreenImpl *psScreen,
+ PVRDRIBufferImpl *psParent,
+ int plane);
+
+ void (*BufferDestroy)(PVRDRIBufferImpl *psBuffer);
+
+ int (*BufferGetFd)(PVRDRIBufferImpl *psBuffer);
+
+ int (*BufferGetHandle)(PVRDRIBufferImpl *psBuffer);
+
+ uint64_t (*BufferGetModifier)(PVRDRIBufferImpl *psBuffer);
+
+ int (*BufferGetName)(PVRDRIBufferImpl *psBuffer);
+
+ int (*BufferGetOffset)(PVRDRIBufferImpl *psBuffer);
+
+ /* Image functions */
+ IMGEGLImage *(*EGLImageCreate)(void);
+ IMGEGLImage *(*EGLImageCreateFromBuffer)(int iWidth,
+ int iHeight,
+ int iStride,
+ IMG_PIXFMT ePixelFormat,
+ IMG_YUV_COLORSPACE eColourSpace,
+ IMG_YUV_CHROMA_INTERP eChromaUInterp,
+ IMG_YUV_CHROMA_INTERP eChromaVInterp,
+ PVRDRIBufferImpl *psBuffer);
+
+ IMGEGLImage *(*EGLImageCreateFromSubBuffer)(IMG_PIXFMT ePixelFormat,
+ PVRDRIBufferImpl *psSubBuffer);
+
+ IMGEGLImage *(*EGLImageDup)(IMGEGLImage *psIn);
+
+ void (*EGLImageSetCallbackData)(IMGEGLImage *psEGLImage, __DRIimage *image);
+
+ void (*EGLImageDestroyExternal)(PVRDRIScreenImpl *psScreenImpl,
+ IMGEGLImage *psEGLImage,
+ PVRDRIEGLImageType eglImageType);
+ void (*EGLImageFree)(IMGEGLImage *psEGLImage);
+
+ void (*EGLImageGetAttribs)(IMGEGLImage *psEGLImage,
+ PVRDRIBufferAttribs *psAttribs);
+
+ /* Sync functions */
+ void *(*CreateFence)(PVRDRIAPIType eAPI,
+ PVRDRIScreenImpl *psScreenImpl,
+ PVRDRIContextImpl *psContextImpl);
+
+ void (*DestroyFence)(void *psDRIFence);
+
+ /*
+ * Support for flushing commands in ClientWaitSync is deprecated
+ * in version 2 (since 1.11), with the caller being responsible
+ * for the flush. A context and API need not be supplied if a flush
+ * isn't requested.
+ */
+ bool (*ClientWaitSync)(PVRDRIAPIType eAPI,
+ PVRDRIContextImpl *psContextImpl,
+ void *psDRIFence,
+ bool bFlushCommands,
+ bool bTimeout,
+ uint64_t uiTimeout);
+
+ bool (*ServerWaitSync)(PVRDRIAPIType eAPI,
+ PVRDRIContextImpl *psContextImpl,
+ void *psDRIFence);
+
+ /* Deprecated in version 2 (since 1.11) */
+ void (*DestroyFences)(PVRDRIScreenImpl *psScreenImpl);
+
+ /* EGL interface functions */
+ /* Deprecated in version 1 (since 1.10) */
+ bool (*EGLDrawableConfigFromGLMode)(PVRDRIDrawableImpl *psPVRDrawable,
+ PVRDRIConfigInfo *psConfigInfo,
+ int supportedAPIs,
+ IMG_PIXFMT ePixFmt);
+
+ /* Blit functions */
+ bool (*BlitEGLImage)(PVRDRIScreenImpl *psScreenImpl,
+ PVRDRIContextImpl *psContextImpl,
+ IMGEGLImage *psDstImage,
+ PVRDRIBufferImpl *psDstBuffer,
+ IMGEGLImage *psSrcImage,
+ PVRDRIBufferImpl *psSrcBuffer,
+ int iDstX, int iDstY,
+ int iDstWidth, int iDstHeight,
+ int iSrcX, int iSrcY,
+ int iSrcWidth, int iSrcHeight,
+ int iFlushFlag);
+
+ /* Mapping functions */
+ void *(*MapEGLImage)(PVRDRIScreenImpl *psScreenImpl,
+ PVRDRIContextImpl *psContextImpl,
+ IMGEGLImage *psImage,
+ PVRDRIBufferImpl *psBuffer,
+ int iX, int iY,
+ int iWidth, int iHeight,
+ unsigned iFlags,
+ int *piStride,
+ void **ppvData);
+
+ bool (*UnmapEGLImage)(PVRDRIScreenImpl *psScreenImpl,
+ PVRDRIContextImpl *psContextImpl,
+ IMGEGLImage *psImage, PVRDRIBufferImpl *psBuffer,
+ void *pvData);
+
+ /* PVR utility support functions */
+ bool (*MesaFormatSupported)(unsigned fmt);
+ unsigned (*DepthStencilBitArraySize)(void);
+ const uint8_t *(*DepthBitsArray)(void);
+ const uint8_t *(*StencilBitsArray)(void);
+ unsigned (*MSAABitArraySize)(void);
+ const uint8_t *(*MSAABitsArray)(void);
+ uint32_t (*MaxPBufferWidth)(void);
+ uint32_t (*MaxPBufferHeight)(void);
+
+ unsigned (*GetNumAPIFuncs)(PVRDRIAPIType eAPI);
+ const char *(*GetAPIFunc)(PVRDRIAPIType eAPI, unsigned index);
+
+ int (*QuerySupportedFormats)(PVRDRIScreenImpl *psScreenImpl,
+ unsigned uNumFormats,
+ const int *piFormats,
+ const IMG_PIXFMT *peImgFormats,
+ bool *pbSupported);
+
+ int (*QueryModifiers)(PVRDRIScreenImpl *psScreenImpl,
+ int iFormat,
+ IMG_PIXFMT eImgFormat,
+ uint64_t *puModifiers,
+ unsigned *puExternalOnly);
+
+ /**********************************************************************
+ * Version 1 functions
+ **********************************************************************/
+
+ unsigned (*CreateContextV1)(PVRDRIScreenImpl *psScreenImpl,
+ PVRDRIContextImpl *psSharedContextImpl,
+ PVRDRIConfig *psConfig,
+ PVRDRIAPIType eAPI,
+ PVRDRIAPISubType eAPISub,
+ unsigned uMajorVersion,
+ unsigned uMinorVersion,
+ uint32_t uFlags,
+ bool bNotifyReset,
+ unsigned uPriority,
+ PVRDRIContextImpl **ppsContextImpl);
+
+ PVRDRIDrawableImpl *(*CreateDrawableWithConfig)(PVRDRIDrawable *psPVRDrawable,
+ PVRDRIConfig *psConfig);
+
+ /**********************************************************************
+ * Version 2 functions
+ **********************************************************************/
+
+ unsigned (*GetFenceCapabilities)(PVRDRIScreenImpl *psScreenImpl);
+
+ void *(*CreateFenceFd)(PVRDRIAPIType eAPI,
+ PVRDRIScreenImpl *psScreenImpl,
+ PVRDRIContextImpl *psContextImpl,
+ int iFd);
+
+ int (*GetFenceFd)(void *psDRIFence);
+} PVRDRISupportInterface;
+
+/* Callbacks into non-impl layer */
+typedef struct
+{
+ /**********************************************************************
+ * Version 0 callbacks
+ **********************************************************************/
+
+ /*
+ * DrawableRecreate and DrawableGetParameters are deprecated in
+ * version 1.
+ */
+ bool (*DrawableRecreate)(PVRDRIDrawable *psPVRDrawable);
+ bool (*DrawableGetParameters)(PVRDRIDrawable *psPVRDrawable,
+ PVRDRIBufferImpl **ppsDstBuffer,
+ PVRDRIBufferImpl **ppsAccumBuffer,
+ PVRDRIBufferAttribs *psAttribs,
+ bool *pbDoubleBuffered);
+
+ PVRDRIImageType (*ImageGetSharedType)(__DRIimage *image);
+ PVRDRIBufferImpl *(*ImageGetSharedBuffer)(__DRIimage *image);
+ IMGEGLImage *(*ImageGetSharedEGLImage)(__DRIimage *image);
+ IMGEGLImage *(*ImageGetEGLImage)(__DRIimage *image);
+ __DRIimage *(*ScreenGetDRIImage)(void *hEGLImage);
+ void (*RefImage)(__DRIimage *image);
+ void (*UnrefImage)(__DRIimage *image);
+
+ /*
+ * If the DRI module calls PVRDRIRegisterCallbacks, or
+ * PVRDRIRegisterVersionedCallbacks with any version number,
+ * the DRI support library can use the callbacks above.
+ * The callbacks below can only be called if
+ * PVRDRIRegisterVersionedCallbacks is called with a suitable
+ * version number.
+ */
+
+ /**********************************************************************
+ * Version 1 callbacks
+ **********************************************************************/
+
+ /*
+ * Deprecated in version 2 (since 1.10).
+ *
+ * DrawableGetParametersV1 is a replacement for DrawableRecreate
+ * and DrawableGetParameters. The DRI Support library must use one
+ * interface or the other, otherwise the results are undefined.
+ */
+ bool (*DrawableGetParametersV1)(PVRDRIDrawable *psPVRDrawable,
+ bool bAllowRecreate,
+ PVRDRIBufferImpl **ppsDstBuffer,
+ PVRDRIBufferImpl **ppsAccumBuffer,
+ PVRDRIBufferAttribs *psAttribs,
+ bool *pbDoubleBuffered);
+
+ /*
+ * Register the DRI Support interface with the DRI module.
+ * The caller is not required to preserve the PVRDRICallbacks structure
+ * after the call, so the callee must make a copy.
+ */
+ bool (*RegisterSupportInterfaceV1)(const PVRDRISupportInterface *psInterface,
+ unsigned uVersion);
+
+ /**********************************************************************
+ * Version 2 callbacks
+ **********************************************************************/
+
+ bool (*ConfigQuery)(const PVRDRIConfig *psConfig,
+ PVRDRIConfigAttrib eConfigAttrib,
+ int *piValueOut);
+ /*
+ * DrawableGetParametersV2 is a replacement for DrawableGetParametersV1.
+ * Unlike earlier versions, the caller is expected to query drawable
+ * information (via DrawableQuery) instead of this information being
+ * returned by the callback.
+ */
+ bool (*DrawableGetParametersV2)(PVRDRIDrawable *psPVRDrawable,
+ uint32_t uiFlags,
+ PVRDRIBufferImpl **ppsDstBuffer,
+ PVRDRIBufferImpl **ppsAccumBuffer);
+ bool (*DrawableQuery)(const PVRDRIDrawable *psPVRDrawable,
+ PVRDRIBufferAttrib eBufferAttrib,
+ uint32_t *uiValueOut);
+
+ /**********************************************************************
+ * Version 3 callbacks
+ **********************************************************************/
+} PVRDRICallbacks;
+
+/*
+ * Older versions of the DRI support library don't support
+ * PVRDRIRegisterVersionedCallbacks.
+ * The caller is not required to preserve the PVRDRICallbacks structure
+ * after the call, so the callee must make a copy.
+ */
+bool PVRDRIRegisterVersionedCallbacks(const PVRDRICallbacks *psCallbacks,
+ unsigned uVersion);
+
+/******************************************************************************
+ * Everything beyond this point is deprecated
+ ******************************************************************************/
+
+/*
+ * Calling PVRDRIRegisterCallbacks is equivalent to calling
+ * PVRDRIRegisterVersionedCallbacks with a version number of zero.
+ * The caller is not required to preserve the PVRDRICallbacks structure
+ * after the call, so the callee must make a copy.
+ */
+void PVRDRIRegisterCallbacks(PVRDRICallbacks *callbacks);
+
+PVRDRIDeviceType PVRDRIGetDeviceTypeFromFd(int iFd);
+
+bool PVRDRIIsFirstScreen(PVRDRIScreenImpl *psScreenImpl);
+
+uint32_t PVRDRIPixFmtGetDepth(IMG_PIXFMT eFmt);
+uint32_t PVRDRIPixFmtGetBPP(IMG_PIXFMT eFmt);
+uint32_t PVRDRIPixFmtGetBlockSize(IMG_PIXFMT eFmt);
+
+/* ScreenImpl functions */
+PVRDRIScreenImpl *PVRDRICreateScreenImpl(int iFd);
+void PVRDRIDestroyScreenImpl(PVRDRIScreenImpl *psScreenImpl);
+
+int PVRDRIAPIVersion(PVRDRIAPIType eAPI,
+ PVRDRIAPISubType eAPISub,
+ PVRDRIScreenImpl *psScreenImpl);
+
+void *PVRDRIEGLGetLibHandle(PVRDRIAPIType eAPI,
+ PVRDRIScreenImpl *psScreenImpl);
+
+PVRDRIGLAPIProc PVRDRIEGLGetProcAddress(PVRDRIAPIType eAPI,
+ PVRDRIScreenImpl *psScreenImpl,
+ const char *psProcName);
+
+bool PVRDRIEGLFlushBuffers(PVRDRIAPIType eAPI,
+ PVRDRIScreenImpl *psScreenImpl,
+ PVRDRIContextImpl *psContextImpl,
+ PVRDRIDrawableImpl *psDrawableImpl,
+ bool bFlushAllSurfaces,
+ bool bSwapBuffers,
+ bool bWaitForHW);
+bool PVRDRIEGLFreeResources(PVRDRIScreenImpl *psPVRScreenImpl);
+void PVRDRIEGLMarkRendersurfaceInvalid(PVRDRIAPIType eAPI,
+ PVRDRIScreenImpl *psScreenImpl,
+ PVRDRIContextImpl *psContextImpl);
+void PVRDRIEGLSetFrontBufferCallback(PVRDRIAPIType eAPI,
+ PVRDRIScreenImpl *psScreenImpl,
+ PVRDRIDrawableImpl *psDrawableImpl,
+ void (*pfnCallback)(PVRDRIDrawable *));
+
+unsigned PVRDRICreateContextImpl(PVRDRIContextImpl **ppsContextImpl,
+ PVRDRIAPIType eAPI,
+ PVRDRIAPISubType eAPISub,
+ PVRDRIScreenImpl *psScreenImpl,
+ const PVRDRIConfigInfo *psConfigInfo,
+ unsigned uMajorVersion,
+ unsigned uMinorVersion,
+ uint32_t uFlags,
+ bool bNotifyReset,
+ unsigned uPriority,
+ PVRDRIContextImpl *psSharedContextImpl);
+
+void PVRDRIDestroyContextImpl(PVRDRIContextImpl *psContextImpl,
+ PVRDRIAPIType eAPI,
+ PVRDRIScreenImpl *psScreenImpl);
+
+bool PVRDRIMakeCurrentGC(PVRDRIAPIType eAPI,
+ PVRDRIScreenImpl *psScreenImpl,
+ PVRDRIContextImpl *psContextImpl,
+ PVRDRIDrawableImpl *psWriteImpl,
+ PVRDRIDrawableImpl *psReadImpl);
+
+void PVRDRIMakeUnCurrentGC(PVRDRIAPIType eAPI,
+ PVRDRIScreenImpl *psScreenImpl);
+
+unsigned PVRDRIGetImageSource(PVRDRIAPIType eAPI,
+ PVRDRIScreenImpl *psScreenImpl,
+ PVRDRIContextImpl *psContextImpl,
+ uint32_t uiTarget,
+ uintptr_t uiBuffer,
+ uint32_t uiLevel,
+ IMGEGLImage *psEGLImage);
+
+bool PVRDRI2BindTexImage(PVRDRIAPIType eAPI,
+ PVRDRIScreenImpl *psScreenImpl,
+ PVRDRIContextImpl *psContextImpl,
+ PVRDRIDrawableImpl *psDrawableImpl);
+
+void PVRDRI2ReleaseTexImage(PVRDRIAPIType eAPI,
+ PVRDRIScreenImpl *psScreenImpl,
+ PVRDRIContextImpl *psContextImpl,
+ PVRDRIDrawableImpl *psDrawableImpl);
+
+/* DrawableImpl functions */
+PVRDRIDrawableImpl *PVRDRICreateDrawableImpl(PVRDRIDrawable *psPVRDrawable);
+void PVRDRIDestroyDrawableImpl(PVRDRIDrawableImpl *psScreenImpl);
+bool PVREGLDrawableCreate(PVRDRIScreenImpl *psScreenImpl,
+ PVRDRIDrawableImpl *psDrawableImpl);
+bool PVREGLDrawableRecreate(PVRDRIScreenImpl *psScreenImpl,
+ PVRDRIDrawableImpl *psDrawableImpl);
+bool PVREGLDrawableDestroy(PVRDRIScreenImpl *psScreenImpl,
+ PVRDRIDrawableImpl *psDrawableImpl);
+void PVREGLDrawableDestroyConfig(PVRDRIDrawableImpl *psDrawableImpl);
+
+/* Buffer functions */
+PVRDRIBufferImpl *PVRDRIBufferCreate(PVRDRIScreenImpl *psScreenImpl,
+ int iWidth,
+ int iHeight,
+ unsigned int uiBpp,
+ unsigned int uiUseFlags,
+ unsigned int *puiStride);
+
+PVRDRIBufferImpl *
+PVRDRIBufferCreateWithModifiers(PVRDRIScreenImpl *psScreenImpl,
+ int iWidth,
+ int iHeight,
+ int iFormat,
+ IMG_PIXFMT eIMGPixelFormat,
+ const uint64_t *puiModifiers,
+ unsigned int uiModifierCount,
+ unsigned int *puiStride);
+
+PVRDRIBufferImpl *PVRDRIBufferCreateFromNames(PVRDRIScreenImpl *psScreenImpl,
+ int iWidth,
+ int iHeight,
+ unsigned uiNumPlanes,
+ const int *piName,
+ const int *piStride,
+ const int *piOffset,
+ const unsigned int *puiWidthShift,
+ const unsigned int *puiHeightShift);
+
+PVRDRIBufferImpl *PVRDRIBufferCreateFromName(PVRDRIScreenImpl *psScreenImpl,
+ int iName,
+ int iWidth,
+ int iHeight,
+ int iStride,
+ int iOffset);
+
+PVRDRIBufferImpl *PVRDRIBufferCreateFromFds(PVRDRIScreenImpl *psScreenImpl,
+ int iWidth,
+ int iHeight,
+ unsigned uiNumPlanes,
+ const int *piFd,
+ const int *piStride,
+ const int *piOffset,
+ const unsigned int *puiWidthShift,
+ const unsigned int *puiHeightShift);
+
+PVRDRIBufferImpl *
+PVRDRIBufferCreateFromFdsWithModifier(PVRDRIScreenImpl *psScreenImpl,
+ int iWidth,
+ int iHeight,
+ uint64_t uiModifier,
+ unsigned uiNumPlanes,
+ const int *piFd,
+ const int *piStride,
+ const int *piOffset,
+ const unsigned int *puiWidthShift,
+ const unsigned int *puiHeightShift);
+
+PVRDRIBufferImpl *PVRDRISubBufferCreate(PVRDRIScreenImpl *psScreen,
+ PVRDRIBufferImpl *psParent,
+ int plane);
+
+void PVRDRIBufferDestroy(PVRDRIBufferImpl *psBuffer);
+
+int PVRDRIBufferGetFd(PVRDRIBufferImpl *psBuffer);
+
+int PVRDRIBufferGetHandle(PVRDRIBufferImpl *psBuffer);
+
+uint64_t PVRDRIBufferGetModifier(PVRDRIBufferImpl *psBuffer);
+
+int PVRDRIBufferGetName(PVRDRIBufferImpl *psBuffer);
+
+int PVRDRIBufferGetOffset(PVRDRIBufferImpl *psBuffer);
+
+/* Image functions */
+IMGEGLImage *PVRDRIEGLImageCreate(void);
+IMGEGLImage *PVRDRIEGLImageCreateFromBuffer(int iWidth,
+ int iHeight,
+ int iStride,
+ IMG_PIXFMT ePixelFormat,
+ IMG_YUV_COLORSPACE eColourSpace,
+ IMG_YUV_CHROMA_INTERP eChromaUInterp,
+ IMG_YUV_CHROMA_INTERP eChromaVInterp,
+ PVRDRIBufferImpl *psBuffer);
+
+IMGEGLImage *PVRDRIEGLImageCreateFromSubBuffer(IMG_PIXFMT ePixelFormat,
+ PVRDRIBufferImpl *psSubBuffer);
+
+IMGEGLImage *PVRDRIEGLImageDup(IMGEGLImage *psIn);
+
+void PVRDRIEGLImageSetCallbackData(IMGEGLImage *psEGLImage, __DRIimage *image);
+
+void PVRDRIEGLImageDestroyExternal(PVRDRIScreenImpl *psScreenImpl,
+ IMGEGLImage *psEGLImage,
+ PVRDRIEGLImageType eglImageType);
+void PVRDRIEGLImageFree(IMGEGLImage *psEGLImage);
+
+void PVRDRIEGLImageGetAttribs(IMGEGLImage *psEGLImage, PVRDRIBufferAttribs *psAttribs);
+
+/* Sync functions */
+void *PVRDRICreateFenceImpl(PVRDRIAPIType eAPI,
+ PVRDRIScreenImpl *psScreenImpl,
+ PVRDRIContextImpl *psContextImpl);
+
+void PVRDRIDestroyFenceImpl(void *psDRIFence);
+
+bool PVRDRIClientWaitSyncImpl(PVRDRIAPIType eAPI,
+ PVRDRIContextImpl *psContextImpl,
+ void *psDRIFence,
+ bool bFlushCommands,
+ bool bTimeout,
+ uint64_t uiTimeout);
+
+bool PVRDRIServerWaitSyncImpl(PVRDRIAPIType eAPI,
+ PVRDRIContextImpl *psContextImpl,
+ void *psDRIFence);
+
+void PVRDRIDestroyFencesImpl(PVRDRIScreenImpl *psScreenImpl);
+
+/* EGL interface functions */
+bool PVRDRIEGLDrawableConfigFromGLMode(PVRDRIDrawableImpl *psPVRDrawable,
+ PVRDRIConfigInfo *psConfigInfo,
+ int supportedAPIs,
+ IMG_PIXFMT ePixFmt);
+
+/* Blit functions */
+bool PVRDRIBlitEGLImage(PVRDRIScreenImpl *psScreenImpl,
+ PVRDRIContextImpl *psContextImpl,
+ IMGEGLImage *psDstImage, PVRDRIBufferImpl *psDstBuffer,
+ IMGEGLImage *psSrcImage, PVRDRIBufferImpl *psSrcBuffer,
+ int iDstX, int iDstY, int iDstWidth, int iDstHeight,
+ int iSrcX, int iSrcY, int iSrcWidth, int iSrcHeight,
+ int iFlushFlag);
+
+/* Mapping functions */
+void *PVRDRIMapEGLImage(PVRDRIScreenImpl *psScreenImpl,
+ PVRDRIContextImpl *psContextImpl,
+ IMGEGLImage *psImage, PVRDRIBufferImpl *psBuffer,
+ int iX, int iY, int iWidth, int iHeight,
+ unsigned uiFlags, int *piStride, void **ppvData);
+
+bool PVRDRIUnmapEGLImage(PVRDRIScreenImpl *psScreenImpl,
+ PVRDRIContextImpl *psContextImpl,
+ IMGEGLImage *psImage, PVRDRIBufferImpl *psBuffer,
+ void *pvData);
+
+/* PVR utility support functions */
+bool PVRDRIMesaFormatSupported(unsigned fmt);
+unsigned PVRDRIDepthStencilBitArraySize(void);
+const uint8_t *PVRDRIDepthBitsArray(void);
+const uint8_t *PVRDRIStencilBitsArray(void);
+unsigned PVRDRIMSAABitArraySize(void);
+const uint8_t *PVRDRIMSAABitsArray(void);
+uint32_t PVRDRIMaxPBufferWidth(void);
+uint32_t PVRDRIMaxPBufferHeight(void);
+
+unsigned PVRDRIGetNumAPIFuncs(PVRDRIAPIType eAPI);
+const char *PVRDRIGetAPIFunc(PVRDRIAPIType eAPI, unsigned index);
+
+int PVRDRIQuerySupportedFormats(PVRDRIScreenImpl *psScreenImpl,
+ unsigned uNumFormats,
+ const int *piFormats,
+ const IMG_PIXFMT *peImgFormats,
+ bool *pbSupported);
+
+int PVRDRIQueryModifiers(PVRDRIScreenImpl *psScreenImpl,
+ int iFormat,
+ IMG_PIXFMT eImgFormat,
+ uint64_t *puModifiers,
+ unsigned *puExternalOnly);
+
+#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 00000000000..b023ef231cc
--- /dev/null
+++ b/src/mesa/drivers/dri/pvr/img_drm_fourcc.h
@@ -0,0 +1,110 @@
+/*************************************************************************/ /*!
+@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 we invent one.
+ * 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 we invent one.
+ * 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')
+#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 00000000000..9e70a960636
--- /dev/null
+++ b/src/mesa/drivers/dri/pvr/imgpixfmts.h
@@ -0,0 +1,80 @@
+/*************************************************************************/ /*!
+@File
+@Title Pixel formats
+@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: This file is autogenerated - DO NOT EDIT.
+ **
+ ** See fmts_systable.txt to add new formats.
+ ****************************************************************************/
+
+#if !defined(_IMGPIXFMTS_H_)
+#define _IMGPIXFMTS_H_
+
+typedef enum _IMG_PIXFMT_
+{
+ IMG_PIXFMT_UNKNOWN = 0,
+ IMG_PIXFMT_R10G10B10A2_UNORM = 25,
+ IMG_PIXFMT_R8G8B8A8_UNORM = 32,
+ IMG_PIXFMT_R8G8B8X8_UNORM = 37,
+ IMG_PIXFMT_D32_FLOAT = 51,
+ IMG_PIXFMT_D24_UNORM_X8_TYPELESS = 58,
+ IMG_PIXFMT_R8G8_UNORM = 62,
+ IMG_PIXFMT_D16_UNORM = 69,
+ IMG_PIXFMT_R8_UNORM = 76,
+ IMG_PIXFMT_S8_UINT = 81,
+ 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_L8_UNORM = 136,
+ IMG_PIXFMT_L8A8_UNORM = 138,
+ IMG_PIXFMT_B4G4R4A4_UNORM = 145,
+ 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_V8U8Y8A8 = 184,
+ IMG_PIXFMT_YVU8_422_2PLANE_PACK8 = 201,
+ IMG_PIXFMT_YVU10_444_1PLANE_PACK10 = 203,
+ IMG_PIXFMT_YUV8_422_2PLANE_PACK8 = 207,
+ IMG_PIXFMT_YUV8_444_3PLANE_PACK8 = 208,
+ IMG_PIXFMT_YVU8_420_2PLANE_PACK8_P = 245,
+ IMG_PIXFMT_YUV8_420_2PLANE_PACK8_P = 249,
+ IMG_PIXFMT_UYVY10_422_1PLANE_PACK10_CUST1 = 252,
+} 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 00000000000..a91ee10d3f3
--- /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 00000000000..064135222b6
--- /dev/null
+++ b/src/mesa/drivers/dri/pvr/mesa_context.c
@@ -0,0 +1,258 @@
+/* -*- mode: c; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* vi: set ts=8 sw=8 sts=8: */
+/**
+ * \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 <dlfcn.h>
+#include <assert.h>
+
+#include "main/version.h"
+#include "main/errors.h"
+
+#include "imports.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 numEntries = _glapi_get_dispatch_table_size();
+ _glapi_proc *table = malloc(numEntries * sizeof(_glapi_proc));
+
+ if (table)
+ {
+ unsigned i;
+
+ for (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;
+ break;
+ case PVRDRI_API_GLES2:
+ return &psPVRScreen->psOGLES2Dispatch;
+ break;
+ case PVRDRI_API_CL:
+ assert(!"OpenCL doesn't have a dispatch table");
+ break;
+ case PVRDRI_API_NONE:
+ assert(!"invalid API");
+ break;
+ }
+ 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;
+ }
+}
+
+static void
+pvrdri_add_mesa_dispatch(struct _glapi_table *psTable,
+ PVRDRIAPIType eAPI,
+ PVRDRIScreenImpl *psScreenImpl,
+ void *pvLibHandle,
+ const char *psFunc)
+{
+ int iOffset;
+ const char *asFunc[] = {NULL, NULL};
+ _glapi_proc pfFunc;
+ const char *error;
+
+ (void) dlerror();
+ pfFunc = dlsym(pvLibHandle, psFunc);
+ error = dlerror();
+ if (error != NULL)
+ {
+ pfFunc = PVRDRIEGLGetProcAddress(eAPI, psScreenImpl, psFunc);
+ if (pfFunc == NULL)
+ {
+#if 0
+ /*
+ * Not all extensions are supported, so there may
+ * be quite a lot of lookup failures.
+ */
+ _mesa_warning(NULL, "Couldn't get address of %s", psFunc);
+#endif
+ return;
+ }
+ }
+
+ 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,
+ PVRDRIScreenImpl *psScreenImpl,
+ void *pvLibHandle,
+ unsigned uNumFuncs)
+{
+ unsigned i;
+
+ for (i = 0; i < uNumFuncs; i++)
+ {
+ const char *psFunc = PVRDRIGetAPIFunc(eAPI, i);
+
+ assert(psFunc);
+
+ pvrdri_add_mesa_dispatch(psTable,
+ eAPI,
+ psScreenImpl,
+ pvLibHandle,
+ psFunc);
+ }
+}
+
+bool
+pvrdri_create_dispatch_table(PVRDRIScreen *psPVRScreen, PVRDRIAPIType eAPI)
+{
+ PVRDRIScreenImpl *psScreenImpl = psPVRScreen->psImpl;
+ struct _glapi_table **ppsTable = pvrdri_get_dispatch_table_ptr(psPVRScreen, eAPI);
+ void *pvLibHandle;
+ unsigned uNumFuncs;
+
+ if (ppsTable == NULL)
+ {
+ return false;
+ }
+
+ if (*ppsTable != NULL)
+ {
+ return true;
+ }
+
+ pvLibHandle = PVRDRIEGLGetLibHandle(eAPI, psScreenImpl);;
+ uNumFuncs = PVRDRIGetNumAPIFuncs(eAPI);
+ if (!pvLibHandle || !uNumFuncs)
+ {
+ return false;
+ }
+
+ *ppsTable = pvrdri_alloc_dispatch_table();
+ if (*ppsTable == NULL)
+ {
+ return false;
+ }
+
+ pvrdri_set_mesa_dispatch(*ppsTable,
+ eAPI,
+ psScreenImpl,
+ pvLibHandle,
+ 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 = 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 00000000000..768731a3761
--- /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',
+ 'pvrcompat.c',
+ 'pvrdrawable.c',
+ 'pvrdri.c',
+ 'pvrext.c',
+ 'pvrimage.c',
+ 'pvrutil.c',
+)
+
+dep_libpvr = [
+ dep_libdrm,
+ dependency('pvrdri', required : false),
+]
+
+libpvr = static_library(
+ 'pvr',
+ [files_pvr, xmlpool_options_h, main_dispatch_h],
+ include_directories : [inc_common, inc_dri_common, inc_util, inc_pvr],
+ c_args : [c_vis_args, no_override_init_args],
+ cpp_args : [cpp_vis_args],
+ dependencies : [dep_libpvr],
+)
+
+dri_drivers += libpvr
+dri_link += 'pvr_dri.so'
diff --git a/src/mesa/drivers/dri/pvr/pvrcompat.c b/src/mesa/drivers/dri/pvr/pvrcompat.c
new file mode 100644
index 00000000000..e429e0cc135
--- /dev/null
+++ b/src/mesa/drivers/dri/pvr/pvrcompat.c
@@ -0,0 +1,1383 @@
+/* -*- mode: c; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* vi: set ts=8 sw=8 sts=8: */
+/*
+ * 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 PVRDRISupportInterface gsSup;
+static unsigned guSupVer;
+
+static pthread_mutex_t gsCompatLock = PTHREAD_MUTEX_INITIALIZER;
+
+static void DumSupFunc(void) { abort(); }
+
+/* Call a function via the DRI Support interface structure */
+#define CallFunc(field, ver, ...) \
+ do { \
+ if (guSupVer >= ver && gsSup.field) \
+ return gsSup.field(__VA_ARGS__); \
+ } while(0)
+
+/* Define a function to test for a given DRI Support function */
+#define DefineFunc_IsSupported(func, field, ver) \
+ bool func ## _IsSupported(void) \
+ { return guSupVer >= ver && gsSup.field; }
+
+
+/*
+ * Lookup a function, and set the pointer to the function address.
+ * If lookup fails, the pointer is set to the address of the dummy
+ * support function, DumSupFunc.
+ */
+#define LookupFunc(func, ptr) \
+ do { \
+ if (!ptr) \
+ { \
+ ptr = dlsym(gpvSupLib, MAKESTRING(func)); \
+ if (!ptr) \
+ ptr = (void *)DumSupFunc; \
+ } \
+ } while(0)
+
+/*
+ * Lookup a legacy DRI support function, and set the function pointer
+ * in the support interface structure, gsSup.
+ * If lookup fails, the function pointer is set to the address of the
+ * dummy support function, DumSupFunc.
+ */
+#define LookupLegacyFunc(func, field) \
+ LookupFunc(func, gsSup.field)
+
+/*
+ * This legacy version of CallFunc should only be used for functions that
+ * used to be called directly in older versions of the DRI Support library.
+ * Do not use this macro for functions that have only ever been available
+ * via the PVRDRISupportInterface structure.
+ * In summary, if you are modifying this file to support a new version of
+ * the PVRDRISupportInterface structure, use CallFunc rather than this
+ * macro.
+ */
+#define CallFuncLegacy(func, field, ...) \
+ do { \
+ LookupLegacyFunc(func, field); \
+ \
+ if (gsSup.field != (void *)DumSupFunc) \
+ return gsSup.field(__VA_ARGS__); \
+ } while(0)
+
+/*
+ * Legacy version of DefineFunc_IsSupported.
+ * See the comments for CallFuncLegacy.
+ */
+#define DefineFunc_IsSupportedLegacy(func, field) \
+ bool func ## _IsSupported(void) \
+ { \
+ LookupLegacyFunc(func, field); \
+ \
+ return gsSup.field != (void *)DumSupFunc; \
+ }
+
+/*
+ * Calculate the size of a particular version of the PVRDRISupportInterface
+ * structure from the name of the last field in that version of the
+ * structure.
+ */
+#define PVRDRIInterfaceSize(field) \
+ (offsetof(PVRDRISupportInterface, field) + \
+ sizeof((PVRDRISupportInterface *)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\n", path);
+ }
+ else
+ {
+ const char *error = dlerror();
+
+ if (!error)
+ {
+ error = "unknown error";
+ }
+
+ errorMessage("%s: Couldn't load %s: %s\n",
+ __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 = dlerror();
+
+ if (!error)
+ {
+ error = "unknown error";
+ }
+
+ errorMessage("%s: Couldn't unload %s: %s\n",
+ __func__, name, error);
+ }
+ else
+ {
+ __driUtilMessage("Unloaded %s\n", 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 bool
+RegisterCallbacksCompat(const PVRDRICallbacks *psCallbacks)
+{
+ void (*pfRegisterCallbacks)(PVRDRICallbacks *psCallbacks) = NULL;
+
+ LookupFunc(PVRDRIRegisterCallbacks, pfRegisterCallbacks);
+
+ if (pfRegisterCallbacks != (void *)&DumSupFunc)
+ {
+ PVRDRICallbacks sCallbacks = *psCallbacks;
+
+ pfRegisterCallbacks(&sCallbacks);
+
+ return true;
+ }
+
+ return false;
+}
+
+static void
+CompatDeinit(void)
+{
+ UnloadSupportLib();
+ memset(&gsSup, 0, sizeof(gsSup));
+ guSupVer = 0;
+}
+
+bool
+PVRDRICompatInit(const PVRDRICallbacks *psCallbacks, unsigned uVersion)
+{
+ bool res;
+
+ bool (*pfRegisterVersionedCallbacks)(const PVRDRICallbacks *psCallbacks,
+ unsigned uVersion) = NULL;
+
+ CompatLock();
+ res = (giSupLibRef++ != 0);
+ if (res)
+ {
+ goto Exit;
+ }
+
+ res = LoadSupportLib();
+ if (!res)
+ {
+ goto Exit;
+ }
+
+ LookupFunc(PVRDRIRegisterVersionedCallbacks, pfRegisterVersionedCallbacks);
+
+ if (pfRegisterVersionedCallbacks != (void *)&DumSupFunc)
+ {
+ res = pfRegisterVersionedCallbacks(psCallbacks, uVersion);
+ }
+ else
+ {
+ res = RegisterCallbacksCompat(psCallbacks);
+ }
+Exit:
+ if (!res)
+ {
+ CompatDeinit();
+ giSupLibRef--;
+ }
+ CompatUnlock();
+
+ return res;
+}
+
+void
+PVRDRICompatDeinit(void)
+{
+ CompatLock();
+
+ if (--giSupLibRef == 0)
+ {
+ CompatDeinit();
+ }
+
+ CompatUnlock();
+}
+
+bool
+PVRDRIRegisterSupportInterfaceV1(const PVRDRISupportInterface *psInterface,
+ unsigned uVersion)
+{
+ size_t uSize;
+
+ /* The "default" case should be associated with the latest version */
+ switch (uVersion)
+ {
+ default:
+ case 2:
+ uSize = PVRDRIInterfaceSize(GetFenceFd);
+ break;
+ case 1:
+ uSize = PVRDRIInterfaceSize(CreateDrawableWithConfig);
+ break;
+ case 0:
+ uSize = PVRDRIInterfaceSize(QueryModifiers);
+ break;
+ }
+
+ memcpy(&gsSup, psInterface, uSize);
+
+ guSupVer = uVersion;
+
+ return true;
+}
+
+PVRDRIDeviceType
+PVRDRIGetDeviceTypeFromFd(int iFd)
+{
+ CallFuncLegacy(PVRDRIGetDeviceTypeFromFd,
+ GetDeviceTypeFromFd,
+ iFd);
+
+ return PVRDRI_DEVICE_TYPE_INVALID;
+}
+
+
+bool
+PVRDRIIsFirstScreen(PVRDRIScreenImpl *psScreenImpl)
+{
+ CallFuncLegacy(PVRDRIIsFirstScreen,
+ IsFirstScreen,
+ psScreenImpl);
+
+ return false;
+}
+
+
+uint32_t
+PVRDRIPixFmtGetDepth(IMG_PIXFMT eFmt)
+{
+ CallFuncLegacy(PVRDRIPixFmtGetDepth,
+ PixFmtGetDepth,
+ eFmt);
+
+ return 0;
+}
+
+uint32_t
+PVRDRIPixFmtGetBPP(IMG_PIXFMT eFmt)
+{
+ CallFuncLegacy(PVRDRIPixFmtGetBPP,
+ PixFmtGetBPP,
+ eFmt);
+
+ return 0;
+}
+
+uint32_t
+PVRDRIPixFmtGetBlockSize(IMG_PIXFMT eFmt)
+{
+ CallFuncLegacy(PVRDRIPixFmtGetBlockSize,
+ PixFmtGetBlockSize,
+ eFmt);
+
+ return 0;
+}
+
+PVRDRIScreenImpl *
+PVRDRICreateScreenImpl(int iFd)
+{
+ CallFuncLegacy(PVRDRICreateScreenImpl,
+ CreateScreen,
+ iFd);
+
+ return NULL;
+}
+
+void
+PVRDRIDestroyScreenImpl(PVRDRIScreenImpl *psScreenImpl)
+{
+ CallFuncLegacy(PVRDRIDestroyScreenImpl,
+ DestroyScreen,
+ psScreenImpl);
+}
+
+int
+PVRDRIAPIVersion(PVRDRIAPIType eAPI,
+ PVRDRIAPISubType eAPISub,
+ PVRDRIScreenImpl *psScreenImpl)
+{
+ CallFuncLegacy(PVRDRIAPIVersion,
+ APIVersion,
+ eAPI,
+ eAPISub,
+ psScreenImpl);
+
+ return 0;
+}
+
+void *
+PVRDRIEGLGetLibHandle(PVRDRIAPIType eAPI,
+ PVRDRIScreenImpl *psScreenImpl)
+{
+ CallFuncLegacy(PVRDRIEGLGetLibHandle,
+ EGLGetLibHandle,
+ eAPI,
+ psScreenImpl);
+
+ return NULL;
+}
+
+PVRDRIGLAPIProc
+PVRDRIEGLGetProcAddress(PVRDRIAPIType eAPI,
+ PVRDRIScreenImpl *psScreenImpl,
+ const char *psProcName)
+{
+ CallFuncLegacy(PVRDRIEGLGetProcAddress,
+ EGLGetProcAddress,
+ eAPI,
+ psScreenImpl,
+ psProcName);
+
+ return (PVRDRIGLAPIProc)NULL;
+}
+
+bool
+PVRDRIEGLFlushBuffers(PVRDRIAPIType eAPI,
+ PVRDRIScreenImpl *psScreenImpl,
+ PVRDRIContextImpl *psContextImpl,
+ PVRDRIDrawableImpl *psDrawableImpl,
+ bool bFlushAllSurfaces,
+ bool bSwapBuffers,
+ bool bWaitForHW)
+{
+ CallFuncLegacy(PVRDRIEGLFlushBuffers,
+ EGLFlushBuffers,
+ eAPI,
+ psScreenImpl,
+ psContextImpl,
+ psDrawableImpl,
+ bFlushAllSurfaces,
+ bSwapBuffers,
+ bWaitForHW);
+
+ return false;
+}
+
+void
+PVRDRIEGLMarkRendersurfaceInvalid(PVRDRIAPIType eAPI,
+ PVRDRIScreenImpl *psScreenImpl,
+ PVRDRIContextImpl *psContextImpl)
+{
+ CallFuncLegacy(PVRDRIEGLMarkRendersurfaceInvalid,
+ EGLMarkRendersurfaceInvalid,
+ eAPI,
+ psScreenImpl,
+ psContextImpl);
+}
+
+static inline void PVRDRIConfigFromMesa(PVRDRIConfigInfo *psConfigInfo,
+ const struct gl_config *psGLMode)
+{
+ memset(psConfigInfo, 0, sizeof(*psConfigInfo));
+
+ if (psGLMode)
+ {
+ psConfigInfo->samples = psGLMode->samples;
+ psConfigInfo->redBits = psGLMode->redBits;
+ psConfigInfo->greenBits = psGLMode->greenBits;
+ psConfigInfo->blueBits = psGLMode->blueBits;
+ psConfigInfo->alphaBits = psGLMode->alphaBits;
+ psConfigInfo->rgbBits = psGLMode->rgbBits;
+ psConfigInfo->depthBits = psGLMode->depthBits;
+ psConfigInfo->stencilBits = psGLMode->stencilBits;
+ psConfigInfo->doubleBufferMode = psGLMode->doubleBufferMode;
+
+ psConfigInfo->sampleBuffers = psGLMode->sampleBuffers;
+ psConfigInfo->bindToTextureRgb = psGLMode->bindToTextureRgb;
+ psConfigInfo->bindToTextureRgba = psGLMode->bindToTextureRgba;
+ }
+}
+
+unsigned
+PVRDRISupportCreateContext(PVRDRIScreenImpl *psScreenImpl,
+ PVRDRIContextImpl *psSharedContextImpl,
+ PVRDRIConfig *psConfig,
+ PVRDRIAPIType eAPI,
+ PVRDRIAPISubType eAPISub,
+ unsigned uMajorVersion,
+ unsigned uMinorVersion,
+ uint32_t uFlags,
+ bool bNotifyReset,
+ unsigned uPriority,
+ PVRDRIContextImpl **ppsContextImpl)
+{
+ PVRDRIConfigInfo sConfigInfo;
+
+ CallFunc(CreateContextV1, 1,
+ psScreenImpl, psSharedContextImpl, psConfig, eAPI, eAPISub,
+ uMajorVersion, uMinorVersion, uFlags, bNotifyReset, uPriority,
+ ppsContextImpl);
+
+ PVRDRIConfigFromMesa(&sConfigInfo, &psConfig->sGLMode);
+
+ CallFuncLegacy(PVRDRICreateContextImpl,
+ CreateContext,
+ ppsContextImpl,
+ eAPI,
+ eAPISub,
+ psScreenImpl,
+ &sConfigInfo,
+ uMajorVersion,
+ uMinorVersion,
+ uFlags,
+ bNotifyReset,
+ uPriority,
+ psSharedContextImpl);
+
+ return PVRDRI_CONTEXT_ERROR_BAD_API;
+}
+
+void
+PVRDRIDestroyContextImpl(PVRDRIContextImpl *psContextImpl,
+ PVRDRIAPIType eAPI,
+ PVRDRIScreenImpl *psScreenImpl)
+{
+ CallFuncLegacy(PVRDRIDestroyContextImpl,
+ DestroyContext,
+ psContextImpl,
+ eAPI,
+ psScreenImpl);
+}
+
+bool
+PVRDRIMakeCurrentGC(PVRDRIAPIType eAPI,
+ PVRDRIScreenImpl *psScreenImpl,
+ PVRDRIContextImpl *psContextImpl,
+ PVRDRIDrawableImpl *psWriteImpl,
+ PVRDRIDrawableImpl *psReadImpl)
+{
+ CallFuncLegacy(PVRDRIMakeCurrentGC,
+ MakeCurrentGC,
+ eAPI,
+ psScreenImpl,
+ psContextImpl,
+ psWriteImpl,
+ psReadImpl);
+
+ return false;
+}
+
+void
+PVRDRIMakeUnCurrentGC(PVRDRIAPIType eAPI,
+ PVRDRIScreenImpl *psScreenImpl)
+{
+ CallFuncLegacy(PVRDRIMakeUnCurrentGC,
+ MakeUnCurrentGC,
+ eAPI,
+ psScreenImpl);
+}
+
+unsigned
+PVRDRIGetImageSource(PVRDRIAPIType eAPI,
+ PVRDRIScreenImpl *psScreenImpl,
+ PVRDRIContextImpl *psContextImpl,
+ uint32_t uiTarget,
+ uintptr_t uiBuffer,
+ uint32_t uiLevel,
+ IMGEGLImage *psEGLImage)
+{
+ CallFuncLegacy(PVRDRIGetImageSource,
+ GetImageSource,
+ eAPI,
+ psScreenImpl,
+ psContextImpl,
+ uiTarget,
+ uiBuffer,
+ uiLevel,
+ psEGLImage);
+
+ return PVRDRI_IMAGE_ERROR_BAD_MATCH;
+}
+
+bool
+PVRDRI2BindTexImage(PVRDRIAPIType eAPI,
+ PVRDRIScreenImpl *psScreenImpl,
+ PVRDRIContextImpl *psContextImpl,
+ PVRDRIDrawableImpl *psDrawableImpl)
+{
+ CallFuncLegacy(PVRDRI2BindTexImage,
+ BindTexImage,
+ eAPI,
+ psScreenImpl,
+ psContextImpl,
+ psDrawableImpl);
+
+ return false;
+}
+
+void
+PVRDRI2ReleaseTexImage(PVRDRIAPIType eAPI,
+ PVRDRIScreenImpl *psScreenImpl,
+ PVRDRIContextImpl *psContextImpl,
+ PVRDRIDrawableImpl *psDrawableImpl)
+{
+ CallFuncLegacy(PVRDRI2ReleaseTexImage,
+ ReleaseTexImage,
+ eAPI,
+ psScreenImpl,
+ psContextImpl,
+ psDrawableImpl);
+}
+
+PVRDRIDrawableImpl *
+PVRDRICreateDrawableImpl(PVRDRIDrawable *psPVRDrawable)
+{
+ CallFuncLegacy(PVRDRICreateDrawableImpl,
+ CreateDrawable,
+ psPVRDrawable);
+
+ return NULL;
+}
+
+PVRDRIDrawableImpl *
+PVRDRISupportCreateDrawable(PVRDRIDrawable *psPVRDrawable,
+ PVRDRIConfig *psConfig)
+{
+ PVRDRIDrawableImpl *psDrawableImpl;
+ PVRDRIConfigInfo sConfigInfo;
+ IMG_PIXFMT ePixelFormat;
+
+ CallFunc(CreateDrawableWithConfig, 1,
+ psPVRDrawable,
+ psConfig);
+
+ ePixelFormat = PVRDRIGetPixelFormat(&psConfig->sGLMode);
+ if (ePixelFormat == IMG_PIXFMT_UNKNOWN)
+ {
+ __driUtilMessage("%s: Couldn't work out pixel format", __func__);
+ return NULL;
+ }
+
+ psDrawableImpl = PVRDRICreateDrawableImpl(psPVRDrawable);
+ if (!psDrawableImpl)
+ {
+ return NULL;
+ }
+
+ PVRDRIConfigFromMesa(&sConfigInfo, &psConfig->sGLMode);
+ if (!PVRDRIEGLDrawableConfigFromGLMode(psDrawableImpl,
+ &sConfigInfo,
+ psConfig->iSupportedAPIs,
+ ePixelFormat))
+ {
+ __driUtilMessage("%s: Couldn't derive EGL config", __func__);
+ PVRDRIDestroyDrawableImpl(psDrawableImpl);
+ return NULL;
+ }
+
+ return psDrawableImpl;
+}
+
+void
+PVRDRIDestroyDrawableImpl(PVRDRIDrawableImpl *psScreenImpl)
+{
+ CallFuncLegacy(PVRDRIDestroyDrawableImpl,
+ DestroyDrawable,
+ psScreenImpl);
+}
+
+bool
+PVREGLDrawableCreate(PVRDRIScreenImpl *psScreenImpl,
+ PVRDRIDrawableImpl *psDrawableImpl)
+{
+ CallFuncLegacy(PVREGLDrawableCreate,
+ EGLDrawableCreate,
+ psScreenImpl,
+ psDrawableImpl);
+
+ return false;
+}
+
+bool
+PVREGLDrawableRecreate(PVRDRIScreenImpl *psScreenImpl,
+ PVRDRIDrawableImpl *psDrawableImpl)
+{
+ CallFuncLegacy(PVREGLDrawableRecreate,
+ EGLDrawableRecreate,
+ psScreenImpl,
+ psDrawableImpl);
+
+ return false;
+}
+
+bool
+PVREGLDrawableDestroy(PVRDRIScreenImpl *psScreenImpl,
+ PVRDRIDrawableImpl *psDrawableImpl)
+{
+ CallFuncLegacy(PVREGLDrawableDestroy,
+ EGLDrawableDestroy,
+ psScreenImpl,
+ psDrawableImpl);
+
+ return false;
+}
+
+void
+PVREGLDrawableDestroyConfig(PVRDRIDrawableImpl *psDrawableImpl)
+{
+ CallFuncLegacy(PVREGLDrawableDestroyConfig,
+ EGLDrawableDestroyConfig,
+ psDrawableImpl);
+}
+
+PVRDRIBufferImpl *
+PVRDRIBufferCreate(PVRDRIScreenImpl *psScreenImpl,
+ int iWidth,
+ int iHeight,
+ unsigned int uiBpp,
+ unsigned int uiUseFlags,
+ unsigned int *puiStride)
+{
+ CallFuncLegacy(PVRDRIBufferCreate,
+ BufferCreate,
+ psScreenImpl,
+ iWidth,
+ iHeight,
+ uiBpp,
+ uiUseFlags,
+ puiStride);
+
+ return NULL;
+}
+
+DefineFunc_IsSupportedLegacy(PVRDRIBufferCreateWithModifiers,
+ BufferCreateWithModifiers)
+
+PVRDRIBufferImpl *
+PVRDRIBufferCreateWithModifiers(PVRDRIScreenImpl *psScreenImpl,
+ int iWidth,
+ int iHeight,
+ int format,
+ IMG_PIXFMT eIMGPixelFormat,
+ const uint64_t *puiModifiers,
+ unsigned int uiModifierCount,
+ unsigned int *puiStride)
+{
+ CallFuncLegacy(PVRDRIBufferCreateWithModifiers,
+ BufferCreateWithModifiers,
+ psScreenImpl,
+ iWidth,
+ iHeight,
+ format,
+ eIMGPixelFormat,
+ puiModifiers,
+ uiModifierCount,
+ puiStride);
+
+ return NULL;
+}
+
+PVRDRIBufferImpl *
+PVRDRIBufferCreateFromNames(PVRDRIScreenImpl *psScreenImpl,
+ int iWidth,
+ int iHeight,
+ unsigned uiNumPlanes,
+ const int *piName,
+ const int *piStride,
+ const int *piOffset,
+ const unsigned int *puiWidthShift,
+ const unsigned int *puiHeightShift)
+{
+ CallFuncLegacy(PVRDRIBufferCreateFromNames,
+ BufferCreateFromNames,
+ psScreenImpl,
+ iWidth,
+ iHeight,
+ uiNumPlanes,
+ piName,
+ piStride,
+ piOffset,
+ puiWidthShift,
+ puiHeightShift);
+
+ return NULL;
+}
+
+PVRDRIBufferImpl *
+PVRDRIBufferCreateFromName(PVRDRIScreenImpl *psScreenImpl,
+ int iName,
+ int iWidth,
+ int iHeight,
+ int iStride,
+ int iOffset)
+{
+ CallFuncLegacy(PVRDRIBufferCreateFromName,
+ BufferCreateFromName,
+ psScreenImpl,
+ iName,
+ iWidth,
+ iHeight,
+ iStride,
+ iOffset);
+
+ return NULL;
+}
+
+PVRDRIBufferImpl *
+PVRDRIBufferCreateFromFds(PVRDRIScreenImpl *psScreenImpl,
+ int iWidth,
+ int iHeight,
+ unsigned uiNumPlanes,
+ const int *piFd,
+ const int *piStride,
+ const int *piOffset,
+ const unsigned int *puiWidthShift,
+ const unsigned int *puiHeightShift)
+{
+ CallFuncLegacy(PVRDRIBufferCreateFromFds,
+ BufferCreateFromFds,
+ psScreenImpl,
+ iWidth,
+ iHeight,
+ uiNumPlanes,
+ piFd,
+ piStride,
+ piOffset,
+ puiWidthShift,
+ puiHeightShift);
+
+ return NULL;
+}
+
+DefineFunc_IsSupportedLegacy(PVRDRIBufferCreateFromFdsWithModifier,
+ BufferCreateFromFdsWithModifier)
+
+PVRDRIBufferImpl *
+PVRDRIBufferCreateFromFdsWithModifier(PVRDRIScreenImpl *psScreenImpl,
+ int iWidth,
+ int iHeight,
+ uint64_t uiModifier,
+ unsigned uiNumPlanes,
+ const int *piFd,
+ const int *piStride,
+ const int *piOffset,
+ const unsigned int *puiWidthShift,
+ const unsigned int *puiHeightShift)
+{
+ CallFuncLegacy(PVRDRIBufferCreateFromFdsWithModifier,
+ BufferCreateFromFdsWithModifier,
+ psScreenImpl,
+ iWidth,
+ iHeight,
+ uiModifier,
+ uiNumPlanes,
+ piFd,
+ piStride,
+ piOffset,
+ puiWidthShift,
+ puiHeightShift);
+
+ if (uiModifier == DRM_FORMAT_MOD_INVALID)
+ {
+ CallFuncLegacy(PVRDRIBufferCreateFromFds,
+ BufferCreateFromFds,
+ psScreenImpl,
+ iWidth,
+ iHeight,
+ uiNumPlanes,
+ piFd,
+ piStride,
+ piOffset,
+ puiWidthShift,
+ puiHeightShift);
+ }
+
+ return NULL;
+}
+
+PVRDRIBufferImpl *
+PVRDRISubBufferCreate(PVRDRIScreenImpl *psScreen,
+ PVRDRIBufferImpl *psParentBuffer,
+ int plane)
+{
+ CallFuncLegacy(PVRDRISubBufferCreate,
+ SubBufferCreate,
+ psScreen,
+ psParentBuffer,
+ plane);
+
+ return NULL;
+}
+
+void
+PVRDRIBufferDestroy(PVRDRIBufferImpl *psBuffer)
+{
+ CallFuncLegacy(PVRDRIBufferDestroy,
+ BufferDestroy,
+ psBuffer);
+}
+
+int
+PVRDRIBufferGetFd(PVRDRIBufferImpl *psBuffer)
+{
+ CallFuncLegacy(PVRDRIBufferGetFd,
+ BufferGetFd,
+ psBuffer);
+
+ return -1;
+}
+
+int
+PVRDRIBufferGetHandle(PVRDRIBufferImpl *psBuffer)
+{
+ CallFuncLegacy(PVRDRIBufferGetHandle,
+ BufferGetHandle,
+ psBuffer);
+
+ return 0;
+}
+
+uint64_t
+PVRDRIBufferGetModifier(PVRDRIBufferImpl *psBuffer)
+{
+ CallFuncLegacy(PVRDRIBufferGetModifier,
+ BufferGetModifier,
+ psBuffer);
+
+ return DRM_FORMAT_MOD_INVALID;
+}
+
+int
+PVRDRIBufferGetName(PVRDRIBufferImpl *psBuffer)
+{
+ CallFuncLegacy(PVRDRIBufferGetName,
+ BufferGetName,
+ psBuffer);
+
+ return 0;
+}
+
+DefineFunc_IsSupportedLegacy(PVRDRIBufferGetOffset, BufferGetOffset)
+
+int
+PVRDRIBufferGetOffset(PVRDRIBufferImpl *psBuffer)
+{
+ CallFuncLegacy(PVRDRIBufferGetOffset,
+ BufferGetOffset,
+ psBuffer);
+
+ return 0;
+}
+
+IMGEGLImage *
+PVRDRIEGLImageCreate(void)
+{
+ CallFuncLegacy(PVRDRIEGLImageCreate,
+ EGLImageCreate);
+
+ return NULL;
+}
+
+IMGEGLImage *
+PVRDRIEGLImageCreateFromBuffer(int iWidth,
+ int iHeight,
+ int iStride,
+ IMG_PIXFMT ePixelFormat,
+ IMG_YUV_COLORSPACE eColourSpace,
+ IMG_YUV_CHROMA_INTERP eChromaUInterp,
+ IMG_YUV_CHROMA_INTERP eChromaVInterp,
+ PVRDRIBufferImpl *psBuffer)
+{
+ CallFuncLegacy(PVRDRIEGLImageCreateFromBuffer,
+ EGLImageCreateFromBuffer,
+ iWidth,
+ iHeight,
+ iStride,
+ ePixelFormat,
+ eColourSpace,
+ eChromaUInterp,
+ eChromaVInterp,
+ psBuffer);
+
+ return NULL;
+}
+
+IMGEGLImage *
+PVRDRIEGLImageCreateFromSubBuffer(IMG_PIXFMT ePixelFormat,
+ PVRDRIBufferImpl *psSubBuffer)
+{
+ CallFuncLegacy(PVRDRIEGLImageCreateFromSubBuffer,
+ EGLImageCreateFromSubBuffer,
+ ePixelFormat,
+ psSubBuffer);
+
+ return NULL;
+}
+
+IMGEGLImage *
+PVRDRIEGLImageDup(IMGEGLImage *psIn)
+{
+ CallFuncLegacy(PVRDRIEGLImageDup,
+ EGLImageDup,
+ psIn);
+
+ return NULL;
+}
+
+void
+PVRDRIEGLImageSetCallbackData(IMGEGLImage *psEGLImage, __DRIimage *image)
+{
+ CallFuncLegacy(PVRDRIEGLImageSetCallbackData,
+ EGLImageSetCallbackData,
+ psEGLImage,
+ image);
+}
+
+void
+PVRDRIEGLImageDestroyExternal(PVRDRIScreenImpl *psScreenImpl,
+ IMGEGLImage *psEGLImage,
+ PVRDRIEGLImageType eglImageType)
+{
+ CallFuncLegacy(PVRDRIEGLImageDestroyExternal,
+ EGLImageDestroyExternal,
+ psScreenImpl,
+ psEGLImage,
+ eglImageType);
+}
+
+void
+PVRDRIEGLImageFree(IMGEGLImage *psEGLImage)
+{
+ CallFuncLegacy(PVRDRIEGLImageFree,
+ EGLImageFree,
+ psEGLImage);
+}
+
+void
+PVRDRIEGLImageGetAttribs(IMGEGLImage *psEGLImage,
+ PVRDRIBufferAttribs *psAttribs)
+{
+ CallFuncLegacy(PVRDRIEGLImageGetAttribs,
+ EGLImageGetAttribs,
+ psEGLImage,
+ psAttribs);
+}
+
+void *
+PVRDRICreateFenceImpl(PVRDRIAPIType eAPI,
+ PVRDRIScreenImpl *psScreenImpl,
+ PVRDRIContextImpl *psContextImpl)
+{
+ CallFuncLegacy(PVRDRICreateFenceImpl,
+ CreateFence,
+ eAPI,
+ psScreenImpl,
+ psContextImpl);
+
+ return NULL;
+}
+
+void *
+PVRDRICreateFenceFdImpl(PVRDRIAPIType eAPI,
+ PVRDRIScreenImpl *psScreenImpl,
+ PVRDRIContextImpl *psContextImpl,
+ int iFd)
+{
+ CallFunc(CreateFenceFd, 2,
+ eAPI,
+ psScreenImpl,
+ psContextImpl,
+ iFd);
+
+ return NULL;
+}
+
+unsigned PVRDRIGetFenceCapabilitiesImpl(PVRDRIScreenImpl *psScreenImpl)
+{
+ CallFunc(GetFenceCapabilities, 2,
+ psScreenImpl);
+
+ return 0;
+}
+
+int PVRDRIGetFenceFdImpl(void *psDRIFence)
+{
+ CallFunc(GetFenceFd, 2,
+ psDRIFence);
+
+ return -1;
+}
+
+void
+PVRDRIDestroyFenceImpl(void *psDRIFence)
+{
+ CallFuncLegacy(PVRDRIDestroyFenceImpl,
+ DestroyFence,
+ psDRIFence);
+}
+
+bool
+PVRDRIClientWaitSyncImpl(PVRDRIAPIType eAPI,
+ PVRDRIContextImpl *psContextImpl,
+ void *psDRIFence,
+ bool bFlushCommands,
+ bool bTimeout,
+ uint64_t uiTimeout)
+{
+ CallFuncLegacy(PVRDRIClientWaitSyncImpl,
+ ClientWaitSync,
+ eAPI,
+ psContextImpl,
+ psDRIFence,
+ bFlushCommands,
+ bTimeout,
+ uiTimeout);
+
+ return false;
+}
+
+bool
+PVRDRIServerWaitSyncImpl(PVRDRIAPIType eAPI,
+ PVRDRIContextImpl *psContextImpl,
+ void *psDRIFence)
+{
+ CallFuncLegacy(PVRDRIServerWaitSyncImpl,
+ ServerWaitSync,
+ eAPI,
+ psContextImpl,
+ psDRIFence);
+
+ return false;
+}
+
+void
+PVRDRIDestroyFencesImpl(PVRDRIScreenImpl *psScreenImpl)
+{
+ CallFuncLegacy(PVRDRIDestroyFencesImpl,
+ DestroyFences,
+ psScreenImpl);
+}
+
+bool
+PVRDRIEGLDrawableConfigFromGLMode(PVRDRIDrawableImpl *psPVRDrawable,
+ PVRDRIConfigInfo *psConfigInfo,
+ int supportedAPIs,
+ IMG_PIXFMT ePixFmt)
+{
+ CallFuncLegacy(PVRDRIEGLDrawableConfigFromGLMode,
+ EGLDrawableConfigFromGLMode,
+ psPVRDrawable,
+ psConfigInfo,
+ supportedAPIs,
+ ePixFmt);
+
+ return false;
+}
+
+DefineFunc_IsSupportedLegacy(PVRDRIBlitEGLImage, BlitEGLImage)
+
+bool
+PVRDRIBlitEGLImage(PVRDRIScreenImpl *psScreenImpl,
+ PVRDRIContextImpl *psContextImpl,
+ IMGEGLImage *psDstImage,
+ PVRDRIBufferImpl *psDstBuffer,
+ IMGEGLImage *psSrcImage,
+ PVRDRIBufferImpl *psSrcBuffer,
+ int iDstX, int iDstY,
+ int iDstWidth, int iDstHeight,
+ int iSrcX, int iSrcY,
+ int iSrcWidth, int iSrcHeight,
+ int iFlushFlag)
+{
+ CallFuncLegacy(PVRDRIBlitEGLImage,
+ BlitEGLImage,
+ psScreenImpl,
+ psContextImpl,
+ psDstImage, psDstBuffer,
+ psSrcImage, psSrcBuffer,
+ iDstX, iDstY,
+ iDstWidth, iDstHeight,
+ iSrcX, iSrcY,
+ iSrcWidth, iSrcHeight,
+ iFlushFlag);
+
+ return false;
+}
+
+DefineFunc_IsSupportedLegacy(PVRDRIMapEGLImage, MapEGLImage)
+
+void *
+PVRDRIMapEGLImage(PVRDRIScreenImpl *psScreenImpl,
+ PVRDRIContextImpl *psContextImpl,
+ IMGEGLImage *psImage,
+ PVRDRIBufferImpl *psBuffer,
+ int iX, int iY, int iWidth, int iHeight,
+ unsigned uiFlags, int *iStride, void **ppvData)
+{
+ CallFuncLegacy(PVRDRIMapEGLImage,
+ MapEGLImage,
+ psScreenImpl,
+ psContextImpl,
+ psImage, psBuffer,
+ iX, iY, iWidth, iHeight,
+ uiFlags, iStride, ppvData);
+
+ return false;
+}
+
+bool
+PVRDRIUnmapEGLImage(PVRDRIScreenImpl *psScreenImpl,
+ PVRDRIContextImpl *psContextImpl,
+ IMGEGLImage *psImage,
+ PVRDRIBufferImpl *psBuffer,
+ void *pvData)
+{
+ CallFuncLegacy(PVRDRIUnmapEGLImage,
+ UnmapEGLImage,
+ psScreenImpl,
+ psContextImpl,
+ psImage, psBuffer,
+ pvData);
+
+ return false;
+}
+
+bool
+PVRDRIMesaFormatSupported(unsigned fmt)
+{
+ CallFuncLegacy(PVRDRIMesaFormatSupported,
+ MesaFormatSupported,
+ fmt);
+
+ return false;
+}
+
+unsigned
+PVRDRIDepthStencilBitArraySize(void)
+{
+ CallFuncLegacy(PVRDRIDepthStencilBitArraySize,
+ DepthStencilBitArraySize);
+
+ return 0;
+}
+
+const uint8_t *
+PVRDRIDepthBitsArray(void)
+{
+ CallFuncLegacy(PVRDRIDepthBitsArray,
+ DepthBitsArray);
+
+ return NULL;
+}
+
+const uint8_t *
+PVRDRIStencilBitsArray(void)
+{
+ CallFuncLegacy(PVRDRIStencilBitsArray,
+ StencilBitsArray);
+
+ return NULL;
+}
+
+unsigned
+PVRDRIMSAABitArraySize(void)
+{
+ CallFuncLegacy(PVRDRIMSAABitArraySize,
+ MSAABitArraySize);
+
+ return 0;
+}
+
+const uint8_t *
+PVRDRIMSAABitsArray(void)
+{
+ CallFuncLegacy(PVRDRIMSAABitsArray,
+ MSAABitsArray);
+
+ return NULL;
+}
+
+uint32_t
+PVRDRIMaxPBufferWidth(void)
+{
+ CallFuncLegacy(PVRDRIMaxPBufferWidth,
+ MaxPBufferWidth);
+
+ return 0;
+}
+
+uint32_t
+PVRDRIMaxPBufferHeight(void)
+{
+ CallFuncLegacy(PVRDRIMaxPBufferHeight,
+ MaxPBufferHeight);
+
+ return 0;
+}
+
+
+unsigned
+PVRDRIGetNumAPIFuncs(PVRDRIAPIType eAPI)
+{
+ CallFuncLegacy(PVRDRIGetNumAPIFuncs,
+ GetNumAPIFuncs,
+ eAPI);
+
+ return 0;
+}
+
+const char *
+PVRDRIGetAPIFunc(PVRDRIAPIType eAPI, unsigned index)
+{
+ CallFuncLegacy(PVRDRIGetAPIFunc,
+ GetAPIFunc,
+ eAPI,
+ index);
+
+ return NULL;
+}
+
+int
+PVRDRIQuerySupportedFormats(PVRDRIScreenImpl *psScreenImpl,
+ unsigned uNumFormats,
+ const int *iFormats,
+ const IMG_PIXFMT *peImgFormats,
+ bool *bSupported)
+{
+ CallFuncLegacy(PVRDRIQuerySupportedFormats,
+ QuerySupportedFormats,
+ psScreenImpl,
+ uNumFormats,
+ iFormats,
+ peImgFormats,
+ bSupported);
+
+ return -1;
+}
+
+int
+PVRDRIQueryModifiers(PVRDRIScreenImpl *psScreenImpl,
+ int iFormat,
+ IMG_PIXFMT eImgFormat,
+ uint64_t *puModifiers,
+ unsigned *puExternalOnly)
+{
+ CallFuncLegacy(PVRDRIQueryModifiers,
+ QueryModifiers,
+ psScreenImpl,
+ iFormat,
+ eImgFormat,
+ puModifiers,
+ puExternalOnly);
+
+ return -1;
+}
diff --git a/src/mesa/drivers/dri/pvr/pvrdrawable.c b/src/mesa/drivers/dri/pvr/pvrdrawable.c
new file mode 100644
index 00000000000..a725645f7b6
--- /dev/null
+++ b/src/mesa/drivers/dri/pvr/pvrdrawable.c
@@ -0,0 +1,542 @@
+/* -*- mode: c; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* vi: set ts=8 sw=8 sts=8: */
+/*
+ * 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 "util/u_atomic.h"
+
+#include "dri_util.h"
+
+#include "pvrdri.h"
+#include "pvrimage.h"
+
+static inline void PVRDRIMarkRenderSurfaceAsInvalid(PVRDRIDrawable *psPVRDrawable)
+{
+ PVRDRIContext *psPVRContext = psPVRDrawable->psPVRContext;
+
+ if (psPVRContext)
+ {
+
+ PVRDRIEGLMarkRendersurfaceInvalid(psPVRContext->eAPI,
+ psPVRContext->psPVRScreen->psImpl,
+ psPVRContext->psImpl);
+ }
+}
+
+/*************************************************************************/ /*!
+ PVR drawable local functions (image driver loader)
+*/ /**************************************************************************/
+
+static inline void PVRDrawableImageDestroy(PVRDRIDrawable *psPVRDrawable)
+{
+ if (psPVRDrawable->psImage)
+ {
+ PVRDRIUnrefImage(psPVRDrawable->psImage);
+ psPVRDrawable->psImage = NULL;
+ }
+}
+
+static inline void PVRDrawableImageAccumDestroy(PVRDRIDrawable *psPVRDrawable)
+{
+ if (psPVRDrawable->psImageAccum)
+ {
+ PVRDRIUnrefImage(psPVRDrawable->psImageAccum);
+ psPVRDrawable->psImageAccum = NULL;
+ }
+}
+
+static void PVRDrawableImageUpdate(PVRDRIDrawable *psPVRDrawable)
+{
+ if (psPVRDrawable->psImage != psPVRDrawable->psDRI)
+ {
+ assert(PVRDRIImageGetSharedBuffer(psPVRDrawable->psDRI) != NULL);
+
+ PVRDrawableImageDestroy(psPVRDrawable);
+
+ PVRDRIRefImage(psPVRDrawable->psDRI);
+ psPVRDrawable->psImage = psPVRDrawable->psDRI;
+ }
+
+ if (psPVRDrawable->psImageAccum != psPVRDrawable->psDRIAccum)
+ {
+ PVRDrawableImageAccumDestroy(psPVRDrawable);
+
+ if (psPVRDrawable->psDRIAccum)
+ {
+ PVRDRIRefImage(psPVRDrawable->psDRIAccum);
+ psPVRDrawable->psImageAccum = psPVRDrawable->psDRIAccum;
+ }
+ }
+}
+
+/*************************************************************************/ /*!
+ Function Name : PVRImageDrawableGetNativeInfo
+ Inputs : psPVRDrawable
+ Returns : Boolean
+ Description : Update native drawable information.
+*/ /**************************************************************************/
+static bool PVRImageDrawableGetNativeInfo(PVRDRIDrawable *psPVRDrawable)
+{
+ __DRIdrawable *psDRIDrawable = psPVRDrawable->psDRIDrawable;
+ __DRIscreen *psDRIScreen = psPVRDrawable->psPVRScreen->psDRIScreen;
+ struct __DRIimageList sImages;
+ uint32_t uiBufferMask;
+ const PVRDRIImageFormat *psFormat;
+
+ assert(psDRIScreen->image.loader != NULL);
+ assert(psDRIScreen->image.loader->getBuffers);
+
+ psFormat = PVRDRIIMGPixelFormatToImageFormat(psPVRDrawable->psPVRScreen,
+ psPVRDrawable->ePixelFormat);
+ if (!psFormat)
+ {
+ errorMessage("%s: Unsupported format (format = %u)\n",
+ __func__, psPVRDrawable->ePixelFormat);
+ return false;
+ }
+
+ if (psPVRDrawable->sConfig.sGLMode.doubleBufferMode)
+ {
+ uiBufferMask = __DRI_IMAGE_BUFFER_BACK;
+ }
+ else
+ {
+ uiBufferMask = __DRI_IMAGE_BUFFER_FRONT;
+ }
+
+#if defined(DRI_IMAGE_HAS_BUFFER_PREV)
+ uiBufferMask |= __DRI_IMAGE_BUFFER_PREV;
+#endif
+
+ if (!psDRIScreen->image.loader->getBuffers(psDRIDrawable,
+ psFormat->iDRIFormat,
+ NULL,
+ psDRIDrawable->loaderPrivate,
+ uiBufferMask,
+ &sImages))
+ {
+ errorMessage("%s: Image get buffers call failed\n", __func__);
+ return false;
+ }
+
+ psPVRDrawable->psDRI =
+ (sImages.image_mask & __DRI_IMAGE_BUFFER_BACK) ?
+ sImages.back : sImages.front;
+
+#if defined(DRI_IMAGE_HAS_BUFFER_PREV)
+ if (sImages.image_mask & __DRI_IMAGE_BUFFER_PREV)
+ {
+ psPVRDrawable->psDRIAccum = sImages.prev;
+ }
+ else
+#endif
+ {
+ psPVRDrawable->psDRIAccum = NULL;
+ }
+
+ return true;
+}
+
+/*************************************************************************/ /*!
+ Function Name : PVRImageDrawableCreate
+ Inputs : psPVRDrawable
+ Returns : Boolean
+ Description : Create drawable
+*/ /**************************************************************************/
+static bool PVRImageDrawableCreate(PVRDRIDrawable *psPVRDrawable)
+{
+ __DRIdrawable *psDRIDrawable = psPVRDrawable->psDRIDrawable;
+ uint32_t uBytesPerPixel;
+ PVRDRIBufferAttribs sBufferAttribs;
+
+ if (!PVRImageDrawableGetNativeInfo(psPVRDrawable))
+ {
+ return false;
+ }
+
+ PVRDRIEGLImageGetAttribs(
+ PVRDRIImageGetEGLImage(psPVRDrawable->psDRI),
+ &sBufferAttribs);
+ uBytesPerPixel = PVRDRIPixFmtGetBlockSize(sBufferAttribs.ePixFormat);
+
+ psDRIDrawable->w = sBufferAttribs.uiWidth;
+ psDRIDrawable->h = sBufferAttribs.uiHeight;
+ psPVRDrawable->uStride = sBufferAttribs.uiStrideInBytes;
+ psPVRDrawable->uBytesPerPixel = uBytesPerPixel;
+
+ PVRDrawableImageUpdate(psPVRDrawable);
+
+ if (!PVREGLDrawableCreate(psPVRDrawable->psPVRScreen->psImpl,
+ psPVRDrawable->psImpl))
+ {
+ errorMessage("%s: Couldn't create EGL drawable\n", __func__);
+ return false;
+ }
+
+ return true;
+}
+
+/*************************************************************************/ /*!
+ Function Name : PVRImageDrawableUpdate
+ Inputs : psPVRDrawable
+ Returns : Boolean
+ Description : Update drawable
+*/ /**************************************************************************/
+static bool PVRImageDrawableUpdate(PVRDRIDrawable *psPVRDrawable,
+ bool bAllowRecreate)
+{
+ __DRIdrawable *psDRIDrawable = psPVRDrawable->psDRIDrawable;
+ uint32_t uBytesPerPixel;
+ PVRDRIBufferAttribs sBufferAttribs;
+ bool bRecreate;
+
+ PVRDRIEGLImageGetAttribs(
+ PVRDRIImageGetEGLImage(psPVRDrawable->psDRI),
+ &sBufferAttribs);
+ uBytesPerPixel = PVRDRIPixFmtGetBlockSize(sBufferAttribs.ePixFormat);
+
+ bRecreate = (!psPVRDrawable->sConfig.sGLMode.doubleBufferMode &&
+ psPVRDrawable->psImage !=
+ psPVRDrawable->psDRI) ||
+ (psDRIDrawable->w != sBufferAttribs.uiWidth) ||
+ (psDRIDrawable->h != sBufferAttribs.uiHeight) ||
+ (psPVRDrawable->uStride !=
+ sBufferAttribs.uiStrideInBytes) ||
+ (psPVRDrawable->uBytesPerPixel != uBytesPerPixel);
+
+ if (bRecreate)
+ {
+ if (bAllowRecreate)
+ {
+ PVRDRIMarkRenderSurfaceAsInvalid(psPVRDrawable);
+
+ psDRIDrawable->w = sBufferAttribs.uiWidth;
+ psDRIDrawable->h = sBufferAttribs.uiHeight;
+ psPVRDrawable->uStride = sBufferAttribs.uiStrideInBytes;
+ psPVRDrawable->uBytesPerPixel = uBytesPerPixel;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ PVRDrawableImageUpdate(psPVRDrawable);
+
+ if (bRecreate)
+ {
+ if (!PVREGLDrawableRecreate(psPVRDrawable->psPVRScreen->psImpl,
+ psPVRDrawable->psImpl))
+ {
+ errorMessage("%s: Couldn't recreate EGL drawable\n",
+ __func__);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/*************************************************************************/ /*!
+ PVR drawable local functions
+*/ /**************************************************************************/
+
+/*************************************************************************/ /*!
+ Function Name : PVRDRIDrawableUpdate
+ Inputs : psPVRDrawable
+ Description : Update drawable
+*/ /**************************************************************************/
+static bool PVRDRIDrawableUpdate(PVRDRIDrawable *psPVRDrawable,
+ bool bAllowRecreate)
+{
+ bool bRes;
+ int iInfoInvalid = 0;
+
+ /*
+ * The test for bDrawableUpdating is needed because drawable
+ * parameters are fetched (via KEGLGetDrawableParameters) when
+ * a drawable is recreated.
+ * The test for bFlushInProgress is to prevent the drawable
+ * information being updated during a flush, which could result
+ * in a call back into the Mesa platform code during the
+ * processing for a buffer swap, which could corrupt the platform
+ * state.
+ */
+ if (psPVRDrawable->bDrawableUpdating ||
+ psPVRDrawable->bFlushInProgress)
+ {
+ return false;
+ }
+ psPVRDrawable->bDrawableUpdating = true;
+
+ if (psPVRDrawable->psPVRScreen->bUseInvalidate)
+ {
+ iInfoInvalid = p_atomic_read(&psPVRDrawable->iInfoInvalid);
+ bRes = !iInfoInvalid;
+ if (bRes)
+ {
+ goto ExitNotUpdating;
+ }
+ }
+
+ bRes = PVRImageDrawableGetNativeInfo(psPVRDrawable);
+ if (!bRes)
+ {
+ goto ExitNotUpdating;
+ }
+
+ bRes = PVRImageDrawableUpdate(psPVRDrawable, bAllowRecreate);
+ if (bRes && iInfoInvalid)
+ {
+ p_atomic_add(&psPVRDrawable->iInfoInvalid, -iInfoInvalid);
+ }
+
+ExitNotUpdating:
+ psPVRDrawable->bDrawableUpdating = false;
+ return bRes;
+}
+
+/*************************************************************************/ /*!
+ Function Name : PVRDRIDrawableRecreateV0
+ Inputs : psPVRDrawable
+ Description : Recreate drawable
+*/ /**************************************************************************/
+bool PVRDRIDrawableRecreateV0(PVRDRIDrawable *psPVRDrawable)
+{
+ return PVRDRIDrawableUpdate(psPVRDrawable, true);
+}
+
+/*************************************************************************/ /*!
+ PVR drawable interface
+*/ /**************************************************************************/
+bool PVRDRIDrawableInit(PVRDRIDrawable *psPVRDrawable)
+{
+ if (psPVRDrawable->bInitialised)
+ {
+ return true;
+ }
+
+ if (!PVRImageDrawableCreate(psPVRDrawable))
+ {
+ return false;
+ }
+
+ psPVRDrawable->bInitialised = true;
+
+ return true;
+}
+
+void PVRDRIDrawableDeinit(PVRDRIDrawable *psPVRDrawable)
+{
+ (void) PVREGLDrawableDestroy(psPVRDrawable->psPVRScreen->psImpl,
+ psPVRDrawable->psImpl);
+
+ PVRDrawableImageDestroy(psPVRDrawable);
+ PVRDrawableImageAccumDestroy(psPVRDrawable);
+
+ psPVRDrawable->bInitialised = false;
+}
+
+static bool PVRDRIDrawableGetParameters(PVRDRIDrawable *psPVRDrawable,
+ PVRDRIBufferImpl **ppsDstBuffer,
+ PVRDRIBufferImpl **ppsAccumBuffer)
+{
+ if (ppsDstBuffer || ppsAccumBuffer)
+ {
+ PVRDRIBufferImpl *psDstBuffer;
+ PVRDRIBufferImpl *psAccumBuffer;
+
+ psDstBuffer = PVRDRIImageGetSharedBuffer(psPVRDrawable->psImage);
+ if (!psDstBuffer)
+ {
+ errorMessage("%s: Couldn't get backing buffer\n",
+ __func__);
+ return false;
+ }
+
+ if (psPVRDrawable->psImageAccum)
+ {
+ psAccumBuffer =
+ PVRDRIImageGetSharedBuffer(psPVRDrawable->psImageAccum);
+ if (!psAccumBuffer)
+ {
+ psAccumBuffer = psDstBuffer;
+ }
+ }
+ else
+ {
+ psAccumBuffer = psDstBuffer;
+ }
+
+ if (ppsDstBuffer)
+ {
+ *ppsDstBuffer = psDstBuffer;
+ }
+
+ if (ppsAccumBuffer)
+ {
+ *ppsAccumBuffer = psAccumBuffer;
+ }
+ }
+
+ return true;
+}
+
+bool PVRDRIDrawableGetParametersV0(PVRDRIDrawable *psPVRDrawable,
+ PVRDRIBufferImpl **ppsDstBuffer,
+ PVRDRIBufferImpl **ppsAccumBuffer,
+ PVRDRIBufferAttribs *psAttribs,
+ bool *pbDoubleBuffered)
+{
+ /*
+ * Some drawable updates may be required, which stop short of
+ * recreating the drawable.
+ */
+ (void) PVRDRIDrawableUpdate(psPVRDrawable, false);
+
+ if (!PVRDRIDrawableGetParameters(psPVRDrawable,
+ ppsDstBuffer,
+ ppsAccumBuffer))
+ {
+ return false;
+ }
+
+ if (psAttribs)
+ {
+ psAttribs->uiWidth = psPVRDrawable->psDRIDrawable->w;
+ psAttribs->uiHeight = psPVRDrawable->psDRIDrawable->h;
+ psAttribs->ePixFormat = psPVRDrawable->ePixelFormat;
+ psAttribs->uiStrideInBytes = psPVRDrawable->uStride;
+ }
+
+ if (pbDoubleBuffered)
+ {
+ *pbDoubleBuffered =
+ psPVRDrawable->sConfig.sGLMode.doubleBufferMode;
+ }
+
+ return true;
+}
+
+bool PVRDRIDrawableGetParametersV1(PVRDRIDrawable *psPVRDrawable,
+ bool bAllowRecreate,
+ PVRDRIBufferImpl **ppsDstBuffer,
+ PVRDRIBufferImpl **ppsAccumBuffer,
+ PVRDRIBufferAttribs *psAttribs,
+ bool *pbDoubleBuffered)
+{
+ if (!PVRDRIDrawableUpdate(psPVRDrawable, bAllowRecreate))
+ {
+ if (bAllowRecreate)
+ {
+ return false;
+ }
+ }
+
+ if (!PVRDRIDrawableGetParameters(psPVRDrawable,
+ ppsDstBuffer,
+ ppsAccumBuffer))
+ {
+ return false;
+ }
+
+ if (psAttribs)
+ {
+ psAttribs->uiWidth = psPVRDrawable->psDRIDrawable->w;
+ psAttribs->uiHeight = psPVRDrawable->psDRIDrawable->h;
+ psAttribs->ePixFormat = psPVRDrawable->ePixelFormat;
+ psAttribs->uiStrideInBytes = psPVRDrawable->uStride;
+ }
+
+ if (pbDoubleBuffered)
+ {
+ *pbDoubleBuffered =
+ psPVRDrawable->sConfig.sGLMode.doubleBufferMode;
+ }
+
+ return true;
+}
+
+bool PVRDRIDrawableQuery(const PVRDRIDrawable *psPVRDrawable,
+ PVRDRIBufferAttrib eBufferAttrib,
+ uint32_t *uiValueOut)
+{
+ if (!psPVRDrawable || !uiValueOut)
+ {
+ return false;
+ }
+
+ switch (eBufferAttrib)
+ {
+ case PVRDRI_BUFFER_ATTRIB_TYPE:
+ *uiValueOut = (uint32_t) psPVRDrawable->eType;
+ return true;
+ case PVRDRI_BUFFER_ATTRIB_WIDTH:
+ *uiValueOut = (uint32_t) psPVRDrawable->psDRIDrawable->w;
+ return true;
+ case PVRDRI_BUFFER_ATTRIB_HEIGHT:
+ *uiValueOut = (uint32_t) psPVRDrawable->psDRIDrawable->h;
+ return true;
+ case PVRDRI_BUFFER_ATTRIB_STRIDE:
+ *uiValueOut = (uint32_t) psPVRDrawable->uStride;
+ return true;
+ case PVRDRI_BUFFER_ATTRIB_PIXEL_FORMAT:
+ STATIC_ASSERT(sizeof(psPVRDrawable->ePixelFormat) <= sizeof(*uiValueOut));
+ *uiValueOut = (uint32_t) psPVRDrawable->ePixelFormat;
+ return true;
+ case PVRDRI_BUFFER_ATTRIB_INVALID:
+ errorMessage("%s: Invalid attribute", __func__);
+ assert(0);
+ break;
+ }
+
+ return false;
+}
+
+bool PVRDRIDrawableGetParametersV2(PVRDRIDrawable *psPVRDrawable,
+ uint32_t uiFlags,
+ PVRDRIBufferImpl **ppsDstBuffer,
+ PVRDRIBufferImpl **ppsAccumBuffer)
+{
+ const bool bNoUpdate = uiFlags & PVRDRI_GETPARAMS_FLAG_NO_UPDATE;
+
+ if (!bNoUpdate)
+ {
+ const bool bAllowRecreate =
+ uiFlags & PVRDRI_GETPARAMS_FLAG_ALLOW_RECREATE;
+
+ if (!PVRDRIDrawableUpdate(psPVRDrawable, bAllowRecreate))
+ {
+ if (bAllowRecreate)
+ {
+ return false;
+ }
+ }
+ }
+
+ return PVRDRIDrawableGetParameters(psPVRDrawable,
+ ppsDstBuffer, ppsAccumBuffer);
+}
diff --git a/src/mesa/drivers/dri/pvr/pvrdri.c b/src/mesa/drivers/dri/pvr/pvrdri.c
new file mode 100644
index 00000000000..b53ddc5c621
--- /dev/null
+++ b/src/mesa/drivers/dri/pvr/pvrdri.c
@@ -0,0 +1,1018 @@
+/* -*- mode: c; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* vi: set ts=8 sw=8 sts=8: */
+/*
+ * 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 <pthread.h>
+#include <string.h>
+#include <xf86drm.h>
+
+#include "EGL/egl.h"
+#include "EGL/eglext.h"
+
+#include "util/u_atomic.h"
+#include "dri_util.h"
+
+#include "pvrdri.h"
+#include "pvrimage.h"
+
+#include "pvrmesa.h"
+
+#define PVR_IMAGE_LOADER_VER_MIN 1
+
+#define PVRDRI_FLUSH_WAIT_FOR_HW (1U << 0)
+#define PVRDRI_FLUSH_NEW_EXTERNAL_FRAME (1U << 1)
+#define PVRDRI_FLUSH_ALL_SURFACES (1U << 2)
+
+typedef struct PVRBufferRec
+{
+ __DRIbuffer sDRIBuffer;
+ PVRDRIBufferImpl *psImpl;
+} PVRBuffer;
+
+/* We need to know the current screen in order to lookup EGL images. */
+static __thread PVRDRIScreen *gpsPVRScreen;
+
+/*************************************************************************/ /*!
+ 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 bool
+PVRDRIFlushBuffers(PVRDRIContext *psPVRContext,
+ PVRDRIDrawable *psPVRDrawable,
+ uint32_t uiFlags)
+{
+ assert(!(uiFlags & ~(PVRDRI_FLUSH_WAIT_FOR_HW |
+ PVRDRI_FLUSH_NEW_EXTERNAL_FRAME |
+ PVRDRI_FLUSH_ALL_SURFACES)));
+
+ return PVRDRIEGLFlushBuffers(psPVRContext->eAPI,
+ psPVRContext->psPVRScreen->psImpl,
+ psPVRContext->psImpl,
+ psPVRDrawable ? psPVRDrawable->psImpl : NULL,
+ uiFlags & PVRDRI_FLUSH_ALL_SURFACES,
+ uiFlags & PVRDRI_FLUSH_NEW_EXTERNAL_FRAME,
+ uiFlags & PVRDRI_FLUSH_WAIT_FOR_HW);
+}
+
+void
+PVRDRIFlushBuffersForSwap(PVRDRIContext *psPVRContext,
+ PVRDRIDrawable *psPVRDrawable)
+{
+ if (psPVRContext)
+ {
+ /*
+ * The bFlushInProgress flag is intended to prevent new
+ * buffers being fetched whilst a flush is in progress,
+ * which may corrupt the state maintained by the Mesa
+ * platform code.
+ */
+ psPVRDrawable->bFlushInProgress = true;
+
+ (void) PVRDRIFlushBuffers(psPVRContext,
+ psPVRDrawable,
+ PVRDRI_FLUSH_NEW_EXTERNAL_FRAME);
+
+ psPVRDrawable->bFlushInProgress = false;
+ }
+}
+
+static void
+PVRDRIFlushBuffersGC(PVRDRIContext *psPVRContext, PVRDRIDrawable *psPVRDrawable)
+{
+ (void) PVRDRIFlushBuffers(psPVRContext,
+ psPVRDrawable,
+ PVRDRI_FLUSH_WAIT_FOR_HW |
+ PVRDRI_FLUSH_ALL_SURFACES);
+}
+
+static void PVRContextUnbind(PVRDRIContext *psPVRContext,
+ bool bMakeUnCurrent,
+ bool bMarkSurfaceInvalid)
+{
+ PVRDRIDrawable *psPVRDrawable = psPVRContext->psPVRDrawable;
+
+ if (bMakeUnCurrent)
+ {
+ uint32_t uiFlags = PVRDRI_FLUSH_ALL_SURFACES;
+
+ (void) PVRDRIFlushBuffers(psPVRContext, psPVRDrawable, uiFlags);
+ }
+ else if (psPVRDrawable)
+ {
+ PVRDRIFlushBuffersGC(psPVRContext, psPVRDrawable);
+ }
+
+ if (bMakeUnCurrent)
+ {
+ PVRDRIMakeUnCurrentGC(psPVRContext->eAPI,
+ psPVRContext->psPVRScreen->psImpl);
+ }
+
+ if (psPVRDrawable != NULL)
+ {
+ if (bMarkSurfaceInvalid)
+ {
+ PVRDRIEGLMarkRendersurfaceInvalid(psPVRContext->eAPI,
+ psPVRContext->psPVRScreen->psImpl,
+ psPVRContext->psImpl);
+ }
+
+ psPVRContext->psPVRDrawable = NULL;
+ psPVRDrawable->psPVRContext = NULL;
+ }
+}
+
+static inline PVRDRIContextImpl *
+getSharedContextImpl(void *pvSharedContextPrivate)
+{
+ if (pvSharedContextPrivate == NULL)
+ {
+ return NULL;
+ }
+ return ((PVRDRIContext *)pvSharedContextPrivate)->psImpl;
+}
+
+
+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);
+
+ PVRDRIDestroyFencesImpl(psPVRScreen->psImpl);
+
+ PVRDRIDestroyFormatInfo(psPVRScreen);
+
+ PVRDRIDestroyScreenImpl(psPVRScreen->psImpl);
+
+ free(psPVRScreen);
+}
+
+static inline void PVRDrawableUnbindContext(PVRDRIDrawable *psPVRDrawable)
+{
+ PVRDRIContext *psPVRContext = psPVRDrawable->psPVRContext;
+
+ if (psPVRContext)
+ {
+ PVRContextUnbind(psPVRContext, false, true);
+ }
+}
+
+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");
+ }
+}
+
+static bool PVRDRIConfigQuery(const PVRDRIConfig *psConfig,
+ PVRDRIConfigAttrib eConfigAttrib,
+ int *piValueOut)
+{
+ if (!psConfig || !piValueOut)
+ {
+ return false;
+ }
+
+ switch (eConfigAttrib)
+ {
+ case PVRDRI_CONFIG_ATTRIB_RENDERABLE_TYPE:
+ *piValueOut = psConfig->iSupportedAPIs;
+ return true;
+ case PVRDRI_CONFIG_ATTRIB_RGB_MODE:
+ *piValueOut = psConfig->sGLMode.rgbMode;
+ return true;
+ case PVRDRI_CONFIG_ATTRIB_DOUBLE_BUFFER_MODE:
+ *piValueOut = psConfig->sGLMode.doubleBufferMode;
+ return true;
+ case PVRDRI_CONFIG_ATTRIB_RED_BITS:
+ *piValueOut = psConfig->sGLMode.redBits;
+ return true;
+ case PVRDRI_CONFIG_ATTRIB_GREEN_BITS:
+ *piValueOut = psConfig->sGLMode.greenBits;
+ return true;
+ case PVRDRI_CONFIG_ATTRIB_BLUE_BITS:
+ *piValueOut = psConfig->sGLMode.blueBits;
+ return true;
+ case PVRDRI_CONFIG_ATTRIB_ALPHA_BITS:
+ *piValueOut = psConfig->sGLMode.alphaBits;
+ return true;
+ case PVRDRI_CONFIG_ATTRIB_RGB_BITS:
+ *piValueOut = psConfig->sGLMode.rgbBits;
+ return true;
+ case PVRDRI_CONFIG_ATTRIB_DEPTH_BITS:
+ *piValueOut = psConfig->sGLMode.depthBits;
+ return true;
+ case PVRDRI_CONFIG_ATTRIB_STENCIL_BITS:
+ *piValueOut = psConfig->sGLMode.stencilBits;
+ return true;
+ case PVRDRI_CONFIG_ATTRIB_SAMPLE_BUFFERS:
+ *piValueOut = psConfig->sGLMode.sampleBuffers;
+ return true;
+ case PVRDRI_CONFIG_ATTRIB_SAMPLES:
+ *piValueOut = psConfig->sGLMode.samples;
+ return true;
+ case PVRDRI_CONFIG_ATTRIB_BIND_TO_TEXTURE_RGB:
+ *piValueOut = psConfig->sGLMode.bindToTextureRgb;
+ return true;
+ case PVRDRI_CONFIG_ATTRIB_BIND_TO_TEXTURE_RGBA:
+ *piValueOut = psConfig->sGLMode.bindToTextureRgba;
+ return true;
+#if defined(__DRI_ATTRIB_YUV_BIT)
+ case PVRDRI_CONFIG_ATTRIB_YUV_ORDER:
+ *piValueOut = psConfig->sGLMode.YUVOrder;
+ return true;
+ case PVRDRI_CONFIG_ATTRIB_YUV_NUM_OF_PLANES:
+ *piValueOut = psConfig->sGLMode.YUVNumberOfPlanes;
+ return true;
+ case PVRDRI_CONFIG_ATTRIB_YUV_SUBSAMPLE:
+ *piValueOut = psConfig->sGLMode.YUVSubsample;
+ return true;
+ case PVRDRI_CONFIG_ATTRIB_YUV_DEPTH_RANGE:
+ *piValueOut = psConfig->sGLMode.YUVDepthRange;
+ return true;
+ case PVRDRI_CONFIG_ATTRIB_YUV_CSC_STANDARD:
+ *piValueOut = psConfig->sGLMode.YUVCSCStandard;
+ return true;
+ case PVRDRI_CONFIG_ATTRIB_YUV_PLANE_BPP:
+ *piValueOut = psConfig->sGLMode.YUVPlaneBPP;
+ return true;
+#endif
+ case PVRDRI_CONFIG_ATTRIB_INVALID:
+ errorMessage("%s: Invalid attribute", __func__);
+ assert(0);
+ /* fallthrough */
+#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
+ }
+
+ return false;
+}
+
+/*************************************************************************/ /*!
+ Mesa driver API functions
+*/ /**************************************************************************/
+static const __DRIconfig **PVRDRIInitScreen(__DRIscreen *psDRIScreen)
+{
+ PVRDRIScreen *psPVRScreen;
+ const __DRIconfig **configs;
+ const PVRDRICallbacks sDRICallbacks = {
+ /* Version 0 callbacks */
+ .DrawableRecreate = PVRDRIDrawableRecreateV0,
+ .DrawableGetParameters = PVRDRIDrawableGetParametersV0,
+ .ImageGetSharedType = PVRDRIImageGetSharedType,
+ .ImageGetSharedBuffer = PVRDRIImageGetSharedBuffer,
+ .ImageGetSharedEGLImage = PVRDRIImageGetSharedEGLImage,
+ .ImageGetEGLImage = PVRDRIImageGetEGLImage,
+ .ScreenGetDRIImage = PVRDRIScreenGetDRIImage,
+ .RefImage = PVRDRIRefImage,
+ .UnrefImage = PVRDRIUnrefImage,
+
+ /* Version 1 callbacks */
+ .DrawableGetParametersV1 = PVRDRIDrawableGetParametersV1,
+ .RegisterSupportInterfaceV1 = PVRDRIRegisterSupportInterfaceV1,
+
+ /* Version 2 callbacks */
+ .ConfigQuery = PVRDRIConfigQuery,
+ .DrawableGetParametersV2 = PVRDRIDrawableGetParametersV2,
+ .DrawableQuery = PVRDRIDrawableQuery,
+ };
+
+ if (!PVRLoaderIsSupported(psDRIScreen))
+ {
+ return NULL;
+ }
+
+ if (!PVRDRICompatInit(&sDRICallbacks, 3))
+ {
+ return NULL;
+ }
+
+ psPVRScreen = calloc(1, sizeof(*psPVRScreen));
+ if (psPVRScreen == NULL)
+ {
+ __driUtilMessage("%s: Couldn't allocate PVRDRIScreen",
+ __func__);
+ goto ErrorCompatDeinit;
+ }
+
+ DRIScreenPrivate(psDRIScreen) = psPVRScreen;
+ psPVRScreen->psDRIScreen = psDRIScreen;
+
+ psPVRScreen->iRefCount = 1;
+ psPVRScreen->bUseInvalidate = (psDRIScreen->dri2.useInvalidate != NULL);
+
+ psDRIScreen->extensions = PVRDRIScreenExtensions();
+
+ psPVRScreen->psImpl = PVRDRICreateScreenImpl(psDRIScreen->fd);
+ if (psPVRScreen->psImpl == NULL)
+ {
+ goto ErrorScreenFree;
+ }
+
+ if (!PVRDRIGetSupportedFormats(psPVRScreen))
+ {
+ goto ErrorScreenImplDeinit;
+ }
+
+ psDRIScreen->max_gl_es1_version =
+ PVRDRIAPIVersion(PVRDRI_API_GLES1,
+ PVRDRI_API_SUB_NONE,
+ psPVRScreen->psImpl);
+
+ psDRIScreen->max_gl_es2_version =
+ PVRDRIAPIVersion(PVRDRI_API_GLES2,
+ PVRDRI_API_SUB_NONE,
+ psPVRScreen->psImpl);
+
+ configs = PVRDRICreateConfigs();
+ if (configs == NULL)
+ {
+ __driUtilMessage("%s: No framebuffer configs", __func__);
+ goto ErrorDestroyFormatInfo;
+ }
+
+ PVRScreenPrintExtensions(psDRIScreen);
+
+ return configs;
+
+ErrorDestroyFormatInfo:
+ PVRDRIDestroyFormatInfo(psPVRScreen);
+
+ErrorScreenImplDeinit:
+ PVRDRIDestroyScreenImpl(psPVRScreen->psImpl);
+
+ErrorScreenFree:
+ free(psPVRScreen);
+
+ErrorCompatDeinit:
+ PVRDRICompatDeinit();
+
+ return NULL;
+}
+
+static void PVRDRIDestroyScreen(__DRIscreen *psDRIScreen)
+{
+ PVRDRIScreen *psPVRScreen = DRIScreenPrivate(psDRIScreen);
+
+#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);
+
+ PVRDRICompatDeinit();
+}
+
+static int PVRDRIScreenSupportedAPIs(PVRDRIScreen *psPVRScreen)
+{
+ unsigned 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;
+ }
+
+ return supported;
+}
+
+static GLboolean PVRDRICreateContext(gl_api eMesaAPI,
+ const struct gl_config *psGLMode,
+ __DRIcontext *psDRIContext,
+ const struct __DriverContextConfig *psCtxConfig,
+ unsigned *puError,
+ void *pvSharedContextPrivate)
+{
+ __DRIscreen *psDRIScreen = psDRIContext->driScreenPriv;
+ PVRDRIScreen *psPVRScreen = DRIScreenPrivate(psDRIScreen);
+ PVRDRIContext *psPVRContext;
+ PVRDRIAPISubType eAPISub = PVRDRI_API_SUB_NONE;
+ bool notify_reset = false;
+ unsigned uPriority = PVRDRI_CONTEXT_PRIORITY_MEDIUM;
+ bool bResult;
+
+ 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:
+ psPVRContext->eAPI = PVRDRI_API_GLES1;
+ break;
+ case API_OPENGLES2:
+ psPVRContext->eAPI = PVRDRI_API_GLES2;
+ break;
+ default:
+ __driUtilMessage("%s: Unsupported API: %d",
+ __func__,
+ (int)eMesaAPI);
+ goto ErrorContextFree;
+ }
+
+ if (psCtxConfig->attribute_mask & __DRIVER_CONTEXT_ATTRIB_RESET_STRATEGY)
+ {
+ switch (psCtxConfig->reset_strategy)
+ {
+ case __DRI_CTX_RESET_LOSE_CONTEXT:
+ notify_reset = true;
+ break;
+ default:
+ __driUtilMessage("%s: Unsupported reset strategy: %d",
+ __func__,
+ (int)psCtxConfig->reset_strategy);
+ goto ErrorContextFree;
+ }
+ }
+
+ if (psCtxConfig->attribute_mask & __DRIVER_CONTEXT_ATTRIB_PRIORITY)
+ {
+ uPriority = psCtxConfig->priority;
+ }
+
+ *puError = PVRDRISupportCreateContext(psPVRScreen->psImpl,
+ getSharedContextImpl(pvSharedContextPrivate),
+ &psPVRContext->sConfig,
+ psPVRContext->eAPI,
+ eAPISub,
+ psCtxConfig->major_version,
+ psCtxConfig->minor_version,
+ psCtxConfig->flags,
+ notify_reset,
+ uPriority,
+ &psPVRContext->psImpl);
+ if (*puError != __DRI_CTX_ERROR_SUCCESS)
+ {
+ goto ErrorContextFree;
+ }
+
+ /*
+ * The dispatch table must be created after the context, because
+ * PVRDRIContextCreate loads the API library, and we need the
+ * library handle to populate the dispatch table.
+ */
+ bResult = pvrdri_create_dispatch_table(psPVRScreen, psPVRContext->eAPI);
+
+ if (!bResult)
+ {
+ __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:
+ PVRDRIDestroyContextImpl(psPVRContext->psImpl,
+ psPVRContext->eAPI,
+ psPVRScreen->psImpl);
+ErrorContextFree:
+ free(psPVRContext);
+
+ return GL_FALSE;
+}
+
+static void PVRDRIDestroyContext(__DRIcontext *psDRIContext)
+{
+ PVRDRIContext *psPVRContext = (PVRDRIContext *)psDRIContext->driverPrivate;
+ PVRDRIScreen *psPVRScreen = psPVRContext->psPVRScreen;
+
+ PVRContextUnbind(psPVRContext, false, false);
+
+ PVRDRIDestroyContextImpl(psPVRContext->psImpl,
+ psPVRContext->eAPI,
+ psPVRScreen->psImpl);
+
+ free(psPVRContext);
+
+#if defined(DEBUG)
+ p_atomic_dec(&psPVRScreen->iContextAlloc);
+#endif
+
+ PVRDRIScreenRemoveReference(psPVRScreen);
+}
+
+IMG_PIXFMT PVRDRIGetPixelFormat(const struct gl_config *psGLMode)
+{
+ switch (psGLMode->rgbBits)
+ {
+ case 32:
+ case 24:
+ if (psGLMode->redMask == 0x00FF0000 &&
+ psGLMode->greenMask == 0x0000FF00 &&
+ psGLMode->blueMask == 0x000000FF)
+ {
+ if (psGLMode->alphaMask == 0xFF000000)
+ {
+ return IMG_PIXFMT_B8G8R8A8_UNORM;
+ }
+ else if (psGLMode->alphaMask == 0)
+ {
+ return IMG_PIXFMT_B8G8R8X8_UNORM;
+ }
+ }
+
+ if (psGLMode->redMask == 0x000000FF &&
+ psGLMode->greenMask == 0x0000FF00 &&
+ psGLMode->blueMask == 0x00FF0000)
+ {
+ if (psGLMode->alphaMask == 0xFF000000)
+ {
+ return IMG_PIXFMT_R8G8B8A8_UNORM;
+ }
+ else if (psGLMode->alphaMask == 0)
+ {
+ return IMG_PIXFMT_R8G8B8X8_UNORM;
+ }
+ }
+
+ __driUtilMessage("%s: Unsupported buffer format", __func__);
+ return IMG_PIXFMT_UNKNOWN;
+
+ case 16:
+ if (psGLMode->redMask == 0xF800 &&
+ psGLMode->greenMask == 0x07E0 &&
+ psGLMode->blueMask == 0x001F)
+ {
+ return IMG_PIXFMT_B5G6R5_UNORM;
+ }
+
+ default:
+ errorMessage("%s: Unsupported screen format\n", __func__);
+ return IMG_PIXFMT_UNKNOWN;
+ }
+}
+
+static GLboolean PVRDRICreateBuffer(__DRIscreen *psDRIScreen,
+ __DRIdrawable *psDRIDrawable,
+ const struct gl_config *psGLMode,
+ GLboolean bIsPixmap)
+{
+ PVRDRIScreen *psPVRScreen = DRIScreenPrivate(psDRIScreen);
+ 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->psDRIDrawable = psDRIDrawable;
+ psPVRDrawable->psPVRScreen = psPVRScreen;
+ psPVRDrawable->sConfig.sGLMode = *psGLMode;
+ psPVRDrawable->sConfig.iSupportedAPIs =
+ PVRDRIScreenSupportedAPIs(psPVRScreen);
+
+ psPVRDrawable->ePixelFormat = PVRDRIGetPixelFormat(psGLMode);
+ if (psPVRDrawable->ePixelFormat == IMG_PIXFMT_UNKNOWN)
+ {
+ __driUtilMessage("%s: Couldn't work out pixel format", __func__);
+ goto ErrorDrawableFree;
+ }
+
+ /*
+ * Mesa doesn't tell us the drawable type so treat double buffered
+ * drawables as windows (although GLX supports double buffered pbuffers)
+ * and single buffered drawables as pixmaps (although these could
+ * actually be pbuffers).
+ */
+ if (psPVRDrawable->sConfig.sGLMode.doubleBufferMode)
+ {
+ psPVRDrawable->eType = PVRDRI_DRAWABLE_WINDOW;
+ }
+ else
+ {
+ psPVRDrawable->eType = PVRDRI_DRAWABLE_PIXMAP;
+ }
+
+ psPVRDrawable->psImpl =
+ PVRDRISupportCreateDrawable(psPVRDrawable,
+ &psPVRDrawable->sConfig);
+ if (!psPVRDrawable->psImpl)
+ {
+ __driUtilMessage("%s: Couldn't allocate PVR drawable", __func__);
+ goto ErrorDrawableFree;
+ }
+
+ /* Initialisation is completed in MakeCurrent */
+#if defined(DEBUG)
+ p_atomic_inc(&psPVRScreen->iDrawableAlloc);
+#endif
+ PVRDRIScreenAddReference(psPVRScreen);
+ return GL_TRUE;
+
+ErrorDrawableFree:
+ PVRDRIDestroyDrawableImpl(psPVRDrawable->psImpl);
+ free(psPVRDrawable);
+ psDRIDrawable->driverPrivate = NULL;
+
+ return GL_FALSE;
+}
+
+static void PVRDRIDestroyBuffer(__DRIdrawable *psDRIDrawable)
+{
+ PVRDRIDrawable *psPVRDrawable = (PVRDRIDrawable *)psDRIDrawable->driverPrivate;
+ PVRDRIScreen *psPVRScreen = psPVRDrawable->psPVRScreen;
+
+ PVRDrawableUnbindContext(psPVRDrawable);
+
+ PVRDRIDrawableDeinit(psPVRDrawable);
+
+ PVREGLDrawableDestroyConfig(psPVRDrawable->psImpl);
+
+ PVRDRIDestroyDrawableImpl(psPVRDrawable->psImpl);
+
+ free(psPVRDrawable);
+
+#if defined(DEBUG)
+ p_atomic_dec(&psPVRScreen->iDrawableAlloc);
+#endif
+
+ PVRDRIScreenRemoveReference(psPVRScreen);
+}
+
+static GLboolean PVRDRIMakeCurrent(__DRIcontext *psDRIContext,
+ __DRIdrawable *psDRIWrite,
+ __DRIdrawable *psDRIRead)
+{
+ PVRDRIContext *psPVRContext = (PVRDRIContext *)psDRIContext->driverPrivate;
+ PVRDRIDrawable *psPVRWrite = (psDRIWrite) ? (PVRDRIDrawable *)psDRIWrite->driverPrivate : NULL;
+ PVRDRIDrawable *psPVRRead = (psDRIRead) ? (PVRDRIDrawable *)psDRIRead->driverPrivate : NULL;
+ PVRDRIDrawable *psPVRDrawableOld = psPVRContext->psPVRDrawable;
+
+ if (psPVRWrite != NULL)
+ {
+ if (!PVRDRIDrawableInit(psPVRWrite))
+ {
+ __driUtilMessage("%s: Couldn't initialise write drawable",
+ __func__);
+ goto ErrorUnlock;
+ }
+ }
+
+ if (psPVRRead != NULL)
+ {
+ if (!PVRDRIDrawableInit(psPVRRead))
+ {
+ __driUtilMessage("%s: Couldn't initialise read drawable",
+ __func__);
+ goto ErrorUnlock;
+ }
+ }
+
+ if (!PVRDRIMakeCurrentGC(psPVRContext->eAPI,
+ psPVRContext->psPVRScreen->psImpl,
+ psPVRContext->psImpl,
+ psPVRWrite == NULL ? NULL : psPVRWrite->psImpl,
+ psPVRRead == NULL ? NULL : psPVRRead->psImpl))
+ {
+ goto ErrorUnlock;
+ }
+
+ if (psPVRDrawableOld != NULL)
+ {
+ psPVRDrawableOld->psPVRContext = NULL;
+ }
+
+
+ if (psPVRWrite != NULL)
+ {
+ psPVRWrite->psPVRContext = psPVRContext;
+ }
+
+ psPVRContext->psPVRDrawable = psPVRWrite;
+
+ pvrdri_set_dispatch_table(psPVRContext);
+
+ PVRDRIThreadSetCurrentScreen(psPVRContext->psPVRScreen);
+
+ return GL_TRUE;
+
+ErrorUnlock:
+ return GL_FALSE;
+}
+
+static GLboolean PVRDRIUnbindContext(__DRIcontext *psDRIContext)
+{
+ PVRDRIContext *psPVRContext = (PVRDRIContext *)psDRIContext->driverPrivate;
+
+ pvrdri_set_null_dispatch_table();
+
+ PVRContextUnbind(psPVRContext, true, false);
+ PVRDRIThreadSetCurrentScreen(NULL);
+
+ return GL_TRUE;
+}
+
+static __DRIbuffer *PVRDRIAllocateBuffer(__DRIscreen *psDRIScreen,
+ unsigned int uAttachment,
+ unsigned int uFormat,
+ int iWidth,
+ int iHeight)
+{
+ PVRDRIScreen *psPVRScreen = DRIScreenPrivate(psDRIScreen);
+ PVRBuffer *psBuffer;
+ unsigned int uiBpp;
+
+ /* GEM names are only supported on primary nodes */
+ if (drmGetNodeTypeFromFd(psDRIScreen->fd) != DRM_NODE_PRIMARY)
+ {
+ __driUtilMessage("%s: Cannot allocate buffer", __func__);
+ return NULL;
+ }
+
+ /* This is based upon PVRDRIGetPixelFormat */
+ switch (uFormat)
+ {
+ case 32:
+ case 16:
+ /* Format (depth) and bpp match */
+ uiBpp = uFormat;
+ break;
+ case 24:
+ uiBpp = 32;
+ break;
+ default:
+ __driUtilMessage("%s: Unsupported format '%u'",
+ __func__, uFormat);
+ return NULL;
+ }
+
+ psBuffer = calloc(1, sizeof(*psBuffer));
+ if (psBuffer == NULL)
+ {
+ __driUtilMessage("%s: Failed to allocate buffer", __func__);
+ return NULL;
+ }
+
+ psBuffer->psImpl = PVRDRIBufferCreate(psPVRScreen->psImpl,
+ iWidth,
+ iHeight,
+ uiBpp,
+ PVDRI_BUFFER_USE_SHARE,
+ &psBuffer->sDRIBuffer.pitch);
+ if (!psBuffer->psImpl)
+ {
+ __driUtilMessage("%s: Failed to create backing buffer",
+ __func__);
+ goto ErrorFreeDRIBuffer;
+ }
+
+ psBuffer->sDRIBuffer.attachment = uAttachment;
+ psBuffer->sDRIBuffer.name = PVRDRIBufferGetName(psBuffer->psImpl);
+ psBuffer->sDRIBuffer.cpp = uiBpp / 8;
+
+#if defined(DEBUG)
+ p_atomic_inc(&psPVRScreen->iBufferAlloc);
+#endif
+
+ return &psBuffer->sDRIBuffer;
+
+ErrorFreeDRIBuffer:
+ free(psBuffer);
+
+ return NULL;
+}
+
+static void PVRDRIReleaseBuffer(__DRIscreen *psDRIScreen,
+ __DRIbuffer *psDRIBuffer)
+{
+ PVRBuffer *psBuffer = (PVRBuffer *)psDRIBuffer;
+#if defined(DEBUG)
+ PVRDRIScreen *psPVRScreen = DRIScreenPrivate(psDRIScreen);
+#endif
+
+ (void)psDRIScreen;
+
+ PVRDRIBufferDestroy(psBuffer->psImpl);
+ free(psBuffer);
+
+#if defined(DEBUG)
+ p_atomic_dec(&psPVRScreen->iBufferAlloc);
+#endif
+}
+
+/* Publish our driver implementation to the world. */
+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;
+}
+
+/*************************************************************************/ /*!
+ Global functions
+*/ /**************************************************************************/
+
+void PVRDRIThreadSetCurrentScreen(PVRDRIScreen *psPVRScreen)
+{
+ gpsPVRScreen = psPVRScreen;
+}
+
+PVRDRIScreen *PVRDRIThreadGetCurrentScreen(void)
+{
+ return gpsPVRScreen;
+}
diff --git a/src/mesa/drivers/dri/pvr/pvrdri.h b/src/mesa/drivers/dri/pvr/pvrdri.h
new file mode 100644
index 00000000000..50d930a59c2
--- /dev/null
+++ b/src/mesa/drivers/dri/pvr/pvrdri.h
@@ -0,0 +1,388 @@
+/* -*- mode: c; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* vi: set ts=8 sw=8 sts=8: */
+/*
+ * 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(__PVRDRI2_H__)
+#define __PVRDRI2_H__
+#include <stdbool.h>
+
+#include <glapi/glapi.h>
+
+#include "main/mtypes.h"
+#include "GL/internal/dri_interface.h"
+
+#include "util/macros.h"
+
+#include "dri_support.h"
+
+/* This should match EGL_MAX_PLANES */
+#define DRI_PLANES_MAX 3
+
+#define DRI2_BUFFERS_MAX (3)
+
+#define DRIScreenPrivate(pScreen) ((pScreen)->driverPrivate)
+
+struct PVRDRIConfigRec
+{
+ struct gl_config sGLMode;
+ int iSupportedAPIs;
+};
+
+struct PVRDRIModifiers
+{
+ /* Number of modifiers for a given format */
+ int iNumModifiers;
+ /* Array of modifiers */
+ uint64_t *puModifiers;
+ /*
+ * Array of booleans that indicates which modifiers in the above array
+ * can only be used for EGL Image External (and so not for scanout).
+ */
+ unsigned *puExternalOnly;
+};
+
+/** Our PVR related screen data */
+typedef struct PVRDRIScreen_TAG
+{
+ /* DRI screen structure pointer */
+ __DRIscreen *psDRIScreen;
+ /* X Server sends invalidate events */
+ bool bUseInvalidate;
+ /* Reference count */
+ int iRefCount;
+
+#if defined(DEBUG)
+ /* Counters of outstanding allocations */
+ int iContextAlloc, iDrawableAlloc, iBufferAlloc;
+#endif
+
+ /* PVR OGLES 1 dispatch table */
+ struct _glapi_table *psOGLES1Dispatch;
+ /* PVR OGLES 2/3 dispatch table */
+ struct _glapi_table *psOGLES2Dispatch;
+
+ PVRDRIScreenImpl *psImpl;
+
+ /*
+ * Number of supported formats:
+ * -1 -> couldn't be queried (pvr_dri_support too old)
+ * 0 -> uninitialised or initialisation failed
+ */
+ int iNumFormats;
+ /* Indicates which entries in the image format array are supported */
+ bool *pbHasFormat;
+ /* Array of modifiers for each image format array entry */
+ struct PVRDRIModifiers *psModifiers;
+} PVRDRIScreen;
+
+/** Our PVR related context data */
+typedef struct PVRDRIContext_TAG
+{
+ /* Pointer to DRI context */
+ __DRIcontext *psDRIContext;
+ /* Pointer to PVRDRIScreen structure */
+ PVRDRIScreen *psPVRScreen;
+
+ PVRDRIConfig sConfig;
+
+ /* Pointer to currently bound drawable */
+ struct PVRDRIDrawable_TAG *psPVRDrawable;
+
+ /* API */
+ PVRDRIAPIType eAPI;
+
+ PVRDRIContextImpl *psImpl;
+} PVRDRIContext;
+
+/** Our PVR related drawable data */
+typedef struct PVRDRIDrawable_TAG
+{
+ /** Ptr to PVR screen, that spawned this drawable */
+ PVRDRIScreen *psPVRScreen;
+
+ /** DRI drawable data */
+ __DRIdrawable *psDRIDrawable;
+
+ PVRDRIDrawableType eType;
+
+ PVRDRIConfig sConfig;
+
+ /** Are surface/buffers created? */
+ bool bInitialised;
+
+ /** Buffer stride */
+ unsigned uStride;
+
+ /* Number of bytes per pixel */
+ unsigned int uBytesPerPixel;
+
+ /* Context bound to this drawable */
+ PVRDRIContext *psPVRContext;
+
+ /* IMG Pixel format for this drawable */
+ IMG_PIXFMT ePixelFormat;
+
+ /* Indicates the drawable info is invalid */
+ int iInfoInvalid;
+
+ /* Indicates the drawable is currently being updated */
+ bool bDrawableUpdating;
+
+ /* Indicates a flush is in progress */
+ bool bFlushInProgress;
+
+ __DRIimage *psDRI;
+ __DRIimage *psImage;
+
+ __DRIimage *psDRIAccum;
+ __DRIimage *psImageAccum;
+
+ PVRDRIDrawableImpl *psImpl;
+} PVRDRIDrawable;
+
+typedef struct PVRDRIImageFormat_TAG
+{
+ /*
+ * IMG pixel format for the entire/overall image, e.g.
+ * IMG_PIXFMT_B8G8R8A8_UNORM or IMG_PIXFMT_YUV420_2PLANE.
+ */
+ IMG_PIXFMT eIMGPixelFormat;
+
+ /*
+ * DRI fourcc for the entire/overall image (defined by dri_interface.h),
+ * e.g. __DRI_IMAGE_FOURCC_ARGB8888 or __DRI_IMAGE_FOURCC_NV12.
+ */
+ int iDRIFourCC;
+
+ /*
+ * DRI format for the entire/overall image (defined by dri_interface.h),
+ * e.g. __DRI_IMAGE_FORMAT_ARGB8888. This isn't applicable for YUV
+ * formats and should be set to __DRI_IMAGE_FORMAT_NONE.
+ */
+ int iDRIFormat;
+
+ /*
+ * DRI components for the entire/overall image (defined by
+ * dri_interface.h), e.g. __DRI_IMAGE_COMPONENTS_RGBA or
+ * __DRI_IMAGE_COMPONENTS_Y_UV.
+ *
+ * This specifies the image components and their groupings, in terms of
+ * sub-images/planes, but not the order in which they appear.
+ *
+ * For example:
+ * - any combination of BGRA channels would correspond to
+ * __DRI_IMAGE_COMPONENTS_RGBA
+ * - any combination of BGR or BGRX would correspond to
+ * __DRI_IMAGE_COMPONENTS_RGB
+ * - any combination of YUV with 2 planes would correspond to
+ * __DRI_IMAGE_COMPONENTS_Y_UV
+ */
+ int iDRIComponents;
+
+ /* The number of sub-images/planes that make up the overall image */
+ unsigned uiNumPlanes;
+
+ /*
+ * Don't return the format when the queryDmaBufFormats DRI Image
+ * extension function is called. Some DRM formats map to multiple
+ * IMG formats. The query should return just one of them.
+ */
+ bool bQueryDmaBufFormatsExclude;
+
+ /* Per-plane information */
+ struct
+ {
+ /* IMG pixel format for the plane */
+ IMG_PIXFMT eIMGPixelFormat;
+
+ /*
+ * This is the amount that the image width should be bit-shifted
+ * in order to give the plane width. This value can be determined
+ * from the YUV sub-sampling ratios and should either be 0 (full
+ * width), 1 (half width) or 2 (quarter width).
+ */
+ unsigned int uiWidthShift;
+
+ /*
+ * This is the amount that the image height should be bit-shifted
+ * in order to give the plane height. This value can be determined
+ * from the YUV sub-sampling ratios and should either be 0 (full
+ * height) or 1 (half height).
+ */
+ unsigned int uiHeightShift;
+ } sPlanes[DRI_PLANES_MAX];
+} PVRDRIImageFormat;
+
+
+/*************************************************************************/ /*!
+ pvrdri.c
+*/ /**************************************************************************/
+
+IMG_PIXFMT PVRDRIGetPixelFormat(const struct gl_config *psGLMode);
+PVRDRIScreen *PVRDRIThreadGetCurrentScreen(void);
+void PVRDRIThreadSetCurrentScreen(PVRDRIScreen *psPVRScreen);
+
+void PVRDRIFlushBuffersForSwap(PVRDRIContext *psPVRContext,
+ PVRDRIDrawable *psPVRDrawable);
+
+
+/*************************************************************************/ /*!
+ pvrutil.c
+*/ /**************************************************************************/
+
+void PRINTFLIKE(1, 2) __driUtilMessage(const char *f, ...);
+void PRINTFLIKE(1, 2) errorMessage(const char *f, ...);
+
+const __DRIconfig **PVRDRICreateConfigs(void);
+
+const PVRDRIImageFormat *PVRDRIFormatToImageFormat(PVRDRIScreen *psPVRScreen,
+ int iDRIFormat);
+const PVRDRIImageFormat *PVRDRIFourCCToImageFormat(PVRDRIScreen *psPVRScreen,
+ int iDRIFourCC);
+const PVRDRIImageFormat *PVRDRIIMGPixelFormatToImageFormat(PVRDRIScreen *psPVRScreen,
+ IMG_PIXFMT eIMGPixelFormat);
+
+IMG_YUV_COLORSPACE PVRDRIToIMGColourSpace(const PVRDRIImageFormat *psFormat,
+ enum __DRIYUVColorSpace eDRIColourSpace,
+ enum __DRISampleRange eDRISampleRange);
+IMG_YUV_CHROMA_INTERP PVRDRIChromaSittingToIMGInterp(const PVRDRIImageFormat *psFormat,
+ enum __DRIChromaSiting eChromaSitting);
+
+bool PVRDRIGetSupportedFormats(PVRDRIScreen *psPVRScreen);
+
+GLboolean PVRDRIQueryDmaBufFormats(__DRIscreen *screen, int max,
+ int *formats, int *count);
+
+GLboolean PVRDRIQueryDmaBufModifiers(__DRIscreen *screen, int fourcc,
+ int max, uint64_t *modifiers,
+ unsigned int *external_only,
+ int *count);
+
+GLboolean PVRDRIQueryDmaBufFormatModifierAttribs(__DRIscreen *screen,
+ uint32_t fourcc,
+ uint64_t modifier,
+ int attrib,
+ uint64_t *value);
+
+void PVRDRIDestroyFormatInfo(PVRDRIScreen *psPVRScreen);
+
+/*************************************************************************/ /*!
+ pvrdrawable.c
+*/ /**************************************************************************/
+
+bool PVRDRIDrawableInit(PVRDRIDrawable *psPVRDrawable);
+void PVRDRIDrawableDeinit(PVRDRIDrawable *psPVRDrawable);
+
+/* Callbacks into non-impl layer */
+
+/* Version 0 callbacks (deprecated) */
+bool PVRDRIDrawableRecreateV0(PVRDRIDrawable *psPVRDrawable);
+bool PVRDRIDrawableGetParametersV0(PVRDRIDrawable *psPVRDrawable,
+ PVRDRIBufferImpl **ppsDstBuffer,
+ PVRDRIBufferImpl **ppsAccumBuffer,
+ PVRDRIBufferAttribs *psAttribs,
+ bool *pbDoubleBuffered);
+
+/* Version 1 callbacks (deprecated) */
+bool PVRDRIDrawableGetParametersV1(PVRDRIDrawable *psPVRDrawable,
+ bool bAllowRecreate,
+ PVRDRIBufferImpl **ppsDstBuffer,
+ PVRDRIBufferImpl **ppsAccumBuffer,
+ PVRDRIBufferAttribs *psAttribs,
+ bool *pbDoubleBuffered);
+
+/* Version 2 callbacks */
+bool PVRDRIDrawableQuery(const PVRDRIDrawable *psPVRDrawable,
+ PVRDRIBufferAttrib eBufferAttrib,
+ uint32_t *uiValueOut);
+bool PVRDRIDrawableGetParametersV2(PVRDRIDrawable *psPVRDrawable,
+ uint32_t uiFlags,
+ PVRDRIBufferImpl **ppsDstBuffer,
+ PVRDRIBufferImpl **ppsAccumBuffer);
+
+/*************************************************************************/ /*!
+ pvrimage.c
+*/ /**************************************************************************/
+
+__DRIimage *PVRDRIScreenGetDRIImage(void *hEGLImage);
+void PVRDRIRefImage(__DRIimage *image);
+void PVRDRIUnrefImage(__DRIimage *image);
+
+/* Callbacks into non-impl layer */
+PVRDRIImageType PVRDRIImageGetSharedType(__DRIimage *image);
+PVRDRIBufferImpl *PVRDRIImageGetSharedBuffer(__DRIimage *image);
+IMGEGLImage *PVRDRIImageGetSharedEGLImage(__DRIimage *image);
+IMGEGLImage *PVRDRIImageGetEGLImage(__DRIimage *image);
+
+/*************************************************************************/ /*!
+ pvrext.c
+*/ /**************************************************************************/
+
+const __DRIextension **PVRDRIScreenExtensions(void);
+const __DRIextension *PVRDRIScreenExtensionVersionInfo(void);
+
+/*************************************************************************/ /*!
+ pvrcompat.c
+*/ /**************************************************************************/
+
+bool PVRDRICompatInit(const PVRDRICallbacks *psCallbacks, unsigned uVersion);
+void PVRDRICompatDeinit(void);
+
+bool PVRDRIRegisterSupportInterfaceV1(const PVRDRISupportInterface *psInterface,
+ unsigned uVersion);
+
+unsigned PVRDRISupportCreateContext(PVRDRIScreenImpl *psScreenImpl,
+ PVRDRIContextImpl *psSharedContextImpl,
+ PVRDRIConfig *psConfig,
+ PVRDRIAPIType eAPI,
+ PVRDRIAPISubType eAPISub,
+ unsigned uMajorVersion,
+ unsigned uMinorVersion,
+ uint32_t uFlags,
+ bool bNotifyReset,
+ unsigned uPriority,
+ PVRDRIContextImpl **ppsContextImpl);
+
+PVRDRIDrawableImpl *PVRDRISupportCreateDrawable(PVRDRIDrawable *psPVRDrawable,
+ PVRDRIConfig *psConfig);
+
+bool PVRDRIBlitEGLImage_IsSupported(void);
+bool PVRDRIMapEGLImage_IsSupported(void);
+bool PVRDRIBufferGetOffset_IsSupported(void);
+bool PVRDRIBufferCreateWithModifiers_IsSupported(void);
+bool PVRDRIBufferCreateFromFdsWithModifier_IsSupported(void);
+
+void *PVRDRICreateFenceFdImpl(PVRDRIAPIType eAPI,
+ PVRDRIScreenImpl *psScreenImpl,
+ PVRDRIContextImpl *psContextImpl,
+ int fd);
+
+unsigned PVRDRIGetFenceCapabilitiesImpl(PVRDRIScreenImpl *psScreenImpl);
+
+int PVRDRIGetFenceFdImpl(void *psDRIFence);
+
+bool PVRDRIValidateImageModifier(PVRDRIScreen *psPVRScreen, const int iFourcc,
+ const uint64_t uiModifier);
+#endif /* defined(__PVRDRI2_H__) */
diff --git a/src/mesa/drivers/dri/pvr/pvrext.c b/src/mesa/drivers/dri/pvr/pvrext.c
new file mode 100644
index 00000000000..c3782b6592b
--- /dev/null
+++ b/src/mesa/drivers/dri/pvr/pvrext.c
@@ -0,0 +1,440 @@
+/* -*- mode: c; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* vi: set ts=8 sw=8 sts=8: */
+/*
+ * 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 "util/u_atomic.h"
+
+#include "dri_util.h"
+#include "utils.h"
+
+#include "dri_support.h"
+#include "pvrdri.h"
+#include "pvrimage.h"
+
+#include "EGL/egl.h"
+#include "EGL/eglext.h"
+
+/* Maximum version numbers for each supported extension */
+#define PVR_DRI_TEX_BUFFER_VERSION 2
+#define PVR_DRI2_FLUSH_VERSION 4
+#define PVR_DRI_IMAGE_VERSION 17
+#define PVR_DRI2_ROBUSTNESS_VERSION 1
+#define PVR_DRI2_FENCE_VERSION 2
+
+static void PVRDRIFlushDrawableContext(PVRDRIDrawable *psPVRDrawable,
+ PVRDRIContext *psPVRContext)
+{
+ PVRDRIContext *psPVRDrawContext = psPVRDrawable->psPVRContext;
+
+ if (psPVRDrawContext)
+ {
+ PVRDRIEGLFlushBuffers(psPVRDrawContext->eAPI,
+ psPVRDrawContext->psPVRScreen->psImpl,
+ psPVRDrawContext->psImpl,
+ psPVRDrawable->psImpl,
+ false,
+ false,
+ (psPVRDrawContext != psPVRContext));
+ }
+}
+
+static void PVRDRIExtSetTexBuffer(__DRIcontext *psDRIContext,
+ GLint target,
+ GLint format,
+ __DRIdrawable *psDRIDrawable)
+{
+ PVRDRIDrawable *psPVRDrawable = (PVRDRIDrawable *)psDRIDrawable->driverPrivate;
+ PVRDRIContext *psPVRContext = (PVRDRIContext *)psDRIContext->driverPrivate;
+
+ (void)target;
+ (void)format;
+
+ if (!psPVRDrawable->bInitialised)
+ {
+ if (!PVRDRIDrawableInit(psPVRDrawable))
+ {
+ __driUtilMessage("%s: Couldn't initialise pixmap", __func__);
+ return;
+ }
+ }
+
+ PVRDRIFlushDrawableContext(psPVRDrawable, psPVRContext);
+ PVRDRI2BindTexImage(psPVRContext->eAPI,
+ psPVRContext->psPVRScreen->psImpl,
+ psPVRContext->psImpl,
+ psPVRDrawable->psImpl);
+}
+
+static void PVRDRIExtReleaseTexBuffer(__DRIcontext *psDRIContext,
+ GLint target,
+ __DRIdrawable *psDRIDrawable)
+{
+ PVRDRIDrawable *psPVRDrawable = (PVRDRIDrawable *)psDRIDrawable->driverPrivate;
+ PVRDRIContext *psPVRContext = (PVRDRIContext *)psDRIContext->driverPrivate;
+
+ (void)target;
+
+ PVRDRI2ReleaseTexImage(psPVRContext->eAPI,
+ psPVRContext->psPVRScreen->psImpl,
+ psPVRContext->psImpl,
+ psPVRDrawable->psImpl);
+}
+
+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 = (PVRDRIDrawable *)psDRIDrawable->driverPrivate;
+ PVRDRIContext *psPVRContext = psPVRDrawable->psPVRContext;
+
+ PVRDRIFlushBuffersForSwap(psPVRContext, psPVRDrawable);
+}
+
+static void PVRDRI2Invalidate(__DRIdrawable *psDRIDrawable)
+{
+ PVRDRIDrawable *psPVRDrawable = (PVRDRIDrawable *)psDRIDrawable->driverPrivate;
+
+ if (psPVRDrawable->psPVRScreen->bUseInvalidate)
+ {
+ p_atomic_inc(&psPVRDrawable->iInfoInvalid);
+ }
+}
+
+static void PVRDRI2FlushWithFlags(__DRIcontext *psDRIContext,
+ __DRIdrawable *psDRIDrawable,
+ unsigned uFlags,
+ enum __DRI2throttleReason eThrottleReason)
+{
+ PVRDRIContext *psPVRContext = (PVRDRIContext *)psDRIContext->driverPrivate;
+
+ (void)eThrottleReason;
+
+ if ((uFlags & __DRI2_FLUSH_DRAWABLE) != 0)
+ {
+ PVRDRIDrawable *psPVRDrawable = psDRIDrawable->driverPrivate;
+
+ PVRDRIFlushBuffersForSwap(psPVRContext, psPVRDrawable);
+ }
+ else if ((uFlags & __DRI2_FLUSH_CONTEXT) != 0)
+ {
+ /*
+ * __DRI2_FLUSH__CONTEXT means "glFlush". Most callers
+ * also specify __DRI2_FLUSH_DRAWABLE. An exception is
+ * GBM, which flushes after an unmap, when there doesn't
+ * appear to be a need to flush outstanding GPU operations.
+ */
+ }
+}
+
+static __DRI2flushExtension pvrDRI2FlushExtension =
+{
+ .base = { .name = __DRI2_FLUSH, .version = PVR_DRI2_FLUSH_VERSION },
+ .flush = PVRDRI2Flush,
+ .invalidate = PVRDRI2Invalidate,
+ .flush_with_flags = PVRDRI2FlushWithFlags,
+};
+
+
+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 = PVRDRIValidateUsage,
+ .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 *dri_screen,
+ int param, unsigned int *value)
+{
+ switch (param)
+ {
+ case __DRI2_RENDERER_HAS_CONTEXT_PRIORITY:
+ value[0] = 0;
+ value[0] |= __DRI2_RENDERER_HAS_CONTEXT_PRIORITY_HIGH;
+ value[0] |= __DRI2_RENDERER_HAS_CONTEXT_PRIORITY_MEDIUM;
+ value[0] |= __DRI2_RENDERER_HAS_CONTEXT_PRIORITY_LOW;
+ return 0;
+
+ default:
+ return driQueryRendererIntegerCommon(dri_screen, param, value);
+ }
+}
+
+static int
+PVRDRIQueryRendererString(__DRIscreen *dri_screen,
+ int param, const char **value)
+{
+ return -1;
+}
+
+static const __DRI2rendererQueryExtension pvrDRIRendererQueryExtension = {
+ .base = { __DRI2_RENDERER_QUERY, 1 },
+
+ .queryInteger = PVRDRIQueryRendererInteger,
+ .queryString = PVRDRIQueryRendererString,
+};
+
+
+#if defined(__DRI2_FENCE)
+static void *PVRDRICreateFenceEXT(__DRIcontext *psDRIContext)
+{
+ PVRDRIContext *psPVRContext = psDRIContext->driverPrivate;
+ PVRDRIScreen *psPVRScreen = psPVRContext->psPVRScreen;
+
+ return PVRDRICreateFenceImpl(psPVRContext->eAPI,
+ psPVRScreen->psImpl,
+ psPVRContext->psImpl);
+}
+
+static void PVRDRIDestroyFenceEXT(__DRIscreen *psDRIScreen, void *psDRIFence)
+{
+ (void)psDRIScreen;
+
+ PVRDRIDestroyFenceImpl(psDRIFence);
+}
+
+static GLboolean PVRDRIClientWaitSyncEXT(__DRIcontext *psDRIContext,
+ void *psDRIFence,
+ unsigned uFlags,
+ uint64_t uiTimeout)
+{
+ bool bFlushCommands = (uFlags & __DRI2_FENCE_FLAG_FLUSH_COMMANDS);
+ bool bTimeout = (uiTimeout != __DRI2_FENCE_TIMEOUT_INFINITE);
+
+ if (psDRIContext && bFlushCommands)
+ {
+ PVRDRIContext *psPVRContext = psDRIContext->driverPrivate;
+ PVRDRIDrawable *psPVRDrawable = psPVRContext->psPVRDrawable;
+
+ (void) PVRDRIEGLFlushBuffers(psPVRContext->eAPI,
+ psPVRContext->psPVRScreen->psImpl,
+ psPVRContext->psImpl,
+ psPVRDrawable ? psPVRDrawable->psImpl : NULL,
+ true, false, false);
+ }
+
+ return PVRDRIClientWaitSyncImpl(PVRDRI_API_NONE,
+ NULL,
+ psDRIFence,
+ false,
+ bTimeout,
+ uiTimeout);
+}
+
+static void PVRDRIServerWaitSyncEXT(__DRIcontext *psDRIContext,
+ void *psDRIFence,
+ unsigned uFlags)
+{
+ (void)uFlags;
+ assert(uFlags == 0);
+
+ if (psDRIFence)
+ {
+ PVRDRIContext *psPVRContext = psDRIContext->driverPrivate;
+
+ if (!PVRDRIServerWaitSyncImpl(psPVRContext->eAPI,
+ psPVRContext->psImpl,
+ psDRIFence))
+ {
+ __driUtilMessage("%s: Server wait sync failed",
+ __func__);
+ }
+ }
+}
+
+static unsigned PVRDRIGetFenceCapabilitiesEXT(__DRIscreen *psDRIScreen)
+{
+ PVRDRIScreen *psPVRScreen = DRIScreenPrivate(psDRIScreen);
+
+ return PVRDRIGetFenceCapabilitiesImpl(psPVRScreen->psImpl);
+}
+
+static void *PVRDRICreateFenceFdEXT(__DRIcontext *psDRIContext, int iFd)
+{
+ PVRDRIContext *psPVRContext = psDRIContext->driverPrivate;
+ PVRDRIScreen *psPVRScreen = psPVRContext->psPVRScreen;
+
+ return PVRDRICreateFenceFdImpl(psPVRContext->eAPI,
+ psPVRScreen->psImpl,
+ psPVRContext->psImpl,
+ iFd);
+}
+
+static int PVRDRIGetFenceFdEXT(__DRIscreen *psDRIScreen, void *psDRIFence)
+{
+ (void)psDRIScreen;
+
+ return PVRDRIGetFenceFdImpl(psDRIFence);
+}
+
+const __DRI2fenceExtension pvrDRIFenceExtension =
+{
+ .base = { .name = __DRI2_FENCE, .version = PVR_DRI2_FENCE_VERSION },
+ .create_fence = PVRDRICreateFenceEXT,
+ /* Not currently supported */
+ .get_fence_from_cl_event = NULL,
+ .destroy_fence = PVRDRIDestroyFenceEXT,
+ .client_wait_sync = PVRDRIClientWaitSyncEXT,
+ .server_wait_sync = PVRDRIServerWaitSyncEXT,
+ .get_capabilities = PVRDRIGetFenceCapabilitiesEXT,
+ .create_fence_fd = PVRDRICreateFenceFdEXT,
+ .get_fence_fd = PVRDRIGetFenceFdEXT,
+};
+#endif /* defined(__DRI2_FENCE) */
+
+/*
+ * 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,
+#if defined(__DRI2_FENCE)
+ &pvrDRIFenceExtension.base,
+#endif
+ &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 },
+#if defined(__DRI2_FENCE)
+ { .name = __DRI2_FENCE, .version = __DRI2_FENCE_VERSION },
+#endif
+ { .name = __DRI2_CONFIG_QUERY, .version = __DRI2_CONFIG_QUERY_VERSION },
+ { .name = NULL, .version = 0 },
+};
+
+const __DRIextension **PVRDRIScreenExtensions(void)
+{
+ if (!PVRDRIBlitEGLImage_IsSupported())
+ {
+ pvrDRIImage.base.version = 8;
+ }
+ else if (!PVRDRIMapEGLImage_IsSupported())
+ {
+ pvrDRIImage.base.version = 11;
+ }
+ else if (!PVRDRIBufferGetOffset_IsSupported())
+ {
+ pvrDRIImage.base.version = 12;
+ }
+ else if (!PVRDRIBufferCreateWithModifiers_IsSupported())
+ {
+ pvrDRIImage.base.version = 13;
+ }
+ else if (!PVRDRIBufferCreateFromFdsWithModifier_IsSupported())
+ {
+ pvrDRIImage.base.version = 14;
+ }
+
+ return apsScreenExtensions;
+}
+
+const __DRIextension *PVRDRIScreenExtensionVersionInfo(void)
+{
+ return asScreenExtensionVersionInfo;
+}
diff --git a/src/mesa/drivers/dri/pvr/pvrimage.c b/src/mesa/drivers/dri/pvr/pvrimage.c
new file mode 100644
index 00000000000..873c852cf9e
--- /dev/null
+++ b/src/mesa/drivers/dri/pvr/pvrimage.c
@@ -0,0 +1,1420 @@
+/* -*- mode: c; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* vi: set ts=8 sw=8 sts=8: */
+/*
+ * 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 <xf86drm.h>
+
+#include "util/u_atomic.h"
+#include "dri_util.h"
+
+#include "img_drm_fourcc.h"
+#include "pvrdri.h"
+#include "pvrimage.h"
+#include "EGL/egl.h"
+#include "EGL/eglext.h"
+
+struct PVRDRIImageShared
+{
+ int iRefCount;
+
+ PVRDRIScreen *psPVRScreen;
+
+ PVRDRIImageType eType;
+ const PVRDRIImageFormat *psFormat;
+ IMG_YUV_COLORSPACE eColourSpace;
+ IMG_YUV_CHROMA_INTERP eChromaUInterp;
+ IMG_YUV_CHROMA_INTERP eChromaVInterp;
+
+ PVRDRIBufferImpl *psBuffer;
+ IMGEGLImage *psEGLImage;
+ PVRDRIEGLImageType eglImageType;
+ struct PVRDRIImageShared *psAncestor;
+};
+
+struct __DRIimageRec
+{
+ int iRefCount;
+
+ void *loaderPrivate;
+
+ struct PVRDRIImageShared *psShared;
+
+ IMGEGLImage *psEGLImage;
+};
+
+
+static struct PVRDRIImageShared *
+CommonImageSharedSetup(PVRDRIScreen *psPVRScreen, PVRDRIImageType eType)
+{
+ struct PVRDRIImageShared *shared;
+
+ shared = calloc(1, sizeof(*shared));
+ if (!shared)
+ {
+ return NULL;
+ }
+
+ shared->psPVRScreen = psPVRScreen;
+ shared->eType = eType;
+ shared->iRefCount = 1;
+
+ assert(shared->eColourSpace == IMG_COLORSPACE_UNDEFINED &&
+ shared->eChromaUInterp == IMG_CHROMA_INTERP_UNDEFINED &&
+ shared->eChromaVInterp == IMG_CHROMA_INTERP_UNDEFINED);
+
+ return shared;
+}
+
+static void DestroyImageShared(struct PVRDRIImageShared *shared)
+{
+ int iRefCount = p_atomic_dec_return(&shared->iRefCount);
+
+ assert(iRefCount >= 0);
+
+ if (iRefCount > 0)
+ {
+ return;
+ }
+
+ switch (shared->eType)
+ {
+ case PVRDRI_IMAGE_FROM_NAMES:
+ case PVRDRI_IMAGE_FROM_DMABUFS:
+ case PVRDRI_IMAGE:
+ if (shared->psBuffer)
+ {
+ PVRDRIBufferDestroy(shared->psBuffer);
+ }
+ assert(!shared->psAncestor);
+ free(shared);
+ return;
+ case PVRDRI_IMAGE_FROM_EGLIMAGE:
+ PVRDRIEGLImageDestroyExternal(shared->psPVRScreen->psImpl,
+ shared->psEGLImage,
+ shared->eglImageType);
+ free(shared);
+ return;
+ case PVRDRI_IMAGE_SUBIMAGE:
+ if (shared->psBuffer)
+ {
+ PVRDRIBufferDestroy(shared->psBuffer);
+ }
+ if (shared->psAncestor)
+ {
+ DestroyImageShared(shared->psAncestor);
+ }
+ free(shared);
+ return;
+ }
+
+ assert(!"unknown image type");
+ free(shared);
+}
+
+static struct PVRDRIImageShared *
+CreateImageSharedFromEGLImage(__DRIscreen *screen,
+ IMGEGLImage *psEGLImage,
+ PVRDRIEGLImageType eglImageType)
+{
+ PVRDRIScreen *psPVRScreen = DRIScreenPrivate(screen);
+ struct PVRDRIImageShared *shared;
+ PVRDRIBufferAttribs sAttribs;
+ const PVRDRIImageFormat *psFormat;
+
+ PVRDRIEGLImageGetAttribs(psEGLImage, &sAttribs);
+
+ psFormat = PVRDRIIMGPixelFormatToImageFormat(psPVRScreen,
+ sAttribs.ePixFormat);
+ if (!psFormat)
+ {
+ return NULL;
+ }
+
+ shared = CommonImageSharedSetup(psPVRScreen, PVRDRI_IMAGE_FROM_EGLIMAGE);
+ if (!shared)
+ {
+ return NULL;
+ }
+
+ shared->psEGLImage = psEGLImage;
+ shared->psFormat = psFormat;
+ shared->eglImageType = eglImageType;
+
+ return shared;
+}
+
+static struct PVRDRIImageShared *
+CreateImageSharedFromNames(__DRIscreen *screen,
+ int width,
+ int height,
+ int fourcc,
+ int *names,
+ int num_names,
+ int *strides,
+ int *offsets)
+{
+ PVRDRIScreen *psPVRScreen = DRIScreenPrivate(screen);
+ struct PVRDRIImageShared *shared;
+ const PVRDRIImageFormat *psFormat;
+ unsigned auiWidthShift[DRI_PLANES_MAX];
+ unsigned auiHeightShift[DRI_PLANES_MAX];
+ int i;
+
+ psFormat = PVRDRIFourCCToImageFormat(psPVRScreen, fourcc);
+ if (!psFormat)
+ {
+ errorMessage("%s: Unsupported DRI FourCC (fourcc = 0x%X)\n",
+ __func__, fourcc);
+ return NULL;
+ }
+
+ if (psFormat->uiNumPlanes < num_names)
+ {
+ errorMessage("%s: Unexpected number of names for DRI FourCC (names = %d, fourcc = 0x%X)\n",
+ __func__, num_names, fourcc);
+ return NULL;
+ }
+
+ for (i = 0; i < num_names; i++)
+ {
+ if (offsets[i] < 0)
+ {
+ errorMessage("%s: Offset %d unsupported (value = %d)\n",
+ __func__, i, offsets[i]);
+ return NULL;
+ }
+
+ auiWidthShift[i] = psFormat->sPlanes[i].uiWidthShift;
+ auiHeightShift[i] = psFormat->sPlanes[i].uiHeightShift;
+ }
+
+ shared = CommonImageSharedSetup(psPVRScreen, PVRDRI_IMAGE_FROM_NAMES);
+ if (!shared)
+ {
+ return NULL;
+ }
+
+ shared->psBuffer = PVRDRIBufferCreateFromNames(psPVRScreen->psImpl,
+ width,
+ height,
+ num_names,
+ names,
+ strides,
+ offsets,
+ auiWidthShift,
+ auiHeightShift);
+
+ if (!shared->psBuffer)
+ {
+ errorMessage("%s: Failed to create buffer for shared image\n", __func__);
+ goto ErrorDestroyImage;
+ }
+
+ shared->psFormat = psFormat;
+ shared->eColourSpace =
+ PVRDRIToIMGColourSpace(psFormat,
+ __DRI_YUV_COLOR_SPACE_UNDEFINED,
+ __DRI_YUV_RANGE_UNDEFINED);
+ shared->eChromaUInterp =
+ PVRDRIChromaSittingToIMGInterp(psFormat,
+ __DRI_YUV_CHROMA_SITING_UNDEFINED);
+ shared->eChromaVInterp =
+ PVRDRIChromaSittingToIMGInterp(psFormat,
+ __DRI_YUV_CHROMA_SITING_UNDEFINED);
+
+ return shared;
+
+ErrorDestroyImage:
+ DestroyImageShared(shared);
+
+ return NULL;
+}
+
+static struct PVRDRIImageShared *
+CreateImageSharedFromDmaBufs(__DRIscreen *screen,
+ int width,
+ int height,
+ int fourcc,
+ uint64_t modifier,
+ int *fds,
+ int num_fds,
+ int *strides,
+ int *offsets,
+ enum __DRIYUVColorSpace color_space,
+ enum __DRISampleRange sample_range,
+ enum __DRIChromaSiting horiz_siting,
+ enum __DRIChromaSiting vert_siting,
+ unsigned *error)
+{
+ PVRDRIScreen *psPVRScreen = DRIScreenPrivate(screen);
+ struct PVRDRIImageShared *shared;
+ const PVRDRIImageFormat *psFormat;
+ unsigned auiWidthShift[DRI_PLANES_MAX];
+ unsigned auiHeightShift[DRI_PLANES_MAX];
+ int i;
+
+ psFormat = PVRDRIFourCCToImageFormat(psPVRScreen, fourcc);
+ if (!psFormat)
+ {
+ errorMessage("%s: Unsupported DRI FourCC (fourcc = 0x%X)\n",
+ __func__, fourcc);
+ *error = __DRI_IMAGE_ERROR_BAD_MATCH;
+ return NULL;
+ }
+
+ /* When a modifier isn't specified, skip the validation */
+ if (modifier != DRM_FORMAT_MOD_INVALID)
+ {
+ /*
+ * The modifier validation has to be done in this "higher" level
+ * function instead of pvr_dri_support. The support for
+ * modifiers is done on per format basis, but there is no way
+ * to pass the format information down to the plane creation API
+ * in pvr_dri_support.
+ */
+ if (!PVRDRIValidateImageModifier(psPVRScreen, fourcc, modifier))
+ {
+ errorMessage("%s: Unsupported mod (fmt = %#x, mod = %"PRIx64")\n",
+ __func__, fourcc, modifier);
+ *error = __DRI_IMAGE_ERROR_BAD_MATCH;
+ return NULL;
+ }
+ }
+
+ if (psFormat->uiNumPlanes < num_fds)
+ {
+ errorMessage("%s: Unexpected number of fds for format (fds = %d, fourcc = 0x%X)\n",
+ __func__, num_fds, fourcc);
+ *error = __DRI_IMAGE_ERROR_BAD_MATCH;
+ return NULL;
+ }
+
+ for (i = 0; i < num_fds; i++)
+ {
+ if (offsets[i] < 0)
+ {
+ errorMessage("%s: Offset %d unsupported (value = %d)\n",
+ __func__, i, offsets[i]);
+ *error = __DRI_IMAGE_ERROR_BAD_ACCESS;
+ return NULL;
+ }
+
+ auiWidthShift[i] = psFormat->sPlanes[i].uiWidthShift;
+ auiHeightShift[i] = psFormat->sPlanes[i].uiHeightShift;
+ }
+
+ shared = CommonImageSharedSetup(psPVRScreen, PVRDRI_IMAGE_FROM_DMABUFS);
+ if (!shared)
+ {
+ *error = __DRI_IMAGE_ERROR_BAD_ALLOC;
+ return NULL;
+ }
+
+ shared->psBuffer = PVRDRIBufferCreateFromFdsWithModifier(psPVRScreen->psImpl,
+ width,
+ height,
+ modifier,
+ num_fds,
+ fds,
+ strides,
+ offsets,
+ auiWidthShift,
+ auiHeightShift);
+
+ if (!shared->psBuffer)
+ {
+ errorMessage("%s: Failed to create buffer for shared image\n", __func__);
+ *error = __DRI_IMAGE_ERROR_BAD_ALLOC;
+ goto ErrorDestroyImage;
+ }
+
+ shared->psFormat = psFormat;
+ shared->eColourSpace = PVRDRIToIMGColourSpace(psFormat, color_space, sample_range);
+ shared->eChromaUInterp = PVRDRIChromaSittingToIMGInterp(psFormat, horiz_siting);
+ shared->eChromaVInterp = PVRDRIChromaSittingToIMGInterp(psFormat, vert_siting);
+
+ return shared;
+
+ErrorDestroyImage:
+ DestroyImageShared(shared);
+
+ return NULL;
+}
+
+static struct PVRDRIImageShared *
+CreateImageShared(__DRIscreen *screen,
+ int width,
+ int height,
+ int format,
+ unsigned int use,
+ int *piStride)
+{
+ PVRDRIScreen *psPVRScreen = DRIScreenPrivate(screen);
+ struct PVRDRIImageShared *shared;
+ const PVRDRIImageFormat *psFormat;
+ unsigned int uiStride;
+
+ if ((use & __DRI_IMAGE_USE_CURSOR) && (use & __DRI_IMAGE_USE_SCANOUT))
+ {
+ return NULL;
+ }
+
+ psFormat = PVRDRIFormatToImageFormat(psPVRScreen, format);
+ if (!psFormat)
+ {
+ errorMessage("%s: Unsupported DRI image format (format = 0x%X)\n",
+ __func__, format);
+ return NULL;
+ }
+
+ if (psFormat->uiNumPlanes != 1)
+ {
+ errorMessage("%s: Only single plane formats are supported (format 0x%X has %u planes)\n",
+ __func__, format, psFormat->uiNumPlanes);
+ return NULL;
+ }
+
+ shared = CommonImageSharedSetup(psPVRScreen, PVRDRI_IMAGE);
+ if (!shared)
+ {
+ return NULL;
+ }
+
+ shared->psBuffer =
+ PVRDRIBufferCreate(psPVRScreen->psImpl,
+ width,
+ height,
+ PVRDRIPixFmtGetBPP(psFormat->eIMGPixelFormat),
+ use,
+ &uiStride);
+ if (!shared->psBuffer)
+ {
+ errorMessage("%s: Failed to create buffer\n", __func__);
+ goto ErrorDestroyImage;
+ }
+
+ shared->psFormat = psFormat;
+
+ *piStride = uiStride;
+
+ return shared;
+
+ErrorDestroyImage:
+ DestroyImageShared(shared);
+
+ return NULL;
+}
+
+static struct PVRDRIImageShared *
+CreateImageSharedWithModifiers(__DRIscreen *screen,
+ int width,
+ int height,
+ int format,
+ const uint64_t *modifiers,
+ unsigned int modifier_count,
+ int *piStride)
+{
+ PVRDRIScreen *psPVRScreen = DRIScreenPrivate(screen);
+ struct PVRDRIImageShared *shared;
+ const PVRDRIImageFormat *psFormat;
+ unsigned int uiStride;
+
+ psFormat = PVRDRIFormatToImageFormat(psPVRScreen, format);
+ if (!psFormat)
+ {
+ errorMessage("%s: Unsupported DRI image format (format = 0x%X)\n",
+ __func__, format);
+ return NULL;
+ }
+
+ shared = CommonImageSharedSetup(psPVRScreen, PVRDRI_IMAGE);
+ if (!shared)
+ {
+ return NULL;
+ }
+
+ shared->psBuffer = PVRDRIBufferCreateWithModifiers(psPVRScreen->psImpl,
+ width,
+ height,
+ psFormat->iDRIFourCC,
+ psFormat->eIMGPixelFormat,
+ modifiers,
+ modifier_count,
+ &uiStride);
+ if (!shared->psBuffer)
+ {
+ errorMessage("%s: Failed to create buffer\n", __func__);
+ goto ErrorDestroyImage;
+ }
+
+ shared->psFormat = psFormat;
+
+ *piStride = uiStride;
+
+ return shared;
+
+ErrorDestroyImage:
+ DestroyImageShared(shared);
+
+ return NULL;
+}
+
+static struct PVRDRIImageShared *RefImageShared(struct PVRDRIImageShared *shared)
+{
+ int iRefCount = p_atomic_inc_return(&shared->iRefCount);
+
+ (void)iRefCount;
+ assert(iRefCount > 1);
+
+ return shared;
+}
+
+static struct PVRDRIImageShared *
+CreateImageSharedForSubImage(struct PVRDRIImageShared *psParent, int plane)
+{
+ struct PVRDRIImageShared *shared;
+ struct PVRDRIImageShared *psAncestor;
+ PVRDRIBufferImpl *psBuffer = NULL;
+
+ /* Sub-images represent a single plane in the parent image */
+ if (!psParent->psBuffer)
+ {
+ return NULL;
+ }
+
+ /*
+ * The ancestor image is the owner of the original buffer that will
+ * back the new image. The parent image may be a child of that image
+ * itself. The ancestor image must not be destroyed until all the
+ * child images that refer to it have been destroyed. A reference
+ * will be taken on the ancestor to ensure that is the case.
+ * We must distinguish between the parent's buffer and the ancestor's
+ * buffer. For example, plane 0 in the parent is not necessarily plane
+ * 0 in the ancestor.
+ */
+ psAncestor = psParent;
+ if (psAncestor->psAncestor)
+ {
+ psAncestor = psAncestor->psAncestor;
+
+ assert(!psAncestor->psAncestor);
+ }
+
+ psBuffer = PVRDRISubBufferCreate(psParent->psPVRScreen->psImpl,
+ psParent->psBuffer,
+ plane);
+ /*
+ * Older versions of PVR DRI Support don't support
+ * PVRDRISubBufferCreate.
+ */
+ if (!psBuffer)
+ {
+ return NULL;
+ }
+
+ shared = CommonImageSharedSetup(NULL, PVRDRI_IMAGE_SUBIMAGE);
+ if (!shared)
+ {
+ goto ErrorDestroyBuffer;
+ }
+
+ shared->psAncestor = RefImageShared(psAncestor);
+ shared->psBuffer = psBuffer;
+ shared->psPVRScreen = psParent->psPVRScreen;
+
+ shared->psFormat = PVRDRIIMGPixelFormatToImageFormat(psParent->psPVRScreen,
+ psParent->psFormat->sPlanes[plane].eIMGPixelFormat);
+ assert(shared->psFormat);
+
+ return shared;
+
+ErrorDestroyBuffer:
+ PVRDRIBufferDestroy(psBuffer);
+ return NULL;
+}
+
+static __DRIimage *CommonImageSetup(void *loaderPrivate)
+{
+ __DRIimage *image;
+
+ image = calloc(1, sizeof(*image));
+ if (!image)
+ {
+ return NULL;
+ }
+
+ image->loaderPrivate = loaderPrivate;
+ image->iRefCount = 1;
+
+ return image;
+}
+
+void PVRDRIDestroyImage(__DRIimage *image)
+{
+ int iRefCount = p_atomic_dec_return(&image->iRefCount);
+
+ assert(iRefCount >= 0);
+
+ if (iRefCount > 0)
+ {
+ return;
+ }
+
+ if (image->psShared)
+ {
+ DestroyImageShared(image->psShared);
+ }
+
+ PVRDRIEGLImageFree(image->psEGLImage);
+
+ free(image);
+}
+
+__DRIimage *PVRDRICreateImageFromName(__DRIscreen *screen,
+ int width, int height, int format,
+ int name, int pitch,
+ void *loaderPrivate)
+{
+ PVRDRIScreen *psPVRScreen = DRIScreenPrivate(screen);
+ const PVRDRIImageFormat *psFormat;
+ int iStride;
+ int iOffset;
+
+ psFormat = PVRDRIFormatToImageFormat(psPVRScreen, format);
+ if (!psFormat)
+ {
+ errorMessage("%s: Unsupported DRI image format (format = 0x%X)\n",
+ __func__, format);
+ return NULL;
+ }
+
+ iStride = pitch * PVRDRIPixFmtGetBlockSize(psFormat->eIMGPixelFormat);
+ iOffset = 0;
+
+ return PVRDRICreateImageFromNames(screen, width, height, psFormat->iDRIFourCC,
+ &name, 1, &iStride, &iOffset, loaderPrivate);
+}
+
+__DRIimage *PVRDRICreateImageFromRenderbuffer2(__DRIcontext *context,
+ int renderbuffer,
+ void *loaderPrivate,
+ unsigned *error)
+{
+ PVRDRIContext *psPVRContext = context->driverPrivate;
+ __DRIscreen *screen = psPVRContext->psPVRScreen->psDRIScreen;
+ unsigned e;
+ IMGEGLImage *psEGLImage;
+ __DRIimage *image;
+
+ image = CommonImageSetup(loaderPrivate);
+ if (!image)
+ {
+ *error = __DRI_IMAGE_ERROR_BAD_ALLOC;
+ return NULL;
+ }
+
+ psEGLImage = PVRDRIEGLImageCreate();
+ if (!psEGLImage)
+ {
+ PVRDRIDestroyImage(image);
+
+ *error = __DRI_IMAGE_ERROR_BAD_ALLOC;
+ return NULL;
+ }
+
+ e = PVRDRIGetImageSource(psPVRContext->eAPI,
+ psPVRContext->psPVRScreen->psImpl,
+ psPVRContext->psImpl,
+ EGL_GL_RENDERBUFFER_KHR,
+ (uintptr_t)renderbuffer,
+ 0,
+ psEGLImage);
+
+ if (e != PVRDRI_IMAGE_ERROR_SUCCESS)
+ {
+ PVRDRIEGLImageFree(psEGLImage);
+ PVRDRIDestroyImage(image);
+
+ *error = e;
+ return NULL;
+ }
+
+ PVRDRIEGLImageSetCallbackData(psEGLImage, image);
+
+ /*
+ * We can't destroy the image after this point, as the
+ * renderbuffer now has a reference to it.
+ */
+ image->psShared = CreateImageSharedFromEGLImage(screen,
+ psEGLImage,
+ PVRDRI_EGLIMAGE_IMGEGL);
+ if (!image->psShared)
+ {
+ *error = __DRI_IMAGE_ERROR_BAD_ALLOC;
+ return NULL;
+ }
+
+ image->psEGLImage = PVRDRIEGLImageDup(image->psShared->psEGLImage);
+ if (!image->psEGLImage)
+ {
+ *error = __DRI_IMAGE_ERROR_BAD_ALLOC;
+ return NULL;
+ }
+
+ image->iRefCount++;
+
+ *error = __DRI_IMAGE_ERROR_SUCCESS;
+ return image;
+}
+
+__DRIimage *PVRDRICreateImageFromRenderbuffer(__DRIcontext *context,
+ int renderbuffer,
+ void *loaderPrivate)
+{
+ unsigned error;
+
+ return PVRDRICreateImageFromRenderbuffer2(context,
+ renderbuffer,
+ loaderPrivate,
+ &error);
+}
+
+__DRIimage *PVRDRICreateImage(__DRIscreen *screen,
+ int width, int height, int format,
+ unsigned int use,
+ void *loaderPrivate)
+{
+ __DRIimage *image;
+ int iStride;
+
+ image = CommonImageSetup(loaderPrivate);
+ if (!image)
+ {
+ return NULL;
+ }
+
+ image->psShared = CreateImageShared(screen, width, height, format, use, &iStride);
+ if (!image->psShared)
+ {
+ PVRDRIDestroyImage(image);
+ return NULL;
+ }
+
+ image->psEGLImage = PVRDRIEGLImageCreateFromBuffer(width, height, iStride,
+ image->psShared->psFormat->eIMGPixelFormat,
+ image->psShared->eColourSpace,
+ image->psShared->eChromaUInterp,
+ image->psShared->eChromaVInterp,
+ image->psShared->psBuffer);
+ if (!image->psEGLImage)
+ {
+ PVRDRIDestroyImage(image);
+ return NULL;
+ }
+
+ PVRDRIEGLImageSetCallbackData(image->psEGLImage, image);
+
+ return image;
+}
+
+__DRIimage *PVRDRICreateImageWithModifiers(__DRIscreen *screen,
+ int width, int height, int format,
+ const uint64_t *modifiers,
+ const unsigned int modifier_count,
+ void *loaderPrivate)
+{
+ __DRIimage *image;
+ int iStride;
+
+ image = CommonImageSetup(loaderPrivate);
+ if (!image)
+ {
+ return NULL;
+ }
+
+ image->psShared = CreateImageSharedWithModifiers(screen, width, height, format,
+ modifiers, modifier_count,
+ &iStride);
+ if (!image->psShared)
+ {
+ PVRDRIDestroyImage(image);
+ return NULL;
+ }
+
+ image->psEGLImage = PVRDRIEGLImageCreateFromBuffer(width, height, iStride,
+ image->psShared->psFormat->eIMGPixelFormat,
+ image->psShared->eColourSpace,
+ image->psShared->eChromaUInterp,
+ image->psShared->eChromaVInterp,
+ image->psShared->psBuffer);
+ if (!image->psEGLImage)
+ {
+ PVRDRIDestroyImage(image);
+ return NULL;
+ }
+
+ PVRDRIEGLImageSetCallbackData(image->psEGLImage, image);
+
+ return image;
+}
+
+GLboolean PVRDRIQueryImage(__DRIimage *image, int attrib, int *value_ptr)
+{
+ struct PVRDRIImageShared *shared = image->psShared;
+ PVRDRIBufferAttribs sAttribs;
+ int value;
+ uint64_t ulValue;
+
+ PVRDRIEGLImageGetAttribs(image->psEGLImage, &sAttribs);
+
+ if (attrib == __DRI_IMAGE_ATTRIB_HANDLE ||
+ attrib == __DRI_IMAGE_ATTRIB_NAME ||
+ attrib == __DRI_IMAGE_ATTRIB_FD ||
+ attrib == __DRI_IMAGE_ATTRIB_OFFSET)
+ {
+ if (!shared->psFormat)
+ {
+ return GL_FALSE;
+ }
+
+ switch (shared->psFormat->iDRIComponents)
+ {
+ case __DRI_IMAGE_COMPONENTS_R:
+ case __DRI_IMAGE_COMPONENTS_RG:
+ case __DRI_IMAGE_COMPONENTS_RGB:
+ case __DRI_IMAGE_COMPONENTS_RGBA:
+#if defined(__DRI_IMAGE_COMPONENTS_EXTERNAL)
+ case __DRI_IMAGE_COMPONENTS_EXTERNAL:
+#endif
+ break;
+ default:
+ return GL_FALSE;
+ }
+ }
+
+ switch (attrib)
+ {
+ case __DRI_IMAGE_ATTRIB_STRIDE:
+ *value_ptr = sAttribs.uiStrideInBytes;
+ break;
+ case __DRI_IMAGE_ATTRIB_HANDLE:
+ value = PVRDRIBufferGetHandle(shared->psBuffer);
+ if (value == -1)
+ {
+ return GL_FALSE;
+ }
+
+ *value_ptr = value;
+ break;
+ case __DRI_IMAGE_ATTRIB_NAME:
+ value = PVRDRIBufferGetName(shared->psBuffer);
+ if (value == -1)
+ {
+ return GL_FALSE;
+ }
+
+ *value_ptr = value;
+ break;
+ case __DRI_IMAGE_ATTRIB_FORMAT:
+ if (!shared->psFormat)
+ {
+ return GL_FALSE;
+ }
+
+ *value_ptr = shared->psFormat->iDRIFormat;
+ break;
+ case __DRI_IMAGE_ATTRIB_WIDTH:
+ *value_ptr = sAttribs.uiWidth;
+ break;
+ case __DRI_IMAGE_ATTRIB_HEIGHT:
+ *value_ptr = sAttribs.uiHeight;
+ break;
+ case __DRI_IMAGE_ATTRIB_COMPONENTS:
+ if (!shared->psFormat || !shared->psFormat->iDRIComponents)
+ {
+ return GL_FALSE;
+ }
+
+ *value_ptr = shared->psFormat->iDRIComponents;
+ break;
+ case __DRI_IMAGE_ATTRIB_FD:
+ value = PVRDRIBufferGetFd(shared->psBuffer);
+ if (value == -1)
+ {
+ return GL_FALSE;
+ }
+
+ *value_ptr = value;
+ break;
+ case __DRI_IMAGE_ATTRIB_FOURCC:
+ *value_ptr = shared->psFormat->iDRIFourCC;
+ break;
+ case __DRI_IMAGE_ATTRIB_NUM_PLANES:
+ *value_ptr = (int)shared->psFormat->uiNumPlanes;
+ break;
+ case __DRI_IMAGE_ATTRIB_OFFSET:
+ *value_ptr = PVRDRIBufferGetOffset(shared->psBuffer);
+ break;
+ case __DRI_IMAGE_ATTRIB_MODIFIER_LOWER:
+ ulValue = PVRDRIBufferGetModifier(shared->psBuffer);
+ *value_ptr = (int)(ulValue & 0xffffffff);
+ break;
+ case __DRI_IMAGE_ATTRIB_MODIFIER_UPPER:
+ ulValue = PVRDRIBufferGetModifier(shared->psBuffer);
+ *value_ptr = (int)((ulValue >> 32) & 0xffffffff);
+ break;
+ default:
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
+}
+
+__DRIimage *PVRDRIDupImage(__DRIimage *srcImage, void *loaderPrivate)
+{
+ __DRIimage *image;
+
+ image = CommonImageSetup(loaderPrivate);
+ if (!image)
+ {
+ return NULL;
+ }
+
+ image->psShared = RefImageShared(srcImage->psShared);
+
+ image->psEGLImage = PVRDRIEGLImageDup(srcImage->psEGLImage);
+ if (!image->psEGLImage)
+ {
+ PVRDRIDestroyImage(image);
+ return NULL;
+ }
+
+ PVRDRIEGLImageSetCallbackData(image->psEGLImage, image);
+
+ return image;
+}
+
+GLboolean PVRDRIValidateUsage(__DRIimage *image, unsigned int use)
+{
+ struct PVRDRIImageShared *shared = image->psShared;
+ __DRIscreen *screen = shared->psPVRScreen->psDRIScreen;
+
+ if (use & (__DRI_IMAGE_USE_SCANOUT | __DRI_IMAGE_USE_CURSOR))
+ {
+ uint64_t modifier;
+
+ /*
+ * We are extra strict in this case as an application may ask for a
+ * handle so that the memory can be wrapped as a framebuffer/used as
+ * a cursor and this can only be done on a card node.
+ */
+ if (drmGetNodeTypeFromFd(screen->fd) != DRM_NODE_PRIMARY)
+ {
+ return GL_FALSE;
+ }
+
+ modifier = PVRDRIBufferGetModifier(shared->psBuffer);
+
+ if (modifier != DRM_FORMAT_MOD_INVALID &&
+ modifier != DRM_FORMAT_MOD_LINEAR)
+ {
+ return GL_FALSE;
+ }
+ }
+ else if (use & (__DRI_IMAGE_USE_SHARE))
+ {
+ /*
+ * We are less strict in this case as it's possible to share buffers
+ * using prime (but not flink) on a render node so we only need to know
+ * whether or not the fd belongs to the display.
+ */
+ if (PVRDRIGetDeviceTypeFromFd(screen->fd) != PVRDRI_DEVICE_TYPE_DISPLAY)
+ {
+ return GL_FALSE;
+ }
+ }
+
+ return GL_TRUE;
+}
+
+__DRIimage *PVRDRICreateImageFromNames(__DRIscreen *screen,
+ int width, int height, int fourcc,
+ int *names, int num_names,
+ int *strides, int *offsets,
+ void *loaderPrivate)
+{
+ __DRIimage *image;
+ int iStride;
+
+ image = CommonImageSetup(loaderPrivate);
+ if (!image)
+ {
+ return NULL;
+ }
+
+ image->psShared = CreateImageSharedFromNames(screen, width, height, fourcc,
+ names, num_names, strides, offsets);
+ if (!image->psShared)
+ {
+ PVRDRIDestroyImage(image);
+ return NULL;
+ }
+
+ if (image->psShared->psFormat->uiNumPlanes == 1)
+ {
+ iStride = strides[0];
+ }
+ else
+ {
+ iStride = width * PVRDRIPixFmtGetBlockSize(image->psShared->psFormat->eIMGPixelFormat);
+ }
+
+ image->psEGLImage = PVRDRIEGLImageCreateFromBuffer(width, height,
+ iStride,
+ image->psShared->psFormat->eIMGPixelFormat,
+ image->psShared->eColourSpace,
+ image->psShared->eChromaUInterp,
+ image->psShared->eChromaVInterp,
+ image->psShared->psBuffer);
+ if (!image->psEGLImage)
+ {
+ PVRDRIDestroyImage(image);
+ return NULL;
+ }
+
+ PVRDRIEGLImageSetCallbackData(image->psEGLImage, image);
+
+ return image;
+}
+
+__DRIimage *PVRDRIFromPlanar(__DRIimage *srcImage, int plane,
+ void *loaderPrivate)
+{
+ __DRIimage *image;
+
+ image = CommonImageSetup(loaderPrivate);
+ if (!image)
+ {
+ return NULL;
+ }
+
+ image->psShared = CreateImageSharedForSubImage(srcImage->psShared,
+ plane);
+
+ if (!image->psShared)
+ {
+ if (plane != 0)
+ {
+ errorMessage("%s: plane %d not supported\n",
+ __func__, plane);
+ }
+
+ image->psShared = RefImageShared(srcImage->psShared);
+
+ image->psEGLImage = PVRDRIEGLImageDup(srcImage->psEGLImage);
+ }
+ else
+ {
+ image->psEGLImage = PVRDRIEGLImageCreateFromSubBuffer(
+ image->psShared->psFormat->eIMGPixelFormat,
+ image->psShared->psBuffer);
+ }
+
+ if (!image->psEGLImage)
+ {
+ PVRDRIDestroyImage(image);
+ return NULL;
+ }
+
+ PVRDRIEGLImageSetCallbackData(image->psEGLImage, image);
+
+ return image;
+}
+
+__DRIimage *
+PVRDRICreateImageFromTexture(__DRIcontext *context,
+ int glTarget,
+ unsigned texture,
+ int depth,
+ int level,
+ unsigned *error,
+ void *loaderPrivate)
+{
+ PVRDRIContext *psPVRContext = context->driverPrivate;
+ __DRIscreen *screen = psPVRContext->psPVRScreen->psDRIScreen;
+ IMGEGLImage *psEGLImage;
+ __DRIimage *image;
+ uint32_t eglTarget;
+ unsigned e;
+
+ switch (glTarget)
+ {
+ case GL_TEXTURE_2D:
+ eglTarget = EGL_GL_TEXTURE_2D_KHR;
+ break;
+ case GL_TEXTURE_CUBE_MAP:
+ eglTarget = EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR + depth;
+ break;
+ default:
+ errorMessage("%s: GL Target %d is not supported\n", __func__, glTarget);
+ *error = __DRI_IMAGE_ERROR_BAD_PARAMETER;
+ return NULL;
+ }
+
+ image = CommonImageSetup(loaderPrivate);
+ if (!image)
+ {
+ return NULL;
+ }
+
+ psEGLImage = PVRDRIEGLImageCreate();
+ if (!psEGLImage)
+ {
+ PVRDRIDestroyImage(image);
+ return NULL;
+ }
+
+ e = PVRDRIGetImageSource(psPVRContext->eAPI,
+ psPVRContext->psPVRScreen->psImpl,
+ psPVRContext->psImpl,
+ eglTarget,
+ (uintptr_t)texture,
+ (uint32_t)level,
+ psEGLImage);
+ *error = e;
+
+ if (e != PVRDRI_IMAGE_ERROR_SUCCESS)
+ {
+ PVRDRIEGLImageFree(psEGLImage);
+ PVRDRIDestroyImage(image);
+ return NULL;
+ }
+
+ PVRDRIEGLImageSetCallbackData(psEGLImage, image);
+
+ /*
+ * We can't destroy the image after this point, as the
+ * texture now has a reference to it.
+ */
+ image->psShared = CreateImageSharedFromEGLImage(screen,
+ psEGLImage,
+ PVRDRI_EGLIMAGE_IMGEGL);
+ if (!image->psShared)
+ {
+ return NULL;
+ }
+
+ image->psEGLImage = PVRDRIEGLImageDup(image->psShared->psEGLImage);
+ if (!image->psEGLImage)
+ {
+ return NULL;
+ }
+
+ image->iRefCount++;
+
+ return image;
+}
+
+__DRIimage *PVRDRICreateImageFromFds(__DRIscreen *screen,
+ int width, int height, int fourcc,
+ int *fds, int num_fds,
+ int *strides, int *offsets,
+ void *loaderPrivate)
+{
+ unsigned error;
+
+ return PVRDRICreateImageFromDmaBufs(screen, width, height, fourcc,
+ fds, num_fds, strides, offsets,
+ __DRI_YUV_COLOR_SPACE_UNDEFINED,
+ __DRI_YUV_RANGE_UNDEFINED,
+ __DRI_YUV_CHROMA_SITING_UNDEFINED,
+ __DRI_YUV_CHROMA_SITING_UNDEFINED,
+ &error,
+ loaderPrivate);
+}
+
+__DRIimage *
+PVRDRICreateImageFromBuffer(__DRIcontext *context,
+ int target,
+ void *buffer,
+ unsigned *error,
+ void *loaderPrivate)
+{
+ PVRDRIContext *psPVRContext = context->driverPrivate;
+ __DRIscreen *screen = psPVRContext->psPVRScreen->psDRIScreen;
+ IMGEGLImage *psEGLImage;
+ __DRIimage *image;
+
+ switch (target)
+ {
+#if defined(EGL_CL_IMAGE_IMG)
+ case EGL_CL_IMAGE_IMG:
+ break;
+#endif
+ default:
+ errorMessage("%s: Target %d is not supported\n", __func__, target);
+ *error = __DRI_IMAGE_ERROR_BAD_PARAMETER;
+ return NULL;
+ }
+
+ image = CommonImageSetup(loaderPrivate);
+ if (!image)
+ {
+ return NULL;
+ }
+
+ psEGLImage = PVRDRIEGLImageCreate();
+ if (!psEGLImage)
+ {
+ PVRDRIDestroyImage(image);
+ return NULL;
+ }
+
+ *error = PVRDRIGetImageSource(PVRDRI_API_CL,
+ psPVRContext->psPVRScreen->psImpl,
+ psPVRContext->psImpl,
+ target,
+ (uintptr_t)buffer,
+ 0,
+ psEGLImage);
+ if (*error != __DRI_IMAGE_ERROR_SUCCESS)
+ {
+ PVRDRIEGLImageFree(psEGLImage);
+ PVRDRIDestroyImage(image);
+ return NULL;
+ }
+
+ PVRDRIEGLImageSetCallbackData(psEGLImage, image);
+
+ /*
+ * We can't destroy the image after this point, as the
+ * OCL image now has a reference to it.
+ */
+ image->psShared = CreateImageSharedFromEGLImage(screen,
+ psEGLImage,
+ PVRDRI_EGLIMAGE_IMGOCL);
+ if (!image->psShared)
+ {
+ return NULL;
+ }
+
+ image->psEGLImage = PVRDRIEGLImageDup(image->psShared->psEGLImage);
+ if (!image->psEGLImage)
+ {
+ return NULL;
+ }
+
+ image->iRefCount++;
+
+ return image;
+}
+
+__DRIimage *PVRDRICreateImageFromDmaBufs2(__DRIscreen *screen,
+ int width, int height, int fourcc,
+ uint64_t modifier,
+ int *fds, int num_fds,
+ int *strides, int *offsets,
+ enum __DRIYUVColorSpace color_space,
+ enum __DRISampleRange sample_range,
+ enum __DRIChromaSiting horiz_siting,
+ enum __DRIChromaSiting vert_siting,
+ unsigned *error,
+ void *loaderPrivate)
+{
+ __DRIimage *image;
+
+ image = CommonImageSetup(loaderPrivate);
+ if (!image)
+ {
+ *error = __DRI_IMAGE_ERROR_BAD_ALLOC;
+ return NULL;
+ }
+
+ image->psShared = CreateImageSharedFromDmaBufs(screen, width, height, fourcc,
+ modifier,
+ fds, num_fds, strides, offsets,
+ color_space, sample_range,
+ horiz_siting, vert_siting,
+ error);
+ if (!image->psShared)
+ {
+ PVRDRIDestroyImage(image);
+ return NULL;
+ }
+
+ image->psEGLImage = PVRDRIEGLImageCreateFromBuffer(width, height,
+ strides[0],
+ image->psShared->psFormat->eIMGPixelFormat,
+ image->psShared->eColourSpace,
+ image->psShared->eChromaUInterp,
+ image->psShared->eChromaVInterp,
+ image->psShared->psBuffer);
+ if (!image->psEGLImage)
+ {
+ PVRDRIDestroyImage(image);
+ *error = __DRI_IMAGE_ERROR_BAD_ALLOC;
+ return NULL;
+ }
+
+ PVRDRIEGLImageSetCallbackData(image->psEGLImage, image);
+
+ *error = __DRI_IMAGE_ERROR_SUCCESS;
+
+ return image;
+}
+
+__DRIimage *PVRDRICreateImageFromDmaBufs(__DRIscreen *screen,
+ int width, int height, int fourcc,
+ int *fds, int num_fds,
+ int *strides, int *offsets,
+ enum __DRIYUVColorSpace color_space,
+ enum __DRISampleRange sample_range,
+ enum __DRIChromaSiting horiz_siting,
+ enum __DRIChromaSiting vert_siting,
+ unsigned *error,
+ void *loaderPrivate)
+{
+ return PVRDRICreateImageFromDmaBufs2(screen,
+ width, height, fourcc,
+ DRM_FORMAT_MOD_INVALID,
+ fds, num_fds,
+ strides, offsets,
+ color_space,
+ sample_range,
+ horiz_siting,
+ vert_siting,
+ error,
+ loaderPrivate);
+}
+
+void PVRDRIRefImage(__DRIimage *image)
+{
+ int iRefCount = p_atomic_inc_return(&image->iRefCount);
+
+ (void)iRefCount;
+ assert(iRefCount > 1);
+}
+
+void PVRDRIUnrefImage(__DRIimage *image)
+{
+ PVRDRIDestroyImage(image);
+}
+
+PVRDRIImageType PVRDRIImageGetSharedType(__DRIimage *image)
+{
+ return image->psShared->eType;
+}
+
+PVRDRIBufferImpl *PVRDRIImageGetSharedBuffer(__DRIimage *pImage)
+{
+ assert(pImage->psShared->eType != PVRDRI_IMAGE_FROM_EGLIMAGE);
+
+ return pImage->psShared->psBuffer;
+}
+
+IMGEGLImage *PVRDRIImageGetSharedEGLImage(__DRIimage *pImage)
+{
+ assert(pImage->psShared->eType == PVRDRI_IMAGE_FROM_EGLIMAGE);
+ return pImage->psShared->psEGLImage;
+}
+
+IMGEGLImage *PVRDRIImageGetEGLImage(__DRIimage *pImage)
+{
+ return pImage->psEGLImage;
+}
+
+__DRIimage *PVRDRIScreenGetDRIImage(void *hEGLImage)
+{
+ PVRDRIScreen *psPVRScreen = PVRDRIThreadGetCurrentScreen();
+
+ if (!psPVRScreen)
+ {
+ return NULL;
+ }
+
+ return psPVRScreen->psDRIScreen->dri2.image->lookupEGLImage(
+ psPVRScreen->psDRIScreen,
+ hEGLImage,
+ psPVRScreen->psDRIScreen->loaderPrivate);
+}
+
+void PVRDRIBlitImage(__DRIcontext *context,
+ __DRIimage *dst, __DRIimage *src,
+ int dstx0, int dsty0, int dstwidth, int dstheight,
+ int srcx0, int srcy0, int srcwidth, int srcheight,
+ int flush_flag)
+{
+ PVRDRIContext *psPVRContext = context->driverPrivate;
+ bool res;
+
+ res = PVRDRIBlitEGLImage(psPVRContext->psPVRScreen->psImpl,
+ psPVRContext->psImpl,
+ dst->psEGLImage, dst->psShared->psBuffer,
+ src->psEGLImage, src->psShared->psBuffer,
+ dstx0, dsty0, dstwidth, dstheight,
+ srcx0, srcy0, srcwidth, srcheight,
+ flush_flag);
+
+
+ if (!res)
+ {
+ __driUtilMessage("%s: PVRDRIBlitEGLImage failed\n", __func__);
+ }
+}
+
+int PVRDRIGetCapabilities(__DRIscreen *screen)
+{
+ (void) screen;
+
+ return __DRI_IMAGE_CAP_GLOBAL_NAMES;
+}
+
+void *PVRDRIMapImage(__DRIcontext *context, __DRIimage *image,
+ int x0, int y0, int width, int height,
+ unsigned int flags, int *stride, void **data)
+{
+ PVRDRIContext *psPVRContext = context->driverPrivate;
+
+ return PVRDRIMapEGLImage(psPVRContext->psPVRScreen->psImpl,
+ psPVRContext->psImpl,
+ image->psEGLImage, image->psShared->psBuffer,
+ x0, y0, width, height, flags, stride, data);
+}
+
+void PVRDRIUnmapImage(__DRIcontext *context, __DRIimage *image, void *data)
+{
+ PVRDRIContext *psPVRContext = context->driverPrivate;
+ bool res;
+
+ res = PVRDRIUnmapEGLImage(psPVRContext->psPVRScreen->psImpl,
+ psPVRContext->psImpl,
+ image->psEGLImage, image->psShared->psBuffer,
+ data);
+ if (!res)
+ {
+ __driUtilMessage("%s: PVRDRIUnmapEGLImage failed\n", __func__);
+ }
+}
diff --git a/src/mesa/drivers/dri/pvr/pvrimage.h b/src/mesa/drivers/dri/pvr/pvrimage.h
new file mode 100644
index 00000000000..9316ea3bedf
--- /dev/null
+++ b/src/mesa/drivers/dri/pvr/pvrimage.h
@@ -0,0 +1,131 @@
+/* -*- mode: c; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* vi: set ts=8 sw=8 sts=8: */
+/*
+ * 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(__PVRIMAGE_H__)
+#define __PVRIMAGE_H__
+
+#include "dri_support.h"
+
+__DRIimage *PVRDRICreateImageFromName(__DRIscreen *screen,
+ int width, int height, int format,
+ int name, int pitch,
+ void *loaderPrivate);
+
+__DRIimage *PVRDRICreateImageFromRenderbuffer(__DRIcontext *context,
+ int renderbuffer,
+ void *loaderPrivate);
+
+void PVRDRIDestroyImage(__DRIimage *image);
+
+__DRIimage *PVRDRICreateImage(__DRIscreen *screen,
+ int width, int height, int format,
+ unsigned int use,
+ void *loaderPrivate);
+
+__DRIimage *PVRDRICreateImageWithModifiers(__DRIscreen *screen,
+ int width, int height, int format,
+ const uint64_t *modifiers,
+ const unsigned int modifier_count,
+ void *loaderPrivate);
+
+GLboolean PVRDRIQueryImage(__DRIimage *image, int attrib, int *value);
+
+__DRIimage *PVRDRIDupImage(__DRIimage *image, void *loaderPrivate);
+
+GLboolean PVRDRIValidateUsage(__DRIimage *image, unsigned int use);
+
+__DRIimage *PVRDRICreateImageFromNames(__DRIscreen *screen,
+ int width, int height, int fourcc,
+ int *names, int num_names,
+ int *strides, int *offsets,
+ void *loaderPrivate);
+
+__DRIimage *PVRDRIFromPlanar(__DRIimage *image, int plane,
+ void *loaderPrivate);
+
+__DRIimage *PVRDRICreateImageFromTexture(__DRIcontext *context,
+ int glTarget,
+ unsigned texture,
+ int depth,
+ int level,
+ unsigned *error,
+ void *loaderPrivate);
+
+__DRIimage *PVRDRICreateImageFromFds(__DRIscreen *screen,
+ int width, int height, int fourcc,
+ int *fds, int num_fds,
+ int *strides, int *offsets,
+ void *loaderPrivate);
+
+__DRIimage *PVRDRICreateImageFromBuffer(__DRIcontext *context,
+ int target,
+ void *buffer,
+ unsigned *error,
+ void *loaderPrivate);
+
+__DRIimage *PVRDRICreateImageFromDmaBufs(__DRIscreen *screen,
+ int width, int height, int fourcc,
+ int *fds, int num_fds,
+ int *strides, int *offsets,
+ enum __DRIYUVColorSpace color_space,
+ enum __DRISampleRange sample_range,
+ enum __DRIChromaSiting horiz_siting,
+ enum __DRIChromaSiting vert_siting,
+ unsigned *error,
+ void *loaderPrivate);
+
+__DRIimage *PVRDRICreateImageFromDmaBufs2(__DRIscreen *screen,
+ int width, int height, int fourcc,
+ uint64_t modifier,
+ int *fds, int num_fds,
+ int *strides, int *offsets,
+ enum __DRIYUVColorSpace color_space,
+ enum __DRISampleRange sample_range,
+ enum __DRIChromaSiting horiz_siting,
+ enum __DRIChromaSiting vert_siting,
+ unsigned *error,
+ void *loaderPrivate);
+
+void PVRDRIBlitImage(__DRIcontext *context,
+ __DRIimage *dst, __DRIimage *src,
+ int dstx0, int dsty0, int dstwidth, int dstheight,
+ int srcx0, int srcy0, int srcwidth, int srcheight,
+ int flush_flag);
+
+int PVRDRIGetCapabilities(__DRIscreen *screen);
+
+void *PVRDRIMapImage(__DRIcontext *context, __DRIimage *image,
+ int x0, int y0, int width, int height,
+ unsigned int flags, int *stride, void **data);
+
+void PVRDRIUnmapImage(__DRIcontext *context, __DRIimage *image, void *data);
+
+__DRIimage *PVRDRICreateImageFromRenderbuffer2(__DRIcontext *context,
+ int renderbuffer,
+ void *loaderPrivate,
+ unsigned *error);
+
+#endif /* !defined(__PVRIMAGE_H__) */
diff --git a/src/mesa/drivers/dri/pvr/pvrmesa.h b/src/mesa/drivers/dri/pvr/pvrmesa.h
new file mode 100644
index 00000000000..6e0fd8d296a
--- /dev/null
+++ b/src/mesa/drivers/dri/pvr/pvrmesa.h
@@ -0,0 +1,41 @@
+/* -*- mode: c; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* vi: set ts=8 sw=8 sts=8: */
+/*
+ * 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 00000000000..b0e5d260341
--- /dev/null
+++ b/src/mesa/drivers/dri/pvr/pvrutil.c
@@ -0,0 +1,1067 @@
+/* -*- mode: c; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* vi: set ts=8 sw=8 sts=8: */
+/*
+ * 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 <stdarg.h>
+#include <stdio.h>
+#include <stdlib.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, ##args)
+#define dbg_printf(f, args...) fprintf(stderr, "LibGL: " f "\n", ##args)
+#endif /* HAVE_ANDROID_PLATFORM */
+
+#define PVRDRIMesaFormatEntry(f) {f, PVRDRI_ ## f }
+
+static const struct
+{
+ mesa_format eMesa;
+ unsigned uPVRDRI;
+} g_asMesaFormats[] = {
+ PVRDRIMesaFormatEntry(MESA_FORMAT_B8G8R8A8_UNORM),
+ PVRDRIMesaFormatEntry(MESA_FORMAT_B8G8R8X8_UNORM),
+#ifdef HAVE_ANDROID_PLATFORM
+ PVRDRIMesaFormatEntry(MESA_FORMAT_R8G8B8A8_UNORM),
+ PVRDRIMesaFormatEntry(MESA_FORMAT_R8G8B8X8_UNORM),
+#endif
+ PVRDRIMesaFormatEntry(MESA_FORMAT_B5G6R5_UNORM),
+};
+
+/* See pvrdri.h for documentation on PVRDRIImageFormat */
+static const PVRDRIImageFormat g_asFormats[] =
+{
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_R10G10B10A2_UNORM,
+ .iDRIFourCC = __DRI_IMAGE_FOURCC_ABGR2101010,
+ .iDRIFormat = __DRI_IMAGE_FORMAT_ABGR2101010,
+ .iDRIComponents = __DRI_IMAGE_COMPONENTS_RGBA,
+ .uiNumPlanes = 1,
+ .sPlanes[0] =
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_R10G10B10A2_UNORM,
+ .uiWidthShift = 0,
+ .uiHeightShift = 0
+ },
+ },
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_B8G8R8A8_UNORM,
+ .iDRIFourCC = __DRI_IMAGE_FOURCC_ARGB8888,
+ .iDRIFormat = __DRI_IMAGE_FORMAT_ARGB8888,
+ .iDRIComponents = __DRI_IMAGE_COMPONENTS_RGBA,
+ .uiNumPlanes = 1,
+ .sPlanes[0] =
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_B8G8R8A8_UNORM,
+ .uiWidthShift = 0,
+ .uiHeightShift = 0
+ },
+ },
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_R8G8B8A8_UNORM,
+ .iDRIFourCC = __DRI_IMAGE_FOURCC_ABGR8888,
+ .iDRIFormat = __DRI_IMAGE_FORMAT_ABGR8888,
+ .iDRIComponents = __DRI_IMAGE_COMPONENTS_RGBA,
+ .uiNumPlanes = 1,
+ .sPlanes[0] =
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_R8G8B8A8_UNORM,
+ .uiWidthShift = 0,
+ .uiHeightShift = 0
+ },
+ },
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_B8G8R8X8_UNORM,
+ .iDRIFourCC = __DRI_IMAGE_FOURCC_XRGB8888,
+ .iDRIFormat = __DRI_IMAGE_FORMAT_XRGB8888,
+ .iDRIComponents = __DRI_IMAGE_COMPONENTS_RGB,
+ .uiNumPlanes = 1,
+ .sPlanes[0] =
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_B8G8R8X8_UNORM,
+ .uiWidthShift = 0,
+ .uiHeightShift = 0
+ },
+ },
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_R8G8B8X8_UNORM,
+ .iDRIFourCC = __DRI_IMAGE_FOURCC_XBGR8888,
+ .iDRIFormat = __DRI_IMAGE_FORMAT_XBGR8888,
+ .iDRIComponents = __DRI_IMAGE_COMPONENTS_RGB,
+ .uiNumPlanes = 1,
+ .sPlanes[0] =
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_R8G8B8X8_UNORM,
+ .uiWidthShift = 0,
+ .uiHeightShift = 0
+ },
+ },
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_B5G6R5_UNORM,
+ .iDRIFourCC = __DRI_IMAGE_FOURCC_RGB565,
+ .iDRIFormat = __DRI_IMAGE_FORMAT_RGB565,
+ .iDRIComponents = __DRI_IMAGE_COMPONENTS_RGB,
+ .uiNumPlanes = 1,
+ .sPlanes[0] =
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_B5G6R5_UNORM,
+ .uiWidthShift = 0,
+ .uiHeightShift = 0
+ },
+ },
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_R8G8_UNORM,
+ .iDRIFourCC = __DRI_IMAGE_FOURCC_GR88,
+ .iDRIFormat = __DRI_IMAGE_FORMAT_GR88,
+ .iDRIComponents = __DRI_IMAGE_COMPONENTS_RG,
+ .uiNumPlanes = 1,
+ .sPlanes[0] =
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_R8G8_UNORM,
+ .uiWidthShift = 0,
+ .uiHeightShift = 0
+ },
+ },
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_R8_UNORM,
+ .iDRIFourCC = __DRI_IMAGE_FOURCC_R8,
+ .iDRIFormat = __DRI_IMAGE_FORMAT_R8,
+ .iDRIComponents = __DRI_IMAGE_COMPONENTS_R,
+ .uiNumPlanes = 1,
+ .sPlanes[0] =
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_R8_UNORM,
+ .uiWidthShift = 0,
+ .uiHeightShift = 0
+ },
+ },
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_L8A8_UNORM,
+ .iDRIFourCC = __DRI_IMAGE_FOURCC_GR88,
+ .iDRIFormat = __DRI_IMAGE_FORMAT_GR88,
+ .iDRIComponents = __DRI_IMAGE_COMPONENTS_RG,
+ .bQueryDmaBufFormatsExclude = true,
+ .uiNumPlanes = 1,
+ .sPlanes[0] =
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_L8A8_UNORM,
+ .uiWidthShift = 0,
+ .uiHeightShift = 0
+ },
+ },
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_L8_UNORM,
+ .iDRIFourCC = __DRI_IMAGE_FOURCC_R8,
+ .iDRIFormat = __DRI_IMAGE_FORMAT_R8,
+ .iDRIComponents = __DRI_IMAGE_COMPONENTS_R,
+ .bQueryDmaBufFormatsExclude = true,
+ .uiNumPlanes = 1,
+ .sPlanes[0] =
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_L8_UNORM,
+ .uiWidthShift = 0,
+ .uiHeightShift = 0
+ },
+ },
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_D32_FLOAT,
+ .iDRIFourCC = 0,
+ .iDRIFormat = __DRI_IMAGE_FORMAT_NONE,
+ .iDRIComponents = 0,
+ .uiNumPlanes = 1,
+ .sPlanes[0] =
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_D32_FLOAT,
+ .uiWidthShift = 0,
+ .uiHeightShift = 0
+ },
+ },
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_S8_UINT,
+ .iDRIFourCC = 0,
+ .iDRIFormat = __DRI_IMAGE_FORMAT_NONE,
+ .iDRIComponents = 0,
+ .uiNumPlanes = 1,
+ .sPlanes[0] =
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_S8_UINT,
+ .uiWidthShift = 0,
+ .uiHeightShift = 0
+ },
+ },
+#if defined(__DRI_IMAGE_FORMAT_ARGB4444)
+ /* We patch this format into Mesa */
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_B4G4R4A4_UNORM,
+ .iDRIFourCC = __DRI_IMAGE_FOURCC_ARGB4444,
+ .iDRIFormat = __DRI_IMAGE_FORMAT_ARGB4444,
+ .iDRIComponents = __DRI_IMAGE_COMPONENTS_RGBA,
+ .uiNumPlanes = 1,
+ .sPlanes[0] =
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_B4G4R4A4_UNORM,
+ .uiWidthShift = 0,
+ .uiHeightShift = 0
+ },
+ },
+#endif
+#if defined(__DRI_IMAGE_FORMAT_ARGB1555)
+ /* We patch this format into Mesa */
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_B5G5R5A1_UNORM,
+ .iDRIFourCC = __DRI_IMAGE_FOURCC_ARGB1555,
+ .iDRIFormat = __DRI_IMAGE_FORMAT_ARGB1555,
+ .iDRIComponents = __DRI_IMAGE_COMPONENTS_RGBA,
+ .uiNumPlanes = 1,
+ .sPlanes[0] =
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_B5G5R5A1_UNORM,
+ .uiWidthShift = 0,
+ .uiHeightShift = 0
+ },
+ },
+#endif
+#if defined(__DRI_IMAGE_COMPONENTS_EXTERNAL)
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_YUYV,
+ .iDRIFourCC = __DRI_IMAGE_FOURCC_YUYV,
+ .iDRIFormat = __DRI_IMAGE_FORMAT_YUYV,
+ .iDRIComponents = __DRI_IMAGE_COMPONENTS_EXTERNAL,
+ .uiNumPlanes = 1,
+ .sPlanes[0] =
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_YUYV,
+ .uiWidthShift = 0,
+ .uiHeightShift = 0
+ },
+ },
+#if defined(__DRI_IMAGE_FOURCC_YVU444_PACK10_IMG)
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_YVU10_444_1PLANE_PACK10,
+ .iDRIFourCC = __DRI_IMAGE_FOURCC_YVU444_PACK10_IMG,
+ .iDRIFormat = __DRI_IMAGE_FORMAT_YVU444_PACK10_IMG,
+ .iDRIComponents = __DRI_IMAGE_COMPONENTS_EXTERNAL,
+ .uiNumPlanes = 1,
+ .sPlanes[0] =
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_YVU10_444_1PLANE_PACK10,
+ .uiWidthShift = 0,
+ .uiHeightShift = 0,
+ },
+ },
+#endif
+#endif
+#if defined(__DRI_IMAGE_FOURCC_MT21)
+ /* We patch this format into Mesa */
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_YVU8_420_2PLANE_PACK8_P,
+ .iDRIFourCC = __DRI_IMAGE_FOURCC_MT21,
+ .iDRIFormat = __DRI_IMAGE_FORMAT_NONE,
+ .iDRIComponents = __DRI_IMAGE_COMPONENTS_Y_UV,
+ .uiNumPlanes = 2,
+ .sPlanes[0] =
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_R8_UNORM,
+ .uiWidthShift = 0,
+ .uiHeightShift = 0
+ },
+ .sPlanes[1] =
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_R8G8_UNORM,
+ .uiWidthShift = 1,
+ .uiHeightShift = 1
+ },
+ },
+#endif
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_YUV420_2PLANE,
+ .iDRIFourCC = __DRI_IMAGE_FOURCC_NV12,
+ .iDRIFormat = __DRI_IMAGE_FORMAT_NONE,
+ .iDRIComponents = __DRI_IMAGE_COMPONENTS_Y_UV,
+ .uiNumPlanes = 2,
+ .sPlanes[0] =
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_R8_UNORM,
+ .uiWidthShift = 0,
+ .uiHeightShift = 0
+ },
+ .sPlanes[1] =
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_R8G8_UNORM,
+ .uiWidthShift = 1,
+ .uiHeightShift = 1
+ },
+ },
+#if defined(__DRI_IMAGE_FOURCC_NV21)
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_YVU420_2PLANE,
+ .iDRIFourCC = __DRI_IMAGE_FOURCC_NV21,
+ .iDRIFormat = __DRI_IMAGE_FORMAT_NONE,
+ .iDRIComponents = __DRI_IMAGE_COMPONENTS_Y_UV,
+ .uiNumPlanes = 2,
+ .sPlanes[0] =
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_R8_UNORM,
+ .uiWidthShift = 0,
+ .uiHeightShift = 0
+ },
+ .sPlanes[1] =
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_R8G8_UNORM,
+ .uiWidthShift = 1,
+ .uiHeightShift = 1
+ },
+ },
+#endif
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_YUV420_3PLANE,
+ .iDRIFourCC = __DRI_IMAGE_FOURCC_YUV420,
+ .iDRIFormat = __DRI_IMAGE_FORMAT_NONE,
+ .iDRIComponents = __DRI_IMAGE_COMPONENTS_Y_U_V,
+ .uiNumPlanes = 3,
+ .sPlanes[0] =
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_R8_UNORM,
+ .uiWidthShift = 0,
+ .uiHeightShift = 0
+ },
+ .sPlanes[1] =
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_R8_UNORM,
+ .uiWidthShift = 1,
+ .uiHeightShift = 1
+ },
+ .sPlanes[2] =
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_R8_UNORM,
+ .uiWidthShift = 1,
+ .uiHeightShift = 1
+ },
+ },
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_YVU420_3PLANE,
+ .iDRIFourCC = __DRI_IMAGE_FOURCC_YVU420,
+ .iDRIFormat = __DRI_IMAGE_FORMAT_NONE,
+ .iDRIComponents = __DRI_IMAGE_COMPONENTS_Y_U_V,
+ .uiNumPlanes = 3,
+ .sPlanes[0] =
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_R8_UNORM,
+ .uiWidthShift = 0,
+ .uiHeightShift = 0
+ },
+ .sPlanes[1] =
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_R8_UNORM,
+ .uiWidthShift = 1,
+ .uiHeightShift = 1
+ },
+ .sPlanes[2] =
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_R8_UNORM,
+ .uiWidthShift = 1,
+ .uiHeightShift = 1
+ },
+ },
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_D16_UNORM,
+ .iDRIFourCC = 0,
+ .iDRIFormat = __DRI_IMAGE_FORMAT_NONE,
+ .iDRIComponents = 0,
+ .uiNumPlanes = 1,
+ .sPlanes[0] =
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_D16_UNORM,
+ .uiWidthShift = 0,
+ .uiHeightShift = 0
+ },
+ },
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_D24_UNORM_X8_TYPELESS,
+ .iDRIFourCC = 0,
+ .iDRIFormat = __DRI_IMAGE_FORMAT_NONE,
+ .iDRIComponents = 0,
+ .uiNumPlanes = 1,
+ .sPlanes[0] =
+ {
+ .eIMGPixelFormat = IMG_PIXFMT_D24_UNORM_X8_TYPELESS,
+ .uiWidthShift = 0,
+ .uiHeightShift = 0
+ },
+ },
+};
+
+/*
+ * Check if a PVR Screen has support for a particular format based upon its
+ * position in g_asFormats. If querying of this information isn't supported
+ * by pvr_dri_support then assume the format is supported.
+ */
+static inline bool
+PVRDRIScreenHasFormatFromIdx(const PVRDRIScreen * const psPVRScreen,
+ const unsigned int uiFormatIdx)
+{
+ if (psPVRScreen->iNumFormats > 0)
+ {
+ if (uiFormatIdx < ARRAY_SIZE(g_asFormats))
+ {
+ return psPVRScreen->pbHasFormat[uiFormatIdx];
+ }
+
+ return false;
+ }
+
+ assert(psPVRScreen->iNumFormats == -1);
+
+ return true;
+}
+
+/* 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);
+}
+
+const __DRIconfig **PVRDRICreateConfigs(void)
+{
+ static const GLenum asBackBufferModes[] = { __DRI_ATTRIB_SWAP_NONE, __DRI_ATTRIB_SWAP_UNDEFINED };
+ const uint8_t *puDepthBits = PVRDRIDepthBitsArray();
+ const uint8_t *puStencilBits = PVRDRIStencilBitsArray();
+ const uint8_t *puMSAASamples = PVRDRIMSAABitsArray();
+ const unsigned uNumBackBufferModes = ARRAY_SIZE(asBackBufferModes);
+ const unsigned uNumDepthStencilBits = PVRDRIDepthStencilBitArraySize();
+ const unsigned uNumMSAASamples = PVRDRIMSAABitArraySize();
+ __DRIconfig **ppsConfigs = NULL;
+ __DRIconfig **ppsNewConfigs;
+ unsigned i;
+
+ for (i = 0; i < ARRAY_SIZE(g_asMesaFormats); i++)
+ {
+ if (!PVRDRIMesaFormatSupported(g_asMesaFormats[i].uPVRDRI))
+ continue;
+
+ ppsNewConfigs = driCreateConfigs(g_asMesaFormats[i].eMesa,
+ puDepthBits,
+ puStencilBits,
+ uNumDepthStencilBits,
+ asBackBufferModes,
+ uNumBackBufferModes,
+ puMSAASamples,
+ uNumMSAASamples,
+ GL_FALSE,
+ GL_FALSE,
+ GL_FALSE
+#if defined(__DRI_ATTRIB_YUV_BIT)
+ , __DRI_ATTRIB_YUV_DEPTH_RANGE_NONE,
+ __DRI_ATTRIB_YUV_CSC_STANDARD_NONE
+#endif
+ );
+
+ ppsConfigs = driConcatConfigs(ppsConfigs, ppsNewConfigs);
+ }
+
+ if (ppsConfigs)
+ {
+ for (i = 0; ppsConfigs[i]; i++)
+ {
+ ppsConfigs[i]->modes.maxPbufferWidth =
+ PVRDRIMaxPBufferWidth();
+ ppsConfigs[i]->modes.maxPbufferHeight =
+ PVRDRIMaxPBufferHeight();
+
+ ppsConfigs[i]->modes.maxPbufferPixels =
+ PVRDRIMaxPBufferWidth() *
+ PVRDRIMaxPBufferHeight();
+ }
+ }
+
+ return (const __DRIconfig **)ppsConfigs;
+}
+
+const PVRDRIImageFormat *PVRDRIFormatToImageFormat(PVRDRIScreen *psPVRScreen,
+ int iDRIFormat)
+{
+ unsigned i;
+
+ assert(iDRIFormat != __DRI_IMAGE_FORMAT_NONE);
+
+ for (i = 0; i < ARRAY_SIZE(g_asFormats); i++)
+ {
+ if (g_asFormats[i].iDRIFormat != iDRIFormat)
+ {
+ continue;
+ }
+
+ if (!PVRDRIScreenHasFormatFromIdx(psPVRScreen, i))
+ {
+ break;
+ }
+
+ return &g_asFormats[i];
+ }
+
+ return NULL;
+}
+
+const PVRDRIImageFormat *PVRDRIFourCCToImageFormat(PVRDRIScreen *psPVRScreen,
+ int iDRIFourCC)
+{
+ unsigned i;
+
+ if (!iDRIFourCC)
+ {
+ return NULL;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(g_asFormats); i++)
+ {
+ if (g_asFormats[i].iDRIFourCC != iDRIFourCC)
+ {
+ continue;
+ }
+
+ if (!PVRDRIScreenHasFormatFromIdx(psPVRScreen, i))
+ {
+ break;
+ }
+
+ return &g_asFormats[i];
+ }
+
+ return NULL;
+}
+
+const PVRDRIImageFormat *PVRDRIIMGPixelFormatToImageFormat(PVRDRIScreen *psPVRScreen,
+ IMG_PIXFMT eIMGPixelFormat)
+{
+ unsigned i;
+
+ assert(eIMGPixelFormat != IMG_PIXFMT_UNKNOWN);
+
+ for (i = 0; i < ARRAY_SIZE(g_asFormats); i++)
+ {
+ if (g_asFormats[i].eIMGPixelFormat != eIMGPixelFormat)
+ {
+ continue;
+ }
+
+ /*
+ * Assume that the screen has the format, i.e. it's supported by
+ * the HW+SW, since we can only have an IMG_PIXFMT from having
+ * called one of the other PVRDRI*ToImageFormat functions or
+ * one of the pvr_dri_support functions.
+ */
+ assert(PVRDRIScreenHasFormatFromIdx(psPVRScreen, i));
+
+ return &g_asFormats[i];
+ }
+
+ return NULL;
+}
+
+/*
+ * The EGL_EXT_image_dma_buf_import says that if a hint is unspecified then
+ * the implementation may guess based on the pixel format or may fallback
+ * to some default value. Furthermore, if a hint is unsupported then the
+ * implementation may use whichever settings it wants to achieve the closest
+ * match.
+ */
+IMG_YUV_COLORSPACE PVRDRIToIMGColourSpace(const PVRDRIImageFormat *psFormat,
+ enum __DRIYUVColorSpace eDRIColourSpace,
+ enum __DRISampleRange eDRISampleRange)
+{
+ switch (psFormat->iDRIComponents)
+ {
+ case __DRI_IMAGE_COMPONENTS_R:
+ case __DRI_IMAGE_COMPONENTS_RG:
+ case __DRI_IMAGE_COMPONENTS_RGB:
+ case __DRI_IMAGE_COMPONENTS_RGBA:
+ return IMG_COLORSPACE_UNDEFINED;
+ case __DRI_IMAGE_COMPONENTS_Y_U_V:
+ case __DRI_IMAGE_COMPONENTS_Y_UV:
+ case __DRI_IMAGE_COMPONENTS_Y_XUXV:
+#if defined(__DRI_IMAGE_COMPONENTS_EXTERNAL)
+ case __DRI_IMAGE_COMPONENTS_EXTERNAL:
+#endif
+ break;
+ default:
+ errorMessage("Unrecognised DRI components (components = 0x%X)\n",
+ psFormat->iDRIComponents);
+ unreachable("unhandled DRI component");
+ return IMG_COLORSPACE_UNDEFINED;
+ }
+
+ switch (eDRIColourSpace)
+ {
+ case __DRI_YUV_COLOR_SPACE_UNDEFINED:
+ case __DRI_YUV_COLOR_SPACE_ITU_REC601:
+ switch (eDRISampleRange)
+ {
+ case __DRI_YUV_RANGE_UNDEFINED:
+ case __DRI_YUV_NARROW_RANGE:
+ return IMG_COLORSPACE_BT601_CONFORMANT_RANGE;
+ case __DRI_YUV_FULL_RANGE:
+ return IMG_COLORSPACE_BT601_FULL_RANGE;
+ default:
+ errorMessage("Unrecognised DRI sample range (sample range = 0x%X)\n",
+ eDRISampleRange);
+ unreachable("unhandled sample range");
+ return IMG_COLORSPACE_UNDEFINED;
+ }
+ case __DRI_YUV_COLOR_SPACE_ITU_REC709:
+ switch (eDRISampleRange)
+ {
+ case __DRI_YUV_RANGE_UNDEFINED:
+ case __DRI_YUV_NARROW_RANGE:
+ return IMG_COLORSPACE_BT709_CONFORMANT_RANGE;
+ case __DRI_YUV_FULL_RANGE:
+ return IMG_COLORSPACE_BT709_FULL_RANGE;
+ default:
+ errorMessage("Unrecognised DRI sample range (sample range = 0x%X)\n",
+ eDRISampleRange);
+ unreachable("unhandled sample range");
+ return IMG_COLORSPACE_UNDEFINED;
+ }
+ case __DRI_YUV_COLOR_SPACE_ITU_REC2020:
+ switch (eDRISampleRange)
+ {
+ case __DRI_YUV_RANGE_UNDEFINED:
+ case __DRI_YUV_NARROW_RANGE:
+ return IMG_COLORSPACE_BT2020_CONFORMANT_RANGE;
+ case __DRI_YUV_FULL_RANGE:
+ return IMG_COLORSPACE_BT2020_FULL_RANGE;
+ default:
+ errorMessage("Unrecognised DRI sample range (sample range = 0x%X)\n",
+ eDRISampleRange);
+ assert(0);
+ return IMG_COLORSPACE_UNDEFINED;
+ }
+ default:
+ errorMessage("Unrecognised DRI colour space (colour space = 0x%X)\n",
+ eDRIColourSpace);
+ unreachable("unhandled color space");
+ return IMG_COLORSPACE_UNDEFINED;
+ }
+}
+
+IMG_YUV_CHROMA_INTERP PVRDRIChromaSittingToIMGInterp(const PVRDRIImageFormat *psFormat,
+ enum __DRIChromaSiting eChromaSitting)
+{
+ switch (psFormat->iDRIComponents)
+ {
+ case __DRI_IMAGE_COMPONENTS_R:
+ case __DRI_IMAGE_COMPONENTS_RG:
+ case __DRI_IMAGE_COMPONENTS_RGB:
+ case __DRI_IMAGE_COMPONENTS_RGBA:
+ return IMG_CHROMA_INTERP_UNDEFINED;
+ case __DRI_IMAGE_COMPONENTS_Y_U_V:
+ case __DRI_IMAGE_COMPONENTS_Y_UV:
+ case __DRI_IMAGE_COMPONENTS_Y_XUXV:
+#if defined(__DRI_IMAGE_COMPONENTS_EXTERNAL)
+ case __DRI_IMAGE_COMPONENTS_EXTERNAL:
+#endif
+ break;
+ default:
+ errorMessage("Unrecognised DRI components (components = 0x%X)\n",
+ psFormat->iDRIComponents);
+ unreachable("unhandled dri component");
+ return IMG_CHROMA_INTERP_UNDEFINED;
+ }
+
+ switch (eChromaSitting)
+ {
+ case __DRI_YUV_CHROMA_SITING_UNDEFINED:
+ case __DRI_YUV_CHROMA_SITING_0:
+ return IMG_CHROMA_INTERP_ZERO;
+ case __DRI_YUV_CHROMA_SITING_0_5:
+ return IMG_CHROMA_INTERP_HALF;
+ default:
+ errorMessage("Unrecognised DRI chroma sitting (chroma sitting = 0x%X)\n",
+ eChromaSitting);
+ unreachable("unhandled chroma sitting");
+ return IMG_CHROMA_INTERP_UNDEFINED;
+ }
+}
+
+bool PVRDRIGetSupportedFormats(PVRDRIScreen *psPVRScreen)
+{
+ int *piFormats;
+ IMG_PIXFMT *peImgFormats;
+ bool bRet = false;
+ unsigned i;
+
+ piFormats = malloc(ARRAY_SIZE(g_asFormats) * sizeof(*piFormats));
+ peImgFormats = malloc(ARRAY_SIZE(g_asFormats) * sizeof(*peImgFormats));
+
+ psPVRScreen->pbHasFormat = malloc(ARRAY_SIZE(g_asFormats) *
+ sizeof(*psPVRScreen->pbHasFormat));
+
+ psPVRScreen->psModifiers = calloc(ARRAY_SIZE(g_asFormats),
+ sizeof(*psPVRScreen->psModifiers));
+
+ if (!piFormats || !peImgFormats ||
+ !psPVRScreen->pbHasFormat || !psPVRScreen->psModifiers)
+ {
+ errorMessage("Out of memory\n");
+
+ goto err_free;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(g_asFormats); i++)
+ {
+ piFormats[i] = g_asFormats[i].bQueryDmaBufFormatsExclude ?
+ 0 : g_asFormats[i].iDRIFourCC;
+
+ peImgFormats[i] = g_asFormats[i].eIMGPixelFormat;
+
+ psPVRScreen->psModifiers[i].iNumModifiers = -1;
+ }
+
+ psPVRScreen->iNumFormats =
+ PVRDRIQuerySupportedFormats(psPVRScreen->psImpl,
+ ARRAY_SIZE(g_asFormats),
+ piFormats,
+ peImgFormats,
+ psPVRScreen->pbHasFormat);
+ if (psPVRScreen->iNumFormats == 0)
+ {
+ __driUtilMessage("Couldn't query supported pixel formats\n");
+ goto err_free;
+ }
+
+ bRet = true;
+ goto cleanup;
+
+err_free:
+ free(psPVRScreen->psModifiers);
+ psPVRScreen->psModifiers = NULL;
+
+ free(psPVRScreen->pbHasFormat);
+ psPVRScreen->pbHasFormat = NULL;
+cleanup:
+ free(peImgFormats);
+ free(piFormats);
+ return bRet;
+}
+
+GLboolean PVRDRIQueryDmaBufFormats(__DRIscreen *screen, int max,
+ int *formats, int *count)
+{
+ PVRDRIScreen *psPVRScreen = DRIScreenPrivate(screen);
+ int i, j;
+
+ assert(psPVRScreen->iNumFormats != 0);
+
+ if (psPVRScreen->iNumFormats < 0)
+ {
+ return GL_FALSE;
+ }
+
+ if (!max)
+ {
+ *count = psPVRScreen->iNumFormats;
+ return GL_TRUE;
+ }
+
+ for (i = 0, j = 0; i < ARRAY_SIZE(g_asFormats) && j < max; i++)
+ {
+ if (psPVRScreen->pbHasFormat[i])
+ {
+ formats[j++] = g_asFormats[i].iDRIFourCC;
+ }
+ }
+
+ *count = j;
+
+ return GL_TRUE;
+}
+
+static bool PVRDRIGetSupportedModifiers(PVRDRIScreen *psPVRScreen,
+ struct PVRDRIModifiers *psModifiers,
+ const PVRDRIImageFormat *psFormat)
+{
+ int iNumModifiers;
+
+ iNumModifiers = PVRDRIQueryModifiers(psPVRScreen->psImpl,
+ psFormat->iDRIFourCC,
+ psFormat->eIMGPixelFormat,
+ NULL, NULL);
+ if (iNumModifiers < 0)
+ {
+ errorMessage("Couldn't query modifiers for format 0x%x\n",
+ psFormat->iDRIFourCC);
+ return false;
+ }
+
+ psModifiers->puModifiers = malloc(iNumModifiers *
+ sizeof(*psModifiers->puModifiers));
+ psModifiers->puExternalOnly = malloc(iNumModifiers *
+ sizeof(*psModifiers->puExternalOnly));
+ if (!psModifiers->puModifiers || !psModifiers->puExternalOnly)
+ {
+ free(psModifiers->puModifiers);
+ psModifiers->puModifiers = NULL;
+
+ free(psModifiers->puExternalOnly);
+ psModifiers->puExternalOnly = NULL;
+
+ errorMessage("Out of memory\n");
+
+ return false;
+ }
+ psModifiers->iNumModifiers = iNumModifiers;
+
+ iNumModifiers = PVRDRIQueryModifiers(psPVRScreen->psImpl,
+ psFormat->iDRIFourCC,
+ psFormat->eIMGPixelFormat,
+ psModifiers->puModifiers,
+ psModifiers->puExternalOnly);
+
+ assert(iNumModifiers == psModifiers->iNumModifiers);
+
+ return true;
+}
+
+static bool PVRDRIGetModifiersForFormat(PVRDRIScreen *psPVRScreen,
+ int fourcc,
+ const PVRDRIImageFormat **ppsFormat,
+ const struct PVRDRIModifiers **ppsModifiers)
+{
+ const PVRDRIImageFormat *psFormat;
+ struct PVRDRIModifiers *psModifiers;
+ unsigned uIdx;
+
+ assert(psPVRScreen->iNumFormats != 0);
+
+ if (psPVRScreen->iNumFormats < 0)
+ {
+ return false;
+ }
+
+ psFormat = PVRDRIFourCCToImageFormat(psPVRScreen, fourcc);
+ if (!psFormat)
+ {
+ return false;
+ }
+
+ uIdx = psFormat - g_asFormats;
+ psModifiers = &psPVRScreen->psModifiers[uIdx];
+
+ if (psModifiers->iNumModifiers < 0)
+ {
+ if (!PVRDRIGetSupportedModifiers(psPVRScreen,
+ psModifiers,
+ psFormat))
+ {
+ return false;
+ }
+ }
+
+ *ppsFormat = psFormat;
+ *ppsModifiers = psModifiers;
+
+ return true;
+}
+
+bool PVRDRIValidateImageModifier(PVRDRIScreen *psPVRScreen, const int iFourcc,
+ const uint64_t uiModifier)
+{
+ const PVRDRIImageFormat *psFormat;
+ const struct PVRDRIModifiers *psModifiers;
+
+ if (!PVRDRIGetModifiersForFormat(psPVRScreen, iFourcc, &psFormat,
+ &psModifiers))
+ {
+ return false;
+ }
+
+ for (unsigned i = 0; i < psModifiers->iNumModifiers; i++)
+ {
+ if (psModifiers->puModifiers[i] == uiModifier)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+GLboolean PVRDRIQueryDmaBufModifiers(__DRIscreen *screen, int fourcc,
+ int max, uint64_t *modifiers,
+ unsigned int *external_only,
+ int *count)
+{
+ PVRDRIScreen *psPVRScreen = DRIScreenPrivate(screen);
+ const PVRDRIImageFormat *psFormat;
+ const struct PVRDRIModifiers *psModifiers;
+ int num_copy;
+
+ if (!PVRDRIGetModifiersForFormat(psPVRScreen,
+ fourcc,
+ &psFormat,
+ &psModifiers))
+ {
+ return GL_FALSE;
+ }
+
+ if (!max)
+ {
+ *count = psModifiers->iNumModifiers;
+ return GL_TRUE;
+ }
+
+ num_copy = (max < psModifiers->iNumModifiers) ?
+ max : psModifiers->iNumModifiers;
+
+ if (modifiers)
+ {
+ (void) memcpy(modifiers,
+ psModifiers->puModifiers,
+ sizeof(*modifiers) * num_copy);
+ }
+
+ if (external_only)
+ {
+ (void) memcpy(external_only,
+ psModifiers->puExternalOnly,
+ sizeof(*external_only) * num_copy);
+ }
+
+ *count = num_copy;
+
+ return GL_TRUE;
+}
+
+GLboolean PVRDRIQueryDmaBufFormatModifierAttribs(__DRIscreen *screen,
+ uint32_t fourcc,
+ uint64_t modifier,
+ int attrib,
+ uint64_t *value)
+{
+ PVRDRIScreen *psPVRScreen = DRIScreenPrivate(screen);
+ const PVRDRIImageFormat *psFormat;
+ const struct PVRDRIModifiers *psModifiers;
+ int i;
+
+ if (!PVRDRIGetModifiersForFormat(psPVRScreen,
+ fourcc,
+ &psFormat,
+ &psModifiers))
+ {
+ return GL_FALSE;
+ }
+
+ for (i = 0; i < psModifiers->iNumModifiers; i++)
+ {
+ if (psModifiers->puModifiers[i] == modifier)
+ {
+ break;
+ }
+ }
+ if (i == psModifiers->iNumModifiers)
+ {
+ return GL_FALSE;
+ }
+
+ switch (attrib)
+ {
+ case __DRI_IMAGE_FORMAT_MODIFIER_ATTRIB_PLANE_COUNT:
+ *value = psFormat->uiNumPlanes;
+ break;
+ default:
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
+}
+
+void PVRDRIDestroyFormatInfo(PVRDRIScreen *psPVRScreen)
+{
+ unsigned i;
+
+ if (psPVRScreen->psModifiers)
+ {
+ for (i = 0; i < ARRAY_SIZE(g_asFormats); i++)
+ {
+ free(psPVRScreen->psModifiers[i].puModifiers);
+ free(psPVRScreen->psModifiers[i].puExternalOnly);
+ }
+ free(psPVRScreen->psModifiers);
+ }
+
+ free(psPVRScreen->pbHasFormat);
+}
diff --git a/src/meson.build b/src/meson.build
index ae094fccf6c..e5865ac2a9d 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -26,6 +26,7 @@ inc_src = include_directories('.')
inc_gallium = include_directories('gallium/include')
inc_gallium_aux = include_directories('gallium/auxiliary')
inc_amd_common = include_directories('amd/common')
+inc_pvr = include_directories('mesa/main', 'mapi/glapi')
libglsl_util = static_library(
'glsl_util',
--
2.22.0