mirror of
https://github.com/brl/mutter.git
synced 2024-11-09 23:46:33 -05:00
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:
parent
21fd87c4af
commit
87f9927375
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 ()
|
||||
|
@ -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 */,
|
||||
|
Loading…
Reference in New Issue
Block a user