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