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