mirror of
https://github.com/thead-yocto-mirror/meta-riscv
synced 2026-06-21 08:52:24 +02:00
mesa-pvr: add patches from visionfive2 buildroot
This is a simply copy/paste of all existing patches from the VisionFive2 buildroot configuration.
This commit is contained in:
committed by
Khem Raj
parent
0c9bf7388f
commit
235a2c600a
4692
recipes-graphics/mesa/mesa-pvr/0001-Add-pvr-dri-driver.patch
Normal file
4692
recipes-graphics/mesa/mesa-pvr/0001-Add-pvr-dri-driver.patch
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,34 @@
|
||||
From 184d3da84d449bc05511cb857cc843285dde4b63 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/67] 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 08eeb61504b..c7e561ef2e4 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.25.1
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
From fec4f46f7cedb6b3e90bf88c3efc3cd5da0d9131 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/67] 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 66dc0927cb7..510289403d2 100644
|
||||
--- a/include/GL/internal/dri_interface.h
|
||||
+++ b/include/GL/internal/dri_interface.h
|
||||
@@ -1367,6 +1367,9 @@ struct __DRIdri2ExtensionRec {
|
||||
#define __DRI_IMAGE_FORMAT_ABGR16161616F 0x1015
|
||||
#define __DRI_IMAGE_FORMAT_SXRGB8 0x1016
|
||||
#define __DRI_IMAGE_FORMAT_ABGR16161616 0x1017
|
||||
+#define __DRI_IMAGE_FORMAT_ARGB4444 0x1018
|
||||
+#define __DRI_IMAGE_FORMAT_YVU444_PACK10_IMG 0x1019
|
||||
+#define __DRI_IMAGE_FORMAT_BGR888 0x101a
|
||||
|
||||
#define __DRI_IMAGE_USE_SHARE 0x0001
|
||||
#define __DRI_IMAGE_USE_SCANOUT 0x0002
|
||||
@@ -1397,6 +1400,7 @@ struct __DRIdri2ExtensionRec {
|
||||
#define __DRI_IMAGE_FOURCC_SABGR8888 0x84324258
|
||||
#define __DRI_IMAGE_FOURCC_SXRGB8888 0x85324258
|
||||
#define __DRI_IMAGE_FOURCC_RGBA16161616 0x38344152 /* fourcc_code('R', 'A', '4', '8' ) */
|
||||
+#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 cd3ce8a8c60..57657592a38 100644
|
||||
--- a/include/drm-uapi/drm_fourcc.h
|
||||
+++ b/include/drm-uapi/drm_fourcc.h
|
||||
@@ -344,6 +344,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 9e5a55a287c..eee28eb4726 100644
|
||||
--- a/src/egl/drivers/dri2/egl_dri2.c
|
||||
+++ b/src/egl/drivers/dri2/egl_dri2.c
|
||||
@@ -2652,6 +2652,7 @@ dri2_num_fourcc_format_planes(EGLint format)
|
||||
case DRM_FORMAT_Y410:
|
||||
case DRM_FORMAT_Y412:
|
||||
case DRM_FORMAT_Y416:
|
||||
+ 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.25.1
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
From e66cd64b65e86a23807260a9a0c73f1355715314 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/67] 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 929b40bbd4a..962170bc58e 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 6accff1b231..d063930bd81 100644
|
||||
--- a/src/mapi/glapi/gen/static_data.py
|
||||
+++ b/src/mapi/glapi/gen/static_data.py
|
||||
@@ -1689,6 +1689,8 @@ offsets = {
|
||||
"VertexAttribs2hvNV": 1653,
|
||||
"VertexAttribs3hvNV": 1654,
|
||||
"VertexAttribs4hvNV": 1655,
|
||||
+ "TexPageCommitmentEXT": 1656,
|
||||
+ "TexturePageCommitmentEXT" : 1657,
|
||||
}
|
||||
|
||||
functions = [
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
From 4a1be491de2ea78be95dc4cf08af4b1da5e16d91 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/67] 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 962170bc58e..e586b0ec19b 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 d063930bd81..79b8f19cb75 100644
|
||||
--- a/src/mapi/glapi/gen/static_data.py
|
||||
+++ b/src/mapi/glapi/gen/static_data.py
|
||||
@@ -1691,6 +1691,12 @@ offsets = {
|
||||
"VertexAttribs4hvNV": 1655,
|
||||
"TexPageCommitmentEXT": 1656,
|
||||
"TexturePageCommitmentEXT" : 1657,
|
||||
+ "CurrentPaletteMatrixOES" : 1658,
|
||||
+ "LoadPaletteFromModelViewMatrixOES" : 1659,
|
||||
+ "MatrixIndexPointerOES" : 1660,
|
||||
+ "WeightPointerOES" : 1661,
|
||||
+ "RenderbufferStorageMultisampleIMG" : 1662,
|
||||
+ "FramebufferTexture2DMultisampleIMG" : 1663,
|
||||
}
|
||||
|
||||
functions = [
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,187 @@
|
||||
From 7fdeb8bf25be01f122a7cb55dbe2b0e67e4a24a2 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/67] 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 510289403d2..b197092939f 100644
|
||||
--- a/include/GL/internal/dri_interface.h
|
||||
+++ b/include/GL/internal/dri_interface.h
|
||||
@@ -1831,6 +1831,19 @@ struct __DRIimageExtensionRec {
|
||||
const unsigned int modifier_count,
|
||||
unsigned int use,
|
||||
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 eee28eb4726..dea5899b3a8 100644
|
||||
--- a/src/egl/drivers/dri2/egl_dri2.c
|
||||
+++ b/src/egl/drivers/dri2/egl_dri2.c
|
||||
@@ -995,6 +995,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)
|
||||
@@ -2360,17 +2364,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 *
|
||||
@@ -2449,7 +2449,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);
|
||||
@@ -2916,7 +2958,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;
|
||||
@@ -3152,6 +3194,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 17e36af22e1..6ffcff8b2cc 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.25.1
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
From fa57726f60bc6fc6e7094f16300cdc41b44ff4f3 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 07/67] 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 6ffcff8b2cc..3cd69b96a0f 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.25.1
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
From f556292d5811750d119acea6c7dc0c5ebd3e1af6 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 08/67] 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 3cd69b96a0f..234449adf64 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.25.1
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
From 13e925af5ba3bd763eb4c9e5d0781f92981550f6 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 09/67] 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 e586b0ec19b..a3bfe86a888 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 79b8f19cb75..99729e21b7f 100644
|
||||
--- a/src/mapi/glapi/gen/static_data.py
|
||||
+++ b/src/mapi/glapi/gen/static_data.py
|
||||
@@ -1697,6 +1697,9 @@ offsets = {
|
||||
"WeightPointerOES" : 1661,
|
||||
"RenderbufferStorageMultisampleIMG" : 1662,
|
||||
"FramebufferTexture2DMultisampleIMG" : 1663,
|
||||
+ "ClearPixelLocalStorageuiEXT" : 1664,
|
||||
+ "FramebufferPixelLocalStorageSizeEXT" : 1665,
|
||||
+ "GetFramebufferPixelLocalStorageSizeEXT" : 1666,
|
||||
}
|
||||
|
||||
functions = [
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
From f43a3258b8f4859ff3e0e3d3d356b319dd6a5435 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/67] 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 a3bfe86a888..b3432820ba6 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 99729e21b7f..c723cb3fab8 100644
|
||||
--- a/src/mapi/glapi/gen/static_data.py
|
||||
+++ b/src/mapi/glapi/gen/static_data.py
|
||||
@@ -1700,6 +1700,8 @@ offsets = {
|
||||
"ClearPixelLocalStorageuiEXT" : 1664,
|
||||
"FramebufferPixelLocalStorageSizeEXT" : 1665,
|
||||
"GetFramebufferPixelLocalStorageSizeEXT" : 1666,
|
||||
+ "FramebufferTexture2DDownsampleIMG" : 1667,
|
||||
+ "FramebufferTextureLayerDownsampleIMG" : 1668,
|
||||
}
|
||||
|
||||
functions = [
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
From cbc7a7501ea4ceffd55ca389deb55d12ff9ceb3f 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 11/67] 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 cf5a0f0a0c0..4e35de0f4ea 100644
|
||||
--- a/src/mapi/glapi/gen/gl_API.xml
|
||||
+++ b/src/mapi/glapi/gen/gl_API.xml
|
||||
@@ -13125,6 +13125,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 c723cb3fab8..73625c7fe41 100644
|
||||
--- a/src/mapi/glapi/gen/static_data.py
|
||||
+++ b/src/mapi/glapi/gen/static_data.py
|
||||
@@ -1702,6 +1702,7 @@ offsets = {
|
||||
"GetFramebufferPixelLocalStorageSizeEXT" : 1666,
|
||||
"FramebufferTexture2DDownsampleIMG" : 1667,
|
||||
"FramebufferTextureLayerDownsampleIMG" : 1668,
|
||||
+ "FramebufferTextureMultiviewOVR" : 1669,
|
||||
}
|
||||
|
||||
functions = [
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
From 91ea37486db99fd403654ebff2a0a8401f7cd600 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 12/67] 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 b3432820ba6..fe8f27e1e6f 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 73625c7fe41..dc6bdc9dcce 100644
|
||||
--- a/src/mapi/glapi/gen/static_data.py
|
||||
+++ b/src/mapi/glapi/gen/static_data.py
|
||||
@@ -1703,6 +1703,7 @@ offsets = {
|
||||
"FramebufferTexture2DDownsampleIMG" : 1667,
|
||||
"FramebufferTextureLayerDownsampleIMG" : 1668,
|
||||
"FramebufferTextureMultiviewOVR" : 1669,
|
||||
+ "FramebufferTextureMultisampleMultiviewOVR" : 1670,
|
||||
}
|
||||
|
||||
functions = [
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
From b38c4118c7a3a060ef1c8b8477200f5a73305397 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 13/67] 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.25.1
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
From b80c78b05ebb661e7f088d0a369b0f0d2990afca 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 14/67] 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 ebc18a73c86..09f4b02e758 100644
|
||||
--- a/src/gallium/frontends/dri/dri2.c
|
||||
+++ b/src/gallium/frontends/dri/dri2.c
|
||||
@@ -2400,7 +2400,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.25.1
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
From 55a15a019dd792477e39f6225f2b4e50a1359b66 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 15/67] 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 cfff0ade90e..c18edc0de4e 100644
|
||||
--- a/src/egl/drivers/dri2/platform_wayland.c
|
||||
+++ b/src/egl/drivers/dri2/platform_wayland.c
|
||||
@@ -633,18 +633,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.25.1
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
From 03f4f18f9edb4090c6aeca16e6f4de602aea68bf 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 16/67] 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 6e825f9a898..ff6d1ffc660 100644
|
||||
--- a/src/loader/loader_dri3_helper.c
|
||||
+++ b/src/loader/loader_dri3_helper.c
|
||||
@@ -863,15 +863,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.25.1
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
From d98cd46b5841ecb785a801a977a1b341d98d08c4 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 17/67] 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 11277d3e4c0..c87eac0d007 100644
|
||||
--- a/src/egl/main/eglcurrent.c
|
||||
+++ b/src/egl/main/eglcurrent.c
|
||||
@@ -44,6 +44,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_INITIAL_EXEC 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.25.1
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,231 @@
|
||||
From 230a8cb550dc23a46a96b1852720c262bb244665 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 19/67] 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 6d34395d65d..eaa0baed066 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"
|
||||
@@ -2311,28 +2315,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);
|
||||
@@ -2363,33 +2454,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
|
||||
|
||||
@@ -3296,6 +3361,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 43c7b917909..e2a7797d73e 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.25.1
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
From 54d08798efca8f8929744a238e2b8b2851083317 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 20/67] 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 c18edc0de4e..c2e428769fe 100644
|
||||
--- a/src/egl/drivers/dri2/platform_wayland.c
|
||||
+++ b/src/egl/drivers/dri2/platform_wayland.c
|
||||
@@ -1112,7 +1112,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.25.1
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
From a6aa5c866c25f7f334afbbcc3835467d50eb8965 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 21/67] 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 c2e428769fe..811d28bd669 100644
|
||||
--- a/src/egl/drivers/dri2/platform_wayland.c
|
||||
+++ b/src/egl/drivers/dri2/platform_wayland.c
|
||||
@@ -1117,6 +1117,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);
|
||||
@@ -1126,10 +1128,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.25.1
|
||||
|
||||
@@ -0,0 +1,380 @@
|
||||
From 404c0e915de381c2337c79657f80b0aa95c1c995 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 22/67] 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 eaa0baed066..db993f8f059 100644
|
||||
--- a/src/egl/drivers/dri2/egl_dri2.c
|
||||
+++ b/src/egl/drivers/dri2/egl_dri2.c
|
||||
@@ -1264,6 +1264,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;
|
||||
@@ -1320,6 +1324,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().
|
||||
*
|
||||
@@ -1332,6 +1390,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;
|
||||
@@ -2309,6 +2369,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)
|
||||
{
|
||||
@@ -2405,14 +2468,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 *
|
||||
@@ -2424,6 +2618,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);
|
||||
@@ -2454,7 +2651,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
|
||||
|
||||
@@ -3377,10 +3588,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 a8bfe45b1f5..546bc0a0dbc 100644
|
||||
--- a/src/egl/drivers/dri2/egl_dri2.h
|
||||
+++ b/src/egl/drivers/dri2/egl_dri2.h
|
||||
@@ -268,6 +268,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
|
||||
};
|
||||
|
||||
@@ -413,6 +422,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.25.1
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
From 1f4a1a21384b00e28b8a9dd2c29f9c261f201c6f 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 23/67] 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.25.1
|
||||
|
||||
224
recipes-graphics/mesa/mesa-pvr/0024-gbm-add-gbm_bo_blit.patch
Normal file
224
recipes-graphics/mesa/mesa-pvr/0024-gbm-add-gbm_bo_blit.patch
Normal file
@@ -0,0 +1,224 @@
|
||||
From 0751612b949f1c90338a14453ff7fa4be8bfd016 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 24/67] 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 | 33 +++++++++++++++++++++++++++++++++
|
||||
src/gbm/main/gbm.c | 31 +++++++++++++++++++++++++++++++
|
||||
src/gbm/main/gbm.h | 21 +++++++++++++++++++++
|
||||
src/gbm/main/gbm_abi_check.c | 20 +++++++++++++++++++-
|
||||
src/gbm/main/gbm_backend_abi.h | 10 +++++++++-
|
||||
5 files changed, 113 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/gbm/backends/dri/gbm_dri.c b/src/gbm/backends/dri/gbm_dri.c
|
||||
index 96fa9217255..bd8a80cdecf 100644
|
||||
--- a/src/gbm/backends/dri/gbm_dri.c
|
||||
+++ b/src/gbm/backends/dri/gbm_dri.c
|
||||
@@ -1355,6 +1355,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)
|
||||
{
|
||||
@@ -1416,6 +1447,8 @@ dri_device_create(int fd, uint32_t gbm_backend_version)
|
||||
|
||||
dri->base.v0.name = "drm";
|
||||
|
||||
+ dri->base.v1.bo_blit = gbm_dri_bo_blit;
|
||||
+
|
||||
dri->visual_table = gbm_dri_visuals_table;
|
||||
dri->num_visuals = ARRAY_SIZE(gbm_dri_visuals_table);
|
||||
|
||||
diff --git a/src/gbm/main/gbm.c b/src/gbm/main/gbm.c
|
||||
index d81931a7483..e2351d34ad8 100644
|
||||
--- a/src/gbm/main/gbm.c
|
||||
+++ b/src/gbm/main/gbm.c
|
||||
@@ -758,6 +758,37 @@ 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)
|
||||
+{
|
||||
+ if (dst_bo->gbm->v0.backend_version >= 1)
|
||||
+ return dst_bo->gbm->v1.bo_blit(dst_bo, src_bo,
|
||||
+ dst_x0, dst_y0, dst_width, dst_height,
|
||||
+ src_x0, src_y0, src_width, src_height,
|
||||
+ flags);
|
||||
+ else
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* A global table of functions and global variables defined in the core GBM
|
||||
* code that need to be accessed directly by GBM backends.
|
||||
diff --git a/src/gbm/main/gbm.h b/src/gbm/main/gbm.h
|
||||
index 3a0fe73faae..7c82cd661a3 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);
|
||||
|
||||
@@ -425,6 +440,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/gbm_abi_check.c b/src/gbm/main/gbm_abi_check.c
|
||||
index f1137be7baf..02ce23b129e 100644
|
||||
--- a/src/gbm/main/gbm_abi_check.c
|
||||
+++ b/src/gbm/main/gbm_abi_check.c
|
||||
@@ -101,6 +101,21 @@ struct gbm_device_abi0 {
|
||||
struct gbm_device_v0_abi0 v0;
|
||||
};
|
||||
|
||||
+#define GBM_BACKEND_ABI_VERSION_abi1 1
|
||||
+struct gbm_device_v1_abi1 {
|
||||
+ 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);
|
||||
+};
|
||||
+
|
||||
+struct gbm_device_abi1 {
|
||||
+ /* Hack to make a gbm_device detectable by its first element. */
|
||||
+ struct gbm_device *(*dummy)(int);
|
||||
+ struct gbm_device_v0_abi0 v0;
|
||||
+ struct gbm_device_v1_abi1 v1;
|
||||
+};
|
||||
+
|
||||
/**
|
||||
* GBM buffer object interface corresponding to GBM_BACKEND_ABI_VERSION = 0
|
||||
*
|
||||
@@ -359,8 +374,11 @@ int main(int argc, char **argv)
|
||||
CHECK_MEMBER_CURRENT(gbm_device_v0, _abi0, surface_has_free_buffers);
|
||||
CHECK_MEMBER_CURRENT(gbm_device_v0, _abi0, surface_destroy);
|
||||
|
||||
+ CHECK_MEMBER_CURRENT(gbm_device_v1, _abi1, bo_blit);
|
||||
+
|
||||
/* Size of ABI-versioned substructures verified by above member checks */
|
||||
- CHECK_SIZE_CURRENT (gbm_device, _abi0);
|
||||
+ CHECK_SIZE (gbm_device, _abi0, _abi1);
|
||||
+ CHECK_SIZE_CURRENT (gbm_device, _abi1);
|
||||
|
||||
|
||||
/* Check current gbm_bo ABI against gbm_bo_abi0*/
|
||||
diff --git a/src/gbm/main/gbm_backend_abi.h b/src/gbm/main/gbm_backend_abi.h
|
||||
index 962ee74f003..3abf29faa92 100644
|
||||
--- a/src/gbm/main/gbm_backend_abi.h
|
||||
+++ b/src/gbm/main/gbm_backend_abi.h
|
||||
@@ -72,7 +72,7 @@ struct gbm_backend_desc;
|
||||
* Core ABI version: 4
|
||||
* ABI version of a buffer object created by a device from the backend: 4
|
||||
*/
|
||||
-#define GBM_BACKEND_ABI_VERSION 0
|
||||
+#define GBM_BACKEND_ABI_VERSION 1
|
||||
|
||||
/**
|
||||
* GBM device interface corresponding to GBM_BACKEND_ABI_VERSION = 0
|
||||
@@ -149,6 +149,13 @@ struct gbm_device_v0 {
|
||||
void (*surface_destroy)(struct gbm_surface *surface);
|
||||
};
|
||||
|
||||
+struct gbm_device_v1 {
|
||||
+ 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);
|
||||
+};
|
||||
+
|
||||
/**
|
||||
* The device used for the memory allocation.
|
||||
*
|
||||
@@ -161,6 +168,7 @@ struct gbm_device {
|
||||
/* Hack to make a gbm_device detectable by its first element. */
|
||||
struct gbm_device *(*dummy)(int);
|
||||
struct gbm_device_v0 v0;
|
||||
+ struct gbm_device_v1 v1;
|
||||
};
|
||||
|
||||
/**
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
From dbe611e4cb6f0dddc05ead03f0341274a6b018c8 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 25/67] 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 bd8a80cdecf..2aa9c7c41ad 100644
|
||||
--- a/src/gbm/backends/dri/gbm_dri.c
|
||||
+++ b/src/gbm/backends/dri/gbm_dri.c
|
||||
@@ -1245,8 +1245,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,
|
||||
@@ -1374,8 +1377,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.25.1
|
||||
|
||||
@@ -0,0 +1,471 @@
|
||||
From f16ea577ee06375423198dced8231d04e94536af 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 26/67] 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 546bc0a0dbc..f41f32cd234 100644
|
||||
--- a/src/egl/drivers/dri2/egl_dri2.h
|
||||
+++ b/src/egl/drivers/dri2/egl_dri2.h
|
||||
@@ -405,6 +405,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 811d28bd669..a096d9500c1 100644
|
||||
--- a/src/egl/drivers/dri2/platform_wayland.c
|
||||
+++ b/src/egl/drivers/dri2/platform_wayland.c
|
||||
@@ -427,6 +427,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().
|
||||
*/
|
||||
@@ -453,6 +546,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);
|
||||
|
||||
@@ -462,11 +558,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);
|
||||
@@ -628,20 +727,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;
|
||||
@@ -656,12 +751,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->wl_win &&
|
||||
(dri2_surf->base.Width != dri2_surf->wl_win->width ||
|
||||
dri2_surf->base.Height != dri2_surf->wl_win->height)) {
|
||||
@@ -703,12 +814,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 *
|
||||
@@ -718,17 +830,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],
|
||||
@@ -798,12 +918,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;
|
||||
}
|
||||
@@ -1054,6 +1192,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;
|
||||
+
|
||||
if (!dri2_surf->wl_win)
|
||||
return _eglError(EGL_BAD_NATIVE_WINDOW, "dri2_swap_buffers");
|
||||
|
||||
@@ -1068,7 +1209,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) {
|
||||
@@ -1153,9 +1294,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;
|
||||
}
|
||||
@@ -1376,6 +1521,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,
|
||||
@@ -1418,7 +1564,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++;
|
||||
@@ -1654,6 +1800,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,
|
||||
@@ -1775,8 +1938,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)
|
||||
@@ -1846,7 +2025,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;
|
||||
@@ -1865,7 +2046,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;
|
||||
@@ -1903,14 +2088,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;
|
||||
@@ -1928,7 +2119,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
|
||||
@@ -1996,6 +2189,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.25.1
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
From 48fe256681d8d7d3892393b102bf0a3ebc697c51 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 27/67] 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 b197092939f..16cc095ea29 100644
|
||||
--- a/include/GL/internal/dri_interface.h
|
||||
+++ b/include/GL/internal/dri_interface.h
|
||||
@@ -2073,12 +2073,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.25.1
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
From 90c87ad050dd7a4deda3ee1609e6cc27ea7dd616 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 28/67] 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.25.1
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
From a763c01172ee21a26f4c9dbb6055093f78d06fb2 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 29/67] 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 fe8f27e1e6f..e0d60faa9d2 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 dc6bdc9dcce..e231c176264 100644
|
||||
--- a/src/mapi/glapi/gen/static_data.py
|
||||
+++ b/src/mapi/glapi/gen/static_data.py
|
||||
@@ -1704,6 +1704,8 @@ offsets = {
|
||||
"FramebufferTextureLayerDownsampleIMG" : 1668,
|
||||
"FramebufferTextureMultiviewOVR" : 1669,
|
||||
"FramebufferTextureMultisampleMultiviewOVR" : 1670,
|
||||
+ "MultiDrawArraysIndirectEXT" : 1671,
|
||||
+ "MultiDrawElementsIndirectEXT" : 1672,
|
||||
}
|
||||
|
||||
functions = [
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,494 @@
|
||||
From 389e1a41360160bf56182a87cc52b5df9dc1265d 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 30/67] 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 | 2 +
|
||||
src/mesa/drivers/dri/common/utils.c | 88 +++++++++++++++++--
|
||||
src/mesa/drivers/dri/common/utils.h | 3 +-
|
||||
src/mesa/drivers/dri/i915/intel_screen.c | 8 +-
|
||||
src/mesa/drivers/dri/i965/brw_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 16cc095ea29..4d5a1874dc2 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 b565a1fe8ec..37a0d4add0c 100644
|
||||
--- a/src/gallium/frontends/dri/dri_screen.c
|
||||
+++ b/src/gallium/frontends/dri/dri_screen.c
|
||||
@@ -324,7 +324,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_TRUE, !mixed_color_depth,
|
||||
+ __DRI_ATTRIB_YUV_DEPTH_RANGE_NONE,
|
||||
+ __DRI_ATTRIB_YUV_CSC_STANDARD_NONE);
|
||||
configs = driConcatConfigs(configs, new_configs);
|
||||
|
||||
/* Multi-sample configs without an accumulation buffer. */
|
||||
@@ -334,7 +336,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, !mixed_color_depth,
|
||||
+ __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 0c93d7df6e2..fd653379b7a 100644
|
||||
--- a/src/gallium/include/pipe/p_format.h
|
||||
+++ b/src/gallium/include/pipe/p_format.h
|
||||
@@ -513,6 +513,8 @@ enum pipe_format {
|
||||
PIPE_FORMAT_R4G4B4X4_UNORM,
|
||||
PIPE_FORMAT_B10G10R10X2_SNORM,
|
||||
PIPE_FORMAT_R5G6B5_SRGB,
|
||||
+ 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 a3f2bc57f46..d268dc41fbb 100644
|
||||
--- a/src/mesa/drivers/dri/common/utils.c
|
||||
+++ b/src/mesa/drivers/dri/common/utils.c
|
||||
@@ -163,6 +163,21 @@ driGetRendererString( char * buffer, const char * hardware_name,
|
||||
* This forces 32-bit color to have 24-bit depth, and
|
||||
* 16-bit color to have 16-bit depth.
|
||||
*
|
||||
+ * \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.
|
||||
@@ -175,7 +190,8 @@ driCreateConfigs(mesa_format format,
|
||||
unsigned num_depth_stencil_bits,
|
||||
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 enable_accum, GLboolean color_depth_match,
|
||||
+ GLint yuv_depth_range, GLint yuv_csc_standard)
|
||||
{
|
||||
static const struct {
|
||||
uint32_t masks[4];
|
||||
@@ -214,6 +230,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;
|
||||
@@ -227,6 +246,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;
|
||||
|
||||
@@ -279,6 +303,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__,
|
||||
@@ -334,8 +385,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;
|
||||
@@ -345,6 +400,8 @@ driCreateConfigs(mesa_format format,
|
||||
modes->stencilBits = stencil_bits[k];
|
||||
modes->depthBits = depth_bits[k];
|
||||
|
||||
+ modes->rgbMode = !is_yuv;
|
||||
+
|
||||
if (db_modes[i] == __DRI_ATTRIB_SWAP_NONE) {
|
||||
modes->doubleBufferMode = GL_FALSE;
|
||||
modes->swapMethod = __DRI_ATTRIB_SWAP_UNDEFINED;
|
||||
@@ -357,6 +414,13 @@ driCreateConfigs(mesa_format format,
|
||||
modes->samples = msaa_samples[h];
|
||||
|
||||
modes->sRGBCapable = is_srgb;
|
||||
+
|
||||
+ 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -436,10 +500,14 @@ driGetConfigAttribIndex(const __DRIconfig *config,
|
||||
break;
|
||||
__ATTRIB(__DRI_ATTRIB_SAMPLES, samples);
|
||||
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.accumRedBits != 0)
|
||||
@@ -505,6 +573,12 @@ driGetConfigAttribIndex(const __DRIconfig *config,
|
||||
__ATTRIB(__DRI_ATTRIB_GREEN_SHIFT, greenShift);
|
||||
__ATTRIB(__DRI_ATTRIB_BLUE_SHIFT, blueShift);
|
||||
__ATTRIB(__DRI_ATTRIB_ALPHA_SHIFT, alphaShift);
|
||||
+ __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);
|
||||
default:
|
||||
/* XXX log an error or smth */
|
||||
return GL_FALSE;
|
||||
diff --git a/src/mesa/drivers/dri/common/utils.h b/src/mesa/drivers/dri/common/utils.h
|
||||
index 7be0465c261..ebd98d9dc33 100644
|
||||
--- a/src/mesa/drivers/dri/common/utils.h
|
||||
+++ b/src/mesa/drivers/dri/common/utils.h
|
||||
@@ -45,7 +45,8 @@ driCreateConfigs(mesa_format format,
|
||||
unsigned num_depth_stencil_bits,
|
||||
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 enable_accum, GLboolean color_depth_match,
|
||||
+ 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 6135357c2a0..a94c6de0a06 100644
|
||||
--- a/src/mesa/drivers/dri/i915/intel_screen.c
|
||||
+++ b/src/mesa/drivers/dri/i915/intel_screen.c
|
||||
@@ -1083,7 +1083,9 @@ intel_screen_make_configs(__DRIscreen *dri_screen)
|
||||
num_depth_stencil_bits,
|
||||
back_buffer_modes, 2,
|
||||
singlesample_samples, 1,
|
||||
- false, false);
|
||||
+ false, false,
|
||||
+ __DRI_ATTRIB_YUV_DEPTH_RANGE_NONE,
|
||||
+ __DRI_ATTRIB_YUV_CSC_STANDARD_NONE);
|
||||
configs = driConcatConfigs(configs, new_configs);
|
||||
}
|
||||
|
||||
@@ -1105,7 +1107,9 @@ intel_screen_make_configs(__DRIscreen *dri_screen)
|
||||
depth_bits, stencil_bits, 1,
|
||||
back_buffer_modes, 1,
|
||||
singlesample_samples, 1,
|
||||
- true, false);
|
||||
+ true, 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/brw_screen.c b/src/mesa/drivers/dri/i965/brw_screen.c
|
||||
index 56811110567..c450bae1054 100644
|
||||
--- a/src/mesa/drivers/dri/i965/brw_screen.c
|
||||
+++ b/src/mesa/drivers/dri/i965/brw_screen.c
|
||||
@@ -2292,7 +2292,9 @@ brw_screen_make_configs(__DRIscreen *dri_screen)
|
||||
num_depth_stencil_bits,
|
||||
back_buffer_modes, 2,
|
||||
singlesample_samples, 1,
|
||||
- false, false);
|
||||
+ false, false,
|
||||
+ __DRI_ATTRIB_YUV_DEPTH_RANGE_NONE,
|
||||
+ __DRI_ATTRIB_YUV_CSC_STANDARD_NONE);
|
||||
configs = driConcatConfigs(configs, new_configs);
|
||||
}
|
||||
|
||||
@@ -2325,7 +2327,9 @@ brw_screen_make_configs(__DRIscreen *dri_screen)
|
||||
depth_bits, stencil_bits, 1,
|
||||
back_buffer_modes, 1,
|
||||
singlesample_samples, 1,
|
||||
- true, false);
|
||||
+ true, false,
|
||||
+ __DRI_ATTRIB_YUV_DEPTH_RANGE_NONE,
|
||||
+ __DRI_ATTRIB_YUV_CSC_STANDARD_NONE);
|
||||
configs = driConcatConfigs(configs, new_configs);
|
||||
}
|
||||
|
||||
@@ -2390,7 +2394,9 @@ brw_screen_make_configs(__DRIscreen *dri_screen)
|
||||
back_buffer_modes, 1,
|
||||
multisample_samples,
|
||||
num_msaa_modes,
|
||||
- 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 c92efcd7b20..fc87d5eb395 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_TRUE, chipset < 0x10,
|
||||
+ __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 3764a5d6538..f7628555b8f 100644
|
||||
--- a/src/mesa/drivers/dri/radeon/radeon_screen.c
|
||||
+++ b/src/mesa/drivers/dri/radeon/radeon_screen.c
|
||||
@@ -838,7 +838,9 @@ __DRIconfig **radeonInitScreen2(__DRIscreen *psp)
|
||||
ARRAY_SIZE(back_buffer_modes),
|
||||
msaa_samples_array,
|
||||
ARRAY_SIZE(msaa_samples_array),
|
||||
- GL_TRUE, GL_FALSE);
|
||||
+ GL_TRUE, 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 edc0324e60b..d58403ea85e 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 9cd026f7507..f81caeceff4 100644
|
||||
--- a/src/mesa/main/formats.c
|
||||
+++ b/src/mesa/main/formats.c
|
||||
@@ -1452,6 +1452,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 21cdea26e08..b2d476577e0 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
|
||||
|
||||
MESA_FORMAT_RG_RB_UNORM8 , other , 2, 1, 1, x16 , , , , xyz1, rgb
|
||||
MESA_FORMAT_GR_BR_UNORM8 , other , 2, 1, 1, x16 , , , , xyz1, rgb
|
||||
diff --git a/src/mesa/main/formats.h b/src/mesa/main/formats.h
|
||||
index 508c9c342d2..0e778d64467 100644
|
||||
--- a/src/mesa/main/formats.h
|
||||
+++ b/src/mesa/main/formats.h
|
||||
@@ -617,6 +617,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 32528a5f16b..8f77d4c58dd 100644
|
||||
--- a/src/mesa/main/mtypes.h
|
||||
+++ b/src/mesa/main/mtypes.h
|
||||
@@ -158,6 +158,7 @@ _mesa_varying_slot_in_fs(gl_varying_slot slot)
|
||||
*/
|
||||
struct gl_config
|
||||
{
|
||||
+ GLboolean rgbMode;
|
||||
GLboolean floatMode;
|
||||
GLuint doubleBufferMode;
|
||||
GLuint stereoMode;
|
||||
@@ -179,6 +180,14 @@ struct gl_config
|
||||
|
||||
/* EXT_framebuffer_sRGB */
|
||||
GLint sRGBCapable;
|
||||
+
|
||||
+ /* EXT_yuv_surface */
|
||||
+ GLint YUVOrder;
|
||||
+ GLint YUVNumberOfPlanes;
|
||||
+ GLint YUVSubsample;
|
||||
+ GLint YUVDepthRange;
|
||||
+ GLint YUVCSCStandard;
|
||||
+ GLint YUVPlaneBPP;
|
||||
};
|
||||
|
||||
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,541 @@
|
||||
From 4e65ae659b775259b4f703eb563feffc623c17b7 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 31/67] 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 4d5a1874dc2..62517e4004a 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 db993f8f059..ee3bcda4d12 100644
|
||||
--- a/src/egl/drivers/dri2/egl_dri2.c
|
||||
+++ b/src/egl/drivers/dri2/egl_dri2.c
|
||||
@@ -306,6 +306,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 *
|
||||
@@ -432,6 +433,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;
|
||||
@@ -536,6 +539,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)
|
||||
@@ -583,6 +653,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;
|
||||
|
||||
@@ -1014,6 +1095,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 e2a7797d73e..6d7f62c6851 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.25.1
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
From 5a22280c13e98932ad45fa6a131217abdffd16b4 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 32/67] 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 62517e4004a..6490f6e80e2 100644
|
||||
--- a/include/GL/internal/dri_interface.h
|
||||
+++ b/include/GL/internal/dri_interface.h
|
||||
@@ -1461,11 +1461,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.25.1
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
From 3d47285da42c76fe36ae67c62e8d0a0d76d18da0 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 33/67] 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 ee3bcda4d12..d511d73f2ed 100644
|
||||
--- a/src/egl/drivers/dri2/egl_dri2.c
|
||||
+++ b/src/egl/drivers/dri2/egl_dri2.c
|
||||
@@ -2769,6 +2769,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 a096d9500c1..72456d5d748 100644
|
||||
--- a/src/egl/drivers/dri2/platform_wayland.c
|
||||
+++ b/src/egl/drivers/dri2/platform_wayland.c
|
||||
@@ -135,6 +135,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,
|
||||
@@ -958,6 +965,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;
|
||||
@@ -1552,6 +1560,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++) {
|
||||
@@ -1563,8 +1572,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.25.1
|
||||
|
||||
@@ -0,0 +1,357 @@
|
||||
From 40c0d03cfb2751279b24890d0f752fade968862e 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 34/67] 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.25.1
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
From 5bd42e648dc9068392641436b70fc28a00689c8e 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 35/67] 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 2aa9c7c41ad..5acb15b516f 100644
|
||||
--- a/src/gbm/backends/dri/gbm_dri.c
|
||||
+++ b/src/gbm/backends/dri/gbm_dri.c
|
||||
@@ -514,11 +514,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 },
|
||||
@@ -571,6 +581,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 7c82cd661a3..81308ab9745 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.25.1
|
||||
|
||||
1491
recipes-graphics/mesa/mesa-pvr/0036-egl-add-null-platform.patch
Normal file
1491
recipes-graphics/mesa/mesa-pvr/0036-egl-add-null-platform.patch
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,509 @@
|
||||
From 02065d490a68d542be56c2ea23346b3fa19928cb 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 37/67] 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/main/eglconfig.c | 20 ++-
|
||||
src/egl/main/eglconfigdebug.c | 321 ++++++++++++++++++++++++++++++++++
|
||||
src/egl/main/eglconfigdebug.h | 55 ++++++
|
||||
src/egl/main/egllog.c | 9 +
|
||||
src/egl/main/egllog.h | 4 +
|
||||
src/egl/meson.build | 2 +
|
||||
6 files changed, 407 insertions(+), 4 deletions(-)
|
||||
create mode 100644 src/egl/main/eglconfigdebug.c
|
||||
create mode 100644 src/egl/main/eglconfigdebug.h
|
||||
|
||||
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..92ac41a5614
|
||||
--- /dev/null
|
||||
+++ b/src/egl/main/eglconfigdebug.c
|
||||
@@ -0,0 +1,321 @@
|
||||
+/*
|
||||
+ * 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];
|
||||
+ EGLint colorBufferType;
|
||||
+ EGLint numPlanes, subsample, order;
|
||||
+};
|
||||
+
|
||||
+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
|
||||
+ *
|
||||
+ * color size
|
||||
+ * 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
|
||||
+ * colbuf --------------- EGL_COLOR_BUFFER_TYPE
|
||||
+ *
|
||||
+ * yuv
|
||||
+ * p -------------------- EGL_YUV_NUMBER_OF_PLANES_EXT
|
||||
+ * sub ------------------ EGL_YUV_SUBSAMPLE_EXT
|
||||
+ * ord ------------------ EGL_YUV_ORDER_EXT
|
||||
+ */
|
||||
+ _eglLog(_EGL_DEBUG, "---------------");
|
||||
+ _eglLog(_EGL_DEBUG, "Configurations:");
|
||||
+ _eglLog(_EGL_DEBUG, "cho bf lv color size dp st ms vis cav bi renderable supported"
|
||||
+ " col yuv ");
|
||||
+ _eglLog(_EGL_DEBUG, "sen id sz l r g b a th cl ns b id eat nd gl es es2 es3 vg surfaces"
|
||||
+ " buf p sub ord");
|
||||
+ _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 inline const char *_enumToString(EGLint constant)
|
||||
+{
|
||||
+ switch (constant) {
|
||||
+ case EGL_YUV_SUBSAMPLE_4_2_0_EXT: return "420";
|
||||
+ case EGL_YUV_SUBSAMPLE_4_2_2_EXT: return "422";
|
||||
+ case EGL_YUV_SUBSAMPLE_4_4_4_EXT: return "444";
|
||||
+ case EGL_YUV_ORDER_AYUV_EXT: return "AYUV";
|
||||
+ case EGL_YUV_ORDER_UYVY_EXT: return "UYVY";
|
||||
+ case EGL_YUV_ORDER_VYUY_EXT: return "VYUY";
|
||||
+ case EGL_YUV_ORDER_YUYV_EXT: return "YUYV";
|
||||
+ case EGL_YUV_ORDER_YVYU_EXT: return "YVYU";
|
||||
+ case EGL_YUV_ORDER_YUV_EXT: return "YUV";
|
||||
+ case EGL_YUV_ORDER_YVU_EXT: return "YVU";
|
||||
+ case EGL_LUMINANCE_BUFFER: return "lum";
|
||||
+ case EGL_YUV_BUFFER_EXT: return "yuv";
|
||||
+ case EGL_RGB_BUFFER: return "rgb";
|
||||
+ default: return "?";
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+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);
|
||||
+ success &= _eglGetConfigAttrib(dpy, conf, EGL_COLOR_BUFFER_TYPE, &attr->colorBufferType);
|
||||
+
|
||||
+ if (conf->Display->Extensions.EXT_yuv_surface) {
|
||||
+ success &= _eglGetConfigAttrib(dpy, conf, EGL_YUV_NUMBER_OF_PLANES_EXT,
|
||||
+ &attr->numPlanes);
|
||||
+ success &= _eglGetConfigAttrib(dpy, conf, EGL_YUV_SUBSAMPLE_EXT, &attr->subsample);
|
||||
+ success &= _eglGetConfigAttrib(dpy, conf, EGL_YUV_ORDER_EXT, &attr->order);
|
||||
+ }
|
||||
+
|
||||
+ 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);
|
||||
+
|
||||
+ _snprintfStrcat(printMsg, maxMsgSize, " %3.3s",
|
||||
+ _enumToString(attr.colorBufferType));
|
||||
+
|
||||
+ if (attr.colorBufferType == EGL_YUV_BUFFER_EXT)
|
||||
+ _snprintfStrcat(printMsg, maxMsgSize, " %1.1d %3.3s %4.4s", attr.numPlanes,
|
||||
+ _enumToString(attr.subsample), _enumToString(attr.order));
|
||||
+
|
||||
+ _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 daa6a3a04f0..384bb98ebb3 100644
|
||||
--- a/src/egl/meson.build
|
||||
+++ b/src/egl/meson.build
|
||||
@@ -31,6 +31,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.25.1
|
||||
|
||||
@@ -0,0 +1,217 @@
|
||||
From d1d64a3c11fbab083d6225857554ac1c9ad645b6 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 38/67] 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 2f8414e0c60..6b26ff979ae 100644
|
||||
--- a/src/egl/drivers/dri2/egl_dri2.c
|
||||
+++ b/src/egl/drivers/dri2/egl_dri2.c
|
||||
@@ -1084,6 +1084,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)
|
||||
@@ -2724,6 +2727,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;
|
||||
@@ -2799,6 +2807,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) {
|
||||
@@ -2862,6 +2875,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) {
|
||||
@@ -3007,6 +3025,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;
|
||||
@@ -3189,6 +3212,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)
|
||||
@@ -3334,6 +3374,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;
|
||||
@@ -3359,6 +3400,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;
|
||||
@@ -3403,7 +3456,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,
|
||||
@@ -3415,7 +3468,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 e4f2c43b4ef..2d3931dfd26 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.25.1
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
From c8a6405eaf4c9693f32381fa7aa6d292e7f95716 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 39/67] 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 2018562a1ec..21d93d372c2 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.25.1
|
||||
|
||||
@@ -0,0 +1,785 @@
|
||||
From dbb0d023abb9e4bfed70144514595f0477840f3e 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 40/67] 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 eb2127e3fe6..64d60ed66e4 100644
|
||||
--- a/src/egl/drivers/dri2/egl_dri2.h
|
||||
+++ b/src/egl/drivers/dri2/egl_dri2.h
|
||||
@@ -332,6 +332,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;
|
||||
@@ -370,13 +387,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;
|
||||
@@ -412,7 +434,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
|
||||
@@ -442,7 +464,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 fb03ecc36fd..5b7c1ec426c 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, ¤t_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,
|
||||
@@ -1062,12 +1434,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));
|
||||
@@ -1114,11 +1509,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.25.1
|
||||
|
||||
@@ -0,0 +1,214 @@
|
||||
From d286d05d0d84c913c8bfcbe8f693083caf3bcc77 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 41/67] 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 64d60ed66e4..eb6e4551087 100644
|
||||
--- a/src/egl/drivers/dri2/egl_dri2.h
|
||||
+++ b/src/egl/drivers/dri2/egl_dri2.h
|
||||
@@ -106,6 +106,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;
|
||||
@@ -338,6 +339,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 5b7c1ec426c..d36dc0ced2a 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.25.1
|
||||
|
||||
@@ -0,0 +1,401 @@
|
||||
From 4f9ca104c16a6eb1af770e2447adb4413fb41cb7 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 42/68] egl/null: add support for DRM image format 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
|
||||
iterate all formats with associated modifiers supported by the display
|
||||
for the primary drm plane in use.
|
||||
|
||||
drmModeFormatModifierBlobIterNext() is added to the DRM api in a different
|
||||
change and it is not upstream at present.
|
||||
|
||||
Internal notes:
|
||||
[1] IN_FORMATS blobs are available since kernel 4.14:
|
||||
- db1689aa61bd1efb5ce9b896e7aa860a85b7f1b6
|
||||
- https://patchwork.freedesktop.org/patch/168543
|
||||
|
||||
[2] 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>
|
||||
---
|
||||
meson.build | 5 +
|
||||
src/egl/drivers/dri2/egl_dri2.h | 3 +
|
||||
src/egl/drivers/dri2/platform_null.c | 221 +++++++++++++++++++++++----
|
||||
3 files changed, 203 insertions(+), 26 deletions(-)
|
||||
|
||||
diff --git a/meson.build b/meson.build
|
||||
index 21d93d372c2..ca89b8ac20d 100644
|
||||
--- a/meson.build
|
||||
+++ b/meson.build
|
||||
@@ -1581,6 +1581,11 @@ if with_gallium_etnaviv
|
||||
_drm_ver = '2.4.89'
|
||||
endif
|
||||
|
||||
+# platform_null relies on DRM format-modifier iterators available since 2.4.108
|
||||
+if with_platform_null
|
||||
+ _drm_ver = '2.4.108'
|
||||
+endif
|
||||
+
|
||||
# Loop over the enables versions and get the highest libdrm requirement for all
|
||||
# active drivers.
|
||||
_drm_blame = ''
|
||||
diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h
|
||||
index eb6e4551087..32ad720b343 100644
|
||||
--- a/src/egl/drivers/dri2/egl_dri2.h
|
||||
+++ b/src/egl/drivers/dri2/egl_dri2.h
|
||||
@@ -117,6 +117,8 @@ struct display_output {
|
||||
uint32_t mode_blob_id;
|
||||
unsigned formats;
|
||||
drmModeAtomicReq *atomic_state;
|
||||
+ uint32_t in_formats_id;
|
||||
+ struct u_vector modifiers;
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -280,6 +282,7 @@ struct dri2_egl_display
|
||||
|
||||
#ifdef HAVE_NULL_PLATFORM
|
||||
bool atomic_enabled;
|
||||
+ bool in_formats_enabled;
|
||||
struct display_output output;
|
||||
#endif
|
||||
|
||||
diff --git a/src/egl/drivers/dri2/platform_null.c b/src/egl/drivers/dri2/platform_null.c
|
||||
index d36dc0ced2a..2c79199da26 100644
|
||||
--- a/src/egl/drivers/dri2/platform_null.c
|
||||
+++ b/src/egl/drivers/dri2/platform_null.c
|
||||
@@ -40,6 +40,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
+#include <util/u_vector.h>
|
||||
#include <xf86drm.h>
|
||||
|
||||
#include "egl_dri2.h"
|
||||
@@ -156,6 +157,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,
|
||||
@@ -645,7 +658,66 @@ drm_event_process(int fd)
|
||||
}
|
||||
|
||||
static bool
|
||||
-display_output_init(int fd, struct display_output *output, bool use_atomic)
|
||||
+plane_init_in_formats(int fd, drmModePlane *plane, struct u_vector *modifiers,
|
||||
+ uint32_t *in_formats_id_out, unsigned *formats_out)
|
||||
+{
|
||||
+ uint32_t blob_id, prev_fmt = DRM_FORMAT_INVALID, count_formats = 0;
|
||||
+ drmModeFormatModifierIterator drm_iter = {0};
|
||||
+ drmModePropertyBlobRes *blob;
|
||||
+ uint64_t prop_value;
|
||||
+ int idx, err;
|
||||
+
|
||||
+ assert(plane && in_formats_id_out && formats_out);
|
||||
+
|
||||
+ err = !object_property_value_for_name(fd, plane->plane_id,
|
||||
+ DRM_MODE_OBJECT_PLANE,
|
||||
+ "IN_FORMATS", &prop_value);
|
||||
+ if (err)
|
||||
+ return false;
|
||||
+
|
||||
+ blob_id = blob_id_from_property_value(prop_value);
|
||||
+ blob = drmModeGetPropertyBlob(fd, blob_id);
|
||||
+
|
||||
+ while (drmModeFormatModifierBlobIterNext(blob, &drm_iter)) {
|
||||
+ if (drm_iter.fmt != prev_fmt) {
|
||||
+ prev_fmt = drm_iter.fmt;
|
||||
+ count_formats++;
|
||||
+
|
||||
+ idx = format_idx_get_from_drm_format(drm_iter.fmt);
|
||||
+ if (idx < 0)
|
||||
+ continue;
|
||||
+
|
||||
+ *formats_out |= (1 << idx);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ drmModeFreePropertyBlob(blob);
|
||||
+
|
||||
+ if (!count_formats) {
|
||||
+ /* None of the formats in the IN_FORMATS blob has associated modifiers */
|
||||
+ _eglLog(_EGL_WARNING, "no format-modifiers found in IN_FORMATS");
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ if (plane->count_formats != count_formats)
|
||||
+ /* Only some of the formats in the IN_FORMATS blob have associated modifiers,
|
||||
+ * try to use this subset.
|
||||
+ */
|
||||
+ _eglLog(_EGL_WARNING, "discarding formats without modifiers");
|
||||
+
|
||||
+ /* Allocate space for modifiers, if ENOMEM fallback to plane formats */
|
||||
+ if (!u_vector_init(modifiers, sizeof(uint64_t), 64)) {
|
||||
+ _eglLog(_EGL_WARNING, "failed to allocate modifiers");
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ *in_formats_id_out = blob_id;
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
+static bool
|
||||
+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;
|
||||
@@ -674,16 +746,34 @@ display_output_init(int fd, struct display_output *output, bool use_atomic)
|
||||
goto err_free_plane;
|
||||
output->mode = connector->modes[mode_idx];
|
||||
|
||||
- /* Record the display supported formats */
|
||||
- for (unsigned i = 0; i < plane->count_formats; i++) {
|
||||
- int format_idx;
|
||||
+ assert(in_formats_enabled_out && !(*in_formats_enabled_out));
|
||||
|
||||
- format_idx = format_idx_get_from_drm_format(plane->formats[i]);
|
||||
- if (format_idx == -1)
|
||||
- continue;
|
||||
+ /* Track display supported formats. Look them up from IN_FORMATS blobs
|
||||
+ * if they are available, otherwise use plane formats.
|
||||
+ */
|
||||
+ if (prefer_in_formats)
|
||||
+ *in_formats_enabled_out = plane_init_in_formats(fd, plane,
|
||||
+ &output->modifiers,
|
||||
+ &output->in_formats_id,
|
||||
+ &output->formats);
|
||||
|
||||
- output->formats |= (1 << format_idx);
|
||||
+ if (!*in_formats_enabled_out) {
|
||||
+ _eglLog(_EGL_WARNING, "fallback to plane formats");
|
||||
+
|
||||
+ for (unsigned i = 0; i < plane->count_formats; i++) {
|
||||
+ int format_idx;
|
||||
+
|
||||
+ format_idx = format_idx_get_from_drm_format(plane->formats[i]);
|
||||
+ 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;
|
||||
|
||||
@@ -983,10 +1073,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 +1093,47 @@ 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);
|
||||
+ uint32_t count_modifiers;
|
||||
+ uint64_t *modifiers;
|
||||
+
|
||||
+ if (dri2_dpy->in_formats_enabled) {
|
||||
+ count_modifiers = u_vector_length(&dri2_dpy->output.modifiers);
|
||||
+ modifiers = u_vector_tail(&dri2_dpy->output.modifiers);
|
||||
+
|
||||
+ return dri2_dpy->image->createImageWithModifiers(dri2_dpy->dri_screen,
|
||||
+ dri2_surf->base.Width,
|
||||
+ dri2_surf->base.Height,
|
||||
+ dri2_surf->format,
|
||||
+ modifiers,
|
||||
+ 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 +1146,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 +1183,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 +1214,30 @@ 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(const int fd, const uint32_t in_formats_id,
|
||||
+ const int drm_format, struct u_vector *modifiers)
|
||||
+{
|
||||
+ drmModeFormatModifierIterator drm_iter = {0};
|
||||
+ drmModePropertyBlobRes *blob;
|
||||
+ uint64_t *mod = NULL;
|
||||
+
|
||||
+ blob = drmModeGetPropertyBlob(fd, in_formats_id);
|
||||
+
|
||||
+ while (drmModeFormatModifierBlobIterNext(blob, &drm_iter)) {
|
||||
+ if (drm_iter.fmt == drm_format) {
|
||||
+ assert(drm_iter.mod != DRM_FORMAT_MOD_INVALID);
|
||||
+
|
||||
+ mod = u_vector_add(modifiers);
|
||||
+ *mod = drm_iter.mod;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ drmModeFreePropertyBlob(blob);
|
||||
+
|
||||
+ return mod != NULL;
|
||||
+}
|
||||
+
|
||||
static _EGLSurface *
|
||||
create_surface(_EGLDisplay *disp, _EGLConfig *config, EGLint type,
|
||||
const EGLint *attrib_list)
|
||||
@@ -1105,6 +1249,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 +1282,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->fd,
|
||||
+ dri2_dpy->output.in_formats_id,
|
||||
+ dri2_null_formats[format_idx].drm_format,
|
||||
+ &dri2_dpy->output.modifiers);
|
||||
+ if (!ret)
|
||||
+ goto err_free_surface;
|
||||
+ }
|
||||
+
|
||||
surface_swap_queue_init(dri2_surf);
|
||||
|
||||
return surf;
|
||||
@@ -1536,6 +1690,8 @@ EGLBoolean
|
||||
dri2_initialize_null(_EGLDisplay *disp)
|
||||
{
|
||||
struct dri2_egl_display *dri2_dpy;
|
||||
+ bool prefer_in_formats = false;
|
||||
+ uint64_t value;
|
||||
int err;
|
||||
|
||||
dri2_dpy = calloc(1, sizeof(*dri2_dpy));
|
||||
@@ -1589,8 +1745,19 @@ dri2_initialize_null(_EGLDisplay *disp)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
+ err = drmGetCap(dri2_dpy->fd_dpy, DRM_CAP_ADDFB2_MODIFIERS, &value);
|
||||
+ if (!err && value) {
|
||||
+ /* 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;
|
||||
}
|
||||
@@ -1640,4 +1807,6 @@ dri2_teardown_null(struct dri2_egl_display *dri2_dpy)
|
||||
drmModeFreeProperty(dri2_dpy->output.connector_prop_res[i]);
|
||||
free(dri2_dpy->output.connector_prop_res);
|
||||
}
|
||||
+
|
||||
+ u_vector_finish(&dri2_dpy->output.modifiers);
|
||||
}
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,203 @@
|
||||
From 1e6466e541e1fc67198be3eeb090e3af22bd6d19 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 43/67] 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 6490f6e80e2..9c7bcac4cae 100644
|
||||
--- a/include/GL/internal/dri_interface.h
|
||||
+++ b/include/GL/internal/dri_interface.h
|
||||
@@ -2052,6 +2052,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 6b26ff979ae..c4a49cae592 100644
|
||||
--- a/src/egl/drivers/dri2/egl_dri2.c
|
||||
+++ b/src/egl/drivers/dri2/egl_dri2.c
|
||||
@@ -2055,6 +2055,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)
|
||||
{
|
||||
@@ -4336,6 +4356,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 18c73c9cd8b..2690a82eb75 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 2d3931dfd26..1cbff9656e4 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 15de7c99496..7274d246194 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.25.1
|
||||
|
||||
@@ -0,0 +1,144 @@
|
||||
From 64e6997ded5825f10125313ea15e3164bdad769b 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 44/67] 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 | 20 ++++++++++++++++----
|
||||
src/meson.build | 2 +-
|
||||
5 files changed, 27 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/meson.build b/meson.build
|
||||
index 21d93d372c2..8db1699729a 100644
|
||||
--- a/meson.build
|
||||
+++ b/meson.build
|
||||
@@ -485,6 +485,10 @@ if with_egl and not _platforms.contains(egl_native_platform)
|
||||
error('-Degl-native-platform does not specify an enabled platform')
|
||||
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 ['freebsd', 'openbsd', 'haiku'].contains(host_machine.system()) and
|
||||
@@ -502,7 +506,7 @@ if (not ['freebsd', 'openbsd', 'haiku'].contains(host_machine.system()) and
|
||||
endif
|
||||
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'
|
||||
@@ -564,7 +568,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 d90a25f97ff..d36e714ea4c 100644
|
||||
--- a/meson_options.txt
|
||||
+++ b/meson_options.txt
|
||||
@@ -290,7 +290,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 8f642d5e14b..605a9717e37 100644
|
||||
--- a/src/glx/meson.build
|
||||
+++ b/src/glx/meson.build
|
||||
@@ -122,7 +122,15 @@ else
|
||||
)
|
||||
endif
|
||||
|
||||
-libglx = static_library(
|
||||
+gl_lib_cargs = [
|
||||
+ '-D_REENTRANT',
|
||||
+]
|
||||
+
|
||||
+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],
|
||||
@@ -138,13 +146,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 c3bab27718d..f6eede56648 100644
|
||||
--- a/src/meson.build
|
||||
+++ b/src/meson.build
|
||||
@@ -110,7 +110,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.25.1
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
From 394d340dda351452571ec8861d6768c52d338251 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 45/67] 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 72456d5d748..06272d4081e 100644
|
||||
--- a/src/egl/drivers/dri2/platform_wayland.c
|
||||
+++ b/src/egl/drivers/dri2/platform_wayland.c
|
||||
@@ -266,6 +266,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;
|
||||
@@ -786,8 +789,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->wl_win &&
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,539 @@
|
||||
From ed4671544a6add01e87e94c04df59a600403dd21 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 46/67] 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 e231c176264..974f366d7b4 100644
|
||||
--- a/src/mapi/glapi/gen/static_data.py
|
||||
+++ b/src/mapi/glapi/gen/static_data.py
|
||||
@@ -1706,6 +1706,21 @@ offsets = {
|
||||
"FramebufferTextureMultisampleMultiviewOVR" : 1670,
|
||||
"MultiDrawArraysIndirectEXT" : 1671,
|
||||
"MultiDrawElementsIndirectEXT" : 1672,
|
||||
+ "IsRenderbufferEXT" : 1673,
|
||||
+ "DeleteRenderbuffersEXT" : 1674,
|
||||
+ "GenRenderbuffersEXT" : 1675,
|
||||
+ "RenderbufferStorageEXT" : 1676,
|
||||
+ "GetRenderbufferParameterivEXT" : 1677,
|
||||
+ "IsFramebufferEXT" : 1678,
|
||||
+ "DeleteFramebuffersEXT" : 1679,
|
||||
+ "GenFramebuffersEXT" : 1680,
|
||||
+ "CheckFramebufferStatusEXT" : 1681,
|
||||
+ "FramebufferTexture1DEXT" : 1682,
|
||||
+ "FramebufferTexture2DEXT" : 1683,
|
||||
+ "FramebufferTexture3DEXT" : 1684,
|
||||
+ "FramebufferRenderbufferEXT" : 1685,
|
||||
+ "GetFramebufferAttachmentParameterivEXT" : 1686,
|
||||
+ "GenerateMipmapEXT" : 1687,
|
||||
}
|
||||
|
||||
functions = [
|
||||
diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c
|
||||
index 49893165250..885aa442911 100644
|
||||
--- a/src/mesa/main/fbobject.c
|
||||
+++ b/src/mesa/main/fbobject.c
|
||||
@@ -1995,6 +1995,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)
|
||||
@@ -2722,6 +2727,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)
|
||||
{
|
||||
@@ -2752,6 +2763,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
|
||||
@@ -2784,6 +2800,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,
|
||||
@@ -2985,6 +3007,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,
|
||||
@@ -3018,6 +3045,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
|
||||
@@ -3253,6 +3285,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.
|
||||
@@ -3299,6 +3336,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)
|
||||
@@ -3338,6 +3380,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)
|
||||
@@ -3950,6 +3997,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,
|
||||
@@ -3990,6 +4043,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,
|
||||
@@ -4100,6 +4159,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,
|
||||
@@ -4353,6 +4421,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,
|
||||
@@ -4754,6 +4831,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 36727bb7060..8d262e53852 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.25.1
|
||||
|
||||
@@ -0,0 +1,321 @@
|
||||
From f775167cbe3f324468f8f355be13bd6efa7d4567 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 47/67] 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 0f683d76e18..13b808bff80 100644
|
||||
--- a/src/egl/drivers/dri2/egl_dri2.h
|
||||
+++ b/src/egl/drivers/dri2/egl_dri2.h
|
||||
@@ -282,6 +282,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
|
||||
|
||||
@@ -442,8 +443,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;
|
||||
@@ -472,12 +477,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 48a586b6f38..33cf576f147 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) {
|
||||
@@ -1640,18 +1722,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.25.1
|
||||
|
||||
@@ -0,0 +1,229 @@
|
||||
From 4d19dc5cc9be4f3f25ed8befbfcda70c047065d3 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 48/67] 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 13b808bff80..141df1b1732 100644
|
||||
--- a/src/egl/drivers/dri2/egl_dri2.h
|
||||
+++ b/src/egl/drivers/dri2/egl_dri2.h
|
||||
@@ -471,6 +471,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 2b329437f88..258e8b6593e 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_dri_surface *surf = dri2_surf->gbm_surf;
|
||||
+
|
||||
+ dri2_surf->front_bo = gbm_bo_create(&dri2_dpy->gbm_dri->base,
|
||||
+ surf->base.v0.width,
|
||||
+ surf->base.v0.height,
|
||||
+ surf->base.v0.format,
|
||||
+ surf->base.v0.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);
|
||||
|
||||
@@ -402,12 +472,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;
|
||||
}
|
||||
@@ -425,6 +510,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;
|
||||
@@ -648,7 +736,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++;
|
||||
@@ -672,6 +761,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.25.1
|
||||
|
||||
@@ -0,0 +1,347 @@
|
||||
From b0ea3289c16d31d840af71876187cf30b2b32e9a Mon Sep 17 00:00:00 2001
|
||||
From: Luigi Santivetti <luigi.santivetti@imgtec.com>
|
||||
Date: Thu, 2 Sep 2021 22:47:54 +0100
|
||||
Subject: [PATCH 49/68] egl/null: expose EXT_yuv_surface support
|
||||
|
||||
---
|
||||
include/GL/internal/dri_interface.h | 2 +
|
||||
src/egl/drivers/dri2/platform_null.c | 177 ++++++++++++++++++++++++---
|
||||
src/mesa/drivers/dri/pvr/pvrutil.c | 8 ++
|
||||
3 files changed, 173 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
|
||||
index 9c7bcac4cae..888a117d56e 100644
|
||||
--- a/include/GL/internal/dri_interface.h
|
||||
+++ b/include/GL/internal/dri_interface.h
|
||||
@@ -1411,6 +1411,8 @@ struct __DRIdri2ExtensionRec {
|
||||
#define __DRI_IMAGE_FORMAT_ARGB4444 0x1018
|
||||
#define __DRI_IMAGE_FORMAT_YVU444_PACK10_IMG 0x1019
|
||||
#define __DRI_IMAGE_FORMAT_BGR888 0x101a
|
||||
+#define __DRI_IMAGE_FORMAT_NV12 0x101b
|
||||
+#define __DRI_IMAGE_FORMAT_NV21 0x101c
|
||||
|
||||
#define __DRI_IMAGE_USE_SHARE 0x0001
|
||||
#define __DRI_IMAGE_USE_SCANOUT 0x0002
|
||||
diff --git a/src/egl/drivers/dri2/platform_null.c b/src/egl/drivers/dri2/platform_null.c
|
||||
index f2c481c256b..d1e576af5ce 100644
|
||||
--- a/src/egl/drivers/dri2/platform_null.c
|
||||
+++ b/src/egl/drivers/dri2/platform_null.c
|
||||
@@ -79,6 +79,35 @@ uint32_t get_back_buffer_id(struct dri2_egl_surface *dri2_surf)
|
||||
.prop_value = value, \
|
||||
}
|
||||
|
||||
+static const struct dri2_null_yuv_attrib {
|
||||
+ uint32_t order;
|
||||
+ uint32_t subsample;
|
||||
+ uint32_t num_planes;
|
||||
+ uint32_t plane_bpp;
|
||||
+} dri2_null_yuv_attribs[] = {
|
||||
+ {
|
||||
+ /* __DRI_IMAGE_FORMAT_YUYV */
|
||||
+ .order = __DRI_ATTRIB_YUV_ORDER_YUYV_BIT,
|
||||
+ .subsample = __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_2_BIT,
|
||||
+ .num_planes = 1,
|
||||
+ .plane_bpp = __DRI_ATTRIB_YUV_PLANE_BPP_8_BIT,
|
||||
+ },
|
||||
+ {
|
||||
+ /* __DRI_IMAGE_FORMAT_NV12 */
|
||||
+ .order = __DRI_ATTRIB_YUV_ORDER_YUV_BIT,
|
||||
+ .subsample = __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_0_BIT,
|
||||
+ .num_planes = 2,
|
||||
+ .plane_bpp = __DRI_ATTRIB_YUV_PLANE_BPP_8_BIT,
|
||||
+ },
|
||||
+ {
|
||||
+ /* __DRI_IMAGE_FORMAT_NV21 */
|
||||
+ .order = __DRI_ATTRIB_YUV_ORDER_YVU_BIT,
|
||||
+ .subsample = __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_0_BIT,
|
||||
+ .num_planes = 2,
|
||||
+ .plane_bpp = __DRI_ATTRIB_YUV_PLANE_BPP_8_BIT,
|
||||
+ },
|
||||
+};
|
||||
+
|
||||
/*
|
||||
* The index of entries in this table is used as a bitmask in
|
||||
* dri2_dpy->formats, which tracks the formats supported by the display.
|
||||
@@ -88,24 +117,49 @@ static const struct dri2_null_format {
|
||||
int dri_image_format;
|
||||
int rgba_shifts[4];
|
||||
unsigned int rgba_sizes[4];
|
||||
+ const struct dri2_null_yuv_attrib *yuv;
|
||||
} dri2_null_formats[] = {
|
||||
{
|
||||
.drm_format = DRM_FORMAT_XRGB8888,
|
||||
.dri_image_format = __DRI_IMAGE_FORMAT_XRGB8888,
|
||||
.rgba_shifts = { 16, 8, 0, -1 },
|
||||
.rgba_sizes = { 8, 8, 8, 0 },
|
||||
+ .yuv = NULL,
|
||||
},
|
||||
{
|
||||
.drm_format = DRM_FORMAT_ARGB8888,
|
||||
.dri_image_format = __DRI_IMAGE_FORMAT_ARGB8888,
|
||||
.rgba_shifts = { 16, 8, 0, 24 },
|
||||
.rgba_sizes = { 8, 8, 8, 8 },
|
||||
+ .yuv = NULL,
|
||||
},
|
||||
{
|
||||
.drm_format = DRM_FORMAT_RGB565,
|
||||
.dri_image_format = __DRI_IMAGE_FORMAT_RGB565,
|
||||
.rgba_shifts = { 11, 5, 0, -1 },
|
||||
.rgba_sizes = { 5, 6, 5, 0 },
|
||||
+ .yuv = NULL,
|
||||
+ },
|
||||
+ {
|
||||
+ .drm_format = DRM_FORMAT_YUYV,
|
||||
+ .dri_image_format = __DRI_IMAGE_FORMAT_YUYV,
|
||||
+ .rgba_shifts = { -1, -1, -1, -1 },
|
||||
+ .rgba_sizes = { 0, 0, 0, 0 },
|
||||
+ .yuv = &dri2_null_yuv_attribs[0],
|
||||
+ },
|
||||
+ {
|
||||
+ .drm_format = DRM_FORMAT_NV12,
|
||||
+ .dri_image_format = __DRI_IMAGE_FORMAT_NV12,
|
||||
+ .rgba_shifts = { -1, -1, -1, -1 },
|
||||
+ .rgba_sizes = { 0, 0, 0, 0 },
|
||||
+ .yuv = &dri2_null_yuv_attribs[1],
|
||||
+ },
|
||||
+ {
|
||||
+ .drm_format = DRM_FORMAT_NV21,
|
||||
+ .dri_image_format = __DRI_IMAGE_FORMAT_NV21,
|
||||
+ .rgba_shifts = { -1, -1, -1, -1 },
|
||||
+ .rgba_sizes = { 0, 0, 0, 0 },
|
||||
+ .yuv = &dri2_null_yuv_attribs[2],
|
||||
},
|
||||
};
|
||||
|
||||
@@ -137,6 +191,36 @@ format_idx_get_from_config(struct dri2_egl_display *dri2_dpy,
|
||||
return -1;
|
||||
}
|
||||
|
||||
+static int
|
||||
+yuv_format_idx_get_from_config(struct dri2_egl_display *dri2_dpy,
|
||||
+ const __DRIconfig *dri_config)
|
||||
+{
|
||||
+ for (unsigned int i = 0; i < ARRAY_SIZE(dri2_null_formats); i++) {
|
||||
+ const struct dri2_null_yuv_attrib *yuv = dri2_null_formats[i].yuv;
|
||||
+ unsigned order, subsample, num_planes, plane_bpp;
|
||||
+
|
||||
+ if (!yuv)
|
||||
+ continue;
|
||||
+
|
||||
+ 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 (order != yuv->order || subsample != yuv->subsample ||
|
||||
+ num_planes != yuv->num_planes || plane_bpp != yuv->plane_bpp)
|
||||
+ continue;
|
||||
+
|
||||
+ return i;
|
||||
+ }
|
||||
+
|
||||
+ return -1;
|
||||
+}
|
||||
+
|
||||
static int
|
||||
format_idx_get_from_dri_image_format(uint32_t dri_image_format)
|
||||
{
|
||||
@@ -1082,23 +1166,21 @@ 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};
|
||||
+ int handle, stride, width, height, format, l_mod, h_mod, offset;
|
||||
+ uint64_t modifier = DRM_FORMAT_MOD_INVALID;
|
||||
+ uint64_t *modifiers = NULL, mods[4] = {0};
|
||||
uint32_t handles[4] = {0};
|
||||
uint32_t pitches[4] = {0};
|
||||
uint32_t offsets[4] = {0};
|
||||
+ __DRIimage *p_image;
|
||||
uint32_t flags = 0;
|
||||
- int handle, stride, width, height, format, l_mod, h_mod;
|
||||
int format_idx;
|
||||
+ int num_planes;
|
||||
|
||||
- dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_HANDLE, &handle);
|
||||
- dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_STRIDE, &stride);
|
||||
dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_WIDTH, &width);
|
||||
dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_HEIGHT, &height);
|
||||
dri2_dpy->image->queryImage(image, __DRI_IMAGE_ATTRIB_FORMAT, &format);
|
||||
|
||||
- handles[0] = (uint32_t) handle;
|
||||
- pitches[0] = (uint32_t) stride;
|
||||
-
|
||||
format_idx = format_idx_get_from_dri_image_format(format);
|
||||
assert(format_idx != -1);
|
||||
|
||||
@@ -1106,10 +1188,44 @@ add_fb_for_dri_image(struct dri2_egl_display *dri2_dpy, __DRIimage *image,
|
||||
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);
|
||||
+ modifier = combine_u32_into_u64((uint32_t) h_mod, (uint32_t) l_mod);
|
||||
+ modifiers = mods;
|
||||
+
|
||||
flags |= DRM_MODE_FB_MODIFIERS;
|
||||
}
|
||||
|
||||
+ dri2_dpy->image->queryImage(image,
|
||||
+ __DRI_IMAGE_ATTRIB_NUM_PLANES, &num_planes);
|
||||
+ if (num_planes <= 0)
|
||||
+ num_planes = 1;
|
||||
+
|
||||
+ for (int i = 0; i < num_planes; i++) {
|
||||
+ if (dri2_dpy->in_formats_enabled) {
|
||||
+ assert(modifiers && modifier != DRM_FORMAT_MOD_INVALID);
|
||||
+ modifiers[i] = modifier;
|
||||
+ }
|
||||
+
|
||||
+ p_image = dri2_dpy->image->fromPlanar(image, i, NULL);
|
||||
+ if (!p_image) {
|
||||
+ assert(i == 0);
|
||||
+ p_image = image;
|
||||
+ }
|
||||
+
|
||||
+ dri2_dpy->image->queryImage(p_image, __DRI_IMAGE_ATTRIB_STRIDE,
|
||||
+ &stride);
|
||||
+ dri2_dpy->image->queryImage(p_image, __DRI_IMAGE_ATTRIB_OFFSET,
|
||||
+ &offset);
|
||||
+ dri2_dpy->image->queryImage(p_image, __DRI_IMAGE_ATTRIB_HANDLE,
|
||||
+ &handle);
|
||||
+
|
||||
+ if (p_image != image)
|
||||
+ dri2_dpy->image->destroyImage(p_image);
|
||||
+
|
||||
+ pitches[i] = (uint32_t) stride;
|
||||
+ offsets[i] = (uint32_t) offset;
|
||||
+ handles[i] = (uint32_t) handle;
|
||||
+ }
|
||||
+
|
||||
return !drmModeAddFB2WithModifiers(dri2_dpy->fd, width, height,
|
||||
dri2_null_formats[format_idx].drm_format,
|
||||
handles, pitches, offsets, modifiers,
|
||||
@@ -1256,6 +1372,7 @@ create_surface(_EGLDisplay *disp, _EGLConfig *config, EGLint type,
|
||||
struct dri2_egl_config *dri2_config = dri2_egl_config(config);
|
||||
struct dri2_egl_surface *dri2_surf;
|
||||
const __DRIconfig *dri_config;
|
||||
+ unsigned int render_type;
|
||||
_EGLSurface *surf;
|
||||
int format_idx;
|
||||
bool ret;
|
||||
@@ -1286,7 +1403,14 @@ create_surface(_EGLDisplay *disp, _EGLConfig *config, EGLint type,
|
||||
goto err_free_surface;
|
||||
}
|
||||
|
||||
- format_idx = format_idx_get_from_config(dri2_dpy, dri_config);
|
||||
+ if (!dri2_dpy->core->getConfigAttrib(dri_config, __DRI_ATTRIB_RENDER_TYPE,
|
||||
+ &render_type))
|
||||
+ goto err_free_surface;
|
||||
+
|
||||
+ if (render_type & __DRI_ATTRIB_YUV_BIT)
|
||||
+ format_idx = yuv_format_idx_get_from_config(dri2_dpy, dri_config);
|
||||
+ else
|
||||
+ format_idx = format_idx_get_from_config(dri2_dpy, dri_config);
|
||||
assert(format_idx != -1);
|
||||
|
||||
dri2_surf->format = dri2_null_formats[format_idx].dri_image_format;
|
||||
@@ -1627,6 +1751,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)
|
||||
{
|
||||
@@ -1635,10 +1770,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[] = {
|
||||
@@ -1720,10 +1856,24 @@ 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 = EGL_WINDOW_BIT;
|
||||
+ unsigned int render_type;
|
||||
int format_idx;
|
||||
|
||||
- format_idx = format_idx_get_from_config(dri2_dpy,
|
||||
- dri2_dpy->driver_configs[i]);
|
||||
+ if (!dri2_dpy->core->getConfigAttrib(dri2_dpy->driver_configs[i],
|
||||
+ __DRI_ATTRIB_RENDER_TYPE,
|
||||
+ &render_type))
|
||||
+ continue;
|
||||
+
|
||||
+ if (render_type & __DRI_ATTRIB_YUV_BIT) {
|
||||
+ format_idx = yuv_format_idx_get_from_config(dri2_dpy,
|
||||
+ dri2_dpy->driver_configs[i]);
|
||||
+ } else {
|
||||
+ format_idx = format_idx_get_from_config(dri2_dpy,
|
||||
+ dri2_dpy->driver_configs[i]);
|
||||
+ surface_type |= EGL_PBUFFER_BIT;
|
||||
+ }
|
||||
+
|
||||
if (format_idx == -1)
|
||||
continue;
|
||||
|
||||
@@ -1735,8 +1885,7 @@ dri2_null_add_configs_for_formats(_EGLDisplay *disp)
|
||||
|
||||
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++;
|
||||
}
|
||||
diff --git a/src/mesa/drivers/dri/pvr/pvrutil.c b/src/mesa/drivers/dri/pvr/pvrutil.c
|
||||
index 945e18cf220..d107a5dafad 100644
|
||||
--- a/src/mesa/drivers/dri/pvr/pvrutil.c
|
||||
+++ b/src/mesa/drivers/dri/pvr/pvrutil.c
|
||||
@@ -174,6 +174,10 @@ PVRDRIFormatToFourCC(int dri_format)
|
||||
return DRM_FORMAT_YVU444_PACK10_IMG;
|
||||
case __DRI_IMAGE_FORMAT_BGR888:
|
||||
return DRM_FORMAT_BGR888;
|
||||
+ case __DRI_IMAGE_FORMAT_NV12:
|
||||
+ return DRM_FORMAT_NV12;
|
||||
+ case __DRI_IMAGE_FORMAT_NV21:
|
||||
+ return DRM_FORMAT_NV21;
|
||||
default:
|
||||
__driUtilMessage("%s: Unknown format: %d", __func__, dri_format);
|
||||
break;
|
||||
@@ -230,6 +234,10 @@ PVRDRIFourCCToDRIFormat(int iFourCC)
|
||||
return __DRI_IMAGE_FORMAT_YVU444_PACK10_IMG;
|
||||
case DRM_FORMAT_BGR888:
|
||||
return __DRI_IMAGE_FORMAT_BGR888;
|
||||
+ case DRM_FORMAT_NV12:
|
||||
+ return __DRI_IMAGE_FORMAT_NV12;
|
||||
+ case DRM_FORMAT_NV21:
|
||||
+ return __DRI_IMAGE_FORMAT_NV21;
|
||||
default:
|
||||
__driUtilMessage("%s: Unknown format: %d", __func__, iFourCC);
|
||||
break;
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,433 @@
|
||||
From db015d5fd0ded075e759677c047c581151bb1b52 Mon Sep 17 00:00:00 2001
|
||||
From: Brendan King <Brendan.King@imgtec.com>
|
||||
Date: Tue, 9 Mar 2021 17:15:30 +0000
|
||||
Subject: [PATCH 50/67] dri: preserve the original FD for driver use.
|
||||
|
||||
If an application uses a different GPU from the default, allow the
|
||||
file descriptor (FD) for that original GPU/display to be preserved
|
||||
for use by drivers. Drivers may wish to use the original FD to
|
||||
allocate shared surfaces, to ensure the surface properties are
|
||||
compatible with the original GPU/display (e.g. for X11 or Wayland).
|
||||
|
||||
This feature is only available on platforms that choose to support
|
||||
it, by implementing the new getDisplayFD function in the DRI image,
|
||||
and DRI2 loader extensions.
|
||||
|
||||
If the feature is available, drivers can obtain the original FD
|
||||
by calling the getDisplayFD function in the relevant loader extension.
|
||||
Drivers should check the FD is valid before use (i.e. not -1). If
|
||||
the FD is valid, it may be equal to the current GPU FD if a different
|
||||
GPU is not being used. The FD is owned by the platform, not the
|
||||
driver, and the platform is responsible for closing it.
|
||||
|
||||
The feature is currently supported by the Wayland, and DRI3 based
|
||||
X11 EGL and GLX platforms.
|
||||
---
|
||||
include/GL/internal/dri_interface.h | 26 +++++++++++++++++--
|
||||
src/egl/drivers/dri2/egl_dri2.c | 10 +++++++
|
||||
src/egl/drivers/dri2/egl_dri2.h | 1 +
|
||||
src/egl/drivers/dri2/platform_wayland.c | 31 ++++++++++++++++++++--
|
||||
src/egl/drivers/dri2/platform_x11.c | 3 +++
|
||||
src/egl/drivers/dri2/platform_x11_dri3.c | 27 ++++++++++++++++++-
|
||||
src/glx/dri3_glx.c | 33 ++++++++++++++++++++++--
|
||||
src/glx/dri3_priv.h | 1 +
|
||||
8 files changed, 125 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
|
||||
index 888a117d56e..2fb440feb50 100644
|
||||
--- a/include/GL/internal/dri_interface.h
|
||||
+++ b/include/GL/internal/dri_interface.h
|
||||
@@ -1146,7 +1146,7 @@ struct __DRIbufferRec {
|
||||
};
|
||||
|
||||
#define __DRI_DRI2_LOADER "DRI_DRI2Loader"
|
||||
-#define __DRI_DRI2_LOADER_VERSION 5
|
||||
+#define __DRI_DRI2_LOADER_VERSION 6
|
||||
|
||||
enum dri_loader_cap {
|
||||
/* Whether the loader handles RGBA channel ordering correctly. If not,
|
||||
@@ -1227,6 +1227,17 @@ struct __DRIdri2LoaderExtensionRec {
|
||||
* \since 5
|
||||
*/
|
||||
void (*destroyLoaderImageState)(void *loaderPrivate);
|
||||
+
|
||||
+ /**
|
||||
+ * Get the display FD
|
||||
+ *
|
||||
+ * Get the FD of the display device.
|
||||
+ *
|
||||
+ * \param loaderPrivate The last parameter of createNewScreen or
|
||||
+ * createNewScreen2.
|
||||
+ * \since 6
|
||||
+ */
|
||||
+ int (*getDisplayFD)(void *loaderPrivate);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -2131,7 +2142,7 @@ struct __DRIimageList {
|
||||
};
|
||||
|
||||
#define __DRI_IMAGE_LOADER "DRI_IMAGE_LOADER"
|
||||
-#define __DRI_IMAGE_LOADER_VERSION 4
|
||||
+#define __DRI_IMAGE_LOADER_VERSION 5
|
||||
|
||||
struct __DRIimageLoaderExtensionRec {
|
||||
__DRIextension base;
|
||||
@@ -2199,6 +2210,17 @@ struct __DRIimageLoaderExtensionRec {
|
||||
* \since 4
|
||||
*/
|
||||
void (*destroyLoaderImageState)(void *loaderPrivate);
|
||||
+
|
||||
+ /**
|
||||
+ * Get the display FD
|
||||
+ *
|
||||
+ * Get the FD of the display device.
|
||||
+ *
|
||||
+ * \param loaderPrivate The last parameter of createNewScreen or
|
||||
+ * createNewScreen2.
|
||||
+ * \since 5
|
||||
+ */
|
||||
+ int (*getDisplayFD)(void *loaderPrivate);
|
||||
};
|
||||
|
||||
/**
|
||||
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
|
||||
index c4a49cae592..1df53ef011c 100644
|
||||
--- a/src/egl/drivers/dri2/egl_dri2.c
|
||||
+++ b/src/egl/drivers/dri2/egl_dri2.c
|
||||
@@ -1367,6 +1367,16 @@ dri2_display_destroy(_EGLDisplay *disp)
|
||||
break;
|
||||
}
|
||||
|
||||
+ switch (disp->Platform) {
|
||||
+ case _EGL_PLATFORM_WAYLAND:
|
||||
+ case _EGL_PLATFORM_X11:
|
||||
+ if (dri2_dpy->fd_dpy >= 0 && dri2_dpy->fd_dpy != dri2_dpy->fd)
|
||||
+ close(dri2_dpy->fd_dpy);
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
if (dri2_dpy->fd >= 0)
|
||||
close(dri2_dpy->fd);
|
||||
|
||||
diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h
|
||||
index 141df1b1732..af03caee623 100644
|
||||
--- a/src/egl/drivers/dri2/egl_dri2.h
|
||||
+++ b/src/egl/drivers/dri2/egl_dri2.h
|
||||
@@ -230,6 +230,7 @@ struct dri2_egl_display
|
||||
const __DRIconfigOptionsExtension *configOptions;
|
||||
const __DRImutableRenderBufferDriverExtension *mutable_render_buffer;
|
||||
int fd;
|
||||
+ int fd_dpy;
|
||||
|
||||
/* dri2_initialize/dri2_terminate increment/decrement this count, so does
|
||||
* dri2_make_current (tracks if there are active contexts/surfaces). */
|
||||
diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c
|
||||
index 06272d4081e..b393e058770 100644
|
||||
--- a/src/egl/drivers/dri2/platform_wayland.c
|
||||
+++ b/src/egl/drivers/dri2/platform_wayland.c
|
||||
@@ -44,6 +44,7 @@
|
||||
#include "loader.h"
|
||||
#include "util/u_vector.h"
|
||||
#include "util/anon_file.h"
|
||||
+#include "util/os_file.h"
|
||||
#include "eglglobals.h"
|
||||
|
||||
#include <wayland-egl-backend.h>
|
||||
@@ -973,21 +974,32 @@ dri2_wl_get_capability(void *loaderPrivate, enum dri_loader_cap cap)
|
||||
}
|
||||
}
|
||||
|
||||
+static int
|
||||
+dri2_wl_get_display_fd(void *loaderPrivate)
|
||||
+{
|
||||
+ _EGLDisplay *disp = loaderPrivate;
|
||||
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
|
||||
+
|
||||
+ return dri2_dpy->fd_dpy;
|
||||
+}
|
||||
+
|
||||
static const __DRIdri2LoaderExtension dri2_loader_extension = {
|
||||
- .base = { __DRI_DRI2_LOADER, 4 },
|
||||
+ .base = { __DRI_DRI2_LOADER, 6 },
|
||||
|
||||
.getBuffers = dri2_wl_get_buffers,
|
||||
.flushFrontBuffer = dri2_wl_flush_front_buffer,
|
||||
.getBuffersWithFormat = dri2_wl_get_buffers_with_format,
|
||||
.getCapability = dri2_wl_get_capability,
|
||||
+ .getDisplayFD = dri2_wl_get_display_fd,
|
||||
};
|
||||
|
||||
static const __DRIimageLoaderExtension image_loader_extension = {
|
||||
- .base = { __DRI_IMAGE_LOADER, 2 },
|
||||
+ .base = { __DRI_IMAGE_LOADER, 5 },
|
||||
|
||||
.getBuffers = image_get_buffers,
|
||||
.flushFrontBuffer = dri2_wl_flush_front_buffer,
|
||||
.getCapability = dri2_wl_get_capability,
|
||||
+ .getDisplayFD = dri2_wl_get_display_fd,
|
||||
};
|
||||
|
||||
static void
|
||||
@@ -1640,12 +1652,14 @@ dri2_initialize_wayland_drm(_EGLDisplay *disp)
|
||||
{
|
||||
_EGLDevice *dev;
|
||||
struct dri2_egl_display *dri2_dpy;
|
||||
+ int fd_old;
|
||||
|
||||
dri2_dpy = calloc(1, sizeof *dri2_dpy);
|
||||
if (!dri2_dpy)
|
||||
return _eglError(EGL_BAD_ALLOC, "eglInitialize");
|
||||
|
||||
dri2_dpy->fd = -1;
|
||||
+ dri2_dpy->fd_dpy = -1;
|
||||
disp->DriverData = (void *) dri2_dpy;
|
||||
if (disp->PlatformDisplay == NULL) {
|
||||
dri2_dpy->wl_dpy = wl_display_connect(NULL);
|
||||
@@ -1690,8 +1704,20 @@ dri2_initialize_wayland_drm(_EGLDisplay *disp)
|
||||
(roundtrip(dri2_dpy) < 0 || !dri2_dpy->authenticated))
|
||||
goto cleanup;
|
||||
|
||||
+ fd_old = dri2_dpy->fd;
|
||||
+ dri2_dpy->fd_dpy = os_dupfd_cloexec(dri2_dpy->fd);
|
||||
dri2_dpy->fd = loader_get_user_preferred_fd(dri2_dpy->fd,
|
||||
&dri2_dpy->is_different_gpu);
|
||||
+ if (dri2_dpy->fd == fd_old) {
|
||||
+ if (dri2_dpy->fd_dpy != -1)
|
||||
+ close(dri2_dpy->fd_dpy);
|
||||
+
|
||||
+ dri2_dpy->fd_dpy = dri2_dpy->fd;
|
||||
+ } else if (dri2_dpy->fd_dpy == -1) {
|
||||
+ _eglError(EGL_NOT_INITIALIZED, "DRI2: failed to dup display FD");
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
dev = _eglAddDevice(dri2_dpy->fd, false);
|
||||
if (!dev) {
|
||||
_eglError(EGL_NOT_INITIALIZED, "DRI2: failed to find EGLDevice");
|
||||
@@ -2236,6 +2262,7 @@ dri2_initialize_wayland_swrast(_EGLDisplay *disp)
|
||||
return _eglError(EGL_BAD_ALLOC, "eglInitialize");
|
||||
|
||||
dri2_dpy->fd = -1;
|
||||
+ dri2_dpy->fd_dpy = -1;
|
||||
disp->DriverData = (void *) dri2_dpy;
|
||||
if (disp->PlatformDisplay == NULL) {
|
||||
dri2_dpy->wl_dpy = wl_display_connect(NULL);
|
||||
diff --git a/src/egl/drivers/dri2/platform_x11.c b/src/egl/drivers/dri2/platform_x11.c
|
||||
index 5ffdf132184..5cf3ce2a369 100644
|
||||
--- a/src/egl/drivers/dri2/platform_x11.c
|
||||
+++ b/src/egl/drivers/dri2/platform_x11.c
|
||||
@@ -1277,6 +1277,7 @@ dri2_initialize_x11_swrast(_EGLDisplay *disp)
|
||||
return _eglError(EGL_BAD_ALLOC, "eglInitialize");
|
||||
|
||||
dri2_dpy->fd = -1;
|
||||
+ dri2_dpy->fd_dpy = -1;
|
||||
if (!dri2_get_xcb_connection(disp, dri2_dpy))
|
||||
goto cleanup;
|
||||
|
||||
@@ -1364,6 +1365,7 @@ dri2_initialize_x11_dri3(_EGLDisplay *disp)
|
||||
return _eglError(EGL_BAD_ALLOC, "eglInitialize");
|
||||
|
||||
dri2_dpy->fd = -1;
|
||||
+ dri2_dpy->fd_dpy = -1;
|
||||
if (!dri2_get_xcb_connection(disp, dri2_dpy))
|
||||
goto cleanup;
|
||||
|
||||
@@ -1472,6 +1474,7 @@ dri2_initialize_x11_dri2(_EGLDisplay *disp)
|
||||
return _eglError(EGL_BAD_ALLOC, "eglInitialize");
|
||||
|
||||
dri2_dpy->fd = -1;
|
||||
+ dri2_dpy->fd_dpy = -1;
|
||||
if (!dri2_get_xcb_connection(disp, dri2_dpy))
|
||||
goto cleanup;
|
||||
|
||||
diff --git a/src/egl/drivers/dri2/platform_x11_dri3.c b/src/egl/drivers/dri2/platform_x11_dri3.c
|
||||
index e117105fcb6..0babf9f867e 100644
|
||||
--- a/src/egl/drivers/dri2/platform_x11_dri3.c
|
||||
+++ b/src/egl/drivers/dri2/platform_x11_dri3.c
|
||||
@@ -32,6 +32,7 @@
|
||||
|
||||
#include <xf86drm.h>
|
||||
#include "util/macros.h"
|
||||
+#include "util/os_file.h"
|
||||
|
||||
#include "egl_dri2.h"
|
||||
#include "platform_x11_dri3.h"
|
||||
@@ -414,11 +415,21 @@ dri3_flush_front_buffer(__DRIdrawable *driDrawable, void *loaderPrivate)
|
||||
_eglLog(_EGL_WARNING, "FIXME: egl/x11 doesn't support front buffer rendering.");
|
||||
}
|
||||
|
||||
+static int
|
||||
+dri3_get_display_fd(void *loaderPrivate)
|
||||
+{
|
||||
+ _EGLDisplay *disp = loaderPrivate;
|
||||
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
|
||||
+
|
||||
+ return dri2_dpy->fd_dpy;
|
||||
+}
|
||||
+
|
||||
const __DRIimageLoaderExtension dri3_image_loader_extension = {
|
||||
- .base = { __DRI_IMAGE_LOADER, 1 },
|
||||
+ .base = { __DRI_IMAGE_LOADER, 5 },
|
||||
|
||||
.getBuffers = loader_dri3_get_buffers,
|
||||
.flushFrontBuffer = dri3_flush_front_buffer,
|
||||
+ .getDisplayFD = dri3_get_display_fd,
|
||||
};
|
||||
|
||||
static EGLBoolean
|
||||
@@ -537,6 +548,7 @@ dri3_x11_connect(struct dri2_egl_display *dri2_dpy)
|
||||
xcb_xfixes_query_version_cookie_t xfixes_query_cookie;
|
||||
xcb_generic_error_t *error;
|
||||
const xcb_query_extension_reply_t *extension;
|
||||
+ int fd_old;
|
||||
|
||||
xcb_prefetch_extension_data (dri2_dpy->conn, &xcb_dri3_id);
|
||||
xcb_prefetch_extension_data (dri2_dpy->conn, &xcb_present_id);
|
||||
@@ -616,12 +628,25 @@ dri3_x11_connect(struct dri2_egl_display *dri2_dpy)
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
+ fd_old = dri2_dpy->fd;
|
||||
+ dri2_dpy->fd_dpy = os_dupfd_cloexec(dri2_dpy->fd);
|
||||
dri2_dpy->fd = loader_get_user_preferred_fd(dri2_dpy->fd, &dri2_dpy->is_different_gpu);
|
||||
+ if (dri2_dpy->fd == fd_old) {
|
||||
+ if (dri2_dpy->fd_dpy != -1)
|
||||
+ close(dri2_dpy->fd_dpy);
|
||||
+
|
||||
+ dri2_dpy->fd_dpy = dri2_dpy->fd;
|
||||
+ } else if (dri2_dpy->fd_dpy == -1) {
|
||||
+ _eglLog(_EGL_WARNING, "DRI3: failed to dup display FD");
|
||||
+ close(dri2_dpy->fd);
|
||||
+ return EGL_FALSE;
|
||||
+ }
|
||||
|
||||
dri2_dpy->driver_name = loader_get_driver_for_fd(dri2_dpy->fd);
|
||||
if (!dri2_dpy->driver_name) {
|
||||
_eglLog(_EGL_WARNING, "DRI3: No driver found");
|
||||
close(dri2_dpy->fd);
|
||||
+ close(dri2_dpy->fd_dpy);
|
||||
return EGL_FALSE;
|
||||
}
|
||||
|
||||
diff --git a/src/glx/dri3_glx.c b/src/glx/dri3_glx.c
|
||||
index db1b079663f..1ed6b60ffe8 100644
|
||||
--- a/src/glx/dri3_glx.c
|
||||
+++ b/src/glx/dri3_glx.c
|
||||
@@ -77,6 +77,7 @@
|
||||
#include "dri3_priv.h"
|
||||
#include "loader.h"
|
||||
#include "dri2.h"
|
||||
+#include "util/os_file.h"
|
||||
|
||||
static struct dri3_drawable *
|
||||
loader_drawable_to_dri3_drawable(struct loader_dri3_drawable *draw) {
|
||||
@@ -529,6 +530,14 @@ dri3_flush_swap_buffers(__DRIdrawable *driDrawable, void *loaderPrivate)
|
||||
loader_dri3_swapbuffer_barrier(draw);
|
||||
}
|
||||
|
||||
+static int
|
||||
+dri3_get_display_fd(void *loaderPrivate)
|
||||
+{
|
||||
+ struct dri3_screen *psc = (struct dri3_screen *)loaderPrivate;
|
||||
+
|
||||
+ return psc->fd_dpy;
|
||||
+}
|
||||
+
|
||||
static void
|
||||
dri_set_background_context(void *loaderPrivate)
|
||||
{
|
||||
@@ -548,11 +557,12 @@ dri_is_thread_safe(void *loaderPrivate)
|
||||
/* The image loader extension record for DRI3
|
||||
*/
|
||||
static const __DRIimageLoaderExtension imageLoaderExtension = {
|
||||
- .base = { __DRI_IMAGE_LOADER, 3 },
|
||||
+ .base = { __DRI_IMAGE_LOADER, 5 },
|
||||
|
||||
.getBuffers = loader_dri3_get_buffers,
|
||||
.flushFrontBuffer = dri3_flush_front_buffer,
|
||||
.flushSwapBuffers = dri3_flush_swap_buffers,
|
||||
+ .getDisplayFD = dri3_get_display_fd,
|
||||
};
|
||||
|
||||
const __DRIuseInvalidateExtension dri3UseInvalidate = {
|
||||
@@ -618,6 +628,10 @@ dri3_destroy_screen(struct glx_screen *base)
|
||||
loader_dri3_close_screen(psc->driScreen);
|
||||
(*psc->core->destroyScreen) (psc->driScreen);
|
||||
driDestroyConfigs(psc->driver_configs);
|
||||
+
|
||||
+ if (psc->fd_dpy != psc->fd)
|
||||
+ close(psc->fd_dpy);
|
||||
+
|
||||
close(psc->fd);
|
||||
free(psc);
|
||||
}
|
||||
@@ -842,8 +856,9 @@ dri3_create_screen(int screen, struct glx_display * priv)
|
||||
struct dri3_screen *psc;
|
||||
__GLXDRIscreen *psp;
|
||||
struct glx_config *configs = NULL, *visuals = NULL;
|
||||
- char *driverName, *driverNameDisplayGPU, *tmp;
|
||||
+ char *driverName = NULL, *driverNameDisplayGPU, *tmp;
|
||||
int i;
|
||||
+ int fd_old;
|
||||
|
||||
psc = calloc(1, sizeof *psc);
|
||||
if (psc == NULL)
|
||||
@@ -851,6 +866,7 @@ dri3_create_screen(int screen, struct glx_display * priv)
|
||||
|
||||
psc->fd = -1;
|
||||
psc->fd_display_gpu = -1;
|
||||
+ psc->fd_dpy = -1;
|
||||
|
||||
if (!glx_screen_init(&psc->base, screen, priv)) {
|
||||
free(psc);
|
||||
@@ -871,12 +887,23 @@ dri3_create_screen(int screen, struct glx_display * priv)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+ fd_old = psc->fd;
|
||||
+ psc->fd_dpy = os_dupfd_cloexec(psc->fd);
|
||||
psc->fd_display_gpu = fcntl(psc->fd, F_DUPFD_CLOEXEC, 3);
|
||||
psc->fd = loader_get_user_preferred_fd(psc->fd, &psc->is_different_gpu);
|
||||
if (!psc->is_different_gpu) {
|
||||
close(psc->fd_display_gpu);
|
||||
psc->fd_display_gpu = -1;
|
||||
}
|
||||
+ if (psc->fd == fd_old) {
|
||||
+ if (psc->fd_dpy != -1)
|
||||
+ close(psc->fd_dpy);
|
||||
+
|
||||
+ psc->fd_dpy = psc->fd;
|
||||
+ } else if (psc->fd_dpy == -1) {
|
||||
+ ErrorMessageF("Unable to dup the display FD");
|
||||
+ goto handle_error;
|
||||
+ }
|
||||
|
||||
driverName = loader_get_driver_for_fd(psc->fd);
|
||||
if (!driverName) {
|
||||
@@ -1049,6 +1076,8 @@ handle_error:
|
||||
if (psc->driScreenDisplayGPU)
|
||||
psc->core->destroyScreen(psc->driScreenDisplayGPU);
|
||||
psc->driScreenDisplayGPU = NULL;
|
||||
+ if (psc->fd_dpy >= 0 && psc->fd_dpy != psc->fd)
|
||||
+ close(psc->fd_dpy);
|
||||
if (psc->fd >= 0)
|
||||
close(psc->fd);
|
||||
if (psc->fd_display_gpu >= 0)
|
||||
diff --git a/src/glx/dri3_priv.h b/src/glx/dri3_priv.h
|
||||
index c0e833c16ef..b3dccf28c06 100644
|
||||
--- a/src/glx/dri3_priv.h
|
||||
+++ b/src/glx/dri3_priv.h
|
||||
@@ -107,6 +107,7 @@ struct dri3_screen {
|
||||
|
||||
void *driver;
|
||||
int fd;
|
||||
+ int fd_dpy;
|
||||
bool is_different_gpu;
|
||||
|
||||
/* fd for display GPU in case of prime */
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
From 627ec429d684c57bdee45a21354009810fc03186 Mon Sep 17 00:00:00 2001
|
||||
From: Brendan King <Brendan.King@imgtec.com>
|
||||
Date: Wed, 28 Apr 2021 10:57:15 +0100
|
||||
Subject: [PATCH 51/67] egl/wayland: a linear buffer is not needed with DRM
|
||||
format modifiers
|
||||
|
||||
If the compositor supports DRM format modifiers, there is no
|
||||
need for an additional linear buffer, as the client can allocate
|
||||
buffers with attributes known to the compositor.
|
||||
---
|
||||
src/egl/drivers/dri2/platform_wayland.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/src/egl/drivers/dri2/platform_wayland.c b/src/egl/drivers/dri2/platform_wayland.c
|
||||
index b393e058770..60683fa6c1a 100644
|
||||
--- a/src/egl/drivers/dri2/platform_wayland.c
|
||||
+++ b/src/egl/drivers/dri2/platform_wayland.c
|
||||
@@ -695,7 +695,7 @@ get_back_bo(struct dri2_egl_surface *dri2_surf)
|
||||
use_flags |= __DRI_IMAGE_USE_PROTECTED;
|
||||
}
|
||||
|
||||
- if (dri2_dpy->is_different_gpu &&
|
||||
+ if (dri2_dpy->is_different_gpu && !num_modifiers &&
|
||||
dri2_surf->back->linear_copy == NULL) {
|
||||
/* The LINEAR modifier should be a perfect alias of the LINEAR use
|
||||
* flag; try the new interface first before the old, then fall back. */
|
||||
@@ -811,7 +811,7 @@ update_buffers(struct dri2_egl_display *dri2_dpy,
|
||||
dri2_surf->color_buffers[i].wl_buffer) {
|
||||
wl_buffer_destroy(dri2_surf->color_buffers[i].wl_buffer);
|
||||
dri2_dpy->image->destroyImage(dri2_surf->color_buffers[i].dri_image);
|
||||
- if (dri2_dpy->is_different_gpu)
|
||||
+ if (dri2_surf->color_buffers[i].linear_copy)
|
||||
dri2_dpy->image->destroyImage(dri2_surf->color_buffers[i].linear_copy);
|
||||
dri2_surf->color_buffers[i].wl_buffer = NULL;
|
||||
dri2_surf->color_buffers[i].dri_image = NULL;
|
||||
@@ -1247,7 +1247,7 @@ dri2_wl_swap_buffers_with_damage(_EGLDisplay *disp,
|
||||
if (!dri2_surf->current->wl_buffer) {
|
||||
__DRIimage *image;
|
||||
|
||||
- if (dri2_dpy->is_different_gpu)
|
||||
+ if (dri2_surf->current->linear_copy)
|
||||
image = dri2_surf->current->linear_copy;
|
||||
else
|
||||
image = dri2_surf->current->dri_image;
|
||||
@@ -1281,7 +1281,7 @@ dri2_wl_swap_buffers_with_damage(_EGLDisplay *disp,
|
||||
|
||||
dri2_flush_drawable_for_swapbuffers(disp, draw);
|
||||
|
||||
- if (dri2_dpy->is_different_gpu) {
|
||||
+ if (dri2_surf->current->linear_copy) {
|
||||
_EGLContext *ctx = _eglGetCurrentContext();
|
||||
struct dri2_egl_context *dri2_ctx = dri2_egl_context(ctx);
|
||||
dri2_dpy->image->blitImage(dri2_ctx->dri_context,
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,303 @@
|
||||
From e57b9a1b34a733f88af51b1395eebe647006939d Mon Sep 17 00:00:00 2001
|
||||
From: Brendan King <Brendan.King@imgtec.com>
|
||||
Date: Wed, 28 Apr 2021 16:33:42 +0100
|
||||
Subject: [PATCH 52/67] dri3: a linear buffer is not needed with DRM format
|
||||
modifiers
|
||||
|
||||
If the X Server supports DRM format modifiers, there is no need
|
||||
for an additional linear buffer, as the client can allocate buffers
|
||||
with attributes known to the Server.
|
||||
---
|
||||
src/egl/drivers/dri2/platform_x11_dri3.c | 7 +-
|
||||
src/glx/dri3_glx.c | 137 +++++++++++++++--------
|
||||
src/loader/loader_dri3_helper.c | 15 +++
|
||||
src/loader/loader_dri3_helper.h | 4 +
|
||||
4 files changed, 113 insertions(+), 50 deletions(-)
|
||||
|
||||
diff --git a/src/egl/drivers/dri2/platform_x11_dri3.c b/src/egl/drivers/dri2/platform_x11_dri3.c
|
||||
index 0babf9f867e..94205a495a6 100644
|
||||
--- a/src/egl/drivers/dri2/platform_x11_dri3.c
|
||||
+++ b/src/egl/drivers/dri2/platform_x11_dri3.c
|
||||
@@ -143,6 +143,7 @@ dri3_create_surface(_EGLDisplay *disp, EGLint type, _EGLConfig *conf,
|
||||
struct dri3_egl_surface *dri3_surf;
|
||||
const __DRIconfig *dri_config;
|
||||
xcb_drawable_t drawable;
|
||||
+ bool is_incompat_gpu;
|
||||
|
||||
dri3_surf = calloc(1, sizeof *dri3_surf);
|
||||
if (!dri3_surf) {
|
||||
@@ -150,6 +151,10 @@ dri3_create_surface(_EGLDisplay *disp, EGLint type, _EGLConfig *conf,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+ is_incompat_gpu = dri2_dpy->is_different_gpu &&
|
||||
+ !loader_dri3_has_modifiers(dri2_dpy->multibuffers_available,
|
||||
+ dri2_dpy->image);
|
||||
+
|
||||
if (!dri2_init_surface(&dri3_surf->surf.base, disp, type, conf,
|
||||
attrib_list, false, native_surface))
|
||||
goto cleanup_surf;
|
||||
@@ -174,7 +179,7 @@ dri3_create_surface(_EGLDisplay *disp, EGLint type, _EGLConfig *conf,
|
||||
|
||||
if (loader_dri3_drawable_init(dri2_dpy->conn, drawable,
|
||||
dri2_dpy->dri_screen,
|
||||
- dri2_dpy->is_different_gpu,
|
||||
+ is_incompat_gpu,
|
||||
dri2_dpy->multibuffers_available,
|
||||
dri_config,
|
||||
&dri2_dpy->loader_dri3_ext,
|
||||
diff --git a/src/glx/dri3_glx.c b/src/glx/dri3_glx.c
|
||||
index 1ed6b60ffe8..025ad0128ec 100644
|
||||
--- a/src/glx/dri3_glx.c
|
||||
+++ b/src/glx/dri3_glx.c
|
||||
@@ -354,6 +354,21 @@ dri3_destroy_drawable(__GLXDRIdrawable *base)
|
||||
free(pdraw);
|
||||
}
|
||||
|
||||
+static bool
|
||||
+dri3_has_multibuffer(const __DRIimageExtension *image,
|
||||
+ const struct dri3_display *pdp)
|
||||
+{
|
||||
+#ifdef HAVE_DRI3_MODIFIERS
|
||||
+ return (image && image->base.version >= 15) &&
|
||||
+ (pdp->dri3Major > 1 ||
|
||||
+ (pdp->dri3Major == 1 && pdp->dri3Minor >= 2)) &&
|
||||
+ (pdp->presentMajor > 1 ||
|
||||
+ (pdp->presentMajor == 1 && pdp->presentMinor >= 2));
|
||||
+#else
|
||||
+ return false;
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
static __GLXDRIdrawable *
|
||||
dri3_create_drawable(struct glx_screen *base, XID xDrawable,
|
||||
GLXDrawable drawable, struct glx_config *config_base)
|
||||
@@ -361,11 +376,9 @@ dri3_create_drawable(struct glx_screen *base, XID xDrawable,
|
||||
struct dri3_drawable *pdraw;
|
||||
struct dri3_screen *psc = (struct dri3_screen *) base;
|
||||
__GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) config_base;
|
||||
- bool has_multibuffer = false;
|
||||
-#ifdef HAVE_DRI3_MODIFIERS
|
||||
const struct dri3_display *const pdp = (struct dri3_display *)
|
||||
base->display->dri3Display;
|
||||
-#endif
|
||||
+ bool has_multibuffer = dri3_has_multibuffer(psc->image, pdp);
|
||||
|
||||
pdraw = calloc(1, sizeof(*pdraw));
|
||||
if (!pdraw)
|
||||
@@ -376,14 +389,6 @@ dri3_create_drawable(struct glx_screen *base, XID xDrawable,
|
||||
pdraw->base.drawable = drawable;
|
||||
pdraw->base.psc = &psc->base;
|
||||
|
||||
-#ifdef HAVE_DRI3_MODIFIERS
|
||||
- if ((psc->image && psc->image->base.version >= 15) &&
|
||||
- (pdp->dri3Major > 1 || (pdp->dri3Major == 1 && pdp->dri3Minor >= 2)) &&
|
||||
- (pdp->presentMajor > 1 ||
|
||||
- (pdp->presentMajor == 1 && pdp->presentMinor >= 2)))
|
||||
- has_multibuffer = true;
|
||||
-#endif
|
||||
-
|
||||
(void) __glXInitialize(psc->base.dpy);
|
||||
|
||||
if (loader_dri3_drawable_init(XGetXCBConnection(base->dpy),
|
||||
@@ -737,13 +742,14 @@ static const struct glx_context_vtable dri3_context_vtable = {
|
||||
.interop_export_object = dri3_interop_export_object
|
||||
};
|
||||
|
||||
-/** dri3_bind_extensions
|
||||
+/** dri3_bind_extensions_part1
|
||||
*
|
||||
- * Enable all of the extensions supported on DRI3
|
||||
+ * Enable the extensions supported on DRI3 that don't depend on
|
||||
+ * whether we are using a different GPU.
|
||||
*/
|
||||
static void
|
||||
-dri3_bind_extensions(struct dri3_screen *psc, struct glx_display * priv,
|
||||
- const char *driverName)
|
||||
+dri3_bind_extensions_part1(struct dri3_screen *psc, struct glx_display * priv,
|
||||
+ const char *driverName)
|
||||
{
|
||||
const __DRIextension **extensions;
|
||||
unsigned mask;
|
||||
@@ -774,16 +780,6 @@ dri3_bind_extensions(struct dri3_screen *psc, struct glx_display * priv,
|
||||
}
|
||||
|
||||
for (i = 0; extensions[i]; i++) {
|
||||
- /* when on a different gpu than the server, the server pixmaps
|
||||
- * can have a tiling mode we can't read. Thus we can't create
|
||||
- * a texture from them.
|
||||
- */
|
||||
- if (!psc->is_different_gpu &&
|
||||
- (strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0)) {
|
||||
- psc->texBuffer = (__DRItexBufferExtension *) extensions[i];
|
||||
- __glXEnableDirectExtension(&psc->base, "GLX_EXT_texture_from_pixmap");
|
||||
- }
|
||||
-
|
||||
if ((strcmp(extensions[i]->name, __DRI2_FLUSH) == 0)) {
|
||||
psc->f = (__DRI2flushExtension *) extensions[i];
|
||||
/* internal driver extension, no GL extension exposed */
|
||||
@@ -817,6 +813,33 @@ dri3_bind_extensions(struct dri3_screen *psc, struct glx_display * priv,
|
||||
}
|
||||
}
|
||||
|
||||
+/** dri3_bind_extensions_part2
|
||||
+ *
|
||||
+ * Enable the extensions supported on DRI3 that depend on whether we
|
||||
+ * are using a different GPU.
|
||||
+ */
|
||||
+static void
|
||||
+dri3_bind_extensions_part2(struct dri3_screen *psc, struct glx_display * priv,
|
||||
+ const char *driverName)
|
||||
+{
|
||||
+ const __DRIextension **extensions;
|
||||
+ int i;
|
||||
+
|
||||
+ extensions = psc->core->getExtensions(psc->driScreen);
|
||||
+
|
||||
+ for (i = 0; extensions[i]; i++) {
|
||||
+ /* when on a different gpu than the server, the server pixmaps
|
||||
+ * can have a tiling mode we can't read. Thus we can't create
|
||||
+ * a texture from them.
|
||||
+ */
|
||||
+ if (!psc->is_different_gpu &&
|
||||
+ (strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0)) {
|
||||
+ psc->texBuffer = (__DRItexBufferExtension *) extensions[i];
|
||||
+ __glXEnableDirectExtension(&psc->base, "GLX_EXT_texture_from_pixmap");
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static char *
|
||||
dri3_get_driver_name(struct glx_screen *glx_screen)
|
||||
{
|
||||
@@ -859,6 +882,8 @@ dri3_create_screen(int screen, struct glx_display * priv)
|
||||
char *driverName = NULL, *driverNameDisplayGPU, *tmp;
|
||||
int i;
|
||||
int fd_old;
|
||||
+ bool is_different_gpu;
|
||||
+ bool have_modifiers;
|
||||
|
||||
psc = calloc(1, sizeof *psc);
|
||||
if (psc == NULL)
|
||||
@@ -890,8 +915,8 @@ dri3_create_screen(int screen, struct glx_display * priv)
|
||||
fd_old = psc->fd;
|
||||
psc->fd_dpy = os_dupfd_cloexec(psc->fd);
|
||||
psc->fd_display_gpu = fcntl(psc->fd, F_DUPFD_CLOEXEC, 3);
|
||||
- psc->fd = loader_get_user_preferred_fd(psc->fd, &psc->is_different_gpu);
|
||||
- if (!psc->is_different_gpu) {
|
||||
+ psc->fd = loader_get_user_preferred_fd(psc->fd, &is_different_gpu);
|
||||
+ if (!is_different_gpu) {
|
||||
close(psc->fd_display_gpu);
|
||||
psc->fd_display_gpu = -1;
|
||||
}
|
||||
@@ -933,27 +958,6 @@ dri3_create_screen(int screen, struct glx_display * priv)
|
||||
goto handle_error;
|
||||
}
|
||||
|
||||
- if (psc->is_different_gpu) {
|
||||
- driverNameDisplayGPU = loader_get_driver_for_fd(psc->fd_display_gpu);
|
||||
- if (driverNameDisplayGPU) {
|
||||
-
|
||||
- /* check if driver name is matching so that non mesa drivers
|
||||
- * will not crash. Also need this check since image extension
|
||||
- * pointer from render gpu is shared with display gpu. Image
|
||||
- * extension pointer is shared because it keeps things simple.
|
||||
- */
|
||||
- if (strcmp(driverName, driverNameDisplayGPU) == 0) {
|
||||
- psc->driScreenDisplayGPU =
|
||||
- psc->image_driver->createNewScreen2(screen, psc->fd_display_gpu,
|
||||
- pdp->loader_extensions,
|
||||
- extensions,
|
||||
- &driver_configs, psc);
|
||||
- }
|
||||
-
|
||||
- free(driverNameDisplayGPU);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
psc->driScreen =
|
||||
psc->image_driver->createNewScreen2(screen, psc->fd,
|
||||
pdp->loader_extensions,
|
||||
@@ -965,7 +969,42 @@ dri3_create_screen(int screen, struct glx_display * priv)
|
||||
goto handle_error;
|
||||
}
|
||||
|
||||
- dri3_bind_extensions(psc, priv, driverName);
|
||||
+ dri3_bind_extensions_part1(psc, priv, driverName);
|
||||
+
|
||||
+ have_modifiers = loader_dri3_has_modifiers(dri3_has_multibuffer(psc->image,
|
||||
+ pdp),
|
||||
+ psc->image);
|
||||
+
|
||||
+ if (is_different_gpu) {
|
||||
+ if (have_modifiers) {
|
||||
+ close(psc->fd_display_gpu);
|
||||
+ psc->fd_display_gpu = -1;
|
||||
+ } else {
|
||||
+ driverNameDisplayGPU = loader_get_driver_for_fd(psc->fd_display_gpu);
|
||||
+ if (driverNameDisplayGPU) {
|
||||
+
|
||||
+ /* check if driver name is matching so that non mesa drivers
|
||||
+ * will not crash. Also need this check since image extension
|
||||
+ * pointer from render gpu is shared with display gpu. Image
|
||||
+ * extension pointer is shared because it keeps things simple.
|
||||
+ */
|
||||
+ if (strcmp(driverName, driverNameDisplayGPU) == 0) {
|
||||
+ psc->driScreenDisplayGPU =
|
||||
+ psc->image_driver->createNewScreen2(screen,
|
||||
+ psc->fd_display_gpu,
|
||||
+ pdp->loader_extensions,
|
||||
+ extensions,
|
||||
+ &driver_configs, psc);
|
||||
+ }
|
||||
+
|
||||
+ free(driverNameDisplayGPU);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ psc->is_different_gpu = is_different_gpu && !have_modifiers;
|
||||
+
|
||||
+ dri3_bind_extensions_part2(psc, priv, driverName);
|
||||
|
||||
if (!psc->image || psc->image->base.version < 7 || !psc->image->createImageFromFds) {
|
||||
ErrorMessageF("Version 7 or imageFromFds image extension not found\n");
|
||||
diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c
|
||||
index ff6d1ffc660..5c0379ab5de 100644
|
||||
--- a/src/loader/loader_dri3_helper.c
|
||||
+++ b/src/loader/loader_dri3_helper.c
|
||||
@@ -2288,3 +2288,18 @@ dri3_find_back_alloc(struct loader_dri3_drawable *draw)
|
||||
|
||||
return back;
|
||||
}
|
||||
+
|
||||
+bool
|
||||
+loader_dri3_has_modifiers(bool multiplanes_available,
|
||||
+ const __DRIimageExtension *image)
|
||||
+{
|
||||
+#ifdef HAVE_DRI3_MODIFIERS
|
||||
+ return multiplanes_available && image &&
|
||||
+ image->base.version >= 15 &&
|
||||
+ image->queryDmaBufModifiers &&
|
||||
+ image->createImageWithModifiers &&
|
||||
+ image->createImageFromDmaBufs2;
|
||||
+#else
|
||||
+ return false;
|
||||
+#endif
|
||||
+}
|
||||
diff --git a/src/loader/loader_dri3_helper.h b/src/loader/loader_dri3_helper.h
|
||||
index 028e25dc070..5790f5444f5 100644
|
||||
--- a/src/loader/loader_dri3_helper.h
|
||||
+++ b/src/loader/loader_dri3_helper.h
|
||||
@@ -287,4 +287,8 @@ loader_dri3_swapbuffer_barrier(struct loader_dri3_drawable *draw);
|
||||
|
||||
void
|
||||
loader_dri3_close_screen(__DRIscreen *dri_screen);
|
||||
+
|
||||
+bool
|
||||
+loader_dri3_has_modifiers(bool multiplanes_available,
|
||||
+ const __DRIimageExtension *image);
|
||||
#endif
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,267 @@
|
||||
From 8de0535741ce8d126da4d9b0b0eb8c46dd4810b5 Mon Sep 17 00:00:00 2001
|
||||
From: Brendan King <Brendan.King@imgtec.com>
|
||||
Date: Thu, 20 May 2021 14:43:29 +0100
|
||||
Subject: [PATCH 53/67] egl/drm: add support for DRI_PRIME GPU selection
|
||||
|
||||
Add support for selecting the GPU to be used for rendering using
|
||||
the DRI_PRIME environment variable. If a different GPU is selected,
|
||||
a duplicate of the file descriptor for the original GPU/display is
|
||||
preserved, which can be obtained by calling the getDisplayFD
|
||||
function in the image loader extension.
|
||||
|
||||
For server side Wayland, the ability to support PRIME is
|
||||
determined by checking for the PRIME import and export
|
||||
capabilities on the driver file descriptor, which may no
|
||||
longer support them if a different GPU from the default has
|
||||
been selected. It may be that the driver can still support
|
||||
PRIME; for example, by making use of the original (default)
|
||||
file descriptor. The driver can indicate it supports PRIME
|
||||
via the getCapabilities function in the DRI Image extension.
|
||||
---
|
||||
include/GL/internal/dri_interface.h | 2 ++
|
||||
src/egl/drivers/dri2/egl_dri2.c | 10 ++++++++
|
||||
src/egl/drivers/dri2/platform_drm.c | 19 ++++++++++-----
|
||||
src/gbm/backends/dri/gbm_dri.c | 38 +++++++++++++++++++++++++----
|
||||
src/gbm/backends/dri/gbm_driint.h | 8 ++++++
|
||||
5 files changed, 66 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
|
||||
index 2fb440feb50..080d191b0a3 100644
|
||||
--- a/include/GL/internal/dri_interface.h
|
||||
+++ b/include/GL/internal/dri_interface.h
|
||||
@@ -1548,6 +1548,8 @@ enum __DRIChromaSiting {
|
||||
*/
|
||||
/*@{*/
|
||||
#define __DRI_IMAGE_CAP_GLOBAL_NAMES 1
|
||||
+#define __DRI_IMAGE_CAP_PRIME_IMPORT 0x2000
|
||||
+#define __DRI_IMAGE_CAP_PRIME_EXPORT 0x4000
|
||||
/*@}*/
|
||||
|
||||
/**
|
||||
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
|
||||
index 1df53ef011c..ec4ac602a84 100644
|
||||
--- a/src/egl/drivers/dri2/egl_dri2.c
|
||||
+++ b/src/egl/drivers/dri2/egl_dri2.c
|
||||
@@ -1368,6 +1368,7 @@ dri2_display_destroy(_EGLDisplay *disp)
|
||||
}
|
||||
|
||||
switch (disp->Platform) {
|
||||
+ case _EGL_PLATFORM_DRM:
|
||||
case _EGL_PLATFORM_WAYLAND:
|
||||
case _EGL_PLATFORM_X11:
|
||||
if (dri2_dpy->fd_dpy >= 0 && dri2_dpy->fd_dpy != dri2_dpy->fd)
|
||||
@@ -3943,6 +3944,15 @@ dri2_bind_wayland_display_wl(_EGLDisplay *disp, struct wl_display *wl_dpy)
|
||||
dri2_dpy->image->base.version >= 7 &&
|
||||
dri2_dpy->image->createImageFromFds != NULL)
|
||||
flags |= WAYLAND_DRM_PRIME;
|
||||
+ else if (dri2_dpy->image->base.version >= 10 &&
|
||||
+ dri2_dpy->image->getCapabilities != NULL) {
|
||||
+ int capabilities;
|
||||
+
|
||||
+ capabilities = dri2_dpy->image->getCapabilities(dri2_dpy->dri_screen);
|
||||
+ if ((capabilities & __DRI_IMAGE_CAP_PRIME_IMPORT) != 0 &&
|
||||
+ (capabilities & __DRI_IMAGE_CAP_PRIME_EXPORT) != 0)
|
||||
+ flags |= WAYLAND_DRM_PRIME;
|
||||
+ }
|
||||
|
||||
dri2_dpy->wl_server_drm =
|
||||
wayland_drm_init(wl_dpy, device_name,
|
||||
diff --git a/src/egl/drivers/dri2/platform_drm.c b/src/egl/drivers/dri2/platform_drm.c
|
||||
index 258e8b6593e..f160ad1175e 100644
|
||||
--- a/src/egl/drivers/dri2/platform_drm.c
|
||||
+++ b/src/egl/drivers/dri2/platform_drm.c
|
||||
@@ -595,7 +595,7 @@ dri2_drm_authenticate(_EGLDisplay *disp, uint32_t id)
|
||||
{
|
||||
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
|
||||
|
||||
- return drmAuthMagic(dri2_dpy->fd, id);
|
||||
+ return drmAuthMagic(dri2_dpy->fd_dpy, id);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -782,6 +782,7 @@ dri2_initialize_drm(_EGLDisplay *disp)
|
||||
return _eglError(EGL_BAD_ALLOC, "eglInitialize");
|
||||
|
||||
dri2_dpy->fd = -1;
|
||||
+ dri2_dpy->fd_dpy = -1;
|
||||
disp->DriverData = (void *) dri2_dpy;
|
||||
|
||||
gbm = disp->PlatformDisplay;
|
||||
@@ -789,16 +790,16 @@ dri2_initialize_drm(_EGLDisplay *disp)
|
||||
char buf[64];
|
||||
int n = snprintf(buf, sizeof(buf), DRM_DEV_NAME, DRM_DIR_NAME, 0);
|
||||
if (n != -1 && n < sizeof(buf))
|
||||
- dri2_dpy->fd = loader_open_device(buf);
|
||||
- gbm = gbm_create_device(dri2_dpy->fd);
|
||||
+ dri2_dpy->fd_dpy = loader_open_device(buf);
|
||||
+ gbm = gbm_create_device(dri2_dpy->fd_dpy);
|
||||
if (gbm == NULL) {
|
||||
err = "DRI2: failed to create gbm device";
|
||||
goto cleanup;
|
||||
}
|
||||
dri2_dpy->own_device = true;
|
||||
} else {
|
||||
- dri2_dpy->fd = os_dupfd_cloexec(gbm_device_get_fd(gbm));
|
||||
- if (dri2_dpy->fd < 0) {
|
||||
+ dri2_dpy->fd_dpy = os_dupfd_cloexec(gbm_device_get_fd(gbm));
|
||||
+ if (dri2_dpy->fd_dpy < 0) {
|
||||
err = "DRI2: failed to fcntl() existing gbm device";
|
||||
goto cleanup;
|
||||
}
|
||||
@@ -810,6 +811,12 @@ dri2_initialize_drm(_EGLDisplay *disp)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
+ if (gbm_dri_device_get_fd(dri2_dpy->gbm_dri) ==
|
||||
+ gbm_device_get_fd(gbm))
|
||||
+ dri2_dpy->fd = dri2_dpy->fd_dpy;
|
||||
+ else
|
||||
+ dri2_dpy->fd = os_dupfd_cloexec(gbm_dri_device_get_fd(dri2_dpy->gbm_dri));
|
||||
+
|
||||
dev = _eglAddDevice(dri2_dpy->fd, dri2_dpy->gbm_dri->software);
|
||||
if (!dev) {
|
||||
err = "DRI2: failed to find EGLDevice";
|
||||
@@ -872,7 +879,7 @@ dri2_initialize_drm(_EGLDisplay *disp)
|
||||
disp->Extensions.EXT_buffer_age = EGL_TRUE;
|
||||
|
||||
#ifdef HAVE_WAYLAND_PLATFORM
|
||||
- dri2_dpy->device_name = loader_get_device_name_for_fd(dri2_dpy->fd);
|
||||
+ dri2_dpy->device_name = loader_get_device_name_for_fd(dri2_dpy->fd_dpy);
|
||||
#endif
|
||||
dri2_set_WL_bind_wayland_display(disp);
|
||||
|
||||
diff --git a/src/gbm/backends/dri/gbm_dri.c b/src/gbm/backends/dri/gbm_dri.c
|
||||
index 5acb15b516f..c1586f42e46 100644
|
||||
--- a/src/gbm/backends/dri/gbm_dri.c
|
||||
+++ b/src/gbm/backends/dri/gbm_dri.c
|
||||
@@ -51,6 +51,7 @@
|
||||
#include "loader.h"
|
||||
#include "util/debug.h"
|
||||
#include "util/macros.h"
|
||||
+#include "util/os_file.h"
|
||||
|
||||
/* For importing wl_buffer */
|
||||
#if HAVE_WAYLAND_PLATFORM
|
||||
@@ -141,6 +142,14 @@ image_get_buffers(__DRIdrawable *driDrawable,
|
||||
surf->dri_private, buffer_mask, buffers);
|
||||
}
|
||||
|
||||
+static int
|
||||
+dri_get_display_fd(void *loaderPrivate)
|
||||
+{
|
||||
+ struct gbm_dri_device *dri = loaderPrivate;
|
||||
+
|
||||
+ return dri->base.v0.fd;
|
||||
+}
|
||||
+
|
||||
static void
|
||||
swrast_get_drawable_info(__DRIdrawable *driDrawable,
|
||||
int *x,
|
||||
@@ -220,20 +229,22 @@ static const __DRIimageLookupExtension image_lookup_extension = {
|
||||
};
|
||||
|
||||
static const __DRIdri2LoaderExtension dri2_loader_extension = {
|
||||
- .base = { __DRI_DRI2_LOADER, 4 },
|
||||
+ .base = { __DRI_DRI2_LOADER, 6 },
|
||||
|
||||
.getBuffers = dri_get_buffers,
|
||||
.flushFrontBuffer = dri_flush_front_buffer,
|
||||
.getBuffersWithFormat = dri_get_buffers_with_format,
|
||||
.getCapability = dri_get_capability,
|
||||
+ .getDisplayFD = dri_get_display_fd,
|
||||
};
|
||||
|
||||
static const __DRIimageLoaderExtension image_loader_extension = {
|
||||
- .base = { __DRI_IMAGE_LOADER, 2 },
|
||||
+ .base = { __DRI_IMAGE_LOADER, 5 },
|
||||
|
||||
.getBuffers = image_get_buffers,
|
||||
.flushFrontBuffer = dri_flush_front_buffer,
|
||||
.getCapability = dri_get_capability,
|
||||
+ .getDisplayFD = dri_get_display_fd,
|
||||
};
|
||||
|
||||
static const __DRIswrastLoaderExtension swrast_loader_extension = {
|
||||
@@ -398,12 +409,12 @@ dri_screen_create_dri2(struct gbm_dri_device *dri, char *driver_name)
|
||||
return -1;
|
||||
|
||||
if (dri->dri2->base.version >= 4) {
|
||||
- dri->screen = dri->dri2->createNewScreen2(0, dri->base.v0.fd,
|
||||
+ dri->screen = dri->dri2->createNewScreen2(0, dri->fd,
|
||||
dri->loader_extensions,
|
||||
dri->driver_extensions,
|
||||
&dri->driver_configs, dri);
|
||||
} else {
|
||||
- dri->screen = dri->dri2->createNewScreen(0, dri->base.v0.fd,
|
||||
+ dri->screen = dri->dri2->createNewScreen(0, dri->fd,
|
||||
dri->loader_extensions,
|
||||
&dri->driver_configs, dri);
|
||||
}
|
||||
@@ -470,8 +481,20 @@ static int
|
||||
dri_screen_create(struct gbm_dri_device *dri)
|
||||
{
|
||||
char *driver_name;
|
||||
+ int dup_fd, new_fd;
|
||||
+ bool is_different_gpu;
|
||||
|
||||
- driver_name = loader_get_driver_for_fd(dri->base.v0.fd);
|
||||
+ dup_fd = os_dupfd_cloexec(dri->fd);
|
||||
+ if (dup_fd < 0)
|
||||
+ return -1;
|
||||
+
|
||||
+ new_fd = loader_get_user_preferred_fd(dup_fd, &is_different_gpu);
|
||||
+ if (new_fd == dup_fd)
|
||||
+ close(new_fd);
|
||||
+ else
|
||||
+ dri->fd = new_fd;
|
||||
+
|
||||
+ driver_name = loader_get_driver_for_fd(dri->fd);
|
||||
if (!driver_name)
|
||||
return -1;
|
||||
|
||||
@@ -1424,6 +1447,9 @@ dri_destroy(struct gbm_device *gbm)
|
||||
dlclose(dri->driver);
|
||||
free(dri->driver_name);
|
||||
|
||||
+ if (dri->fd >= 0 && dri->fd != dri->base.v0.fd)
|
||||
+ close (dri->fd);
|
||||
+
|
||||
free(dri);
|
||||
}
|
||||
|
||||
@@ -1445,6 +1471,8 @@ dri_device_create(int fd, uint32_t gbm_backend_version)
|
||||
if (!dri)
|
||||
return NULL;
|
||||
|
||||
+ dri->fd = fd;
|
||||
+
|
||||
dri->base.v0.fd = fd;
|
||||
dri->base.v0.backend_version = gbm_backend_version;
|
||||
dri->base.v0.bo_create = gbm_dri_bo_create;
|
||||
diff --git a/src/gbm/backends/dri/gbm_driint.h b/src/gbm/backends/dri/gbm_driint.h
|
||||
index 9e77ba5887c..e33a96edb0b 100644
|
||||
--- a/src/gbm/backends/dri/gbm_driint.h
|
||||
+++ b/src/gbm/backends/dri/gbm_driint.h
|
||||
@@ -61,6 +61,8 @@ struct gbm_dri_visual {
|
||||
struct gbm_dri_device {
|
||||
struct gbm_device base;
|
||||
|
||||
+ int fd;
|
||||
+
|
||||
void *driver;
|
||||
char *driver_name; /* Name of the DRI module, without the _dri suffix */
|
||||
bool software; /* A software driver was loaded */
|
||||
@@ -191,4 +193,10 @@ gbm_dri_bo_unmap_dumb(struct gbm_dri_bo *bo)
|
||||
bo->map = NULL;
|
||||
}
|
||||
|
||||
+static inline int
|
||||
+gbm_dri_device_get_fd(struct gbm_dri_device *dri)
|
||||
+{
|
||||
+ return dri->fd;
|
||||
+}
|
||||
+
|
||||
#endif
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,304 @@
|
||||
From f1f625dbcb4e0cc062369729b1da3d7fc65969e8 Mon Sep 17 00:00:00 2001
|
||||
From: Brendan King <Brendan.King@imgtec.com>
|
||||
Date: Thu, 20 May 2021 20:16:18 +0100
|
||||
Subject: [PATCH 54/67] egl/null: add support for DRI_PRIME GPU selection
|
||||
|
||||
Add support for selecting the GPU to be used for rendering using
|
||||
the DRI_PRIME environment variable. If a different GPU is selected,
|
||||
a duplicate of the file descriptor for the original GPU/display is
|
||||
preserved, which can be obtained by calling the getDisplayFD
|
||||
function in the image loader extension.
|
||||
|
||||
This change includes code, in function dri2_null_try_device, to
|
||||
skip display devices that are not supported by the PVR driver.
|
||||
This is to prevent failure on PC based test systems, that often
|
||||
include display hardware that is incompatible with the driver.
|
||||
This code would not be needed for systems that don't use the PVR
|
||||
driver, or on production systems that use the PVR driver.
|
||||
---
|
||||
src/egl/drivers/dri2/egl_dri2.c | 1 +
|
||||
src/egl/drivers/dri2/platform_null.c | 133 +++++++++++++++++++--------
|
||||
2 files changed, 98 insertions(+), 36 deletions(-)
|
||||
|
||||
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
|
||||
index ec4ac602a84..56b5175db6e 100644
|
||||
--- a/src/egl/drivers/dri2/egl_dri2.c
|
||||
+++ b/src/egl/drivers/dri2/egl_dri2.c
|
||||
@@ -1369,6 +1369,7 @@ dri2_display_destroy(_EGLDisplay *disp)
|
||||
|
||||
switch (disp->Platform) {
|
||||
case _EGL_PLATFORM_DRM:
|
||||
+ case _EGL_PLATFORM_NULL:
|
||||
case _EGL_PLATFORM_WAYLAND:
|
||||
case _EGL_PLATFORM_X11:
|
||||
if (dri2_dpy->fd_dpy >= 0 && dri2_dpy->fd_dpy != dri2_dpy->fd)
|
||||
diff --git a/src/egl/drivers/dri2/platform_null.c b/src/egl/drivers/dri2/platform_null.c
|
||||
index db6f1147670..af77ea4dd89 100644
|
||||
--- a/src/egl/drivers/dri2/platform_null.c
|
||||
+++ b/src/egl/drivers/dri2/platform_null.c
|
||||
@@ -44,6 +44,7 @@
|
||||
|
||||
#include "egl_dri2.h"
|
||||
#include "loader.h"
|
||||
+#include "util/os_file.h"
|
||||
|
||||
#define NULL_CARD_MINOR_MAX 63U
|
||||
|
||||
@@ -953,7 +954,7 @@ swap_idle_get_target_frame(struct dri2_egl_surface *dri2_surf,
|
||||
* 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);
|
||||
+ err = display_get_vblank_sequence(dri2_dpy->fd_dpy, current_vblank_out);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -1003,7 +1004,7 @@ swap_vblank_state_transition(struct dri2_egl_surface *dri2_surf,
|
||||
uint32_t flags = DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT;
|
||||
int err;
|
||||
|
||||
- err = display_request_vblank(dri2_dpy->fd, target_frame,
|
||||
+ err = display_request_vblank(dri2_dpy->fd_dpy, target_frame,
|
||||
flags, dri2_surf);
|
||||
if (err) {
|
||||
dri2_surf->swap_state = SWAP_ERROR;
|
||||
@@ -1029,7 +1030,7 @@ swap_flip_state_transition(struct dri2_egl_surface *dri2_surf)
|
||||
flags |= DRM_MODE_PAGE_FLIP_ASYNC;
|
||||
}
|
||||
|
||||
- err = display_output_flip(dri2_dpy->fd, &dri2_dpy->output,
|
||||
+ err = display_output_flip(dri2_dpy->fd_dpy, &dri2_dpy->output,
|
||||
dri2_surf->swap_data->fb_id, flags, dri2_surf);
|
||||
if (err) {
|
||||
dri2_surf->swap_state = SWAP_ERROR;
|
||||
@@ -1049,7 +1050,7 @@ swap_poll_state_transition(struct dri2_egl_surface *dri2_surf)
|
||||
int err;
|
||||
|
||||
/* dri2_surf->swap_state is being set inside the handler */
|
||||
- err = drm_event_process(dri2_dpy->fd);
|
||||
+ err = drm_event_process(dri2_dpy->fd_dpy);
|
||||
if (err) {
|
||||
dri2_surf->swap_state = SWAP_ERROR;
|
||||
return err;
|
||||
@@ -1201,7 +1202,7 @@ add_fb_for_dri_image(struct dri2_egl_display *dri2_dpy, __DRIimage *image,
|
||||
handles[i] = (uint32_t) handle;
|
||||
}
|
||||
|
||||
- return !drmModeAddFB2WithModifiers(dri2_dpy->fd, width, height,
|
||||
+ return !drmModeAddFB2WithModifiers(dri2_dpy->fd_dpy, width, height,
|
||||
dri2_null_formats[format_idx].drm_format,
|
||||
handles, pitches, offsets, modifiers,
|
||||
fb_id_out, flags);
|
||||
@@ -1459,7 +1460,7 @@ dri2_null_create_window_surface(_EGLDisplay *disp, _EGLConfig *config,
|
||||
goto err_destroy_surface;
|
||||
}
|
||||
|
||||
- err = display_output_modeset(dri2_dpy->fd, &dri2_dpy->output,
|
||||
+ err = display_output_modeset(dri2_dpy->fd_dpy, &dri2_dpy->output,
|
||||
dri2_surf->front_buffer.fb_id);
|
||||
if (err) {
|
||||
_eglError(EGL_BAD_NATIVE_WINDOW, "window set mode");
|
||||
@@ -1573,11 +1574,11 @@ dri2_null_destroy_surface(_EGLDisplay *disp, _EGLSurface *surf)
|
||||
dri2_dpy->image->destroyImage(dri2_surf->front_buffer.dri_image);
|
||||
|
||||
if (dri2_surf->front_buffer.fb_id)
|
||||
- drmModeRmFB(dri2_dpy->fd, dri2_surf->front_buffer.fb_id);
|
||||
+ drmModeRmFB(dri2_dpy->fd_dpy, 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)
|
||||
- drmModeRmFB(dri2_dpy->fd, dri2_surf->color_buffers[i].fb_id);
|
||||
+ drmModeRmFB(dri2_dpy->fd_dpy, dri2_surf->color_buffers[i].fb_id);
|
||||
if (dri2_surf->color_buffers[i].dri_image)
|
||||
dri2_dpy->image->destroyImage(dri2_surf->color_buffers[i].dri_image);
|
||||
}
|
||||
@@ -1734,12 +1735,22 @@ dri2_null_flush_front_buffer(__DRIdrawable * driDrawable, void *loaderPrivate)
|
||||
(void) loaderPrivate;
|
||||
}
|
||||
|
||||
+static int
|
||||
+dri2_null_get_display_fd(void *loaderPrivate)
|
||||
+{
|
||||
+ _EGLDisplay *disp = loaderPrivate;
|
||||
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
|
||||
+
|
||||
+ return dri2_dpy->fd_dpy;
|
||||
+}
|
||||
+
|
||||
static const __DRIimageLoaderExtension image_loader_extension = {
|
||||
- .base = { __DRI_IMAGE_LOADER, 2 },
|
||||
+ .base = { __DRI_IMAGE_LOADER, 5 },
|
||||
|
||||
.getBuffers = dri2_null_image_get_buffers,
|
||||
.flushFrontBuffer = dri2_null_flush_front_buffer,
|
||||
.getCapability = dri2_null_get_capability,
|
||||
+ .getDisplayFD = dri2_null_get_display_fd,
|
||||
};
|
||||
|
||||
static const __DRIextension *image_loader_extensions[] = {
|
||||
@@ -1768,12 +1779,74 @@ dri2_null_device_is_kms(int fd)
|
||||
return is_kms;
|
||||
}
|
||||
|
||||
+static bool
|
||||
+dri2_null_try_device(_EGLDisplay *disp)
|
||||
+{
|
||||
+ struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
|
||||
+
|
||||
+ if (!dri2_null_device_is_kms(dri2_dpy->fd_dpy))
|
||||
+ return false;
|
||||
+
|
||||
+#if 1
|
||||
+ /* Skip devices not supported by the pvr driver */
|
||||
+ {
|
||||
+ char *driver_name = loader_get_driver_for_fd(dri2_dpy->fd_dpy);
|
||||
+ bool skip = !driver_name || !!strcmp(driver_name, "pvr");
|
||||
+
|
||||
+ free(driver_name);
|
||||
+
|
||||
+ if (skip)
|
||||
+ return false;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
+ dri2_dpy->fd = os_dupfd_cloexec(dri2_dpy->fd_dpy);
|
||||
+ if (dri2_dpy->fd < 0) {
|
||||
+ _eglLog(_EGL_WARNING, "DRI2: failed to dup display FD");
|
||||
+ dri2_dpy->fd = dri2_dpy->fd_dpy;
|
||||
+ } else {
|
||||
+ int fd_old;
|
||||
+ bool is_different_gpu;
|
||||
+
|
||||
+ fd_old = dri2_dpy->fd;
|
||||
+ dri2_dpy->fd = loader_get_user_preferred_fd(dri2_dpy->fd,
|
||||
+ &is_different_gpu);
|
||||
+ if (dri2_dpy->fd == fd_old) {
|
||||
+ close (dri2_dpy->fd);
|
||||
+ dri2_dpy->fd = dri2_dpy->fd_dpy;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ dri2_dpy->driver_name = loader_get_driver_for_fd(dri2_dpy->fd);
|
||||
+ if (!dri2_dpy->driver_name)
|
||||
+ return false;
|
||||
+
|
||||
+ if (dri2_load_driver_dri3(disp)) {
|
||||
+ _EGLDevice *dev = _eglAddDevice(dri2_dpy->fd, false);
|
||||
+ if (!dev) {
|
||||
+ dlclose(dri2_dpy->driver);
|
||||
+ _eglLog(_EGL_WARNING, "DRI2: failed to find EGLDevice");
|
||||
+ } else {
|
||||
+ dri2_dpy->loader_extensions = image_loader_extensions;
|
||||
+ dri2_dpy->own_device = 1;
|
||||
+ disp->Device = dev;
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ free(dri2_dpy->driver_name);
|
||||
+ dri2_dpy->driver_name = NULL;
|
||||
+
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
static bool
|
||||
dri2_null_probe_device(_EGLDisplay *disp)
|
||||
{
|
||||
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
|
||||
|
||||
dri2_dpy->fd = -1;
|
||||
+ dri2_dpy->fd_dpy = -1;
|
||||
|
||||
for (unsigned i = 0; i <= NULL_CARD_MINOR_MAX; i++) {
|
||||
char *card_path;
|
||||
@@ -1781,32 +1854,20 @@ dri2_null_probe_device(_EGLDisplay *disp)
|
||||
if (asprintf(&card_path, DRM_DEV_NAME, DRM_DIR_NAME, i) < 0)
|
||||
continue;
|
||||
|
||||
- dri2_dpy->fd = loader_open_device(card_path);
|
||||
+ dri2_dpy->fd_dpy = loader_open_device(card_path);
|
||||
free(card_path);
|
||||
- if (dri2_dpy->fd < 0)
|
||||
+ if (dri2_dpy->fd_dpy < 0)
|
||||
continue;
|
||||
|
||||
- if (dri2_null_device_is_kms(dri2_dpy->fd)) {
|
||||
- dri2_dpy->driver_name = loader_get_driver_for_fd(dri2_dpy->fd);
|
||||
- if (dri2_dpy->driver_name) {
|
||||
- if (dri2_load_driver_dri3(disp)) {
|
||||
- _EGLDevice *dev = _eglAddDevice(dri2_dpy->fd, false);
|
||||
- if (!dev) {
|
||||
- dlclose(dri2_dpy->driver);
|
||||
- _eglLog(_EGL_WARNING, "DRI2: failed to find EGLDevice");
|
||||
- } else {
|
||||
- dri2_dpy->loader_extensions = image_loader_extensions;
|
||||
- dri2_dpy->own_device = 1;
|
||||
- disp->Device = dev;
|
||||
- return true;
|
||||
- }
|
||||
- }
|
||||
- free(dri2_dpy->driver_name);
|
||||
- dri2_dpy->driver_name = NULL;
|
||||
- }
|
||||
- }
|
||||
+ if (dri2_null_try_device(disp))
|
||||
+ return true;
|
||||
+
|
||||
+ close(dri2_dpy->fd_dpy);
|
||||
+
|
||||
+ if (dri2_dpy->fd >= 0 && dri2_dpy->fd != dri2_dpy->fd_dpy)
|
||||
+ close(dri2_dpy->fd);
|
||||
|
||||
- close(dri2_dpy->fd);
|
||||
+ dri2_dpy->fd_dpy = -1;
|
||||
dri2_dpy->fd = -1;
|
||||
}
|
||||
|
||||
@@ -1867,7 +1928,7 @@ 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);
|
||||
+ err = drmGetCap(dri2_dpy->fd_dpy, DRM_CAP_ASYNC_PAGE_FLIP, &value);
|
||||
if (err || value == 0) {
|
||||
|
||||
/* DRM/KMS does not support async page flip. In order to support
|
||||
@@ -1914,7 +1975,7 @@ dri2_initialize_null(_EGLDisplay *disp)
|
||||
* modesetting if not. If this succeeds then universal planes will also have
|
||||
* been enabled.
|
||||
*/
|
||||
- err = drmSetClientCap(dri2_dpy->fd, DRM_CLIENT_CAP_ATOMIC, 1);
|
||||
+ err = drmSetClientCap(dri2_dpy->fd_dpy, DRM_CLIENT_CAP_ATOMIC, 1);
|
||||
dri2_dpy->atomic_enabled = !err;
|
||||
|
||||
if (!dri2_dpy->atomic_enabled) {
|
||||
@@ -1922,7 +1983,7 @@ dri2_initialize_null(_EGLDisplay *disp)
|
||||
* Enable universal planes so that we can get the pixel formats for the
|
||||
* primary plane
|
||||
*/
|
||||
- err = drmSetClientCap(dri2_dpy->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
|
||||
+ err = drmSetClientCap(dri2_dpy->fd_dpy, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
|
||||
if (err) {
|
||||
_eglError(EGL_NOT_INITIALIZED, "failed to enable universal planes");
|
||||
goto cleanup;
|
||||
@@ -1955,7 +2016,7 @@ dri2_initialize_null(_EGLDisplay *disp)
|
||||
prefer_in_formats = dri2_dpy->image->base.version >= 14 &&
|
||||
dri2_dpy->image->createImageWithModifiers;
|
||||
|
||||
- if (!display_output_init(dri2_dpy->fd, &dri2_dpy->output,
|
||||
+ if (!display_output_init(dri2_dpy->fd_dpy, &dri2_dpy->output,
|
||||
dri2_dpy->atomic_enabled,
|
||||
prefer_in_formats,
|
||||
&dri2_dpy->in_formats_enabled)) {
|
||||
@@ -1990,7 +2051,7 @@ dri2_teardown_null(struct dri2_egl_display *dri2_dpy)
|
||||
drmModeFreeFormats(dri2_dpy->output.in_formats);
|
||||
|
||||
if (dri2_dpy->output.mode_blob_id)
|
||||
- drmModeDestroyPropertyBlob(dri2_dpy->fd, dri2_dpy->output.mode_blob_id);
|
||||
+ drmModeDestroyPropertyBlob(dri2_dpy->fd_dpy, dri2_dpy->output.mode_blob_id);
|
||||
|
||||
if (dri2_dpy->output.plane_prop_res) {
|
||||
for (unsigned i = 0; dri2_dpy->output.plane_prop_res[i]; i++)
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
From 693fff6d87abfcae887afde7f80f402b7ff5c0ab Mon Sep 17 00:00:00 2001
|
||||
From: Brendan King <Brendan.King@imgtec.com>
|
||||
Date: Mon, 28 Jun 2021 16:36:15 +0100
|
||||
Subject: [PATCH 55/67] egl/null: introduce NULL_DRM_DISPLAY
|
||||
|
||||
Introduce the NULL_DRM_DISPLAY environment variable, which allows
|
||||
a particular DRM display to be selected, rather than the first
|
||||
suitable DRM device found.
|
||||
|
||||
To select a particular display, NULL_DRM_DISPLAY should be set to
|
||||
the card number (i.e. minor number) of the DRM device representing
|
||||
the display. For example, NULL_DRM_DISPLAY=2 will select
|
||||
/dev/dri/card2.
|
||||
---
|
||||
src/egl/drivers/dri2/platform_null.c | 65 ++++++++++++++++++++--------
|
||||
1 file changed, 46 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/src/egl/drivers/dri2/platform_null.c b/src/egl/drivers/dri2/platform_null.c
|
||||
index af77ea4dd89..529cc7a2a2f 100644
|
||||
--- a/src/egl/drivers/dri2/platform_null.c
|
||||
+++ b/src/egl/drivers/dri2/platform_null.c
|
||||
@@ -1784,6 +1784,8 @@ dri2_null_try_device(_EGLDisplay *disp)
|
||||
{
|
||||
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
|
||||
|
||||
+ dri2_dpy->fd = -1;
|
||||
+
|
||||
if (!dri2_null_device_is_kms(dri2_dpy->fd_dpy))
|
||||
return false;
|
||||
|
||||
@@ -1841,34 +1843,56 @@ dri2_null_try_device(_EGLDisplay *disp)
|
||||
}
|
||||
|
||||
static bool
|
||||
-dri2_null_probe_device(_EGLDisplay *disp)
|
||||
+dri2_null_probe_device(_EGLDisplay *disp, unsigned minor)
|
||||
{
|
||||
struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
|
||||
+ char *card_path;
|
||||
|
||||
- dri2_dpy->fd = -1;
|
||||
- dri2_dpy->fd_dpy = -1;
|
||||
+ if (asprintf(&card_path, DRM_DEV_NAME, DRM_DIR_NAME, minor) < 0)
|
||||
+ goto cleanup;
|
||||
|
||||
- for (unsigned i = 0; i <= NULL_CARD_MINOR_MAX; i++) {
|
||||
- char *card_path;
|
||||
+ dri2_dpy->fd_dpy = loader_open_device(card_path);
|
||||
+ free(card_path);
|
||||
+ if (dri2_dpy->fd_dpy < 0)
|
||||
+ goto cleanup;
|
||||
|
||||
- if (asprintf(&card_path, DRM_DEV_NAME, DRM_DIR_NAME, i) < 0)
|
||||
- continue;
|
||||
+ if (dri2_null_try_device(disp))
|
||||
+ return true;
|
||||
|
||||
- dri2_dpy->fd_dpy = loader_open_device(card_path);
|
||||
- free(card_path);
|
||||
- if (dri2_dpy->fd_dpy < 0)
|
||||
- continue;
|
||||
+ close(dri2_dpy->fd_dpy);
|
||||
|
||||
- if (dri2_null_try_device(disp))
|
||||
- return true;
|
||||
+ if (dri2_dpy->fd >= 0 && dri2_dpy->fd != dri2_dpy->fd_dpy)
|
||||
+ close(dri2_dpy->fd);
|
||||
|
||||
- close(dri2_dpy->fd_dpy);
|
||||
+cleanup:
|
||||
+ dri2_dpy->fd_dpy = -1;
|
||||
+ dri2_dpy->fd = -1;
|
||||
|
||||
- if (dri2_dpy->fd >= 0 && dri2_dpy->fd != dri2_dpy->fd_dpy)
|
||||
- close(dri2_dpy->fd);
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
+static bool
|
||||
+dri2_null_probe_devices(_EGLDisplay *disp)
|
||||
+{
|
||||
+ const char *null_drm_display = getenv("NULL_DRM_DISPLAY");
|
||||
+
|
||||
+ if (null_drm_display) {
|
||||
+ char *endptr;
|
||||
+ long val = strtol(null_drm_display, &endptr, 10);
|
||||
|
||||
- dri2_dpy->fd_dpy = -1;
|
||||
- dri2_dpy->fd = -1;
|
||||
+ if (endptr != null_drm_display && !*endptr &&
|
||||
+ val >= 0 && val <= NULL_CARD_MINOR_MAX) {
|
||||
+ if (dri2_null_probe_device(disp, (unsigned)val))
|
||||
+ return true;
|
||||
+ } else {
|
||||
+ _eglLog(_EGL_FATAL, "NULL_DRM_DISPLAY is invalid: %s",
|
||||
+ null_drm_display);
|
||||
+ }
|
||||
+ } else {
|
||||
+ for (unsigned i = 0; i <= NULL_CARD_MINOR_MAX; i++) {
|
||||
+ if (dri2_null_probe_device(disp, i))
|
||||
+ return true;
|
||||
+ }
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -1965,7 +1989,10 @@ dri2_initialize_null(_EGLDisplay *disp)
|
||||
|
||||
disp->DriverData = (void *) dri2_dpy;
|
||||
|
||||
- if (!dri2_null_probe_device(disp)) {
|
||||
+ dri2_dpy->fd_dpy = -1;
|
||||
+ dri2_dpy->fd = -1;
|
||||
+
|
||||
+ if (!dri2_null_probe_devices(disp)) {
|
||||
_eglError(EGL_NOT_INITIALIZED, "failed to load driver");
|
||||
goto cleanup;
|
||||
}
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
From a422756b7d73b48d3d10d15066a61e9332370719 Mon Sep 17 00:00:00 2001
|
||||
From: Brendan King <Brendan.King@imgtec.com>
|
||||
Date: Mon, 21 Jun 2021 17:05:17 +0100
|
||||
Subject: [PATCH 56/67] vulkan/wsi: check the DRI3 and Present XCB reply
|
||||
pointers
|
||||
|
||||
Check that the DRI3 and Present version replies are not NULL
|
||||
before accessing the version fields.
|
||||
---
|
||||
src/vulkan/wsi/wsi_common_x11.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c
|
||||
index 9dce78eddeb..9eb624df640 100644
|
||||
--- a/src/vulkan/wsi/wsi_common_x11.c
|
||||
+++ b/src/vulkan/wsi/wsi_common_x11.c
|
||||
@@ -216,7 +216,7 @@ wsi_x11_connection_create(struct wsi_device *wsi_dev,
|
||||
|
||||
ver_cookie = xcb_dri3_query_version(conn, 1, 2);
|
||||
ver_reply = xcb_dri3_query_version_reply(conn, ver_cookie, NULL);
|
||||
- has_dri3_v1_2 =
|
||||
+ has_dri3_v1_2 = ver_reply != NULL &&
|
||||
(ver_reply->major_version > 1 || ver_reply->minor_version >= 2);
|
||||
free(ver_reply);
|
||||
}
|
||||
@@ -230,7 +230,7 @@ wsi_x11_connection_create(struct wsi_device *wsi_dev,
|
||||
|
||||
ver_cookie = xcb_present_query_version(conn, 1, 2);
|
||||
ver_reply = xcb_present_query_version_reply(conn, ver_cookie, NULL);
|
||||
- has_present_v1_2 =
|
||||
+ has_present_v1_2 = ver_reply != NULL &&
|
||||
(ver_reply->major_version > 1 || ver_reply->minor_version >= 2);
|
||||
free(ver_reply);
|
||||
}
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
From b900d4998b95a8bdfb01600f81635ff76810cfe6 Mon Sep 17 00:00:00 2001
|
||||
From: Brendan King <Brendan.King@imgtec.com>
|
||||
Date: Tue, 16 Feb 2021 20:17:32 +0000
|
||||
Subject: [PATCH 57/67] vulkan/wsi: Allow host visible memory to be requested
|
||||
|
||||
Allow host visible memory to be explicitly requested when allocating
|
||||
native images.
|
||||
|
||||
For a software driver on X11, we need to be able to map the memory on
|
||||
the host, in order to present the contents to the X Server.
|
||||
---
|
||||
src/vulkan/wsi/wsi_common_display.c | 2 +-
|
||||
src/vulkan/wsi/wsi_common_drm.c | 17 +++++++++++++----
|
||||
src/vulkan/wsi/wsi_common_private.h | 1 +
|
||||
src/vulkan/wsi/wsi_common_wayland.c | 3 ++-
|
||||
src/vulkan/wsi/wsi_common_x11.c | 1 +
|
||||
5 files changed, 18 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/src/vulkan/wsi/wsi_common_display.c b/src/vulkan/wsi/wsi_common_display.c
|
||||
index aa07cada107..71a84e54079 100644
|
||||
--- a/src/vulkan/wsi/wsi_common_display.c
|
||||
+++ b/src/vulkan/wsi/wsi_common_display.c
|
||||
@@ -1031,7 +1031,7 @@ wsi_display_image_init(VkDevice device_h,
|
||||
return VK_ERROR_DEVICE_LOST;
|
||||
|
||||
VkResult result = wsi_create_native_image(&chain->base, create_info,
|
||||
- 0, NULL, NULL,
|
||||
+ 0, NULL, NULL, false,
|
||||
&image->base);
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
diff --git a/src/vulkan/wsi/wsi_common_drm.c b/src/vulkan/wsi/wsi_common_drm.c
|
||||
index 70d934aef13..aabb761908c 100644
|
||||
--- a/src/vulkan/wsi/wsi_common_drm.c
|
||||
+++ b/src/vulkan/wsi/wsi_common_drm.c
|
||||
@@ -66,6 +66,7 @@ wsi_device_matches_drm_fd(const struct wsi_device *wsi, int drm_fd)
|
||||
static uint32_t
|
||||
select_memory_type(const struct wsi_device *wsi,
|
||||
bool want_device_local,
|
||||
+ bool want_host_visible,
|
||||
uint32_t type_bits)
|
||||
{
|
||||
assert(type_bits);
|
||||
@@ -74,8 +75,10 @@ select_memory_type(const struct wsi_device *wsi,
|
||||
for (uint32_t i = 0; i < wsi->memory_props.memoryTypeCount; i++) {
|
||||
const VkMemoryType type = wsi->memory_props.memoryTypes[i];
|
||||
bool local = type.propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
|
||||
+ bool host = type.propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
|
||||
|
||||
- if ((type_bits & (1 << i)) && local == want_device_local)
|
||||
+ if ((type_bits & (1 << i)) && local == want_device_local &&
|
||||
+ (!want_host_visible || host))
|
||||
return i;
|
||||
all_local &= local;
|
||||
}
|
||||
@@ -83,6 +86,8 @@ select_memory_type(const struct wsi_device *wsi,
|
||||
/* ignore want_device_local when all memory types are device-local */
|
||||
if (all_local) {
|
||||
assert(!want_device_local);
|
||||
+ /* currently, host visibility is only needed with device local */
|
||||
+ assert(!want_host_visible);
|
||||
return ffs(type_bits) - 1;
|
||||
}
|
||||
|
||||
@@ -107,6 +112,7 @@ wsi_create_native_image(const struct wsi_swapchain *chain,
|
||||
uint32_t num_modifier_lists,
|
||||
const uint32_t *num_modifiers,
|
||||
const uint64_t *const *modifiers,
|
||||
+ bool host_visible,
|
||||
struct wsi_image *image)
|
||||
{
|
||||
const struct wsi_device *wsi = chain->wsi;
|
||||
@@ -317,7 +323,8 @@ wsi_create_native_image(const struct wsi_swapchain *chain,
|
||||
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
|
||||
.pNext = &memory_dedicated_info,
|
||||
.allocationSize = reqs.size,
|
||||
- .memoryTypeIndex = select_memory_type(wsi, true, reqs.memoryTypeBits),
|
||||
+ .memoryTypeIndex = select_memory_type(wsi, true, host_visible,
|
||||
+ reqs.memoryTypeBits),
|
||||
};
|
||||
result = wsi->AllocateMemory(chain->device, &memory_info,
|
||||
&chain->alloc, &image->memory);
|
||||
@@ -488,7 +495,8 @@ wsi_create_prime_image(const struct wsi_swapchain *chain,
|
||||
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
|
||||
.pNext = &prime_memory_dedicated_info,
|
||||
.allocationSize = linear_size,
|
||||
- .memoryTypeIndex = select_memory_type(wsi, false, reqs.memoryTypeBits),
|
||||
+ .memoryTypeIndex = select_memory_type(wsi, false, false,
|
||||
+ reqs.memoryTypeBits),
|
||||
};
|
||||
result = wsi->AllocateMemory(chain->device, &prime_memory_info,
|
||||
&chain->alloc, &image->prime.memory);
|
||||
@@ -542,7 +550,8 @@ wsi_create_prime_image(const struct wsi_swapchain *chain,
|
||||
.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
|
||||
.pNext = &memory_dedicated_info,
|
||||
.allocationSize = reqs.size,
|
||||
- .memoryTypeIndex = select_memory_type(wsi, true, reqs.memoryTypeBits),
|
||||
+ .memoryTypeIndex = select_memory_type(wsi, true, false,
|
||||
+ reqs.memoryTypeBits),
|
||||
};
|
||||
result = wsi->AllocateMemory(chain->device, &memory_info,
|
||||
&chain->alloc, &image->memory);
|
||||
diff --git a/src/vulkan/wsi/wsi_common_private.h b/src/vulkan/wsi/wsi_common_private.h
|
||||
index 1fe8211f9cb..5ad087b32e0 100644
|
||||
--- a/src/vulkan/wsi/wsi_common_private.h
|
||||
+++ b/src/vulkan/wsi/wsi_common_private.h
|
||||
@@ -94,6 +94,7 @@ wsi_create_native_image(const struct wsi_swapchain *chain,
|
||||
uint32_t num_modifier_lists,
|
||||
const uint32_t *num_modifiers,
|
||||
const uint64_t *const *modifiers,
|
||||
+ bool host_visible,
|
||||
struct wsi_image *image);
|
||||
|
||||
VkResult
|
||||
diff --git a/src/vulkan/wsi/wsi_common_wayland.c b/src/vulkan/wsi/wsi_common_wayland.c
|
||||
index 40f5338314f..983833e880b 100644
|
||||
--- a/src/vulkan/wsi/wsi_common_wayland.c
|
||||
+++ b/src/vulkan/wsi/wsi_common_wayland.c
|
||||
@@ -1074,7 +1074,8 @@ wsi_wl_image_init(struct wsi_wl_swapchain *chain,
|
||||
result = wsi_create_native_image(&chain->base, pCreateInfo,
|
||||
chain->num_drm_modifiers > 0 ? 1 : 0,
|
||||
&chain->num_drm_modifiers,
|
||||
- &chain->drm_modifiers, &image->base);
|
||||
+ &chain->drm_modifiers, false,
|
||||
+ &image->base);
|
||||
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c
|
||||
index 9eb624df640..eb639d6c265 100644
|
||||
--- a/src/vulkan/wsi/wsi_common_x11.c
|
||||
+++ b/src/vulkan/wsi/wsi_common_x11.c
|
||||
@@ -1315,6 +1315,7 @@ x11_image_init(VkDevice device_h, struct x11_swapchain *chain,
|
||||
} else {
|
||||
result = wsi_create_native_image(&chain->base, pCreateInfo,
|
||||
num_tranches, num_modifiers, modifiers,
|
||||
+ chain->base.wsi->sw,
|
||||
&image->base);
|
||||
}
|
||||
if (result < 0)
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,419 @@
|
||||
From afcfb076e89365ff1f33c658a6a615d2108d97f5 Mon Sep 17 00:00:00 2001
|
||||
From: Brendan King <Brendan.King@imgtec.com>
|
||||
Date: Thu, 17 Jun 2021 17:17:07 +0100
|
||||
Subject: [PATCH 58/67] vulkan/wsi: make the display FD available
|
||||
|
||||
Pass the display FD to the Vulkan image create and memory
|
||||
allocation functions when allocating swapchain images.
|
||||
---
|
||||
src/vulkan/wsi/wsi_common.h | 14 +++
|
||||
src/vulkan/wsi/wsi_common_display.c | 2 +-
|
||||
src/vulkan/wsi/wsi_common_drm.c | 22 ++++-
|
||||
src/vulkan/wsi/wsi_common_private.h | 2 +
|
||||
src/vulkan/wsi/wsi_common_wayland.c | 127 ++++++++++++++++++++++------
|
||||
src/vulkan/wsi/wsi_common_x11.c | 42 ++++++---
|
||||
6 files changed, 169 insertions(+), 40 deletions(-)
|
||||
|
||||
diff --git a/src/vulkan/wsi/wsi_common.h b/src/vulkan/wsi/wsi_common.h
|
||||
index d5367db3a94..c2563c677e6 100644
|
||||
--- a/src/vulkan/wsi/wsi_common.h
|
||||
+++ b/src/vulkan/wsi/wsi_common.h
|
||||
@@ -37,6 +37,8 @@
|
||||
#define VK_STRUCTURE_TYPE_WSI_MEMORY_ALLOCATE_INFO_MESA (VkStructureType)1000001003
|
||||
#define VK_STRUCTURE_TYPE_WSI_SURFACE_SUPPORTED_COUNTERS_MESA (VkStructureType)1000001005
|
||||
#define VK_STRUCTURE_TYPE_WSI_MEMORY_SIGNAL_SUBMIT_INFO_MESA (VkStructureType)1000001006
|
||||
+#define VK_STRUCTURE_TYPE_WSI_IMAGE_CREATE_INFO2_MESA (VkStructureType)1000001007
|
||||
+#define VK_STRUCTURE_TYPE_WSI_MEMORY_ALLOCATE_INFO2_MESA (VkStructureType)1000001008
|
||||
|
||||
/* This is always chained to VkImageCreateInfo when a wsi image is created.
|
||||
* It indicates that the image can be transitioned to/from
|
||||
@@ -75,6 +77,18 @@ struct wsi_memory_signal_submit_info {
|
||||
VkDeviceMemory memory;
|
||||
};
|
||||
|
||||
+struct wsi_image_create_info2 {
|
||||
+ VkStructureType sType;
|
||||
+ const void *pNext;
|
||||
+ int display_fd;
|
||||
+};
|
||||
+
|
||||
+struct wsi_memory_allocate_info2 {
|
||||
+ VkStructureType sType;
|
||||
+ const void *pNext;
|
||||
+ int display_fd;
|
||||
+};
|
||||
+
|
||||
struct wsi_fence {
|
||||
VkDevice device;
|
||||
const struct wsi_device *wsi_device;
|
||||
diff --git a/src/vulkan/wsi/wsi_common_display.c b/src/vulkan/wsi/wsi_common_display.c
|
||||
index 71a84e54079..f135b4e38de 100644
|
||||
--- a/src/vulkan/wsi/wsi_common_display.c
|
||||
+++ b/src/vulkan/wsi/wsi_common_display.c
|
||||
@@ -1032,7 +1032,7 @@ wsi_display_image_init(VkDevice device_h,
|
||||
|
||||
VkResult result = wsi_create_native_image(&chain->base, create_info,
|
||||
0, NULL, NULL, false,
|
||||
- &image->base);
|
||||
+ wsi->fd, &image->base);
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
|
||||
diff --git a/src/vulkan/wsi/wsi_common_drm.c b/src/vulkan/wsi/wsi_common_drm.c
|
||||
index aabb761908c..6201891ca80 100644
|
||||
--- a/src/vulkan/wsi/wsi_common_drm.c
|
||||
+++ b/src/vulkan/wsi/wsi_common_drm.c
|
||||
@@ -113,6 +113,7 @@ wsi_create_native_image(const struct wsi_swapchain *chain,
|
||||
const uint32_t *num_modifiers,
|
||||
const uint64_t *const *modifiers,
|
||||
bool host_visible,
|
||||
+ int display_fd,
|
||||
struct wsi_image *image)
|
||||
{
|
||||
const struct wsi_device *wsi = chain->wsi;
|
||||
@@ -170,6 +171,12 @@ wsi_create_native_image(const struct wsi_swapchain *chain,
|
||||
__vk_append_struct(&image_info, &image_format_list);
|
||||
}
|
||||
|
||||
+ struct wsi_image_create_info2 image_wsi_info2 = {
|
||||
+ .sType = VK_STRUCTURE_TYPE_WSI_IMAGE_CREATE_INFO2_MESA,
|
||||
+ .display_fd = display_fd,
|
||||
+ };
|
||||
+ __vk_append_struct(&image_info, &image_wsi_info2);
|
||||
+
|
||||
VkImageDrmFormatModifierListCreateInfoEXT image_modifier_list;
|
||||
|
||||
uint32_t image_modifier_count = 0, modifier_prop_count = 0;
|
||||
@@ -308,9 +315,14 @@ wsi_create_native_image(const struct wsi_swapchain *chain,
|
||||
.pNext = NULL,
|
||||
.implicit_sync = true,
|
||||
};
|
||||
+ const struct wsi_memory_allocate_info2 memory_wsi_info2 = {
|
||||
+ .sType = VK_STRUCTURE_TYPE_WSI_MEMORY_ALLOCATE_INFO2_MESA,
|
||||
+ .pNext = &memory_wsi_info,
|
||||
+ .display_fd = display_fd,
|
||||
+ };
|
||||
const VkExportMemoryAllocateInfo memory_export_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO,
|
||||
- .pNext = &memory_wsi_info,
|
||||
+ .pNext = &memory_wsi_info2,
|
||||
.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
|
||||
};
|
||||
const VkMemoryDedicatedAllocateInfo memory_dedicated_info = {
|
||||
@@ -440,6 +452,7 @@ VkResult
|
||||
wsi_create_prime_image(const struct wsi_swapchain *chain,
|
||||
const VkSwapchainCreateInfoKHR *pCreateInfo,
|
||||
bool use_modifier,
|
||||
+ int display_fd,
|
||||
struct wsi_image *image)
|
||||
{
|
||||
const struct wsi_device *wsi = chain->wsi;
|
||||
@@ -480,9 +493,14 @@ wsi_create_prime_image(const struct wsi_swapchain *chain,
|
||||
.pNext = NULL,
|
||||
.implicit_sync = true,
|
||||
};
|
||||
+ const struct wsi_memory_allocate_info2 memory_wsi_info2 = {
|
||||
+ .sType = VK_STRUCTURE_TYPE_WSI_MEMORY_ALLOCATE_INFO2_MESA,
|
||||
+ .pNext = &memory_wsi_info,
|
||||
+ .display_fd = display_fd,
|
||||
+ };
|
||||
const VkExportMemoryAllocateInfo prime_memory_export_info = {
|
||||
.sType = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO,
|
||||
- .pNext = &memory_wsi_info,
|
||||
+ .pNext = &memory_wsi_info2,
|
||||
.handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT,
|
||||
};
|
||||
const VkMemoryDedicatedAllocateInfo prime_memory_dedicated_info = {
|
||||
diff --git a/src/vulkan/wsi/wsi_common_private.h b/src/vulkan/wsi/wsi_common_private.h
|
||||
index 5ad087b32e0..e46328156dc 100644
|
||||
--- a/src/vulkan/wsi/wsi_common_private.h
|
||||
+++ b/src/vulkan/wsi/wsi_common_private.h
|
||||
@@ -95,12 +95,14 @@ wsi_create_native_image(const struct wsi_swapchain *chain,
|
||||
const uint32_t *num_modifiers,
|
||||
const uint64_t *const *modifiers,
|
||||
bool host_visible,
|
||||
+ int display_fd,
|
||||
struct wsi_image *image);
|
||||
|
||||
VkResult
|
||||
wsi_create_prime_image(const struct wsi_swapchain *chain,
|
||||
const VkSwapchainCreateInfoKHR *pCreateInfo,
|
||||
bool use_modifier,
|
||||
+ int display_fd,
|
||||
struct wsi_image *image);
|
||||
|
||||
void
|
||||
diff --git a/src/vulkan/wsi/wsi_common_wayland.c b/src/vulkan/wsi/wsi_common_wayland.c
|
||||
index 983833e880b..1109d3f07b6 100644
|
||||
--- a/src/vulkan/wsi/wsi_common_wayland.c
|
||||
+++ b/src/vulkan/wsi/wsi_common_wayland.c
|
||||
@@ -32,6 +32,8 @@
|
||||
#include <pthread.h>
|
||||
#include <poll.h>
|
||||
#include <sys/mman.h>
|
||||
+#include <fcntl.h>
|
||||
+#include <xf86drm.h>
|
||||
|
||||
#include "drm-uapi/drm_fourcc.h"
|
||||
|
||||
@@ -82,6 +84,9 @@ struct wsi_wl_display {
|
||||
|
||||
struct wsi_wayland *wsi_wl;
|
||||
|
||||
+ int fd;
|
||||
+ bool authenticated;
|
||||
+
|
||||
/* Points to formats in wsi_wl_display_drm or wsi_wl_display_dmabuf */
|
||||
struct u_vector * formats;
|
||||
|
||||
@@ -261,10 +266,52 @@ wsi_wl_display_add_wl_shm_format(struct wsi_wl_display *display,
|
||||
}
|
||||
}
|
||||
|
||||
+static int
|
||||
+open_display_device(const char *name)
|
||||
+{
|
||||
+ int fd;
|
||||
+
|
||||
+#ifdef O_CLOEXEC
|
||||
+ fd = open(name, O_RDWR | O_CLOEXEC);
|
||||
+ if (fd != -1 || errno != EINVAL) {
|
||||
+ return fd;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
+ fd = open(name, O_RDWR);
|
||||
+ if (fd != -1) {
|
||||
+ long flags = fcntl(fd, F_GETFD);
|
||||
+
|
||||
+ if (flags != -1) {
|
||||
+ if (!fcntl(fd, F_SETFD, flags | FD_CLOEXEC))
|
||||
+ return fd;
|
||||
+ }
|
||||
+ close (fd);
|
||||
+ }
|
||||
+
|
||||
+ return -1;
|
||||
+}
|
||||
|
||||
static void
|
||||
drm_handle_device(void *data, struct wl_drm *drm, const char *name)
|
||||
{
|
||||
+ struct wsi_wl_display *display = data;
|
||||
+ const int fd = open_display_device(name);
|
||||
+
|
||||
+ if (fd != -1) {
|
||||
+ if (drmGetNodeTypeFromFd(fd) != DRM_NODE_RENDER) {
|
||||
+ drm_magic_t magic;
|
||||
+
|
||||
+ if (drmGetMagic(fd, &magic)) {
|
||||
+ close(fd);
|
||||
+ return;
|
||||
+ }
|
||||
+ wl_drm_authenticate(drm, magic);
|
||||
+ } else {
|
||||
+ display->authenticated = true;
|
||||
+ }
|
||||
+ display->fd = fd;
|
||||
+ }
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
@@ -346,6 +393,9 @@ drm_handle_format(void *data, struct wl_drm *drm, uint32_t wl_format)
|
||||
static void
|
||||
drm_handle_authenticated(void *data, struct wl_drm *drm)
|
||||
{
|
||||
+ struct wsi_wl_display *display = data;
|
||||
+
|
||||
+ display->authenticated = true;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -487,6 +537,9 @@ wsi_wl_display_finish(struct wsi_wl_display *display)
|
||||
wl_proxy_wrapper_destroy(display->wl_display_wrapper);
|
||||
if (display->queue)
|
||||
wl_event_queue_destroy(display->queue);
|
||||
+
|
||||
+ if (display->fd != -1)
|
||||
+ close(display->fd);
|
||||
}
|
||||
|
||||
static VkResult
|
||||
@@ -501,6 +554,7 @@ wsi_wl_display_init(struct wsi_wayland *wsi_wl,
|
||||
display->wsi_wl = wsi_wl;
|
||||
display->wl_display = wl_display;
|
||||
display->sw = sw;
|
||||
+ display->fd = -1;
|
||||
|
||||
if (get_format_list) {
|
||||
if (!u_vector_init(&display->swrast.formats, sizeof(VkFormat), 8) ||
|
||||
@@ -542,41 +596,60 @@ wsi_wl_display_init(struct wsi_wayland *wsi_wl,
|
||||
/* Round-trip to get wl_drms and zwp_linux_dmabuf_v1 globals */
|
||||
wl_display_roundtrip_queue(display->wl_display, display->queue);
|
||||
|
||||
+ if (!display->drm.wl_drm && !display->dmabuf.wl_dmabuf && !display->swrast.wl_shm) {
|
||||
+ result = VK_ERROR_SURFACE_LOST_KHR;
|
||||
+ goto fail_registry;
|
||||
+ }
|
||||
+
|
||||
/* Round-trip again to get formats, modifiers and capabilities */
|
||||
- if (display->drm.wl_drm || display->dmabuf.wl_dmabuf || display->swrast.wl_shm)
|
||||
- wl_display_roundtrip_queue(display->wl_display, display->queue);
|
||||
+ wl_display_roundtrip_queue(display->wl_display, display->queue);
|
||||
|
||||
- if (wsi_wl->wsi->force_bgra8_unorm_first) {
|
||||
- /* Find BGRA8_UNORM in the list and swap it to the first position if we
|
||||
- * can find it. Some apps get confused if SRGB is first in the list.
|
||||
- */
|
||||
- VkFormat *first_fmt = u_vector_head(display->formats);
|
||||
- VkFormat *iter_fmt;
|
||||
- u_vector_foreach(iter_fmt, display->formats) {
|
||||
- if (*iter_fmt == VK_FORMAT_B8G8R8A8_UNORM) {
|
||||
- *iter_fmt = *first_fmt;
|
||||
- *first_fmt = VK_FORMAT_B8G8R8A8_UNORM;
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
+ if (display->fd == -1) {
|
||||
+ result = VK_ERROR_SURFACE_LOST_KHR;
|
||||
+ goto fail_registry;
|
||||
}
|
||||
|
||||
- /* Prefer the linux-dmabuf protocol if available */
|
||||
- if (display->sw)
|
||||
- display->formats = &display->swrast.formats;
|
||||
- else if (display->dmabuf.wl_dmabuf) {
|
||||
- display->formats = &display->dmabuf.formats;
|
||||
- } else if (display->drm.wl_drm &&
|
||||
- (display->drm.capabilities & WL_DRM_CAPABILITY_PRIME)) {
|
||||
- /* We need prime support for wl_drm */
|
||||
- display->formats = &display->drm.formats;
|
||||
- }
|
||||
+ wl_display_roundtrip_queue(display->wl_display, display->queue);
|
||||
|
||||
- if (!display->formats) {
|
||||
+ if (!display->authenticated) {
|
||||
result = VK_ERROR_SURFACE_LOST_KHR;
|
||||
goto fail_registry;
|
||||
}
|
||||
|
||||
+ if (get_format_list) {
|
||||
+ /* Prefer the linux-dmabuf protocol if available */
|
||||
+ if (display->sw)
|
||||
+ display->formats = &display->swrast.formats;
|
||||
+ else if(display->dmabuf.wl_dmabuf &&
|
||||
+ u_vector_length(&display->dmabuf.formats)) {
|
||||
+ display->formats = &display->dmabuf.formats;
|
||||
+ } else if (display->drm.wl_drm &&
|
||||
+ display->drm.capabilities & WL_DRM_CAPABILITY_PRIME) {
|
||||
+ display->formats = &display->drm.formats;
|
||||
+ }
|
||||
+
|
||||
+ if (!display->formats) {
|
||||
+ result = VK_ERROR_SURFACE_LOST_KHR;
|
||||
+ goto fail_registry;
|
||||
+ }
|
||||
+
|
||||
+ if (wsi_wl->wsi->force_bgra8_unorm_first) {
|
||||
+ /* Find BGRA8_UNORM in the list and swap it to the first position if
|
||||
+ * we can find it. Some apps get confused if SRGB is first in the
|
||||
+ * list.
|
||||
+ */
|
||||
+ VkFormat *first_fmt = u_vector_tail(display->formats);
|
||||
+ VkFormat *iter_fmt;
|
||||
+ u_vector_foreach(iter_fmt, display->formats) {
|
||||
+ if (*iter_fmt == VK_FORMAT_B8G8R8A8_UNORM) {
|
||||
+ *iter_fmt = *first_fmt;
|
||||
+ *first_fmt = VK_FORMAT_B8G8R8A8_UNORM;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
/* We don't need this anymore */
|
||||
wl_registry_destroy(registry);
|
||||
|
||||
@@ -1075,7 +1148,7 @@ wsi_wl_image_init(struct wsi_wl_swapchain *chain,
|
||||
chain->num_drm_modifiers > 0 ? 1 : 0,
|
||||
&chain->num_drm_modifiers,
|
||||
&chain->drm_modifiers, false,
|
||||
- &image->base);
|
||||
+ display->fd, &image->base);
|
||||
|
||||
if (result != VK_SUCCESS)
|
||||
return result;
|
||||
diff --git a/src/vulkan/wsi/wsi_common_x11.c b/src/vulkan/wsi/wsi_common_x11.c
|
||||
index eb639d6c265..ba64e260932 100644
|
||||
--- a/src/vulkan/wsi/wsi_common_x11.c
|
||||
+++ b/src/vulkan/wsi/wsi_common_x11.c
|
||||
@@ -1303,7 +1303,8 @@ x11_image_init(VkDevice device_h, struct x11_swapchain *chain,
|
||||
const VkAllocationCallbacks* pAllocator,
|
||||
const uint64_t *const *modifiers,
|
||||
const uint32_t *num_modifiers,
|
||||
- int num_tranches, struct x11_image *image)
|
||||
+ int num_tranches, int display_fd,
|
||||
+ struct x11_image *image)
|
||||
{
|
||||
xcb_void_cookie_t cookie;
|
||||
VkResult result;
|
||||
@@ -1311,11 +1312,12 @@ x11_image_init(VkDevice device_h, struct x11_swapchain *chain,
|
||||
|
||||
if (chain->base.use_prime_blit) {
|
||||
bool use_modifier = num_tranches > 0;
|
||||
- result = wsi_create_prime_image(&chain->base, pCreateInfo, use_modifier, &image->base);
|
||||
+ result = wsi_create_prime_image(&chain->base, pCreateInfo, use_modifier,
|
||||
+ display_fd, &image->base);
|
||||
} else {
|
||||
result = wsi_create_native_image(&chain->base, pCreateInfo,
|
||||
num_tranches, num_modifiers, modifiers,
|
||||
- chain->base.wsi->sw,
|
||||
+ chain->base.wsi->sw, display_fd,
|
||||
&image->base);
|
||||
}
|
||||
if (result < 0)
|
||||
@@ -1687,14 +1689,34 @@ x11_surface_create_swapchain(VkIcdSurfaceBase *icd_surface,
|
||||
modifiers, num_modifiers, &num_tranches,
|
||||
pAllocator);
|
||||
|
||||
+
|
||||
uint32_t image = 0;
|
||||
- for (; image < chain->base.image_count; image++) {
|
||||
- result = x11_image_init(device, chain, pCreateInfo, pAllocator,
|
||||
- (const uint64_t *const *)modifiers,
|
||||
- num_modifiers, num_tranches,
|
||||
- &chain->images[image]);
|
||||
- if (result != VK_SUCCESS)
|
||||
- goto fail_init_images;
|
||||
+ {
|
||||
+ int display_fd = -1;
|
||||
+
|
||||
+ if (!wsi_device->sw) {
|
||||
+ xcb_screen_iterator_t screen_iter =
|
||||
+ xcb_setup_roots_iterator(xcb_get_setup(conn));
|
||||
+ xcb_screen_t *screen = screen_iter.data;
|
||||
+
|
||||
+ display_fd = wsi_dri3_open(conn, screen->root, None);
|
||||
+ }
|
||||
+
|
||||
+ for (; image < chain->base.image_count; image++) {
|
||||
+ result = x11_image_init(device, chain, pCreateInfo, pAllocator,
|
||||
+ (const uint64_t *const *)modifiers,
|
||||
+ num_modifiers, num_tranches,
|
||||
+ display_fd, &chain->images[image]);
|
||||
+ if (result != VK_SUCCESS) {
|
||||
+ if (display_fd >= 0)
|
||||
+ close(display_fd);
|
||||
+
|
||||
+ goto fail_init_images;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (display_fd >= 0)
|
||||
+ close(display_fd);
|
||||
}
|
||||
|
||||
if ((chain->base.present_mode == VK_PRESENT_MODE_FIFO_KHR ||
|
||||
--
|
||||
2.25.1
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,76 @@
|
||||
From 83953c9325e4cc9adb23ad7654a02ddabdd3fd99 Mon Sep 17 00:00:00 2001
|
||||
From: brendan King <Brendan.King@imgtec.com>
|
||||
Date: Fri, 30 Jul 2021 15:34:13 +0100
|
||||
Subject: [PATCH 60/67] vulkan/wsi: Disable use of VK_EXT_pci_bus_info
|
||||
|
||||
The VK_EXT_pci_bus_info related code has been wrapped in
|
||||
VULKAN_WSI_USE_PCI_BUS_INFO, effectively disabling it.
|
||||
|
||||
Not all platforms support the VK_EXT_pci_bus_info extension.
|
||||
A better fix might be to pass another parameter to wsi_device_init,
|
||||
to indicate that the device is a PCI one.
|
||||
---
|
||||
src/vulkan/wsi/wsi_common.c | 4 ++++
|
||||
src/vulkan/wsi/wsi_common.h | 2 ++
|
||||
src/vulkan/wsi/wsi_common_drm.c | 4 ++++
|
||||
3 files changed, 10 insertions(+)
|
||||
|
||||
diff --git a/src/vulkan/wsi/wsi_common.c b/src/vulkan/wsi/wsi_common.c
|
||||
index b1360edb911..66d6683a7c1 100644
|
||||
--- a/src/vulkan/wsi/wsi_common.c
|
||||
+++ b/src/vulkan/wsi/wsi_common.c
|
||||
@@ -56,11 +56,15 @@ wsi_device_init(struct wsi_device *wsi,
|
||||
WSI_GET_CB(GetPhysicalDeviceQueueFamilyProperties);
|
||||
#undef WSI_GET_CB
|
||||
|
||||
+#if defined(VULKAN_WSI_USE_PCI_BUS_INFO)
|
||||
wsi->pci_bus_info.sType =
|
||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT;
|
||||
+#endif
|
||||
VkPhysicalDeviceProperties2 pdp2 = {
|
||||
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2,
|
||||
+#if defined(VULKAN_WSI_USE_PCI_BUS_INFO)
|
||||
.pNext = &wsi->pci_bus_info,
|
||||
+#endif
|
||||
};
|
||||
GetPhysicalDeviceProperties2(pdevice, &pdp2);
|
||||
|
||||
diff --git a/src/vulkan/wsi/wsi_common.h b/src/vulkan/wsi/wsi_common.h
|
||||
index c2563c677e6..4a733665d2c 100644
|
||||
--- a/src/vulkan/wsi/wsi_common.h
|
||||
+++ b/src/vulkan/wsi/wsi_common.h
|
||||
@@ -112,7 +112,9 @@ struct wsi_device {
|
||||
VkPhysicalDeviceMemoryProperties memory_props;
|
||||
uint32_t queue_family_count;
|
||||
|
||||
+#if defined(VULKAN_WSI_USE_PCI_BUS_INFO)
|
||||
VkPhysicalDevicePCIBusInfoPropertiesEXT pci_bus_info;
|
||||
+#endif
|
||||
|
||||
bool supports_modifiers;
|
||||
uint32_t maxImageDimension2D;
|
||||
diff --git a/src/vulkan/wsi/wsi_common_drm.c b/src/vulkan/wsi/wsi_common_drm.c
|
||||
index 6201891ca80..49a78cf4c62 100644
|
||||
--- a/src/vulkan/wsi/wsi_common_drm.c
|
||||
+++ b/src/vulkan/wsi/wsi_common_drm.c
|
||||
@@ -45,6 +45,7 @@ wsi_device_matches_drm_fd(const struct wsi_device *wsi, int drm_fd)
|
||||
if (ret)
|
||||
return false;
|
||||
|
||||
+#if defined(VULKAN_WSI_USE_PCI_BUS_INFO)
|
||||
bool match = false;
|
||||
switch (fd_device->bustype) {
|
||||
case DRM_BUS_PCI:
|
||||
@@ -57,6 +58,9 @@ wsi_device_matches_drm_fd(const struct wsi_device *wsi, int drm_fd)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
+#else
|
||||
+ const bool match = true;
|
||||
+#endif
|
||||
|
||||
drmFreeDevice(&fd_device);
|
||||
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
From 10a0d4ec4f9d468c792f5e675d924fa7a8f97373 Mon Sep 17 00:00:00 2001
|
||||
From: brendan King <Brendan.King@imgtec.com>
|
||||
Date: Mon, 2 Aug 2021 16:29:36 +0100
|
||||
Subject: [PATCH 61/67] vulkan/wsi: default to force_bgra8_unorm_first true
|
||||
|
||||
If VULKAN_WSI_BGRA8_SNORM_FIRST is not defined, default to
|
||||
force_bgra8_unorm_first true.
|
||||
|
||||
This brings Mesa WSI into line with IMG WSI with regards to the
|
||||
VK_FORMAT_B8G8R8A8_UNORM and VK_FORMAT_B8G8R8A8_SRGB formats.
|
||||
With this change, the IMG Vulkan unit test, vkbonjour, will default
|
||||
to VK_FORMAT_B8G8R8A8_UNORM rather than VK_FORMAT_B8G8R8A8_SRGB.
|
||||
---
|
||||
src/vulkan/wsi/wsi_common.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/src/vulkan/wsi/wsi_common.c b/src/vulkan/wsi/wsi_common.c
|
||||
index 66d6683a7c1..1ffca6fecfb 100644
|
||||
--- a/src/vulkan/wsi/wsi_common.c
|
||||
+++ b/src/vulkan/wsi/wsi_common.c
|
||||
@@ -158,6 +158,10 @@ wsi_device_init(struct wsi_device *wsi,
|
||||
driQueryOptionb(dri_options, "vk_wsi_force_bgra8_unorm_first");
|
||||
}
|
||||
}
|
||||
+#if !defined(VULKAN_WSI_BGRA8_SNORM_FIRST)
|
||||
+ else
|
||||
+ wsi->force_bgra8_unorm_first = true;
|
||||
+#endif
|
||||
|
||||
return VK_SUCCESS;
|
||||
#if defined(VK_USE_PLATFORM_XCB_KHR) || \
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
From 7e8bb12d48651796da6d8f3df1b388551d3b5510 Mon Sep 17 00:00:00 2001
|
||||
From: brendan King <Brendan.King@imgtec.com>
|
||||
Date: Mon, 2 Aug 2021 11:21:16 +0100
|
||||
Subject: [PATCH 62/67] vulkan/wsi: enable additional formats for Wayland
|
||||
|
||||
Add VK_FORMAT_R5G6B5_UNORM_PACK16.
|
||||
|
||||
This is for compatibility with IMG WSI.
|
||||
---
|
||||
src/vulkan/wsi/wsi_common_wayland.c | 10 ++++++++++
|
||||
1 file changed, 10 insertions(+)
|
||||
|
||||
diff --git a/src/vulkan/wsi/wsi_common_wayland.c b/src/vulkan/wsi/wsi_common_wayland.c
|
||||
index 1109d3f07b6..e520aa9af00 100644
|
||||
--- a/src/vulkan/wsi/wsi_common_wayland.c
|
||||
+++ b/src/vulkan/wsi/wsi_common_wayland.c
|
||||
@@ -68,6 +68,7 @@ struct wsi_wl_display_dmabuf {
|
||||
struct {
|
||||
struct u_vector argb8888;
|
||||
struct u_vector xrgb8888;
|
||||
+ struct u_vector rgb565;
|
||||
} modifiers;
|
||||
};
|
||||
|
||||
@@ -441,6 +442,9 @@ dmabuf_handle_modifier(void *data, struct zwp_linux_dmabuf_v1 *dmabuf,
|
||||
case WL_DRM_FORMAT_XRGB8888:
|
||||
modifiers = &display->dmabuf.modifiers.xrgb8888;
|
||||
break;
|
||||
+ case WL_DRM_FORMAT_RGB565:
|
||||
+ modifiers = &display->dmabuf.modifiers.rgb565;
|
||||
+ break;
|
||||
default:
|
||||
return; /* Unsupported format */
|
||||
}
|
||||
@@ -527,6 +531,7 @@ wsi_wl_display_finish(struct wsi_wl_display *display)
|
||||
u_vector_finish(&display->dmabuf.formats);
|
||||
u_vector_finish(&display->dmabuf.modifiers.argb8888);
|
||||
u_vector_finish(&display->dmabuf.modifiers.xrgb8888);
|
||||
+ u_vector_finish(&display->dmabuf.modifiers.rgb565);
|
||||
if (display->swrast.wl_shm)
|
||||
wl_shm_destroy(display->swrast.wl_shm);
|
||||
if (display->drm.wl_drm)
|
||||
@@ -563,6 +568,8 @@ wsi_wl_display_init(struct wsi_wayland *wsi_wl,
|
||||
!u_vector_init(&display->dmabuf.modifiers.argb8888,
|
||||
sizeof(uint64_t), 32) ||
|
||||
!u_vector_init(&display->dmabuf.modifiers.xrgb8888,
|
||||
+ sizeof(uint64_t), 32) ||
|
||||
+ !u_vector_init(&display->dmabuf.modifiers.rgb565,
|
||||
sizeof(uint64_t), 32)) {
|
||||
result = VK_ERROR_OUT_OF_HOST_MEMORY;
|
||||
goto fail;
|
||||
@@ -1356,6 +1363,9 @@ wsi_wl_surface_create_swapchain(VkIcdSurfaceBase *icd_surface,
|
||||
case WL_DRM_FORMAT_XRGB8888:
|
||||
modifiers = &chain->display->dmabuf.modifiers.xrgb8888;
|
||||
break;
|
||||
+ case WL_DRM_FORMAT_RGB565:
|
||||
+ modifiers = &chain->display->dmabuf.modifiers.rgb565;
|
||||
+ break;
|
||||
default:
|
||||
modifiers = NULL;
|
||||
break;
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
From c2b91fcb7c88bfec23077ae31c0035684249ea1b Mon Sep 17 00:00:00 2001
|
||||
From: brendan King <Brendan.King@imgtec.com>
|
||||
Date: Tue, 3 Aug 2021 15:44:57 +0100
|
||||
Subject: [PATCH 63/67] vulkan/wsi: enable additional formats for Display
|
||||
|
||||
Add VK_FORMAT_R5G6B5_UNORM_PACK16.
|
||||
|
||||
This is for compatibility with IMG WSI.
|
||||
---
|
||||
src/vulkan/wsi/wsi_common_display.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/src/vulkan/wsi/wsi_common_display.c b/src/vulkan/wsi/wsi_common_display.c
|
||||
index f135b4e38de..298c78809c3 100644
|
||||
--- a/src/vulkan/wsi/wsi_common_display.c
|
||||
+++ b/src/vulkan/wsi/wsi_common_display.c
|
||||
@@ -900,6 +900,7 @@ static const struct {
|
||||
} available_surface_formats[] = {
|
||||
{ .format = VK_FORMAT_B8G8R8A8_SRGB, .drm_format = DRM_FORMAT_XRGB8888 },
|
||||
{ .format = VK_FORMAT_B8G8R8A8_UNORM, .drm_format = DRM_FORMAT_XRGB8888 },
|
||||
+ { .format = VK_FORMAT_R5G6B5_UNORM_PACK16, .drm_format = DRM_FORMAT_RGB565 },
|
||||
};
|
||||
|
||||
static void
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,183 @@
|
||||
From 85762f3538a21a99bf1b71d87345ebe51f9de453 Mon Sep 17 00:00:00 2001
|
||||
From: Luigi Santivetti <luigi.santivetti@imgtec.com>
|
||||
Date: Thu, 12 Aug 2021 00:55:46 +0100
|
||||
Subject: [PATCH 64/67] mesa/main: dri: add YUV420_3PLANE and YVU420_3PLANE
|
||||
|
||||
---
|
||||
include/GL/internal/dri_interface.h | 2 ++
|
||||
src/gallium/include/pipe/p_format.h | 3 +++
|
||||
src/mesa/drivers/dri/common/utils.c | 18 ++++++++++++++++++
|
||||
src/mesa/drivers/dri/pvr/dri_support.h | 2 ++
|
||||
src/mesa/drivers/dri/pvr/pvrutil.c | 13 +++++++++++++
|
||||
src/mesa/main/format_info.py | 2 +-
|
||||
src/mesa/main/formats.c | 2 ++
|
||||
src/mesa/main/formats.csv | 2 ++
|
||||
src/mesa/main/formats.h | 6 ++++++
|
||||
9 files changed, 49 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h
|
||||
index 080d191b0a3..7d9a1bd9ba6 100644
|
||||
--- a/include/GL/internal/dri_interface.h
|
||||
+++ b/include/GL/internal/dri_interface.h
|
||||
@@ -1424,6 +1424,8 @@ struct __DRIdri2ExtensionRec {
|
||||
#define __DRI_IMAGE_FORMAT_BGR888 0x101a
|
||||
#define __DRI_IMAGE_FORMAT_NV12 0x101b
|
||||
#define __DRI_IMAGE_FORMAT_NV21 0x101c
|
||||
+#define __DRI_IMAGE_FORMAT_YU12 0x101d
|
||||
+#define __DRI_IMAGE_FORMAT_YV12 0x101e
|
||||
|
||||
#define __DRI_IMAGE_USE_SHARE 0x0001
|
||||
#define __DRI_IMAGE_USE_SCANOUT 0x0002
|
||||
diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h
|
||||
index fd653379b7a..970f07598d5 100644
|
||||
--- a/src/gallium/include/pipe/p_format.h
|
||||
+++ b/src/gallium/include/pipe/p_format.h
|
||||
@@ -516,6 +516,9 @@ enum pipe_format {
|
||||
PIPE_FORMAT_YUV420_2PLANE,
|
||||
PIPE_FORMAT_YVU420_2PLANE,
|
||||
|
||||
+ PIPE_FORMAT_YUV420_3PLANE,
|
||||
+ PIPE_FORMAT_YVU420_3PLANE,
|
||||
+
|
||||
PIPE_FORMAT_COUNT
|
||||
};
|
||||
|
||||
diff --git a/src/mesa/drivers/dri/common/utils.c b/src/mesa/drivers/dri/common/utils.c
|
||||
index d268dc41fbb..df5f8cbfdc0 100644
|
||||
--- a/src/mesa/drivers/dri/common/utils.c
|
||||
+++ b/src/mesa/drivers/dri/common/utils.c
|
||||
@@ -330,6 +330,24 @@ driCreateConfigs(mesa_format format,
|
||||
yuv_subsample = __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_0_BIT;
|
||||
yuv_plane_bpp = __DRI_ATTRIB_YUV_PLANE_BPP_8_BIT;
|
||||
break;
|
||||
+ case MESA_FORMAT_YUV420_3PLANE:
|
||||
+ 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 = 3;
|
||||
+ 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_3PLANE:
|
||||
+ 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 = 3;
|
||||
+ 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__,
|
||||
diff --git a/src/mesa/drivers/dri/pvr/dri_support.h b/src/mesa/drivers/dri/pvr/dri_support.h
|
||||
index ab0b9dd9a23..a4999dc36bf 100644
|
||||
--- a/src/mesa/drivers/dri/pvr/dri_support.h
|
||||
+++ b/src/mesa/drivers/dri/pvr/dri_support.h
|
||||
@@ -189,6 +189,8 @@ typedef enum
|
||||
#define PVRDRI_MESA_FORMAT_YVU420_2PLANE 8
|
||||
#define PVRDRI_MESA_FORMAT_B8G8R8A8_SRGB 9
|
||||
#define PVRDRI_MESA_FORMAT_R8G8B8A8_SRGB 10
|
||||
+#define PVRDRI_MESA_FORMAT_YUV420_3PLANE 11
|
||||
+#define PVRDRI_MESA_FORMAT_YVU420_3PLANE 12
|
||||
|
||||
/* The blit flags match their DRI counterparts */
|
||||
#define PVRDRI_BLIT_FLAG_FLUSH 0x0001
|
||||
diff --git a/src/mesa/drivers/dri/pvr/pvrutil.c b/src/mesa/drivers/dri/pvr/pvrutil.c
|
||||
index d107a5dafad..ee11ac55914 100644
|
||||
--- a/src/mesa/drivers/dri/pvr/pvrutil.c
|
||||
+++ b/src/mesa/drivers/dri/pvr/pvrutil.c
|
||||
@@ -118,6 +118,10 @@ PVRDRIMesaFormatToMesaFormat(int pvrdri_mesa_format)
|
||||
return MESA_FORMAT_B8G8R8A8_SRGB;
|
||||
case PVRDRI_MESA_FORMAT_R8G8B8A8_SRGB:
|
||||
return MESA_FORMAT_R8G8B8A8_SRGB;
|
||||
+ case PVRDRI_MESA_FORMAT_YUV420_3PLANE:
|
||||
+ return MESA_FORMAT_YUV420_3PLANE;
|
||||
+ case PVRDRI_MESA_FORMAT_YVU420_3PLANE:
|
||||
+ return MESA_FORMAT_YVU420_3PLANE;
|
||||
default:
|
||||
__driUtilMessage("%s: Unknown format: %d", __func__, pvrdri_mesa_format);
|
||||
break;
|
||||
@@ -178,6 +182,11 @@ PVRDRIFormatToFourCC(int dri_format)
|
||||
return DRM_FORMAT_NV12;
|
||||
case __DRI_IMAGE_FORMAT_NV21:
|
||||
return DRM_FORMAT_NV21;
|
||||
+ case __DRI_IMAGE_FORMAT_YU12:
|
||||
+ return DRM_FORMAT_YUV420;
|
||||
+ case __DRI_IMAGE_FORMAT_YV12:
|
||||
+ return DRM_FORMAT_YVU420;
|
||||
+
|
||||
default:
|
||||
__driUtilMessage("%s: Unknown format: %d", __func__, dri_format);
|
||||
break;
|
||||
@@ -238,6 +247,10 @@ PVRDRIFourCCToDRIFormat(int iFourCC)
|
||||
return __DRI_IMAGE_FORMAT_NV12;
|
||||
case DRM_FORMAT_NV21:
|
||||
return __DRI_IMAGE_FORMAT_NV21;
|
||||
+ case DRM_FORMAT_YUV420:
|
||||
+ return __DRI_IMAGE_FORMAT_YU12;
|
||||
+ case DRM_FORMAT_YVU420:
|
||||
+ return __DRI_IMAGE_FORMAT_YV12;
|
||||
default:
|
||||
__driUtilMessage("%s: Unknown format: %d", __func__, iFourCC);
|
||||
break;
|
||||
diff --git a/src/mesa/main/format_info.py b/src/mesa/main/format_info.py
|
||||
index d58403ea85e..bc18db74f17 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', 'MESA_FORMAT_YUV420_2PLANE', 'MESA_FORMAT_YVU420_2PLANE']:
|
||||
+ elif fmat.name in ['MESA_FORMAT_YCBCR', 'MESA_FORMAT_YCBCR_REV', 'MESA_FORMAT_YUV420_2PLANE', 'MESA_FORMAT_YVU420_2PLANE', 'MESA_FORMAT_YUV420_3PLANE', 'MESA_FORMAT_YVU420_3PLANE']:
|
||||
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 f81caeceff4..d7b0d0a07c9 100644
|
||||
--- a/src/mesa/main/formats.c
|
||||
+++ b/src/mesa/main/formats.c
|
||||
@@ -1455,6 +1455,8 @@ _mesa_format_matches_format_and_type(mesa_format mformat,
|
||||
switch (mformat) {
|
||||
case MESA_FORMAT_YUV420_2PLANE:
|
||||
case MESA_FORMAT_YVU420_2PLANE:
|
||||
+ case MESA_FORMAT_YUV420_3PLANE:
|
||||
+ case MESA_FORMAT_YVU420_3PLANE:
|
||||
return false;
|
||||
|
||||
default:
|
||||
diff --git a/src/mesa/main/formats.csv b/src/mesa/main/formats.csv
|
||||
index b2d476577e0..825443b10ce 100644
|
||||
--- a/src/mesa/main/formats.csv
|
||||
+++ b/src/mesa/main/formats.csv
|
||||
@@ -94,6 +94,8 @@ MESA_FORMAT_YCBCR , other , 1, 1, 1, x16 , , ,
|
||||
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
|
||||
+MESA_FORMAT_YUV420_3PLANE , other , 1, 1, 1, x8 , , , , y___, yuv
|
||||
+MESA_FORMAT_YVU420_3PLANE , other , 1, 1, 1, x8 , , , , y___, yuv
|
||||
|
||||
MESA_FORMAT_RG_RB_UNORM8 , other , 2, 1, 1, x16 , , , , xyz1, rgb
|
||||
MESA_FORMAT_GR_BR_UNORM8 , other , 2, 1, 1, x16 , , , , xyz1, rgb
|
||||
diff --git a/src/mesa/main/formats.h b/src/mesa/main/formats.h
|
||||
index 0e778d64467..1ab03d2be7e 100644
|
||||
--- a/src/mesa/main/formats.h
|
||||
+++ b/src/mesa/main/formats.h
|
||||
@@ -624,6 +624,12 @@ typedef enum pipe_format mesa_format;
|
||||
#define HAVE_MESA_FORMAT_YVU420_2PLANE
|
||||
#define MESA_FORMAT_YVU420_2PLANE PIPE_FORMAT_YVU420_2PLANE
|
||||
|
||||
+#define HAVE_MESA_FORMAT_YUV420_3PLANE
|
||||
+#define MESA_FORMAT_YUV420_3PLANE PIPE_FORMAT_YUV420_3PLANE
|
||||
+
|
||||
+#define HAVE_MESA_FORMAT_YVU420_3PLANE
|
||||
+#define MESA_FORMAT_YVU420_3PLANE PIPE_FORMAT_YVU420_3PLANE
|
||||
+
|
||||
#define MESA_FORMAT_COUNT PIPE_FORMAT_COUNT
|
||||
|
||||
/* Packed to array format adapters */
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
From 89f34a04c15c8657cb77bbbc94fb9b9d0ac76980 Mon Sep 17 00:00:00 2001
|
||||
From: Luigi Santivetti <luigi.santivetti@imgtec.com>
|
||||
Date: Mon, 23 Aug 2021 09:18:37 +0100
|
||||
Subject: [PATCH 65/67] egl/null: add support for YU12 and YV12
|
||||
|
||||
---
|
||||
src/egl/drivers/dri2/platform_null.c | 28 ++++++++++++++++++++++++++++
|
||||
1 file changed, 28 insertions(+)
|
||||
|
||||
diff --git a/src/egl/drivers/dri2/platform_null.c b/src/egl/drivers/dri2/platform_null.c
|
||||
index 529cc7a2a2f..2e86d6533de 100644
|
||||
--- a/src/egl/drivers/dri2/platform_null.c
|
||||
+++ b/src/egl/drivers/dri2/platform_null.c
|
||||
@@ -106,6 +106,20 @@ static const struct dri2_null_yuv_attrib {
|
||||
.num_planes = 2,
|
||||
.plane_bpp = __DRI_ATTRIB_YUV_PLANE_BPP_8_BIT,
|
||||
},
|
||||
+ {
|
||||
+ /* __DRI_IMAGE_FORMAT_YU12 */
|
||||
+ .order = __DRI_ATTRIB_YUV_ORDER_YUV_BIT,
|
||||
+ .subsample = __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_0_BIT,
|
||||
+ .num_planes = 3,
|
||||
+ .plane_bpp = __DRI_ATTRIB_YUV_PLANE_BPP_8_BIT,
|
||||
+ },
|
||||
+ {
|
||||
+ /* __DRI_IMAGE_FORMAT_YV12 */
|
||||
+ .order = __DRI_ATTRIB_YUV_ORDER_YVU_BIT,
|
||||
+ .subsample = __DRI_ATTRIB_YUV_SUBSAMPLE_4_2_0_BIT,
|
||||
+ .num_planes = 3,
|
||||
+ .plane_bpp = __DRI_ATTRIB_YUV_PLANE_BPP_8_BIT,
|
||||
+ },
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -161,6 +175,20 @@ static const struct dri2_null_format {
|
||||
.rgba_sizes = { 0, 0, 0, 0 },
|
||||
.yuv = &dri2_null_yuv_attribs[2],
|
||||
},
|
||||
+ {
|
||||
+ .drm_format = DRM_FORMAT_YUV420,
|
||||
+ .dri_image_format = __DRI_IMAGE_FORMAT_YU12,
|
||||
+ .rgba_shifts = { -1, -1, -1, -1 },
|
||||
+ .rgba_sizes = { 0, 0, 0, 0 },
|
||||
+ .yuv = &dri2_null_yuv_attribs[3],
|
||||
+ },
|
||||
+ {
|
||||
+ .drm_format = DRM_FORMAT_YVU420,
|
||||
+ .dri_image_format = __DRI_IMAGE_FORMAT_YV12,
|
||||
+ .rgba_shifts = { -1, -1, -1, -1 },
|
||||
+ .rgba_sizes = { 0, 0, 0, 0 },
|
||||
+ .yuv = &dri2_null_yuv_attribs[4],
|
||||
+ },
|
||||
};
|
||||
|
||||
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
From 28e4349702566ba34dad4c214c64bfd702177c8a Mon Sep 17 00:00:00 2001
|
||||
From: brendan King <Brendan.King@imgtec.com>
|
||||
Date: Thu, 16 Sep 2021 17:46:28 +0100
|
||||
Subject: [PATCH 66/67] mesa: partially revert pbuffer attribute removal
|
||||
|
||||
This partially reverts commit 5ffd1ebe6b3c8c7dd316dd47fac088044222e6ef
|
||||
("mesa: Remove misc pbuffer attributes from struct gl_config").
|
||||
|
||||
The IMG PowerVR driver sets meaningful values for the maximum
|
||||
pbuffer width, height and pixels.
|
||||
---
|
||||
src/mesa/drivers/dri/common/utils.c | 7 ++++---
|
||||
src/mesa/main/mtypes.h | 5 +++++
|
||||
2 files changed, 9 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/src/mesa/drivers/dri/common/utils.c b/src/mesa/drivers/dri/common/utils.c
|
||||
index df5f8cbfdc0..28debe4e013 100644
|
||||
--- a/src/mesa/drivers/dri/common/utils.c
|
||||
+++ b/src/mesa/drivers/dri/common/utils.c
|
||||
@@ -480,6 +480,7 @@ __DRIconfig **driConcatConfigs(__DRIconfig **a,
|
||||
return all;
|
||||
}
|
||||
|
||||
+/* careful, lack of trailing semicolon */
|
||||
#define __ATTRIB(attrib, field) case attrib: *value = config->modes.field; break
|
||||
|
||||
/**
|
||||
@@ -555,9 +556,9 @@ driGetConfigAttribIndex(const __DRIconfig *config,
|
||||
__ATTRIB(__DRI_ATTRIB_GREEN_MASK, greenMask);
|
||||
__ATTRIB(__DRI_ATTRIB_BLUE_MASK, blueMask);
|
||||
__ATTRIB(__DRI_ATTRIB_ALPHA_MASK, alphaMask);
|
||||
- case __DRI_ATTRIB_MAX_PBUFFER_WIDTH:
|
||||
- case __DRI_ATTRIB_MAX_PBUFFER_HEIGHT:
|
||||
- case __DRI_ATTRIB_MAX_PBUFFER_PIXELS:
|
||||
+ __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_WIDTH, maxPbufferWidth);
|
||||
+ __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_HEIGHT, maxPbufferHeight);
|
||||
+ __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_PIXELS, maxPbufferPixels);
|
||||
case __DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH:
|
||||
case __DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT:
|
||||
case __DRI_ATTRIB_VISUAL_SELECT_GROUP:
|
||||
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
|
||||
index 8f77d4c58dd..e37c61d23d0 100644
|
||||
--- a/src/mesa/main/mtypes.h
|
||||
+++ b/src/mesa/main/mtypes.h
|
||||
@@ -175,6 +175,11 @@ struct gl_config
|
||||
/* ARB_multisample / SGIS_multisample */
|
||||
GLuint samples;
|
||||
|
||||
+ /* GLX 1.3 */
|
||||
+ GLint maxPbufferWidth;
|
||||
+ GLint maxPbufferHeight;
|
||||
+ GLint maxPbufferPixels;
|
||||
+
|
||||
/* OML_swap_method */
|
||||
GLint swapMethod;
|
||||
|
||||
--
|
||||
2.25.1
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
From 9bb8868ebab2d041c24c76487b6419a8039a5ce7 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 67/67] 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 56b5175db6e..1b10c2e7362 100644
|
||||
--- a/src/egl/drivers/dri2/egl_dri2.c
|
||||
+++ b/src/egl/drivers/dri2/egl_dri2.c
|
||||
@@ -407,6 +407,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 };
|
||||
@@ -530,11 +531,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;
|
||||
@@ -614,6 +621,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.25.1
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
From f9c028d508bac22d7c78b0232c625e27d13340a7 Mon Sep 17 00:00:00 2001
|
||||
From: Brendan King <Brendan.King@imgtec.com>
|
||||
Date: Thu, 11 Nov 2021 12:09:38 +0000
|
||||
Subject: [PATCH 68/68] GL_ARB_geometry_shader4 entry points.
|
||||
|
||||
---
|
||||
src/mapi/glapi/gen/ARB_geometry_shader4.xml | 97 +++++++++++++++++++++
|
||||
src/mapi/glapi/gen/gl_API.xml | 2 +-
|
||||
src/mapi/glapi/gen/static_data.py | 4 +
|
||||
3 files changed, 102 insertions(+), 1 deletion(-)
|
||||
create mode 100644 src/mapi/glapi/gen/ARB_geometry_shader4.xml
|
||||
|
||||
diff --git a/src/mapi/glapi/gen/ARB_geometry_shader4.xml b/src/mapi/glapi/gen/ARB_geometry_shader4.xml
|
||||
new file mode 100644
|
||||
index 00000000000..d92dc577b17
|
||||
--- /dev/null
|
||||
+++ b/src/mapi/glapi/gen/ARB_geometry_shader4.xml
|
||||
@@ -0,0 +1,97 @@
|
||||
+<?xml version="1.0"?>
|
||||
+<!DOCTYPE OpenGLAPI SYSTEM "gl_API.dtd">
|
||||
+
|
||||
+<!-- Note: no GLX protocol info yet. -->
|
||||
+
|
||||
+
|
||||
+<OpenGLAPI>
|
||||
+<category name="GL_ARB_geometry_shader4" number="47">
|
||||
+ <enum name="GEOMETRY_SHADER_ARB" value="0x8DD9"/>
|
||||
+ <enum name="GEOMETRY_VERTICES_OUT_ARB" value="0x8DDA"/>
|
||||
+ <enum name="GEOMETRY_INPUT_TYPE_ARB" value="0x8DDB"/>
|
||||
+ <enum name="GEOMETRY_OUTPUT_TYPE_ARB" value="0x8DDC"/>
|
||||
+
|
||||
+ <enum name="MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB"
|
||||
+ count="1" value="0x8C29">
|
||||
+ <size name="Get" mode="get"/>
|
||||
+ </enum>
|
||||
+ <enum name="MAX_GEOMETRY_VARYING_COMPONENTS_ARB"
|
||||
+ count="1" value="0x8DDD">
|
||||
+ <size name="Get" mode="get"/>
|
||||
+ </enum>
|
||||
+ <enum name="MAX_VERTEX_VARYING_COMPONENTS_ARB"
|
||||
+ count="1" value="0x8DDE">
|
||||
+ <size name="Get" mode="get"/>
|
||||
+ </enum>
|
||||
+ <enum name="MAX_VARYING_COMPONENTS"
|
||||
+ count="1" value="0x8B4B">
|
||||
+ <size name="Get" mode="get"/>
|
||||
+ </enum>
|
||||
+ <enum name="MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB"
|
||||
+ count="1" value="0x8DDF">
|
||||
+ <size name="Get" mode="get"/>
|
||||
+ </enum>
|
||||
+ <enum name="MAX_GEOMETRY_OUTPUT_VERTICES_ARB"
|
||||
+ count="1" value="0x8DE0">
|
||||
+ <size name="Get" mode="get"/>
|
||||
+ </enum>
|
||||
+ <enum name="MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB"
|
||||
+ count="1" value="0x8DE1">
|
||||
+ <size name="Get" mode="get"/>
|
||||
+ </enum>
|
||||
+
|
||||
+ <enum name="LINES_ADJACENCY_ARB" value="0xA"/>
|
||||
+ <enum name="LINE_STRIP_ADJACENCY_ARB" value="0xB"/>
|
||||
+ <enum name="TRIANGLES_ADJACENCY_ARB" value="0xC"/>
|
||||
+ <enum name="TRIANGLE_STRIP_ADJACENCY_ARB" value="0xD"/>
|
||||
+
|
||||
+ <enum name="FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB" value="0x8DA8"/>
|
||||
+ <enum name="FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB" value="0x8DA9"/>
|
||||
+
|
||||
+
|
||||
+ <enum name="FRAMEBUFFER_ATTACHMENT_LAYERED_ARB"
|
||||
+ count="1" value="0x8DA7">
|
||||
+ <size name="GetFramebufferAttachmentParameteriv" mode="get"/>
|
||||
+ </enum>
|
||||
+ <enum name="FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER"
|
||||
+ count="1" value="0x8CD4">
|
||||
+ <size name="GetFramebufferAttachmentParameteriv" mode="get"/>
|
||||
+ </enum>
|
||||
+
|
||||
+ <enum name="PROGRAM_POINT_SIZE_ARB" value="0x8642"/>
|
||||
+ <enum name="PROGRAM_POINT_SIZE_ARB"
|
||||
+ count="1" value="0x8642">
|
||||
+ <size name="Get" mode="get"/>
|
||||
+ </enum>
|
||||
+
|
||||
+ <function name="ProgramParameteriARB" exec="dynamic">
|
||||
+ <param name="program" type="GLuint"/>
|
||||
+ <param name="pname" type="GLenum"/>
|
||||
+ <param name="value" type="GLint"/>
|
||||
+ </function>
|
||||
+
|
||||
+ <function name="FramebufferTextureARB" exec="dynamic">
|
||||
+ <param name="target" type="GLenum"/>
|
||||
+ <param name="attachment" type="GLenum"/>
|
||||
+ <param name="texture" type="GLuint"/>
|
||||
+ <param name="level" type="GLint"/>
|
||||
+ </function>
|
||||
+
|
||||
+ <function name="FramebufferTextureLayerARB" 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"/>
|
||||
+ </function>
|
||||
+
|
||||
+ <function name="FramebufferTextureFaceARB" exec="dynamic">
|
||||
+ <param name="target" type="GLenum"/>
|
||||
+ <param name="attachment" type="GLenum"/>
|
||||
+ <param name="texture" type="GLuint"/>
|
||||
+ <param name="level" type="GLint"/>
|
||||
+ <param name="face" type="GLenum"/>
|
||||
+ </function>
|
||||
+</category>
|
||||
+
|
||||
+</OpenGLAPI>
|
||||
diff --git a/src/mapi/glapi/gen/gl_API.xml b/src/mapi/glapi/gen/gl_API.xml
|
||||
index 4e35de0f4ea..d5a5e7f5386 100644
|
||||
--- a/src/mapi/glapi/gen/gl_API.xml
|
||||
+++ b/src/mapi/glapi/gen/gl_API.xml
|
||||
@@ -8064,7 +8064,7 @@
|
||||
|
||||
<!-- 46. GL_ARB_framebuffer_sRGB -->
|
||||
|
||||
-<!-- 47. GL_ARB_geometry_shader4. There are no intentions to implement this extension -->
|
||||
+<xi:include href="ARB_geometry_shader4.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
|
||||
|
||||
<!-- 48. GL_ARB_half_float_vertex -->
|
||||
|
||||
diff --git a/src/mapi/glapi/gen/static_data.py b/src/mapi/glapi/gen/static_data.py
|
||||
index 974f366d7b4..833ad73dd6a 100644
|
||||
--- a/src/mapi/glapi/gen/static_data.py
|
||||
+++ b/src/mapi/glapi/gen/static_data.py
|
||||
@@ -1721,6 +1721,10 @@ offsets = {
|
||||
"FramebufferRenderbufferEXT" : 1685,
|
||||
"GetFramebufferAttachmentParameterivEXT" : 1686,
|
||||
"GenerateMipmapEXT" : 1687,
|
||||
+ "ProgramParameteriARB" : 1688,
|
||||
+ "FramebufferTextureARB" : 1689,
|
||||
+ "FramebufferTextureLayerARB" : 1690,
|
||||
+ "FramebufferTextureFaceARB" : 1691,
|
||||
}
|
||||
|
||||
functions = [
|
||||
--
|
||||
2.25.1
|
||||
|
||||
Reference in New Issue
Block a user