Use sRGB encoded reference values for 8-bit Display P3 tests
[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_THROW(NotSupportedError, "No configs available with the requested attributes");
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 or Display P3 and
868                 // pixel component size is 8 bits (which is why we are here in expectedUint8).
869                 if (m_colorSpace == EGL_GL_COLORSPACE_SRGB_KHR ||
870                                 m_colorSpace == EGL_GL_COLORSPACE_DISPLAY_P3_EXT)
871                 {
872                         float srgbReference;
873
874                         if (reference <= 0.0031308)
875                         {
876                                 srgbReference = 12.92f * reference;
877                         }
878                         else
879                         {
880                                 float powRef = deFloatPow(reference, (1.0f/2.4f));
881                                 srgbReference = (1.055f * powRef) - 0.055f;
882                         }
883                         expected = static_cast<deUint8>(deRound(srgbReference * 255.0));
884                 }
885                 else
886                 {
887                         expected = static_cast<deUint8>(deRound(reference * 255.0));
888                 }
889         }
890         return expected;
891 }
892
893 deUint8 WideColorSurfaceTest::expectedAlpha8 (float reference)
894 {
895         deUint8 expected;
896         if (reference < 0.0)
897         {
898                 expected = 0;
899         }
900         else if (reference >= 1.0)
901         {
902                 expected = 255;
903         }
904         else
905         {
906                 // The sRGB transfer function is not applied to alpha
907                 expected = static_cast<deUint8>(deRound(reference * 255.0));
908         }
909         return expected;
910 }
911
912 // Return true for value out of range (fail)
913 bool WideColorSurfaceTest::checkWithThreshold8(deUint8 value, deUint8 reference, deUint8 threshold)
914 {
915         const deUint8 low = reference >= threshold ? static_cast<deUint8>(reference - threshold) : 0;
916         const deUint8 high = reference <= (255 - threshold) ? static_cast<deUint8>(reference + threshold) : 255;
917         return !((value >= low) && (value <= high));
918 }
919
920 bool WideColorSurfaceTest::checkWithThreshold10(deUint32 value, deUint32 reference, deUint32 threshold)
921 {
922         const deUint32 low = reference >= threshold ? reference - threshold : 0;
923         const deUint32 high = reference <= (1023 - threshold) ? reference + threshold : 1023;
924         return !((value >= low) && (value <= high));
925 }
926
927 bool WideColorSurfaceTest::checkWithThresholdFloat(float value, float reference, float threshold)
928 {
929         const float low = reference - threshold;
930         const float high = reference + threshold;
931         return !((value >= low) && (value <= high));
932 }
933
934 void WideColorSurfaceTest::testPixels (float reference, float increment)
935 {
936         tcu::TestLog&   log                             = m_testCtx.getLog();
937
938         if (m_componentType == EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT)
939         {
940                 float pixels[16];
941                 const float expected[4] =
942                 {
943                         reference,
944                         reference + increment,
945                         reference - increment,
946                         reference + 2 * increment
947                 };
948                 readPixels(m_gl, pixels);
949
950                 if (checkWithThresholdFloat(pixels[0], expected[0], increment) ||
951                                 checkWithThresholdFloat(pixels[1], expected[1], increment) ||
952                                 checkWithThresholdFloat(pixels[2], expected[2], increment) ||
953                                 checkWithThresholdFloat(pixels[3], expected[3], increment))
954                 {
955                         if (m_debugLog.str().size() > 0)
956                         {
957                                 log << tcu::TestLog::Message
958                                         << "Prior passing tests\n"
959                                         << m_debugLog.str()
960                                         << tcu::TestLog::EndMessage;
961                                 m_debugLog.str("");
962                         }
963                         log << tcu::TestLog::Message
964                                 << "Image comparison failed: "
965                                 << "reference = " << reference
966                                 << ", expected = " << expected[0]
967                                         << ":" << expected[1]
968                                         << ":" << expected[2]
969                                         << ":" << expected[3]
970                                 << ", result = " << pixels[0]
971                                         << ":" << pixels[1]
972                                         << ":" << pixels[2]
973                                         << ":" << pixels[3]
974                                 << tcu::TestLog::EndMessage;
975                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Color test failed");
976                 }
977                 else
978                 {
979                         // Pixel matches expected value
980                         m_debugLog << "Image comparison passed: "
981                                 << "reference = " << reference
982                                 << ", result = " << pixels[0]
983                                         << ":" << pixels[1]
984                                         << ":" << pixels[2]
985                                         << ":" << pixels[3]
986                                 << "\n";
987                 }
988         }
989         else if (m_redSize > 8)
990         {
991                 deUint32 buffer[16];
992                 readPixels(m_gl, buffer);
993                 deUint32 pixels[4];
994                 deUint32 expected[4];
995
996                 pixels[0] = buffer[0] & 0x3ff;
997                 pixels[1] = (buffer[0] >> 10) & 0x3ff;
998                 pixels[2] = (buffer[0] >> 20) & 0x3ff;
999                 pixels[3] = (buffer[0] >> 30) & 0x3;
1000
1001                 expected[0] = expectedUint10(reference);
1002                 expected[1] = expectedUint10(reference + increment);
1003                 expected[2] = expectedUint10(reference - increment);
1004                 expected[3] = expectedUint2(reference + 2 * increment);
1005                 if (checkWithThreshold10(pixels[0], expected[0]) || checkWithThreshold10(pixels[1], expected[1])
1006                                 || checkWithThreshold10(pixels[2], expected[2]) || checkWithThreshold10(pixels[3], expected[3]))
1007                 {
1008                         if (m_debugLog.str().size() > 0) {
1009                                 log << tcu::TestLog::Message
1010                                         << "Prior passing tests\n"
1011                                         << m_debugLog.str()
1012                                         << tcu::TestLog::EndMessage;
1013                                 m_debugLog.str("");
1014                         }
1015                         log << tcu::TestLog::Message
1016                                 << "Image comparison failed: "
1017                                 << "reference = " << reference
1018                                 << ", expected = " << static_cast<deUint32>(expected[0])
1019                                         << ":" << static_cast<deUint32>(expected[1])
1020                                         << ":" << static_cast<deUint32>(expected[2])
1021                                         << ":" << static_cast<deUint32>(expected[3])
1022                                 << ", result = " << static_cast<deUint32>(pixels[0])
1023                                         << ":" << static_cast<deUint32>(pixels[1])
1024                                         << ":" << static_cast<deUint32>(pixels[2])
1025                                         << ":" << static_cast<deUint32>(pixels[3])
1026                                 << tcu::TestLog::EndMessage;
1027                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Color test failed");
1028                 }
1029                 else
1030                 {
1031                         // Pixel matches expected value
1032                         m_debugLog << "Image comparison passed: "
1033                                 << "reference = " << reference
1034                                 << ", result = " << static_cast<deUint32>(pixels[0])
1035                                         << ":" << static_cast<deUint32>(pixels[1])
1036                                         << ":" << static_cast<deUint32>(pixels[2])
1037                                         << ":" << static_cast<deUint32>(pixels[3])
1038                                 << "\n";
1039                 }
1040         }
1041         else
1042         {
1043                 deUint8 pixels[16];
1044                 deUint8 expected[4];
1045                 readPixels(m_gl, pixels);
1046
1047                 expected[0] = expectedUint8(reference);
1048                 expected[1] = expectedUint8(reference + increment);
1049                 expected[2] = expectedUint8(reference - increment);
1050                 expected[3] = expectedAlpha8(reference + 2 * increment);
1051                 if (checkWithThreshold8(pixels[0], expected[0]) || checkWithThreshold8(pixels[1], expected[1])
1052                                 || checkWithThreshold8(pixels[2], expected[2]) || checkWithThreshold8(pixels[3], expected[3]))
1053                 {
1054                         if (m_debugLog.str().size() > 0) {
1055                                 log << tcu::TestLog::Message
1056                                         << "(C)Prior passing tests\n"
1057                                         << m_debugLog.str()
1058                                         << tcu::TestLog::EndMessage;
1059                                 m_debugLog.str("");
1060                         }
1061                         log << tcu::TestLog::Message
1062                                 << "Image comparison failed: "
1063                                 << "reference = " << reference
1064                                 << ", expected = " << static_cast<deUint32>(expected[0])
1065                                         << ":" << static_cast<deUint32>(expected[1])
1066                                         << ":" << static_cast<deUint32>(expected[2])
1067                                         << ":" << static_cast<deUint32>(expected[3])
1068                                 << ", result = " << static_cast<deUint32>(pixels[0])
1069                                         << ":" << static_cast<deUint32>(pixels[1])
1070                                         << ":" << static_cast<deUint32>(pixels[2])
1071                                         << ":" << static_cast<deUint32>(pixels[3])
1072                                 << tcu::TestLog::EndMessage;
1073                         m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Color test failed");
1074                 }
1075                 else
1076                 {
1077                         // Pixel matches expected value
1078                         m_debugLog << "Image comparison passed: "
1079                                 << "reference = " << reference
1080                                 << ", result = " << static_cast<deUint32>(pixels[0])
1081                                         << ":" << static_cast<deUint32>(pixels[1])
1082                                         << ":" << static_cast<deUint32>(pixels[2])
1083                                         << ":" << static_cast<deUint32>(pixels[3])
1084                                 << "\n";
1085                 }
1086         }
1087 }
1088
1089 void WideColorSurfaceTest::doClearTest (EGLSurface surface)
1090 {
1091         tcu::TestLog&   log                             = m_testCtx.getLog();
1092         const Library&  egl                             = m_eglTestCtx.getLibrary();
1093         const EGLint    attribList[]    =
1094         {
1095                 EGL_CONTEXT_CLIENT_VERSION, 2,
1096                 EGL_NONE
1097         };
1098         EGLContext              eglContext              = egl.createContext(m_eglDisplay, m_eglConfig, EGL_NO_CONTEXT, attribList);
1099         EGLU_CHECK_MSG(egl, "eglCreateContext");
1100
1101         egl.makeCurrent(m_eglDisplay, surface, surface, eglContext);
1102         EGLU_CHECK_MSG(egl, "eglMakeCurrent");
1103
1104         {
1105                 // put gles2Renderer inside it's own scope so that it's cleaned
1106                 // up before we hit the destroyContext
1107                 const GLES2Renderer gles2Renderer(m_gl, 128, 128);
1108
1109                 std::vector<Iteration>::const_iterator it;      // declare an Iterator to a vector of strings
1110                 log << tcu::TestLog::Message << "m_iterations.count = " << m_iterations.size() << tcu::TestLog::EndMessage;
1111                 for(it = m_iterations.begin() ; it < m_iterations.end(); it++)
1112                 {
1113                         float reference = it->start;
1114                         log << tcu::TestLog::Message << "start = " << it->start
1115                                                 << tcu::TestLog::EndMessage;
1116                         log << tcu::TestLog::Message
1117                                                 << "increment = " << it->increment
1118                                                 << tcu::TestLog::EndMessage;
1119                         log << tcu::TestLog::Message
1120                                                 << "count = " << it->iterationCount
1121                                                 << tcu::TestLog::EndMessage;
1122                         m_debugLog.str("");
1123                         for (int iterationCount = 0; iterationCount < it->iterationCount; iterationCount++)
1124                         {
1125                                 const Color     clearColor(reference, reference + it->increment, reference - it->increment, reference + 2 * it->increment);
1126
1127                                 clearColorScreen(m_gl, clearColor);
1128                                 GLU_EXPECT_NO_ERROR(m_gl.getError(), "Clear to test value");
1129
1130                                 testPixels(reference, it->increment);
1131
1132                                 // reset buffer contents so that we know render below did something
1133                                 const Color     clearColor2(1.0f - reference, 1.0f, 1.0f, 1.0f);
1134                                 clearColorScreen(m_gl, clearColor2);
1135                                 GLU_EXPECT_NO_ERROR(m_gl.getError(), "Clear to 1.0f - reference value");
1136
1137                                 const ColoredRect       coloredRect     (IVec2(0.0f, 0.0f), IVec2(1.0f, 1.0f), clearColor);
1138                                 gles2Renderer.render(coloredRect);
1139                                 testPixels(reference, it->increment);
1140
1141                                 reference += it->increment;
1142                         }
1143
1144                         EGLU_CHECK_CALL(egl, swapBuffers(m_eglDisplay, surface));
1145                 }
1146         }
1147
1148         // disconnect surface & context so they can be destroyed when
1149         // this function exits.
1150         EGLU_CHECK_CALL(egl, makeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
1151
1152         egl.destroyContext(m_eglDisplay, eglContext);
1153 }
1154
1155 void WideColorSurfaceTest::executeTest (void)
1156 {
1157         tcu::TestLog&                                           log                             = m_testCtx.getLog();
1158         const Library&                                          egl                             = m_eglTestCtx.getLibrary();
1159         const eglu::NativeDisplayFactory&       displayFactory  = m_eglTestCtx.getNativeDisplayFactory();
1160         eglu::NativeDisplay&                            nativeDisplay   = m_eglTestCtx.getNativeDisplay();
1161         egl.bindAPI(EGL_OPENGL_ES_API);
1162
1163         if (m_surfaceType & EGL_PBUFFER_BIT)
1164         {
1165                 log << tcu::TestLog::Message << "Test Pbuffer" << tcu::TestLog::EndMessage;
1166
1167                 std::vector<EGLint>                     attribs;
1168                 attribs.push_back(EGL_WIDTH);
1169                 attribs.push_back(128);
1170                 attribs.push_back(EGL_HEIGHT);
1171                 attribs.push_back(128);
1172                 if (m_colorSpace != EGL_NONE)
1173                 {
1174                         attribs.push_back(EGL_GL_COLORSPACE_KHR);
1175                         attribs.push_back(m_colorSpace);
1176                 }
1177                 attribs.push_back(EGL_NONE);
1178                 attribs.push_back(EGL_NONE);
1179                 const EGLSurface surface = egl.createPbufferSurface(m_eglDisplay, m_eglConfig, attribs.data());
1180                 if ((surface == EGL_NO_SURFACE) && (egl.getError() == EGL_BAD_MATCH))
1181                 {
1182                         TCU_THROW(NotSupportedError, "Colorspace is not supported with this format");
1183                 }
1184                 TCU_CHECK(surface != EGL_NO_SURFACE);
1185                 EGLU_CHECK_MSG(egl, "eglCreatePbufferSurface()");
1186
1187                 doClearTest(surface);
1188
1189                 egl.destroySurface(m_eglDisplay, surface);
1190                 EGLU_CHECK_MSG(egl, "eglDestroySurface()");
1191         }
1192         else if (m_surfaceType & EGL_WINDOW_BIT)
1193         {
1194                 log << tcu::TestLog::Message << "Test Window" << tcu::TestLog::EndMessage;
1195
1196                 const eglu::NativeWindowFactory&        windowFactory   = eglu::selectNativeWindowFactory(displayFactory, m_testCtx.getCommandLine());
1197
1198                 de::UniquePtr<eglu::NativeWindow>       window                  (windowFactory.createWindow(&nativeDisplay, m_eglDisplay, m_eglConfig, DE_NULL, eglu::WindowParams(128, 128, eglu::parseWindowVisibility(m_testCtx.getCommandLine()))));
1199                 std::vector<EGLAttrib>          attribs;
1200                 if (m_colorSpace != EGL_NONE)
1201                 {
1202                         attribs.push_back(EGL_GL_COLORSPACE_KHR);
1203                         attribs.push_back(m_colorSpace);
1204                 }
1205                 attribs.push_back(EGL_NONE);
1206                 attribs.push_back(EGL_NONE);
1207
1208                 EGLSurface      surface;
1209                 try
1210                 {
1211                         surface = eglu::createWindowSurface(nativeDisplay, *window, m_eglDisplay, m_eglConfig, attribs.data());
1212                 }
1213                 catch (const eglu::Error& error)
1214                 {
1215                         if (error.getError() == EGL_BAD_MATCH)
1216                                 TCU_THROW(NotSupportedError, "createWindowSurface is not supported for this config");
1217
1218                         throw;
1219                 }
1220                 TCU_CHECK(surface != EGL_NO_SURFACE);
1221                 EGLU_CHECK_MSG(egl, "eglCreateWindowSurface()");
1222
1223                 doClearTest(surface);
1224
1225                 if (m_testAttribList.size() > 0)
1226                 {
1227                         for (deUint32 i = 0; i < m_testAttribList.size(); i +=2)
1228                         {
1229                                 if (!egl.surfaceAttrib(m_eglDisplay, surface, m_testAttribList[i], m_testAttribList[i+1]))
1230                                 {
1231                                         // Implementation can return EGL_BAD_PARAMETER if given value is not supported.
1232                                         EGLint error = egl.getError();
1233                                         if (error != EGL_BAD_PARAMETER)
1234                                                 TCU_FAIL("Unable to set HDR metadata on surface");
1235
1236                                         log << tcu::TestLog::Message <<
1237                                                 "Warning: Metadata value " << m_testAttribList[i+1] << " for attrib 0x" <<
1238                                                 std::hex << m_testAttribList[i] << std::dec <<
1239                                                 " not supported by the implementation." << tcu::TestLog::EndMessage;
1240                                         m_testAttribList[i+1] = EGL_BAD_PARAMETER;
1241                                 }
1242                         }
1243                         for (deUint32 i = 0; i < m_testAttribList.size(); i +=2)
1244                         {
1245                                 // Skip unsupported values.
1246                                 if (m_testAttribList[i+1] == EGL_BAD_PARAMETER)
1247                                         continue;
1248
1249                                 EGLint value;
1250                                 egl.querySurface(m_eglDisplay, surface, m_testAttribList[i], &value);
1251                                 TCU_CHECK(value == m_testAttribList[i+1]);
1252                         }
1253                 }
1254
1255                 egl.destroySurface(m_eglDisplay, surface);
1256                 EGLU_CHECK_MSG(egl, "eglDestroySurface()");
1257         }
1258         else if (m_surfaceType & EGL_PIXMAP_BIT)
1259         {
1260                 log << tcu::TestLog::Message << "Test Pixmap" << tcu::TestLog::EndMessage;
1261
1262                 const eglu::NativePixmapFactory&        pixmapFactory   = eglu::selectNativePixmapFactory(displayFactory, m_testCtx.getCommandLine());
1263
1264                 de::UniquePtr<eglu::NativePixmap>       pixmap                  (pixmapFactory.createPixmap(&nativeDisplay, m_eglDisplay, m_eglConfig, DE_NULL, 128, 128));
1265                 const EGLSurface                                        surface                 = eglu::createPixmapSurface(nativeDisplay, *pixmap, m_eglDisplay, m_eglConfig, DE_NULL);
1266                 TCU_CHECK(surface != EGL_NO_SURFACE);
1267                 EGLU_CHECK_MSG(egl, "eglCreatePixmapSurface()");
1268
1269                 doClearTest(surface);
1270
1271                 egl.destroySurface(m_eglDisplay, surface);
1272                 EGLU_CHECK_MSG(egl, "eglDestroySurface()");
1273         }
1274         else
1275                 TCU_FAIL("No valid surface types supported in config");
1276 }
1277
1278 TestCase::IterateResult WideColorSurfaceTest::iterate (void)
1279 {
1280         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1281         executeTest();
1282         return STOP;
1283 }
1284
1285 } // anonymous
1286
1287 WideColorTests::WideColorTests (EglTestContext& eglTestCtx)
1288         : TestCaseGroup(eglTestCtx, "wide_color", "Wide Color tests")
1289 {
1290 }
1291
1292 void WideColorTests::init (void)
1293 {
1294         addChild(new WideColorFP16Test(m_eglTestCtx, "fp16", "Verify that FP16 pixel format is present"));
1295         addChild(new WideColor1010102Test(m_eglTestCtx, "1010102", "Check if 1010102 pixel format is present"));
1296
1297         // This is an increment FP16 can do between -1.0 to 1.0
1298         const float fp16Increment1 = deFloatPow(2.0, -11.0);
1299         // This is an increment FP16 can do between 1.0 to 2.0
1300         const float fp16Increment2 = deFloatPow(2.0, -10.0);
1301
1302         const EGLint windowAttribListFP16[] =
1303         {
1304                 EGL_SURFACE_TYPE,                               EGL_WINDOW_BIT,
1305                 EGL_RENDERABLE_TYPE,                    EGL_OPENGL_ES2_BIT,
1306                 EGL_RED_SIZE,                                   16,
1307                 EGL_GREEN_SIZE,                                 16,
1308                 EGL_BLUE_SIZE,                                  16,
1309                 EGL_ALPHA_SIZE,                                 16,
1310                 EGL_COLOR_COMPONENT_TYPE_EXT,   EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT,
1311                 EGL_NONE,                                               EGL_NONE
1312         };
1313
1314         std::vector<Iteration> fp16Iterations;
1315         // -0.333251953125f ~ -1/3 as seen in FP16
1316         fp16Iterations.push_back(Iteration(-0.333251953125f, fp16Increment1, 10));
1317         // test crossing 0
1318         fp16Iterations.push_back( Iteration(-fp16Increment1 * 5.0f, fp16Increment1, 10));
1319         // test crossing 1.0
1320         fp16Iterations.push_back( Iteration(1.0f - fp16Increment2 * 5.0f, fp16Increment2, 10));
1321         addChild(new WideColorSurfaceTest(m_eglTestCtx, "window_fp16_default_colorspace", "FP16 window surface has FP16 pixels in it", windowAttribListFP16, EGL_NONE, fp16Iterations));
1322         addChild(new WideColorSurfaceTest(m_eglTestCtx, "window_fp16_colorspace_srgb", "FP16 window surface, explicit sRGB colorspace", windowAttribListFP16, EGL_GL_COLORSPACE_SRGB_KHR, fp16Iterations));
1323         addChild(new WideColorSurfaceTest(m_eglTestCtx, "window_fp16_colorspace_p3", "FP16 window surface, explicit Display-P3 colorspace", windowAttribListFP16, EGL_GL_COLORSPACE_DISPLAY_P3_EXT, fp16Iterations));
1324         addChild(new WideColorSurfaceTest(m_eglTestCtx, "window_fp16_colorspace_scrgb", "FP16 window surface, explicit scRGB colorspace", windowAttribListFP16, EGL_GL_COLORSPACE_SCRGB_EXT, fp16Iterations));
1325         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));
1326
1327         const EGLint pbufferAttribListFP16[] =
1328         {
1329                 EGL_SURFACE_TYPE,                               EGL_PBUFFER_BIT,
1330                 EGL_RENDERABLE_TYPE,                    EGL_OPENGL_ES2_BIT,
1331                 EGL_RED_SIZE,                                   16,
1332                 EGL_GREEN_SIZE,                                 16,
1333                 EGL_BLUE_SIZE,                                  16,
1334                 EGL_ALPHA_SIZE,                                 16,
1335                 EGL_COLOR_COMPONENT_TYPE_EXT,   EGL_COLOR_COMPONENT_TYPE_FLOAT_EXT,
1336                 EGL_NONE,                                               EGL_NONE
1337         };
1338         addChild(new WideColorSurfaceTest(m_eglTestCtx, "pbuffer_fp16_default_colorspace", "FP16 pbuffer surface has FP16 pixels in it", pbufferAttribListFP16, EGL_NONE, fp16Iterations));
1339         addChild(new WideColorSurfaceTest(m_eglTestCtx, "pbuffer_fp16_colorspace_srgb", "FP16 pbuffer surface, explicit sRGB colorspace", pbufferAttribListFP16, EGL_GL_COLORSPACE_SRGB_KHR, fp16Iterations));
1340         addChild(new WideColorSurfaceTest(m_eglTestCtx, "pbuffer_fp16_colorspace_p3", "FP16 pbuffer surface, explicit Display-P3 colorspace", pbufferAttribListFP16, EGL_GL_COLORSPACE_DISPLAY_P3_EXT, fp16Iterations));
1341         addChild(new WideColorSurfaceTest(m_eglTestCtx, "pbuffer_fp16_colorspace_scrgb", "FP16 pbuffer surface, explicit scRGB colorspace", pbufferAttribListFP16, EGL_GL_COLORSPACE_SCRGB_EXT, fp16Iterations));
1342         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));
1343
1344         const EGLint windowAttribList1010102[] =
1345         {
1346                 EGL_SURFACE_TYPE,                               EGL_WINDOW_BIT,
1347                 EGL_RENDERABLE_TYPE,                    EGL_OPENGL_ES2_BIT,
1348                 EGL_RED_SIZE,                                   10,
1349                 EGL_GREEN_SIZE,                                 10,
1350                 EGL_BLUE_SIZE,                                  10,
1351                 EGL_ALPHA_SIZE,                                 2,
1352                 EGL_NONE,                                               EGL_NONE
1353         };
1354
1355         std::vector<Iteration> int1010102Iterations;
1356         // -0.333251953125f ~ -1/3 as seen in fp16
1357         // Negative values will be 0 on read with fixed point pixel formats
1358         int1010102Iterations.push_back(Iteration(-0.333251953125f, fp16Increment1, 10));
1359         // test crossing 0
1360         int1010102Iterations.push_back(Iteration(-fp16Increment1 * 5.0f, fp16Increment1, 10));
1361         // test crossing 1.0
1362         // Values > 1.0 will be truncated to 1.0 with fixed point pixel formats
1363         int1010102Iterations.push_back(Iteration(1.0f - fp16Increment2 * 5.0f, fp16Increment2, 10));
1364         addChild(new WideColorSurfaceTest(m_eglTestCtx, "window_1010102_colorspace_default", "1010102 Window surface, default (sRGB) colorspace", windowAttribList1010102, EGL_NONE, int1010102Iterations));
1365         addChild(new WideColorSurfaceTest(m_eglTestCtx, "window_1010102_colorspace_srgb", "1010102 Window surface, explicit sRGB colorspace", windowAttribList1010102, EGL_GL_COLORSPACE_SRGB_KHR, int1010102Iterations));
1366         addChild(new WideColorSurfaceTest(m_eglTestCtx, "window_1010102_colorspace_p3", "1010102 Window surface, explicit Display-P3 colorspace", windowAttribList1010102, EGL_GL_COLORSPACE_DISPLAY_P3_EXT, int1010102Iterations));
1367
1368         const EGLint pbufferAttribList1010102[] =
1369         {
1370                 EGL_SURFACE_TYPE,                               EGL_PBUFFER_BIT,
1371                 EGL_RENDERABLE_TYPE,                    EGL_OPENGL_ES2_BIT,
1372                 EGL_RED_SIZE,                                   10,
1373                 EGL_GREEN_SIZE,                                 10,
1374                 EGL_BLUE_SIZE,                                  10,
1375                 EGL_ALPHA_SIZE,                                 2,
1376                 EGL_NONE,                                               EGL_NONE
1377         };
1378         addChild(new WideColorSurfaceTest(m_eglTestCtx, "pbuffer_1010102_colorspace_default", "1010102 pbuffer surface, default (sRGB) colorspace", pbufferAttribList1010102, EGL_NONE, int1010102Iterations));
1379         addChild(new WideColorSurfaceTest(m_eglTestCtx, "pbuffer_1010102_colorspace_srgb", "1010102 pbuffer surface, explicit sRGB colorspace", pbufferAttribList1010102, EGL_GL_COLORSPACE_SRGB_KHR, int1010102Iterations));
1380         addChild(new WideColorSurfaceTest(m_eglTestCtx, "pbuffer_1010102_colorspace_p3", "1010102 pbuffer surface, explicit Display-P3 colorspace", pbufferAttribList1010102, EGL_GL_COLORSPACE_DISPLAY_P3_EXT, int1010102Iterations));
1381
1382         const EGLint windowAttribList8888[] =
1383         {
1384                 EGL_SURFACE_TYPE,                               EGL_WINDOW_BIT,
1385                 EGL_RENDERABLE_TYPE,                    EGL_OPENGL_ES2_BIT,
1386                 EGL_RED_SIZE,                                   8,
1387                 EGL_GREEN_SIZE,                                 8,
1388                 EGL_BLUE_SIZE,                                  8,
1389                 EGL_ALPHA_SIZE,                                 8,
1390                 EGL_NONE,                                               EGL_NONE
1391         };
1392
1393         std::vector<Iteration> int8888Iterations;
1394         // -0.333251953125f ~ -1/3 as seen in fp16
1395         // Negative values will be 0 on read with fixed point pixel formats
1396         int8888Iterations.push_back(Iteration(-0.333251953125f, fp16Increment1, 10));
1397         // test crossing 0
1398         int8888Iterations.push_back(Iteration(-fp16Increment1 * 5.0f, fp16Increment1, 10));
1399         // test crossing 1.0
1400         // Values > 1.0 will be truncated to 1.0 with fixed point pixel formats
1401         int8888Iterations.push_back(Iteration(1.0f - fp16Increment2 * 5.0f, fp16Increment2, 10));
1402         addChild(new WideColorSurfaceTest(m_eglTestCtx, "window_8888_colorspace_default", "8888 window surface, default (sRGB) colorspace", windowAttribList8888, EGL_NONE, int8888Iterations));
1403         addChild(new WideColorSurfaceTest(m_eglTestCtx, "window_8888_colorspace_srgb", "8888 window surface, explicit sRGB colorspace", windowAttribList8888, EGL_GL_COLORSPACE_SRGB_KHR, int8888Iterations));
1404         addChild(new WideColorSurfaceTest(m_eglTestCtx, "window_8888_colorspace_p3", "8888 window surface, explicit Display-P3 colorspace", windowAttribList8888, EGL_GL_COLORSPACE_DISPLAY_P3_EXT, int8888Iterations));
1405
1406         const EGLint pbufferAttribList8888[] =
1407         {
1408                 EGL_SURFACE_TYPE,                               EGL_PBUFFER_BIT,
1409                 EGL_RENDERABLE_TYPE,                    EGL_OPENGL_ES2_BIT,
1410                 EGL_RED_SIZE,                                   8,
1411                 EGL_GREEN_SIZE,                                 8,
1412                 EGL_BLUE_SIZE,                                  8,
1413                 EGL_ALPHA_SIZE,                                 8,
1414                 EGL_NONE,                                               EGL_NONE
1415         };
1416         addChild(new WideColorSurfaceTest(m_eglTestCtx, "pbuffer_8888_colorspace_default", "8888 pbuffer surface, default (sRGB) colorspace", pbufferAttribList8888, EGL_NONE, int8888Iterations));
1417         addChild(new WideColorSurfaceTest(m_eglTestCtx, "pbuffer_8888_colorspace_srgb", "8888 pbuffer surface, explicit sRGB colorspace", pbufferAttribList8888, EGL_GL_COLORSPACE_SRGB_KHR, int8888Iterations));
1418         addChild(new WideColorSurfaceTest(m_eglTestCtx, "pbuffer_8888_colorspace_p3", "8888 pbuffer surface, explicit Display-P3 colorspace", pbufferAttribList8888, EGL_GL_COLORSPACE_DISPLAY_P3_EXT, int8888Iterations));
1419 }
1420
1421 TestCaseGroup* createWideColorTests (EglTestContext& eglTestCtx)
1422 {
1423         return new WideColorTests(eglTestCtx);
1424 }
1425
1426 class Smpte2086ColorTest : public WideColorTest
1427 {
1428 public:
1429         Smpte2086ColorTest              (EglTestContext&        eglTestCtx,
1430                                                          const char*            name,
1431                                                          const char*            description);
1432
1433         void                            executeTest                             (void);
1434         IterateResult           iterate                                 (void);
1435 };
1436
1437 Smpte2086ColorTest::Smpte2086ColorTest (EglTestContext& eglTestCtx, const char* name, const char* description)
1438                 : WideColorTest(eglTestCtx, name, description)
1439 {
1440 }
1441
1442 #define METADATA_SCALE(x) (static_cast<EGLint>(x * EGL_METADATA_SCALING_EXT))
1443
1444 void Smpte2086ColorTest::executeTest (void)
1445 {
1446         tcu::TestLog&                                           log                             = m_testCtx.getLog();
1447         const Library&                                          egl                             = m_eglTestCtx.getLibrary();
1448         egl.bindAPI(EGL_OPENGL_ES_API);
1449
1450         log << tcu::TestLog::Message << "Test SMPTE 2086 Metadata on Window" << tcu::TestLog::EndMessage;
1451
1452         checkSMPTE2086();
1453
1454         // This is an increment FP16 can do between -1.0 to 1.0
1455         const float fp16Increment1 = deFloatPow(2.0, -11.0);
1456         // This is an increment FP16 can do between 1.0 to 2.0
1457         const float fp16Increment2 = deFloatPow(2.0, -10.0);
1458
1459         std::vector<Iteration> int8888Iterations;
1460         // -0.333251953125f ~ -1/3 as seen in fp16
1461         // Negative values will be 0 on read with fixed point pixel formats
1462         int8888Iterations.push_back(Iteration(-0.333251953125f, fp16Increment1, 10));
1463         // test crossing 0
1464         int8888Iterations.push_back(Iteration(-fp16Increment1 * 5.0f, fp16Increment1, 10));
1465         // test crossing 1.0
1466         // Values > 1.0 will be truncated to 1.0 with fixed point pixel formats
1467         int8888Iterations.push_back(Iteration(1.0f - fp16Increment2 * 5.0f, fp16Increment2, 10));
1468
1469         const EGLint windowAttribList8888[] =
1470         {
1471                 EGL_SURFACE_TYPE,                               EGL_WINDOW_BIT,
1472                 EGL_RENDERABLE_TYPE,                    EGL_OPENGL_ES2_BIT,
1473                 EGL_RED_SIZE,                                   8,
1474                 EGL_GREEN_SIZE,                                 8,
1475                 EGL_BLUE_SIZE,                                  8,
1476                 EGL_ALPHA_SIZE,                                 8,
1477                 EGL_NONE,                                               EGL_NONE
1478         };
1479
1480         WideColorSurfaceTest testObj(m_eglTestCtx, "window_8888_colorspace_default", "8888 window surface, default (sRGB) colorspace", windowAttribList8888, EGL_NONE, int8888Iterations);
1481
1482         const EGLint testAttrs[] =
1483         {
1484                 EGL_SMPTE2086_DISPLAY_PRIMARY_RX_EXT, METADATA_SCALE(0.680),
1485                 EGL_SMPTE2086_DISPLAY_PRIMARY_RY_EXT, METADATA_SCALE(0.320),
1486                 EGL_SMPTE2086_DISPLAY_PRIMARY_GX_EXT, METADATA_SCALE(0.265),
1487                 EGL_SMPTE2086_DISPLAY_PRIMARY_GY_EXT, METADATA_SCALE(0.690),
1488                 EGL_SMPTE2086_DISPLAY_PRIMARY_BX_EXT, METADATA_SCALE(0.440),
1489                 EGL_SMPTE2086_DISPLAY_PRIMARY_BY_EXT, METADATA_SCALE(0.320),
1490                 EGL_SMPTE2086_WHITE_POINT_X_EXT, METADATA_SCALE(0.2200),
1491                 EGL_SMPTE2086_WHITE_POINT_Y_EXT, METADATA_SCALE(0.2578),
1492                 EGL_SMPTE2086_MAX_LUMINANCE_EXT, METADATA_SCALE(1.31),
1493                 EGL_SMPTE2086_MIN_LUMINANCE_EXT, METADATA_SCALE(0.123),
1494                 EGL_NONE
1495         };
1496         testObj.addTestAttributes(testAttrs);
1497
1498         testObj.init();
1499         testObj.executeTest();
1500 }
1501
1502 TestCase::IterateResult Smpte2086ColorTest::iterate (void)
1503 {
1504         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1505         executeTest();
1506         return STOP;
1507 }
1508
1509 class Cta8613ColorTest : public WideColorTest
1510 {
1511 public:
1512         Cta8613ColorTest                (EglTestContext&        eglTestCtx,
1513                                                          const char*            name,
1514                                                          const char*            description);
1515
1516         void                            executeTest                             (void);
1517         IterateResult           iterate                                 (void);
1518 };
1519
1520 Cta8613ColorTest::Cta8613ColorTest (EglTestContext& eglTestCtx, const char* name, const char* description)
1521                 : WideColorTest(eglTestCtx, name, description)
1522 {
1523 }
1524
1525 #define METADATA_SCALE(x) (static_cast<EGLint>(x * EGL_METADATA_SCALING_EXT))
1526
1527 void Cta8613ColorTest::executeTest (void)
1528 {
1529         tcu::TestLog&                                           log                             = m_testCtx.getLog();
1530         const Library&                                          egl                             = m_eglTestCtx.getLibrary();
1531         egl.bindAPI(EGL_OPENGL_ES_API);
1532
1533         log << tcu::TestLog::Message << "Test CTA 861.3 Metadata on Window" << tcu::TestLog::EndMessage;
1534
1535         checkCTA861_3();
1536
1537         // This is an increment FP16 can do between -1.0 to 1.0
1538         const float fp16Increment1 = deFloatPow(2.0, -11.0);
1539         // This is an increment FP16 can do between 1.0 to 2.0
1540         const float fp16Increment2 = deFloatPow(2.0, -10.0);
1541
1542         std::vector<Iteration> int8888Iterations;
1543         // -0.333251953125f ~ -1/3 as seen in fp16
1544         // Negative values will be 0 on read with fixed point pixel formats
1545         int8888Iterations.push_back(Iteration(-0.333251953125f, fp16Increment1, 10));
1546         // test crossing 0
1547         int8888Iterations.push_back(Iteration(-fp16Increment1 * 5.0f, fp16Increment1, 10));
1548         // test crossing 1.0
1549         // Values > 1.0 will be truncated to 1.0 with fixed point pixel formats
1550         int8888Iterations.push_back(Iteration(1.0f - fp16Increment2 * 5.0f, fp16Increment2, 10));
1551
1552         const EGLint windowAttribList8888[] =
1553         {
1554                 EGL_SURFACE_TYPE,                               EGL_WINDOW_BIT,
1555                 EGL_RENDERABLE_TYPE,                    EGL_OPENGL_ES2_BIT,
1556                 EGL_RED_SIZE,                                   8,
1557                 EGL_GREEN_SIZE,                                 8,
1558                 EGL_BLUE_SIZE,                                  8,
1559                 EGL_ALPHA_SIZE,                                 8,
1560                 EGL_NONE,                                               EGL_NONE
1561         };
1562
1563         WideColorSurfaceTest testObj(m_eglTestCtx, "window_8888_colorspace_default", "8888 window surface, default (sRGB) colorspace", windowAttribList8888, EGL_NONE, int8888Iterations);
1564
1565         const EGLint testAttrs[] =
1566         {
1567                 EGL_CTA861_3_MAX_CONTENT_LIGHT_LEVEL_EXT, METADATA_SCALE(1.31),
1568                 EGL_CTA861_3_MAX_FRAME_AVERAGE_LEVEL_EXT, METADATA_SCALE(0.6),
1569                 EGL_NONE
1570         };
1571         testObj.addTestAttributes(testAttrs);
1572
1573         testObj.init();
1574         testObj.executeTest();
1575 }
1576
1577 TestCase::IterateResult Cta8613ColorTest::iterate (void)
1578 {
1579         m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1580         executeTest();
1581         return STOP;
1582 }
1583
1584 class HdrColorTests : public TestCaseGroup
1585 {
1586 public:
1587         HdrColorTests           (EglTestContext& eglTestCtx);
1588         void                            init                            (void);
1589
1590 private:
1591         HdrColorTests           (const HdrColorTests&);
1592         HdrColorTests&          operator=                       (const HdrColorTests&);
1593 };
1594
1595 HdrColorTests::HdrColorTests (EglTestContext& eglTestCtx)
1596                 : TestCaseGroup(eglTestCtx, "hdr_metadata", "HDR Metadata tests")
1597 {
1598 }
1599
1600 void HdrColorTests::init (void)
1601 {
1602         addChild(new Smpte2086ColorTest(m_eglTestCtx, "smpte2086", "Verify that SMPTE 2086 extension exists"));
1603         addChild(new Cta8613ColorTest(m_eglTestCtx, "cta861_3", "Verify that CTA 861.3 extension exists"));
1604 }
1605
1606 TestCaseGroup* createHdrColorTests (EglTestContext& eglTestCtx)
1607 {
1608         return new HdrColorTests(eglTestCtx);
1609 }
1610
1611 } // egl
1612 } // deqp