Compare commits
6 Commits
| Author | SHA256 | Date | |
|---|---|---|---|
| c007c6da60 | |||
| 7a02ac3468 | |||
| 8d634d07fe | |||
| 7f06ec8a09 | |||
| 1ddf0497ef | |||
| d6cf8f4121 |
211
0001-Fix-attribute-handling-for-eglCreateWindow-PixmapSur.patch
Normal file
211
0001-Fix-attribute-handling-for-eglCreateWindow-PixmapSur.patch
Normal file
@@ -0,0 +1,211 @@
|
||||
From e511d6586e261b54d4443e073c30615ea520b21b Mon Sep 17 00:00:00 2001
|
||||
From: Kyle Brenneman <kbrenneman@nvidia.com>
|
||||
Date: Mon, 1 Dec 2025 12:05:41 -0700
|
||||
Subject: [PATCH 1/4] Fix attribute handling for eglCreateWindow/PixmapSurface
|
||||
|
||||
Fix eplX11CreateWindowSurface and eplX11CreatePixmapSurface so that they
|
||||
pass the attribute list from the application to
|
||||
eplX11GetInternalSurfaceAttribs.
|
||||
|
||||
Currently, they pass NULL, and ignore the application's attributes.
|
||||
|
||||
Also, update eplX11GetInternalSurfaceAttribs so that it'll check the
|
||||
EGL_RENDER_BUFFER attribute, without passing it to the driver. The
|
||||
driver doesn't accept EGL_RENDER_BUFFER for platform surfaces, since
|
||||
that's determined instead by whether we pass a GL_BACK attachment to
|
||||
eglPlatformCreateSurfaceNVX.
|
||||
|
||||
egl-x11 doesn't currently support single-buffered windows, so it'll
|
||||
issue a warning if the application requests EGL_SINGLE_BUFFER but
|
||||
otherwise ignore it.
|
||||
---
|
||||
src/x11/x11-pixmap.c | 5 ++-
|
||||
src/x11/x11-platform.c | 83 ++++++++++++++++++++++++++++++++++--------
|
||||
src/x11/x11-platform.h | 5 ++-
|
||||
src/x11/x11-window.c | 9 ++++-
|
||||
4 files changed, 80 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/src/x11/x11-pixmap.c b/src/x11/x11-pixmap.c
|
||||
index 0a8cb1c..e2d7dc4 100644
|
||||
--- a/src/x11/x11-pixmap.c
|
||||
+++ b/src/x11/x11-pixmap.c
|
||||
@@ -370,6 +370,7 @@ static void PixmapDamageCallback(void *param, int syncfd, unsigned int flags)
|
||||
void eplX11DestroyPixmap(EplSurface *surf)
|
||||
{
|
||||
X11Pixmap *ppix = (X11Pixmap *) surf->priv;
|
||||
+
|
||||
surf->priv = NULL;
|
||||
if (ppix != NULL)
|
||||
{
|
||||
@@ -468,10 +469,10 @@ EGLSurface eplX11CreatePixmapSurface(EplPlatformData *plat, EplDisplay *pdpy, Ep
|
||||
fmt = eplFormatInfoLookup(configInfo->fourcc);
|
||||
assert(fmt != NULL);
|
||||
|
||||
- internalAttribs = eplX11GetInternalSurfaceAttribs(plat, pdpy, internalAttribs);
|
||||
+ internalAttribs = eplX11GetInternalSurfaceAttribs(plat, pdpy, EPL_SURFACE_TYPE_PIXMAP, attribs);
|
||||
if (internalAttribs == NULL)
|
||||
{
|
||||
- goto done;
|
||||
+ return EGL_NO_SURFACE;
|
||||
}
|
||||
|
||||
geomCookie = xcb_get_geometry(inst->conn, xpix);
|
||||
diff --git a/src/x11/x11-platform.c b/src/x11/x11-platform.c
|
||||
index 13e67a1..9be220e 100644
|
||||
--- a/src/x11/x11-platform.c
|
||||
+++ b/src/x11/x11-platform.c
|
||||
@@ -1311,34 +1311,85 @@ static EGLBoolean eplX11WaitGL(EplDisplay *pdpy, EplSurface *psurf)
|
||||
return ret;
|
||||
}
|
||||
|
||||
-EGLAttrib *eplX11GetInternalSurfaceAttribs(EplPlatformData *plat, EplDisplay *pdpy, const EGLAttrib *attribs)
|
||||
+EGLAttrib *eplX11GetInternalSurfaceAttribs(EplPlatformData *plat,
|
||||
+ EplDisplay *pdpy, EplSurfaceType surface_type, const EGLAttrib *attribs)
|
||||
{
|
||||
EGLAttrib *internalAttribs = NULL;
|
||||
- int count = 0;
|
||||
+ int count = eplCountAttribs(attribs);
|
||||
+
|
||||
+ // Allocate extra space so that we can add EGL_SURFACE_Y_INVERTED_NVX below.
|
||||
+ internalAttribs = malloc((count + 3) * sizeof(EGLAttrib));
|
||||
+ if (internalAttribs == NULL)
|
||||
+ {
|
||||
+ eplSetError(plat, EGL_BAD_ALLOC, "Out of memory\n");
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ count = 0;
|
||||
+ internalAttribs[count++] = EGL_SURFACE_Y_INVERTED_NVX;
|
||||
+ internalAttribs[count++] = EGL_TRUE;
|
||||
|
||||
if (attribs != NULL)
|
||||
{
|
||||
- for (count = 0; attribs[count] != EGL_NONE; count += 2)
|
||||
+ int i;
|
||||
+ for (i=0; attribs[i] != EGL_NONE; i += 2)
|
||||
{
|
||||
- if (attribs[count] == EGL_SURFACE_Y_INVERTED_NVX)
|
||||
+ if (attribs[i] == EGL_SURFACE_Y_INVERTED_NVX)
|
||||
{
|
||||
- eplSetError(plat, EGL_BAD_ATTRIBUTE, "Invalid attribute 0x%04x\n", attribs[count]);
|
||||
+ eplSetError(plat, EGL_BAD_ATTRIBUTE, "Invalid attribute 0x%04x\n", attribs[i]);
|
||||
+ free(internalAttribs);
|
||||
return NULL;
|
||||
}
|
||||
+ else if (attribs[i] == EGL_RENDER_BUFFER)
|
||||
+ {
|
||||
+ /*
|
||||
+ * eglPlatformCreateSurfaceNVX doesn't accept the
|
||||
+ * EGL_RENDER_BUFFER attribute, since it's the platform library
|
||||
+ * that allocates and specifies the front and back buffers, not
|
||||
+ * the driver.
|
||||
+ */
|
||||
+ if (surface_type != EPL_SURFACE_TYPE_WINDOW)
|
||||
+ {
|
||||
+ /*
|
||||
+ * The EGL_RENDER_BUFFER is not valid for pixmaps, since
|
||||
+ * they're always single-buffered.
|
||||
+ */
|
||||
+ eplSetError(plat, EGL_BAD_ATTRIBUTE, "EGL_RENDER_BUFFER is not valid for pixmaps");
|
||||
+ free(internalAttribs);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ else if (attribs[i + 1] == EGL_SINGLE_BUFFER)
|
||||
+ {
|
||||
+ /*
|
||||
+ * We don't currently support single-buffered rendering for
|
||||
+ * a window, but this attribute is only a hint, so it's not
|
||||
+ * an error to request it.
|
||||
+ *
|
||||
+ * If we do implement EGL_SINGLE_BUFFER for windows in the
|
||||
+ * future, then we'd do that by passing only a GL_FRONT
|
||||
+ * buffer to eglPlatformCreateSurfaceNVX, like we do for
|
||||
+ * pixmaps.
|
||||
+ */
|
||||
+ plat->callbacks.debugMessage(EGL_DEBUG_MSG_WARN_KHR,
|
||||
+ "EGL_SINGLE_BUFFER requested, but single-buffered rendering is not supported");
|
||||
+ }
|
||||
+ else if (attribs[i + 1] != EGL_BACK_BUFFER)
|
||||
+ {
|
||||
+ eplSetError(plat, EGL_BAD_ATTRIBUTE,
|
||||
+ "Invalid EGL_RENDER_BUFFER value 0x%04x", attribs[i + 1]);
|
||||
+ free(internalAttribs);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ internalAttribs[count++] = attribs[i];
|
||||
+ internalAttribs[count++] = attribs[i + 1];
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
- internalAttribs = malloc((count + 3) * sizeof(EGLAttrib));
|
||||
- if (internalAttribs == NULL)
|
||||
- {
|
||||
- eplSetError(plat, EGL_BAD_ALLOC, "Out of memory\n");
|
||||
- return NULL;
|
||||
- }
|
||||
-
|
||||
- memcpy(internalAttribs, attribs, count * sizeof(EGLAttrib));
|
||||
- internalAttribs[count] = EGL_SURFACE_Y_INVERTED_NVX;
|
||||
- internalAttribs[count + 1] = EGL_TRUE;
|
||||
- internalAttribs[count + 2] = EGL_NONE;
|
||||
+ internalAttribs[count] = EGL_NONE;
|
||||
return internalAttribs;
|
||||
}
|
||||
|
||||
diff --git a/src/x11/x11-platform.h b/src/x11/x11-platform.h
|
||||
index ebd8b8a..c90f67d 100644
|
||||
--- a/src/x11/x11-platform.h
|
||||
+++ b/src/x11/x11-platform.h
|
||||
@@ -429,13 +429,14 @@ EGLBoolean eplX11InitConfigList(EplPlatformData *plat, X11DisplayInstance *inst)
|
||||
*
|
||||
* \param plat The platform data
|
||||
* \param pdpy The display data
|
||||
+ * \param surface_type The type of surface that the attributes are for.
|
||||
* \param attribs The attribute list that was passed to eglCreateWindowSurface
|
||||
* or eglCreatePixmapSurface.
|
||||
* \return The EGLAttrib array to pass to the driver, or NULL on error. The
|
||||
* caller must free the array using free().
|
||||
*/
|
||||
-
|
||||
-EGLAttrib *eplX11GetInternalSurfaceAttribs(EplPlatformData *plat, EplDisplay *pdpy, const EGLAttrib *attribs);
|
||||
+EGLAttrib *eplX11GetInternalSurfaceAttribs(EplPlatformData *plat,
|
||||
+ EplDisplay *pdpy, EplSurfaceType surface_type, const EGLAttrib *attribs);
|
||||
|
||||
EGLBoolean eplX11HookChooseConfig(EGLDisplay edpy, EGLint const *attribs,
|
||||
EGLConfig *configs, EGLint configSize, EGLint *numConfig);
|
||||
diff --git a/src/x11/x11-window.c b/src/x11/x11-window.c
|
||||
index 2376b61..040d7bf 100644
|
||||
--- a/src/x11/x11-window.c
|
||||
+++ b/src/x11/x11-window.c
|
||||
@@ -732,6 +732,11 @@ void eplX11FreeWindow(EplSurface *surf)
|
||||
{
|
||||
X11Window *pwin = (X11Window *) surf->priv;
|
||||
|
||||
+ if (pwin == NULL)
|
||||
+ {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
FreeWindowBuffers(surf);
|
||||
|
||||
if (pwin->inst->conn != NULL && pwin->present_event != NULL)
|
||||
@@ -1308,10 +1313,10 @@ EGLSurface eplX11CreateWindowSurface(EplPlatformData *plat, EplDisplay *pdpy, Ep
|
||||
return EGL_NO_SURFACE;
|
||||
}
|
||||
|
||||
- internalAttribs = eplX11GetInternalSurfaceAttribs(plat, pdpy, internalAttribs);
|
||||
+ internalAttribs = eplX11GetInternalSurfaceAttribs(plat, pdpy, EPL_SURFACE_TYPE_WINDOW, attribs);
|
||||
if (internalAttribs == NULL)
|
||||
{
|
||||
- goto done;
|
||||
+ return EGL_NO_SURFACE;
|
||||
}
|
||||
|
||||
fmt = eplX11FindDriverFormat(inst, configInfo->fourcc);
|
||||
--
|
||||
2.51.0
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
From 741bb123f2577efc8ca56f836c90a6b3b9fd074b Mon Sep 17 00:00:00 2001
|
||||
From: Kyle Brenneman <kbrenneman@nvidia.com>
|
||||
Date: Fri, 18 Apr 2025 09:34:14 -0600
|
||||
Subject: [PATCH 1/3] Increment version number to 1.0.2.
|
||||
|
||||
---
|
||||
meson.build | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/meson.build b/meson.build
|
||||
index b8680c0..1109916 100644
|
||||
--- a/meson.build
|
||||
+++ b/meson.build
|
||||
@@ -14,7 +14,7 @@
|
||||
# limitations under the License.
|
||||
|
||||
project('egl-x11', 'c',
|
||||
- version : '1.0.1',
|
||||
+ version : '1.0.2',
|
||||
default_options : ['c_std=gnu99'],
|
||||
)
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
From 30455efd7dc4d461d38f65849b3cd482787ad90d Mon Sep 17 00:00:00 2001
|
||||
From: Kyle Brenneman <kbrenneman@nvidia.com>
|
||||
Date: Thu, 1 May 2025 12:30:03 -0600
|
||||
Subject: [PATCH 2/3] Don't close the syncfd in WaitImplicitFence.
|
||||
|
||||
In WaitImplicitFence, we pass the syncfd to eglCreateSync, which takes
|
||||
ownership of it, so we shouldn't close it ourselves.
|
||||
---
|
||||
src/x11/x11-window.c | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
diff --git a/src/x11/x11-window.c b/src/x11/x11-window.c
|
||||
index ae7bc17..48de96c 100644
|
||||
--- a/src/x11/x11-window.c
|
||||
+++ b/src/x11/x11-window.c
|
||||
@@ -1710,7 +1710,6 @@ static EGLBoolean WaitImplicitFence(EplDisplay *pdpy, X11ColorBuffer *buffer)
|
||||
if (fd >= 0)
|
||||
{
|
||||
success = WaitForSyncFDGPU(pdpy->priv->inst, fd);
|
||||
- close(fd);
|
||||
}
|
||||
|
||||
if (success)
|
||||
--
|
||||
2.43.0
|
||||
|
||||
119
0002-Handle-eglQuerySurface-EGL_RENDER_BUFFER.patch
Normal file
119
0002-Handle-eglQuerySurface-EGL_RENDER_BUFFER.patch
Normal file
@@ -0,0 +1,119 @@
|
||||
From 5e373f88a21b8aa190bf67eec8c6158d8642f289 Mon Sep 17 00:00:00 2001
|
||||
From: Kyle Brenneman <kbrenneman@nvidia.com>
|
||||
Date: Mon, 1 Dec 2025 13:33:44 -0700
|
||||
Subject: [PATCH 2/4] Handle eglQuerySurface(EGL_RENDER_BUFFER)
|
||||
|
||||
Add a hook for eglQuerySurface to handle EGL_RENDER_BUFFER.
|
||||
|
||||
For windows, always return EGL_BACK_BUFFER, and for pixmaps, always
|
||||
return EGL_SINGLE_BUFFER.
|
||||
---
|
||||
src/x11/x11-platform.c | 56 ++++++++++++++++++++++++++++++++++++++++++
|
||||
src/x11/x11-platform.h | 1 +
|
||||
2 files changed, 57 insertions(+)
|
||||
|
||||
diff --git a/src/x11/x11-platform.c b/src/x11/x11-platform.c
|
||||
index 9be220e..1d73bdc 100644
|
||||
--- a/src/x11/x11-platform.c
|
||||
+++ b/src/x11/x11-platform.c
|
||||
@@ -79,11 +79,13 @@ static void eplX11TerminateDisplay(EplPlatformData *plat, EplDisplay *pdpy);
|
||||
static void eplX11DestroySurface(EplDisplay *pdpy, EplSurface *surf);
|
||||
static void eplX11FreeSurface(EplDisplay *pdpy, EplSurface *surf);
|
||||
static EGLBoolean eplX11WaitGL(EplDisplay *pdpy, EplSurface *psurf);
|
||||
+static EGLBoolean eplX11HookQuerySurface(EGLDisplay edpy, EGLSurface esurf, EGLint attribute, EGLint *value);
|
||||
|
||||
static const EplHookFunc X11_HOOK_FUNCTIONS[] =
|
||||
{
|
||||
{ "eglChooseConfig", eplX11HookChooseConfig },
|
||||
{ "eglGetConfigAttrib", eplX11HookGetConfigAttrib },
|
||||
+ { "eglQuerySurface", eplX11HookQuerySurface },
|
||||
{ "eglSwapInterval", eplX11SwapInterval },
|
||||
};
|
||||
static const int NUM_X11_HOOK_FUNCTIONS = sizeof(X11_HOOK_FUNCTIONS) / sizeof(X11_HOOK_FUNCTIONS[0]);
|
||||
@@ -183,6 +185,7 @@ EGLBoolean eplX11LoadEGLExternalPlatformCommon(int major, int minor,
|
||||
|
||||
plat->priv->egl.QueryDisplayAttribKHR = driver->getProcAddress("eglQueryDisplayAttribKHR");
|
||||
plat->priv->egl.SwapInterval = driver->getProcAddress("eglSwapInterval");
|
||||
+ plat->priv->egl.QuerySurface = driver->getProcAddress("eglQuerySurface");
|
||||
plat->priv->egl.QueryDmaBufFormatsEXT = driver->getProcAddress("eglQueryDmaBufFormatsEXT");
|
||||
plat->priv->egl.QueryDmaBufModifiersEXT = driver->getProcAddress("eglQueryDmaBufModifiersEXT");
|
||||
plat->priv->egl.CreateSync = driver->getProcAddress("eglCreateSync");
|
||||
@@ -202,6 +205,7 @@ EGLBoolean eplX11LoadEGLExternalPlatformCommon(int major, int minor,
|
||||
|
||||
if (plat->priv->egl.QueryDisplayAttribKHR == NULL
|
||||
|| plat->priv->egl.SwapInterval == NULL
|
||||
+ || plat->priv->egl.QuerySurface == NULL
|
||||
|| plat->priv->egl.QueryDmaBufFormatsEXT == NULL
|
||||
|| plat->priv->egl.QueryDmaBufModifiersEXT == NULL
|
||||
|| plat->priv->egl.CreateSync == NULL
|
||||
@@ -1512,3 +1516,55 @@ uint32_t eplX11GetNativeXID(EplDisplay *pdpy, void *native_surface, EGLBoolean c
|
||||
|
||||
return xid;
|
||||
}
|
||||
+
|
||||
+EGLBoolean eplX11HookQuerySurface(EGLDisplay edpy, EGLSurface esurf, EGLint attribute, EGLint *value)
|
||||
+{
|
||||
+ EplDisplay *pdpy = NULL;
|
||||
+ EplSurface *psurf = NULL;
|
||||
+ EGLBoolean ret = EGL_FALSE;
|
||||
+
|
||||
+ pdpy = eplDisplayAcquire(edpy);
|
||||
+ if (pdpy == NULL)
|
||||
+ {
|
||||
+ return EGL_FALSE;
|
||||
+ }
|
||||
+
|
||||
+ if (value == NULL)
|
||||
+ {
|
||||
+ eplSetError(pdpy->platform, EGL_BAD_ATTRIBUTE, "value pointer must not be NULL");
|
||||
+ eplDisplayRelease(pdpy);
|
||||
+ return EGL_FALSE;
|
||||
+ }
|
||||
+
|
||||
+ psurf = eplSurfaceAcquire(pdpy, esurf);
|
||||
+ if (psurf != NULL)
|
||||
+ {
|
||||
+ if (attribute == EGL_RENDER_BUFFER)
|
||||
+ {
|
||||
+ if (psurf->type == EPL_SURFACE_TYPE_WINDOW)
|
||||
+ {
|
||||
+ *value = EGL_BACK_BUFFER;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ *value = EGL_SINGLE_BUFFER;
|
||||
+ }
|
||||
+ ret = EGL_TRUE;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ ret = pdpy->platform->priv->egl.QuerySurface(pdpy->internal_display,
|
||||
+ psurf->internal_surface, attribute, value);
|
||||
+ }
|
||||
+ eplSurfaceRelease(pdpy, psurf);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ // If we don't recognize the EGLSurface, then just pass the call
|
||||
+ // through to the driver.
|
||||
+ ret = pdpy->platform->priv->egl.QuerySurface(pdpy->internal_display, esurf, attribute, value);
|
||||
+ }
|
||||
+
|
||||
+ eplDisplayRelease(pdpy);
|
||||
+ return ret;
|
||||
+}
|
||||
diff --git a/src/x11/x11-platform.h b/src/x11/x11-platform.h
|
||||
index c90f67d..62fd866 100644
|
||||
--- a/src/x11/x11-platform.h
|
||||
+++ b/src/x11/x11-platform.h
|
||||
@@ -73,6 +73,7 @@ struct _EplImplPlatform
|
||||
{
|
||||
PFNEGLQUERYDISPLAYATTRIBKHRPROC QueryDisplayAttribKHR;
|
||||
PFNEGLSWAPINTERVALPROC SwapInterval;
|
||||
+ PFNEGLQUERYSURFACEPROC QuerySurface;
|
||||
PFNEGLQUERYDMABUFFORMATSEXTPROC QueryDmaBufFormatsEXT;
|
||||
PFNEGLQUERYDMABUFMODIFIERSEXTPROC QueryDmaBufModifiersEXT;
|
||||
PFNEGLCREATESYNCPROC CreateSync;
|
||||
--
|
||||
2.51.0
|
||||
|
||||
247
0003-Enable-implicit-sync-if-we-re-talking-to-the-NVIDIA-.patch
Normal file
247
0003-Enable-implicit-sync-if-we-re-talking-to-the-NVIDIA-.patch
Normal file
@@ -0,0 +1,247 @@
|
||||
From f0c64b0fd24b884247889cb86a343c2adf65edc7 Mon Sep 17 00:00:00 2001
|
||||
From: Kyle Brenneman <kbrenneman@nvidia.com>
|
||||
Date: Wed, 25 Jun 2025 17:17:15 -0600
|
||||
Subject: [PATCH 4/4] Enable implicit sync if we're talking to the NVIDIA Xorg
|
||||
server module.
|
||||
|
||||
Although the NVIDIA driver doesn't support implicit sync semantics, the
|
||||
NVIDIA Xorg driver will extract and attach the fence attached to the
|
||||
dma-buf when it processes a PresentPixmap or CopyArea request, which is
|
||||
enough for egl-x11 to use its implicit sync path.
|
||||
|
||||
Thus, we can set supports_implicit_sync if the server is on a non-NV
|
||||
device, or if the server is running on the NVIDIA Xorg module (which we
|
||||
can check by looking for the NVIDIA-specific NV-GLX extension).
|
||||
|
||||
Also added some environment variables to control the sync path:
|
||||
|
||||
Setting __NV_X11_FORCE_IMPLICIT_SYNC=1 will force egl-x11 to enable its
|
||||
implicit sync path, though it will still use explicit sync first if
|
||||
that's available. Setting it to "0" will disable the implicit sync path.
|
||||
|
||||
Setting __NV_X11_DISABLE_EXPLICIT_SYNC=1 will disable the explicit sync
|
||||
path.
|
||||
---
|
||||
src/x11/x11-platform.c | 62 ++++++++++++++++++++++++++++++++----------
|
||||
src/x11/x11-window.c | 28 +++++++++++--------
|
||||
2 files changed, 64 insertions(+), 26 deletions(-)
|
||||
|
||||
diff --git a/src/x11/x11-platform.c b/src/x11/x11-platform.c
|
||||
index 1d73bdc..a073f34 100644
|
||||
--- a/src/x11/x11-platform.c
|
||||
+++ b/src/x11/x11-platform.c
|
||||
@@ -709,6 +709,21 @@ static void eplX11CleanupDisplay(EplDisplay *pdpy)
|
||||
}
|
||||
}
|
||||
|
||||
+static EGLBoolean CheckX11Extension(xcb_connection_t *conn, const char *name)
|
||||
+{
|
||||
+ xcb_generic_error_t *error = NULL;
|
||||
+ xcb_query_extension_reply_t *reply = xcb_query_extension_reply(conn,
|
||||
+ xcb_query_extension(conn, strlen(name), name), &error);
|
||||
+ EGLBoolean ret = EGL_FALSE;
|
||||
+ if (reply != NULL)
|
||||
+ {
|
||||
+ ret = (reply->present != 0);
|
||||
+ free(reply);
|
||||
+ }
|
||||
+ free(error);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* Checks whether the server has the necessary support that we need.
|
||||
*
|
||||
@@ -727,7 +742,6 @@ static EGLBoolean CheckServerExtensions(X11DisplayInstance *inst)
|
||||
xcb_dri3_query_version_reply_t *dri3Reply = NULL;
|
||||
xcb_present_query_version_cookie_t presentCookie;
|
||||
xcb_present_query_version_reply_t *presentReply = NULL;
|
||||
- xcb_query_extension_reply_t *nvglxReply = NULL;
|
||||
EGLBoolean success = EGL_FALSE;
|
||||
|
||||
// Check to make sure that we're using a domain socket, since we need to be
|
||||
@@ -765,17 +779,7 @@ static EGLBoolean CheckServerExtensions(X11DisplayInstance *inst)
|
||||
* we could add some requests to NV-GLX to support older (pre DRI3 1.2)
|
||||
* servers or non-Linux systems.
|
||||
*/
|
||||
- const char NVGLX_EXTENSION_NAME[] = "NV-GLX";
|
||||
- xcb_query_extension_cookie_t extCookie = xcb_query_extension(inst->conn,
|
||||
- sizeof(NVGLX_EXTENSION_NAME) - 1, NVGLX_EXTENSION_NAME);
|
||||
- nvglxReply = xcb_query_extension_reply(inst->conn, extCookie, &error);
|
||||
- if (nvglxReply == NULL)
|
||||
- {
|
||||
- // XQueryExtension isn't supposed to generate any errors.
|
||||
- goto done;
|
||||
- }
|
||||
-
|
||||
- if (nvglxReply->present)
|
||||
+ if (CheckX11Extension(inst->conn, "NV-GLX"))
|
||||
{
|
||||
goto done;
|
||||
}
|
||||
@@ -821,7 +825,6 @@ static EGLBoolean CheckServerExtensions(X11DisplayInstance *inst)
|
||||
success = EGL_TRUE;
|
||||
|
||||
done:
|
||||
- free(nvglxReply);
|
||||
free(presentReply);
|
||||
free(dri3Reply);
|
||||
free(error);
|
||||
@@ -893,6 +896,7 @@ X11DisplayInstance *eplX11DisplayInstanceCreate(EplDisplay *pdpy, EGLBoolean fro
|
||||
EplInternalDisplay *internalDpy = NULL;
|
||||
EGLBoolean supportsDirect = EGL_FALSE;
|
||||
EGLBoolean supportsLinear = EGL_FALSE;
|
||||
+ const char *env;
|
||||
|
||||
inst = calloc(1, sizeof(X11DisplayInstance));
|
||||
if (inst == NULL)
|
||||
@@ -1013,7 +1017,15 @@ X11DisplayInstance *eplX11DisplayInstanceCreate(EplDisplay *pdpy, EGLBoolean fro
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- inst->supports_implicit_sync = EGL_FALSE;
|
||||
+ /*
|
||||
+ * The NVIDIA driver does not support implicit sync semantics in OpenGL
|
||||
+ * and similar. However, if the NVIDIA server-side driver module for
|
||||
+ * Xorg supports DRI3 1.2, then it will will extract and attach fences
|
||||
+ * from the dma-buf when it processes a PresentPixmap or CopyArea
|
||||
+ * request, which is all we actually need in order to use our implicit
|
||||
+ * sync path.
|
||||
+ */
|
||||
+ inst->supports_implicit_sync = CheckX11Extension(inst->conn, "NV-GLX");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1047,6 +1059,19 @@ X11DisplayInstance *eplX11DisplayInstanceCreate(EplDisplay *pdpy, EGLBoolean fro
|
||||
inst->supports_implicit_sync = EGL_TRUE;
|
||||
}
|
||||
|
||||
+ env = getenv("__NV_X11_FORCE_IMPLICIT_SYNC");
|
||||
+ if (env != NULL)
|
||||
+ {
|
||||
+ if (strcmp(env, "1") == 0)
|
||||
+ {
|
||||
+ inst->supports_implicit_sync = EGL_TRUE;
|
||||
+ }
|
||||
+ else if (strcmp(env, "0") == 0)
|
||||
+ {
|
||||
+ inst->supports_implicit_sync = EGL_FALSE;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (inst->device == EGL_NO_DEVICE_EXT)
|
||||
{
|
||||
if (from_init)
|
||||
@@ -1192,6 +1217,15 @@ X11DisplayInstance *eplX11DisplayInstanceCreate(EplDisplay *pdpy, EGLBoolean fro
|
||||
}
|
||||
}
|
||||
|
||||
+ if (inst->supports_explicit_sync)
|
||||
+ {
|
||||
+ env = getenv("__NV_X11_DISABLE_EXPLICIT_SYNC");
|
||||
+ if (env != NULL && atoi(env) != 0)
|
||||
+ {
|
||||
+ inst->supports_explicit_sync = EGL_FALSE;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (inst->force_prime && !inst->supports_prime)
|
||||
{
|
||||
if (from_init)
|
||||
diff --git a/src/x11/x11-window.c b/src/x11/x11-window.c
|
||||
index 040d7bf..5a458ba 100644
|
||||
--- a/src/x11/x11-window.c
|
||||
+++ b/src/x11/x11-window.c
|
||||
@@ -340,15 +340,14 @@ static void FreeColorBuffer(X11DisplayInstance *inst, X11ColorBuffer *buffer)
|
||||
static X11ColorBuffer *AllocOneColorBuffer(X11DisplayInstance *inst,
|
||||
const EplFormatInfo *fmt, uint32_t width, uint32_t height,
|
||||
const uint64_t *modifiers, int num_modifiers,
|
||||
- EGLBoolean scanout)
|
||||
+ EGLBoolean prime)
|
||||
{
|
||||
- int fd = -1;
|
||||
uint32_t flags = 0;
|
||||
X11ColorBuffer *buffer = NULL;
|
||||
|
||||
assert(num_modifiers > 0);
|
||||
|
||||
- if (scanout)
|
||||
+ if (!prime)
|
||||
{
|
||||
flags |= GBM_BO_USE_SCANOUT;
|
||||
}
|
||||
@@ -370,14 +369,14 @@ static X11ColorBuffer *AllocOneColorBuffer(X11DisplayInstance *inst,
|
||||
goto done;
|
||||
}
|
||||
|
||||
- fd = gbm_bo_get_fd(buffer->gbo);
|
||||
- if (fd < 0)
|
||||
+ buffer->fd = gbm_bo_get_fd(buffer->gbo);
|
||||
+ if (buffer->fd < 0)
|
||||
{
|
||||
goto done;
|
||||
}
|
||||
|
||||
buffer->buffer = inst->platform->priv->egl.PlatformImportColorBufferNVX(inst->internal_display->edpy,
|
||||
- fd, width, height, gbm_bo_get_format(buffer->gbo),
|
||||
+ buffer->fd, width, height, gbm_bo_get_format(buffer->gbo),
|
||||
gbm_bo_get_stride(buffer->gbo),
|
||||
gbm_bo_get_offset(buffer->gbo, 0),
|
||||
gbm_bo_get_modifier(buffer->gbo));
|
||||
@@ -386,11 +385,15 @@ static X11ColorBuffer *AllocOneColorBuffer(X11DisplayInstance *inst,
|
||||
goto done;
|
||||
}
|
||||
|
||||
-done:
|
||||
- if (fd >= 0)
|
||||
+ if (prime || !inst->supports_implicit_sync)
|
||||
{
|
||||
- close(fd);
|
||||
+ // We only need to hold on to a file descriptor for a shared dma-buf,
|
||||
+ // and only if we're using implicit sync.
|
||||
+ close(buffer->fd);
|
||||
+ buffer->fd = -1;
|
||||
}
|
||||
+
|
||||
+done:
|
||||
if (buffer->buffer == NULL)
|
||||
{
|
||||
FreeColorBuffer(inst, buffer);
|
||||
@@ -497,7 +500,7 @@ static EGLBoolean AllocWindowBuffers(EplSurface *surf,
|
||||
EGLBoolean success = EGL_TRUE;
|
||||
|
||||
front = AllocOneColorBuffer(pwin->inst, pwin->format->fmt, pwin->pending_width, pwin->pending_height,
|
||||
- modifiers, num_modifiers, !prime);
|
||||
+ modifiers, num_modifiers, prime);
|
||||
if (front == NULL)
|
||||
{
|
||||
goto done;
|
||||
@@ -508,7 +511,7 @@ static EGLBoolean AllocWindowBuffers(EplSurface *surf,
|
||||
modifier = gbm_bo_get_modifier(front->gbo);
|
||||
|
||||
back = AllocOneColorBuffer(pwin->inst, pwin->format->fmt, pwin->pending_width, pwin->pending_height,
|
||||
- &modifier, 1, !prime);
|
||||
+ &modifier, 1, prime);
|
||||
if (back == NULL)
|
||||
{
|
||||
goto done;
|
||||
@@ -1785,6 +1788,7 @@ static int CheckBufferReleaseImplicit(EplDisplay *pdpy, EplSurface *surf,
|
||||
{
|
||||
if (buffer != skip && buffer->status == BUFFER_STATUS_IDLE_NOTIFIED)
|
||||
{
|
||||
+ assert(buffer->fd >= 0);
|
||||
buffers[count] = buffer;
|
||||
fds[count].fd = buffer->fd;
|
||||
fds[count].events = POLLOUT;
|
||||
@@ -2107,7 +2111,7 @@ static X11ColorBuffer *GetFreeBuffer(EplDisplay *pdpy, EplSurface *surf,
|
||||
else
|
||||
{
|
||||
buffer = AllocOneColorBuffer(pwin->inst, pwin->format->fmt, pwin->width, pwin->height,
|
||||
- &pwin->modifier, 1, !pwin->prime);
|
||||
+ &pwin->modifier, 1, pwin->prime);
|
||||
}
|
||||
if (buffer == NULL)
|
||||
{
|
||||
--
|
||||
2.51.0
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
From f4263093fa941ecbecfcbe2035a2db2499ec7a5b Mon Sep 17 00:00:00 2001
|
||||
From: Kyle Brenneman <kbrenneman@nvidia.com>
|
||||
Date: Thu, 1 May 2025 12:34:30 -0600
|
||||
Subject: [PATCH 3/3] Fix the error reporting in WaitTimelinePoint.
|
||||
|
||||
In WaitTimelinePoint, return success if drmSyncobjTimelineWait succeeds,
|
||||
and report an error only if it fails.
|
||||
---
|
||||
src/x11/x11-window.c | 5 ++++-
|
||||
1 file changed, 4 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/x11/x11-window.c b/src/x11/x11-window.c
|
||||
index ae7bc17..02167a9 100644
|
||||
--- a/src/x11/x11-window.c
|
||||
+++ b/src/x11/x11-window.c
|
||||
@@ -1886,11 +1886,14 @@ static EGLBoolean WaitTimelinePoint(X11DisplayInstance *inst, X11Timeline *timel
|
||||
&timeline->handle, &timeline->point, 1, INT64_MAX,
|
||||
DRM_SYNCOBJ_WAIT_FLAGS_WAIT_FOR_SUBMIT,
|
||||
&first) == 0)
|
||||
+ {
|
||||
+ success = EGL_TRUE;
|
||||
+ }
|
||||
+ else
|
||||
{
|
||||
eplSetError(inst->platform, EGL_BAD_ALLOC,
|
||||
"Internal error: drmSyncobjTimelineWait(WAIT_FOR_SUBMIT) failed: %s\n",
|
||||
strerror(errno));
|
||||
- success = EGL_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
||||
BIN
egl-x11-1.0.1.tar.gz
LFS
BIN
egl-x11-1.0.1.tar.gz
LFS
Binary file not shown.
3
egl-x11-1.0.4.tar.gz
Normal file
3
egl-x11-1.0.4.tar.gz
Normal file
@@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:209b9c2f59a54195789820b38e2a581d18b76f85d7fef5b674504061743fd5ee
|
||||
size 72446
|
||||
@@ -1,3 +1,27 @@
|
||||
-------------------------------------------------------------------
|
||||
Mon Dec 22 15:08:23 UTC 2025 - Stefan Dirsch <sndirsch@suse.com>
|
||||
|
||||
- update to v1.0.4 tarball/version 1.0.5
|
||||
- supersedes the following patches:
|
||||
* 0001-Increment-the-version-number-to-1.0.3.patch
|
||||
* 0002-egl-x11-Add-support-for-tegradisp-drm.patch
|
||||
- added latest patches from git since 1.0.4
|
||||
* 0001-Fix-attribute-handling-for-eglCreateWindow-PixmapSur.patch
|
||||
* 0002-Handle-eglQuerySurface-EGL_RENDER_BUFFER.patch
|
||||
* 0003-Enable-implicit-sync-if-we-re-talking-to-the-NVIDIA-.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Tue Aug 12 14:20:20 UTC 2025 - Stefan Dirsch <sndirsch@suse.com>
|
||||
|
||||
- updated to v1.0.2 tarball/version 1.0.3 with patches below
|
||||
(needed by 580.76.05 driver, boo#1247907)
|
||||
- added 0001-Increment-the-version-number-to-1.0.3.patch
|
||||
- added 0002-egl-x11-Add-support-for-tegradisp-drm.patch
|
||||
- supersedes the following patches
|
||||
* 0001-Increment-version-number-to-1.0.2.patch
|
||||
* 0002-Don-t-close-the-syncfd-in-WaitImplicitFence.patch
|
||||
* 0003-Fix-the-error-reporting-in-WaitTimelinePoint.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu May 15 13:40:54 UTC 2025 - Stefan Dirsch <sndirsch@suse.com>
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#
|
||||
# spec file for package libnvidia-egl-x11
|
||||
#
|
||||
# Copyright (c) 2025 SUSE LLC
|
||||
# Copyright (c) 2025 SUSE LLC and contributors
|
||||
#
|
||||
# All modifications and additions to the file contributed by third parties
|
||||
# remain the property of their copyright owners, unless otherwise agreed
|
||||
@@ -20,18 +20,18 @@
|
||||
%define lname libnvidia-egl-x11%{so_ver}
|
||||
%define rname egl-x11
|
||||
Name: libnvidia-egl-x11
|
||||
Version: 1.0.1
|
||||
Version: 1.0.5
|
||||
Release: 0
|
||||
Summary: NVIDIA XLib and XCB EGL Platform Library
|
||||
# src/x11/dma-buf.h:/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
License: Apache-2.0
|
||||
Group: Development/Libraries/C and C++
|
||||
URL: https://github.com/NVIDIA/egl-x11
|
||||
Source0: https://github.com/sndirsch/egl-x11/archive/%{version}/%{rname}-%{version}.tar.gz
|
||||
Source0: %{rname}-1.0.4.tar.gz
|
||||
Source1: baselibs.conf
|
||||
Patch1: 0001-Increment-version-number-to-1.0.2.patch
|
||||
Patch2: 0002-Don-t-close-the-syncfd-in-WaitImplicitFence.patch
|
||||
Patch3: 0003-Fix-the-error-reporting-in-WaitTimelinePoint.patch
|
||||
Patch1: 0001-Fix-attribute-handling-for-eglCreateWindow-PixmapSur.patch
|
||||
Patch2: 0002-Handle-eglQuerySurface-EGL_RENDER_BUFFER.patch
|
||||
Patch3: 0003-Enable-implicit-sync-if-we-re-talking-to-the-NVIDIA-.patch
|
||||
BuildRequires: gcc-c++
|
||||
BuildRequires: meson
|
||||
BuildRequires: ninja
|
||||
@@ -95,7 +95,7 @@ This package provides headers and libraries required to build software
|
||||
using %{name}.
|
||||
|
||||
%prep
|
||||
%autosetup -n %{rname}-%{version} -p1
|
||||
%autosetup -n %{rname}-1.0.4 -p1
|
||||
|
||||
%build
|
||||
export LDFLAGS="-Wl,-z,noexecstack -Wl,-z,now -Wl,-z,relro %{?_lto_cflags}"
|
||||
|
||||
Reference in New Issue
Block a user