[mutter] cogl-winsys-glx: Add support for NV_robustness_video_memory_purge
- From: Rui Matos <rtcm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] cogl-winsys-glx: Add support for NV_robustness_video_memory_purge
- Date: Tue, 28 Jun 2016 17:54:39 +0000 (UTC)
commit 87f9927375bfb34c984975cb6039580a2e99285d
Author: Rui Matos <tiagomatos gmail com>
Date: Sun May 29 20:29:49 2016 +0200
cogl-winsys-glx: Add support for NV_robustness_video_memory_purge
This adds API to allow callers to specify that they're interested in
video memory purge errors.
https://bugzilla.gnome.org/show_bug.cgi?id=739178
cogl/cogl/cogl-renderer-private.h | 1 +
cogl/cogl/cogl-renderer.c | 10 ++++++
cogl/cogl/cogl-xlib-renderer.h | 41 ++++++++++++++++++++++++
cogl/cogl/cogl.symbols | 1 +
cogl/cogl/gl-prototypes/cogl-all-functions.h | 8 +++++
cogl/cogl/winsys/cogl-winsys-glx.c | 43 ++++++++++++++++++++++++++
6 files changed, 104 insertions(+), 0 deletions(-)
---
diff --git a/cogl/cogl/cogl-renderer-private.h b/cogl/cogl/cogl-renderer-private.h
index 080bb32..06aa213 100644
--- a/cogl/cogl/cogl-renderer-private.h
+++ b/cogl/cogl/cogl-renderer-private.h
@@ -66,6 +66,7 @@ struct _CoglRenderer
#ifdef COGL_HAS_XLIB_SUPPORT
Display *foreign_xdpy;
CoglBool xlib_enable_event_retrieval;
+ CoglBool xlib_want_reset_on_video_memory_purge;
#endif
CoglDriver driver;
diff --git a/cogl/cogl/cogl-renderer.c b/cogl/cogl/cogl-renderer.c
index fabaf81..498a00f 100644
--- a/cogl/cogl/cogl-renderer.c
+++ b/cogl/cogl/cogl-renderer.c
@@ -286,6 +286,16 @@ cogl_xlib_renderer_set_event_retrieval_enabled (CoglRenderer *renderer,
renderer->xlib_enable_event_retrieval = enable;
}
+
+void
+cogl_xlib_renderer_request_reset_on_video_memory_purge (CoglRenderer *renderer,
+ CoglBool enable)
+{
+ _COGL_RETURN_IF_FAIL (cogl_is_renderer (renderer));
+ _COGL_RETURN_IF_FAIL (!renderer->connected);
+
+ renderer->xlib_want_reset_on_video_memory_purge = enable;
+}
#endif /* COGL_HAS_XLIB_SUPPORT */
CoglBool
diff --git a/cogl/cogl/cogl-xlib-renderer.h b/cogl/cogl/cogl-xlib-renderer.h
index fdce06b..d33f830 100644
--- a/cogl/cogl/cogl-xlib-renderer.h
+++ b/cogl/cogl/cogl-xlib-renderer.h
@@ -173,6 +173,47 @@ cogl_xlib_renderer_get_display (CoglRenderer *renderer);
XVisualInfo *
cogl_xlib_renderer_get_visual_info (CoglRenderer *renderer);
+/**
+ * cogl_xlib_renderer_request_reset_on_video_memory_purge:
+ * @renderer: a #CoglRenderer
+ * @enable: The new value
+ *
+ * Sets whether Cogl should make use of the
+ * NV_robustness_video_memory_purge extension, if exposed by the
+ * driver, by initializing the GLX context appropriately.
+ *
+ * The extension is only useful when running on certain versions of
+ * the NVIDIA driver. Quoting from the spec:
+ *
+ * "The NVIDIA OpenGL driver architecture on Linux has a limitation:
+ * resources located in video memory are not persistent across certain
+ * events. VT switches, suspend/resume events, and mode switching
+ * events may erase the contents of video memory. Any resource that
+ * is located exclusively in video memory, such as framebuffer objects
+ * (FBOs), will be lost."
+ *
+ * "This extension provides a way for applications to discover when video
+ * memory content has been lost, so that the application can re-populate
+ * the video memory content as necessary."
+ *
+ * "Any driver that exposes this extension is a driver that considers
+ * video memory to be volatile. Once the driver stack has been
+ * improved, the extension will no longer be exposed."
+ *
+ * cogl_get_graphics_reset_status() needs to be called at least once
+ * every frame to find out if video memory was purged.
+ *
+ * Note that this doesn't cause Cogl to enable robust buffer access
+ * but other context reset errors may still happen and be reported via
+ * cogl_get_graphics_reset_status() if external factors cause the
+ * driver to trigger them.
+ *
+ * This defaults to %FALSE and is effective only if called before
+ * cogl_display_setup() .
+ */
+void
+cogl_xlib_renderer_request_reset_on_video_memory_purge (CoglRenderer *renderer,
+ CoglBool enable);
COGL_END_DECLS
/* The gobject introspection scanner seems to parse public headers in
diff --git a/cogl/cogl/cogl.symbols b/cogl/cogl/cogl.symbols
index ad42407..cdac572 100644
--- a/cogl/cogl/cogl.symbols
+++ b/cogl/cogl/cogl.symbols
@@ -1042,6 +1042,7 @@ cogl_xlib_renderer_get_foreign_display
cogl_xlib_renderer_get_visual_info
cogl_xlib_renderer_handle_event
cogl_xlib_renderer_remove_filter
+cogl_xlib_renderer_request_reset_on_video_memory_purge
cogl_xlib_renderer_set_event_retrieval_enabled
cogl_xlib_renderer_set_foreign_display
cogl_xlib_set_display
diff --git a/cogl/cogl/gl-prototypes/cogl-all-functions.h b/cogl/cogl/gl-prototypes/cogl-all-functions.h
index 7ac9022..0c80fbc 100644
--- a/cogl/cogl/gl-prototypes/cogl-all-functions.h
+++ b/cogl/cogl/gl-prototypes/cogl-all-functions.h
@@ -326,3 +326,11 @@ COGL_EXT_BEGIN (draw_buffers, 2, 0,
COGL_EXT_FUNCTION (void, glDrawBuffers,
(GLsizei n, const GLenum *bufs))
COGL_EXT_END ()
+
+COGL_EXT_BEGIN (robustness, 255, 255,
+ 0,
+ "ARB\0",
+ "robustness\0")
+COGL_EXT_FUNCTION (GLenum, glGetGraphicsResetStatus,
+ (void))
+COGL_EXT_END ()
diff --git a/cogl/cogl/winsys/cogl-winsys-glx.c b/cogl/cogl/winsys/cogl-winsys-glx.c
index 72d9e56..f88ee37 100644
--- a/cogl/cogl/winsys/cogl-winsys-glx.c
+++ b/cogl/cogl/winsys/cogl-winsys-glx.c
@@ -71,6 +71,11 @@
#include <GL/glx.h>
#include <X11/Xlib.h>
+/* This is a relatively new extension */
+#ifndef GLX_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV
+#define GLX_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV 0x20F7
+#endif
+
#define COGL_ONSCREEN_X11_EVENT_MASK (StructureNotifyMask | ExposureMask)
#define MAX_GLX_CONFIG_ATTRIBS 30
@@ -1025,12 +1030,50 @@ create_gl3_context (CoglDisplay *display,
GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
None
};
+ /* NV_robustness_video_memory_purge relies on GLX_ARB_create_context
+ and in part on ARB_robustness. Namely, it needs the notification
+ strategy to be set to GLX_LOSE_CONTEXT_ON_RESET_ARB and that the
+ driver exposes the GetGraphicsResetStatusARB function. This means
+ we don't actually enable robust buffer access. */
+ static const int attrib_list_reset_on_purge[] =
+ {
+ GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
+ GLX_CONTEXT_MINOR_VERSION_ARB, 1,
+ GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
+ GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
+ GLX_GENERATE_RESET_ON_VIDEO_MEMORY_PURGE_NV,
+ GL_TRUE,
+ GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
+ GLX_LOSE_CONTEXT_ON_RESET_ARB,
+ None
+ };
/* Make sure that the display supports the GLX_ARB_create_context
extension */
if (glx_renderer->glXCreateContextAttribs == NULL)
return NULL;
+ /* We can't check the presence of this extension with the usual
+ COGL_WINSYS_FEATURE machinery because that only gets initialized
+ later when the CoglContext is created. */
+ if (display->renderer->xlib_want_reset_on_video_memory_purge &&
+ strstr (glx_renderer->glXQueryExtensionsString (xlib_renderer->xdpy,
+ DefaultScreen (xlib_renderer->xdpy)),
+ "GLX_NV_robustness_video_memory_purge"))
+ {
+ CoglXlibTrapState old_state;
+ GLXContext ctx;
+
+ _cogl_xlib_renderer_trap_errors (display->renderer, &old_state);
+ ctx = glx_renderer->glXCreateContextAttribs (xlib_renderer->xdpy,
+ fb_config,
+ NULL /* share_context */,
+ True, /* direct */
+ attrib_list_reset_on_purge);
+ if (!_cogl_xlib_renderer_untrap_errors (display->renderer, &old_state) && ctx)
+ return ctx;
+ }
+
return glx_renderer->glXCreateContextAttribs (xlib_renderer->xdpy,
fb_config,
NULL /* share_context */,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]