13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program Tester Core
33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * ----------------------------------------
43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project
63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License");
83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License.
93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at
103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *      http://www.apache.org/licenses/LICENSE-2.0
123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software
143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS,
153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and
173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License.
183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*!
203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file
213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief Platform that uses X11 via GLX.
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuX11GlxPlatform.hpp"
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuX11Platform.hpp"
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "tcuRenderTarget.hpp"
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "glwInitFunctions.hpp"
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deUniquePtr.hpp"
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <sstream>
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <iterator>
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <set>
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define GLX_GLXEXT_PROTOTYPES
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <GL/glx.h>
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace tcu
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace x11
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace glx
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing de::UniquePtr;
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing de::MovePtr;
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing glu::ApiType;
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing glu::ContextFactory;
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing glu::ContextType;
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing glu::RenderConfig;
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing glu::RenderContext;
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::CommandLine;
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing tcu::RenderTarget;
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::string;
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::set;
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::istringstream;
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::ostringstream;
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryusing std::istream_iterator;
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytypedef RenderConfig::Visibility Visibility;
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyrytemplate<typename T>
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic inline T checkGLX(T value, const char* expr, const char* file, int line)
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!value)
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		throw tcu::TestError("GLX call failed", expr, file, line);
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return value;
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define TCU_CHECK_GLX(EXPR) checkGLX(EXPR, #EXPR, __FILE__, __LINE__)
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define TCU_CHECK_GLX_CONFIG(EXPR) checkGLX((EXPR) == Success, #EXPR, __FILE__, __LINE__)
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass GlxContextFactory : public glu::ContextFactory
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							GlxContextFactory	(EventState& eventState);
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							~GlxContextFactory	(void);
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RenderContext*			createContext		(const RenderConfig&	config,
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												 const CommandLine&		cmdLine) const;
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	EventState&				getEventState		(void) const { return m_eventState;}
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const PFNGLXCREATECONTEXTATTRIBSARBPROC
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							m_glXCreateContextAttribsARB;
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	EventState&				m_eventState;
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
91d689910a69d08d7acfeba8115d154eb59c6427c1Kristof Kosztyoclass GlxDisplay : public XlibDisplay
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							GlxDisplay				(EventState&	eventState,
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry													 const char*	name);
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						getGlxMajorVersion		(void) const { return m_majorVersion; }
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						getGlxMinorVersion		(void) const { return m_minorVersion; }
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					isGlxExtensionSupported (const char* extName) const;
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						m_errorBase;
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						m_eventBase;
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						m_majorVersion;
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						m_minorVersion;
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	set<string>				m_extensions;
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass GlxVisual
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							GlxVisual			(GlxDisplay& display, GLXFBConfig fbConfig);
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						getAttrib			(int attribute);
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Visual*					getXVisual			(void) { return m_visual; }
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLXContext				createContext		(const GlxContextFactory&	factory,
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												 const ContextType&			contextType);
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLXWindow				createWindow		(::Window xWindow);
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GlxDisplay&				getGlxDisplay		(void) { return m_display; }
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	::Display*				getXDisplay			(void) { return m_display.getXDisplay(); }
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GlxDisplay&				m_display;
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	::Visual*				m_visual;
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const GLXFBConfig		m_fbConfig;
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass GlxDrawable
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual					~GlxDrawable		(void) {}
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void			processEvents		(void) {}
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void			getDimensions		(int* width, int* height) = 0;
133653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos	int						getWidth			(void);
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						getHeight			(void);
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					swapBuffers			(void) { glXSwapBuffers(getXDisplay(), getGLXDrawable()); }
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual ::Display*		getXDisplay			(void) = 0;
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual GLXDrawable		getGLXDrawable		(void) = 0;
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							GlxDrawable			() {}
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	unsigned int			getAttrib			(int attribute);
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass GlxWindow : public GlxDrawable
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							GlxWindow			(GlxVisual& visual, const RenderConfig& cfg);
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							~GlxWindow			(void);
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					processEvents		(void) { m_x11Window.processEvents(); }
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	::Display*				getXDisplay			(void) { return m_x11Display.getXDisplay(); }
152653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos	void					getDimensions		(int* width, int* height);
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected:
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLXDrawable				getGLXDrawable		() { return m_GLXDrawable; }
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
158d689910a69d08d7acfeba8115d154eb59c6427c1Kristof Kosztyo	XlibDisplay&			m_x11Display;
159d689910a69d08d7acfeba8115d154eb59c6427c1Kristof Kosztyo	XlibWindow				m_x11Window;
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const GLXDrawable		m_GLXDrawable;
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass GlxRenderContext : public RenderContext
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
166653ad0e8a4209754304cbd5b5ceb4fdc7b29c01aPyry Haulos										GlxRenderContext	(const GlxContextFactory&	factory,
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry															 const RenderConfig&		config);
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										~GlxRenderContext	(void);
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual ContextType					getType				(void) const;
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void						postIterate			(void);
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void								makeCurrent			(void);
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void								clearCurrent		(void);
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual const glw::Functions&		getFunctions		(void) const;
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual const tcu::RenderTarget&	getRenderTarget		(void) const;
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GlxDisplay							m_glxDisplay;
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GlxVisual							m_glxVisual;
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ContextType							m_type;
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLXContext							m_GLXContext;
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	UniquePtr<GlxDrawable>				m_glxDrawable;
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RenderTarget						m_renderTarget;
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glw::Functions						m_functions;
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyryextern "C"
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	static int tcuX11GlxErrorHandler (::Display* display, XErrorEvent* event)
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		char buf[80];
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		XGetErrorText(display, event->error_code, buf, sizeof(buf));
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		tcu::print("X operation %u:%u failed: %s\n",
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				   event->request_code, event->minor_code, buf);
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 0;
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1983c827367444ee418f129b2c238299f49d3264554Jarkko PoyryGlxContextFactory::GlxContextFactory (EventState& eventState)
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: glu::ContextFactory			("glx", "X11 GLX OpenGL Context")
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_glXCreateContextAttribsARB	(
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		reinterpret_cast<PFNGLXCREATECONTEXTATTRIBSARBPROC>(
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_CHECK_GLX(
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				glXGetProcAddress(
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					reinterpret_cast<const GLubyte*>("glXCreateContextAttribsARB")))))
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_eventState					(eventState)
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	XSetErrorHandler(tcuX11GlxErrorHandler);
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2103c827367444ee418f129b2c238299f49d3264554Jarkko PoyryRenderContext* GlxContextFactory::createContext (const RenderConfig&	config,
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry												 const CommandLine&		cmdLine) const
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DE_UNREF(cmdLine);
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GlxRenderContext* const renderContext = new GlxRenderContext(*this, config);
2153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return renderContext;
2163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2183c827367444ee418f129b2c238299f49d3264554Jarkko PoyryGlxContextFactory::~GlxContextFactory (void)
2193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2223c827367444ee418f129b2c238299f49d3264554Jarkko PoyryGlxDisplay::GlxDisplay (EventState& eventState, const char* name)
223d689910a69d08d7acfeba8115d154eb59c6427c1Kristof Kosztyo	: XlibDisplay	(eventState, name)
2243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const Bool supported = glXQueryExtension(m_display, &m_errorBase, &m_eventBase);
2263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!supported)
2273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_THROW(NotSupportedError, "GLX protocol not supported by X server");
2283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TCU_CHECK_GLX(glXQueryVersion(m_display, &m_majorVersion, &m_minorVersion));
2303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int screen = XDefaultScreen(m_display);
2333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// nVidia doesn't seem to report client-side extensions correctly,
2343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// so only use server side
2353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const char* const extensions =
2363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_CHECK_GLX(glXQueryServerString(m_display, screen, GLX_EXTENSIONS));
2373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		istringstream extStream(extensions);
2383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_extensions = set<string>(istream_iterator<string>(extStream),
2393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry								   istream_iterator<string>());
2403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2443c827367444ee418f129b2c238299f49d3264554Jarkko Poyrybool GlxDisplay::isGlxExtensionSupported (const char* extName) const
2453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m_extensions.find(extName) != m_extensions.end();
2473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! Throw `tcu::NotSupportedError` if `dpy` is not compatible with GLX
2503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! version `major`.`minor`.
2513c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void checkGlxVersion (const GlxDisplay& dpy, int major, int minor)
2523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int dpyMajor = dpy.getGlxMajorVersion();
2543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int dpyMinor = dpy.getGlxMinorVersion();
2553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!(dpyMajor == major && dpyMinor >= minor))
2563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ostringstream oss;
2583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		oss << "Server GLX version "
2593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< dpyMajor << "." << dpyMinor
2603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< " not compatible with required version "
2613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			<< major << "." << minor;
2623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_THROW(NotSupportedError, oss.str().c_str());
2633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//! Throw `tcu::NotSupportedError` if `dpy` does not support extension `extName`.
2673c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic void checkGlxExtension (const GlxDisplay& dpy, const char* extName)
2683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (!dpy.isGlxExtensionSupported(extName))
2703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		ostringstream oss;
2723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		oss << "GLX extension \"" << extName << "\" not supported";
2733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_THROW(NotSupportedError, oss.str().c_str());
2743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2773c827367444ee418f129b2c238299f49d3264554Jarkko PoyryGlxVisual::GlxVisual (GlxDisplay& display, GLXFBConfig fbConfig)
2783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_display		(display)
2793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_visual		(DE_NULL)
2803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_fbConfig	(fbConfig)
2813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	XVisualInfo* visualInfo = glXGetVisualFromFBConfig(getXDisplay(), fbConfig);
2833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (visualInfo != DE_NULL)
2843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
2853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_visual = visualInfo->visual;
2863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		XFree(visualInfo);
2873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
2883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2903c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint GlxVisual::getAttrib (int attribute)
2913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
2923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int fbvalue;
2933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TCU_CHECK_GLX_CONFIG(glXGetFBConfigAttrib(getXDisplay(), m_fbConfig, attribute, &fbvalue));
2943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return fbvalue;
2953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
2963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2973c827367444ee418f129b2c238299f49d3264554Jarkko PoyryGLXContext GlxVisual::createContext (const GlxContextFactory&	factory,
2983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									 const ContextType&			contextType)
2993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int				profileMask	= 0;
3013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const ApiType	apiType		= contextType.getAPI();
3023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	checkGlxVersion(m_display, 1, 4);
3043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	checkGlxExtension(m_display, "GLX_ARB_create_context");
3053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	checkGlxExtension(m_display, "GLX_ARB_create_context_profile");
3063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (apiType.getProfile())
3083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::PROFILE_ES:
3103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			checkGlxExtension(m_display, "GLX_EXT_create_context_es2_profile");
3113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			profileMask = GLX_CONTEXT_ES2_PROFILE_BIT_EXT;
3123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
3133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::PROFILE_CORE:
3143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			profileMask = GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
3153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
3163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case glu::PROFILE_COMPATIBILITY:
3173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			profileMask = GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
3183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
3193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
3201cc61b7d03cad727bbddd00cea8d78f4f6cc9047Jarkko Pöyry			DE_FATAL("Impossible context profile");
3213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
3223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const int attribs[] =
3243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
3253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLX_CONTEXT_MAJOR_VERSION_ARB,	apiType.getMajorVersion(),
3263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLX_CONTEXT_MINOR_VERSION_ARB,	apiType.getMinorVersion(),
3273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLX_CONTEXT_FLAGS_ARB,			0,
3283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GLX_CONTEXT_PROFILE_MASK_ARB,	profileMask,
3293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		None
3303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
3313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return TCU_CHECK_GLX(factory.m_glXCreateContextAttribsARB(
3323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							 getXDisplay(), m_fbConfig, DE_NULL, True, attribs));
3333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3353c827367444ee418f129b2c238299f49d3264554Jarkko PoyryGLXWindow GlxVisual::createWindow (::Window xWindow)
3363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return TCU_CHECK_GLX(glXCreateWindow(getXDisplay(), m_fbConfig, xWindow, NULL));
3383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3403c827367444ee418f129b2c238299f49d3264554Jarkko Poyryunsigned GlxDrawable::getAttrib (int attrib)
3413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	unsigned int value = 0;
3433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glXQueryDrawable(getXDisplay(), getGLXDrawable(), attrib, &value);
3443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return value;
3453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3473c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint GlxDrawable::getWidth (void)
3483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int width = 0;
3503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	getDimensions(&width, DE_NULL);
3513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return width;
3523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3543c827367444ee418f129b2c238299f49d3264554Jarkko Poyryint GlxDrawable::getHeight (void)
3553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int height = 0;
3573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	getDimensions(DE_NULL, &height);
3583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return height;
3593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3613c827367444ee418f129b2c238299f49d3264554Jarkko PoyryGlxWindow::GlxWindow (GlxVisual& visual, const RenderConfig& cfg)
3623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_x11Display	(visual.getGlxDisplay())
3633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_x11Window	(m_x11Display, cfg.width, cfg.height,
3643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry					 visual.getXVisual())
3653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_GLXDrawable	(visual.createWindow(m_x11Window.getXID()))
3663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_x11Window.setVisibility(cfg.windowVisibility != RenderConfig::VISIBILITY_HIDDEN);
3683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3703c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid GlxWindow::getDimensions (int* width, int* height)
3713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (width != DE_NULL)
3733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		*width = getAttrib(GLX_WIDTH);
3743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (height != DE_NULL)
3753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		*height = getAttrib(GLX_HEIGHT);
3763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// glXQueryDrawable may be buggy, so fall back to X geometry if needed
3783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if ((width != DE_NULL && *width == 0) || (height != DE_NULL && *height == 0))
3793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		m_x11Window.getDimensions(width, height);
3803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3823c827367444ee418f129b2c238299f49d3264554Jarkko PoyryGlxWindow::~GlxWindow (void)
3833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glXDestroyWindow(m_x11Display.getXDisplay(), m_GLXDrawable);
3853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
3863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
3873c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic const struct Attribute
3883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						glxAttribute;
3903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int	RenderConfig::*		cfgMember;
3913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} s_attribs[] =
3923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
3933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ GLX_RED_SIZE,		&RenderConfig::redBits		},
3943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ GLX_GREEN_SIZE,	&RenderConfig::greenBits	},
3953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ GLX_BLUE_SIZE,	&RenderConfig::blueBits		},
3963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ GLX_ALPHA_SIZE,	&RenderConfig::alphaBits	},
3973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ GLX_DEPTH_SIZE,	&RenderConfig::depthBits	},
3983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ GLX_STENCIL_SIZE,	&RenderConfig::stencilBits	},
3993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ GLX_SAMPLES,		&RenderConfig::numSamples	},
4003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{ GLX_FBCONFIG_ID,	&RenderConfig::id			},
4013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
4023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4033c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic deUint32 surfaceTypeToDrawableBits (RenderConfig::SurfaceType type)
4043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (type)
4063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case RenderConfig::SURFACETYPE_WINDOW:
4083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return GLX_WINDOW_BIT;
4093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case RenderConfig::SURFACETYPE_OFFSCREEN_NATIVE:
4103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return GLX_PIXMAP_BIT;
4113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case RenderConfig::SURFACETYPE_OFFSCREEN_GENERIC:
4123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return GLX_PBUFFER_BIT;
4133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case RenderConfig::SURFACETYPE_DONT_CARE:
4143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT;
4153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
4161cc61b7d03cad727bbddd00cea8d78f4f6cc9047Jarkko Pöyry			DE_FATAL("Impossible case");
4173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return 0;
4193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4213c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic bool configMatches (GlxVisual& visual, const RenderConfig& renderCfg)
4223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (renderCfg.id != RenderConfig::DONT_CARE)
4243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return visual.getAttrib(GLX_FBCONFIG_ID) == renderCfg.id;
4253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (const Attribute* it = DE_ARRAY_BEGIN(s_attribs); it != DE_ARRAY_END(s_attribs); it++)
4273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		const int requested = renderCfg.*it->cfgMember;
4293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (requested != RenderConfig::DONT_CARE &&
4303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			requested != visual.getAttrib(it->glxAttribute))
4313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false;
4323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
4353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint32 bits = surfaceTypeToDrawableBits(renderCfg.surfaceType);
4363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if ((visual.getAttrib(GLX_DRAWABLE_TYPE) & bits) == 0)
4383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false;
4393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// It shouldn't be possible to have GLX_WINDOW_BIT set without a visual,
4413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		// but let's make sure.
4423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (renderCfg.surfaceType == RenderConfig::SURFACETYPE_WINDOW &&
4433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			visual.getXVisual() == DE_NULL)
4443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return false;
4453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
4463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return true;
4483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4503c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Rank
4513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4523c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
4533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry				Rank		(void) : m_value(0), m_bitsLeft(64) {}
4543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void		add			(size_t bits, deUint32 value);
4553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void		sub			(size_t bits, deUint32 value);
4563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint64	getValue	(void) { return m_value; }
4573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
4593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint64	m_value;
4603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	size_t		m_bitsLeft;
4613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
4623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4633c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Rank::add (size_t bits, deUint32 value)
4643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TCU_CHECK_INTERNAL(m_bitsLeft >= bits);
4663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_bitsLeft -= bits;
4673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_value = m_value << bits | de::min((1U << bits) - 1, value);
4683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4703c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid Rank::sub (size_t bits, deUint32 value)
4713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TCU_CHECK_INTERNAL(m_bitsLeft >= bits);
4733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_bitsLeft -= bits;
4743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_value = m_value << bits | ((1U << bits) - 1 - de::min((1U << bits) - 1U, value));
4753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
4763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4773c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic deUint64 configRank (GlxVisual& visual)
4783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
4793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Sanity checks.
4803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (visual.getAttrib(GLX_DOUBLEBUFFER)					== False	||
4813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		(visual.getAttrib(GLX_RENDER_TYPE) & GLX_RGBA_BIT)	== 0)
4823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return 0;
4833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Rank rank;
4853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int caveat		= visual.getAttrib(GLX_CONFIG_CAVEAT);
4863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int redSize		= visual.getAttrib(GLX_RED_SIZE);
4873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int greenSize	= visual.getAttrib(GLX_GREEN_SIZE);
4883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int blueSize	= visual.getAttrib(GLX_BLUE_SIZE);
4893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int alphaSize	= visual.getAttrib(GLX_ALPHA_SIZE);
4903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int depthSize	= visual.getAttrib(GLX_DEPTH_SIZE);
4913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int stencilSize	= visual.getAttrib(GLX_STENCIL_SIZE);
4923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int minRGB		= de::min(redSize, de::min(greenSize, blueSize));
4933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Prefer conformant configurations.
4953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rank.add(1, (caveat != GLX_NON_CONFORMANT_CONFIG));
4963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
4973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Prefer non-transparent configurations.
4983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rank.add(1, visual.getAttrib(GLX_TRANSPARENT_TYPE) == GLX_NONE);
4993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Avoid stereo
5013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rank.add(1, visual.getAttrib(GLX_STEREO) == False);
5023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Avoid overlays
5043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rank.add(1, visual.getAttrib(GLX_LEVEL) == 0);
5053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Prefer to have some alpha.
5073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rank.add(1, alphaSize > 0);
5083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Prefer to have a depth buffer.
5103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rank.add(1, depthSize > 0);
5113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Prefer to have a stencil buffer.
5133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rank.add(1, stencilSize > 0);
5143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Avoid slow configurations.
5163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rank.add(1, (caveat != GLX_SLOW_CONFIG));
5173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Prefer larger, evenly distributed color depths
5193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rank.add(4, de::min(minRGB, alphaSize));
5203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// If alpha is low, choose best RGB
5223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rank.add(4, minRGB);
5233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Prefer larger depth and stencil buffers
5253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rank.add(6, deUint32(depthSize + stencilSize));
5263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Avoid excessive sampling
5283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rank.sub(5, visual.getAttrib(GLX_SAMPLES));
5293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Prefer True/DirectColor
5313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int visualType = visual.getAttrib(GLX_X_VISUAL_TYPE);
5323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	rank.add(1, visualType == GLX_TRUE_COLOR || visualType == GLX_DIRECT_COLOR);
5333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return rank.getValue();
5353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5373c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystatic GlxVisual chooseVisual (GlxDisplay& display, const RenderConfig& cfg)
5383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	::Display*	dpy			= display.getXDisplay();
5403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint64	maxRank		= 0;
5413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLXFBConfig	maxConfig	= DE_NULL;
5423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int			numElems	= 0;
5433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	GLXFBConfig* const fbConfigs = glXGetFBConfigs(dpy, DefaultScreen(dpy), &numElems);
5453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TCU_CHECK_MSG(fbConfigs != DE_NULL, "Couldn't query framebuffer configurations");
5463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	for (int i = 0; i < numElems; i++)
5483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		GlxVisual visual(display, fbConfigs[i]);
5503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (!configMatches(visual, cfg))
5523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			continue;
5533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		deUint64 cfgRank = configRank(visual);
5553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (cfgRank > maxRank)
5573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		{
5583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			maxRank		= cfgRank;
5593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			maxConfig	= fbConfigs[i];
5603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		}
5613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	XFree(fbConfigs);
5633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (maxRank == 0)
5653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		TCU_THROW(NotSupportedError, "Requested GLX configuration not found or unusable");
5663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return GlxVisual(display, maxConfig);
5683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
5693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5703c827367444ee418f129b2c238299f49d3264554Jarkko PoyryGlxDrawable* createDrawable (GlxVisual& visual, const RenderConfig& config)
5713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
5723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	RenderConfig::SurfaceType surfaceType = config.surfaceType;
5733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (surfaceType == RenderConfig::SURFACETYPE_DONT_CARE)
5753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		if (visual.getXVisual() == DE_NULL)
5773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// No visual, cannot create X window
5783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			surfaceType = RenderConfig::SURFACETYPE_OFFSCREEN_NATIVE;
5793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		else
5803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			surfaceType = RenderConfig::SURFACETYPE_WINDOW;
5813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
5823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	switch (surfaceType)
5843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
5853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case RenderConfig::SURFACETYPE_DONT_CARE:
5861cc61b7d03cad727bbddd00cea8d78f4f6cc9047Jarkko Pöyry			DE_FATAL("Impossible case");
5873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case RenderConfig::SURFACETYPE_WINDOW:
5893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			return new GlxWindow(visual, config);
5903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			break;
5913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case RenderConfig::SURFACETYPE_OFFSCREEN_NATIVE:
5933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// \todo [2013-11-28 lauri] Pixmaps
5943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5953c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		case RenderConfig::SURFACETYPE_OFFSCREEN_GENERIC:
5963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			// \todo [2013-11-28 lauri] Pbuffers
5973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
5983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		default:
5993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry			TCU_THROW(NotSupportedError, "Unsupported surface type");
6003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return DE_NULL;
6033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6053c827367444ee418f129b2c238299f49d3264554Jarkko Poyrystruct GlxFunctionLoader : public glw::FunctionLoader
6063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							GlxFunctionLoader	(void) {}
6083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glw::GenericFuncType	get					(const char* name) const
6103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
6113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		return glXGetProcAddress(reinterpret_cast<const GLubyte*>(name));
6123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	}
6133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
6143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6153c827367444ee418f129b2c238299f49d3264554Jarkko PoyryGlxRenderContext::GlxRenderContext (const GlxContextFactory&	factory,
6163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									const RenderConfig&			config)
6173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	: m_glxDisplay		(factory.getEventState(), DE_NULL)
6183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_glxVisual		(chooseVisual(m_glxDisplay, config))
6193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_type			(config.type)
6203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_GLXContext		(m_glxVisual.createContext(factory, config.type))
6213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_glxDrawable		(createDrawable(m_glxVisual, config))
6223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	, m_renderTarget	(m_glxDrawable->getWidth(), m_glxDrawable->getHeight(),
6233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						 PixelFormat(m_glxVisual.getAttrib(GLX_RED_SIZE),
6243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									 m_glxVisual.getAttrib(GLX_GREEN_SIZE),
6253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									 m_glxVisual.getAttrib(GLX_BLUE_SIZE),
6263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry									 m_glxVisual.getAttrib(GLX_ALPHA_SIZE)),
6273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						 m_glxVisual.getAttrib(GLX_DEPTH_SIZE),
6283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						 m_glxVisual.getAttrib(GLX_STENCIL_SIZE),
6293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry						 m_glxVisual.getAttrib(GLX_SAMPLES))
6303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const GlxFunctionLoader loader;
6323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	makeCurrent();
6333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	glu::initFunctions(&m_functions, &loader, config.type.getAPI());
6343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6363c827367444ee418f129b2c238299f49d3264554Jarkko PoyryGlxRenderContext::~GlxRenderContext (void)
6373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	clearCurrent();
6393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	if (m_GLXContext != DE_NULL)
6403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		glXDestroyContext(m_glxDisplay.getXDisplay(), m_GLXContext);
6413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6433c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid GlxRenderContext::makeCurrent (void)
6443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	const GLXDrawable drawRead = m_glxDrawable->getGLXDrawable();
6463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TCU_CHECK_GLX(glXMakeContextCurrent(m_glxDisplay.getXDisplay(),
6473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										drawRead, drawRead, m_GLXContext));
6483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6503c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid GlxRenderContext::clearCurrent (void)
6513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	TCU_CHECK_GLX(glXMakeContextCurrent(m_glxDisplay.getXDisplay(),
6533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry										None, None, DE_NULL));
6543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6563c827367444ee418f129b2c238299f49d3264554Jarkko PoyryContextType GlxRenderContext::getType (void) const
6573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m_type;
6593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6613c827367444ee418f129b2c238299f49d3264554Jarkko Poyryvoid GlxRenderContext::postIterate (void)
6623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_glxDrawable->swapBuffers();
6643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_glxDrawable->processEvents();
6653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	m_glxDisplay.processEvents();
6663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6683c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst RenderTarget& GlxRenderContext::getRenderTarget (void) const
6693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m_renderTarget;
6713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6733c827367444ee418f129b2c238299f49d3264554Jarkko Poyryconst glw::Functions& GlxRenderContext::getFunctions (void) const
6743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return m_functions;
6763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6783c827367444ee418f129b2c238299f49d3264554Jarkko PoyryMovePtr<ContextFactory> createContextFactory (EventState& eventState)
6793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
6803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	return MovePtr<ContextFactory>(new GlxContextFactory(eventState));
6813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}
6823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
6833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // glx
6843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // x11
6853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // tcu
686