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