diff --git a/plugins/GSdx/GSWndOGL.cpp b/plugins/GSdx/GSWndOGL.cpp index 1785c23dac..d30ac951ed 100644 --- a/plugins/GSdx/GSWndOGL.cpp +++ b/plugins/GSdx/GSWndOGL.cpp @@ -24,7 +24,7 @@ #if defined(__unix__) GSWndOGL::GSWndOGL() - : m_NativeWindow(0), m_NativeDisplay(NULL), m_context(0), m_swapinterval_ext(NULL), m_swapinterval_mesa(NULL) + : m_NativeWindow(0), m_NativeDisplay(nullptr), m_context(0), m_has_late_vsync(false), m_swapinterval_ext(nullptr), m_swapinterval_mesa(nullptr) { } @@ -126,6 +126,9 @@ void GSWndOGL::PopulateWndGlFunction() { m_swapinterval_ext = (PFNGLXSWAPINTERVALEXTPROC) glXGetProcAddress((const GLubyte*) "glXSwapIntervalEXT"); m_swapinterval_mesa = (PFNGLXSWAPINTERVALMESAPROC)glXGetProcAddress((const GLubyte*) "glXSwapIntervalMESA"); + + const char* ext = glXQueryExtensionsString(m_NativeDisplay, DefaultScreen(m_NativeDisplay)); + m_has_late_vsync = m_swapinterval_ext && ext && strstr(ext, "GLX_EXT_swap_control"); } bool GSWndOGL::Attach(void* handle, bool managed) diff --git a/plugins/GSdx/GSWndOGL.h b/plugins/GSdx/GSWndOGL.h index 2aabec8928..1602f6705e 100644 --- a/plugins/GSdx/GSWndOGL.h +++ b/plugins/GSdx/GSWndOGL.h @@ -30,6 +30,7 @@ class GSWndOGL final : public GSWndGL Window m_NativeWindow; Display* m_NativeDisplay; GLXContext m_context; + bool m_has_late_vsync; PFNGLXSWAPINTERVALEXTPROC m_swapinterval_ext; PFNGLXSWAPINTERVALMESAPROC m_swapinterval_mesa; @@ -38,7 +39,7 @@ class GSWndOGL final : public GSWndGL void CreateContext(int major, int minor); void SetSwapInterval(int vsync); - bool HasLateVsyncSupport() { return false; } + bool HasLateVsyncSupport() { return m_has_late_vsync; } public: GSWndOGL(); diff --git a/plugins/GSdx/GSWndWGL.cpp b/plugins/GSdx/GSWndWGL.cpp index 1e1405ada6..bdeb35d73b 100644 --- a/plugins/GSdx/GSWndWGL.cpp +++ b/plugins/GSdx/GSWndWGL.cpp @@ -40,7 +40,7 @@ static void win_error(const char* msg, bool fatal = true) GSWndWGL::GSWndWGL() - : m_NativeWindow(NULL), m_NativeDisplay(NULL), m_context(NULL) + : m_NativeWindow(nullptr), m_NativeDisplay(nullptr), m_context(nullptr), m_has_late_vsync(false) { } @@ -142,6 +142,15 @@ void GSWndWGL::DetachContext() void GSWndWGL::PopulateWndGlFunction() { m_swapinterval = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT"); + + // To ease the process, extension management is itself an extension. Clever isn't it! + PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)wglGetProcAddress("wglGetExtensionsStringARB"); + if (wglGetExtensionsStringARB) { + const char* ext = wglGetExtensionsStringARB(m_NativeDisplay); + m_has_late_vsync = m_swapinterval && ext && strstr(ext, "WGL_EXT_swap_control_tear"); + } else { + m_has_late_vsync = false; + } } bool GSWndWGL::Attach(void* handle, bool managed) diff --git a/plugins/GSdx/GSWndWGL.h b/plugins/GSdx/GSWndWGL.h index c235367f78..d15fde45f0 100644 --- a/plugins/GSdx/GSWndWGL.h +++ b/plugins/GSdx/GSWndWGL.h @@ -28,6 +28,7 @@ class GSWndWGL : public GSWndGL HWND m_NativeWindow; HDC m_NativeDisplay; HGLRC m_context; + bool m_has_late_vsync; PFNWGLSWAPINTERVALEXTPROC m_swapinterval; @@ -38,7 +39,7 @@ class GSWndWGL : public GSWndGL void OpenWGLDisplay(); void SetSwapInterval(int vsync); - bool HasLateVsyncSupport() { return false; } + bool HasLateVsyncSupport() { return m_has_late_vsync; } static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);