Merge "Further relax line verification in primitive bbox tests" into nougat-cts-dev...
[platform/upstream/VK-GL-CTS.git] / framework / platform / X11 / tcuX11GlxPlatform.cpp
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program Tester Core
3  * ----------------------------------------
4  *
5  * Copyright 2014 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Platform that uses X11 via GLX.
22  *//*--------------------------------------------------------------------*/
23
24 #include "tcuX11GlxPlatform.hpp"
25 #include "tcuX11Platform.hpp"
26
27 #include "tcuRenderTarget.hpp"
28 #include "glwInitFunctions.hpp"
29 #include "deUniquePtr.hpp"
30
31 #include <sstream>
32 #include <iterator>
33 #include <set>
34
35 #define GLX_GLXEXT_PROTOTYPES
36 #include <GL/glx.h>
37
38 namespace tcu
39 {
40 namespace x11
41 {
42 namespace glx
43 {
44
45 using de::UniquePtr;
46 using de::MovePtr;
47 using glu::ApiType;
48 using glu::ContextFactory;
49 using glu::ContextType;
50 using glu::RenderConfig;
51 using glu::RenderContext;
52 using tcu::CommandLine;
53 using tcu::RenderTarget;
54 using std::string;
55 using std::set;
56 using std::istringstream;
57 using std::ostringstream;
58 using std::istream_iterator;
59
60 typedef RenderConfig::Visibility Visibility;
61
62
63 template<typename T>
64 static inline T checkGLX(T value, const char* expr, const char* file, int line)
65 {
66         if (!value)
67                 throw tcu::TestError("GLX call failed", expr, file, line);
68         return value;
69 }
70
71 #define TCU_CHECK_GLX(EXPR) checkGLX(EXPR, #EXPR, __FILE__, __LINE__)
72 #define TCU_CHECK_GLX_CONFIG(EXPR) checkGLX((EXPR) == Success, #EXPR, __FILE__, __LINE__)
73
74 class GlxContextFactory : public glu::ContextFactory
75 {
76 public:
77                                                         GlxContextFactory       (EventState& eventState);
78                                                         ~GlxContextFactory      (void);
79         RenderContext*                  createContext           (const RenderConfig&    config,
80                                                                                                  const CommandLine&             cmdLine) const;
81
82         EventState&                             getEventState           (void) const { return m_eventState;}
83
84         const PFNGLXCREATECONTEXTATTRIBSARBPROC
85                                                         m_glXCreateContextAttribsARB;
86
87 private:
88         EventState&                             m_eventState;
89 };
90
91 class GlxDisplay : public XlibDisplay
92 {
93 public:
94                                                         GlxDisplay                              (EventState&    eventState,
95                                                                                                          const char*    name);
96         int                                             getGlxMajorVersion              (void) const { return m_majorVersion; }
97         int                                             getGlxMinorVersion              (void) const { return m_minorVersion; }
98         bool                                    isGlxExtensionSupported (const char* extName) const;
99
100 private:
101         int                                             m_errorBase;
102         int                                             m_eventBase;
103         int                                             m_majorVersion;
104         int                                             m_minorVersion;
105         set<string>                             m_extensions;
106 };
107
108 class GlxVisual
109 {
110 public:
111                                                         GlxVisual                       (GlxDisplay& display, GLXFBConfig fbConfig);
112         int                                             getAttrib                       (int attribute);
113         Visual*                                 getXVisual                      (void) { return m_visual; }
114         GLXContext                              createContext           (const GlxContextFactory&       factory,
115                                                                                                  const ContextType&                     contextType);
116         GLXWindow                               createWindow            (::Window xWindow);
117         GlxDisplay&                             getGlxDisplay           (void) { return m_display; }
118         ::Display*                              getXDisplay                     (void) { return m_display.getXDisplay(); }
119
120 private:
121         GlxDisplay&                             m_display;
122         ::Visual*                               m_visual;
123         const GLXFBConfig               m_fbConfig;
124 };
125
126 class GlxDrawable
127 {
128 public:
129         virtual                                 ~GlxDrawable            (void) {}
130
131         virtual void                    processEvents           (void) {}
132         virtual void                    getDimensions           (int* width, int* height) = 0;
133         int                                             getWidth                        (void);
134         int                                             getHeight                       (void);
135         void                                    swapBuffers                     (void) { glXSwapBuffers(getXDisplay(), getGLXDrawable()); }
136
137         virtual ::Display*              getXDisplay                     (void) = 0;
138         virtual GLXDrawable             getGLXDrawable          (void) = 0;
139
140 protected:
141                                                         GlxDrawable                     () {}
142         unsigned int                    getAttrib                       (int attribute);
143 };
144
145 class GlxWindow : public GlxDrawable
146 {
147 public:
148                                                         GlxWindow                       (GlxVisual& visual, const RenderConfig& cfg);
149                                                         ~GlxWindow                      (void);
150         void                                    processEvents           (void) { m_x11Window.processEvents(); }
151         ::Display*                              getXDisplay                     (void) { return m_x11Display.getXDisplay(); }
152         void                                    getDimensions           (int* width, int* height);
153
154 protected:
155         GLXDrawable                             getGLXDrawable          () { return m_GLXDrawable; }
156
157 private:
158         XlibDisplay&                    m_x11Display;
159         XlibWindow                              m_x11Window;
160         const GLXDrawable               m_GLXDrawable;
161 };
162
163 class GlxRenderContext : public RenderContext
164 {
165 public:
166                                                                                 GlxRenderContext        (const GlxContextFactory&       factory,
167                                                                                                                          const RenderConfig&            config);
168                                                                                 ~GlxRenderContext       (void);
169         virtual ContextType                                     getType                         (void) const;
170         virtual void                                            postIterate                     (void);
171         void                                                            makeCurrent                     (void);
172         void                                                            clearCurrent            (void);
173         virtual const glw::Functions&           getFunctions            (void) const;
174         virtual const tcu::RenderTarget&        getRenderTarget         (void) const;
175
176 private:
177         GlxDisplay                                                      m_glxDisplay;
178         GlxVisual                                                       m_glxVisual;
179         ContextType                                                     m_type;
180         GLXContext                                                      m_GLXContext;
181         UniquePtr<GlxDrawable>                          m_glxDrawable;
182         RenderTarget                                            m_renderTarget;
183         glw::Functions                                          m_functions;
184 };
185
186 extern "C"
187 {
188         static int tcuX11GlxErrorHandler (::Display* display, XErrorEvent* event)
189         {
190                 char buf[80];
191                 XGetErrorText(display, event->error_code, buf, sizeof(buf));
192                 tcu::print("X operation %u:%u failed: %s\n",
193                                    event->request_code, event->minor_code, buf);
194                 return 0;
195         }
196 }
197
198 GlxContextFactory::GlxContextFactory (EventState& eventState)
199         : glu::ContextFactory                   ("glx", "X11 GLX OpenGL Context")
200         , m_glXCreateContextAttribsARB  (
201                 reinterpret_cast<PFNGLXCREATECONTEXTATTRIBSARBPROC>(
202                         TCU_CHECK_GLX(
203                                 glXGetProcAddress(
204                                         reinterpret_cast<const GLubyte*>("glXCreateContextAttribsARB")))))
205         , m_eventState                                  (eventState)
206 {
207         XSetErrorHandler(tcuX11GlxErrorHandler);
208 }
209
210 RenderContext* GlxContextFactory::createContext (const RenderConfig&    config,
211                                                                                                  const CommandLine&             cmdLine) const
212 {
213         DE_UNREF(cmdLine);
214         GlxRenderContext* const renderContext = new GlxRenderContext(*this, config);
215         return renderContext;
216 }
217
218 GlxContextFactory::~GlxContextFactory (void)
219 {
220 }
221
222 GlxDisplay::GlxDisplay (EventState& eventState, const char* name)
223         : XlibDisplay   (eventState, name)
224 {
225         const Bool supported = glXQueryExtension(m_display, &m_errorBase, &m_eventBase);
226         if (!supported)
227                 TCU_THROW(NotSupportedError, "GLX protocol not supported by X server");
228
229         TCU_CHECK_GLX(glXQueryVersion(m_display, &m_majorVersion, &m_minorVersion));
230
231         {
232                 const int screen = XDefaultScreen(m_display);
233                 // nVidia doesn't seem to report client-side extensions correctly,
234                 // so only use server side
235                 const char* const extensions =
236                         TCU_CHECK_GLX(glXQueryServerString(m_display, screen, GLX_EXTENSIONS));
237                 istringstream extStream(extensions);
238                 m_extensions = set<string>(istream_iterator<string>(extStream),
239                                                                    istream_iterator<string>());
240         }
241 }
242
243
244 bool GlxDisplay::isGlxExtensionSupported (const char* extName) const
245 {
246         return m_extensions.find(extName) != m_extensions.end();
247 }
248
249 //! Throw `tcu::NotSupportedError` if `dpy` is not compatible with GLX
250 //! version `major`.`minor`.
251 static void checkGlxVersion (const GlxDisplay& dpy, int major, int minor)
252 {
253         const int dpyMajor = dpy.getGlxMajorVersion();
254         const int dpyMinor = dpy.getGlxMinorVersion();
255         if (!(dpyMajor == major && dpyMinor >= minor))
256         {
257                 ostringstream oss;
258                 oss << "Server GLX version "
259                         << dpyMajor << "." << dpyMinor
260                         << " not compatible with required version "
261                         << major << "." << minor;
262                 TCU_THROW(NotSupportedError, oss.str().c_str());
263         }
264 }
265
266 //! Throw `tcu::NotSupportedError` if `dpy` does not support extension `extName`.
267 static void checkGlxExtension (const GlxDisplay& dpy, const char* extName)
268 {
269         if (!dpy.isGlxExtensionSupported(extName))
270         {
271                 ostringstream oss;
272                 oss << "GLX extension \"" << extName << "\" not supported";
273                 TCU_THROW(NotSupportedError, oss.str().c_str());
274         }
275 }
276
277 GlxVisual::GlxVisual (GlxDisplay& display, GLXFBConfig fbConfig)
278         : m_display             (display)
279         , m_visual              (DE_NULL)
280         , m_fbConfig    (fbConfig)
281 {
282         XVisualInfo* visualInfo = glXGetVisualFromFBConfig(getXDisplay(), fbConfig);
283         if (visualInfo != DE_NULL)
284         {
285                 m_visual = visualInfo->visual;
286                 XFree(visualInfo);
287         }
288 }
289
290 int GlxVisual::getAttrib (int attribute)
291 {
292         int fbvalue;
293         TCU_CHECK_GLX_CONFIG(glXGetFBConfigAttrib(getXDisplay(), m_fbConfig, attribute, &fbvalue));
294         return fbvalue;
295 }
296
297 GLXContext GlxVisual::createContext (const GlxContextFactory&   factory,
298                                                                          const ContextType&                     contextType)
299 {
300         int                             profileMask     = 0;
301         const ApiType   apiType         = contextType.getAPI();
302
303         checkGlxVersion(m_display, 1, 4);
304         checkGlxExtension(m_display, "GLX_ARB_create_context");
305         checkGlxExtension(m_display, "GLX_ARB_create_context_profile");
306
307         switch (apiType.getProfile())
308         {
309                 case glu::PROFILE_ES:
310                         checkGlxExtension(m_display, "GLX_EXT_create_context_es2_profile");
311                         profileMask = GLX_CONTEXT_ES2_PROFILE_BIT_EXT;
312                         break;
313                 case glu::PROFILE_CORE:
314                         profileMask = GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
315                         break;
316                 case glu::PROFILE_COMPATIBILITY:
317                         profileMask = GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
318                         break;
319                 default:
320                         DE_FATAL("Impossible context profile");
321         }
322
323         const int attribs[] =
324         {
325                 GLX_CONTEXT_MAJOR_VERSION_ARB,  apiType.getMajorVersion(),
326                 GLX_CONTEXT_MINOR_VERSION_ARB,  apiType.getMinorVersion(),
327                 GLX_CONTEXT_FLAGS_ARB,                  0,
328                 GLX_CONTEXT_PROFILE_MASK_ARB,   profileMask,
329                 None
330         };
331         return TCU_CHECK_GLX(factory.m_glXCreateContextAttribsARB(
332                                                          getXDisplay(), m_fbConfig, DE_NULL, True, attribs));
333 }
334
335 GLXWindow GlxVisual::createWindow (::Window xWindow)
336 {
337         return TCU_CHECK_GLX(glXCreateWindow(getXDisplay(), m_fbConfig, xWindow, NULL));
338 }
339
340 unsigned GlxDrawable::getAttrib (int attrib)
341 {
342         unsigned int value = 0;
343         glXQueryDrawable(getXDisplay(), getGLXDrawable(), attrib, &value);
344         return value;
345 }
346
347 int GlxDrawable::getWidth (void)
348 {
349         int width = 0;
350         getDimensions(&width, DE_NULL);
351         return width;
352 }
353
354 int GlxDrawable::getHeight (void)
355 {
356         int height = 0;
357         getDimensions(DE_NULL, &height);
358         return height;
359 }
360
361 GlxWindow::GlxWindow (GlxVisual& visual, const RenderConfig& cfg)
362         : m_x11Display  (visual.getGlxDisplay())
363         , m_x11Window   (m_x11Display, cfg.width, cfg.height,
364                                          visual.getXVisual())
365         , m_GLXDrawable (visual.createWindow(m_x11Window.getXID()))
366 {
367         m_x11Window.setVisibility(cfg.windowVisibility != RenderConfig::VISIBILITY_HIDDEN);
368 }
369
370 void GlxWindow::getDimensions (int* width, int* height)
371 {
372         if (width != DE_NULL)
373                 *width = getAttrib(GLX_WIDTH);
374         if (height != DE_NULL)
375                 *height = getAttrib(GLX_HEIGHT);
376
377         // glXQueryDrawable may be buggy, so fall back to X geometry if needed
378         if ((width != DE_NULL && *width == 0) || (height != DE_NULL && *height == 0))
379                 m_x11Window.getDimensions(width, height);
380 }
381
382 GlxWindow::~GlxWindow (void)
383 {
384         glXDestroyWindow(m_x11Display.getXDisplay(), m_GLXDrawable);
385 }
386
387 static const struct Attribute
388 {
389         int                                             glxAttribute;
390         int     RenderConfig::*         cfgMember;
391 } s_attribs[] =
392 {
393         { GLX_RED_SIZE,         &RenderConfig::redBits          },
394         { GLX_GREEN_SIZE,       &RenderConfig::greenBits        },
395         { GLX_BLUE_SIZE,        &RenderConfig::blueBits         },
396         { GLX_ALPHA_SIZE,       &RenderConfig::alphaBits        },
397         { GLX_DEPTH_SIZE,       &RenderConfig::depthBits        },
398         { GLX_STENCIL_SIZE,     &RenderConfig::stencilBits      },
399         { GLX_SAMPLES,          &RenderConfig::numSamples       },
400         { GLX_FBCONFIG_ID,      &RenderConfig::id                       },
401 };
402
403 static deUint32 surfaceTypeToDrawableBits (RenderConfig::SurfaceType type)
404 {
405         switch (type)
406         {
407                 case RenderConfig::SURFACETYPE_WINDOW:
408                         return GLX_WINDOW_BIT;
409                 case RenderConfig::SURFACETYPE_OFFSCREEN_NATIVE:
410                         return GLX_PIXMAP_BIT;
411                 case RenderConfig::SURFACETYPE_OFFSCREEN_GENERIC:
412                         return GLX_PBUFFER_BIT;
413                 case RenderConfig::SURFACETYPE_DONT_CARE:
414                         return GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT;
415                 default:
416                         DE_FATAL("Impossible case");
417         }
418         return 0;
419 }
420
421 static bool configMatches (GlxVisual& visual, const RenderConfig& renderCfg)
422 {
423         if (renderCfg.id != RenderConfig::DONT_CARE)
424                 return visual.getAttrib(GLX_FBCONFIG_ID) == renderCfg.id;
425
426         for (const Attribute* it = DE_ARRAY_BEGIN(s_attribs); it != DE_ARRAY_END(s_attribs); it++)
427         {
428                 const int requested = renderCfg.*it->cfgMember;
429                 if (requested != RenderConfig::DONT_CARE &&
430                         requested != visual.getAttrib(it->glxAttribute))
431                         return false;
432         }
433
434         {
435                 deUint32 bits = surfaceTypeToDrawableBits(renderCfg.surfaceType);
436
437                 if ((visual.getAttrib(GLX_DRAWABLE_TYPE) & bits) == 0)
438                         return false;
439
440                 // It shouldn't be possible to have GLX_WINDOW_BIT set without a visual,
441                 // but let's make sure.
442                 if (renderCfg.surfaceType == RenderConfig::SURFACETYPE_WINDOW &&
443                         visual.getXVisual() == DE_NULL)
444                         return false;
445         }
446
447         return true;
448 }
449
450 class Rank
451 {
452 public:
453                                 Rank            (void) : m_value(0), m_bitsLeft(64) {}
454         void            add                     (size_t bits, deUint32 value);
455         void            sub                     (size_t bits, deUint32 value);
456         deUint64        getValue        (void) { return m_value; }
457
458 private:
459         deUint64        m_value;
460         size_t          m_bitsLeft;
461 };
462
463 void Rank::add (size_t bits, deUint32 value)
464 {
465         TCU_CHECK_INTERNAL(m_bitsLeft >= bits);
466         m_bitsLeft -= bits;
467         m_value = m_value << bits | de::min((1U << bits) - 1, value);
468 }
469
470 void Rank::sub (size_t bits, deUint32 value)
471 {
472         TCU_CHECK_INTERNAL(m_bitsLeft >= bits);
473         m_bitsLeft -= bits;
474         m_value = m_value << bits | ((1U << bits) - 1 - de::min((1U << bits) - 1U, value));
475 }
476
477 static deUint64 configRank (GlxVisual& visual)
478 {
479         // Sanity checks.
480         if (visual.getAttrib(GLX_DOUBLEBUFFER)                                  == False        ||
481                 (visual.getAttrib(GLX_RENDER_TYPE) & GLX_RGBA_BIT)      == 0)
482                 return 0;
483
484         Rank rank;
485         int caveat              = visual.getAttrib(GLX_CONFIG_CAVEAT);
486         int redSize             = visual.getAttrib(GLX_RED_SIZE);
487         int greenSize   = visual.getAttrib(GLX_GREEN_SIZE);
488         int blueSize    = visual.getAttrib(GLX_BLUE_SIZE);
489         int alphaSize   = visual.getAttrib(GLX_ALPHA_SIZE);
490         int depthSize   = visual.getAttrib(GLX_DEPTH_SIZE);
491         int stencilSize = visual.getAttrib(GLX_STENCIL_SIZE);
492         int minRGB              = de::min(redSize, de::min(greenSize, blueSize));
493
494         // Prefer conformant configurations.
495         rank.add(1, (caveat != GLX_NON_CONFORMANT_CONFIG));
496
497         // Prefer non-transparent configurations.
498         rank.add(1, visual.getAttrib(GLX_TRANSPARENT_TYPE) == GLX_NONE);
499
500         // Avoid stereo
501         rank.add(1, visual.getAttrib(GLX_STEREO) == False);
502
503         // Avoid overlays
504         rank.add(1, visual.getAttrib(GLX_LEVEL) == 0);
505
506         // Prefer to have some alpha.
507         rank.add(1, alphaSize > 0);
508
509         // Prefer to have a depth buffer.
510         rank.add(1, depthSize > 0);
511
512         // Prefer to have a stencil buffer.
513         rank.add(1, stencilSize > 0);
514
515         // Avoid slow configurations.
516         rank.add(1, (caveat != GLX_SLOW_CONFIG));
517
518         // Prefer larger, evenly distributed color depths
519         rank.add(4, de::min(minRGB, alphaSize));
520
521         // If alpha is low, choose best RGB
522         rank.add(4, minRGB);
523
524         // Prefer larger depth and stencil buffers
525         rank.add(6, deUint32(depthSize + stencilSize));
526
527         // Avoid excessive sampling
528         rank.sub(5, visual.getAttrib(GLX_SAMPLES));
529
530         // Prefer True/DirectColor
531         int visualType = visual.getAttrib(GLX_X_VISUAL_TYPE);
532         rank.add(1, visualType == GLX_TRUE_COLOR || visualType == GLX_DIRECT_COLOR);
533
534         return rank.getValue();
535 }
536
537 static GlxVisual chooseVisual (GlxDisplay& display, const RenderConfig& cfg)
538 {
539         ::Display*      dpy                     = display.getXDisplay();
540         deUint64        maxRank         = 0;
541         GLXFBConfig     maxConfig       = DE_NULL;
542         int                     numElems        = 0;
543
544         GLXFBConfig* const fbConfigs = glXGetFBConfigs(dpy, DefaultScreen(dpy), &numElems);
545         TCU_CHECK_MSG(fbConfigs != DE_NULL, "Couldn't query framebuffer configurations");
546
547         for (int i = 0; i < numElems; i++)
548         {
549                 GlxVisual visual(display, fbConfigs[i]);
550
551                 if (!configMatches(visual, cfg))
552                         continue;
553
554                 deUint64 cfgRank = configRank(visual);
555
556                 if (cfgRank > maxRank)
557                 {
558                         maxRank         = cfgRank;
559                         maxConfig       = fbConfigs[i];
560                 }
561         }
562         XFree(fbConfigs);
563
564         if (maxRank == 0)
565                 TCU_THROW(NotSupportedError, "Requested GLX configuration not found or unusable");
566
567         return GlxVisual(display, maxConfig);
568 }
569
570 GlxDrawable* createDrawable (GlxVisual& visual, const RenderConfig& config)
571 {
572         RenderConfig::SurfaceType surfaceType = config.surfaceType;
573
574         if (surfaceType == RenderConfig::SURFACETYPE_DONT_CARE)
575         {
576                 if (visual.getXVisual() == DE_NULL)
577                         // No visual, cannot create X window
578                         surfaceType = RenderConfig::SURFACETYPE_OFFSCREEN_NATIVE;
579                 else
580                         surfaceType = RenderConfig::SURFACETYPE_WINDOW;
581         }
582
583         switch (surfaceType)
584         {
585                 case RenderConfig::SURFACETYPE_DONT_CARE:
586                         DE_FATAL("Impossible case");
587
588                 case RenderConfig::SURFACETYPE_WINDOW:
589                         return new GlxWindow(visual, config);
590                         break;
591
592                 case RenderConfig::SURFACETYPE_OFFSCREEN_NATIVE:
593                         // \todo [2013-11-28 lauri] Pixmaps
594
595                 case RenderConfig::SURFACETYPE_OFFSCREEN_GENERIC:
596                         // \todo [2013-11-28 lauri] Pbuffers
597
598                 default:
599                         TCU_THROW(NotSupportedError, "Unsupported surface type");
600         }
601
602         return DE_NULL;
603 }
604
605 struct GlxFunctionLoader : public glw::FunctionLoader
606 {
607                                                         GlxFunctionLoader       (void) {}
608
609         glw::GenericFuncType    get                                     (const char* name) const
610         {
611                 return glXGetProcAddress(reinterpret_cast<const GLubyte*>(name));
612         }
613 };
614
615 GlxRenderContext::GlxRenderContext (const GlxContextFactory&    factory,
616                                                                         const RenderConfig&                     config)
617         : m_glxDisplay          (factory.getEventState(), DE_NULL)
618         , m_glxVisual           (chooseVisual(m_glxDisplay, config))
619         , m_type                        (config.type)
620         , m_GLXContext          (m_glxVisual.createContext(factory, config.type))
621         , m_glxDrawable         (createDrawable(m_glxVisual, config))
622         , m_renderTarget        (m_glxDrawable->getWidth(), m_glxDrawable->getHeight(),
623                                                  PixelFormat(m_glxVisual.getAttrib(GLX_RED_SIZE),
624                                                                          m_glxVisual.getAttrib(GLX_GREEN_SIZE),
625                                                                          m_glxVisual.getAttrib(GLX_BLUE_SIZE),
626                                                                          m_glxVisual.getAttrib(GLX_ALPHA_SIZE)),
627                                                  m_glxVisual.getAttrib(GLX_DEPTH_SIZE),
628                                                  m_glxVisual.getAttrib(GLX_STENCIL_SIZE),
629                                                  m_glxVisual.getAttrib(GLX_SAMPLES))
630 {
631         const GlxFunctionLoader loader;
632         makeCurrent();
633         glu::initFunctions(&m_functions, &loader, config.type.getAPI());
634 }
635
636 GlxRenderContext::~GlxRenderContext (void)
637 {
638         clearCurrent();
639         if (m_GLXContext != DE_NULL)
640                 glXDestroyContext(m_glxDisplay.getXDisplay(), m_GLXContext);
641 }
642
643 void GlxRenderContext::makeCurrent (void)
644 {
645         const GLXDrawable drawRead = m_glxDrawable->getGLXDrawable();
646         TCU_CHECK_GLX(glXMakeContextCurrent(m_glxDisplay.getXDisplay(),
647                                                                                 drawRead, drawRead, m_GLXContext));
648 }
649
650 void GlxRenderContext::clearCurrent (void)
651 {
652         TCU_CHECK_GLX(glXMakeContextCurrent(m_glxDisplay.getXDisplay(),
653                                                                                 None, None, DE_NULL));
654 }
655
656 ContextType GlxRenderContext::getType (void) const
657 {
658         return m_type;
659 }
660
661 void GlxRenderContext::postIterate (void)
662 {
663         m_glxDrawable->swapBuffers();
664         m_glxDrawable->processEvents();
665         m_glxDisplay.processEvents();
666 }
667
668 const RenderTarget& GlxRenderContext::getRenderTarget (void) const
669 {
670         return m_renderTarget;
671 }
672
673 const glw::Functions& GlxRenderContext::getFunctions (void) const
674 {
675         return m_functions;
676 }
677
678 MovePtr<ContextFactory> createContextFactory (EventState& eventState)
679 {
680         return MovePtr<ContextFactory>(new GlxContextFactory(eventState));
681 }
682
683 } // glx
684 } // x11
685 } // tcu