From 30eda6909f5c03757466a9513b32d55d8e3ed2d2 Mon Sep 17 00:00:00 2001 From: "Dr. Chat" Date: Sun, 20 Dec 2015 21:13:51 -0600 Subject: [PATCH] GLContext::WasLost - Determines if we lost the context due to a TDR or another outstanding event. --- src/xenia/ui/gl/gl_context.cc | 75 +++++++++++++++++++++++++-------- src/xenia/ui/gl/gl_context.h | 3 ++ src/xenia/ui/graphics_context.h | 6 +++ 3 files changed, 66 insertions(+), 18 deletions(-) diff --git a/src/xenia/ui/gl/gl_context.cc b/src/xenia/ui/gl/gl_context.cc index 97989999f..cc40e161d 100644 --- a/src/xenia/ui/gl/gl_context.cc +++ b/src/xenia/ui/gl/gl_context.cc @@ -133,20 +133,31 @@ bool GLContext::Initialize(GLContext* share_context) { return false; } + bool robust_access_supported = false; + if (GLEW_ARB_robustness) { + robust_access_supported = true; + } + int context_flags = 0; if (FLAGS_gl_debug) { context_flags |= WGL_CONTEXT_DEBUG_BIT_ARB; } + if (robust_access_supported) { + context_flags |= WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB; + } - int attrib_list[] = {WGL_CONTEXT_MAJOR_VERSION_ARB, - 4, - WGL_CONTEXT_MINOR_VERSION_ARB, - 5, - WGL_CONTEXT_FLAGS_ARB, - context_flags, - WGL_CONTEXT_PROFILE_MASK_ARB, - WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, - 0}; + int attrib_list[] = { + WGL_CONTEXT_MAJOR_VERSION_ARB, + 4, + WGL_CONTEXT_MINOR_VERSION_ARB, + 5, + WGL_CONTEXT_FLAGS_ARB, + context_flags, + WGL_CONTEXT_PROFILE_MASK_ARB, + WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, + WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, + robust_access_supported ? WGL_LOSE_CONTEXT_ON_RESET_ARB : 0, + 0}; glrc_ = wglCreateContextAttribsARB( dc_, share_context ? share_context->glrc_ : nullptr, attrib_list); @@ -196,20 +207,31 @@ std::unique_ptr GLContext::CreateOffscreen( { GraphicsContextLock context_lock(parent_context); + bool robust_access_supported = false; + if (GLEW_ARB_robustness) { + robust_access_supported = true; + } + int context_flags = 0; if (FLAGS_gl_debug) { context_flags |= WGL_CONTEXT_DEBUG_BIT_ARB; } + if (robust_access_supported) { + context_flags |= WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB; + } - int attrib_list[] = {WGL_CONTEXT_MAJOR_VERSION_ARB, - 4, - WGL_CONTEXT_MINOR_VERSION_ARB, - 5, - WGL_CONTEXT_FLAGS_ARB, - context_flags, - WGL_CONTEXT_PROFILE_MASK_ARB, - WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, - 0}; + int attrib_list[] = { + WGL_CONTEXT_MAJOR_VERSION_ARB, + 4, + WGL_CONTEXT_MINOR_VERSION_ARB, + 5, + WGL_CONTEXT_FLAGS_ARB, + context_flags, + WGL_CONTEXT_PROFILE_MASK_ARB, + WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB, + WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, + robust_access_supported ? WGL_LOSE_CONTEXT_ON_RESET_ARB : 0, + 0}; new_glrc = wglCreateContextAttribsARB(parent_context->dc_, parent_context->glrc_, attrib_list); if (!new_glrc) { @@ -450,6 +472,23 @@ void GLContext::ClearCurrent() { } } +bool GLContext::WasLost() { + if (context_lost_) { + return true; + } + + auto status = glGetGraphicsResetStatusARB(); + if (status != GL_NO_ERROR) { + // Graphics card reset. + XELOGE("============= TDR detected on context %p! Context %s =============", + glrc_, status == GL_GUILTY_CONTEXT_RESET ? "guilty" : "innocent"); + context_lost_ = true; + return true; + } + + return false; +} + void GLContext::BeginSwap() { SCOPE_profile_cpu_i("gpu", "xe::ui::gl::GLContext::BeginSwap"); float clear_color[] = {238 / 255.0f, 238 / 255.0f, 238 / 255.0f, 1.0f}; diff --git a/src/xenia/ui/gl/gl_context.h b/src/xenia/ui/gl/gl_context.h index 65d2beb5a..120ad4c03 100644 --- a/src/xenia/ui/gl/gl_context.h +++ b/src/xenia/ui/gl/gl_context.h @@ -40,6 +40,7 @@ class GLContext : public GraphicsContext { bool is_current() override; bool MakeCurrent() override; void ClearCurrent() override; + bool WasLost() override; void BeginSwap() override; void EndSwap() override; @@ -80,6 +81,8 @@ class GLContext : public GraphicsContext { Blitter blitter_; std::unique_ptr immediate_drawer_; + + bool context_lost_ = false; }; } // namespace gl diff --git a/src/xenia/ui/graphics_context.h b/src/xenia/ui/graphics_context.h index 1ca00dbc8..ef352099f 100644 --- a/src/xenia/ui/graphics_context.h +++ b/src/xenia/ui/graphics_context.h @@ -45,6 +45,12 @@ class GraphicsContext { virtual bool MakeCurrent() = 0; virtual void ClearCurrent() = 0; + // Returns true if the OS took away our context because we caused a TDR or + // some other outstanding error. When this happens, this context, as well as + // any other shared contexts are junk. + // This context must be made current in order for this call to work properly. + virtual bool WasLost() { return false; } + virtual void BeginSwap() = 0; virtual void EndSwap() = 0;