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