Exemple #1
0
// Returns the Visual and depth of the chosen GLXFBConfig
//
GLFWbool _glfwChooseVisualGLX(const _GLFWctxconfig* ctxconfig,
                              const _GLFWfbconfig* fbconfig,
                              Visual** visual, int* depth)
{
    GLXFBConfig native;
    XVisualInfo* result;

    if (!chooseFBConfig(fbconfig, &native))
    {
        _glfwInputError(GLFW_FORMAT_UNAVAILABLE,
                        "GLX: Failed to find a suitable GLXFBConfig");
        return GLFW_FALSE;
    }

    result = glXGetVisualFromFBConfig(_glfw.x11.display, native);
    if (!result)
    {
        _glfwInputError(GLFW_PLATFORM_ERROR,
                        "GLX: Failed to retrieve Visual for GLXFBConfig");
        return GLFW_FALSE;
    }

    *visual = result->visual;
    *depth = result->depth;

    XFree(result);
    return GLFW_TRUE;
}
	GLXFBConfig GLXGLSupport::selectFBConfig (const int* minAttribs, const int *maxAttribs)
	{
		GLXFBConfig *fbConfigs;
		GLXFBConfig fbConfig = 0;
		int config, nConfigs = 0;
		
		fbConfigs = chooseFBConfig(minAttribs, &nConfigs);
		
		// this is a fix for cases where chooseFBConfig is not supported.
		// On the 10/2010 chooseFBConfig was not supported on VirtualBox
		// http://www.virtualbox.org/ticket/7195
		if (!nConfigs) 		
		{ 		    
			fbConfigs = glXGetFBConfigs(mGLDisplay, DefaultScreen(mGLDisplay), &nConfigs); 		
		}
		
		if (! nConfigs) 
			return 0;
		
		fbConfig = fbConfigs[0];
		
		if (maxAttribs)
		{
			FBConfigAttribs maximum(maxAttribs);
			FBConfigAttribs best(maxAttribs);
			FBConfigAttribs candidate(maxAttribs);
			
			best.load(this, fbConfig);
			
			for (config = 1; config < nConfigs; config++)
			{
				candidate.load(this, fbConfigs[config]);
				
				if (candidate > maximum)
					continue;
				
				if (candidate > best)
				{
					fbConfig = fbConfigs[config];		
					
					best.load(this, fbConfig);
				}
			}
		}

		XFree (fbConfigs);
		return fbConfig;
	}
	GLXFBConfig GLXGLSupport::getFBConfigFromVisualID(VisualID visualid)
	{
		GLXFBConfig fbConfig = 0;
		
		if (GLXEW_SGIX_fbconfig && glXGetFBConfigFromVisualSGIX)
		{
			XVisualInfo visualInfo;
			
			visualInfo.screen = DefaultScreen(mGLDisplay);
			visualInfo.depth = DefaultDepth(mGLDisplay, DefaultScreen(mGLDisplay));
			visualInfo.visualid = visualid;
			
			fbConfig = glXGetFBConfigFromVisualSGIX(mGLDisplay, &visualInfo);
		}
		
		if (! fbConfig)
		{
			int minAttribs[] = {
				GLX_DRAWABLE_TYPE,  GLX_WINDOW_BIT || GLX_PIXMAP_BIT,
				GLX_RENDER_TYPE,	GLX_RGBA_BIT,
				GLX_RED_SIZE,	   1,
				GLX_BLUE_SIZE,	  1,
				GLX_GREEN_SIZE,	 1,
				None
			};
			int nConfigs = 0;
			
			GLXFBConfig *fbConfigs = chooseFBConfig(minAttribs, &nConfigs);
			
			for (int i = 0; i < nConfigs && ! fbConfig; i++)
			{
				XVisualInfo *visualInfo = getVisualFromFBConfig(fbConfigs[i]);
				
				if (visualInfo->visualid == visualid)
					fbConfig = fbConfigs[i];
				
				XFree(visualInfo);
			}

			XFree(fbConfigs);
		}
		
		return fbConfig;
	}
// Returns the Visual and depth of the chosen GLXFBConfig
//
static void
ChooseVisualGLX(OSGLContext_glx_data* glxInfo,
                const FramebufferConfig& fbconfig,
                Visual** visual,
                int* depth)
{
    GLXFBConfig native;

    chooseFBConfig(glxInfo, fbconfig, &native);

    XVisualInfo* result = glxInfo->_imp->GetVisualFromFBConfig(glxInfo->_imp->x11.display, native);
    if (!result) {
        throw std::runtime_error("GLX: Failed to retrieve Visual for GLXFBConfig");
    }

    *visual = result->visual;
    *depth = result->depth;

    XFree(result);
}
GLXFBConfig GLXGLSupport::selectFBConfig (const int* minAttribs, const int *maxAttribs)
{
    GLXFBConfig *fbConfigs;
    GLXFBConfig fbConfig = 0;
    int config, nConfigs = 0;

    fbConfigs = chooseFBConfig(minAttribs, &nConfigs);

    if (! nConfigs)
        return 0;

    fbConfig = fbConfigs[0];

    if (maxAttribs)
    {
        FBConfigAttribs maximum(maxAttribs);
        FBConfigAttribs best(maxAttribs);
        FBConfigAttribs candidate(maxAttribs);

        best.load(this, fbConfig);

        for (config = 1; config < nConfigs; config++)
        {
            candidate.load(this, fbConfigs[config]);

            if (candidate > maximum)
                continue;

            if (candidate > best)
            {
                fbConfig = fbConfigs[config];

                best.load(this, fbConfig);
            }
        }
    }

    XFree (fbConfigs);
    return fbConfig;
}
// Prepare for creation of the OpenGL context
//
int _glfwCreateContext(_GLFWwindow* window,
                       const _GLFWwndconfig* wndconfig,
                       const _GLFWfbconfig* fbconfig)
{
    int attribs[40];
    GLXFBConfig native;
    GLXContext share = NULL;

    if (wndconfig->share)
        share = wndconfig->share->glx.context;

    if (!chooseFBConfig(fbconfig, &native))
    {
        _glfwInputError(GLFW_PLATFORM_ERROR,
                        "GLX: Failed to find a suitable GLXFBConfig");
        return GL_FALSE;
    }

    // Retrieve the corresponding visual
    if (_glfw.glx.SGIX_fbconfig)
    {
        window->glx.visual =
            _glfw.glx.GetVisualFromFBConfigSGIX(_glfw.x11.display, native);
    }
    else
        window->glx.visual = glXGetVisualFromFBConfig(_glfw.x11.display, native);

    if (window->glx.visual == NULL)
    {
        _glfwInputError(GLFW_PLATFORM_ERROR,
                        "GLX: Failed to retrieve visual for GLXFBConfig");
        return GL_FALSE;
    }

    if (wndconfig->clientAPI == GLFW_OPENGL_ES_API)
    {
        if (!_glfw.glx.ARB_create_context ||
            !_glfw.glx.ARB_create_context_profile ||
            !_glfw.glx.EXT_create_context_es2_profile)
        {
            _glfwInputError(GLFW_API_UNAVAILABLE,
                            "GLX: OpenGL ES requested but "
                            "GLX_EXT_create_context_es2_profile is unavailable");
            return GL_FALSE;
        }
    }

    if (wndconfig->glForward)
    {
        if (!_glfw.glx.ARB_create_context)
        {
            _glfwInputError(GLFW_VERSION_UNAVAILABLE,
                            "GLX: Forward compatibility requested but "
                            "GLX_ARB_create_context_profile is unavailable");
            return GL_FALSE;
        }
    }

    if (wndconfig->glProfile)
    {
        if (!_glfw.glx.ARB_create_context ||
            !_glfw.glx.ARB_create_context_profile)
        {
            _glfwInputError(GLFW_VERSION_UNAVAILABLE,
                            "GLX: An OpenGL profile requested but "
                            "GLX_ARB_create_context_profile is unavailable");
            return GL_FALSE;
        }
    }

    _glfwGrabXErrorHandler();

    if (_glfw.glx.ARB_create_context)
    {
        int index = 0, mask = 0, flags = 0, strategy = 0;

        if (wndconfig->clientAPI == GLFW_OPENGL_API)
        {
            if (wndconfig->glForward)
                flags |= GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;

            if (wndconfig->glDebug)
                flags |= GLX_CONTEXT_DEBUG_BIT_ARB;

            if (wndconfig->glProfile)
            {
                if (wndconfig->glProfile == GLFW_OPENGL_CORE_PROFILE)
                    mask |= GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
                else if (wndconfig->glProfile == GLFW_OPENGL_COMPAT_PROFILE)
                    mask |= GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
            }
        }
        else
            mask |= GLX_CONTEXT_ES2_PROFILE_BIT_EXT;

        if (wndconfig->glRobustness != GLFW_NO_ROBUSTNESS)
        {
            if (_glfw.glx.ARB_create_context_robustness)
            {
                if (wndconfig->glRobustness == GLFW_NO_RESET_NOTIFICATION)
                    strategy = GLX_NO_RESET_NOTIFICATION_ARB;
                else if (wndconfig->glRobustness == GLFW_LOSE_CONTEXT_ON_RESET)
                    strategy = GLX_LOSE_CONTEXT_ON_RESET_ARB;

                flags |= GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB;
            }
        }

        if (wndconfig->glMajor != 1 || wndconfig->glMinor != 0)
        {
            // NOTE: Only request an explicitly versioned context when
            //       necessary, as explicitly requesting version 1.0 does not
            //       always return the highest available version

            setGLXattrib(GLX_CONTEXT_MAJOR_VERSION_ARB, wndconfig->glMajor);
            setGLXattrib(GLX_CONTEXT_MINOR_VERSION_ARB, wndconfig->glMinor);
        }

        if (mask)
            setGLXattrib(GLX_CONTEXT_PROFILE_MASK_ARB, mask);

        if (flags)
            setGLXattrib(GLX_CONTEXT_FLAGS_ARB, flags);

        if (strategy)
            setGLXattrib(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, strategy);

        setGLXattrib(None, None);

        window->glx.context =
            _glfw.glx.CreateContextAttribsARB(_glfw.x11.display,
                                              native,
                                              share,
                                              True,
                                              attribs);

        if (window->glx.context == NULL)
        {
            // HACK: This is a fallback for the broken Mesa implementation of
            //       GLX_ARB_create_context_profile, which fails default 1.0
            //       context creation with a GLXBadProfileARB error in violation
            //       of the extension spec
            if (_glfw.x11.errorCode == _glfw.glx.errorBase + GLXBadProfileARB &&
                wndconfig->clientAPI == GLFW_OPENGL_API &&
                wndconfig->glProfile == GLFW_OPENGL_ANY_PROFILE &&
                wndconfig->glForward == GL_FALSE)
            {
                window->glx.context = createLegacyContext(window, native, share);
            }
        }
    }
    else
        window->glx.context = createLegacyContext(window, native, share);

    _glfwReleaseXErrorHandler();

    if (window->glx.context == NULL)
    {
        _glfwInputXError(GLFW_PLATFORM_ERROR, "GLX: Failed to create context");
        return GL_FALSE;
    }

    return GL_TRUE;
}
Exemple #7
0
// Create the OpenGL or OpenGL ES context
//
GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
                               const _GLFWctxconfig* ctxconfig,
                               const _GLFWfbconfig* fbconfig)
{
    int attribs[40];
    GLXFBConfig native = NULL;
    GLXContext share = NULL;

    if (ctxconfig->share)
        share = ctxconfig->share->context.glx.handle;

    if (!chooseFBConfig(fbconfig, &native))
    {
        _glfwInputError(GLFW_FORMAT_UNAVAILABLE,
                        "GLX: Failed to find a suitable GLXFBConfig");
        return GLFW_FALSE;
    }

    if (ctxconfig->client == GLFW_OPENGL_ES_API)
    {
        if (!_glfw.glx.ARB_create_context ||
            !_glfw.glx.ARB_create_context_profile ||
            !_glfw.glx.EXT_create_context_es2_profile)
        {
            _glfwInputError(GLFW_API_UNAVAILABLE,
                            "GLX: OpenGL ES requested but GLX_EXT_create_context_es2_profile is unavailable");
            return GLFW_FALSE;
        }
    }

    if (ctxconfig->forward)
    {
        if (!_glfw.glx.ARB_create_context)
        {
            _glfwInputError(GLFW_VERSION_UNAVAILABLE,
                            "GLX: Forward compatibility requested but GLX_ARB_create_context_profile is unavailable");
            return GLFW_FALSE;
        }
    }

    if (ctxconfig->profile)
    {
        if (!_glfw.glx.ARB_create_context ||
            !_glfw.glx.ARB_create_context_profile)
        {
            _glfwInputError(GLFW_VERSION_UNAVAILABLE,
                            "GLX: An OpenGL profile requested but GLX_ARB_create_context_profile is unavailable");
            return GLFW_FALSE;
        }
    }

    _glfwGrabErrorHandlerX11();

    if (_glfw.glx.ARB_create_context)
    {
        int index = 0, mask = 0, flags = 0;

        if (ctxconfig->client == GLFW_OPENGL_API)
        {
            if (ctxconfig->forward)
                flags |= GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;

            if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE)
                mask |= GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
            else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE)
                mask |= GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
        }
        else
            mask |= GLX_CONTEXT_ES2_PROFILE_BIT_EXT;

        if (ctxconfig->debug)
            flags |= GLX_CONTEXT_DEBUG_BIT_ARB;
        if (ctxconfig->noerror)
            flags |= GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR;

        if (ctxconfig->robustness)
        {
            if (_glfw.glx.ARB_create_context_robustness)
            {
                if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION)
                {
                    setGLXattrib(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
                                 GLX_NO_RESET_NOTIFICATION_ARB);
                }
                else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET)
                {
                    setGLXattrib(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
                                 GLX_LOSE_CONTEXT_ON_RESET_ARB);
                }

                flags |= GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB;
            }
        }

        if (ctxconfig->release)
        {
            if (_glfw.glx.ARB_context_flush_control)
            {
                if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE)
                {
                    setGLXattrib(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB,
                                 GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB);
                }
                else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH)
                {
                    setGLXattrib(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB,
                                 GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB);
                }
            }
        }

        // NOTE: Only request an explicitly versioned context when necessary, as
        //       explicitly requesting version 1.0 does not always return the
        //       highest version supported by the driver
        if (ctxconfig->major != 1 || ctxconfig->minor != 0)
        {
            setGLXattrib(GLX_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major);
            setGLXattrib(GLX_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor);
        }

        if (mask)
            setGLXattrib(GLX_CONTEXT_PROFILE_MASK_ARB, mask);

        if (flags)
            setGLXattrib(GLX_CONTEXT_FLAGS_ARB, flags);

        setGLXattrib(None, None);

        window->context.glx.handle =
            _glfw.glx.CreateContextAttribsARB(_glfw.x11.display,
                                              native,
                                              share,
                                              True,
                                              attribs);

        // HACK: This is a fallback for broken versions of the Mesa
        //       implementation of GLX_ARB_create_context_profile that fail
        //       default 1.0 context creation with a GLXBadProfileARB error in
        //       violation of the extension spec
        if (!window->context.glx.handle)
        {
            if (_glfw.x11.errorCode == _glfw.glx.errorBase + GLXBadProfileARB &&
                ctxconfig->client == GLFW_OPENGL_API &&
                ctxconfig->profile == GLFW_OPENGL_ANY_PROFILE &&
                ctxconfig->forward == GLFW_FALSE)
            {
                window->context.glx.handle =
                    createLegacyContext(window, native, share);
            }
        }
    }
    else
        window->context.glx.handle = createLegacyContext(window, native, share);

    _glfwReleaseErrorHandlerX11();

    if (!window->context.glx.handle)
    {
        _glfwInputErrorX11(GLFW_VERSION_UNAVAILABLE, "GLX: Failed to create context");
        return GLFW_FALSE;
    }

    window->context.glx.window =
        glXCreateWindow(_glfw.x11.display, native, window->x11.handle, NULL);
    if (!window->context.glx.window)
    {
        _glfwInputError(GLFW_PLATFORM_ERROR, "GLX: Failed to create window");
        return GLFW_FALSE;
    }

    window->context.makeCurrent = makeContextCurrent;
    window->context.swapBuffers = swapBuffers;
    window->context.swapInterval = swapInterval;
    window->context.extensionSupported = extensionSupported;
    window->context.getProcAddress = getProcAddress;
    window->context.destroy = destroyContext;

    return GLFW_TRUE;
}
int main(int argc, char* argv[]) {
    Display *display = XOpenDisplay(NULL);
    if (!display)
        fail("Failed to open X display\n");
    checkGlxVersion(display);
    auto bestFbc = chooseFBConfig(display);

    // Get a visual
    XVisualInfo *vi = glXGetVisualFromFBConfig(display, bestFbc);
    printf("Chosen visual ID = 0x%lx\n", vi->visualid);

    printf("Creating colormap\n");
    XSetWindowAttributes swa;
    Colormap cmap;
    swa.colormap = cmap = XCreateColormap(display,
            RootWindow(display, vi->screen),
            vi->visual, AllocNone);
    swa.background_pixmap = None ;
    swa.border_pixel      = 0;
    swa.event_mask        = StructureNotifyMask;

    printf("Creating window\n");
    Window win = XCreateWindow(display, RootWindow(display, vi->screen),
            0, 0, 100, 100, 0, vi->depth, InputOutput,
            vi->visual,
            CWBorderPixel|CWColormap|CWEventMask, &swa);
    if (!win)
        fail("Failed to create window.\n");

    // Done with the visual info data
    XFree(vi);
    XStoreName(display, win, "GL 3.0 Window");
    printf("Mapping window\n");
    XMapWindow(display, win);

    auto context = createContext(display, bestFbc);
    printf("Making context current\n");
    glXMakeCurrent(display, win, context);
    initGlew();

    GLuint tex_;
    GLuint fbo_;
    glGenTextures(1, &tex_);
    glBindTexture(GL_TEXTURE_2D, tex_);

    glGenFramebuffers(1, &fbo_);
    glBindFramebuffer(GL_FRAMEBUFFER, fbo_);
    glFramebufferTexture2D(GL_FRAMEBUFFER,
                           GL_COLOR_ATTACHMENT0,
                           GL_TEXTURE_2D,
                           tex_,
                           0);
    printGlErrors();

    glBindTexture(GL_TEXTURE_2D, tex_);
    glTexStorage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 2, 2);
    char source_pixels[16] = {
        1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4
    };
    printGlErrors();
    printf("Crash here\n");
    glTexSubImage2D(GL_TEXTURE_2D,
                    0,
                    0, 0,
                    2, 2,
                    GL_RGBA, GL_UNSIGNED_BYTE,
                    source_pixels);
    printf("Crashed :( \n");
    printGlErrors();

    glCheckFramebufferStatus(GL_FRAMEBUFFER);

    char pixels[16] = {0};
    glReadPixels(0, 0, 2, 2, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
    glCheckFramebufferStatus(GL_FRAMEBUFFER);
    printGlErrors();

    glXMakeCurrent(display, 0, 0);
    glXDestroyContext(display, context);
    XDestroyWindow(display, win);
    XFreeColormap(display, cmap);
    XCloseDisplay(display);
    printf("Test success\n");
    return 0;
}
	//-------------------------------------------------------------------------------------------------//
	GLXGLSupport::GLXGLSupport() : mGLDisplay(0), mXDisplay(0)
	{
		// A connection that might be shared with the application for GL rendering:
		mGLDisplay = getGLDisplay();
		
		// A connection that is NOT shared to enable independent event processing:
		mXDisplay  = getXDisplay();
		
		int dummy;
		
		if (XQueryExtension(mXDisplay, "RANDR", &dummy, &dummy, &dummy))
		{
			XRRScreenConfiguration *screenConfig;
			
			screenConfig = XRRGetScreenInfo(mXDisplay, DefaultRootWindow(mXDisplay));
			
			if (screenConfig) 
			{
				XRRScreenSize *screenSizes;
				int nSizes = 0;
				Rotation currentRotation;
				int currentSizeID = XRRConfigCurrentConfiguration(screenConfig, &currentRotation);
				
				screenSizes = XRRConfigSizes(screenConfig, &nSizes);
				
				mCurrentMode.first.first = screenSizes[currentSizeID].width;
				mCurrentMode.first.second = screenSizes[currentSizeID].height;
				mCurrentMode.second = XRRConfigCurrentRate(screenConfig);
				
				mOriginalMode = mCurrentMode;
				
				for(int sizeID = 0; sizeID < nSizes; sizeID++) 
				{
					short *rates;
					int nRates = 0;
					
					rates = XRRConfigRates(screenConfig, sizeID, &nRates);
					
					for (int rate = 0; rate < nRates; rate++)
					{
						VideoMode mode;
						
						mode.first.first = screenSizes[sizeID].width;
						mode.first.second = screenSizes[sizeID].height;
						mode.second = rates[rate];
						
						mVideoModes.push_back(mode);
					}
				}
				XRRFreeScreenConfigInfo(screenConfig);
			}
		}
		else
		{
			mCurrentMode.first.first = DisplayWidth(mXDisplay, DefaultScreen(mXDisplay));
			mCurrentMode.first.second = DisplayHeight(mXDisplay, DefaultScreen(mXDisplay));
			mCurrentMode.second = 0;
			
			mOriginalMode = mCurrentMode;
			
			mVideoModes.push_back(mCurrentMode);
		}
		
		GLXFBConfig *fbConfigs;
		int config, nConfigs = 0;
		
		fbConfigs = chooseFBConfig(NULL, &nConfigs);
		
		for (config = 0; config < nConfigs; config++)
		{
			int caveat, samples;
			
			getFBConfigAttrib (fbConfigs[config], GLX_CONFIG_CAVEAT, &caveat);
			
			if (caveat != GLX_SLOW_CONFIG)
			{
				getFBConfigAttrib (fbConfigs[config], GLX_SAMPLES, &samples);
				mSampleLevels.push_back(StringConverter::toString(samples));
			}
		}
		
		XFree (fbConfigs);
		
		remove_duplicates(mSampleLevels);
	}
Exemple #10
0
void
OSGLContext_x11Private::createContextGLX(OSGLContext_glx_data* glxInfo,
                                         const FramebufferConfig& fbconfig,
                                         int /*major*/,
                                         int /*minor*/,
                                         bool coreProfile,
                                         int rendererID,
                                         const OSGLContext_x11* shareContext)
{
    GLXFBConfig native = NULL;
    GLXContext share = shareContext ? shareContext->_imp->glxContextHandle : 0;

    chooseFBConfig(glxInfo, fbconfig, &native);

    GrabErrorHandlerX11();

    if (!glxInfo->_imp->ARB_create_context) {
        glxContextHandle = createLegacyContext(glxInfo, native, share);
    } else {
        std::vector<int> attribs;
        int mask = 0, flags = 0;

        /*if (ctxconfig->forward)
            flags |= GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;*/

        if (coreProfile) {
            mask |= GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
        } else {
            mask |= GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
        }


        // Note that we do NOT request a specific version. Sometimes a driver might report that its maximum compatibility
        //profile is 3.0 but we ask for 2.0, hence it will fail context creation whereas it should not. Instead we check
        //OpenGL version once context is created and check that we have at least 2.0
        /*if ( (major != 1) || (minor != 0) ) {
            setGLXattrib(GLX_CONTEXT_MAJOR_VERSION_ARB, major);
            setGLXattrib(GLX_CONTEXT_MINOR_VERSION_ARB, minor);
           }*/

        if (mask) {
            setGLXattrib(GLX_CONTEXT_PROFILE_MASK_ARB, mask);
        }

        if (flags) {
            setGLXattrib(GLX_CONTEXT_FLAGS_ARB, flags);
        }

        if ( glxInfo->_imp->MESA_query_renderer && (rendererID != -1) && (rendererID != 0) ) {
            setGLXattrib(GLX_RENDERER_ID_MESA, rendererID);
        }

        setGLXattrib(None, None);

        glxContextHandle = glxInfo->_imp->CreateContextAttribsARB(glxInfo->_imp->x11.display, native, share, True /*direct*/, &attribs[0]);

        // HACK: This is a fallback for broken versions of the Mesa
        //       implementation of GLX_ARB_create_context_profile that fail
        //       default 1.0 context creation with a GLXBadProfileARB error in
        //       violation of the extension spec
        if (!glxContextHandle) {
            if (gX11ErrorCode == glxInfo->_imp->errorBase + GLXBadProfileARB
                /*&& ctxconfig->client == GLFW_OPENGL_API &&
                   ctxconfig->profile == GLFW_OPENGL_ANY_PROFILE &&
                   ctxconfig->forward == GLFW_FALSE*/) {
                glxContextHandle = createLegacyContext(glxInfo, native, share);
            }
        }
    }


    ReleaseErrorHandlerX11(glxInfo);

    if (!glxContextHandle) {
        throw std::runtime_error("GLX: Failed to create context");
    }


    glxWindowHandle = glxInfo->_imp->CreateWindow(glxInfo->_imp->x11.display, native, x11Window.handle, NULL);
    if (!glxWindowHandle) {
        glxInfo->_imp->DestroyContext(glxInfo->_imp->x11.display, glxContextHandle);
        glxContextHandle = 0;
        throw std::runtime_error("GLX: Failed to create window");
    }

    if ( !glxInfo->_imp->IsDirect(glxInfo->_imp->x11.display, glxContextHandle) ) {
        glxInfo->_imp->DestroyContext(glxInfo->_imp->x11.display, glxContextHandle);
        glxContextHandle = 0;
        glxInfo->_imp->DestroyWindow(glxInfo->_imp->x11.display, glxWindowHandle);
        glxWindowHandle = 0;
        throw std::runtime_error("GLX: Created context is not doing direct rendering");
    }

    /*_window = glxInfo->CreateWindow(glxInfo->display, native, window->x11.handle, NULL);
       if (!_window) {
        throw std::runtime_error("GLX: Failed to create window");
       }*/
} // createContextGLX