Add Wayland with GPU support.

Cherry-pick from http://192.168.110.45/sdk/buildroot/-/commit/ed70e2b79cbc7a504792899e2cd3577777fd54bd
This commit is contained in:
Windsome Zeng
2022-06-21 14:08:48 +08:00
parent 9234eab162
commit c50e5ba7a5
65 changed files with 21691 additions and 250 deletions
File diff suppressed because it is too large Load Diff
@@ -1,30 +0,0 @@
From 705490763fcc052defa2d49a5c5200775cd12c54 Mon Sep 17 00:00:00 2001
From: Peter Seiderer <ps.report@gmx.net>
Date: Wed, 4 Mar 2020 08:27:24 +0100
Subject: [PATCH] c99_math: import isinf for uclibc based toolchains
The same fix as for glibc >= 2.23 is needed for uclibc
based toolchains.
[Upstream suggested: https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4042]
Signed-off-by: Peter Seiderer <ps.report@gmx.net>
---
include/c99_math.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/c99_math.h b/include/c99_math.h
index e906c26aa54..c8a73a2d2c7 100644
--- a/include/c99_math.h
+++ b/include/c99_math.h
@@ -190,7 +190,7 @@ fpclassify(double x)
* undefines those functions, which in glibc 2.23, are defined as macros rather
* than functions as in glibc 2.22.
*/
-#if __cplusplus >= 201103L && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 23))
+#if __cplusplus >= 201103L && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 23) || defined(__UCLIBC__))
#include <cmath>
using std::fpclassify;
--
2.25.1
@@ -0,0 +1,34 @@
From dbbfc6aadf0c6b40c47b325bf9bb35cf1d552d9c Mon Sep 17 00:00:00 2001
From: Frank Binns <frank.binns@imgtec.com>
Date: Wed, 17 Jun 2015 15:37:18 +0100
Subject: [PATCH 02/50] Force Mesa to use the PVR driver for platform devices
For platform devices, Mesa uses the DRM driver name to determine which DRI
driver to load. This doesn't work in the multi-DRM driver model where there
are separate DRM drivers for the display and GPU. This is because we normally
want Mesa to deal with the display driver and the name of this won't match
that of the DRI driver. For the time being, take the easy approach and just
force it to use the PVR DRI driver.
---
src/loader/loader.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/loader/loader.c b/src/loader/loader.c
index d64bc7c10f2..cfadecf02b4 100644
--- a/src/loader/loader.c
+++ b/src/loader/loader.c
@@ -436,7 +436,11 @@ loader_get_pci_driver(int fd)
char *driver = NULL;
if (!loader_get_pci_id_for_fd(fd, &vendor_id, &chip_id))
+#if 1
+ return strdup("pvr");
+#else
return NULL;
+#endif
for (i = 0; i < ARRAY_SIZE(driver_map); i++) {
if (vendor_id != driver_map[i].vendor_id)
--
2.17.1
@@ -1,41 +0,0 @@
From 7b46756a99aca7f27a45c3b99460f088570f6f53 Mon Sep 17 00:00:00 2001
From: Romain Naour <romain.naour@smile.fr>
Date: Wed, 17 Apr 2019 23:07:42 +0200
Subject: [PATCH] meson: Set proper value for LIBCLC_INCLUDEDIR
LIBCLC_INCLUDEDIR is the location where mesa3d OpenCL implementation
will look for OpenCL "headers" on the target, when building the OpenCL
kernels.
The value returned by pkg-config for includedir is relevant when
cross-compiling, on the build machine. But in this specific case, we
really need a value that is valid on the target.
Those headers are installed by the libclc package in /usr/share so
that they are not removed by Buildroot target-finalize logic.
Based on the patch for autotools provided by Valentin Korenblit.
Signed-off-by: Romain Naour <romain.naour@smile.fr>
Signed-off-by: Bernd Kuhls <bernd.kuhls@t-online.de>
[rebased for 20.2.0 & 20.3.0]
---
src/gallium/frontends/clover/meson.build | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/gallium/frontends/clover/meson.build b/src/gallium/frontends/clover/meson.build
index 62ac5f5278d..ecdeb39669c 100644
--- a/src/gallium/frontends/clover/meson.build
+++ b/src/gallium/frontends/clover/meson.build
@@ -27,7 +27,7 @@
'-DCL_USE_DEPRECATED_OPENCL_2_0_APIS',
'-DCL_USE_DEPRECATED_OPENCL_2_1_APIS',
'-DCL_USE_DEPRECATED_OPENCL_2_2_APIS',
- '-DLIBCLC_INCLUDEDIR="@0@/"'.format(dep_clc.get_variable(pkgconfig : 'includedir')),
+ '-DLIBCLC_INCLUDEDIR="/usr/share"',
'-DLIBCLC_LIBEXECDIR="@0@/"'.format(dep_clc.get_variable(pkgconfig : 'libexecdir'))
]
clover_spirv_cpp_args = []
--
2.20.1
@@ -0,0 +1,80 @@
From 94cfbd20ea72aac430abf5097133b1356c0a52a1 Mon Sep 17 00:00:00 2001
From: Frank Binns <frank.binns@imgtec.com>
Date: Thu, 5 Jun 2014 12:07:01 +0100
Subject: [PATCH 03/50] dri: Add some new DRI formats and fourccs
Add ARGB4444 DRI format and fourcc.
Add YVU444_PACK10_IMG DRI format and fourcc.
Add BGR888 DRI format and fourcc.
---
include/GL/internal/dri_interface.h | 4 ++++
include/drm-uapi/drm_fourcc.h | 1 +
src/egl/drivers/dri2/egl_dri2.c | 1 +
src/mesa/drivers/dri/common/dri_util.c | 5 +++++
4 files changed, 11 insertions(+)
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index 9b85e67ce49..e668798e87f 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -1366,6 +1366,9 @@ struct __DRIdri2ExtensionRec {
#define __DRI_IMAGE_FORMAT_XBGR16161616F 0x1014
#define __DRI_IMAGE_FORMAT_ABGR16161616F 0x1015
#define __DRI_IMAGE_FORMAT_SXRGB8 0x1016
+#define __DRI_IMAGE_FORMAT_ARGB4444 0x1017
+#define __DRI_IMAGE_FORMAT_YVU444_PACK10_IMG 0x1018
+#define __DRI_IMAGE_FORMAT_BGR888 0x1019
#define __DRI_IMAGE_USE_SHARE 0x0001
#define __DRI_IMAGE_USE_SCANOUT 0x0002
@@ -1395,6 +1398,7 @@ struct __DRIdri2ExtensionRec {
#define __DRI_IMAGE_FOURCC_SARGB8888 0x83324258
#define __DRI_IMAGE_FOURCC_SABGR8888 0x84324258
#define __DRI_IMAGE_FOURCC_SXRGB8888 0x85324258
+#define __DRI_IMAGE_FOURCC_SBGR888 0xff324742
/**
* Queryable on images created by createImageFromNames.
diff --git a/include/drm-uapi/drm_fourcc.h b/include/drm-uapi/drm_fourcc.h
index 3f9c8110355..8af9b16ff88 100644
--- a/include/drm-uapi/drm_fourcc.h
+++ b/include/drm-uapi/drm_fourcc.h
@@ -307,6 +307,7 @@ extern "C" {
#define DRM_FORMAT_YUV444 fourcc_code('Y', 'U', '2', '4') /* non-subsampled Cb (1) and Cr (2) planes */
#define DRM_FORMAT_YVU444 fourcc_code('Y', 'V', '2', '4') /* non-subsampled Cr (1) and Cb (2) planes */
+#define DRM_FORMAT_YVU444_PACK10_IMG fourcc_code('I', 'M', 'G', '2')
/*
* Format Modifiers:
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index 62fc7fb7783..4f52985c48e 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -2659,6 +2659,7 @@ dri2_num_fourcc_format_planes(EGLint format)
case DRM_FORMAT_VYUY:
case DRM_FORMAT_AYUV:
case DRM_FORMAT_XYUV8888:
+ case DRM_FORMAT_YVU444_PACK10_IMG:
return 1;
case DRM_FORMAT_NV12:
diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c
index e2a11240dea..caed5fa6a68 100644
--- a/src/mesa/drivers/dri/common/dri_util.c
+++ b/src/mesa/drivers/dri/common/dri_util.c
@@ -904,6 +904,11 @@ static const struct {
.mesa_format = MESA_FORMAT_B5G5R5A1_UNORM,
.internal_format = GL_RGB5_A1,
},
+ {
+ .image_format = __DRI_IMAGE_FORMAT_ARGB4444,
+ .mesa_format = MESA_FORMAT_B4G4R4A4_UNORM,
+ .internal_format = GL_RGBA4,
+ },
{
.image_format = __DRI_IMAGE_FORMAT_XRGB8888,
.mesa_format = MESA_FORMAT_B8G8R8X8_UNORM,
--
2.17.1
@@ -1,84 +0,0 @@
From e3b47c1b84964c62b3e1fa782f1ffa4be0ae62f9 Mon Sep 17 00:00:00 2001
From: Peter Seiderer <ps.report@gmx.net>
Date: Mon, 9 Mar 2020 13:01:14 +0100
Subject: [PATCH] vc4: add meson option to disable optional neon support
Not all toolchains are able to compile the runtime
optional vc4 neon support, so add an meson option
to force disabling it at compile time.
[Upstream: https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4114]
Signed-off-by: Peter Seiderer <ps.report@gmx.net>
Signed-off-by: Bernd Kuhls <bernd.kuhls@t-online.de>
[rebased for 20.2.0, 20.3.0 & 21.1.0]
---
meson_options.txt | 7 +++++++
src/gallium/drivers/vc4/meson.build | 4 ++--
src/gallium/drivers/vc4/vc4_tiling.h | 4 ++--
3 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/meson_options.txt b/meson_options.txt
index a39596a6f19..0f6b6c62b55 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -123,6 +123,13 @@ option(
choices : ['auto', 'true', 'false', 'enabled', 'disabled'],
description : 'enable gallium va frontend.',
)
+option(
+ 'gallium-vc4-neon',
+ type : 'combo',
+ value : 'auto',
+ choices : ['auto', 'disabled'],
+ description : 'enable gallium vc4 optional neon support.',
+)
option(
'va-libs-path',
type : 'string',
diff --git a/src/gallium/drivers/vc4/meson.build b/src/gallium/drivers/vc4/meson.build
index 5ce5af5f6b4..e3f7d8d62ae 100644
--- a/src/gallium/drivers/vc4/meson.build
+++ b/src/gallium/drivers/vc4/meson.build
@@ -84,7 +84,7 @@ files_libvc4 = files(
vc4_c_args = []
libvc4_neon = []
-if host_machine.cpu_family() == 'arm'
+if host_machine.cpu_family() == 'arm' and get_option('gallium-vc4-neon') != 'disabled'
libvc4_neon = static_library(
'vc4_neon',
'vc4_tiling_lt_neon.c',
@@ -93,7 +93,7 @@ if host_machine.cpu_family() == 'arm'
],
c_args : '-mfpu=neon',
)
- vc4_c_args += '-DUSE_ARM_ASM'
+ vc4_c_args += '-DVC4_TILING_LT_NEON'
endif
if dep_simpenrose.found()
diff --git a/src/gallium/drivers/vc4/vc4_tiling.h b/src/gallium/drivers/vc4/vc4_tiling.h
index 66767e7f1f8..7446f1c3d0c 100644
--- a/src/gallium/drivers/vc4/vc4_tiling.h
+++ b/src/gallium/drivers/vc4/vc4_tiling.h
@@ -89,7 +89,7 @@ vc4_load_lt_image(void *dst, uint32_t dst_stride,
void *src, uint32_t src_stride,
int cpp, const struct pipe_box *box)
{
-#ifdef USE_ARM_ASM
+#ifdef VC4_TILING_LT_NEON
if (util_get_cpu_caps()->has_neon) {
vc4_load_lt_image_neon(dst, dst_stride, src, src_stride,
cpp, box);
@@ -105,7 +105,7 @@ vc4_store_lt_image(void *dst, uint32_t dst_stride,
void *src, uint32_t src_stride,
int cpp, const struct pipe_box *box)
{
-#ifdef USE_ARM_ASM
+#ifdef VC4_TILING_LT_NEON
if (util_get_cpu_caps()->has_neon) {
vc4_store_lt_image_neon(dst, dst_stride, src, src_stride,
cpp, box);
--
2.25.1
@@ -0,0 +1,104 @@
From c9723120dbbe1d73c258d1aa119e05a24ab98b8a Mon Sep 17 00:00:00 2001
From: Frank Binns <frank.binns@imgtec.com>
Date: Wed, 12 Aug 2015 09:11:51 +0100
Subject: [PATCH 04/50] GL_EXT_sparse_texture entry points
---
src/mapi/glapi/gen/EXT_sparse_texture.xml | 56 +++++++++++++++++++++++
src/mapi/glapi/gen/es_EXT.xml | 3 ++
src/mapi/glapi/gen/static_data.py | 2 +
3 files changed, 61 insertions(+)
create mode 100644 src/mapi/glapi/gen/EXT_sparse_texture.xml
diff --git a/src/mapi/glapi/gen/EXT_sparse_texture.xml b/src/mapi/glapi/gen/EXT_sparse_texture.xml
new file mode 100644
index 00000000000..48d03e7b9c0
--- /dev/null
+++ b/src/mapi/glapi/gen/EXT_sparse_texture.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0"?>
+<!DOCTYPE OpenGLAPI SYSTEM "gl_API.dtd">
+
+<OpenGLAPI>
+
+<category name="EXT_sparse_texture" number="240">
+
+ <enum name="TEXTURE_SPARSE_EXT" value="0x91A6"/>
+ <enum name="VIRTUAL_PAGE_SIZE_INDEX_EXT" value="0x91A7"/>
+
+ <enum name="NUM_SPARSE_LEVELS_EXT" value="0x91AA"/>
+
+ <enum name="NUM_VIRTUAL_PAGE_SIZES_EXT" value="0x91A8"/>
+
+ <enum name="VIRTUAL_PAGE_SIZE_X_EXT" value="0x9195"/>
+ <enum name="VIRTUAL_PAGE_SIZE_Y_EXT" value="0x9196"/>
+ <enum name="VIRTUAL_PAGE_SIZE_Z_EXT" value="0x9197"/>
+
+ <enum name="TEXTURE_2D" value="0x0DE1"/>
+ <enum name="TEXTURE_2D_ARRAY" value="0x8C1A"/>
+ <enum name="TEXTURE_CUBE_MAP" value="0x8513"/>
+ <enum name="TEXTURE_CUBE_MAP_ARRAY_OES" value="0x9009"/>
+ <enum name="TEXTURE_3D" value="0x806F"/>
+
+ <enum name="MAX_SPARSE_TEXTURE_SIZE_EXT" value="0x9198"/>
+ <enum name="MAX_SPARSE_3D_TEXTURE_SIZE_EXT" value="0x9199"/>
+ <enum name="MAX_SPARSE_ARRAY_TEXTURE_LAYERS_EXT" value="0x919A"/>
+ <enum name="SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_EXT" value="0x91A9"/>
+
+ <function name="TexPageCommitmentEXT" es2="3.1" exec="dynamic">
+ <param name="target" type="GLenum"/>
+ <param name="level" type="GLint"/>
+ <param name="xoffset" type="GLint"/>
+ <param name="yoffset" type="GLint"/>
+ <param name="zoffset" type="GLint"/>
+ <param name="width" type="GLsizei"/>
+ <param name="height" type="GLsizei"/>
+ <param name="depth" type="GLsizei"/>
+ <param name="commit" type="GLboolean"/>
+ </function>
+
+ <function name="TexturePageCommitmentEXT" es2="3.1" exec="dynamic">
+ <param name="texture" type="GLuint"/>
+ <param name="level" type="GLint"/>
+ <param name="xoffset" type="GLint"/>
+ <param name="yoffset" type="GLint"/>
+ <param name="zoffset" type="GLint"/>
+ <param name="width" type="GLsizei"/>
+ <param name="height" type="GLsizei"/>
+ <param name="depth" type="GLsizei"/>
+ <param name="commit" type="GLboolean"/>
+ </function>
+
+</category>
+
+</OpenGLAPI>
diff --git a/src/mapi/glapi/gen/es_EXT.xml b/src/mapi/glapi/gen/es_EXT.xml
index 4386375940f..d8a80995d92 100644
--- a/src/mapi/glapi/gen/es_EXT.xml
+++ b/src/mapi/glapi/gen/es_EXT.xml
@@ -1433,6 +1433,9 @@
</category>
+<!-- 240. EXT_sparse_texture -->
+<xi:include href="EXT_sparse_texture.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
<category name="GL_OES_viewport_array" number="267">
<function name="ViewportArrayvOES" es2="3.1" alias="ViewportArrayv">
<param name="first" type="GLuint"/>
diff --git a/src/mapi/glapi/gen/static_data.py b/src/mapi/glapi/gen/static_data.py
index 5b51c222d79..a151a5d5fb4 100644
--- a/src/mapi/glapi/gen/static_data.py
+++ b/src/mapi/glapi/gen/static_data.py
@@ -1677,6 +1677,8 @@ offsets = {
"SecondaryColor3hNV": 1641,
"SecondaryColor3hvNV": 1642,
"InternalSetError": 1643,
+ "TexPageCommitmentEXT": 1644,
+ "TexturePageCommitmentEXT" : 1645,
}
functions = [
--
2.17.1
@@ -1,40 +0,0 @@
From fdc8b5a205e2116408aeb9fd305e57f656e2e89d Mon Sep 17 00:00:00 2001
From: Bernd Kuhls <bernd.kuhls@t-online.de>
Date: Sun, 9 Aug 2020 17:06:26 +0200
Subject: [PATCH] src/util/rand_xor: Include stddef.h to fix build error
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Fixes
In file included from ../src/util/rand_xor.c:29:
output/host/x86_64-buildroot-linux-uclibc/sysroot/usr/include/sys/random.h:27:35:
error: unknown type name size_t
extern int getrandom(void *__buf, size_t count, unsigned int flags)
seen with gcc version 8.3.0 (Buildroot 2020.02) and uClibc.
Patch sent upstream:
https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6248
Signed-off-by: Bernd Kuhls <bernd.kuhls@t-online.de>
---
src/util/rand_xor.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/util/rand_xor.c b/src/util/rand_xor.c
index 81b64f1ea71..fcb481487fa 100644
--- a/src/util/rand_xor.c
+++ b/src/util/rand_xor.c
@@ -25,6 +25,7 @@
#include "detect_os.h"
#if !DETECT_OS_WINDOWS
+#include <stddef.h>
#if defined(HAVE_GETRANDOM)
#include <sys/random.h>
#endif
--
2.27.0
@@ -0,0 +1,106 @@
From 329dd07729514a93a298e8ab6485822444ed4b28 Mon Sep 17 00:00:00 2001
From: Brendan King <Brendan.King@imgtec.com>
Date: Mon, 10 Mar 2014 12:27:03 +0000
Subject: [PATCH 05/50] Add support for various GLES extensions
Add support for:
EXT_occlusion_query_boolean
IMG_multisampled_render_to_texture
OES_matrix_palette
---
src/mapi/glapi/gen/es_EXT.xml | 41 ++++++++++++++++++++++++-------
src/mapi/glapi/gen/static_data.py | 6 +++++
2 files changed, 38 insertions(+), 9 deletions(-)
diff --git a/src/mapi/glapi/gen/es_EXT.xml b/src/mapi/glapi/gen/es_EXT.xml
index d8a80995d92..42f4b2b80fb 100644
--- a/src/mapi/glapi/gen/es_EXT.xml
+++ b/src/mapi/glapi/gen/es_EXT.xml
@@ -285,28 +285,25 @@
<enum name="WEIGHT_ARRAY_BUFFER_BINDING_OES" value="0x889E"/>
<enum name="MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES" value="0x8B9E"/>
- <function name="CurrentPaletteMatrixOES" alias="CurrentPaletteMatrixARB"
- exec="skip">
+ <function name="CurrentPaletteMatrixOES" es1="1.0" exec="dynamic">
<param name="matrixpaletteindex" type="GLuint"/>
</function>
- <!-- no offset -->
- <function name="LoadPaletteFromModelViewMatrixOES" exec="skip">
+ <function name="LoadPaletteFromModelViewMatrixOES" es1="1.0" exec="dynamic">
</function>
- <function name="MatrixIndexPointerOES" alias="MatrixIndexPointerARB"
- exec="skip">
+ <function name="MatrixIndexPointerOES" es1="1.0" exec="dynamic">
<param name="size" type="GLint"/>
<param name="type" type="GLenum"/>
<param name="stride" type="GLsizei"/>
- <param name="pointer" type="const GLvoid *"/>
+ <param name="pointer" type="GLvoid *"/>
</function>
- <function name="WeightPointerOES" alias="WeightPointerARB" exec="skip">
+ <function name="WeightPointerOES" es1="1.0" exec="dynamic">
<param name="size" type="GLint"/>
<param name="type" type="GLenum"/>
<param name="stride" type="GLsizei"/>
- <param name="pointer" type="const GLvoid *"/>
+ <param name="pointer" type="GLvoid *"/>
</function>
</category>
@@ -680,6 +677,32 @@
</enum>
</category>
+<!-- 74. GL_IMG_multisampled_render_to_texture -->
+<category name="GL_IMG_multisampled_render_to_texture" number="74">
+ <enum name="RENDERBUFFER_SAMPLES_IMG" value="0x9133"/>
+ <enum name="FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_IMG" value="0x9134"/>
+ <enum name="MAX_SAMPLES_IMG" value="0x9135"/>
+ <enum name="TEXTURE_SAMPLES_IMG" value="0x9136"/>
+
+ <function name="RenderbufferStorageMultisampleIMG" es2="2.0" exec="dynamic">
+ <param name="target" type="GLenum"/>
+ <param name="samples" type="GLsizei"/>
+ <param name="internalformat" type="GLenum"/>
+ <param name="width" type="GLsizei"/>
+ <param name="height" type="GLsizei"/>
+ </function>
+
+ <function name="FramebufferTexture2DMultisampleIMG" es2="2.0"
+ exec="dynamic">
+ <param name="target" type="GLenum"/>
+ <param name="attachment" type="GLenum"/>
+ <param name="textarget" type="GLenum"/>
+ <param name="texture" type="GLuint"/>
+ <param name="level" type="GLint"/>
+ <param name="samples" type="GLsizei"/>
+ </function>
+</category>
+
<!-- 87. GL_OES_EGL_image_external -->
<category name="GL_OES_EGL_image_external" number="87">
<enum name="TEXTURE_EXTERNAL_OES" value="0x8D65"/>
diff --git a/src/mapi/glapi/gen/static_data.py b/src/mapi/glapi/gen/static_data.py
index a151a5d5fb4..b23ae713f6f 100644
--- a/src/mapi/glapi/gen/static_data.py
+++ b/src/mapi/glapi/gen/static_data.py
@@ -1679,6 +1679,12 @@ offsets = {
"InternalSetError": 1643,
"TexPageCommitmentEXT": 1644,
"TexturePageCommitmentEXT" : 1645,
+ "CurrentPaletteMatrixOES" : 1646,
+ "LoadPaletteFromModelViewMatrixOES" : 1647,
+ "MatrixIndexPointerOES" : 1648,
+ "WeightPointerOES" : 1649,
+ "RenderbufferStorageMultisampleIMG" : 1650,
+ "FramebufferTexture2DMultisampleIMG" : 1651,
}
functions = [
--
2.17.1
@@ -1,43 +0,0 @@
From e501b7c17ada9c694d3f8302622b78d733485b38 Mon Sep 17 00:00:00 2001
From: Fabrice Fontaine <fontaine.fabrice@gmail.com>
Date: Sat, 21 Aug 2021 17:55:33 +0200
Subject: [PATCH] src/util/futex.h: fix build on 32-bit architectures using
64-bit time_t
Fix the following build failure on 32-bit architectures using 64-bit
time_t (e.g. riscv32):
../src/util/futex.h: In function 'sys_futex':
../src/util/futex.h:39:19: error: 'SYS_futex' undeclared (first use in this function); did you mean 'sys_futex'?
39 | return syscall(SYS_futex, addr1, op, val1, timeout, addr2, val3);
| ^~~~~~~~~
| sys_futex
Fixes:
- http://autobuild.buildroot.org/results/692700a5f967760a0b8cd358b1712f1d5a7b681e
Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
[Upstream status:
https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12496]
---
src/util/futex.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/util/futex.h b/src/util/futex.h
index 43097f4cd5b..221eda9db0c 100644
--- a/src/util/futex.h
+++ b/src/util/futex.h
@@ -34,6 +34,10 @@
#include <sys/syscall.h>
#include <sys/time.h>
+#ifndef SYS_futex
+#define SYS_futex SYS_futex_time64
+#endif
+
static inline long sys_futex(void *addr1, int op, int val1, const struct timespec *timeout, void *addr2, int val3)
{
return syscall(SYS_futex, addr1, op, val1, timeout, addr2, val3);
--
2.32.0
@@ -0,0 +1,187 @@
From e89ccf17b6a484d74fc1f0a45266ffc8f7fc3fec Mon Sep 17 00:00:00 2001
From: Brendan King <Brendan.King@imgtec.com>
Date: Tue, 11 Mar 2014 11:50:53 +0000
Subject: [PATCH 06/50] Add EGL_IMG_cl_image extension
Add support for the experimental EGL_IMG_cl_image extension to EGL, and
the DRI2 EGL driver.
---
include/EGL/eglmesaext.h | 5 +++
include/GL/internal/dri_interface.h | 13 +++++++
src/egl/drivers/dri2/egl_dri2.c | 60 +++++++++++++++++++++++++----
src/egl/main/eglapi.c | 1 +
src/egl/main/egldisplay.h | 2 +
5 files changed, 73 insertions(+), 8 deletions(-)
diff --git a/include/EGL/eglmesaext.h b/include/EGL/eglmesaext.h
index f0395a8a58c..5d11f3e488e 100644
--- a/include/EGL/eglmesaext.h
+++ b/include/EGL/eglmesaext.h
@@ -49,6 +49,11 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSREGIONNOK) (EGLDisplay dpy, EG
#define EGL_DRM_BUFFER_FORMAT_RGB565_MESA 0x3292
#endif /* EGL_MESA_drm_image_formats */
+#ifndef EGL_IMG_cl_image
+#define EGL_IMG_cl_image 1
+#define EGL_CL_IMAGE_IMG 0x6010
+#endif /* Experimental eglCreateImageKHR target */
+
#ifdef __cplusplus
}
#endif
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index e668798e87f..06eab0da5aa 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -1807,6 +1807,19 @@ struct __DRIimageExtensionRec {
uint32_t flags,
unsigned *error,
void *loaderPrivate);
+
+ /**
+ * Support for experimental EGL_CL_IMAGE_IMG.
+ * Like createImageFromTexture, but from a buffer, the contents
+ * of which depend on the target.
+ *
+ * \since 8
+ */
+ __DRIimage *(*createImageFromBuffer)(__DRIcontext *context,
+ int target,
+ void *buffer,
+ unsigned *error,
+ void *loaderPrivate);
};
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index 4f52985c48e..fb5d5617511 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -1008,6 +1008,10 @@ dri2_setup_screen(_EGLDisplay *disp)
disp->Extensions.EXT_image_dma_buf_import_modifiers = EGL_TRUE;
}
#endif
+ if (dri2_dpy->image->base.version >= 8 &&
+ dri2_dpy->image->createImageFromBuffer) {
+ disp->Extensions.IMG_cl_image = EGL_TRUE;
+ }
}
if (dri2_dpy->flush_control)
@@ -2373,17 +2377,13 @@ dri2_get_sync_values_chromium(_EGLDisplay *disp, _EGLSurface *surf,
return dri2_dpy->vtbl->get_sync_values(disp, surf, ust, msc, sbc);
}
-/**
- * Set the error code after a call to
- * dri2_egl_image::dri_image::createImageFromTexture.
- */
static void
-dri2_create_image_khr_texture_error(int dri_error)
+dri2_create_image_khr_error(int dri_error)
{
EGLint egl_error = egl_error_from_dri_image_error(dri_error);
if (egl_error != EGL_SUCCESS)
- _eglError(egl_error, "dri2_create_image_khr_texture");
+ _eglError(egl_error, "dri2_create_image_khr");
}
static _EGLImage *
@@ -2462,7 +2462,49 @@ dri2_create_image_khr_texture(_EGLDisplay *disp, _EGLContext *ctx,
attrs.GLTextureLevel,
&error,
NULL);
- dri2_create_image_khr_texture_error(error);
+ dri2_create_image_khr_error(error);
+
+ if (!dri2_img->dri_image) {
+ free(dri2_img);
+ return EGL_NO_IMAGE_KHR;
+ }
+ return &dri2_img->base;
+}
+
+static _EGLImage *
+dri2_create_image_img_buffer(_EGLDisplay *disp, _EGLContext *ctx,
+ EGLenum target,
+ EGLClientBuffer buffer,
+ const EGLint *attr_list)
+{
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+ struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx);
+ struct dri2_egl_image *dri2_img;
+ unsigned error;
+
+ switch (target) {
+ case EGL_CL_IMAGE_IMG:
+ break;
+ default:
+ _eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr");
+ return EGL_NO_IMAGE_KHR;
+ }
+
+ dri2_img = malloc(sizeof *dri2_img);
+ if (!dri2_img) {
+ _eglError(EGL_BAD_ALLOC, "dri2_create_image_khr");
+ return EGL_NO_IMAGE_KHR;
+ }
+
+ _eglInitImage(&dri2_img->base, disp);
+
+ dri2_img->dri_image =
+ dri2_dpy->image->createImageFromBuffer(dri2_ctx->dri_context,
+ target,
+ buffer,
+ &error,
+ NULL);
+ dri2_create_image_khr_error(error);
if (!dri2_img->dri_image) {
free(dri2_img);
@@ -2923,7 +2965,7 @@ dri2_create_image_dma_buf(_EGLDisplay *disp, _EGLContext *ctx,
&error,
NULL);
}
- dri2_create_image_khr_texture_error(error);
+ dri2_create_image_khr_error(error);
if (!dri_image)
return EGL_NO_IMAGE_KHR;
@@ -3159,6 +3201,8 @@ dri2_create_image_khr(_EGLDisplay *disp, _EGLContext *ctx, EGLenum target,
case EGL_WAYLAND_BUFFER_WL:
return dri2_create_image_wayland_wl_buffer(disp, ctx, buffer, attr_list);
#endif
+ case EGL_CL_IMAGE_IMG:
+ return dri2_create_image_img_buffer(disp, ctx, target, buffer, attr_list);
default:
_eglError(EGL_BAD_PARAMETER, "dri2_create_image_khr");
return EGL_NO_IMAGE_KHR;
diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c
index df0a0011dbf..e08b525c319 100644
--- a/src/egl/main/eglapi.c
+++ b/src/egl/main/eglapi.c
@@ -549,6 +549,7 @@ _eglCreateExtensionsString(_EGLDisplay *disp)
_EGL_CHECK_EXTENSION(WL_bind_wayland_display);
_EGL_CHECK_EXTENSION(WL_create_wayland_buffer_from_image);
+ _EGL_CHECK_EXTENSION(IMG_cl_image);
#undef _EGL_CHECK_EXTENSION
}
diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h
index 4d2afbc712e..5b05dcc1e6d 100644
--- a/src/egl/main/egldisplay.h
+++ b/src/egl/main/egldisplay.h
@@ -150,6 +150,8 @@ struct _egl_extensions
EGLBoolean WL_bind_wayland_display;
EGLBoolean WL_create_wayland_buffer_from_image;
+
+ EGLBoolean IMG_cl_image;
};
struct _egl_display
--
2.17.1
@@ -0,0 +1,66 @@
From 090a4c570fb58b5cd55a7628e6805cf16b36b030 Mon Sep 17 00:00:00 2001
From: Frank Binns <frank.binns@imgtec.com>
Date: Wed, 4 Jun 2014 13:43:03 +0100
Subject: [PATCH 07/50] egl_dri2: set pbuffer config attribs to 0 for
non-pbuffer configs
If the EGL_PBUFFER_BIT isn't set in the surface type, don't set the
EGL_MAX_PBUFFER_WIDTH, EGL_MAX_PBUFFER_HEIGHT and
EGL_MAX_PBUFFER_PIXELS attributes to non-zero values when adding an
EGL config. If the EGL_PBUFFER_BIT is set, don't override non-zero
values from the DRI config.
---
src/egl/drivers/dri2/egl_dri2.c | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index fb5d5617511..a47589d929f 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -415,6 +415,7 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id,
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
_EGLConfig base;
unsigned int attrib, value, double_buffer;
+ unsigned int pbuffer_width = 0, pbuffer_height = 0, pbuffer_pixels = 0;
bool srgb = false;
EGLint key, bind_to_texture_rgb, bind_to_texture_rgba;
int dri_shifts[4] = { -1, -1, -1, -1 };
@@ -536,11 +537,17 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id,
break;
case __DRI_ATTRIB_MAX_PBUFFER_WIDTH:
- base.MaxPbufferWidth = _EGL_MAX_PBUFFER_WIDTH;
+ pbuffer_width = (value != 0) ? value : _EGL_MAX_PBUFFER_WIDTH;
break;
+
case __DRI_ATTRIB_MAX_PBUFFER_HEIGHT:
- base.MaxPbufferHeight = _EGL_MAX_PBUFFER_HEIGHT;
+ pbuffer_height = (value != 0) ? value : _EGL_MAX_PBUFFER_HEIGHT;
+ break;
+
+ case __DRI_ATTRIB_MAX_PBUFFER_PIXELS:
+ pbuffer_pixels = value;
break;
+
case __DRI_ATTRIB_MUTABLE_RENDER_BUFFER:
if (disp->Extensions.KHR_mutable_render_buffer)
surface_type |= EGL_MUTABLE_RENDER_BUFFER_BIT_KHR;
@@ -553,6 +560,15 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id,
}
}
+ if (surface_type & EGL_PBUFFER_BIT) {
+ if (pbuffer_pixels == 0)
+ pbuffer_pixels = pbuffer_width * pbuffer_height;
+
+ base.MaxPbufferWidth = pbuffer_width;
+ base.MaxPbufferHeight = pbuffer_height;
+ base.MaxPbufferPixels = pbuffer_pixels;
+ }
+
if (attr_list)
for (int i = 0; attr_list[i] != EGL_NONE; i += 2)
_eglSetConfigKey(&base, attr_list[i], attr_list[i+1]);
--
2.17.1
@@ -0,0 +1,51 @@
From 9aab53e750f23aa9e2d8f1bfb2d9f6ff4ac3155a Mon Sep 17 00:00:00 2001
From: Frank Binns <frank.binns@imgtec.com>
Date: Wed, 18 Jun 2014 17:10:28 +0100
Subject: [PATCH 08/50] egl: Be stricter when making a context current without
any surfaces
The EGL_KHR_surfaceless_context extension spec states for eglMakeCurrent:
"If <ctx> does not support being bound without read and draw
surfaces, and both <draw> and <read> are EGL_NO_SURFACE, an
EGL_BAD_MATCH error is generated."
Only OpenGLES contexts support this, via the GL_OES_surfaceless_context,
so if EGL_KHR_surfaceless_context is supported and the context isn't an
OpenGLES context then set the EGL error to EGL_BAD_MATCH.
NOTE: This patch can't be upstreamed as is because we set the error to
EGL_BAD_MATCH if we have an OpenGLES 1.x context but the
GL_OES_surfaceless_context extension spec says:
"This extension is written against the OpenGL ES 2.0 Specification
but can apply to OpenGL ES 1.1 with the GL_OES_framebuffer_object
extension."
All Mesa OpenGLES drivers support GL_OES_framebuffer_object, but we
don't, so there would never be a reason to check whether or not this
extension is supported.
In order to upstream this patch the check would need to be changed
to set the error to EGL_BAD_MATCH if EGL_KHR_surfaceless_context is
supported and the context API isn't OpenGLES or the OpenGLES version
is 1.0.
---
src/egl/main/eglapi.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c
index e08b525c319..9d90f503cc5 100644
--- a/src/egl/main/eglapi.c
+++ b/src/egl/main/eglapi.c
@@ -888,6 +888,9 @@ eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read,
RETURN_EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE);
if (draw_surf || read_surf)
RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_FALSE);
+ if (disp->Extensions.KHR_surfaceless_context && context &&
+ (context->ClientAPI != EGL_OPENGL_ES_API || context->ClientMajorVersion == 1))
+ RETURN_EGL_ERROR(disp, EGL_BAD_MATCH, EGL_FALSE);
}
/* If a native window underlying either draw or read is no longer valid,
--
2.17.1
@@ -0,0 +1,46 @@
From 0b65066319eff5c482614574d4a4192454837835 Mon Sep 17 00:00:00 2001
From: Frank Binns <frank.binns@imgtec.com>
Date: Tue, 15 Sep 2015 14:15:31 +0100
Subject: [PATCH 09/50] egl: optimise eglMakeCurrent for the case where nothing
has changed
When an application calls eglMakeCurrent with a context, draw surface and
read surface that match those that are currently bound to the calling
thread don't perform a flush as this is an expensive operation.
---
src/egl/main/eglapi.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c
index 9d90f503cc5..bc7014ef8ed 100644
--- a/src/egl/main/eglapi.c
+++ b/src/egl/main/eglapi.c
@@ -853,6 +853,7 @@ eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read,
EGLContext ctx)
{
_EGLDisplay *disp = _eglLockDisplay(dpy);
+ _EGLContext *current_context = _eglGetCurrentContext();
_EGLContext *context = _eglLookupContext(ctx, disp);
_EGLSurface *draw_surf = _eglLookupSurface(draw, disp);
_EGLSurface *read_surf = _eglLookupSurface(read, disp);
@@ -909,7 +910,16 @@ eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read,
draw_surf && !draw_surf->ProtectedContent)
RETURN_EGL_ERROR(disp, EGL_BAD_ACCESS, EGL_FALSE);
- ret = disp->Driver->MakeCurrent(disp, draw_surf, read_surf, context);
+ /* As an optimisation don't do anything unless something has changed */
+ if (context != current_context ||
+ (current_context &&
+ (draw_surf != current_context->DrawSurface ||
+ read_surf != current_context->ReadSurface)) ||
+ (!current_context && (draw_surf || read_surf))) {
+ ret = disp->Driver->MakeCurrent(disp, draw_surf, read_surf, context);
+ } else {
+ ret = EGL_TRUE;
+ }
RETURN_EGL_EVAL(disp, ret);
}
--
2.17.1
@@ -0,0 +1,84 @@
From 921ab82e655c9a3ffab6e39847a7d2d61338221e Mon Sep 17 00:00:00 2001
From: Rufus Hamade <rufus.hamade@imgtec.com>
Date: Thu, 4 Feb 2016 14:09:26 +0000
Subject: [PATCH 10/50] GL_EXT_shader_pixel_local_storage2 entry points
---
.../gen/EXT_shader_pixel_local_storage2.xml | 35 +++++++++++++++++++
src/mapi/glapi/gen/es_EXT.xml | 3 ++
src/mapi/glapi/gen/static_data.py | 3 ++
3 files changed, 41 insertions(+)
create mode 100644 src/mapi/glapi/gen/EXT_shader_pixel_local_storage2.xml
diff --git a/src/mapi/glapi/gen/EXT_shader_pixel_local_storage2.xml b/src/mapi/glapi/gen/EXT_shader_pixel_local_storage2.xml
new file mode 100644
index 00000000000..20e186c0f0d
--- /dev/null
+++ b/src/mapi/glapi/gen/EXT_shader_pixel_local_storage2.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0"?>
+<!DOCTYPE OpenGLAPI SYSTEM "gl_API.dtd">
+
+<OpenGLAPI>
+
+<category name="EXT_shader_pixel_local_storage2" number="240">
+
+ <enum name="GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_FAST_SIZE_EXT" value="0x8F63"/>
+ <enum name="GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_SIZE_EXT" value="0x8F67"/>
+ <enum name="GL_SHADER_PIXEL_LOCAL_STORAGE_EXT" value="0x8F64"/>
+ <enum name="GL_MAX_SHADER_COMBINED_LOCAL_STORAGE_FAST_SIZE_EXT" value="0x9650"/>
+ <enum name="GL_MAX_SHADER_COMBINED_LOCAL_STORAGE_SIZE_EXT" value="0x9651"/>
+ <enum name="GL_FRAMEBUFFER_INCOMPLETE_INSUFFICIENT_SHADER_COMBINED_LOCAL_STORAGE_EXT" value="0x9652"/>
+
+ <function name="ClearPixelLocalStorageuiEXT" es2="3.1" exec="dynamic">
+ <param name="offset" type="GLsizei"/>
+ <param name="n" type="GLsizei"/>
+ <param name="values" type="const GLuint *"/>
+ </function>
+
+ <function name="FramebufferPixelLocalStorageSizeEXT" es2="3.1"
+ exec="dynamic">
+ <param name="target" type="GLuint"/>
+ <param name="size" type="GLsizei"/>
+ </function>
+
+ <function name="GetFramebufferPixelLocalStorageSizeEXT" es2="3.1"
+ exec="dynamic">
+ <param name="target" type="GLuint"/>
+ <return type="GLsizei"/>
+ </function>
+
+</category>
+
+</OpenGLAPI>
diff --git a/src/mapi/glapi/gen/es_EXT.xml b/src/mapi/glapi/gen/es_EXT.xml
index 42f4b2b80fb..c7fde29732a 100644
--- a/src/mapi/glapi/gen/es_EXT.xml
+++ b/src/mapi/glapi/gen/es_EXT.xml
@@ -1459,6 +1459,9 @@
<!-- 240. EXT_sparse_texture -->
<xi:include href="EXT_sparse_texture.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+<!-- 253. GL_EXT_shader_pixel_local_storage2 -->
+<xi:include href="EXT_shader_pixel_local_storage2.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
<category name="GL_OES_viewport_array" number="267">
<function name="ViewportArrayvOES" es2="3.1" alias="ViewportArrayv">
<param name="first" type="GLuint"/>
diff --git a/src/mapi/glapi/gen/static_data.py b/src/mapi/glapi/gen/static_data.py
index b23ae713f6f..1ace5e201d8 100644
--- a/src/mapi/glapi/gen/static_data.py
+++ b/src/mapi/glapi/gen/static_data.py
@@ -1685,6 +1685,9 @@ offsets = {
"WeightPointerOES" : 1649,
"RenderbufferStorageMultisampleIMG" : 1650,
"FramebufferTexture2DMultisampleIMG" : 1651,
+ "ClearPixelLocalStorageuiEXT" : 1652,
+ "FramebufferPixelLocalStorageSizeEXT" : 1653,
+ "GetFramebufferPixelLocalStorageSizeEXT" : 1654,
}
functions = [
--
2.17.1
@@ -0,0 +1,85 @@
From 67428e8b27839095214419dabccaeffab923a89b Mon Sep 17 00:00:00 2001
From: Rufus Hamade <rufus.hamade@imgtec.com>
Date: Thu, 4 Feb 2016 14:09:26 +0000
Subject: [PATCH 11/50] GL_IMG_framebuffer_downsample entry points
---
.../glapi/gen/IMG_framebuffer_downsample.xml | 37 +++++++++++++++++++
src/mapi/glapi/gen/es_EXT.xml | 3 ++
src/mapi/glapi/gen/static_data.py | 2 +
3 files changed, 42 insertions(+)
create mode 100644 src/mapi/glapi/gen/IMG_framebuffer_downsample.xml
diff --git a/src/mapi/glapi/gen/IMG_framebuffer_downsample.xml b/src/mapi/glapi/gen/IMG_framebuffer_downsample.xml
new file mode 100644
index 00000000000..b5ce77dfb08
--- /dev/null
+++ b/src/mapi/glapi/gen/IMG_framebuffer_downsample.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0"?>
+<!DOCTYPE OpenGLAPI SYSTEM "gl_API.dtd">
+
+<OpenGLAPI>
+
+<category name="GL_IMG_framebuffer_downsample" number="255">
+
+ <enum name="FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_AND_DOWNSAMPLE_IMG" value="0x913C"/>
+ <enum name="NUM_DOWNSAMPLE_SCALES_IMG" value="0x913D"/>
+ <enum name="DOWNSAMPLE_SCALES_IMG" value="0x913E"/>
+ <enum name="FRAMEBUFFER_ATTACHMENT_TEXTURE_SCALE_IMG" value="0x913F"/>
+
+ <function name="FramebufferTexture2DDownsampleIMG" es1="1.0" es2="2.0"
+ exec="dynamic">
+ <param name="target" type="GLenum"/>
+ <param name="attachment" type="GLenum"/>
+ <param name="textarget" type="GLenum"/>
+ <param name="texture" type="GLuint"/>
+ <param name="level" type="GLint"/>
+ <param name="xscale" type="GLint"/>
+ <param name="yscale" type="GLint"/>
+ </function>
+
+ <function name="FramebufferTextureLayerDownsampleIMG" es1="1.0" es2="2.0"
+ exec="dynamic">
+ <param name="target" type="GLenum"/>
+ <param name="attachment" type="GLenum"/>
+ <param name="texture" type="GLuint"/>
+ <param name="level" type="GLint"/>
+ <param name="layer" type="GLint"/>
+ <param name="xscale" type="GLint"/>
+ <param name="yscale" type="GLint"/>
+ </function>
+
+</category>
+
+</OpenGLAPI>
diff --git a/src/mapi/glapi/gen/es_EXT.xml b/src/mapi/glapi/gen/es_EXT.xml
index c7fde29732a..6aea8c55fac 100644
--- a/src/mapi/glapi/gen/es_EXT.xml
+++ b/src/mapi/glapi/gen/es_EXT.xml
@@ -1462,6 +1462,9 @@
<!-- 253. GL_EXT_shader_pixel_local_storage2 -->
<xi:include href="EXT_shader_pixel_local_storage2.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+<!-- 255. GL_IMG_framebuffer_downsample -->
+<xi:include href="IMG_framebuffer_downsample.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
<category name="GL_OES_viewport_array" number="267">
<function name="ViewportArrayvOES" es2="3.1" alias="ViewportArrayv">
<param name="first" type="GLuint"/>
diff --git a/src/mapi/glapi/gen/static_data.py b/src/mapi/glapi/gen/static_data.py
index 1ace5e201d8..2838a4451a2 100644
--- a/src/mapi/glapi/gen/static_data.py
+++ b/src/mapi/glapi/gen/static_data.py
@@ -1688,6 +1688,8 @@ offsets = {
"ClearPixelLocalStorageuiEXT" : 1652,
"FramebufferPixelLocalStorageSizeEXT" : 1653,
"GetFramebufferPixelLocalStorageSizeEXT" : 1654,
+ "FramebufferTexture2DDownsampleIMG" : 1655,
+ "FramebufferTextureLayerDownsampleIMG" : 1656,
}
functions = [
--
2.17.1
@@ -0,0 +1,53 @@
From 5aed29849109fcb20934186b9f4ffc0606b40f8e Mon Sep 17 00:00:00 2001
From: Brendan King <Brendan.King@imgtec.com>
Date: Mon, 11 Jul 2016 12:45:30 +0100
Subject: [PATCH 12/50] GL_OVR_multiview entry points
---
src/mapi/glapi/gen/gl_API.xml | 17 +++++++++++++++++
src/mapi/glapi/gen/static_data.py | 1 +
2 files changed, 18 insertions(+)
diff --git a/src/mapi/glapi/gen/gl_API.xml b/src/mapi/glapi/gen/gl_API.xml
index dcdbe80290c..d6fae3b1988 100644
--- a/src/mapi/glapi/gen/gl_API.xml
+++ b/src/mapi/glapi/gen/gl_API.xml
@@ -13101,6 +13101,23 @@
</function>
</category>
+<category name="GL_OVR_multiview" number="478">
+ <enum name="FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR" value="0x9630" />
+ <enum name="FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR" value="0x9632" />
+ <enum name="MAX_VIEWS_OVR" value="0x9631">
+ <size name="Get" mode="get"/>
+ </enum>
+ <enum name="FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR" value="0x9633" />
+ <function name="FramebufferTextureMultiviewOVR" es2="3.0" exec="dynamic">
+ <param name="target" type="GLenum"/>
+ <param name="attachment" type="GLenum"/>
+ <param name="texture" type="GLuint"/>
+ <param name="level" type="GLint"/>
+ <param name="baseViewIndex" type="GLint"/>
+ <param name="numViews" type="GLsizei"/>
+ </function>
+</category>
+
<xi:include href="EXT_window_rectangles.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<!-- 520. GL_EXT_shader_framebuffer_fetch -->
diff --git a/src/mapi/glapi/gen/static_data.py b/src/mapi/glapi/gen/static_data.py
index 2838a4451a2..015e4efed7a 100644
--- a/src/mapi/glapi/gen/static_data.py
+++ b/src/mapi/glapi/gen/static_data.py
@@ -1690,6 +1690,7 @@ offsets = {
"GetFramebufferPixelLocalStorageSizeEXT" : 1654,
"FramebufferTexture2DDownsampleIMG" : 1655,
"FramebufferTextureLayerDownsampleIMG" : 1656,
+ "FramebufferTextureMultiviewOVR" : 1657,
}
functions = [
--
2.17.1
@@ -0,0 +1,68 @@
From 95383627bc57aa19f0e5d40ae8c91f4d91230708 Mon Sep 17 00:00:00 2001
From: Brendan King <Brendan.King@imgtec.com>
Date: Mon, 11 Jul 2016 13:29:51 +0100
Subject: [PATCH 13/50] Add OVR_multiview_multisampled_render_to_texture
---
...ltiview_multisampled_render_to_texture.xml | 21 +++++++++++++++++++
src/mapi/glapi/gen/es_EXT.xml | 3 +++
src/mapi/glapi/gen/static_data.py | 1 +
3 files changed, 25 insertions(+)
create mode 100644 src/mapi/glapi/gen/OVR_multiview_multisampled_render_to_texture.xml
diff --git a/src/mapi/glapi/gen/OVR_multiview_multisampled_render_to_texture.xml b/src/mapi/glapi/gen/OVR_multiview_multisampled_render_to_texture.xml
new file mode 100644
index 00000000000..86bebc728e9
--- /dev/null
+++ b/src/mapi/glapi/gen/OVR_multiview_multisampled_render_to_texture.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<!DOCTYPE OpenGLAPI SYSTEM "gl_API.dtd">
+
+<OpenGLAPI>
+
+<category name="GL_OVR_multiview_multisampled_render_to_texture" number="250">
+
+ <function name="FramebufferTextureMultisampleMultiviewOVR" es2="3.0"
+ exec="dynamic">
+ <param name="target" type="GLenum"/>
+ <param name="attachment" type="GLenum"/>
+ <param name="texture" type="GLuint"/>
+ <param name="level" type="GLint"/>
+ <param name="samples" type="GLsizei"/>
+ <param name="baseViewIndex" type="GLint"/>
+ <param name="numViews" type="GLsizei"/>
+ </function>
+
+</category>
+
+</OpenGLAPI>
diff --git a/src/mapi/glapi/gen/es_EXT.xml b/src/mapi/glapi/gen/es_EXT.xml
index 6aea8c55fac..359cc9ca8cf 100644
--- a/src/mapi/glapi/gen/es_EXT.xml
+++ b/src/mapi/glapi/gen/es_EXT.xml
@@ -1459,6 +1459,9 @@
<!-- 240. EXT_sparse_texture -->
<xi:include href="EXT_sparse_texture.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+<!-- 250. GL_OVR_multiview_multisampled_render_to_texture -->
+<xi:include href="OVR_multiview_multisampled_render_to_texture.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
<!-- 253. GL_EXT_shader_pixel_local_storage2 -->
<xi:include href="EXT_shader_pixel_local_storage2.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
diff --git a/src/mapi/glapi/gen/static_data.py b/src/mapi/glapi/gen/static_data.py
index 015e4efed7a..d13dc915d6f 100644
--- a/src/mapi/glapi/gen/static_data.py
+++ b/src/mapi/glapi/gen/static_data.py
@@ -1691,6 +1691,7 @@ offsets = {
"FramebufferTexture2DDownsampleIMG" : 1655,
"FramebufferTextureLayerDownsampleIMG" : 1656,
"FramebufferTextureMultiviewOVR" : 1657,
+ "FramebufferTextureMultisampleMultiviewOVR" : 1658,
}
functions = [
--
2.17.1
@@ -0,0 +1,57 @@
From 2d7c499fe386f83e6f77ddc1e9dbd437e5dbe59a Mon Sep 17 00:00:00 2001
From: Frank Binns <frank.binns@imgtec.com>
Date: Thu, 18 Aug 2016 15:52:28 +0100
Subject: [PATCH 14/50] wayland-drm: install wayland-drm.xml to the configured
pkgdatadir
Add a pkg-config file as well so that it can be located without hardcoding the
path.
---
src/egl/wayland/wayland-drm/meson.build | 15 +++++++++++++++
src/egl/wayland/wayland-drm/wayland-drm.pc.in | 7 +++++++
2 files changed, 22 insertions(+)
create mode 100644 src/egl/wayland/wayland-drm/wayland-drm.pc.in
diff --git a/src/egl/wayland/wayland-drm/meson.build b/src/egl/wayland/wayland-drm/meson.build
index b4782a013c9..f291ef9f55e 100644
--- a/src/egl/wayland/wayland-drm/meson.build
+++ b/src/egl/wayland/wayland-drm/meson.build
@@ -49,6 +49,21 @@ libwayland_drm = static_library(
build_by_default : false,
)
+install_data('wayland-drm.xml')
+
+pkg.generate(
+ filebase : 'wayland-drm',
+ name : 'Mesa Wayland Protocols',
+ description : 'Mesa Wayland protocol files',
+ version : meson.project_version(),
+ variables : [
+ 'datarootdir=${prefix}/' + get_option('datadir'),
+ 'pkgdatadir=${pc_sysrootdir}${datarootdir}/' + meson.project_name(),
+ ],
+ install_dir : '@0@/@1@/pkgconfig'.format(get_option('prefix'),
+ get_option('datadir')),
+)
+
# linux-dmabuf isn't part of wayland-drm, but this happens to be the only
# place which is a) guaranteed to be built when building either or both
# of EGL and Vulkan WSI, and b) guaranteed to be included before both,
diff --git a/src/egl/wayland/wayland-drm/wayland-drm.pc.in b/src/egl/wayland/wayland-drm/wayland-drm.pc.in
new file mode 100644
index 00000000000..d08ccdaf6ce
--- /dev/null
+++ b/src/egl/wayland/wayland-drm/wayland-drm.pc.in
@@ -0,0 +1,7 @@
+prefix=@prefix@
+datarootdir=@datarootdir@
+pkgdatadir=${pc_sysrootdir}@datadir@/@PACKAGE@
+
+Name: @PACKAGE_NAME@ Wayland Protocols
+Description: @PACKAGE_NAME@ Wayland protocol files
+Version: @PACKAGE_VERSION@
\ No newline at end of file
--
2.17.1
@@ -0,0 +1,27 @@
From 2cc857d6ae366e5599a7d39b975ab030ec915001 Mon Sep 17 00:00:00 2001
From: Brendan King <Brendan.King@imgtec.com>
Date: Wed, 26 Oct 2016 16:24:28 +0100
Subject: [PATCH 15/50] Enable buffer sharing in the kms_swrast driver
Enable buffer sharing, so that a DRI driver can be loaded by a
Wayland client when kms_swrast is being used by the compositor.
---
src/gallium/frontends/dri/dri2.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/gallium/frontends/dri/dri2.c b/src/gallium/frontends/dri/dri2.c
index b0c0d7eafbe..d78e1638d1d 100644
--- a/src/gallium/frontends/dri/dri2.c
+++ b/src/gallium/frontends/dri/dri2.c
@@ -2300,7 +2300,7 @@ dri_kms_init_screen(__DRIscreen * sPriv)
if (!configs)
goto destroy_screen;
- screen->can_share_buffer = false;
+ screen->can_share_buffer = true;
screen->auto_fake_front = dri_with_format(sPriv);
screen->broken_invalidate = !sPriv->dri2.useInvalidate;
screen->lookup_egl_image = dri2_lookup_egl_image;
--
2.17.1
@@ -0,0 +1,46 @@
From 39233fe0599c68e7b20e4074b0aa7c8e639f648b Mon Sep 17 00:00:00 2001
From: James Glanville <James.Glanville@imgtec.com>
Date: Tue, 28 Feb 2017 16:08:47 +0000
Subject: [PATCH 16/50] egl/wayland: add support for RGB565 back buffers
---
src/egl/drivers/dri2/platform_wayland.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c
index f65d9e45d8f..6eb2c7cbdf6 100644
--- a/src/egl/drivers/dri2/platform_wayland.c
+++ b/src/egl/drivers/dri2/platform_wayland.c
@@ -647,18 +647,27 @@ back_bo_to_dri_buffer(struct dri2_egl_surface *dri2_surf, __DRIbuffer *buffer)
struct dri2_egl_display *dri2_dpy =
dri2_egl_display(dri2_surf->base.Resource.Display);
__DRIimage *image;
- int name, pitch;
+ int name, pitch, format;
image = dri2_surf->back->dri_image;
dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_NAME, &name);
dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_STRIDE, &pitch);
+ dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_FORMAT, &format);
buffer->attachment = __DRI_BUFFER_BACK_LEFT;
buffer->name = name;
buffer->pitch = pitch;
- buffer->cpp = 4;
buffer->flags = 0;
+
+ switch (format) {
+ case __DRI_IMAGE_FORMAT_RGB565:
+ buffer->cpp = 2;
+ break;
+ default:
+ buffer->cpp = 4;
+ break;
+ }
}
static int
--
2.17.1
@@ -0,0 +1,49 @@
From ef372bd8c5ee377bac81f22174b9e01a30cffe53 Mon Sep 17 00:00:00 2001
From: Brendan King <Brendan.King@imgtec.com>
Date: Thu, 13 Apr 2017 10:12:40 +0100
Subject: [PATCH 17/50] egl/dri3: fix segfault in eglCopyBuffers
The loader_dri3_copy_drawable function expected the drawable to have
a fake front buffer, resulting in a segfault if there wasn't one,
when dri3_fence_reset was called.
If there is no fake front buffer, but there are back buffers, use the
current back buffer.
---
src/loader/loader_dri3_helper.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c
index ccf8d1795e7..0f7cf0d186c 100644
--- a/src/loader/loader_dri3_helper.c
+++ b/src/loader/loader_dri3_helper.c
@@ -858,15 +858,24 @@ loader_dri3_copy_drawable(struct loader_dri3_drawable *draw,
xcb_drawable_t dest,
xcb_drawable_t src)
{
+ struct loader_dri3_buffer *buffer;
+
+ if (draw->have_fake_front)
+ buffer = dri3_fake_front_buffer(draw);
+ else if (draw->have_back)
+ buffer = dri3_back_buffer(draw);
+ else
+ return;
+
loader_dri3_flush(draw, __DRI2_FLUSH_DRAWABLE, __DRI2_THROTTLE_COPYSUBBUFFER);
- dri3_fence_reset(draw->conn, dri3_fake_front_buffer(draw));
+ dri3_fence_reset(draw->conn, buffer);
dri3_copy_area(draw->conn,
src, dest,
dri3_drawable_gc(draw),
0, 0, 0, 0, draw->width, draw->height);
- dri3_fence_trigger(draw->conn, dri3_fake_front_buffer(draw));
- dri3_fence_await(draw->conn, draw, dri3_fake_front_buffer(draw));
+ dri3_fence_trigger(draw->conn, buffer);
+ dri3_fence_await(draw->conn, draw, buffer);
}
void
--
2.17.1
@@ -0,0 +1,78 @@
From ce5d9f5a0a95658e2c9d54726bcd8986d7e2be4a Mon Sep 17 00:00:00 2001
From: Iosif Antochi <iosif.antochi@imgtec.com>
Date: Wed, 14 Jun 2017 14:49:55 +0100
Subject: [PATCH 18/50] egl: automatically call eglReleaseThread on thread
termination
EGL thread cleanup conformance tests could run out of memory as the contexts
were not freed even though the application requested to have them deleted.
This was caused by the fact that the contexts were still current on their
threads when delete was called and (in order not to block any potential
pending renders) they were just marked for delete.
Fix this by calling eglReleaseThread on thread termination. This is safe to
do even if this was already called by the application since, according to the
EGL 1.5 spec, eglReleaseThread can be called multiple times without error.
Fixes:
dEQP-EGL.functional.thread_cleanup.multi_context_*
dEQP-EGL.functional.robustness.create_context.query_robust_access
---
src/egl/main/eglcurrent.c | 27 ++++++++++++++++++++++++++-
1 file changed, 26 insertions(+), 1 deletion(-)
diff --git a/src/egl/main/eglcurrent.c b/src/egl/main/eglcurrent.c
index 29be4268025..e93793a6073 100644
--- a/src/egl/main/eglcurrent.c
+++ b/src/egl/main/eglcurrent.c
@@ -43,6 +43,7 @@ static mtx_t _egl_TSDMutex = _MTX_INITIALIZER_NP;
static EGLBoolean _egl_TSDInitialized;
static tss_t _egl_TSD;
static void _eglDestroyThreadInfo(_EGLThreadInfo *t);
+static void _eglDestroyThreadInfoCallback(_EGLThreadInfo *t);
#ifdef USE_ELF_TLS
static __thread const _EGLThreadInfo *_egl_TLS
@@ -86,7 +87,7 @@ static inline EGLBoolean _eglInitTSD()
/* check again after acquiring lock */
if (!_egl_TSDInitialized) {
- if (tss_create(&_egl_TSD, (void (*)(void *)) _eglDestroyThreadInfo) != thrd_success) {
+ if (tss_create(&_egl_TSD, (void (*)(void *)) _eglDestroyThreadInfoCallback) != thrd_success) {
mtx_unlock(&_egl_TSDMutex);
return EGL_FALSE;
}
@@ -135,6 +136,30 @@ _eglDestroyThreadInfo(_EGLThreadInfo *t)
}
+/**
+ * Delete/free a _EGLThreadInfo object.
+ */
+static void
+_eglDestroyThreadInfoCallback(_EGLThreadInfo *t)
+{
+ /* If this callback is called on thread termination then try to also give a
+ * chance to cleanup to the client drivers. If called for module termination
+ * then just release the thread information as calling eglReleaseThread
+ * would result in a deadlock.
+ */
+ if (_egl_TSDInitialized) {
+ /* The callback handler has replaced the TLS entry, which is passed in as
+ * 't', with NULL. Restore it here so that the release thread finds it in
+ * the TLS entry.
+ */
+ _eglSetTSD(t);
+ eglReleaseThread();
+ } else {
+ _eglDestroyThreadInfo(t);
+ }
+}
+
+
/**
* Make sure TSD is initialized and return current value.
*/
--
2.17.1
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,231 @@
From 072528e4c6b37df46499a87478f535f6235ffde5 Mon Sep 17 00:00:00 2001
From: Eric Engestrom <eric.engestrom@imgtec.com>
Date: Mon, 6 Feb 2017 15:54:00 +0000
Subject: [PATCH 20/50] egl: add support for EGL_TIZEN_image_native_surface
---
src/egl/drivers/dri2/egl_dri2.c | 127 ++++++++++++++++++++------
src/egl/drivers/dri2/platform_tizen.c | 1 +
src/egl/main/eglapi.c | 2 +
src/egl/main/egldisplay.h | 2 +
4 files changed, 102 insertions(+), 30 deletions(-)
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index e9f745e4258..04e05567acb 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -58,6 +58,10 @@
#include "X11/Xlibint.h"
#endif
+#ifdef HAVE_TIZEN_PLATFORM
+#include <tpl.h>
+#endif
+
#include "egldefines.h"
#include "egl_dri2.h"
#include "GL/mesa_glinterop.h"
@@ -2340,28 +2344,115 @@ dri2_fourcc_from_tbm_format(tbm_format format)
switch (format) {
case TBM_FORMAT_ARGB8888:
return DRM_FORMAT_ARGB8888;
+ case TBM_FORMAT_ABGR8888:
+ return DRM_FORMAT_ABGR8888;
case TBM_FORMAT_XRGB8888:
return DRM_FORMAT_XRGB8888;
+ case TBM_FORMAT_XBGR8888:
+ return DRM_FORMAT_XBGR8888;
+ case TBM_FORMAT_ARGB4444:
+ return DRM_FORMAT_ARGB4444;
+ case TBM_FORMAT_ARGB1555:
+ return DRM_FORMAT_ARGB1555;
case TBM_FORMAT_RGB565:
return DRM_FORMAT_RGB565;
+ case TBM_FORMAT_YUV420:
+ return DRM_FORMAT_YUV420;
+ case TBM_FORMAT_YVU420:
+ return DRM_FORMAT_YVU420;
+ case TBM_FORMAT_NV12:
+ return DRM_FORMAT_NV12;
+ case TBM_FORMAT_NV21:
+ return DRM_FORMAT_NV21;
default:
_eglLog(_EGL_DEBUG, "%s: unsupported tbm format %#x", __func__, format);
return 0;
}
}
+static _EGLImage *
+dri2_create_image_tbm_surface(_EGLDisplay *disp, _EGLContext *ctx,
+ tbm_surface_h tbm_surf)
+{
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+ __DRIimage *dri_image;
+ tbm_surface_info_s info;
+ int fd[TBM_SURF_PLANE_MAX], pitch[TBM_SURF_PLANE_MAX], offset[TBM_SURF_PLANE_MAX];
+ int fourcc;
+ int i;
+
+ if (tbm_surface_get_info(tbm_surf, &info)) {
+ _eglError(EGL_BAD_PARAMETER, "tbm_surface_get_info");
+ return NULL;
+ }
+
+ fourcc = dri2_fourcc_from_tbm_format(info.format);
+ if (!fourcc) {
+ _eglError(EGL_BAD_PARAMETER, "dri2_fourcc_from_tbm_format");
+ return NULL;
+ }
+
+ for (i = 0; i < info.num_planes; i++) {
+ tbm_bo tbm_buf;
+
+ tbm_buf = tbm_surface_internal_get_bo(tbm_surf, i);
+ if (!tbm_buf) {
+ _eglError(EGL_BAD_PARAMETER, "tbm_surface_internal_get_bo");
+ goto fail_close;
+ }
+
+ pitch[i] = info.planes[i].stride;
+ offset[i] = info.planes[i].offset;
+ fd[i] = tbm_bo_export_fd(tbm_buf);
+ }
+
+ dri_image = dri2_dpy->image->createImageFromFds(dri2_dpy->dri_screen,
+ info.width,
+ info.height,
+ fourcc,
+ &fd[0],
+ info.num_planes,
+ &pitch[0],
+ &offset[0],
+ tbm_surf);
+ for (i = 0; i < info.num_planes; i++) {
+ close(fd[i]);
+ fd[i] = -1;
+ }
+
+ if (!dri_image) {
+ _eglError(EGL_BAD_PARAMETER, "createImageFromFds");
+ return NULL;
+ }
+
+ return dri2_create_image_from_dri(disp, dri_image);
+
+fail_close:
+ while (i--)
+ close(fd[i]);
+
+ return NULL;
+}
+
+static _EGLImage *
+dri2_create_image_tizen(_EGLDisplay *disp, _EGLContext *ctx,
+ EGLClientBuffer _buffer,
+ const EGLint *attr_list)
+{
+ tbm_surface_h tbm_surf = (tbm_surface_h)_buffer;
+
+ return dri2_create_image_tbm_surface(disp, ctx, tbm_surf);
+}
+
static _EGLImage *
dri2_create_image_wayland_wl_buffer_tizen(_EGLDisplay *disp, _EGLContext *ctx,
EGLClientBuffer _buffer,
const EGLint *attr_list)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
- __DRIimage *dri_image;
_EGLImageAttribs attrs;
tbm_surface_h tbm_surf;
- tbm_bo tbm_buf;
tbm_surface_info_s info;
- int fourcc, fd, pitch, offset;
tbm_surf = tpl_display_get_buffer_from_native_pixmap(dri2_dpy->tpl_dpy,
(tpl_handle_t) _buffer);
@@ -2392,33 +2483,7 @@ dri2_create_image_wayland_wl_buffer_tizen(_EGLDisplay *disp, _EGLContext *ctx,
return NULL;
}
- tbm_buf = tbm_surface_internal_get_bo(tbm_surf, attrs.PlaneWL);
- if (!tbm_buf) {
- _eglError(EGL_BAD_PARAMETER, "tbm_surface_internal_get_bo");
- return NULL;
- }
-
- fourcc = dri2_fourcc_from_tbm_format(info.format);
- pitch = info.planes[attrs.PlaneWL].stride;
- offset = info.planes[attrs.PlaneWL].offset;
- fd = tbm_bo_export_fd(tbm_buf);
-
- dri_image = dri2_dpy->image->createImageFromFds(dri2_dpy->dri_screen,
- info.width,
- info.height,
- fourcc,
- &fd,
- 1,
- &pitch,
- &offset,
- tbm_surf);
- close(fd);
- if (dri_image == NULL) {
- _eglError(EGL_BAD_PARAMETER, "createImageFromFds");
- return NULL;
- }
-
- return dri2_create_image_from_dri(disp, dri_image);
+ return dri2_create_image_tbm_surface(disp, ctx, tbm_surf);
}
#endif
@@ -3319,6 +3384,8 @@ dri2_create_image_khr(_EGLDisplay *disp, _EGLContext *ctx, EGLenum target,
#ifdef HAVE_TIZEN_PLATFORM
case EGL_WAYLAND_BUFFER_WL:
return dri2_create_image_wayland_wl_buffer_tizen(disp, ctx, buffer, attr_list);
+ case EGL_NATIVE_SURFACE_TIZEN:
+ return dri2_create_image_tizen(disp, ctx, buffer, attr_list);
#endif
case EGL_CL_IMAGE_IMG:
return dri2_create_image_img_buffer(disp, ctx, target, buffer, attr_list);
diff --git a/src/egl/drivers/dri2/platform_tizen.c b/src/egl/drivers/dri2/platform_tizen.c
index a08bc8c07bf..ad75c115d7e 100644
--- a/src/egl/drivers/dri2/platform_tizen.c
+++ b/src/egl/drivers/dri2/platform_tizen.c
@@ -965,6 +965,7 @@ dri2_initialize_tizen(_EGLDisplay *dpy)
dpy->Extensions.EXT_swap_buffers_with_damage = EGL_TRUE;
dpy->Extensions.KHR_image_base = EGL_TRUE;
dpy->Extensions.WL_bind_wayland_display = EGL_TRUE;
+ dpy->Extensions.TIZEN_image_native_surface = EGL_TRUE;
/*
* Fill vtbl last to prevent accidentally calling virtual function during
diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c
index 4c29eedb684..c4dcc015941 100644
--- a/src/egl/main/eglapi.c
+++ b/src/egl/main/eglapi.c
@@ -553,6 +553,8 @@ _eglCreateExtensionsString(_EGLDisplay *disp)
_EGL_CHECK_EXTENSION(NV_post_sub_buffer);
+ _EGL_CHECK_EXTENSION(TIZEN_image_native_surface);
+
_EGL_CHECK_EXTENSION(WL_bind_wayland_display);
_EGL_CHECK_EXTENSION(WL_create_wayland_buffer_from_image);
diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h
index cbb098331bf..0a7366b7c07 100644
--- a/src/egl/main/egldisplay.h
+++ b/src/egl/main/egldisplay.h
@@ -149,6 +149,8 @@ struct _egl_extensions
EGLBoolean NV_post_sub_buffer;
+ EGLBoolean TIZEN_image_native_surface;
+
EGLBoolean WL_bind_wayland_display;
EGLBoolean WL_create_wayland_buffer_from_image;
--
2.17.1
@@ -0,0 +1,33 @@
From 66118837ec11358ea86373c343c147e9659c19b8 Mon Sep 17 00:00:00 2001
From: Brendan King <Brendan.King@imgtec.com>
Date: Wed, 8 Nov 2017 15:15:20 +0000
Subject: [PATCH 21/50] egl/wayland: post maximum damage when blitting
When blitting, as part of the "is_different_gpu" case when swapping
buffers, the blit is done using the full surface dimensions, ignoring
the damage region. This results in corruption of the non damaged region
on screen. Workaround this by posting maximum damage when blitting.
A better fix would be to limit the blit to the damaged region, at least
when the number of damage rectangles is 1.
---
src/egl/drivers/dri2/platform_wayland.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c
index 6eb2c7cbdf6..b76c63f1439 100644
--- a/src/egl/drivers/dri2/platform_wayland.c
+++ b/src/egl/drivers/dri2/platform_wayland.c
@@ -1121,7 +1121,8 @@ dri2_wl_swap_buffers_with_damage(_EGLDisplay *disp,
/* If the compositor doesn't support damage_buffer, we deliberately
* ignore the damage region and post maximum damage, due to
* https://bugs.freedesktop.org/78190 */
- if (!n_rects || !try_damage_buffer(dri2_surf, rects, n_rects))
+ if (dri2_dpy->is_different_gpu ||
+ !n_rects || !try_damage_buffer(dri2_surf, rects, n_rects))
wl_surface_damage(dri2_surf->wl_surface_wrapper,
0, 0, INT32_MAX, INT32_MAX);
--
2.17.1
@@ -0,0 +1,46 @@
From d9235705f0c6ff56712577670f9b174f02400f5f Mon Sep 17 00:00:00 2001
From: Brendan King <Brendan.King@imgtec.com>
Date: Wed, 8 Nov 2017 15:26:25 +0000
Subject: [PATCH 22/50] egl/wayland: flush the drawable before blitting
Flush the drawable before blitting in the "is_different_gpu" case when
swapping buffers, and pass the flush flag to the blitImage call. The
change brings the code into line with the way the DRI3 GLX code works.
For the PowerVR driver, the drawable parameters that will be used in
the flush have been obtained previously, including any native fence
associated with the blit source. The blit will result in a new native
fence for the source, and make the one in the drawable parameters
invalid.
---
src/egl/drivers/dri2/platform_wayland.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c
index b76c63f1439..3e6456234fe 100644
--- a/src/egl/drivers/dri2/platform_wayland.c
+++ b/src/egl/drivers/dri2/platform_wayland.c
@@ -1126,6 +1126,8 @@ dri2_wl_swap_buffers_with_damage(_EGLDisplay *disp,
wl_surface_damage(dri2_surf->wl_surface_wrapper,
0, 0, INT32_MAX, INT32_MAX);
+ dri2_flush_drawable_for_swapbuffers(disp, draw);
+
if (dri2_dpy->is_different_gpu) {
_EGLContext *ctx = _eglGetCurrentContext();
struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx);
@@ -1135,10 +1137,9 @@ dri2_wl_swap_buffers_with_damage(_EGLDisplay *disp,
0, 0, dri2_surf->base.Width,
dri2_surf->base.Height,
0, 0, dri2_surf->base.Width,
- dri2_surf->base.Height, 0);
+ dri2_surf->base.Height, __BLIT_FLAG_FLUSH);
}
- dri2_flush_drawable_for_swapbuffers(disp, draw);
dri2_dpy->flush->invalidate(dri2_surf->dri_drawable);
wl_surface_commit(dri2_surf->wl_surface_wrapper);
--
2.17.1
@@ -0,0 +1,380 @@
From 201283a29b24ebff36b1616809c55c71eaf549ea Mon Sep 17 00:00:00 2001
From: Frank Binns <frank.binns@imgtec.com>
Date: Wed, 25 Oct 2017 18:15:00 +0100
Subject: [PATCH 23/50] egl/tizen: create an internal _EGLImage for each tbm
surface
Create an internal _EGLImage the first time a tbm surface is seen
by eglCreateImageKHR (with either the EGL_WAYLAND_BUFFER_WL or
EGL_NATIVE_SURFACE_TIZEN target) and return a copy of it to the
caller. This avoids some tbm surfaces being frequently mapped and
then unmapped from the GPU.
---
src/egl/drivers/dri2/egl_dri2.c | 236 +++++++++++++++++++++++++-
src/egl/drivers/dri2/egl_dri2.h | 12 ++
src/egl/drivers/dri2/platform_tizen.c | 6 +
3 files changed, 251 insertions(+), 3 deletions(-)
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index 04e05567acb..69da031fa00 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -1293,6 +1293,10 @@ dri2_display_destroy(_EGLDisplay *disp)
break;
#ifdef HAVE_TIZEN_PLATFORM
case _EGL_PLATFORM_TIZEN:
+ if (dri2_dpy->image_list_mutex_initialized) {
+ pthread_mutex_destroy(&dri2_dpy->image_list_mutex);
+ dri2_dpy->image_list_mutex_initialized = false;
+ }
if (dri2_dpy->tpl_dpy)
tpl_object_unreference((tpl_object_t *) dri2_dpy->tpl_dpy);
break;
@@ -1349,6 +1353,60 @@ dri2_egl_surface_free_local_buffers(struct dri2_egl_surface *dri2_surf)
}
}
+static void
+dri2_display_release_resources_tizen(_EGLDisplay *disp)
+{
+#ifdef HAVE_TIZEN_PLATFORM
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+ _EGLResource *image_elem;
+
+ /* Destroy _EGLImages in the image_list */
+ pthread_mutex_lock(&dri2_dpy->image_list_mutex);
+ image_elem = dri2_dpy->image_list;
+ dri2_dpy->image_list = NULL;
+ pthread_mutex_unlock(&dri2_dpy->image_list_mutex);
+
+ while (image_elem) {
+ _EGLImage *img = (_EGLImage *) image_elem;
+ struct dri2_egl_image *dri2_img = dri2_egl_image(img);
+
+ image_elem = image_elem->Next;
+
+ /*
+ * Delete the tbm surface user data (_EGLImage), unless the tbm surface
+ * was destroyed since we started processing the image_list.
+ */
+ if (dri2_img->tbm_surf)
+ tbm_surface_internal_delete_user_data(dri2_img->tbm_surf,
+ (unsigned long) disp);
+
+ /*
+ * dri2_orphan_tbm_surf_egl_image won't be able to transfer the
+ * _EGLImage to the orphan_image_list once we have started processing
+ * the image_list so we must destroy it ourselves.
+ */
+ dri2_dpy->image->destroyImage(dri2_img->dri_image);
+ free(dri2_img);
+ }
+
+ /* Destroy _EGLimages in the orphan_image_list*/
+ pthread_mutex_lock(&dri2_dpy->image_list_mutex);
+ image_elem = dri2_dpy->orphan_image_list;
+ dri2_dpy->orphan_image_list = NULL;
+ pthread_mutex_unlock(&dri2_dpy->image_list_mutex);
+
+ while (image_elem) {
+ _EGLImage *img = (_EGLImage *) image_elem;
+ struct dri2_egl_image *dri2_img = dri2_egl_image(img);
+
+ image_elem = image_elem->Next;
+
+ dri2_dpy->image->destroyImage(dri2_img->dri_image);
+ free(dri2_img);
+ }
+#endif
+}
+
/**
* Called via eglTerminate(), drv->Terminate().
*
@@ -1361,6 +1419,8 @@ dri2_terminate(_EGLDisplay *disp)
/* Release all non-current Context/Surfaces. */
_eglReleaseDisplayResources(disp);
+ dri2_display_release_resources_tizen(disp);
+
dri2_display_release(disp);
return EGL_TRUE;
@@ -2338,6 +2398,9 @@ dri2_create_image_khr_renderbuffer(_EGLDisplay *disp, _EGLContext *ctx,
}
#ifdef HAVE_TIZEN_PLATFORM
+static EGLBoolean
+dri2_destroy_image_khr(_EGLDisplay *disp, _EGLImage *image);
+
int
dri2_fourcc_from_tbm_format(tbm_format format)
{
@@ -2434,14 +2497,145 @@ fail_close:
return NULL;
}
+static void
+dri2_orphan_tbm_surf_egl_image(void *user_data)
+{
+ _EGLImage *img = user_data;
+ struct dri2_egl_image *dri2_img = dri2_egl_image(img);
+ _EGLDisplay *disp = img->Resource.Display;
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+
+ /*
+ * Transfer the passed in _EGLImage from the image_list to the
+ * orphan_image_list so that it can be cleaned up at some later
+ * point. This is necessary as the disp->Mutex needs to be held
+ * in order destroy the _EGLImage and this could potentially cause
+ * a deadlock in the event that the tbm surface is destroyed.
+ */
+ pthread_mutex_lock(&dri2_dpy->image_list_mutex);
+ /*
+ * This may be NULL if called via dri2_terminate or if dri2_terminate is
+ * running in another thread.
+ */
+ if (dri2_dpy->image_list) {
+ _EGLResource *image_elem;
+
+ /* Remove the _EGLImage from the image_list */
+ image_elem = dri2_dpy->image_list;
+ if (image_elem != &img->Resource) {
+ while (image_elem) {
+ if (image_elem->Next == &img->Resource)
+ break;
+ image_elem = image_elem->Next;
+ }
+ image_elem->Next = img->Resource.Next;
+ } else {
+ dri2_dpy->image_list = img->Resource.Next;
+ }
+
+ /* Add the _EGLImage to the orphan_image_list */
+ img->Resource.Next = dri2_dpy->orphan_image_list;
+ dri2_dpy->orphan_image_list = &img->Resource;
+ }
+
+ /*
+ * This function may have been called via tbm_surface_destroy so tbm_surf
+ * may be invalid after this function returns.
+ */
+ dri2_img->tbm_surf = NULL;
+ pthread_mutex_unlock(&dri2_dpy->image_list_mutex);
+}
+
+static _EGLImage *
+dri2_get_tbm_surf_egl_image(_EGLDisplay *disp, _EGLContext *ctx,
+ tbm_surface_h tbm_surf)
+{
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+ struct dri2_egl_image *dri2_img;
+ _EGLImage *img;
+ int ret;
+
+ ret = tbm_surface_internal_get_user_data(tbm_surf, (unsigned long) disp,
+ (void **) &img);
+ if (ret)
+ return img;
+
+ img = dri2_create_image_tbm_surface(disp, ctx, tbm_surf);
+ if (!img) {
+ _eglError(EGL_BAD_PARAMETER, "dri2_create_image_tbm_surface failed");
+ goto fail_exit;
+ }
+ dri2_img = dri2_egl_image(img);
+
+ /* Use 'disp' as the 'key' as the _EGLimage is tied to it */
+ ret = tbm_surface_internal_add_user_data(tbm_surf, (unsigned long) disp,
+ dri2_orphan_tbm_surf_egl_image);
+ if (!ret) {
+ _eglError(EGL_BAD_PARAMETER, "dri2_get_tbm_surf_egl_image");
+ goto fail_destroy_image;
+ }
+
+ ret = tbm_surface_internal_set_user_data(tbm_surf, (unsigned long) disp, img);
+ if (!ret) {
+ _eglError(EGL_BAD_PARAMETER, "dri2_get_tbm_surf_egl_image");
+ goto fail_delete_user_data;
+ }
+
+ /*
+ * Store the tbm surface so that the user data (_EGLImage) can be destroyed
+ * in dri2_terminate. We don't take a reference on the surface as this would
+ * prevent it from being destroyed until eglTerminate is called. This isn't
+ * an issue since it will be set to NULL, via dri2_orphan_tbm_surf_egl_image,
+ * once the surface is destroyed (although it's actually safe to call tbm
+ * surface functions with stale/NULL pointers).
+ */
+ dri2_img->tbm_surf = tbm_surf;
+
+ /*
+ * Add to the list of _EGLImages that are associated with tbm surfaces.
+ * This allows the _EGLImage to be destroyed if the application calls
+ * eglTerminate before the tbm surface is destroyed.
+ */
+ pthread_mutex_lock(&dri2_dpy->image_list_mutex);
+ img->Resource.Next = dri2_dpy->image_list;
+ dri2_dpy->image_list = &img->Resource;
+ pthread_mutex_unlock(&dri2_dpy->image_list_mutex);
+
+ return img;
+
+fail_delete_user_data:
+ tbm_surface_internal_delete_user_data(tbm_surf, (unsigned long) disp);
+fail_destroy_image:
+ dri2_destroy_image_khr(disp, img);
+fail_exit:
+ return NULL;
+}
+
static _EGLImage *
dri2_create_image_tizen(_EGLDisplay *disp, _EGLContext *ctx,
EGLClientBuffer _buffer,
const EGLint *attr_list)
{
- tbm_surface_h tbm_surf = (tbm_surface_h)_buffer;
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+ tbm_surface_h tbm_surf = (tbm_surface_h) _buffer;
+ _EGLImage *img;
+ struct dri2_egl_image *dri2_img;
+ __DRIimage *dri_image;
+
+ img = dri2_get_tbm_surf_egl_image(disp, ctx, tbm_surf);
+ if (!img) {
+ _eglError(EGL_BAD_PARAMETER, "dri2_create_image_tizen");
+ return NULL;
+ }
+ dri2_img = dri2_egl_image(img);
+
+ dri_image = dri2_dpy->image->fromPlanar(dri2_img->dri_image, 0, NULL);
+ if (!dri_image) {
+ _eglError(EGL_BAD_PARAMETER, "dri2_create_image_tizen");
+ return NULL;
+ }
- return dri2_create_image_tbm_surface(disp, ctx, tbm_surf);
+ return dri2_create_image_from_dri(disp, dri_image);
}
static _EGLImage *
@@ -2453,6 +2647,9 @@ dri2_create_image_wayland_wl_buffer_tizen(_EGLDisplay *disp, _EGLContext *ctx,
_EGLImageAttribs attrs;
tbm_surface_h tbm_surf;
tbm_surface_info_s info;
+ _EGLImage *img;
+ struct dri2_egl_image *dri2_img;
+ __DRIimage *dri_image;
tbm_surf = tpl_display_get_buffer_from_native_pixmap(dri2_dpy->tpl_dpy,
(tpl_handle_t) _buffer);
@@ -2483,7 +2680,21 @@ dri2_create_image_wayland_wl_buffer_tizen(_EGLDisplay *disp, _EGLContext *ctx,
return NULL;
}
- return dri2_create_image_tbm_surface(disp, ctx, tbm_surf);
+ img = dri2_get_tbm_surf_egl_image(disp, ctx, tbm_surf);
+ if (!img) {
+ _eglError(EGL_BAD_PARAMETER, "dri2_create_image_wayland_wl_buffer_tizen");
+ return NULL;
+ }
+ dri2_img = dri2_egl_image(img);
+
+ dri_image =
+ dri2_dpy->image->fromPlanar(dri2_img->dri_image, attrs.PlaneWL, NULL);
+ if (!dri_image) {
+ _eglError(EGL_BAD_PARAMETER, "dri2_create_image_wayland_wl_buffer_tizen");
+ return NULL;
+ }
+
+ return dri2_create_image_from_dri(disp, dri_image);
}
#endif
@@ -3400,10 +3611,29 @@ dri2_destroy_image_khr(_EGLDisplay *disp, _EGLImage *image)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
struct dri2_egl_image *dri2_img = dri2_egl_image(image);
+#ifdef HAVE_TIZEN_PLATFORM
+ _EGLResource *image_elem;
+#endif
dri2_dpy->image->destroyImage(dri2_img->dri_image);
free(dri2_img);
+#ifdef HAVE_TIZEN_PLATFORM
+ /* Take the opportunity to destroy orphaned tbm surface _EGLImages */
+ pthread_mutex_lock(&dri2_dpy->image_list_mutex);
+ image_elem = dri2_dpy->orphan_image_list;
+ dri2_dpy->orphan_image_list = NULL;
+ pthread_mutex_unlock(&dri2_dpy->image_list_mutex);
+
+ while (image_elem) {
+ dri2_img = dri2_egl_image((_EGLImage *) image_elem);
+ image_elem = image_elem->Next;
+
+ dri2_dpy->image->destroyImage(dri2_img->dri_image);
+ free(dri2_img);
+ }
+#endif
+
return EGL_TRUE;
}
diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h
index 4d66936da28..e516c54810d 100644
--- a/src/egl/drivers/dri2/egl_dri2.h
+++ b/src/egl/drivers/dri2/egl_dri2.h
@@ -260,6 +260,15 @@ struct dri2_egl_display
#ifdef HAVE_TIZEN_PLATFORM
tpl_display_t *tpl_dpy;
+ /*
+ * The image_list_mutex protects the image_list and orphan_image_list. It
+ * should never be held while calling a libtbm function as this may result
+ * in a deadlock.
+ */
+ pthread_mutex_t image_list_mutex;
+ bool image_list_mutex_initialized;
+ _EGLResource *image_list;
+ _EGLResource *orphan_image_list;
#endif
};
@@ -404,6 +413,9 @@ struct dri2_egl_image
{
_EGLImage base;
__DRIimage *dri_image;
+#ifdef HAVE_TIZEN_PLATFORM
+ tbm_surface_h tbm_surf;
+#endif
};
struct dri2_egl_sync {
diff --git a/src/egl/drivers/dri2/platform_tizen.c b/src/egl/drivers/dri2/platform_tizen.c
index ad75c115d7e..49462152beb 100644
--- a/src/egl/drivers/dri2/platform_tizen.c
+++ b/src/egl/drivers/dri2/platform_tizen.c
@@ -891,6 +891,7 @@ dri2_initialize_tizen(_EGLDisplay *dpy)
{
struct dri2_egl_display *dri2_dpy;
int i;
+ int err;
dri2_dpy = calloc(1, sizeof(*dri2_dpy));
if (!dri2_dpy)
@@ -906,6 +907,11 @@ dri2_initialize_tizen(_EGLDisplay *dpy)
goto cleanup;
}
+ err = pthread_mutex_init(&dri2_dpy->image_list_mutex, NULL);
+ if (err)
+ goto cleanup;
+ dri2_dpy->image_list_mutex_initialized = true;
+
for (i = TIZEN_DRM_RENDER_MINOR_START; i <= TIZEN_DRM_RENDER_MINOR_MAX; i++) {
char *render_path;
--
2.17.1
@@ -0,0 +1,54 @@
From b9cce4ff02e66d6db913cd10352af61d3d81d9ad Mon Sep 17 00:00:00 2001
From: Brendan King <Brendan.King@imgtec.com>
Date: Thu, 23 Nov 2017 15:50:21 +0000
Subject: [PATCH 24/50] dri: use a supported API in driCreateNewContext
Don't assume the screen supports OpenGL when creating a new context,
use an API that the screen supports.
---
src/mesa/drivers/dri/common/dri_util.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c
index caed5fa6a68..6c45eb007fc 100644
--- a/src/mesa/drivers/dri/common/dri_util.c
+++ b/src/mesa/drivers/dri/common/dri_util.c
@@ -50,6 +50,7 @@
#include "main/debug_output.h"
#include "main/errors.h"
#include "main/macros.h"
+#include "util/bitscan.h"
driOptionDescription __dri2ConfigOptions[] = {
DRI_CONF_SECTION_DEBUG
@@ -332,7 +333,11 @@ driCreateContextAttribs(__DRIscreen *screen, int api,
mesa_api = API_OPENGLES;
break;
case __DRI_API_GLES2:
+ ctx_config.major_version = 2;
+ mesa_api = API_OPENGLES2;
+ break;
case __DRI_API_GLES3:
+ ctx_config.major_version = 3;
mesa_api = API_OPENGLES2;
break;
case __DRI_API_OPENGL_CORE:
@@ -515,7 +520,14 @@ static __DRIcontext *
driCreateNewContext(__DRIscreen *screen, const __DRIconfig *config,
__DRIcontext *shared, void *data)
{
- return driCreateNewContextForAPI(screen, __DRI_API_OPENGL,
+ int apifs;
+
+ apifs = ffs(screen->api_mask);
+
+ if (!apifs)
+ return NULL;
+
+ return driCreateNewContextForAPI(screen, apifs - 1,
config, shared, data);
}
--
2.17.1
@@ -0,0 +1,157 @@
From 7b733f4e2b20614d9f367186810c4fcac4aa820c Mon Sep 17 00:00:00 2001
From: Brendan King <Brendan.King@imgtec.com>
Date: Tue, 28 Nov 2017 16:27:38 +0000
Subject: [PATCH 25/50] gbm: add gbm_bo_blit
For the GBM DRI backend, gbm_bo_blit is a wrapper around blitImage in
the DRI Image extension.
---
src/gbm/backends/dri/gbm_dri.c | 32 ++++++++++++++++++++++++++++++++
src/gbm/main/gbm.c | 28 ++++++++++++++++++++++++++++
src/gbm/main/gbm.h | 21 +++++++++++++++++++++
src/gbm/main/gbmint.h | 4 ++++
4 files changed, 85 insertions(+)
diff --git a/src/gbm/backends/dri/gbm_dri.c b/src/gbm/backends/dri/gbm_dri.c
index b5634741554..ca865f4df9c 100644
--- a/src/gbm/backends/dri/gbm_dri.c
+++ b/src/gbm/backends/dri/gbm_dri.c
@@ -1334,6 +1334,37 @@ gbm_dri_surface_destroy(struct gbm_surface *_surf)
free(surf);
}
+static int
+gbm_dri_bo_blit(struct gbm_bo *_dst_bo, struct gbm_bo *_src_bo,
+ int dst_x0, int dst_y0, int dst_width, int dst_height,
+ int src_x0, int src_y0, int src_width, int src_height,
+ enum gbm_blit_flags flags)
+{
+ struct gbm_dri_device *dri = gbm_dri_device(_dst_bo->gbm);
+ struct gbm_dri_bo *dst_bo = gbm_dri_bo(_dst_bo);
+ struct gbm_dri_bo *src_bo = gbm_dri_bo(_src_bo);
+
+ if (!dri->image || dri->image->base.version < 9 || !dri->image->blitImage) {
+ errno = ENOSYS;
+ return 0;
+ }
+
+ mtx_lock(&dri->mutex);
+ if (!dri->context)
+ dri->context = dri->dri2->createNewContext(dri->screen, NULL,
+ NULL, NULL);
+ assert(dri->context);
+ mtx_unlock(&dri->mutex);
+
+ /* GBM flags and DRI flags are the same, so just pass them on */
+ dri->image->blitImage(dri->context, dst_bo->image, src_bo->image,
+ dst_x0, dst_y0, dst_width, dst_height,
+ src_x0, src_y0, src_width, src_height,
+ flags);
+
+ return 1;
+}
+
static void
dri_destroy(struct gbm_device *gbm)
{
@@ -1383,6 +1414,7 @@ dri_device_create(int fd)
dri->base.destroy = dri_destroy;
dri->base.surface_create = gbm_dri_surface_create;
dri->base.surface_destroy = gbm_dri_surface_destroy;
+ dri->base.bo_blit = gbm_dri_bo_blit;
dri->base.name = "drm";
diff --git a/src/gbm/main/gbm.c b/src/gbm/main/gbm.c
index 954b3c35b0d..78de34286bd 100644
--- a/src/gbm/main/gbm.c
+++ b/src/gbm/main/gbm.c
@@ -741,3 +741,31 @@ gbm_format_get_name(uint32_t gbm_format, struct gbm_format_name_desc *desc)
return desc->name;
}
+
+/**
+ * Blit from one buffer object to another
+ *
+ * \param dst_bo The destination buffer object
+ * \param src_bo The source buffer object
+ * \param dst_x0 The X coordinate (top left origin) of the destination rectangle
+ * \param dst_y0 The Y coordinate (top left origin) of the destination rectangle
+ * \param dst_width The width of the destination rectangle
+ * \param dst_height The height of the destination rectangle
+ * \param src_x0 The X coordinate (top left origin) of the source rectangle
+ * \param src_y0 The Y coordinate (top left origin) of the source rectangle
+ * \param src_width The width of the source rectangle
+ * \param src_height The height of the source rectangle
+ * \param flags The flags for the blit
+ * \return 1 on success, 0 otherwise
+ */
+GBM_EXPORT int
+gbm_bo_blit(struct gbm_bo *dst_bo, struct gbm_bo *src_bo,
+ int dst_x0, int dst_y0, int dst_width, int dst_height,
+ int src_x0, int src_y0, int src_width, int src_height,
+ enum gbm_blit_flags flags)
+{
+ return dst_bo->gbm->bo_blit(dst_bo, src_bo,
+ dst_x0, dst_y0, dst_width, dst_height,
+ src_x0, src_y0, src_width, src_height,
+ flags);
+}
diff --git a/src/gbm/main/gbm.h b/src/gbm/main/gbm.h
index 5801cd526a0..e754edd5654 100644
--- a/src/gbm/main/gbm.h
+++ b/src/gbm/main/gbm.h
@@ -246,6 +246,21 @@ enum gbm_bo_flags {
GBM_BO_USE_PROTECTED = (1 << 5),
};
+/**
+ * Flags to control the behaviour of a blit - these are passed to
+ * gbm_bo_blit().
+ */
+enum gbm_blit_flags {
+ /**
+ * Force blit execution in finite time
+ */
+ GBM_BLIT_FLAG_FLUSH = 0x0001,
+ /**
+ * Flush, and wait for the blit to complete
+ */
+ GBM_BLIT_FLAG_FINISH = 0x0002
+};
+
int
gbm_device_get_fd(struct gbm_device *gbm);
@@ -422,6 +437,12 @@ gbm_surface_destroy(struct gbm_surface *surface);
char *
gbm_format_get_name(uint32_t gbm_format, struct gbm_format_name_desc *desc);
+int
+gbm_bo_blit(struct gbm_bo *dst_bo, struct gbm_bo *src_bo,
+ int dst_x0, int dst_y0, int dst_width, int dst_height,
+ int src_x0, int src_y0, int src_width, int src_height,
+ enum gbm_blit_flags flags);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/gbm/main/gbmint.h b/src/gbm/main/gbmint.h
index 192577431e2..fb95954ab32 100644
--- a/src/gbm/main/gbmint.h
+++ b/src/gbm/main/gbmint.h
@@ -98,6 +98,10 @@ struct gbm_device {
struct gbm_bo *bo);
int (*surface_has_free_buffers)(struct gbm_surface *surface);
void (*surface_destroy)(struct gbm_surface *surface);
+ int (*bo_blit)(struct gbm_bo *dst_bo, struct gbm_bo *src_bo,
+ int dst_x0, int dst_y0, int dst_width, int dst_height,
+ int src_x0, int src_y0, int src_width, int src_height,
+ enum gbm_blit_flags flags);
};
/**
--
2.17.1
@@ -0,0 +1,44 @@
From 5ed87bbc92b8034b14060d5170c3d82bfce54fb7 Mon Sep 17 00:00:00 2001
From: Brendan King <Brendan.King@imgtec.com>
Date: Fri, 1 Dec 2017 08:31:15 +0000
Subject: [PATCH 26/50] gbm: don't assert if DRI context creation fails
If the DRI backend fails to create a DRI context, return an error,
rather than asserting.
---
src/gbm/backends/dri/gbm_dri.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/src/gbm/backends/dri/gbm_dri.c b/src/gbm/backends/dri/gbm_dri.c
index ca865f4df9c..f9adbc5c001 100644
--- a/src/gbm/backends/dri/gbm_dri.c
+++ b/src/gbm/backends/dri/gbm_dri.c
@@ -1224,8 +1224,11 @@ gbm_dri_bo_map(struct gbm_bo *_bo,
if (!dri->context)
dri->context = dri->dri2->createNewContext(dri->screen, NULL,
NULL, NULL);
- assert(dri->context);
mtx_unlock(&dri->mutex);
+ if (!dri->context) {
+ errno = ENOSYS;
+ return NULL;
+ }
/* GBM flags and DRI flags are the same, so just pass them on */
return dri->image->mapImage(dri->context, bo->image, x, y,
@@ -1353,8 +1356,11 @@ gbm_dri_bo_blit(struct gbm_bo *_dst_bo, struct gbm_bo *_src_bo,
if (!dri->context)
dri->context = dri->dri2->createNewContext(dri->screen, NULL,
NULL, NULL);
- assert(dri->context);
mtx_unlock(&dri->mutex);
+ if (!dri->context) {
+ errno = ENOSYS;
+ return 0;
+ }
/* GBM flags and DRI flags are the same, so just pass them on */
dri->image->blitImage(dri->context, dst_bo->image, src_bo->image,
--
2.17.1
@@ -0,0 +1,471 @@
From daf743a8fdc7171dea73c390e3255b5c6e19046c Mon Sep 17 00:00:00 2001
From: Brendan King <Brendan.King@imgtec.com>
Date: Fri, 17 Mar 2017 16:23:07 +0000
Subject: [PATCH 27/50] egl/wayland: add pbuffer support
The pbuffer code is based on that in the Surfaceless platform code.
---
src/egl/drivers/dri2/egl_dri2.h | 4 +
src/egl/drivers/dri2/platform_wayland.c | 270 ++++++++++++++++++++----
2 files changed, 236 insertions(+), 38 deletions(-)
diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h
index e516c54810d..a33d87b23c1 100644
--- a/src/egl/drivers/dri2/egl_dri2.h
+++ b/src/egl/drivers/dri2/egl_dri2.h
@@ -396,6 +396,10 @@ struct dri2_egl_surface
__DRIimage *front;
unsigned int visual;
+#ifdef HAVE_WAYLAND_PLATFORM
+ void *swrast_front;
+#endif
+
int out_fence_fd;
EGLBoolean enable_out_fence;
diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c
index 3e6456234fe..43ad6420174 100644
--- a/src/egl/drivers/dri2/platform_wayland.c
+++ b/src/egl/drivers/dri2/platform_wayland.c
@@ -416,6 +416,99 @@ dri2_wl_create_pixmap_surface(_EGLDisplay *disp, _EGLConfig *conf,
return NULL;
}
+static _EGLSurface *
+dri2_wl_create_pbuffer_surface(_EGLDisplay *disp, _EGLConfig *conf,
+ const EGLint *attrib_list)
+{
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+ struct dri2_egl_config *dri2_conf = dri2_egl_config(conf);
+ struct dri2_egl_surface *dri2_surf;
+ int visual_idx;
+ const __DRIconfig *config;
+
+ dri2_surf = calloc(1, sizeof *dri2_surf);
+ if (!dri2_surf) {
+ _eglError(EGL_BAD_ALLOC, "dri2_create_surface");
+ return NULL;
+ }
+
+ if (!dri2_init_surface(&dri2_surf->base, disp, EGL_PBUFFER_BIT, conf,
+ attrib_list, false, NULL))
+ goto cleanup_surf;
+
+ config = dri2_get_dri_config(dri2_conf, EGL_PBUFFER_BIT,
+ dri2_surf->base.GLColorspace);
+ if (!config) {
+ _eglError(EGL_BAD_MATCH, "Unsupported surfacetype/colorspace configuration");
+ goto cleanup_surf;
+ }
+
+ visual_idx = dri2_wl_visual_idx_from_config(dri2_dpy, config);
+ assert(visual_idx != -1);
+
+ if (dri2_dpy->wl_dmabuf || dri2_dpy->wl_drm) {
+ dri2_surf->format = dri2_wl_visuals[visual_idx].wl_drm_format;
+ } else {
+ assert(dri2_dpy->wl_shm);
+ dri2_surf->format = dri2_wl_visuals[visual_idx].wl_shm_format;
+ }
+
+ if (!dri2_create_drawable(dri2_dpy, config, dri2_surf, dri2_surf))
+ goto cleanup_surf;
+
+ return &dri2_surf->base;
+
+ cleanup_surf:
+ free(dri2_surf);
+
+ return NULL;
+}
+
+static int
+allocate_front_buffer(struct dri2_egl_display *dri2_dpy,
+ struct dri2_egl_surface *dri2_surf,
+ EGLBoolean need_name)
+{
+ int use_flags = need_name ? __DRI_IMAGE_USE_SHARE : 0;
+ int visual_idx;
+ unsigned int dri_image_format;
+
+ visual_idx = dri2_wl_visual_idx_from_fourcc(dri2_surf->format);
+ assert(visual_idx != -1);
+ dri_image_format = dri2_wl_visuals[visual_idx].dri_image_format;
+
+ if (!dri2_surf->front)
+ dri2_surf->front = dri2_dpy->image->createImage(dri2_dpy->dri_screen,
+ dri2_surf->base.Width,
+ dri2_surf->base.Height,
+ dri_image_format,
+ use_flags,
+ NULL);
+ if (!dri2_surf->front) {
+ _eglError(EGL_BAD_ALLOC, "failed to allocate front buffer");
+ return -1;
+ }
+
+ return 0;
+}
+
+static void
+free_front_buffer(struct dri2_egl_display *dri2_dpy,
+ struct dri2_egl_surface *dri2_surf)
+{
+ if (dri2_surf->front) {
+ dri2_dpy->image->destroyImage(dri2_surf->front);
+ dri2_surf->front = NULL;
+ }
+}
+
+static void
+swrast_free_front_buffer(struct dri2_egl_surface *dri2_surf)
+{
+ free(dri2_surf->swrast_front);
+ dri2_surf->swrast_front = NULL;
+}
+
/**
* Called via eglDestroySurface(), drv->DestroySurface().
*/
@@ -442,6 +535,9 @@ dri2_wl_destroy_surface(_EGLDisplay *disp, _EGLSurface *surf)
if (dri2_dpy->dri2)
dri2_egl_surface_free_local_buffers(dri2_surf);
+ free_front_buffer(dri2_dpy, dri2_surf);
+ swrast_free_front_buffer(dri2_surf);
+
if (dri2_surf->throttle_callback)
wl_callback_destroy(dri2_surf->throttle_callback);
@@ -451,11 +547,14 @@ dri2_wl_destroy_surface(_EGLDisplay *disp, _EGLSurface *surf)
dri2_surf->wl_win->destroy_window_callback = NULL;
}
- wl_proxy_wrapper_destroy(dri2_surf->wl_surface_wrapper);
- wl_proxy_wrapper_destroy(dri2_surf->wl_dpy_wrapper);
+ if (dri2_surf->wl_surface_wrapper)
+ wl_proxy_wrapper_destroy(dri2_surf->wl_surface_wrapper);
+ if (dri2_surf->wl_dpy_wrapper)
+ wl_proxy_wrapper_destroy(dri2_surf->wl_dpy_wrapper);
if (dri2_surf->wl_drm_wrapper)
wl_proxy_wrapper_destroy(dri2_surf->wl_drm_wrapper);
- wl_event_queue_destroy(dri2_surf->wl_queue);
+ if (dri2_surf->wl_queue)
+ wl_event_queue_destroy(dri2_surf->wl_queue);
dri2_fini_surface(surf);
free(surf);
@@ -642,20 +741,16 @@ get_back_bo(struct dri2_egl_surface *dri2_surf)
static void
-back_bo_to_dri_buffer(struct dri2_egl_surface *dri2_surf, __DRIbuffer *buffer)
+bo_to_dri_buffer(struct dri2_egl_display *dri2_dpy, unsigned int attachment,
+ __DRIimage *image, __DRIbuffer *buffer)
{
- struct dri2_egl_display *dri2_dpy =
- dri2_egl_display(dri2_surf->base.Resource.Display);
- __DRIimage *image;
int name, pitch, format;
- image = dri2_surf->back->dri_image;
-
dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_NAME, &name);
dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_STRIDE, &pitch);
dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_FORMAT, &format);
- buffer->attachment = __DRI_BUFFER_BACK_LEFT;
+ buffer->attachment = attachment;
buffer->name = name;
buffer->pitch = pitch;
buffer->flags = 0;
@@ -670,12 +765,28 @@ back_bo_to_dri_buffer(struct dri2_egl_surface *dri2_surf, __DRIbuffer *buffer)
}
}
-static int
-update_buffers(struct dri2_egl_surface *dri2_surf)
+static void
+back_bo_to_dri_buffer(struct dri2_egl_display *dri2_dpy,
+ struct dri2_egl_surface *dri2_surf,
+ __DRIbuffer *buffer)
{
- struct dri2_egl_display *dri2_dpy =
- dri2_egl_display(dri2_surf->base.Resource.Display);
+ bo_to_dri_buffer(dri2_dpy, __DRI_BUFFER_BACK_LEFT,
+ dri2_surf->back->dri_image, buffer);
+}
+static void
+front_bo_to_dri_buffer(struct dri2_egl_display *dri2_dpy,
+ struct dri2_egl_surface *dri2_surf,
+ __DRIbuffer *buffer)
+{
+ bo_to_dri_buffer(dri2_dpy, __DRI_BUFFER_FRONT_LEFT,
+ dri2_surf->front, buffer);
+}
+
+static int
+update_buffers(struct dri2_egl_display *dri2_dpy,
+ struct dri2_egl_surface *dri2_surf)
+{
if (dri2_surf->base.Width != dri2_surf->wl_win->width ||
dri2_surf->base.Height != dri2_surf->wl_win->height) {
@@ -715,12 +826,13 @@ update_buffers(struct dri2_egl_surface *dri2_surf)
}
static int
-update_buffers_if_needed(struct dri2_egl_surface *dri2_surf)
+update_buffers_if_needed(struct dri2_egl_display *dri2_dpy,
+ struct dri2_egl_surface *dri2_surf)
{
if (dri2_surf->back != NULL)
return 0;
- return update_buffers(dri2_surf);
+ return update_buffers(dri2_dpy, dri2_surf);
}
static __DRIbuffer *
@@ -730,17 +842,25 @@ dri2_wl_get_buffers_with_format(__DRIdrawable * driDrawable,
int *out_count, void *loaderPrivate)
{
struct dri2_egl_surface *dri2_surf = loaderPrivate;
+ struct dri2_egl_display *dri2_dpy =
+ dri2_egl_display(dri2_surf->base.Resource.Display);
int i, j;
- if (update_buffers(dri2_surf) < 0)
- return NULL;
-
for (i = 0, j = 0; i < 2 * count; i += 2, j++) {
__DRIbuffer *local;
switch (attachments[i]) {
case __DRI_BUFFER_BACK_LEFT:
- back_bo_to_dri_buffer(dri2_surf, &dri2_surf->buffers[j]);
+ if (update_buffers(dri2_dpy, dri2_surf) < 0)
+ return NULL;
+
+ back_bo_to_dri_buffer(dri2_dpy, dri2_surf, &dri2_surf->buffers[j]);
+ break;
+ case __DRI_BUFFER_FRONT_LEFT:
+ if (allocate_front_buffer(dri2_dpy, dri2_surf, EGL_TRUE) < 0)
+ return NULL;
+
+ front_bo_to_dri_buffer(dri2_dpy, dri2_surf, &dri2_surf->buffers[j]);
break;
default:
local = dri2_egl_surface_alloc_local_buffer(dri2_surf, attachments[i],
@@ -810,12 +930,30 @@ image_get_buffers(__DRIdrawable *driDrawable,
struct __DRIimageList *buffers)
{
struct dri2_egl_surface *dri2_surf = loaderPrivate;
+ struct dri2_egl_display *dri2_dpy =
+ dri2_egl_display(dri2_surf->base.Resource.Display);
- if (update_buffers(dri2_surf) < 0)
- return 0;
+ buffers->image_mask = 0;
+ buffers->front = NULL;
+ buffers->back = NULL;
+
+ if (buffer_mask & __DRI_IMAGE_BUFFER_BACK)
+ {
+ if (update_buffers(dri2_dpy, dri2_surf) < 0)
+ return 0;
+
+ buffers->image_mask |= __DRI_IMAGE_BUFFER_BACK;
+ buffers->back = dri2_surf->back->dri_image;
+ }
- buffers->image_mask = __DRI_IMAGE_BUFFER_BACK;
- buffers->back = dri2_surf->back->dri_image;
+ if (buffer_mask & __DRI_IMAGE_BUFFER_FRONT)
+ {
+ if (allocate_front_buffer(dri2_dpy, dri2_surf, EGL_FALSE) < 0)
+ return 0;
+
+ buffers->image_mask |= __DRI_IMAGE_BUFFER_FRONT;
+ buffers->front = dri2_surf->front;
+ }
return 1;
}
@@ -1066,6 +1204,9 @@ dri2_wl_swap_buffers_with_damage(_EGLDisplay *disp,
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
+ if (draw->Type != EGL_WINDOW_BIT)
+ return EGL_TRUE;
+
while (dri2_surf->throttle_callback != NULL)
if (wl_display_dispatch_queue(dri2_dpy->wl_dpy,
dri2_surf->wl_queue) == -1)
@@ -1077,7 +1218,7 @@ dri2_wl_swap_buffers_with_damage(_EGLDisplay *disp,
/* Make sure we have a back buffer in case we're swapping without ever
* rendering. */
- if (update_buffers_if_needed(dri2_surf) < 0)
+ if (update_buffers_if_needed(dri2_dpy, dri2_surf) < 0)
return _eglError(EGL_BAD_ALLOC, "dri2_swap_buffers");
if (draw->SwapInterval > 0) {
@@ -1162,9 +1303,13 @@ dri2_wl_swap_buffers_with_damage(_EGLDisplay *disp,
static EGLint
dri2_wl_query_buffer_age(_EGLDisplay *disp, _EGLSurface *surface)
{
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surface);
- if (update_buffers_if_needed(dri2_surf) < 0) {
+ if (surface->Type != EGL_WINDOW_BIT)
+ return 0;
+
+ if (update_buffers_if_needed(dri2_dpy, dri2_surf) < 0) {
_eglError(EGL_BAD_ALLOC, "dri2_query_buffer_age");
return -1;
}
@@ -1385,6 +1530,7 @@ static const struct dri2_egl_display_vtbl dri2_wl_display_vtbl = {
.authenticate = dri2_wl_authenticate,
.create_window_surface = dri2_wl_create_window_surface,
.create_pixmap_surface = dri2_wl_create_pixmap_surface,
+ .create_pbuffer_surface = dri2_wl_create_pbuffer_surface,
.destroy_surface = dri2_wl_destroy_surface,
.create_image = dri2_create_image_khr,
.swap_buffers = dri2_wl_swap_buffers,
@@ -1427,7 +1573,7 @@ dri2_wl_add_configs_for_visuals(_EGLDisplay *disp)
continue;
dri2_conf = dri2_add_config(disp, dri2_dpy->driver_configs[i],
- count + 1, EGL_WINDOW_BIT, NULL, dri2_wl_visuals[j].rgba_shifts, dri2_wl_visuals[j].rgba_sizes);
+ count + 1, EGL_WINDOW_BIT | EGL_PBUFFER_BIT, NULL, dri2_wl_visuals[j].rgba_shifts, dri2_wl_visuals[j].rgba_sizes);
if (dri2_conf) {
if (dri2_conf->base.ConfigID == count + 1)
count++;
@@ -1662,6 +1808,23 @@ dri2_wl_swrast_get_stride_for_format(int format, int w)
return w * (dri2_wl_visuals[visual_idx].bpp / 8);
}
+static EGLBoolean
+swrast_allocate_local_buffer(int format, int w, int h, void **data)
+{
+ int stride, size_map;
+ void *data_map;
+
+ stride = dri2_wl_swrast_get_stride_for_format(format, w);
+ size_map = h * stride;
+
+ data_map = malloc(size_map);
+ if (!data_map)
+ return EGL_FALSE;
+
+ *data = data_map;
+ return EGL_TRUE;
+}
+
static EGLBoolean
dri2_wl_swrast_allocate_buffer(struct dri2_egl_surface *dri2_surf,
int format, int w, int h,
@@ -1782,8 +1945,24 @@ swrast_update_buffers(struct dri2_egl_surface *dri2_surf)
return 0;
}
+static int
+swrast_allocate_front_buffer(struct dri2_egl_surface *dri2_surf)
+{
+ if (!dri2_surf->swrast_front) {
+ if (!swrast_allocate_local_buffer(dri2_surf->format,
+ dri2_surf->base.Width,
+ dri2_surf->base.Height,
+ &dri2_surf->swrast_front)) {
+ _eglError(EGL_BAD_ALLOC, "failed to allocate front buffer");
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
static void*
-dri2_wl_swrast_get_frontbuffer_data(struct dri2_egl_surface *dri2_surf)
+dri2_wl_swrast_get_currentbuffer_data(struct dri2_egl_surface *dri2_surf)
{
/* if there has been a resize: */
if (!dri2_surf->current)
@@ -1853,7 +2032,9 @@ dri2_wl_swrast_get_drawable_info(__DRIdrawable * draw,
{
struct dri2_egl_surface *dri2_surf = loaderPrivate;
- (void) swrast_update_buffers(dri2_surf);
+ if (dri2_surf->base.Type == EGL_WINDOW_BIT)
+ (void) swrast_update_buffers(dri2_surf);
+
*x = 0;
*y = 0;
*w = dri2_surf->base.Width;
@@ -1872,7 +2053,11 @@ dri2_wl_swrast_get_image(__DRIdrawable * read,
int dst_stride = copy_width;
char *src, *dst;
- src = dri2_wl_swrast_get_frontbuffer_data(dri2_surf);
+ if (dri2_surf->base.Type == EGL_WINDOW_BIT)
+ src = dri2_wl_swrast_get_currentbuffer_data(dri2_surf);
+ else
+ src = dri2_surf->swrast_front;
+
if (!src) {
memset(data, 0, copy_width * h);
return;
@@ -1910,14 +2095,20 @@ dri2_wl_swrast_put_image2(__DRIdrawable * draw, int op,
assert(copy_width <= stride);
- (void) swrast_update_buffers(dri2_surf);
- dst = dri2_wl_swrast_get_backbuffer_data(dri2_surf);
+ if (dri2_surf->base.Type == EGL_WINDOW_BIT) {
+ (void) swrast_update_buffers(dri2_surf);
+ dst = dri2_wl_swrast_get_backbuffer_data(dri2_surf);
- /* partial copy, copy old content */
- if (copy_width < dst_stride)
- dri2_wl_swrast_get_image(draw, 0, 0,
- dri2_surf->base.Width, dri2_surf->base.Height,
- dst, loaderPrivate);
+ /* partial copy, copy old content */
+ if (copy_width < dst_stride)
+ dri2_wl_swrast_get_image(draw, 0, 0,
+ dri2_surf->base.Width, dri2_surf->base.Height,
+ dst, loaderPrivate);
+ } else {
+ (void) swrast_allocate_front_buffer(dri2_surf);
+ dst = dri2_surf->swrast_front;
+ assert(dst);
+ }
dst += x_offset;
dst += y * dst_stride;
@@ -1935,7 +2126,9 @@ dri2_wl_swrast_put_image2(__DRIdrawable * draw, int op,
src += stride;
dst += dst_stride;
}
- dri2_wl_swrast_commit_backbuffer(dri2_surf);
+
+ if (dri2_surf->base.Type == EGL_WINDOW_BIT)
+ dri2_wl_swrast_commit_backbuffer(dri2_surf);
}
static void
@@ -2000,6 +2193,7 @@ static const struct dri2_egl_display_vtbl dri2_wl_swrast_display_vtbl = {
.authenticate = NULL,
.create_window_surface = dri2_wl_create_window_surface,
.create_pixmap_surface = dri2_wl_create_pixmap_surface,
+ .create_pbuffer_surface = dri2_wl_create_pbuffer_surface,
.destroy_surface = dri2_wl_destroy_surface,
.create_image = dri2_create_image_khr,
.swap_buffers = dri2_wl_swrast_swap_buffers,
--
2.17.1
@@ -0,0 +1,121 @@
From eeda62ee212dcd8fae6c138f4a3b27e3f2ffe8c0 Mon Sep 17 00:00:00 2001
From: Frank Binns <frank.binns@imgtec.com>
Date: Mon, 18 Dec 2017 19:22:50 +0000
Subject: [PATCH 28/50] egl/tizen: support DRI driver handling of swap preserve
This adds a new flag (__DRI_IMAGE_BUFFER_PREV) to the __DRIimageBufferMask
enum that allows a DRI driver to request the previous back buffer. This
will only be returned if the swap behaviour is EGL_BUFFER_PRESERVED and
should result in the DRI driver preserving the previous content instead of
this being done in the platform code. For hardware that supports it, this
should avoid a blit being performed every frame, although this will still
be necessary under certain conditions, e.g. an empty swap.
---
include/GL/internal/dri_interface.h | 3 +++
src/egl/drivers/dri2/platform_tizen.c | 29 +++++++++++++++++++++------
2 files changed, 26 insertions(+), 6 deletions(-)
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index 06eab0da5aa..cf1cb574c41 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -2049,12 +2049,15 @@ enum __DRIimageBufferMask {
* OpenGL ES API and little change to the SurfaceFlinger API.
*/
__DRI_IMAGE_BUFFER_SHARED = (1 << 2),
+#define DRI_IMAGE_HAS_BUFFER_PREV
+ __DRI_IMAGE_BUFFER_PREV = (1 << 31),
};
struct __DRIimageList {
uint32_t image_mask;
__DRIimage *back;
__DRIimage *front;
+ __DRIimage *prev;
};
#define __DRI_IMAGE_LOADER "DRI_IMAGE_LOADER"
diff --git a/src/egl/drivers/dri2/platform_tizen.c b/src/egl/drivers/dri2/platform_tizen.c
index 49462152beb..2bc9b3e7c64 100644
--- a/src/egl/drivers/dri2/platform_tizen.c
+++ b/src/egl/drivers/dri2/platform_tizen.c
@@ -147,7 +147,8 @@ create_image_from_native(struct dri2_egl_surface *dri2_surf,
}
static int
-get_back_bo(struct dri2_egl_surface *dri2_surf, bool allow_update)
+get_back_bo(struct dri2_egl_surface *dri2_surf, bool allow_update,
+ bool allow_preserve)
{
struct dri2_egl_display *dri2_dpy =
dri2_egl_display(dri2_surf->base.Resource.Display);
@@ -277,7 +278,7 @@ get_back_bo(struct dri2_egl_surface *dri2_surf, bool allow_update)
dri2_surf->back->locked = true;
if (dri2_surf->base.SwapBehavior == EGL_BUFFER_PRESERVED &&
- dri2_surf->current) {
+ allow_preserve && dri2_surf->current) {
_EGLContext *ctx = _eglGetCurrentContext();
struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx);
@@ -609,7 +610,7 @@ dri2_tizen_swap_buffers_with_damage(_EGLDisplay *dpy, _EGLSurface *draw,
* Make sure we have a back buffer in case we're swapping without ever
* rendering.
*/
- if (get_back_bo(dri2_surf, false) < 0) {
+ if (get_back_bo(dri2_surf, false, true) < 0) {
_eglError(EGL_BAD_ALLOC, "DRI2: failed to get back buffer");
return EGL_FALSE;
}
@@ -673,7 +674,7 @@ dri2_tizen_query_buffer_age(_EGLDisplay *dpy, _EGLSurface *surface)
{
struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surface);
- if (get_back_bo(dri2_surf, false) < 0) {
+ if (get_back_bo(dri2_surf, false, true) < 0) {
_eglError(EGL_BAD_ALLOC, "DRI2: failed to get back buffer");
return -1;
}
@@ -748,14 +749,22 @@ dri2_tizen_get_buffers(__DRIdrawable *driDrawable,
buffers->image_mask = 0;
buffers->front = NULL;
buffers->back = NULL;
+ buffers->prev = NULL;
if (buffer_mask & __DRI_IMAGE_BUFFER_FRONT)
if (get_front_bo(dri2_surf) < 0)
return 0;
- if (buffer_mask & __DRI_IMAGE_BUFFER_BACK)
- if (get_back_bo(dri2_surf, true) < 0)
+ if (buffer_mask & __DRI_IMAGE_BUFFER_BACK) {
+ /*
+ * The DRI driver has requested the previous buffer so it will take care
+ * of preserving the previous content.
+ */
+ bool allow_preserve = !(buffer_mask & __DRI_IMAGE_BUFFER_PREV);
+
+ if (get_back_bo(dri2_surf, true, allow_preserve) < 0)
return 0;
+ }
if (buffer_mask & __DRI_IMAGE_BUFFER_FRONT) {
buffers->front = dri2_surf->front;
@@ -767,6 +776,14 @@ dri2_tizen_get_buffers(__DRIdrawable *driDrawable,
buffers->image_mask |= __DRI_IMAGE_BUFFER_BACK;
}
+ if (buffer_mask & __DRI_IMAGE_BUFFER_PREV) {
+ if (dri2_surf->base.SwapBehavior == EGL_BUFFER_PRESERVED &&
+ dri2_surf->current) {
+ buffers->prev = dri2_surf->current->dri_image;
+ buffers->image_mask |= __DRI_IMAGE_BUFFER_PREV;
+ }
+ }
+
return 1;
}
--
2.17.1
@@ -0,0 +1,29 @@
From c431639246d96adce4a8807fa62b3b53cca3adf2 Mon Sep 17 00:00:00 2001
From: Eric Engestrom <eric.engestrom@imgtec.com>
Date: Mon, 25 Sep 2017 15:58:49 +0100
Subject: [PATCH 29/50] egl: eglBindAPI workaround for dEQP bug
dEQP relies on eglBindAPI to only return true if the API can
successfully be used to create contexts, which the spec does not
require.
Until dEQP is fixed, just disable GL on non-X11 platforms.
---
src/egl/main/eglcurrent.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/egl/main/eglcurrent.h b/src/egl/main/eglcurrent.h
index d9a4a90174e..32570970947 100644
--- a/src/egl/main/eglcurrent.h
+++ b/src/egl/main/eglcurrent.h
@@ -71,7 +71,7 @@ struct _egl_thread_info
static inline EGLBoolean
_eglIsApiValid(EGLenum api)
{
-#ifdef ANDROID
+#ifndef HAVE_X11_PLATFORM
/* OpenGL is not a valid/supported API on Android */
return api == EGL_OPENGL_ES_API;
#else
--
2.17.1
@@ -0,0 +1,56 @@
From 651ae0156f4cec4dbf70eef95e1eceebe8941a20 Mon Sep 17 00:00:00 2001
From: Brendan King <Brendan.King@imgtec.com>
Date: Tue, 30 Jan 2018 10:25:11 +0000
Subject: [PATCH 30/50] GL_EXT_multi_draw_indirect entry points
---
src/mapi/glapi/gen/es_EXT.xml | 19 +++++++++++++++++++
src/mapi/glapi/gen/static_data.py | 2 ++
2 files changed, 21 insertions(+)
diff --git a/src/mapi/glapi/gen/es_EXT.xml b/src/mapi/glapi/gen/es_EXT.xml
index 359cc9ca8cf..de2862a71a5 100644
--- a/src/mapi/glapi/gen/es_EXT.xml
+++ b/src/mapi/glapi/gen/es_EXT.xml
@@ -1140,6 +1140,25 @@
</category>
+<category name="GL_EXT_multi_draw_indirect" number="205">
+
+ <function name="MultiDrawArraysIndirectEXT" es2="3.1" exec="dynamic">
+ <param name="mode" type="GLenum"/>
+ <param name="indirect" type="const GLvoid *"/>
+ <param name="drawcount" type="GLsizei"/>
+ <param name="stride" type="GLsizei"/>
+ </function>
+
+ <function name="MultiDrawElementsIndirectEXT" es2="3.1" exec="dynamic">
+ <param name="mode" type="GLenum"/>
+ <param name="type" type="GLenum"/>
+ <param name="indirect" type="const GLvoid *"/>
+ <param name="drawcount" type="GLsizei"/>
+ <param name="stride" type="GLsizei"/>
+ </function>
+
+</category>
+
<category name="GL_EXT_copy_image" number="208">
<function name="CopyImageSubDataEXT" alias="CopyImageSubData" es2="3.0">
diff --git a/src/mapi/glapi/gen/static_data.py b/src/mapi/glapi/gen/static_data.py
index d13dc915d6f..32fb3b8f4f7 100644
--- a/src/mapi/glapi/gen/static_data.py
+++ b/src/mapi/glapi/gen/static_data.py
@@ -1692,6 +1692,8 @@ offsets = {
"FramebufferTextureLayerDownsampleIMG" : 1656,
"FramebufferTextureMultiviewOVR" : 1657,
"FramebufferTextureMultisampleMultiviewOVR" : 1658,
+ "MultiDrawArraysIndirectEXT" : 1659,
+ "MultiDrawElementsIndirectEXT" : 1660,
}
functions = [
--
2.17.1
@@ -0,0 +1,494 @@
From d4632fc9ce17416cd1f3019af554a320e142dc3b Mon Sep 17 00:00:00 2001
From: Frank Binns <frank.binns@imgtec.com>
Date: Fri, 22 Dec 2017 17:17:50 +0000
Subject: [PATCH 31/50] dri: add support for YUV DRI config
This is prerequisite for adding support for EGL_EXT_yuv_surface.
This also adds support for NV12 and NV21 EGL configs.
---
include/GL/internal/dri_interface.h | 42 ++++++++-
src/gallium/frontends/dri/dri_screen.c | 8 +-
src/gallium/include/pipe/p_format.h | 3 +
src/mesa/drivers/dri/common/utils.c | 87 +++++++++++++++++--
src/mesa/drivers/dri/common/utils.h | 3 +-
src/mesa/drivers/dri/i915/intel_screen.c | 8 +-
src/mesa/drivers/dri/i965/intel_screen.c | 12 ++-
src/mesa/drivers/dri/nouveau/nouveau_screen.c | 4 +-
src/mesa/drivers/dri/radeon/radeon_screen.c | 4 +-
src/mesa/main/format_info.py | 2 +-
src/mesa/main/formats.c | 9 ++
src/mesa/main/formats.csv | 2 +
src/mesa/main/formats.h | 7 ++
src/mesa/main/mtypes.h | 9 ++
14 files changed, 181 insertions(+), 19 deletions(-)
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index cf1cb574c41..cff3d9019dd 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -826,7 +826,13 @@ struct __DRIuseInvalidateExtensionRec {
#define __DRI_ATTRIB_GREEN_SHIFT 51
#define __DRI_ATTRIB_BLUE_SHIFT 52
#define __DRI_ATTRIB_ALPHA_SHIFT 53
-#define __DRI_ATTRIB_MAX 54
+#define __DRI_ATTRIB_YUV_ORDER 54
+#define __DRI_ATTRIB_YUV_NUMBER_OF_PLANES 55
+#define __DRI_ATTRIB_YUV_SUBSAMPLE 56
+#define __DRI_ATTRIB_YUV_DEPTH_RANGE 57
+#define __DRI_ATTRIB_YUV_CSC_STANDARD 58
+#define __DRI_ATTRIB_YUV_PLANE_BPP 59
+#define __DRI_ATTRIB_MAX 60
/* __DRI_ATTRIB_RENDER_TYPE */
#define __DRI_ATTRIB_RGBA_BIT 0x01
@@ -834,6 +840,7 @@ struct __DRIuseInvalidateExtensionRec {
#define __DRI_ATTRIB_LUMINANCE_BIT 0x04
#define __DRI_ATTRIB_FLOAT_BIT 0x08
#define __DRI_ATTRIB_UNSIGNED_FLOAT_BIT 0x10
+#define __DRI_ATTRIB_YUV_BIT 0x20
/* __DRI_ATTRIB_CONFIG_CAVEAT */
#define __DRI_ATTRIB_SLOW_BIT 0x01
@@ -860,6 +867,39 @@ struct __DRIuseInvalidateExtensionRec {
#define __DRI_ATTRIB_SWAP_COPY 0x8062
#define __DRI_ATTRIB_SWAP_UNDEFINED 0x8063
+/* __DRI_ATTRIB_YUV_ORDER */
+#define __DRI_ATTRIB_YUV_ORDER_NONE 0x0
+#define __DRI_ATTRIB_YUV_ORDER_YUV_BIT 0x1
+#define __DRI_ATTRIB_YUV_ORDER_YVU_BIT 0x2
+#define __DRI_ATTRIB_YUV_ORDER_YUYV_BIT 0x4
+#define __DRI_ATTRIB_YUV_ORDER_UYVY_BIT 0x8
+#define __DRI_ATTRIB_YUV_ORDER_YVYU_BIT 0x10
+#define __DRI_ATTRIB_YUV_ORDER_VYUY_BIT 0x20
+#define __DRI_ATTRIB_YUV_ORDER_AYUV_BIT 0x40
+
+/* __DRI_ATTRIB_YUV_SUBSAMPLE */
+#define __DRI_ATTRIB_YUV_SUBSAMPLE_NONE 0x0
+#define __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_0_BIT 0x1
+#define __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_2_BIT 0x2
+#define __DRI_ATTRIB_YUV_SUBSAMPLE_4_4_4_BIT 0x4
+
+/* __DRI_ATTRIB_YUV_DEPTH_RANGE */
+#define __DRI_ATTRIB_YUV_DEPTH_RANGE_NONE 0x0
+#define __DRI_ATTRIB_YUV_DEPTH_RANGE_LIMITED_BIT 0x1
+#define __DRI_ATTRIB_YUV_DEPTH_RANGE_FULL_BIT 0x2
+
+/* __DRI_ATTRIB_YUV_CSC_STANDARD */
+#define __DRI_ATTRIB_YUV_CSC_STANDARD_NONE 0x0
+#define __DRI_ATTRIB_YUV_CSC_STANDARD_601_BIT 0x1
+#define __DRI_ATTRIB_YUV_CSC_STANDARD_709_BIT 0x2
+#define __DRI_ATTRIB_YUV_CSC_STANDARD_2020_BIT 0x4
+
+/* __DRI_ATTRIB_YUV_PLANE_BPP */
+#define __DRI_ATTRIB_YUV_PLANE_BPP_NONE 0x0
+#define __DRI_ATTRIB_YUV_PLANE_BPP_0_BIT 0x1
+#define __DRI_ATTRIB_YUV_PLANE_BPP_8_BIT 0x2
+#define __DRI_ATTRIB_YUV_PLANE_BPP_10_BIT 0x4
+
/**
* This extension defines the core DRI functionality.
*
diff --git a/src/gallium/frontends/dri/dri_screen.c b/src/gallium/frontends/dri/dri_screen.c
index 20ee86f52b7..09f13dd9b77 100644
--- a/src/gallium/frontends/dri/dri_screen.c
+++ b/src/gallium/frontends/dri/dri_screen.c
@@ -306,7 +306,9 @@ dri_fill_in_modes(struct dri_screen *screen)
depth_buffer_factor, back_buffer_modes,
ARRAY_SIZE(back_buffer_modes),
msaa_modes, 1,
- GL_TRUE, !mixed_color_depth, GL_FALSE);
+ GL_TRUE, !mixed_color_depth, GL_FALSE,
+ __DRI_ATTRIB_YUV_DEPTH_RANGE_NONE,
+ __DRI_ATTRIB_YUV_CSC_STANDARD_NONE);
configs = driConcatConfigs(configs, new_configs);
/* Multi-sample configs without an accumulation buffer. */
@@ -316,7 +318,9 @@ dri_fill_in_modes(struct dri_screen *screen)
depth_buffer_factor, back_buffer_modes,
ARRAY_SIZE(back_buffer_modes),
msaa_modes+1, num_msaa_modes-1,
- GL_FALSE, !mixed_color_depth, GL_FALSE);
+ GL_FALSE, !mixed_color_depth, GL_FALSE,
+ __DRI_ATTRIB_YUV_DEPTH_RANGE_NONE,
+ __DRI_ATTRIB_YUV_CSC_STANDARD_NONE);
configs = driConcatConfigs(configs, new_configs);
}
}
diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h
index 7c62b722e5d..a3a417ea0d8 100644
--- a/src/gallium/include/pipe/p_format.h
+++ b/src/gallium/include/pipe/p_format.h
@@ -493,6 +493,9 @@ enum pipe_format {
PIPE_FORMAT_R8_G8B8_420_UNORM,
+ PIPE_FORMAT_YUV420_2PLANE,
+ PIPE_FORMAT_YVU420_2PLANE,
+
PIPE_FORMAT_COUNT
};
diff --git a/src/mesa/drivers/dri/common/utils.c b/src/mesa/drivers/dri/common/utils.c
index 0fdca2d9d84..85ffe2de64d 100644
--- a/src/mesa/drivers/dri/common/utils.c
+++ b/src/mesa/drivers/dri/common/utils.c
@@ -166,6 +166,21 @@ driGetRendererString( char * buffer, const char * hardware_name,
* which translates to
* EGL_MUTABLE_RENDER_BUFFER_BIT_KHR.
*
+ * \param yuv_depth_range YUV pixel depth range. For non-YUV pixel formats this
+ * should be \c __DRI_ATTRIB_YUV_DEPTH_RANGE_NONE.
+ * Otherwise valid values are
+ * \c __DRI_ATTRIB_YUV_DEPTH_RANGE_LIMITED_BIT and
+ * \c __DRI_ATTRIB_YUV_DEPTH_RANGE_FULL_BIT. See the
+ * EGL_EXT_yuv_surface extension spec for more details.
+ * \param yuv_csc_standard YUV color conversion standard. For non-YUV pixel
+ * formats this should be
+ * \c __DRI_ATTRIB_YUV_CSC_STANDARD_NONE. Otherwise
+ * valid values are
+ * \c __DRI_ATTRIB_YUV_CSC_STANDARD_601_BIT,
+ * \c __DRI_ATTRIB_YUV_CSC_STANDARD_709_BIT and
+ * \c __DRI_ATTRIB_YUV_CSC_STANDARD_2020_BIT. See the
+ * EGL_EXT_yuv_surface extension spec for more details.
+ *
* \returns
* Pointer to any array of pointers to the \c __DRIconfig structures created
* for the specified formats. If there is an error, \c NULL is returned.
@@ -179,7 +194,8 @@ driCreateConfigs(mesa_format format,
const GLenum * db_modes, unsigned num_db_modes,
const uint8_t * msaa_samples, unsigned num_msaa_modes,
GLboolean enable_accum, GLboolean color_depth_match,
- GLboolean mutable_render_buffer)
+ GLboolean mutable_render_buffer,
+ GLint yuv_depth_range, GLint yuv_csc_standard)
{
static const struct {
uint32_t masks[4];
@@ -218,6 +234,9 @@ driCreateConfigs(mesa_format format,
/* MESA_FORMAT_RGBA_FLOAT16 */
{{ 0, 0, 0, 0},
{ 0, 16, 32, 48 }},
+ /* Mesa YUV formats */
+ {{ 0, 0, 0, 0 },
+ { -1, -1, -1, -1}},
};
const uint32_t * masks;
@@ -231,6 +250,11 @@ driCreateConfigs(mesa_format format,
int green_bits;
int blue_bits;
int alpha_bits;
+ int yuv_order = __DRI_ATTRIB_YUV_ORDER_NONE;
+ int yuv_num_planes = 0;
+ int yuv_subsample = __DRI_ATTRIB_YUV_SUBSAMPLE_NONE;
+ int yuv_plane_bpp = __DRI_ATTRIB_YUV_PLANE_BPP_NONE;
+ bool is_yuv = false;
bool is_srgb;
bool is_float;
@@ -282,6 +306,33 @@ driCreateConfigs(mesa_format format,
masks = format_table[8].masks;
shifts = format_table[8].shifts;
break;
+ case MESA_FORMAT_YCBCR:
+ masks = format_table[11].masks;
+ shifts = format_table[11].shifts;
+ is_yuv = true; /* FIXME: This should come from formats_info.py */
+ yuv_order = __DRI_ATTRIB_YUV_ORDER_YUYV_BIT;
+ yuv_num_planes = 1;
+ yuv_subsample = __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_2_BIT;
+ yuv_plane_bpp = __DRI_ATTRIB_YUV_PLANE_BPP_8_BIT;
+ break;
+ case MESA_FORMAT_YUV420_2PLANE:
+ masks = format_table[11].masks;
+ shifts = format_table[11].shifts;
+ is_yuv = true; /* FIXME: This should come from formats_info.py */
+ yuv_order = __DRI_ATTRIB_YUV_ORDER_YUV_BIT;
+ yuv_num_planes = 2;
+ yuv_subsample = __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_0_BIT;
+ yuv_plane_bpp = __DRI_ATTRIB_YUV_PLANE_BPP_8_BIT;
+ break;
+ case MESA_FORMAT_YVU420_2PLANE:
+ masks = format_table[11].masks;
+ shifts = format_table[11].shifts;
+ is_yuv = true; /* FIXME: This should come from formats_info.py */
+ yuv_order = __DRI_ATTRIB_YUV_ORDER_YVU_BIT;
+ yuv_num_planes = 2;
+ yuv_subsample = __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_0_BIT;
+ yuv_plane_bpp = __DRI_ATTRIB_YUV_PLANE_BPP_8_BIT;
+ break;
default:
fprintf(stderr, "[%s:%u] Unknown framebuffer type %s (%d).\n",
__func__, __LINE__,
@@ -337,8 +388,12 @@ driCreateConfigs(mesa_format format,
modes->greenShift = shifts[1];
modes->blueShift = shifts[2];
modes->alphaShift = shifts[3];
- modes->rgbBits = modes->redBits + modes->greenBits
- + modes->blueBits + modes->alphaBits;
+
+ if (is_yuv)
+ modes->rgbBits = 8;
+ else
+ modes->rgbBits = modes->redBits + modes->greenBits
+ + modes->blueBits + modes->alphaBits;
modes->accumRedBits = 16 * j;
modes->accumGreenBits = 16 * j;
@@ -355,6 +410,7 @@ driCreateConfigs(mesa_format format,
modes->transparentBlue = GLX_DONT_CARE;
modes->transparentAlpha = GLX_DONT_CARE;
modes->transparentIndex = GLX_DONT_CARE;
+ modes->rgbMode = !is_yuv;
if (db_modes[i] == __DRI_ATTRIB_SWAP_NONE) {
modes->doubleBufferMode = GL_FALSE;
@@ -379,6 +435,13 @@ driCreateConfigs(mesa_format format,
modes->yInverted = GL_TRUE;
modes->sRGBCapable = is_srgb;
modes->mutableRenderBuffer = mutable_render_buffer;
+
+ modes->YUVOrder = yuv_order;
+ modes->YUVNumberOfPlanes = yuv_num_planes;
+ modes->YUVSubsample = yuv_subsample;
+ modes->YUVDepthRange = yuv_depth_range;
+ modes->YUVCSCStandard = yuv_csc_standard;
+ modes->YUVPlaneBPP = yuv_plane_bpp;
}
}
}
@@ -468,6 +531,12 @@ static const struct { unsigned int attrib, offset; } attribMap[] = {
__ATTRIB(__DRI_ATTRIB_YINVERTED, yInverted),
__ATTRIB(__DRI_ATTRIB_FRAMEBUFFER_SRGB_CAPABLE, sRGBCapable),
__ATTRIB(__DRI_ATTRIB_MUTABLE_RENDER_BUFFER, mutableRenderBuffer),
+ __ATTRIB(__DRI_ATTRIB_YUV_ORDER, YUVOrder),
+ __ATTRIB(__DRI_ATTRIB_YUV_NUMBER_OF_PLANES, YUVNumberOfPlanes),
+ __ATTRIB(__DRI_ATTRIB_YUV_SUBSAMPLE, YUVSubsample),
+ __ATTRIB(__DRI_ATTRIB_YUV_DEPTH_RANGE, YUVDepthRange),
+ __ATTRIB(__DRI_ATTRIB_YUV_CSC_STANDARD, YUVCSCStandard),
+ __ATTRIB(__DRI_ATTRIB_YUV_PLANE_BPP, YUVPlaneBPP),
/* The struct field doesn't matter here, these are handled by the
* switch in driGetConfigAttribIndex. We need them in the array
@@ -487,10 +556,14 @@ driGetConfigAttribIndex(const __DRIconfig *config,
{
switch (attribMap[index].attrib) {
case __DRI_ATTRIB_RENDER_TYPE:
- /* no support for color index mode */
- *value = __DRI_ATTRIB_RGBA_BIT;
- if (config->modes.floatMode)
- *value |= __DRI_ATTRIB_FLOAT_BIT;
+ /* no support for color index mode */
+ if (config->modes.rgbMode)
+ *value = __DRI_ATTRIB_RGBA_BIT;
+ else
+ *value = __DRI_ATTRIB_YUV_BIT;
+
+ if (config->modes.floatMode)
+ *value |= __DRI_ATTRIB_FLOAT_BIT;
break;
case __DRI_ATTRIB_CONFIG_CAVEAT:
if (config->modes.visualRating == GLX_NON_CONFORMANT_CONFIG)
diff --git a/src/mesa/drivers/dri/common/utils.h b/src/mesa/drivers/dri/common/utils.h
index 7c9719f9f42..8159300c01d 100644
--- a/src/mesa/drivers/dri/common/utils.h
+++ b/src/mesa/drivers/dri/common/utils.h
@@ -46,7 +46,8 @@ driCreateConfigs(mesa_format format,
const GLenum * db_modes, unsigned num_db_modes,
const uint8_t * msaa_samples, unsigned num_msaa_modes,
GLboolean enable_accum, GLboolean color_depth_match,
- GLboolean mutable_render_buffer);
+ GLboolean mutable_render_buffer,
+ GLint yuv_depth_range, GLint yuv_csc_standards);
__DRIconfig **driConcatConfigs(__DRIconfig **a,
__DRIconfig **b);
diff --git a/src/mesa/drivers/dri/i915/intel_screen.c b/src/mesa/drivers/dri/i915/intel_screen.c
index 60b35d37a6e..62973d83bd5 100644
--- a/src/mesa/drivers/dri/i915/intel_screen.c
+++ b/src/mesa/drivers/dri/i915/intel_screen.c
@@ -1067,7 +1067,9 @@ intel_screen_make_configs(__DRIscreen *dri_screen)
num_depth_stencil_bits,
back_buffer_modes, 2,
singlesample_samples, 1,
- false, false, false);
+ false, false, false,
+ __DRI_ATTRIB_YUV_DEPTH_RANGE_NONE,
+ __DRI_ATTRIB_YUV_CSC_STANDARD_NONE);
configs = driConcatConfigs(configs, new_configs);
}
@@ -1089,7 +1091,9 @@ intel_screen_make_configs(__DRIscreen *dri_screen)
depth_bits, stencil_bits, 1,
back_buffer_modes, 1,
singlesample_samples, 1,
- true, false, false);
+ true, false, false,
+ __DRI_ATTRIB_YUV_DEPTH_RANGE_NONE,
+ __DRI_ATTRIB_YUV_CSC_STANDARD_NONE);
configs = driConcatConfigs(configs, new_configs);
}
diff --git a/src/mesa/drivers/dri/i965/intel_screen.c b/src/mesa/drivers/dri/i965/intel_screen.c
index 1e34cbbca1a..8fed9c6931a 100644
--- a/src/mesa/drivers/dri/i965/intel_screen.c
+++ b/src/mesa/drivers/dri/i965/intel_screen.c
@@ -2336,7 +2336,9 @@ intel_screen_make_configs(__DRIscreen *dri_screen)
back_buffer_modes, 2,
singlesample_samples, 1,
false, false,
- /*mutable_render_buffer*/ true);
+ /*mutable_render_buffer*/ true,
+ __DRI_ATTRIB_YUV_DEPTH_RANGE_NONE,
+ __DRI_ATTRIB_YUV_CSC_STANDARD_NONE);
configs = driConcatConfigs(configs, new_configs);
}
@@ -2369,7 +2371,9 @@ intel_screen_make_configs(__DRIscreen *dri_screen)
depth_bits, stencil_bits, 1,
back_buffer_modes, 1,
singlesample_samples, 1,
- true, false, false);
+ true, false, false,
+ __DRI_ATTRIB_YUV_DEPTH_RANGE_NONE,
+ __DRI_ATTRIB_YUV_CSC_STANDARD_NONE);
configs = driConcatConfigs(configs, new_configs);
}
@@ -2434,7 +2438,9 @@ intel_screen_make_configs(__DRIscreen *dri_screen)
back_buffer_modes, 1,
multisample_samples,
num_msaa_modes,
- false, false, false);
+ false, false, false,
+ __DRI_ATTRIB_YUV_DEPTH_RANGE_NONE,
+ __DRI_ATTRIB_YUV_CSC_STANDARD_NONE);
configs = driConcatConfigs(configs, new_configs);
}
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_screen.c b/src/mesa/drivers/dri/nouveau/nouveau_screen.c
index ba85aacf741..9d4c1d9bd94 100644
--- a/src/mesa/drivers/dri/nouveau/nouveau_screen.c
+++ b/src/mesa/drivers/dri/nouveau/nouveau_screen.c
@@ -79,7 +79,9 @@ nouveau_get_configs(uint32_t chipset)
ARRAY_SIZE(back_buffer_modes),
msaa_samples,
ARRAY_SIZE(msaa_samples),
- GL_TRUE, chipset < 0x10, GL_FALSE);
+ GL_TRUE, chipset < 0x10, GL_FALSE,
+ __DRI_ATTRIB_YUV_DEPTH_RANGE_NONE,
+ __DRI_ATTRIB_YUV_CSC_STANDARD_NONE);
assert(config);
configs = driConcatConfigs(configs, config);
diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c
index f61fe399c09..84aef8dd041 100644
--- a/src/mesa/drivers/dri/radeon/radeon_screen.c
+++ b/src/mesa/drivers/dri/radeon/radeon_screen.c
@@ -839,7 +839,9 @@ __DRIconfig **radeonInitScreen2(__DRIscreen *psp)
ARRAY_SIZE(back_buffer_modes),
msaa_samples_array,
ARRAY_SIZE(msaa_samples_array),
- GL_TRUE, GL_FALSE, GL_FALSE);
+ GL_TRUE, GL_FALSE, GL_FALSE,
+ __DRI_ATTRIB_YUV_DEPTH_RANGE_NONE,
+ __DRI_ATTRIB_YUV_CSC_STANDARD_NONE);
configs = driConcatConfigs(configs, new_configs);
}
diff --git a/src/mesa/main/format_info.py b/src/mesa/main/format_info.py
index 42c236c7a6a..e07d2d98b89 100644
--- a/src/mesa/main/format_info.py
+++ b/src/mesa/main/format_info.py
@@ -29,7 +29,7 @@ import sys
def get_gl_base_format(fmat):
if fmat.name == 'MESA_FORMAT_NONE':
return 'GL_NONE'
- elif fmat.name in ['MESA_FORMAT_YCBCR', 'MESA_FORMAT_YCBCR_REV']:
+ elif fmat.name in ['MESA_FORMAT_YCBCR', 'MESA_FORMAT_YCBCR_REV', 'MESA_FORMAT_YUV420_2PLANE', 'MESA_FORMAT_YVU420_2PLANE']:
return 'GL_YCBCR_MESA'
elif fmat.has_channel('r'):
if fmat.has_channel('g'):
diff --git a/src/mesa/main/formats.c b/src/mesa/main/formats.c
index ac00a21306b..de7b9feb14b 100644
--- a/src/mesa/main/formats.c
+++ b/src/mesa/main/formats.c
@@ -1450,6 +1450,15 @@ _mesa_format_matches_format_and_type(mesa_format mformat,
if (error)
*error = GL_NO_ERROR;
+ switch (mformat) {
+ case MESA_FORMAT_YUV420_2PLANE:
+ case MESA_FORMAT_YVU420_2PLANE:
+ return false;
+
+ default:
+ break;
+ }
+
if (_mesa_is_format_compressed(mformat)) {
if (error)
*error = GL_INVALID_ENUM;
diff --git a/src/mesa/main/formats.csv b/src/mesa/main/formats.csv
index e2b54e935bb..166c3d4830d 100644
--- a/src/mesa/main/formats.csv
+++ b/src/mesa/main/formats.csv
@@ -92,6 +92,8 @@ MESA_FORMAT_A2R10G10B10_UNORM , packed, 1, 1, 1, un2 , un10, un10, u
MESA_FORMAT_YCBCR , other , 1, 1, 1, x16 , , , , xyzw, yuv
MESA_FORMAT_YCBCR_REV , other , 1, 1, 1, x16 , , , , xyzw, yuv
+MESA_FORMAT_YUV420_2PLANE , other , 1, 1, 1, x8 , , , , y___, yuv
+MESA_FORMAT_YVU420_2PLANE , other , 1, 1, 1, x8 , , , , y___, yuv
# Array normalized formats
MESA_FORMAT_A_UNORM8 , array , 1, 1, 1, un8 , , , , 000x, rgb
diff --git a/src/mesa/main/formats.h b/src/mesa/main/formats.h
index 29c1308c383..4fcb5f73225 100644
--- a/src/mesa/main/formats.h
+++ b/src/mesa/main/formats.h
@@ -615,6 +615,13 @@ typedef enum pipe_format mesa_format;
#define MESA_FORMAT_ATC_RGB PIPE_FORMAT_ATC_RGB
#define MESA_FORMAT_ATC_RGBA_EXPLICIT PIPE_FORMAT_ATC_RGBA_EXPLICIT
#define MESA_FORMAT_ATC_RGBA_INTERPOLATED PIPE_FORMAT_ATC_RGBA_INTERPOLATED
+
+#define HAVE_MESA_FORMAT_YUV420_2PLANE
+#define MESA_FORMAT_YUV420_2PLANE PIPE_FORMAT_YUV420_2PLANE
+
+#define HAVE_MESA_FORMAT_YVU420_2PLANE
+#define MESA_FORMAT_YVU420_2PLANE PIPE_FORMAT_YVU420_2PLANE
+
#define MESA_FORMAT_COUNT PIPE_FORMAT_COUNT
/* Packed to array format adapters */
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 70e7b218197..96e55fc987d 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -162,6 +162,7 @@ _mesa_varying_slot_in_fs(gl_varying_slot slot)
*/
struct gl_config
{
+ GLboolean rgbMode;
GLboolean floatMode;
GLuint doubleBufferMode;
GLuint stereoMode;
@@ -214,6 +215,14 @@ struct gl_config
/* EGL_KHR_mutable_render_buffer */
GLuint mutableRenderBuffer; /* bool */
+
+ /* EXT_yuv_surface */
+ GLint YUVOrder;
+ GLint YUVNumberOfPlanes;
+ GLint YUVSubsample;
+ GLint YUVDepthRange;
+ GLint YUVCSCStandard;
+ GLint YUVPlaneBPP;
};
--
2.17.1
@@ -0,0 +1,541 @@
From cc2b278f33c3c9f5f74aa5b36ead67f89cb7a20d Mon Sep 17 00:00:00 2001
From: Frank Binns <frank.binns@imgtec.com>
Date: Wed, 20 Dec 2017 17:41:38 +0000
Subject: [PATCH 32/50] egl: add support for EXT_yuv_surface
This implements EXT_yuv_surface but doesn't expose it for any platform.
---
include/GL/internal/dri_interface.h | 1 +
src/egl/drivers/dri2/egl_dri2.c | 83 +++++++++
src/egl/main/eglapi.c | 1 +
src/egl/main/eglconfig.c | 255 +++++++++++++++++++++++++++-
src/egl/main/eglconfig.h | 12 ++
src/egl/main/egldisplay.h | 1 +
6 files changed, 348 insertions(+), 5 deletions(-)
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index cff3d9019dd..89e29299840 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -1154,6 +1154,7 @@ enum dri_loader_cap {
*/
DRI_LOADER_CAP_RGBA_ORDERING,
DRI_LOADER_CAP_FP16,
+ DRI_LOADER_CAP_YUV_SURFACE_IMG = 0x7001,
};
struct __DRIdri2LoaderExtensionRec {
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index 69da031fa00..a0b52eab983 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -319,6 +319,7 @@ static const EGLint dri2_to_egl_attribute_map[__DRI_ATTRIB_MAX] = {
[__DRI_ATTRIB_MAX_SWAP_INTERVAL] = EGL_MAX_SWAP_INTERVAL,
[__DRI_ATTRIB_MIN_SWAP_INTERVAL] = EGL_MIN_SWAP_INTERVAL,
[__DRI_ATTRIB_YINVERTED] = EGL_Y_INVERTED_NOK,
+ [__DRI_ATTRIB_YUV_NUMBER_OF_PLANES] = EGL_YUV_NUMBER_OF_PLANES_EXT,
};
const __DRIconfig *
@@ -446,6 +447,8 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id,
value = EGL_RGB_BUFFER;
else if (value & __DRI_ATTRIB_LUMINANCE_BIT)
value = EGL_LUMINANCE_BUFFER;
+ else if (value & __DRI_ATTRIB_YUV_BIT)
+ value = EGL_YUV_BUFFER_EXT;
else
return NULL;
base.ColorBufferType = value;
@@ -556,6 +559,73 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id,
if (disp->Extensions.KHR_mutable_render_buffer)
surface_type |= EGL_MUTABLE_RENDER_BUFFER_BIT_KHR;
break;
+
+ case __DRI_ATTRIB_YUV_ORDER:
+ if (value & __DRI_ATTRIB_YUV_ORDER_YUV_BIT)
+ value = EGL_YUV_ORDER_YUV_EXT;
+ else if (value & __DRI_ATTRIB_YUV_ORDER_YVU_BIT)
+ value = EGL_YUV_ORDER_YVU_EXT;
+ else if (value & __DRI_ATTRIB_YUV_ORDER_YUYV_BIT)
+ value = EGL_YUV_ORDER_YUYV_EXT;
+ else if (value & __DRI_ATTRIB_YUV_ORDER_UYVY_BIT)
+ value = EGL_YUV_ORDER_UYVY_EXT;
+ else if (value & __DRI_ATTRIB_YUV_ORDER_YVYU_BIT)
+ value = EGL_YUV_ORDER_YVYU_EXT;
+ else if (value & __DRI_ATTRIB_YUV_ORDER_VYUY_BIT)
+ value = EGL_YUV_ORDER_VYUY_EXT;
+ else if (value & __DRI_ATTRIB_YUV_ORDER_AYUV_BIT)
+ value = EGL_YUV_ORDER_AYUV_EXT;
+ else
+ value = EGL_NONE;
+ _eglSetConfigKey(&base, EGL_YUV_ORDER_EXT, value);
+ break;
+
+ case __DRI_ATTRIB_YUV_SUBSAMPLE:
+ if (value & __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_0_BIT)
+ value = EGL_YUV_SUBSAMPLE_4_2_0_EXT;
+ else if (value & __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_2_BIT)
+ value = EGL_YUV_SUBSAMPLE_4_2_2_EXT;
+ else if (value & __DRI_ATTRIB_YUV_SUBSAMPLE_4_4_4_BIT)
+ value = EGL_YUV_SUBSAMPLE_4_4_4_EXT;
+ else
+ value = EGL_NONE;
+ _eglSetConfigKey(&base, EGL_YUV_SUBSAMPLE_EXT, value);
+ break;
+
+ case __DRI_ATTRIB_YUV_DEPTH_RANGE:
+ if (value & __DRI_ATTRIB_YUV_DEPTH_RANGE_LIMITED_BIT)
+ value = EGL_YUV_DEPTH_RANGE_LIMITED_EXT;
+ else if (value & __DRI_ATTRIB_YUV_DEPTH_RANGE_FULL_BIT)
+ value = EGL_YUV_DEPTH_RANGE_FULL_EXT;
+ else
+ value = EGL_NONE;
+ _eglSetConfigKey(&base, EGL_YUV_DEPTH_RANGE_EXT, value);
+ break;
+
+ case __DRI_ATTRIB_YUV_CSC_STANDARD:
+ if (value & __DRI_ATTRIB_YUV_CSC_STANDARD_601_BIT)
+ value = EGL_YUV_CSC_STANDARD_601_EXT;
+ else if (value & __DRI_ATTRIB_YUV_CSC_STANDARD_709_BIT)
+ value = EGL_YUV_CSC_STANDARD_709_EXT;
+ else if (value & __DRI_ATTRIB_YUV_CSC_STANDARD_2020_BIT)
+ value = EGL_YUV_CSC_STANDARD_2020_EXT;
+ else
+ value = EGL_NONE;
+ _eglSetConfigKey(&base, EGL_YUV_CSC_STANDARD_EXT, value);
+ break;
+
+ case __DRI_ATTRIB_YUV_PLANE_BPP:
+ if (value & __DRI_ATTRIB_YUV_PLANE_BPP_0_BIT)
+ value = EGL_YUV_PLANE_BPP_0_EXT;
+ else if (value & __DRI_ATTRIB_YUV_PLANE_BPP_8_BIT)
+ value = EGL_YUV_PLANE_BPP_8_EXT;
+ else if (value & __DRI_ATTRIB_YUV_PLANE_BPP_10_BIT)
+ value = EGL_YUV_PLANE_BPP_10_EXT;
+ else
+ value = EGL_NONE;
+ _eglSetConfigKey(&base, EGL_YUV_PLANE_BPP_EXT, value);
+ break;
+
default:
key = dri2_to_egl_attribute_map[attrib];
if (key != 0)
@@ -612,6 +682,17 @@ dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id,
base.RenderableType = disp->ClientAPIs;
base.Conformant = disp->ClientAPIs;
+ /*
+ * We assume that if dri_config is YUV then GL_EXT_YUV_target must be
+ * supported, which requires OpenGL ES 3.0.
+ */
+ if (base.ColorBufferType == EGL_YUV_BUFFER_EXT) {
+ base.RenderableType &= EGL_OPENGL_ES3_BIT;
+ base.Conformant &= EGL_OPENGL_ES3_BIT;
+ }
+ if (!base.RenderableType)
+ return NULL;
+
base.MinSwapInterval = dri2_dpy->min_swap_interval;
base.MaxSwapInterval = dri2_dpy->max_swap_interval;
@@ -1043,6 +1124,8 @@ dri2_setup_screen(_EGLDisplay *disp)
disp->Extensions.EXT_protected_surface =
dri2_renderer_query_integer(dri2_dpy,
__DRI2_RENDERER_HAS_PROTECTED_CONTENT);
+
+ disp->Extensions.EXT_yuv_surface = EGL_TRUE;
}
void
diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c
index c4dcc015941..8d9f4a76330 100644
--- a/src/egl/main/eglapi.c
+++ b/src/egl/main/eglapi.c
@@ -512,6 +512,7 @@ _eglCreateExtensionsString(_EGLDisplay *disp)
_EGL_CHECK_EXTENSION(EXT_surface_CTA861_3_metadata);
_EGL_CHECK_EXTENSION(EXT_surface_SMPTE2086_metadata);
_EGL_CHECK_EXTENSION(EXT_swap_buffers_with_damage);
+ _EGL_CHECK_EXTENSION(EXT_yuv_surface);
_EGL_CHECK_EXTENSION(IMG_context_priority);
diff --git a/src/egl/main/eglconfig.c b/src/egl/main/eglconfig.c
index 17d8f3555d4..5e56948ab72 100644
--- a/src/egl/main/eglconfig.c
+++ b/src/egl/main/eglconfig.c
@@ -258,6 +258,24 @@ static const struct {
{ EGL_COLOR_COMPONENT_TYPE_EXT, ATTRIB_TYPE_ENUM,
ATTRIB_CRITERION_EXACT,
EGL_COLOR_COMPONENT_TYPE_FIXED_EXT },
+ { EGL_YUV_ORDER_EXT, ATTRIB_TYPE_ENUM,
+ ATTRIB_CRITERION_EXACT,
+ EGL_DONT_CARE },
+ { EGL_YUV_NUMBER_OF_PLANES_EXT, ATTRIB_TYPE_INTEGER,
+ ATTRIB_CRITERION_ATLEAST,
+ 0 },
+ { EGL_YUV_SUBSAMPLE_EXT, ATTRIB_TYPE_ENUM,
+ ATTRIB_CRITERION_EXACT,
+ EGL_DONT_CARE },
+ { EGL_YUV_DEPTH_RANGE_EXT, ATTRIB_TYPE_ENUM,
+ ATTRIB_CRITERION_EXACT,
+ EGL_DONT_CARE },
+ { EGL_YUV_CSC_STANDARD_EXT, ATTRIB_TYPE_ENUM,
+ ATTRIB_CRITERION_EXACT,
+ EGL_DONT_CARE },
+ { EGL_YUV_PLANE_BPP_EXT, ATTRIB_TYPE_ENUM,
+ ATTRIB_CRITERION_EXACT,
+ EGL_DONT_CARE },
};
@@ -296,6 +314,28 @@ _eglValidateConfig(const _EGLConfig *conf, EGLBoolean for_matching)
if (val > 1 || val < 0)
valid = EGL_FALSE;
break;
+ case EGL_YUV_NUMBER_OF_PLANES_EXT:
+ /* From the EGL_EXT_yuv_surface spec (v9):
+ *
+ * The allowed values for EGL_YUV_NUMBER_OF_PLANES_EXT must
+ * be greater than zero and not more than three.
+ *
+ * However, it also says:
+ *
+ * Attribute Default Selection Sort Sort
+ * Criteria Order Priority
+ * ---------------------------- ------- --------- ----- --------
+ * EGL_YUV_NUMBER_OF_PLANES_EXT 0 At least None
+ *
+ * This means that we need to allow the value 0 when doing config
+ * matching (where it's essentially treated as EGL_DONT_CARE).
+ * Furthermore, this attribute isn't applicable to non-YUV EGL
+ * color buffer types. Allow 0 through here and then do further
+ * validation later on.
+ */
+ if (val < 0 || val > 3)
+ valid = EGL_FALSE;
+ break;
default:
if (val < 0)
valid = EGL_FALSE;
@@ -318,7 +358,43 @@ _eglValidateConfig(const _EGLConfig *conf, EGLBoolean for_matching)
valid = EGL_FALSE;
break;
case EGL_COLOR_BUFFER_TYPE:
- if (val != EGL_RGB_BUFFER && val != EGL_LUMINANCE_BUFFER)
+ if (val != EGL_RGB_BUFFER && val != EGL_LUMINANCE_BUFFER &&
+ val != EGL_YUV_BUFFER_EXT)
+ valid = EGL_FALSE;
+ break;
+ case EGL_YUV_ORDER_EXT:
+ if (val != EGL_NONE &&
+ val != EGL_YUV_ORDER_YUV_EXT && val != EGL_YUV_ORDER_YVU_EXT &&
+ val != EGL_YUV_ORDER_YUYV_EXT && val != EGL_YUV_ORDER_UYVY_EXT &&
+ val != EGL_YUV_ORDER_YVYU_EXT && val != EGL_YUV_ORDER_VYUY_EXT &&
+ val != EGL_YUV_ORDER_AYUV_EXT)
+ valid = EGL_FALSE;
+ break;
+ case EGL_YUV_SUBSAMPLE_EXT:
+ if (val != EGL_NONE &&
+ val != EGL_YUV_SUBSAMPLE_4_2_0_EXT &&
+ val != EGL_YUV_SUBSAMPLE_4_2_2_EXT &&
+ val != EGL_YUV_SUBSAMPLE_4_4_4_EXT)
+ valid = EGL_FALSE;
+ break;
+ case EGL_YUV_DEPTH_RANGE_EXT:
+ if (val != EGL_NONE &&
+ val != EGL_YUV_DEPTH_RANGE_LIMITED_EXT &&
+ val != EGL_YUV_DEPTH_RANGE_FULL_EXT)
+ valid = EGL_FALSE;
+ break;
+ case EGL_YUV_CSC_STANDARD_EXT:
+ if (val != EGL_NONE &&
+ val != EGL_YUV_CSC_STANDARD_601_EXT &&
+ val != EGL_YUV_CSC_STANDARD_709_EXT &&
+ val != EGL_YUV_CSC_STANDARD_2020_EXT)
+ valid = EGL_FALSE;
+ break;
+ case EGL_YUV_PLANE_BPP_EXT:
+ if (val != EGL_NONE &&
+ val != EGL_YUV_PLANE_BPP_0_EXT &&
+ val != EGL_YUV_PLANE_BPP_8_EXT &&
+ val != EGL_YUV_PLANE_BPP_10_EXT)
valid = EGL_FALSE;
break;
case EGL_COLOR_COMPONENT_TYPE_EXT:
@@ -404,6 +480,11 @@ _eglValidateConfig(const _EGLConfig *conf, EGLBoolean for_matching)
if (conf->LuminanceSize + conf->AlphaSize != conf->BufferSize)
valid = EGL_FALSE;
break;
+ case EGL_YUV_BUFFER_EXT:
+ if (conf->RedSize || conf->GreenSize || conf->BlueSize ||
+ conf->AlphaSize || conf->LuminanceSize)
+ valid = EGL_FALSE;
+ break;
}
if (!valid) {
_eglLog(_EGL_DEBUG, "conflicting color buffer type and channel sizes");
@@ -430,6 +511,88 @@ _eglValidateConfig(const _EGLConfig *conf, EGLBoolean for_matching)
return EGL_FALSE;
}
+ /* From the EGL_EXT_yuv_surface spec (v9):
+ *
+ * SUBSAMPLE_EXT NUMBER_OF_PLANES_EXT ORDER_EXT PLANE_BPP_EXT
+ * ------------------- -------------------- ----------------- ------------------
+ * SUBSAMPLE_4_2_0_EXT 2 or 3 ORDER_YUV_EXT or PLANE_BPP_8_EXT or
+ * ORDER_YVU_EXT PLANE_BPP_10_EXT
+ */
+ if (conf->YUVSubsampleEXT == EGL_YUV_SUBSAMPLE_4_2_0_EXT) {
+ if ((!for_matching || conf->YUVNumberOfPlanesEXT != 0) &&
+ conf->YUVNumberOfPlanesEXT != 2 &&
+ conf->YUVNumberOfPlanesEXT != 3)
+ valid = EGL_FALSE;
+ if (conf->YUVOrderEXT != EGL_DONT_CARE &&
+ conf->YUVOrderEXT != EGL_YUV_ORDER_YUV_EXT &&
+ conf->YUVOrderEXT != EGL_YUV_ORDER_YVU_EXT)
+ valid = EGL_FALSE;
+ if (conf->YUVPlaneBPPEXT != EGL_DONT_CARE &&
+ conf->YUVPlaneBPPEXT != EGL_YUV_PLANE_BPP_8_EXT &&
+ conf->YUVPlaneBPPEXT != EGL_YUV_PLANE_BPP_10_EXT)
+ valid = EGL_FALSE;
+ }
+ /* From the EGL_EXT_yuv_surface spec (v9):
+ *
+ * SUBSAMPLE_EXT NUMBER_OF_PLANES_EXT ORDER_EXT PLANE_BPP_EXT
+ * ------------------- -------------------- ----------------- ------------------
+ * SUBSAMPLE_4_2_2_EXT 1 ORDER_YUYV_EXT or PLANE_BPP_8_EXT or
+ * ORDER_YVYU_EXT or PLANE_BPP_10_EXT
+ * ORDER_UYVY_EXT or
+ * ORDER_VYUY_EXT
+ *
+ * SUBSAMPLE_4_2_2_EXT 2 or 3 ORDER_YUV_EXT or PLANE_BPP_8_EXT or
+ * ORDER_YVU_EXT PLANE_BPP_10_EXT
+ */
+ else if (conf->YUVSubsampleEXT == EGL_YUV_SUBSAMPLE_4_2_2_EXT) {
+ if ((!for_matching || conf->YUVNumberOfPlanesEXT != 0) &&
+ conf->YUVNumberOfPlanesEXT != 1 &&
+ conf->YUVNumberOfPlanesEXT != 2 &&
+ conf->YUVNumberOfPlanesEXT != 3)
+ valid = EGL_FALSE;
+ if (conf->YUVNumberOfPlanesEXT == 1) {
+ if (conf->YUVOrderEXT != EGL_DONT_CARE &&
+ conf->YUVOrderEXT != EGL_YUV_ORDER_YUYV_EXT &&
+ conf->YUVOrderEXT != EGL_YUV_ORDER_YVYU_EXT &&
+ conf->YUVOrderEXT != EGL_YUV_ORDER_UYVY_EXT &&
+ conf->YUVOrderEXT != EGL_YUV_ORDER_VYUY_EXT)
+ valid = EGL_FALSE;
+ } else if (conf->YUVNumberOfPlanesEXT == 2 ||
+ conf->YUVNumberOfPlanesEXT == 3) {
+ if (conf->YUVOrderEXT != EGL_DONT_CARE &&
+ conf->YUVOrderEXT != EGL_YUV_ORDER_YUV_EXT &&
+ conf->YUVOrderEXT != EGL_YUV_ORDER_YVU_EXT)
+ valid = EGL_FALSE;
+ }
+ if (conf->YUVPlaneBPPEXT != EGL_DONT_CARE &&
+ conf->YUVPlaneBPPEXT != EGL_YUV_PLANE_BPP_8_EXT &&
+ conf->YUVPlaneBPPEXT != EGL_YUV_PLANE_BPP_10_EXT)
+ valid = EGL_FALSE;
+ }
+ /* From the EGL_EXT_yuv_surface spec (v9):
+ *
+ * SUBSAMPLE_EXT NUMBER_OF_PLANES_EXT ORDER_EXT PLANE_BPP_EXT
+ * ------------------- -------------------- ----------------- ------------------
+ * SUBSAMPLE_4_4_4_EXT 1 ORDER_AYUV_EXT PLANE_BPP_8_EXT or
+ * PLANE_BPP_10_EXT
+ */
+ else if (conf->YUVSubsampleEXT == EGL_YUV_SUBSAMPLE_4_4_4_EXT) {
+ if ((!for_matching || conf->YUVNumberOfPlanesEXT != 0) &&
+ conf->YUVNumberOfPlanesEXT != 1)
+ valid = EGL_FALSE;
+ if (conf->YUVOrderEXT != EGL_DONT_CARE &&
+ conf->YUVOrderEXT != EGL_YUV_ORDER_AYUV_EXT)
+ valid = EGL_FALSE;
+ if (conf->YUVPlaneBPPEXT != EGL_DONT_CARE &&
+ conf->YUVPlaneBPPEXT != EGL_YUV_PLANE_BPP_8_EXT &&
+ conf->YUVPlaneBPPEXT != EGL_YUV_PLANE_BPP_10_EXT)
+ valid = EGL_FALSE;
+ }
+ if (!valid) {
+ _eglLog(_EGL_DEBUG, "invalid YUV subsample/num planes/order/bpp combination");
+ return EGL_FALSE;
+ }
+
return valid;
}
@@ -509,6 +672,28 @@ _eglIsConfigAttribValid(_EGLConfig *conf, EGLint attr)
return conf->Display->Extensions.ANDROID_framebuffer_target;
case EGL_RECORDABLE_ANDROID:
return conf->Display->Extensions.ANDROID_recordable;
+ case EGL_YUV_ORDER_EXT:
+ case EGL_YUV_NUMBER_OF_PLANES_EXT:
+ case EGL_YUV_SUBSAMPLE_EXT:
+ case EGL_YUV_DEPTH_RANGE_EXT:
+ case EGL_YUV_CSC_STANDARD_EXT:
+ case EGL_YUV_PLANE_BPP_EXT:
+ return conf->Display->Extensions.EXT_yuv_surface;
+ default:
+ break;
+ }
+
+ return EGL_TRUE;
+}
+
+static inline EGLBoolean
+_eglIsConfigAttribValueValid(_EGLConfig *conf, EGLint attr, EGLint val)
+{
+ switch (attr) {
+ case EGL_COLOR_BUFFER_TYPE:
+ if (!conf->Display->Extensions.EXT_yuv_surface && val == EGL_YUV_BUFFER_EXT)
+ return EGL_FALSE;
+ break;
default:
break;
}
@@ -543,6 +728,9 @@ _eglParseConfigAttribList(_EGLConfig *conf, _EGLDisplay *disp,
if (!_eglIsConfigAttribValid(conf, attr))
return EGL_FALSE;
+ if (!_eglIsConfigAttribValueValid(conf, attr, val))
+ return EGL_FALSE;
+
_eglSetConfigKey(conf, attr, val);
}
@@ -617,6 +805,7 @@ _eglCompareConfigs(const _EGLConfig *conf1, const _EGLConfig *conf2,
/* the enum values have the desired ordering */
STATIC_ASSERT(EGL_RGB_BUFFER < EGL_LUMINANCE_BUFFER);
+ STATIC_ASSERT(EGL_LUMINANCE_BUFFER < EGL_YUV_BUFFER_EXT);
val1 = conf1->ColorBufferType - conf2->ColorBufferType;
if (val1)
return val1;
@@ -636,16 +825,42 @@ _eglCompareConfigs(const _EGLConfig *conf1, const _EGLConfig *conf2,
val1 += conf1->BlueSize;
val2 += conf2->BlueSize;
}
+ if (criteria->AlphaSize > 0) {
+ val1 += conf1->AlphaSize;
+ val2 += conf2->AlphaSize;
+ }
}
- else {
+ else if (conf1->ColorBufferType == EGL_LUMINANCE_BUFFER) {
if (criteria->LuminanceSize > 0) {
val1 += conf1->LuminanceSize;
val2 += conf2->LuminanceSize;
}
+ if (criteria->AlphaSize > 0) {
+ val1 += conf1->AlphaSize;
+ val2 += conf2->AlphaSize;
+ }
}
- if (criteria->AlphaSize > 0) {
- val1 += conf1->AlphaSize;
- val2 += conf2->AlphaSize;
+ else {
+ /* From the EGL_EXT_yuv_surface spec (v9):
+ *
+ * Special: by larger total number of color bits
+ * ...
+ * for YUV color buffers, this returns the integer value with
+ * respect to the enumeration provided for EGL_YUV_PLANE_BPP_EXT
+ *
+ * and:
+ *
+ * EGL_BUFFER_SIZE gives the total of the color component bits of
+ * the color buffer for EGL_RGB_BUFFER or for EGL_LUMINANCE_BUFFER.
+ * ...
+ * When EGL_COLOR_BUFFER_TYPE is of type EGL_YUV_BUFFER_EXT,
+ * this will reflect the enumeration provided as an integer)
+ * for EGL_YUV_PLANE_BPP_EXT, giving a value of 0, 8 or 10
+ */
+ if (criteria->BufferSize > 0) {
+ val1 = conf1->BufferSize;
+ val2 = conf2->BufferSize;
+ }
}
}
else {
@@ -664,6 +879,36 @@ _eglCompareConfigs(const _EGLConfig *conf1, const _EGLConfig *conf2,
return (val1 - val2);
}
+ if (conf1->YUVOrderEXT != conf2->YUVOrderEXT)
+ {
+ const EGLint yuv_order[] = {
+ EGL_NONE,
+ EGL_YUV_ORDER_YUV_EXT,
+ EGL_YUV_ORDER_YVU_EXT,
+ EGL_YUV_ORDER_YUYV_EXT,
+ EGL_YUV_ORDER_YVYU_EXT,
+ EGL_YUV_ORDER_UYVY_EXT,
+ EGL_YUV_ORDER_VYUY_EXT,
+ EGL_YUV_ORDER_AYUV_EXT,
+ };
+
+ val1 = val2 = 0;
+ for (i = 0; i < ARRAY_SIZE(yuv_order); i++) {
+ if (yuv_order[i] == conf1->YUVOrderEXT) {
+ val1 = i;
+ break;
+ }
+ }
+ for (i = 0; i < ARRAY_SIZE(yuv_order); i++) {
+ if (yuv_order[i] == conf2->YUVOrderEXT) {
+ val2 = i;
+ break;
+ }
+ }
+ if (val1 != val2)
+ return val1 - val2;
+ }
+
/* EGL_NATIVE_VISUAL_TYPE cannot be compared here */
return (compare_id) ? (conf1->ConfigID - conf2->ConfigID) : 0;
diff --git a/src/egl/main/eglconfig.h b/src/egl/main/eglconfig.h
index 1f2a4008f12..d4a748970b5 100644
--- a/src/egl/main/eglconfig.h
+++ b/src/egl/main/eglconfig.h
@@ -89,6 +89,12 @@ struct _egl_config
EGLint FramebufferTargetAndroid;
EGLint RecordableAndroid;
EGLint ComponentType;
+ EGLint YUVOrderEXT;
+ EGLint YUVNumberOfPlanesEXT;
+ EGLint YUVSubsampleEXT;
+ EGLint YUVDepthRangeEXT;
+ EGLint YUVCSCStandardEXT;
+ EGLint YUVPlaneBPPEXT;
};
@@ -139,6 +145,12 @@ _eglOffsetOfConfig(EGLint attr)
ATTRIB_MAP(EGL_FRAMEBUFFER_TARGET_ANDROID, FramebufferTargetAndroid);
ATTRIB_MAP(EGL_RECORDABLE_ANDROID, RecordableAndroid);
ATTRIB_MAP(EGL_COLOR_COMPONENT_TYPE_EXT, ComponentType);
+ ATTRIB_MAP(EGL_YUV_ORDER_EXT, YUVOrderEXT);
+ ATTRIB_MAP(EGL_YUV_NUMBER_OF_PLANES_EXT, YUVNumberOfPlanesEXT);
+ ATTRIB_MAP(EGL_YUV_SUBSAMPLE_EXT, YUVSubsampleEXT);
+ ATTRIB_MAP(EGL_YUV_DEPTH_RANGE_EXT, YUVDepthRangeEXT);
+ ATTRIB_MAP(EGL_YUV_CSC_STANDARD_EXT, YUVCSCStandardEXT);
+ ATTRIB_MAP(EGL_YUV_PLANE_BPP_EXT, YUVPlaneBPPEXT);
#undef ATTRIB_MAP
default:
return -1;
diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h
index 0a7366b7c07..020529c57e2 100644
--- a/src/egl/main/egldisplay.h
+++ b/src/egl/main/egldisplay.h
@@ -112,6 +112,7 @@ struct _egl_extensions
EGLBoolean EXT_surface_CTA861_3_metadata;
EGLBoolean EXT_surface_SMPTE2086_metadata;
EGLBoolean EXT_swap_buffers_with_damage;
+ EGLBoolean EXT_yuv_surface;
unsigned int IMG_context_priority;
#define __EGL_CONTEXT_PRIORITY_LOW_BIT 0
--
2.17.1
@@ -0,0 +1,35 @@
From ab2935ddffde305a6bdf49a9e928de407e04871b Mon Sep 17 00:00:00 2001
From: Frank Binns <frank.binns@imgtec.com>
Date: Fri, 2 Feb 2018 16:59:52 +0000
Subject: [PATCH 33/50] dri: add missing __DRI_IMAGE_COMPONENTS define for
EGL_TEXTURE_EXTERNAL_WL
The __DRI_IMAGE_COMPONENTS defines have been re-ordered, to make it
less likely that new defines will be added with the same values as
existing ones.
---
include/GL/internal/dri_interface.h | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index 89e29299840..8214e7a55c3 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -1459,11 +1459,12 @@ struct __DRIdri2ExtensionRec {
#define __DRI_IMAGE_COMPONENTS_Y_U_V 0x3003
#define __DRI_IMAGE_COMPONENTS_Y_UV 0x3004
#define __DRI_IMAGE_COMPONENTS_Y_XUXV 0x3005
+#define __DRI_IMAGE_COMPONENTS_R 0x3006
+#define __DRI_IMAGE_COMPONENTS_RG 0x3007
#define __DRI_IMAGE_COMPONENTS_Y_UXVX 0x3008
#define __DRI_IMAGE_COMPONENTS_AYUV 0x3009
#define __DRI_IMAGE_COMPONENTS_XYUV 0x300A
-#define __DRI_IMAGE_COMPONENTS_R 0x3006
-#define __DRI_IMAGE_COMPONENTS_RG 0x3007
+#define __DRI_IMAGE_COMPONENTS_EXTERNAL 0x300B
/**
--
2.17.1
@@ -0,0 +1,74 @@
From 2b9a147b073ed8ff1d52246be5c885959d859c45 Mon Sep 17 00:00:00 2001
From: Frank Binns <frank.binns@imgtec.com>
Date: Thu, 11 Jan 2018 09:38:47 +0000
Subject: [PATCH 34/50] egl/wayland: expose EXT_yuv_surface support
This adds support for YUYV configs.
---
src/egl/drivers/dri2/egl_dri2.c | 1 +
src/egl/drivers/dri2/platform_wayland.c | 15 ++++++++++++++-
2 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index a0b52eab983..d359934a818 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -2798,6 +2798,7 @@ static const struct wl_drm_components_descriptor {
{ __DRI_IMAGE_COMPONENTS_Y_U_V, EGL_TEXTURE_Y_U_V_WL, 3 },
{ __DRI_IMAGE_COMPONENTS_Y_UV, EGL_TEXTURE_Y_UV_WL, 2 },
{ __DRI_IMAGE_COMPONENTS_Y_XUXV, EGL_TEXTURE_Y_XUXV_WL, 2 },
+ { __DRI_IMAGE_COMPONENTS_EXTERNAL, EGL_TEXTURE_EXTERNAL_WL, 1 },
};
static _EGLImage *
diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c
index 43ad6420174..de12ec21f53 100644
--- a/src/egl/drivers/dri2/platform_wayland.c
+++ b/src/egl/drivers/dri2/platform_wayland.c
@@ -134,6 +134,13 @@ static const struct dri2_wl_visual {
{ 11, 5, 0, -1 },
{ 5, 6, 5, 0 },
},
+ {
+ "YUYV",
+ WL_DRM_FORMAT_YUYV, WL_SHM_FORMAT_YUYV,
+ __DRI_IMAGE_FORMAT_YUYV, __DRI_IMAGE_FORMAT_NONE, 32,
+ { -1, -1, -1, -1 },
+ { 0, 0, 0, 0 },
+ },
};
static_assert(ARRAY_SIZE(dri2_wl_visuals) <= EGL_DRI2_MAX_FORMATS,
@@ -970,6 +977,7 @@ dri2_wl_get_capability(void *loaderPrivate, enum dri_loader_cap cap)
{
switch (cap) {
case DRI_LOADER_CAP_FP16:
+ case DRI_LOADER_CAP_YUV_SURFACE_IMG:
return 1;
default:
return 0;
@@ -1561,6 +1569,7 @@ dri2_wl_add_configs_for_visuals(_EGLDisplay *disp)
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
unsigned int format_count[ARRAY_SIZE(dri2_wl_visuals)] = { 0 };
unsigned int count = 0;
+ EGLint surface_type;
bool assigned;
for (unsigned i = 0; dri2_dpy->driver_configs[i]; i++) {
@@ -1572,8 +1581,12 @@ dri2_wl_add_configs_for_visuals(_EGLDisplay *disp)
if (!BITSET_TEST(dri2_dpy->formats, j))
continue;
+ surface_type = EGL_WINDOW_BIT;
+ if (dri2_wl_visuals[j].wl_drm_format != WL_DRM_FORMAT_YUYV)
+ surface_type |= EGL_PBUFFER_BIT;
+
dri2_conf = dri2_add_config(disp, dri2_dpy->driver_configs[i],
- count + 1, EGL_WINDOW_BIT | EGL_PBUFFER_BIT, NULL, dri2_wl_visuals[j].rgba_shifts, dri2_wl_visuals[j].rgba_sizes);
+ count + 1, surface_type, NULL, dri2_wl_visuals[j].rgba_shifts, dri2_wl_visuals[j].rgba_sizes);
if (dri2_conf) {
if (dri2_conf->base.ConfigID == count + 1)
count++;
--
2.17.1
@@ -0,0 +1,357 @@
From daf8ff0be3c3fbfe5bfba656eca511a45720bdea Mon Sep 17 00:00:00 2001
From: Frank Binns <frank.binns@imgtec.com>
Date: Tue, 13 Feb 2018 14:47:48 +0000
Subject: [PATCH 35/50] egl/tizen: expose EXT_yuv_surface support
This adds support for NV12 and NV21 configs.
---
src/egl/drivers/dri2/platform_tizen.c | 278 ++++++++++++++++++--------
1 file changed, 200 insertions(+), 78 deletions(-)
diff --git a/src/egl/drivers/dri2/platform_tizen.c b/src/egl/drivers/dri2/platform_tizen.c
index 2bc9b3e7c64..b6478a1875b 100644
--- a/src/egl/drivers/dri2/platform_tizen.c
+++ b/src/egl/drivers/dri2/platform_tizen.c
@@ -100,37 +100,93 @@ create_image_from_native(struct dri2_egl_surface *dri2_surf,
{
_EGLSurface *surf = &dri2_surf->base;
struct dri2_egl_display *dri2_dpy = dri2_egl_display(surf->Resource.Display);
+ struct dri2_egl_config *dri2_conf = dri2_egl_config(surf->Config);
+ const __DRIconfig *config =
+ dri2_get_dri_config(dri2_conf, surf->Type, surf->GLColorspace);
tbm_bo tbm_buf;
tbm_surface_info_s info;
- int fd, fourcc, offset, pitch;
+ int fd[TBM_SURF_PLANE_MAX];
+ int offset[TBM_SURF_PLANE_MAX];
+ int pitch[TBM_SURF_PLANE_MAX];
+ int fourcc;
__DRIimage *dri_image;
-
- tbm_buf = tbm_surface_internal_get_bo(tbm_surf, 0);
- if (!tbm_buf) {
- _eglLog(_EGL_DEBUG, "%s: failed to get bo for tbm surface", __func__);
- return NULL;
- }
+ enum __DRIYUVColorSpace color_space;
+ enum __DRISampleRange sample_range;
+ unsigned csc_standard;
+ unsigned depth_range;
+ unsigned create_error;
if (tbm_surface_get_info(tbm_surf, &info)) {
_eglLog(_EGL_DEBUG, "%s: failed to get tbm surface info", __func__);
return NULL;
}
- fd = tbm_bo_export_fd(tbm_buf);
fourcc = dri2_fourcc_from_tbm_format(info.format);
- offset = info.planes[0].offset;
- pitch = info.planes[0].stride;
-
- dri_image = dri2_dpy->image->createImageFromFds(dri2_dpy->dri_screen,
- info.width,
- info.height,
- fourcc,
- &fd,
- 1,
- &pitch,
- &offset,
- loaderPrivate);
- close(fd);
+
+ for (unsigned i = 0; i < info.num_planes; i++) {
+ int index = tbm_surface_internal_get_plane_bo_idx(tbm_surf, i);
+
+ tbm_buf = tbm_surface_internal_get_bo(tbm_surf, index);
+ if (!tbm_buf) {
+ while (i--)
+ close(fd[i]);
+ _eglLog(_EGL_DEBUG, "%s: failed to get bo %d for tbm surface",
+ __func__, i);
+ return NULL;
+ }
+
+ fd[i] = tbm_bo_export_fd(tbm_buf);
+ offset[i] = info.planes[i].offset;
+ pitch[i] = info.planes[i].stride;
+ }
+
+ dri2_dpy->core->getConfigAttrib(config,
+ __DRI_ATTRIB_YUV_CSC_STANDARD, &csc_standard);
+ switch (csc_standard) {
+ case __DRI_ATTRIB_YUV_CSC_STANDARD_601_BIT:
+ color_space = __DRI_YUV_COLOR_SPACE_ITU_REC601;
+ break;
+ case __DRI_ATTRIB_YUV_CSC_STANDARD_709_BIT:
+ color_space = __DRI_YUV_COLOR_SPACE_ITU_REC709;
+ break;
+ case __DRI_ATTRIB_YUV_CSC_STANDARD_2020_BIT:
+ color_space = __DRI_YUV_COLOR_SPACE_ITU_REC2020;
+ break;
+ default:
+ color_space = __DRI_YUV_COLOR_SPACE_UNDEFINED;
+ break;
+ }
+
+ dri2_dpy->core->getConfigAttrib(config,
+ __DRI_ATTRIB_YUV_DEPTH_RANGE, &depth_range);
+ switch (depth_range) {
+ case __DRI_ATTRIB_YUV_DEPTH_RANGE_LIMITED_BIT:
+ sample_range = __DRI_YUV_NARROW_RANGE;
+ break;
+ case __DRI_ATTRIB_YUV_DEPTH_RANGE_FULL_BIT:
+ sample_range = __DRI_YUV_FULL_RANGE;
+ break;
+ default:
+ sample_range = __DRI_YUV_RANGE_UNDEFINED;
+ break;
+ }
+
+ dri_image = dri2_dpy->image->createImageFromDmaBufs(dri2_dpy->dri_screen,
+ info.width,
+ info.height,
+ fourcc,
+ fd,
+ info.num_planes,
+ pitch,
+ offset,
+ color_space,
+ sample_range,
+ __DRI_YUV_CHROMA_SITING_UNDEFINED,
+ __DRI_YUV_CHROMA_SITING_UNDEFINED,
+ &create_error,
+ loaderPrivate);
+ for (unsigned i = 0; i < info.num_planes; i++)
+ close(fd[i]);
if (!dri_image) {
_eglLog(_EGL_DEBUG, "%s: failed to create dri image from tbm bo", __func__);
@@ -792,10 +848,22 @@ dri2_tizen_flush_front_buffer(__DRIdrawable * driDrawable, void *loaderPrivate)
{
}
+static unsigned
+dri2_tizen_get_capability(void *loaderPrivate, enum dri_loader_cap cap)
+{
+ switch (cap) {
+ case DRI_LOADER_CAP_YUV_SURFACE_IMG:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
static const __DRIimageLoaderExtension tizen_image_loader_extension = {
- .base = { __DRI_IMAGE_LOADER, 1 },
+ .base = { __DRI_IMAGE_LOADER, 2 },
.getBuffers = dri2_tizen_get_buffers,
.flushFrontBuffer = dri2_tizen_flush_front_buffer,
+ .getCapability = dri2_tizen_get_capability,
};
static const __DRIextension *image_loader_extensions[] = {
@@ -804,6 +872,41 @@ static const __DRIextension *image_loader_extensions[] = {
NULL,
};
+static EGLBoolean
+derive_yuv_native_visual_from_config(struct dri2_egl_display *dri2_dpy,
+ const __DRIconfig *dri_config,
+ int *native_visual)
+{
+ unsigned order, subsample, num_planes, plane_bpp;
+
+ dri2_dpy->core->getConfigAttrib(dri_config, __DRI_ATTRIB_YUV_ORDER,
+ &order);
+ dri2_dpy->core->getConfigAttrib(dri_config, __DRI_ATTRIB_YUV_SUBSAMPLE,
+ &subsample);
+ dri2_dpy->core->getConfigAttrib(dri_config, __DRI_ATTRIB_YUV_NUMBER_OF_PLANES,
+ &num_planes);
+ dri2_dpy->core->getConfigAttrib(dri_config, __DRI_ATTRIB_YUV_PLANE_BPP,
+ &plane_bpp);
+
+ if ((plane_bpp & __DRI_ATTRIB_YUV_PLANE_BPP_8_BIT) == 0)
+ return EGL_FALSE;
+
+ if (num_planes != 2)
+ return EGL_FALSE;
+
+ if (subsample & __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_0_BIT) {
+ if (order & __DRI_ATTRIB_YUV_ORDER_YUV_BIT) {
+ *native_visual = TBM_FORMAT_NV12;
+ return EGL_TRUE;
+ } else if (order & __DRI_ATTRIB_YUV_ORDER_YVU_BIT) {
+ *native_visual = TBM_FORMAT_NV21;
+ return EGL_TRUE;
+ }
+ }
+
+ return EGL_FALSE;
+}
+
static EGLBoolean
dri2_tizen_add_configs(_EGLDisplay *dpy)
{
@@ -811,83 +914,102 @@ dri2_tizen_add_configs(_EGLDisplay *dpy)
int count = 0;
for (unsigned i = 0; dri2_dpy->driver_configs[i]; i++) {
- static const struct rgba_shifts_and_sizes pbuffer_sasa[] = {
- {
- /* ARGB8888 */
- { 16, 8, 0, 24 },
- { 8, 8, 8, 8 },
- },
- {
- /* RGB888 */
- { 16, 8, 0, -1 },
- { 8, 8, 8, 0 },
- },
- {
- /* RGB565 */
- { 11, 5, 0, -1 },
- { 5, 6, 5, 0 },
- },
- };
struct dri2_egl_config *dri2_cfg;
- int shifts[4];
- unsigned int sizes[4];
+ unsigned int render_type;
unsigned int caveat = 0;
int surface_type = 0;
- tpl_bool_t is_slow;
EGLint attr_list[] = {
EGL_NATIVE_VISUAL_ID, 0,
EGL_CONFIG_CAVEAT, EGL_NONE,
EGL_NONE,
};
- tpl_result_t res;
-
- dri2_get_shifts_and_sizes(dri2_dpy->core, dri2_dpy->driver_configs[i],
- shifts, sizes);
dri2_dpy->core->getConfigAttrib(dri2_dpy->driver_configs[i],
- __DRI_ATTRIB_BUFFER_SIZE, &depth);
+ __DRI_ATTRIB_CONFIG_CAVEAT, &caveat);
dri2_dpy->core->getConfigAttrib(dri2_dpy->driver_configs[i],
- __DRI_ATTRIB_CONFIG_CAVEAT, &caveat);
+ __DRI_ATTRIB_RENDER_TYPE, &render_type);
+
+ if (render_type & __DRI_ATTRIB_RGBA_BIT) {
+ static const struct rgba_shifts_and_sizes pbuffer_sasa[] = {
+ {
+ /* ARGB8888 */
+ { 16, 8, 0, 24 },
+ { 8, 8, 8, 8 },
+ },
+ {
+ /* RGB888 */
+ { 16, 8, 0, -1 },
+ { 8, 8, 8, 0 },
+ },
+ {
+ /* RGB565 */
+ { 11, 5, 0, -1 },
+ { 5, 6, 5, 0 },
+ },
+ };
+ int shifts[4];
+ unsigned int sizes[4];
+ unsigned int depth;
+ tpl_bool_t is_slow;
+ tpl_result_t res;
- res = tpl_display_query_config(dri2_dpy->tpl_dpy, TPL_SURFACE_TYPE_WINDOW,
- sizes[0], sizes[1], sizes[2], sizes[3],
- depth, &attr_list[1], &is_slow);
- if (res != TPL_ERROR_NONE)
- continue;
- surface_type |= EGL_WINDOW_BIT;
+ dri2_get_shifts_and_sizes(dri2_dpy->core, dri2_dpy->driver_configs[i],
+ shifts, sizes);
- if (is_slow)
- caveat |= __DRI_ATTRIB_SLOW_BIT;
+ dri2_dpy->core->getConfigAttrib(dri2_dpy->driver_configs[i],
+ __DRI_ATTRIB_BUFFER_SIZE, &depth);
+
+ res = tpl_display_query_config(dri2_dpy->tpl_dpy,
+ TPL_SURFACE_TYPE_WINDOW,
+ sizes[0], sizes[1], sizes[2], sizes[3],
+ depth, &attr_list[1], &is_slow);
+ if (res != TPL_ERROR_NONE)
+ continue;
- res = tpl_display_query_config(dri2_dpy->tpl_dpy, TPL_SURFACE_TYPE_PIXMAP,
- sizes[0], sizes[1], sizes[2], sizes[3],
- depth, NULL, &is_slow);
- if (res == TPL_ERROR_NONE) {
- surface_type |= EGL_PIXMAP_BIT;
+ surface_type |= EGL_WINDOW_BIT;
if (is_slow)
caveat |= __DRI_ATTRIB_SLOW_BIT;
- }
- for (unsigned j = 0; j < ARRAY_SIZE(pbuffer_sasa); j++) {
- const struct rgba_shifts_and_sizes *pbuffer_sas = &pbuffer_sasa[j];
-
- if (shifts[0] == pbuffer_sas->shifts[0] &&
- shifts[1] == pbuffer_sas->shifts[1] &&
- shifts[2] == pbuffer_sas->shifts[2] &&
- shifts[3] == pbuffer_sas->shifts[3] &&
- sizes[0] == pbuffer_sas->sizes[0] &&
- sizes[1] == pbuffer_sas->sizes[1] &&
- sizes[2] == pbuffer_sas->sizes[2] &&
- sizes[3] == pbuffer_sas->sizes[3]) {
- surface_type |= EGL_PBUFFER_BIT;
- break;
+ res = tpl_display_query_config(dri2_dpy->tpl_dpy,
+ TPL_SURFACE_TYPE_PIXMAP,
+ sizes[0], sizes[1], sizes[2], sizes[3],
+ depth, NULL, &is_slow);
+ if (res == TPL_ERROR_NONE) {
+ surface_type |= EGL_PIXMAP_BIT;
+
+ if (is_slow)
+ caveat |= __DRI_ATTRIB_SLOW_BIT;
}
- }
- if (dri2_dpy->image->base.version >= 9 && dri2_dpy->image->blitImage)
- surface_type |= EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
+ for (unsigned j = 0; j < ARRAY_SIZE(pbuffer_sasa); j++) {
+ const struct rgba_shifts_and_sizes *pbuffer_sas = &pbuffer_sasa[j];
+
+ if (shifts[0] == pbuffer_sas->shifts[0] &&
+ shifts[1] == pbuffer_sas->shifts[1] &&
+ shifts[2] == pbuffer_sas->shifts[2] &&
+ shifts[3] == pbuffer_sas->shifts[3] &&
+ sizes[0] == pbuffer_sas->sizes[0] &&
+ sizes[1] == pbuffer_sas->sizes[1] &&
+ sizes[2] == pbuffer_sas->sizes[2] &&
+ sizes[3] == pbuffer_sas->sizes[3]) {
+ surface_type |= EGL_PBUFFER_BIT;
+ break;
+ }
+
+ }
+
+ if (dri2_dpy->image->base.version >= 9 && dri2_dpy->image->blitImage)
+ surface_type |= EGL_SWAP_BEHAVIOR_PRESERVED_BIT;
+ } else if (render_type & __DRI_ATTRIB_YUV_BIT) {
+ if (!derive_yuv_native_visual_from_config(dri2_dpy,
+ dri2_dpy->driver_configs[i],
+ &attr_list[1]))
+ continue;
+ surface_type = EGL_WINDOW_BIT;
+ caveat = 0;
+ }
if (caveat & __DRI_ATTRIB_NON_CONFORMANT_CONFIG)
attr_list[3] = EGL_NON_CONFORMANT_CONFIG;
--
2.17.1
@@ -0,0 +1,69 @@
From 812b414afa598605ddc163d0a07f4374d1a625c9 Mon Sep 17 00:00:00 2001
From: Silvestrs Timofejevs <silvestrs.timofejevs@imgtec.com>
Date: Thu, 30 Aug 2018 13:48:53 +0100
Subject: [PATCH 36/50] gbm: add some new GBM formats
GBM_FORMAT_ARGB4444
GBM_FORMAT_BGR888
GBM_FORMAT_YUYV
GBM_FORMAT_YVU444_PACK10_IMG
---
src/gbm/backends/dri/gbm_dri.c | 16 ++++++++++++++++
src/gbm/main/gbm.h | 2 ++
2 files changed, 18 insertions(+)
diff --git a/src/gbm/backends/dri/gbm_dri.c b/src/gbm/backends/dri/gbm_dri.c
index f9adbc5c001..1144e9a62d1 100644
--- a/src/gbm/backends/dri/gbm_dri.c
+++ b/src/gbm/backends/dri/gbm_dri.c
@@ -508,11 +508,21 @@ static const struct gbm_dri_visual gbm_dri_visuals_table[] = {
{ 10, 5, 0, 11 },
{ 5, 5, 5, 1 },
},
+ {
+ GBM_FORMAT_ARGB4444, __DRI_IMAGE_FORMAT_ARGB4444,
+ { 8, 4, 0, 12 },
+ { 4, 4, 4, 4 },
+ },
{
GBM_FORMAT_RGB565, __DRI_IMAGE_FORMAT_RGB565,
{ 11, 5, 0, -1 },
{ 5, 6, 5, 0 },
},
+ {
+ GBM_FORMAT_BGR888, __DRI_IMAGE_FORMAT_BGR888,
+ { 0, 8, 16, -1 },
+ { 8, 8, 8, 0 },
+ },
{
GBM_FORMAT_XRGB8888, __DRI_IMAGE_FORMAT_XRGB8888,
{ 16, 8, 0, -1 },
@@ -565,6 +575,12 @@ static const struct gbm_dri_visual gbm_dri_visuals_table[] = {
{ 16, 16, 16, 16 },
true,
},
+ {
+ GBM_FORMAT_YUYV, __DRI_IMAGE_FORMAT_YUYV,
+ },
+ {
+ GBM_FORMAT_YVU444_PACK10_IMG, __DRI_IMAGE_FORMAT_YVU444_PACK10_IMG,
+ },
};
static int
diff --git a/src/gbm/main/gbm.h b/src/gbm/main/gbm.h
index e754edd5654..19b601dc1f3 100644
--- a/src/gbm/main/gbm.h
+++ b/src/gbm/main/gbm.h
@@ -167,6 +167,8 @@ enum gbm_bo_format {
#define GBM_FORMAT_AYUV __gbm_fourcc_code('A', 'Y', 'U', 'V') /* [31:0] A:Y:Cb:Cr 8:8:8:8 little endian */
+#define GBM_FORMAT_YVU444_PACK10_IMG __gbm_fourcc_code('I', 'M', 'G', '2') /* [31:0] unused:Y:Cr:Cb 2:10:10:10 little endian */
+
/*
* 2 plane YCbCr
* index 0 = Y plane, [7:0] Y
--
2.17.1
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,480 @@
From 7065e8e6bc0c3674ae310468b95cef1d538f5f03 Mon Sep 17 00:00:00 2001
From: Silvestrs Timofejevs <silvestrs.timofejevs@imgtec.com>
Date: Mon, 24 Sep 2018 14:14:25 +0100
Subject: [PATCH 38/50] egl: add config debug printout
Feature to print out EGL returned configs for debug purposes.
'eglChooseConfig' and 'eglGetConfigs' debug information printout is
enabled when the log level equals '_EGL_DEBUG'. The configs are
printed, and if any of them are "chosen" they are marked with their
index in the chosen configs array.
---
src/egl/Makefile.sources | 4 +-
src/egl/main/eglconfig.c | 20 ++-
src/egl/main/eglconfigdebug.c | 276 ++++++++++++++++++++++++++++++++++
src/egl/main/eglconfigdebug.h | 55 +++++++
src/egl/main/egllog.c | 9 ++
src/egl/main/egllog.h | 4 +
src/egl/meson.build | 2 +
7 files changed, 365 insertions(+), 5 deletions(-)
create mode 100644 src/egl/main/eglconfigdebug.c
create mode 100644 src/egl/main/eglconfigdebug.h
diff --git a/src/egl/Makefile.sources b/src/egl/Makefile.sources
index 5f5b6d27e64..d757ba9bed4 100644
--- a/src/egl/Makefile.sources
+++ b/src/egl/Makefile.sources
@@ -25,7 +25,9 @@ LIBEGL_C_FILES := \
main/eglsync.c \
main/eglsync.h \
main/eglentrypoint.h \
- main/egltypedefs.h
+ main/egltypedefs.h \
+ main/eglconfigdebug.h \
+ main/eglconfigdebug.c
dri2_backend_core_FILES := \
drivers/dri2/egl_dri2.c \
diff --git a/src/egl/main/eglconfig.c b/src/egl/main/eglconfig.c
index 5e56948ab72..ea4b3c15f3f 100644
--- a/src/egl/main/eglconfig.c
+++ b/src/egl/main/eglconfig.c
@@ -40,6 +40,7 @@
#include "util/macros.h"
#include "eglconfig.h"
+#include "eglconfigdebug.h"
#include "egldisplay.h"
#include "eglcurrent.h"
#include "egllog.h"
@@ -1039,14 +1040,21 @@ _eglChooseConfig(_EGLDisplay *disp, const EGLint *attrib_list,
EGLConfig *configs, EGLint config_size, EGLint *num_configs)
{
_EGLConfig criteria;
+ EGLBoolean result;
if (!_eglParseConfigAttribList(&criteria, disp, attrib_list))
return _eglError(EGL_BAD_ATTRIBUTE, "eglChooseConfig");
- return _eglFilterConfigArray(disp->Configs,
- configs, config_size, num_configs,
- _eglFallbackMatch, _eglFallbackCompare,
- (void *) &criteria);
+ result = _eglFilterConfigArray(disp->Configs,
+ configs, config_size, num_configs,
+ _eglFallbackMatch, _eglFallbackCompare,
+ (void *) &criteria);
+
+ if (result && (_eglGetLogLevel() == _EGL_DEBUG))
+ eglPrintConfigDebug(disp, configs, *num_configs,
+ EGL_CONFIG_DEBUG_CHOOSE);
+
+ return result;
}
@@ -1096,5 +1104,9 @@ _eglGetConfigs(_EGLDisplay *disp, EGLConfig *configs,
*num_config = _eglFlattenArray(disp->Configs, (void *) configs,
sizeof(configs[0]), config_size, _eglFlattenConfig);
+ if (_eglGetLogLevel() == _EGL_DEBUG)
+ eglPrintConfigDebug(disp, configs, *num_config,
+ EGL_CONFIG_DEBUG_GET);
+
return EGL_TRUE;
}
diff --git a/src/egl/main/eglconfigdebug.c b/src/egl/main/eglconfigdebug.c
new file mode 100644
index 00000000000..13e0a8bc350
--- /dev/null
+++ b/src/egl/main/eglconfigdebug.c
@@ -0,0 +1,276 @@
+/*
+ * Copyright 2017 Imagination Technologies.
+ * All Rights Reserved.
+ *
+ * Based on eglinfo, which has copyright:
+ * Copyright (C) 2005 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, 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
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "eglarray.h"
+#include "eglconfig.h"
+#include "eglconfigdebug.h"
+#include "egldisplay.h"
+#include "egllog.h"
+#include "egltypedefs.h"
+
+/* Max debug message length */
+#define CONFIG_DEBUG_MSG_MAX 1000
+
+/*
+ * These are X visual types, so if you're running eglinfo under
+ * something not X, they probably don't make sense.
+ */
+static const char *const vnames[] = { "SG", "GS", "SC", "PC", "TC", "DC" };
+
+struct _printAttributes {
+ EGLint id, size, level;
+ EGLint red, green, blue, alpha;
+ EGLint depth, stencil;
+ EGLint renderable, surfaces;
+ EGLint vid, vtype, caveat, bindRgb, bindRgba;
+ EGLint samples, sampleBuffers;
+ char surfString[100];
+};
+
+static void
+_printHeaderFormat(void)
+{
+ /*
+ * EGL configuration output legend:
+ *
+ * chosen --------------- eglChooseConfig returned config priority,
+ * only relevant when eglChooseConfig is called.
+ * id ------------------- EGL_CONFIG_ID
+ * bfsz ----------------- EGL_BUFFER_SIZE
+ * lvl ------------------ EGL_LEVEL
+ *
+ * colourbuffer
+ * r -------------------- EGL_RED_SIZE
+ * g -------------------- EGL_GREEN_SIZE
+ * b -------------------- EGL_BLUE_SIZE
+ * a -------------------- EGL_ALPHA_SIZE
+ * dpth ----------------- EGL_DEPTH_SIZE
+ * stcl ----------------- EGL_STENCIL_SIZE
+ *
+ * multisample
+ * ns ------------------- EGL_SAMPLES
+ * b -------------------- EGL_SAMPLE_BUFFERS
+ * visid ---------------- EGL_NATIVE_VISUAL_ID/EGL_NATIVE_VISUAL_TYPE
+ * caveat --------------- EGL_CONFIG_CAVEAT
+ * bind ----------------- EGL_BIND_TO_TEXTURE_RGB/EGL_BIND_TO_TEXTURE_RGBA
+ *
+ * renderable
+ * gl, es, es2, es3, vg - EGL_RENDERABLE_TYPE
+ *
+ * supported
+ * surfaces ------------- EGL_SURFACE_TYPE
+ */
+ _eglLog(_EGL_DEBUG, "---------------");
+ _eglLog(_EGL_DEBUG, "Configurations:");
+ _eglLog(_EGL_DEBUG, "cho bf lv colourbuffer dp st ms vis cav bi renderable supported");
+ _eglLog(_EGL_DEBUG, "sen id sz l r g b a th cl ns b id eat nd gl es es2 es3 vg surfaces");
+ _eglLog(_EGL_DEBUG, "---------------");
+}
+
+static void
+_snprintfStrcat(char *const msg, const int maxSize, const char *fmt, ...)
+{
+ int maxAllowed;
+ va_list args;
+
+ maxAllowed = maxSize - strlen(msg);
+
+ va_start(args, fmt);
+ (void) vsnprintf(&msg[strlen(msg)], maxAllowed, fmt, args);
+ va_end(args);
+}
+
+static void
+_eglGetConfigAttrs(_EGLDisplay *const dpy, _EGLConfig *const conf,
+ struct _printAttributes *const attr)
+{
+ EGLBoolean success = EGL_TRUE;
+
+ success &= _eglGetConfigAttrib(dpy, conf, EGL_CONFIG_ID, &attr->id);
+ success &= _eglGetConfigAttrib(dpy, conf, EGL_BUFFER_SIZE, &attr->size);
+ success &= _eglGetConfigAttrib(dpy, conf, EGL_LEVEL, &attr->level);
+
+ success &= _eglGetConfigAttrib(dpy, conf, EGL_RED_SIZE, &attr->red);
+ success &= _eglGetConfigAttrib(dpy, conf, EGL_GREEN_SIZE, &attr->green);
+ success &= _eglGetConfigAttrib(dpy, conf, EGL_BLUE_SIZE, &attr->blue);
+ success &= _eglGetConfigAttrib(dpy, conf, EGL_ALPHA_SIZE, &attr->alpha);
+ success &= _eglGetConfigAttrib(dpy, conf, EGL_DEPTH_SIZE, &attr->depth);
+ success &= _eglGetConfigAttrib(dpy, conf, EGL_STENCIL_SIZE, &attr->stencil);
+ success &= _eglGetConfigAttrib(dpy, conf, EGL_NATIVE_VISUAL_ID, &attr->vid);
+ success &= _eglGetConfigAttrib(dpy, conf, EGL_NATIVE_VISUAL_TYPE, &attr->vtype);
+
+ success &= _eglGetConfigAttrib(dpy, conf, EGL_CONFIG_CAVEAT, &attr->caveat);
+ success &= _eglGetConfigAttrib(dpy, conf, EGL_BIND_TO_TEXTURE_RGB, &attr->bindRgb);
+ success &= _eglGetConfigAttrib(dpy, conf, EGL_BIND_TO_TEXTURE_RGBA, &attr->bindRgba);
+ success &= _eglGetConfigAttrib(dpy, conf, EGL_RENDERABLE_TYPE, &attr->renderable);
+ success &= _eglGetConfigAttrib(dpy, conf, EGL_SURFACE_TYPE, &attr->surfaces);
+
+ success &= _eglGetConfigAttrib(dpy, conf, EGL_SAMPLES, &attr->samples);
+ success &= _eglGetConfigAttrib(dpy, conf, EGL_SAMPLE_BUFFERS, &attr->sampleBuffers);
+
+ if (!success)
+ _eglLog(_EGL_DEBUG, "%s: config tainted, could not obtain all attributes",
+ __func__);
+}
+
+static void
+_eglPrintConfig(_EGLDisplay *const dpy, _EGLConfig *const conf,
+ char *const printMsg, const int maxMsgSize)
+{
+ struct _printAttributes attr = { 0 };
+
+ _eglGetConfigAttrs(dpy, conf, &attr);
+
+ if (attr.surfaces & EGL_WINDOW_BIT)
+ strcat(attr.surfString, "win,");
+ if (attr.surfaces & EGL_PBUFFER_BIT)
+ strcat(attr.surfString, "pb,");
+ if (attr.surfaces & EGL_PIXMAP_BIT)
+ strcat(attr.surfString, "pix,");
+ if (attr.surfaces & EGL_STREAM_BIT_KHR)
+ strcat(attr.surfString, "str,");
+ if (attr.surfaces & EGL_SWAP_BEHAVIOR_PRESERVED_BIT)
+ strcat(attr.surfString, "prsv,");
+ if (strlen(attr.surfString) > 0)
+ attr.surfString[strlen(attr.surfString) - 1] = 0;
+
+ _snprintfStrcat(printMsg, maxMsgSize,
+ "0x%03x %2d %2d %2d %2d %2d %2d %2d %2d %2d%2d 0x%08x%2s ",
+ attr.id, attr.size, attr.level,
+ attr.red, attr.green, attr.blue, attr.alpha,
+ attr.depth, attr.stencil,
+ attr.samples, attr.sampleBuffers, attr.vid,
+ attr.vtype < 6 ? vnames[attr.vtype] : "--");
+
+ _snprintfStrcat(printMsg, maxMsgSize,
+ "%c %c %c %c %c %c %c %15s",
+ (attr.caveat != EGL_NONE) ? 'y' : ' ',
+ (attr.bindRgba) ? 'a' : (attr.bindRgb) ? 'y' : ' ',
+ (attr.renderable & EGL_OPENGL_BIT) ? 'y' : ' ',
+ (attr.renderable & EGL_OPENGL_ES_BIT) ? 'y' : ' ',
+ (attr.renderable & EGL_OPENGL_ES2_BIT) ? 'y' : ' ',
+ (attr.renderable & EGL_OPENGL_ES3_BIT) ? 'y' : ' ',
+ (attr.renderable & EGL_OPENVG_BIT) ? 'y' : ' ',
+ attr.surfString);
+
+ _eglLog(_EGL_DEBUG, printMsg);
+}
+
+static void
+_eglMarkChosenConfig(_EGLConfig *const config,
+ _EGLConfig *const *const chosenConfigs,
+ const EGLint numConfigs, char *const printMsg,
+ const int maxMsgSize)
+{
+ const char padding[] = " ";
+
+ if (chosenConfigs == NULL) {
+ _snprintfStrcat(printMsg, maxMsgSize, "%s ", &padding[0]);
+ return;
+ }
+
+ /* Find a match, "mark" and return */
+ for (EGLint i = 0; i < numConfigs; i++) {
+ if (config == chosenConfigs[i]) {
+ _snprintfStrcat(printMsg, maxMsgSize, "%*d ", strlen(padding), i);
+ return;
+ }
+ }
+
+ _snprintfStrcat(printMsg, maxMsgSize, "%s ", &padding[0]);
+}
+
+static void
+_eglPrintConfigs(_EGLDisplay *const dpy,
+ EGLConfig *const configs, const EGLint numConfigs,
+ const enum EGL_CONFIG_DEBUG_OPTION printOption)
+{
+ const int maxMsgSize = CONFIG_DEBUG_MSG_MAX;
+ EGLint numConfigsToPrint;
+ _EGLConfig **configsToPrint;
+ _EGLConfig **chosenConfigs;
+ char *printMsg;
+
+ printMsg = malloc(maxMsgSize);
+ if (!printMsg) {
+ _eglLog(_EGL_DEBUG, "%s: failed to allocate the print message", __func__);
+ return;
+ }
+
+ /*
+ * If the printout request came from the 'eglChooseConfig', all
+ * configs are printed, and the "chosen" configs are marked.
+ */
+ if (printOption == EGL_CONFIG_DEBUG_CHOOSE) {
+ configsToPrint = (_EGLConfig **) dpy->Configs->Elements;
+ numConfigsToPrint = dpy->Configs->Size;
+ chosenConfigs = (_EGLConfig **) configs;
+ } else {
+ assert(printOption == EGL_CONFIG_DEBUG_GET);
+ configsToPrint = (_EGLConfig **) configs;
+ numConfigsToPrint = numConfigs;
+ chosenConfigs = NULL;
+ }
+
+ _printHeaderFormat();
+ for (EGLint i = 0; i < numConfigsToPrint; i++) {
+ _EGLConfig *configToPrint = configsToPrint[i];
+
+ /* "clear" message */
+ printMsg[0] = '\0';
+
+ _eglMarkChosenConfig(configToPrint, chosenConfigs, numConfigs,
+ printMsg, maxMsgSize);
+
+ _eglPrintConfig(dpy, configToPrint, printMsg, maxMsgSize);
+ }
+
+ free(printMsg);
+}
+
+void eglPrintConfigDebug(_EGLDisplay *const dpy,
+ EGLConfig *const configs, const EGLint numConfigs,
+ const enum EGL_CONFIG_DEBUG_OPTION printOption)
+{
+ if (!numConfigs || !configs) {
+ _eglLog(_EGL_DEBUG, "%s: nothing to print", __func__);
+ return;
+ }
+
+ switch (printOption) {
+ case EGL_CONFIG_DEBUG_CHOOSE:
+ case EGL_CONFIG_DEBUG_GET:
+ _eglPrintConfigs(dpy, configs, numConfigs, printOption);
+ break;
+ default:
+ _eglLog(_EGL_DEBUG, "%s: bad debug option", __func__);
+ break;
+ }
+}
diff --git a/src/egl/main/eglconfigdebug.h b/src/egl/main/eglconfigdebug.h
new file mode 100644
index 00000000000..562aefff9de
--- /dev/null
+++ b/src/egl/main/eglconfigdebug.h
@@ -0,0 +1,55 @@
+/**************************************************************************
+ * Copyright 2017 Imagination Technologies.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND 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 EGLCONFIGDEBUG_INCLUDED
+#define EGLCONFIGDEBUG_INCLUDED
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "egltypedefs.h"
+
+/**
+ * Config printout options.
+ */
+enum EGL_CONFIG_DEBUG_OPTION {
+ EGL_CONFIG_DEBUG_CHOOSE,
+ EGL_CONFIG_DEBUG_GET,
+};
+
+/**
+ * Print the list of configs and the associated attributes.
+ */
+void eglPrintConfigDebug(_EGLDisplay *const dpy,
+ EGLConfig *const configs, const EGLint numConfigs,
+ const enum EGL_CONFIG_DEBUG_OPTION printOption);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* EGLCONFIGDEBUG_INCLUDED */
diff --git a/src/egl/main/egllog.c b/src/egl/main/egllog.c
index 973b7600ab1..7a9032f9bbb 100644
--- a/src/egl/main/egllog.c
+++ b/src/egl/main/egllog.c
@@ -153,6 +153,15 @@ _eglInitLogger(void)
}
}
+/**
+ * Return the log level.
+ */
+EGLint
+_eglGetLogLevel(void)
+{
+ return logging.level;
+}
+
/**
* Log a message with message logger.
diff --git a/src/egl/main/egllog.h b/src/egl/main/egllog.h
index 2a06a34684a..a1cf9770ed8 100644
--- a/src/egl/main/egllog.h
+++ b/src/egl/main/egllog.h
@@ -44,6 +44,10 @@ extern "C" {
#define _EGL_DEBUG 3 /* useful info for debugging */
+extern EGLint
+_eglGetLogLevel(void);
+
+
extern void
_eglLog(EGLint level, const char *fmtStr, ...);
diff --git a/src/egl/meson.build b/src/egl/meson.build
index d23d62562da..e0628c41c43 100644
--- a/src/egl/meson.build
+++ b/src/egl/meson.build
@@ -30,6 +30,8 @@ files_egl = files(
'main/eglapi.c',
'main/eglarray.c',
'main/eglarray.h',
+ 'main/eglconfigdebug.c',
+ 'main/eglconfigdebug.h',
'main/eglconfig.c',
'main/eglconfig.h',
'main/eglcontext.c',
--
2.17.1
@@ -0,0 +1,217 @@
From 1b9ddfc2a489056311c6eff3760ad6f450d13c94 Mon Sep 17 00:00:00 2001
From: Frank Binns <frank.binns@imgtec.com>
Date: Tue, 29 Jan 2019 14:36:25 +0000
Subject: [PATCH 39/50] egl: add support for EXT_image_gl_colorspace
---
src/egl/drivers/dri2/egl_dri2.c | 57 +++++++++++++++++++++++++++++++--
src/egl/main/eglapi.c | 1 +
src/egl/main/egldisplay.h | 1 +
src/egl/main/eglimage.c | 14 ++++++++
src/egl/main/eglimage.h | 3 ++
5 files changed, 74 insertions(+), 2 deletions(-)
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index ee19d125675..f001ee7b98f 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -1113,6 +1113,9 @@ dri2_setup_screen(_EGLDisplay *disp)
dri2_dpy->image->createImageFromBuffer) {
disp->Extensions.IMG_cl_image = EGL_TRUE;
}
+
+ if (disp->Extensions.KHR_gl_colorspace)
+ disp->Extensions.EXT_image_gl_colorspace = EGL_TRUE;
}
if (dri2_dpy->flush_control)
@@ -2752,6 +2755,11 @@ dri2_create_image_wayland_wl_buffer_tizen(_EGLDisplay *disp, _EGLContext *ctx,
return NULL;
}
+ if (attrs.GLColorspace != EGL_GL_COLORSPACE_DEFAULT_EXT) {
+ _eglError(EGL_BAD_MATCH, "unsupported colorspace");
+ return NULL;
+ }
+
if (tbm_surface_get_info(tbm_surf, &info)) {
_eglError(EGL_BAD_PARAMETER, "tbm_surface_get_info");
return NULL;
@@ -2827,6 +2835,11 @@ dri2_create_image_wayland_wl_buffer(_EGLDisplay *disp, _EGLContext *ctx,
if (!_eglParseImageAttribList(&attrs, disp, attr_list))
return NULL;
+ if (attrs.GLColorspace != EGL_GL_COLORSPACE_DEFAULT_EXT) {
+ _eglError(EGL_BAD_MATCH, "unsupported colorspace");
+ return NULL;
+ }
+
plane = attrs.PlaneWL;
f = buffer->driver_format;
if (plane < 0 || plane >= f->nplanes) {
@@ -2890,6 +2903,11 @@ dri2_create_image_khr_texture(_EGLDisplay *disp, _EGLContext *ctx,
if (!_eglParseImageAttribList(&attrs, disp, attr_list))
return EGL_NO_IMAGE_KHR;
+ if (attrs.GLColorspace != EGL_GL_COLORSPACE_DEFAULT_EXT) {
+ _eglError(EGL_BAD_MATCH, "unsupported colorspace");
+ return EGL_NO_IMAGE_KHR;
+ }
+
switch (target) {
case EGL_GL_TEXTURE_2D_KHR:
if (!disp->Extensions.KHR_gl_texture_2D_image) {
@@ -3035,6 +3053,11 @@ dri2_create_image_mesa_drm_buffer(_EGLDisplay *disp, _EGLContext *ctx,
return NULL;
}
+ if (attrs.GLColorspace != EGL_GL_COLORSPACE_DEFAULT_EXT) {
+ _eglError(EGL_BAD_MATCH, "unsupported colorspace");
+ return NULL;
+ }
+
switch (attrs.DRMBufferFormatMESA) {
case EGL_DRM_BUFFER_FORMAT_ARGB32_MESA:
format = __DRI_IMAGE_FORMAT_ARGB8888;
@@ -3211,6 +3234,23 @@ dri2_num_fourcc_format_planes(EGLint format)
}
}
+static int
+dri2_get_srgb_fourcc(int drm_fourcc)
+{
+ switch (drm_fourcc) {
+ case DRM_FORMAT_ARGB8888:
+ return __DRI_IMAGE_FOURCC_SARGB8888;
+ case DRM_FORMAT_ABGR8888:
+ return __DRI_IMAGE_FOURCC_SABGR8888;
+ case DRM_FORMAT_BGR888:
+ return __DRI_IMAGE_FOURCC_SBGR888;
+ default:
+ _eglLog(_EGL_DEBUG, "%s: no matching sRGB FourCC for %#x",
+ __func__, drm_fourcc);
+ return 0;
+ }
+}
+
/* Returns the total number of file descriptors. Zero indicates an error. */
static unsigned
dri2_check_dma_buf_format(const _EGLImageAttribs *attrs)
@@ -3356,6 +3396,7 @@ dri2_create_image_dma_buf(_EGLDisplay *disp, _EGLContext *ctx,
int fds[DMA_BUF_MAX_PLANES];
int pitches[DMA_BUF_MAX_PLANES];
int offsets[DMA_BUF_MAX_PLANES];
+ int fourcc;
uint64_t modifier;
bool has_modifier = false;
unsigned error;
@@ -3381,6 +3422,18 @@ dri2_create_image_dma_buf(_EGLDisplay *disp, _EGLContext *ctx,
if (!num_fds)
return NULL;
+ if (attrs.GLColorspace == EGL_GL_COLORSPACE_SRGB_KHR) {
+ fourcc = dri2_get_srgb_fourcc(attrs.DMABufFourCC.Value);
+ if (fourcc == 0) {
+ _eglError(EGL_BAD_MATCH, "unsupported colorspace");
+ return NULL;
+ }
+ } else {
+ assert(attrs.GLColorspace == EGL_GL_COLORSPACE_LINEAR_KHR ||
+ attrs.GLColorspace == EGL_GL_COLORSPACE_DEFAULT_EXT);
+ fourcc = attrs.DMABufFourCC.Value;
+ }
+
for (unsigned i = 0; i < num_fds; ++i) {
fds[i] = attrs.DMABufPlaneFds[i].Value;
pitches[i] = attrs.DMABufPlanePitches[i].Value;
@@ -3425,7 +3478,7 @@ dri2_create_image_dma_buf(_EGLDisplay *disp, _EGLContext *ctx,
}
dri_image =
dri2_dpy->image->createImageFromDmaBufs2(dri2_dpy->dri_screen,
- attrs.Width, attrs.Height, attrs.DMABufFourCC.Value,
+ attrs.Width, attrs.Height, fourcc,
modifier, fds, num_fds, pitches, offsets,
attrs.DMABufYuvColorSpaceHint.Value,
attrs.DMABufSampleRangeHint.Value,
@@ -3437,7 +3490,7 @@ dri2_create_image_dma_buf(_EGLDisplay *disp, _EGLContext *ctx,
else {
dri_image =
dri2_dpy->image->createImageFromDmaBufs(dri2_dpy->dri_screen,
- attrs.Width, attrs.Height, attrs.DMABufFourCC.Value,
+ attrs.Width, attrs.Height, fourcc,
fds, num_fds, pitches, offsets,
attrs.DMABufYuvColorSpaceHint.Value,
attrs.DMABufSampleRangeHint.Value,
diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c
index 893541f55b1..431dd70d1d8 100644
--- a/src/egl/main/eglapi.c
+++ b/src/egl/main/eglapi.c
@@ -508,6 +508,7 @@ _eglCreateExtensionsString(_EGLDisplay *disp)
_EGL_CHECK_EXTENSION(EXT_create_context_robustness);
_EGL_CHECK_EXTENSION(EXT_image_dma_buf_import);
_EGL_CHECK_EXTENSION(EXT_image_dma_buf_import_modifiers);
+ _EGL_CHECK_EXTENSION(EXT_image_gl_colorspace);
_EGL_CHECK_EXTENSION(EXT_protected_surface);
_EGL_CHECK_EXTENSION(EXT_surface_CTA861_3_metadata);
_EGL_CHECK_EXTENSION(EXT_surface_SMPTE2086_metadata);
diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h
index 8489af9dde2..6e5b29fe1ac 100644
--- a/src/egl/main/egldisplay.h
+++ b/src/egl/main/egldisplay.h
@@ -108,6 +108,7 @@ struct _egl_extensions
EGLBoolean EXT_create_context_robustness;
EGLBoolean EXT_image_dma_buf_import;
EGLBoolean EXT_image_dma_buf_import_modifiers;
+ EGLBoolean EXT_image_gl_colorspace;
EGLBoolean EXT_pixel_format_float;
EGLBoolean EXT_protected_surface;
EGLBoolean EXT_surface_CTA861_3_metadata;
diff --git a/src/egl/main/eglimage.c b/src/egl/main/eglimage.c
index 64bf7f2bfe9..73d4e85b82e 100644
--- a/src/egl/main/eglimage.c
+++ b/src/egl/main/eglimage.c
@@ -46,6 +46,18 @@ _eglParseKHRImageAttribs(_EGLImageAttribs *attrs, _EGLDisplay *disp,
attrs->ImagePreserved = val;
break;
+ case EGL_GL_COLORSPACE_KHR:
+ if (!disp->Extensions.EXT_image_gl_colorspace)
+ return EGL_BAD_PARAMETER;
+
+ if (val != EGL_GL_COLORSPACE_SRGB_KHR &&
+ val != EGL_GL_COLORSPACE_LINEAR_KHR &&
+ val != EGL_GL_COLORSPACE_DEFAULT_EXT)
+ return EGL_BAD_PARAMETER;
+
+ attrs->GLColorspace = val;
+ break;
+
case EGL_GL_TEXTURE_LEVEL_KHR:
if (!disp->Extensions.KHR_gl_texture_2D_image)
return EGL_BAD_PARAMETER;
@@ -285,6 +297,8 @@ _eglParseImageAttribList(_EGLImageAttribs *attrs, _EGLDisplay *disp,
memset(attrs, 0, sizeof(*attrs));
+ attrs->GLColorspace = EGL_GL_COLORSPACE_DEFAULT_EXT;
+
if (!attrib_list)
return EGL_TRUE;
diff --git a/src/egl/main/eglimage.h b/src/egl/main/eglimage.h
index 9837f05dad1..fc02d7a265c 100644
--- a/src/egl/main/eglimage.h
+++ b/src/egl/main/eglimage.h
@@ -80,6 +80,9 @@ struct _egl_image_attribs
struct _egl_image_attrib_int DMABufChromaHorizontalSiting;
struct _egl_image_attrib_int DMABufChromaVerticalSiting;
+ /* EGL_EXT_image_gl_colorspace */
+ EGLint GLColorspace;
+
/* EGL_EXT_protected_surface */
EGLBoolean ProtectedContent;
};
--
2.17.1
@@ -0,0 +1,35 @@
From 04993e64906c7481f877dd6775a935259ea2d5b9 Mon Sep 17 00:00:00 2001
From: Brendan King <Brendan.King@imgtec.com>
Date: Mon, 24 Jun 2019 09:35:39 +0100
Subject: [PATCH 40/50] meson: force C++ 2011 for "thread_local"
For some combinations of Meson and the GNU C++ compiler, Meson does
not add '-std=c++11' to the command line arguments, resulting in
compilation errors, due to the use of the "thread_local" keyword (a
C++ 2011 feature). If the C++ compiler doesn't understand the
"thread_local" keyword by default, add '-std=c++11' to the compiler
command line arguments.
---
meson.build | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/meson.build b/meson.build
index 56340b8ef3b..3c55447b6eb 100644
--- a/meson.build
+++ b/meson.build
@@ -32,6 +32,12 @@ project(
cc = meson.get_compiler('c')
cpp = meson.get_compiler('cpp')
+if not cpp.compiles('thread_local int x = 0;', name : 'thread_local')
+ if cpp.has_argument('-std=c++11')
+ add_project_arguments('-std=c++11', language : 'cpp')
+ endif
+endif
+
null_dep = dependency('', required : false)
if get_option('layout') != 'mirror'
--
2.17.1
@@ -0,0 +1,785 @@
From dc031ad65131ed5de6e8dd8db21d49c0185d6e0b Mon Sep 17 00:00:00 2001
From: Luigi Santivetti <luigi.santivetti@imgtec.com>
Date: Wed, 19 Jun 2019 16:36:06 +0100
Subject: [PATCH 41/50] dri2: add support for swap intervals other than 1
Before this change, the swap interval was fixed at 1, with page flips
scheduled on the next vblank. This change allows any swap interval
between 0 and 10 to be set.
An additional thread is created, so as not to rely on the application
polling for previously scheduled drm events (be it a flip or a vblank).
Instead, each call to swap buffers made by the application will be
queued, and consumed asynchronously by the additional thread. This
ensures that drm events will be handled as soon as possible,
regardless of the timing of subsequent calls to swap buffers.
Change-Id: If7c0495df7ddfaa08583a14f820c46e1b97da788
Signed-off-by: Luigi Santivetti <luigi.santivetti@imgtec.com>
---
src/egl/drivers/dri2/egl_dri2.h | 34 +-
src/egl/drivers/dri2/platform_null.c | 541 +++++++++++++++++++++++----
2 files changed, 497 insertions(+), 78 deletions(-)
diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h
index 95435b9ee12..2fdba4bd62e 100644
--- a/src/egl/drivers/dri2/egl_dri2.h
+++ b/src/egl/drivers/dri2/egl_dri2.h
@@ -324,6 +324,23 @@ struct tpl_swap_queue_elem
};
#endif
+#ifdef HAVE_NULL_PLATFORM
+struct swap_queue_elem
+{
+ uint32_t swap_interval;
+ uint32_t back_id;
+ uint32_t fb_id;
+};
+
+enum {
+ SWAP_IDLE,
+ SWAP_FLIP,
+ SWAP_VBLANK,
+ SWAP_POLL,
+ SWAP_ERROR,
+};
+#endif
+
struct dri2_egl_surface
{
_EGLSurface base;
@@ -362,13 +379,18 @@ struct dri2_egl_surface
#ifdef HAVE_TIZEN_PLATFORM
tpl_surface_t *tpl_surf;
bool reset;
+ struct tpl_swap_queue_elem swap_queue[DRI2_SURFACE_NUM_COLOR_BUFFERS];
+#endif
+#if defined(HAVE_TIZEN_PLATFORM) || defined(HAVE_NULL_PLATFORM)
/*
* Protects swap_queue_idx_head, swap_queue_idx_tail and
* color_buffers.locked.
*/
pthread_mutex_t mutex;
pthread_cond_t swap_queue_cond;
- struct tpl_swap_queue_elem swap_queue[DRI2_SURFACE_NUM_COLOR_BUFFERS];
+#if defined(HAVE_NULL_PLATFORM)
+ pthread_cond_t swap_unlock_buffer_cond;
+#endif
int swap_queue_idx_head;
int swap_queue_idx_tail;
pthread_t swap_queue_processor;
@@ -404,7 +426,7 @@ struct dri2_egl_surface
#endif
bool locked;
int age;
- } color_buffers[4], *back, *current;
+ } color_buffers[DRI2_SURFACE_NUM_COLOR_BUFFERS], *back, *current;
#endif
#ifdef HAVE_ANDROID_PLATFORM
@@ -433,7 +455,13 @@ struct dri2_egl_surface
#endif
#ifdef HAVE_NULL_PLATFORM
- uint32_t front_fb_id;
+ uint32_t front_fb_id;
+ struct swap_queue_elem swap_queue[DRI2_SURFACE_NUM_COLOR_BUFFERS];
+ struct swap_queue_elem *swap_data;
+ int swap_state;
+ bool mutex_init;
+ bool cond_init;
+ bool cond_init_unlock_buffer;
#endif
int out_fence_fd;
diff --git a/src/egl/drivers/dri2/platform_null.c b/src/egl/drivers/dri2/platform_null.c
index 2b3b08cc259..0b20aef9e4d 100644
--- a/src/egl/drivers/dri2/platform_null.c
+++ b/src/egl/drivers/dri2/platform_null.c
@@ -31,6 +31,7 @@
#include <drm_fourcc.h>
#include <fcntl.h>
#include <poll.h>
+#include <pthread.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
@@ -58,6 +59,17 @@ struct object_property {
uint64_t prop_value;
};
+static inline
+uint32_t get_back_buffer_id(struct dri2_egl_surface *dri2_surf)
+{
+ uintptr_t offset = ((uintptr_t) dri2_surf->back) -
+ ((uintptr_t) &dri2_surf->color_buffers[0]);
+
+ assert(dri2_surf->back && !(offset >> 32));
+
+ return (uint32_t) (offset / sizeof(dri2_surf->color_buffers[0]));
+}
+
#define object_property_set_named(output, object_type, prop_name, value) \
{ \
.object_id = (output)->object_type##_id, \
@@ -176,36 +188,6 @@ property_id_get_for_name(drmModePropertyRes **prop_res, const char *prop_name)
return 0;
}
-static void
-flip_handler(int fd, unsigned int sequence, unsigned int tv_sec,
- unsigned int tv_usec, void *user_data)
-{
- bool *plocked = user_data;
-
- if (plocked)
- *plocked = false;
-}
-
-static bool
-flip_process(int fd)
-{
- static drmEventContext evctx =
- {.version = 2, .page_flip_handler = flip_handler};
- struct pollfd pfd = {.fd = fd, .events = POLLIN};
- int ret;
-
- do {
- ret = poll(&pfd, 1, -1);
- } while (ret > 0 && pfd.revents != pfd.events);
-
- if (ret <= 0)
- return false;
-
- drmHandleEvent(fd, &evctx);
-
- return true;
-}
-
static drmModePropertyRes **
object_get_property_resources(int fd, uint32_t object_id, uint32_t object_type)
{
@@ -495,6 +477,113 @@ display_output_atomic_modeset(int fd, struct display_output *output, uint32_t fb
DRM_MODE_ATOMIC_ALLOW_MODESET, NULL);
}
+static void
+swap_enqueue_data(struct dri2_egl_surface *dri2_surf, uint32_t back_id,
+ uint32_t interval)
+{
+ struct swap_queue_elem *swap_data;
+
+ pthread_mutex_lock(&dri2_surf->mutex);
+ swap_data = &dri2_surf->swap_queue[dri2_surf->swap_queue_idx_tail];
+ swap_data->swap_interval = interval;
+ swap_data->fb_id = dri2_surf->back->fb_id;
+ swap_data->back_id = back_id;
+
+ dri2_surf->swap_queue_idx_tail++;
+ dri2_surf->swap_queue_idx_tail %= ARRAY_SIZE(dri2_surf->swap_queue);
+
+ /* Notify the swap thread there is new work to do */
+ pthread_cond_signal(&dri2_surf->swap_queue_cond);
+ pthread_mutex_unlock(&dri2_surf->mutex);
+}
+
+static void
+swap_dequeue_data_start(struct dri2_egl_surface *dri2_surf)
+{
+ pthread_mutex_lock(&dri2_surf->mutex);
+ while (dri2_surf->swap_queue_idx_head == dri2_surf->swap_queue_idx_tail)
+ pthread_cond_wait(&dri2_surf->swap_queue_cond, &dri2_surf->mutex);
+
+ dri2_surf->swap_data =
+ &dri2_surf->swap_queue[dri2_surf->swap_queue_idx_head];
+ pthread_mutex_unlock(&dri2_surf->mutex);
+}
+
+static void
+swap_dequeue_data_finish(struct dri2_egl_surface *dri2_surf)
+{
+ pthread_mutex_lock(&dri2_surf->mutex);
+
+ if (dri2_surf->current)
+ dri2_surf->current->locked = false;
+
+ dri2_surf->current =
+ &dri2_surf->color_buffers[dri2_surf->swap_data->back_id];
+ dri2_surf->swap_state = SWAP_IDLE;
+
+ dri2_surf->swap_queue_idx_head++;
+ dri2_surf->swap_queue_idx_head %= ARRAY_SIZE(dri2_surf->swap_queue);
+
+ /* Notify get_back_bo that a buffer has become available */
+ pthread_cond_signal(&dri2_surf->swap_unlock_buffer_cond);
+ pthread_mutex_unlock(&dri2_surf->mutex);
+}
+
+static void
+flip_handler(int fd, unsigned int sequence, unsigned int tv_sec,
+ unsigned int tv_usec, void *flip_data)
+{
+ struct dri2_egl_surface *dri2_surf = flip_data;
+
+ (void) tv_sec;
+ (void) tv_usec;
+ (void) sequence;
+
+ /* Ultimate queueing ops */
+ swap_dequeue_data_finish(dri2_surf);
+}
+
+static void
+vblank_handler(int fd, unsigned int sequence, unsigned int tv_sec,
+ unsigned int tv_usec, void *vblank_data)
+{
+ struct dri2_egl_surface *dri2_surf = vblank_data;
+
+ (void) tv_sec;
+ (void) tv_usec;
+ (void) sequence;
+
+ dri2_surf->swap_state = SWAP_FLIP;
+}
+
+static int
+drm_event_process(int fd)
+{
+ static drmEventContext evctx = {
+ .version = 2,
+ .page_flip_handler = flip_handler,
+ .vblank_handler = vblank_handler
+ };
+ struct pollfd pfd = {.fd = fd, .events = POLLIN};
+ int ret;
+
+ do {
+ ret = poll(&pfd, 1, -1);
+ } while (ret > 0 && pfd.revents != pfd.events);
+
+ if (ret <= 0)
+ /* Man says:
+ *
+ * On error, -1 is returned, and errno is set to indicate the
+ * cause of the error.
+ */
+ return -1;
+
+ drmHandleEvent(fd, &evctx);
+
+ return 0;
+}
+
static bool
display_output_init(int fd, struct display_output *output, bool use_atomic)
{
@@ -571,10 +660,46 @@ static int
display_output_flip(int fd, struct display_output *output, uint32_t fb_id,
uint32_t flags, void *flip_data)
{
- if (output->atomic_state)
- return display_output_atomic_flip(fd, output, fb_id, flags, flip_data);
+ int err;
+
+ do {
+ if (output->atomic_state)
+ err = display_output_atomic_flip(fd, output, fb_id, flags, flip_data);
+ else
+ err = drmModePageFlip(fd, output->crtc_id, fb_id, flags, flip_data);
+ } while (err == -EBUSY);
+
+ return err;
+}
+
+static int
+display_request_vblank(int fd, uint32_t target_frame, uint32_t flags,
+ void *vblank_data)
+{
+ drmVBlank vblank = {
+ .request = {
+ .type = flags,
+ .sequence = target_frame,
+ .signal = (unsigned long)vblank_data,
+ }
+ };
+
+ return drmWaitVBlank(fd, &vblank);
+}
+
+static int
+display_get_vblank_sequence(int fd, uint32_t *current_vblank_out)
+{
+ drmVBlank vblank = { .request = { .type = DRM_VBLANK_RELATIVE } };
+ int err;
+
+ err = drmWaitVBlank(fd, &vblank);
+ if (err)
+ return err;
- return drmModePageFlip(fd, output->crtc_id, fb_id, flags, flip_data);
+ *current_vblank_out = vblank.reply.sequence;
+
+ return 0;
}
static int
@@ -587,6 +712,213 @@ display_output_modeset(int fd, struct display_output *output, uint32_t fb_id)
&output->connector_id, 1, &output->mode);
}
+static int
+swap_idle_get_target_frame(struct dri2_egl_surface *dri2_surf,
+ uint32_t *current_vblank_out, uint32_t *target_frame_out)
+{
+ struct dri2_egl_display *dri2_dpy =
+ dri2_egl_display(dri2_surf->base.Resource.Display);
+ int err;
+
+ /* For intarvals bigger than 1, always update current_vblank. The
+ * spec isn't fully clear, nonetheless page 25 and 26 of the PDF of the
+ * EGL 1.5 spec say:
+ *
+ * "[the parameter interval] indicates the number of swap intervals
+ * that will elapse before a buffer swap takes place after calling
+ * eglSwapBuffers."
+ *
+ * We need to guarantee that the target frame is always ahead of the
+ * current vblank by the number of intervals set at the time swapBuffer
+ * is called. For intervals of 1 or 0, we don't need a target frame.
+ */
+ err = display_get_vblank_sequence(dri2_dpy->fd, current_vblank_out);
+ if (err)
+ return err;
+
+ assert(dri2_surf->swap_data->swap_interval > 0);
+
+ /* -1 accounts for vsync locked flip, so get a vblank one frame earlier */
+ *target_frame_out =
+ *current_vblank_out + dri2_surf->swap_data->swap_interval - 1;
+
+ return 0;
+}
+
+static int
+swap_idle_state_transition(struct dri2_egl_surface *dri2_surf,
+ uint32_t *target_frame_out)
+{
+ uint32_t current_vblank = 0;
+ uint32_t target_frame = 0;
+ int err;
+
+ /* update dri2_surf->swap_data */
+ swap_dequeue_data_start(dri2_surf);
+
+ /* update next target frame */
+ if (dri2_surf->swap_data->swap_interval > 1) {
+ err = swap_idle_get_target_frame(dri2_surf, &current_vblank,
+ &target_frame);
+ if (err) {
+ dri2_surf->swap_state = SWAP_ERROR;
+ return err;
+ }
+ }
+
+ dri2_surf->swap_state =
+ target_frame <= current_vblank ? SWAP_FLIP : SWAP_VBLANK;
+ *target_frame_out = target_frame;
+
+ return 0;
+}
+
+static int
+swap_vblank_state_transition(struct dri2_egl_surface *dri2_surf,
+ uint32_t target_frame)
+{
+ struct dri2_egl_display *dri2_dpy =
+ dri2_egl_display(dri2_surf->base.Resource.Display);
+ uint32_t flags = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT;
+ int err;
+
+ err = display_request_vblank(dri2_dpy->fd, target_frame,
+ flags, dri2_surf);
+ if (err) {
+ dri2_surf->swap_state = SWAP_ERROR;
+ return err;
+ }
+
+ dri2_surf->swap_state = SWAP_POLL;
+
+ return 0;
+}
+
+static int
+swap_flip_state_transition(struct dri2_egl_surface *dri2_surf)
+{
+ struct dri2_egl_display *dri2_dpy =
+ dri2_egl_display(dri2_surf->base.Resource.Display);
+ uint32_t flags;
+ int err;
+
+ flags = DRM_MODE_PAGE_FLIP_EVENT;
+ if (dri2_surf->swap_data->swap_interval == 0) {
+ assert(!dri2_dpy->atomic_enabled);
+ flags |= DRM_MODE_PAGE_FLIP_ASYNC;
+ }
+
+ err = display_output_flip(dri2_dpy->fd, &dri2_dpy->output,
+ dri2_surf->swap_data->fb_id, flags, dri2_surf);
+ if (err) {
+ dri2_surf->swap_state = SWAP_ERROR;
+ return err;
+ }
+
+ dri2_surf->swap_state = SWAP_POLL;
+
+ return 0;
+}
+
+static int
+swap_poll_state_transition(struct dri2_egl_surface *dri2_surf)
+{
+ struct dri2_egl_display *dri2_dpy =
+ dri2_egl_display(dri2_surf->base.Resource.Display);
+ int err;
+
+ /* dri2_surf->swap_state is being set inside the handler */
+ err = drm_event_process(dri2_dpy->fd);
+ if (err) {
+ dri2_surf->swap_state = SWAP_ERROR;
+ return err;
+ }
+
+ return 0;
+}
+
+static inline void
+swap_error_print_message(const int state, const int err)
+{
+ switch (state) {
+ case SWAP_IDLE:
+ _eglLog(_EGL_WARNING,
+ "failed to get a target frame (err=%d)", err);
+ break;
+ case SWAP_FLIP:
+ _eglLog(_EGL_WARNING,
+ "failed to schedule a pageflip (err=%d)", err);
+ break;
+ case SWAP_VBLANK:
+ _eglLog(_EGL_WARNING,
+ "failed to request a vblank event (err=%d)", err);
+ break;
+ case SWAP_POLL:
+ _eglLog(_EGL_WARNING,
+ "failed to poll for drm event (err=%d)", err);
+ break;
+ case SWAP_ERROR:
+ _eglLog(_EGL_WARNING,
+ "failed to swap buffers, unknown swap state");
+ break;
+ default:
+ _eglLog(_EGL_FATAL,
+ "failed to swap buffers (unknown error)");
+ };
+}
+
+static void
+swap_error_state_handler(struct dri2_egl_surface *dri2_surf,
+ int state, int err)
+{
+ static bool do_log = true;
+
+ if (do_log) {
+ swap_error_print_message(state, err);
+ do_log = false;
+ }
+
+ swap_dequeue_data_finish(dri2_surf);
+}
+
+static void *
+swap_queue_processor_worker(void *data)
+{
+ struct dri2_egl_surface *dri2_surf = data;
+ int state = SWAP_IDLE, err = SWAP_ERROR;
+ uint32_t target_frame = 0;
+
+ assert(dri2_surf->swap_state == SWAP_IDLE);
+
+ while (1) {
+ switch (dri2_surf->swap_state) {
+ case SWAP_IDLE:
+ err = swap_idle_state_transition(dri2_surf, &target_frame);
+ break;
+ case SWAP_VBLANK:
+ err = swap_vblank_state_transition(dri2_surf, target_frame);
+ break;
+ case SWAP_FLIP:
+ err = swap_flip_state_transition(dri2_surf);
+ break;
+ case SWAP_POLL:
+ err = swap_poll_state_transition(dri2_surf);
+ break;
+ case SWAP_ERROR:
+ swap_error_state_handler(dri2_surf, state, err);
+ break;
+ default:
+ dri2_surf->swap_state = SWAP_ERROR;
+ break;
+ }
+
+ if (!err)
+ state = dri2_surf->swap_state;
+ }
+
+ return NULL;
+}
+
static bool
add_fb_for_dri_image(struct dri2_egl_display *dri2_dpy, __DRIimage *image,
uint32_t *fb_id_out)
@@ -651,15 +983,18 @@ get_back_bo(struct dri2_egl_surface *dri2_surf)
struct dri2_egl_display *dri2_dpy =
dri2_egl_display(dri2_surf->base.Resource.Display);
- if (!dri2_surf->back) {
+ pthread_mutex_lock(&dri2_surf->mutex);
+ while (!dri2_surf->back) {
for (unsigned i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
if (!dri2_surf->color_buffers[i].locked) {
dri2_surf->back = &dri2_surf->color_buffers[i];
break;
}
}
+
+ /* Wait for a flip to get a buffer off the screen and unlock it */
if (!dri2_surf->back)
- return false;
+ pthread_cond_wait(&dri2_surf->swap_unlock_buffer_cond, &dri2_surf->mutex);
}
if (!dri2_surf->back->dri_image) {
@@ -671,19 +1006,23 @@ get_back_bo(struct dri2_egl_surface *dri2_surf)
__DRI_IMAGE_USE_SCANOUT,
NULL);
if (!dri2_surf->back->dri_image)
- return false;
+ goto err_unlock;
}
if (!dri2_surf->back->fb_id) {
if (!add_fb_for_dri_image(dri2_dpy, dri2_surf->back->dri_image,
- &dri2_surf->back->fb_id)) {
- return false;
- }
+ &dri2_surf->back->fb_id))
+ goto err_unlock;
}
dri2_surf->back->locked = 1;
+ pthread_mutex_unlock(&dri2_surf->mutex);
return true;
+
+err_unlock:
+ pthread_mutex_unlock(&dri2_surf->mutex);
+ return false;
}
static _EGLSurface *
@@ -770,6 +1109,26 @@ dri2_null_create_window_surface(_EGLDisplay *disp, _EGLConfig *config,
dri2_surf->base.Width = dri2_dpy->output.mode.hdisplay;
dri2_surf->base.Height = dri2_dpy->output.mode.vdisplay;
+ /* After the dri2_surf is created, init thread's data */
+ dri2_surf->mutex_init = !pthread_mutex_init(&dri2_surf->mutex, NULL);
+ if (!dri2_surf->mutex_init) {
+ _eglError(EGL_BAD_ALLOC, "failed to init swap thread mutex");
+ goto err_destroy_surface;
+ }
+
+ dri2_surf->cond_init = !pthread_cond_init(&dri2_surf->swap_queue_cond, NULL);
+ if (!dri2_surf->cond_init) {
+ _eglError(EGL_BAD_ALLOC, "failed to init swap queue condition");
+ goto err_destroy_surface;
+ }
+
+ dri2_surf->cond_init_unlock_buffer =
+ !pthread_cond_init(&dri2_surf->swap_unlock_buffer_cond, NULL);
+ if (!dri2_surf->cond_init_unlock_buffer) {
+ _eglError(EGL_BAD_ALLOC, "failed to init swap buffer unlock condition");
+ goto err_destroy_surface;
+ }
+
if (!get_front_bo(dri2_surf)) {
_eglError(EGL_BAD_NATIVE_WINDOW, "window get buffer");
goto err_destroy_surface;
@@ -783,6 +1142,14 @@ dri2_null_create_window_surface(_EGLDisplay *disp, _EGLConfig *config,
}
dri2_dpy->output.in_use = true;
+ dri2_surf->swap_state = SWAP_IDLE;
+
+ err = pthread_create(&dri2_surf->swap_queue_processor, NULL,
+ swap_queue_processor_worker, dri2_surf);
+ if (err) {
+ _eglError(EGL_BAD_ALLOC, "failed to create swap thread");
+ goto err_destroy_surface;
+ }
return surf;
@@ -808,8 +1175,27 @@ dri2_null_destroy_surface(_EGLDisplay *disp, _EGLSurface *surf)
/* If there's a current surface then a page flip has been performed, so make
* sure we process the flip event.
*/
- if (dri2_surf->current)
- flip_process(dri2_dpy->fd);
+ if (dri2_surf->swap_queue_processor) {
+ pthread_mutex_lock(&dri2_surf->mutex);
+
+ /* Wait for any outstanding swaps to complete */
+ while (dri2_surf->swap_queue_idx_head != dri2_surf->swap_queue_idx_tail)
+ pthread_cond_wait(&dri2_surf->swap_unlock_buffer_cond,
+ &dri2_surf->mutex);
+
+ pthread_mutex_unlock(&dri2_surf->mutex);
+ pthread_cancel(dri2_surf->swap_queue_processor);
+ pthread_join(dri2_surf->swap_queue_processor, NULL);
+ }
+
+ if (dri2_surf->cond_init)
+ pthread_cond_destroy(&dri2_surf->swap_queue_cond);
+
+ if (dri2_surf->cond_init_unlock_buffer)
+ pthread_cond_destroy(&dri2_surf->swap_unlock_buffer_cond);
+
+ if (dri2_surf->mutex_init)
+ pthread_mutex_destroy(&dri2_surf->mutex);
if (dri2_surf->front)
dri2_dpy->image->destroyImage(dri2_surf->front);
@@ -837,9 +1223,7 @@ dri2_null_swap_buffers(_EGLDisplay *disp, _EGLSurface *draw)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
- bool *plocked = NULL;
- uint32_t flags;
- int err;
+ uint32_t back_id;
if (dri2_surf->base.Type != EGL_WINDOW_BIT)
return EGL_TRUE;
@@ -858,34 +1242,13 @@ dri2_null_swap_buffers(_EGLDisplay *disp, _EGLSurface *draw)
dri2_flush_drawable_for_swapbuffers(disp, draw);
dri2_dpy->flush->invalidate(dri2_surf->dri_drawable);
- if (dri2_surf->current) {
- /* Wait for the previous flip to happen so the next one can be queued */
- if (!flip_process(dri2_dpy->fd)) {
- _eglError(EGL_BAD_NATIVE_WINDOW, "dri2_null_swap_buffers process");
- return EGL_FALSE;
- }
+ back_id = get_back_buffer_id(dri2_surf);
+ assert(dri2_surf->back == &dri2_surf->color_buffers[back_id]);
- plocked = &dri2_surf->current->locked;
- }
-
- flags = DRM_MODE_PAGE_FLIP_EVENT;
- if (draw->SwapInterval == 0)
- flags |= DRM_MODE_PAGE_FLIP_ASYNC;
-
- do {
- err = display_output_flip(dri2_dpy->fd, &dri2_dpy->output,
- dri2_surf->back->fb_id, flags, plocked);
- } while (err == -EBUSY);
-
- if (err) {
- _eglError(EGL_BAD_NATIVE_WINDOW, "dri2_null_swap_buffers flip");
- dri2_surf->back->locked = false;
- dri2_surf->back = NULL;
- return EGL_FALSE;
- }
+ swap_enqueue_data(dri2_surf, back_id, draw->SwapInterval);
+ /* This back buffer is tracked in the swap_data, safe to drop it now */
dri2_surf->back->age = 1;
- dri2_surf->current = dri2_surf->back;
dri2_surf->back = NULL;
return EGL_TRUE;
@@ -904,11 +1267,20 @@ dri2_null_query_buffer_age(_EGLDisplay *disp, _EGLSurface *surface)
return dri2_surf->back->age;
}
+static EGLBoolean
+dri2_null_swap_interval(_EGLDisplay *dpy, _EGLSurface *draw, EGLint interval)
+{
+ _eglLog(_EGL_DEBUG, "DRI2: set swap interval to %d", interval);
+ draw->SwapInterval = interval;
+ return EGL_TRUE;
+}
+
static struct dri2_egl_display_vtbl dri2_null_display_vtbl = {
.create_window_surface = dri2_null_create_window_surface,
.create_pbuffer_surface = dri2_null_create_pbuffer_surface,
.destroy_surface = dri2_null_destroy_surface,
.create_image = dri2_create_image_khr,
+ .swap_interval = dri2_null_swap_interval,
.swap_buffers = dri2_null_swap_buffers,
.query_buffer_age = dri2_null_query_buffer_age,
.get_dri_drawable = dri2_surface_get_dri_drawable,
@@ -1059,12 +1431,35 @@ dri2_null_add_configs_for_formats(_EGLDisplay *disp)
return count != 0;
}
+static void
+dri2_null_setup_swap_interval(_EGLDisplay *disp)
+{
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+ const int swap_max_interval = 10; /* Arbitrary max value */
+ uint64_t value;
+ int err;
+
+ dri2_setup_swap_interval(disp, swap_max_interval);
+
+ err = drmGetCap(dri2_dpy->fd, DRM_CAP_ASYNC_PAGE_FLIP, &value);
+ if (err || value == 0)
+ dri2_dpy->min_swap_interval = 1;
+
+ /**
+ * drm/atomic: Reject FLIP_ASYNC unconditionally
+ * upstream f2cbda2dba11de868759cae9c0d2bab5b8411406
+ *
+ * Only allow swap interval 0 for legacy DRM/KMS and let
+ * the app be aware that swap interval is clamped to 1.
+ */
+ if (dri2_dpy->atomic_enabled)
+ dri2_dpy->min_swap_interval = 1;
+}
EGLBoolean
dri2_initialize_null(_EGLDisplay *disp)
{
struct dri2_egl_display *dri2_dpy;
- uint64_t value;
int err;
dri2_dpy = calloc(1, sizeof(*dri2_dpy));
@@ -1111,11 +1506,7 @@ dri2_initialize_null(_EGLDisplay *disp)
}
dri2_setup_screen(disp);
- dri2_setup_swap_interval(disp, 1);
-
- err = drmGetCap(dri2_dpy->fd, DRM_CAP_ASYNC_PAGE_FLIP, &value);
- if (err || value == 0)
- dri2_dpy->min_swap_interval = 1;
+ dri2_null_setup_swap_interval(disp);
if (dri2_dpy->image->base.version < NULL_IMAGE_EXTENSION_VERSION_MIN) {
_eglError(EGL_NOT_INITIALIZED, "image extension version too old");
--
2.17.1
@@ -0,0 +1,214 @@
From 58d5fa48cf14a930322b5645dd5e26c8b546f394 Mon Sep 17 00:00:00 2001
From: Silvestrs Timofejevs <silvestrs.timofejevs@imgtec.com>
Date: Mon, 2 Sep 2019 09:32:01 +0100
Subject: [PATCH 42/50] null_platform: add support for explicit synchronisation
This change adds support for the 'in' fence, the 'out' fence will
potentially be added in subsequent optimisation changes.
Explicit synchronisation KMS 'in' and 'out' properties have been first
added in Linux kernel 4.10 as an additional feature to the atomic mode
setting.
9626014258a5957ff120b3987ee72decdbe0c798 - 'in' property
beaf5af48034c9e2ebb8b2b1fb12dc4d8aeba99e - 'out' property
Unlike many other features - it doesn't have an in kernel capability
flag, so the support for it can be tested in the following way:
KMS creates an additional set of properties when the version of kernel
is new enough to support it ('in' and 'out' fence properties). When
the user-space requests all the properties from the kernel via
drmModeObjectGetProperties it is possible to determine whether the
required property is supported by the kernel or not.
The explicit synchronisation is used when available, otherwise the
implicit sync model is used instead. If explicit synchronisation is
available but 'in' fence failed to attach in KMS, the system falls
back to the implicit synchronisation model.
egl_dri2.c already creates the GPU 'out' fence that is then used by
the null_platform as KMS 'in' fence. null_platform takes owenership of
this fence fd during the swap buffers operation, at which point the
fence fd is no longer available to be used outside of null_platform.
EGL_LOG_LEVEL=debug should give some useful information in case of
explicit synchronisation failure. As mentioned above, this failure
will result in implicit synchronisation being used instead.
Change-Id: Ib9c4a0bc3ea1b21192ee37909d7580d6b7b366ec
---
src/egl/drivers/dri2/egl_dri2.h | 2 +
src/egl/drivers/dri2/platform_null.c | 77 +++++++++++++++++++++++++++-
2 files changed, 77 insertions(+), 2 deletions(-)
diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h
index 2fdba4bd62e..3d5c9adb4f3 100644
--- a/src/egl/drivers/dri2/egl_dri2.h
+++ b/src/egl/drivers/dri2/egl_dri2.h
@@ -100,6 +100,7 @@ struct wl_buffer;
#ifdef HAVE_NULL_PLATFORM
struct display_output {
bool in_use;
+ bool in_fence_supported;
uint32_t connector_id;
drmModePropertyRes **connector_prop_res;
uint32_t crtc_id;
@@ -330,6 +331,7 @@ struct swap_queue_elem
uint32_t swap_interval;
uint32_t back_id;
uint32_t fb_id;
+ int kms_in_fence_fd;
};
enum {
diff --git a/src/egl/drivers/dri2/platform_null.c b/src/egl/drivers/dri2/platform_null.c
index 0b20aef9e4d..c25ae0b2a04 100644
--- a/src/egl/drivers/dri2/platform_null.c
+++ b/src/egl/drivers/dri2/platform_null.c
@@ -401,6 +401,9 @@ display_output_atomic_init(int fd, struct display_output *output)
if (!output->atomic_state)
goto err_destroy_mode_prop_blob;
+ if (property_id_get_for_name(plane_prop_res, "IN_FENCE_FD"))
+ output->in_fence_supported = true;
+
output->connector_prop_res = connector_prop_res;
output->crtc_prop_res = crtc_prop_res;
output->plane_prop_res = plane_prop_res;
@@ -418,6 +421,53 @@ err_free_connector_prop_res:
return false;
}
+static void
+display_output_atomic_add_in_fence(struct display_output *output,
+ int kms_in_fence_fd)
+{
+ const struct object_property obj_sync_props[] = {
+ object_property_set_named(output, plane, "IN_FENCE_FD", kms_in_fence_fd),
+ };
+ int err;
+
+ /* Explicit synchronisation is not being used */
+ if (kms_in_fence_fd < 0)
+ return;
+
+ err = atomic_state_add_object_properties(output->atomic_state,
+ obj_sync_props,
+ ARRAY_SIZE(obj_sync_props));
+ if (err)
+ _eglLog(_EGL_DEBUG, "%s: failed to add props ERR = %d", __func__, err);
+}
+
+static void
+atomic_claim_in_fence_fd(struct dri2_egl_surface *dri2_surf,
+ struct swap_queue_elem *swap_data)
+{
+ /* Explicit synchronisation is not being used */
+ if (!dri2_surf->enable_out_fence)
+ return;
+
+ if (dri2_surf->out_fence_fd < 0) {
+ _eglLog(_EGL_DEBUG, "%s: missing 'in' fence", __func__);
+ return;
+ }
+
+ /* Take ownership of the fd */
+ swap_data->kms_in_fence_fd = dri2_surf->out_fence_fd;
+ dri2_surf->out_fence_fd = -1;
+}
+
+static void
+atomic_relinquish_in_fence_fd(struct dri2_egl_surface *dri2_surf,
+ struct swap_queue_elem *swap_data)
+{
+ /* KMS is now in control of the fence (post drmModeAtomicCommit) */
+ close(swap_data->kms_in_fence_fd);
+ swap_data->kms_in_fence_fd = -1;
+}
+
static int
display_output_atomic_flip(int fd, struct display_output *output, uint32_t fb_id,
uint32_t flags, void *flip_data)
@@ -425,6 +475,8 @@ display_output_atomic_flip(int fd, struct display_output *output, uint32_t fb_id
const struct object_property obj_props[] = {
object_property_set_named(output, plane, "FB_ID", fb_id),
};
+ struct dri2_egl_surface *dri2_surf = flip_data;
+ struct swap_queue_elem *swap_data = dri2_surf->swap_data;
int err;
/* Reset atomic state */
@@ -435,13 +487,19 @@ display_output_atomic_flip(int fd, struct display_output *output, uint32_t fb_id
if (err)
return err;
+ display_output_atomic_add_in_fence(output, swap_data->kms_in_fence_fd);
+
/*
* Don't block - like drmModePageFlip, drmModeAtomicCommit will return
* -EBUSY if the commit can't be queued in the kernel.
*/
flags |= DRM_MODE_ATOMIC_NONBLOCK;
- return drmModeAtomicCommit(fd, output->atomic_state, flags, flip_data);
+ err = drmModeAtomicCommit(fd, output->atomic_state, flags, flip_data);
+
+ atomic_relinquish_in_fence_fd(dri2_surf, swap_data);
+
+ return err;
}
static int
@@ -489,6 +547,8 @@ swap_enqueue_data(struct dri2_egl_surface *dri2_surf, uint32_t back_id,
swap_data->fb_id = dri2_surf->back->fb_id;
swap_data->back_id = back_id;
+ atomic_claim_in_fence_fd(dri2_surf, swap_data);
+
dri2_surf->swap_queue_idx_tail++;
dri2_surf->swap_queue_idx_tail %= ARRAY_SIZE(dri2_surf->swap_queue);
@@ -1025,11 +1085,21 @@ err_unlock:
return false;
}
+static void surface_swap_queue_init(struct dri2_egl_surface *dri2_surf)
+{
+ struct swap_queue_elem *swap_queue = &dri2_surf->swap_queue[0];
+ const int num_el = ARRAY_SIZE(dri2_surf->swap_queue);
+
+ for (int i = 0; i < num_el; i++)
+ swap_queue[i].kms_in_fence_fd = -1;
+}
+
static _EGLSurface *
create_surface(_EGLDisplay *disp, _EGLConfig *config, EGLint type,
const EGLint *attrib_list)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+ struct display_output *output = &dri2_dpy->output;
struct dri2_egl_config *dri2_config = dri2_egl_config(config);
struct dri2_egl_surface *dri2_surf;
const __DRIconfig *dri_config;
@@ -1043,7 +1113,8 @@ create_surface(_EGLDisplay *disp, _EGLConfig *config, EGLint type,
}
surf = &dri2_surf->base;
- if (!dri2_init_surface(surf, disp, type, config, attrib_list, false, NULL))
+ if (!dri2_init_surface(surf, disp, type, config, attrib_list,
+ output->in_fence_supported, NULL))
goto err_free_surface;
dri_config = dri2_get_dri_config(dri2_config, type,
@@ -1066,6 +1137,8 @@ create_surface(_EGLDisplay *disp, _EGLConfig *config, EGLint type,
dri2_surf->format = dri2_null_formats[format_idx].dri_image_format;
+ surface_swap_queue_init(dri2_surf);
+
return surf;
err_free_surface:
--
2.17.1
@@ -0,0 +1,372 @@
From ac19d1d06ea2433fed707210f4433133a58a12dc Mon Sep 17 00:00:00 2001
From: Luigi Santivetti <luigi.santivetti@imgtec.com>
Date: Thu, 26 Sep 2019 13:32:15 +0100
Subject: [PATCH 43/50] dri2: add support for image modifiers
This change introduces support for image modifiers to platform_null. In
order for it to create an image with modifiers, it relies on libdrm to
populate all formats with associated modifiers supported by the display
for the primary drm plane in use.
drmModePopulateFormats() is added to the DRM api in a different change
and it is not upstream at present.
NOTES:
[1] IN_FORMATS blobs are available since kernel 4.14:
- db1689aa61bd1efb5ce9b896e7aa860a85b7f1b6
- https://patchwork.freedesktop.org/patch/168543
[2] for the record, in order to test this change, it was needed to:
- edit pvrdri_impl.c, as fbc relies on the BVNC for selecting which
algorithm and fourcc code are to be used. To sidestep this, include
img_drm_fourcc_internal.h instead of powervr/img_drm_fourcc.h and
manually add the list of g_auiAll_mods[]
- edit null_disp_drv.h, by removing DRM_FORMAT_MOD_LINEAR
- edit pvrrem_conv_sw_fbdc.c, log from decompress_fb() by building
with RFB_DEBUG=1, the log file is under /var/log
[3] the dri image->base.version threshold is 14.
- Unlike for platform_wayland, where no details were found regarding
why it's using 15
- dri_interface.h makes createImageWithModifiers available since
version 14
- dri/gbm_dri.c as an example checks for minimum version 14.
Change-Id: I0f7b030f6e1943690692674bf18daabfc153208a
Signed-off-by: Luigi Santivetti <luigi.santivetti@imgtec.com>
---
src/egl/drivers/dri2/egl_dri2.h | 6 +
src/egl/drivers/dri2/platform_null.c | 174 +++++++++++++++++++++++----
2 files changed, 159 insertions(+), 21 deletions(-)
diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h
index 3d5c9adb4f3..6ec9ee01885 100644
--- a/src/egl/drivers/dri2/egl_dri2.h
+++ b/src/egl/drivers/dri2/egl_dri2.h
@@ -110,6 +110,7 @@ struct display_output {
drmModeModeInfo mode;
uint32_t mode_blob_id;
unsigned formats;
+ drmModeFormats *in_formats;
drmModeAtomicReq *atomic_state;
};
#endif
@@ -274,6 +275,7 @@ struct dri2_egl_display
#ifdef HAVE_NULL_PLATFORM
bool atomic_enabled;
+ bool in_formats_enabled;
struct display_output output;
#endif
@@ -373,6 +375,10 @@ struct dri2_egl_surface
#if defined(HAVE_WAYLAND_PLATFORM) || defined(HAVE_NULL_PLATFORM)
int format;
#endif
+#if defined(HAVE_NULL_PLATFORM)
+ uint64_t *modifiers;
+ uint32_t count_modifiers;
+#endif
#ifdef HAVE_DRM_PLATFORM
struct gbm_dri_surface *gbm_surf;
diff --git a/src/egl/drivers/dri2/platform_null.c b/src/egl/drivers/dri2/platform_null.c
index c25ae0b2a04..701460dde4e 100644
--- a/src/egl/drivers/dri2/platform_null.c
+++ b/src/egl/drivers/dri2/platform_null.c
@@ -156,6 +156,18 @@ format_idx_get_from_drm_format(uint32_t drm_format)
return -1;
}
+static inline uint32_t
+blob_id_from_property_value(uint64_t prop_value)
+{
+ /* The KMS properties documetation, 01.org/linuxgraphics, says:
+ *
+ * For all property types except blob properties the value is a 64-bit
+ * unsigned integer.
+ */
+ assert(!(prop_value >> 32));
+ return (uint32_t) prop_value;
+}
+
static int
atomic_state_add_object_properties(drmModeAtomicReq *atomic_state,
const struct object_property *props,
@@ -644,14 +656,45 @@ drm_event_process(int fd)
return 0;
}
+static drmModeFormatsPtr
+plane_get_in_formats(int fd, drmModePlane *plane)
+{
+ drmModeFormatsPtr drm_mode_fmt = NULL;
+ drmModePropertyBlobRes *blob;
+ uint64_t prop_value;
+ uint32_t blob_id;
+ int err;
+
+ if (!plane)
+ return NULL;
+
+ err = !object_property_value_for_name(fd, plane->plane_id, DRM_MODE_OBJECT_PLANE,
+ "IN_FORMATS", &prop_value);
+ if (err)
+ return NULL;
+
+ blob_id = blob_id_from_property_value(prop_value);
+ blob = drmModeGetPropertyBlob(fd, blob_id);
+
+ err = drmModePopulateFormats(blob, &drm_mode_fmt);
+ if (err)
+ _eglLog(_EGL_WARNING,"failed to populate in_formats (%d)", err);
+
+ drmModeFreePropertyBlob(blob);
+
+ return drm_mode_fmt;
+}
+
static bool
-display_output_init(int fd, struct display_output *output, bool use_atomic)
+display_output_init(int fd, struct display_output *output, bool use_atomic,
+ bool prefer_in_formats, bool *in_formats_enabled_out)
{
drmModeRes *resources;
drmModeConnector *connector;
drmModeCrtc *crtc;
drmModePlane *plane;
unsigned mode_idx;
+ uint32_t drm_format;
resources = drmModeGetResources(fd);
if (!resources)
@@ -674,18 +717,41 @@ display_output_init(int fd, struct display_output *output, bool use_atomic)
goto err_free_plane;
output->mode = connector->modes[mode_idx];
+ assert(in_formats_enabled_out && !(*in_formats_enabled_out));
+
+ /* can in_formats be enabled for this display? */
+ if (prefer_in_formats) {
+ output->in_formats = plane_get_in_formats(fd, plane);
+ if (!output->in_formats) {
+ _eglLog(_EGL_WARNING,
+ "fallback to plane formats, no in_formats found");
+ } else if (output->in_formats->count != plane->count_formats) {
+ /* exit the process with generic failure 1 */
+ _eglLog(_EGL_FATAL,
+ "kernel bug: formats count mismatch, exit");
+ } else {
+ *in_formats_enabled_out = true;
+ }
+ }
+
/* Record the display supported formats */
for (unsigned i = 0; i < plane->count_formats; i++) {
int format_idx;
- format_idx = format_idx_get_from_drm_format(plane->formats[i]);
+ drm_format = *in_formats_enabled_out ?
+ output->in_formats->formats[i].format : plane->formats[i];
+ format_idx = format_idx_get_from_drm_format(drm_format);
if (format_idx == -1)
continue;
output->formats |= (1 << format_idx);
}
+
+ /* At this point we can only shut down if the look up failed and
+ * it is safe to pass NULL to drmModeFreeFormats().
+ */
if (!output->formats)
- goto err_free_plane;
+ goto err_free_formats;
output->connector_id = connector->connector_id;
output->crtc_id = crtc->crtc_id;
@@ -705,6 +771,8 @@ display_output_init(int fd, struct display_output *output, bool use_atomic)
return true;
+err_free_formats:
+ drmModeFreeFormats(output->in_formats);
err_free_plane:
drmModeFreePlane(plane);
err_free_crtc:
@@ -983,10 +1051,12 @@ static bool
add_fb_for_dri_image(struct dri2_egl_display *dri2_dpy, __DRIimage *image,
uint32_t *fb_id_out)
{
+ uint64_t modifiers[4] = {0};
uint32_t handles[4] = {0};
uint32_t pitches[4] = {0};
uint32_t offsets[4] = {0};
- int handle, stride, width, height, format;
+ uint32_t flags = 0;
+ int handle, stride, width, height, format, l_mod, h_mod;
int format_idx;
dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_HANDLE, &handle);
@@ -1001,9 +1071,41 @@ add_fb_for_dri_image(struct dri2_egl_display *dri2_dpy, __DRIimage *image,
format_idx = format_idx_get_from_dri_image_format(format);
assert(format_idx != -1);
- return !drmModeAddFB2(dri2_dpy->fd, width, height,
- dri2_null_formats[format_idx].drm_format,
- handles, pitches, offsets, fb_id_out, 0);
+ if (dri2_dpy->in_formats_enabled) {
+ dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_MODIFIER_UPPER, &h_mod);
+ dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_MODIFIER_LOWER, &l_mod);
+
+ modifiers[0] = combine_u32_into_u64((uint32_t) h_mod, (uint32_t) l_mod);
+ flags |= DRM_MODE_FB_MODIFIERS;
+ }
+
+ return !drmModeAddFB2WithModifiers(dri2_dpy->fd, width, height,
+ dri2_null_formats[format_idx].drm_format,
+ handles, pitches, offsets, modifiers,
+ fb_id_out, flags);
+}
+
+static __DRIimage *
+create_image(struct dri2_egl_surface *dri2_surf, uint32_t flags)
+{
+ struct dri2_egl_display *dri2_dpy =
+ dri2_egl_display(dri2_surf->base.Resource.Display);
+
+ if (dri2_dpy->in_formats_enabled)
+ return dri2_dpy->image->createImageWithModifiers(dri2_dpy->dri_screen,
+ dri2_surf->base.Width,
+ dri2_surf->base.Height,
+ dri2_surf->format,
+ dri2_surf->modifiers,
+ dri2_surf->count_modifiers,
+ NULL);
+
+ return dri2_dpy->image->createImage(dri2_dpy->dri_screen,
+ dri2_surf->base.Width,
+ dri2_surf->base.Height,
+ dri2_surf->format,
+ flags,
+ NULL);
}
static bool
@@ -1016,12 +1118,7 @@ get_front_bo(struct dri2_egl_surface *dri2_surf)
if (dri2_surf->base.Type == EGL_WINDOW_BIT)
use |= __DRI_IMAGE_USE_SCANOUT;
- dri2_surf->front = dri2_dpy->image->createImage(dri2_dpy->dri_screen,
- dri2_surf->base.Width,
- dri2_surf->base.Height,
- dri2_surf->format,
- use,
- NULL);
+ dri2_surf->front = create_image(dri2_surf, use);
if (!dri2_surf->front)
return false;
@@ -1058,13 +1155,8 @@ get_back_bo(struct dri2_egl_surface *dri2_surf)
}
if (!dri2_surf->back->dri_image) {
- dri2_surf->back->dri_image =
- dri2_dpy->image->createImage(dri2_dpy->dri_screen,
- dri2_surf->base.Width,
- dri2_surf->base.Height,
- dri2_surf->format,
- __DRI_IMAGE_USE_SCANOUT,
- NULL);
+ dri2_surf->back->dri_image = create_image(dri2_surf,
+ __DRI_IMAGE_USE_SCANOUT);
if (!dri2_surf->back->dri_image)
goto err_unlock;
}
@@ -1094,6 +1186,26 @@ static void surface_swap_queue_init(struct dri2_egl_surface *dri2_surf)
swap_queue[i].kms_in_fence_fd = -1;
}
+static bool
+in_formats_get_modifiers(drmModeFormats *in_formats, int drm_format,
+ uint64_t **out_modifiers, uint32_t *out_count)
+{
+ unsigned i;
+
+ if (!in_formats)
+ return false;
+
+ for (i = 0; i < in_formats->count; i++) {
+ if (in_formats->formats[i].format == drm_format) {
+ *out_modifiers = in_formats->formats[i].modifiers;
+ *out_count = in_formats->formats[i].count_modifiers;
+ return true;
+ }
+ }
+
+ return false;
+}
+
static _EGLSurface *
create_surface(_EGLDisplay *disp, _EGLConfig *config, EGLint type,
const EGLint *attrib_list)
@@ -1105,6 +1217,7 @@ create_surface(_EGLDisplay *disp, _EGLConfig *config, EGLint type,
const __DRIconfig *dri_config;
_EGLSurface *surf;
int format_idx;
+ bool ret;
dri2_surf = calloc(1, sizeof(*dri2_surf));
if (!dri2_surf) {
@@ -1137,6 +1250,15 @@ create_surface(_EGLDisplay *disp, _EGLConfig *config, EGLint type,
dri2_surf->format = dri2_null_formats[format_idx].dri_image_format;
+ if (dri2_dpy->in_formats_enabled) {
+ ret = in_formats_get_modifiers(dri2_dpy->output.in_formats,
+ dri2_null_formats[format_idx].drm_format,
+ &dri2_surf->modifiers,
+ &dri2_surf->count_modifiers);
+ if (!ret || dri2_surf->count_modifiers <= 0)
+ goto err_free_surface;
+ }
+
surface_swap_queue_init(dri2_surf);
return surf;
@@ -1533,6 +1655,7 @@ EGLBoolean
dri2_initialize_null(_EGLDisplay *disp)
{
struct dri2_egl_display *dri2_dpy;
+ bool prefer_in_formats;
int err;
dri2_dpy = calloc(1, sizeof(*dri2_dpy));
@@ -1586,8 +1709,16 @@ dri2_initialize_null(_EGLDisplay *disp)
goto cleanup;
}
+ /* in_formats could be supported by the platform, however not being
+ * actually enabled, i.e. in_formats init can still fail.
+ */
+ prefer_in_formats = dri2_dpy->image->base.version >= 14 &&
+ dri2_dpy->image->createImageWithModifiers;
+
if (!display_output_init(dri2_dpy->fd, &dri2_dpy->output,
- dri2_dpy->atomic_enabled)) {
+ dri2_dpy->atomic_enabled,
+ prefer_in_formats,
+ &dri2_dpy->in_formats_enabled)) {
_eglError(EGL_NOT_INITIALIZED, "failed to create output");
goto cleanup;
}
@@ -1616,6 +1747,7 @@ void
dri2_teardown_null(struct dri2_egl_display *dri2_dpy)
{
drmModeAtomicFree(dri2_dpy->output.atomic_state);
+ drmModeFreeFormats(dri2_dpy->output.in_formats);
if (dri2_dpy->output.mode_blob_id)
drmModeDestroyPropertyBlob(dri2_dpy->fd, dri2_dpy->output.mode_blob_id);
--
2.17.1
@@ -0,0 +1,203 @@
From 7c21f010de28888376dcafd99d3fa43d15279dc6 Mon Sep 17 00:00:00 2001
From: Brendan King <Brendan.King@imgtec.com>
Date: Mon, 10 Feb 2020 09:23:03 +0000
Subject: [PATCH 44/50] egl: query the supported ES2 context version
For OpenGL ES contexts, the EGL specification states that querying
EGL_CONTEXT_CLIENT_VERSION with eglQueryContext may return a version
that differs from that specified at context creation time. For example,
if an OpenGL ES2 context is specified at context creation time, an
OpenGL ES3 context may be created, and so "3" should be returned
when EGL_CONTEXT_CLIENT_VERSION is queried.
A new EGL driver API function has been added,
QueryContextClientVersion, that is called when the context client
version is queried, allowing EGL drivers to override the default
value (i.e. the version specified at context creation time). If the
function returns zero, the default is used.
For DRI drivers, QueryContextClientVersion returns zero for all API
contexts other than OpenGL ES2. For OpenGL ES2, the supported context
client version is queried via the Query Renderer driver extension, using
integer query __DRI2_RENDERER_OPENGL_ES2_CONTEXT_CLIENT_VERSION_IMG. If
the query isn't supported, or the query returns zero, zero is returned
to the caller.
IMG NOTE: In order to avoid potential name and value clashes, "_IMG"
has been added to the end of the new query name, this should be removed
if an attempt is made to push this patch upstream. The value of the new
query should be adjusted to be the next one in sequence, rather than the
large value it currently has.
---
include/GL/internal/dri_interface.h | 2 ++
src/egl/drivers/dri2/egl_dri2.c | 21 +++++++++++++++++++++
src/egl/drivers/haiku/egl_haiku.cpp | 9 +++++++++
src/egl/main/eglapi.c | 2 +-
src/egl/main/eglcontext.c | 16 ++++++++++++++--
src/egl/main/eglcontext.h | 3 ++-
src/egl/main/egldriver.h | 1 +
7 files changed, 50 insertions(+), 4 deletions(-)
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
index 8214e7a55c3..302e4e08de0 100644
--- a/include/GL/internal/dri_interface.h
+++ b/include/GL/internal/dri_interface.h
@@ -2028,6 +2028,8 @@ typedef struct __DRIDriverVtableExtensionRec {
#define __DRI2_RENDERER_HAS_PROTECTED_CONTENT 0x000e
+#define __DRI2_RENDERER_OPENGL_ES2_CONTEXT_CLIENT_VERSION_IMG 0x7001
+
typedef struct __DRI2rendererQueryExtensionRec __DRI2rendererQueryExtension;
struct __DRI2rendererQueryExtensionRec {
__DRIextension base;
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index f001ee7b98f..cda414f4adc 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -2083,6 +2083,26 @@ dri2_make_current(_EGLDisplay *disp, _EGLSurface *dsurf,
return EGL_TRUE;
}
+static EGLint
+dri2_query_context_client_version(_EGLDisplay *disp, _EGLContext *ctx)
+{
+ struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx);
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
+
+ switch (dri2_ctx->base.ClientAPI) {
+ case EGL_OPENGL_ES_API:
+ switch (dri2_ctx->base.ClientMajorVersion) {
+ case 2:
+ return dri2_renderer_query_integer(dri2_dpy,
+ __DRI2_RENDERER_OPENGL_ES2_CONTEXT_CLIENT_VERSION_IMG);
+ default:
+ return 0;
+ }
+ default:
+ return 0;
+ }
+}
+
__DRIdrawable *
dri2_surface_get_dri_drawable(_EGLSurface *surf)
{
@@ -4347,6 +4367,7 @@ const _EGLDriver _eglDriver = {
.CreateContext = dri2_create_context,
.DestroyContext = dri2_destroy_context,
.MakeCurrent = dri2_make_current,
+ .QueryContextClientVersion = dri2_query_context_client_version,
.CreateWindowSurface = dri2_create_window_surface,
.CreatePixmapSurface = dri2_create_pixmap_surface,
.CreatePbufferSurface = dri2_create_pbuffer_surface,
diff --git a/src/egl/drivers/haiku/egl_haiku.cpp b/src/egl/drivers/haiku/egl_haiku.cpp
index 8eda31c2936..6fc58371063 100644
--- a/src/egl/drivers/haiku/egl_haiku.cpp
+++ b/src/egl/drivers/haiku/egl_haiku.cpp
@@ -297,6 +297,14 @@ haiku_make_current(_EGLDisplay *disp, _EGLSurface *dsurf,
}
+extern "C"
+EGLint
+haiku_dri2_query_context_client_version(_EGLDisplay *disp, _EGLContext *ctx)
+{
+ // Tell caller to use the default value.
+ return 0;
+}
+
extern "C"
EGLBoolean
haiku_swap_buffers(_EGLDisplay *disp, _EGLSurface *surf)
@@ -316,6 +324,7 @@ const _EGLDriver _eglDriver = {
.CreateContext = haiku_create_context,
.DestroyContext = haiku_destroy_context,
.MakeCurrent = haiku_make_current,
+ .QueryContextClientVersion = haiku_dri2_query_context_client_version,
.CreateWindowSurface = haiku_create_window_surface,
.CreatePixmapSurface = haiku_create_pixmap_surface,
.CreatePbufferSurface = haiku_create_pbuffer_surface,
diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c
index 431dd70d1d8..900ef7ab4cc 100644
--- a/src/egl/main/eglapi.c
+++ b/src/egl/main/eglapi.c
@@ -948,7 +948,7 @@ eglQueryContext(EGLDisplay dpy, EGLContext ctx,
_EGL_CHECK_CONTEXT(disp, context, EGL_FALSE);
- ret = _eglQueryContext(context, attribute, value);
+ ret = _eglQueryContext(disp, context, attribute, value);
RETURN_EGL_EVAL(disp, ret);
}
diff --git a/src/egl/main/eglcontext.c b/src/egl/main/eglcontext.c
index 65dc886abbb..09e7d3ee589 100644
--- a/src/egl/main/eglcontext.c
+++ b/src/egl/main/eglcontext.c
@@ -35,6 +35,7 @@
#include "eglcontext.h"
#include "egldisplay.h"
#include "eglcurrent.h"
+#include "egldriver.h"
#include "eglsurface.h"
#include "egllog.h"
#include "util/macros.h"
@@ -670,8 +671,19 @@ _eglQueryContextRenderBuffer(_EGLContext *ctx)
}
+static EGLint
+_eglQueryContextClientVersion(_EGLDisplay *disp, _EGLContext *ctx)
+{
+ EGLint version;
+
+ version = disp->Driver->QueryContextClientVersion(disp, ctx);
+
+ return (version) ? version : ctx->ClientMajorVersion;
+}
+
EGLBoolean
-_eglQueryContext(_EGLContext *c, EGLint attribute, EGLint *value)
+_eglQueryContext(_EGLDisplay *disp, _EGLContext *c,
+ EGLint attribute, EGLint *value)
{
if (!value)
return _eglError(EGL_BAD_PARAMETER, "eglQueryContext");
@@ -688,7 +700,7 @@ _eglQueryContext(_EGLContext *c, EGLint attribute, EGLint *value)
*value = c->Config ? c->Config->ConfigID : 0;
break;
case EGL_CONTEXT_CLIENT_VERSION:
- *value = c->ClientMajorVersion;
+ *value = _eglQueryContextClientVersion(disp, c);
break;
case EGL_CONTEXT_CLIENT_TYPE:
*value = c->ClientAPI;
diff --git a/src/egl/main/eglcontext.h b/src/egl/main/eglcontext.h
index 06029e81251..d890217852d 100644
--- a/src/egl/main/eglcontext.h
+++ b/src/egl/main/eglcontext.h
@@ -74,7 +74,8 @@ _eglInitContext(_EGLContext *ctx, _EGLDisplay *disp,
extern EGLBoolean
-_eglQueryContext(_EGLContext *ctx, EGLint attribute, EGLint *value);
+_eglQueryContext(_EGLDisplay *disp, _EGLContext *ctx,
+ EGLint attribute, EGLint *value);
extern EGLBoolean
diff --git a/src/egl/main/egldriver.h b/src/egl/main/egldriver.h
index 12f9a0aab86..92af8bd16d5 100644
--- a/src/egl/main/egldriver.h
+++ b/src/egl/main/egldriver.h
@@ -97,6 +97,7 @@ struct _egl_driver
EGLBoolean (*MakeCurrent)(_EGLDisplay *disp,
_EGLSurface *draw, _EGLSurface *read,
_EGLContext *ctx);
+ EGLint (*QueryContextClientVersion)(_EGLDisplay *disp, _EGLContext *ctx);
/* surface funcs */
_EGLSurface *(*CreateWindowSurface)(_EGLDisplay *disp, _EGLConfig *config,
--
2.17.1
@@ -0,0 +1,140 @@
From 43662126e9973c6cff496ba32fae3cf372e0646b Mon Sep 17 00:00:00 2001
From: Brendan King <Brendan.King@imgtec.com>
Date: Thu, 11 Jun 2020 12:29:51 +0100
Subject: [PATCH 45/50] meson: allow libGL to be built without GLX
If Meson is run with option "glx" set to "null", build the
OpenGL library without GLX.
The "eglBindAPI workaround for dEQP bug" change to eglcurrent.h
(commit 2d46c91040aeb8ebad486214159c34417fbc87db) has been
modified to use a new EGL_WITH_OPENGL define, which indicates
whether OpneGL is present or not. This allows EGL to be used
with OpenGL on platforms other than X11.
---
meson.build | 8 ++++++--
meson_options.txt | 2 +-
src/egl/main/eglcurrent.h | 7 +++----
src/glx/meson.build | 16 ++++++++++++----
src/meson.build | 2 +-
5 files changed, 23 insertions(+), 12 deletions(-)
diff --git a/meson.build b/meson.build
index 3c55447b6eb..af020203752 100644
--- a/meson.build
+++ b/meson.build
@@ -459,6 +459,10 @@ else
with_egl = false
endif
+if with_egl and with_opengl and with_glx != 'disabled'
+ pre_args += '-DEGL_WITH_OPENGL'
+endif
+
# Android uses emutls for versions <= P/28. For USE_ELF_TLS we need ELF TLS.
use_elf_tls = false
if not ['windows', 'freebsd', 'openbsd', 'haiku'].contains(host_machine.system()) and (not with_platform_android or get_option('platform-sdk-version') >= 29)
@@ -466,7 +470,7 @@ if not ['windows', 'freebsd', 'openbsd', 'haiku'].contains(host_machine.system()
use_elf_tls = true
endif
-if with_glx != 'disabled'
+if with_glx != 'disabled' and with_glx != 'null'
if not (with_platform_x11 and with_any_opengl)
error('Cannot build GLX support without X11 platform support and at least one OpenGL API')
elif with_glx == 'gallium-xlib'
@@ -528,7 +532,7 @@ if with_any_vk and (with_platform_x11 and not with_dri3)
error('Vulkan drivers require dri3 for X11 support')
endif
if with_dri
- if with_glx == 'disabled' and not with_egl and not with_gbm
+ if (with_glx == 'disabled' or with_glx == 'null') and not with_egl and not with_gbm
error('building dri drivers require at least one windowing system')
endif
endif
diff --git a/meson_options.txt b/meson_options.txt
index 9073223e8f5..4038629544e 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -267,7 +267,7 @@ option(
'glx',
type : 'combo',
value : 'auto',
- choices : ['auto', 'disabled', 'dri', 'xlib', 'gallium-xlib'],
+ choices : ['auto', 'disabled', 'dri', 'xlib', 'gallium-xlib', 'null'],
description : 'Build support for GLX platform'
)
option(
diff --git a/src/egl/main/eglcurrent.h b/src/egl/main/eglcurrent.h
index 32570970947..dcc418afd6f 100644
--- a/src/egl/main/eglcurrent.h
+++ b/src/egl/main/eglcurrent.h
@@ -71,11 +71,10 @@ struct _egl_thread_info
static inline EGLBoolean
_eglIsApiValid(EGLenum api)
{
-#ifndef HAVE_X11_PLATFORM
- /* OpenGL is not a valid/supported API on Android */
- return api == EGL_OPENGL_ES_API;
-#else
+#ifdef EGL_WITH_OPENGL
return (api == EGL_OPENGL_ES_API || api == EGL_OPENGL_API);
+#else
+ return api == EGL_OPENGL_ES_API;
#endif
}
diff --git a/src/glx/meson.build b/src/glx/meson.build
index 58f9e1aa896..41ca936b8f4 100644
--- a/src/glx/meson.build
+++ b/src/glx/meson.build
@@ -126,7 +126,11 @@ gl_lib_cargs = [
'-D_REENTRANT',
]
-libglx = static_library(
+if with_glx == 'null'
+ libglx_link = [libglapi]
+ libglx_link_whole = [libglapi_static]
+else
+ libglx = static_library(
'glx',
[files_libglx, glx_generated],
include_directories : [inc_include, inc_src, inc_mapi, inc_mesa, inc_gallium, inc_gallium_aux, inc_glapi, inc_loader],
@@ -143,13 +147,17 @@ libglx = static_library(
idep_mesautil, idep_xmlconfig,
dep_libdrm, dep_dri2proto, dep_glproto, dep_x11, dep_glvnd,
],
-)
+ )
+
+ libglx_link = [libglapi_static,libglapi]
+ libglx_link_whole = [libglx]
+endif
libgl = shared_library(
gl_lib_name,
[],
- link_with : [libglapi_static, libglapi],
- link_whole : libglx,
+ link_with : libglx_link,
+ link_whole : libglx_link_whole,
link_args : [ld_args_bsymbolic, ld_args_gc_sections, extra_ld_args_libgl],
dependencies : [
dep_libdrm, dep_dl, dep_m, dep_thread, dep_x11, dep_xcb_glx, dep_xcb,
diff --git a/src/meson.build b/src/meson.build
index d96c754a63d..a92580b2dd5 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -104,7 +104,7 @@ subdir('loader')
if with_platform_haiku
subdir('hgl')
endif
-if with_glx == 'dri'
+if with_glx == 'dri' or with_glx == 'null'
subdir('glx')
endif
if with_gbm
--
2.17.1
@@ -0,0 +1,38 @@
From bc8f13db460c79ef9036e7f0983bb039ac1af777 Mon Sep 17 00:00:00 2001
From: Brendan King <Brendan.King@imgtec.com>
Date: Tue, 25 Aug 2020 14:12:32 +0100
Subject: [PATCH 46/50] egl/wayland: process non-resized window movement
The dx and dy parameters to the wl_egl_window_resize function were
not being processed unless the window width or height were being
changed.
---
src/egl/drivers/dri2/platform_wayland.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c
index de12ec21f53..f4b43aa26a2 100644
--- a/src/egl/drivers/dri2/platform_wayland.c
+++ b/src/egl/drivers/dri2/platform_wayland.c
@@ -265,6 +265,9 @@ resize_callback(struct wl_egl_window *wl_win, void *data)
struct dri2_egl_display *dri2_dpy =
dri2_egl_display(dri2_surf->base.Resource.Display);
+ dri2_surf->dx = wl_win->dx;
+ dri2_surf->dy = wl_win->dy;
+
if (dri2_surf->base.Width == wl_win->width &&
dri2_surf->base.Height == wl_win->height)
return;
@@ -799,8 +802,6 @@ update_buffers(struct dri2_egl_display *dri2_dpy,
dri2_surf->base.Width = dri2_surf->wl_win->width;
dri2_surf->base.Height = dri2_surf->wl_win->height;
- dri2_surf->dx = dri2_surf->wl_win->dx;
- dri2_surf->dy = dri2_surf->wl_win->dy;
}
if (dri2_surf->base.Width != dri2_surf->wl_win->attached_width ||
--
2.17.1
@@ -0,0 +1,539 @@
From 22afb695d4598a52198f9bbe98b359f9fcf77cfa Mon Sep 17 00:00:00 2001
From: Brendan King <Brendan.King@imgtec.com>
Date: Mon, 10 Mar 2014 13:43:45 +0000
Subject: [PATCH 47/50] Separate EXT_framebuffer_object from ARB version
This patch separates the EXT_framebuffer_object entry points from the ARB
equivalents.
Probably not all this separation is necessary; it looks like only
BindRenderbuffer
BindFramebuffer
GetFramebufferAttachmentParameteriv
take advantage of the split.
Next time this patch is implemented, see if it can be trimmed down to
just the above functions, as it may be more upstreamable.
We may need to implement the EXT restrictions if we want to upstream.
---
src/mapi/glapi/gen/EXT_framebuffer_object.xml | 30 +++----
src/mapi/glapi/gen/static_data.py | 15 ++++
src/mesa/main/fbobject.c | 83 +++++++++++++++++++
src/mesa/main/fbobject.h | 54 ++++++++++++
src/mesa/main/genmipmap.c | 6 ++
src/mesa/main/genmipmap.h | 3 +
6 files changed, 176 insertions(+), 15 deletions(-)
diff --git a/src/mapi/glapi/gen/EXT_framebuffer_object.xml b/src/mapi/glapi/gen/EXT_framebuffer_object.xml
index 6c0e54af1c9..957b6a3a632 100644
--- a/src/mapi/glapi/gen/EXT_framebuffer_object.xml
+++ b/src/mapi/glapi/gen/EXT_framebuffer_object.xml
@@ -70,7 +70,7 @@
</enum>
<enum name="INVALID_FRAMEBUFFER_OPERATION_EXT" value="0x0506"/>
- <function name="IsRenderbufferEXT" alias="IsRenderbuffer">
+ <function name="IsRenderbufferEXT">
<param name="renderbuffer" type="GLuint"/>
<return type="GLboolean"/>
</function>
@@ -81,30 +81,30 @@
<glx rop="4316"/>
</function>
- <function name="DeleteRenderbuffersEXT" alias="DeleteRenderbuffers">
+ <function name="DeleteRenderbuffersEXT">
<param name="n" type="GLsizei"/>
<param name="renderbuffers" type="const GLuint *"/>
</function>
- <function name="GenRenderbuffersEXT" alias="GenRenderbuffers">
+ <function name="GenRenderbuffersEXT">
<param name="n" type="GLsizei"/>
<param name="renderbuffers" type="GLuint *"/>
</function>
- <function name="RenderbufferStorageEXT" alias="RenderbufferStorage">
+ <function name="RenderbufferStorageEXT">
<param name="target" type="GLenum"/>
<param name="internalformat" type="GLenum"/>
<param name="width" type="GLsizei"/>
<param name="height" type="GLsizei"/>
</function>
- <function name="GetRenderbufferParameterivEXT" alias="GetRenderbufferParameteriv">
+ <function name="GetRenderbufferParameterivEXT">
<param name="target" type="GLenum"/>
<param name="pname" type="GLenum"/>
<param name="params" type="GLint *"/>
</function>
- <function name="IsFramebufferEXT" alias="IsFramebuffer">
+ <function name="IsFramebufferEXT">
<param name="framebuffer" type="GLuint"/>
<return type="GLboolean"/>
</function>
@@ -115,22 +115,22 @@
<glx rop="4319"/>
</function>
- <function name="DeleteFramebuffersEXT" alias="DeleteFramebuffers">
+ <function name="DeleteFramebuffersEXT">
<param name="n" type="GLsizei"/>
<param name="framebuffers" type="const GLuint *"/>
</function>
- <function name="GenFramebuffersEXT" alias="GenFramebuffers">
+ <function name="GenFramebuffersEXT">
<param name="n" type="GLsizei"/>
<param name="framebuffers" type="GLuint *"/>
</function>
- <function name="CheckFramebufferStatusEXT" alias="CheckFramebufferStatus">
+ <function name="CheckFramebufferStatusEXT">
<param name="target" type="GLenum"/>
<return type="GLenum"/>
</function>
- <function name="FramebufferTexture1DEXT" alias="FramebufferTexture1D">
+ <function name="FramebufferTexture1DEXT">
<param name="target" type="GLenum"/>
<param name="attachment" type="GLenum"/>
<param name="textarget" type="GLenum"/>
@@ -138,7 +138,7 @@
<param name="level" type="GLint"/>
</function>
- <function name="FramebufferTexture2DEXT" alias="FramebufferTexture2D">
+ <function name="FramebufferTexture2DEXT">
<param name="target" type="GLenum"/>
<param name="attachment" type="GLenum"/>
<param name="textarget" type="GLenum"/>
@@ -146,7 +146,7 @@
<param name="level" type="GLint"/>
</function>
- <function name="FramebufferTexture3DEXT" alias="FramebufferTexture3D">
+ <function name="FramebufferTexture3DEXT">
<param name="target" type="GLenum"/>
<param name="attachment" type="GLenum"/>
<param name="textarget" type="GLenum"/>
@@ -155,21 +155,21 @@
<param name="zoffset" type="GLint"/>
</function>
- <function name="FramebufferRenderbufferEXT" alias="FramebufferRenderbuffer">
+ <function name="FramebufferRenderbufferEXT">
<param name="target" type="GLenum"/>
<param name="attachment" type="GLenum"/>
<param name="renderbuffertarget" type="GLenum"/>
<param name="renderbuffer" type="GLuint"/>
</function>
- <function name="GetFramebufferAttachmentParameterivEXT" alias="GetFramebufferAttachmentParameteriv">
+ <function name="GetFramebufferAttachmentParameterivEXT">
<param name="target" type="GLenum"/>
<param name="attachment" type="GLenum"/>
<param name="pname" type="GLenum"/>
<param name="params" type="GLint *"/>
</function>
- <function name="GenerateMipmapEXT" alias="GenerateMipmap">
+ <function name="GenerateMipmapEXT">
<param name="target" type="GLenum"/>
</function>
</category>
diff --git a/src/mapi/glapi/gen/static_data.py b/src/mapi/glapi/gen/static_data.py
index 32fb3b8f4f7..ecd650ab814 100644
--- a/src/mapi/glapi/gen/static_data.py
+++ b/src/mapi/glapi/gen/static_data.py
@@ -1694,6 +1694,21 @@ offsets = {
"FramebufferTextureMultisampleMultiviewOVR" : 1658,
"MultiDrawArraysIndirectEXT" : 1659,
"MultiDrawElementsIndirectEXT" : 1660,
+ "IsRenderbufferEXT" : 1661,
+ "DeleteRenderbuffersEXT" : 1662,
+ "GenRenderbuffersEXT" : 1663,
+ "RenderbufferStorageEXT" : 1664,
+ "GetRenderbufferParameterivEXT" : 1665,
+ "IsFramebufferEXT" : 1666,
+ "DeleteFramebuffersEXT" : 1667,
+ "GenFramebuffersEXT" : 1668,
+ "CheckFramebufferStatusEXT" : 1669,
+ "FramebufferTexture1DEXT" : 1670,
+ "FramebufferTexture2DEXT" : 1671,
+ "FramebufferTexture3DEXT" : 1672,
+ "FramebufferRenderbufferEXT" : 1673,
+ "GetFramebufferAttachmentParameterivEXT" : 1674,
+ "GenerateMipmapEXT" : 1675,
}
functions = [
diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c
index 798f59d2499..21507ff7c19 100644
--- a/src/mesa/main/fbobject.c
+++ b/src/mesa/main/fbobject.c
@@ -1973,6 +1973,11 @@ _mesa_detach_renderbuffer(struct gl_context *ctx,
return progress;
}
+GLboolean GLAPIENTRY
+_mesa_IsRenderbufferEXT(GLuint renderbuffer)
+{
+ return _mesa_IsRenderbuffer(renderbuffer);
+}
void GLAPIENTRY
_mesa_DeleteRenderbuffers(GLsizei n, const GLuint *renderbuffers)
@@ -2682,6 +2687,12 @@ renderbuffer_storage_target(GLenum target, GLenum internalFormat,
}
+void GLAPIENTRY
+_mesa_DeleteRenderbuffersEXT(GLsizei n, const GLuint *renderbuffers)
+{
+ _mesa_DeleteRenderbuffers(n, renderbuffers);
+}
+
void GLAPIENTRY
_mesa_EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
{
@@ -2712,6 +2723,11 @@ _mesa_EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
ctx->Driver.EGLImageTargetRenderbufferStorage(ctx, rb, image);
}
+void GLAPIENTRY
+_mesa_GenRenderbuffersEXT(GLsizei n, GLuint *renderbuffers)
+{
+ _mesa_GenRenderbuffers(n, renderbuffers);
+}
/**
* Helper function for _mesa_GetRenderbufferParameteriv() and
@@ -2744,6 +2760,12 @@ _mesa_RenderbufferStorage(GLenum target, GLenum internalFormat,
NO_SAMPLES, 0, "glRenderbufferStorage");
}
+void GLAPIENTRY
+_mesa_RenderbufferStorageEXT(GLenum target, GLenum internalFormat,
+ GLsizei width, GLsizei height)
+{
+ _mesa_RenderbufferStorage(target, internalFormat, width, height);
+}
void GLAPIENTRY
_mesa_RenderbufferStorageMultisample(GLenum target, GLsizei samples,
@@ -2945,6 +2967,11 @@ _mesa_GetNamedRenderbufferParameteriv(GLuint renderbuffer, GLenum pname,
"glGetNamedRenderbufferParameteriv");
}
+void GLAPIENTRY
+_mesa_GetRenderbufferParameterivEXT(GLenum target, GLenum pname, GLint *params)
+{
+ _mesa_GetRenderbufferParameteriv(target, pname, params);
+}
void GLAPIENTRY
_mesa_GetNamedRenderbufferParameterivEXT(GLuint renderbuffer, GLenum pname,
@@ -2978,6 +3005,11 @@ _mesa_IsFramebuffer(GLuint framebuffer)
return GL_FALSE;
}
+GLboolean GLAPIENTRY
+_mesa_IsFramebufferEXT(GLuint framebuffer)
+{
+ return _mesa_IsFramebuffer(framebuffer);
+}
/**
* Check if any of the attachments of the given framebuffer are textures
@@ -3212,6 +3244,11 @@ _mesa_DeleteFramebuffers(GLsizei n, const GLuint *framebuffers)
}
}
+void GLAPIENTRY
+_mesa_DeleteFramebuffersEXT(GLsizei n, const GLuint *framebuffers)
+{
+ _mesa_DeleteFramebuffers(n, framebuffers);
+}
/**
* This is the implementation for glGenFramebuffers and glCreateFramebuffers.
@@ -3258,6 +3295,11 @@ create_framebuffers(GLsizei n, GLuint *framebuffers, bool dsa)
_mesa_HashUnlockMutex(ctx->Shared->FrameBuffers);
}
+void GLAPIENTRY
+_mesa_GenFramebuffersEXT(GLsizei n, GLuint *framebuffers)
+{
+ _mesa_GenFramebuffers(n, framebuffers);
+}
void GLAPIENTRY
_mesa_GenFramebuffers(GLsizei n, GLuint *framebuffers)
@@ -3297,6 +3339,11 @@ _mesa_check_framebuffer_status(struct gl_context *ctx,
return buffer->_Status;
}
+GLenum GLAPIENTRY
+_mesa_CheckFramebufferStatusEXT(GLenum target)
+{
+ return _mesa_CheckFramebufferStatus(target);
+}
GLenum GLAPIENTRY
_mesa_CheckFramebufferStatus_no_error(GLenum target)
@@ -3909,6 +3956,12 @@ _mesa_FramebufferTexture1D_no_error(GLenum target, GLenum attachment,
texture, level, 0);
}
+void GLAPIENTRY
+_mesa_FramebufferTexture1DEXT(GLenum target, GLenum attachment,
+ GLenum textarget, GLuint texture, GLint level)
+{
+ _mesa_FramebufferTexture1D(target, attachment, textarget, texture, level);
+}
void GLAPIENTRY
_mesa_FramebufferTexture1D(GLenum target, GLenum attachment,
@@ -3949,6 +4002,12 @@ _mesa_FramebufferTexture2DMultisampleEXT(GLenum target, GLenum attachment,
false);
}
+void GLAPIENTRY
+_mesa_FramebufferTexture2DEXT(GLenum target, GLenum attachment,
+ GLenum textarget, GLuint texture, GLint level)
+{
+ _mesa_FramebufferTexture2D(target, attachment, textarget, texture, level);
+}
void GLAPIENTRY
_mesa_FramebufferTexture3D_no_error(GLenum target, GLenum attachment,
@@ -4059,6 +4118,15 @@ frame_buffer_texture(GLuint framebuffer, GLenum target,
level, 0, layer, layered);
}
+void GLAPIENTRY
+_mesa_FramebufferTexture3DEXT(GLenum target, GLenum attachment,
+ GLenum textarget, GLuint texture,
+ GLint level, GLint zoffset)
+{
+ _mesa_FramebufferTexture3D(target, attachment, textarget, texture,
+ level, zoffset);
+}
+
void GLAPIENTRY
_mesa_FramebufferTextureLayer_no_error(GLenum target, GLenum attachment,
GLuint texture, GLint level,
@@ -4312,6 +4380,15 @@ _mesa_FramebufferRenderbuffer(GLenum target, GLenum attachment,
renderbuffer, "glFramebufferRenderbuffer");
}
+void GLAPIENTRY
+_mesa_FramebufferRenderbufferEXT(GLenum target, GLenum attachment,
+ GLenum renderbufferTarget,
+ GLuint renderbuffer)
+{
+ _mesa_FramebufferRenderbuffer(target, attachment, renderbufferTarget,
+ renderbuffer);
+}
+
void GLAPIENTRY
_mesa_NamedFramebufferRenderbuffer_no_error(GLuint framebuffer,
GLenum attachment,
@@ -4713,6 +4790,12 @@ invalid_pname_enum:
return;
}
+void GLAPIENTRY
+_mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment,
+ GLenum pname, GLint *params)
+{
+ _mesa_GetFramebufferAttachmentParameteriv(target, attachment, pname, params);
+}
void GLAPIENTRY
_mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment,
diff --git a/src/mesa/main/fbobject.h b/src/mesa/main/fbobject.h
index 2a32c158e68..98271d76f50 100644
--- a/src/mesa/main/fbobject.h
+++ b/src/mesa/main/fbobject.h
@@ -145,6 +145,9 @@ _mesa_bind_framebuffers(struct gl_context *ctx,
extern GLboolean GLAPIENTRY
_mesa_IsRenderbuffer(GLuint renderbuffer);
+extern GLboolean GLAPIENTRY
+_mesa_IsRenderbufferEXT(GLuint renderbuffer);
+
extern void GLAPIENTRY
_mesa_BindRenderbuffer(GLenum target, GLuint renderbuffer);
@@ -157,12 +160,18 @@ _mesa_DeleteRenderbuffers(GLsizei n, const GLuint *renderbuffers);
void GLAPIENTRY
_mesa_GenRenderbuffers_no_error(GLsizei n, GLuint *renderbuffers);
+extern void GLAPIENTRY
+_mesa_DeleteRenderbuffersEXT(GLsizei n, const GLuint *renderbuffers);
+
extern void GLAPIENTRY
_mesa_GenRenderbuffers(GLsizei n, GLuint *renderbuffers);
void GLAPIENTRY
_mesa_CreateRenderbuffers_no_error(GLsizei n, GLuint *renderbuffers);
+extern void GLAPIENTRY
+_mesa_GenRenderbuffersEXT(GLsizei n, GLuint *renderbuffers);
+
extern void GLAPIENTRY
_mesa_CreateRenderbuffers(GLsizei n, GLuint *renderbuffers);
@@ -170,6 +179,10 @@ extern void GLAPIENTRY
_mesa_RenderbufferStorage(GLenum target, GLenum internalformat,
GLsizei width, GLsizei height);
+extern void GLAPIENTRY
+_mesa_RenderbufferStorageEXT(GLenum target, GLenum internalformat,
+ GLsizei width, GLsizei height);
+
extern void GLAPIENTRY
_mesa_RenderbufferStorageMultisample(GLenum target, GLsizei samples,
GLenum internalformat,
@@ -213,6 +226,10 @@ extern void GLAPIENTRY
_mesa_GetRenderbufferParameteriv(GLenum target, GLenum pname,
GLint *params);
+extern void GLAPIENTRY
+_mesa_GetRenderbufferParameterivEXT(GLenum target, GLenum pname,
+ GLint *params);
+
void GLAPIENTRY
_mesa_GetNamedRenderbufferParameteriv(GLuint renderbuffer, GLenum pname,
GLint *params);
@@ -220,6 +237,9 @@ _mesa_GetNamedRenderbufferParameteriv(GLuint renderbuffer, GLenum pname,
extern GLboolean GLAPIENTRY
_mesa_IsFramebuffer(GLuint framebuffer);
+extern GLboolean GLAPIENTRY
+_mesa_IsFramebufferEXT(GLuint framebuffer);
+
extern void GLAPIENTRY
_mesa_BindFramebuffer(GLenum target, GLuint framebuffer);
@@ -229,9 +249,15 @@ _mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer);
extern void GLAPIENTRY
_mesa_DeleteFramebuffers(GLsizei n, const GLuint *framebuffers);
+extern void GLAPIENTRY
+_mesa_DeleteFramebuffersEXT(GLsizei n, const GLuint *framebuffers);
+
extern void GLAPIENTRY
_mesa_GenFramebuffers(GLsizei n, GLuint *framebuffers);
+extern void GLAPIENTRY
+_mesa_GenFramebuffersEXT(GLsizei n, GLuint *framebuffers);
+
extern void GLAPIENTRY
_mesa_CreateFramebuffers(GLsizei n, GLuint *framebuffers);
@@ -241,6 +267,9 @@ _mesa_CheckFramebufferStatus_no_error(GLenum target);
extern GLenum GLAPIENTRY
_mesa_CheckFramebufferStatus(GLenum target);
+extern GLenum GLAPIENTRY
+_mesa_CheckFramebufferStatusEXT(GLenum target);
+
extern GLenum GLAPIENTRY
_mesa_CheckNamedFramebufferStatus(GLuint framebuffer, GLenum target);
@@ -259,6 +288,11 @@ extern void GLAPIENTRY
_mesa_FramebufferTexture2D_no_error(GLenum target, GLenum attachment,
GLenum textarget, GLuint texture,
GLint level);
+
+extern void GLAPIENTRY
+_mesa_FramebufferTexture1DEXT(GLenum target, GLenum attachment,
+ GLenum textarget, GLuint texture, GLint level);
+
extern void GLAPIENTRY
_mesa_FramebufferTexture2D(GLenum target, GLenum attachment,
GLenum textarget, GLuint texture, GLint level);
@@ -272,6 +306,11 @@ extern void GLAPIENTRY
_mesa_FramebufferTexture3D_no_error(GLenum target, GLenum attachment,
GLenum textarget, GLuint texture,
GLint level, GLint layer);
+
+extern void GLAPIENTRY
+_mesa_FramebufferTexture2DEXT(GLenum target, GLenum attachment,
+ GLenum textarget, GLuint texture, GLint level);
+
extern void GLAPIENTRY
_mesa_FramebufferTexture3D(GLenum target, GLenum attachment,
GLenum textarget, GLuint texture,
@@ -281,6 +320,12 @@ extern void GLAPIENTRY
_mesa_FramebufferTextureLayer_no_error(GLenum target, GLenum attachment,
GLuint texture, GLint level,
GLint layer);
+
+extern void GLAPIENTRY
+_mesa_FramebufferTexture3DEXT(GLenum target, GLenum attachment,
+ GLenum textarget, GLuint texture,
+ GLint level, GLint zoffset);
+
extern void GLAPIENTRY
_mesa_FramebufferTextureLayer(GLenum target, GLenum attachment,
GLuint texture, GLint level, GLint layer);
@@ -342,6 +387,11 @@ _mesa_NamedFramebufferRenderbuffer_no_error(GLuint framebuffer,
GLenum renderbuffertarget,
GLuint renderbuffer);
+extern void GLAPIENTRY
+_mesa_FramebufferRenderbufferEXT(GLenum target, GLenum attachment,
+ GLenum renderbuffertarget,
+ GLuint renderbuffer);
+
extern void GLAPIENTRY
_mesa_NamedFramebufferRenderbuffer(GLuint framebuffer, GLenum attachment,
GLenum renderbuffertarget,
@@ -390,6 +440,10 @@ _mesa_InvalidateSubFramebuffer_no_error(GLenum target, GLsizei numAttachments,
const GLenum *attachments, GLint x,
GLint y, GLsizei width, GLsizei height);
+extern void GLAPIENTRY
+_mesa_GetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment,
+ GLenum pname, GLint *params);
+
extern void GLAPIENTRY
_mesa_InvalidateSubFramebuffer(GLenum target, GLsizei numAttachments,
const GLenum *attachments, GLint x, GLint y,
diff --git a/src/mesa/main/genmipmap.c b/src/mesa/main/genmipmap.c
index 16e2b037635..4d7b7db36a5 100644
--- a/src/mesa/main/genmipmap.c
+++ b/src/mesa/main/genmipmap.c
@@ -267,3 +267,9 @@ _mesa_GenerateMultiTexMipmapEXT(GLenum texunit, GLenum target)
validate_params_and_generate_mipmap(texObj,
"glGenerateMultiTexMipmapEXT");
}
+
+void GLAPIENTRY
+_mesa_GenerateMipmapEXT(GLenum target)
+{
+ _mesa_GenerateMipmap(target);
+}
diff --git a/src/mesa/main/genmipmap.h b/src/mesa/main/genmipmap.h
index c661f2184c7..ff3b45a4417 100644
--- a/src/mesa/main/genmipmap.h
+++ b/src/mesa/main/genmipmap.h
@@ -44,6 +44,9 @@ _mesa_GenerateMipmap(GLenum target);
void GLAPIENTRY
_mesa_GenerateTextureMipmap_no_error(GLuint texture);
+extern void GLAPIENTRY
+_mesa_GenerateMipmapEXT(GLenum target);
+
extern void GLAPIENTRY
_mesa_GenerateTextureMipmap(GLuint texture);
--
2.17.1
@@ -0,0 +1,321 @@
From b2bee752e8c3d4188037b0d538b86836a0ba19d3 Mon Sep 17 00:00:00 2001
From: Luigi Santivetti <luigi.santivetti@imgtec.com>
Date: Mon, 21 Oct 2019 09:21:52 +0100
Subject: [PATCH 48/50] egl/null: add support for async flip with front buffer
rendering
This change enables the application to render into the buffer being
scanned out if the display driver doesn't support
DRM_CAP_ASYNC_PAGE_FLIP.
The egl display now tracks the DRM async flip capabilities, allowing
platform_null to always return the buffer on screen to the application
when the swap interval is set to 0, but the DRM driver doesn't support
async flip.
platform_null can be in several alternative states by the time
eglSwapInterval() is called, following is a summary of them.
1. platform_null was initialised and it has already flipped. In this
case, return to the client API a reference to the buffer on screen
2. platform_null was initialised but no back buffer was requested yet
from the client API. In this case, return a reference to the front
buffer
3. platform_null was initialised and the client API has already got
a back buffer, but no flip was scheduled. In this case, make sure
to flip and return the buffer on the screen
Note that this change also refactors the color buffers and front
buffer code. Platform null after this change has a dedicated struct
for storing front buffer DRI data and framebuffer id.
Also be noted that min_swap_interval is no longer clamped to 1 when
DRM_CAP_ASYNC_PAGE_FLIP isn't supported. This is because,
if min_swap_interval is automatically promoted to 1, Mesa EGL will de
facto prevent the application from requesting any swap interval less
than 1.
Change-Id: I3930cfcdb30bfb5358166911bcf84a78bdb4548d
Signed-off-by: Luigi Santivetti <luigi.santivetti@imgtec.com>
---
src/egl/drivers/dri2/egl_dri2.h | 8 +-
src/egl/drivers/dri2/platform_null.c | 153 +++++++++++++++++++++------
2 files changed, 129 insertions(+), 32 deletions(-)
diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h
index 6ec9ee01885..9d60d21e8fd 100644
--- a/src/egl/drivers/dri2/egl_dri2.h
+++ b/src/egl/drivers/dri2/egl_dri2.h
@@ -276,6 +276,7 @@ struct dri2_egl_display
#ifdef HAVE_NULL_PLATFORM
bool atomic_enabled;
bool in_formats_enabled;
+ bool async_flip_enabled;
struct display_output output;
#endif
@@ -434,8 +435,12 @@ struct dri2_egl_surface
#endif
bool locked;
int age;
+#ifdef HAVE_NULL_PLATFORM
+ } color_buffers[DRI2_SURFACE_NUM_COLOR_BUFFERS], *back, *current, front_buffer;
+#else
} color_buffers[DRI2_SURFACE_NUM_COLOR_BUFFERS], *back, *current;
#endif
+#endif
#ifdef HAVE_ANDROID_PLATFORM
struct ANativeWindow *window;
@@ -463,12 +468,13 @@ struct dri2_egl_surface
#endif
#ifdef HAVE_NULL_PLATFORM
- uint32_t front_fb_id;
struct swap_queue_elem swap_queue[DRI2_SURFACE_NUM_COLOR_BUFFERS];
struct swap_queue_elem *swap_data;
int swap_state;
bool mutex_init;
bool cond_init;
+ bool front_render_enabled;
+ bool front_render_init;
bool cond_init_unlock_buffer;
#endif
diff --git a/src/egl/drivers/dri2/platform_null.c b/src/egl/drivers/dri2/platform_null.c
index 701460dde4e..4969121bf37 100644
--- a/src/egl/drivers/dri2/platform_null.c
+++ b/src/egl/drivers/dri2/platform_null.c
@@ -601,6 +601,15 @@ swap_dequeue_data_finish(struct dri2_egl_surface *dri2_surf)
pthread_mutex_unlock(&dri2_surf->mutex);
}
+static void
+swap_drain_queue_data(struct dri2_egl_surface *dri2_surf)
+{
+ pthread_mutex_lock(&dri2_surf->mutex);
+ while (dri2_surf->swap_queue_idx_head != dri2_surf->swap_queue_idx_tail)
+ pthread_cond_wait(&dri2_surf->swap_unlock_buffer_cond, &dri2_surf->mutex);
+ pthread_mutex_unlock(&dri2_surf->mutex);
+}
+
static void
flip_handler(int fd, unsigned int sequence, unsigned int tv_sec,
unsigned int tv_usec, void *flip_data)
@@ -1118,15 +1127,15 @@ get_front_bo(struct dri2_egl_surface *dri2_surf)
if (dri2_surf->base.Type == EGL_WINDOW_BIT)
use |= __DRI_IMAGE_USE_SCANOUT;
- dri2_surf->front = create_image(dri2_surf, use);
- if (!dri2_surf->front)
+ dri2_surf->front_buffer.dri_image = create_image(dri2_surf, use);
+ if (!dri2_surf->front_buffer.dri_image)
return false;
if (dri2_surf->base.Type == EGL_WINDOW_BIT) {
- if (!add_fb_for_dri_image(dri2_dpy, dri2_surf->front,
- &dri2_surf->front_fb_id)) {
- dri2_dpy->image->destroyImage(dri2_surf->front);
- dri2_surf->front = NULL;
+ if (!add_fb_for_dri_image(dri2_dpy, dri2_surf->front_buffer.dri_image,
+ &dri2_surf->front_buffer.fb_id)) {
+ dri2_dpy->image->destroyImage(dri2_surf->front_buffer.dri_image);
+ dri2_surf->front_buffer.dri_image = NULL;
return false;
}
}
@@ -1330,7 +1339,7 @@ dri2_null_create_window_surface(_EGLDisplay *disp, _EGLConfig *config,
}
err = display_output_modeset(dri2_dpy->fd, &dri2_dpy->output,
- dri2_surf->front_fb_id);
+ dri2_surf->front_buffer.fb_id);
if (err) {
_eglError(EGL_BAD_NATIVE_WINDOW, "window set mode");
goto err_destroy_surface;
@@ -1360,6 +1369,60 @@ dri2_null_create_pbuffer_surface(_EGLDisplay *disp, _EGLConfig *config,
return create_surface(disp, config, EGL_PBUFFER_BIT, attrib_list);
}
+static void
+dri2_null_init_front_buffer_render(_EGLSurface *draw)
+{
+ struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
+
+ dri2_surf->front_render_init = true;
+
+ /* Drain the queue. swap_buffer_unlock_cond signals for the last time
+ * when the last back buffer in the queue went on screen and it's being
+ * tracked as current by then.
+ */
+ swap_drain_queue_data(dri2_surf);
+
+ /* If previously flipped, take a reference to the current buffer */
+ if (dri2_surf->current) {
+ assert(dri2_surf->current->dri_image);
+ dri2_surf->back = dri2_surf->current;
+
+ for (unsigned i = 0; i < DRI2_SURFACE_NUM_COLOR_BUFFERS; i++)
+ dri2_surf->color_buffers[i].age = 0;
+
+ return;
+ }
+
+ /* If the application hasn't yet fetched a back buffer, then it's not too
+ * late to use front buffer's dri_image and fb_id.
+ */
+ if (!dri2_surf->back) {
+ assert(dri2_surf->front_buffer.dri_image);
+ dri2_surf->back = &dri2_surf->front_buffer;
+
+ /* Don't need to reset buffer age since no flip was requested yet */
+
+ return;
+ }
+
+ /* In order to initialise one color buffer for front buffer rendering,
+ * one page flip must occur.
+ */
+ swap_enqueue_data(dri2_surf, get_back_buffer_id(dri2_surf), 1);
+
+ return dri2_null_init_front_buffer_render(draw);
+}
+
+static void
+dri2_null_disable_front_buffer_render(_EGLSurface *draw)
+{
+ struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
+
+ dri2_surf->front_render_enabled = false;
+ dri2_surf->front_render_init = false;
+ dri2_surf->back = NULL;
+}
+
static EGLBoolean
dri2_null_destroy_surface(_EGLDisplay *disp, _EGLSurface *surf)
{
@@ -1371,14 +1434,7 @@ dri2_null_destroy_surface(_EGLDisplay *disp, _EGLSurface *surf)
* sure we process the flip event.
*/
if (dri2_surf->swap_queue_processor) {
- pthread_mutex_lock(&dri2_surf->mutex);
-
- /* Wait for any outstanding swaps to complete */
- while (dri2_surf->swap_queue_idx_head != dri2_surf->swap_queue_idx_tail)
- pthread_cond_wait(&dri2_surf->swap_unlock_buffer_cond,
- &dri2_surf->mutex);
-
- pthread_mutex_unlock(&dri2_surf->mutex);
+ swap_drain_queue_data(dri2_surf);
pthread_cancel(dri2_surf->swap_queue_processor);
pthread_join(dri2_surf->swap_queue_processor, NULL);
}
@@ -1392,11 +1448,11 @@ dri2_null_destroy_surface(_EGLDisplay *disp, _EGLSurface *surf)
if (dri2_surf->mutex_init)
pthread_mutex_destroy(&dri2_surf->mutex);
- if (dri2_surf->front)
- dri2_dpy->image->destroyImage(dri2_surf->front);
+ if (dri2_surf->front_buffer.dri_image)
+ dri2_dpy->image->destroyImage(dri2_surf->front_buffer.dri_image);
- if (dri2_surf->front_fb_id)
- drmModeRmFB(dri2_dpy->fd, dri2_surf->front_fb_id);
+ if (dri2_surf->front_buffer.fb_id)
+ drmModeRmFB(dri2_dpy->fd, dri2_surf->front_buffer.fb_id);
for (unsigned i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) {
if (dri2_surf->color_buffers[i].fb_id)
@@ -1423,6 +1479,16 @@ dri2_null_swap_buffers(_EGLDisplay *disp, _EGLSurface *draw)
if (dri2_surf->base.Type != EGL_WINDOW_BIT)
return EGL_TRUE;
+ /* Flush and early return, no swap takes place */
+ if (dri2_surf->front_render_enabled) {
+ dri2_flush_drawable_for_swapbuffers(disp, draw);
+
+ if (!dri2_surf->front_render_init)
+ dri2_null_init_front_buffer_render(draw);
+
+ return EGL_TRUE;
+ }
+
for (unsigned i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++)
if (dri2_surf->color_buffers[i].age > 0)
dri2_surf->color_buffers[i].age++;
@@ -1465,6 +1531,22 @@ dri2_null_query_buffer_age(_EGLDisplay *disp, _EGLSurface *surface)
static EGLBoolean
dri2_null_swap_interval(_EGLDisplay *dpy, _EGLSurface *draw, EGLint interval)
{
+ struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
+ struct dri2_egl_display *dri2_dpy =
+ dri2_egl_display(dri2_surf->base.Resource.Display);
+
+ /* dri2_dpy tracks whether the display driver is async flip capable.
+ * If it isn't, enable front buffer rendering when swap interval
+ * 0 is passed in from the application.
+ */
+ if (!interval && !dri2_dpy->async_flip_enabled) {
+ if (!dri2_surf->front_render_enabled)
+ dri2_surf->front_render_enabled = true;
+ } else {
+ if (dri2_surf->front_render_enabled)
+ dri2_null_disable_front_buffer_render(draw);
+ }
+
_eglLog(_EGL_DEBUG, "DRI2: set swap interval to %d", interval);
draw->SwapInterval = interval;
return EGL_TRUE;
@@ -1502,7 +1584,7 @@ dri2_null_image_get_buffers(__DRIdrawable *driDrawable, unsigned int format,
if (buffer_mask & __DRI_IMAGE_BUFFER_FRONT) {
buffers->image_mask |= __DRI_IMAGE_BUFFER_FRONT;
- buffers->front = dri2_surf->front;
+ buffers->front = dri2_surf->front_buffer.dri_image;
}
if (buffer_mask & __DRI_IMAGE_BUFFER_BACK) {
@@ -1637,18 +1719,27 @@ dri2_null_setup_swap_interval(_EGLDisplay *disp)
dri2_setup_swap_interval(disp, swap_max_interval);
err = drmGetCap(dri2_dpy->fd, DRM_CAP_ASYNC_PAGE_FLIP, &value);
- if (err || value == 0)
- dri2_dpy->min_swap_interval = 1;
+ if (err || value == 0) {
- /**
- * drm/atomic: Reject FLIP_ASYNC unconditionally
- * upstream f2cbda2dba11de868759cae9c0d2bab5b8411406
- *
- * Only allow swap interval 0 for legacy DRM/KMS and let
- * the app be aware that swap interval is clamped to 1.
- */
- if (dri2_dpy->atomic_enabled)
- dri2_dpy->min_swap_interval = 1;
+ /* DRM/KMS does not support async page flip. In order to support
+ * swap interval 0, use front buffer rendering.
+ */
+ _eglLog(_EGL_DEBUG,
+ "drm async flip not supported, use front buffer");
+ } else {
+
+ /* drm/atomic: Reject FLIP_ASYNC unconditionally
+ * upstream f2cbda2dba11de868759cae9c0d2bab5b8411406
+ *
+ * Legacy DRM/KMS can use DRM_MODE_PAGE_FLIP_ASYNC, for atomic
+ * drivers fallback to front buffer rendering.
+ */
+ if (dri2_dpy->atomic_enabled)
+ _eglLog(_EGL_DEBUG,
+ "async flip not supported by atomic, use front buffer");
+ else
+ dri2_dpy->async_flip_enabled = true;
+ }
}
EGLBoolean
--
2.17.1
@@ -0,0 +1,229 @@
From 8ea569933388752a39e859989b69ab2f09f68309 Mon Sep 17 00:00:00 2001
From: Brendan King <Brendan.King@imgtec.com>
Date: Fri, 21 Aug 2020 12:13:28 +0100
Subject: [PATCH 49/50] gbm: add pbuffer support
The EGL backend GLX provider for XWayland may get the EGL configs it
uses to generate the GLX ones from GBM. That platform doesn't support
pbuffers. When the client tries to match GLX configs with the DRI ones,
a mismatch in the pbuffer attributes will result in the GLX config
being rejected.
Although support for creating pbuffers has been added, this isn't
required when using the EGL backend GLX provider, as indirect GLX
isn't supported.
---
src/egl/drivers/dri2/egl_dri2.h | 3 +
src/egl/drivers/dri2/platform_drm.c | 110 +++++++++++++++++++++++++---
2 files changed, 103 insertions(+), 10 deletions(-)
diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h
index 9d60d21e8fd..2292f29772d 100644
--- a/src/egl/drivers/dri2/egl_dri2.h
+++ b/src/egl/drivers/dri2/egl_dri2.h
@@ -462,6 +462,9 @@ struct dri2_egl_surface
/* surfaceless and device */
__DRIimage *front;
unsigned int visual;
+#ifdef HAVE_DRM_PLATFORM
+ struct gbm_bo *front_bo;
+#endif
#ifdef HAVE_WAYLAND_PLATFORM
void *swrast_front;
diff --git a/src/egl/drivers/dri2/platform_drm.c b/src/egl/drivers/dri2/platform_drm.c
index 2944a5d7ad4..7fb8d2376d8 100644
--- a/src/egl/drivers/dri2/platform_drm.c
+++ b/src/egl/drivers/dri2/platform_drm.c
@@ -41,6 +41,38 @@
#include "egl_dri2.h"
#include "loader.h"
+static bool
+dri2_drm_alloc_front_image(struct dri2_egl_surface *dri2_surf)
+{
+ if (!dri2_surf->front_bo) {
+ struct dri2_egl_display *dri2_dpy =
+ dri2_egl_display(dri2_surf->base.Resource.Display);
+
+ struct gbm_surface *surf = &dri2_surf->gbm_surf->base;
+
+ dri2_surf->front_bo = gbm_bo_create(&dri2_dpy->gbm_dri->base,
+ surf->width,
+ surf->height,
+ surf->format,
+ surf->flags);
+ if (!dri2_surf->front_bo) {
+ _eglError(EGL_BAD_ALLOC, "failed to allocate front buffer");
+ return false;
+ }
+ }
+
+ return true;
+}
+
+static void
+dri2_drm_free_front_image(struct dri2_egl_surface *dri2_surf)
+{
+ if (dri2_surf->front_bo) {
+ gbm_bo_destroy(dri2_surf->front_bo);
+ dri2_surf->front_bo = NULL;
+ }
+}
+
static struct gbm_bo *
lock_front_buffer(struct gbm_surface *_surf)
{
@@ -138,8 +170,8 @@ dri2_drm_config_is_compatible(struct dri2_egl_display *dri2_dpy,
}
static _EGLSurface *
-dri2_drm_create_window_surface(_EGLDisplay *disp, _EGLConfig *conf,
- void *native_surface, const EGLint *attrib_list)
+dri2_drm_create_surface(_EGLDisplay *disp, EGLint type, _EGLConfig *conf,
+ void *native_surface, const EGLint *attrib_list)
{
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
struct dri2_egl_config *dri2_conf = dri2_egl_config(conf);
@@ -154,11 +186,25 @@ dri2_drm_create_window_surface(_EGLDisplay *disp, _EGLConfig *conf,
return NULL;
}
- if (!dri2_init_surface(&dri2_surf->base, disp, EGL_WINDOW_BIT, conf,
+ if (!dri2_init_surface(&dri2_surf->base, disp, type, conf,
attrib_list, false, native_surface))
goto cleanup_surf;
- config = dri2_get_dri_config(dri2_conf, EGL_WINDOW_BIT,
+ if (type == EGL_PBUFFER_BIT) {
+ struct gbm_device *gbm = disp->PlatformDisplay;
+ _EGLSurface *surf = &dri2_surf->base;
+
+ assert(!surface);
+
+ surface = gbm_surface_create(gbm, surf->Width, surf->Height,
+ conf->NativeVisualID, GBM_BO_USE_RENDERING);
+ if (!surface) {
+ _eglError(EGL_BAD_ALLOC, "Failed to allocate pbuffer GBM surface");
+ goto cleanup_surf;
+ }
+ }
+
+ config = dri2_get_dri_config(dri2_conf, type,
dri2_surf->base.GLColorspace);
if (!config) {
@@ -183,11 +229,22 @@ dri2_drm_create_window_surface(_EGLDisplay *disp, _EGLConfig *conf,
return &dri2_surf->base;
cleanup_surf:
+ if (type == EGL_PBUFFER_BIT && surface != NULL)
+ gbm_surface_destroy(surface);
+
free(dri2_surf);
return NULL;
}
+static _EGLSurface *
+dri2_drm_create_window_surface(_EGLDisplay *disp, _EGLConfig *conf,
+ void *native_surface, const EGLint *attrib_list)
+{
+ return dri2_drm_create_surface(disp, EGL_WINDOW_BIT, conf,
+ native_surface, attrib_list);
+}
+
static _EGLSurface *
dri2_drm_create_pixmap_surface(_EGLDisplay *disp, _EGLConfig *conf,
void *native_window, const EGLint *attrib_list)
@@ -202,6 +259,14 @@ dri2_drm_create_pixmap_surface(_EGLDisplay *disp, _EGLConfig *conf,
return NULL;
}
+static _EGLSurface *
+dri2_drm_create_pbuffer_surface(_EGLDisplay *disp, _EGLConfig *conf,
+ const EGLint *attrib_list)
+{
+ return dri2_drm_create_surface(disp, EGL_PBUFFER_BIT, conf,
+ NULL, attrib_list);
+}
+
static EGLBoolean
dri2_drm_destroy_surface(_EGLDisplay *disp, _EGLSurface *surf)
{
@@ -217,6 +282,11 @@ dri2_drm_destroy_surface(_EGLDisplay *disp, _EGLSurface *surf)
dri2_egl_surface_free_local_buffers(dri2_surf);
+ dri2_drm_free_front_image(dri2_surf);
+
+ if (surf->Type == EGL_PBUFFER_BIT)
+ gbm_surface_destroy(&dri2_surf->gbm_surf->base);
+
dri2_fini_surface(surf);
free(surf);
@@ -400,12 +470,27 @@ dri2_drm_image_get_buffers(__DRIdrawable *driDrawable,
struct dri2_egl_surface *dri2_surf = loaderPrivate;
struct gbm_dri_bo *bo;
- if (get_back_bo(dri2_surf) < 0)
- return 0;
+ buffers->image_mask = 0;
+ buffers->front = NULL;
+ buffers->back = NULL;
- bo = gbm_dri_bo(dri2_surf->back->bo);
- buffers->image_mask = __DRI_IMAGE_BUFFER_BACK;
- buffers->back = bo->image;
+ if (buffer_mask & __DRI_IMAGE_BUFFER_FRONT) {
+ if (!dri2_drm_alloc_front_image(dri2_surf))
+ return 0;
+
+ bo = gbm_dri_bo(dri2_surf->front_bo);
+ buffers->image_mask |= __DRI_IMAGE_BUFFER_FRONT;
+ buffers->front = bo->image;
+ }
+
+ if (buffer_mask & __DRI_IMAGE_BUFFER_BACK) {
+ if (get_back_bo(dri2_surf) < 0)
+ return 0;
+
+ bo = gbm_dri_bo(dri2_surf->back->bo);
+ buffers->image_mask |= __DRI_IMAGE_BUFFER_BACK;
+ buffers->back = bo->image;
+ }
return 1;
}
@@ -423,6 +508,9 @@ dri2_drm_swap_buffers(_EGLDisplay *disp, _EGLSurface *draw)
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
struct dri2_egl_surface *dri2_surf = dri2_egl_surface(draw);
+ if (dri2_surf->base.Type != EGL_WINDOW_BIT)
+ return EGL_TRUE;
+
if (!dri2_dpy->flush) {
dri2_dpy->core->swapBuffers(dri2_surf->dri_drawable);
return EGL_TRUE;
@@ -646,7 +734,8 @@ drm_add_configs_for_visuals(_EGLDisplay *disp)
};
dri2_conf = dri2_add_config(disp, dri2_dpy->driver_configs[i],
- config_count + 1, EGL_WINDOW_BIT, attr_list, NULL, NULL);
+ config_count + 1, EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
+ attr_list, NULL, NULL);
if (dri2_conf) {
if (dri2_conf->base.ConfigID == config_count + 1)
config_count++;
@@ -670,6 +759,7 @@ static const struct dri2_egl_display_vtbl dri2_drm_display_vtbl = {
.authenticate = dri2_drm_authenticate,
.create_window_surface = dri2_drm_create_window_surface,
.create_pixmap_surface = dri2_drm_create_pixmap_surface,
+ .create_pbuffer_surface = dri2_drm_create_pbuffer_surface,
.destroy_surface = dri2_drm_destroy_surface,
.create_image = dri2_drm_create_image_khr,
.swap_buffers = dri2_drm_swap_buffers,
--
2.17.1
@@ -0,0 +1,84 @@
From b8488580d9d7e034aa39426f6ef161035e56915d Mon Sep 17 00:00:00 2001
From: Luigi Santivetti <luigi.santivetti@imagination.corp-partner.google.com>
Date: Mon, 25 Jan 2021 11:05:49 +0000
Subject: [PATCH 50/50] egl/null: expose EXT_yuv_surface support
---
src/egl/drivers/dri2/platform_null.c | 28 +++++++++++++++++++++++++---
1 file changed, 25 insertions(+), 3 deletions(-)
diff --git a/src/egl/drivers/dri2/platform_null.c b/src/egl/drivers/dri2/platform_null.c
index 4969121bf37..9830b73d704 100644
--- a/src/egl/drivers/dri2/platform_null.c
+++ b/src/egl/drivers/dri2/platform_null.c
@@ -106,6 +106,12 @@ static const struct dri2_null_format {
.rgba_shifts = { 11, 5, 0, -1 },
.rgba_sizes = { 5, 6, 5, 0 },
},
+ {
+ .drm_format = DRM_FORMAT_YUYV,
+ .dri_image_format = __DRI_IMAGE_FORMAT_YUYV,
+ .rgba_shifts = { -1, -1, -1, -1 },
+ .rgba_sizes = { 0, 0, 0, 0 },
+ },
};
@@ -1595,6 +1601,17 @@ dri2_null_image_get_buffers(__DRIdrawable *driDrawable, unsigned int format,
return 1;
}
+static unsigned
+dri2_null_get_capability(void *loaderPrivate, enum dri_loader_cap cap)
+{
+ switch (cap) {
+ case DRI_LOADER_CAP_YUV_SURFACE_IMG:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
static void
dri2_null_flush_front_buffer(__DRIdrawable * driDrawable, void *loaderPrivate)
{
@@ -1603,10 +1620,11 @@ dri2_null_flush_front_buffer(__DRIdrawable * driDrawable, void *loaderPrivate)
}
static const __DRIimageLoaderExtension image_loader_extension = {
- .base = { __DRI_IMAGE_LOADER, 1 },
+ .base = { __DRI_IMAGE_LOADER, 2 },
.getBuffers = dri2_null_image_get_buffers,
.flushFrontBuffer = dri2_null_flush_front_buffer,
+ .getCapability = dri2_null_get_capability,
};
static const __DRIextension *image_loader_extensions[] = {
@@ -1688,6 +1706,7 @@ dri2_null_add_configs_for_formats(_EGLDisplay *disp)
for (unsigned i = 0; dri2_dpy->driver_configs[i]; i++) {
struct dri2_egl_config *dri2_conf;
+ EGLint surface_type;
int format_idx;
format_idx = format_idx_get_from_config(dri2_dpy,
@@ -1698,10 +1717,13 @@ dri2_null_add_configs_for_formats(_EGLDisplay *disp)
if (!(dri2_dpy->output.formats & (1 << format_idx)))
continue;
+ surface_type = EGL_WINDOW_BIT;
+ if (dri2_null_formats[format_idx].drm_format != DRM_FORMAT_YUYV)
+ surface_type |= EGL_PBUFFER_BIT;
+
dri2_conf = dri2_add_config(disp,
dri2_dpy->driver_configs[i], count + 1,
- EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
- NULL, NULL, NULL);
+ surface_type, NULL, NULL, NULL);
if (dri2_conf)
count++;
}
--
2.17.1
+7
View File
@@ -351,6 +351,13 @@ config BR2_PACKAGE_MESA3D_DRI_DRIVER_RADEON
help
Legacy Radeon driver for R100 series GPUs.
config BR2_PACKAGE_MESA3D_DRI_DRIVER_PVR
bool "DRI pvr driver"
depends on BR2_PACKAGE_IMG_GPU_POWERVR
select BR2_PACKAGE_MESA3D_DRI_DRIVER
help
Support for Imagination PowerVR GPUs.
comment "Vulkan drivers"
config BR2_PACKAGE_MESA3D_VULKAN_DRIVER_INTEL
+3 -3
View File
@@ -1,6 +1,6 @@
# From https://lists.freedesktop.org/archives/mesa-announce/2021-September/000644.html
sha256 5cd32f5d089dca75300578a3d771a656eaed652090573a2655fe4e7022d56bfc mesa-21.1.8.tar.xz
sha512 80fcf2b1d59b49e384e9aa1ae63a3ce709833059af1ffd8eb821054c1976709134098cfc79fac1578a2f08a003223f1c96b38e2e650c5be49821c6f2fe1047af mesa-21.1.8.tar.xz
# From https://lists.freedesktop.org/archives/mesa-announce/2021-March/000624.html
sha256 379fc984459394f2ab2d84049efdc3a659869dc1328ce72ef0598506611712bb mesa-21.0.1.tar.xz
sha512 b31b78778b6092dfaf0712f90de3074217574389c4236f8379c127739874f6bd1b47883140a26445d25e58df87e6207278efd048453096ee710d334b1dcfe419 mesa-21.0.1.tar.xz
# License
sha256 998437f3f75f0c542046f83c1cb349408122268168fb13eb4ae6967aa18b7d98 docs/license.rst
+2 -7
View File
@@ -5,7 +5,7 @@
################################################################################
# When updating the version, please also update mesa3d-headers
MESA3D_VERSION = 21.1.8
MESA3D_VERSION = 21.0.1
MESA3D_SOURCE = mesa-$(MESA3D_VERSION).tar.xz
MESA3D_SITE = https://archive.mesa3d.org
MESA3D_LICENSE = MIT, SGI, Khronos
@@ -76,12 +76,6 @@ MESA3D_CONF_OPTS += \
-Dgallium-xa=disabled
endif
ifeq ($(BR2_ARM_CPU_HAS_NEON),y)
MESA3D_CONF_OPTS += -Dgallium-vc4-neon=auto
else
MESA3D_CONF_OPTS += -Dgallium-vc4-neon=disabled
endif
# Drivers
#Gallium Drivers
@@ -106,6 +100,7 @@ MESA3D_DRI_DRIVERS-$(BR2_PACKAGE_MESA3D_DRI_DRIVER_I915) += i915
MESA3D_DRI_DRIVERS-$(BR2_PACKAGE_MESA3D_DRI_DRIVER_I965) += i965
MESA3D_DRI_DRIVERS-$(BR2_PACKAGE_MESA3D_DRI_DRIVER_NOUVEAU) += nouveau
MESA3D_DRI_DRIVERS-$(BR2_PACKAGE_MESA3D_DRI_DRIVER_RADEON) += r100
MESA3D_DRI_DRIVERS-$(BR2_PACKAGE_MESA3D_DRI_DRIVER_PVR) += pvr
# Vulkan Drivers
MESA3D_VULKAN_DRIVERS-$(BR2_PACKAGE_MESA3D_VULKAN_DRIVER_INTEL) += intel
+1
View File
@@ -9,3 +9,4 @@ source "package/starfive/v4l2_test/Config.in"
source "package/starfive/mailbox-test/Config.in"
source "package/starfive/e24-test/Config.in"
source "package/starfive/stfisp_setfile/Config.in.host"
source "package/starfive/img-gpu-powervr/Config.in"
@@ -0,0 +1,97 @@
comment "img-gpu-powervr needs a glibc toolchain"
depends on BR2_riscv
depends on !BR2_TOOLCHAIN_USES_GLIBC
config BR2_PACKAGE_IMG_GPU_POWERVR
bool "img-gpu-powervr"
# Pre-built binaries only available for RISCV
depends on BR2_riscv
# Library binaries are linked against libc.so.6
depends on BR2_TOOLCHAIN_USES_GLIBC
# Library binaries are linked against libdrm.so.2, except framebuffer
# output on RISCV
select BR2_PACKAGE_LIBDRM if !(BR2_riscv && BR2_PACKAGE_IMG_GPU_POWERVR_OUTPUT_FB)
select BR2_PACKAGE_HAS_LIBEGL
select BR2_PACKAGE_HAS_LIBGLES
select BR2_PACKAGE_HAS_LIBOPENCL
select BR2_PACKAGE_HAS_LIBVULKAN
select BR2_PACKAGE_MESA3D
select BR2_PACKAGE_MESA3D_OPENGL_EGL
select BR2_PACKAGE_MESA3D_DRI_DRIVER_PVR
help
Userspace libraries for Imagination PowerGPU GPU on StarFive platforms
It contains libraries and headers for GLES, OpenCL, and
Vulkan. It also contains a DRI plugin for X11. It also
contains a plugin for DirectFB-1.4.0.
This library is provided by StarFive as-is and doesn't have
an upstream.
if BR2_PACKAGE_IMG_GPU_POWERVR
choice
prompt "Output option"
help
There are two versions of this library: one for
direct framebuffer access, one for X11 rendering.
Choose here which version to install.
config BR2_PACKAGE_IMG_GPU_POWERVR_OUTPUT_X11
bool "X11"
depends on BR2_PACKAGE_XORG7
# The i.MX8 blob doesn't support X11 output
depends on !BR2_PACKAGE_FREESCALE_IMX_PLATFORM_IMX8M
select BR2_PACKAGE_XLIB_LIBXDAMAGE
select BR2_PACKAGE_XLIB_LIBXEXT
select BR2_PACKAGE_XLIB_LIBXFIXES
comment "X11 backend needs Xorg package"
depends on !BR2_PACKAGE_XORG7
config BR2_PACKAGE_IMG_GPU_POWERVR_OUTPUT_FB
bool "Framebuffer"
config BR2_PACKAGE_IMG_GPU_POWERVR_OUTPUT_WL
bool "Wayland"
select BR2_PACKAGE_WAYLAND
select BR2_PACKAGE_HAS_LIBEGL_WAYLAND
endchoice
config BR2_PACKAGE_IMG_GPU_POWERVR_OUTPUT
string
default "x11" if BR2_PACKAGE_IMG_GPU_POWERVR_OUTPUT_X11
default "fb" if BR2_PACKAGE_IMG_GPU_POWERVR_OUTPUT_FB
default "wayland" if BR2_PACKAGE_IMG_GPU_POWERVR_OUTPUT_WL
config BR2_PACKAGE_PROVIDES_LIBEGL
default "img-gpu-powervr"
config BR2_PACKAGE_PROVIDES_LIBGLES
default "img-gpu-powervr"
config BR2_PACKAGE_PROVIDES_LIBOPENCL
default "img-gpu-powervr"
config BR2_PACKAGE_PROVIDES_LIBVULKAN
default "img-gpu-powervr"
config BR2_PACKAGE_IMG_GPU_POWERVR_EXAMPLES
bool "install examples"
depends on BR2_INSTALL_LIBSTDCPP
help
Copy the PowerVR examples to the target.
Warning: examples take approximately 150 MB of disk space.
comment "img-gpu-powervr-examples need a toolchain w/ C++ support"
depends on !BR2_INSTALL_LIBSTDCPP
config BR2_PACKAGE_IMG_GPU_POWERVR_GMEM_INFO
bool "install gmem_info tool"
help
Copy the gmem_info tool to the target which provides
information about GPU memory consumption.
endif
@@ -0,0 +1,5 @@
# Locally calculated
# sha256 1324b1aaf190110b80ad9a6f6533f4f50dce9e9ab8d49d8503f59764b151d219 imx-gpu-viv-6.4.3.p2.0-aarch32.bin
# sha256 003c30baefb1655790b475c3cdfa5cefbf81ea89ef37c6649b64f151dd23a52e imx-gpu-viv-6.4.3.p2.0-aarch64.bin
# sha256 ea58636bf34f589048fcd46e38497c47229fde8498df086ff5fb52f9ef8e15ee COPYING
# sha256 50099e283cfd307f84f159aeb1a6f462351320273dbcdb80d7f2c9db0494b71c EULA
@@ -0,0 +1,99 @@
################################################################################
#
# img-gpu-powervr
#
# This file is for Imagination PowerVR GPU, modified from freescale-imx/imx-gpu-viv
#
# Windsome Zeng <windsome.zeng@starfivetech.com>
#
################################################################################
# ifeq ($(BR2_aarch64),y)
# IMG_GPU_POWERVR_VERSION = 6.4.3.p2.0-aarch64
# else
# IMG_GPU_POWERVR_VERSION = 6.4.3.p2.0-aarch32
# endif
# IMG_GPU_POWERVR_SITE = $(FREESCALE_IMX_SITE)
# IMG_GPU_POWERVR_SOURCE = imx-gpu-viv-$(IMG_GPU_POWERVR_VERSION).bin
IMG_GPU_POWERVR_INSTALL_STAGING = YES
IMG_GPU_POWERVR_LICENSE = Strictly Confidential
IMG_GPU_POWERVR_REDISTRIBUTE = NO
IMG_GPU_POWERVR_PROVIDES = libgles libopencl
IMG_GPU_POWERVR_LIB_TARGET = $(call qstrip,$(BR2_PACKAGE_IMG_GPU_POWERVR_OUTPUT))
ifeq ($(IMG_GPU_POWERVR_LIB_TARGET),x11)
# The libGAL.so library provided by imx-gpu-viv uses X functions. Packages
# may want to link against libGAL.so (QT5 Base with OpenGL and X support
# does so). For this to work we need build dependencies to libXdamage,
# libXext and libXfixes so that X functions used in libGAL.so are referenced.
IMG_GPU_POWERVR_DEPENDENCIES += xlib_libXdamage xlib_libXext xlib_libXfixes
endif
# Libraries are linked against libdrm, except framebuffer output on ARM
ifneq ($(IMG_GPU_POWERVR_LIB_TARGET)$(BR2_riscv),fby)
IMG_GPU_POWERVR_DEPENDENCIES += libdrm
endif
ifeq ($(IMG_GPU_POWERVR_LIB_TARGET),wayland)
IMG_GPU_POWERVR_DEPENDENCIES += wayland
endif
# define IMG_GPU_POWERVR_EXTRACT_CMDS
# $(call FREESCALE_IMX_EXTRACT_HELPER,$(IMG_GPU_POWERVR_DL_DIR)/$(IMG_GPU_POWERVR_SOURCE))
# endef
# ifeq ($(IMG_GPU_POWERVR_LIB_TARGET),fb)
# define IMG_GPU_POWERVR_FIXUP_PKGCONFIG
# ln -sf egl_linuxfb.pc $(@D)/gpu-core/usr/lib/pkgconfig/egl.pc
# endef
# else ifeq ($(IMG_GPU_POWERVR_LIB_TARGET),wayland)
# define IMG_GPU_POWERVR_FIXUP_PKGCONFIG
# ln -sf egl_wayland.pc $(@D)/gpu-core/usr/lib/pkgconfig/egl.pc
# endef
# else ifeq ($(IMG_GPU_POWERVR_LIB_TARGET),x11)
# define IMG_GPU_POWERVR_FIXUP_PKGCONFIG
# $(foreach lib,egl gbm glesv1_cm glesv2 vg, \
# ln -sf $(lib)_x11.pc $(@D)/gpu-core/usr/lib/pkgconfig/$(lib).pc
# )
# endef
# endif
# Instead of building, we fix up the inconsistencies that exist
# in the upstream archive here. We also remove unused backend files.
# Make sure these commands are idempotent.
# define IMG_GPU_POWERVR_BUILD_CMDS
# cp -dpfr $(@D)/gpu-core/usr/lib/$(IMG_GPU_POWERVR_LIB_TARGET)/* $(@D)/gpu-core/usr/lib/
# $(foreach backend,fb x11 wayland, \
# $(RM) -r $(@D)/gpu-core/usr/lib/$(backend)
# )
# $(IMG_GPU_POWERVR_FIXUP_PKGCONFIG)
# endef
#
# define IMG_GPU_POWERVR_INSTALL_STAGING_CMDS
# cp -r $(@D)/gpu-core/usr/* $(STAGING_DIR)/usr
# endef
# ifeq ($(BR2_PACKAGE_IMG_GPU_POWERVR_EXAMPLES),y)
# define IMG_GPU_POWERVR_INSTALL_EXAMPLES
# mkdir -p $(TARGET_DIR)/usr/share/examples/
# cp -r $(@D)/gpu-demos/opt/* $(TARGET_DIR)/usr/share/examples/
# endef
# endif
#
# ifeq ($(BR2_PACKAGE_IMG_GPU_POWERVR_GMEM_INFO),y)
# define IMG_GPU_POWERVR_INSTALL_GMEM_INFO
# cp -dpfr $(@D)/gpu-tools/gmem-info/usr/bin/* $(TARGET_DIR)/usr/bin/
# endef
# endif
# define IMG_GPU_POWERVR_INSTALL_TARGET_CMDS
# $(IMG_GPU_POWERVR_INSTALL_EXAMPLES)
# $(IMG_GPU_POWERVR_INSTALL_GMEM_INFO)
# cp -a $(@D)/gpu-core/usr/lib $(TARGET_DIR)/usr
# $(INSTALL) -D -m 0644 $(@D)/gpu-core/etc/Vivante.icd $(TARGET_DIR)/etc/OpenCL/vendors/Vivante.icd
# endef
$(eval $(generic-package))
@@ -0,0 +1,29 @@
From 0f85e6d2e358c530dd1136d71bfd306cd64c4305 Mon Sep 17 00:00:00 2001
From: Brendan King <Brendan.King@imgtec.com>
Date: Tue, 4 Sep 2018 14:59:09 +0100
Subject: [PATCH 1/2] backend-drm: disable "bo geometry out of bounds" message
The message was being printed repeatedly whilst running an opaque
windowed application, because the application wasn't within the
framebuffer dimension limits.
---
libweston/backend-drm/fb.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/libweston/backend-drm/fb.c b/libweston/backend-drm/fb.c
index e7349c4b..da781015 100644
--- a/libweston/backend-drm/fb.c
+++ b/libweston/backend-drm/fb.c
@@ -343,7 +343,9 @@ drm_fb_get_from_dmabuf(struct linux_dmabuf_buffer *dmabuf,
fb->width > backend->max_width ||
backend->min_height > fb->height ||
fb->height > backend->max_height) {
+#if 0
weston_log("bo geometry out of bounds\n");
+#endif
goto err_free;
}
--
2.17.1
@@ -0,0 +1,63 @@
From 4a6e5e4ac0a2c63eb78e442bc34a0ee6a0f470d4 Mon Sep 17 00:00:00 2001
From: Brendan King <Brendan.King@imgtec.com>
Date: Thu, 15 Apr 2021 19:30:02 +0100
Subject: [PATCH 3/3] libweston: reduce checks for dmabufs with DRM modifiers
If the buffer associated with a dmabuf has a DRM modifier, then
checking the stride and stride*height against the size of the
dambuf may not make sense, so skip the check.
IMG lossy framebuffers have a smaller size than that of the
equivalent linear framebuffer.
---
libweston/linux-dmabuf.c | 33 ++++++++++++++++++---------------
1 file changed, 18 insertions(+), 15 deletions(-)
diff --git a/libweston/linux-dmabuf.c b/libweston/linux-dmabuf.c
index 796e9826..0bbfe480 100644
--- a/libweston/linux-dmabuf.c
+++ b/libweston/linux-dmabuf.c
@@ -240,22 +240,25 @@ params_create_common(struct wl_client *client,
goto err_out;
}
- if (buffer->attributes.offset[i] + buffer->attributes.stride[i] > size) {
- wl_resource_post_error(params_resource,
- ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_OUT_OF_BOUNDS,
- "invalid stride %i for plane %i",
- buffer->attributes.stride[i], i);
- goto err_out;
- }
+ if (buffer->attributes.modifier[i] == DRM_FORMAT_MOD_INVALID ||
+ buffer->attributes.modifier[i] == DRM_FORMAT_MOD_LINEAR) {
+ if (buffer->attributes.offset[i] + buffer->attributes.stride[i] > size) {
+ wl_resource_post_error(params_resource,
+ ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_OUT_OF_BOUNDS,
+ "invalid stride %i for plane %i",
+ buffer->attributes.stride[i], i);
+ goto err_out;
+ }
- /* Only valid for first plane as other planes might be
- * sub-sampled according to fourcc format */
- if (i == 0 &&
- buffer->attributes.offset[i] + buffer->attributes.stride[i] * height > size) {
- wl_resource_post_error(params_resource,
- ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_OUT_OF_BOUNDS,
- "invalid buffer stride or height for plane %i", i);
- goto err_out;
+ /* Only valid for first plane as other planes might be
+ * sub-sampled according to fourcc format */
+ if (i == 0 &&
+ buffer->attributes.offset[i] + buffer->attributes.stride[i] * height > size) {
+ wl_resource_post_error(params_resource,
+ ZWP_LINUX_BUFFER_PARAMS_V1_ERROR_OUT_OF_BOUNDS,
+ "invalid buffer stride or height for plane %i", i);
+ goto err_out;
+ }
}
}
--
2.17.1
+2 -2
View File
@@ -40,11 +40,11 @@ config BR2_PACKAGE_WESTON_DEFAULT_FBDEV
config BR2_PACKAGE_WESTON_DEFAULT_DRM
bool "drm"
depends on BR2_PACKAGE_MESA3D_OPENGL_EGL || BR2_PACKAGE_IMX_GPU_VIV_OUTPUT_WL
depends on BR2_PACKAGE_MESA3D_OPENGL_EGL || BR2_PACKAGE_IMX_GPU_VIV_OUTPUT_WL || BR2_PACKAGE_IMG_GPU_POWERVR_OUTPUT_WL
select BR2_PACKAGE_WESTON_DRM
comment "drm backend needs mesa3d w/ EGL driver"
depends on !BR2_PACKAGE_MESA3D_OPENGL_EGL && !BR2_PACKAGE_IMX_GPU_VIV_OUTPUT_WL
depends on !BR2_PACKAGE_MESA3D_OPENGL_EGL && !BR2_PACKAGE_IMX_GPU_VIV_OUTPUT_WL && !BR2_PACKAGE_IMG_GPU_POWERVR_OUTPUT_WL
config BR2_PACKAGE_WESTON_DEFAULT_X11
bool "X11"