Merge vk-gl-cts/vulkan-cts-1.1.2 into vk-gl-cts/vulkan-cts-1.1.3
[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_requestedRedSize;
591         EGLint                                                          m_redSize;
592         EGLint                                                          m_alphaSize;
593         EGLint                                                          m_colorSpace;
594         const std::vector<struct Iteration> m_iterations;
595         std::stringstream                                       m_debugLog;
596 };
597
598 WideColorSurfaceTest::WideColorSurfaceTest (EglTestContext& eglTestCtx, const char* name, const char* description, const EGLint* attribList, EGLint colorSpace, const std::vector<struct Iteration>& iterations)
599         : WideColorTest                 (eglTestCtx, name, description)
600         , m_surfaceType                 (0)
601         , m_componentType               (EGL_COLOR_COMPONENT_TYPE_FIXED_EXT)
602         , m_requestedRedSize    (0)
603         , m_redSize                             (0)
604         , m_alphaSize                   (0)
605         , m_colorSpace                  (colorSpace)
606         , m_iterations                  (iterations)
607 {
608         deUint32 idx = 0;
609         while (attribList[idx] != EGL_NONE)
610         {
611                 if (attribList[idx] == EGL_COLOR_COMPONENT_TYPE_EXT)
612                 {
613                         m_componentType = attribList[idx + 1];
614                 }
615                 else if (attribList[idx] == EGL_SURFACE_TYPE)
616                 {
617                         m_surfaceType = attribList[idx+1];
618                 }
619                 else if (attribList[idx] == EGL_RED_SIZE)
620                 {
621                         m_requestedRedSize = attribList[idx + 1];
622                 }
623                 m_attribList.push_back(attribList[idx++]);
624                 m_attribList.push_back(attribList[idx++]);
625         }
626         m_attribList.push_back(EGL_NONE);
627 }
628
629 void WideColorSurfaceTest::addTestAttributes(const EGLint *attributes)
630 {
631         deUint32 idx = 0;
632         if (attributes == DE_NULL) return;
633
634         while (attributes[idx] != EGL_NONE)
635         {
636                 m_testAttribList.push_back(attributes[idx++]);
637                 m_testAttribList.push_back(attributes[idx++]);
638         }
639 }
640
641 void WideColorSurfaceTest::init (void)
642 {
643         const Library&  egl     = m_eglTestCtx.getLibrary();
644         tcu::TestLog&   log     = m_testCtx.getLog();
645
646         WideColorTest::init();
647
648         // Only check for pixel format required for this specific run
649         // If not available, check will abort test with "NotSupported"
650         switch (m_requestedRedSize)
651         {
652                 case 10:
653                         check1010102Support();
654                         break;
655                 case 16:
656                         checkPixelFloatSupport();
657                         checkFP16Support();
658                         break;
659         }
660
661         if (m_colorSpace != EGL_NONE && !eglu::hasExtension(egl, m_eglDisplay, "EGL_KHR_gl_colorspace"))
662                 TCU_THROW(NotSupportedError, "EGL_KHR_gl_colorspace is not supported");
663
664         switch (m_colorSpace) {
665                 case EGL_GL_COLORSPACE_SRGB_KHR:
666                         checkColorSpaceSupport();
667                         break;
668                 case EGL_GL_COLORSPACE_DISPLAY_P3_EXT:
669                         checkDisplayP3Support();
670                         break;
671                 case EGL_GL_COLORSPACE_SCRGB_EXT:
672                         checkSCRGBSupport();
673                         break;
674                 case EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT:
675                         checkSCRGBLinearSupport();
676                         break;
677                 case EGL_GL_COLORSPACE_BT2020_LINEAR_EXT:
678                         checkbt2020linear();
679                         break;
680                 case EGL_GL_COLORSPACE_BT2020_PQ_EXT:
681                         checkbt2020pq();
682                         break;
683                 default:
684                         break;
685         }
686
687         EGLint numConfigs = 0;
688
689         // Query from EGL implementation
690         EGLU_CHECK_CALL(egl, chooseConfig(m_eglDisplay, &m_attribList[0], DE_NULL, 0, &numConfigs));
691
692         if (numConfigs <= 0)
693         {
694                 log << tcu::TestLog::Message << "No configs returned." << tcu::TestLog::EndMessage;
695                 TCU_THROW(NotSupportedError, "No configs available with the requested attributes");
696         }
697
698         log << tcu::TestLog::Message << numConfigs << " configs returned" << tcu::TestLog::EndMessage;
699
700         EGLBoolean success = egl.chooseConfig(m_eglDisplay, &m_attribList[0], &m_eglConfig, 1, &numConfigs);
701         if (success != EGL_TRUE)
702         {
703                 log << tcu::TestLog::Message << "Fail, eglChooseConfig returned an error." << tcu::TestLog::EndMessage;
704                 TCU_FAIL("eglChooseConfig failed");
705         }
706         if (numConfigs > 1)
707         {
708                 log << tcu::TestLog::Message << "Fail, more configs returned than requested." << tcu::TestLog::EndMessage;
709                 TCU_FAIL("Too many configs returned");
710         }
711
712         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
713
714         m_redSize = eglu::getConfigAttribInt(egl, m_eglDisplay, m_eglConfig, EGL_RED_SIZE);
715         m_alphaSize = eglu::getConfigAttribInt(egl, m_eglDisplay, m_eglConfig, EGL_ALPHA_SIZE);
716         writeEglConfig(m_eglConfig);
717 }
718
719 void WideColorSurfaceTest::readPixels (const glw::Functions& gl, float* dataPtr)
720 {
721         gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_FLOAT, dataPtr);
722         GLU_EXPECT_NO_ERROR(m_gl.getError(), "glReadPixels with floats");
723 }
724
725 void WideColorSurfaceTest::readPixels (const glw::Functions& gl, deUint32 *dataPtr)
726 {
727         gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, dataPtr);
728         GLU_EXPECT_NO_ERROR(m_gl.getError(), "glReadPixels with RGBA_1010102 (32bits)");
729 }
730
731 void WideColorSurfaceTest::readPixels (const glw::Functions& gl, deUint8 *dataPtr)
732 {
733         gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, dataPtr);
734         GLU_EXPECT_NO_ERROR(m_gl.getError(), "glReadPixels with RGBA_8888 (8 bit components)");
735 }
736
737 void WideColorSurfaceTest::writeEglConfig (EGLConfig config)
738 {
739         const Library&  egl     = m_eglTestCtx.getLibrary();
740         tcu::TestLog&   log             = m_testCtx.getLog();
741         qpEglConfigInfo info;
742         EGLint                  val             = 0;
743
744         info.bufferSize = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_BUFFER_SIZE);
745
746         info.redSize = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_RED_SIZE);
747
748         info.greenSize = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_GREEN_SIZE);
749
750         info.blueSize = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_BLUE_SIZE);
751
752         info.luminanceSize = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_LUMINANCE_SIZE);
753
754         info.alphaSize = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_ALPHA_SIZE);
755
756         info.alphaMaskSize = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_ALPHA_MASK_SIZE);
757
758         val = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_BIND_TO_TEXTURE_RGB);
759         info.bindToTextureRGB = val == EGL_TRUE ? true : false;
760
761         val = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_BIND_TO_TEXTURE_RGBA);
762         info.bindToTextureRGBA = val == EGL_TRUE ? true : false;
763
764         val = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_COLOR_BUFFER_TYPE);
765         std::string colorBufferType = de::toString(eglu::getColorBufferTypeStr(val));
766         info.colorBufferType = colorBufferType.c_str();
767
768         val = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_CONFIG_CAVEAT);
769         std::string caveat = de::toString(eglu::getConfigCaveatStr(val));
770         info.configCaveat = caveat.c_str();
771
772         info.configID = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_CONFIG_ID);
773
774         val = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_CONFORMANT);
775         std::string conformant = de::toString(eglu::getAPIBitsStr(val));
776         info.conformant = conformant.c_str();
777
778         info.depthSize = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_DEPTH_SIZE);
779
780         info.level = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_LEVEL);
781
782         info.maxPBufferWidth = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_MAX_PBUFFER_WIDTH);
783
784         info.maxPBufferHeight = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_MAX_PBUFFER_HEIGHT);
785
786         info.maxPBufferPixels = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_MAX_PBUFFER_PIXELS);
787
788         info.maxSwapInterval = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_MAX_SWAP_INTERVAL);
789
790         info.minSwapInterval = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_MIN_SWAP_INTERVAL);
791
792         val = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_NATIVE_RENDERABLE);
793         info.nativeRenderable = val == EGL_TRUE ? true : false;
794
795         val = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_RENDERABLE_TYPE);
796         std::string renderableTypes = de::toString(eglu::getAPIBitsStr(val));
797         info.renderableType = renderableTypes.c_str();
798
799         info.sampleBuffers = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_SAMPLE_BUFFERS);
800
801         info.samples = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_SAMPLES);
802
803         info.stencilSize = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_STENCIL_SIZE);
804
805         val = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_SURFACE_TYPE);
806         std::string surfaceTypes = de::toString(eglu::getSurfaceBitsStr(val));
807         info.surfaceTypes = surfaceTypes.c_str();
808
809         val = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_TRANSPARENT_TYPE);
810         std::string transparentType = de::toString(eglu::getTransparentTypeStr(val));
811         info.transparentType = transparentType.c_str();
812
813         info.transparentRedValue = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_TRANSPARENT_RED_VALUE);
814
815         info.transparentGreenValue = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_TRANSPARENT_GREEN_VALUE);
816
817         info.transparentBlueValue = eglu::getConfigAttribInt(egl, m_eglDisplay, config, EGL_TRANSPARENT_BLUE_VALUE);
818
819         log.writeEglConfig(&info);
820 }
821
822 deUint32 WideColorSurfaceTest::expectedUint10 (float reference)
823 {
824         deUint32 expected;
825
826         if (reference < 0.0)
827         {
828                 expected = 0;
829         }
830         else if (reference > 1.0)
831         {
832                 expected = 1023;
833         }
834         else
835         {
836                 expected = static_cast<deUint32>(deRound(reference * 1023.0));
837         }
838
839         return expected;
840 }
841
842 deUint32 WideColorSurfaceTest::expectedUint2 (float reference)
843 {
844         deUint32 expected;
845
846         if (reference < 0.0)
847         {
848                 expected = 0;
849         }
850         else if (reference > 1.0)
851         {
852                 expected = 3;
853         }
854         else
855         {
856                 expected = static_cast<deUint32>(deRound(reference * 3.0));
857         }
858
859         return expected;
860 }
861
862 deUint8 WideColorSurfaceTest::expectedUint8 (float reference)
863 {
864         deUint8 expected;
865         if (reference < 0.0)
866         {
867                 expected = 0;
868         }
869         else if (reference >= 1.0)
870         {
871                 expected = 255;
872         }
873         else
874         {
875                 // Apply sRGB transfer function when colorspace is sRGB or Display P3 and
876                 // pixel component size is 8 bits (which is why we are here in expectedUint8).
877                 if (m_colorSpace == EGL_GL_COLORSPACE_SRGB_KHR ||
878                                 m_colorSpace == EGL_GL_COLORSPACE_DISPLAY_P3_EXT)
879                 {
880                         float srgbReference;
881
882                         if (reference <= 0.0031308)
883                         {
884                                 srgbReference = 12.92f * reference;
885                         }
886                         else
887                         {
888                                 float powRef = deFloatPow(reference, (1.0f/2.4f));
889                                 srgbReference = (1.055f * powRef) - 0.055f;
890                         }
891                         expected = static_cast<deUint8>(deRound(srgbReference * 255.0));
892                 }
893                 else
894                 {
895                         expected = static_cast<deUint8>(deRound(reference * 255.0));
896                 }
897         }
898         return expected;
899 }
900
901 deUint8 WideColorSurfaceTest::expectedAlpha8 (float reference)
902 {
903         deUint8 expected;
904         if (m_alphaSize == 0)
905         {
906                 // Surfaces without alpha are read back as opaque.
907                 expected = 255;
908         }
909         else if (reference < 0.0)
910         {
911                 expected = 0;
912         }
913         else if (reference >= 1.0)
914         {
915                 expected = 255;
916         }
917         else
918         {
919                 // The sRGB transfer function is not applied to alpha
920                 expected = static_cast<deUint8>(deRound(reference * 255.0));
921         }
922         return expected;
923 }
924
925 // Return true for value out of range (fail)
926 bool WideColorSurfaceTest::checkWithThreshold8(deUint8 value, deUint8 reference, deUint8 threshold)
927 {
928         const deUint8 low = reference >= threshold ? static_cast<deUint8>(reference - threshold) : 0;
929         const deUint8 high = reference <= (255 - threshold) ? static_cast<deUint8>(reference + threshold) : 255;
930         return !((value >= low) && (value <= high));
931 }
932
933 bool WideColorSurfaceTest::checkWithThreshold10(deUint32 value, deUint32 reference, deUint32 threshold)
934 {
935         const deUint32 low = reference >= threshold ? reference - threshold : 0;
936         const deUint32 high = reference <= (1023 - threshold) ? reference + threshold : 1023;
937         return !((value >= low) && (value <= high));
938 }
939
940 bool WideColorSurfaceTest::checkWithThresholdFloat(float value, float reference, float threshold)
941 {
942         const float low = reference - threshold;
943         const float high = reference + threshold;
944         return !((value >= low) && (value <= high));
945 }
946
947 void WideColorSurfaceTest::testPixels (float reference, float increment)
948 {
949         tcu::TestLog&   log                             = m_testCtx.getLog();
950
951         if (m_componentType == EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT)
952         {
953                 float pixels[16];
954                 const float expected[4] =
955                 {
956                         reference,
957                         reference + increment,
958                         reference - increment,
959                         reference + 2 * increment
960                 };
961                 readPixels(m_gl, pixels);
962
963                 if (checkWithThresholdFloat(pixels[0], expected[0], increment) ||
964                                 checkWithThresholdFloat(pixels[1], expected[1], increment) ||
965                                 checkWithThresholdFloat(pixels[2], expected[2], increment) ||
966                                 checkWithThresholdFloat(pixels[3], expected[3], increment))
967                 {
968                         if (m_debugLog.str().size() > 0)
969                         {
970                                 log << tcu::TestLog::Message
971                                         << "Prior passing tests\n"
972                                         << m_debugLog.str()
973                                         << tcu::TestLog::EndMessage;
974                                 m_debugLog.str("");
975                         }
976                         log << tcu::TestLog::Message
977                                 << "Image comparison failed: "
978                                 << "reference = " << reference
979                                 << ", expected = " << expected[0]
980                                         << ":" << expected[1]
981                                         << ":" << expected[2]
982                                         << ":" << expected[3]
983                                 << ", result = " << pixels[0]
984                                         << ":" << pixels[1]
985                                         << ":" << pixels[2]
986                                         << ":" << pixels[3]
987                                 << tcu::TestLog::EndMessage;
988                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Color test failed");
989                 }
990                 else
991                 {
992                         // Pixel matches expected value
993                         m_debugLog << "Image comparison passed: "
994                                 << "reference = " << reference
995                                 << ", result = " << pixels[0]
996                                         << ":" << pixels[1]
997                                         << ":" << pixels[2]
998                                         << ":" << pixels[3]
999                                 << "\n";
1000                 }
1001         }
1002         else if (m_redSize > 8)
1003         {
1004                 deUint32 buffer[16];
1005                 readPixels(m_gl, buffer);
1006                 deUint32 pixels[4];
1007                 deUint32 expected[4];
1008
1009                 pixels[0] = buffer[0] & 0x3ff;
1010                 pixels[1] = (buffer[0] >> 10) & 0x3ff;
1011                 pixels[2] = (buffer[0] >> 20) & 0x3ff;
1012                 pixels[3] = (buffer[0] >> 30) & 0x3;
1013
1014                 expected[0] = expectedUint10(reference);
1015                 expected[1] = expectedUint10(reference + increment);
1016                 expected[2] = expectedUint10(reference - increment);
1017                 expected[3] = expectedUint2(reference + 2 * increment);
1018                 if (checkWithThreshold10(pixels[0], expected[0]) || checkWithThreshold10(pixels[1], expected[1])
1019                                 || checkWithThreshold10(pixels[2], expected[2]) || checkWithThreshold10(pixels[3], expected[3]))
1020                 {
1021                         if (m_debugLog.str().size() > 0) {
1022                                 log << tcu::TestLog::Message
1023                                         << "Prior passing tests\n"
1024                                         << m_debugLog.str()
1025                                         << tcu::TestLog::EndMessage;
1026                                 m_debugLog.str("");
1027                         }
1028                         log << tcu::TestLog::Message
1029                                 << "Image comparison failed: "
1030                                 << "reference = " << reference
1031                                 << ", expected = " << static_cast<deUint32>(expected[0])
1032                                         << ":" << static_cast<deUint32>(expected[1])
1033                                         << ":" << static_cast<deUint32>(expected[2])
1034                                         << ":" << static_cast<deUint32>(expected[3])
1035                                 << ", result = " << static_cast<deUint32>(pixels[0])
1036                                         << ":" << static_cast<deUint32>(pixels[1])
1037                                         << ":" << static_cast<deUint32>(pixels[2])
1038                                         << ":" << static_cast<deUint32>(pixels[3])
1039                                 << tcu::TestLog::EndMessage;
1040                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Color test failed");
1041                 }
1042                 else
1043                 {
1044                         // Pixel matches expected value
1045                         m_debugLog << "Image comparison passed: "
1046                                 << "reference = " << reference
1047                                 << ", result = " << static_cast<deUint32>(pixels[0])
1048                                         << ":" << static_cast<deUint32>(pixels[1])
1049                                         << ":" << static_cast<deUint32>(pixels[2])
1050                                         << ":" << static_cast<deUint32>(pixels[3])
1051                                 << "\n";
1052                 }
1053         }
1054         else
1055         {
1056                 deUint8 pixels[16];
1057                 deUint8 expected[4];
1058                 readPixels(m_gl, pixels);
1059
1060                 expected[0] = expectedUint8(reference);
1061                 expected[1] = expectedUint8(reference + increment);
1062                 expected[2] = expectedUint8(reference - increment);
1063                 expected[3] = expectedAlpha8(reference + 2 * increment);
1064                 if (checkWithThreshold8(pixels[0], expected[0]) || checkWithThreshold8(pixels[1], expected[1])
1065                                 || checkWithThreshold8(pixels[2], expected[2]) || checkWithThreshold8(pixels[3], expected[3]))
1066                 {
1067                         if (m_debugLog.str().size() > 0) {
1068                                 log << tcu::TestLog::Message
1069                                         << "Prior passing tests\n"
1070                                         << m_debugLog.str()
1071                                         << tcu::TestLog::EndMessage;
1072                                 m_debugLog.str("");
1073                         }
1074                         log << tcu::TestLog::Message
1075                                 << "Image comparison failed: "
1076                                 << "reference = " << reference
1077                                 << ", expected = " << static_cast<deUint32>(expected[0])
1078                                         << ":" << static_cast<deUint32>(expected[1])
1079                                         << ":" << static_cast<deUint32>(expected[2])
1080                                         << ":" << static_cast<deUint32>(expected[3])
1081                                 << ", result = " << static_cast<deUint32>(pixels[0])
1082                                         << ":" << static_cast<deUint32>(pixels[1])
1083                                         << ":" << static_cast<deUint32>(pixels[2])
1084                                         << ":" << static_cast<deUint32>(pixels[3])
1085                                 << tcu::TestLog::EndMessage;
1086                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Color test failed");
1087                 }
1088                 else
1089                 {
1090                         // Pixel matches expected value
1091                         m_debugLog << "Image comparison passed: "
1092                                 << "reference = " << reference
1093                                 << ", result = " << static_cast<deUint32>(pixels[0])
1094                                         << ":" << static_cast<deUint32>(pixels[1])
1095                                         << ":" << static_cast<deUint32>(pixels[2])
1096                                         << ":" << static_cast<deUint32>(pixels[3])
1097                                 << "\n";
1098                 }
1099         }
1100 }
1101
1102 void WideColorSurfaceTest::doClearTest (EGLSurface surface)
1103 {
1104         tcu::TestLog&   log                             = m_testCtx.getLog();
1105         const Library&  egl                             = m_eglTestCtx.getLibrary();
1106         const EGLint    attribList[]    =
1107         {
1108                 EGL_CONTEXT_CLIENT_VERSION, 2,
1109                 EGL_NONE
1110         };
1111         EGLContext              eglContext              = egl.createContext(m_eglDisplay, m_eglConfig, EGL_NO_CONTEXT, attribList);
1112         EGLU_CHECK_MSG(egl, "eglCreateContext");
1113
1114         egl.makeCurrent(m_eglDisplay, surface, surface, eglContext);
1115         EGLU_CHECK_MSG(egl, "eglMakeCurrent");
1116
1117         {
1118                 // put gles2Renderer inside it's own scope so that it's cleaned
1119                 // up before we hit the destroyContext
1120                 const GLES2Renderer gles2Renderer(m_gl, 128, 128);
1121
1122                 std::vector<Iteration>::const_iterator it;      // declare an Iterator to a vector of strings
1123                 log << tcu::TestLog::Message << "m_iterations.count = " << m_iterations.size() << tcu::TestLog::EndMessage;
1124                 for(it = m_iterations.begin() ; it < m_iterations.end(); it++)
1125                 {
1126                         float reference = it->start;
1127                         log << tcu::TestLog::Message << "start = " << it->start
1128                                                 << tcu::TestLog::EndMessage;
1129                         log << tcu::TestLog::Message
1130                                                 << "increment = " << it->increment
1131                                                 << tcu::TestLog::EndMessage;
1132                         log << tcu::TestLog::Message
1133                                                 << "count = " << it->iterationCount
1134                                                 << tcu::TestLog::EndMessage;
1135                         m_debugLog.str("");
1136                         for (int iterationCount = 0; iterationCount < it->iterationCount; iterationCount++)
1137                         {
1138                                 const Color     clearColor(reference, reference + it->increment, reference - it->increment, reference + 2 * it->increment);
1139
1140                                 clearColorScreen(m_gl, clearColor);
1141                                 GLU_EXPECT_NO_ERROR(m_gl.getError(), "Clear to test value");
1142
1143                                 testPixels(reference, it->increment);
1144
1145                                 // reset buffer contents so that we know render below did something
1146                                 const Color     clearColor2(1.0f - reference, 1.0f, 1.0f, 1.0f);
1147                                 clearColorScreen(m_gl, clearColor2);
1148                                 GLU_EXPECT_NO_ERROR(m_gl.getError(), "Clear to 1.0f - reference value");
1149
1150                                 const ColoredRect       coloredRect     (IVec2(0, 0), IVec2(1, 1), clearColor);
1151                                 gles2Renderer.render(coloredRect);
1152                                 testPixels(reference, it->increment);
1153
1154                                 reference += it->increment;
1155                         }
1156
1157                         EGLU_CHECK_CALL(egl, swapBuffers(m_eglDisplay, surface));
1158                 }
1159         }
1160
1161         // disconnect surface & context so they can be destroyed when
1162         // this function exits.
1163         EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
1164
1165         egl.destroyContext(m_eglDisplay, eglContext);
1166 }
1167
1168 void WideColorSurfaceTest::executeTest (void)
1169 {
1170         tcu::TestLog&                                           log                             = m_testCtx.getLog();
1171         const Library&                                          egl                             = m_eglTestCtx.getLibrary();
1172         const eglu::NativeDisplayFactory&       displayFactory  = m_eglTestCtx.getNativeDisplayFactory();
1173         eglu::NativeDisplay&                            nativeDisplay   = m_eglTestCtx.getNativeDisplay();
1174         egl.bindAPI(EGL_OPENGL_ES_API);
1175
1176         if (m_surfaceType & EGL_PBUFFER_BIT)
1177         {
1178                 log << tcu::TestLog::Message << "Test Pbuffer" << tcu::TestLog::EndMessage;
1179
1180                 std::vector<EGLint>                     attribs;
1181                 attribs.push_back(EGL_WIDTH);
1182                 attribs.push_back(128);
1183                 attribs.push_back(EGL_HEIGHT);
1184                 attribs.push_back(128);
1185                 if (m_colorSpace != EGL_NONE)
1186                 {
1187                         attribs.push_back(EGL_GL_COLORSPACE_KHR);
1188                         attribs.push_back(m_colorSpace);
1189                 }
1190                 attribs.push_back(EGL_NONE);
1191                 attribs.push_back(EGL_NONE);
1192                 const EGLSurface surface = egl.createPbufferSurface(m_eglDisplay, m_eglConfig, attribs.data());
1193                 if ((surface == EGL_NO_SURFACE) && (egl.getError() == EGL_BAD_MATCH))
1194                 {
1195                         TCU_THROW(NotSupportedError, "Colorspace is not supported with this format");
1196                 }
1197                 TCU_CHECK(surface != EGL_NO_SURFACE);
1198                 EGLU_CHECK_MSG(egl, "eglCreatePbufferSurface()");
1199
1200                 doClearTest(surface);
1201
1202                 egl.destroySurface(m_eglDisplay, surface);
1203                 EGLU_CHECK_MSG(egl, "eglDestroySurface()");
1204         }
1205         else if (m_surfaceType & EGL_WINDOW_BIT)
1206         {
1207                 log << tcu::TestLog::Message << "Test Window" << tcu::TestLog::EndMessage;
1208
1209                 const eglu::NativeWindowFactory&        windowFactory   = eglu::selectNativeWindowFactory(displayFactory, m_testCtx.getCommandLine());
1210
1211                 de::UniquePtr<eglu::NativeWindow>       window                  (windowFactory.createWindow(&nativeDisplay, m_eglDisplay, m_eglConfig, DE_NULL, eglu::WindowParams(128, 128, eglu::parseWindowVisibility(m_testCtx.getCommandLine()))));
1212                 std::vector<EGLAttrib>          attribs;
1213                 if (m_colorSpace != EGL_NONE)
1214                 {
1215                         attribs.push_back(EGL_GL_COLORSPACE_KHR);
1216                         attribs.push_back(m_colorSpace);
1217                 }
1218                 attribs.push_back(EGL_NONE);
1219                 attribs.push_back(EGL_NONE);
1220
1221                 EGLSurface      surface;
1222                 try
1223                 {
1224                         surface = eglu::createWindowSurface(nativeDisplay, *window, m_eglDisplay, m_eglConfig, attribs.data());
1225                 }
1226                 catch (const eglu::Error& error)
1227                 {
1228                         if (error.getError() == EGL_BAD_MATCH)
1229                                 TCU_THROW(NotSupportedError, "createWindowSurface is not supported for this config");
1230
1231                         throw;
1232                 }
1233                 TCU_CHECK(surface != EGL_NO_SURFACE);
1234                 EGLU_CHECK_MSG(egl, "eglCreateWindowSurface()");
1235
1236                 doClearTest(surface);
1237
1238                 if (m_testAttribList.size() > 0)
1239                 {
1240                         for (deUint32 i = 0; i < m_testAttribList.size(); i +=2)
1241                         {
1242                                 if (!egl.surfaceAttrib(m_eglDisplay, surface, m_testAttribList[i], m_testAttribList[i+1]))
1243                                 {
1244                                         // Implementation can return EGL_BAD_PARAMETER if given value is not supported.
1245                                         EGLint error = egl.getError();
1246                                         if (error != EGL_BAD_PARAMETER)
1247                                                 TCU_FAIL("Unable to set HDR metadata on surface");
1248
1249                                         log << tcu::TestLog::Message <<
1250                                                 "Warning: Metadata value " << m_testAttribList[i+1] << " for attrib 0x" <<
1251                                                 std::hex << m_testAttribList[i] << std::dec <<
1252                                                 " not supported by the implementation." << tcu::TestLog::EndMessage;
1253                                         m_testAttribList[i+1] = EGL_BAD_PARAMETER;
1254                                 }
1255                         }
1256                         for (deUint32 i = 0; i < m_testAttribList.size(); i +=2)
1257                         {
1258                                 // Skip unsupported values.
1259                                 if (m_testAttribList[i+1] == EGL_BAD_PARAMETER)
1260                                         continue;
1261
1262                                 EGLint value;
1263                                 egl.querySurface(m_eglDisplay, surface, m_testAttribList[i], &value);
1264                                 TCU_CHECK(value == m_testAttribList[i+1]);
1265                         }
1266                 }
1267
1268                 egl.destroySurface(m_eglDisplay, surface);
1269                 EGLU_CHECK_MSG(egl, "eglDestroySurface()");
1270         }
1271         else if (m_surfaceType & EGL_PIXMAP_BIT)
1272         {
1273                 log << tcu::TestLog::Message << "Test Pixmap" << tcu::TestLog::EndMessage;
1274
1275                 const eglu::NativePixmapFactory&        pixmapFactory   = eglu::selectNativePixmapFactory(displayFactory, m_testCtx.getCommandLine());
1276
1277                 de::UniquePtr<eglu::NativePixmap>       pixmap                  (pixmapFactory.createPixmap(&nativeDisplay, m_eglDisplay, m_eglConfig, DE_NULL, 128, 128));
1278                 const EGLSurface                                        surface                 = eglu::createPixmapSurface(nativeDisplay, *pixmap, m_eglDisplay, m_eglConfig, DE_NULL);
1279                 TCU_CHECK(surface != EGL_NO_SURFACE);
1280                 EGLU_CHECK_MSG(egl, "eglCreatePixmapSurface()");
1281
1282                 doClearTest(surface);
1283
1284                 egl.destroySurface(m_eglDisplay, surface);
1285                 EGLU_CHECK_MSG(egl, "eglDestroySurface()");
1286         }
1287         else
1288                 TCU_FAIL("No valid surface types supported in config");
1289 }
1290
1291 TestCase::IterateResult WideColorSurfaceTest::iterate (void)
1292 {
1293         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1294         executeTest();
1295         return STOP;
1296 }
1297
1298 } // anonymous
1299
1300 WideColorTests::WideColorTests (EglTestContext& eglTestCtx)
1301         : TestCaseGroup(eglTestCtx, "wide_color", "Wide Color tests")
1302 {
1303 }
1304
1305 void WideColorTests::init (void)
1306 {
1307         addChild(new WideColorFP16Test(m_eglTestCtx, "fp16", "Verify that FP16 pixel format is present"));
1308         addChild(new WideColor1010102Test(m_eglTestCtx, "1010102", "Check if 1010102 pixel format is present"));
1309
1310         // This is an increment FP16 can do between -1.0 to 1.0
1311         const float fp16Increment1 = deFloatPow(2.0, -11.0);
1312         // This is an increment FP16 can do between 1.0 to 2.0
1313         const float fp16Increment2 = deFloatPow(2.0, -10.0);
1314
1315         std::vector<Iteration> iterations;
1316         // -0.333251953125f ~ -1/3 as seen in FP16
1317         // Negative values will be 0 on read with fixed point pixel formats
1318         iterations.push_back(Iteration(-0.333251953125f, fp16Increment1, 10));
1319         // test crossing 0
1320         iterations.push_back(Iteration(-fp16Increment1 * 5.0f, fp16Increment1, 10));
1321         // test crossing 1.0
1322         // Values > 1.0 will be truncated to 1.0 with fixed point pixel formats
1323         iterations.push_back(Iteration(1.0f - fp16Increment2 * 5.0f, fp16Increment2, 10));
1324
1325         const EGLint windowAttribListFP16[] =
1326         {
1327                 EGL_SURFACE_TYPE,                               EGL_WINDOW_BIT,
1328                 EGL_RENDERABLE_TYPE,                    EGL_OPENGL_ES2_BIT,
1329                 EGL_RED_SIZE,                                   16,
1330                 EGL_GREEN_SIZE,                                 16,
1331                 EGL_BLUE_SIZE,                                  16,
1332                 EGL_ALPHA_SIZE,                                 16,
1333                 EGL_COLOR_COMPONENT_TYPE_EXT,   EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT,
1334                 EGL_NONE,                                               EGL_NONE
1335         };
1336         addChild(new WideColorSurfaceTest(m_eglTestCtx, "window_fp16_default_colorspace", "FP16 window surface has FP16 pixels in it", windowAttribListFP16, EGL_NONE, iterations));
1337         addChild(new WideColorSurfaceTest(m_eglTestCtx, "window_fp16_colorspace_srgb", "FP16 window surface, explicit sRGB colorspace", windowAttribListFP16, EGL_GL_COLORSPACE_SRGB_KHR, iterations));
1338         addChild(new WideColorSurfaceTest(m_eglTestCtx, "window_fp16_colorspace_p3", "FP16 window surface, explicit Display-P3 colorspace", windowAttribListFP16, EGL_GL_COLORSPACE_DISPLAY_P3_EXT, iterations));
1339         addChild(new WideColorSurfaceTest(m_eglTestCtx, "window_fp16_colorspace_scrgb", "FP16 window surface, explicit scRGB colorspace", windowAttribListFP16, EGL_GL_COLORSPACE_SCRGB_EXT, iterations));
1340         addChild(new WideColorSurfaceTest(m_eglTestCtx, "window_fp16_colorspace_scrgb_linear", "FP16 window surface, explicit scRGB linear colorspace", windowAttribListFP16, EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT, iterations));
1341
1342         const EGLint pbufferAttribListFP16[] =
1343         {
1344                 EGL_SURFACE_TYPE,                               EGL_PBUFFER_BIT,
1345                 EGL_RENDERABLE_TYPE,                    EGL_OPENGL_ES2_BIT,
1346                 EGL_RED_SIZE,                                   16,
1347                 EGL_GREEN_SIZE,                                 16,
1348                 EGL_BLUE_SIZE,                                  16,
1349                 EGL_ALPHA_SIZE,                                 16,
1350                 EGL_COLOR_COMPONENT_TYPE_EXT,   EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT,
1351                 EGL_NONE,                                               EGL_NONE
1352         };
1353         addChild(new WideColorSurfaceTest(m_eglTestCtx, "pbuffer_fp16_default_colorspace", "FP16 pbuffer surface has FP16 pixels in it", pbufferAttribListFP16, EGL_NONE, iterations));
1354         addChild(new WideColorSurfaceTest(m_eglTestCtx, "pbuffer_fp16_colorspace_srgb", "FP16 pbuffer surface, explicit sRGB colorspace", pbufferAttribListFP16, EGL_GL_COLORSPACE_SRGB_KHR, iterations));
1355         addChild(new WideColorSurfaceTest(m_eglTestCtx, "pbuffer_fp16_colorspace_p3", "FP16 pbuffer surface, explicit Display-P3 colorspace", pbufferAttribListFP16, EGL_GL_COLORSPACE_DISPLAY_P3_EXT, iterations));
1356         addChild(new WideColorSurfaceTest(m_eglTestCtx, "pbuffer_fp16_colorspace_scrgb", "FP16 pbuffer surface, explicit scRGB colorspace", pbufferAttribListFP16, EGL_GL_COLORSPACE_SCRGB_EXT, iterations));
1357         addChild(new WideColorSurfaceTest(m_eglTestCtx, "pbuffer_fp16_colorspace_scrgb_linear", "FP16 pbuffer surface, explicit scRGB linear colorspace", pbufferAttribListFP16, EGL_GL_COLORSPACE_SCRGB_LINEAR_EXT, iterations));
1358
1359         const EGLint windowAttribList1010102[] =
1360         {
1361                 EGL_SURFACE_TYPE,                               EGL_WINDOW_BIT,
1362                 EGL_RENDERABLE_TYPE,                    EGL_OPENGL_ES2_BIT,
1363                 EGL_RED_SIZE,                                   10,
1364                 EGL_GREEN_SIZE,                                 10,
1365                 EGL_BLUE_SIZE,                                  10,
1366                 EGL_ALPHA_SIZE,                                 2,
1367                 EGL_NONE,                                               EGL_NONE
1368         };
1369         addChild(new WideColorSurfaceTest(m_eglTestCtx, "window_1010102_colorspace_default", "1010102 Window surface, default (sRGB) colorspace", windowAttribList1010102, EGL_NONE, iterations));
1370         addChild(new WideColorSurfaceTest(m_eglTestCtx, "window_1010102_colorspace_srgb", "1010102 Window surface, explicit sRGB colorspace", windowAttribList1010102, EGL_GL_COLORSPACE_SRGB_KHR, iterations));
1371         addChild(new WideColorSurfaceTest(m_eglTestCtx, "window_1010102_colorspace_p3", "1010102 Window surface, explicit Display-P3 colorspace", windowAttribList1010102, EGL_GL_COLORSPACE_DISPLAY_P3_EXT, iterations));
1372
1373         const EGLint pbufferAttribList1010102[] =
1374         {
1375                 EGL_SURFACE_TYPE,                               EGL_PBUFFER_BIT,
1376                 EGL_RENDERABLE_TYPE,                    EGL_OPENGL_ES2_BIT,
1377                 EGL_RED_SIZE,                                   10,
1378                 EGL_GREEN_SIZE,                                 10,
1379                 EGL_BLUE_SIZE,                                  10,
1380                 EGL_ALPHA_SIZE,                                 2,
1381                 EGL_NONE,                                               EGL_NONE
1382         };
1383         addChild(new WideColorSurfaceTest(m_eglTestCtx, "pbuffer_1010102_colorspace_default", "1010102 pbuffer surface, default (sRGB) colorspace", pbufferAttribList1010102, EGL_NONE, iterations));
1384         addChild(new WideColorSurfaceTest(m_eglTestCtx, "pbuffer_1010102_colorspace_srgb", "1010102 pbuffer surface, explicit sRGB colorspace", pbufferAttribList1010102, EGL_GL_COLORSPACE_SRGB_KHR, iterations));
1385         addChild(new WideColorSurfaceTest(m_eglTestCtx, "pbuffer_1010102_colorspace_p3", "1010102 pbuffer surface, explicit Display-P3 colorspace", pbufferAttribList1010102, EGL_GL_COLORSPACE_DISPLAY_P3_EXT, iterations));
1386
1387         const EGLint windowAttribList8888[] =
1388         {
1389                 EGL_SURFACE_TYPE,                               EGL_WINDOW_BIT,
1390                 EGL_RENDERABLE_TYPE,                    EGL_OPENGL_ES2_BIT,
1391                 EGL_RED_SIZE,                                   8,
1392                 EGL_GREEN_SIZE,                                 8,
1393                 EGL_BLUE_SIZE,                                  8,
1394                 EGL_ALPHA_SIZE,                                 8,
1395                 EGL_NONE,                                               EGL_NONE
1396         };
1397         addChild(new WideColorSurfaceTest(m_eglTestCtx, "window_8888_colorspace_default", "8888 window surface, default (sRGB) colorspace", windowAttribList8888, EGL_NONE, iterations));
1398         addChild(new WideColorSurfaceTest(m_eglTestCtx, "window_8888_colorspace_srgb", "8888 window surface, explicit sRGB colorspace", windowAttribList8888, EGL_GL_COLORSPACE_SRGB_KHR, iterations));
1399         addChild(new WideColorSurfaceTest(m_eglTestCtx, "window_8888_colorspace_p3", "8888 window surface, explicit Display-P3 colorspace", windowAttribList8888, EGL_GL_COLORSPACE_DISPLAY_P3_EXT, iterations));
1400
1401         const EGLint pbufferAttribList8888[] =
1402         {
1403                 EGL_SURFACE_TYPE,                               EGL_PBUFFER_BIT,
1404                 EGL_RENDERABLE_TYPE,                    EGL_OPENGL_ES2_BIT,
1405                 EGL_RED_SIZE,                                   8,
1406                 EGL_GREEN_SIZE,                                 8,
1407                 EGL_BLUE_SIZE,                                  8,
1408                 EGL_ALPHA_SIZE,                                 8,
1409                 EGL_NONE,                                               EGL_NONE
1410         };
1411         addChild(new WideColorSurfaceTest(m_eglTestCtx, "pbuffer_8888_colorspace_default", "8888 pbuffer surface, default (sRGB) colorspace", pbufferAttribList8888, EGL_NONE, iterations));
1412         addChild(new WideColorSurfaceTest(m_eglTestCtx, "pbuffer_8888_colorspace_srgb", "8888 pbuffer surface, explicit sRGB colorspace", pbufferAttribList8888, EGL_GL_COLORSPACE_SRGB_KHR, iterations));
1413         addChild(new WideColorSurfaceTest(m_eglTestCtx, "pbuffer_8888_colorspace_p3", "8888 pbuffer surface, explicit Display-P3 colorspace", pbufferAttribList8888, EGL_GL_COLORSPACE_DISPLAY_P3_EXT, iterations));
1414
1415         const EGLint windowAttribList888[] =
1416         {
1417                 EGL_SURFACE_TYPE,                               EGL_WINDOW_BIT,
1418                 EGL_RENDERABLE_TYPE,                    EGL_OPENGL_ES2_BIT,
1419                 EGL_RED_SIZE,                                   8,
1420                 EGL_GREEN_SIZE,                                 8,
1421                 EGL_BLUE_SIZE,                                  8,
1422                 EGL_NONE,                                               EGL_NONE
1423         };
1424         addChild(new WideColorSurfaceTest(m_eglTestCtx, "window_888_colorspace_default", "888 window surface, default (sRGB) colorspace", windowAttribList888, EGL_NONE, iterations));
1425         addChild(new WideColorSurfaceTest(m_eglTestCtx, "window_888_colorspace_srgb", "888 window surface, explicit sRGB colorspace", windowAttribList888, EGL_GL_COLORSPACE_SRGB_KHR, iterations));
1426         addChild(new WideColorSurfaceTest(m_eglTestCtx, "window_888_colorspace_p3", "888 window surface, explicit Display-P3 colorspace", windowAttribList888, EGL_GL_COLORSPACE_DISPLAY_P3_EXT, iterations));
1427
1428         const EGLint pbufferAttribList888[] =
1429         {
1430                 EGL_SURFACE_TYPE,                               EGL_PBUFFER_BIT,
1431                 EGL_RENDERABLE_TYPE,                    EGL_OPENGL_ES2_BIT,
1432                 EGL_RED_SIZE,                                   8,
1433                 EGL_GREEN_SIZE,                                 8,
1434                 EGL_BLUE_SIZE,                                  8,
1435                 EGL_NONE,                                               EGL_NONE
1436         };
1437         addChild(new WideColorSurfaceTest(m_eglTestCtx, "pbuffer_888_colorspace_default", "888 pbuffer surface, default (sRGB) colorspace", pbufferAttribList888, EGL_NONE, iterations));
1438         addChild(new WideColorSurfaceTest(m_eglTestCtx, "pbuffer_888_colorspace_srgb", "888 pbuffer surface, explicit sRGB colorspace", pbufferAttribList888, EGL_GL_COLORSPACE_SRGB_KHR, iterations));
1439         addChild(new WideColorSurfaceTest(m_eglTestCtx, "pbuffer_888_colorspace_p3", "888 pbuffer surface, explicit Display-P3 colorspace", pbufferAttribList888, EGL_GL_COLORSPACE_DISPLAY_P3_EXT, iterations));
1440
1441 }
1442
1443 TestCaseGroup* createWideColorTests (EglTestContext& eglTestCtx)
1444 {
1445         return new WideColorTests(eglTestCtx);
1446 }
1447
1448 class Smpte2086ColorTest : public WideColorTest
1449 {
1450 public:
1451         Smpte2086ColorTest              (EglTestContext&        eglTestCtx,
1452                                                          const char*            name,
1453                                                          const char*            description);
1454
1455         void                            executeTest                             (void);
1456         IterateResult           iterate                                 (void);
1457 };
1458
1459 Smpte2086ColorTest::Smpte2086ColorTest (EglTestContext& eglTestCtx, const char* name, const char* description)
1460                 : WideColorTest(eglTestCtx, name, description)
1461 {
1462 }
1463
1464 #define METADATA_SCALE(x) (static_cast<EGLint>(x * EGL_METADATA_SCALING_EXT))
1465
1466 void Smpte2086ColorTest::executeTest (void)
1467 {
1468         tcu::TestLog&                                           log                             = m_testCtx.getLog();
1469         const Library&                                          egl                             = m_eglTestCtx.getLibrary();
1470         egl.bindAPI(EGL_OPENGL_ES_API);
1471
1472         log << tcu::TestLog::Message << "Test SMPTE 2086 Metadata on Window" << tcu::TestLog::EndMessage;
1473
1474         checkSMPTE2086();
1475
1476         // This is an increment FP16 can do between -1.0 to 1.0
1477         const float fp16Increment1 = deFloatPow(2.0, -11.0);
1478         // This is an increment FP16 can do between 1.0 to 2.0
1479         const float fp16Increment2 = deFloatPow(2.0, -10.0);
1480
1481         std::vector<Iteration> int8888Iterations;
1482         // -0.333251953125f ~ -1/3 as seen in fp16
1483         // Negative values will be 0 on read with fixed point pixel formats
1484         int8888Iterations.push_back(Iteration(-0.333251953125f, fp16Increment1, 10));
1485         // test crossing 0
1486         int8888Iterations.push_back(Iteration(-fp16Increment1 * 5.0f, fp16Increment1, 10));
1487         // test crossing 1.0
1488         // Values > 1.0 will be truncated to 1.0 with fixed point pixel formats
1489         int8888Iterations.push_back(Iteration(1.0f - fp16Increment2 * 5.0f, fp16Increment2, 10));
1490
1491         const EGLint windowAttribList8888[] =
1492         {
1493                 EGL_SURFACE_TYPE,                               EGL_WINDOW_BIT,
1494                 EGL_RENDERABLE_TYPE,                    EGL_OPENGL_ES2_BIT,
1495                 EGL_RED_SIZE,                                   8,
1496                 EGL_GREEN_SIZE,                                 8,
1497                 EGL_BLUE_SIZE,                                  8,
1498                 EGL_ALPHA_SIZE,                                 8,
1499                 EGL_NONE,                                               EGL_NONE
1500         };
1501
1502         WideColorSurfaceTest testObj(m_eglTestCtx, "window_8888_colorspace_default", "8888 window surface, default (sRGB) colorspace", windowAttribList8888, EGL_NONE, int8888Iterations);
1503
1504         const EGLint testAttrs[] =
1505         {
1506                 EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT, METADATA_SCALE(0.680),
1507                 EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT, METADATA_SCALE(0.320),
1508                 EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT, METADATA_SCALE(0.265),
1509                 EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT, METADATA_SCALE(0.690),
1510                 EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT, METADATA_SCALE(0.440),
1511                 EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT, METADATA_SCALE(0.320),
1512                 EGL_SMPTE2086_WHITE_POINT_X_EXT, METADATA_SCALE(0.2200),
1513                 EGL_SMPTE2086_WHITE_POINT_Y_EXT, METADATA_SCALE(0.2578),
1514                 EGL_SMPTE2086_MAX_LUMINANCE_EXT, METADATA_SCALE(1.31),
1515                 EGL_SMPTE2086_MIN_LUMINANCE_EXT, METADATA_SCALE(0.123),
1516                 EGL_NONE
1517         };
1518         testObj.addTestAttributes(testAttrs);
1519
1520         testObj.init();
1521         testObj.executeTest();
1522 }
1523
1524 TestCase::IterateResult Smpte2086ColorTest::iterate (void)
1525 {
1526         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1527         executeTest();
1528         return STOP;
1529 }
1530
1531 class Cta8613ColorTest : public WideColorTest
1532 {
1533 public:
1534         Cta8613ColorTest                (EglTestContext&        eglTestCtx,
1535                                                          const char*            name,
1536                                                          const char*            description);
1537
1538         void                            executeTest                             (void);
1539         IterateResult           iterate                                 (void);
1540 };
1541
1542 Cta8613ColorTest::Cta8613ColorTest (EglTestContext& eglTestCtx, const char* name, const char* description)
1543                 : WideColorTest(eglTestCtx, name, description)
1544 {
1545 }
1546
1547 #define METADATA_SCALE(x) (static_cast<EGLint>(x * EGL_METADATA_SCALING_EXT))
1548
1549 void Cta8613ColorTest::executeTest (void)
1550 {
1551         tcu::TestLog&                                           log                             = m_testCtx.getLog();
1552         const Library&                                          egl                             = m_eglTestCtx.getLibrary();
1553         egl.bindAPI(EGL_OPENGL_ES_API);
1554
1555         log << tcu::TestLog::Message << "Test CTA 861.3 Metadata on Window" << tcu::TestLog::EndMessage;
1556
1557         checkCTA861_3();
1558
1559         // This is an increment FP16 can do between -1.0 to 1.0
1560         const float fp16Increment1 = deFloatPow(2.0, -11.0);
1561         // This is an increment FP16 can do between 1.0 to 2.0
1562         const float fp16Increment2 = deFloatPow(2.0, -10.0);
1563
1564         std::vector<Iteration> int8888Iterations;
1565         // -0.333251953125f ~ -1/3 as seen in fp16
1566         // Negative values will be 0 on read with fixed point pixel formats
1567         int8888Iterations.push_back(Iteration(-0.333251953125f, fp16Increment1, 10));
1568         // test crossing 0
1569         int8888Iterations.push_back(Iteration(-fp16Increment1 * 5.0f, fp16Increment1, 10));
1570         // test crossing 1.0
1571         // Values > 1.0 will be truncated to 1.0 with fixed point pixel formats
1572         int8888Iterations.push_back(Iteration(1.0f - fp16Increment2 * 5.0f, fp16Increment2, 10));
1573
1574         const EGLint windowAttribList8888[] =
1575         {
1576                 EGL_SURFACE_TYPE,                               EGL_WINDOW_BIT,
1577                 EGL_RENDERABLE_TYPE,                    EGL_OPENGL_ES2_BIT,
1578                 EGL_RED_SIZE,                                   8,
1579                 EGL_GREEN_SIZE,                                 8,
1580                 EGL_BLUE_SIZE,                                  8,
1581                 EGL_ALPHA_SIZE,                                 8,
1582                 EGL_NONE,                                               EGL_NONE
1583         };
1584
1585         WideColorSurfaceTest testObj(m_eglTestCtx, "window_8888_colorspace_default", "8888 window surface, default (sRGB) colorspace", windowAttribList8888, EGL_NONE, int8888Iterations);
1586
1587         const EGLint testAttrs[] =
1588         {
1589                 EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT, METADATA_SCALE(1.31),
1590                 EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT, METADATA_SCALE(0.6),
1591                 EGL_NONE
1592         };
1593         testObj.addTestAttributes(testAttrs);
1594
1595         testObj.init();
1596         testObj.executeTest();
1597 }
1598
1599 TestCase::IterateResult Cta8613ColorTest::iterate (void)
1600 {
1601         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1602         executeTest();
1603         return STOP;
1604 }
1605
1606 class HdrColorTests : public TestCaseGroup
1607 {
1608 public:
1609         HdrColorTests           (EglTestContext& eglTestCtx);
1610         void                            init                            (void);
1611
1612 private:
1613         HdrColorTests           (const HdrColorTests&);
1614         HdrColorTests&          operator=                       (const HdrColorTests&);
1615 };
1616
1617 HdrColorTests::HdrColorTests (EglTestContext& eglTestCtx)
1618                 : TestCaseGroup(eglTestCtx, "hdr_metadata", "HDR Metadata tests")
1619 {
1620 }
1621
1622 void HdrColorTests::init (void)
1623 {
1624         addChild(new Smpte2086ColorTest(m_eglTestCtx, "smpte2086", "Verify that SMPTE 2086 extension exists"));
1625         addChild(new Cta8613ColorTest(m_eglTestCtx, "cta861_3", "Verify that CTA 861.3 extension exists"));
1626 }
1627
1628 TestCaseGroup* createHdrColorTests (EglTestContext& eglTestCtx)
1629 {
1630         return new HdrColorTests(eglTestCtx);
1631 }
1632
1633 } // egl
1634 } // deqp