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