| 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 |
| |