Fix handling of EGL_NONE as color space
[platform/upstream/VK-GL-CTS.git] / modules / egl / teglWideColorTests.cpp
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program EGL Module
3  * ---------------------------------------
4  *
5  * Copyright 2017 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 Test KHR_wide_color
22  *//*--------------------------------------------------------------------*/
23
24 #include "teglWideColorTests.hpp"
25
26 #include "tcuImageCompare.hpp"
27 #include "tcuTestLog.hpp"
28 #include "tcuSurface.hpp"
29 #include "tcuTextureUtil.hpp"
30
31 #include "egluNativeWindow.hpp"
32 #include "egluStrUtil.hpp"
33 #include "egluUtil.hpp"
34 #include "egluConfigFilter.hpp"
35
36 #include "eglwLibrary.hpp"
37 #include "eglwEnums.hpp"
38
39 #include "gluDefs.hpp"
40 #include "gluRenderContext.hpp"
41 #include "gluShaderProgram.hpp"
42
43 #include "glwDefs.hpp"
44 #include "glwEnums.hpp"
45 #include "glwFunctions.hpp"
46
47 #include "deMath.h"
48 #include "deRandom.hpp"
49 #include "deString.h"
50 #include "deStringUtil.hpp"
51
52 #include <string>
53 #include <vector>
54 #include <sstream>
55
56 using std::string;
57 using std::vector;
58 using glw::GLubyte;
59 using glw::GLfloat;
60 using tcu::IVec2;
61
62 using namespace eglw;
63
64 namespace deqp
65 {
66 namespace egl
67 {
68 namespace
69 {
70
71 typedef tcu::Vec4 Color;
72
73 class GLES2Renderer;
74
75 class ReferenceRenderer;
76
77 class WideColorTests : public TestCaseGroup
78 {
79 public:
80                                                 WideColorTests          (EglTestContext& eglTestCtx);
81         void                            init                            (void);
82
83 private:
84                                                 WideColorTests          (const WideColorTests&);
85         WideColorTests&         operator=                       (const WideColorTests&);
86 };
87
88 class WideColorTest : public TestCase
89 {
90 public:
91         enum DrawType
92         {
93                 DRAWTYPE_GLES2_CLEAR,
94                 DRAWTYPE_GLES2_RENDER
95         };
96
97                                                 WideColorTest                           (EglTestContext& eglTestCtx, const char* name, const char* description);
98                                                 ~WideColorTest                          (void);
99
100         void                            init                                            (void);
101         void                            deinit                                          (void);
102         void                            checkPixelFloatSupport          (void);
103         void                            checkColorSpaceSupport          (void);
104         void                            checkDisplayP3Support           (void);
105         void                            checkDisplayP3LinearSupport (void);
106         void                            check1010102Support                     (void);
107         void                            checkFP16Support                        (void);
108         void                            checkSCRGBSupport                       (void);
109         void                            checkSCRGBLinearSupport         (void);
110
111 protected:
112         void                            initEGLSurface                          (EGLConfig config);
113         void                            initEGLContext                          (EGLConfig config);
114
115         EGLDisplay                      m_eglDisplay;
116         glw::Functions          m_gl;
117 };
118
119 struct ColoredRect
120 {
121 public:
122                         ColoredRect (const IVec2& bottomLeft_, const IVec2& topRight_, const Color& color_);
123         IVec2   bottomLeft;
124         IVec2   topRight;
125         Color   color;
126 };
127
128 ColoredRect::ColoredRect (const IVec2& bottomLeft_, const IVec2& topRight_, const Color& color_)
129         : bottomLeft    (bottomLeft_)
130         , topRight              (topRight_)
131         , color                 (color_)
132 {
133 }
134
135 void clearColorScreen (const glw::Functions& gl, const Color& clearColor)
136 {
137         gl.clearColor(clearColor.x(), clearColor.y(), clearColor.z(), clearColor.w());
138         gl.clear(GL_COLOR_BUFFER_BIT);
139 }
140
141 float windowToDeviceCoordinates (int x, int length)
142 {
143         return (2.0f * float(x) / float(length)) - 1.0f;
144 }
145
146 class GLES2Renderer
147 {
148 public:
149                                                         GLES2Renderer           (const glw::Functions& gl, int width, int height);
150                                                         ~GLES2Renderer          (void);
151         void                                    render                          (const ColoredRect& coloredRect) const;
152
153 private:
154                                                         GLES2Renderer           (const GLES2Renderer&);
155         GLES2Renderer&                  operator=                       (const GLES2Renderer&);
156
157         const glw::Functions&   m_gl;
158         glu::ShaderProgram              m_glProgram;
159         glw::GLuint                             m_coordLoc;
160         glw::GLuint                             m_colorLoc;
161         glw::GLuint                             m_bufWidth;
162         glw::GLuint                             m_bufHeight;
163 };
164
165 // generate sources for vertex and fragment buffer
166 glu::ProgramSources getSources (void)
167 {
168         const char* const vertexShaderSource =
169                 "attribute mediump vec2 a_pos;\n"
170                 "attribute mediump vec4 a_color;\n"
171                 "varying mediump vec4 v_color;\n"
172                 "void main(void)\n"
173                 "{\n"
174                 "\tv_color = a_color;\n"
175                 "\tgl_Position = vec4(a_pos, 0.0, 1.0);\n"
176                 "}";
177
178         const char* const fragmentShaderSource =
179                 "varying mediump vec4 v_color;\n"
180                 "void main(void)\n"
181                 "{\n"
182                 "\tgl_FragColor = v_color;\n"
183                 "}";
184
185         return glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource);
186 }
187
188 GLES2Renderer::GLES2Renderer (const glw::Functions& gl, int width, int height)
189         : m_gl                          (gl)
190         , m_glProgram           (gl, getSources())
191         , m_coordLoc            ((glw::GLuint)-1)
192         , m_colorLoc            ((glw::GLuint)-1)
193         , m_bufWidth            (width)
194         , m_bufHeight           (height)
195 {
196         m_colorLoc = m_gl.getAttribLocation(m_glProgram.getProgram(), "a_color");
197         m_coordLoc = m_gl.getAttribLocation(m_glProgram.getProgram(), "a_pos");
198         GLU_EXPECT_NO_ERROR(m_gl.getError(), "Failed to get attribute locations");
199 }
200
201 GLES2Renderer::~GLES2Renderer (void)
202 {
203 }
204
205 void GLES2Renderer::render (const struct ColoredRect &coloredRect) const
206 {
207         const float x1 = windowToDeviceCoordinates(coloredRect.bottomLeft.x(), m_bufWidth);
208         const float y1 = windowToDeviceCoordinates(coloredRect.bottomLeft.y(), m_bufHeight);
209         const float x2 = windowToDeviceCoordinates(coloredRect.topRight.x(), m_bufWidth);
210         const float y2 = windowToDeviceCoordinates(coloredRect.topRight.y(), m_bufHeight);
211
212         const glw::GLfloat coords[] =
213         {
214                 x1, y1, 0.0f, 1.0f,
215                 x1, y2, 0.0f, 1.0f,
216                 x2, y2, 0.0f, 1.0f,
217
218                 x2, y2, 0.0f, 1.0f,
219                 x2, y1, 0.0f, 1.0f,
220                 x1, y1, 0.0f, 1.0f
221         };
222
223         const glw::GLfloat colors[] =
224         {
225                 coloredRect.color.x(), coloredRect.color.y(), coloredRect.color.z(), coloredRect.color.w(),
226                 coloredRect.color.x(), coloredRect.color.y(), coloredRect.color.z(), coloredRect.color.w(),
227                 coloredRect.color.x(), coloredRect.color.y(), coloredRect.color.z(), coloredRect.color.w(),
228
229                 coloredRect.color.x(), coloredRect.color.y(), coloredRect.color.z(), coloredRect.color.w(),
230                 coloredRect.color.x(), coloredRect.color.y(), coloredRect.color.z(), coloredRect.color.w(),
231                 coloredRect.color.x(), coloredRect.color.y(), coloredRect.color.z(), coloredRect.color.w(),
232         };
233
234         m_gl.useProgram(m_glProgram.getProgram());
235         GLU_EXPECT_NO_ERROR(m_gl.getError(), "glUseProgram() failed");
236
237         m_gl.enableVertexAttribArray(m_coordLoc);
238         m_gl.enableVertexAttribArray(m_colorLoc);
239         GLU_EXPECT_NO_ERROR(m_gl.getError(), "Failed to enable attributes");
240
241         m_gl.vertexAttribPointer(m_coordLoc, 4, GL_FLOAT, GL_FALSE, 0, coords);
242         m_gl.vertexAttribPointer(m_colorLoc, 4, GL_FLOAT, GL_TRUE, 0, colors);
243         GLU_EXPECT_NO_ERROR(m_gl.getError(), "Failed to set attribute pointers");
244
245         m_gl.drawArrays(GL_TRIANGLES, 0, DE_LENGTH_OF_ARRAY(coords)/4);
246         GLU_EXPECT_NO_ERROR(m_gl.getError(), "glDrawArrays(), failed");
247
248         m_gl.disableVertexAttribArray(m_coordLoc);
249         m_gl.disableVertexAttribArray(m_colorLoc);
250         GLU_EXPECT_NO_ERROR(m_gl.getError(), "Failed to disable attributes");
251
252         m_gl.useProgram(0);
253         GLU_EXPECT_NO_ERROR(m_gl.getError(), "glUseProgram() failed");
254 }
255
256 class ReferenceRenderer
257 {
258 public:
259                                                 ReferenceRenderer               (void);
260 private:
261                                                 ReferenceRenderer               (const ReferenceRenderer&);
262         ReferenceRenderer&      operator=                               (const ReferenceRenderer&);
263 };
264
265 ReferenceRenderer::ReferenceRenderer (void)
266 {
267 }
268
269 WideColorTest::WideColorTest (EglTestContext& eglTestCtx, const char* name, const char* description)
270         : TestCase                               (eglTestCtx, name, description)
271         , m_eglDisplay                   (EGL_NO_DISPLAY)
272 {
273 }
274
275 WideColorTest::~WideColorTest (void)
276 {
277         deinit();
278 }
279
280 void WideColorTest::init (void)
281 {
282         m_eglDisplay            = eglu::getAndInitDisplay(m_eglTestCtx.getNativeDisplay());
283
284         m_eglTestCtx.initGLFunctions(&m_gl, glu::ApiType::es(2,0));
285 }
286
287 void WideColorTest::checkPixelFloatSupport (void)
288 {
289         const Library&  egl     = m_eglTestCtx.getLibrary();
290
291         if (!eglu::hasExtension(egl, m_eglDisplay, "EGL_EXT_pixel_format_float"))
292                 TCU_THROW(NotSupportedError, "EGL_EXT_pixel_format_float is not supported");
293 }
294
295 void WideColorTest::checkColorSpaceSupport (void)
296 {
297         const Library&  egl     = m_eglTestCtx.getLibrary();
298
299         if (!eglu::hasExtension(egl, m_eglDisplay, "EGL_KHR_gl_colorspace"))
300                 TCU_THROW(NotSupportedError, "EGL_KHR_gl_colorspace is not supported");
301 }
302
303 void WideColorTest::checkDisplayP3Support (void)
304 {
305         const Library&  egl     = m_eglTestCtx.getLibrary();
306
307         if (!eglu::hasExtension(egl, m_eglDisplay, "EGL_EXT_gl_colorspace_display_p3"))
308                 TCU_THROW(NotSupportedError, "EGL_EXT_gl_colorspace_display_p3 is not supported");
309 }
310
311 void WideColorTest::checkDisplayP3LinearSupport (void)
312 {
313         const Library&  egl     = m_eglTestCtx.getLibrary();
314
315         if (!eglu::hasExtension(egl, m_eglDisplay, "EGL_EXT_gl_colorspace_display_p3_linear"))
316                 TCU_THROW(NotSupportedError, "EGL_EXT_gl_colorspace_display_p3_linear is not supported");
317 }
318
319 void WideColorTest::checkSCRGBSupport (void)
320 {
321         const Library&  egl     = m_eglTestCtx.getLibrary();
322
323         if (!eglu::hasExtension(egl, m_eglDisplay, "EGL_EXT_gl_colorspace_scrgb"))
324                 TCU_THROW(NotSupportedError, "EGL_EXT_gl_colorspace_scrgb is not supported");
325 }
326
327 void WideColorTest::checkSCRGBLinearSupport (void)
328 {
329         const Library&  egl     = m_eglTestCtx.getLibrary();
330
331         if (!eglu::hasExtension(egl, m_eglDisplay, "EGL_EXT_gl_colorspace_scrgb_linear"))
332                 TCU_THROW(NotSupportedError, "EGL_EXT_gl_colorspace_scrgb_linear is not supported");
333 }
334
335 void WideColorTest::check1010102Support (void)
336 {
337         const Library&  egl     = m_eglTestCtx.getLibrary();
338         tcu::TestLog&   log     = m_testCtx.getLog();
339
340         const EGLint attribList[] =
341         {
342                 EGL_SURFACE_TYPE,                               EGL_WINDOW_BIT,
343                 EGL_RENDERABLE_TYPE,                    EGL_OPENGL_ES2_BIT,
344                 EGL_RED_SIZE,                                   10,
345                 EGL_GREEN_SIZE,                                 10,
346                 EGL_BLUE_SIZE,                                  10,
347                 EGL_ALPHA_SIZE,                                 2,
348                 EGL_NONE,                                               EGL_NONE
349         };
350         EGLint numConfigs = 0;
351         EGLConfig config;
352
353         // Query from EGL implementation
354         EGLU_CHECK_CALL(egl, chooseConfig(m_eglDisplay, &attribList[0], DE_NULL, 0, &numConfigs));
355
356         if (numConfigs <= 0)
357         {
358                 log << tcu::TestLog::Message << "No configs returned." << tcu::TestLog::EndMessage;
359                 TCU_THROW(NotSupportedError, "10:10:10:2 pixel format is not supported");
360         }
361
362         log << tcu::TestLog::Message << numConfigs << " configs returned" << tcu::TestLog::EndMessage;
363
364         EGLU_CHECK_CALL(egl, chooseConfig(m_eglDisplay, &attribList[0], &config, 1, &numConfigs));
365         if (numConfigs > 1)
366         {
367                 log << tcu::TestLog::Message << "Fail, more configs returned than requested." << tcu::TestLog::EndMessage;
368                 TCU_FAIL("Too many configs returned");
369         }
370
371         EGLint components[4];
372
373         EGLU_CHECK_CALL(egl, getConfigAttrib(m_eglDisplay, config, EGL_RED_SIZE, &components[0]));
374         EGLU_CHECK_CALL(egl, getConfigAttrib(m_eglDisplay, config, EGL_GREEN_SIZE, &components[1]));
375         EGLU_CHECK_CALL(egl, getConfigAttrib(m_eglDisplay, config, EGL_BLUE_SIZE, &components[2]));
376         EGLU_CHECK_CALL(egl, getConfigAttrib(m_eglDisplay, config, EGL_ALPHA_SIZE, &components[3]));
377
378         TCU_CHECK_MSG(components[0] == 10, "Missing 10bit deep red channel");
379         TCU_CHECK_MSG(components[1] == 10, "Missing 10bit deep green channel");
380         TCU_CHECK_MSG(components[2] == 10, "Missing 10bit deep blue channel");
381         TCU_CHECK_MSG(components[3] == 2, "Missing 2bit deep alpha channel");
382 }
383
384 void WideColorTest::checkFP16Support (void)
385 {
386         const Library&  egl                     = m_eglTestCtx.getLibrary();
387         tcu::TestLog&   log                     = m_testCtx.getLog();
388         EGLint                  numConfigs      = 0;
389         EGLConfig               config;
390
391         const EGLint attribList[] =
392         {
393                 EGL_SURFACE_TYPE,                         EGL_WINDOW_BIT,
394                 EGL_RENDERABLE_TYPE,              EGL_OPENGL_ES2_BIT,
395                 EGL_RED_SIZE,                             16,
396                 EGL_GREEN_SIZE,                           16,
397                 EGL_BLUE_SIZE,                            16,
398                 EGL_ALPHA_SIZE,                           16,
399                 EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT,
400                 EGL_NONE,                                         EGL_NONE
401         };
402
403         // Query from EGL implementation
404         EGLU_CHECK_CALL(egl, chooseConfig(m_eglDisplay, &attribList[0], DE_NULL, 0, &numConfigs));
405
406         if (numConfigs <= 0)
407         {
408                 log << tcu::TestLog::Message << "No configs returned." << tcu::TestLog::EndMessage;
409                 TCU_THROW(NotSupportedError, "10:10:10:2 pixel format is not supported");
410         }
411
412         log << tcu::TestLog::Message << numConfigs << " configs returned" << tcu::TestLog::EndMessage;
413
414         EGLBoolean success = egl.chooseConfig(m_eglDisplay, &attribList[0], &config, 1, &numConfigs);
415         if (success != EGL_TRUE)
416         {
417                 log << tcu::TestLog::Message << "Fail, eglChooseConfig returned an error." << tcu::TestLog::EndMessage;
418                 TCU_FAIL("eglChooseConfig failed");
419         }
420         if (numConfigs > 1)
421         {
422                 log << tcu::TestLog::Message << "Fail, more configs returned than requested." << tcu::TestLog::EndMessage;
423                 TCU_FAIL("Too many configs returned");
424         }
425
426         EGLint components[4];
427
428         success = egl.getConfigAttrib(m_eglDisplay, config, EGL_RED_SIZE, &components[0]);
429         TCU_CHECK_MSG(success == EGL_TRUE, "eglGetConfigAttrib failed");
430         EGLU_CHECK(egl);
431         success = egl.getConfigAttrib(m_eglDisplay, config, EGL_GREEN_SIZE, &components[1]);
432         TCU_CHECK_MSG(success == EGL_TRUE, "eglGetConfigAttrib failed");
433         EGLU_CHECK(egl);
434         success = egl.getConfigAttrib(m_eglDisplay, config, EGL_BLUE_SIZE, &components[2]);
435         TCU_CHECK_MSG(success == EGL_TRUE, "eglGetConfigAttrib failed");
436         EGLU_CHECK(egl);
437         success = egl.getConfigAttrib(m_eglDisplay, config, EGL_ALPHA_SIZE, &components[3]);
438         TCU_CHECK_MSG(success == EGL_TRUE, "eglGetConfigAttrib failed");
439         EGLU_CHECK(egl);
440
441         TCU_CHECK_MSG(components[0] == 16, "Missing 16bit deep red channel");
442         TCU_CHECK_MSG(components[1] == 16, "Missing 16bit deep green channel");
443         TCU_CHECK_MSG(components[2] == 16, "Missing 16bit deep blue channel");
444         TCU_CHECK_MSG(components[3] == 16, "Missing 16bit deep alpha channel");
445 }
446
447 void WideColorTest::deinit (void)
448 {
449         const Library&  egl     = m_eglTestCtx.getLibrary();
450
451         if (m_eglDisplay != EGL_NO_DISPLAY)
452         {
453                 egl.terminate(m_eglDisplay);
454                 m_eglDisplay = EGL_NO_DISPLAY;
455         }
456 }
457
458 class WideColorFP16Test : public WideColorTest
459 {
460 public:
461                                                 WideColorFP16Test               (EglTestContext& eglTestCtx, const char* name, const char* description);
462
463         void                            init                                    (void);
464         void                            executeTest                             (void);
465         IterateResult           iterate                                 (void);
466 };
467
468 WideColorFP16Test::WideColorFP16Test (EglTestContext&   eglTestCtx,
469                                                                           const char*           name,
470                                                                           const char*           description)
471         : WideColorTest(eglTestCtx, name, description)
472 {
473 }
474
475
476 void WideColorFP16Test::executeTest (void)
477 {
478         checkPixelFloatSupport();
479         checkFP16Support();
480 }
481
482 TestCase::IterateResult WideColorFP16Test::iterate (void)
483 {
484         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
485         executeTest();
486         return STOP;
487 }
488
489 void WideColorFP16Test::init (void)
490 {
491         WideColorTest::init();
492 }
493
494 class WideColor1010102Test : public WideColorTest
495 {
496 public:
497                                                 WideColor1010102Test    (EglTestContext&        eglTestCtx,
498                                                                                                  const char*            name,
499                                                                                                  const char*            description);
500
501         void                            executeTest                             (void);
502         IterateResult           iterate                                 (void);
503 };
504
505 WideColor1010102Test::WideColor1010102Test (EglTestContext& eglTestCtx, const char* name, const char* description)
506         : WideColorTest(eglTestCtx, name, description)
507 {
508 }
509
510 void WideColor1010102Test::executeTest (void)
511 {
512         check1010102Support();
513 }
514
515 TestCase::IterateResult WideColor1010102Test::iterate (void)
516 {
517         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
518         executeTest();
519         return STOP;
520 }
521
522 struct Iteration
523 {
524         float   start;
525         float   increment;
526         int             iterationCount;
527         Iteration(float s, float i, int c)
528                 : start(s), increment(i), iterationCount(c) {}
529 };
530
531 class WideColorSurfaceTest : public WideColorTest
532 {
533 public:
534                                                 WideColorSurfaceTest    (EglTestContext&                                eglTestCtx,
535                                                                                                  const char*                                    name,
536                                                                                                  const char*                                    description,
537                                                                                                  const EGLint*                                  attribList,
538                                                                                                  EGLint                                                 colorSpace,
539                                                                                                  const std::vector<Iteration>&  iterations);
540
541         void                            init                                    (void);
542         void                            executeTest                             (void);
543         IterateResult           iterate                                 (void);
544
545 protected:
546         void                            readPixels                              (const glw::Functions& gl, float* dataPtr);
547         void                            readPixels                              (const glw::Functions& gl, deUint32* dataPtr);
548         void                            readPixels                              (const glw::Functions& gl, deUint8* dataPtr);
549         deUint32                        expectedUint10                  (float reference);
550         deUint32                        expectedUint2                   (float reference);
551         deUint8                         expectedUint8                   (float reference);
552         deUint8                         expectedAlpha8                  (float reference);
553         bool                            checkWithThreshold8             (deUint8 value, deUint8 reference, deUint8 threshold = 1);
554         bool                            checkWithThreshold10    (deUint32 value, deUint32 reference, deUint32 threshold = 1);
555         bool                            checkWithThresholdFloat (float value, float reference, float threshold);
556         void                            doClearTest                             (EGLSurface surface);
557         void                            testPixels                              (float reference, float increment);
558         void                            writeEglConfig                  (EGLConfig config);
559
560 private:
561         std::vector<EGLint>                                     m_attribList;
562         EGLConfig                                                       m_eglConfig;
563         EGLint                                                          m_surfaceType;
564         EGLint                                                          m_componentType;
565         EGLint                                                          m_redSize;
566         EGLint                                                          m_colorSpace;
567         const std::vector<struct Iteration> m_iterations;
568         std::stringstream                                       m_debugLog;
569 };
570
571 WideColorSurfaceTest::WideColorSurfaceTest (EglTestContext& eglTestCtx, const char* name, const char* description, const EGLint* attribList, EGLint colorSpace, const std::vector<struct Iteration>& iterations)
572         : WideColorTest         (eglTestCtx, name, description)
573         , m_colorSpace          (colorSpace)
574         , m_iterations          (iterations)
575 {
576         deUint32 idx = 0;
577         while (attribList[idx] != EGL_NONE)
578         {
579                 if (attribList[idx] == EGL_COLOR_COMPONENT_TYPE_EXT)
580                 {
581                         m_componentType = attribList[idx + 1];
582                 }
583                 else if (attribList[idx] == EGL_SURFACE_TYPE)
584                 {
585                         m_surfaceType = attribList[idx+1];
586                 }
587                 else if (attribList[idx] == EGL_RED_SIZE)
588                 {
589                         m_redSize = attribList[idx + 1];
590                 }
591                 m_attribList.push_back(attribList[idx++]);
592                 m_attribList.push_back(attribList[idx++]);
593         }
594         m_attribList.push_back(EGL_NONE);
595 }
596
597 void WideColorSurfaceTest::init (void)
598 {
599         const Library&  egl     = m_eglTestCtx.getLibrary();
600         tcu::TestLog&   log     = m_testCtx.getLog();
601
602         WideColorTest::init();
603
604         // Only check for pixel format required for this specific run
605         // If not available, check will abort test with "NotSupported"
606         switch (m_redSize)
607         {
608                 case 10:
609                         check1010102Support();
610                         break;
611                 case 16:
612                         checkPixelFloatSupport();
613                         checkFP16Support();
614                         break;
615         }
616
617         if (m_colorSpace != DE_NULL && !eglu::hasExtension(egl, m_eglDisplay, "EGL_KHR_gl_colorspace"))
618                 TCU_THROW(NotSupportedError, "EGL_KHR_gl_colorspace is not supported");
619
620         switch (m_colorSpace) {
621                 case EGL_GL_COLORSPACE_SRGB_KHR:
622                         checkColorSpaceSupport();
623                         break;
624                 case EGL_GL_COLORSPACE_DISPLAY_P3_EXT:
625                         checkDisplayP3Support();
626                         break;
627                 case EGL_GL_COLORSPACE_SCRGB_EXT:
628                         checkSCRGBSupport();
629                         break;
630                 case EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT:
631                         checkSCRGBLinearSupport();
632                         break;
633                 default:
634                         break;
635         }
636
637         EGLint numConfigs = 0;
638
639         // Query from EGL implementation
640         EGLU_CHECK_CALL(egl, chooseConfig(m_eglDisplay, &m_attribList[0], DE_NULL, 0, &numConfigs));
641
642         if (numConfigs <= 0)
643         {
644                 log << tcu::TestLog::Message << "No configs returned." << tcu::TestLog::EndMessage;
645                 TCU_FAIL("No configs returned");
646         }
647
648         log << tcu::TestLog::Message << numConfigs << " configs returned" << tcu::TestLog::EndMessage;
649
650         EGLBoolean success = egl.chooseConfig(m_eglDisplay, &m_attribList[0], &m_eglConfig, 1, &numConfigs);
651         if (success != EGL_TRUE)
652         {
653                 log << tcu::TestLog::Message << "Fail, eglChooseConfig returned an error." << tcu::TestLog::EndMessage;
654                 TCU_FAIL("eglChooseConfig failed");
655         }
656         if (numConfigs > 1)
657         {
658                 log << tcu::TestLog::Message << "Fail, more configs returned than requested." << tcu::TestLog::EndMessage;
659                 TCU_FAIL("Too many configs returned");
660         }
661
662         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
663
664         writeEglConfig(m_eglConfig);
665
666 }
667
668 void WideColorSurfaceTest::readPixels (const glw::Functions& gl, float* dataPtr)
669 {
670         gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_FLOAT, dataPtr);
671         GLU_EXPECT_NO_ERROR(m_gl.getError(), "glReadPixels with floats");
672 }
673
674 void WideColorSurfaceTest::readPixels (const glw::Functions& gl, deUint32 *dataPtr)
675 {
676         gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, dataPtr);
677         GLU_EXPECT_NO_ERROR(m_gl.getError(), "glReadPixels with RGBA_1010102 (32bits)");
678 }
679
680 void WideColorSurfaceTest::readPixels (const glw::Functions& gl, deUint8 *dataPtr)
681 {
682         gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, dataPtr);
683         GLU_EXPECT_NO_ERROR(m_gl.getError(), "glReadPixels with RGBA_8888 (8 bit components)");
684 }
685
686 void WideColorSurfaceTest::writeEglConfig (EGLConfig config)
687 {
688         const Library&  egl     = m_eglTestCtx.getLibrary();
689         tcu::TestLog&   log             = m_testCtx.getLog();
690         qpEglConfigInfo info;
691         EGLint                  val             = 0;
692
693         info.bufferSize = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_BUFFER_SIZE);
694
695         info.redSize = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_RED_SIZE);
696
697         info.greenSize = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_GREEN_SIZE);
698
699         info.blueSize = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_BLUE_SIZE);
700
701         info.luminanceSize = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_LUMINANCE_SIZE);
702
703         info.alphaSize = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_ALPHA_SIZE);
704
705         info.alphaMaskSize = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_ALPHA_MASK_SIZE);
706
707         val = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_BIND_TO_TEXTURE_RGB);
708         info.bindToTextureRGB = val == EGL_TRUE ? true : false;
709
710         val = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_BIND_TO_TEXTURE_RGBA);
711         info.bindToTextureRGBA = val == EGL_TRUE ? true : false;
712
713         val = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_COLOR_BUFFER_TYPE);
714         std::string colorBufferType = de::toString(eglu::getColorBufferTypeStr(val));
715         info.colorBufferType = colorBufferType.c_str();
716
717         val = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_CONFIG_CAVEAT);
718         std::string caveat = de::toString(eglu::getConfigCaveatStr(val));
719         info.configCaveat = caveat.c_str();
720
721         info.configID = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_CONFIG_ID);
722
723         val = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_CONFORMANT);
724         std::string conformant = de::toString(eglu::getAPIBitsStr(val));
725         info.conformant = conformant.c_str();
726
727         info.depthSize = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_DEPTH_SIZE);
728
729         info.level = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_LEVEL);
730
731         info.maxPBufferWidth = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_MAX_PBUFFER_WIDTH);
732
733         info.maxPBufferHeight = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_MAX_PBUFFER_HEIGHT);
734
735         info.maxPBufferPixels = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_MAX_PBUFFER_PIXELS);
736
737         info.maxSwapInterval = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_MAX_SWAP_INTERVAL);
738
739         info.minSwapInterval = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_MIN_SWAP_INTERVAL);
740
741         val = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_NATIVE_RENDERABLE);
742         info.nativeRenderable = val == EGL_TRUE ? true : false;
743
744         val = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_RENDERABLE_TYPE);
745         std::string renderableTypes = de::toString(eglu::getAPIBitsStr(val));
746         info.renderableType = renderableTypes.c_str();
747
748         info.sampleBuffers = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_SAMPLE_BUFFERS);
749
750         info.samples = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_SAMPLES);
751
752         info.stencilSize = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_STENCIL_SIZE);
753
754         val = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_SURFACE_TYPE);
755         std::string surfaceTypes = de::toString(eglu::getSurfaceBitsStr(val));
756         info.surfaceTypes = surfaceTypes.c_str();
757
758         val = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_TRANSPARENT_TYPE);
759         std::string transparentType = de::toString(eglu::getTransparentTypeStr(val));
760         info.transparentType = transparentType.c_str();
761
762         info.transparentRedValue = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_TRANSPARENT_RED_VALUE);
763
764         info.transparentGreenValue = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_TRANSPARENT_GREEN_VALUE);
765
766         info.transparentBlueValue = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_TRANSPARENT_BLUE_VALUE);
767
768         log.writeEglConfig(&info);
769 }
770
771 deUint32 WideColorSurfaceTest::expectedUint10 (float reference)
772 {
773         deUint32 expected;
774
775         if (reference < 0.0)
776         {
777                 expected = 0;
778         }
779         else if (reference > 1.0)
780         {
781                 expected = 1023;
782         }
783         else
784         {
785                 expected = static_cast<deUint32>(deRound(reference * 1023.0));
786         }
787
788         return expected;
789 }
790
791 deUint32 WideColorSurfaceTest::expectedUint2 (float reference)
792 {
793         deUint32 expected;
794
795         if (reference < 0.0)
796         {
797                 expected = 0;
798         }
799         else if (reference > 1.0)
800         {
801                 expected = 3;
802         }
803         else
804         {
805                 expected = static_cast<deUint32>(deRound(reference * 3.0));
806         }
807
808         return expected;
809 }
810
811 deUint8 WideColorSurfaceTest::expectedUint8 (float reference)
812 {
813         deUint8 expected;
814         if (reference < 0.0)
815         {
816                 expected = 0;
817         }
818         else if (reference >= 1.0)
819         {
820                 expected = 255;
821         }
822         else
823         {
824                 // Apply sRGB transfer function when colorspace is sRGB and pixel component
825                 // size is 8 bits (which is why we are here in expectedUint8).
826                 if (m_colorSpace == EGL_GL_COLORSPACE_SRGB_KHR)
827                 {
828                         float srgbReference;
829
830                         if (reference <= 0.0031308)
831                         {
832                                 srgbReference = 12.92f * reference;
833                         }
834                         else
835                         {
836                                 float powRef = deFloatPow(reference, (1.0f/2.4f));
837                                 srgbReference = (1.055f * powRef) - 0.055f;
838                         }
839                         expected = static_cast<deUint8>(deRound(srgbReference * 255.0));
840                 }
841                 else
842                 {
843                         expected = static_cast<deUint8>(deRound(reference * 255.0));
844                 }
845         }
846         return expected;
847 }
848
849 deUint8 WideColorSurfaceTest::expectedAlpha8 (float reference)
850 {
851         deUint8 expected;
852         if (reference < 0.0)
853         {
854                 expected = 0;
855         }
856         else if (reference >= 1.0)
857         {
858                 expected = 255;
859         }
860         else
861         {
862                 // The sRGB transfer function is not applied to alpha
863                 expected = static_cast<deUint8>(deRound(reference * 255.0));
864         }
865         return expected;
866 }
867
868 // Return true for value out of range (fail)
869 bool WideColorSurfaceTest::checkWithThreshold8(deUint8 value, deUint8 reference, deUint8 threshold)
870 {
871         const deUint8 low = reference >= threshold ? static_cast<deUint8>(reference - threshold) : 0;
872         const deUint8 high = reference <= (255 - threshold) ? static_cast<deUint8>(reference + threshold) : 255;
873         return !((value >= low) && (value <= high));
874 }
875
876 bool WideColorSurfaceTest::checkWithThreshold10(deUint32 value, deUint32 reference, deUint32 threshold)
877 {
878         const deUint32 low = reference >= threshold ? reference - threshold : 0;
879         const deUint32 high = reference <= (1023 - threshold) ? reference + threshold : 1023;
880         return !((value >= low) && (value <= high));
881 }
882
883 bool WideColorSurfaceTest::checkWithThresholdFloat(float value, float reference, float threshold)
884 {
885         const float low = reference - threshold;
886         const float high = reference + threshold;
887         return !((value >= low) && (value <= high));
888 }
889
890 void WideColorSurfaceTest::testPixels (float reference, float increment)
891 {
892         tcu::TestLog&   log                             = m_testCtx.getLog();
893
894         if (m_componentType == EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT)
895         {
896                 float pixels[16];
897                 const float expected[4] =
898                 {
899                         reference,
900                         reference + increment,
901                         reference - increment,
902                         reference + 2 * increment
903                 };
904                 readPixels(m_gl, pixels);
905
906                 if (checkWithThresholdFloat(pixels[0], expected[0], increment) ||
907                                 checkWithThresholdFloat(pixels[1], expected[1], increment) ||
908                                 checkWithThresholdFloat(pixels[2], expected[2], increment) ||
909                                 checkWithThresholdFloat(pixels[3], expected[3], increment))
910                 {
911                         if (m_debugLog.str().size() > 0)
912                         {
913                                 log << tcu::TestLog::Message
914                                         << "Prior passing tests\n"
915                                         << m_debugLog.str()
916                                         << tcu::TestLog::EndMessage;
917                                 m_debugLog.str("");
918                         }
919                         log << tcu::TestLog::Message
920                                 << "Image comparison failed: "
921                                 << "reference = " << reference
922                                 << ", expected = " << expected[0]
923                                         << ":" << expected[1]
924                                         << ":" << expected[2]
925                                         << ":" << expected[3]
926                                 << ", result = " << pixels[0]
927                                         << ":" << pixels[1]
928                                         << ":" << pixels[2]
929                                         << ":" << pixels[3]
930                                 << tcu::TestLog::EndMessage;
931                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Color test failed");
932                 }
933                 else
934                 {
935                         // Pixel matches expected value
936                         m_debugLog << "Image comparison passed: "
937                                 << "reference = " << reference
938                                 << ", result = " << pixels[0]
939                                         << ":" << pixels[1]
940                                         << ":" << pixels[2]
941                                         << ":" << pixels[3]
942                                 << "\n";
943                 }
944         }
945         else if (m_redSize > 8)
946         {
947                 deUint32 buffer[16];
948                 readPixels(m_gl, buffer);
949                 deUint32 pixels[4];
950                 deUint32 expected[4];
951
952                 pixels[0] = buffer[0] & 0x3ff;
953                 pixels[1] = (buffer[0] >> 10) & 0x3ff;
954                 pixels[2] = (buffer[0] >> 20) & 0x3ff;
955                 pixels[3] = (buffer[0] >> 30) & 0x3;
956
957                 expected[0] = expectedUint10(reference);
958                 expected[1] = expectedUint10(reference + increment);
959                 expected[2] = expectedUint10(reference - increment);
960                 expected[3] = expectedUint2(reference + 2 * increment);
961                 if (checkWithThreshold10(pixels[0], expected[0]) || checkWithThreshold10(pixels[1], expected[1])
962                                 || checkWithThreshold10(pixels[2], expected[2]) || checkWithThreshold10(pixels[3], expected[3]))
963                 {
964                         if (m_debugLog.str().size() > 0) {
965                                 log << tcu::TestLog::Message
966                                         << "Prior passing tests\n"
967                                         << m_debugLog.str()
968                                         << tcu::TestLog::EndMessage;
969                                 m_debugLog.str("");
970                         }
971                         log << tcu::TestLog::Message
972                                 << "Image comparison failed: "
973                                 << "reference = " << reference
974                                 << ", expected = " << static_cast<deUint32>(expected[0])
975                                         << ":" << static_cast<deUint32>(expected[1])
976                                         << ":" << static_cast<deUint32>(expected[2])
977                                         << ":" << static_cast<deUint32>(expected[3])
978                                 << ", result = " << static_cast<deUint32>(pixels[0])
979                                         << ":" << static_cast<deUint32>(pixels[1])
980                                         << ":" << static_cast<deUint32>(pixels[2])
981                                         << ":" << static_cast<deUint32>(pixels[3])
982                                 << tcu::TestLog::EndMessage;
983                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Color test failed");
984                 }
985                 else
986                 {
987                         // Pixel matches expected value
988                         m_debugLog << "Image comparison passed: "
989                                 << "reference = " << reference
990                                 << ", result = " << static_cast<deUint32>(pixels[0])
991                                         << ":" << static_cast<deUint32>(pixels[1])
992                                         << ":" << static_cast<deUint32>(pixels[2])
993                                         << ":" << static_cast<deUint32>(pixels[3])
994                                 << "\n";
995                 }
996         }
997         else
998         {
999                 deUint8 pixels[16];
1000                 deUint8 expected[4];
1001                 readPixels(m_gl, pixels);
1002
1003                 expected[0] = expectedUint8(reference);
1004                 expected[1] = expectedUint8(reference + increment);
1005                 expected[2] = expectedUint8(reference - increment);
1006                 expected[3] = expectedAlpha8(reference + 2 * increment);
1007                 if (checkWithThreshold8(pixels[0], expected[0]) || checkWithThreshold8(pixels[1], expected[1])
1008                                 || checkWithThreshold8(pixels[2], expected[2]) || checkWithThreshold8(pixels[3], expected[3]))
1009                 {
1010                         if (m_debugLog.str().size() > 0) {
1011                                 log << tcu::TestLog::Message
1012                                         << "(C)Prior passing tests\n"
1013                                         << m_debugLog.str()
1014                                         << tcu::TestLog::EndMessage;
1015                                 m_debugLog.str("");
1016                         }
1017                         log << tcu::TestLog::Message
1018                                 << "Image comparison failed: "
1019                                 << "reference = " << reference
1020                                 << ", expected = " << static_cast<deUint32>(expected[0])
1021                                         << ":" << static_cast<deUint32>(expected[1])
1022                                         << ":" << static_cast<deUint32>(expected[2])
1023                                         << ":" << static_cast<deUint32>(expected[3])
1024                                 << ", result = " << static_cast<deUint32>(pixels[0])
1025                                         << ":" << static_cast<deUint32>(pixels[1])
1026                                         << ":" << static_cast<deUint32>(pixels[2])
1027                                         << ":" << static_cast<deUint32>(pixels[3])
1028                                 << tcu::TestLog::EndMessage;
1029                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Color test failed");
1030                 }
1031                 else
1032                 {
1033                         // Pixel matches expected value
1034                         m_debugLog << "Image comparison passed: "
1035                                 << "reference = " << reference
1036                                 << ", result = " << static_cast<deUint32>(pixels[0])
1037                                         << ":" << static_cast<deUint32>(pixels[1])
1038                                         << ":" << static_cast<deUint32>(pixels[2])
1039                                         << ":" << static_cast<deUint32>(pixels[3])
1040                                 << "\n";
1041                 }
1042         }
1043 }
1044
1045 void WideColorSurfaceTest::doClearTest (EGLSurface surface)
1046 {
1047         tcu::TestLog&   log                             = m_testCtx.getLog();
1048         const Library&  egl                             = m_eglTestCtx.getLibrary();
1049         const EGLint    attribList[]    =
1050         {
1051                 EGL_CONTEXT_CLIENT_VERSION, 2,
1052                 EGL_NONE
1053         };
1054         EGLContext              eglContext              = egl.createContext(m_eglDisplay, m_eglConfig, EGL_NO_CONTEXT, attribList);
1055         EGLU_CHECK_MSG(egl, "eglCreateContext");
1056
1057         egl.makeCurrent(m_eglDisplay, surface, surface, eglContext);
1058         EGLU_CHECK_MSG(egl, "eglMakeCurrent");
1059
1060         {
1061                 // put gles2Renderer inside it's own scope so that it's cleaned
1062                 // up before we hit the destroyContext
1063                 const GLES2Renderer gles2Renderer(m_gl, 128, 128);
1064
1065                 std::vector<Iteration>::const_iterator it;      // declare an Iterator to a vector of strings
1066                 log << tcu::TestLog::Message << "m_iterations.count = " << m_iterations.size() << tcu::TestLog::EndMessage;
1067                 for(it = m_iterations.begin() ; it < m_iterations.end(); it++)
1068                 {
1069                         float reference = it->start;
1070                         log << tcu::TestLog::Message << "start = " << it->start
1071                                                 << tcu::TestLog::EndMessage;
1072                         log << tcu::TestLog::Message
1073                                                 << "increment = " << it->increment
1074                                                 << tcu::TestLog::EndMessage;
1075                         log << tcu::TestLog::Message
1076                                                 << "count = " << it->iterationCount
1077                                                 << tcu::TestLog::EndMessage;
1078                         m_debugLog.str("");
1079                         for (int iterationCount = 0; iterationCount < it->iterationCount; iterationCount++)
1080                         {
1081                                 const Color     clearColor(reference, reference + it->increment, reference - it->increment, reference + 2 * it->increment);
1082
1083                                 clearColorScreen(m_gl, clearColor);
1084                                 GLU_EXPECT_NO_ERROR(m_gl.getError(), "Clear to test value");
1085
1086                                 testPixels(reference, it->increment);
1087
1088                                 // reset buffer contents so that we know render below did something
1089                                 const Color     clearColor2(1.0f - reference, 1.0f, 1.0f, 1.0f);
1090                                 clearColorScreen(m_gl, clearColor2);
1091                                 GLU_EXPECT_NO_ERROR(m_gl.getError(), "Clear to 1.0f - reference value");
1092
1093                                 const ColoredRect       coloredRect     (IVec2(0.0f, 0.0f), IVec2(1.0f, 1.0f), clearColor);
1094                                 gles2Renderer.render(coloredRect);
1095                                 testPixels(reference, it->increment);
1096
1097                                 reference += it->increment;
1098                         }
1099
1100                         EGLU_CHECK_CALL(egl, swapBuffers(m_eglDisplay, surface));
1101                 }
1102         }
1103
1104         // disconnect surface & context so they can be destroyed when
1105         // this function exits.
1106         EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
1107
1108         egl.destroyContext(m_eglDisplay, eglContext);
1109 }
1110
1111 void WideColorSurfaceTest::executeTest (void)
1112 {
1113         tcu::TestLog&                                           log                             = m_testCtx.getLog();
1114         const Library&                                          egl                             = m_eglTestCtx.getLibrary();
1115         const eglu::NativeDisplayFactory&       displayFactory  = m_eglTestCtx.getNativeDisplayFactory();
1116         eglu::NativeDisplay&                            nativeDisplay   = m_eglTestCtx.getNativeDisplay();
1117         egl.bindAPI(EGL_OPENGL_ES_API);
1118
1119         if (m_surfaceType & EGL_PBUFFER_BIT)
1120         {
1121                 log << tcu::TestLog::Message << "Test Pbuffer" << tcu::TestLog::EndMessage;
1122
1123                 std::vector<EGLint>                     attribs;
1124                 attribs.push_back(EGL_WIDTH);
1125                 attribs.push_back(128);
1126                 attribs.push_back(EGL_HEIGHT);
1127                 attribs.push_back(128);
1128                 if (m_colorSpace != EGL_NONE)
1129                 {
1130                         attribs.push_back(EGL_GL_COLORSPACE_KHR);
1131                         attribs.push_back(m_colorSpace);
1132                 }
1133                 attribs.push_back(EGL_NONE);
1134                 attribs.push_back(EGL_NONE);
1135                 const EGLSurface surface = egl.createPbufferSurface(m_eglDisplay, m_eglConfig, attribs.data());
1136                 if ((surface == EGL_NO_SURFACE) && (egl.getError() == EGL_BAD_MATCH))
1137                 {
1138                         TCU_THROW(NotSupportedError, "Colorspace is not supported with this format");
1139                 }
1140                 TCU_CHECK(surface != EGL_NO_SURFACE);
1141                 EGLU_CHECK_MSG(egl, "eglCreatePbufferSurface()");
1142
1143                 doClearTest(surface);
1144
1145                 egl.destroySurface(m_eglDisplay, surface);
1146                 EGLU_CHECK_MSG(egl, "eglDestroySurface()");
1147         }
1148         else if (m_surfaceType & EGL_WINDOW_BIT)
1149         {
1150                 log << tcu::TestLog::Message << "Test Window" << tcu::TestLog::EndMessage;
1151
1152                 const eglu::NativeWindowFactory&        windowFactory   = eglu::selectNativeWindowFactory(displayFactory, m_testCtx.getCommandLine());
1153
1154                 de::UniquePtr<eglu::NativeWindow>       window                  (windowFactory.createWindow(&nativeDisplay, m_eglDisplay, m_eglConfig, DE_NULL, eglu::WindowParams(128, 128, eglu::parseWindowVisibility(m_testCtx.getCommandLine()))));
1155                 std::vector<EGLAttrib>          attribs;
1156                 if (m_colorSpace != EGL_NONE)
1157                 {
1158                         attribs.push_back(EGL_GL_COLORSPACE_KHR);
1159                         attribs.push_back(m_colorSpace);
1160                 }
1161                 attribs.push_back(EGL_NONE);
1162                 attribs.push_back(EGL_NONE);
1163
1164                 const EGLSurface                                        surface                 = eglu::createWindowSurface(nativeDisplay, *window, m_eglDisplay, m_eglConfig, attribs.data());
1165                 TCU_CHECK(surface != EGL_NO_SURFACE);
1166                 EGLU_CHECK_MSG(egl, "eglCreateWindowSurface()");
1167
1168                 doClearTest(surface);
1169
1170                 egl.destroySurface(m_eglDisplay, surface);
1171                 EGLU_CHECK_MSG(egl, "eglDestroySurface()");
1172         }
1173         else if (m_surfaceType & EGL_PIXMAP_BIT)
1174         {
1175                 log << tcu::TestLog::Message << "Test Pixmap" << tcu::TestLog::EndMessage;
1176
1177                 const eglu::NativePixmapFactory&        pixmapFactory   = eglu::selectNativePixmapFactory(displayFactory, m_testCtx.getCommandLine());
1178
1179                 de::UniquePtr<eglu::NativePixmap>       pixmap                  (pixmapFactory.createPixmap(&nativeDisplay, m_eglDisplay, m_eglConfig, DE_NULL, 128, 128));
1180                 const EGLSurface                                        surface                 = eglu::createPixmapSurface(nativeDisplay, *pixmap, m_eglDisplay, m_eglConfig, DE_NULL);
1181                 TCU_CHECK(surface != EGL_NO_SURFACE);
1182                 EGLU_CHECK_MSG(egl, "eglCreatePixmapSurface()");
1183
1184                 doClearTest(surface);
1185
1186                 egl.destroySurface(m_eglDisplay, surface);
1187                 EGLU_CHECK_MSG(egl, "eglDestroySurface()");
1188         }
1189         else
1190                 TCU_FAIL("No valid surface types supported in config");
1191 }
1192
1193 TestCase::IterateResult WideColorSurfaceTest::iterate (void)
1194 {
1195         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1196         executeTest();
1197         return STOP;
1198 }
1199
1200 } // anonymous
1201
1202 WideColorTests::WideColorTests (EglTestContext& eglTestCtx)
1203         : TestCaseGroup(eglTestCtx, "wide_color", "Wide Color tests")
1204 {
1205 }
1206
1207 void WideColorTests::init (void)
1208 {
1209         addChild(new WideColorFP16Test(m_eglTestCtx, "fp16", "Verify that FP16 pixel format is present"));
1210         addChild(new WideColor1010102Test(m_eglTestCtx, "1010102", "Check if 1010102 pixel format is present"));
1211
1212         // This is an increment FP16 can do between -1.0 to 1.0
1213         const float fp16Increment1 = deFloatPow(2.0, -11.0);
1214         // This is an increment FP16 can do between 1.0 to 2.0
1215         const float fp16Increment2 = deFloatPow(2.0, -10.0);
1216
1217         const EGLint windowAttribListFP16[] =
1218         {
1219                 EGL_SURFACE_TYPE,                               EGL_WINDOW_BIT,
1220                 EGL_RENDERABLE_TYPE,                    EGL_OPENGL_ES2_BIT,
1221                 EGL_RED_SIZE,                                   16,
1222                 EGL_GREEN_SIZE,                                 16,
1223                 EGL_BLUE_SIZE,                                  16,
1224                 EGL_ALPHA_SIZE,                                 16,
1225                 EGL_COLOR_COMPONENT_TYPE_EXT,   EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT,
1226                 EGL_NONE,                                               EGL_NONE
1227         };
1228
1229         std::vector<Iteration> fp16Iterations;
1230         // -0.333251953125f ~ -1/3 as seen in FP16
1231         fp16Iterations.push_back(Iteration(-0.333251953125f, fp16Increment1, 10));
1232         // test crossing 0
1233         fp16Iterations.push_back( Iteration(-fp16Increment1 * 5.0f, fp16Increment1, 10));
1234         // test crossing 1.0
1235         fp16Iterations.push_back( Iteration(1.0f - fp16Increment2 * 5.0f, fp16Increment2, 10));
1236         addChild(new WideColorSurfaceTest(m_eglTestCtx, "window_fp16_default_colorspace", "FP16 window surface has FP16 pixels in it", windowAttribListFP16, DE_NULL, fp16Iterations));
1237         addChild(new WideColorSurfaceTest(m_eglTestCtx, "window_fp16_colorspace_srgb", "FP16 window surface, explicit sRGB colorspace", windowAttribListFP16, EGL_GL_COLORSPACE_SRGB_KHR, fp16Iterations));
1238         addChild(new WideColorSurfaceTest(m_eglTestCtx, "window_fp16_colorspace_p3", "FP16 window surface, explicit Display-P3 colorspace", windowAttribListFP16, EGL_GL_COLORSPACE_DISPLAY_P3_EXT, fp16Iterations));
1239         addChild(new WideColorSurfaceTest(m_eglTestCtx, "window_fp16_colorspace_scrgb", "FP16 window surface, explicit scRGB colorspace", windowAttribListFP16, EGL_GL_COLORSPACE_SCRGB_EXT, fp16Iterations));
1240         addChild(new WideColorSurfaceTest(m_eglTestCtx, "window_fp16_colorspace_scrgb_linear", "FP16 window surface, explicit scRGB linear colorspace", windowAttribListFP16, EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT, fp16Iterations));
1241
1242         const EGLint pbufferAttribListFP16[] =
1243         {
1244                 EGL_SURFACE_TYPE,                               EGL_PBUFFER_BIT,
1245                 EGL_RENDERABLE_TYPE,                    EGL_OPENGL_ES2_BIT,
1246                 EGL_RED_SIZE,                                   16,
1247                 EGL_GREEN_SIZE,                                 16,
1248                 EGL_BLUE_SIZE,                                  16,
1249                 EGL_ALPHA_SIZE,                                 16,
1250                 EGL_COLOR_COMPONENT_TYPE_EXT,   EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT,
1251                 EGL_NONE,                                               EGL_NONE
1252         };
1253         addChild(new WideColorSurfaceTest(m_eglTestCtx, "pbuffer_fp16_default_colorspace", "FP16 pbuffer surface has FP16 pixels in it", pbufferAttribListFP16, DE_NULL, fp16Iterations));
1254         addChild(new WideColorSurfaceTest(m_eglTestCtx, "pbuffer_fp16_colorspace_srgb", "FP16 pbuffer surface, explicit sRGB colorspace", pbufferAttribListFP16, EGL_GL_COLORSPACE_SRGB_KHR, fp16Iterations));
1255         addChild(new WideColorSurfaceTest(m_eglTestCtx, "pbuffer_fp16_colorspace_p3", "FP16 pbuffer surface, explicit Display-P3 colorspace", pbufferAttribListFP16, EGL_GL_COLORSPACE_DISPLAY_P3_EXT, fp16Iterations));
1256         addChild(new WideColorSurfaceTest(m_eglTestCtx, "pbuffer_fp16_colorspace_scrgb", "FP16 pbuffer surface, explicit scRGB colorspace", pbufferAttribListFP16, EGL_GL_COLORSPACE_SCRGB_EXT, fp16Iterations));
1257         addChild(new WideColorSurfaceTest(m_eglTestCtx, "pbuffer_fp16_colorspace_scrgb_linear", "FP16 pbuffer surface, explicit scRGB linear colorspace", pbufferAttribListFP16, EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT, fp16Iterations));
1258
1259         const EGLint windowAttribList1010102[] =
1260         {
1261                 EGL_SURFACE_TYPE,                               EGL_WINDOW_BIT,
1262                 EGL_RENDERABLE_TYPE,                    EGL_OPENGL_ES2_BIT,
1263                 EGL_RED_SIZE,                                   10,
1264                 EGL_GREEN_SIZE,                                 10,
1265                 EGL_BLUE_SIZE,                                  10,
1266                 EGL_ALPHA_SIZE,                                 2,
1267                 EGL_NONE,                                               EGL_NONE
1268         };
1269
1270         std::vector<Iteration> int1010102Iterations;
1271         // -0.333251953125f ~ -1/3 as seen in fp16
1272         // Negative values will be 0 on read with fixed point pixel formats
1273         int1010102Iterations.push_back(Iteration(-0.333251953125f, fp16Increment1, 10));
1274         // test crossing 0
1275         int1010102Iterations.push_back(Iteration(-fp16Increment1 * 5.0f, fp16Increment1, 10));
1276         // test crossing 1.0
1277         // Values > 1.0 will be truncated to 1.0 with fixed point pixel formats
1278         int1010102Iterations.push_back(Iteration(1.0f - fp16Increment2 * 5.0f, fp16Increment2, 10));
1279         addChild(new WideColorSurfaceTest(m_eglTestCtx, "window_1010102_colorspace_default", "1010102 Window surface, default (sRGB) colorspace", windowAttribList1010102, DE_NULL, int1010102Iterations));
1280         addChild(new WideColorSurfaceTest(m_eglTestCtx, "window_1010102_colorspace_srgb", "1010102 Window surface, explicit sRGB colorspace", windowAttribList1010102, EGL_GL_COLORSPACE_SRGB_KHR, int1010102Iterations));
1281         addChild(new WideColorSurfaceTest(m_eglTestCtx, "window_1010102_colorspace_p3", "1010102 Window surface, explicit Display-P3 colorspace", windowAttribList1010102, EGL_GL_COLORSPACE_DISPLAY_P3_EXT, int1010102Iterations));
1282
1283         const EGLint pbufferAttribList1010102[] =
1284         {
1285                 EGL_SURFACE_TYPE,                               EGL_PBUFFER_BIT,
1286                 EGL_RENDERABLE_TYPE,                    EGL_OPENGL_ES2_BIT,
1287                 EGL_RED_SIZE,                                   10,
1288                 EGL_GREEN_SIZE,                                 10,
1289                 EGL_BLUE_SIZE,                                  10,
1290                 EGL_ALPHA_SIZE,                                 2,
1291                 EGL_NONE,                                               EGL_NONE
1292         };
1293         addChild(new WideColorSurfaceTest(m_eglTestCtx, "pbuffer_1010102_colorspace_default", "1010102 pbuffer surface, default (sRGB) colorspace", pbufferAttribList1010102, DE_NULL, int1010102Iterations));
1294         addChild(new WideColorSurfaceTest(m_eglTestCtx, "pbuffer_1010102_colorspace_srgb", "1010102 pbuffer surface, explicit sRGB colorspace", pbufferAttribList1010102, EGL_GL_COLORSPACE_SRGB_KHR, int1010102Iterations));
1295         addChild(new WideColorSurfaceTest(m_eglTestCtx, "pbuffer_1010102_colorspace_p3", "1010102 pbuffer surface, explicit Display-P3 colorspace", pbufferAttribList1010102, EGL_GL_COLORSPACE_DISPLAY_P3_EXT, int1010102Iterations));
1296
1297         const EGLint windowAttribList8888[] =
1298         {
1299                 EGL_SURFACE_TYPE,                               EGL_WINDOW_BIT,
1300                 EGL_RENDERABLE_TYPE,                    EGL_OPENGL_ES2_BIT,
1301                 EGL_RED_SIZE,                                   8,
1302                 EGL_GREEN_SIZE,                                 8,
1303                 EGL_BLUE_SIZE,                                  8,
1304                 EGL_ALPHA_SIZE,                                 8,
1305                 EGL_NONE,                                               EGL_NONE
1306         };
1307
1308         std::vector<Iteration> int8888Iterations;
1309         // -0.333251953125f ~ -1/3 as seen in fp16
1310         // Negative values will be 0 on read with fixed point pixel formats
1311         int8888Iterations.push_back(Iteration(-0.333251953125f, fp16Increment1, 10));
1312         // test crossing 0
1313         int8888Iterations.push_back(Iteration(-fp16Increment1 * 5.0f, fp16Increment1, 10));
1314         // test crossing 1.0
1315         // Values > 1.0 will be truncated to 1.0 with fixed point pixel formats
1316         int8888Iterations.push_back(Iteration(1.0f - fp16Increment2 * 5.0f, fp16Increment2, 10));
1317         addChild(new WideColorSurfaceTest(m_eglTestCtx, "window_8888_colorspace_default", "8888 window surface, default (sRGB) colorspace", windowAttribList8888, DE_NULL, int8888Iterations));
1318         addChild(new WideColorSurfaceTest(m_eglTestCtx, "window_8888_colorspace_srgb", "8888 window surface, explicit sRGB colorspace", windowAttribList8888, EGL_GL_COLORSPACE_SRGB_KHR, int8888Iterations));
1319         addChild(new WideColorSurfaceTest(m_eglTestCtx, "window_8888_colorspace_p3", "8888 window surface, explicit Display-P3 colorspace", windowAttribList8888, EGL_GL_COLORSPACE_DISPLAY_P3_EXT, int8888Iterations));
1320
1321         const EGLint pbufferAttribList8888[] =
1322         {
1323                 EGL_SURFACE_TYPE,                               EGL_PBUFFER_BIT,
1324                 EGL_RENDERABLE_TYPE,                    EGL_OPENGL_ES2_BIT,
1325                 EGL_RED_SIZE,                                   8,
1326                 EGL_GREEN_SIZE,                                 8,
1327                 EGL_BLUE_SIZE,                                  8,
1328                 EGL_ALPHA_SIZE,                                 8,
1329                 EGL_NONE,                                               EGL_NONE
1330         };
1331         addChild(new WideColorSurfaceTest(m_eglTestCtx, "pbuffer_8888_colorspace_default", "8888 pbuffer surface, default (sRGB) colorspace", pbufferAttribList8888, DE_NULL, int8888Iterations));
1332         addChild(new WideColorSurfaceTest(m_eglTestCtx, "pbuffer_8888_colorspace_srgb", "8888 pbuffer surface, explicit sRGB colorspace", pbufferAttribList8888, EGL_GL_COLORSPACE_SRGB_KHR, int8888Iterations));
1333         addChild(new WideColorSurfaceTest(m_eglTestCtx, "pbuffer_8888_colorspace_p3", "8888 pbuffer surface, explicit Display-P3 colorspace", pbufferAttribList8888, EGL_GL_COLORSPACE_DISPLAY_P3_EXT, int8888Iterations));
1334 }
1335
1336 TestCaseGroup* createWideColorTests (EglTestContext& eglTestCtx)
1337 {
1338         return new WideColorTests(eglTestCtx);
1339 }
1340
1341 } // egl
1342 } // deqp