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