tcuX11GlxPlatform.cpp revision 1cc61b7d03cad727bbddd00cea8d78f4f6cc9047
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 913c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass GlxDisplay : public x11::Display 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; 1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 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(); } 1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry void getDimensions (int* width, int* height); 1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprotected: 1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry GLXDrawable getGLXDrawable () { return m_GLXDrawable; } 1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate: 1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry x11::Display& m_x11Display; 1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry x11::Window m_x11Window; 1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry const GLXDrawable m_GLXDrawable; 1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry}; 1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass GlxRenderContext : public RenderContext 1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{ 1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic: 1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry 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) 2233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry : x11::Display (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