Home | History | Annotate | Download | only in functional
      1 /*-------------------------------------------------------------------------
      2  * drawElements Quality Program OpenGL ES 3.0 Module
      3  * -------------------------------------------------
      4  *
      5  * Copyright 2014 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 Pixel Buffer Object tests
     22  *//*--------------------------------------------------------------------*/
     23 
     24 #include "es3fPixelBufferObjectTests.hpp"
     25 
     26 #include "tcuTexture.hpp"
     27 #include "tcuTextureUtil.hpp"
     28 #include "tcuImageCompare.hpp"
     29 #include "tcuTestLog.hpp"
     30 #include "tcuRenderTarget.hpp"
     31 
     32 #include "gluTextureUtil.hpp"
     33 #include "gluPixelTransfer.hpp"
     34 #include "gluShaderProgram.hpp"
     35 
     36 #include "deRandom.hpp"
     37 #include "deString.h"
     38 
     39 #include <string>
     40 #include <sstream>
     41 
     42 #include "glw.h"
     43 
     44 using std::string;
     45 using std::stringstream;
     46 
     47 namespace deqp
     48 {
     49 namespace gles3
     50 {
     51 namespace Functional
     52 {
     53 
     54 namespace
     55 {
     56 
     57 class ReadPixelsTest : public TestCase
     58 {
     59 public:
     60 	struct TestSpec
     61 	{
     62 		enum FramebufferType
     63 		{
     64 			FRAMEBUFFERTYPE_NATIVE = 0,
     65 			FRAMEBUFFERTYPE_RENDERBUFFER
     66 		};
     67 
     68 		string			name;
     69 		string			description;
     70 
     71 		bool			useColorClear;
     72 		bool			renderTriangles;
     73 
     74 		FramebufferType	framebufferType;
     75 		GLenum			renderbufferFormat;
     76 	};
     77 
     78 					ReadPixelsTest				(Context& context, const TestSpec& spec);
     79 					~ReadPixelsTest				(void);
     80 
     81 	void			init						(void);
     82 	void			deinit						(void);
     83 
     84 	IterateResult	iterate						(void);
     85 
     86 private:
     87 	void						renderTriangle	(const tcu::Vec3& a, const tcu::Vec3& b, const tcu::Vec3& c);
     88 	void						clearColor		(float r, float g, float b, float a);
     89 
     90 	de::Random					m_random;
     91 	tcu::TestLog&				m_log;
     92 	glu::ShaderProgram*			m_program;
     93 
     94 	TestSpec::FramebufferType	m_framebuffeType;
     95 
     96 	GLenum						m_renderbufferFormat;
     97 	tcu::TextureChannelClass	m_texChannelClass;
     98 
     99 	bool						m_useColorClears;
    100 	bool						m_renderTriangles;
    101 
    102 	GLfloat						m_colorScale;
    103 };
    104 
    105 
    106 ReadPixelsTest::ReadPixelsTest (Context& context, const TestSpec& spec)
    107 	: TestCase				(context, spec.name.c_str(), spec.description.c_str())
    108 	, m_random				(deStringHash(spec.name.c_str()))
    109 	, m_log					(m_testCtx.getLog())
    110 	, m_program				(NULL)
    111 	, m_framebuffeType		(spec.framebufferType)
    112 	, m_renderbufferFormat	(spec.renderbufferFormat)
    113 	, m_texChannelClass		(tcu::TEXTURECHANNELCLASS_LAST)
    114 	, m_useColorClears		(spec.useColorClear)
    115 	, m_renderTriangles		(spec.renderTriangles)
    116 	, m_colorScale			(1.0f)
    117 {
    118 
    119 	if (m_framebuffeType == TestSpec::FRAMEBUFFERTYPE_NATIVE)
    120 	{
    121 		m_colorScale = 1.0f;
    122 	}
    123 	else if (m_framebuffeType == TestSpec::FRAMEBUFFERTYPE_RENDERBUFFER)
    124 	{
    125 		m_texChannelClass = tcu::getTextureChannelClass(glu::mapGLInternalFormat(spec.renderbufferFormat).type);
    126 		switch (m_texChannelClass)
    127 		{
    128 			case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
    129 				m_colorScale = 1.0f;
    130 				break;
    131 
    132 			case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
    133 				m_colorScale = 100.0f;
    134 				break;
    135 
    136 			case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
    137 				m_colorScale = 100.0f;
    138 				break;
    139 
    140 			case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
    141 				m_colorScale = 100.0f;
    142 				break;
    143 
    144 			default:
    145 				DE_ASSERT(false);
    146 		}
    147 	}
    148 	else
    149 		DE_ASSERT(false);
    150 }
    151 
    152 ReadPixelsTest::~ReadPixelsTest (void)
    153 {
    154 }
    155 
    156 void ReadPixelsTest::init (void)
    157 {
    158 	// Check extensions
    159 	if (m_framebuffeType == TestSpec::FRAMEBUFFERTYPE_RENDERBUFFER)
    160 	{
    161 		bool supported = false;
    162 
    163 		if (m_renderbufferFormat == GL_RGBA16F
    164 			|| m_renderbufferFormat == GL_RG16F)
    165 		{
    166 			std::istringstream extensions(std::string((const char*)glGetString(GL_EXTENSIONS)));
    167 			std::string extension;
    168 
    169 			while (std::getline(extensions, extension, ' '))
    170 			{
    171 				if (extension=="GL_EXT_color_buffer_half_float")
    172 				{
    173 					supported = true;
    174 					break;
    175 				}
    176 				if (extension=="GL_EXT_color_buffer_float")
    177 				{
    178 					supported = true;
    179 					break;
    180 				}
    181 			}
    182 		}
    183 		else if (m_renderbufferFormat == GL_RGBA32F
    184 				|| m_renderbufferFormat == GL_RG32F
    185 				|| m_renderbufferFormat == GL_R11F_G11F_B10F)
    186 		{
    187 			std::istringstream extensions(std::string((const char*)glGetString(GL_EXTENSIONS)));
    188 			std::string extension;
    189 
    190 			while (std::getline(extensions, extension, ' '))
    191 			{
    192 				if (extension=="GL_EXT_color_buffer_float")
    193 				{
    194 					supported = true;
    195 					break;
    196 				}
    197 			}
    198 		}
    199 		else
    200 			supported = true;
    201 
    202 		if (!supported)
    203 			throw tcu::NotSupportedError("Renderbuffer format not supported", "", __FILE__, __LINE__);
    204 	}
    205 
    206 	std::string outtype = "";
    207 
    208 	if (m_framebuffeType == TestSpec::FRAMEBUFFERTYPE_NATIVE)
    209 		outtype = "vec4";
    210 	else if (m_framebuffeType == TestSpec::FRAMEBUFFERTYPE_RENDERBUFFER)
    211 	{
    212 		switch (m_texChannelClass)
    213 		{
    214 			case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
    215 				outtype = "vec4";
    216 				break;
    217 
    218 			case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
    219 				outtype = "ivec4";
    220 				break;
    221 
    222 			case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
    223 				outtype = "uvec4";
    224 				break;
    225 
    226 			case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
    227 				outtype = "vec4";
    228 				break;
    229 
    230 			default:
    231 				DE_ASSERT(false);
    232 		}
    233 	}
    234 	else
    235 		DE_ASSERT(false);
    236 
    237 
    238 	const char* vertexShaderSource =
    239 	"#version 300 es\n"
    240 	"in mediump vec3 a_position;\n"
    241 	"in mediump vec4 a_color;\n"
    242 	"uniform mediump float u_colorScale;\n"
    243 	"out mediump vec4 v_color;\n"
    244 	"void main(void)\n"
    245 	"{\n"
    246 	"\tgl_Position = vec4(a_position, 1.0);\n"
    247 	"\tv_color = u_colorScale * a_color;\n"
    248 	"}";
    249 
    250 	stringstream fragmentShaderSource;
    251 
    252 	fragmentShaderSource <<
    253 	"#version 300 es\n"
    254 	"in mediump vec4 v_color;\n";
    255 
    256 
    257 	fragmentShaderSource << "layout (location = 0) out mediump " << outtype << " o_color;\n"
    258 	"void main(void)\n"
    259 	"{\n"
    260 	"\to_color = " << outtype << "(v_color);\n"
    261 	"}";
    262 
    263 	m_program = new glu::ShaderProgram(m_context.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource.str()));
    264 
    265 	if (!m_program->isOk())
    266 	{
    267 		m_log << *m_program;
    268 		TCU_FAIL("Failed to compile shader");
    269 	}
    270 }
    271 
    272 void ReadPixelsTest::deinit (void)
    273 {
    274 	if (m_program)
    275 		delete m_program;
    276 	m_program = NULL;
    277 }
    278 
    279 void ReadPixelsTest::renderTriangle (const tcu::Vec3& a, const tcu::Vec3& b, const tcu::Vec3& c)
    280 {
    281 	float positions[3*3];
    282 
    283 	positions[0] = a.x();
    284 	positions[1] = a.y();
    285 	positions[2] = a.z();
    286 
    287 	positions[3] = b.x();
    288 	positions[4] = b.y();
    289 	positions[5] = b.z();
    290 
    291 	positions[6] = c.x();
    292 	positions[7] = c.y();
    293 	positions[8] = c.z();
    294 
    295 	float colors[] = {
    296 		1.0f, 0.0f, 0.0f, 1.0f,
    297 		0.0f, 1.0f, 0.0f, 1.0f,
    298 		0.0f, 0.0f, 1.0f, 1.0f
    299 	};
    300 
    301 	GLU_CHECK_CALL(glUseProgram(m_program->getProgram()));
    302 
    303 	GLuint coordLoc = (GLuint)-1;
    304 	GLuint colorLoc = (GLuint)-1;
    305 	GLuint colorScaleLoc = (GLuint)-1;
    306 
    307 	colorScaleLoc = glGetUniformLocation(m_program->getProgram(), "u_colorScale");
    308 	TCU_CHECK(colorScaleLoc != (GLuint)-1);
    309 
    310 	GLU_CHECK_CALL(glUniform1f(colorScaleLoc, m_colorScale));
    311 
    312 	coordLoc = glGetAttribLocation(m_program->getProgram(), "a_position");
    313 	TCU_CHECK(coordLoc != (GLuint)-1);
    314 
    315 	colorLoc = glGetAttribLocation(m_program->getProgram(), "a_color");
    316 	TCU_CHECK(colorLoc != (GLuint)-1);
    317 
    318 	GLU_CHECK_CALL(glEnableVertexAttribArray(colorLoc));
    319 	GLU_CHECK_CALL(glEnableVertexAttribArray(coordLoc));
    320 
    321 	GLU_CHECK_CALL(glVertexAttribPointer(coordLoc, 3, GL_FLOAT, GL_FALSE, 0, positions));
    322 	GLU_CHECK_CALL(glVertexAttribPointer(colorLoc, 4, GL_FLOAT, GL_FALSE, 0, colors));
    323 
    324 	GLU_CHECK_CALL(glDrawArrays(GL_TRIANGLES, 0, 3));
    325 
    326 	GLU_CHECK_CALL(glDisableVertexAttribArray(colorLoc));
    327 	GLU_CHECK_CALL(glDisableVertexAttribArray(coordLoc));
    328 
    329 }
    330 
    331 
    332 void ReadPixelsTest::clearColor (float r, float g, float b, float a)
    333 {
    334 	if (m_framebuffeType == TestSpec::FRAMEBUFFERTYPE_NATIVE)
    335 	{
    336 		GLU_CHECK_CALL(glClearColor(r, g, b, a));
    337 		GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT));
    338 	}
    339 	else if (m_framebuffeType == TestSpec::FRAMEBUFFERTYPE_RENDERBUFFER)
    340 	{
    341 		switch (m_texChannelClass)
    342 		{
    343 			case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
    344 			{
    345 				GLU_CHECK_CALL(glClearColor(r, g, b, a));
    346 				GLU_CHECK_CALL(glClear(GL_COLOR_BUFFER_BIT));
    347 				break;
    348 			}
    349 
    350 			case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
    351 			{
    352 				GLint color[4] = { (GLint)r, (GLint)g, (GLint)b, (GLint)a };
    353 
    354 				GLU_CHECK_CALL(glClearBufferiv(GL_COLOR, 0, color));
    355 				break;
    356 			}
    357 
    358 			case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
    359 			{
    360 				GLuint color[4] = { (GLuint)r, (GLuint)g, (GLuint)b, (GLuint)a };
    361 
    362 				GLU_CHECK_CALL(glClearBufferuiv(GL_COLOR, 0, color));
    363 				break;
    364 			}
    365 
    366 			case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
    367 			{
    368 				GLfloat color[4] = { (GLfloat)r, (GLfloat)g, (GLfloat)b, (GLfloat)a };
    369 
    370 				GLU_CHECK_CALL(glClearBufferfv(GL_COLOR, 0, color));
    371 				break;
    372 			}
    373 
    374 			default:
    375 				DE_ASSERT(false);
    376 		}
    377 	}
    378 	else
    379 		DE_ASSERT(false);
    380 
    381 }
    382 
    383 TestCase::IterateResult ReadPixelsTest::iterate(void)
    384 {
    385 	int width				= m_context.getRenderTarget().getWidth();
    386 	int height				= m_context.getRenderTarget().getHeight();
    387 
    388 	GLuint framebuffer	= 0;
    389 	GLuint renderbuffer	= 0;
    390 
    391 	switch (m_framebuffeType)
    392 	{
    393 		case TestSpec::FRAMEBUFFERTYPE_NATIVE:
    394 			GLU_CHECK_CALL(glBindFramebuffer(GL_FRAMEBUFFER, framebuffer));
    395 			break;
    396 
    397 		case TestSpec::FRAMEBUFFERTYPE_RENDERBUFFER:
    398 		{
    399 			GLU_CHECK_CALL(glGenFramebuffers(1, &framebuffer));
    400 			GLU_CHECK_CALL(glGenRenderbuffers(1, &renderbuffer));
    401 
    402 			GLU_CHECK_CALL(glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer));
    403 			GLU_CHECK_CALL(glRenderbufferStorage(GL_RENDERBUFFER, m_renderbufferFormat, width, height));
    404 
    405 			GLU_CHECK_CALL(glBindFramebuffer(GL_FRAMEBUFFER, framebuffer));
    406 			GLU_CHECK_CALL(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer));
    407 
    408 			break;
    409 		}
    410 
    411 		default:
    412 			DE_ASSERT(false);
    413 	}
    414 
    415 	clearColor(m_colorScale * 0.4f, m_colorScale * 1.0f, m_colorScale * 0.5f, m_colorScale * 1.0f);
    416 
    417 	if (m_useColorClears)
    418 	{
    419 		const int maxClearCount	= 10;
    420 		const int minClearCount	= 6;
    421 		const int minClearSize	= 15;
    422 
    423 		int clearCount = m_random.getInt(minClearCount, maxClearCount);
    424 
    425 		for (int clearNdx = 0; clearNdx < clearCount; clearNdx++)
    426 		{
    427 			int clearX = m_random.getInt(0, width - minClearSize);
    428 			int clearY = m_random.getInt(0, height - minClearSize);
    429 
    430 			int clearWidth = m_random.getInt(minClearSize, width - clearX);
    431 			int clearHeight = m_random.getInt(minClearSize, height - clearY);
    432 
    433 			float clearRed		= m_colorScale * m_random.getFloat();
    434 			float clearGreen	= m_colorScale * m_random.getFloat();
    435 			float clearBlue		= m_colorScale * m_random.getFloat();
    436 			float clearAlpha	= m_colorScale * (0.5f + 0.5f * m_random.getFloat());
    437 
    438 			GLU_CHECK_CALL(glEnable(GL_SCISSOR_TEST));
    439 			GLU_CHECK_CALL(glScissor(clearX, clearY, clearWidth, clearHeight));
    440 
    441 			clearColor(clearRed, clearGreen, clearBlue, clearAlpha);
    442 		}
    443 
    444 		GLU_CHECK_CALL(glDisable(GL_SCISSOR_TEST));
    445 	}
    446 
    447 	if (m_renderTriangles)
    448 	{
    449 		const int minTriangleCount = 4;
    450 		const int maxTriangleCount = 10;
    451 
    452 		int triangleCount = m_random.getInt(minTriangleCount, maxTriangleCount);
    453 
    454 		for (int triangleNdx = 0; triangleNdx < triangleCount; triangleNdx++)
    455 		{
    456 			float x1 = 2.0f * m_random.getFloat() - 1.0f;
    457 			float y1 = 2.0f * m_random.getFloat() - 1.0f;
    458 			float z1 = 2.0f * m_random.getFloat() - 1.0f;
    459 
    460 			float x2 = 2.0f * m_random.getFloat() - 1.0f;
    461 			float y2 = 2.0f * m_random.getFloat() - 1.0f;
    462 			float z2 = 2.0f * m_random.getFloat() - 1.0f;
    463 
    464 			float x3 = 2.0f * m_random.getFloat() - 1.0f;
    465 			float y3 = 2.0f * m_random.getFloat() - 1.0f;
    466 			float z3 = 2.0f * m_random.getFloat() - 1.0f;
    467 
    468 			renderTriangle(tcu::Vec3(x1, y1, z1), tcu::Vec3(x2, y2, z2), tcu::Vec3(x3, y3, z3));
    469 		}
    470 	}
    471 
    472 	tcu::TextureFormat	readFormat;
    473 	GLenum				readPixelsFormat;
    474 	GLenum				readPixelsType;
    475 	bool				floatCompare;
    476 
    477 
    478 	if (m_framebuffeType == TestSpec::FRAMEBUFFERTYPE_NATIVE)
    479 	{
    480 		readFormat			= glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE);
    481 		readPixelsFormat	= GL_RGBA;
    482 		readPixelsType		= GL_UNSIGNED_BYTE;
    483 		floatCompare		= false;
    484 	}
    485 	else if (m_framebuffeType == TestSpec::FRAMEBUFFERTYPE_RENDERBUFFER)
    486 	{
    487 		switch (m_texChannelClass)
    488 		{
    489 			case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
    490 				readFormat			= glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE);
    491 				readPixelsFormat	= GL_RGBA;
    492 				readPixelsType		= GL_UNSIGNED_BYTE;
    493 				floatCompare		= true;
    494 				break;
    495 
    496 			case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
    497 				readFormat			= glu::mapGLTransferFormat(GL_RGBA_INTEGER, GL_INT);
    498 				readPixelsFormat	= GL_RGBA_INTEGER;
    499 				readPixelsType		= GL_INT;
    500 				floatCompare		= false;
    501 				break;
    502 
    503 			case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
    504 				readFormat			= glu::mapGLTransferFormat(GL_RGBA_INTEGER, GL_UNSIGNED_INT);
    505 				readPixelsFormat	= GL_RGBA_INTEGER;
    506 				readPixelsType		= GL_UNSIGNED_INT;
    507 				floatCompare		= false;
    508 				break;
    509 
    510 			case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
    511 				readFormat			= glu::mapGLTransferFormat(GL_RGBA, GL_FLOAT);
    512 				readPixelsFormat	= GL_RGBA;
    513 				readPixelsType		= GL_FLOAT;
    514 				floatCompare		= true;
    515 				break;
    516 
    517 			default:
    518 				DE_ASSERT(false);
    519 				// Silence warnings
    520 				readFormat			= glu::mapGLTransferFormat(GL_RGBA, GL_FLOAT);
    521 				readPixelsFormat	= GL_RGBA;
    522 				readPixelsType		= GL_FLOAT;
    523 				floatCompare		= true;
    524 		}
    525 	}
    526 	else
    527 	{
    528 		// Silence warnings
    529 		readFormat			= glu::mapGLTransferFormat(GL_RGBA, GL_FLOAT);
    530 		readPixelsFormat	= GL_RGBA;
    531 		readPixelsType		= GL_FLOAT;
    532 		floatCompare		= true;
    533 		DE_ASSERT(false);
    534 	}
    535 
    536 	tcu::Texture2D	readRefrence	(readFormat, width, height);
    537 	const int		readDataSize	= readRefrence.getWidth() * readRefrence.getHeight() * readFormat.getPixelSize();
    538 
    539 	readRefrence.allocLevel(0);
    540 
    541 	GLuint pixelBuffer = (GLuint)-1;
    542 
    543 	GLU_CHECK_CALL(glGenBuffers(1, &pixelBuffer));
    544 	GLU_CHECK_CALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, pixelBuffer));
    545 	GLU_CHECK_CALL(glBufferData(GL_PIXEL_PACK_BUFFER, readDataSize, NULL, GL_STREAM_READ));
    546 
    547 	GLU_CHECK_CALL(glReadPixels(0, 0, width, height, readPixelsFormat, readPixelsType, 0));
    548 
    549 	const deUint8* bufferData = (const deUint8*)glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, readDataSize, GL_MAP_READ_BIT);
    550 	GLU_CHECK_MSG("glMapBufferRange() failed");
    551 
    552 	tcu::ConstPixelBufferAccess readResult(readFormat, width, height, 1, bufferData);
    553 
    554 	GLU_CHECK_CALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0));
    555 
    556 	GLU_CHECK_CALL(glReadPixels(0, 0, width, height, readPixelsFormat, readPixelsType, readRefrence.getLevel(0).getDataPtr()));
    557 
    558 	if (framebuffer)
    559 		GLU_CHECK_CALL(glDeleteFramebuffers(1, &framebuffer));
    560 
    561 	if (renderbuffer)
    562 		GLU_CHECK_CALL(glDeleteRenderbuffers(1, &renderbuffer));
    563 
    564 
    565 	bool isOk = false;
    566 
    567 	if (floatCompare)
    568 		isOk = tcu::floatThresholdCompare(m_log, "Result comparision", "Result of read pixels to memory compared with result of read pixels to buffer", readRefrence.getLevel(0), readResult, tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::COMPARE_LOG_RESULT);
    569 	else
    570 		isOk = tcu::intThresholdCompare(m_log, "Result comparision", "Result of read pixels to memory compared with result of read pixels to buffer", readRefrence.getLevel(0), readResult, tcu::UVec4(0, 0, 0, 0), tcu::COMPARE_LOG_RESULT);
    571 
    572 	GLU_CHECK_CALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, pixelBuffer));
    573 	GLU_CHECK_CALL(glUnmapBuffer(GL_PIXEL_PACK_BUFFER));
    574 	GLU_CHECK_CALL(glDeleteBuffers(1, &pixelBuffer));
    575 
    576 	if (isOk)
    577 	{
    578 		m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    579 		return STOP;
    580 	}
    581 	else
    582 	{
    583 		m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
    584 		return STOP;
    585 	}
    586 }
    587 
    588 } // anonymous
    589 
    590 PixelBufferObjectTests::PixelBufferObjectTests (Context& context)
    591 	: TestCaseGroup (context, "pbo", "Pixel buffer objects tests")
    592 {
    593 }
    594 
    595 PixelBufferObjectTests::~PixelBufferObjectTests (void)
    596 {
    597 }
    598 
    599 void PixelBufferObjectTests::init (void)
    600 {
    601 	TestCaseGroup* nativeFramebufferGroup = new TestCaseGroup(m_context, "native", "Tests with reading from native framebuffer");
    602 
    603 	ReadPixelsTest::TestSpec nativeFramebufferTests[] = {
    604 		{
    605 			"clears",
    606 			"Simple read pixels test with color clears",
    607 			true,
    608 			false,
    609 			ReadPixelsTest::TestSpec::FRAMEBUFFERTYPE_NATIVE,
    610 			GL_NONE
    611 		},
    612 		{
    613 			"triangles",
    614 			"Simple read pixels test rendering triangles",
    615 			false,
    616 			true,
    617 			ReadPixelsTest::TestSpec::FRAMEBUFFERTYPE_NATIVE,
    618 			GL_NONE
    619 		}
    620 	};
    621 
    622 	for (int testNdx = 0; testNdx < DE_LENGTH_OF_ARRAY(nativeFramebufferTests); testNdx++)
    623 	{
    624 		nativeFramebufferGroup->addChild(new ReadPixelsTest(m_context, nativeFramebufferTests[testNdx]));
    625 	}
    626 
    627 	addChild(nativeFramebufferGroup);
    628 
    629 	TestCaseGroup* renderbufferGroup = new TestCaseGroup(m_context, "renderbuffer", "Tests with reading from renderbuffer");
    630 
    631 	GLenum renderbufferFormats[] = {
    632 		GL_RGBA8,
    633 		GL_RGBA8I,
    634 		GL_RGBA8UI,
    635 		GL_RGBA16F,
    636 		GL_RGBA16I,
    637 		GL_RGBA16UI,
    638 		GL_RGBA32F,
    639 		GL_RGBA32I,
    640 		GL_RGBA32UI,
    641 
    642 		GL_SRGB8_ALPHA8,
    643 		GL_RGB10_A2,
    644 		GL_RGB10_A2UI,
    645 		GL_RGBA4,
    646 		GL_RGB5_A1,
    647 
    648 		GL_RGB8,
    649 		GL_RGB565,
    650 
    651 		GL_R11F_G11F_B10F,
    652 
    653 		GL_RG8,
    654 		GL_RG8I,
    655 		GL_RG8UI,
    656 		GL_RG16F,
    657 		GL_RG16I,
    658 		GL_RG16UI,
    659 		GL_RG32F,
    660 		GL_RG32I,
    661 		GL_RG32UI
    662 	};
    663 
    664 	const char* renderbufferFormatsStr[] = {
    665 		"rgba8",
    666 		"rgba8i",
    667 		"rgba8ui",
    668 		"rgba16f",
    669 		"rgba16i",
    670 		"rgba16ui",
    671 		"rgba32f",
    672 		"rgba32i",
    673 		"rgba32ui",
    674 
    675 		"srgb8_alpha8",
    676 		"rgb10_a2",
    677 		"rgb10_a2ui",
    678 		"rgba4",
    679 		"rgb5_a1",
    680 
    681 		"rgb8",
    682 		"rgb565",
    683 
    684 		"r11f_g11f_b10f",
    685 
    686 		"rg8",
    687 		"rg8i",
    688 		"rg8ui",
    689 		"rg16f",
    690 		"rg16i",
    691 		"rg16ui",
    692 		"rg32f",
    693 		"rg32i",
    694 		"rg32ui"
    695 	};
    696 
    697 	DE_STATIC_ASSERT(DE_LENGTH_OF_ARRAY(renderbufferFormatsStr) == DE_LENGTH_OF_ARRAY(renderbufferFormats));
    698 
    699 	for (int formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(renderbufferFormats); formatNdx++)
    700 	{
    701 		for (int trianglesClears = 0; trianglesClears < 2; trianglesClears++)
    702 		{
    703 			ReadPixelsTest::TestSpec testSpec;
    704 
    705 			testSpec.name					= string(renderbufferFormatsStr [formatNdx]) + "_" + (trianglesClears == 0 ? "triangles" : "clears"),
    706 			testSpec.description			= testSpec.name;
    707 			testSpec.useColorClear			= trianglesClears == 1,
    708 			testSpec.renderTriangles		= trianglesClears == 0,
    709 			testSpec.framebufferType		= ReadPixelsTest::TestSpec::FRAMEBUFFERTYPE_RENDERBUFFER,
    710 			testSpec.renderbufferFormat		= renderbufferFormats[formatNdx];
    711 
    712 			renderbufferGroup->addChild(new ReadPixelsTest(m_context, testSpec));
    713 		}
    714 	}
    715 
    716 	addChild(renderbufferGroup);
    717 }
    718 
    719 } // Functional
    720 } // gles3
    721 } // deqp
    722