From 2c1b96a851f2313e6832989fe13d49ca05c4545c Mon Sep 17 00:00:00 2001 From: Frank Binns Date: Tue, 14 Apr 2020 09:47:46 +0100 Subject: [PATCH 01/50] Add pvr dri driver --- meson.build | 19 +- meson_options.txt | 2 +- src/mesa/drivers/dri/meson.build | 5 + src/mesa/drivers/dri/pvr/dri_support.h | 1270 ++++++++++++++++ src/mesa/drivers/dri/pvr/img_drm_fourcc.h | 113 ++ src/mesa/drivers/dri/pvr/imgpixfmts.h | 307 ++++ src/mesa/drivers/dri/pvr/imgyuv.h | 58 + src/mesa/drivers/dri/pvr/mesa_context.c | 208 +++ src/mesa/drivers/dri/pvr/meson.build | 53 + src/mesa/drivers/dri/pvr/pvrcb.c | 282 ++++ src/mesa/drivers/dri/pvr/pvrcompat.c | 1552 ++++++++++++++++++++ src/mesa/drivers/dri/pvr/pvrdrawable_mod.c | 385 +++++ src/mesa/drivers/dri/pvr/pvrdri.c | 603 ++++++++ src/mesa/drivers/dri/pvr/pvrdri.h | 176 +++ src/mesa/drivers/dri/pvr/pvrdri_mod.c | 584 ++++++++ src/mesa/drivers/dri/pvr/pvrdri_mod.h | 450 ++++++ src/mesa/drivers/dri/pvr/pvrdri_support.h | 439 ++++++ src/mesa/drivers/dri/pvr/pvrext.c | 698 +++++++++ src/mesa/drivers/dri/pvr/pvrext_mod.c | 276 ++++ src/mesa/drivers/dri/pvr/pvrimage_mod.c | 1282 ++++++++++++++++ src/mesa/drivers/dri/pvr/pvrmesa.h | 36 + src/mesa/drivers/dri/pvr/pvrutil.c | 239 +++ src/mesa/drivers/dri/pvr/pvrutil_mod.c | 921 ++++++++++++ src/meson.build | 1 + 24 files changed, 9950 insertions(+), 9 deletions(-) create mode 100644 src/mesa/drivers/dri/pvr/dri_support.h create mode 100644 src/mesa/drivers/dri/pvr/img_drm_fourcc.h create mode 100644 src/mesa/drivers/dri/pvr/imgpixfmts.h create mode 100644 src/mesa/drivers/dri/pvr/imgyuv.h create mode 100644 src/mesa/drivers/dri/pvr/mesa_context.c create mode 100644 src/mesa/drivers/dri/pvr/meson.build create mode 100644 src/mesa/drivers/dri/pvr/pvrcb.c create mode 100644 src/mesa/drivers/dri/pvr/pvrcompat.c create mode 100644 src/mesa/drivers/dri/pvr/pvrdrawable_mod.c create mode 100644 src/mesa/drivers/dri/pvr/pvrdri.c create mode 100644 src/mesa/drivers/dri/pvr/pvrdri.h create mode 100644 src/mesa/drivers/dri/pvr/pvrdri_mod.c create mode 100644 src/mesa/drivers/dri/pvr/pvrdri_mod.h create mode 100644 src/mesa/drivers/dri/pvr/pvrdri_support.h create mode 100644 src/mesa/drivers/dri/pvr/pvrext.c create mode 100644 src/mesa/drivers/dri/pvr/pvrext_mod.c create mode 100644 src/mesa/drivers/dri/pvr/pvrimage_mod.c create mode 100644 src/mesa/drivers/dri/pvr/pvrmesa.h create mode 100644 src/mesa/drivers/dri/pvr/pvrutil.c create mode 100644 src/mesa/drivers/dri/pvr/pvrutil_mod.c diff --git a/meson.build b/meson.build index 932eb136681..15e08dfea1c 100644 --- a/meson.build +++ b/meson.build @@ -160,11 +160,11 @@ if dri_drivers.contains('auto') if system_has_kms_drm # TODO: PPC, Sparc if ['x86', 'x86_64'].contains(host_machine.cpu_family()) - dri_drivers = ['i915', 'i965', 'r100', 'r200', 'nouveau'] + dri_drivers = ['i915', 'i965', 'r100', 'r200', 'nouveau', 'pvr'] elif ['arm', 'aarch64'].contains(host_machine.cpu_family()) - dri_drivers = [] + dri_drivers = ['pvr'] elif ['mips', 'mips64'].contains(host_machine.cpu_family()) - dri_drivers = ['r100', 'r200', 'nouveau'] + dri_drivers = ['r100', 'r200', 'nouveau', 'pvr'] else error('Unknown architecture @0@. Please pass -Ddri-drivers to set driver options. Patches gladly accepted to fix this.'.format( host_machine.cpu_family())) @@ -183,6 +183,7 @@ with_dri_i965 = dri_drivers.contains('i965') with_dri_r100 = dri_drivers.contains('r100') with_dri_r200 = dri_drivers.contains('r200') with_dri_nouveau = dri_drivers.contains('nouveau') +with_dri_pvr = dri_drivers.contains('pvr') with_dri = dri_drivers.length() != 0 @@ -1435,14 +1436,16 @@ _drm_amdgpu_ver = '2.4.100' _drm_radeon_ver = '2.4.71' _drm_nouveau_ver = '2.4.102' _drm_intel_ver = '2.4.75' +_drm_pvr_ver = '2.4.60' _drm_ver = '2.4.81' _libdrm_checks = [ - ['intel', with_dri_i915 or with_gallium_i915], - ['amdgpu', with_amd_vk 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)], + with_gallium_r300 or with_gallium_r600), true], + ['nouveau', (with_gallium_nouveau or with_dri_nouveau), true], + ['pvr', with_dri_pvr, false], ] # VC4 only needs core libdrm support of this version, not a libdrm_vc4 @@ -1472,7 +1475,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 fc73f6e1c24..6f001343ae6 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -45,7 +45,7 @@ option( 'dri-drivers', type : 'array', value : ['auto'], - choices : ['auto', 'i915', 'i965', 'r100', 'r200', 'nouveau'], + choices : ['auto', 'i915', 'i965', 'r100', 'r200', 'nouveau', 'pvr'], description : 'List of dri drivers to build. If this is set to auto all drivers applicable to the target OS/architecture will be built' ) option( diff --git a/src/mesa/drivers/dri/meson.build b/src/mesa/drivers/dri/meson.build index 97210c8e638..2018e3fc1c4 100644 --- a/src/mesa/drivers/dri/meson.build +++ b/src/mesa/drivers/dri/meson.build @@ -47,6 +47,11 @@ if with_dri_nouveau _dri_drivers += libnouveau_vieux _dri_link += 'nouveau_vieux_dri.so' endif +if with_dri_pvr + subdir('pvr') + _dri_drivers += libpvr + _dri_link += 'pvr_dri.so' +endif if _dri_drivers != [] libmesa_dri_drivers = shared_library( diff --git a/src/mesa/drivers/dri/pvr/dri_support.h b/src/mesa/drivers/dri/pvr/dri_support.h new file mode 100644 index 00000000000..b5da4d95a03 --- /dev/null +++ b/src/mesa/drivers/dri/pvr/dri_support.h @@ -0,0 +1,1270 @@ +/* -*- 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 +#include + +#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, + PVRDRI_DEVICE_TYPE_CARD, +} PVRDRIDeviceType; + +/* API type. */ +typedef enum +{ + PVRDRI_API_NONE = 0, + PVRDRI_API_GLES1 = 2, + PVRDRI_API_GLES2 = 3, + PVRDRI_API_CL = 4, + PVRDRI_API_GL_COMPAT = 5, + PVRDRI_API_GL_CORE = 6, +} PVRDRIAPIType; + +/* 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, + + /* Valid for use with with PVRDRICallbacksV2 */ + PVRDRI_CONFIG_ATTRIB_RED_MASK = 21, + PVRDRI_CONFIG_ATTRIB_GREEN_MASK = 22, + PVRDRI_CONFIG_ATTRIB_BLUE_MASK = 23, + PVRDRI_CONFIG_ATTRIB_ALPHA_MASK = 24, + PVRDRI_CONFIG_ATTRIB_SRGB_CAPABLE = 25 +} PVRDRIConfigAttrib; + +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_GL 0x0008 +#define PVRDRI_API_BIT_GLES3 0x0040 + +/* Mesa config formats. These need not match their MESA_FORMAT counterparts */ +#define PVRDRI_MESA_FORMAT_NONE 0 +#define PVRDRI_MESA_FORMAT_B8G8R8A8_UNORM 1 +#define PVRDRI_MESA_FORMAT_B8G8R8X8_UNORM 2 +#define PVRDRI_MESA_FORMAT_B5G6R5_UNORM 3 +#define PVRDRI_MESA_FORMAT_R8G8B8A8_UNORM 4 +#define PVRDRI_MESA_FORMAT_R8G8B8X8_UNORM 5 +#define PVRDRI_MESA_FORMAT_YCBCR 6 +#define PVRDRI_MESA_FORMAT_YUV420_2PLANE 7 +#define PVRDRI_MESA_FORMAT_YVU420_2PLANE 8 +#define PVRDRI_MESA_FORMAT_B8G8R8A8_SRGB 9 +#define PVRDRI_MESA_FORMAT_R8G8B8A8_SRGB 10 + +/* 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 PVRDRI_YUV defines match their __DRI_ATTRIB_YUV 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 PVRDRICallbacks version 2 */ +#define PVRDRI_GETPARAMS_FLAG_ALLOW_RECREATE 0x1 +/* Since PVRDRICallbacks 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; + +/* PVRDRISupportInterface (deprecated) */ +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); + /* Obsolete (no longer supported) */ + bool (*EGLFreeResources)(PVRDRIScreenImpl *psPVRScreenImpl); + void (*EGLMarkRendersurfaceInvalid)(PVRDRIAPIType eAPI, + PVRDRIScreenImpl *psScreenImpl, + PVRDRIContextImpl *psContextImpl); + /* Obsolete (no longer supported) */ + void (*EGLSetFrontBufferCallback)(PVRDRIAPIType eAPI, + PVRDRIScreenImpl *psScreenImpl, + PVRDRIDrawableImpl *psDrawableImpl, + void (*pfnCallback)(PVRDRIDrawable *)); + + /* Obsolete (no longer supported) */ + 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); + + /* Obsolete (no longer supported) */ + 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); + + /* Obsolete (no longer supported) */ + PVRDRIBufferImpl *(*BufferCreateFromName)(PVRDRIScreenImpl *psScreenImpl, + int iName, + int iWidth, + int iHeight, + int iStride, + int iOffset); + + /* Obsolete (no longer supported) */ + 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); + + /* + * When calling ClientWaitSync, the eAPI, psContextImpl and + * bFlushCommands parameters must be set to PVRDRI_API_NONE, + * NULL and false, respectively. + */ + bool (*ClientWaitSync)(PVRDRIAPIType eAPI, + PVRDRIContextImpl *psContextImpl, + void *psDRIFence, + bool bFlushCommands, + bool bTimeout, + uint64_t uiTimeout); + + bool (*ServerWaitSync)(PVRDRIAPIType eAPI, + PVRDRIContextImpl *psContextImpl, + void *psDRIFence); + + /* Obsolete (no longer supported) */ + void (*DestroyFences)(PVRDRIScreenImpl *psScreenImpl); + + /* EGL interface functions */ + + /* Obsolete (no longer supported) */ + 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 (deprecated) */ +typedef struct +{ + /********************************************************************** + * Version 0 callbacks + **********************************************************************/ + + /* Obsolete (no longer supported) */ + bool (*DrawableRecreate)(PVRDRIDrawable *psPVRDrawable); + /* Obsolete (no longer supported) */ + 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 + **********************************************************************/ + + /* Obsolete (no longer supported) */ + 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; + +/* + * The caller of PVRDRIRegisterVersionedCallbacks is not required to preserve + * the PVRDRICallbacks structure after the call, so the callee may need to + * make a copy of the structure. + */ +bool PVRDRIRegisterVersionedCallbacks(const PVRDRICallbacks *psCallbacks, + unsigned uVersion); + +/* The context flags match their __DRI_CTX_RESET counterparts */ +#define PVRDRI_CONTEXT_RESET_NO_NOTIFICATION 0 +#define PVRDRI_CONTEXT_RESET_LOSE_CONTEXT 1 + +/* The context flags match their __DRI_CTX_RELEASE counterparts */ +#define PVRDRI_CONTEXT_RELEASE_BEHAVIOR_NONE 0 +#define PVRDRI_CONTEXT_RELEASE_BEHAVIOR_FLUSH 1 + +/* The flush flags match their __DRI2_FLUSH counterparts */ +#define PVRDRI_FLUSH_DRAWABLE (1 << 0) +#define PVRDRI_FLUSH_CONTEXT (1 << 1) +#define PVRDRI_FLUSH_INVALIDATE_ANCILLARY (1 << 2) + +/* The throttle reason defines match their __DRI2_THROTTLE counterparts */ +#define PVRDRI_THROTTLE_SWAPBUFFER 0 +#define PVRDRI_THROTTLE_COPYSUBBUFFER 1 +#define PVRDRI_THROTTLE_FLUSHFRONT 2 + +/* The render query defines match their __DRI2_RENDERER counterparts */ +#define PVRDRI_RENDERER_VENDOR_ID 0x0000 +#define PVRDRI_RENDERER_DEVICE_ID 0x0001 + +#define PVRDRI_RENDERER_HAS_TEXTURE_3D 0x000b +#define PVRDRI_RENDERER_HAS_FRAMEBUFFER_SRGB 0x000c + +#define PVRDRI_RENDERER_HAS_CONTEXT_PRIORITY 0x000d +#define PVRDRI_RENDERER_HAS_CONTEXT_PRIORITY_LOW (1 << 0) +#define PVRDRI_RENDERER_HAS_CONTEXT_PRIORITY_MEDIUM (1 << 1) +#define PVRDRI_RENDERER_HAS_CONTEXT_PRIORITY_HIGH (1 << 2) + +#define PVRDRI_RENDERER_OPENGL_ES2_CONTEXT_CLIENT_VERSION_IMG 0x7001 + +/* The fence extension defines match their __DRI2_FENCE counterparts */ +#define PVRDRI_FENCE_TIMEOUT_INFINITE 0xffffffffffffffffull +#define PVRDRI_FENCE_FLAG_FLUSH_COMMANDS (1 << 0) + +/* The YUV defines match their __DRI_YUV counterparts */ +#define PVRDRI_YUV_COLOR_SPACE_UNDEFINED 0 +#define PVRDRI_YUV_COLOR_SPACE_ITU_REC601 0x327F +#define PVRDRI_YUV_COLOR_SPACE_ITU_REC709 0x3280 +#define PVRDRI_YUV_COLOR_SPACE_ITU_REC2020 0x3281 + +#define PVRDRI_YUV_RANGE_UNDEFINED 0 +#define PVRDRI_YUV_FULL_RANGE 0x3282 +#define PVRDRI_YUV_NARROW_RANGE 0x3283 + +#define PVRDRI_YUV_CHROMA_SITING_UNDEFINED 0 +#define PVRDRI_YUV_CHROMA_SITING_0 0x3284 +#define PVRDRI_YUV_CHROMA_SITING_0_5 0x3285 + +/* + * The image component defines match their __DRI2_IMAGE_COMPONENTS + * counterparts. + */ +#define PVRDRI_IMAGE_COMPONENTS_RGB 0x3001 +#define PVRDRI_IMAGE_COMPONENTS_RGBA 0x3002 +#define PVRDRI_IMAGE_COMPONENTS_Y_U_V 0x3003 +#define PVRDRI_IMAGE_COMPONENTS_Y_UV 0x3004 +#define PVRDRI_IMAGE_COMPONENTS_Y_XUXV 0x3005 +#define PVRDRI_IMAGE_COMPONENTS_R 0x3006 +#define PVRDRI_IMAGE_COMPONENTS_RG 0x3007 +#define PVRDRI_IMAGE_COMPONENTS_Y_UXVX 0x3008 +#define PVRDRI_IMAGE_COMPONENTS_AYUV 0x3009 +#define PVRDRI_IMAGE_COMPONENTS_XYUV 0x300A +#define PVRDRI_IMAGE_COMPONENTS_EXTERNAL 0x300B + +/* + * The image format modifier attribute defines match their + * __DRI_IMAGE_FORMAT_MODIFIER_ATTRIB counterparts. + */ +#define PVRDRI_IMAGE_FORMAT_MODIFIER_ATTRIB_PLANE_COUNT 0x0001 + +/* The image attribute defines match their __DRI_IMAGE_ATTRIB counterparts */ +#define PVRDRI_IMAGE_ATTRIB_STRIDE 0x2000 +#define PVRDRI_IMAGE_ATTRIB_HANDLE 0x2001 +#define PVRDRI_IMAGE_ATTRIB_NAME 0x2002 +#define PVRDRI_IMAGE_ATTRIB_FORMAT 0x2003 +#define PVRDRI_IMAGE_ATTRIB_WIDTH 0x2004 +#define PVRDRI_IMAGE_ATTRIB_HEIGHT 0x2005 +#define PVRDRI_IMAGE_ATTRIB_COMPONENTS 0x2006 +#define PVRDRI_IMAGE_ATTRIB_FD 0x2007 +#define PVRDRI_IMAGE_ATTRIB_FOURCC 0x2008 +#define PVRDRI_IMAGE_ATTRIB_NUM_PLANES 0x2009 +#define PVRDRI_IMAGE_ATTRIB_OFFSET 0x200A +#define PVRDRI_IMAGE_ATTRIB_MODIFIER_LOWER 0x200B +#define PVRDRI_IMAGE_ATTRIB_MODIFIER_UPPER 0x200C + +/* The GL defines match their EGL_GL counterparts */ +#define PVRDRI_GL_RENDERBUFFER 0x30B9 +#define PVRDRI_GL_TEXTURE_2D 0x30B1 +#define PVRDRI_GL_TEXTURE_3D 0x30B2 +#define PVRDRI_GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x30B3 +#define PVRDRI_GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x30B4 +#define PVRDRI_GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x30B5 +#define PVRDRI_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x30B6 +#define PVRDRI_GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x30B7 +#define PVRDRI_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x30B8 + +/* The CL defines match their EGL_CL counterparts */ +#define PVRDRI_CL_IMAGE_IMG 0x6010 + +/* The swap attribute defines match their __DRI_ATTRIB_SWAP counterparts */ +#define PVRDRI_ATTRIB_SWAP_NONE 0x0000 +#define PVRDRI_ATTRIB_SWAP_EXCHANGE 0x8061 +#define PVRDRI_ATTRIB_SWAP_COPY 0x8062 +#define PVRDRI_ATTRIB_SWAP_UNDEFINED 0x8063 + +struct __DRIscreenRec; +struct __DRIcontextRec; +struct __DRIdrawableRec; +struct __DRIbufferRec; +struct __DRIconfigRec; + +struct DRISUPScreen; +struct DRISUPContext; +struct DRISUPDrawable; +struct DRISUPBuffer; + +struct PVRDRIContextConfig +{ + unsigned int uMajorVersion; + unsigned int uMinorVersion; + uint32_t uFlags; + + int iResetStrategy; + unsigned int uPriority; + int iReleaseBehavior; +}; + +/* The image capability defines match their __DRI_IMAGE_CAP counterparts */ +#define PVRDRI_IMAGE_CAP_GLOBAL_NAMES 1 + +/* + * PVR DRI Support interface V2. + * This structure may change over time, as older interfaces become obsolete. + * For example, the v0 interface may be removed if superseded by newer + * interfaces. + */ +struct PVRDRISupportInterfaceV2 +{ + struct + { + struct DRISUPScreen *(*CreateScreen) + (struct __DRIscreenRec *psDRIScreen, + int iFD, + bool bUseInvalidate, + void *pvLoaderPrivate, + const struct __DRIconfigRec ***pppsConfigs, + int *piMaxGLES1Version, + int *piMaxGLES2Version); + + void (*DestroyScreen) + (struct DRISUPScreen *psDRISUPScreen); + + unsigned int (*CreateContext) + (PVRDRIAPIType eAPI, + PVRDRIConfig *psPVRDRIConfig, + struct PVRDRIContextConfig *psCtxConfig, + struct __DRIcontextRec *psDRIContext, + struct DRISUPContext *psDRISUPSharedContext, + struct DRISUPScreen *psDRISUPScreen, + struct DRISUPContext **ppsDRISUPContext); + + void (*DestroyContext) + (struct DRISUPContext *psDRISUPContext); + + struct DRISUPDrawable *(*CreateDrawable) + (struct __DRIdrawableRec *psDRIDrawable, + struct DRISUPScreen *psDRISUPDrawable, + void *pvLoaderPrivate, + PVRDRIConfig *psPVRDRIConfig); + + void (*DestroyDrawable) + (struct DRISUPDrawable *psDRISUPDrawable); + + bool (*MakeCurrent) + (struct DRISUPContext *psDRISUPContext, + struct DRISUPDrawable *psDRISUPWrite, + struct DRISUPDrawable *psDRISUPRead); + + bool (*UnbindContext) + (struct DRISUPContext *psDRISUPContext); + + struct DRISUPBuffer *(*AllocateBuffer) + (struct DRISUPScreen *psDRISUPScreen, + unsigned int uAttachment, + unsigned int uFormat, + int iWidth, + int iHeight, + unsigned int *puName, + unsigned int *puPitch, + unsigned int *puCPP, + unsigned int *puFlags); + + void (*ReleaseBuffer) + (struct DRISUPScreen *psDRISUPScreen, + struct DRISUPBuffer *psDRISUPBuffer); + + /* Functions to support the DRI TexBuffer extension */ + void (*SetTexBuffer2) + (struct DRISUPContext *psDRISUPContext, + int iTarget, + int iFormat, + struct DRISUPDrawable *psDRISUPDrawable); + + void (*ReleaseTexBuffer) + (struct DRISUPContext *psDRISUPContext, + int iTarget, + struct DRISUPDrawable *psDRISUPDrawable); + + /* Functions to support the DRI Flush extension */ + void (*Flush) + (struct DRISUPDrawable *psDRISUPDrawable); + + void (*Invalidate) + (struct DRISUPDrawable *psDRISUPDrawable); + + void (*FlushWithFlags) + (struct DRISUPContext *psDRISUPContext, + struct DRISUPDrawable *psDRISUPDrawable, + unsigned int uFlags, + unsigned int uThrottleReason); + + /* Functions to support the DRI Image extension */ + __DRIimage *(*CreateImageFromName) + (struct DRISUPScreen *psDRISUPScreen, + int iWidth, + int iHeight, + int iFourCC, + int iName, + int iPitch, + void *pvLoaderPrivate); + + __DRIimage *(*CreateImageFromRenderbuffer) + (struct DRISUPContext *psDRISUPContext, + int iRenderBuffer, + void *pvLoaderPrivate); + + void (*DestroyImage) + (__DRIimage *psImage); + + __DRIimage *(*CreateImage) + (struct DRISUPScreen *psDRISUPScreen, + int iWidth, + int iHeight, + int iFourCC, + unsigned int uUse, + void *pvLoaderPrivate); + + bool (*QueryImage) + (__DRIimage *psImage, + int iAttrib, + int *iValue); + + __DRIimage *(*DupImage) + (__DRIimage *psImage, + void *pvLoaderPrivate); + + bool (*ValidateImageUsage) + (__DRIimage *psImage, + unsigned int uUse); + + __DRIimage *(*CreateImageFromNames) + (struct DRISUPScreen *psDRISUPScreen, + int iWidth, + int iHeight, + int iFourCC, + int *piNames, + int iNumNames, + int *piStrides, + int *piOffsets, + void *pvLoaderPrivate); + __DRIimage *(*FromPlanar)(__DRIimage *psImage, + int iPlane, + void *pvLoaderPrivate); + + __DRIimage *(*CreateImageFromTexture) + (struct DRISUPContext *psDRISUPContext, + int iTarget, + unsigned int uTexture, + int iDepth, + int iLevel, + unsigned int *puError, + void *pvLoaderPrivate); + + __DRIimage *(*CreateImageFromFDs) + (struct DRISUPScreen *psDRISUPcreen, + int iWidth, + int iHeight, + int iFourCC, + int *piFDs, + int iNumFDs, + int *piStrides, + int *piOffsets, + void *pvLoaderPrivate); + + __DRIimage *(*CreateImageFromDMABufs) + (struct DRISUPScreen *psDRISUPScreen, + int iWidth, + int iHeight, + int iFourCC, + int *piFDs, + int iNumFDs, + int *piStrides, + int *piOffsets, + unsigned int uColorSpace, + unsigned int uSampleRange, + unsigned int uHorizSiting, + unsigned int uVertSiting, + unsigned int *puError, + void *pvLoaderPrivate); + + int (*GetImageCapabilities) + (struct DRISUPScreen *psDRISUPScreen); + + void (*BlitImage) + (struct DRISUPContext *psDRISUPContext, + __DRIimage *psDst, + __DRIimage *psSrc, + int iDstX0, + int iDstY0, + int iDstWidth, + int iDstHeight, + int iSrcX0, int + iSrcY0, + int iSrcWidth, + int iSrcHeight, + int iFlushFlag); + + void *(*MapImage) + (struct DRISUPContext *psDRISUPContext, + __DRIimage *psImage, + int iX0, + int iY0, + int iWidth, + int iHeight, + unsigned int uFlags, + int *piStride, + void **ppvData); + + void (*UnmapImage) + (struct DRISUPContext *psDRISUPContext, + __DRIimage *psImage, + void *pvData); + + __DRIimage *(*CreateImageWithModifiers) + (struct DRISUPScreen *psDRISUPScreen, + int iWidth, + int iHeight, + int iFourCC, + const uint64_t *puModifiers, + const unsigned int uModifierCount, + void *pvLoaderPrivate); + + __DRIimage *(*CreateImageFromDMABufs2) + (struct DRISUPScreen *psDRISUPScreen, + int iWidth, + int iHeight, + int iFourCC, + uint64_t uModifier, + int *piFDs, + int iNumFDs, + int *piStrides, + int *piOffsets, + unsigned int uColorSpace, + unsigned int uSampleRange, + unsigned int uHorizSiting, + unsigned int uVertSiting, + unsigned int *puError, + void *pvLoaderPrivate); + + bool (*QueryDMABufFormats) + (struct DRISUPScreen *psDRISUPScreen, + int iMax, + int *piFormats, + int *piCount); + + bool (*QueryDMABufModifiers) + (struct DRISUPScreen *psDRISUPScreen, + int iFourCC, + int iMax, + uint64_t *puModifiers, + unsigned int *piExternalOnly, + int *piCount); + + bool (*QueryDMABufFormatModifierAttribs) + (struct DRISUPScreen *psDRISUPScreen, + uint32_t uFourcc, + uint64_t uModifier, + int iAttrib, + uint64_t *puValue); + + __DRIimage *(*CreateImageFromRenderBuffer2) + (struct DRISUPContext *psDRISUPContext, + int iRenderBuffer, + void *pvLoaderPrivate, + unsigned int *puError); + + __DRIimage *(*CreateImageFromBuffer) + (struct DRISUPContext *psDRISUPContext, + int iTarget, + void *pvBuffer, + unsigned int *puError, + void *pvLoaderPrivate); + + /* Functions to support the DRI Renderer Query extension */ + int (*QueryRendererInteger) + (struct DRISUPScreen *psDRISUPScreen, + int iAttribute, + unsigned int *puValue); + + int (*QueryRendererString) + (struct DRISUPScreen *psDRISUPScreen, + int iAttribute, + const char **ppszValue); + + /* Functions to support the DRI Fence extension */ + void *(*CreateFence) + (struct DRISUPContext *psDRISUPContext); + + void (*DestroyFence) + (struct DRISUPScreen *psDRISUPScreen, + void *pvFence); + + bool (*ClientWaitSync) + (struct DRISUPContext *psDRISUPContext, + void *pvFence, + unsigned int uFlags, + uint64_t uTimeout); + + void (*ServerWaitSync) + (struct DRISUPContext *psDRISUPContext, + void *pvFence, + unsigned int uFlags); + + unsigned int (*GetFenceCapabilities) + (struct DRISUPScreen *psDRISUPScreen); + + void *(*CreateFenceFD) + (struct DRISUPContext *psDRISUPContext, + int iFD); + + int (*GetFenceFD) + (struct DRISUPScreen *psDRISUPScreen, + void *pvFence); + + unsigned int (*GetNumAPIProcs) + (struct DRISUPScreen *psDRISUPScreen, + PVRDRIAPIType eAPI); + + const char *(*GetAPIProcName) + (struct DRISUPScreen *psDRISUPScreen, + PVRDRIAPIType eAPI, + unsigned int uIndex); + + void *(*GetAPIProcAddress) + (struct DRISUPScreen *psDRISUPScreen, + PVRDRIAPIType eAPI, + unsigned int uIndex); + + void (*SetDamageRegion) + (struct DRISUPDrawable *psDRISUPDrawable, + unsigned int uNRects, + int *piRects); + } v0; + /* The v1 interface is an extension of v0, so v0 is required as well */ + struct { + void *(*GetFenceFromCLEvent) + (struct DRISUPScreen *psDRISUPScreen, + intptr_t iCLEvent); + } v1; + /* The v2 interface is an extension of v1, so v1 is required as well */ + struct { + int (*GetAPIVersion) + (struct DRISUPScreen *psDRISUPScreen, + PVRDRIAPIType eAPI); + } v2; + /* + * The v3 interface has no additional entry points. It indicates that + * OpenCL event based fences are available, provided the DDK is built + * with OpenCL support. + */ +}; + +/* + * Buffer mask values for the GetBuffers callback. These are the same as + * their enum __DRIimageBufferMask counterparts. + */ +#define PVRDRI_IMAGE_BUFFER_BACK (1U << 0) +#define PVRDRI_IMAGE_BUFFER_FRONT (1U << 1) +#define PVRDRI_IMAGE_BUFFER_PREV (1U << 31) + +struct PVRDRIImageList { + uint32_t uImageMask; + __DRIimage *psBack; + __DRIimage *psFront; + __DRIimage *psPrev; +}; + +/* The loader capabilities defines match their dri_loader_cap counterparts */ +#define PVRDRI_LOADER_CAP_RGBA_ORDERING 0 + +/* + * PVR DRI Support callback interface V2. + * This structure may change over time, as older interfaces become obsolete. + * For example, the v0 interface may be removed if superseded by newer + * interfaces. + */ +struct PVRDRICallbacksV2 +{ + struct { + bool (*RegisterSupportInterface) + (const void *psInterface, + unsigned int uVersion, + unsigned int uMinVersion); + + int (*GetBuffers) + (struct __DRIdrawableRec *psDRIDrawable, + unsigned int uFourCC, + uint32_t *puStamp, + void *pvLoaderPrivate, + uint32_t uBufferMask, + struct PVRDRIImageList *psImageList); + + bool (*CreateConfigs) + (struct __DRIconfigRec ***pppsConfigs, + struct __DRIscreenRec *psDRIScreen, + int iPVRDRIMesaFormat, + const uint8_t *puDepthBits, + const uint8_t *puStencilBits, + unsigned int uNumDepthStencilBits, + const unsigned int *puDBModes, + unsigned int uNumDBModes, + const uint8_t *puMSAASamples, + unsigned int uNumMSAAModes, + bool bEnableAccum, + bool bColorDepthMatch, + bool bMutableRenderBuffer, + int iYUVDepthRange, + int iYUVCSCStandard, + uint32_t uMaxPbufferWidth, + uint32_t uMaxPbufferHeight); + + struct __DRIconfigRec **(*ConcatConfigs) + (struct __DRIscreenRec *psDRIScreen, + struct __DRIconfigRec **ppsConfigA, + struct __DRIconfigRec **ppsConfigB); + + bool (*ConfigQuery) + (const PVRDRIConfig *psConfig, + PVRDRIConfigAttrib eConfigAttrib, + unsigned int *puValueOut); + + __DRIimage *(*LookupEGLImage) + (struct __DRIscreenRec *psDRIScreen, + void *pvImage, + void *pvLoaderPrivate); + + unsigned int (*GetCapability) + (struct __DRIscreenRec *psDRIScreen, + unsigned int uCapability); + } v0; + /* The v1 interface is an extension of v0, so v0 is required as well */ + struct { + void (*FlushFrontBuffer) + (struct __DRIdrawableRec *psDRIDrawable, + void *pvLoaderPrivate); + } v1; +}; + +#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..8d570ff8f53 --- /dev/null +++ b/src/mesa/drivers/dri/pvr/img_drm_fourcc.h @@ -0,0 +1,113 @@ +/*************************************************************************/ /*! +@File +@Title Wrapper around drm_fourcc.h +@Description FourCCs and DRM framebuffer modifiers that are not in the + Kernel's and libdrm's drm_fourcc.h can be added here. +@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved +@License MIT + +The contents of this file are subject to the MIT license as set out below. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ /**************************************************************************/ + +#ifndef IMG_DRM_FOURCC_H +#define IMG_DRM_FOURCC_H + +#if defined(__KERNEL__) +#include +#else +/* + * Include types.h to workaround versions of libdrm older than 2.4.68 + * not including the correct headers. + */ +#include + +#include +#endif + +/* + * Don't get too inspired by this example :) + * ADF doesn't support DRM modifiers, so the memory layout had to be + * included in the fourcc name, but the proper way to specify information + * additional to pixel formats is to use DRM modifiers. + * + * See upstream drm_fourcc.h for the proper naming convention. + */ +#ifndef DRM_FORMAT_BGRA8888_DIRECT_16x4 +#define DRM_FORMAT_BGRA8888_DIRECT_16x4 fourcc_code('I', 'M', 'G', '0') +#endif + +/* + * Upstream doesn't have a floating point format yet, so let's make one + * up. + * Note: The kernel's core DRM needs to know about this format, + * otherwise it won't be supported and should not be exposed by our + * kernel modules either. + * Refer to the provided kernel patch adding this format. + */ +#if !defined(__KERNEL__) +#define DRM_FORMAT_ABGR16_IMG fourcc_code('I', 'M', 'G', '1') +#endif + +/* + * Upstream does not have a packed 10 Bits Per Channel YVU format yet, + * so let`s make one up. + * Note: at the moment this format is not intended to be used with + * a framebuffer, so the kernels core DRM doesn`t need to know + * about this format. This means that the kernel doesn`t need + * to be patched. + */ +#if !defined(__KERNEL__) +#define DRM_FORMAT_YVU444_PACK10_IMG fourcc_code('I', 'M', 'G', '2') +#define DRM_FORMAT_YUV422_2PLANE_PACK10_IMG fourcc_code('I', 'M', 'G', '3') +#define DRM_FORMAT_YUV420_2PLANE_PACK10_IMG fourcc_code('I', 'M', 'G', '4') +#endif + +/* + * Value chosen in the middle of 255 pool to minimise the chance of hitting + * the same value potentially defined by other vendors in the drm_fourcc.h + */ +#define DRM_FORMAT_MOD_VENDOR_PVR 0x92 + +#ifndef DRM_FORMAT_MOD_VENDOR_NONE +#define DRM_FORMAT_MOD_VENDOR_NONE 0 +#endif + +#ifndef DRM_FORMAT_RESERVED +#define DRM_FORMAT_RESERVED ((1ULL << 56) - 1) +#endif + +#ifndef fourcc_mod_code +#define fourcc_mod_code(vendor, val) \ + ((((__u64)DRM_FORMAT_MOD_VENDOR_## vendor) << 56) | (val & 0x00ffffffffffffffULL)) +#endif + +#ifndef DRM_FORMAT_MOD_INVALID +#define DRM_FORMAT_MOD_INVALID fourcc_mod_code(NONE, DRM_FORMAT_RESERVED) +#endif + +#ifndef DRM_FORMAT_MOD_LINEAR +#define DRM_FORMAT_MOD_LINEAR fourcc_mod_code(NONE, 0) +#endif + +#define DRM_FORMAT_MOD_PVR_FBCDC_8x8_V7 fourcc_mod_code(PVR, 6) +#define DRM_FORMAT_MOD_PVR_FBCDC_16x4_V7 fourcc_mod_code(PVR, 12) + +#endif /* IMG_DRM_FOURCC_H */ diff --git a/src/mesa/drivers/dri/pvr/imgpixfmts.h b/src/mesa/drivers/dri/pvr/imgpixfmts.h new file mode 100644 index 00000000000..da12a0fb5f6 --- /dev/null +++ b/src/mesa/drivers/dri/pvr/imgpixfmts.h @@ -0,0 +1,307 @@ +/*************************************************************************/ /*! +@File imgpixfmts.h +@Copyright Copyright (c) Imagination Technologies Ltd. All Rights Reserved +@License MIT + +The contents of this file are subject to the MIT license as set out below. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ /**************************************************************************/ + +/****************************************************************************** + ** + ** WARNING: File is autogenerated by parsesystable.py - DO NOT EDIT. + ** Use fmts_systable.txt to add new formats. + ** + *****************************************************************************/ + +#if !defined(IMGPIXFMTS_H) +#define IMGPIXFMTS_H + +typedef enum _IMG_PIXFMT_ +{ + IMG_PIXFMT_UNKNOWN = 0, + IMG_PIXFMT_RESERVED_1 = 1, + IMG_PIXFMT_RESERVED_2 = 2, + IMG_PIXFMT_RESERVED_3 = 3, + IMG_PIXFMT_RESERVED_4 = 4, + IMG_PIXFMT_RESERVED_5 = 5, + IMG_PIXFMT_RESERVED_6 = 6, + IMG_PIXFMT_RESERVED_7 = 7, + IMG_PIXFMT_RESERVED_8 = 8, + IMG_PIXFMT_RESERVED_9 = 9, + IMG_PIXFMT_RESERVED_10 = 10, + IMG_PIXFMT_RESERVED_11 = 11, + IMG_PIXFMT_RESERVED_12 = 12, + IMG_PIXFMT_RESERVED_13 = 13, + IMG_PIXFMT_RESERVED_14 = 14, + IMG_PIXFMT_RESERVED_15 = 15, + IMG_PIXFMT_RESERVED_16 = 16, + IMG_PIXFMT_RESERVED_17 = 17, + IMG_PIXFMT_RESERVED_18 = 18, + IMG_PIXFMT_RESERVED_19 = 19, + IMG_PIXFMT_RESERVED_20 = 20, + IMG_PIXFMT_RESERVED_21 = 21, + IMG_PIXFMT_RESERVED_22 = 22, + IMG_PIXFMT_RESERVED_23 = 23, + IMG_PIXFMT_RESERVED_24 = 24, + IMG_PIXFMT_R10G10B10A2_UNORM = 25, + IMG_PIXFMT_RESERVED_26 = 26, + IMG_PIXFMT_RESERVED_27 = 27, + IMG_PIXFMT_B10G10R10A2_UNORM = 28, + IMG_PIXFMT_RESERVED_29 = 29, + IMG_PIXFMT_RESERVED_30 = 30, + IMG_PIXFMT_RESERVED_31 = 31, + IMG_PIXFMT_R8G8B8A8_UNORM = 32, + IMG_PIXFMT_R8G8B8A8_UNORM_SRGB = 33, + IMG_PIXFMT_RESERVED_34 = 34, + IMG_PIXFMT_RESERVED_35 = 35, + IMG_PIXFMT_RESERVED_36 = 36, + IMG_PIXFMT_R8G8B8X8_UNORM = 37, + IMG_PIXFMT_RESERVED_38 = 38, + IMG_PIXFMT_RESERVED_39 = 39, + IMG_PIXFMT_RESERVED_40 = 40, + IMG_PIXFMT_RESERVED_41 = 41, + IMG_PIXFMT_RESERVED_42 = 42, + IMG_PIXFMT_RESERVED_43 = 43, + IMG_PIXFMT_RESERVED_44 = 44, + IMG_PIXFMT_RESERVED_45 = 45, + IMG_PIXFMT_RESERVED_46 = 46, + IMG_PIXFMT_RESERVED_47 = 47, + IMG_PIXFMT_RESERVED_48 = 48, + IMG_PIXFMT_RESERVED_49 = 49, + IMG_PIXFMT_RESERVED_50 = 50, + IMG_PIXFMT_D32_FLOAT = 51, + IMG_PIXFMT_RESERVED_52 = 52, + IMG_PIXFMT_RESERVED_53 = 53, + IMG_PIXFMT_RESERVED_54 = 54, + IMG_PIXFMT_RESERVED_55 = 55, + IMG_PIXFMT_RESERVED_56 = 56, + IMG_PIXFMT_RESERVED_57 = 57, + IMG_PIXFMT_D24_UNORM_X8_TYPELESS = 58, + IMG_PIXFMT_RESERVED_59 = 59, + IMG_PIXFMT_RESERVED_60 = 60, + IMG_PIXFMT_RESERVED_61 = 61, + IMG_PIXFMT_R8G8_UNORM = 62, + IMG_PIXFMT_RESERVED_63 = 63, + IMG_PIXFMT_RESERVED_64 = 64, + IMG_PIXFMT_RESERVED_65 = 65, + IMG_PIXFMT_RESERVED_66 = 66, + IMG_PIXFMT_RESERVED_67 = 67, + IMG_PIXFMT_RESERVED_68 = 68, + IMG_PIXFMT_D16_UNORM = 69, + IMG_PIXFMT_RESERVED_70 = 70, + IMG_PIXFMT_RESERVED_71 = 71, + IMG_PIXFMT_RESERVED_72 = 72, + IMG_PIXFMT_RESERVED_73 = 73, + IMG_PIXFMT_RESERVED_74 = 74, + IMG_PIXFMT_RESERVED_75 = 75, + IMG_PIXFMT_R8_UNORM = 76, + IMG_PIXFMT_RESERVED_77 = 77, + IMG_PIXFMT_RESERVED_78 = 78, + IMG_PIXFMT_RESERVED_79 = 79, + IMG_PIXFMT_RESERVED_80 = 80, + IMG_PIXFMT_S8_UINT = 81, + IMG_PIXFMT_RESERVED_82 = 82, + IMG_PIXFMT_RESERVED_83 = 83, + IMG_PIXFMT_RESERVED_84 = 84, + IMG_PIXFMT_B5G6R5_UNORM = 85, + IMG_PIXFMT_R5G6B5_UNORM = 86, + IMG_PIXFMT_B5G5R5A1_UNORM = 87, + IMG_PIXFMT_B5G5R5X1_UNORM = 88, + IMG_PIXFMT_B8G8R8A8_UNORM = 89, + IMG_PIXFMT_B8G8R8X8_UNORM = 90, + IMG_PIXFMT_B8G8R8A8_UINT = 91, + IMG_PIXFMT_B8G8R8A8_SNORM = 92, + IMG_PIXFMT_B8G8R8A8_SINT = 93, + IMG_PIXFMT_B8G8R8A8_UNORM_SRGB = 94, + IMG_PIXFMT_RESERVED_95 = 95, + IMG_PIXFMT_RESERVED_96 = 96, + IMG_PIXFMT_RESERVED_97 = 97, + IMG_PIXFMT_RESERVED_98 = 98, + IMG_PIXFMT_RESERVED_99 = 99, + IMG_PIXFMT_RESERVED_100 = 100, + IMG_PIXFMT_RESERVED_101 = 101, + IMG_PIXFMT_RESERVED_102 = 102, + IMG_PIXFMT_RESERVED_103 = 103, + IMG_PIXFMT_RESERVED_104 = 104, + IMG_PIXFMT_RESERVED_105 = 105, + IMG_PIXFMT_RESERVED_106 = 106, + IMG_PIXFMT_RESERVED_107 = 107, + IMG_PIXFMT_RESERVED_108 = 108, + IMG_PIXFMT_RESERVED_109 = 109, + IMG_PIXFMT_RESERVED_110 = 110, + IMG_PIXFMT_RESERVED_111 = 111, + IMG_PIXFMT_RESERVED_112 = 112, + IMG_PIXFMT_RESERVED_113 = 113, + IMG_PIXFMT_RESERVED_114 = 114, + IMG_PIXFMT_RESERVED_115 = 115, + IMG_PIXFMT_RESERVED_116 = 116, + IMG_PIXFMT_RESERVED_117 = 117, + IMG_PIXFMT_RESERVED_118 = 118, + IMG_PIXFMT_RESERVED_119 = 119, + IMG_PIXFMT_RESERVED_120 = 120, + IMG_PIXFMT_RESERVED_121 = 121, + IMG_PIXFMT_RESERVED_122 = 122, + IMG_PIXFMT_RESERVED_123 = 123, + IMG_PIXFMT_RESERVED_124 = 124, + IMG_PIXFMT_RESERVED_125 = 125, + IMG_PIXFMT_RESERVED_126 = 126, + IMG_PIXFMT_RESERVED_127 = 127, + IMG_PIXFMT_RESERVED_128 = 128, + IMG_PIXFMT_RESERVED_129 = 129, + IMG_PIXFMT_RESERVED_130 = 130, + IMG_PIXFMT_RESERVED_131 = 131, + IMG_PIXFMT_RESERVED_132 = 132, + IMG_PIXFMT_RESERVED_133 = 133, + IMG_PIXFMT_RESERVED_134 = 134, + IMG_PIXFMT_RESERVED_135 = 135, + IMG_PIXFMT_L8_UNORM = 136, + IMG_PIXFMT_RESERVED_137 = 137, + IMG_PIXFMT_L8A8_UNORM = 138, + IMG_PIXFMT_RESERVED_139 = 139, + IMG_PIXFMT_RESERVED_140 = 140, + IMG_PIXFMT_RESERVED_141 = 141, + IMG_PIXFMT_RESERVED_142 = 142, + IMG_PIXFMT_RESERVED_143 = 143, + IMG_PIXFMT_RESERVED_144 = 144, + IMG_PIXFMT_B4G4R4A4_UNORM = 145, + IMG_PIXFMT_RESERVED_146 = 146, + IMG_PIXFMT_RESERVED_147 = 147, + IMG_PIXFMT_RESERVED_148 = 148, + IMG_PIXFMT_RESERVED_149 = 149, + IMG_PIXFMT_RESERVED_150 = 150, + IMG_PIXFMT_RESERVED_151 = 151, + IMG_PIXFMT_RESERVED_152 = 152, + IMG_PIXFMT_RESERVED_153 = 153, + IMG_PIXFMT_RESERVED_154 = 154, + IMG_PIXFMT_RESERVED_155 = 155, + IMG_PIXFMT_RESERVED_156 = 156, + IMG_PIXFMT_RESERVED_157 = 157, + IMG_PIXFMT_RESERVED_158 = 158, + IMG_PIXFMT_RESERVED_159 = 159, + IMG_PIXFMT_R8G8B8_UNORM = 160, + IMG_PIXFMT_R8G8B8_UNORM_SRGB = 161, + IMG_PIXFMT_RESERVED_162 = 162, + IMG_PIXFMT_RESERVED_163 = 163, + IMG_PIXFMT_RESERVED_164 = 164, + IMG_PIXFMT_RESERVED_165 = 165, + IMG_PIXFMT_RESERVED_166 = 166, + IMG_PIXFMT_RESERVED_167 = 167, + IMG_PIXFMT_RESERVED_168 = 168, + IMG_PIXFMT_RESERVED_169 = 169, + IMG_PIXFMT_RESERVED_170 = 170, + IMG_PIXFMT_UYVY = 171, + IMG_PIXFMT_VYUY = 172, + IMG_PIXFMT_YUYV = 173, + IMG_PIXFMT_YVYU = 174, + IMG_PIXFMT_YVU420_2PLANE = 175, + IMG_PIXFMT_YUV420_2PLANE = 176, + IMG_PIXFMT_YVU420_2PLANE_MACRO_BLOCK = 177, + IMG_PIXFMT_YUV420_3PLANE = 178, + IMG_PIXFMT_YVU420_3PLANE = 179, + IMG_PIXFMT_RESERVED_180 = 180, + IMG_PIXFMT_RESERVED_181 = 181, + IMG_PIXFMT_RESERVED_182 = 182, + IMG_PIXFMT_RESERVED_183 = 183, + IMG_PIXFMT_RESERVED_184 = 184, + IMG_PIXFMT_RESERVED_185 = 185, + IMG_PIXFMT_RESERVED_186 = 186, + IMG_PIXFMT_RESERVED_187 = 187, + IMG_PIXFMT_RESERVED_188 = 188, + IMG_PIXFMT_RESERVED_189 = 189, + IMG_PIXFMT_RESERVED_190 = 190, + IMG_PIXFMT_RESERVED_191 = 191, + IMG_PIXFMT_RESERVED_192 = 192, + IMG_PIXFMT_RESERVED_193 = 193, + IMG_PIXFMT_RESERVED_194 = 194, + IMG_PIXFMT_RESERVED_195 = 195, + IMG_PIXFMT_RESERVED_196 = 196, + IMG_PIXFMT_RESERVED_197 = 197, + IMG_PIXFMT_RESERVED_198 = 198, + IMG_PIXFMT_RESERVED_199 = 199, + IMG_PIXFMT_RESERVED_200 = 200, + IMG_PIXFMT_YVU8_422_2PLANE_PACK8 = 201, + IMG_PIXFMT_RESERVED_202 = 202, + IMG_PIXFMT_YVU10_444_1PLANE_PACK10 = 203, + IMG_PIXFMT_RESERVED_204 = 204, + IMG_PIXFMT_RESERVED_205 = 205, + IMG_PIXFMT_RESERVED_206 = 206, + IMG_PIXFMT_YUV8_422_2PLANE_PACK8 = 207, + IMG_PIXFMT_YUV8_444_3PLANE_PACK8 = 208, + IMG_PIXFMT_RESERVED_209 = 209, + IMG_PIXFMT_RESERVED_210 = 210, + IMG_PIXFMT_RESERVED_211 = 211, + IMG_PIXFMT_RESERVED_212 = 212, + IMG_PIXFMT_RESERVED_213 = 213, + IMG_PIXFMT_RESERVED_214 = 214, + IMG_PIXFMT_RESERVED_215 = 215, + IMG_PIXFMT_RESERVED_216 = 216, + IMG_PIXFMT_RESERVED_217 = 217, + IMG_PIXFMT_RESERVED_218 = 218, + IMG_PIXFMT_RESERVED_219 = 219, + IMG_PIXFMT_RESERVED_220 = 220, + IMG_PIXFMT_RESERVED_221 = 221, + IMG_PIXFMT_RESERVED_222 = 222, + IMG_PIXFMT_RESERVED_223 = 223, + IMG_PIXFMT_RESERVED_224 = 224, + IMG_PIXFMT_RESERVED_225 = 225, + IMG_PIXFMT_RESERVED_226 = 226, + IMG_PIXFMT_RESERVED_227 = 227, + IMG_PIXFMT_RESERVED_228 = 228, + IMG_PIXFMT_RESERVED_229 = 229, + IMG_PIXFMT_RESERVED_230 = 230, + IMG_PIXFMT_RESERVED_231 = 231, + IMG_PIXFMT_RESERVED_232 = 232, + IMG_PIXFMT_RESERVED_233 = 233, + IMG_PIXFMT_RESERVED_234 = 234, + IMG_PIXFMT_RESERVED_235 = 235, + IMG_PIXFMT_RESERVED_236 = 236, + IMG_PIXFMT_RESERVED_237 = 237, + IMG_PIXFMT_RESERVED_238 = 238, + IMG_PIXFMT_RESERVED_239 = 239, + IMG_PIXFMT_RESERVED_240 = 240, + IMG_PIXFMT_RESERVED_241 = 241, + IMG_PIXFMT_RESERVED_242 = 242, + IMG_PIXFMT_RESERVED_243 = 243, + IMG_PIXFMT_RESERVED_244 = 244, + IMG_PIXFMT_YVU8_420_2PLANE_PACK8_P = 245, + IMG_PIXFMT_RESERVED_246 = 246, + IMG_PIXFMT_RESERVED_247 = 247, + IMG_PIXFMT_RESERVED_248 = 248, + IMG_PIXFMT_YUV8_420_2PLANE_PACK8_P = 249, + IMG_PIXFMT_RESERVED_250 = 250, + IMG_PIXFMT_RESERVED_251 = 251, + IMG_PIXFMT_UYVY10_422_1PLANE_PACK10_CUST1 = 252, + IMG_PIXFMT_RESERVED_253 = 253, + IMG_PIXFMT_RESERVED_254 = 254, + IMG_PIXFMT_RESERVED_255 = 255, + IMG_PIXFMT_RESERVED_256 = 256, + IMG_PIXFMT_RESERVED_257 = 257, + IMG_PIXFMT_RESERVED_258 = 258, + IMG_PIXFMT_RESERVED_259 = 259, + IMG_PIXFMT_RESERVED_260 = 260, + IMG_PIXFMT_RESERVED_261 = 261, + IMG_PIXFMT_RESERVED_262 = 262, + IMG_PIXFMT_RESERVED_263 = 263, + IMG_PIXFMT_RESERVED_264 = 264, +#define IMG_PIXFMT_ENUM_COUNT 265 +} IMG_PIXFMT; + +#endif /* IMGPIXFMTS_H */ diff --git a/src/mesa/drivers/dri/pvr/imgyuv.h b/src/mesa/drivers/dri/pvr/imgyuv.h new file mode 100644 index 00000000000..7ae8fd19ac0 --- /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..d36bae5ac54 --- /dev/null +++ b/src/mesa/drivers/dri/pvr/mesa_context.c @@ -0,0 +1,208 @@ +/** + * \file context.c + * Mesa context/visual/framebuffer management functions. + * \author Brian Paul + */ + +/* + * Mesa 3-D graphics library + * Version: 7.1 + * + * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. + * + * The contents of this file are subject to the MIT license as set out below. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include + +#include "main/version.h" +#include "main/errors.h" + +#include "dri_support.h" +#include "dri_util.h" +#include "glapi.h" +#include "dispatch.h" +#include "pvrmesa.h" + +/** + * This is the default function we plug into all dispatch table slots This + * helps prevents a segfault when someone calls a GL function without first + * checking if the extension is supported. + */ +static int +generic_nop(void) +{ + _mesa_warning(NULL, "User called no-op dispatch function (an unsupported extension function?)"); + + return 0; +} + +/** + * Allocate and initialise a new dispatch table. + */ +static struct _glapi_table * +pvrdri_alloc_dispatch_table(void) +{ + unsigned int numEntries = _glapi_get_dispatch_table_size(); + _glapi_proc *table; + + table = malloc(numEntries * sizeof(_glapi_proc)); + if (table) + for (unsigned int i = 0; i < numEntries; i++) + table[i] = (_glapi_proc) generic_nop; + + return (struct _glapi_table *) table; +} + +/** + * Return a pointer to the pointer to the dispatch table of an API in + * PVRDRIScreen. + */ +static struct _glapi_table ** +pvrdri_get_dispatch_table_ptr(PVRDRIScreen *psPVRScreen, PVRDRIAPIType eAPI) +{ + switch (eAPI) { + case PVRDRI_API_GLES1: + return &psPVRScreen->psOGLES1Dispatch; + case PVRDRI_API_GLES2: + return &psPVRScreen->psOGLES2Dispatch; + case PVRDRI_API_GL_COMPAT: + case PVRDRI_API_GL_CORE: + return &psPVRScreen->psOGLDispatch; + default: + return NULL; + } +} + +/** + * Return a pointer to the dispatch table of an API. + */ +static struct _glapi_table * +pvrdri_get_dispatch_table(PVRDRIScreen *psPVRScreen, PVRDRIAPIType eAPI) +{ + struct _glapi_table **ppsTable = + pvrdri_get_dispatch_table_ptr(psPVRScreen, eAPI); + + return ppsTable ? *ppsTable : NULL; +} + +/** + * Free all dispatch tables. + */ +void +pvrdri_free_dispatch_tables(PVRDRIScreen *psPVRScreen) +{ + if (psPVRScreen->psOGLES1Dispatch != NULL) { + free(psPVRScreen->psOGLES1Dispatch); + psPVRScreen->psOGLES1Dispatch = NULL; + } + + if (psPVRScreen->psOGLES2Dispatch != NULL) { + free(psPVRScreen->psOGLES2Dispatch); + psPVRScreen->psOGLES2Dispatch = NULL; + } + + if (psPVRScreen->psOGLDispatch != NULL) { + free(psPVRScreen->psOGLDispatch); + psPVRScreen->psOGLDispatch = NULL; + } +} + +static void +pvrdri_add_mesa_dispatch(struct _glapi_table *psTable, PVRDRIAPIType eAPI, + struct DRISUPScreen *psDRISUPScreen, + unsigned int uIdx) +{ + const char *asFunc[] = { NULL, NULL }; + int iOffset; + const char *psFunc; + _glapi_proc pfFunc; + + pfFunc = DRISUPGetAPIProcAddress(psDRISUPScreen, eAPI, uIdx); + if (pfFunc == NULL) + return; + + psFunc = DRISUPGetAPIProcName(psDRISUPScreen, eAPI, uIdx); + assert(psFunc != NULL); + + asFunc[0] = psFunc; + iOffset = _glapi_add_dispatch(asFunc, ""); + if (iOffset == -1) { + _mesa_warning(NULL, "Couldn't add %s to the Mesa dispatch table", + psFunc); + } else { + SET_by_offset(psTable, iOffset, pfFunc); + } +} + +static void +pvrdri_set_mesa_dispatch(struct _glapi_table *psTable, PVRDRIAPIType eAPI, + struct DRISUPScreen *psDRISUPScreen, + unsigned int uNumFuncs) +{ + for (unsigned int i = 0; i < uNumFuncs; i++) + pvrdri_add_mesa_dispatch(psTable, eAPI, psDRISUPScreen, i); +} + +bool +pvrdri_create_dispatch_table(PVRDRIScreen *psPVRScreen, PVRDRIAPIType eAPI) +{ + struct DRISUPScreen *psDRISUPScreen = psPVRScreen->psDRISUPScreen; + struct _glapi_table **ppsTable; + unsigned int uNumFuncs; + + ppsTable = pvrdri_get_dispatch_table_ptr(psPVRScreen, eAPI); + if (ppsTable == NULL) + return false; + + if (*ppsTable != NULL) + return true; + + uNumFuncs = DRISUPGetNumAPIProcs(psDRISUPScreen, eAPI); + if (!uNumFuncs) + return false; + + *ppsTable = pvrdri_alloc_dispatch_table(); + if (*ppsTable == NULL) + return false; + + pvrdri_set_mesa_dispatch(*ppsTable, eAPI, psDRISUPScreen, uNumFuncs); + + return true; +} + +void +pvrdri_set_null_dispatch_table(void) +{ + _glapi_set_dispatch(NULL); +} + +void +pvrdri_set_dispatch_table(PVRDRIContext *psPVRContext) +{ + struct _glapi_table *psTable; + + psTable = pvrdri_get_dispatch_table(psPVRContext->psPVRScreen, + psPVRContext->eAPI); + + _glapi_set_dispatch(psTable); +} diff --git a/src/mesa/drivers/dri/pvr/meson.build b/src/mesa/drivers/dri/pvr/meson.build new file mode 100644 index 00000000000..51b3b11948d --- /dev/null +++ b/src/mesa/drivers/dri/pvr/meson.build @@ -0,0 +1,53 @@ +# Copyright (c) Imagination Technologies Ltd. +# +# The contents of this file are subject to the MIT license as set out below. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +files_pvr = files( + 'mesa_context.c', + 'pvrcb.c', + 'pvrcompat.c', + 'pvrdrawable_mod.c', + 'pvrdri.c', + 'pvrdri_mod.c', + 'pvrext.c', + 'pvrext_mod.c', + 'pvrimage_mod.c', + 'pvrutil.c', + 'pvrutil_mod.c', +) + +dep_libpvr = [ + dep_libdrm, +] + +if with_platform_tizen + dep_libpvr += dep_dlog +endif + +libpvr = static_library( + 'pvr', + [files_pvr, main_dispatch_h], + include_directories : [inc_include, inc_src, inc_mapi, inc_mesa, + inc_dri_common, inc_util, inc_pvr], + c_args : [no_override_init_args], + gnu_symbol_visibility : 'hidden', + dependencies : [dep_libpvr], +) diff --git a/src/mesa/drivers/dri/pvr/pvrcb.c b/src/mesa/drivers/dri/pvr/pvrcb.c new file mode 100644 index 00000000000..e1232e5c400 --- /dev/null +++ b/src/mesa/drivers/dri/pvr/pvrcb.c @@ -0,0 +1,282 @@ +/* + * 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 + +#include "utils.h" +#include "pvrdri.h" + +int +MODSUPGetBuffers(__DRIdrawable *psDRIDrawable, unsigned int uFourCC, + uint32_t *puStamp, void *pvLoaderPrivate, + uint32_t uBufferMask, struct PVRDRIImageList *psImageList) +{ + PVRDRIDrawable *psPVRDrawable = psDRIDrawable->driverPrivate; + __DRIscreen *psDRIScreen = psDRIDrawable->driScreenPriv; + struct __DRIimageList sDRIList; + int res; + +#if !defined(DRI_IMAGE_HAS_BUFFER_PREV) + uBufferMask &= ~PVRDRI_IMAGE_BUFFER_PREV; +#endif + + if (psPVRDrawable->uFourCC != uFourCC) { + psPVRDrawable->uDRIFormat = PVRDRIFourCCToDRIFormat(uFourCC); + psPVRDrawable->uFourCC = uFourCC; + } + + res = psDRIScreen->image.loader->getBuffers(psDRIDrawable, + psPVRDrawable->uDRIFormat, + puStamp, + pvLoaderPrivate, + uBufferMask, &sDRIList); + + if (res) { + psImageList->uImageMask = sDRIList.image_mask; + psImageList->psBack = sDRIList.back; + psImageList->psFront = sDRIList.front; + psImageList->psPrev = sDRIList.prev; + } + + return res; +} + +bool +MODSUPCreateConfigs(__DRIconfig ***pppsConfigs, __DRIscreen *psDRIScreen, + int iPVRDRIMesaFormat, const uint8_t *puDepthBits, + const uint8_t *puStencilBits, + unsigned int uNumDepthStencilBits, + const unsigned int *puDBModes, unsigned int uNumDBModes, + const uint8_t *puMSAASamples, unsigned int uNumMSAAModes, + bool bEnableAccum, bool bColorDepthMatch, + bool bMutableRenderBuffer, + int iYUVDepthRange, int iYUVCSCStandard, + uint32_t uMaxPbufferWidth, uint32_t uMaxPbufferHeight) +{ + __DRIconfig **ppsConfigs; + mesa_format eFormat = PVRDRIMesaFormatToMesaFormat(iPVRDRIMesaFormat); + unsigned int i; + + (void) psDRIScreen; + + switch (eFormat) { + case MESA_FORMAT_NONE: + __driUtilMessage("%s: Unknown PVR DRI format: %u", + __func__, iPVRDRIMesaFormat); + return false; + default: + break; + } + + /* + * The double buffered modes array argument for driCreateConfigs has + * entries of type GLenum. + */ + static_assert(sizeof(GLenum) == sizeof(unsigned int), + "Size mismatch between GLenum and unsigned int"); + + ppsConfigs = driCreateConfigs(eFormat, puDepthBits, puStencilBits, + uNumDepthStencilBits, (GLenum *) puDBModes, + uNumDBModes, puMSAASamples, uNumMSAAModes, + bEnableAccum, bColorDepthMatch, + bMutableRenderBuffer, + iYUVDepthRange, iYUVCSCStandard); + if (!ppsConfigs) + return false; + + for (i = 0; ppsConfigs[i]; i++) { + ppsConfigs[i]->modes.maxPbufferWidth = uMaxPbufferWidth; + ppsConfigs[i]->modes.maxPbufferHeight = uMaxPbufferHeight; + ppsConfigs[i]->modes.maxPbufferPixels = + uMaxPbufferWidth * uMaxPbufferHeight; + } + + *pppsConfigs = ppsConfigs; + + return true; +} + +__DRIconfig ** +MODSUPConcatConfigs(__DRIscreen *psDRIScreen, + __DRIconfig **ppsConfigA, __DRIconfig **ppsConfigB) +{ + (void) psDRIScreen; + + return driConcatConfigs(ppsConfigA, ppsConfigB); +} + +struct __DRIimageRec * +MODSUPLookupEGLImage(__DRIscreen *psDRIScreen, void *pvImage, + void *pvLoaderPrivate) +{ + return psDRIScreen->dri2.image->lookupEGLImage(psDRIScreen, + pvImage, + pvLoaderPrivate); +} + + +unsigned int +MODSUPGetCapability(__DRIscreen *psDRIScreen, unsigned int uCapability) +{ + if (psDRIScreen->image.loader->base.version >= 2 && + psDRIScreen->image.loader->getCapability) { + enum dri_loader_cap eCapability = + (enum dri_loader_cap) uCapability; + + return psDRIScreen->image.loader->getCapability( + psDRIScreen->loaderPrivate, + eCapability); + } + + return 0; +} + +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 +#if !defined(__DRI_ATTRIB_YUV_BIT) + case PVRDRI_CONFIG_ATTRIB_YUV_ORDER: + case PVRDRI_CONFIG_ATTRIB_YUV_NUM_OF_PLANES: + case PVRDRI_CONFIG_ATTRIB_YUV_SUBSAMPLE: + case PVRDRI_CONFIG_ATTRIB_YUV_DEPTH_RANGE: + case PVRDRI_CONFIG_ATTRIB_YUV_CSC_STANDARD: + case PVRDRI_CONFIG_ATTRIB_YUV_PLANE_BPP: + return false; +#endif + case PVRDRI_CONFIG_ATTRIB_RED_MASK: + *piValueOut = psConfig->sGLMode.redMask; + return true; + case PVRDRI_CONFIG_ATTRIB_GREEN_MASK: + *piValueOut = psConfig->sGLMode.greenMask; + return true; + case PVRDRI_CONFIG_ATTRIB_BLUE_MASK: + *piValueOut = psConfig->sGLMode.blueMask; + return true; + case PVRDRI_CONFIG_ATTRIB_ALPHA_MASK: + *piValueOut = psConfig->sGLMode.alphaMask; + return true; + case PVRDRI_CONFIG_ATTRIB_SRGB_CAPABLE: + *piValueOut = psConfig->sGLMode.sRGBCapable; + return true; + case PVRDRI_CONFIG_ATTRIB_INVALID: + errorMessage("%s: Invalid attribute", __func__); + assert(0); + return false; + default: + return false; + } +} + +bool +MODSUPConfigQuery(const PVRDRIConfig *psConfig, + PVRDRIConfigAttrib eConfigAttrib, unsigned int *puValueOut) +{ + bool bRes; + int iValue; + + bRes = PVRDRIConfigQuery(psConfig, eConfigAttrib, &iValue); + if (bRes) + *puValueOut = (unsigned int) iValue; + + return bRes; +} + +void +MODSUPFlushFrontBuffer(struct __DRIdrawableRec *psDRIDrawable, + void *pvLoaderPrivate) +{ + PVRDRIDrawable *psPVRDrawable = psDRIDrawable->driverPrivate; + __DRIscreen *psDRIScreen = psDRIDrawable->driScreenPriv; + + if (!psPVRDrawable->sConfig.sGLMode.doubleBufferMode) + psDRIScreen->image.loader->flushFrontBuffer(psDRIDrawable, + pvLoaderPrivate); +} diff --git a/src/mesa/drivers/dri/pvr/pvrcompat.c b/src/mesa/drivers/dri/pvr/pvrcompat.c new file mode 100644 index 00000000000..70335a2c7d9 --- /dev/null +++ b/src/mesa/drivers/dri/pvr/pvrcompat.c @@ -0,0 +1,1552 @@ +/* + * 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 +#include +#include +#include +#include +#include + +#include + +#include "pvrdri.h" +#include "pvrdri_mod.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 struct PVRDRISupportInterfaceV2 gsSupV2; + +static pthread_mutex_t gsCompatLock = PTHREAD_MUTEX_INITIALIZER; + +/* Call a function via the DRI Support interface structure */ +#define CallFunc(field, ...) \ + do { \ + if (gsSup.field) \ + return gsSup.field(__VA_ARGS__); \ + } while(0) + +/* Lookup a function, and set the pointer to the function address */ +#define LookupFunc(func, ptr) \ + do { \ + ptr = dlsym(gpvSupLib, MAKESTRING(func)); \ + } while(0) + +/* + * 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) + +/* Call a function via the DRI Support interface structure */ +#define CallFuncV2(field, ...) \ + do { \ + if (gsSupV2.field) \ + return gsSupV2.field(__VA_ARGS__); \ + } while(0) + +/* Calculate the start of the PVRDRISupportInterfaceV2 structure */ +#define PVRDRIInterfaceV2Start(field) \ + (offsetof(struct PVRDRISupportInterfaceV2, field)) + +/* Calculate the end of the PVRDRISupportInterfaceV2 structure */ +#define PVRDRIInterfaceV2End(field) \ + (offsetof(struct PVRDRISupportInterfaceV2, field) + \ + sizeof((struct PVRDRISupportInterfaceV2 *)0)->field) + +static void +CompatLock(void) +{ + int ret; + + ret = pthread_mutex_lock(&gsCompatLock); + if (ret) { + errorMessage("%s: Failed to lock mutex (%d)", __func__, ret); + abort(); + } +} + +static void +CompatUnlock(void) +{ + int ret; + + ret = pthread_mutex_unlock(&gsCompatLock); + if (ret) { + errorMessage("%s: Failed to unlock mutex (%d)", __func__, ret); + abort(); + } +} + +static void * +LoadLib(const char *path) +{ + void *handle; + + /* Clear the error */ + (void) dlerror(); + + handle = dlopen(path, RTLD_NOW); + if (handle) { + __driUtilMessage("Loaded %s", path); + } else { + const char *error; + + error = dlerror(); + if (!error) + error = "unknown error"; + + errorMessage("%s: Couldn't load %s: %s", __func__, path, error); + } + + return handle; +} + +static void +UnloadLib(void *handle, const char *name) +{ + if (!handle) + return; + + /* Clear the error */ + (void) dlerror(); + + if (dlclose(handle)) { + const char *error; + + error = dlerror(); + if (!error) + error = "unknown error"; + + errorMessage("%s: Couldn't unload %s: %s", __func__, name, error); + } else { + __driUtilMessage("Unloaded %s", name); + } +} + +static bool +LoadSupportLib(void) +{ + gpvSupLib = LoadLib(PVRDRI_SUPPORT_LIB); + + return gpvSupLib != NULL; +} + +static void +UnloadSupportLib(void) +{ + UnloadLib(gpvSupLib, PVRDRI_SUPPORT_LIB); + gpvSupLib = NULL; +} + +static void +CompatDeinit(void) +{ + UnloadSupportLib(); + memset(&gsSup, 0, sizeof(gsSup)); + memset(&gsSupV2, 0, sizeof(gsSupV2)); +} + +static void +SetupLocalDRISupportInterfaceV2(void) +{ + gsSupV2.v0.CreateScreen = DRIMODCreateScreen; + gsSupV2.v0.DestroyScreen = DRIMODDestroyScreen; + gsSupV2.v0.CreateContext = DRIMODCreateContext; + gsSupV2.v0.DestroyContext = DRIMODDestroyContext; + gsSupV2.v0.CreateDrawable = DRIMODCreateDrawable; + gsSupV2.v0.DestroyDrawable = DRIMODDestroyDrawable; + gsSupV2.v0.MakeCurrent = DRIMODMakeCurrent; + gsSupV2.v0.UnbindContext = DRIMODUnbindContext; + gsSupV2.v0.AllocateBuffer = DRIMODAllocateBuffer; + gsSupV2.v0.ReleaseBuffer = DRIMODReleaseBuffer; + gsSupV2.v0.SetTexBuffer2 = DRIMODSetTexBuffer2; + gsSupV2.v0.ReleaseTexBuffer = DRIMODReleaseTexBuffer; + gsSupV2.v0.Flush = DRIMODFlush; + gsSupV2.v0.Invalidate = DRIMODInvalidate; + gsSupV2.v0.FlushWithFlags = DRIMODFlushWithFlags; + gsSupV2.v0.CreateImageFromName = DRIMODCreateImageFromName; + gsSupV2.v0.CreateImageFromRenderbuffer = + DRIMODCreateImageFromRenderbuffer; + gsSupV2.v0.DestroyImage = DRIMODDestroyImage; + gsSupV2.v0.CreateImage = DRIMODCreateImage; + gsSupV2.v0.QueryImage = DRIMODQueryImage; + gsSupV2.v0.DupImage = DRIMODDupImage; + gsSupV2.v0.ValidateImageUsage = DRIMODValidateImageUsage; + gsSupV2.v0.CreateImageFromNames = DRIMODCreateImageFromNames; + gsSupV2.v0.FromPlanar = DRIMODFromPlanar; + gsSupV2.v0.CreateImageFromTexture = DRIMODCreateImageFromTexture; + gsSupV2.v0.CreateImageFromFDs = DRIMODCreateImageFromFDs; + gsSupV2.v0.CreateImageFromDMABufs = DRIMODCreateImageFromDMABufs; + gsSupV2.v0.GetImageCapabilities = DRIMODGetImageCapabilities; + gsSupV2.v0.BlitImage = DRIMODBlitImage; + gsSupV2.v0.MapImage = DRIMODMapImage; + gsSupV2.v0.UnmapImage = DRIMODUnmapImage; + gsSupV2.v0.CreateImageWithModifiers = DRIMODCreateImageWithModifiers; + gsSupV2.v0.CreateImageFromDMABufs2 = DRIMODCreateImageFromDMABufs2; + gsSupV2.v0.QueryDMABufFormats = DRIMODQueryDMABufFormats; + gsSupV2.v0.QueryDMABufModifiers = DRIMODQueryDMABufModifiers; + gsSupV2.v0.QueryDMABufFormatModifierAttribs = + DRIMODQueryDMABufFormatModifierAttribs; + gsSupV2.v0.CreateImageFromRenderBuffer2 = + DRIMODCreateImageFromRenderBuffer2; + gsSupV2.v0.CreateImageFromBuffer = DRIMODCreateImageFromBuffer; + gsSupV2.v0.QueryRendererInteger = DRIMODQueryRendererInteger; + gsSupV2.v0.QueryRendererString = DRIMODQueryRendererString; + gsSupV2.v0.CreateFence = DRIMODCreateFence; + gsSupV2.v0.DestroyFence = DRIMODDestroyFence; + gsSupV2.v0.ClientWaitSync = DRIMODClientWaitSync; + gsSupV2.v0.ServerWaitSync = DRIMODServerWaitSync; + gsSupV2.v0.GetFenceCapabilities = DRIMODGetFenceCapabilities; + gsSupV2.v0.CreateFenceFD = DRIMODCreateFenceFD; + gsSupV2.v0.GetFenceFD = DRIMODGetFenceFD; + gsSupV2.v0.GetNumAPIProcs = DRIMODGetNumAPIProcs; + gsSupV2.v0.GetAPIProcName = DRIMODGetAPIProcName; + gsSupV2.v0.GetAPIProcAddress = DRIMODGetAPIProcAddress; + gsSupV2.v0.SetDamageRegion = DRIMODSetDamageRegion; + + PVRDRIAdjustExtensions(0, 0); +} + +bool +PVRDRICompatInit(const PVRDRICallbacks *psCallbacks, unsigned int uVersion, + const struct PVRDRICallbacksV2 *psCallbacksV2, + unsigned int uVersionV2, unsigned int uMinVersionV2) +{ + bool (*pfRegisterVersionedCallbacks)(const PVRDRICallbacks *psCallbacks, + unsigned int uVersion); + bool (*pfRegisterVersionedCallbacksV2)(const void *pvCallbacks, + unsigned int uVersion, + unsigned int uMinVersion); + bool res; + + CompatLock(); + res = (giSupLibRef++ != 0); + if (res) + goto Exit; + + res = LoadSupportLib(); + if (!res) + goto Exit; + + LookupFunc(PVRDRIRegisterVersionedCallbacksV2, + pfRegisterVersionedCallbacksV2); + + LookupFunc(PVRDRIRegisterVersionedCallbacks, + pfRegisterVersionedCallbacks); + + res = (pfRegisterVersionedCallbacksV2 != NULL) || + (pfRegisterVersionedCallbacks != NULL); + if (!res) + goto Exit; + + if (pfRegisterVersionedCallbacksV2) { + res = pfRegisterVersionedCallbacksV2(psCallbacksV2, + uVersionV2, uMinVersionV2); + } else { + res = pfRegisterVersionedCallbacks(psCallbacks, uVersion); + if (res) + SetupLocalDRISupportInterfaceV2(); + } + +Exit: + if (!res) { + CompatDeinit(); + giSupLibRef--; + } + CompatUnlock(); + + return res; +} + +void +PVRDRICompatDeinit(void) +{ + CompatLock(); + if (--giSupLibRef == 0) + CompatDeinit(); + CompatUnlock(); +} + +bool +PVRDRIRegisterSupportInterfaceV1(const PVRDRISupportInterface *psInterface, + unsigned int uVersion) +{ + size_t uSize; + + memset(&gsSup, 0, sizeof(gsSup)); + memset(&gsSupV2, 0, sizeof(gsSupV2)); + + /* The "default" case should be associated with the latest version */ + switch (uVersion) { + default: + case 2: + uSize = PVRDRIInterfaceSize(GetFenceFd); + break; + case 1: + case 0: + return false; + } + + memcpy(&gsSup, psInterface, uSize); + + return true; +} + +bool +MODSUPRegisterSupportInterfaceV2(const void *pvInterface, + unsigned int uVersion, + unsigned int uMinVersion) +{ + size_t uStart, uEnd; + + memset(&gsSup, 0, sizeof(gsSup)); + memset(&gsSupV2, 0, sizeof(gsSupV2)); + + if (uVersion < uMinVersion) + return false; + + /* + * Minimum versions we support. To prevent the accumulation of old unused + * interfaces in the PVRDRIInterfaceV2 structure, the caller specifies the + * minimum version it supports. This will be pointed to be the psInterface + * argument. Assuming we support that version, we must copy the structure + * passed to us into the correct place in our version of the interface + * structure. + */ + switch (uMinVersion) { + case 0: + uStart = PVRDRIInterfaceV2Start(v0); + break; + case 1: + case 2: + /* These versions require version 0 */ + return false; + default: + return false; + } + + /* The "default" case should be associated with the latest version */ + switch (uVersion) { + default: + case 3: + /* + * This version is an extension of version 2, with no new + * entry points. + */ + case 2: + /* This version is an extension of versions 0 and 1 */ + if (uMinVersion > 0) + return false; + + uEnd = PVRDRIInterfaceV2End(v2); + break; + case 1: + /* This version is an extension of version 0 */ + if (uMinVersion > 0) + return false; + + uEnd = PVRDRIInterfaceV2End(v1); + break; + case 0: + uEnd = PVRDRIInterfaceV2End(v0); + break; + } + + memcpy(((char *) &gsSupV2) + uStart, pvInterface, uEnd - uStart); + + PVRDRIAdjustExtensions(uVersion, uMinVersion); + + return true; +} + +struct DRISUPScreen * +DRISUPCreateScreen(struct __DRIscreenRec *psDRIScreen, int iFD, + bool bUseInvalidate, void *pvLoaderPrivate, + const struct __DRIconfigRec ***pppsConfigs, + int *piMaxGLES1Version, int *piMaxGLES2Version) +{ + CallFuncV2(v0.CreateScreen, + psDRIScreen, iFD, bUseInvalidate, pvLoaderPrivate, pppsConfigs, + piMaxGLES1Version, piMaxGLES2Version); + + return NULL; +} + +void +DRISUPDestroyScreen(struct DRISUPScreen *psDRISUPScreen) +{ + CallFuncV2(v0.DestroyScreen, + psDRISUPScreen); +} + +unsigned int +DRISUPCreateContext(PVRDRIAPIType eAPI, PVRDRIConfig *psPVRDRIConfig, + struct PVRDRIContextConfig *psCtxConfig, + struct __DRIcontextRec *psDRIContext, + struct DRISUPContext *psDRISUPSharedContext, + struct DRISUPScreen *psDRISUPScreen, + struct DRISUPContext **ppsDRISUPContext) +{ + CallFuncV2(v0.CreateContext, + eAPI, psPVRDRIConfig, psCtxConfig, psDRIContext, + psDRISUPSharedContext, psDRISUPScreen, ppsDRISUPContext); + + return PVRDRI_CONTEXT_ERROR_BAD_API; +} + +void +DRISUPDestroyContext(struct DRISUPContext *psDRISUPContext) +{ + CallFuncV2(v0.DestroyContext, + psDRISUPContext); +} + +struct DRISUPDrawable * +DRISUPCreateDrawable(struct __DRIdrawableRec *psDRIDrawable, + struct DRISUPScreen *psDRISUPScreen, + void *pvLoaderPrivate, PVRDRIConfig *psPVRDRIConfig) +{ + CallFuncV2(v0.CreateDrawable, + psDRIDrawable, psDRISUPScreen, pvLoaderPrivate, psPVRDRIConfig); + + return NULL; +} + +void +DRISUPDestroyDrawable(struct DRISUPDrawable *psDRISUPDrawable) +{ + CallFuncV2(v0.DestroyDrawable, + psDRISUPDrawable); +} + +bool +DRISUPMakeCurrent(struct DRISUPContext *psDRISUPContext, + struct DRISUPDrawable *psDRISUPWrite, + struct DRISUPDrawable *psDRISUPRead) +{ + CallFuncV2(v0.MakeCurrent, + psDRISUPContext, psDRISUPWrite, psDRISUPRead); + + return false; +} + +bool +DRISUPUnbindContext(struct DRISUPContext *psDRISUPContext) +{ + CallFuncV2(v0.UnbindContext, + psDRISUPContext); + + return false; +} + +struct DRISUPBuffer * +DRISUPAllocateBuffer(struct DRISUPScreen *psDRISUPScreen, + unsigned int uAttachment, unsigned int uFormat, + int iWidth, int iHeight, unsigned int *puName, + unsigned int *puPitch, unsigned int *puCPP, + unsigned int *puFlags) +{ + CallFuncV2(v0.AllocateBuffer, + psDRISUPScreen, uAttachment, uFormat, iWidth, iHeight, puName, + puPitch, puCPP, puFlags); + + return NULL; +} + +void +DRISUPReleaseBuffer(struct DRISUPScreen *psDRISUPScreen, + struct DRISUPBuffer *psDRISUPBuffer) +{ + CallFuncV2(v0.ReleaseBuffer, + psDRISUPScreen, psDRISUPBuffer); +} + +void +DRISUPSetTexBuffer2(struct DRISUPContext *psDRISUPContext, int iTarget, + int iFormat, struct DRISUPDrawable *psDRISUPDrawable) +{ + CallFuncV2(v0.SetTexBuffer2, + psDRISUPContext, iTarget, iFormat, psDRISUPDrawable); +} + +void +DRISUPReleaseTexBuffer(struct DRISUPContext *psDRISUPContext, int iTarget, + struct DRISUPDrawable *psDRISUPDrawable) +{ + CallFuncV2(v0.ReleaseTexBuffer, + psDRISUPContext, iTarget, psDRISUPDrawable); +} + +void +DRISUPFlush(struct DRISUPDrawable *psDRISUPDrawable) +{ + CallFuncV2(v0.Flush, + psDRISUPDrawable); +} + +void +DRISUPInvalidate(struct DRISUPDrawable *psDRISUPDrawable) +{ + CallFuncV2(v0.Invalidate, + psDRISUPDrawable); +} + +void +DRISUPFlushWithFlags(struct DRISUPContext *psDRISUPContext, + struct DRISUPDrawable *psDRISUPDrawable, + unsigned int uFlags, unsigned int uThrottleReason) +{ + CallFuncV2(v0.FlushWithFlags, + psDRISUPContext, psDRISUPDrawable, uFlags, uThrottleReason); +} + +__DRIimage * +DRISUPCreateImageFromName(struct DRISUPScreen *psDRISUPScreen, + int iWidth, int iHeight, int iFourCC, int iName, + int iPitch, void *pvLoaderPrivate) +{ + CallFuncV2(v0.CreateImageFromName, + psDRISUPScreen, iWidth, iHeight, iFourCC, iName, iPitch, + pvLoaderPrivate); + + return NULL; +} + +__DRIimage * +DRISUPCreateImageFromRenderbuffer(struct DRISUPContext *psDRISUPContext, + int iRenderBuffer, void *pvLoaderPrivate) +{ + CallFuncV2(v0.CreateImageFromRenderbuffer, + psDRISUPContext, iRenderBuffer, pvLoaderPrivate); + + return NULL; +} + +void +DRISUPDestroyImage(__DRIimage *psImage) +{ + CallFuncV2(v0.DestroyImage, psImage); +} + +__DRIimage * +DRISUPCreateImage(struct DRISUPScreen *psDRISUPScreen, + int iWidth, int iHeight, int iFourCC, unsigned int uUse, + void *pvLoaderPrivate) +{ + CallFuncV2(v0.CreateImage, + psDRISUPScreen, iWidth, iHeight, iFourCC, uUse, pvLoaderPrivate); + + return NULL; +} + +bool +DRISUPQueryImage(__DRIimage *psImage, int iAttrib, int *piValue) +{ + CallFuncV2(v0.QueryImage, + psImage, iAttrib, piValue); + + return false; +} + +__DRIimage * +DRISUPDupImage(__DRIimage *psImage, void *pvLoaderPrivate) +{ + CallFuncV2(v0.DupImage, + psImage, pvLoaderPrivate); + + return NULL; +} + +bool +DRISUPValidateImageUsage(__DRIimage *psImage, unsigned int uUse) +{ + CallFuncV2(v0.ValidateImageUsage, + psImage, uUse); + + return false; +} + +__DRIimage * +DRISUPCreateImageFromNames(struct DRISUPScreen *psDRISUPScreen, + int iWidth, int iHeight, int iFourCC, + int *piNames, int iNumNames, + int *piStrides, int *piOffsets, + void *pvLoaderPrivate) +{ + CallFuncV2(v0.CreateImageFromNames, + psDRISUPScreen, iWidth, iHeight, iFourCC, piNames, iNumNames, + piStrides, piOffsets, pvLoaderPrivate); + + return NULL; +} + +__DRIimage * +DRISUPFromPlanar(__DRIimage *psImage, int iPlane, void *pvLoaderPrivate) +{ + CallFuncV2(v0.FromPlanar, + psImage, iPlane, pvLoaderPrivate); + + return NULL; +} + +__DRIimage * +DRISUPCreateImageFromTexture(struct DRISUPContext *psDRISUPContext, + int iTarget, unsigned int uTexture, int iDepth, + int iLevel, unsigned int *puError, + void *pvLoaderPrivate) +{ + CallFuncV2(v0.CreateImageFromTexture, + psDRISUPContext, iTarget, uTexture, iDepth, iLevel, puError, + pvLoaderPrivate); + + return NULL; +} + +__DRIimage * +DRISUPCreateImageFromFDs(struct DRISUPScreen *psDRISUPcreen, + int iWidth, int iHeight, int iFourCC, + int *piFDs, int iNumFDs, int *piStrides, + int *piOffsets, void *pvLoaderPrivate) +{ + CallFuncV2(v0.CreateImageFromFDs, + psDRISUPcreen, iWidth, iHeight, iFourCC, piFDs, iNumFDs, + piStrides, piOffsets, pvLoaderPrivate); + + return NULL; +} + +__DRIimage * +DRISUPCreateImageFromDmaBufs(struct DRISUPScreen *psDRISUPScreen, + int iWidth, int iHeight, int iFourCC, + int *piFDs, int iNumFDs, + int *piStrides, int *piOffsets, + unsigned int uColorSpace, + unsigned int uSampleRange, + unsigned int uHorizSiting, + unsigned int uVertSiting, + unsigned int *puError, + void *pvLoaderPrivate) +{ + CallFuncV2(v0.CreateImageFromDMABufs, + psDRISUPScreen, iWidth, iHeight, iFourCC, piFDs, iNumFDs, + piStrides, piOffsets, uColorSpace, uSampleRange, + uHorizSiting, uVertSiting, puError, pvLoaderPrivate); + + return NULL; +} + +int +DRISUPGetImageCapabilities(struct DRISUPScreen *psDRISUPScreen) +{ + CallFuncV2(v0.GetImageCapabilities, + psDRISUPScreen); + + return 0; +} + +void +DRISUPBlitImage(struct DRISUPContext *psDRISUPContext, + __DRIimage *psDst, __DRIimage *psSrc, int iDstX0, int iDstY0, + int iDstWidth, int iDstHeight, int iSrcX0, int iSrcY0, + int iSrcWidth, int iSrcHeight, int iFlushFlag) +{ + CallFuncV2(v0.BlitImage, + psDRISUPContext, psDst, psSrc, iDstX0, iDstY0, + iDstWidth, iDstHeight, iSrcX0, iSrcY0, + iSrcWidth, iSrcHeight, iFlushFlag); +} + +void * +DRISUPMapImage(struct DRISUPContext *psDRISUPContext, __DRIimage* psImage, + int iX0, int iY0, int iWidth, int iHeight, unsigned int uFlags, + int *piStride, void **ppvData) +{ + CallFuncV2(v0.MapImage, + psDRISUPContext, psImage, iX0, iY0, iWidth, iHeight, uFlags, + piStride, ppvData); + + return NULL; +} + +void +DRISUPUnmapImage(struct DRISUPContext *psDRISUPContext, __DRIimage *psImage, + void *pvData) +{ + CallFuncV2(v0.UnmapImage, + psDRISUPContext, psImage, pvData); +} + +__DRIimage * +DRISUPCreateImageWithModifiers(struct DRISUPScreen *psDRISUPScreen, + int iWidth, int iHeight, int iFourCC, + const uint64_t *puModifiers, + const unsigned int uModifierCount, + void *pvLoaderPrivate) +{ + CallFuncV2(v0.CreateImageWithModifiers, + psDRISUPScreen, iWidth, iHeight, iFourCC, puModifiers, + uModifierCount, pvLoaderPrivate); + + return NULL; +} + +__DRIimage * +DRISUPCreateImageFromDMABufs2(struct DRISUPScreen *psDRISUPScreen, + int iWidth, int iHeight, int iFourCC, + uint64_t uModifier, int *piFDs, int iNumFDs, + int *piStrides, int *piOffsets, + unsigned int uColorSpace, + unsigned int uSampleRange, + unsigned int uHorizSiting, + unsigned int uVertSiting, + unsigned int *puError, void *pvLoaderPrivate) +{ + CallFuncV2(v0.CreateImageFromDMABufs2, + psDRISUPScreen, iWidth, iHeight, iFourCC, uModifier, + piFDs, iNumFDs, piStrides, piOffsets, uColorSpace, uSampleRange, + uHorizSiting, uVertSiting, puError, pvLoaderPrivate); + + return NULL; +} + +bool +DRISUPQueryDMABufFormats(struct DRISUPScreen *psDRISUPScreen, int iMax, + int *piFormats, int *piCount) +{ + CallFuncV2(v0.QueryDMABufFormats, + psDRISUPScreen, iMax, piFormats, piCount); + + return false; +} + +bool +DRISUPQueryDMABufModifiers(struct DRISUPScreen *psDRISUPScreen, int iFourCC, + int iMax, uint64_t *puModifiers, + unsigned int *piExternalOnly, int *piCount) +{ + CallFuncV2(v0.QueryDMABufModifiers, + psDRISUPScreen, iFourCC, iMax, puModifiers, piExternalOnly, + piCount); + + return false; +} + +bool +DRISUPQueryDMABufFormatModifierAttribs(struct DRISUPScreen *psDRISUPScreen, + uint32_t iFourCC, uint64_t uModifier, + int iAttrib, uint64_t *puValue) +{ + CallFuncV2(v0.QueryDMABufFormatModifierAttribs, + psDRISUPScreen, iFourCC, uModifier, iAttrib, puValue); + + return false; +} + +__DRIimage * +DRISUPCreateImageFromRenderBuffer2(struct DRISUPContext *psDRISUPContext, + int iRenderBuffer, void *pvLoaderPrivate, + unsigned int *puError) +{ + CallFuncV2(v0.CreateImageFromRenderBuffer2, + psDRISUPContext, iRenderBuffer, pvLoaderPrivate, puError); + + return NULL; +} + +__DRIimage * +DRISUPCreateImageFromBuffer(struct DRISUPContext *psDRISUPContext, + int iTarget, void *pvBuffer, + unsigned int *puError, void *pvLoaderPrivate) +{ + CallFuncV2(v0.CreateImageFromBuffer, + psDRISUPContext, iTarget, pvBuffer, puError, pvLoaderPrivate); + + return NULL; +} + +int +DRISUPQueryRendererInteger(struct DRISUPScreen *psDRISUPScreen, + int iAttribute, unsigned int *puValue) +{ + CallFuncV2(v0.QueryRendererInteger, + psDRISUPScreen, iAttribute, puValue); + + return -1; +} + +int +DRISUPQueryRendererString(struct DRISUPScreen *psDRISUPScreen, + int iAttribute, const char **ppszValue) +{ + CallFuncV2(v0.QueryRendererString, + psDRISUPScreen, iAttribute, ppszValue); + + return -1; +} + +void * +DRISUPCreateFence(struct DRISUPContext *psDRISUPContext) +{ + CallFuncV2(v0.CreateFence, + psDRISUPContext); + + return NULL; +} + +void +DRISUPDestroyFence(struct DRISUPScreen *psDRISUPScreen, void *pvFence) +{ + CallFuncV2(v0.DestroyFence, + psDRISUPScreen, pvFence); +} + +bool +DRISUPClientWaitSync(struct DRISUPContext *psDRISUPContext, void *pvFence, + unsigned int uFlags, uint64_t uTimeout) +{ + CallFuncV2(v0.ClientWaitSync, + psDRISUPContext, pvFence, uFlags, uTimeout); + + return false; +} + +void +DRISUPServerWaitSync(struct DRISUPContext *psDRISUPContext, void *pvFence, + unsigned int uFlags) +{ + CallFuncV2(v0.ServerWaitSync, + psDRISUPContext, pvFence, uFlags); +} + +unsigned int +DRISUPGetFenceCapabilities(struct DRISUPScreen *psDRISUPScreen) +{ + CallFuncV2(v0.GetFenceCapabilities, + psDRISUPScreen); + + return 0; +} + +void * +DRISUPCreateFenceFD(struct DRISUPContext *psDRISUPContext, int iFD) +{ + CallFuncV2(v0.CreateFenceFD, + psDRISUPContext, iFD); + + return NULL; +} + +int +DRISUPGetFenceFD(struct DRISUPScreen *psDRISUPScreen, void *pvFence) +{ + CallFuncV2(v0.GetFenceFD, + psDRISUPScreen, pvFence); + + return -1; +} + +void * +DRISUPGetFenceFromCLEvent(struct DRISUPScreen *psDRISUPScreen, + intptr_t iCLEvent) +{ + CallFuncV2(v1.GetFenceFromCLEvent, + psDRISUPScreen, iCLEvent); + + return NULL; +} + +int +DRISUPGetAPIVersion(struct DRISUPScreen *psDRISUPScreen, + PVRDRIAPIType eAPI) +{ + CallFuncV2(v2.GetAPIVersion, + psDRISUPScreen, eAPI); + + return 0; +} + +unsigned int +DRISUPGetNumAPIProcs(struct DRISUPScreen *psDRISUPScreen, + PVRDRIAPIType eAPI) +{ + CallFuncV2(v0.GetNumAPIProcs, + psDRISUPScreen, eAPI); + + return 0; +} + +const char * +DRISUPGetAPIProcName(struct DRISUPScreen *psDRISUPScreen, PVRDRIAPIType eAPI, + unsigned int uIndex) +{ + CallFuncV2(v0.GetAPIProcName, + psDRISUPScreen, eAPI, uIndex); + + return NULL; +} + +void * +DRISUPGetAPIProcAddress(struct DRISUPScreen *psDRISUPScreen, + PVRDRIAPIType eAPI, unsigned int uIndex) +{ + CallFuncV2(v0.GetAPIProcAddress, + psDRISUPScreen, eAPI, uIndex); + + return NULL; +} + +void +DRISUPSetDamageRegion(struct DRISUPDrawable *psDRISUPDrawable, + unsigned int uNRects, int *piRects) +{ + CallFuncV2(v0.SetDamageRegion, + psDRISUPDrawable, uNRects, piRects); +} + +/****************************************************************************** + * PVR DRI Support interface, version 1. + * Everything below this point is deprecated. + *****************************************************************************/ + +PVRDRIDeviceType +PVRDRIGetDeviceTypeFromFd(int iFd) +{ + CallFunc(GetDeviceTypeFromFd, iFd); + + return PVRDRI_DEVICE_TYPE_INVALID; +} + + +bool +PVRDRIIsFirstScreen(PVRDRIScreenImpl *psScreenImpl) +{ + CallFunc(IsFirstScreen, psScreenImpl); + + return false; +} + + +uint32_t +PVRDRIPixFmtGetDepth(IMG_PIXFMT eFmt) +{ + CallFunc(PixFmtGetDepth, eFmt); + + return 0; +} + +uint32_t +PVRDRIPixFmtGetBPP(IMG_PIXFMT eFmt) +{ + CallFunc(PixFmtGetBPP, eFmt); + + return 0; +} + +uint32_t +PVRDRIPixFmtGetBlockSize(IMG_PIXFMT eFmt) +{ + CallFunc(PixFmtGetBlockSize, eFmt); + + return 0; +} + +PVRDRIScreenImpl * +PVRDRICreateScreenImpl(int iFd) +{ + CallFunc(CreateScreen, iFd); + + return NULL; +} + +void +PVRDRIDestroyScreenImpl(PVRDRIScreenImpl *psScreenImpl) +{ + CallFunc(DestroyScreen, psScreenImpl); +} + +int +PVRDRIAPIVersion(PVRDRIAPIType eAPI, PVRDRIAPISubType eAPISub, + PVRDRIScreenImpl *psScreenImpl) +{ + CallFunc(APIVersion, eAPI, eAPISub, psScreenImpl); + + return 0; +} + +void * +PVRDRIEGLGetLibHandle(PVRDRIAPIType eAPI, PVRDRIScreenImpl *psScreenImpl) +{ + CallFunc(EGLGetLibHandle, eAPI, psScreenImpl); + + return NULL; +} + +PVRDRIGLAPIProc +PVRDRIEGLGetProcAddress(PVRDRIAPIType eAPI, PVRDRIScreenImpl *psScreenImpl, + const char *psProcName) +{ + CallFunc(EGLGetProcAddress, eAPI, psScreenImpl, psProcName); + + return (PVRDRIGLAPIProc) NULL; +} + +bool +PVRDRIEGLFlushBuffers(PVRDRIAPIType eAPI, PVRDRIScreenImpl *psScreenImpl, + PVRDRIContextImpl *psContextImpl, + PVRDRIDrawableImpl *psDrawableImpl, + bool bFlushAllSurfaces, bool bSwapBuffers, + bool bWaitForHW) +{ + CallFunc(EGLFlushBuffers, eAPI, psScreenImpl, psContextImpl, + psDrawableImpl, bFlushAllSurfaces, bSwapBuffers, bWaitForHW); + + return false; +} + +void +PVRDRIEGLMarkRendersurfaceInvalid(PVRDRIAPIType eAPI, + PVRDRIScreenImpl *psScreenImpl, + PVRDRIContextImpl *psContextImpl) +{ + CallFunc(EGLMarkRendersurfaceInvalid, eAPI, psScreenImpl, psContextImpl); +} + +unsigned int +PVRDRICreateContextV1(PVRDRIScreenImpl *psScreenImpl, + PVRDRIContextImpl *psSharedContextImpl, + PVRDRIConfig *psConfig, + PVRDRIAPIType eAPI, PVRDRIAPISubType eAPISub, + unsigned int uMajorVersion, unsigned int uMinorVersion, + uint32_t uFlags, bool bNotifyReset, + unsigned int uPriority, + PVRDRIContextImpl **ppsContextImpl) +{ + CallFunc(CreateContextV1, psScreenImpl, psSharedContextImpl, psConfig, + eAPI, eAPISub, uMajorVersion, uMinorVersion, uFlags, bNotifyReset, + uPriority, ppsContextImpl); + + return PVRDRI_CONTEXT_ERROR_BAD_API; +} + +void +PVRDRIDestroyContextImpl(PVRDRIContextImpl *psContextImpl, PVRDRIAPIType eAPI, + PVRDRIScreenImpl *psScreenImpl) +{ + CallFunc(DestroyContext, psContextImpl, eAPI, psScreenImpl); +} + +bool +PVRDRIMakeCurrentGC(PVRDRIAPIType eAPI, PVRDRIScreenImpl *psScreenImpl, + PVRDRIContextImpl *psContextImpl, + PVRDRIDrawableImpl *psWriteImpl, + PVRDRIDrawableImpl *psReadImpl) +{ + CallFunc(MakeCurrentGC, eAPI, psScreenImpl, psContextImpl, psWriteImpl, + psReadImpl); + + return false; +} + +void +PVRDRIMakeUnCurrentGC(PVRDRIAPIType eAPI, PVRDRIScreenImpl *psScreenImpl) +{ + CallFunc(MakeUnCurrentGC, eAPI, psScreenImpl); +} + +unsigned int +PVRDRIGetImageSource(PVRDRIAPIType eAPI, PVRDRIScreenImpl *psScreenImpl, + PVRDRIContextImpl *psContextImpl, uint32_t uiTarget, + uintptr_t uiBuffer, uint32_t uiLevel, + IMGEGLImage *psEGLImage) +{ + CallFunc(GetImageSource, eAPI, psScreenImpl, psContextImpl, uiTarget, + uiBuffer, uiLevel, psEGLImage); + + return PVRDRI_IMAGE_ERROR_BAD_MATCH; +} + +bool +PVRDRI2BindTexImage(PVRDRIAPIType eAPI, PVRDRIScreenImpl *psScreenImpl, + PVRDRIContextImpl *psContextImpl, + PVRDRIDrawableImpl *psDrawableImpl) +{ + CallFunc(BindTexImage, eAPI, psScreenImpl, psContextImpl, psDrawableImpl); + + return false; +} + +void +PVRDRI2ReleaseTexImage(PVRDRIAPIType eAPI, PVRDRIScreenImpl *psScreenImpl, + PVRDRIContextImpl *psContextImpl, + PVRDRIDrawableImpl *psDrawableImpl) +{ + CallFunc(ReleaseTexImage, eAPI, psScreenImpl, psContextImpl, psDrawableImpl); +} + +PVRDRIDrawableImpl * +PVRDRICreateDrawableWithConfig(PVRDRIDrawable *psPVRDrawable, + PVRDRIConfig *psConfig) +{ + CallFunc(CreateDrawableWithConfig, psPVRDrawable, psConfig); + + return NULL; +} + +void +PVRDRIDestroyDrawableImpl(PVRDRIDrawableImpl *psScreenImpl) +{ + CallFunc(DestroyDrawable, psScreenImpl); +} + +bool +PVREGLDrawableCreate(PVRDRIScreenImpl *psScreenImpl, + PVRDRIDrawableImpl *psDrawableImpl) +{ + CallFunc(EGLDrawableCreate, psScreenImpl, psDrawableImpl); + + return false; +} + +bool +PVREGLDrawableRecreate(PVRDRIScreenImpl *psScreenImpl, + PVRDRIDrawableImpl *psDrawableImpl) +{ + CallFunc(EGLDrawableRecreate, psScreenImpl, psDrawableImpl); + + return false; +} + +bool +PVREGLDrawableDestroy(PVRDRIScreenImpl *psScreenImpl, + PVRDRIDrawableImpl *psDrawableImpl) +{ + CallFunc(EGLDrawableDestroy, psScreenImpl, psDrawableImpl); + + return false; +} + +void +PVREGLDrawableDestroyConfig(PVRDRIDrawableImpl *psDrawableImpl) +{ + CallFunc(EGLDrawableDestroyConfig, psDrawableImpl); +} + +PVRDRIBufferImpl * +PVRDRIBufferCreate(PVRDRIScreenImpl *psScreenImpl, int iWidth, int iHeight, + unsigned int uiBpp, unsigned int uiUseFlags, + unsigned int *puiStride) +{ + CallFunc(BufferCreate, psScreenImpl, iWidth, iHeight, uiBpp, uiUseFlags, + puiStride); + + return NULL; +} + +PVRDRIBufferImpl * +PVRDRIBufferCreateWithModifiers(PVRDRIScreenImpl *psScreenImpl, + int iWidth, int iHeight, + int format, IMG_PIXFMT eIMGPixelFormat, + const uint64_t *puiModifiers, + unsigned int uiModifierCount, + unsigned int *puiStride) +{ + CallFunc(BufferCreateWithModifiers, psScreenImpl, iWidth, iHeight, format, + eIMGPixelFormat, puiModifiers, uiModifierCount, puiStride); + + return NULL; +} + +PVRDRIBufferImpl * +PVRDRIBufferCreateFromNames(PVRDRIScreenImpl *psScreenImpl, + int iWidth, int iHeight, unsigned int uiNumPlanes, + const int *piName, const int *piStride, + const int *piOffset, + const unsigned int *puiWidthShift, + const unsigned int *puiHeightShift) +{ + CallFunc(BufferCreateFromNames, psScreenImpl, iWidth, iHeight, uiNumPlanes, + piName, piStride, piOffset, puiWidthShift, puiHeightShift); + + return NULL; +} + +PVRDRIBufferImpl * +PVRDRIBufferCreateFromFdsWithModifier(PVRDRIScreenImpl *psScreenImpl, + int iWidth, int iHeight, + uint64_t uiModifier, + unsigned int uiNumPlanes, + const int *piFd, const int *piStride, + const int *piOffset, + const unsigned int *puiWidthShift, + const unsigned int *puiHeightShift) +{ + CallFunc(BufferCreateFromFdsWithModifier, psScreenImpl, iWidth, iHeight, + uiModifier, uiNumPlanes, piFd, piStride, piOffset, + puiWidthShift, puiHeightShift); + + return NULL; +} + +PVRDRIBufferImpl * +PVRDRISubBufferCreate(PVRDRIScreenImpl *psScreen, + PVRDRIBufferImpl *psParentBuffer, int plane) +{ + CallFunc(SubBufferCreate, psScreen, psParentBuffer, plane); + + return NULL; +} + +void +PVRDRIBufferDestroy(PVRDRIBufferImpl *psBuffer) +{ + CallFunc(BufferDestroy, psBuffer); +} + +int +PVRDRIBufferGetFd(PVRDRIBufferImpl *psBuffer) +{ + CallFunc(BufferGetFd, psBuffer); + + return -1; +} + +int +PVRDRIBufferGetHandle(PVRDRIBufferImpl *psBuffer) +{ + CallFunc(BufferGetHandle, psBuffer); + + return 0; +} + +uint64_t +PVRDRIBufferGetModifier(PVRDRIBufferImpl *psBuffer) +{ + CallFunc(BufferGetModifier, psBuffer); + + return DRM_FORMAT_MOD_INVALID; +} + +int +PVRDRIBufferGetName(PVRDRIBufferImpl *psBuffer) +{ + CallFunc(BufferGetName, psBuffer); + + return 0; +} + +int +PVRDRIBufferGetOffset(PVRDRIBufferImpl *psBuffer) +{ + CallFunc(BufferGetOffset, psBuffer); + + return 0; +} + +IMGEGLImage * +PVRDRIEGLImageCreate(void) +{ + CallFunc(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) +{ + CallFunc(EGLImageCreateFromBuffer, iWidth, iHeight, iStride, ePixelFormat, + eColourSpace, eChromaUInterp, eChromaVInterp, psBuffer); + + return NULL; +} + +IMGEGLImage * +PVRDRIEGLImageCreateFromSubBuffer(IMG_PIXFMT ePixelFormat, + PVRDRIBufferImpl *psSubBuffer) +{ + CallFunc(EGLImageCreateFromSubBuffer, ePixelFormat, psSubBuffer); + + return NULL; +} + +IMGEGLImage * +PVRDRIEGLImageDup(IMGEGLImage *psIn) +{ + CallFunc(EGLImageDup, psIn); + + return NULL; +} + +void +PVRDRIEGLImageSetCallbackData(IMGEGLImage *psEGLImage, __DRIimage *image) +{ + CallFunc(EGLImageSetCallbackData, psEGLImage, image); +} + +void +PVRDRIEGLImageDestroyExternal(PVRDRIScreenImpl *psScreenImpl, + IMGEGLImage *psEGLImage, + PVRDRIEGLImageType eglImageType) +{ + CallFunc(EGLImageDestroyExternal, psScreenImpl, psEGLImage, eglImageType); +} + +void +PVRDRIEGLImageFree(IMGEGLImage *psEGLImage) +{ + CallFunc(EGLImageFree, psEGLImage); +} + +void +PVRDRIEGLImageGetAttribs(IMGEGLImage *psEGLImage, + PVRDRIBufferAttribs *psAttribs) +{ + CallFunc(EGLImageGetAttribs, psEGLImage, psAttribs); +} + +void * +PVRDRICreateFenceImpl(PVRDRIAPIType eAPI, PVRDRIScreenImpl *psScreenImpl, + PVRDRIContextImpl *psContextImpl) +{ + CallFunc(CreateFence, eAPI, psScreenImpl, psContextImpl); + + return NULL; +} + +void * +PVRDRICreateFenceFd(PVRDRIAPIType eAPI, PVRDRIScreenImpl *psScreenImpl, + PVRDRIContextImpl *psContextImpl, int iFd) +{ + CallFunc(CreateFenceFd, eAPI, psScreenImpl, psContextImpl, iFd); + + return NULL; +} + +unsigned int +PVRDRIGetFenceCapabilities(PVRDRIScreenImpl *psScreenImpl) +{ + CallFunc(GetFenceCapabilities, psScreenImpl); + + return 0; +} + +int +PVRDRIGetFenceFd(void *pvFence) +{ + CallFunc(GetFenceFd, pvFence); + + return -1; +} + +void +PVRDRIDestroyFenceImpl(void *pvFence) +{ + CallFunc(DestroyFence, pvFence); +} + +bool +PVRDRIClientWaitSyncImpl(PVRDRIAPIType eAPI, PVRDRIContextImpl *psContextImpl, + void *pvFence, bool bFlushCommands, bool bTimeout, + uint64_t uiTimeout) +{ + CallFunc(ClientWaitSync, eAPI, psContextImpl, pvFence, bFlushCommands, + bTimeout, uiTimeout); + + return false; +} + +bool +PVRDRIServerWaitSyncImpl(PVRDRIAPIType eAPI, PVRDRIContextImpl *psContextImpl, + void *pvFence) +{ + CallFunc(ServerWaitSync, eAPI, psContextImpl, pvFence); + + return false; +} + +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) +{ + CallFunc(BlitEGLImage, psScreenImpl, psContextImpl, + psDstImage, psDstBuffer, + psSrcImage, psSrcBuffer, + iDstX, iDstY, iDstWidth, iDstHeight, + iSrcX, iSrcY, iSrcWidth, iSrcHeight, + iFlushFlag); + + return false; +} + +void * +PVRDRIMapEGLImage(PVRDRIScreenImpl *psScreenImpl, + PVRDRIContextImpl *psContextImpl, + IMGEGLImage *psImage, PVRDRIBufferImpl *psBuffer, + int iX, int iY, int iWidth, int iHeight, + unsigned int uiFlags, int *piStride, void **ppvData) +{ + CallFunc(MapEGLImage, psScreenImpl, psContextImpl, psImage, psBuffer, + iX, iY, iWidth, iHeight, uiFlags, piStride, ppvData); + + return NULL; +} + +bool +PVRDRIUnmapEGLImage(PVRDRIScreenImpl *psScreenImpl, + PVRDRIContextImpl *psContextImpl, + IMGEGLImage *psImage, PVRDRIBufferImpl *psBuffer, + void *pvData) +{ + CallFunc(UnmapEGLImage, psScreenImpl, psContextImpl, psImage, psBuffer, + pvData); + + return false; +} + +bool +PVRDRIMesaFormatSupported(unsigned int iFormat) +{ + CallFunc(MesaFormatSupported, iFormat); + + return false; +} + +unsigned int +PVRDRIDepthStencilBitArraySize(void) +{ + CallFunc(DepthStencilBitArraySize); + + return 0; +} + +const uint8_t * +PVRDRIDepthBitsArray(void) +{ + CallFunc(DepthBitsArray); + + return NULL; +} + +const uint8_t * +PVRDRIStencilBitsArray(void) +{ + CallFunc(StencilBitsArray); + + return NULL; +} + +unsigned int +PVRDRIMSAABitArraySize(void) +{ + CallFunc(MSAABitArraySize); + + return 0; +} + +const uint8_t * +PVRDRIMSAABitsArray(void) +{ + CallFunc(MSAABitsArray); + + return NULL; +} + +uint32_t +PVRDRIMaxPBufferWidth(void) +{ + CallFunc(MaxPBufferWidth); + + return 0; +} + +uint32_t +PVRDRIMaxPBufferHeight(void) +{ + CallFunc(MaxPBufferHeight); + + return 0; +} + + +unsigned int +PVRDRIGetNumAPIFuncs(PVRDRIAPIType eAPI) +{ + CallFunc(GetNumAPIFuncs, eAPI); + + return 0; +} + +const char * +PVRDRIGetAPIFunc(PVRDRIAPIType eAPI, unsigned int index) +{ + CallFunc(GetAPIFunc, eAPI, index); + + return NULL; +} + +int +PVRDRIQuerySupportedFormats(PVRDRIScreenImpl *psScreenImpl, + unsigned int uNumFormats, const int *piFormats, + const IMG_PIXFMT *peImgFormats, bool *bSupported) +{ + CallFunc(QuerySupportedFormats, psScreenImpl, uNumFormats, piFormats, + peImgFormats, bSupported); + + return -1; +} + +int +PVRDRIQueryModifiers(PVRDRIScreenImpl *psScreenImpl, + int iFormat, IMG_PIXFMT eImgFormat, + uint64_t *puModifiers, unsigned int *puExternalOnly) +{ + CallFunc(QueryModifiers, psScreenImpl, iFormat, eImgFormat, puModifiers, + puExternalOnly); + + return -1; +} diff --git a/src/mesa/drivers/dri/pvr/pvrdrawable_mod.c b/src/mesa/drivers/dri/pvr/pvrdrawable_mod.c new file mode 100644 index 00000000000..505f4329cb8 --- /dev/null +++ b/src/mesa/drivers/dri/pvr/pvrdrawable_mod.c @@ -0,0 +1,385 @@ +/* + * 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 + +#include "util/u_atomic.h" +#include "pvrdri_mod.h" + +static inline void +PVRDRIMarkRenderSurfaceAsInvalid(struct DRISUPDrawable *psPVRDrawable) +{ + struct DRISUPContext *psPVRContext = psPVRDrawable->psPVRContext; + + if (psPVRContext) { + struct DRISUPScreen *psPVRScreen = psPVRContext->psPVRScreen; + + PVRDRIEGLMarkRendersurfaceInvalid(psPVRContext->eAPI, + psPVRScreen->psImpl, + psPVRContext->psImpl); + } +} + +/*************************************************************************//*! + PVR drawable local functions (image driver loader) + *//**************************************************************************/ + +static inline void +PVRDrawableImageDestroy(struct DRISUPDrawable *psPVRDrawable) +{ + if (psPVRDrawable->psImage) { + PVRDRIUnrefImage(psPVRDrawable->psImage); + psPVRDrawable->psImage = NULL; + } +} + +static inline void +PVRDrawableImageAccumDestroy(struct DRISUPDrawable *psPVRDrawable) +{ + if (psPVRDrawable->psImageAccum) { + PVRDRIUnrefImage(psPVRDrawable->psImageAccum); + psPVRDrawable->psImageAccum = NULL; + } +} + +static void +PVRDrawableImageUpdate(struct DRISUPDrawable *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(struct DRISUPDrawable *psPVRDrawable) +{ + struct PVRDRIImageList sImages; + uint32_t uBufferMask; + + if (psPVRDrawable->bDoubleBufferMode) + uBufferMask = PVRDRI_IMAGE_BUFFER_BACK; + else + uBufferMask = PVRDRI_IMAGE_BUFFER_FRONT; + + uBufferMask |= PVRDRI_IMAGE_BUFFER_PREV; + + if (!MODSUPGetBuffers(psPVRDrawable->psDRIDrawable, + psPVRDrawable->psFormat->iDRIFourCC, + NULL, psPVRDrawable->pvLoaderPrivate, + uBufferMask, &sImages)) { + errorMessage("%s: Image get buffers call failed", __func__); + return false; + } + + psPVRDrawable->psDRI = + (sImages.uImageMask & PVRDRI_IMAGE_BUFFER_BACK) ? + sImages.psBack : sImages.psFront; + + if (sImages.uImageMask & PVRDRI_IMAGE_BUFFER_PREV) + psPVRDrawable->psDRIAccum = sImages.psPrev; + else + psPVRDrawable->psDRIAccum = NULL; + + return true; +} + +/*************************************************************************//*! +Function Name : PVRImageDrawableCreate +Inputs : psPVRDrawable +Returns : Boolean +Description : Create drawable + *//**************************************************************************/ +static bool +PVRImageDrawableCreate(struct DRISUPDrawable *psPVRDrawable) +{ + uint32_t uBytesPerPixel; + PVRDRIBufferAttribs sBufferAttribs; + + if (!PVRImageDrawableGetNativeInfo(psPVRDrawable)) + return false; + + PVRDRIEGLImageGetAttribs(PVRDRIImageGetEGLImage(psPVRDrawable->psDRI), + &sBufferAttribs); + uBytesPerPixel = PVRDRIPixFmtGetBlockSize(sBufferAttribs.ePixFormat); + + psPVRDrawable->uWidth = sBufferAttribs.uiWidth; + psPVRDrawable->uHeight = 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", __func__); + return false; + } + + return true; +} + +/*************************************************************************//*! +Function Name : PVRImageDrawableUpdate +Inputs : psPVRDrawable +Returns : Boolean +Description : Update drawable + *//**************************************************************************/ +static bool +PVRImageDrawableUpdate(struct DRISUPDrawable *psPVRDrawable, + bool bAllowRecreate) +{ + uint32_t uBytesPerPixel; + PVRDRIBufferAttribs sBufferAttribs; + bool bRecreate; + + PVRDRIEGLImageGetAttribs(PVRDRIImageGetEGLImage(psPVRDrawable->psDRI), + &sBufferAttribs); + uBytesPerPixel = PVRDRIPixFmtGetBlockSize(sBufferAttribs.ePixFormat); + + bRecreate = + (!psPVRDrawable->bDoubleBufferMode && + psPVRDrawable->psImage != psPVRDrawable->psDRI) || + (psPVRDrawable->uWidth != sBufferAttribs.uiWidth) || + (psPVRDrawable->uHeight != sBufferAttribs.uiHeight) || + (psPVRDrawable->uStride != sBufferAttribs.uiStrideInBytes) || + (psPVRDrawable->uBytesPerPixel != uBytesPerPixel); + + if (bRecreate) { + if (bAllowRecreate) { + PVRDRIMarkRenderSurfaceAsInvalid(psPVRDrawable); + + psPVRDrawable->uWidth = sBufferAttribs.uiWidth; + psPVRDrawable->uHeight = 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", __func__); + return false; + } + } + + return true; +} + +/*************************************************************************//*! + PVR drawable local functions + *//**************************************************************************/ + +/*************************************************************************//*! +Function Name : PVRDRIDrawableUpdate +Inputs : psPVRDrawable +Description : Update drawable + *//**************************************************************************/ +static bool +PVRDRIDrawableUpdate(struct DRISUPDrawable *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; +} + +/*************************************************************************//*! + PVR drawable interface + *//**************************************************************************/ +bool +PVRDRIDrawableInit(struct DRISUPDrawable *psPVRDrawable) +{ + if (psPVRDrawable->bInitialised) + return true; + + if (!PVRImageDrawableCreate(psPVRDrawable)) + return false; + + psPVRDrawable->bInitialised = true; + + return true; +} + +void +PVRDRIDrawableDeinit(struct DRISUPDrawable *psPVRDrawable) +{ + (void) PVREGLDrawableDestroy(psPVRDrawable->psPVRScreen->psImpl, + psPVRDrawable->psImpl); + + PVRDrawableImageDestroy(psPVRDrawable); + PVRDrawableImageAccumDestroy(psPVRDrawable); + + psPVRDrawable->bInitialised = false; +} + +static bool +PVRDRIDrawableGetParameters(struct DRISUPDrawable *psPVRDrawable, + PVRDRIBufferImpl **ppsDstBuffer, + PVRDRIBufferImpl **ppsAccumBuffer) +{ + if (ppsDstBuffer || ppsAccumBuffer) { + __DRIimage *psDstImage = psPVRDrawable->psImage; + __DRIimage *psAccumImage = psPVRDrawable->psImageAccum; + PVRDRIBufferImpl *psDstBuffer, *psAccumBuffer; + + psDstBuffer = PVRDRIImageGetSharedBuffer(psDstImage); + if (!psDstBuffer) { + errorMessage("%s: Couldn't get backing buffer", __func__); + return false; + } + + if (psAccumImage) { + psAccumBuffer = PVRDRIImageGetSharedBuffer(psAccumImage); + if (!psAccumBuffer) + psAccumBuffer = psDstBuffer; + } else { + psAccumBuffer = psDstBuffer; + } + + if (ppsDstBuffer) + *ppsDstBuffer = psDstBuffer; + + if (ppsAccumBuffer) + *ppsAccumBuffer = psAccumBuffer; + } + + return true; +} + +bool +PVRDRIDrawableQuery(const PVRDRIDrawable *psPVRDRIDrawable, + PVRDRIBufferAttrib eBufferAttrib, uint32_t *uiValueOut) +{ + const struct DRISUPDrawable *psPVRDrawable; + + if (!psPVRDRIDrawable || !uiValueOut) + return false; + + psPVRDrawable = (const struct DRISUPDrawable *) psPVRDRIDrawable; + + switch (eBufferAttrib) { + case PVRDRI_BUFFER_ATTRIB_TYPE: + *uiValueOut = (uint32_t) psPVRDrawable->eType; + return true; + case PVRDRI_BUFFER_ATTRIB_WIDTH: + *uiValueOut = (uint32_t) psPVRDrawable->uWidth; + return true; + case PVRDRI_BUFFER_ATTRIB_HEIGHT: + *uiValueOut = (uint32_t) psPVRDrawable->uHeight; + return true; + case PVRDRI_BUFFER_ATTRIB_STRIDE: + *uiValueOut = (uint32_t) psPVRDrawable->uStride; + return true; + case PVRDRI_BUFFER_ATTRIB_PIXEL_FORMAT: + *uiValueOut = (uint32_t) psPVRDrawable->psFormat->eIMGPixelFormat; + static_assert(sizeof(IMG_PIXFMT) <= sizeof(*uiValueOut), + "Type size mismatch"); + return true; + case PVRDRI_BUFFER_ATTRIB_INVALID: + errorMessage("%s: Invalid attribute", __func__); + assert(0); + return false; + default: + return false; + } +} + +bool +PVRDRIDrawableGetParametersV2(PVRDRIDrawable *psPVRDRIDrawable, + uint32_t uiFlags, + PVRDRIBufferImpl **ppsDstBuffer, + PVRDRIBufferImpl **ppsAccumBuffer) +{ + const bool bNoUpdate = uiFlags & PVRDRI_GETPARAMS_FLAG_NO_UPDATE; + struct DRISUPDrawable *psPVRDrawable; + + psPVRDrawable = (struct DRISUPDrawable *) psPVRDRIDrawable; + + 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..45950552647 --- /dev/null +++ b/src/mesa/drivers/dri/pvr/pvrdri.c @@ -0,0 +1,603 @@ +/* + * 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 +#include + +#include "util/u_atomic.h" +#include "utils.h" + +#include "pvrdri.h" +#include "pvrmesa.h" +#include "pvrdri_mod.h" + +#define PVR_IMAGE_LOADER_VER_MIN 1 + +struct PVRBuffer { + __DRIbuffer sDRIBuffer; + struct DRISUPBuffer *psDRISUPBuffer; +}; + +/*************************************************************************//*! + Local functions + *//**************************************************************************/ + +static bool +PVRLoaderIsSupported(__DRIscreen *psDRIScreen) +{ + if (psDRIScreen->image.loader) { + if (psDRIScreen->image.loader->base.version < PVR_IMAGE_LOADER_VER_MIN) { + __driUtilMessage("%s: Image loader extension version %d but need %d", + __func__, psDRIScreen->image.loader->base.version, + PVR_IMAGE_LOADER_VER_MIN); + return false; + } else if (!psDRIScreen->image.loader->getBuffers) { + __driUtilMessage("%s: Image loader extension missing support for getBuffers", + __func__); + return false; + } + } else { + __driUtilMessage("%s: Image loader extension required", __func__); + return false; + } + + return true; +} + +static inline struct DRISUPContext * +getSharedContextImpl(void *pvSharedContextPrivate) +{ + if (pvSharedContextPrivate == NULL) + return NULL; + + return ((PVRDRIContext *) pvSharedContextPrivate)->psDRISUPContext; +} + +static void +PVRDRIScreenAddReference(PVRDRIScreen *psPVRScreen) +{ + int iRefCount = p_atomic_inc_return(&psPVRScreen->iRefCount); + + (void) iRefCount; + assert(iRefCount > 1); +} + +static void +PVRDRIScreenRemoveReference(PVRDRIScreen *psPVRScreen) +{ + int iRefCount = p_atomic_dec_return(&psPVRScreen->iRefCount); + + assert(iRefCount >= 0); + + if (iRefCount != 0) + return; + + pvrdri_free_dispatch_tables(psPVRScreen); + DRISUPDestroyScreen(psPVRScreen->psDRISUPScreen); + PVRDRICompatDeinit(); + free(psPVRScreen); +} + +static void +PVRScreenPrintExtensions(__DRIscreen *psDRIScreen) +{ + /* Don't attempt to print anything if LIBGL_DEBUG isn't in the environment */ + if (getenv("LIBGL_DEBUG") == NULL) + return; + + if (psDRIScreen->extensions) { + const __DRIextension *psScreenExtensionVersionInfo = + PVRDRIScreenExtensionVersionInfo(); + int i; + int j; + + __driUtilMessage("Supported screen extensions:"); + + for (i = 0; psDRIScreen->extensions[i]; i++) { + for (j = 0; psScreenExtensionVersionInfo[j].name; j++) { + if (strcmp(psDRIScreen->extensions[i]->name, + psScreenExtensionVersionInfo[j].name) == 0) { + __driUtilMessage("\t%s (supported version: %u - max version: %u)", + psDRIScreen->extensions[i]->name, + psDRIScreen->extensions[i]->version, + psScreenExtensionVersionInfo[j].version); + break; + } + } + + if (psScreenExtensionVersionInfo[j].name == NULL) { + __driUtilMessage("\t%s (supported version: %u - max version: unknown)", + psDRIScreen->extensions[i]->name, + psDRIScreen->extensions[i]->version); + } + } + } else { + __driUtilMessage("No screen extensions found"); + } +} + +/*************************************************************************//*! + Mesa driver API functions + *//**************************************************************************/ + +static const __DRIconfig ** +PVRDRIInitScreen(__DRIscreen *psDRIScreen) +{ + PVRDRIScreen *psPVRScreen; + const __DRIconfig **ppsConfigs; + int iMaxGLES1Version, iMaxGLES2Version; + const PVRDRICallbacks sDRICallbacks = { + /* Version 0 callbacks */ + .ImageGetSharedType = PVRDRIImageGetSharedType, + .ImageGetSharedBuffer = PVRDRIImageGetSharedBuffer, + .ImageGetSharedEGLImage = PVRDRIImageGetSharedEGLImage, + .ImageGetEGLImage = PVRDRIImageGetEGLImage, + .ScreenGetDRIImage = PVRDRIScreenGetDRIImage, + .RefImage = PVRDRIRefImage, + .UnrefImage = PVRDRIUnrefImage, + + /* Version 1 callbacks */ + .RegisterSupportInterfaceV1 = PVRDRIRegisterSupportInterfaceV1, + + /* Version 2 callbacks */ + .ConfigQuery = PVRDRIConfigQuery, + .DrawableGetParametersV2 = PVRDRIDrawableGetParametersV2, + .DrawableQuery = PVRDRIDrawableQuery, + }; + const struct PVRDRICallbacksV2 sDRICallbacksV2 = { + /* Version 0 callbacks */ + .v0.RegisterSupportInterface = MODSUPRegisterSupportInterfaceV2, + .v0.GetBuffers = MODSUPGetBuffers, + .v0.CreateConfigs = MODSUPCreateConfigs, + .v0.ConcatConfigs = MODSUPConcatConfigs, + .v0.ConfigQuery = MODSUPConfigQuery, + .v0.LookupEGLImage = MODSUPLookupEGLImage, + .v0.GetCapability = MODSUPGetCapability, + /* Version 1 callbacks */ + .v1.FlushFrontBuffer = MODSUPFlushFrontBuffer, + }; + + if (!PVRLoaderIsSupported(psDRIScreen)) + return NULL; + + if (!PVRDRICompatInit(&sDRICallbacks, 3, &sDRICallbacksV2, 1, 0)) + return NULL; + + psPVRScreen = calloc(1, sizeof(*psPVRScreen)); + if (psPVRScreen == NULL) { + __driUtilMessage("%s: Couldn't allocate PVRDRIScreen", __func__); + goto ErrorCompatDeinit; + } + + psDRIScreen->driverPrivate = psPVRScreen; + psPVRScreen->psDRIScreen = psDRIScreen; + psPVRScreen->iRefCount = 1; + + psPVRScreen->psDRISUPScreen = + DRISUPCreateScreen(psDRIScreen, psDRIScreen->fd, + psDRIScreen->dri2.useInvalidate != NULL, + psDRIScreen->loaderPrivate, + &ppsConfigs, &iMaxGLES1Version, &iMaxGLES2Version); + if (!psPVRScreen->psDRISUPScreen) + goto ErrorScreenFree; + + psDRIScreen->max_gl_es1_version = iMaxGLES1Version; + psDRIScreen->max_gl_es2_version = iMaxGLES2Version; + + psDRIScreen->max_gl_compat_version = + DRISUPGetAPIVersion(psPVRScreen->psDRISUPScreen, PVRDRI_API_GL_COMPAT); + psDRIScreen->max_gl_core_version = + DRISUPGetAPIVersion(psPVRScreen->psDRISUPScreen, PVRDRI_API_GL_CORE); + + psDRIScreen->extensions = PVRDRIScreenExtensions(); + + PVRScreenPrintExtensions(psDRIScreen); + + return ppsConfigs; + +ErrorScreenFree: + psDRIScreen->driverPrivate = NULL; + free(psPVRScreen); + +ErrorCompatDeinit: + PVRDRICompatDeinit(); + + return NULL; +} + +static void +PVRDRIDestroyScreen(__DRIscreen *psDRIScreen) +{ + PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate; + +#if defined(DEBUG) + if (psPVRScreen->iBufferAlloc != 0 || + psPVRScreen->iDrawableAlloc != 0 || + psPVRScreen->iContextAlloc != 0) { + errorMessage("%s: Outstanding allocations: Contexts: %d Drawables: %d Buffers: %d", + __func__, psPVRScreen->iContextAlloc, + psPVRScreen->iDrawableAlloc, psPVRScreen->iBufferAlloc); + + if (psPVRScreen->iRefCount > 1) { + errorMessage("%s: PVRDRIScreen resources will not be freed until its %d references are removed", + __func__, psPVRScreen->iRefCount - 1); + } + } +#endif + + PVRDRIScreenRemoveReference(psPVRScreen); +} + +static int +PVRDRIScreenSupportedAPIs(PVRDRIScreen *psPVRScreen) +{ + unsigned int api_mask = psPVRScreen->psDRIScreen->api_mask; + int supported = 0; + + if ((api_mask & (1 << __DRI_API_GLES)) != 0) + supported |= PVRDRI_API_BIT_GLES; + + if ((api_mask & (1 << __DRI_API_GLES2)) != 0) + supported |= PVRDRI_API_BIT_GLES2; + + if ((api_mask & (1 << __DRI_API_GLES3)) != 0) + supported |= PVRDRI_API_BIT_GLES3; + + if ((api_mask & (1 << __DRI_API_OPENGL)) != 0) + supported |= PVRDRI_API_BIT_GL; + + if ((api_mask & (1 << __DRI_API_OPENGL_CORE)) != 0) + supported |= PVRDRI_API_BIT_GL; + + return supported; +} + +static GLboolean +PVRDRICreateContext(gl_api eMesaAPI, const struct gl_config *psGLMode, + __DRIcontext *psDRIContext, + const struct __DriverContextConfig *psCtxConfig, + unsigned int *puError, void *pvSharedContextPrivate) +{ + __DRIscreen *psDRIScreen = psDRIContext->driScreenPriv; + PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate; + PVRDRIContext *psPVRContext; + struct DRISUPContext *psDRISUPContext; + struct DRISUPContext *psDRISUPSharedContext; + struct PVRDRIContextConfig sCtxConfig; + PVRDRIAPIType eAPI; + + psDRISUPSharedContext = getSharedContextImpl(pvSharedContextPrivate); + + sCtxConfig.uMajorVersion = psCtxConfig->major_version; + sCtxConfig.uMinorVersion = psCtxConfig->minor_version; + sCtxConfig.uFlags = psCtxConfig->flags; + sCtxConfig.iResetStrategy = PVRDRI_CONTEXT_RESET_NO_NOTIFICATION; + sCtxConfig.uPriority = PVRDRI_CONTEXT_PRIORITY_MEDIUM; + sCtxConfig.iReleaseBehavior = PVRDRI_CONTEXT_RELEASE_BEHAVIOR_FLUSH; + + psPVRContext = calloc(1, sizeof(*psPVRContext)); + if (psPVRContext == NULL) { + __driUtilMessage("%s: Couldn't allocate PVRDRIContext", __func__); + *puError = __DRI_CTX_ERROR_NO_MEMORY; + return GL_FALSE; + } + + psPVRContext->psDRIContext = psDRIContext; + psPVRContext->psPVRScreen = psPVRScreen; + + if (psGLMode) + psPVRContext->sConfig.sGLMode = *psGLMode; + + switch (eMesaAPI) { + case API_OPENGLES: + eAPI = PVRDRI_API_GLES1; + break; + case API_OPENGLES2: + eAPI = PVRDRI_API_GLES2; + break; + case API_OPENGL_COMPAT: + eAPI = PVRDRI_API_GL_COMPAT; + break; + case API_OPENGL_CORE: + eAPI = PVRDRI_API_GL_CORE; + break; + default: + __driUtilMessage("%s: Unsupported API: %d", + __func__, (int) eMesaAPI); + *puError = __DRI_CTX_ERROR_BAD_API; + goto ErrorContextFree; + } + psPVRContext->eAPI = eAPI; + + if ((psCtxConfig->attribute_mask & + __DRIVER_CONTEXT_ATTRIB_RESET_STRATEGY) != 0) { + sCtxConfig.iResetStrategy = psCtxConfig->reset_strategy; + } + + if ((psCtxConfig->attribute_mask & + __DRIVER_CONTEXT_ATTRIB_RELEASE_BEHAVIOR) != 0) { + sCtxConfig.iReleaseBehavior = psCtxConfig->release_behavior; + } + + if ((psCtxConfig->attribute_mask & + __DRIVER_CONTEXT_ATTRIB_PRIORITY) != 0) { + sCtxConfig.uPriority = psCtxConfig->priority; + } + + *puError = DRISUPCreateContext(eAPI, &psPVRContext->sConfig, &sCtxConfig, + psDRIContext, psDRISUPSharedContext, + psPVRScreen->psDRISUPScreen, + &psDRISUPContext); + if (*puError != __DRI_CTX_ERROR_SUCCESS) + goto ErrorContextFree; + + psPVRContext->psDRISUPContext = psDRISUPContext; + + if (!pvrdri_create_dispatch_table(psPVRScreen, eAPI)) { + __driUtilMessage("%s: Couldn't create dispatch table", __func__); + *puError = __DRI_CTX_ERROR_BAD_API; + goto ErrorContextDestroy; + } +#if defined(DEBUG) + p_atomic_inc(&psPVRScreen->iContextAlloc); +#endif + + psDRIContext->driverPrivate = (void *) psPVRContext; + PVRDRIScreenAddReference(psPVRScreen); + + *puError = __DRI_CTX_ERROR_SUCCESS; + + return GL_TRUE; + +ErrorContextDestroy: + DRISUPDestroyContext(psPVRContext->psDRISUPContext); + +ErrorContextFree: + free(psPVRContext); + + return GL_FALSE; +} + +static void +PVRDRIDestroyContext(__DRIcontext *psDRIContext) +{ + PVRDRIContext *psPVRContext = psDRIContext->driverPrivate; + PVRDRIScreen *psPVRScreen = psPVRContext->psPVRScreen; + + DRISUPDestroyContext(psPVRContext->psDRISUPContext); + +#if defined(DEBUG) + p_atomic_dec(&psPVRScreen->iContextAlloc); +#endif + + PVRDRIScreenRemoveReference(psPVRScreen); + free(psPVRContext); +} + +static GLboolean +PVRDRICreateBuffer(__DRIscreen *psDRIScreen, __DRIdrawable *psDRIDrawable, + const struct gl_config *psGLMode, GLboolean bIsPixmap) +{ + PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate; + PVRDRIDrawable *psPVRDrawable = NULL; + + /* No known callers ever set this to true */ + if (bIsPixmap) + return GL_FALSE; + + if (!psGLMode) { + __driUtilMessage("%s: Invalid GL config", __func__); + return GL_FALSE; + } + + psPVRDrawable = calloc(1, sizeof(*psPVRDrawable)); + if (!psPVRDrawable) { + __driUtilMessage("%s: Couldn't allocate PVR drawable", __func__); + goto ErrorDrawableFree; + } + + psDRIDrawable->driverPrivate = (void *) psPVRDrawable; + psPVRDrawable->psDRIDrawable = psDRIDrawable; + psPVRDrawable->psPVRScreen = psPVRScreen; + psPVRDrawable->sConfig.sGLMode = *psGLMode; + psPVRDrawable->sConfig.iSupportedAPIs = + PVRDRIScreenSupportedAPIs(psPVRScreen); + + psPVRDrawable->psDRISUPDrawable = + DRISUPCreateDrawable(psDRIDrawable, psPVRScreen->psDRISUPScreen, + psDRIDrawable->loaderPrivate, + &psPVRDrawable->sConfig); + if (!psPVRDrawable->psDRISUPDrawable) { + __driUtilMessage("%s: Couldn't create DRI Support drawable", + __func__); + goto ErrorDrawableFree; + } + + /* Initialisation is completed in MakeCurrent */ +#if defined(DEBUG) + p_atomic_inc(&psPVRScreen->iDrawableAlloc); +#endif + PVRDRIScreenAddReference(psPVRScreen); + return GL_TRUE; + +ErrorDrawableFree: + DRISUPDestroyDrawable(psPVRDrawable->psDRISUPDrawable); + free(psPVRDrawable); + psDRIDrawable->driverPrivate = NULL; + + return GL_FALSE; +} + +static void +PVRDRIDestroyBuffer(__DRIdrawable *psDRIDrawable) +{ + PVRDRIDrawable *psPVRDrawable = psDRIDrawable->driverPrivate; + + DRISUPDestroyDrawable(psPVRDrawable->psDRISUPDrawable); + +#if defined(DEBUG) + p_atomic_dec(&psPVRDrawable->psPVRScreen->iDrawableAlloc); +#endif + + PVRDRIScreenRemoveReference(psPVRDrawable->psPVRScreen); + free(psPVRDrawable); +} + +static GLboolean +PVRDRIMakeCurrent(__DRIcontext *psDRIContext, + __DRIdrawable *psDRIWrite, __DRIdrawable *psDRIRead) +{ + PVRDRIContext *psPVRContext = psDRIContext->driverPrivate; + struct DRISUPDrawable *psDRISUPWrite; + struct DRISUPDrawable *psDRISUPRead; + + if (psDRIWrite) { + PVRDRIDrawable *psPVRWrite = psDRIWrite->driverPrivate; + + psDRISUPWrite = psPVRWrite->psDRISUPDrawable; + } else { + psDRISUPWrite = NULL; + } + + if (psDRIRead) { + PVRDRIDrawable *psPVRRead = psDRIRead->driverPrivate; + + psDRISUPRead = psPVRRead->psDRISUPDrawable; + } else { + psDRISUPRead = NULL; + } + + if (!DRISUPMakeCurrent(psPVRContext->psDRISUPContext, + psDRISUPWrite, psDRISUPRead)) + goto ErrorUnlock; + + pvrdri_set_dispatch_table(psPVRContext); + + return GL_TRUE; + +ErrorUnlock: + return GL_FALSE; +} + +static GLboolean +PVRDRIUnbindContext(__DRIcontext *psDRIContext) +{ + PVRDRIContext *psPVRContext = psDRIContext->driverPrivate; + + pvrdri_set_null_dispatch_table(); + DRISUPUnbindContext(psPVRContext->psDRISUPContext); + + return GL_TRUE; +} + +static __DRIbuffer * +PVRDRIAllocateBuffer(__DRIscreen *psDRIScreen, unsigned int uAttachment, + unsigned int uFormat, int iWidth, int iHeight) +{ + PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate; + struct PVRBuffer *psBuffer; + + psBuffer = calloc(1, sizeof(*psBuffer)); + if (psBuffer == NULL) { + __driUtilMessage("%s: Failed to allocate buffer", __func__); + return NULL; + } + + psBuffer->psDRISUPBuffer = + DRISUPAllocateBuffer(psPVRScreen->psDRISUPScreen, uAttachment, uFormat, + iWidth, iHeight, &psBuffer->sDRIBuffer.name, + &psBuffer->sDRIBuffer.pitch, + &psBuffer->sDRIBuffer.cpp, + &psBuffer->sDRIBuffer.flags); + if (!psBuffer->psDRISUPBuffer) { + __driUtilMessage("%s: Failed to create DRI Support buffer", __func__); + goto ErrorFreeDRIBuffer; + } + + psBuffer->sDRIBuffer.attachment = uAttachment; + +#if defined(DEBUG) + p_atomic_inc(&psPVRScreen->iBufferAlloc); +#endif + + return &psBuffer->sDRIBuffer; + +ErrorFreeDRIBuffer: + free(psBuffer); + + return NULL; +} + +static void +PVRDRIReleaseBuffer(__DRIscreen *psDRIScreen, __DRIbuffer *psDRIBuffer) +{ + struct PVRBuffer *psPVRBuffer = (struct PVRBuffer *) psDRIBuffer; + PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate; + + DRISUPReleaseBuffer(psPVRScreen->psDRISUPScreen, + psPVRBuffer->psDRISUPBuffer); + +#if defined(DEBUG) + p_atomic_dec(&psPVRScreen->iBufferAlloc); +#endif + + free(psPVRBuffer); +} + +static const struct __DriverAPIRec pvr_driver_api = { + .InitScreen = PVRDRIInitScreen, + .DestroyScreen = PVRDRIDestroyScreen, + .CreateContext = PVRDRICreateContext, + .DestroyContext = PVRDRIDestroyContext, + .CreateBuffer = PVRDRICreateBuffer, + .DestroyBuffer = PVRDRIDestroyBuffer, + .SwapBuffers = NULL, + .MakeCurrent = PVRDRIMakeCurrent, + .UnbindContext = PVRDRIUnbindContext, + .AllocateBuffer = PVRDRIAllocateBuffer, + .ReleaseBuffer = PVRDRIReleaseBuffer, +}; + +static const struct __DRIDriverVtableExtensionRec pvr_vtable = { + .base = {__DRI_DRIVER_VTABLE, 1}, + .vtable = &pvr_driver_api, +}; + +static const __DRIextension *pvr_driver_extensions[] = { + &driCoreExtension.base, + &driImageDriverExtension.base, + &driDRI2Extension.base, + &pvr_vtable.base, + NULL +}; + +const __DRIextension **__driDriverGetExtensions_pvr(void); + +PUBLIC const __DRIextension ** +__driDriverGetExtensions_pvr(void) +{ + globalDriverAPI = &pvr_driver_api; + + return pvr_driver_extensions; +} diff --git a/src/mesa/drivers/dri/pvr/pvrdri.h b/src/mesa/drivers/dri/pvr/pvrdri.h new file mode 100644 index 00000000000..8b37876411a --- /dev/null +++ b/src/mesa/drivers/dri/pvr/pvrdri.h @@ -0,0 +1,176 @@ +/* + * Copyright (c) Imagination Technologies Ltd. + * + * The contents of this file are subject to the MIT license as set out below. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#if !defined(__PVRDRI_H__) +#define __PVRDRI_H__ + +#include +#include +#include + +#include + +#include "main/mtypes.h" +#include "util/macros.h" +#include "dri_util.h" +#include "pvrdri_support.h" + +struct PVRDRIConfigRec { + struct gl_config sGLMode; + int iSupportedAPIs; +}; + +/* PVR screen data */ +typedef struct PVRDRIScreen_TAG { + /* DRI screen structure pointer */ + __DRIscreen *psDRIScreen; + + /* Opaque PVR DRI Support screen structure pointer */ + struct DRISUPScreen *psDRISUPScreen; + + /* Reference count */ + int iRefCount; + +#if defined(DEBUG) + /* Counters of outstanding allocations */ + int iContextAlloc; + int iDrawableAlloc; + int iBufferAlloc; +#endif + + /* PVR OGLES 1 dispatch table */ + struct _glapi_table *psOGLES1Dispatch; + /* PVR OGLES 2/3 dispatch table */ + struct _glapi_table *psOGLES2Dispatch; + /* PVR OGL dispatch table */ + struct _glapi_table *psOGLDispatch; +} PVRDRIScreen; + +/* PVR context data */ +typedef struct PVRDRIContext_TAG { + /* Pointer to DRI context */ + __DRIcontext *psDRIContext; + + /* Opaque PVR DRI Support context structure pointer */ + struct DRISUPContext *psDRISUPContext; + + /* Pointer to PVRDRIScreen structure */ + PVRDRIScreen *psPVRScreen; + + /* GL config */ + PVRDRIConfig sConfig; + + /* API */ + PVRDRIAPIType eAPI; +} PVRDRIContext; + +/* PVR drawable data */ +typedef struct PVRDRIDrawable_TAG { + PVRDRIScreen *psPVRScreen; + __DRIdrawable *psDRIDrawable; + PVRDRIConfig sConfig; + struct DRISUPDrawable *psDRISUPDrawable; + unsigned int uFourCC; + unsigned int uDRIFormat; +} PVRDRIDrawable; + +/*************************************************************************//*! + pvrutil.c + *//**************************************************************************/ + +void PRINTFLIKE(1, 2) __driUtilMessage(const char *f, ...); +void PRINTFLIKE(1, 2) errorMessage(const char *f, ...); + +mesa_format PVRDRIMesaFormatToMesaFormat(int pvrdri_mesa_format); +int PVRDRIFormatToFourCC(int dri_format); +int PVRDRIFourCCToDRIFormat(int iFourCC); + +/*************************************************************************//*! + pvrext.c + *//**************************************************************************/ + +const __DRIextension **PVRDRIScreenExtensions(void); +const __DRIextension *PVRDRIScreenExtensionVersionInfo(void); + +void PVRDRIAdjustExtensions(unsigned int uVersion, unsigned int uMinVersion); + +/*************************************************************************//*! + pvrcompat.c + *//**************************************************************************/ + +bool PVRDRICompatInit(const PVRDRICallbacks *psCallbacks, + unsigned int uVersion, + const struct PVRDRICallbacksV2 *psCallbacksV2, + unsigned int uVersionV2, unsigned int uMinVersionV2); +void PVRDRICompatDeinit(void); + +bool PVRDRIRegisterSupportInterfaceV1(const PVRDRISupportInterface *psInterface, + unsigned int uVersion); +bool MODSUPRegisterSupportInterfaceV2(const void *pvInterface, + unsigned int uVersion, + unsigned int uMinVersion); + +/*************************************************************************//*! + pvrcb.c + *//**************************************************************************/ + +int MODSUPGetBuffers(struct __DRIdrawableRec *psDRIDrawable, + unsigned int uFourCC, uint32_t *puStamp, + void *pvLoaderPrivate, uint32_t uBufferMask, + struct PVRDRIImageList *psImageList); + +bool MODSUPCreateConfigs(struct __DRIconfigRec ***psConfigs, + struct __DRIscreenRec *psDRIScreen, + int iPVRDRIMesaFormat, const uint8_t *puDepthBits, + const uint8_t *puStencilBits, + unsigned int uNumDepthStencilBits, + const unsigned int *puDBModes, + unsigned int uNumDBModes, + const uint8_t *puMSAASamples, + unsigned int uNumMSAAModes, bool bEnableAccum, + bool bColorDepthMatch, bool bMutableRenderBuffer, + int iYUVDepthRange, int iYUVCSCStandard, + uint32_t uMaxPbufferWidth, uint32_t uMaxPbufferHeight); + +struct __DRIconfigRec **MODSUPConcatConfigs(struct __DRIscreenRec *psDRIScreen, + struct __DRIconfigRec **ppsConfigA, + struct __DRIconfigRec **ppsConfigB); + +__DRIimage *MODSUPLookupEGLImage(struct __DRIscreenRec *psDRIScreen, + void *pvImage, void *pvLoaderPrivate); + +unsigned int MODSUPGetCapability(struct __DRIscreenRec *psDRIScreen, + unsigned int uCapability); + +bool PVRDRIConfigQuery(const PVRDRIConfig *psConfig, + PVRDRIConfigAttrib eConfigAttrib, int *piValueOut); + +bool MODSUPConfigQuery(const PVRDRIConfig *psConfig, + PVRDRIConfigAttrib eConfigAttrib, + unsigned int *puValueOut); + +void MODSUPFlushFrontBuffer(struct __DRIdrawableRec *psDRIDrawable, + void *pvLoaderPrivate); + +#endif /* defined(__PVRDRI_H__) */ diff --git a/src/mesa/drivers/dri/pvr/pvrdri_mod.c b/src/mesa/drivers/dri/pvr/pvrdri_mod.c new file mode 100644 index 00000000000..0abe8a38d3a --- /dev/null +++ b/src/mesa/drivers/dri/pvr/pvrdri_mod.c @@ -0,0 +1,584 @@ +/* + * 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 +#include + +#include "pvrdri_mod.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) + + +/* We need to know the current screen in order to lookup EGL images. */ +static __thread struct DRISUPScreen *gpsPVRScreen; + +/*************************************************************************//*! + Local functions + *//**************************************************************************/ + +static inline bool +PVRDRIFlushBuffers(struct DRISUPContext *psPVRContext, + struct DRISUPDrawable *psPVRDrawable, uint32_t uiFlags) +{ + PVRDRIDrawableImpl *psDrawableImpl; + bool bFlushAllSurfaces = (uiFlags & PVRDRI_FLUSH_ALL_SURFACES) != 0; + bool bSwapBuffers = (uiFlags & PVRDRI_FLUSH_NEW_EXTERNAL_FRAME) != 0; + bool bWaitForHW = (uiFlags & PVRDRI_FLUSH_WAIT_FOR_HW) != 0; + + psDrawableImpl = psPVRDrawable ? psPVRDrawable->psImpl : NULL; + + 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, psDrawableImpl, + bFlushAllSurfaces, bSwapBuffers, bWaitForHW); +} + +void +PVRDRIFlushBuffersForSwap(struct DRISUPContext *psPVRContext, + struct DRISUPDrawable *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(struct DRISUPContext *psPVRContext, + struct DRISUPDrawable *psPVRDrawable) +{ + (void) PVRDRIFlushBuffers(psPVRContext, psPVRDrawable, + PVRDRI_FLUSH_WAIT_FOR_HW | + PVRDRI_FLUSH_ALL_SURFACES); +} + +static void +PVRContextUnbind(struct DRISUPContext *psPVRContext, bool bMakeUnCurrent, + bool bMarkSurfaceInvalid) +{ + struct DRISUPScreen *psPVRScreen = psPVRContext->psPVRScreen; + struct DRISUPDrawable *psPVRDrawable = psPVRContext->psPVRDrawable; + + if (bMakeUnCurrent && !psPVRContext->bMakeUncurrentNoFlush) { + uint32_t uiFlags = PVRDRI_FLUSH_ALL_SURFACES; + + (void) PVRDRIFlushBuffers(psPVRContext, psPVRDrawable, uiFlags); + } else if (psPVRDrawable) { + PVRDRIFlushBuffersGC(psPVRContext, psPVRDrawable); + } + + if (bMakeUnCurrent) + PVRDRIMakeUnCurrentGC(psPVRContext->eAPI, psPVRScreen->psImpl); + + if (psPVRDrawable != NULL) { + if (bMarkSurfaceInvalid) { + PVRDRIEGLMarkRendersurfaceInvalid(psPVRContext->eAPI, + psPVRScreen->psImpl, + psPVRContext->psImpl); + } + + psPVRContext->psPVRDrawable = NULL; + psPVRDrawable->psPVRContext = NULL; + } +} + +static inline void +PVRDrawableUnbindContext(struct DRISUPDrawable *psPVRDrawable) +{ + struct DRISUPContext *psPVRContext = psPVRDrawable->psPVRContext; + + if (psPVRContext) + PVRContextUnbind(psPVRContext, false, true); +} + +/*************************************************************************//*! + Mesa driver API functions + *//**************************************************************************/ +struct DRISUPScreen * +DRIMODCreateScreen(struct __DRIscreenRec *psDRIScreen, int iFD, + bool bUseInvalidate, void *pvLoaderPrivate, + const struct __DRIconfigRec ***pppsConfigs, + int *piMaxGLES1Version, int *piMaxGLES2Version) +{ + struct DRISUPScreen *psPVRScreen; + const struct __DRIconfigRec **ppsConfigs; + + psPVRScreen = calloc(1, sizeof(*psPVRScreen)); + if (psPVRScreen == NULL) { + __driUtilMessage("%s: Couldn't allocate PVRDRIScreen", __func__); + return NULL; + } + + psPVRScreen->psDRIScreen = psDRIScreen; + psPVRScreen->iFD = iFD; + psPVRScreen->bUseInvalidate = bUseInvalidate; + psPVRScreen->pvLoaderPrivate = pvLoaderPrivate; + + if (!PVRDRIGetMesaFormats(psPVRScreen)) + goto ErrorScreenFree; + + psPVRScreen->psImpl = PVRDRICreateScreenImpl(iFD); + if (psPVRScreen->psImpl == NULL) + goto ErrorScreenFree; + + if (!PVRDRIGetSupportedFormats(psPVRScreen)) + goto ErrorScreenImplDeinit; + + ppsConfigs = PVRDRICreateConfigs(psPVRScreen); + if (ppsConfigs == NULL) { + __driUtilMessage("%s: No framebuffer configs", __func__); + goto ErrorDestroyFormatInfo; + } + + *piMaxGLES1Version = PVRDRIAPIVersion(PVRDRI_API_GLES1, + PVRDRI_API_SUB_NONE, + psPVRScreen->psImpl); + + *piMaxGLES2Version = PVRDRIAPIVersion(PVRDRI_API_GLES2, + PVRDRI_API_SUB_NONE, + psPVRScreen->psImpl); + + *pppsConfigs = ppsConfigs; + + return psPVRScreen; + +ErrorDestroyFormatInfo: + PVRDRIDestroyFormatInfo(psPVRScreen); + +ErrorScreenImplDeinit: + PVRDRIDestroyScreenImpl(psPVRScreen->psImpl); + +ErrorScreenFree: + PVRDRIFreeMesaFormats(psPVRScreen); + + free(psPVRScreen); + + return NULL; +} + +void +DRIMODDestroyScreen(struct DRISUPScreen *psPVRScreen) +{ + PVRDRIDestroyFormatInfo(psPVRScreen); + PVRDRIDestroyScreenImpl(psPVRScreen->psImpl); + PVRDRIFreeMesaFormats(psPVRScreen); + free(psPVRScreen); +} + +unsigned int +DRIMODCreateContext(PVRDRIAPIType eAPI, PVRDRIConfig *psPVRDRIConfig, + struct PVRDRIContextConfig *psCtxConfig, + struct __DRIcontextRec *psDRIContext, + struct DRISUPContext *psPVRSharedContext, + struct DRISUPScreen *psPVRScreen, + struct DRISUPContext **ppsPVRContext) +{ + struct DRISUPContext *psPVRContext; + PVRDRIContextImpl *psSharedImpl; + bool bNotifyReset; + unsigned int uError; + + psSharedImpl = psPVRSharedContext ? psPVRSharedContext->psImpl : NULL, + psPVRContext = calloc(1, sizeof(*psPVRContext)); + if (psPVRContext == NULL) { + __driUtilMessage("%s: Couldn't allocate PVRDRIContext", __func__); + return PVRDRI_CONTEXT_ERROR_NO_MEMORY; + } + + psPVRContext->psDRIContext = psDRIContext; + psPVRContext->psPVRScreen = psPVRScreen; + + switch (eAPI) { + case PVRDRI_API_GLES1: + case PVRDRI_API_GLES2: + break; + default: + __driUtilMessage("%s: Unsupported API: %d", __func__, (int) eAPI); + uError = PVRDRI_CONTEXT_ERROR_BAD_API; + goto ErrorContextFree; + } + psPVRContext->eAPI = eAPI; + + switch (psCtxConfig->iResetStrategy) { + case PVRDRI_CONTEXT_RESET_NO_NOTIFICATION: + bNotifyReset = false; + break; + case PVRDRI_CONTEXT_RESET_LOSE_CONTEXT: + bNotifyReset = true; + break; + default: + __driUtilMessage("%s: Unsupported reset strategy: %d", + __func__, psCtxConfig->iResetStrategy); + uError = PVRDRI_CONTEXT_ERROR_UNKNOWN_ATTRIBUTE; + goto ErrorContextFree; + } + + switch (psCtxConfig->iReleaseBehavior) { + case PVRDRI_CONTEXT_RELEASE_BEHAVIOR_NONE: + psPVRContext->bMakeUncurrentNoFlush = true; + break; + case PVRDRI_CONTEXT_RELEASE_BEHAVIOR_FLUSH: + psPVRContext->bMakeUncurrentNoFlush = false; + break; + default: + __driUtilMessage("%s: Unsupported release behaviour: %d", + __func__, psCtxConfig->iReleaseBehavior); + uError = PVRDRI_CONTEXT_ERROR_UNKNOWN_ATTRIBUTE; + goto ErrorContextFree; + } + + uError = PVRDRICreateContextV1(psPVRScreen->psImpl, psSharedImpl, + psPVRDRIConfig, psPVRContext->eAPI, + PVRDRI_API_SUB_NONE, + psCtxConfig->uMajorVersion, + psCtxConfig->uMinorVersion, + psCtxConfig->uFlags, bNotifyReset, + psCtxConfig->uPriority, + &psPVRContext->psImpl); + if (uError != PVRDRI_CONTEXT_ERROR_SUCCESS) + goto ErrorContextFree; + + *ppsPVRContext = psPVRContext; + + return uError; + +ErrorContextFree: + free(psPVRContext); + + return uError; +} + +void +DRIMODDestroyContext(struct DRISUPContext *psPVRContext) +{ + struct DRISUPScreen *psPVRScreen = psPVRContext->psPVRScreen; + + PVRContextUnbind(psPVRContext, false, false); + PVRDRIDestroyContextImpl(psPVRContext->psImpl, psPVRContext->eAPI, + psPVRScreen->psImpl); + free(psPVRContext); +} + +static IMG_PIXFMT +PVRDRIGetPixelFormat(PVRDRIConfig *psPVRDRIConfig) +{ + unsigned int uRGBBits; + unsigned int uRedMask, uGreenMask, uBlueMask, uAlphaMask; + unsigned int uSRGBCapable; + bool bRes; + + bRes = MODSUPConfigQuery(psPVRDRIConfig, + PVRDRI_CONFIG_ATTRIB_RGB_BITS, &uRGBBits); + + bRes &= MODSUPConfigQuery(psPVRDRIConfig, + PVRDRI_CONFIG_ATTRIB_RED_MASK, &uRedMask); + + bRes &= MODSUPConfigQuery(psPVRDRIConfig, + PVRDRI_CONFIG_ATTRIB_GREEN_MASK, + &uGreenMask); + + bRes &= MODSUPConfigQuery(psPVRDRIConfig, + PVRDRI_CONFIG_ATTRIB_BLUE_MASK, &uBlueMask); + + bRes &= MODSUPConfigQuery(psPVRDRIConfig, + PVRDRI_CONFIG_ATTRIB_ALPHA_MASK, + &uAlphaMask); + + bRes &= MODSUPConfigQuery(psPVRDRIConfig, + PVRDRI_CONFIG_ATTRIB_SRGB_CAPABLE, + &uSRGBCapable); + + if (!bRes) { + __driUtilMessage("%s: Config query failed", __func__); + return IMG_PIXFMT_UNKNOWN; + } + + switch (uRGBBits) { + case 32: + case 24: + if (uRedMask == 0x00FF0000 && + uGreenMask == 0x0000FF00 && uBlueMask == 0x000000FF) { + if (uAlphaMask == 0xFF000000) { + if (uSRGBCapable) + return IMG_PIXFMT_B8G8R8A8_UNORM_SRGB; + else + return IMG_PIXFMT_B8G8R8A8_UNORM; + } else if (uAlphaMask == 0) { + return IMG_PIXFMT_B8G8R8X8_UNORM; + } + } + + if (uRedMask == 0x000000FF && + uGreenMask == 0x0000FF00 && uBlueMask == 0x00FF0000) { + if (uAlphaMask == 0xFF000000) { + if (uSRGBCapable) + return IMG_PIXFMT_R8G8B8A8_UNORM_SRGB; + else + return IMG_PIXFMT_R8G8B8A8_UNORM; + } else if (uAlphaMask == 0) { + return IMG_PIXFMT_R8G8B8X8_UNORM; + } + } + + __driUtilMessage("%s: Unsupported format", __func__); + + return IMG_PIXFMT_UNKNOWN; + case 16: + if (uRedMask == 0xF800 && + uGreenMask == 0x07E0 && uBlueMask == 0x001F) { + return IMG_PIXFMT_B5G6R5_UNORM; + } + + __driUtilMessage("%s: Unsupported format", __func__); + + return IMG_PIXFMT_UNKNOWN; + default: + __driUtilMessage("%s: Unsupported format", __func__); + + return IMG_PIXFMT_UNKNOWN; + } +} + +struct DRISUPDrawable * +DRIMODCreateDrawable(struct __DRIdrawableRec *psDRIDrawable, + struct DRISUPScreen *psPVRScreen, void *pvLoaderPrivate, + PVRDRIConfig *psPVRDRIConfig) +{ + struct DRISUPDrawable *psPVRDrawable; + IMG_PIXFMT ePixelFormat; + unsigned int uDoubleBufferMode; + + psPVRDrawable = calloc(1, sizeof(*psPVRDrawable)); + if (!psPVRDrawable) { + __driUtilMessage("%s: Couldn't allocate PVR drawable", __func__); + goto ErrorDrawableFree; + } + + psPVRDrawable->psDRIDrawable = psDRIDrawable; + psPVRDrawable->psPVRScreen = psPVRScreen; + psPVRDrawable->pvLoaderPrivate = pvLoaderPrivate; + psPVRDrawable->psConfig = psPVRDRIConfig; + + ePixelFormat = PVRDRIGetPixelFormat(psPVRDRIConfig); + if (ePixelFormat == IMG_PIXFMT_UNKNOWN) { + __driUtilMessage("%s: Couldn't determine IMG pixel format", __func__); + goto ErrorDrawableFree; + } + + psPVRDrawable->psFormat = + PVRDRIIMGPixelFormatToImageFormat(psPVRScreen, ePixelFormat); + if (!psPVRDrawable->psFormat) { + __driUtilMessage("%s: Unsupported IMG pixel format (format = %u)", + __func__, ePixelFormat); + return false; + } + + if (!MODSUPConfigQuery(psPVRDRIConfig, + PVRDRI_CONFIG_ATTRIB_DOUBLE_BUFFER_MODE, + &uDoubleBufferMode)) { + __driUtilMessage("%s: Couldn't query double buffer mode", __func__); + goto ErrorDrawableFree; + } + psPVRDrawable->bDoubleBufferMode = (uDoubleBufferMode != 0); + + /* + * We aren't told the type of the drawable so treat double buffered + * drawables as windows and single buffered drawables as pixmaps (although + * these could actually be pbuffers). + */ + if (psPVRDrawable->bDoubleBufferMode) + psPVRDrawable->eType = PVRDRI_DRAWABLE_WINDOW; + else + psPVRDrawable->eType = PVRDRI_DRAWABLE_PIXMAP; + + psPVRDrawable->psImpl = + PVRDRICreateDrawableWithConfig((PVRDRIDrawable *) psPVRDrawable, + psPVRDRIConfig); + if (!psPVRDrawable->psImpl) { + __driUtilMessage("%s: Couldn't create PVR drawable", __func__); + goto ErrorDrawableFree; + } + + return psPVRDrawable; + +ErrorDrawableFree: + PVRDRIDestroyDrawableImpl(psPVRDrawable->psImpl); + free(psPVRDrawable); + + return NULL; +} + +void +DRIMODDestroyDrawable(struct DRISUPDrawable *psPVRDrawable) +{ + PVRDrawableUnbindContext(psPVRDrawable); + PVRDRIDrawableDeinit(psPVRDrawable); + PVREGLDrawableDestroyConfig(psPVRDrawable->psImpl); + PVRDRIDestroyDrawableImpl(psPVRDrawable->psImpl); + free(psPVRDrawable); +} + +bool +DRIMODMakeCurrent(struct DRISUPContext *psPVRContext, + struct DRISUPDrawable *psPVRWrite, + struct DRISUPDrawable *psPVRRead) +{ + struct DRISUPDrawable *psPVRDrawableOld = psPVRContext->psPVRDrawable; + + if (psPVRWrite != NULL) { + if (!PVRDRIDrawableInit(psPVRWrite)) { + __driUtilMessage("%s: Couldn't initialise write drawable", __func__); + return false; + } + } + + if (psPVRRead != NULL) { + if (!PVRDRIDrawableInit(psPVRRead)) { + __driUtilMessage("%s: Couldn't initialise read drawable", __func__); + return false; + } + } + + if (!PVRDRIMakeCurrentGC(psPVRContext->eAPI, + psPVRContext->psPVRScreen->psImpl, + psPVRContext->psImpl, + psPVRWrite == NULL ? NULL : psPVRWrite->psImpl, + psPVRRead == NULL ? NULL : psPVRRead->psImpl)) + return false; + + if (psPVRDrawableOld != NULL) + psPVRDrawableOld->psPVRContext = NULL; + + if (psPVRWrite != NULL) + psPVRWrite->psPVRContext = psPVRContext; + + psPVRContext->psPVRDrawable = psPVRWrite; + + DRIMODThreadSetCurrentScreen(psPVRContext->psPVRScreen); + + return true; +} + +bool +DRIMODUnbindContext(struct DRISUPContext *psPVRContext) +{ + PVRContextUnbind(psPVRContext, true, false); + DRIMODThreadSetCurrentScreen(NULL); + + return true; +} + +struct DRISUPBuffer * +DRIMODAllocateBuffer(struct DRISUPScreen *psPVRScreen, + unsigned int uAttachment, unsigned int uFormat, + int iWidth, int iHeight, unsigned int *puName, + unsigned int *puPitch, unsigned int *puCPP, + unsigned int *puFlags) +{ + PVRDRIBufferImpl *psPVRBufferImpl; + unsigned int uBPP; + unsigned int uPitch; + + (void) uAttachment; + + /* GEM names are only supported on primary nodes */ + if (drmGetNodeTypeFromFd(psPVRScreen->iFD) != 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 */ + uBPP = uFormat; + break; + case 24: + uBPP = 32; + break; + default: + __driUtilMessage("%s: Unsupported format '%u'", __func__, uFormat); + return NULL; + } + + psPVRBufferImpl = PVRDRIBufferCreate(psPVRScreen->psImpl, iWidth, iHeight, + uBPP, PVDRI_BUFFER_USE_SHARE, &uPitch); + if (!psPVRBufferImpl) { + __driUtilMessage("%s: Failed to create backing buffer", __func__); + return NULL; + } + + *puName = PVRDRIBufferGetName(psPVRBufferImpl); + *puPitch = uPitch; + *puCPP = uBPP / 8; + *puFlags = 0; + + return (struct DRISUPBuffer *) psPVRBufferImpl; +} + +void +DRIMODReleaseBuffer(struct DRISUPScreen *psPVRScreen, + struct DRISUPBuffer *psPVRBuffer) +{ + PVRDRIBufferImpl *psPVRBufferImpl = (PVRDRIBufferImpl *) psPVRBuffer; + + (void) psPVRScreen; + + PVRDRIBufferDestroy(psPVRBufferImpl); +} + +/*************************************************************************//*! + Global functions + *//**************************************************************************/ + +void +DRIMODThreadSetCurrentScreen(struct DRISUPScreen *psPVRScreen) +{ + gpsPVRScreen = psPVRScreen; +} + +struct DRISUPScreen * +DRIMODThreadGetCurrentScreen(void) +{ + return gpsPVRScreen; +} diff --git a/src/mesa/drivers/dri/pvr/pvrdri_mod.h b/src/mesa/drivers/dri/pvr/pvrdri_mod.h new file mode 100644 index 00000000000..e46b7b083e1 --- /dev/null +++ b/src/mesa/drivers/dri/pvr/pvrdri_mod.h @@ -0,0 +1,450 @@ +/* + * Copyright (c) Imagination Technologies Ltd. + * + * The contents of this file are subject to the MIT license as set out below. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#if !defined(__PVRDRI_MOD_H__) +#define __PVRDRI_MOD_H__ + +#include +#include + +#include "pvrdri.h" + +/* This should match EGL_MAX_PLANES */ +#define DRI_PLANES_MAX 3 + +#define DRI2_BUFFERS_MAX 3 + +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 int *puExternalOnly; +}; + +/** Our PVR related screen data */ +struct DRISUPScreen { + /* DRI screen structure pointer */ + struct __DRIscreenRec *psDRIScreen; + + /* Use invalidate events */ + bool bUseInvalidate; + + int iFD; + + void *pvLoaderPrivate; + + 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; + + /* Supported Mesa formats */ + unsigned int *puMesaFormats; + unsigned int uNumMesaFormats; +}; + +/** Our PVR related context data */ +struct DRISUPContext { + /* Pointer to DRI context */ + struct __DRIcontextRec *psDRIContext; + + /* Pointer to PVRDRIScreen structure */ + struct DRISUPScreen *psPVRScreen; + + /* Pointer to currently bound drawable */ + struct DRISUPDrawable *psPVRDrawable; + + /* API */ + PVRDRIAPIType eAPI; + + PVRDRIContextImpl *psImpl; + + /* Don't flush when the context is made uncurrent */ + bool bMakeUncurrentNoFlush; +}; + +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 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; + + /* + * True if the format represents an sRGB colour space and false if it + * represents a linear one. + */ + bool bIsSRGB; + + /* The number of sub-images/planes that make up the overall image */ + unsigned int uiNumPlanes; + + /* 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; + +/** Our PVR related drawable data */ +struct DRISUPDrawable { + /** Ptr to PVR screen, that spawned this drawable */ + struct DRISUPScreen *psPVRScreen; + + /** DRI drawable data */ + struct __DRIdrawableRec *psDRIDrawable; + + void *pvLoaderPrivate; + + bool bDoubleBufferMode; + PVRDRIDrawableType eType; + + PVRDRIConfig *psConfig; + + /** Are surface/buffers created? */ + bool bInitialised; + + /* Width and height */ + uint32_t uWidth; + uint32_t uHeight; + + /** Buffer stride */ + unsigned int uStride; + + /* Number of bytes per pixel */ + unsigned int uBytesPerPixel; + + /* Context bound to this drawable */ + struct DRISUPContext *psPVRContext; + + /* Format of this drawable */ + const PVRDRIImageFormat *psFormat; + + /* 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; +}; + +/*************************************************************************//*! + pvrdri_mod.c + *//**************************************************************************/ + +struct DRISUPScreen *DRIMODThreadGetCurrentScreen(void); +void DRIMODThreadSetCurrentScreen(struct DRISUPScreen *psPVRScreen); + +void PVRDRIFlushBuffersForSwap(struct DRISUPContext *psPVRContext, + struct DRISUPDrawable *psPVRDrawable); + +/*************************************************************************//*! + pvrutil_mod.c + *//**************************************************************************/ + +const struct __DRIconfigRec **PVRDRICreateConfigs(const struct DRISUPScreen + *psPVRScreen); +const PVRDRIImageFormat *PVRDRIFourCCToImageFormat(struct DRISUPScreen + *psPVRScreen, + int iDRIFourCC); +const PVRDRIImageFormat *PVRDRIIMGPixelFormatToImageFormat(struct DRISUPScreen *psPVRScreen, + IMG_PIXFMT eIMGPixelFormat); +IMG_YUV_COLORSPACE PVRDRIToIMGColourSpace(const PVRDRIImageFormat *psFormat, + unsigned int uDRIColourSpace, + unsigned int uDRISampleRange); +IMG_YUV_CHROMA_INTERP PVRDRIChromaSittingToIMGInterp(const PVRDRIImageFormat *psFormat, + unsigned int uChromaSitting); +bool PVRDRIGetSupportedFormats(struct DRISUPScreen *psPVRScreen); +void PVRDRIDestroyFormatInfo(struct DRISUPScreen *psPVRScreen); +bool PVRDRIValidateImageModifier(struct DRISUPScreen *psPVRScreen, + const int iFourCC, const uint64_t uiModifier); +bool PVRDRIGetMesaFormats(struct DRISUPScreen *psPVRScreen); +void PVRDRIFreeMesaFormats(struct DRISUPScreen *psPVRScreen); + +/*************************************************************************//*! + pvrdrawable_mod.c + *//**************************************************************************/ + +bool PVRDRIDrawableInit(struct DRISUPDrawable *psPVRDrawable); +void PVRDRIDrawableDeinit(struct DRISUPDrawable *psPVRDrawable); +bool PVRDRIDrawableQuery(const PVRDRIDrawable *psPVRDRIDrawable, + PVRDRIBufferAttrib eBufferAttrib, + uint32_t *uiValueOut); +bool PVRDRIDrawableGetParametersV2(PVRDRIDrawable *psPVRDRIDrawable, + uint32_t uiFlags, + PVRDRIBufferImpl **ppsDstBuffer, + PVRDRIBufferImpl **ppsAccumBuffer); + +/*************************************************************************//*! +pvrimage_mod.c + *//**************************************************************************/ + +__DRIimage *PVRDRIScreenGetDRIImage(void *hEGLImage); +void PVRDRIRefImage(__DRIimage *psImage); +void PVRDRIUnrefImage(__DRIimage *psImage); +PVRDRIImageType PVRDRIImageGetSharedType(__DRIimage *psImage); +PVRDRIBufferImpl *PVRDRIImageGetSharedBuffer(__DRIimage *psImage); +IMGEGLImage *PVRDRIImageGetSharedEGLImage(__DRIimage *psImage); +IMGEGLImage *PVRDRIImageGetEGLImage(__DRIimage *psImage); + +/*************************************************************************//*! + Functions to implement PVRDRISupportInterfaceV2, for backwards compatibility + With DRI Support libraries that only provide PVRDRISupportInterface. + *//**************************************************************************/ + +struct DRISUPScreen *DRIMODCreateScreen(struct __DRIscreenRec *psDRIScreen, + int iFD, bool bUseInvalidate, + void *pvLoaderPrivate, + const struct __DRIconfigRec ***pppsConfigs, + int *piMaxGLES1Version, + int *piMaxGLES2Version); +void DRIMODDestroyScreen(struct DRISUPScreen *psDRISUPScreen); + +unsigned int DRIMODCreateContext(PVRDRIAPIType eAPI, + PVRDRIConfig *psPVRDRIConfig, + struct PVRDRIContextConfig *psCtxConfig, + struct __DRIcontextRec *psDRIContext, + struct DRISUPContext *psDRISUPSharedContext, + struct DRISUPScreen *psDRISUPScreen, + struct DRISUPContext **ppsDRISUPContext); +void DRIMODDestroyContext(struct DRISUPContext *psDRISUPContext); + +struct DRISUPDrawable *DRIMODCreateDrawable(struct __DRIdrawableRec *psDRIDrawable, + struct DRISUPScreen *psDRISUPScreen, + void *pvLoaderPrivate, + PVRDRIConfig *psPVRDRIConfig); +void DRIMODDestroyDrawable(struct DRISUPDrawable *psDRISUPDrawable); + +bool DRIMODMakeCurrent(struct DRISUPContext *psDRISUPContext, + struct DRISUPDrawable *psDRISUPWrite, + struct DRISUPDrawable *psDRISUPRead); +bool DRIMODUnbindContext(struct DRISUPContext *psDRISUPContext); + +struct DRISUPBuffer *DRIMODAllocateBuffer(struct DRISUPScreen *psDRISUPScreen, + unsigned int uAttchment, + unsigned int uFormat, + int iWidth, int iHeight, + unsigned int *puName, + unsigned int *puPitch, + unsigned int *puCPP, + unsigned int *puFlags); +void DRIMODReleaseBuffer(struct DRISUPScreen *psDRISUPScreen, + struct DRISUPBuffer *psDRISUPBuffer); +void DRIMODSetTexBuffer2(struct DRISUPContext *psDRISUPContext, int iTarget, + int iFormat, struct DRISUPDrawable *psDRISUPDrawable); +void DRIMODReleaseTexBuffer(struct DRISUPContext *psDRISUPContext, + int iTarget, + struct DRISUPDrawable *psDRISUPDrawable); + +void DRIMODFlush(struct DRISUPDrawable *psDRISUPDrawable); +void DRIMODInvalidate(struct DRISUPDrawable *psDRISUPDrawable); +void DRIMODFlushWithFlags(struct DRISUPContext *psDRISUPContext, + struct DRISUPDrawable *psDRISUPDrawable, + unsigned int uFlags, unsigned int uThrottleReason); + +__DRIimage *DRIMODCreateImageFromName(struct DRISUPScreen *psDRISUPScreen, + int iWidth, int iHeight, int iFourCC, + int iName, int iPitch, + void *pvLoaderPrivate); +__DRIimage *DRIMODCreateImageFromRenderbuffer(struct DRISUPContext *psDRISUPContext, + int iRenderBuffer, + void *pvLoaderPrivate); +void DRIMODDestroyImage(__DRIimage *psImage); +__DRIimage *DRIMODCreateImage(struct DRISUPScreen *psDRISUPScreen, + int iWidth, int iHeight, int iFourCC, + unsigned int uUse, void *pvLoaderPrivate); +bool DRIMODQueryImage(__DRIimage *psImage, int iAttrib, int *iValue); +__DRIimage *DRIMODDupImage(__DRIimage *psImage, void *pvLoaderPrivate); +bool DRIMODValidateImageUsage(__DRIimage *psImage, unsigned int uUse); +__DRIimage *DRIMODCreateImageFromNames(struct DRISUPScreen *psDRISUPScreen, + int iWidth, int iHeight, int iFourCC, + int *piNames, int iNumNames, + int *piStrides, int *piOffsets, + void *pvLoaderPrivate); +__DRIimage *DRIMODFromPlanar(__DRIimage *psImage, int iPlane, + void *pvLoaderPrivate); +__DRIimage *DRIMODCreateImageFromTexture(struct DRISUPContext *psDRISUPContext, + int iTarget, unsigned int uTexture, + int iDepth, int iLevel, + unsigned int *puError, + void *pvLoaderPrivate); +__DRIimage *DRIMODCreateImageFromFDs(struct DRISUPScreen *psDRISUPcreen, + int iWidth, int iHeight, int iFourCC, + int *piFDs, int iNumFDs, + int *piStrides, int *piOffsets, + void *pvLoaderPrivate); +__DRIimage *DRIMODCreateImageFromDMABufs(struct DRISUPScreen *psDRISUPScreen, + int iWidth, int iHeight, int iFourCC, + int *piFDs, int iNumFDs, + int *piStrides, int *piOffsets, + unsigned int uColorSpace, + unsigned int uSampleRange, + unsigned int uHorizSiting, + unsigned int uVertSiting, + unsigned int *puError, + void *pvLoaderPrivate); +int DRIMODGetImageCapabilities(struct DRISUPScreen *psDRISUPScreen); +void DRIMODBlitImage(struct DRISUPContext *psDRISUPContext, + __DRIimage *psDst, __DRIimage *psSrc, + int iDstX0, int iDstY0, int iDstWidth, int iDstHeight, + int iSrcX0, int iSrcY0, int iSrcWidth, int iSrcHeight, + int iFlushFlag); +void *DRIMODMapImage(struct DRISUPContext *psDRISUPContext, + __DRIimage *psImage, + int iX0, int iY0, int iWidth, int iHeight, + unsigned int iFlags, int *iStride, void **ppvData); +void DRIMODUnmapImage(struct DRISUPContext *psDRISUPContext, + __DRIimage *psImage, void *pvData); +__DRIimage *DRIMODCreateImageWithModifiers(struct DRISUPScreen *psDRISUPScreen, + int iWidth, int iHeight, + int iFourCC, + const uint64_t *puModifiers, + const unsigned int uModifierCount, + void *pvLoaderPrivate); +__DRIimage *DRIMODCreateImageFromDMABufs2(struct DRISUPScreen *psDRISUPScreen, + int iWidth, int iHeight, + int iFourCC, uint64_t uModifier, + int *piFDs, int iNumFDs, + int *piStrides, int *piOffsets, + unsigned int uColorSpace, + unsigned int uSampleRange, + unsigned int uHorizSiting, + unsigned int uVertSiting, + unsigned int *puError, + void *pvLoaderPrivate); + +bool DRIMODQueryDMABufFormats(struct DRISUPScreen *psDRISUPScreen, int iMax, + int *piFormats, int *piCount); +bool DRIMODQueryDMABufModifiers(struct DRISUPScreen *psDRISUPScreen, + int iFourCC, int iMax, uint64_t *puModifiers, + unsigned int *piExternalOnly, int *piCount); +bool DRIMODQueryDMABufFormatModifierAttribs(struct DRISUPScreen *psDRISUPScreen, + uint32_t uFourCC, + uint64_t uModifier, + int iAttribute, + uint64_t *puValue); + +__DRIimage *DRIMODCreateImageFromRenderBuffer2(struct DRISUPContext *psDRISUPContext, + int iRenderBuffer, + void *pvLoaderPrivate, + unsigned int *puError); +__DRIimage *DRIMODCreateImageFromBuffer(struct DRISUPContext *psDRISUPContext, + int iTarget, void *pvBuffer, + unsigned int *puError, + void *pvLoaderPrivate); + +int DRIMODQueryRendererInteger(struct DRISUPScreen *psDRISUPScreen, + int iAttribute, unsigned int *puValue); +int DRIMODQueryRendererString(struct DRISUPScreen *psDRISUPScreen, + int iAttribute, const char **ppszValue); + +void *DRIMODCreateFence(struct DRISUPContext *psDRISUPContext); +void DRIMODDestroyFence(struct DRISUPScreen *psDRISUPScreen, void *pvFence); +bool DRIMODClientWaitSync(struct DRISUPContext *psDRISUPContext, + void *pvFence, unsigned int uFlags, + uint64_t uTimeout); +void DRIMODServerWaitSync(struct DRISUPContext *psDRISUPContext, + void *pvFence, unsigned int uFlags); +unsigned int DRIMODGetFenceCapabilities(struct DRISUPScreen *psDRISUPScreen); +void *DRIMODCreateFenceFD(struct DRISUPContext *psDRISUPContext, int iFD); +int DRIMODGetFenceFD(struct DRISUPScreen *psDRISUPScreen, void *pvFence); + +unsigned int DRIMODGetNumAPIProcs(struct DRISUPScreen *psDRISUPScreen, + PVRDRIAPIType eAPI); +const char *DRIMODGetAPIProcName(struct DRISUPScreen *psDRISUPScreen, + PVRDRIAPIType eAPI, unsigned int uIndex); +void *DRIMODGetAPIProcAddress(struct DRISUPScreen *psDRISUPScreen, + PVRDRIAPIType eAPI, unsigned int uIndex); + +void DRIMODSetDamageRegion(struct DRISUPDrawable *psDRISUPDrawable, + unsigned int uNRects, int *piRects); + +#endif /* defined(__PVRDRI_MOD_H__) */ diff --git a/src/mesa/drivers/dri/pvr/pvrdri_support.h b/src/mesa/drivers/dri/pvr/pvrdri_support.h new file mode 100644 index 00000000000..ced4f80ccc6 --- /dev/null +++ b/src/mesa/drivers/dri/pvr/pvrdri_support.h @@ -0,0 +1,439 @@ +/* + * Copyright (c) Imagination Technologies Ltd. + * + * The contents of this file are subject to the MIT license as set out below. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#if !defined(__PVRDRI_SUPPORT_H__) +#define __PVRDRI_SUPPORT_H__ + +#include +#include + +#include "dri_support.h" + +struct DRISUPScreen *DRISUPCreateScreen(struct __DRIscreenRec *psDRIScreen, + int iFD, bool bUseInvalidate, + void *pvLoaderPrivate, + const struct __DRIconfigRec ***pppsConfigs, + int *piMaxGLES1Version, + int *piMaxGLES2Version); +void DRISUPDestroyScreen(struct DRISUPScreen *psDRISUPScreen); + +unsigned int DRISUPCreateContext(PVRDRIAPIType eAPI, + PVRDRIConfig *psPVRDRIConfig, + struct PVRDRIContextConfig *psCtxConfig, + struct __DRIcontextRec *psDRIContext, + struct DRISUPContext *psDRISUPSharedContext, + struct DRISUPScreen *psDRISUPScreen, + struct DRISUPContext **ppsDRISUPContext); +void DRISUPDestroyContext(struct DRISUPContext *psDRISUPContext); + +struct DRISUPDrawable *DRISUPCreateDrawable(struct __DRIdrawableRec *psDRIDrawable, + struct DRISUPScreen *psDRISUPScreen, + void *pvLoaderPrivate, + PVRDRIConfig *psPVRDRIConfig); +void DRISUPDestroyDrawable(struct DRISUPDrawable *psDRISUPDrawable); + +bool DRISUPMakeCurrent(struct DRISUPContext *psDRISUPContext, + struct DRISUPDrawable *psDRISUPWrite, + struct DRISUPDrawable *psDRISUPRead); +bool DRISUPUnbindContext(struct DRISUPContext *psDRISUPContext); + +struct DRISUPBuffer *DRISUPAllocateBuffer(struct DRISUPScreen *psDRISUPScreen, + unsigned int uAttchment, + unsigned int uFormat, + int iWidth, int iHeight, + unsigned int *puName, + unsigned int *puPitch, + unsigned int *puCPP, + unsigned int *puFlags); +void DRISUPReleaseBuffer(struct DRISUPScreen *psDRISUPScreen, + struct DRISUPBuffer *psDRISUPBuffer); +void DRISUPSetTexBuffer2(struct DRISUPContext *psDRISUPContext, + int iTarget, int iFormat, + struct DRISUPDrawable *psDRISUPDrawable); +void DRISUPReleaseTexBuffer(struct DRISUPContext *psDRISUPContext, + int iTarget, + struct DRISUPDrawable *psDRISUPDrawable); + +void DRISUPFlush(struct DRISUPDrawable *psDRISUPDrawable); +void DRISUPInvalidate(struct DRISUPDrawable *psDRISUPDrawable); +void DRISUPFlushWithFlags(struct DRISUPContext *psDRISUPContext, + struct DRISUPDrawable *psDRISUPDrawable, + unsigned int uFlags, unsigned int uThrottleReason); + +__DRIimage *DRISUPCreateImageFromName(struct DRISUPScreen *psDRISUPScreen, + int iWidth, int iHeight, int iFourCC, + int iName, int iPitch, + void *pvLoaderPrivate); +__DRIimage *DRISUPCreateImageFromRenderbuffer(struct DRISUPContext *psDRISUPContext, + int iRenderBuffer, + void *pvLoaderPrivate); +void DRISUPDestroyImage(__DRIimage *psImage); +__DRIimage *DRISUPCreateImage(struct DRISUPScreen *psDRISUPScreen, + int iWidth, int iHeight, int iFourCC, + unsigned int uUse, void *pvLoaderPrivate); +bool DRISUPQueryImage(__DRIimage *psImage, int iAttrib, int *piValue); +__DRIimage *DRISUPDupImage(__DRIimage *psImage, void *pvLoaderPrivate); +bool DRISUPValidateImageUsage(__DRIimage *psImage, unsigned int uUse); +__DRIimage *DRISUPCreateImageFromNames(struct DRISUPScreen *psDRISUPScreen, + int iWidth, int iHeight, int iFourCC, + int *piNames, int iNumNames, + int *piStrides, int *piOffsets, + void *pvLoaderPrivate); +__DRIimage *DRISUPFromPlanar(__DRIimage *psImage, int iPlane, + void *pvLoaderPrivate); +__DRIimage *DRISUPCreateImageFromTexture(struct DRISUPContext *psDRISUPContext, + int iTarget, unsigned int uTexture, + int iDepth, int iLevel, + unsigned int *puError, + void *pvLoaderPrivate); +__DRIimage *DRISUPCreateImageFromFDs(struct DRISUPScreen *psDRISUPcreen, + int iWidth, int iHeight, int iFourCC, + int *piFDs, int iNumFDs, + int *piStrides, int *piOffsets, + void *pvLoaderPrivate); +__DRIimage *DRISUPCreateImageFromDmaBufs(struct DRISUPScreen *psDRISUPScreen, + int iWidth, int iHeight, int iFourCC, + int *piFDs, int iNumFDs, + int *piStrides, int *piOffsets, + unsigned int uColorSpace, + unsigned int uSampleRange, + unsigned int uHorizSiting, + unsigned int uVertSiting, + unsigned int *puError, + void *pvLoaderPrivate); +int DRISUPGetImageCapabilities(struct DRISUPScreen *psDRISUPScreen); +void DRISUPBlitImage(struct DRISUPContext *psDRISUPContext, + __DRIimage *psDst, __DRIimage *psSrc, + int iDstX0, int iDstY0, int iDstWidth, int iDstHeight, + int iSrcX0, int iSrcY0, int iSrcWidth, int iSrcHeight, + int iFlushFlag); +void *DRISUPMapImage(struct DRISUPContext *psDRISUPContext, + __DRIimage *psImage, + int iX0, int iY0, int iWidth, int iHeight, + unsigned int uFlags, int *piStride, void **ppvData); +void DRISUPUnmapImage(struct DRISUPContext *psDRISUPContext, + __DRIimage *psImage, void *pvData); +__DRIimage *DRISUPCreateImageWithModifiers(struct DRISUPScreen *psDRISUPScreen, + int iWidth, int iHeight, int iFourCC, + const uint64_t *puModifiers, + const unsigned int uModifierCount, + void *pvLoaderPrivate); +__DRIimage *DRISUPCreateImageFromDMABufs2(struct DRISUPScreen *psDRISUPScreen, + int iWidth, int iHeight, + int iFourCC, uint64_t uModifier, + int *piFDs, int iNumFDs, + int *piStrides, int *piOffsets, + unsigned int uColorSpace, + unsigned int uSampleRange, + unsigned int uHorizSiting, + unsigned int uVertSiting, + unsigned int *puError, + void *pvLoaderPrivate); + +bool DRISUPQueryDMABufFormats(struct DRISUPScreen *psDRISUPScreen, int iMax, + int *piFormats, int *piCount); +bool DRISUPQueryDMABufModifiers(struct DRISUPScreen *psDRISUPScreen, + int iFourCC, int iMax, uint64_t *puModifiers, + unsigned int *piExternalOnly, int *piCount); +bool DRISUPQueryDMABufFormatModifierAttribs(struct DRISUPScreen *psDRISUPScreen, + uint32_t uFourcc, + uint64_t uModifier, + int iAttrib, uint64_t *puValue); + +__DRIimage *DRISUPCreateImageFromRenderBuffer2(struct DRISUPContext *psDRISUPContext, + int iRenderBuffer, + void *pvLoaderPrivate, + unsigned int *puError); + +__DRIimage *DRISUPCreateImageFromBuffer(struct DRISUPContext *psDRISUPContext, + int iTarget, void *pvBuffer, + unsigned int *puError, + void *pvLoaderPrivate); + +int DRISUPQueryRendererInteger(struct DRISUPScreen *psDRISUPScreen, + int iAttribute, unsigned int *puValue); +int DRISUPQueryRendererString(struct DRISUPScreen *psDRISUPScreen, + int iAttribute, const char **ppszValue); + +void *DRISUPCreateFence(struct DRISUPContext *psDRISUPContext); +void DRISUPDestroyFence(struct DRISUPScreen *psDRISUPScreen, void *pvFence); +bool DRISUPClientWaitSync(struct DRISUPContext *psDRISUPContext, + void *pvFence, unsigned int uFlags, + uint64_t uTimeout); +void DRISUPServerWaitSync(struct DRISUPContext *psDRISUPContext, + void *pvFence, unsigned int uFlags); +unsigned int DRISUPGetFenceCapabilities(struct DRISUPScreen *psDRISUPScreen); +void *DRISUPCreateFenceFD(struct DRISUPContext *psDRISUPContext, int iFD); +int DRISUPGetFenceFD(struct DRISUPScreen *psDRISUPScreen, void *pvFence); +void *DRISUPGetFenceFromCLEvent(struct DRISUPScreen *psDRISUPScreen, + intptr_t iCLEvent); +int DRISUPGetAPIVersion(struct DRISUPScreen *psDRISUPScreen, + PVRDRIAPIType eAPI); + +unsigned int DRISUPGetNumAPIProcs(struct DRISUPScreen *psDRISUPScreen, + PVRDRIAPIType eAPI); +const char *DRISUPGetAPIProcName(struct DRISUPScreen *psDRISUPScreen, + PVRDRIAPIType eAPI, unsigned int uIndex); +void *DRISUPGetAPIProcAddress(struct DRISUPScreen *psDRISUPScreen, + PVRDRIAPIType eAPI, unsigned int uIndex); + +void DRISUPSetDamageRegion(struct DRISUPDrawable *psDRISUPDrawable, + unsigned int uNRects, int *piRects); + +/****************************************************************************** + * PVR DRI Support interface, version 1. + * Everything below this point is deprecated. + *****************************************************************************/ + +#include "imgpixfmts.h" +#include "imgyuv.h" + +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); +void PVRDRIEGLMarkRendersurfaceInvalid(PVRDRIAPIType eAPI, + PVRDRIScreenImpl *psScreenImpl, + PVRDRIContextImpl *psContextImpl); + +unsigned int PVRDRICreateContextV1(PVRDRIScreenImpl *psScreenImpl, + PVRDRIContextImpl *psSharedContextImpl, + PVRDRIConfig *psConfig, + PVRDRIAPIType eAPI, + PVRDRIAPISubType eAPISub, + unsigned int uMajorVersion, + unsigned int uMinorVersion, + uint32_t uFlags, bool bNotifyReset, + unsigned int uPriority, + PVRDRIContextImpl **ppsContextImpl); +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 int 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 *PVRDRICreateDrawableWithConfig(PVRDRIDrawable *psPVRDrawable, + PVRDRIConfig *psConfig); +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 int uiNumPlanes, + const int *piName, + const int *piStride, + const int *piOffset, + const unsigned int *puiWidthShift, + const unsigned int *puiHeightShift); +PVRDRIBufferImpl *PVRDRIBufferCreateFromFds(PVRDRIScreenImpl *psScreenImpl, + int iWidth, int iHeight, + unsigned int 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 int 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 *pvFence); + +bool PVRDRIClientWaitSyncImpl(PVRDRIAPIType eAPI, + PVRDRIContextImpl *psContextImpl, + void *pvFence, bool bFlushCommands, + bool bTimeout, uint64_t uiTimeout); +bool PVRDRIServerWaitSyncImpl(PVRDRIAPIType eAPI, + PVRDRIContextImpl *psContextImpl, + void *pvFence); + +/* 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 int uiFlags, int *piStride, void **ppvData); +bool PVRDRIUnmapEGLImage(PVRDRIScreenImpl *psScreenImpl, + PVRDRIContextImpl *psContextImpl, + IMGEGLImage *psImage, PVRDRIBufferImpl *psBuffer, + void *pvData); + +/* Fence functions */ +void *PVRDRICreateFenceImpl(PVRDRIAPIType eAPI, + PVRDRIScreenImpl *psScreenImpl, + PVRDRIContextImpl *psContextImpl); +void *PVRDRICreateFenceFd(PVRDRIAPIType eAPI, PVRDRIScreenImpl *psScreenImpl, + PVRDRIContextImpl *psContextImpl, int iFd); +unsigned int PVRDRIGetFenceCapabilities(PVRDRIScreenImpl *psScreenImpl); +int PVRDRIGetFenceFd(void *pvFence); +void PVRDRIDestroyFenceImpl(void *pvFence); + +bool PVRDRIClientWaitSyncImpl(PVRDRIAPIType eAPI, + PVRDRIContextImpl *psContextImpl, void *pvFence, + bool bFlushCommands, + bool bTimeout, uint64_t uiTimeout); + +bool PVRDRIServerWaitSyncImpl(PVRDRIAPIType eAPI, + PVRDRIContextImpl *psContextImpl, + void *pvFence); + +/* PVR utility support functions */ +bool PVRDRIMesaFormatSupported(unsigned int iFormat); +unsigned int PVRDRIDepthStencilBitArraySize(void); +const uint8_t *PVRDRIDepthBitsArray(void); +const uint8_t *PVRDRIStencilBitsArray(void); +unsigned int PVRDRIMSAABitArraySize(void); +const uint8_t *PVRDRIMSAABitsArray(void); +uint32_t PVRDRIMaxPBufferWidth(void); +uint32_t PVRDRIMaxPBufferHeight(void); + +unsigned int PVRDRIGetNumAPIFuncs(PVRDRIAPIType eAPI); +const char *PVRDRIGetAPIFunc(PVRDRIAPIType eAPI, unsigned int index); + +int PVRDRIQuerySupportedFormats(PVRDRIScreenImpl *psScreenImpl, + unsigned int uNumFormats, + const int *piFormats, + const IMG_PIXFMT *peImgFormats, + bool *pbSupported); +int PVRDRIQueryModifiers(PVRDRIScreenImpl *psScreenImpl, + int iFormat, IMG_PIXFMT eImgFormat, + uint64_t *puModifiers, unsigned int *puExternalOnly); + +#endif /* defined(__PVRDRI_SUPPORT_H__) */ diff --git a/src/mesa/drivers/dri/pvr/pvrext.c b/src/mesa/drivers/dri/pvr/pvrext.c new file mode 100644 index 00000000000..eb94f3f50c5 --- /dev/null +++ b/src/mesa/drivers/dri/pvr/pvrext.c @@ -0,0 +1,698 @@ +/* + * 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) + * + * #endif + * + * However, if it appears in all versions then there's no need for it to + * be protected. + * + * 2) Each driver supported extension should have a define for the maximum + * version supported by the driver. This should be used when initialising + * the corresponding extension structure. The Mesa extension version define + * should *NOT* be used. + * + * 3) If the driver supports a range of versions for a given extension then + * it should protect the extension code based on the Mesa extension version + * define. For example, if the driver has to support versions 7 to 8 of the + * __DRI_IMAGE extension then any fields, in the __DRIimageExtension + * structure, that appear in version 8 but not 7 should be protected as + * follows: + * #if (__DRI_IMAGE_VERSION >= 8) + * .createImageFromDmaBufs = PVRDRICreateImageFromDmaBufs, + * #endif + * + * Obviously any other associated code should also be protected in the same + * way. + */ + +#include "dri_util.h" +#include "utils.h" + +#include "dri_support.h" +#include "pvrdri.h" + +#include "EGL/egl.h" +#include "EGL/eglext.h" +#include "EGL/eglmesaext.h" + +/* Maximum version numbers for each supported extension */ +#define PVR_DRI_TEX_BUFFER_VERSION 3 +#define PVR_DRI2_FLUSH_VERSION 4 +#define PVR_DRI_IMAGE_VERSION 17 +#define PVR_DRI2_ROBUSTNESS_VERSION 1 +#define PVR_DRI2_FENCE_VERSION 2 +#define PVR_DRI2_RENDERER_QUERY_VERSION 1 +#define PVR_DRI2_BUFFER_DAMAGE_VERSION 1 + +static void +PVRDRIExtSetTexBuffer(__DRIcontext *psDRIContext, GLint iTarget, + GLint iFormat, __DRIdrawable *psDRIDrawable) +{ + PVRDRIDrawable *psPVRDrawable = psDRIDrawable->driverPrivate; + PVRDRIContext *psPVRContext = psDRIContext->driverPrivate; + + DRISUPSetTexBuffer2(psPVRContext->psDRISUPContext, + iTarget, iFormat, psPVRDrawable->psDRISUPDrawable); +} + +static void +PVRDRIExtReleaseTexBuffer(__DRIcontext *psDRIContext, GLint iTarget, + __DRIdrawable *psDRIDrawable) +{ + PVRDRIDrawable *psPVRDrawable = psDRIDrawable->driverPrivate; + PVRDRIContext *psPVRContext = psDRIContext->driverPrivate; + + DRISUPReleaseTexBuffer(psPVRContext->psDRISUPContext, + iTarget, psPVRDrawable->psDRISUPDrawable); + +} + +static __DRItexBufferExtension pvrDRITexBufferExtension = { + .base = { + .name = __DRI_TEX_BUFFER, + .version = PVR_DRI_TEX_BUFFER_VERSION, + }, + .setTexBuffer = NULL, + .setTexBuffer2 = PVRDRIExtSetTexBuffer, + .releaseTexBuffer = PVRDRIExtReleaseTexBuffer, +}; + +static void +PVRDRI2Flush(__DRIdrawable *psDRIDrawable) +{ + PVRDRIDrawable *psPVRDrawable = psDRIDrawable->driverPrivate; + + DRISUPFlush(psPVRDrawable->psDRISUPDrawable); +} + +static void +PVRDRI2Invalidate(__DRIdrawable *psDRIDrawable) +{ + PVRDRIDrawable *psPVRDrawable = psDRIDrawable->driverPrivate; + + DRISUPInvalidate(psPVRDrawable->psDRISUPDrawable); +} + +static void +PVRDRI2FlushWithFlags(__DRIcontext *psDRIContext, + __DRIdrawable *psDRIDrawable, + unsigned int uFlags, + enum __DRI2throttleReason eThrottleReason) +{ + PVRDRIContext *psPVRContext = psDRIContext->driverPrivate; + struct DRISUPDrawable *psDRISUPDrawable; + + if ((uFlags & __DRI2_FLUSH_DRAWABLE) != 0) { + PVRDRIDrawable *psPVRDrawable = psDRIDrawable->driverPrivate; + + psDRISUPDrawable = psPVRDrawable->psDRISUPDrawable; + } else { + psDRISUPDrawable = NULL; + } + + DRISUPFlushWithFlags(psPVRContext->psDRISUPContext, psDRISUPDrawable, + uFlags, (unsigned int) eThrottleReason); +} + +static __DRI2flushExtension pvrDRI2FlushExtension = { + .base = { + .name = __DRI2_FLUSH, + .version = PVR_DRI2_FLUSH_VERSION, + }, + .flush = PVRDRI2Flush, + .invalidate = PVRDRI2Invalidate, + .flush_with_flags = PVRDRI2FlushWithFlags, +}; + +static __DRIimage * +PVRDRICreateImageFromName(__DRIscreen *psDRIScreen, int iWidth, int iHeight, + int iFormat, int iName, int iPitch, + void *pvLoaderPrivate) +{ + PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate; + int iFourCC = PVRDRIFormatToFourCC(iFormat); + + return DRISUPCreateImageFromName(psPVRScreen->psDRISUPScreen, + iWidth, iHeight, iFourCC, iName, iPitch, + pvLoaderPrivate); +} + +static __DRIimage * +PVRDRICreateImageFromRenderbuffer(__DRIcontext *psDRIContext, + int iRenderBuffer, void *pvLoaderPrivate) +{ + PVRDRIContext *psPVRContext = psDRIContext->driverPrivate; + + return DRISUPCreateImageFromRenderbuffer(psPVRContext->psDRISUPContext, + iRenderBuffer, pvLoaderPrivate); +} + +static void +PVRDRIDestroyImage(__DRIimage *psImage) +{ + DRISUPDestroyImage(psImage); +} + +static __DRIimage * +PVRDRICreateImage(__DRIscreen *psDRIScreen, int iWidth, int iHeight, + int iFormat, unsigned int uUse, void *pvLoaderPrivate) +{ + PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate; + int iFourCC = PVRDRIFormatToFourCC(iFormat); + + return DRISUPCreateImage(psPVRScreen->psDRISUPScreen, iWidth, iHeight, + iFourCC, uUse, pvLoaderPrivate); +} + +static GLboolean +PVRDRIQueryImage(__DRIimage *psImage, int iAttrib, int *piValue) +{ + int iFourCC; + + switch (iAttrib) { + case PVRDRI_IMAGE_ATTRIB_FORMAT: + if (DRISUPQueryImage(psImage, + PVRDRI_IMAGE_ATTRIB_FOURCC, &iFourCC)) { + *piValue = PVRDRIFourCCToDRIFormat(iFourCC); + return GL_TRUE; + } + return GL_FALSE; + default: + return DRISUPQueryImage(psImage, iAttrib, piValue); + } + +} + +static __DRIimage * +PVRDRIDupImage(__DRIimage *psImage, void *pvLoaderPrivate) +{ + return DRISUPDupImage(psImage, pvLoaderPrivate); +} + +static GLboolean +PVRDRIValidateImageUsage(__DRIimage *psImage, unsigned int uUse) +{ + return DRISUPValidateImageUsage(psImage, uUse); +} + +static __DRIimage * +PVRDRICreateImageFromNames(__DRIscreen *psDRIScreen, int iWidth, int iHeight, + int iFourCC, int *piNames, int iNumNames, + int *piStrides, int *piOffsets, + void *pvLoaderPrivate) +{ + PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate; + + return DRISUPCreateImageFromNames(psPVRScreen->psDRISUPScreen, + iWidth, iHeight, iFourCC, + piNames, iNumNames, + piStrides, piOffsets, pvLoaderPrivate); +} + +static __DRIimage * +PVRDRIFromPlanar(__DRIimage *psImage, int iPlane, void *pvLoaderPrivate) +{ + return DRISUPFromPlanar(psImage, iPlane, pvLoaderPrivate); +} + +static __DRIimage * +PVRDRICreateImageFromTexture(__DRIcontext *psDRIContext, int iTarget, + unsigned int uTexture, int iDepth, int iLevel, + unsigned int *puError, void *pvLoaderPrivate) +{ + PVRDRIContext *psPVRContext = psDRIContext->driverPrivate; + int iEGLTarget; + + switch (iTarget) { + case GL_TEXTURE_2D: + iEGLTarget = PVRDRI_GL_TEXTURE_2D; + break; + case GL_TEXTURE_3D: + iEGLTarget = PVRDRI_GL_TEXTURE_3D; + break; + case GL_TEXTURE_CUBE_MAP: + iEGLTarget = PVRDRI_GL_TEXTURE_CUBE_MAP_POSITIVE_X; + break; + default: + errorMessage("%s: GL Target %d is not supported", + __func__, iTarget); + *puError = __DRI_IMAGE_ERROR_BAD_PARAMETER; + return NULL; + } + + return DRISUPCreateImageFromTexture(psPVRContext->psDRISUPContext, + iEGLTarget, uTexture, iDepth, iLevel, + puError, pvLoaderPrivate); +} + +static __DRIimage * +PVRDRICreateImageFromFds(__DRIscreen *psDRIScreen, int iWidth, int iHeight, + int iFourCC, int *piFDs, int iNumFDs, + int *piStrides, int *piOffsets, + void *pvLoaderPrivate) +{ + PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate; + + return DRISUPCreateImageFromFDs(psPVRScreen->psDRISUPScreen, + iWidth, iHeight, iFourCC, piFDs, iNumFDs, + piStrides, piOffsets, pvLoaderPrivate); +} + +static __DRIimage * +PVRDRICreateImageFromDmaBufs(__DRIscreen *psDRIScreen, + int iWidth, int iHeight, int iFourCC, + int *piFDs, int iNumFDs, + int *piStrides, int *piOffsets, + enum __DRIYUVColorSpace eColorSpace, + enum __DRISampleRange eSampleRange, + enum __DRIChromaSiting eHorizSiting, + enum __DRIChromaSiting eVertSiting, + unsigned int *puError, void *pvLoaderPrivate) +{ + PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate; + + return DRISUPCreateImageFromDmaBufs(psPVRScreen->psDRISUPScreen, + iWidth, iHeight, iFourCC, + piFDs, iNumFDs, piStrides, piOffsets, + (unsigned int) eColorSpace, + (unsigned int) eSampleRange, + (unsigned int) eHorizSiting, + (unsigned int) eVertSiting, + puError, pvLoaderPrivate); +} + +static void +PVRDRIBlitImage(__DRIcontext *psDRIContext, + __DRIimage *psDst, __DRIimage *psSrc, + int iDstX0, int iDstY0, int iDstWidth, int iDstHeight, + int iSrcX0, int iSrcY0, int iSrcWidth, int iSrcHeight, + int iFlushFlag) +{ + PVRDRIContext *psPVRContext = psDRIContext->driverPrivate; + + return DRISUPBlitImage(psPVRContext->psDRISUPContext, + psDst, psSrc, + iDstX0, iDstY0, iDstWidth, iDstHeight, + iSrcX0, iSrcY0, iSrcWidth, iSrcHeight, + iFlushFlag); +} + +static int +PVRDRIGetCapabilities(__DRIscreen *psDRIScreen) +{ + PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate; + + return DRISUPGetImageCapabilities(psPVRScreen->psDRISUPScreen); +} + +static void * +PVRDRIMapImage(__DRIcontext *psDRIContext, __DRIimage *psImage, + int iX0, int iY0, int iWidth, int iHeight, + unsigned int iFlags, int *piStride, void **ppvData) +{ + PVRDRIContext *psPVRContext = psDRIContext->driverPrivate; + + return DRISUPMapImage(psPVRContext->psDRISUPContext, psImage, + iX0, iY0, iWidth, iHeight, iFlags, piStride, + ppvData); +} + +static void +PVRDRIUnmapImage(__DRIcontext *psDRIContext, __DRIimage *psImage, + void *pvData) +{ + PVRDRIContext *psPVRContext = psDRIContext->driverPrivate; + + return DRISUPUnmapImage(psPVRContext->psDRISUPContext, psImage, pvData); +} + +static __DRIimage * +PVRDRICreateImageWithModifiers(__DRIscreen *psDRIScreen, + int iWidth, int iHeight, int iFormat, + const uint64_t *puModifiers, + const unsigned int uModifierCount, + void *pvLoaderPrivate) +{ + PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate; + int iFourCC = PVRDRIFormatToFourCC(iFormat); + + return DRISUPCreateImageWithModifiers(psPVRScreen->psDRISUPScreen, + iWidth, iHeight, iFourCC, + puModifiers, uModifierCount, + pvLoaderPrivate); +} + +static __DRIimage * +PVRDRICreateImageFromDmaBufs2(__DRIscreen *psDRIScreen, + int iWidth, int iHeight, + int iFourCC, uint64_t uModifier, + int *piFDs, int iNumFDs, + int *piStrides, int *piOffsets, + enum __DRIYUVColorSpace eColorSpace, + enum __DRISampleRange eSampleRange, + enum __DRIChromaSiting eHorizSiting, + enum __DRIChromaSiting eVertSiting, + unsigned int *puError, void *pvLoaderPrivate) +{ + PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate; + + return DRISUPCreateImageFromDMABufs2(psPVRScreen->psDRISUPScreen, + iWidth, iHeight, iFourCC, uModifier, + piFDs, iNumFDs, piStrides, piOffsets, + (unsigned int) eColorSpace, + (unsigned int) eSampleRange, + (unsigned int) eHorizSiting, + (unsigned int) eVertSiting, + puError, pvLoaderPrivate); +} + +static GLboolean +PVRDRIQueryDmaBufFormats(__DRIscreen *psDRIScreen, int iMax, + int *piFormats, int *piCount) +{ + PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate; + + return DRISUPQueryDMABufFormats(psPVRScreen->psDRISUPScreen, iMax, + piFormats, piCount); +} + +static GLboolean +PVRDRIQueryDmaBufModifiers(__DRIscreen *psDRIScreen, int iFourCC, int iMax, + uint64_t *puModifiers, + unsigned int *puExternalOnly, int *piCount) +{ + PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate; + + return DRISUPQueryDMABufModifiers(psPVRScreen->psDRISUPScreen, iFourCC, + iMax, + puModifiers, puExternalOnly, piCount); +} + +static GLboolean +PVRDRIQueryDmaBufFormatModifierAttribs(__DRIscreen *psDRIScreen, + uint32_t uFourCC, uint64_t uModifier, + int iAttrib, uint64_t *puValue) +{ + PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate; + struct DRISUPScreen *psDRISUPScreen = psPVRScreen->psDRISUPScreen; + + return DRISUPQueryDMABufFormatModifierAttribs(psDRISUPScreen, uFourCC, + uModifier, iAttrib, puValue); +} + +static __DRIimage * +PVRDRICreateImageFromRenderbuffer2(__DRIcontext *psDRIContext, + int iRenderBuffer, void *pvLoaderPrivate, + unsigned int *puError) +{ + PVRDRIContext *psPVRContext = psDRIContext->driverPrivate; + struct DRISUPContext *psDRISUPContext = psPVRContext->psDRISUPContext; + + return DRISUPCreateImageFromRenderBuffer2(psDRISUPContext, iRenderBuffer, + pvLoaderPrivate, puError); +} + +#if defined(EGL_IMG_cl_image) +static __DRIimage * +PVRDRICreateImageFromBuffer(__DRIcontext *psDRIContext, int iTarget, + void *pvBuffer, unsigned int *puError, + void *pvLoaderPrivate) +{ + PVRDRIContext *psPVRContext = psDRIContext->driverPrivate; + + return DRISUPCreateImageFromBuffer(psPVRContext->psDRISUPContext, iTarget, + pvBuffer, puError, pvLoaderPrivate); +} +#endif + +static __DRIimageExtension pvrDRIImage = { + .base = { + .name = __DRI_IMAGE, + .version = PVR_DRI_IMAGE_VERSION, + }, + .createImageFromName = PVRDRICreateImageFromName, + .createImageFromRenderbuffer = PVRDRICreateImageFromRenderbuffer, + .destroyImage = PVRDRIDestroyImage, + .createImage = PVRDRICreateImage, + .queryImage = PVRDRIQueryImage, + .dupImage = PVRDRIDupImage, + .validateUsage = PVRDRIValidateImageUsage, + .createImageFromNames = PVRDRICreateImageFromNames, + .fromPlanar = PVRDRIFromPlanar, + .createImageFromTexture = PVRDRICreateImageFromTexture, + .createImageFromFds = PVRDRICreateImageFromFds, + .createImageFromDmaBufs = PVRDRICreateImageFromDmaBufs, + .blitImage = PVRDRIBlitImage, + .getCapabilities = PVRDRIGetCapabilities, + .mapImage = PVRDRIMapImage, + .unmapImage = PVRDRIUnmapImage, + .createImageWithModifiers = PVRDRICreateImageWithModifiers, + .createImageFromDmaBufs2 = PVRDRICreateImageFromDmaBufs2, + .queryDmaBufFormats = PVRDRIQueryDmaBufFormats, + .queryDmaBufModifiers = PVRDRIQueryDmaBufModifiers, + .queryDmaBufFormatModifierAttribs = + PVRDRIQueryDmaBufFormatModifierAttribs, + .createImageFromRenderbuffer2 = PVRDRICreateImageFromRenderbuffer2, +#if defined(EGL_IMG_cl_image) + .createImageFromBuffer = PVRDRICreateImageFromBuffer, +#endif +}; + +static __DRIrobustnessExtension pvrDRIRobustness = { + .base = { + .name = __DRI2_ROBUSTNESS, + .version = PVR_DRI2_ROBUSTNESS_VERSION, + } +}; + +static int +PVRDRIQueryRendererInteger(__DRIscreen *psDRIScreen, int iAttribute, + unsigned int *puValue) +{ + PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate; + int res; + + res = DRISUPQueryRendererInteger(psPVRScreen->psDRISUPScreen, + iAttribute, puValue); + if (res == -1) + return driQueryRendererIntegerCommon(psDRIScreen, iAttribute, puValue); + + return res; +} + +static int +PVRDRIQueryRendererString(__DRIscreen *psDRIScreen, int iAttribute, + const char **ppszValue) +{ + PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate; + + return DRISUPQueryRendererString(psPVRScreen->psDRISUPScreen, iAttribute, + ppszValue); +} + +static const __DRI2rendererQueryExtension pvrDRIRendererQueryExtension = { + .base = { + .name = __DRI2_RENDERER_QUERY, + .version = PVR_DRI2_RENDERER_QUERY_VERSION, + }, + .queryInteger = PVRDRIQueryRendererInteger, + .queryString = PVRDRIQueryRendererString, +}; + + +static void * +PVRDRICreateFenceEXT(__DRIcontext *psDRIContext) +{ + PVRDRIContext *psPVRContext = psDRIContext->driverPrivate; + + return DRISUPCreateFence(psPVRContext->psDRISUPContext); +} + +static void +PVRDRIDestroyFenceEXT(__DRIscreen *psDRIScreen, void *pvFence) +{ + PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate; + + return DRISUPDestroyFence(psPVRScreen->psDRISUPScreen, pvFence); +} + +static GLboolean +PVRDRIClientWaitSyncEXT(__DRIcontext *psDRIContext, void *pvFence, + unsigned int uFlags, uint64_t uTimeout) +{ + struct DRISUPContext *psDRISUPContext; + + if (psDRIContext) { + PVRDRIContext *psPVRContext = psDRIContext->driverPrivate; + + psDRISUPContext = psPVRContext->psDRISUPContext; + } else { + psDRISUPContext = NULL; + } + + return DRISUPClientWaitSync(psDRISUPContext, pvFence, uFlags, uTimeout); +} + +static void +PVRDRIServerWaitSyncEXT(__DRIcontext *psDRIContext, void *pvFence, + unsigned int uFlags) +{ + PVRDRIContext *psPVRContext = psDRIContext->driverPrivate; + + return DRISUPServerWaitSync(psPVRContext->psDRISUPContext, pvFence, uFlags); +} + +static unsigned int +PVRDRIGetFenceCapabilitiesEXT(__DRIscreen *psDRIScreen) +{ + PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate; + + return DRISUPGetFenceCapabilities(psPVRScreen->psDRISUPScreen); +} + +static void * +PVRDRICreateFenceFdEXT(__DRIcontext *psDRIContext, int iFD) +{ + PVRDRIContext *psPVRContext = psDRIContext->driverPrivate; + + return DRISUPCreateFenceFD(psPVRContext->psDRISUPContext, iFD); +} + +static int +PVRDRIGetFenceFdEXT(__DRIscreen *psDRIScreen, void *pvFence) +{ + PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate; + + return DRISUPGetFenceFD(psPVRScreen->psDRISUPScreen, pvFence); +} + +static void * +PVRDRIGetFenceFromClEventEXT(__DRIscreen *psDRIScreen, intptr_t iClEvent) +{ + PVRDRIScreen *psPVRScreen = psDRIScreen->driverPrivate; + + return DRISUPGetFenceFromCLEvent(psPVRScreen->psDRISUPScreen, iClEvent); +} + +__DRI2fenceExtension pvrDRIFenceExtension = { + .base = { + .name = __DRI2_FENCE, + .version = PVR_DRI2_FENCE_VERSION, + }, + .create_fence = PVRDRICreateFenceEXT, + .get_fence_from_cl_event = PVRDRIGetFenceFromClEventEXT, + .destroy_fence = PVRDRIDestroyFenceEXT, + .client_wait_sync = PVRDRIClientWaitSyncEXT, + .server_wait_sync = PVRDRIServerWaitSyncEXT, + .get_capabilities = PVRDRIGetFenceCapabilitiesEXT, + .create_fence_fd = PVRDRICreateFenceFdEXT, + .get_fence_fd = PVRDRIGetFenceFdEXT, +}; + +static void +PVRDRISetDamageRegion(__DRIdrawable *psDRIDrawable, + unsigned int uNRects, int *piRects) +{ + PVRDRIDrawable *psPVRDrawable = psDRIDrawable->driverPrivate; + + DRISUPSetDamageRegion(psPVRDrawable->psDRISUPDrawable, uNRects, piRects); +} + +const __DRI2bufferDamageExtension pvrDRIbufferDamageExtension = { + .base = { + .name = __DRI2_BUFFER_DAMAGE, + .version = PVR_DRI2_BUFFER_DAMAGE_VERSION, + }, + .set_damage_region = PVRDRISetDamageRegion, +}; + +/* + * Extension lists + * + * NOTE: When adding a new screen extension asScreenExtensionVersionInfo + * should also be updated accordingly. + */ +static const __DRIextension *apsScreenExtensions[] = { + &pvrDRITexBufferExtension.base, + &pvrDRI2FlushExtension.base, + &pvrDRIImage.base, + &pvrDRIRobustness.base, + &pvrDRIRendererQueryExtension.base, + &pvrDRIFenceExtension.base, + &pvrDRIbufferDamageExtension.base, + &dri2ConfigQueryExtension.base, + NULL +}; + +static const __DRIextension asScreenExtensionVersionInfo[] = { + {.name = __DRI_TEX_BUFFER,.version = __DRI_TEX_BUFFER_VERSION}, + {.name = __DRI2_FLUSH,.version = __DRI2_FLUSH_VERSION}, + {.name = __DRI_IMAGE,.version = __DRI_IMAGE_VERSION}, + {.name = __DRI2_ROBUSTNESS,.version = __DRI2_ROBUSTNESS_VERSION}, + {.name = __DRI2_RENDERER_QUERY,.version = __DRI2_RENDERER_QUERY_VERSION}, + {.name = __DRI2_FENCE,.version = __DRI2_FENCE_VERSION}, + {.name = __DRI2_BUFFER_DAMAGE,.version = __DRI2_BUFFER_DAMAGE_VERSION}, + {.name = __DRI2_CONFIG_QUERY,.version = __DRI2_CONFIG_QUERY_VERSION}, + {.name = NULL,.version = 0}, +}; + +const __DRIextension ** +PVRDRIScreenExtensions(void) +{ + return apsScreenExtensions; +} + +const __DRIextension * +PVRDRIScreenExtensionVersionInfo(void) +{ + return asScreenExtensionVersionInfo; +} + +void +PVRDRIAdjustExtensions(unsigned int uVersion, unsigned int uMinVersion) +{ + switch (uVersion) { + default: + case 3: + break; + case 2: + case 1: + case 0: + /* The KHR_cl_event2 EGL extension is not supported */ + pvrDRIFenceExtension.get_fence_from_cl_event = NULL; + break; + } +} diff --git a/src/mesa/drivers/dri/pvr/pvrext_mod.c b/src/mesa/drivers/dri/pvr/pvrext_mod.c new file mode 100644 index 00000000000..dfb5c79eeb4 --- /dev/null +++ b/src/mesa/drivers/dri/pvr/pvrext_mod.c @@ -0,0 +1,276 @@ +/* + * 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 +#include + +#include "util/u_atomic.h" +#include "pvrdri_mod.h" + +static void +PVRDRIFlushDrawableContext(struct DRISUPDrawable *psPVRDrawable, + struct DRISUPContext *psPVRContext) +{ + struct DRISUPContext *psPVRDrawContext = psPVRDrawable->psPVRContext; + + if (psPVRDrawContext) { + PVRDRIEGLFlushBuffers(psPVRDrawContext->eAPI, + psPVRDrawContext->psPVRScreen->psImpl, + psPVRDrawContext->psImpl, + psPVRDrawable->psImpl, + false, + false, (psPVRDrawContext != psPVRContext)); + } +} + +void +DRIMODSetTexBuffer2(struct DRISUPContext *psPVRContext, int iTarget, + int iFormat, struct DRISUPDrawable *psPVRDrawable) +{ + (void) iTarget; + (void) iFormat; + + 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); +} + +void +DRIMODReleaseTexBuffer(struct DRISUPContext *psPVRContext, int iTarget, + struct DRISUPDrawable *psPVRDrawable) +{ + (void) iTarget; + + PVRDRI2ReleaseTexImage(psPVRContext->eAPI, + psPVRContext->psPVRScreen->psImpl, + psPVRContext->psImpl, psPVRDrawable->psImpl); +} + +void +DRIMODFlush(struct DRISUPDrawable *psPVRDrawable) +{ + struct DRISUPContext *psPVRContext = psPVRDrawable->psPVRContext; + + PVRDRIFlushBuffersForSwap(psPVRContext, psPVRDrawable); +} + +void +DRIMODInvalidate(struct DRISUPDrawable *psPVRDrawable) +{ + if (psPVRDrawable->psPVRScreen->bUseInvalidate) + p_atomic_inc(&psPVRDrawable->iInfoInvalid); +} + +void +DRIMODFlushWithFlags(struct DRISUPContext *psPVRContext, + struct DRISUPDrawable *psPVRDrawable, + unsigned int uFlags, unsigned int uThrottleReason) +{ + (void) uThrottleReason; + + if ((uFlags & PVRDRI_FLUSH_DRAWABLE) != 0) { + PVRDRIFlushBuffersForSwap(psPVRContext, psPVRDrawable); + } else if ((uFlags & PVRDRI_FLUSH_CONTEXT) != 0) { + /* + * PVRDRI_FLUSH__CONTEXT means "glFlush". Most callers also specify + * PVRDRI_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. + */ + } +} + +int +DRIMODQueryRendererInteger(struct DRISUPScreen *psPVRScreen, int iAttribute, + unsigned int *puValue) +{ + (void) psPVRScreen; + + switch (iAttribute) { + case PVRDRI_RENDERER_HAS_CONTEXT_PRIORITY: + puValue[0] = 0; + puValue[0] |= PVRDRI_RENDERER_HAS_CONTEXT_PRIORITY_HIGH; + puValue[0] |= PVRDRI_RENDERER_HAS_CONTEXT_PRIORITY_MEDIUM; + puValue[0] |= PVRDRI_RENDERER_HAS_CONTEXT_PRIORITY_LOW; + return 0; + case PVRDRI_RENDERER_HAS_FRAMEBUFFER_SRGB: + puValue[0] = 1; + return 0; + default: + return -1; + } +} + +int +DRIMODQueryRendererString(struct DRISUPScreen *psPVRScreen, int iAttribute, + const char **ppszValue) +{ + (void) psPVRScreen; + (void) iAttribute; + (void) ppszValue; + + return -1; +} + +void * +DRIMODCreateFence(struct DRISUPContext *psPVRContext) +{ + return PVRDRICreateFenceImpl(psPVRContext->eAPI, + psPVRContext->psPVRScreen->psImpl, + psPVRContext->psImpl); +} + +void +DRIMODDestroyFence(struct DRISUPScreen *psPVRScreen, void *pvFence) +{ + (void) psPVRScreen; + + PVRDRIDestroyFenceImpl(pvFence); +} + +bool +DRIMODClientWaitSync(struct DRISUPContext *psPVRContext, void *pvFence, + unsigned int uFlags, uint64_t uTimeout) +{ + bool bFlushCommands = (uFlags & PVRDRI_FENCE_FLAG_FLUSH_COMMANDS); + bool bTimeout = (uTimeout != PVRDRI_FENCE_TIMEOUT_INFINITE); + + if (psPVRContext && bFlushCommands) { + struct DRISUPDrawable *psPVRDrawable; + PVRDRIDrawableImpl *psDrawableImpl; + + psPVRDrawable = psPVRContext->psPVRDrawable; + psDrawableImpl = psPVRDrawable ? psPVRDrawable->psImpl : NULL; + + (void) PVRDRIEGLFlushBuffers(psPVRContext->eAPI, + psPVRContext->psPVRScreen->psImpl, + psPVRContext->psImpl, + psDrawableImpl, true, false, false); + } + + return PVRDRIClientWaitSyncImpl(PVRDRI_API_NONE, NULL, pvFence, false, + bTimeout, uTimeout); +} + +void +DRIMODServerWaitSync(struct DRISUPContext *psPVRContext, void *pvFence, + unsigned int uFlags) +{ + assert(uFlags == 0); + (void) uFlags; + + if (pvFence) { + if (!PVRDRIServerWaitSyncImpl(psPVRContext->eAPI, + psPVRContext->psImpl, pvFence)) { + __driUtilMessage("%s: Server wait sync failed", __func__); + } + } +} + +unsigned int +DRIMODGetFenceCapabilities(struct DRISUPScreen *psPVRScreen) +{ + return PVRDRIGetFenceCapabilities(psPVRScreen->psImpl); +} + +void * +DRIMODCreateFenceFD(struct DRISUPContext *psPVRContext, int iFD) +{ + return PVRDRICreateFenceFd(psPVRContext->eAPI, + psPVRContext->psPVRScreen->psImpl, + psPVRContext->psImpl, iFD); +} + +int +DRIMODGetFenceFD(struct DRISUPScreen *psPVRScreen, void *pvFence) +{ + (void) psPVRScreen; + + return PVRDRIGetFenceFd(pvFence); +} + +unsigned int +DRIMODGetNumAPIProcs(struct DRISUPScreen *psPVRScreen, PVRDRIAPIType eAPI) +{ + (void) psPVRScreen; + + return PVRDRIGetNumAPIFuncs(eAPI); +} + +const char * +DRIMODGetAPIProcName(struct DRISUPScreen *psPVRScreen, PVRDRIAPIType eAPI, + unsigned int uIndex) +{ + (void) psPVRScreen; + + return PVRDRIGetAPIFunc(eAPI, uIndex); +} + +void * +DRIMODGetAPIProcAddress(struct DRISUPScreen *psPVRScreen, PVRDRIAPIType eAPI, + unsigned int uIndex) +{ + const char *pszFunc; + void *pvHandle; + void *pvFunc; + const char *pszError; + + pszFunc = PVRDRIGetAPIFunc(eAPI, uIndex); + if (!pszFunc) { + __driUtilMessage("%s: No Proc for API %u at index %u", + __func__, (unsigned int) eAPI, uIndex); + return NULL; + } + + pvHandle = PVRDRIEGLGetLibHandle(eAPI, psPVRScreen->psImpl); + if (!pvHandle) { + __driUtilMessage("%s: No library handle for API %u", + __func__, (unsigned int) eAPI); + return NULL; + } + + (void) dlerror(); + pvFunc = dlsym(pvHandle, pszFunc); + pszError = dlerror(); + if (pszError) + pvFunc = PVRDRIEGLGetProcAddress(eAPI, psPVRScreen->psImpl, pszFunc); + + return pvFunc; +} + +void +DRIMODSetDamageRegion(struct DRISUPDrawable *psDRISUPDrawable, + unsigned int uNRects, int *piRects) +{ + (void) psDRISUPDrawable; + (void) uNRects; + (void) piRects; +} diff --git a/src/mesa/drivers/dri/pvr/pvrimage_mod.c b/src/mesa/drivers/dri/pvr/pvrimage_mod.c new file mode 100644 index 00000000000..df4a7f4d6fb --- /dev/null +++ b/src/mesa/drivers/dri/pvr/pvrimage_mod.c @@ -0,0 +1,1282 @@ +/* + * 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 +#include + +#include "util/u_atomic.h" +#include + +#include "img_drm_fourcc.h" +#include "pvrdri_mod.h" + +struct PVRDRIImageShared { + int iRefCount; + + struct DRISUPScreen *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 *pvLoaderPrivate; + + struct PVRDRIImageShared *psShared; + + IMGEGLImage *psEGLImage; +}; + + +static struct PVRDRIImageShared * +CommonImageSharedSetup(struct DRISUPScreen *psPVRScreen, + PVRDRIImageType eType) +{ + struct PVRDRIImageShared *psShared; + + psShared = calloc(1, sizeof(*psShared)); + if (!psShared) + return NULL; + + psShared->psPVRScreen = psPVRScreen; + psShared->eType = eType; + psShared->iRefCount = 1; + + assert(psShared->eColourSpace == IMG_COLORSPACE_UNDEFINED && + psShared->eChromaUInterp == IMG_CHROMA_INTERP_UNDEFINED && + psShared->eChromaVInterp == IMG_CHROMA_INTERP_UNDEFINED); + + return psShared; +} + +static void +DestroyImageShared(struct PVRDRIImageShared *psShared) +{ + int iRefCount = p_atomic_dec_return(&psShared->iRefCount); + + assert(iRefCount >= 0); + + if (iRefCount > 0) + return; + + switch (psShared->eType) { + case PVRDRI_IMAGE_FROM_NAMES: + case PVRDRI_IMAGE_FROM_DMABUFS: + case PVRDRI_IMAGE: + if (psShared->psBuffer) + PVRDRIBufferDestroy(psShared->psBuffer); + + assert(!psShared->psAncestor); + break; + case PVRDRI_IMAGE_FROM_EGLIMAGE: { + PVRDRIScreenImpl *psScreenImpl; + + psScreenImpl = psShared->psPVRScreen->psImpl; + + PVRDRIEGLImageDestroyExternal(psScreenImpl, + psShared->psEGLImage, + psShared->eglImageType); + break; + } + case PVRDRI_IMAGE_SUBIMAGE: + if (psShared->psBuffer) + PVRDRIBufferDestroy(psShared->psBuffer); + + if (psShared->psAncestor) + DestroyImageShared(psShared->psAncestor); + break; + default: + errorMessage("%s: Unknown image type: %d", + __func__, (int) psShared->eType); + break; + } + + free(psShared); +} + +static struct PVRDRIImageShared * +CreateImageSharedFromEGLImage(struct DRISUPScreen *psPVRScreen, + IMGEGLImage *psEGLImage, + PVRDRIEGLImageType eglImageType) +{ + struct PVRDRIImageShared *psShared; + PVRDRIBufferAttribs sAttribs; + const PVRDRIImageFormat *psFormat; + + PVRDRIEGLImageGetAttribs(psEGLImage, &sAttribs); + + psFormat = PVRDRIIMGPixelFormatToImageFormat(psPVRScreen, + sAttribs.ePixFormat); + if (!psFormat) + return NULL; + + psShared = CommonImageSharedSetup(psPVRScreen, PVRDRI_IMAGE_FROM_EGLIMAGE); + if (!psShared) + return NULL; + + psShared->psEGLImage = psEGLImage; + psShared->psFormat = psFormat; + psShared->eglImageType = eglImageType; + + return psShared; +} + +static struct PVRDRIImageShared * +CreateImageSharedFromNames(struct DRISUPScreen *psPVRScreen, + int iWidth, int iHeight, int iFourCC, + int *piNames, int iNumNames, + int *piStrides, int *piOffsets) +{ + struct PVRDRIImageShared *psShared; + const PVRDRIImageFormat *psFormat; + int aiPlaneNames[DRI_PLANES_MAX]; + unsigned int auiWidthShift[DRI_PLANES_MAX]; + unsigned int auiHeightShift[DRI_PLANES_MAX]; + unsigned int i; + + psFormat = PVRDRIFourCCToImageFormat(psPVRScreen, iFourCC); + if (!psFormat) { + errorMessage("%s: Unsupported DRI FourCC (fourcc = 0x%X)", + __func__, iFourCC); + return NULL; + } + + if (iNumNames != 1 && iNumNames != (int) psFormat->uiNumPlanes) { + errorMessage("%s: Unexpected number of names (%d) for fourcc " + "(#%x) - expected 1 or %u", + __func__, iNumNames, iFourCC, psFormat->uiNumPlanes); + return NULL; + } + + for (i = 0; i < psFormat->uiNumPlanes; i++) { + if (piOffsets[i] < 0) { + errorMessage("%s: Offset %d unsupported (value = %d)", + __func__, i, piOffsets[i]); + return NULL; + } + + aiPlaneNames[i] = iNumNames == 1 ? piNames[0] : piNames[i]; + auiWidthShift[i] = psFormat->sPlanes[i].uiWidthShift; + auiHeightShift[i] = psFormat->sPlanes[i].uiHeightShift; + } + + psShared = + CommonImageSharedSetup(psPVRScreen, PVRDRI_IMAGE_FROM_NAMES); + if (!psShared) + return NULL; + + psShared->psBuffer = PVRDRIBufferCreateFromNames(psPVRScreen->psImpl, + iWidth, iHeight, + psFormat->uiNumPlanes, + aiPlaneNames, + piStrides, piOffsets, + auiWidthShift, + auiHeightShift); + if (!psShared->psBuffer) { + errorMessage("%s: Failed to create buffer for shared image", + __func__); + goto ErrorDestroyImage; + } + + psShared->psFormat = psFormat; + psShared->eColourSpace = + PVRDRIToIMGColourSpace(psFormat, + PVRDRI_YUV_COLOR_SPACE_UNDEFINED, + PVRDRI_YUV_RANGE_UNDEFINED); + psShared->eChromaUInterp = + PVRDRIChromaSittingToIMGInterp(psFormat, + PVRDRI_YUV_CHROMA_SITING_UNDEFINED); + psShared->eChromaVInterp = + PVRDRIChromaSittingToIMGInterp(psFormat, + PVRDRI_YUV_CHROMA_SITING_UNDEFINED); + + return psShared; + +ErrorDestroyImage: + DestroyImageShared(psShared); + + return NULL; +} + +static struct PVRDRIImageShared * +CreateImageSharedFromDMABufs(struct DRISUPScreen *psPVRScreen, + int iWidth, int iHeight, + int iFourCC, uint64_t uModifier, + int *piFDs, int iNumFDs, + int *piStrides, int *piOffsets, + unsigned int uColorSpace, + unsigned int uSampleRange, + unsigned int uHorizSiting, + unsigned int uVertSiting, + unsigned int *puError) +{ + struct PVRDRIImageShared *psShared; + const PVRDRIImageFormat *psFormat; + int aiPlaneFDs[DRI_PLANES_MAX]; + unsigned int auiWidthShift[DRI_PLANES_MAX]; + unsigned int auiHeightShift[DRI_PLANES_MAX]; + unsigned int i; + + psFormat = PVRDRIFourCCToImageFormat(psPVRScreen, iFourCC); + if (!psFormat) { + errorMessage("%s: Unsupported DRI FourCC (fourcc = 0x%X)", + __func__, iFourCC); + *puError = PVRDRI_IMAGE_ERROR_BAD_MATCH; + return NULL; + } + + /* When a modifier isn't specified, skip the validation */ + if (uModifier != 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, iFourCC, uModifier)) { + errorMessage("%s: Unsupported mod (fmt = %#x, mod = %#llx", + __func__, iFourCC, + (long long unsigned int) uModifier); + *puError = PVRDRI_IMAGE_ERROR_BAD_MATCH; + return NULL; + } + } + + if (iNumFDs != 1 && iNumFDs != (int) psFormat->uiNumPlanes) { + errorMessage("%s: Unexpected number of FDs (%d) for fourcc " + "(#%x) - expected 1 or %u", + __func__, iNumFDs, iFourCC, psFormat->uiNumPlanes); + *puError = PVRDRI_IMAGE_ERROR_BAD_MATCH; + return NULL; + } + + for (i = 0; i < psFormat->uiNumPlanes; i++) { + if (piOffsets[i] < 0) { + errorMessage("%s: Offset %d unsupported (value = %d)", + __func__, i, piOffsets[i]); + *puError = PVRDRI_IMAGE_ERROR_BAD_ACCESS; + return NULL; + } + + aiPlaneFDs[i] = iNumFDs == 1 ? piFDs[0] : piFDs[i]; + auiWidthShift[i] = psFormat->sPlanes[i].uiWidthShift; + auiHeightShift[i] = psFormat->sPlanes[i].uiHeightShift; + } + + psShared = CommonImageSharedSetup(psPVRScreen, + PVRDRI_IMAGE_FROM_DMABUFS); + if (!psShared) { + *puError = PVRDRI_IMAGE_ERROR_BAD_ALLOC; + return NULL; + } + + psShared->psBuffer = + PVRDRIBufferCreateFromFdsWithModifier(psPVRScreen->psImpl, + iWidth, iHeight, uModifier, + psFormat->uiNumPlanes, aiPlaneFDs, + piStrides, piOffsets, + auiWidthShift, auiHeightShift); + if (!psShared->psBuffer) { + errorMessage("%s: Failed to create buffer for shared image", + __func__); + *puError = PVRDRI_IMAGE_ERROR_BAD_ALLOC; + goto ErrorDestroyImage; + } + + psShared->psFormat = psFormat; + psShared->eColourSpace = PVRDRIToIMGColourSpace(psFormat, uColorSpace, + uSampleRange); + psShared->eChromaUInterp = PVRDRIChromaSittingToIMGInterp(psFormat, + uHorizSiting); + psShared->eChromaVInterp = PVRDRIChromaSittingToIMGInterp(psFormat, + uVertSiting); + + *puError = PVRDRI_IMAGE_ERROR_SUCCESS; + + return psShared; + +ErrorDestroyImage: + DestroyImageShared(psShared); + + return NULL; +} + +static struct PVRDRIImageShared * +CreateImageShared(struct DRISUPScreen *psPVRScreen, int iWidth, int iHeight, + int iFourCC, unsigned int use, int *piStride) +{ + struct PVRDRIImageShared *psShared; + const PVRDRIImageFormat *psFormat; + unsigned int uStride; + unsigned int uBPP; + + if ((use & PVDRI_BUFFER_USE_CURSOR) + && (use & PVDRI_BUFFER_USE_SCANOUT)) { + return NULL; + } + + psFormat = PVRDRIFourCCToImageFormat(psPVRScreen, iFourCC); + if (!psFormat) { + errorMessage("%s: Unsupported DRI image format (format = 0x%X)", + __func__, iFourCC); + return NULL; + } + + if (psFormat->uiNumPlanes != 1) { + errorMessage("%s: Only single plane formats are supported (format 0x%X has %u planes)", + __func__, iFourCC, psFormat->uiNumPlanes); + return NULL; + } + + uBPP = PVRDRIPixFmtGetBPP(psFormat->eIMGPixelFormat); + + psShared = CommonImageSharedSetup(psPVRScreen, PVRDRI_IMAGE); + if (!psShared) + return NULL; + + psShared->psBuffer = + PVRDRIBufferCreate(psPVRScreen->psImpl, iWidth, iHeight, uBPP, use, + &uStride); + if (!psShared->psBuffer) { + errorMessage("%s: Failed to create buffer", __func__); + goto ErrorDestroyImage; + } + + psShared->psFormat = psFormat; + + *piStride = uStride; + + return psShared; + +ErrorDestroyImage: + DestroyImageShared(psShared); + + return NULL; +} + +static struct PVRDRIImageShared * +CreateImageSharedWithModifiers(struct DRISUPScreen *psPVRScreen, + int iWidth, int iHeight, int iFourCC, + const uint64_t *puModifiers, + unsigned int uModifierCount, int *piStride) +{ + struct PVRDRIImageShared *psShared; + const PVRDRIImageFormat *psFormat; + unsigned int uStride; + + psFormat = PVRDRIFourCCToImageFormat(psPVRScreen, iFourCC); + if (!psFormat) { + errorMessage("%s: Unsupported DRI image format (format = 0x%X)", + __func__, iFourCC); + return NULL; + } + + psShared = CommonImageSharedSetup(psPVRScreen, PVRDRI_IMAGE); + if (!psShared) + return NULL; + + psShared->psBuffer = + PVRDRIBufferCreateWithModifiers(psPVRScreen->psImpl, iWidth, iHeight, + psFormat->iDRIFourCC, + psFormat->eIMGPixelFormat, + puModifiers, uModifierCount, &uStride); + if (!psShared->psBuffer) { + errorMessage("%s: Failed to create buffer", __func__); + goto ErrorDestroyImage; + } + + psShared->psFormat = psFormat; + + *piStride = uStride; + + return psShared; + +ErrorDestroyImage: + DestroyImageShared(psShared); + + return NULL; +} + +static struct PVRDRIImageShared * +RefImageShared(struct PVRDRIImageShared *psShared) +{ + int iRefCount = p_atomic_inc_return(&psShared->iRefCount); + + (void) iRefCount; + assert(iRefCount > 1); + + return psShared; +} + +static struct PVRDRIImageShared * +CreateImageSharedForSubImage(struct PVRDRIImageShared *psParent, int iPlane) +{ + struct PVRDRIImageShared *psShared; + struct PVRDRIImageShared *psAncestor; + PVRDRIBufferImpl *psBuffer = NULL; + IMG_PIXFMT eIMGPixelFormat; + + /* 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, iPlane); + if (!psBuffer) + return NULL; + + psShared = CommonImageSharedSetup(NULL, PVRDRI_IMAGE_SUBIMAGE); + if (!psShared) + goto ErrorDestroyBuffer; + + psShared->psAncestor = RefImageShared(psAncestor); + psShared->psBuffer = psBuffer; + psShared->psPVRScreen = psParent->psPVRScreen; + + eIMGPixelFormat = psParent->psFormat->sPlanes[iPlane].eIMGPixelFormat; + + psShared->psFormat = + PVRDRIIMGPixelFormatToImageFormat(psParent->psPVRScreen, + eIMGPixelFormat); + + assert(psShared->psFormat); + + return psShared; + +ErrorDestroyBuffer: + PVRDRIBufferDestroy(psBuffer); + return NULL; +} + +static __DRIimage * +CommonImageSetup(void *pvLoaderPrivate) +{ + __DRIimage *psImage; + + psImage = calloc(1, sizeof(*psImage)); + if (!psImage) + return NULL; + + psImage->pvLoaderPrivate = pvLoaderPrivate; + psImage->iRefCount = 1; + + return psImage; +} + +void +DRIMODDestroyImage(__DRIimage *psImage) +{ + int iRefCount = p_atomic_dec_return(&psImage->iRefCount); + + assert(iRefCount >= 0); + + if (iRefCount > 0) + return; + + if (psImage->psShared) + DestroyImageShared(psImage->psShared); + + PVRDRIEGLImageFree(psImage->psEGLImage); + free(psImage); +} + +__DRIimage * +DRIMODCreateImageFromName(struct DRISUPScreen *psPVRScreen, + int iWidth, int iHeight, int iFourCC, int iName, + int iPitch, void *pvLoaderPrivate) +{ + const PVRDRIImageFormat *psFormat; + int iStride; + int iOffset; + + psFormat = PVRDRIFourCCToImageFormat(psPVRScreen, iFourCC); + if (!psFormat) { + errorMessage("%s: Unsupported DRI image FourCC (format = 0x%X)", + __func__, iFourCC); + return NULL; + } + + iStride = iPitch * PVRDRIPixFmtGetBlockSize(psFormat->eIMGPixelFormat); + iOffset = 0; + + return DRIMODCreateImageFromNames(psPVRScreen, iWidth, iHeight, iFourCC, + &iName, 1, &iStride, &iOffset, + pvLoaderPrivate); +} + +__DRIimage * +DRIMODCreateImageFromRenderBuffer2(struct DRISUPContext *psPVRContext, + int iRenderBuffer, void *pvLoaderPrivate, + unsigned int *puError) +{ + struct DRISUPScreen *psPVRScreen = psPVRContext->psPVRScreen; + unsigned int uError; + IMGEGLImage *psEGLImage; + __DRIimage *psImage; + + psImage = CommonImageSetup(pvLoaderPrivate); + if (!psImage) { + *puError = PVRDRI_IMAGE_ERROR_BAD_ALLOC; + return NULL; + } + + psEGLImage = PVRDRIEGLImageCreate(); + if (!psEGLImage) { + DRIMODDestroyImage(psImage); + + *puError = PVRDRI_IMAGE_ERROR_BAD_ALLOC; + return NULL; + } + + uError = PVRDRIGetImageSource(psPVRContext->eAPI, psPVRScreen->psImpl, + psPVRContext->psImpl, PVRDRI_GL_RENDERBUFFER, + (uintptr_t) iRenderBuffer, 0, psEGLImage); + if (uError != PVRDRI_IMAGE_ERROR_SUCCESS) { + PVRDRIEGLImageFree(psEGLImage); + DRIMODDestroyImage(psImage); + + *puError = uError; + return NULL; + } + + PVRDRIEGLImageSetCallbackData(psEGLImage, psImage); + + /* + * We can't destroy the image after this point, as the + * renderbuffer now has a reference to it. + */ + psImage->psShared = + CreateImageSharedFromEGLImage(psPVRScreen, psEGLImage, + PVRDRI_EGLIMAGE_IMGEGL); + if (!psImage->psShared) { + *puError = PVRDRI_IMAGE_ERROR_BAD_ALLOC; + return NULL; + } + + psImage->psEGLImage = PVRDRIEGLImageDup(psImage->psShared->psEGLImage); + if (!psImage->psEGLImage) { + *puError = PVRDRI_IMAGE_ERROR_BAD_ALLOC; + return NULL; + } + + psImage->iRefCount++; + + *puError = PVRDRI_IMAGE_ERROR_SUCCESS; + return psImage; +} + + +__DRIimage * +DRIMODCreateImageFromRenderbuffer(struct DRISUPContext *psPVRContext, + int iRenderBuffer, void *pvLoaderPrivate) +{ + unsigned int uError; + + return DRIMODCreateImageFromRenderBuffer2(psPVRContext, iRenderBuffer, + pvLoaderPrivate, &uError); +} + +__DRIimage * +DRIMODCreateImage(struct DRISUPScreen *psPVRScreen, int iWidth, int iHeight, + int iFourCC, unsigned int uUse, void *pvLoaderPrivate) +{ + __DRIimage *psImage; + struct PVRDRIImageShared *psShared; + IMG_PIXFMT eIMGPixelFormat; + int iStride; + + psImage = CommonImageSetup(pvLoaderPrivate); + if (!psImage) + return NULL; + + psShared = CreateImageShared(psPVRScreen, iWidth, iHeight, iFourCC, uUse, + &iStride); + if (!psShared) { + DRIMODDestroyImage(psImage); + return NULL; + } + + psImage->psShared = psShared; + eIMGPixelFormat = psShared->psFormat->eIMGPixelFormat; + + psImage->psEGLImage = + PVRDRIEGLImageCreateFromBuffer(iWidth, iHeight, iStride, + eIMGPixelFormat, psShared->eColourSpace, + psShared->eChromaUInterp, + psShared->eChromaVInterp, + psShared->psBuffer); + if (!psImage->psEGLImage) { + DRIMODDestroyImage(psImage); + return NULL; + } + + PVRDRIEGLImageSetCallbackData(psImage->psEGLImage, psImage); + + return psImage; +} + +__DRIimage * +DRIMODCreateImageWithModifiers(struct DRISUPScreen *psPVRScreen, + int iWidth, int iHeight, int iFourCC, + const uint64_t *puModifiers, + const unsigned int uModifierCount, + void *pvLoaderPrivate) +{ + __DRIimage *psImage; + struct PVRDRIImageShared *psShared; + IMG_PIXFMT eIMGPixelFormat; + int iStride; + + psImage = CommonImageSetup(pvLoaderPrivate); + if (!psImage) + return NULL; + + psShared = CreateImageSharedWithModifiers(psPVRScreen, + iWidth, iHeight, iFourCC, + puModifiers, uModifierCount, + &iStride); + if (!psShared) { + DRIMODDestroyImage(psImage); + return NULL; + } + + psImage->psShared = psShared; + eIMGPixelFormat = psShared->psFormat->eIMGPixelFormat; + + psImage->psEGLImage = + PVRDRIEGLImageCreateFromBuffer(iWidth, iHeight, iStride, + eIMGPixelFormat, psShared->eColourSpace, + psShared->eChromaUInterp, + psShared->eChromaVInterp, + psShared->psBuffer); + if (!psImage->psEGLImage) { + DRIMODDestroyImage(psImage); + return NULL; + } + + PVRDRIEGLImageSetCallbackData(psImage->psEGLImage, psImage); + + return psImage; +} + +bool +DRIMODQueryImage(__DRIimage *psImage, int attrib, int *value_ptr) +{ + struct PVRDRIImageShared *psShared = psImage->psShared; + PVRDRIBufferAttribs sAttribs; + int value; + uint64_t ulValue; + + PVRDRIEGLImageGetAttribs(psImage->psEGLImage, &sAttribs); + + if (attrib == PVRDRI_IMAGE_ATTRIB_HANDLE || + attrib == PVRDRI_IMAGE_ATTRIB_NAME || + attrib == PVRDRI_IMAGE_ATTRIB_FD || + attrib == PVRDRI_IMAGE_ATTRIB_OFFSET) { + if (!psShared->psFormat) + return false; + + switch (psShared->psFormat->iDRIComponents) { + case PVRDRI_IMAGE_COMPONENTS_R: + case PVRDRI_IMAGE_COMPONENTS_RG: + case PVRDRI_IMAGE_COMPONENTS_RGB: + case PVRDRI_IMAGE_COMPONENTS_RGBA: + case PVRDRI_IMAGE_COMPONENTS_EXTERNAL: + break; + default: + return false; + } + } + + switch (attrib) { + case PVRDRI_IMAGE_ATTRIB_STRIDE: + *value_ptr = sAttribs.uiStrideInBytes; + break; + case PVRDRI_IMAGE_ATTRIB_HANDLE: + value = PVRDRIBufferGetHandle(psShared->psBuffer); + if (value == -1) + return false; + + *value_ptr = value; + break; + case PVRDRI_IMAGE_ATTRIB_NAME: + value = PVRDRIBufferGetName(psShared->psBuffer); + if (value == -1) + return false; + + *value_ptr = value; + break; + case PVRDRI_IMAGE_ATTRIB_FORMAT: + /* The caller should use PVRDRI_IMAGE_ATTRIB_FOURCC, and convert. */ + return false; + case PVRDRI_IMAGE_ATTRIB_WIDTH: + *value_ptr = sAttribs.uiWidth; + break; + case PVRDRI_IMAGE_ATTRIB_HEIGHT: + *value_ptr = sAttribs.uiHeight; + break; + case PVRDRI_IMAGE_ATTRIB_COMPONENTS: + if (!psShared->psFormat || !psShared->psFormat->iDRIComponents) + return false; + + *value_ptr = psShared->psFormat->iDRIComponents; + break; + case PVRDRI_IMAGE_ATTRIB_FD: + value = PVRDRIBufferGetFd(psShared->psBuffer); + if (value == -1) + return false; + + *value_ptr = value; + break; + case PVRDRI_IMAGE_ATTRIB_FOURCC: + *value_ptr = psShared->psFormat->iDRIFourCC; + break; + case PVRDRI_IMAGE_ATTRIB_NUM_PLANES: + *value_ptr = (int) psShared->psFormat->uiNumPlanes; + break; + case PVRDRI_IMAGE_ATTRIB_OFFSET: + *value_ptr = PVRDRIBufferGetOffset(psShared->psBuffer); + break; + case PVRDRI_IMAGE_ATTRIB_MODIFIER_LOWER: + ulValue = PVRDRIBufferGetModifier(psShared->psBuffer); + *value_ptr = (int) (ulValue & 0xffffffff); + break; + case PVRDRI_IMAGE_ATTRIB_MODIFIER_UPPER: + ulValue = PVRDRIBufferGetModifier(psShared->psBuffer); + *value_ptr = (int) ((ulValue >> 32) & 0xffffffff); + break; + default: + return false; + } + + return true; +} + +__DRIimage * +DRIMODDupImage(__DRIimage *psSrc, void *pvLoaderPrivate) +{ + __DRIimage *psDst; + + psDst = CommonImageSetup(pvLoaderPrivate); + if (!psDst) + return NULL; + + psDst->psShared = RefImageShared(psSrc->psShared); + + psDst->psEGLImage = PVRDRIEGLImageDup(psSrc->psEGLImage); + if (!psDst->psEGLImage) { + DRIMODDestroyImage(psDst); + return NULL; + } + + PVRDRIEGLImageSetCallbackData(psDst->psEGLImage, psDst); + + return psDst; +} + +bool +DRIMODValidateImageUsage(__DRIimage *psImage, unsigned int uUse) +{ + struct PVRDRIImageShared *psShared = psImage->psShared; + + if (uUse & (PVDRI_BUFFER_USE_SCANOUT | PVDRI_BUFFER_USE_CURSOR)) { + uint64_t uModifier; + + /* + * 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(psShared->psPVRScreen->iFD) != DRM_NODE_PRIMARY) + return false; + + uModifier = PVRDRIBufferGetModifier(psShared->psBuffer); + if (uModifier != DRM_FORMAT_MOD_INVALID && + uModifier != DRM_FORMAT_MOD_LINEAR) + return false; + } else if (uUse & (PVDRI_BUFFER_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(psShared->psPVRScreen->iFD) != + PVRDRI_DEVICE_TYPE_DISPLAY) + return false; + } + + return true; +} + +__DRIimage * +DRIMODCreateImageFromNames(struct DRISUPScreen *psPVRScreen, + int iWidth, int iHeight, int iFourCC, + int *piNames, int iNumNames, + int *piStrides, int *piOffsets, + void *pvLoaderPrivate) +{ + __DRIimage *psImage; + struct PVRDRIImageShared *psShared; + IMG_PIXFMT eIMGPixelFormat; + int iStride; + + psImage = CommonImageSetup(pvLoaderPrivate); + if (!psImage) + return NULL; + + psShared = CreateImageSharedFromNames(psPVRScreen, + iWidth, iHeight, iFourCC, + piNames, iNumNames, + piStrides, piOffsets); + if (!psShared) { + DRIMODDestroyImage(psImage); + return NULL; + } + + psImage->psShared = psShared; + eIMGPixelFormat = psShared->psFormat->eIMGPixelFormat; + + if (psShared->psFormat->uiNumPlanes == 1) + iStride = piStrides[0]; + else + iStride = iWidth * PVRDRIPixFmtGetBlockSize(eIMGPixelFormat); + + psImage->psEGLImage = + PVRDRIEGLImageCreateFromBuffer(iWidth, iHeight, iStride, + eIMGPixelFormat, psShared->eColourSpace, + psShared->eChromaUInterp, + psShared->eChromaVInterp, + psShared->psBuffer); + if (!psImage->psEGLImage) { + DRIMODDestroyImage(psImage); + return NULL; + } + + PVRDRIEGLImageSetCallbackData(psImage->psEGLImage, psImage); + + return psImage; +} + +__DRIimage * +DRIMODFromPlanar(__DRIimage *psSrc, int iPlane, void *pvLoaderPrivate) +{ + __DRIimage *psDst; + struct PVRDRIImageShared *psShared; + + psDst = CommonImageSetup(pvLoaderPrivate); + if (!psDst) + return NULL; + + psShared = CreateImageSharedForSubImage(psSrc->psShared, iPlane); + if (!psShared) { + if (iPlane != 0) { + errorMessage("%s: plane %d not supported", __func__, iPlane); + } else { + psDst->psShared = RefImageShared(psSrc->psShared); + psDst->psEGLImage = PVRDRIEGLImageDup(psSrc->psEGLImage); + } + } else { + IMG_PIXFMT eIMGPixelFormat; + + psDst->psShared = psShared; + eIMGPixelFormat = psShared->psFormat->eIMGPixelFormat; + + psDst->psEGLImage = + PVRDRIEGLImageCreateFromSubBuffer(eIMGPixelFormat, psShared->psBuffer); + } + + if (!psDst->psEGLImage) { + DRIMODDestroyImage(psDst); + return NULL; + } + + PVRDRIEGLImageSetCallbackData(psDst->psEGLImage, psDst); + + return psDst; +} + +__DRIimage * +DRIMODCreateImageFromTexture(struct DRISUPContext *psPVRContext, int iTarget, + unsigned int uTexture, int iDepth, int iLevel, + unsigned int *puError, void *pvLoaderPrivate) +{ + IMGEGLImage *psEGLImage; + __DRIimage *psImage; + uint32_t iEGLTarget; + unsigned int uError; + + switch (iTarget) { + case PVRDRI_GL_TEXTURE_2D: + iEGLTarget = iTarget; + break; + case PVRDRI_GL_TEXTURE_CUBE_MAP_POSITIVE_X: + iEGLTarget = iTarget + iDepth; + break; + default: + errorMessage("%s: EGL GL texture %d is not supported", + __func__, iTarget); + *puError = PVRDRI_IMAGE_ERROR_BAD_PARAMETER; + return NULL; + } + + psImage = CommonImageSetup(pvLoaderPrivate); + if (!psImage) + return NULL; + + psEGLImage = PVRDRIEGLImageCreate(); + if (!psEGLImage) { + DRIMODDestroyImage(psImage); + return NULL; + } + + uError = PVRDRIGetImageSource(psPVRContext->eAPI, + psPVRContext->psPVRScreen->psImpl, + psPVRContext->psImpl, iEGLTarget, uTexture, + iLevel, psEGLImage); + *puError = uError; + + if (uError != PVRDRI_IMAGE_ERROR_SUCCESS) { + PVRDRIEGLImageFree(psEGLImage); + DRIMODDestroyImage(psImage); + return NULL; + } + + PVRDRIEGLImageSetCallbackData(psEGLImage, psImage); + + /* + * We can't destroy the image after this point, as the texture now has a + * reference to it. + */ + psImage->psShared = + CreateImageSharedFromEGLImage(psPVRContext->psPVRScreen, psEGLImage, + PVRDRI_EGLIMAGE_IMGEGL); + if (!psImage->psShared) + return NULL; + + psImage->psEGLImage = PVRDRIEGLImageDup(psImage->psShared->psEGLImage); + if (!psImage->psEGLImage) + return NULL; + + psImage->iRefCount++; + + return psImage; +} + +__DRIimage * +DRIMODCreateImageFromFDs(struct DRISUPScreen *psPVRScreen, + int iWidth, int iHeight, int iFourCC, + int *piFDs, int iNumFDs, + int *piStrides, int *piOffsets, + void *pvLoaderPrivate) +{ + unsigned int uError; + + return DRIMODCreateImageFromDMABufs(psPVRScreen, iWidth, iHeight, iFourCC, + piFDs, iNumFDs, piStrides, piOffsets, + PVRDRI_YUV_COLOR_SPACE_UNDEFINED, + PVRDRI_YUV_RANGE_UNDEFINED, + PVRDRI_YUV_CHROMA_SITING_UNDEFINED, + PVRDRI_YUV_CHROMA_SITING_UNDEFINED, + &uError, pvLoaderPrivate); +} + +__DRIimage * +DRIMODCreateImageFromBuffer(struct DRISUPContext *psPVRContext, int iTarget, + void *pvBuffer, unsigned int *puError, + void *pvLoaderPrivate) +{ + IMGEGLImage *psEGLImage; + __DRIimage *psImage; + + switch (iTarget) { + case PVRDRI_CL_IMAGE_IMG: + break; + default: + errorMessage("%s: Target %d is not supported", __func__, iTarget); + *puError = PVRDRI_IMAGE_ERROR_BAD_PARAMETER; + return NULL; + } + + psImage = CommonImageSetup(pvLoaderPrivate); + if (!psImage) { + *puError = PVRDRI_IMAGE_ERROR_BAD_ALLOC; + return NULL; + } + + psEGLImage = PVRDRIEGLImageCreate(); + if (!psEGLImage) { + DRIMODDestroyImage(psImage); + + *puError = PVRDRI_IMAGE_ERROR_BAD_ALLOC; + return NULL; + } + + *puError = PVRDRIGetImageSource(PVRDRI_API_CL, + psPVRContext->psPVRScreen->psImpl, + psPVRContext->psImpl, iTarget, + (uintptr_t) pvBuffer, 0, psEGLImage); + if (*puError != PVRDRI_IMAGE_ERROR_SUCCESS) { + PVRDRIEGLImageFree(psEGLImage); + DRIMODDestroyImage(psImage); + return NULL; + } + + PVRDRIEGLImageSetCallbackData(psEGLImage, psImage); + + /* + * We can't destroy the image after this point, as the OCL image now has a + * reference to it. + */ + psImage->psShared = + CreateImageSharedFromEGLImage(psPVRContext->psPVRScreen, psEGLImage, + PVRDRI_EGLIMAGE_IMGOCL); + if (!psImage->psShared) { + *puError = PVRDRI_IMAGE_ERROR_BAD_ALLOC; + return NULL; + } + + psImage->psEGLImage = PVRDRIEGLImageDup(psImage->psShared->psEGLImage); + if (!psImage->psEGLImage) { + *puError = PVRDRI_IMAGE_ERROR_BAD_ALLOC; + return NULL; + } + + psImage->iRefCount++; + + *puError = PVRDRI_IMAGE_ERROR_SUCCESS; + + return psImage; +} + +__DRIimage * +DRIMODCreateImageFromDMABufs2(struct DRISUPScreen *psPVRScreen, + int iWidth, int iHeight, + int iFourCC, uint64_t uModifier, + int *piFDs, int iNumFDs, + int *piStrides, int *piOffsets, + unsigned int uColorSpace, + unsigned int uSampleRange, + unsigned int uHorizSiting, + unsigned int uVertSiting, + unsigned int *puError, + void *pvLoaderPrivate) +{ + __DRIimage *psImage; + struct PVRDRIImageShared *psShared; + IMG_PIXFMT eIMGPixelFormat; + + psImage = CommonImageSetup(pvLoaderPrivate); + if (!psImage) { + *puError = PVRDRI_IMAGE_ERROR_BAD_ALLOC; + return NULL; + } + + psShared = CreateImageSharedFromDMABufs(psPVRScreen, iWidth, iHeight, + iFourCC, uModifier, piFDs, iNumFDs, + piStrides, piOffsets, + uColorSpace, uSampleRange, + uHorizSiting, uVertSiting, + puError); + if (!psShared) { + DRIMODDestroyImage(psImage); + return NULL; + } + + psImage->psShared = psShared; + eIMGPixelFormat = psShared->psFormat->eIMGPixelFormat; + + psImage->psEGLImage = + PVRDRIEGLImageCreateFromBuffer(iWidth, iHeight, piStrides[0], + eIMGPixelFormat, psShared->eColourSpace, + psShared->eChromaUInterp, + psShared->eChromaVInterp, + psShared->psBuffer); + if (!psImage->psEGLImage) { + DRIMODDestroyImage(psImage); + *puError = PVRDRI_IMAGE_ERROR_BAD_ALLOC; + return NULL; + } + + PVRDRIEGLImageSetCallbackData(psImage->psEGLImage, psImage); + + *puError = PVRDRI_IMAGE_ERROR_SUCCESS; + + return psImage; +} + +__DRIimage * +DRIMODCreateImageFromDMABufs(struct DRISUPScreen *psPVRScreen, + int iWidth, int iHeight, int iFourCC, + int *piFDs, int iNumFDs, + int *piStrides, int *piOffsets, + unsigned int uColorSpace, + unsigned int uSampleRange, + unsigned int uHorizSiting, + unsigned int uVertSiting, + unsigned int *puError, + void *pvLoaderPrivate) +{ + return DRIMODCreateImageFromDMABufs2(psPVRScreen, iWidth, iHeight, + iFourCC, DRM_FORMAT_MOD_INVALID, + piFDs, iNumFDs, + piStrides, piOffsets, + uColorSpace, uSampleRange, + uHorizSiting, uVertSiting, + puError, pvLoaderPrivate); +} + +void +PVRDRIRefImage(__DRIimage *psImage) +{ + int iRefCount = p_atomic_inc_return(&psImage->iRefCount); + + (void) iRefCount; + assert(iRefCount > 1); +} + +void +PVRDRIUnrefImage(__DRIimage *psImage) +{ + DRIMODDestroyImage(psImage); +} + +PVRDRIImageType +PVRDRIImageGetSharedType(__DRIimage *psImage) +{ + return psImage->psShared->eType; +} + +PVRDRIBufferImpl * +PVRDRIImageGetSharedBuffer(__DRIimage *psImage) +{ + assert(psImage->psShared->eType != PVRDRI_IMAGE_FROM_EGLIMAGE); + + return psImage->psShared->psBuffer; +} + +IMGEGLImage * +PVRDRIImageGetSharedEGLImage(__DRIimage *psImage) +{ + assert(psImage->psShared->eType == PVRDRI_IMAGE_FROM_EGLIMAGE); + + return psImage->psShared->psEGLImage; +} + +IMGEGLImage * +PVRDRIImageGetEGLImage(__DRIimage *psImage) +{ + return psImage->psEGLImage; +} + +__DRIimage * +PVRDRIScreenGetDRIImage(void *hEGLImage) +{ + struct DRISUPScreen *psPVRScreen; + + psPVRScreen = DRIMODThreadGetCurrentScreen(); + if (!psPVRScreen) + return NULL; + + return MODSUPLookupEGLImage(psPVRScreen->psDRIScreen, hEGLImage, + psPVRScreen->pvLoaderPrivate); +} + +void +DRIMODBlitImage(struct DRISUPContext *psPVRContext, + __DRIimage *psDst, __DRIimage *psSrc, + int iDstX0, int iDstY0, int iDstWidth, int iDstHeight, + int iSrcX0, int iSrcY0, int iSrcWidth, int iSrcHeight, + int iFlushFlag) +{ + bool bRes; + + bRes = PVRDRIBlitEGLImage(psPVRContext->psPVRScreen->psImpl, + psPVRContext->psImpl, + psDst->psEGLImage, psDst->psShared->psBuffer, + psSrc->psEGLImage, psSrc->psShared->psBuffer, + iDstX0, iDstY0, iDstWidth, iDstHeight, + iSrcX0, iSrcY0, iSrcWidth, iSrcHeight, + iFlushFlag); + if (!bRes) + __driUtilMessage("%s: PVRDRIBlitEGLImage failed", __func__); +} + +int +DRIMODGetImageCapabilities(struct DRISUPScreen *psPVRScreen) +{ + (void) psPVRScreen; + + return PVRDRI_IMAGE_CAP_GLOBAL_NAMES; +} + +void * +DRIMODMapImage(struct DRISUPContext *psPVRContext, __DRIimage *psImage, + int iX0, int iY0, int iWidth, int iHeight, + unsigned int iFlags, int *iStride, void **ppvData) +{ + return PVRDRIMapEGLImage(psPVRContext->psPVRScreen->psImpl, + psPVRContext->psImpl, + psImage->psEGLImage, psImage->psShared->psBuffer, + iX0, iY0, iWidth, iHeight, iFlags, iStride, + ppvData); +} + +void +DRIMODUnmapImage(struct DRISUPContext *psPVRContext, __DRIimage *psImage, + void *pvData) +{ + bool bRes; + + bRes = PVRDRIUnmapEGLImage(psPVRContext->psPVRScreen->psImpl, + psPVRContext->psImpl, psImage->psEGLImage, + psImage->psShared->psBuffer, pvData); + if (!bRes) + __driUtilMessage("%s: PVRDRIUnmapEGLImage failed", __func__); +} diff --git a/src/mesa/drivers/dri/pvr/pvrmesa.h b/src/mesa/drivers/dri/pvr/pvrmesa.h new file mode 100644 index 00000000000..5e1c9c1b2e6 --- /dev/null +++ b/src/mesa/drivers/dri/pvr/pvrmesa.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) Imagination Technologies Ltd. + * + * The contents of this file are subject to the MIT license as set out below. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#if !defined(__PVRMESA_H__) +#define __PVRMESA_H__ + +#include "pvrdri.h" + +void pvrdri_free_dispatch_tables(PVRDRIScreen *psPVRScreen); +bool pvrdri_create_dispatch_table(PVRDRIScreen *psPVRScreen, + PVRDRIAPIType eAPI); +void pvrdri_set_null_dispatch_table(void); +void pvrdri_set_dispatch_table(PVRDRIContext *psPVRContext); + +#endif /* !defined(__PVRMESA_H__) */ diff --git a/src/mesa/drivers/dri/pvr/pvrutil.c b/src/mesa/drivers/dri/pvr/pvrutil.c new file mode 100644 index 00000000000..945e18cf220 --- /dev/null +++ b/src/mesa/drivers/dri/pvr/pvrutil.c @@ -0,0 +1,239 @@ +/* + * Copyright (c) Imagination Technologies Ltd. + * + * The contents of this file are subject to the MIT license as set out below. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include +#include +#include + +#include "drm-uapi/drm_fourcc.h" + +#include "utils.h" +#include "dri_util.h" +#include "pvrdri.h" + +#define MESSAGE_LENGTH_MAX 1024 + +/* + * Define before including android/log.h and dlog.h as this is used by these + * headers. + */ +#define LOG_TAG "PVR-MESA" + +#if defined(HAVE_ANDROID_PLATFORM) +#include +#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 +#define err_printf(f, args...) LOGE(f, ##args) +#define dbg_printf(f, args...) LOGD(f, ##args) +#else +#define err_printf(f, args...) fprintf(stderr, f "\n", ##args) +#define dbg_printf(f, args...) fprintf(stderr, "LibGL: " f "\n", ##args) +#endif /* HAVE_ANDROID_PLATFORM */ + +/* Standard error message */ +void PRINTFLIKE(1, 2) +errorMessage(const char *f, ...) +{ + char message[MESSAGE_LENGTH_MAX]; + va_list args; + + va_start(args, f); + vsnprintf(message, sizeof message, f, args); + va_end(args); + + err_printf("%s", message); +} + +void PRINTFLIKE(1, 2) +__driUtilMessage(const char *f, ...) +{ + char message[MESSAGE_LENGTH_MAX]; + va_list args; + + /* + * On Android and Tizen, always print messages; otherwise, only print if + * the environment variable LIBGL_DEBUG=verbose. + */ +#if !defined(HAVE_ANDROID_PLATFORM) && !defined(HAVE_TIZEN_PLATFORM) + char *ev = getenv("LIBGL_DEBUG"); + + if (!ev || strcmp(ev, "verbose") != 0) + return; +#endif + + va_start(args, f); + vsnprintf(message, sizeof message, f, args); + va_end(args); + + dbg_printf("%s", message); +} + +mesa_format +PVRDRIMesaFormatToMesaFormat(int pvrdri_mesa_format) +{ + switch (pvrdri_mesa_format) { + case PVRDRI_MESA_FORMAT_NONE: + return MESA_FORMAT_NONE; + case PVRDRI_MESA_FORMAT_B8G8R8A8_UNORM: + return MESA_FORMAT_B8G8R8A8_UNORM; + case PVRDRI_MESA_FORMAT_B8G8R8X8_UNORM: + return MESA_FORMAT_B8G8R8X8_UNORM; + case PVRDRI_MESA_FORMAT_B5G6R5_UNORM: + return MESA_FORMAT_B5G6R5_UNORM; + case PVRDRI_MESA_FORMAT_R8G8B8A8_UNORM: + return MESA_FORMAT_R8G8B8A8_UNORM; + case PVRDRI_MESA_FORMAT_R8G8B8X8_UNORM: + return MESA_FORMAT_R8G8B8X8_UNORM; + case PVRDRI_MESA_FORMAT_YCBCR: + return MESA_FORMAT_YCBCR; + case PVRDRI_MESA_FORMAT_YUV420_2PLANE: + return MESA_FORMAT_YUV420_2PLANE; + case PVRDRI_MESA_FORMAT_YVU420_2PLANE: + return MESA_FORMAT_YVU420_2PLANE; + case PVRDRI_MESA_FORMAT_B8G8R8A8_SRGB: + return MESA_FORMAT_B8G8R8A8_SRGB; + case PVRDRI_MESA_FORMAT_R8G8B8A8_SRGB: + return MESA_FORMAT_R8G8B8A8_SRGB; + default: + __driUtilMessage("%s: Unknown format: %d", __func__, pvrdri_mesa_format); + break; + } + + return MESA_FORMAT_NONE; +} + +int +PVRDRIFormatToFourCC(int dri_format) +{ + switch (dri_format) { + case __DRI_IMAGE_FORMAT_RGB565: + return DRM_FORMAT_RGB565; + case __DRI_IMAGE_FORMAT_XRGB8888: + return DRM_FORMAT_XRGB8888; + case __DRI_IMAGE_FORMAT_ARGB8888: + return DRM_FORMAT_ARGB8888; + case __DRI_IMAGE_FORMAT_ABGR8888: + return DRM_FORMAT_ABGR8888; + case __DRI_IMAGE_FORMAT_XBGR8888: + return DRM_FORMAT_XBGR8888; + case __DRI_IMAGE_FORMAT_R8: + return DRM_FORMAT_R8; + case __DRI_IMAGE_FORMAT_GR88: + return DRM_FORMAT_GR88; + case __DRI_IMAGE_FORMAT_NONE: + return 0; + case __DRI_IMAGE_FORMAT_XRGB2101010: + return DRM_FORMAT_XRGB2101010; + case __DRI_IMAGE_FORMAT_ARGB2101010: + return DRM_FORMAT_ARGB2101010; + case __DRI_IMAGE_FORMAT_SARGB8: + return __DRI_IMAGE_FOURCC_SARGB8888; + case __DRI_IMAGE_FORMAT_ARGB1555: + return DRM_FORMAT_ARGB1555; + case __DRI_IMAGE_FORMAT_R16: + return DRM_FORMAT_R16; + case __DRI_IMAGE_FORMAT_GR1616: + return DRM_FORMAT_GR1616; + case __DRI_IMAGE_FORMAT_YUYV: + return DRM_FORMAT_YUYV; + case __DRI_IMAGE_FORMAT_XBGR2101010: + return DRM_FORMAT_XBGR2101010; + case __DRI_IMAGE_FORMAT_ABGR2101010: + return DRM_FORMAT_ABGR2101010; + case __DRI_IMAGE_FORMAT_SABGR8: + return __DRI_IMAGE_FOURCC_SABGR8888; + case __DRI_IMAGE_FORMAT_UYVY: + return DRM_FORMAT_UYVY; + case __DRI_IMAGE_FORMAT_ARGB4444: + return DRM_FORMAT_ARGB4444; + case __DRI_IMAGE_FORMAT_YVU444_PACK10_IMG: + return DRM_FORMAT_YVU444_PACK10_IMG; + case __DRI_IMAGE_FORMAT_BGR888: + return DRM_FORMAT_BGR888; + default: + __driUtilMessage("%s: Unknown format: %d", __func__, dri_format); + break; + } + + return 0; +} + +int +PVRDRIFourCCToDRIFormat(int iFourCC) +{ + switch (iFourCC) { + case 0: + return __DRI_IMAGE_FORMAT_NONE; + case DRM_FORMAT_RGB565: + return __DRI_IMAGE_FORMAT_RGB565; + case DRM_FORMAT_XRGB8888: + return __DRI_IMAGE_FORMAT_XRGB8888; + case DRM_FORMAT_ARGB8888: + return __DRI_IMAGE_FORMAT_ARGB8888; + case DRM_FORMAT_ABGR8888: + return __DRI_IMAGE_FORMAT_ABGR8888; + case DRM_FORMAT_XBGR8888: + return __DRI_IMAGE_FORMAT_XBGR8888; + case DRM_FORMAT_R8: + return __DRI_IMAGE_FORMAT_R8; + case DRM_FORMAT_GR88: + return __DRI_IMAGE_FORMAT_GR88; + case DRM_FORMAT_XRGB2101010: + return __DRI_IMAGE_FORMAT_XRGB2101010; + case DRM_FORMAT_ARGB2101010: + return __DRI_IMAGE_FORMAT_ARGB2101010; + case __DRI_IMAGE_FOURCC_SARGB8888: + return __DRI_IMAGE_FORMAT_SARGB8; + case DRM_FORMAT_ARGB1555: + return __DRI_IMAGE_FORMAT_ARGB1555; + case DRM_FORMAT_R16: + return __DRI_IMAGE_FORMAT_R16; + case DRM_FORMAT_GR1616: + return __DRI_IMAGE_FORMAT_GR1616; + case DRM_FORMAT_YUYV: + return __DRI_IMAGE_FORMAT_YUYV; + case DRM_FORMAT_XBGR2101010: + return __DRI_IMAGE_FORMAT_XBGR2101010; + case DRM_FORMAT_ABGR2101010: + return __DRI_IMAGE_FORMAT_ABGR2101010; + case __DRI_IMAGE_FOURCC_SABGR8888: + return __DRI_IMAGE_FORMAT_SABGR8; + case DRM_FORMAT_UYVY: + return __DRI_IMAGE_FORMAT_UYVY; + case DRM_FORMAT_ARGB4444: + return __DRI_IMAGE_FORMAT_ARGB4444; + case DRM_FORMAT_YVU444_PACK10_IMG: + return __DRI_IMAGE_FORMAT_YVU444_PACK10_IMG; + case DRM_FORMAT_BGR888: + return __DRI_IMAGE_FORMAT_BGR888; + default: + __driUtilMessage("%s: Unknown format: %d", __func__, iFourCC); + break; + } + + return 0; +} diff --git a/src/mesa/drivers/dri/pvr/pvrutil_mod.c b/src/mesa/drivers/dri/pvr/pvrutil_mod.c new file mode 100644 index 00000000000..5b05eb76b01 --- /dev/null +++ b/src/mesa/drivers/dri/pvr/pvrutil_mod.c @@ -0,0 +1,921 @@ +/* + * 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 +#include +#include + +#include "img_drm_fourcc.h" +#include "pvrdri_mod.h" + +/* + * The following sRGB formats defined may not be defined in drm_fourcc.h, but + * match the corresponding __DRI_IMAGE_FOURCC formats in Mesa. + */ +#if !defined(DRM_FORMAT_SARGB8888) +#define DRM_FORMAT_SARGB8888 0x83324258 +#endif + +#if !defined(DRM_FORMAT_SABGR8888) +#define DRM_FORMAT_SABGR8888 0x84324258 +#endif + +#if !defined(DRM_FORMAT_SBGR888) +#define DRM_FORMAT_SBGR888 0xff324742 +#endif + +static const PVRDRIImageFormat g_asFormats[] = { + { + .eIMGPixelFormat = IMG_PIXFMT_R10G10B10A2_UNORM, + .iDRIFourCC = DRM_FORMAT_ABGR2101010, + .iDRIComponents = PVRDRI_IMAGE_COMPONENTS_RGBA, + .uiNumPlanes = 1, + .sPlanes[0] = { + .eIMGPixelFormat = IMG_PIXFMT_R10G10B10A2_UNORM, + .uiWidthShift = 0, + .uiHeightShift = 0}, + }, + { + .eIMGPixelFormat = IMG_PIXFMT_B8G8R8A8_UNORM, + .iDRIFourCC = DRM_FORMAT_ARGB8888, + .iDRIComponents = PVRDRI_IMAGE_COMPONENTS_RGBA, + .uiNumPlanes = 1, + .sPlanes[0] = { + .eIMGPixelFormat = IMG_PIXFMT_B8G8R8A8_UNORM, + .uiWidthShift = 0, + .uiHeightShift = 0}, + }, + { + .eIMGPixelFormat = IMG_PIXFMT_B8G8R8A8_UNORM_SRGB, + .iDRIFourCC = DRM_FORMAT_SARGB8888, + .iDRIComponents = PVRDRI_IMAGE_COMPONENTS_RGBA, + .bIsSRGB = true, + .uiNumPlanes = 1, + .sPlanes[0] = { + .eIMGPixelFormat = IMG_PIXFMT_B8G8R8A8_UNORM_SRGB, + .uiWidthShift = 0, + .uiHeightShift = 0}, + }, + { + .eIMGPixelFormat = IMG_PIXFMT_R8G8B8A8_UNORM, + .iDRIFourCC = DRM_FORMAT_ABGR8888, + .iDRIComponents = PVRDRI_IMAGE_COMPONENTS_RGBA, + .uiNumPlanes = 1, + .sPlanes[0] = { + .eIMGPixelFormat = IMG_PIXFMT_R8G8B8A8_UNORM, + .uiWidthShift = 0, + .uiHeightShift = 0}, + }, + { + .eIMGPixelFormat = IMG_PIXFMT_R8G8B8A8_UNORM_SRGB, + .iDRIFourCC = DRM_FORMAT_SABGR8888, + .iDRIComponents = PVRDRI_IMAGE_COMPONENTS_RGBA, + .bIsSRGB = true, + .uiNumPlanes = 1, + .sPlanes[0] = { + .eIMGPixelFormat = IMG_PIXFMT_R8G8B8A8_UNORM_SRGB, + .uiWidthShift = 0, + .uiHeightShift = 0}, + }, + { + .eIMGPixelFormat = IMG_PIXFMT_B8G8R8X8_UNORM, + .iDRIFourCC = DRM_FORMAT_XRGB8888, + .iDRIComponents = PVRDRI_IMAGE_COMPONENTS_RGB, + .uiNumPlanes = 1, + .sPlanes[0] = { + .eIMGPixelFormat = IMG_PIXFMT_B8G8R8X8_UNORM, + .uiWidthShift = 0, + .uiHeightShift = 0}, + }, + { + .eIMGPixelFormat = IMG_PIXFMT_R8G8B8X8_UNORM, + .iDRIFourCC = DRM_FORMAT_XBGR8888, + .iDRIComponents = PVRDRI_IMAGE_COMPONENTS_RGB, + .uiNumPlanes = 1, + .sPlanes[0] = { + .eIMGPixelFormat = IMG_PIXFMT_R8G8B8X8_UNORM, + .uiWidthShift = 0, + .uiHeightShift = 0}, + }, + { + .eIMGPixelFormat = IMG_PIXFMT_R8G8B8_UNORM, + .iDRIFourCC = DRM_FORMAT_BGR888, + .iDRIComponents = PVRDRI_IMAGE_COMPONENTS_RGB, + .uiNumPlanes = 1, + .sPlanes[0] = { + .eIMGPixelFormat = IMG_PIXFMT_R8G8B8_UNORM, + .uiWidthShift = 0, + .uiHeightShift = 0}, + }, +#if defined(DRM_FORMAT_SBGR888) + { + .eIMGPixelFormat = IMG_PIXFMT_R8G8B8_UNORM_SRGB, + .iDRIFourCC = DRM_FORMAT_SBGR888, + .iDRIComponents = PVRDRI_IMAGE_COMPONENTS_RGB, + .bIsSRGB = true, + .uiNumPlanes = 1, + .sPlanes[0] = { + .eIMGPixelFormat = IMG_PIXFMT_R8G8B8_UNORM_SRGB, + .uiWidthShift = 0, + .uiHeightShift = 0}, + }, +#endif + { + .eIMGPixelFormat = IMG_PIXFMT_B5G6R5_UNORM, + .iDRIFourCC = DRM_FORMAT_RGB565, + .iDRIComponents = PVRDRI_IMAGE_COMPONENTS_RGB, + .uiNumPlanes = 1, + .sPlanes[0] = { + .eIMGPixelFormat = IMG_PIXFMT_B5G6R5_UNORM, + .uiWidthShift = 0, + .uiHeightShift = 0}, + }, + { + .eIMGPixelFormat = IMG_PIXFMT_R8G8_UNORM, + .iDRIFourCC = DRM_FORMAT_GR88, + .iDRIComponents = PVRDRI_IMAGE_COMPONENTS_RG, + .uiNumPlanes = 1, + .sPlanes[0] = { + .eIMGPixelFormat = IMG_PIXFMT_R8G8_UNORM, + .uiWidthShift = 0, + .uiHeightShift = 0}, + }, + { + .eIMGPixelFormat = IMG_PIXFMT_R8_UNORM, + .iDRIFourCC = DRM_FORMAT_R8, + .iDRIComponents = PVRDRI_IMAGE_COMPONENTS_R, + .uiNumPlanes = 1, + .sPlanes[0] = { + .eIMGPixelFormat = IMG_PIXFMT_R8_UNORM, + .uiWidthShift = 0, + .uiHeightShift = 0}, + }, + { + .eIMGPixelFormat = IMG_PIXFMT_L8A8_UNORM, + .iDRIFourCC = 0, + .iDRIComponents = 0, + .uiNumPlanes = 1, + .sPlanes[0] = { + .eIMGPixelFormat = IMG_PIXFMT_L8A8_UNORM, + .uiWidthShift = 0, + .uiHeightShift = 0}, + }, + { + .eIMGPixelFormat = IMG_PIXFMT_L8_UNORM, + .iDRIFourCC = 0, + .iDRIComponents = 0, + .uiNumPlanes = 1, + .sPlanes[0] = { + .eIMGPixelFormat = IMG_PIXFMT_L8_UNORM, + .uiWidthShift = 0, + .uiHeightShift = 0}, + }, + { + .eIMGPixelFormat = IMG_PIXFMT_D32_FLOAT, + .iDRIFourCC = 0, + .iDRIComponents = 0, + .uiNumPlanes = 1, + .sPlanes[0] = { + .eIMGPixelFormat = IMG_PIXFMT_D32_FLOAT, + .uiWidthShift = 0, + .uiHeightShift = 0}, + }, + { + .eIMGPixelFormat = IMG_PIXFMT_S8_UINT, + .iDRIFourCC = 0, + .iDRIComponents = 0, + .uiNumPlanes = 1, + .sPlanes[0] = { + .eIMGPixelFormat = IMG_PIXFMT_S8_UINT, + .uiWidthShift = 0, + .uiHeightShift = 0}, + }, +#if defined(DRM_FORMAT_ARGB4444) + { + .eIMGPixelFormat = IMG_PIXFMT_B4G4R4A4_UNORM, + .iDRIFourCC = DRM_FORMAT_ARGB4444, + .iDRIComponents = PVRDRI_IMAGE_COMPONENTS_RGBA, + .uiNumPlanes = 1, + .sPlanes[0] = { + .eIMGPixelFormat = IMG_PIXFMT_B4G4R4A4_UNORM, + .uiWidthShift = 0, + .uiHeightShift = 0}, + }, +#endif +#if defined(DRM_FORMAT_ARGB1555) + { + .eIMGPixelFormat = IMG_PIXFMT_B5G5R5A1_UNORM, + .iDRIFourCC = DRM_FORMAT_ARGB1555, + .iDRIComponents = PVRDRI_IMAGE_COMPONENTS_RGBA, + .uiNumPlanes = 1, + .sPlanes[0] = { + .eIMGPixelFormat = IMG_PIXFMT_B5G5R5A1_UNORM, + .uiWidthShift = 0, + .uiHeightShift = 0}, + }, +#endif + { + .eIMGPixelFormat = IMG_PIXFMT_YUYV, + .iDRIFourCC = DRM_FORMAT_YUYV, + .iDRIComponents = PVRDRI_IMAGE_COMPONENTS_EXTERNAL, + .uiNumPlanes = 1, + .sPlanes[0] = { + .eIMGPixelFormat = IMG_PIXFMT_YUYV, + .uiWidthShift = 0, + .uiHeightShift = 0}, + }, +#if defined(DRM_FORMAT_YVU444_PACK10_IMG) + { + .eIMGPixelFormat = IMG_PIXFMT_YVU10_444_1PLANE_PACK10, + .iDRIFourCC = DRM_FORMAT_YVU444_PACK10_IMG, + .iDRIComponents = PVRDRI_IMAGE_COMPONENTS_EXTERNAL, + .uiNumPlanes = 1, + .sPlanes[0] = { + .eIMGPixelFormat = IMG_PIXFMT_YVU10_444_1PLANE_PACK10, + .uiWidthShift = 0, + .uiHeightShift = 0, + }, + }, +#endif + { + .eIMGPixelFormat = IMG_PIXFMT_YUV420_2PLANE, + .iDRIFourCC = DRM_FORMAT_NV12, + .iDRIComponents = PVRDRI_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(DRM_FORMAT_NV21) + { + .eIMGPixelFormat = IMG_PIXFMT_YVU420_2PLANE, + .iDRIFourCC = DRM_FORMAT_NV21, + .iDRIComponents = PVRDRI_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 = DRM_FORMAT_YUV420, + .iDRIComponents = PVRDRI_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 = DRM_FORMAT_YVU420, + .iDRIComponents = PVRDRI_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_YUV8_444_3PLANE_PACK8, + .iDRIFourCC = DRM_FORMAT_YUV444, + .iDRIComponents = PVRDRI_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 = 0, + .uiHeightShift = 0}, + .sPlanes[2] = { + .eIMGPixelFormat = IMG_PIXFMT_R8_UNORM, + .uiWidthShift = 0, + .uiHeightShift = 0}, + }, + { + .eIMGPixelFormat = IMG_PIXFMT_D16_UNORM, + .iDRIFourCC = 0, + .iDRIComponents = 0, + .uiNumPlanes = 1, + .sPlanes[0] = { + .eIMGPixelFormat = IMG_PIXFMT_D16_UNORM, + .uiWidthShift = 0, + .uiHeightShift = 0}, + }, + { + .eIMGPixelFormat = IMG_PIXFMT_D24_UNORM_X8_TYPELESS, + .iDRIFourCC = 0, + .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 struct DRISUPScreen *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; +} + +const struct __DRIconfigRec ** +PVRDRICreateConfigs(const struct DRISUPScreen *psPVRScreen) +{ + static const unsigned int auBackBufferModes[] = { + PVRDRI_ATTRIB_SWAP_NONE, + PVRDRI_ATTRIB_SWAP_UNDEFINED, + }; + const uint8_t *puDepthBits = PVRDRIDepthBitsArray(); + const uint8_t *puStencilBits = PVRDRIStencilBitsArray(); + const uint8_t *puMSAASamples = PVRDRIMSAABitsArray(); + const unsigned int uNumBackBufferModes = ARRAY_SIZE(auBackBufferModes); + const unsigned int uNumDepthStencilBits = + PVRDRIDepthStencilBitArraySize(); + const unsigned int uNumMSAASamples = PVRDRIMSAABitArraySize(); + struct __DRIconfigRec **ppsConfigs = NULL; + struct __DRIconfigRec **ppsNewConfigs; + unsigned int i; + + for (i = 0; i < psPVRScreen->uNumMesaFormats; i++) { + if (!MODSUPCreateConfigs(&ppsNewConfigs, psPVRScreen->psDRIScreen, + psPVRScreen->puMesaFormats[i], + puDepthBits, puStencilBits, + uNumDepthStencilBits, + auBackBufferModes, uNumBackBufferModes, + puMSAASamples, uNumMSAASamples, + false, false, false, + PVRDRI_YUV_DEPTH_RANGE_NONE, + PVRDRI_YUV_CSC_STANDARD_NONE, + PVRDRIMaxPBufferWidth(), + PVRDRIMaxPBufferHeight())) { + __driUtilMessage("%s: Couldn't create DRI configs", __func__); + return NULL; + } + + ppsConfigs = MODSUPConcatConfigs(psPVRScreen->psDRIScreen, + ppsConfigs, ppsNewConfigs); + } + + return (const struct __DRIconfigRec **) ppsConfigs; +} + +const PVRDRIImageFormat * +PVRDRIFourCCToImageFormat(struct DRISUPScreen *psPVRScreen, int iDRIFourCC) +{ + unsigned int 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(struct DRISUPScreen *psPVRScreen, + IMG_PIXFMT eIMGPixelFormat) +{ + unsigned int 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, + unsigned int uDRIColourSpace, + unsigned int uDRISampleRange) +{ + switch (psFormat->iDRIComponents) { + case PVRDRI_IMAGE_COMPONENTS_R: + case PVRDRI_IMAGE_COMPONENTS_RG: + case PVRDRI_IMAGE_COMPONENTS_RGB: + case PVRDRI_IMAGE_COMPONENTS_RGBA: + return IMG_COLORSPACE_UNDEFINED; + case PVRDRI_IMAGE_COMPONENTS_Y_U_V: + case PVRDRI_IMAGE_COMPONENTS_Y_UV: + case PVRDRI_IMAGE_COMPONENTS_Y_XUXV: + case PVRDRI_IMAGE_COMPONENTS_EXTERNAL: + break; + default: + errorMessage("%s: Unrecognised DRI components (components = 0x%X)", + __func__, psFormat->iDRIComponents); + unreachable("unhandled DRI component"); + return IMG_COLORSPACE_UNDEFINED; + } + + switch (uDRIColourSpace) { + case PVRDRI_YUV_COLOR_SPACE_UNDEFINED: + case PVRDRI_YUV_COLOR_SPACE_ITU_REC601: + switch (uDRISampleRange) { + case PVRDRI_YUV_RANGE_UNDEFINED: + case PVRDRI_YUV_NARROW_RANGE: + return IMG_COLORSPACE_BT601_CONFORMANT_RANGE; + case PVRDRI_YUV_FULL_RANGE: + return IMG_COLORSPACE_BT601_FULL_RANGE; + default: + errorMessage ("%s: Unrecognised DRI sample range (sample range = 0x%X)", + __func__, uDRISampleRange); + unreachable("unhandled sample range"); + return IMG_COLORSPACE_UNDEFINED; + } + case PVRDRI_YUV_COLOR_SPACE_ITU_REC709: + switch (uDRISampleRange) { + case PVRDRI_YUV_RANGE_UNDEFINED: + case PVRDRI_YUV_NARROW_RANGE: + return IMG_COLORSPACE_BT709_CONFORMANT_RANGE; + case PVRDRI_YUV_FULL_RANGE: + return IMG_COLORSPACE_BT709_FULL_RANGE; + default: + errorMessage ("%s: Unrecognised DRI sample range (sample range = 0x%X)", + __func__, uDRISampleRange); + unreachable("unhandled sample range"); + return IMG_COLORSPACE_UNDEFINED; + } + case PVRDRI_YUV_COLOR_SPACE_ITU_REC2020: + switch (uDRISampleRange) { + case PVRDRI_YUV_RANGE_UNDEFINED: + case PVRDRI_YUV_NARROW_RANGE: + return IMG_COLORSPACE_BT2020_CONFORMANT_RANGE; + case PVRDRI_YUV_FULL_RANGE: + return IMG_COLORSPACE_BT2020_FULL_RANGE; + default: + errorMessage ("%s: Unrecognised DRI sample range (sample range = 0x%X)", + __func__, uDRISampleRange); + assert(0); + return IMG_COLORSPACE_UNDEFINED; + } + default: + errorMessage ("%s: Unrecognised DRI color space (color space = 0x%X)", + __func__, uDRIColourSpace); + unreachable("unhandled color space"); + return IMG_COLORSPACE_UNDEFINED; + } +} + +IMG_YUV_CHROMA_INTERP +PVRDRIChromaSittingToIMGInterp(const PVRDRIImageFormat *psFormat, + unsigned int uChromaSitting) +{ + switch (psFormat->iDRIComponents) { + case PVRDRI_IMAGE_COMPONENTS_R: + case PVRDRI_IMAGE_COMPONENTS_RG: + case PVRDRI_IMAGE_COMPONENTS_RGB: + case PVRDRI_IMAGE_COMPONENTS_RGBA: + return IMG_CHROMA_INTERP_UNDEFINED; + case PVRDRI_IMAGE_COMPONENTS_Y_U_V: + case PVRDRI_IMAGE_COMPONENTS_Y_UV: + case PVRDRI_IMAGE_COMPONENTS_Y_XUXV: + case PVRDRI_IMAGE_COMPONENTS_EXTERNAL: + break; + default: + errorMessage("%s: Unrecognised DRI components (components = 0x%X)", + __func__, psFormat->iDRIComponents); + unreachable("unhandled dri component"); + return IMG_CHROMA_INTERP_UNDEFINED; + } + + switch (uChromaSitting) { + case PVRDRI_YUV_CHROMA_SITING_UNDEFINED: + case PVRDRI_YUV_CHROMA_SITING_0: + return IMG_CHROMA_INTERP_ZERO; + case PVRDRI_YUV_CHROMA_SITING_0_5: + return IMG_CHROMA_INTERP_HALF; + default: + errorMessage ("%s: Unrecognised DRI chroma sitting (chroma sitting = 0x%X)", + __func__, uChromaSitting); + unreachable("unhandled chroma sitting"); + return IMG_CHROMA_INTERP_UNDEFINED; + } +} + +bool +PVRDRIGetSupportedFormats(struct DRISUPScreen *psPVRScreen) +{ + int *piFormats; + IMG_PIXFMT *peImgFormats; + bool bRet = false; + unsigned int 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("%s: Out of memory", __func__); + goto err_free; + } + + for (i = 0; i < ARRAY_SIZE(g_asFormats); i++) { + piFormats[i] = 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("%s: Couldn't query supported pixel formats", + __func__); + 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; +} + +bool +DRIMODQueryDMABufFormats(struct DRISUPScreen *psPVRScreen, int iMax, + int *piFormats, int *piCount) +{ + int iLim; + unsigned int i; + int j; + + assert(psPVRScreen->iNumFormats != 0); + + if (psPVRScreen->iNumFormats < 0) + return false; + + iLim = (iMax) ? iMax : psPVRScreen->iNumFormats; + + for (i = 0, j = 0; i < ARRAY_SIZE(g_asFormats) && j < iLim; i++) { + /* + * SRGB formats don't map to DRM formats, as defined by drm_fourcc.h, so + * should not be returned. + */ + if (g_asFormats[i].bIsSRGB) + continue; + + if (psPVRScreen->pbHasFormat[i] && g_asFormats[i].iDRIFourCC) { + if (iMax) + piFormats[j] = g_asFormats[i].iDRIFourCC; + j++; + } + } + + *piCount = j; + + return true; +} + +static bool +PVRDRIGetSupportedModifiers(struct DRISUPScreen *psPVRScreen, + struct PVRDRIModifiers *psModifiers, + const PVRDRIImageFormat *psFormat) +{ + int iNumModifiers; + + iNumModifiers = PVRDRIQueryModifiers(psPVRScreen->psImpl, + psFormat->iDRIFourCC, + psFormat->eIMGPixelFormat, + NULL, NULL); + if (iNumModifiers < 0) { + errorMessage("%s: Couldn't query modifiers for format 0x%x", + __func__, 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("%s: Out of memory", __func__); + + 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(struct DRISUPScreen *psPVRScreen, int iFourCC, + const PVRDRIImageFormat **ppsFormat, + const struct PVRDRIModifiers **ppsModifiers) +{ + const PVRDRIImageFormat *psFormat; + struct PVRDRIModifiers *psModifiers; + unsigned int uIdx; + + assert(psPVRScreen->iNumFormats != 0); + + if (psPVRScreen->iNumFormats < 0) + return false; + + psFormat = PVRDRIFourCCToImageFormat(psPVRScreen, iFourCC); + 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(struct DRISUPScreen *psPVRScreen, + const int iFourCC, const uint64_t uiModifier) +{ + const PVRDRIImageFormat *psFormat; + const struct PVRDRIModifiers *psModifiers; + + if (!PVRDRIGetModifiersForFormat(psPVRScreen, iFourCC, &psFormat, + &psModifiers)) + return false; + + for (int i = 0; i < psModifiers->iNumModifiers; i++) + if (psModifiers->puModifiers[i] == uiModifier) + return true; + + return false; +} + +bool +DRIMODQueryDMABufModifiers(struct DRISUPScreen *psPVRScreen, int iFourCC, + int iMax, uint64_t *puModifiers, + unsigned int *puExternalOnly, int *piCount) +{ + const PVRDRIImageFormat *psFormat; + const struct PVRDRIModifiers *psModifiers; + int iNumCopy; + + if (!PVRDRIGetModifiersForFormat(psPVRScreen, iFourCC, &psFormat, + &psModifiers)) + return false; + + if (!iMax) { + *piCount = psModifiers->iNumModifiers; + return true; + } + + iNumCopy = (iMax < psModifiers->iNumModifiers) ? + iMax : psModifiers->iNumModifiers; + + if (puModifiers) + (void) memcpy(puModifiers, psModifiers->puModifiers, + sizeof(*puModifiers) * iNumCopy); + + if (puExternalOnly) + (void) memcpy(puExternalOnly, psModifiers->puExternalOnly, + sizeof(*puExternalOnly) * iNumCopy); + + *piCount = iNumCopy; + + return true; +} + +bool +DRIMODQueryDMABufFormatModifierAttribs(struct DRISUPScreen *psPVRScreen, + uint32_t uFourCC, uint64_t uModifier, + int iAttribute, uint64_t *puValue) +{ + const PVRDRIImageFormat *psFormat; + const struct PVRDRIModifiers *psModifiers; + int i; + + if (!PVRDRIGetModifiersForFormat(psPVRScreen, uFourCC, &psFormat, + &psModifiers)) + return false; + + for (i = 0; i < psModifiers->iNumModifiers; i++) + if (psModifiers->puModifiers[i] == uModifier) + break; + + if (i == psModifiers->iNumModifiers) + return false; + + switch (iAttribute) { + case PVRDRI_IMAGE_FORMAT_MODIFIER_ATTRIB_PLANE_COUNT: + *puValue = psFormat->uiNumPlanes; + break; + default: + return false; + } + + return true; +} + +void +PVRDRIDestroyFormatInfo(struct DRISUPScreen *psPVRScreen) +{ + unsigned int 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); +} + +bool +PVRDRIGetMesaFormats(struct DRISUPScreen *psPVRScreen) +{ + const unsigned int auMesaFormatsBase[] = { + PVRDRI_MESA_FORMAT_B8G8R8A8_UNORM, + PVRDRI_MESA_FORMAT_B8G8R8A8_SRGB, + PVRDRI_MESA_FORMAT_B8G8R8X8_UNORM, + PVRDRI_MESA_FORMAT_B5G6R5_UNORM, + }; + const unsigned int auMesaFormatsRGB[] = { + PVRDRI_MESA_FORMAT_R8G8B8A8_UNORM, + PVRDRI_MESA_FORMAT_R8G8B8A8_SRGB, + PVRDRI_MESA_FORMAT_R8G8B8X8_UNORM, + }; + unsigned int uSizeMesaFormats; + bool bCapRGB; + unsigned int i, j; + + bCapRGB = MODSUPGetCapability(psPVRScreen->psDRIScreen, + PVRDRI_LOADER_CAP_RGBA_ORDERING) != 0; + + uSizeMesaFormats = sizeof(auMesaFormatsBase); + if (bCapRGB) + uSizeMesaFormats += sizeof(auMesaFormatsRGB); + + /* + * We haven't checked if any of the Mesa formats are supported by the DDK + * at this point, so we may allocate more memory than we need. + */ + psPVRScreen->puMesaFormats = malloc(uSizeMesaFormats); + if (psPVRScreen->puMesaFormats == NULL) { + __driUtilMessage("%s: Out of memory", __func__); + return false; + } + + for (i = 0, j = 0; i < ARRAY_SIZE(auMesaFormatsBase); i++) { + unsigned int uMesaFormat = auMesaFormatsBase[i]; + + if (!PVRDRIMesaFormatSupported(uMesaFormat)) + continue; + + psPVRScreen->puMesaFormats[j++] = uMesaFormat; + } + + if (bCapRGB) { + for (i = 0; i < ARRAY_SIZE(auMesaFormatsRGB); i++) { + unsigned int uMesaFormat = auMesaFormatsRGB[i]; + + if (!PVRDRIMesaFormatSupported(uMesaFormat)) + continue; + + psPVRScreen->puMesaFormats[j++] = uMesaFormat; + } + } + + assert((j * sizeof(psPVRScreen->puMesaFormats[0])) <= + uSizeMesaFormats); + + psPVRScreen->uNumMesaFormats = j; + + return true; +} + +void +PVRDRIFreeMesaFormats(struct DRISUPScreen *psPVRScreen) +{ + free(psPVRScreen->puMesaFormats); +} diff --git a/src/meson.build b/src/meson.build index 84a990358a3..d96c754a63d 100644 --- a/src/meson.build +++ b/src/meson.build @@ -25,6 +25,7 @@ inc_gallium = include_directories('gallium/include') inc_gallium_aux = include_directories('gallium/auxiliary') inc_amd_common = include_directories('amd/common') inc_amd_common_llvm = include_directories('amd/llvm') +inc_pvr = include_directories('mesa/main', 'mapi/glapi') libglsl_util = static_library( 'glsl_util', -- 2.17.1