diff options
| author | degasus <wickmarkus@web.de> | 2014-12-20 10:57:34 +0100 |
|---|---|---|
| committer | degasus <wickmarkus@web.de> | 2014-12-20 10:57:34 +0100 |
| commit | e6137407bae433e8a88d423e5d944bf7f49bc368 (patch) | |
| tree | 95935d2fa28a235aa24e288f8cc2419de8023c3f /Source/Core/VideoBackends/OGL/GLInterface | |
| parent | 31bc51072bd0f6d5e0517fbb854d0fc96b13f721 (diff) | |
GLX: try to get an OpenGL 3.3 core context
Diffstat (limited to 'Source/Core/VideoBackends/OGL/GLInterface')
| -rw-r--r-- | Source/Core/VideoBackends/OGL/GLInterface/GLX.cpp | 129 | ||||
| -rw-r--r-- | Source/Core/VideoBackends/OGL/GLInterface/GLX.h | 1 |
2 files changed, 81 insertions, 49 deletions
diff --git a/Source/Core/VideoBackends/OGL/GLInterface/GLX.cpp b/Source/Core/VideoBackends/OGL/GLInterface/GLX.cpp index 12912b0f5d..900a74b0c8 100644 --- a/Source/Core/VideoBackends/OGL/GLInterface/GLX.cpp +++ b/Source/Core/VideoBackends/OGL/GLInterface/GLX.cpp @@ -9,9 +9,22 @@ #include "VideoCommon/RenderBase.h" #include "VideoCommon/VideoConfig.h" +#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 +#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 + +typedef GLXContext (*PFNGLXCREATECONTEXTATTRIBSPROC)(Display*, GLXFBConfig, GLXContext, Bool, const int*); typedef int ( * PFNGLXSWAPINTERVALSGIPROC) (int interval); + +static PFNGLXCREATECONTEXTATTRIBSPROC glXCreateContextAttribs = nullptr; static PFNGLXSWAPINTERVALSGIPROC glXSwapIntervalSGI = nullptr; +static bool s_glxError; +static int ctxErrorHandler(Display *dpy, XErrorEvent *ev) +{ + s_glxError = true; + return 0; +} + void cInterfaceGLX::SwapInterval(int Interval) { if (glXSwapIntervalSGI) @@ -33,68 +46,86 @@ void cInterfaceGLX::Swap() // Call browser: Core.cpp:EmuThread() > main.cpp:Video_Initialize() bool cInterfaceGLX::Create(void *window_handle) { - int glxMajorVersion, glxMinorVersion; - - // attributes for a single buffered visual in RGBA format with at least - // 8 bits per color - int attrListSgl[] = {GLX_RGBA, GLX_RED_SIZE, 8, - GLX_GREEN_SIZE, 8, - GLX_BLUE_SIZE, 8, - None}; - - // attributes for a double buffered visual in RGBA format with at least - // 8 bits per color - int attrListDbl[] = {GLX_RGBA, GLX_DOUBLEBUFFER, - GLX_RED_SIZE, 8, - GLX_GREEN_SIZE, 8, - GLX_BLUE_SIZE, 8, - None }; - - int attrListDefault[] = { - GLX_RGBA, - GLX_RED_SIZE, 1, - GLX_GREEN_SIZE, 1, - GLX_BLUE_SIZE, 1, - GLX_DOUBLEBUFFER, - None }; - dpy = XOpenDisplay(nullptr); int screen = DefaultScreen(dpy); + // checking glx version + int glxMajorVersion, glxMinorVersion; glXQueryVersion(dpy, &glxMajorVersion, &glxMinorVersion); - NOTICE_LOG(VIDEO, "glX-Version %d.%d", glxMajorVersion, glxMinorVersion); + if (glxMajorVersion < 1 || (glxMajorVersion == 1 && glxMinorVersion < 4)) + { + ERROR_LOG(VIDEO, "glX-Version %d.%d detected, but need at least 1.4", + glxMajorVersion, glxMinorVersion); + return false; + } - // Get an appropriate visual - vi = glXChooseVisual(dpy, screen, attrListDbl); - if (vi == nullptr) + // loading core context creation function + glXCreateContextAttribs = (PFNGLXCREATECONTEXTATTRIBSPROC)GetFuncAddress("glXCreateContextAttribsARB"); + if (!glXCreateContextAttribs) { - vi = glXChooseVisual(dpy, screen, attrListSgl); - if (vi != nullptr) - { - ERROR_LOG(VIDEO, "Only single buffered visual!"); - } - else - { - vi = glXChooseVisual(dpy, screen, attrListDefault); - if (vi == nullptr) - { - ERROR_LOG(VIDEO, "Could not choose visual (glXChooseVisual)"); - return false; - } - } + ERROR_LOG(VIDEO, "glXCreateContextAttribsARB not found, do you support GLX_ARB_create_context?"); + return false; } - else + + // choosing framebuffer + int visual_attribs[] = + { + GLX_X_RENDERABLE , True, + GLX_DRAWABLE_TYPE , GLX_WINDOW_BIT, + GLX_X_VISUAL_TYPE , GLX_TRUE_COLOR, + GLX_RED_SIZE , 8, + GLX_GREEN_SIZE , 8, + GLX_BLUE_SIZE , 8, + GLX_DEPTH_SIZE , 0, + GLX_STENCIL_SIZE , 0, + GLX_DOUBLEBUFFER , True, + None + }; + int fbcount = 0; + GLXFBConfig* fbc = glXChooseFBConfig(dpy, screen, visual_attribs, &fbcount); + if (!fbc || !fbcount) { - NOTICE_LOG(VIDEO, "Got double buffered visual!"); + ERROR_LOG(VIDEO, "Failed to retrieve a framebuffer config"); + return false; } + fbconfig = *fbc; + XFree(fbc); + + // Get an appropriate visual + vi = glXGetVisualFromFBConfig(dpy, fbconfig); // Create a GLX context. - ctx = glXCreateContext(dpy, vi, nullptr, GL_TRUE); - if (!ctx) + // We try to get a 3.3 core profile, else we try it with anything we get. + int context_attribs[] = { - PanicAlert("Unable to create GLX context."); - return false; + GLX_CONTEXT_MAJOR_VERSION_ARB, 3, + GLX_CONTEXT_MINOR_VERSION_ARB, 3, + GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, + GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB, + None + }; + s_glxError = false; + XErrorHandler oldHandler = XSetErrorHandler(&ctxErrorHandler); + ctx = glXCreateContextAttribs(dpy, fbconfig, 0, True, context_attribs); + XSync(dpy, False); + if (!ctx || s_glxError) + { + int context_attribs_legacy[] = + { + GLX_CONTEXT_MAJOR_VERSION_ARB, 1, + GLX_CONTEXT_MINOR_VERSION_ARB, 0, + None + }; + s_glxError = false; + ctx = glXCreateContextAttribs(dpy, fbconfig, 0, True, context_attribs_legacy); + XSync(dpy, False); + if (!ctx || s_glxError) + { + ERROR_LOG(VIDEO, "Unable to create GL context."); + return false; + } } + XSetErrorHandler(oldHandler); XWindow.Initialize(dpy); diff --git a/Source/Core/VideoBackends/OGL/GLInterface/GLX.h b/Source/Core/VideoBackends/OGL/GLInterface/GLX.h index fa97efdabf..8198ea9194 100644 --- a/Source/Core/VideoBackends/OGL/GLInterface/GLX.h +++ b/Source/Core/VideoBackends/OGL/GLInterface/GLX.h @@ -18,6 +18,7 @@ private: Window win; GLXContext ctx; XVisualInfo *vi; + GLXFBConfig fbconfig; public: friend class cX11Window; void SwapInterval(int Interval) override; |
