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