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
This commit is contained in:
Rui Matos 2016-05-29 20:29:49 +02:00
parent 21fd87c4af
commit 87f9927375
6 changed files with 104 additions and 0 deletions

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 ()

View File

@ -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 */,