Home | History | Annotate | Download | only in functional
      1 /*-------------------------------------------------------------------------
      2  * drawElements Quality Program OpenGL ES 3.1 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 EXT Shader Framebuffer Fetch Tests.
     22  *//*--------------------------------------------------------------------*/
     23 
     24 #include "es31fShaderFramebufferFetchTests.hpp"
     25 #include "es31fFboTestUtil.hpp"
     26 
     27 #include "tcuTestLog.hpp"
     28 #include "tcuSurface.hpp"
     29 #include "tcuTextureUtil.hpp"
     30 #include "tcuImageCompare.hpp"
     31 #include "tcuVectorUtil.hpp"
     32 
     33 #include "gluShaderProgram.hpp"
     34 #include "gluPixelTransfer.hpp"
     35 #include "gluTextureUtil.hpp"
     36 #include "gluContextInfo.hpp"
     37 #include "gluObjectWrapper.hpp"
     38 
     39 #include "glwFunctions.hpp"
     40 #include "glwEnums.hpp"
     41 
     42 #include "deStringUtil.hpp"
     43 
     44 #include <vector>
     45 
     46 namespace deqp
     47 {
     48 namespace gles31
     49 {
     50 namespace Functional
     51 {
     52 namespace
     53 {
     54 
     55 using std::vector;
     56 using std::string;
     57 using tcu::TestLog;
     58 
     59 using namespace glw;
     60 using namespace FboTestUtil;
     61 
     62 static void checkExtensionSupport (Context& context, const char* extName)
     63 {
     64 	if (!context.getContextInfo().isExtensionSupported(extName))
     65 		throw tcu::NotSupportedError(string(extName) + " not supported");
     66 }
     67 
     68 static void checkFramebufferFetchSupport (Context& context)
     69 {
     70 	checkExtensionSupport(context, "GL_EXT_shader_framebuffer_fetch");
     71 }
     72 
     73 static bool isRequiredFormat (deUint32 format, glu::RenderContext& renderContext)
     74 {
     75 	const bool isES32 = glu::contextSupports(renderContext.getType(), glu::ApiType::es(3, 2));
     76 	switch (format)
     77 	{
     78 		// Color-renderable formats
     79 		case GL_RGBA32I:
     80 		case GL_RGBA32UI:
     81 		case GL_RGBA16I:
     82 		case GL_RGBA16UI:
     83 		case GL_RGBA8:
     84 		case GL_RGBA8I:
     85 		case GL_RGBA8UI:
     86 		case GL_SRGB8_ALPHA8:
     87 		case GL_RGB10_A2:
     88 		case GL_RGB10_A2UI:
     89 		case GL_RGBA4:
     90 		case GL_RGB5_A1:
     91 		case GL_RGB8:
     92 		case GL_RGB565:
     93 		case GL_RG32I:
     94 		case GL_RG32UI:
     95 		case GL_RG16I:
     96 		case GL_RG16UI:
     97 		case GL_RG8:
     98 		case GL_RG8I:
     99 		case GL_RG8UI:
    100 		case GL_R32I:
    101 		case GL_R32UI:
    102 		case GL_R16I:
    103 		case GL_R16UI:
    104 		case GL_R8:
    105 		case GL_R8I:
    106 		case GL_R8UI:
    107 			return true;
    108 
    109 		// Float format
    110 		case GL_RGBA32F:
    111 		case GL_RGB32F:
    112 		case GL_R11F_G11F_B10F:
    113 		case GL_RG32F:
    114 		case GL_R32F:
    115 			return isES32;
    116 
    117 		default:
    118 			return false;
    119 	}
    120 }
    121 
    122 tcu::TextureFormat getReadPixelFormat (const tcu::TextureFormat& format)
    123 {
    124 	switch (tcu::getTextureChannelClass(format.type))
    125 	{
    126 		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
    127 			return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT32);
    128 
    129 		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
    130 			return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::SIGNED_INT32);
    131 
    132 		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
    133 		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
    134 			return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8);
    135 
    136 		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
    137 			return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT);
    138 
    139 		default:
    140 			DE_ASSERT(false);
    141 			return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8);
    142 	}
    143 }
    144 
    145 tcu::Vec4 getFixedPointFormatThreshold (const tcu::TextureFormat& sourceFormat, const tcu::TextureFormat& readPixelsFormat)
    146 {
    147 	DE_ASSERT(tcu::getTextureChannelClass(sourceFormat.type) != tcu::TEXTURECHANNELCLASS_FLOATING_POINT);
    148 	DE_ASSERT(tcu::getTextureChannelClass(readPixelsFormat.type) != tcu::TEXTURECHANNELCLASS_FLOATING_POINT);
    149 
    150 	DE_ASSERT(tcu::getTextureChannelClass(sourceFormat.type) != tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER);
    151 	DE_ASSERT(tcu::getTextureChannelClass(readPixelsFormat.type) != tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER);
    152 
    153 	DE_ASSERT(tcu::getTextureChannelClass(sourceFormat.type) != tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER);
    154 	DE_ASSERT(tcu::getTextureChannelClass(readPixelsFormat.type) != tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER);
    155 
    156 	const tcu::IVec4	srcBits		= tcu::getTextureFormatBitDepth(sourceFormat);
    157 	const tcu::IVec4	readBits	= tcu::getTextureFormatBitDepth(readPixelsFormat);
    158 
    159 	return tcu::Vec4(3.0f) / ((tcu::Vector<deUint64, 4>(1) << (tcu::min(srcBits, readBits).cast<deUint64>())) - tcu::Vector<deUint64, 4>(1)).cast<float>();
    160 }
    161 
    162 tcu::UVec4 getFloatULPThreshold (const tcu::TextureFormat& sourceFormat, const tcu::TextureFormat& readPixelsFormat)
    163 {
    164 	const tcu::IVec4	srcMantissaBits		= tcu::getTextureFormatMantissaBitDepth(sourceFormat);
    165 	const tcu::IVec4	readMantissaBits	= tcu::getTextureFormatMantissaBitDepth(readPixelsFormat);
    166 	tcu::IVec4			ULPDiff(0);
    167 
    168 	for (int i = 0; i < 4; i++)
    169 		if (readMantissaBits[i] >= srcMantissaBits[i])
    170 			ULPDiff[i] = readMantissaBits[i] - srcMantissaBits[i];
    171 
    172 	return tcu::UVec4(4) * (tcu::UVec4(1) << (ULPDiff.cast<deUint32>()));
    173 }
    174 
    175 static bool isAnyExtensionSupported (Context& context, const std::vector<std::string>& requiredExts)
    176 {
    177 	for (std::vector<std::string>::const_iterator iter = requiredExts.begin(); iter != requiredExts.end(); iter++)
    178 	{
    179 		const std::string& extension = *iter;
    180 
    181 		if (context.getContextInfo().isExtensionSupported(extension.c_str()))
    182 			return true;
    183 	}
    184 
    185 	return false;
    186 }
    187 
    188 static std::string getColorOutputType(tcu::TextureFormat format)
    189 {
    190 	switch (tcu::getTextureChannelClass(format.type))
    191 	{
    192 		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:		return "uvec4";
    193 		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:		return "ivec4";
    194 		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
    195 		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
    196 		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:		return "vec4";
    197 		default:
    198 			DE_FATAL("Unsupported TEXTURECHANNELCLASS");
    199 			return "";
    200 	}
    201 }
    202 
    203 static std::vector<std::string> getEnablingExtensions (deUint32 format, glu::RenderContext& renderContext)
    204 {
    205 	const bool					isES32 = glu::contextSupports(renderContext.getType(), glu::ApiType::es(3, 2));
    206 	std::vector<std::string>	out;
    207 
    208 	DE_ASSERT(!isRequiredFormat(format, renderContext));
    209 
    210 	switch (format)
    211 	{
    212 		case GL_RGB16F:
    213 			out.push_back("GL_EXT_color_buffer_half_float");
    214 			break;
    215 
    216 		case GL_RGBA16F:
    217 		case GL_RG16F:
    218 		case GL_R16F:
    219 			out.push_back("GL_EXT_color_buffer_half_float");
    220 
    221 		case GL_RGBA32F:
    222 		case GL_RGB32F:
    223 		case GL_R11F_G11F_B10F:
    224 		case GL_RG32F:
    225 		case GL_R32F:
    226 			if (!isES32)
    227 				out.push_back("GL_EXT_color_buffer_float");
    228 			break;
    229 
    230 		default:
    231 			break;
    232 	}
    233 
    234 	return out;
    235 }
    236 
    237 void checkFormatSupport (Context& context, deUint32 sizedFormat)
    238 {
    239 	const bool						isCoreFormat	= isRequiredFormat(sizedFormat, context.getRenderContext());
    240 	const std::vector<std::string>	requiredExts	= (!isCoreFormat) ? getEnablingExtensions(sizedFormat, context.getRenderContext()) : std::vector<std::string>();
    241 
    242 	// Check that we don't try to use invalid formats.
    243 	DE_ASSERT(isCoreFormat || !requiredExts.empty());
    244 
    245 	if (!requiredExts.empty() && !isAnyExtensionSupported(context, requiredExts))
    246 		throw tcu::NotSupportedError("Format not supported");
    247 }
    248 
    249 tcu::Vec4 scaleColorValue (tcu::TextureFormat format, const tcu::Vec4& color)
    250 {
    251 	const tcu::TextureFormatInfo	fmtInfo			= tcu::getTextureFormatInfo(format);
    252 	const tcu::Vec4					cScale			= fmtInfo.valueMax-fmtInfo.valueMin;
    253 	const tcu::Vec4					cBias			= fmtInfo.valueMin;
    254 
    255 	return tcu::RGBA(color).toVec() * cScale + cBias;
    256 }
    257 
    258 // Base class for framebuffer fetch test cases
    259 
    260 class FramebufferFetchTestCase : public TestCase
    261 {
    262 public:
    263 									FramebufferFetchTestCase		(Context& context, const char* name, const char* desc, deUint32 format);
    264 									~FramebufferFetchTestCase		(void);
    265 
    266 	void							init							(void);
    267 	void							deinit							(void);
    268 
    269 protected:
    270 	string							genPassThroughVertSource		(void);
    271 	virtual glu::ProgramSources		genShaderSources				(void);
    272 
    273 	void							genFramebufferWithTexture		(const tcu::Vec4& color);
    274 	void							genAttachementTexture			(const tcu::Vec4& color);
    275 	void							genUniformColor					(const tcu::Vec4& color);
    276 
    277 	void							render							(void);
    278 	void							verifyRenderbuffer				(TestLog& log, const tcu::TextureFormat& format, const tcu::TextureLevel& reference, const tcu::TextureLevel& result);
    279 
    280 	const glw::Functions&			m_gl;
    281 	const deUint32					m_format;
    282 
    283 	glu::ShaderProgram*				m_program;
    284 	GLuint							m_framebuffer;
    285 	GLuint							m_texColorBuffer;
    286 
    287 	tcu::TextureFormat				m_texFmt;
    288 	glu::TransferFormat				m_transferFmt;
    289 	bool							m_isFilterable;
    290 
    291 	enum
    292 	{
    293 		VIEWPORT_WIDTH	= 64,
    294 		VIEWPORT_HEIGHT = 64,
    295 	};
    296 };
    297 
    298 FramebufferFetchTestCase::FramebufferFetchTestCase (Context& context, const char* name, const char* desc, deUint32 format)
    299 	: TestCase (context, name, desc)
    300 	, m_gl					(m_context.getRenderContext().getFunctions())
    301 	, m_format				(format)
    302 	, m_program				(DE_NULL)
    303 	, m_framebuffer			(0)
    304 	, m_texColorBuffer		(0)
    305 	, m_texFmt				(glu::mapGLInternalFormat(m_format))
    306 	, m_transferFmt			(glu::getTransferFormat(m_texFmt))
    307 	, m_isFilterable		(glu::isGLInternalColorFormatFilterable(m_format))
    308 {
    309 }
    310 
    311 FramebufferFetchTestCase::~FramebufferFetchTestCase (void)
    312 {
    313 	FramebufferFetchTestCase::deinit();
    314 }
    315 
    316 void FramebufferFetchTestCase::init (void)
    317 {
    318 	checkFramebufferFetchSupport (m_context);
    319 	checkFormatSupport(m_context, m_format);
    320 
    321 	DE_ASSERT(!m_program);
    322 	m_program = new glu::ShaderProgram(m_context.getRenderContext(), genShaderSources());
    323 
    324 	m_testCtx.getLog() << *m_program;
    325 
    326 	if (!m_program->isOk())
    327 	{
    328 		delete m_program;
    329 		m_program = DE_NULL;
    330 		TCU_FAIL("Failed to compile shader program");
    331 	}
    332 
    333 	m_gl.useProgram(m_program->getProgram());
    334 }
    335 
    336 void FramebufferFetchTestCase::deinit (void)
    337 {
    338 	delete m_program;
    339 	m_program = DE_NULL;
    340 
    341 	if (m_framebuffer)
    342 	{
    343 		m_gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
    344 		m_gl.deleteFramebuffers(1, &m_framebuffer);
    345 		m_framebuffer = 0;
    346 	}
    347 
    348 	if (m_texColorBuffer)
    349 	{
    350 		m_gl.deleteTextures(1, &m_texColorBuffer);
    351 		m_texColorBuffer = 0;
    352 	}
    353 }
    354 
    355 string FramebufferFetchTestCase::genPassThroughVertSource (void)
    356 {
    357 	std::ostringstream vertShaderSource;
    358 
    359 	vertShaderSource	<< "#version 310 es\n"
    360 						<< "in highp vec4 a_position;\n"
    361 						<< "\n"
    362 						<< "void main (void)\n"
    363 						<< "{\n"
    364 						<< "	gl_Position = a_position;\n"
    365 						<< "}\n";
    366 
    367 	return vertShaderSource.str();
    368 }
    369 
    370 glu::ProgramSources FramebufferFetchTestCase::genShaderSources (void)
    371 {
    372 	const string		vecType	= getColorOutputType(m_texFmt);
    373 	std::ostringstream	fragShaderSource;
    374 
    375 	fragShaderSource	<< "#version 310 es\n"
    376 						<< "#extension GL_EXT_shader_framebuffer_fetch : require\n"
    377 						<< "layout(location = 0) inout highp " << vecType << " o_color;\n"
    378 						<< "uniform highp " << vecType << " u_color;\n"
    379 						<< "\n"
    380 						<< "void main (void)\n"
    381 						<< "{\n"
    382 						<< "	o_color += u_color;\n"
    383 						<< "}\n";
    384 
    385 	return glu::makeVtxFragSources(genPassThroughVertSource(), fragShaderSource.str());
    386 }
    387 
    388 void FramebufferFetchTestCase::genFramebufferWithTexture (const tcu::Vec4& color)
    389 {
    390 	m_gl.genFramebuffers(1, &m_framebuffer);
    391 	m_gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
    392 
    393 	genAttachementTexture(color);
    394 	GLU_EXPECT_NO_ERROR(m_gl.getError(), "genAttachementTexture()");
    395 
    396 	m_gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texColorBuffer, 0);
    397 	TCU_CHECK(m_gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
    398 }
    399 
    400 void FramebufferFetchTestCase::genAttachementTexture (const tcu::Vec4& color)
    401 {
    402 	tcu::TextureLevel			data					(glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
    403 	tcu::TextureChannelClass	textureChannelClass =	tcu::getTextureChannelClass(m_texFmt.type);
    404 
    405 	m_gl.genTextures(1, &m_texColorBuffer);
    406 	m_gl.bindTexture(GL_TEXTURE_2D, m_texColorBuffer);
    407 
    408 	m_gl.texParameteri(GL_TEXTURE_2D,	GL_TEXTURE_WRAP_S,		GL_CLAMP_TO_EDGE);
    409 	m_gl.texParameteri(GL_TEXTURE_2D,	GL_TEXTURE_WRAP_T,		GL_CLAMP_TO_EDGE);
    410 	m_gl.texParameteri(GL_TEXTURE_2D,	GL_TEXTURE_WRAP_R,		GL_CLAMP_TO_EDGE);
    411 	m_gl.texParameteri(GL_TEXTURE_2D,	GL_TEXTURE_MIN_FILTER,	m_isFilterable ? GL_LINEAR : GL_NEAREST);
    412 	m_gl.texParameteri(GL_TEXTURE_2D,	GL_TEXTURE_MAG_FILTER,	m_isFilterable ? GL_LINEAR : GL_NEAREST);
    413 
    414 	if (textureChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
    415 		tcu::clear(data.getAccess(), color.asUint());
    416 	else if (textureChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
    417 		tcu::clear(data.getAccess(), color.asInt());
    418 	else
    419 		tcu::clear(data.getAccess(), color);
    420 
    421 	m_gl.texImage2D(GL_TEXTURE_2D, 0, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 0, m_transferFmt.format, m_transferFmt.dataType, data.getAccess().getDataPtr());
    422 	m_gl.bindTexture(GL_TEXTURE_2D, 0);
    423 }
    424 
    425 void FramebufferFetchTestCase::verifyRenderbuffer (TestLog&	log, const tcu::TextureFormat& format, const tcu::TextureLevel&	reference, const tcu::TextureLevel&	result)
    426 {
    427 	m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
    428 
    429 	switch (tcu::getTextureChannelClass(format.type))
    430 	{
    431 		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
    432 		{
    433 			const string		name		= "Renderbuffer";
    434 			const string		desc		= "Compare renderbuffer (floating_point)";
    435 			const tcu::UVec4	threshold	= getFloatULPThreshold(format, result.getFormat());
    436 
    437 			if (!tcu::floatUlpThresholdCompare(log, name.c_str(), desc.c_str(), reference, result, threshold, tcu::COMPARE_LOG_RESULT))
    438 				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
    439 
    440 			break;
    441 		}
    442 
    443 		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
    444 		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
    445 		{
    446 			const string		name		= "Renderbuffer";
    447 			const string		desc		= "Compare renderbuffer (integer)";
    448 			const tcu::UVec4	threshold	(1, 1, 1, 1);
    449 
    450 			if (!tcu::intThresholdCompare(log, name.c_str(), desc.c_str(), reference, result, threshold, tcu::COMPARE_LOG_RESULT))
    451 				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
    452 
    453 			break;
    454 		}
    455 
    456 		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
    457 		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
    458 		{
    459 			const string		name		= "Renderbuffer";
    460 			const string		desc		= "Compare renderbuffer (fixed point)";
    461 			const tcu::Vec4		threshold	= getFixedPointFormatThreshold(format, result.getFormat());
    462 
    463 			if (!tcu::floatThresholdCompare(log, name.c_str(), desc.c_str(), reference, result, threshold, tcu::COMPARE_LOG_RESULT))
    464 				m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
    465 
    466 			break;
    467 		}
    468 
    469 		default:
    470 		{
    471 			DE_ASSERT(DE_FALSE);
    472 			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
    473 		}
    474 	}
    475 }
    476 
    477 void FramebufferFetchTestCase::genUniformColor (const tcu::Vec4& color)
    478 {
    479 	const GLuint colorLocation	= m_gl.getUniformLocation(m_program->getProgram(), "u_color");
    480 
    481 	switch (tcu::getTextureChannelClass(m_texFmt.type))
    482 	{
    483 		case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
    484 		{
    485 			m_gl.uniform4uiv(colorLocation, 1, color.asUint().getPtr());
    486 			break;
    487 		}
    488 
    489 		case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
    490 		{
    491 			m_gl.uniform4iv(colorLocation, 1, color.asInt().getPtr());
    492 			break;
    493 		}
    494 		case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
    495 		case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
    496 		case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
    497 		{
    498 			m_gl.uniform4fv(colorLocation, 1, color.asFloat().getPtr());
    499 			break;
    500 		}
    501 		default:
    502 			DE_ASSERT(DE_FALSE);
    503 	}
    504 
    505 	GLU_EXPECT_NO_ERROR(m_gl.getError(), "genUniformColor()");
    506 }
    507 
    508 void FramebufferFetchTestCase::render (void)
    509 {
    510 	const GLfloat coords[] =
    511 	{
    512 		-1.0f, -1.0f,
    513 		+1.0f, -1.0f,
    514 		+1.0f, +1.0f,
    515 		-1.0f, +1.0f,
    516 	};
    517 
    518 	const GLushort indices[] =
    519 	{
    520 		0, 1, 2, 2, 3, 0,
    521 	};
    522 
    523 	const GLuint	coordLocation	= m_gl.getAttribLocation(m_program->getProgram(), "a_position");
    524 
    525 	m_gl.viewport(0, 0, VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
    526 
    527 	glu::Buffer coordinatesBuffer(m_context.getRenderContext());
    528 	glu::Buffer elementsBuffer(m_context.getRenderContext());
    529 
    530 	m_gl.bindBuffer(GL_ARRAY_BUFFER, *coordinatesBuffer);
    531 	m_gl.bufferData(GL_ARRAY_BUFFER, (GLsizeiptr)sizeof(coords), coords, GL_STATIC_DRAW);
    532 	m_gl.enableVertexAttribArray(coordLocation);
    533 	m_gl.vertexAttribPointer(coordLocation, 2, GL_FLOAT, GL_FALSE, 0, DE_NULL);
    534 
    535 	m_gl.bindBuffer(GL_ELEMENT_ARRAY_BUFFER, *elementsBuffer);
    536 	m_gl.bufferData(GL_ELEMENT_ARRAY_BUFFER, (GLsizeiptr)sizeof(indices), &indices[0], GL_STATIC_DRAW);
    537 
    538 	m_gl.drawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, DE_NULL);
    539 	GLU_EXPECT_NO_ERROR(m_gl.getError(), "render()");
    540 }
    541 
    542 // Test description:
    543 // - Attach texture containing solid color to framebuffer.
    544 // - Draw full quad covering the entire viewport.
    545 // - Sum framebuffer read color with passed in uniform color.
    546 // - Compare resulting surface with reference.
    547 
    548 class TextureFormatTestCase : public FramebufferFetchTestCase
    549 {
    550 public:
    551 						TextureFormatTestCase		(Context& context, const char* name, const char* desc, deUint32 format);
    552 						~TextureFormatTestCase		(void) {};
    553 
    554 	IterateResult		iterate						(void);
    555 
    556 private:
    557 	tcu::TextureLevel	genReferenceTexture			(const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor);
    558 };
    559 
    560 TextureFormatTestCase::TextureFormatTestCase (Context& context, const char* name, const char* desc, deUint32 format)
    561 	: FramebufferFetchTestCase(context, name, desc, format)
    562 {
    563 }
    564 
    565 tcu::TextureLevel TextureFormatTestCase::genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor)
    566 {
    567 	tcu::TextureLevel			reference			(glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
    568 	tcu::TextureChannelClass	textureChannelClass = tcu::getTextureChannelClass(m_texFmt.type);
    569 
    570 	if (textureChannelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
    571 	{
    572 		tcu::clear(reference.getAccess(), fbColor.asUint() + uniformColor.asUint());
    573 	}
    574 	else if (textureChannelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
    575 	{
    576 		tcu::clear(reference.getAccess(), fbColor.asInt() + uniformColor.asInt());
    577 	}
    578 	else
    579 	{
    580 		if (tcu::isSRGB(m_texFmt))
    581 		{
    582 			const tcu::Vec4	fragmentColor = tcu::sRGBToLinear(fbColor) + uniformColor;
    583 			tcu::clear(reference.getAccess(), tcu::linearToSRGB(fragmentColor));
    584 		}
    585 		else
    586 		{
    587 			tcu::clear(reference.getAccess(), fbColor + uniformColor);
    588 		}
    589 	}
    590 
    591 	return reference;
    592 }
    593 
    594 TextureFormatTestCase::IterateResult TextureFormatTestCase::iterate (void)
    595 {
    596 	const tcu::Vec4		uniformColor	= scaleColorValue(m_texFmt, tcu::Vec4(0.1f, 0.1f, 0.1f, 1.0f));
    597 	const tcu::Vec4		fbColor			= scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f));
    598 
    599 	tcu::TextureLevel	reference		= genReferenceTexture(fbColor, uniformColor);
    600 	tcu::TextureLevel	result			(getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
    601 
    602 	genFramebufferWithTexture(fbColor);
    603 	genUniformColor(uniformColor);
    604 	render();
    605 
    606 	glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
    607 	verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
    608 
    609 	return STOP;
    610 }
    611 
    612 // Test description:
    613 // - Attach multiple textures containing solid colors to framebuffer.
    614 // - Draw full quad covering the entire viewport.
    615 // - For each render target sum framebuffer read color with passed in uniform color.
    616 // - Compare resulting surfaces with references.
    617 
    618 class MultipleRenderTargetsTestCase : public FramebufferFetchTestCase
    619 {
    620 public:
    621 						MultipleRenderTargetsTestCase		(Context& context, const char* name, const char* desc, deUint32 format);
    622 						~MultipleRenderTargetsTestCase		(void);
    623 
    624 	IterateResult		iterate								(void);
    625 	void				deinit								(void);
    626 
    627 private:
    628 	void				genFramebufferWithTextures			(const vector<tcu::Vec4>& colors);
    629 	void				genAttachmentTextures				(const vector<tcu::Vec4>& colors);
    630 	tcu::TextureLevel	genReferenceTexture					(const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor);
    631 	glu::ProgramSources genShaderSources					(void);
    632 
    633 	enum
    634 	{
    635 		MAX_COLOR_BUFFERS = 4
    636 	};
    637 
    638 	GLuint				m_texColorBuffers					[MAX_COLOR_BUFFERS];
    639 	GLenum				m_colorBuffers						[MAX_COLOR_BUFFERS];
    640 };
    641 
    642 MultipleRenderTargetsTestCase::MultipleRenderTargetsTestCase (Context& context, const char* name, const char* desc, deUint32 format)
    643 	: FramebufferFetchTestCase(context, name, desc, format)
    644 	, m_texColorBuffers ()
    645 {
    646 	m_colorBuffers[0] = GL_COLOR_ATTACHMENT0;
    647 	m_colorBuffers[1] = GL_COLOR_ATTACHMENT1;
    648 	m_colorBuffers[2] = GL_COLOR_ATTACHMENT2;
    649 	m_colorBuffers[3] = GL_COLOR_ATTACHMENT3;
    650 }
    651 
    652 MultipleRenderTargetsTestCase::~MultipleRenderTargetsTestCase (void)
    653 {
    654 	MultipleRenderTargetsTestCase::deinit();
    655 }
    656 
    657 void MultipleRenderTargetsTestCase::deinit (void)
    658 {
    659 	// Clean up texture data
    660 	for (int i = 0; i < DE_LENGTH_OF_ARRAY(m_texColorBuffers); ++i)
    661 	{
    662 		if (m_texColorBuffers[i])
    663 			m_context.getRenderContext().getFunctions().deleteTextures(1, &m_texColorBuffers[i]);
    664 	}
    665 
    666 	FramebufferFetchTestCase::deinit();
    667 }
    668 
    669 void MultipleRenderTargetsTestCase::genFramebufferWithTextures (const vector<tcu::Vec4>& colors)
    670 {
    671 	m_gl.genFramebuffers(1, &m_framebuffer);
    672 	m_gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
    673 
    674 	genAttachmentTextures(colors);
    675 
    676 	for (int i = 0; i < DE_LENGTH_OF_ARRAY(m_texColorBuffers); ++i)
    677 		m_gl.framebufferTexture2D(GL_FRAMEBUFFER, m_colorBuffers[i], GL_TEXTURE_2D, m_texColorBuffers[i], 0);
    678 
    679 	TCU_CHECK(m_gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
    680 
    681 	m_gl.drawBuffers((glw::GLsizei)MAX_COLOR_BUFFERS, &m_colorBuffers[0]);
    682 	GLU_EXPECT_NO_ERROR(m_gl.getError(), "genFramebufferWithTextures()");
    683 }
    684 
    685 void MultipleRenderTargetsTestCase::genAttachmentTextures (const vector<tcu::Vec4>& colors)
    686 {
    687 	tcu::TextureLevel	data	(glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
    688 
    689 	m_gl.genTextures(MAX_COLOR_BUFFERS, m_texColorBuffers);
    690 
    691 	for (int i = 0; i < DE_LENGTH_OF_ARRAY(m_texColorBuffers); ++i)
    692 	{
    693 		m_gl.bindTexture(GL_TEXTURE_2D, m_texColorBuffers[i]);
    694 
    695 		m_gl.texParameteri(GL_TEXTURE_2D,	GL_TEXTURE_WRAP_S,		GL_CLAMP_TO_EDGE);
    696 		m_gl.texParameteri(GL_TEXTURE_2D,	GL_TEXTURE_WRAP_T,		GL_CLAMP_TO_EDGE);
    697 		m_gl.texParameteri(GL_TEXTURE_2D,	GL_TEXTURE_WRAP_R,		GL_CLAMP_TO_EDGE);
    698 		m_gl.texParameteri(GL_TEXTURE_2D,	GL_TEXTURE_MIN_FILTER,	m_isFilterable ? GL_LINEAR : GL_NEAREST);
    699 		m_gl.texParameteri(GL_TEXTURE_2D,	GL_TEXTURE_MAG_FILTER,	m_isFilterable ? GL_LINEAR : GL_NEAREST);
    700 
    701 		clear(data.getAccess(), colors[i]);
    702 		m_gl.texImage2D(GL_TEXTURE_2D, 0, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 0, m_transferFmt.format, m_transferFmt.dataType, data.getAccess().getDataPtr());
    703 	}
    704 
    705 	m_gl.bindTexture(GL_TEXTURE_2D, 0);
    706 	GLU_EXPECT_NO_ERROR(m_gl.getError(), "genAttachmentTextures()");
    707 }
    708 
    709 tcu::TextureLevel MultipleRenderTargetsTestCase::genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor)
    710 {
    711 	tcu::TextureLevel	reference	(glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
    712 	tcu::clear(reference.getAccess(), fbColor + uniformColor);
    713 
    714 	return reference;
    715 }
    716 
    717 glu::ProgramSources MultipleRenderTargetsTestCase::genShaderSources (void)
    718 {
    719 	const string		vecType	= getColorOutputType(m_texFmt);
    720 	std::ostringstream	fragShaderSource;
    721 
    722 	fragShaderSource	<< "#version 310 es\n"
    723 						<< "#extension GL_EXT_shader_framebuffer_fetch : require\n"
    724 						<< "layout(location = 0) inout highp " << vecType << " o_color0;\n"
    725 						<< "layout(location = 1) inout highp " << vecType << " o_color1;\n"
    726 						<< "layout(location = 2) inout highp " << vecType << " o_color2;\n"
    727 						<< "layout(location = 3) inout highp " << vecType << " o_color3;\n"
    728 						<< "uniform highp " << vecType << " u_color;\n"
    729 						<< "\n"
    730 						<< "void main (void)\n"
    731 						<< "{\n"
    732 						<< "	o_color0 += u_color;\n"
    733 						<< "	o_color1 += u_color;\n"
    734 						<< "	o_color2 += u_color;\n"
    735 						<< "	o_color3 += u_color;\n"
    736 						<< "}\n";
    737 
    738 	return glu::makeVtxFragSources(genPassThroughVertSource(), fragShaderSource.str());
    739 }
    740 
    741 MultipleRenderTargetsTestCase::IterateResult MultipleRenderTargetsTestCase::iterate (void)
    742 {
    743 	const tcu::Vec4		uniformColor	= scaleColorValue(m_texFmt, tcu::Vec4(0.1f, 0.1f, 0.1f, 1.0f));
    744 	tcu::TextureLevel	result			(getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
    745 
    746 	vector<tcu::Vec4> colors;
    747 	colors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.9f, 0.0f, 0.0f, 1.0f)));
    748 	colors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 0.9f, 0.0f, 1.0f)));
    749 	colors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 0.0f, 0.9f, 1.0f)));
    750 	colors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 0.9f, 0.9f, 1.0f)));
    751 
    752 	genFramebufferWithTextures(colors);
    753 	genUniformColor(uniformColor);
    754 	render();
    755 
    756 	for (int i = 0; i < DE_LENGTH_OF_ARRAY(m_colorBuffers); ++i)
    757 	{
    758 		tcu::TextureLevel	reference		= genReferenceTexture(colors[i], uniformColor);
    759 
    760 		m_gl.readBuffer(m_colorBuffers[i]);
    761 		glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
    762 		verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
    763 	}
    764 
    765 	return STOP;
    766 }
    767 
    768 // Test description:
    769 // - Same as TextureFormatTestCase except uses built-in fragment output of ES 2.0
    770 
    771 class LastFragDataTestCase : public FramebufferFetchTestCase
    772 {
    773 public:
    774 						LastFragDataTestCase			(Context& context, const char* name, const char* desc, deUint32 format);
    775 						~LastFragDataTestCase			(void) {};
    776 
    777 	IterateResult		iterate							(void);
    778 
    779 private:
    780 	glu::ProgramSources genShaderSources				(void);
    781 	tcu::TextureLevel	genReferenceTexture				(const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor);
    782 };
    783 
    784 LastFragDataTestCase::LastFragDataTestCase (Context& context, const char* name, const char* desc, deUint32 format)
    785 	: FramebufferFetchTestCase(context, name, desc, format)
    786 {
    787 }
    788 
    789 glu::ProgramSources LastFragDataTestCase::genShaderSources (void)
    790 {
    791 	const string		vecType	= getColorOutputType(m_texFmt);
    792 	std::ostringstream	vertShaderSource;
    793 	std::ostringstream	fragShaderSource;
    794 
    795 	vertShaderSource	<< "#version 100\n"
    796 						<< "attribute vec4 a_position;\n"
    797 						<< "\n"
    798 						<< "void main (void)\n"
    799 						<< "{\n"
    800 						<< "	gl_Position = a_position;\n"
    801 						<< "}\n";
    802 
    803 	fragShaderSource	<< "#version 100\n"
    804 						<< "#extension GL_EXT_shader_framebuffer_fetch : require\n"
    805 						<< "uniform highp " << vecType << " u_color;\n"
    806 						<< "\n"
    807 						<< "void main (void)\n"
    808 						<< "{\n"
    809 						<< "	gl_FragColor = u_color + gl_LastFragData[0];\n"
    810 						<< "}\n";
    811 
    812 	return glu::makeVtxFragSources(vertShaderSource.str(), fragShaderSource.str());
    813 }
    814 
    815 tcu::TextureLevel LastFragDataTestCase::genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor)
    816 {
    817 	tcu::TextureLevel	reference	(glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
    818 	tcu::clear(reference.getAccess(), fbColor + uniformColor);
    819 
    820 	return reference;
    821 }
    822 
    823 LastFragDataTestCase::IterateResult LastFragDataTestCase::iterate (void)
    824 {
    825 	const tcu::Vec4		uniformColor	= scaleColorValue(m_texFmt, tcu::Vec4(0.1f, 0.1f, 0.1f, 1.0f));
    826 	const tcu::Vec4		fbColor			= scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f));
    827 
    828 	tcu::TextureLevel	reference		= genReferenceTexture(fbColor, uniformColor);
    829 	tcu::TextureLevel	result			(getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
    830 
    831 	genFramebufferWithTexture(fbColor);
    832 	genUniformColor(uniformColor);
    833 	render();
    834 
    835 	glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
    836 	verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
    837 
    838 	return STOP;
    839 }
    840 
    841 // Test description:
    842 // - Attach texture containing solid color to framebuffer.
    843 // - Create one 2D texture for sampler with a grid pattern
    844 // - Draw full screen quad covering the entire viewport.
    845 // - Sum color values taken from framebuffer texture and sampled texture
    846 // - Compare resulting surface with reference.
    847 
    848 class TexelFetchTestCase : public FramebufferFetchTestCase
    849 {
    850 public:
    851 						TexelFetchTestCase		(Context& context, const char* name, const char* desc, deUint32 format);
    852 						~TexelFetchTestCase		(void) {}
    853 
    854 	IterateResult		iterate					(void);
    855 
    856 private:
    857 	glu::ProgramSources genShaderSources		(void);
    858 	tcu::TextureLevel	genReferenceTexture		(const tcu::Vec4& colorEven, const tcu::Vec4& colorOdd, const tcu::Vec4& fbColor);
    859 	void				genSamplerTexture		(const tcu::Vec4& colorEven, const tcu::Vec4& colorOdd);
    860 
    861 	GLuint				m_samplerTexture;
    862 };
    863 
    864 TexelFetchTestCase::TexelFetchTestCase (Context& context, const char* name, const char* desc, deUint32 format)
    865 	: FramebufferFetchTestCase(context, name, desc, format)
    866 	, m_samplerTexture(0)
    867 {
    868 }
    869 
    870 void TexelFetchTestCase::genSamplerTexture (const tcu::Vec4& colorEven, const tcu::Vec4& colorOdd)
    871 {
    872 	tcu::TextureLevel	data	(glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
    873 
    874 	m_gl.activeTexture(GL_TEXTURE1);
    875 
    876 	m_gl.genTextures(1, &m_samplerTexture);
    877 	m_gl.bindTexture(GL_TEXTURE_2D, m_texColorBuffer);
    878 	m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    879 	m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    880 
    881 	tcu::fillWithGrid(data.getAccess(), 8, colorEven, colorOdd);
    882 
    883 	m_gl.texImage2D(GL_TEXTURE_2D, 0, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 0, m_transferFmt.format, m_transferFmt.dataType, data.getAccess().getDataPtr());
    884 	m_gl.bindTexture(GL_TEXTURE_2D, 0);
    885 
    886 	const GLuint samplerLocation = m_gl.getUniformLocation(m_program->getProgram(), "u_sampler");
    887 	m_gl.uniform1i(samplerLocation, 1);
    888 
    889 	GLU_EXPECT_NO_ERROR(m_gl.getError(), "genSamplerTexture()");
    890 }
    891 
    892 glu::ProgramSources TexelFetchTestCase::genShaderSources (void)
    893 {
    894 	const string		vecType	= getColorOutputType(m_texFmt);
    895 	std::ostringstream	fragShaderSource;
    896 
    897 	fragShaderSource	<< "#version 310 es\n"
    898 						<< "#extension GL_EXT_shader_framebuffer_fetch : require\n"
    899 						<< "layout(location = 0) inout highp " << vecType << " o_color;\n"
    900 						<< "\n"
    901 						<< "uniform sampler2D u_sampler;\n"
    902 						<< "void main (void)\n"
    903 						<< "{\n"
    904 						<< "	o_color += texelFetch(u_sampler, ivec2(gl_FragCoord), 0);\n"
    905 						<< "}\n";
    906 
    907 	return glu::makeVtxFragSources(genPassThroughVertSource(), fragShaderSource.str());
    908 }
    909 
    910 tcu::TextureLevel TexelFetchTestCase::genReferenceTexture (const tcu::Vec4& colorEven, const tcu::Vec4& colorOdd, const tcu::Vec4& fbColor)
    911 {
    912 	tcu::TextureLevel	reference	(glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
    913 	tcu::fillWithGrid(reference.getAccess(), 8, colorEven + fbColor, colorOdd + fbColor);
    914 
    915 	return reference;
    916 }
    917 
    918 TexelFetchTestCase::IterateResult TexelFetchTestCase::iterate (void)
    919 {
    920 	const tcu::Vec4		fbColor			= scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 0.5f, 1.0f));
    921 	const tcu::Vec4		colorEven		= scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.5f, 0.0f, 1.0f));
    922 	const tcu::Vec4		colorOdd		= scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 0.5f, 1.0f));
    923 
    924 	genSamplerTexture(colorEven, colorOdd);
    925 	tcu::TextureLevel	reference		= genReferenceTexture(colorEven, colorOdd, fbColor);
    926 	tcu::TextureLevel	result			(getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
    927 
    928 	genFramebufferWithTexture(fbColor);
    929 	render();
    930 
    931 	glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
    932 	verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
    933 
    934 	// cleanup
    935 	m_gl.deleteTextures(1, &m_samplerTexture);
    936 
    937 	return STOP;
    938 }
    939 
    940 // Test description:
    941 // - Attach texture containing solid color to framebuffer.
    942 // - Draw full screen quad covering the entire viewport.
    943 // - Multiple assignments are made to the output color for fragments on the right vertical half of the screen.
    944 // - A single assignment is made to the output color for fragments on the left vertical centre of the screen.
    945 // - Values are calculated using the sum of the passed in uniform color and the previous framebuffer color.
    946 // - Compare resulting surface with reference.
    947 
    948 class MultipleAssignmentTestCase : public FramebufferFetchTestCase
    949 {
    950 public:
    951 						MultipleAssignmentTestCase		(Context& context, const char* name, const char* desc, deUint32 format);
    952 						~MultipleAssignmentTestCase		(void) {}
    953 
    954 	IterateResult		iterate							(void);
    955 
    956 private:
    957 	glu::ProgramSources genShaderSources				(void);
    958 	tcu::TextureLevel	genReferenceTexture				(const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor);
    959 };
    960 
    961 MultipleAssignmentTestCase::MultipleAssignmentTestCase (Context& context, const char* name, const char* desc, deUint32 format)
    962 	: FramebufferFetchTestCase(context, name, desc, format)
    963 {
    964 }
    965 
    966 glu::ProgramSources MultipleAssignmentTestCase::genShaderSources (void)
    967 {
    968 	const string		vecType = getColorOutputType(m_texFmt);
    969 	std::ostringstream	vertShaderSource;
    970 	std::ostringstream	fragShaderSource;
    971 
    972 	vertShaderSource	<< "#version 310 es\n"
    973 						<< "in highp vec4 a_position;\n"
    974 						<< "out highp vec4 v_position;\n"
    975 						<< "\n"
    976 						<< "void main (void)\n"
    977 						<< "{\n"
    978 						<< "	gl_Position = a_position;\n"
    979 						<< "	v_position  = gl_Position;\n"
    980 						<< "}\n";
    981 
    982 	fragShaderSource	<< "#version 310 es\n"
    983 						<< "#extension GL_EXT_shader_framebuffer_fetch : require\n"
    984 						<< "in highp vec4 v_position;\n"
    985 						<< "layout(location = 0) inout highp " << vecType << " o_color;\n"
    986 						<< "uniform highp " << vecType << " u_color;\n"
    987 						<< "\n"
    988 						<< "void main (void)\n"
    989 						<< "{\n"
    990 						<< "	if (v_position.x > 0.0f)\n"
    991 						<< "		o_color += u_color;\n"
    992 						<< "\n"
    993 						<< "	o_color += u_color;\n"
    994 						<< "}\n";
    995 
    996 	return glu::makeVtxFragSources(vertShaderSource.str(), fragShaderSource.str());
    997 }
    998 
    999 tcu::TextureLevel MultipleAssignmentTestCase::genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor)
   1000 {
   1001 	tcu::TextureLevel	reference	(glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
   1002 
   1003 	int	width	= reference.getAccess().getWidth();
   1004 	int	height	= reference.getAccess().getHeight();
   1005 	int	left	= width /2;
   1006 	int	top		= height/2;
   1007 
   1008 	tcu::Vec4 compositeColor(uniformColor * 2.0f);
   1009 
   1010 	tcu::clear(getSubregion(reference.getAccess(), left,		0,		0, width-left,	top,		1),	fbColor + compositeColor);
   1011 	tcu::clear(getSubregion(reference.getAccess(), 0,			top,	0, left,		height-top,	1), fbColor + uniformColor);
   1012 	tcu::clear(getSubregion(reference.getAccess(), left,		top,	0, width-left,	height-top, 1), fbColor + compositeColor);
   1013 	tcu::clear(getSubregion(reference.getAccess(), 0,			0,		0, left,		top,		1),	fbColor + uniformColor);
   1014 
   1015 	return reference;
   1016 }
   1017 
   1018 MultipleAssignmentTestCase::IterateResult MultipleAssignmentTestCase::iterate (void)
   1019 {
   1020 	const tcu::Vec4		fbColor			= scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f));
   1021 	const tcu::Vec4		uniformColor	= scaleColorValue(m_texFmt, tcu::Vec4(0.25f, 0.0f, 0.0f, 1.0f));
   1022 
   1023 	tcu::TextureLevel	reference		= genReferenceTexture(fbColor, uniformColor);
   1024 	tcu::TextureLevel	result			(getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
   1025 
   1026 	genFramebufferWithTexture(fbColor);
   1027 	genUniformColor(uniformColor);
   1028 	render();
   1029 
   1030 	glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
   1031 	verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
   1032 
   1033 	return STOP;
   1034 }
   1035 
   1036 // Test description:
   1037 // - Attach texture containing grid pattern to framebuffer.
   1038 // - Using framebuffer reads discard odd squares in the grid.
   1039 // - The even squares framebuffer color is added to the passed in uniform color.
   1040 
   1041 class FragmentDiscardTestCase : public FramebufferFetchTestCase
   1042 {
   1043 public:
   1044 						FragmentDiscardTestCase		(Context& context, const char* name, const char* desc, deUint32 format);
   1045 						~FragmentDiscardTestCase	(void) {}
   1046 
   1047 	IterateResult		iterate						(void);
   1048 
   1049 private:
   1050 	glu::ProgramSources genShaderSources			(void);
   1051 	void				genFramebufferWithGrid		(const tcu::Vec4& fbColorEven, const tcu::Vec4& fbColorOdd);
   1052 	tcu::TextureLevel	genReferenceTexture			(const tcu::Vec4& fbColorEven, const tcu::Vec4& fbColorOdd);
   1053 };
   1054 
   1055 FragmentDiscardTestCase::FragmentDiscardTestCase (Context& context, const char* name, const char* desc, deUint32 format)
   1056 	: FramebufferFetchTestCase(context, name, desc, format)
   1057 {
   1058 }
   1059 
   1060 glu::ProgramSources FragmentDiscardTestCase::genShaderSources (void)
   1061 {
   1062 	const string		vecType	= getColorOutputType(m_texFmt);
   1063 	std::ostringstream	fragShaderSource;
   1064 
   1065 	fragShaderSource	<< "#version 310 es\n"
   1066 						<< "#extension GL_EXT_shader_framebuffer_fetch : require\n"
   1067 						<< "layout(location = 0) inout highp " << vecType << " o_color;\n"
   1068 						<< "uniform highp " << vecType << " u_color;\n"
   1069 						<< "\n"
   1070 						<< "void main (void)\n"
   1071 						<< "{\n"
   1072 						<< "	const highp float threshold = 0.0005f;\n"
   1073 						<< "	bool valuesEqual = all(lessThan(abs(o_color - u_color), vec4(threshold)));\n\n"
   1074 						<< "	if (valuesEqual)\n"
   1075 						<< "		o_color += u_color;\n"
   1076 						<< "	else\n"
   1077 						<< "		discard;\n"
   1078 						<< "}\n";
   1079 
   1080 	return glu::makeVtxFragSources(genPassThroughVertSource(), fragShaderSource.str());
   1081 }
   1082 
   1083 void FragmentDiscardTestCase::genFramebufferWithGrid (const tcu::Vec4& fbColorEven, const tcu::Vec4& fbColorOdd)
   1084 {
   1085 	tcu::TextureLevel data	(glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
   1086 
   1087 	m_gl.genFramebuffers(1, &m_framebuffer);
   1088 	m_gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
   1089 
   1090 	m_gl.genTextures(1, &m_texColorBuffer);
   1091 	m_gl.bindTexture(GL_TEXTURE_2D, m_texColorBuffer);
   1092 
   1093 	tcu::fillWithGrid(data.getAccess(), 8, fbColorEven, fbColorOdd);
   1094 
   1095 	m_gl.texImage2D(GL_TEXTURE_2D, 0, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 0, m_transferFmt.format, m_transferFmt.dataType, data.getAccess().getDataPtr());
   1096 	m_gl.bindTexture(GL_TEXTURE_2D, 0);
   1097 
   1098 	m_gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texColorBuffer, 0);
   1099 	TCU_CHECK(m_gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
   1100 }
   1101 
   1102 tcu::TextureLevel FragmentDiscardTestCase::genReferenceTexture (const tcu::Vec4& fbColorEven, const tcu::Vec4& fbColorOdd)
   1103 {
   1104 	tcu::TextureLevel	reference	(glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
   1105 	tcu::fillWithGrid(reference.getAccess(), 8, fbColorEven + fbColorEven, fbColorOdd);
   1106 
   1107 	return reference;
   1108 }
   1109 
   1110 FragmentDiscardTestCase::IterateResult FragmentDiscardTestCase::iterate (void)
   1111 {
   1112 	const tcu::Vec4		fbColorEven		= scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 1.0f, 1.0f));
   1113 	const tcu::Vec4		fbColorOdd		= scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 1.0f, 1.0f, 1.0f));
   1114 
   1115 	tcu::TextureLevel	reference		= genReferenceTexture(fbColorEven, fbColorOdd);
   1116 	tcu::TextureLevel	result			(getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
   1117 	genFramebufferWithGrid(fbColorEven, fbColorOdd);
   1118 
   1119 	genUniformColor(fbColorEven);
   1120 	render();
   1121 
   1122 	glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
   1123 	verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
   1124 
   1125 	return STOP;
   1126 }
   1127 
   1128 // Test description:
   1129 // - Create 2D texture array containing three mipmaps.
   1130 // - Each mipmap level is assigned a different color.
   1131 // - Attach single mipmap level to framebuffer and draw full screen quad.
   1132 // - Sum framebuffer read color with passed in uniform color.
   1133 // - Compare resulting surface with reference.
   1134 // - Repeat for subsequent mipmap levels.
   1135 
   1136 class TextureLevelTestCase : public FramebufferFetchTestCase
   1137 {
   1138 public:
   1139 						TextureLevelTestCase			(Context& context, const char* name, const char* desc, deUint32 format);
   1140 						~TextureLevelTestCase			(void) {}
   1141 
   1142 	IterateResult		iterate							(void);
   1143 
   1144 private:
   1145 	void				create2DTextureArrayMipMaps		(const vector<tcu::Vec4>& colors);
   1146 	tcu::TextureLevel	genReferenceTexture				(int level, const vector<tcu::Vec4>& colors, const tcu::Vec4& uniformColor);
   1147 	void				genReferenceMipmap				(const tcu::Vec4& color, tcu::TextureLevel& reference);
   1148 };
   1149 
   1150 TextureLevelTestCase::TextureLevelTestCase (Context& context, const char* name, const char* desc, deUint32 format)
   1151 	: FramebufferFetchTestCase(context, name, desc, format)
   1152 {
   1153 }
   1154 
   1155 void TextureLevelTestCase::create2DTextureArrayMipMaps (const vector<tcu::Vec4>& colors)
   1156 {
   1157 	int						numLevels	= (int)colors.size();
   1158 	tcu::TextureLevel		levelData	(glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType));
   1159 
   1160 	m_gl.genTextures(1, &m_texColorBuffer);
   1161 	m_gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_texColorBuffer);
   1162 
   1163 	m_gl.texImage3D(GL_TEXTURE_2D_ARRAY, 0, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1, 0, m_transferFmt.format, m_transferFmt.dataType, DE_NULL);
   1164 	m_gl.generateMipmap(GL_TEXTURE_2D_ARRAY);
   1165 
   1166 	for (int level = 0; level < numLevels; level++)
   1167 	{
   1168 		int		levelW		= de::max(1, VIEWPORT_WIDTH		>> level);
   1169 		int		levelH		= de::max(1, VIEWPORT_HEIGHT	>> level);
   1170 
   1171 		levelData.setSize(levelW, levelH, 1);
   1172 
   1173 		clear(levelData.getAccess(), colors[level]);
   1174 		m_gl.texImage3D(GL_TEXTURE_2D_ARRAY, level, m_format, levelW, levelH, 1, 0, m_transferFmt.format, m_transferFmt.dataType, levelData.getAccess().getDataPtr());
   1175 	}
   1176 
   1177 	m_gl.bindTexture(GL_TEXTURE_2D_ARRAY, 0);
   1178 	GLU_EXPECT_NO_ERROR(m_gl.getError(), "create2DTextureArrayMipMaps()");
   1179 }
   1180 
   1181 tcu::TextureLevel TextureLevelTestCase::genReferenceTexture (int level, const vector<tcu::Vec4>& colors, const tcu::Vec4& uniformColor)
   1182 {
   1183 	tcu::TextureLevel	reference	(glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH >> level, VIEWPORT_HEIGHT >> level, 1);
   1184 
   1185 	genReferenceMipmap(colors[level] + uniformColor, reference);
   1186 
   1187 	return reference;
   1188 }
   1189 
   1190 void TextureLevelTestCase::genReferenceMipmap (const tcu::Vec4& color, tcu::TextureLevel& reference)
   1191 {
   1192 	const int	width	= reference.getAccess().getWidth();
   1193 	const int	height	= reference.getAccess().getHeight();
   1194 	const int	left	= width  / 2;
   1195 	const int	top		= height / 2;
   1196 
   1197 	clear(getSubregion(reference.getAccess(), left,		0,		0, width-left,	top,		1),	color);
   1198 	clear(getSubregion(reference.getAccess(), 0,		top,	0, left,		height-top,	1), color);
   1199 	clear(getSubregion(reference.getAccess(), left,		top,	0, width-left,	height-top, 1), color);
   1200 	clear(getSubregion(reference.getAccess(), 0,		0,		0, left,		top,		1),	color);
   1201 }
   1202 
   1203 TextureLevelTestCase::IterateResult TextureLevelTestCase::iterate (void)
   1204 {
   1205 	const tcu::Vec4		uniformColor	= scaleColorValue(m_texFmt, tcu::Vec4(0.1f, 0.0f, 0.0f, 1.0f));
   1206 	vector<tcu::Vec4>	levelColors;
   1207 
   1208 	levelColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.4f, 0.0f, 0.0f, 1.0f)));
   1209 	levelColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.2f, 0.0f, 0.0f, 1.0f)));
   1210 	levelColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)));
   1211 
   1212 	m_gl.genFramebuffers(1, &m_framebuffer);
   1213 	m_gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
   1214 
   1215 	create2DTextureArrayMipMaps(levelColors);
   1216 
   1217 	// attach successive mipmap layers to framebuffer and render
   1218 	for (int level = 0; level < (int)levelColors.size(); ++level)
   1219 	{
   1220 		std::ostringstream name, desc;
   1221 		name << "Level "		<< level;
   1222 		desc << "Mipmap level " << level;
   1223 
   1224 		const tcu::ScopedLogSection	section			(m_testCtx.getLog(), name.str(), desc.str());
   1225 		tcu::TextureLevel			result			(getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH >> level, VIEWPORT_HEIGHT >> level);
   1226 		tcu::TextureLevel			reference		= genReferenceTexture(level, levelColors, uniformColor);
   1227 
   1228 		m_gl.framebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_texColorBuffer, level, 0);
   1229 
   1230 		genUniformColor(uniformColor);
   1231 		render();
   1232 
   1233 		glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
   1234 		verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
   1235 
   1236 		if (m_testCtx.getTestResult() != QP_TEST_RESULT_PASS)
   1237 			return STOP;
   1238 	}
   1239 
   1240 	return STOP;
   1241 }
   1242 
   1243 class TextureLayerTestCase : public FramebufferFetchTestCase
   1244 {
   1245 public:
   1246 						TextureLayerTestCase		(Context& context, const char* name, const char* desc, deUint32 format);
   1247 						~TextureLayerTestCase		(void) {}
   1248 
   1249 	IterateResult		iterate						(void);
   1250 
   1251 private:
   1252 	void				create2DTextureArrayLayers	(const vector<tcu::Vec4>&  colors);
   1253 	tcu::TextureLevel	genReferenceTexture			(int layer, const vector<tcu::Vec4>& colors, const tcu::Vec4& uniformColor);
   1254 };
   1255 
   1256 TextureLayerTestCase::TextureLayerTestCase (Context& context, const char* name, const char* desc, deUint32 format)
   1257 	: FramebufferFetchTestCase(context, name, desc, format)
   1258 {
   1259 }
   1260 
   1261 void TextureLayerTestCase::create2DTextureArrayLayers (const vector<tcu::Vec4>& colors)
   1262 {
   1263 	int						numLayers	= (int)colors.size();
   1264 	tcu::TextureLevel		layerData	(glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType));
   1265 
   1266 	m_gl.genTextures(1, &m_texColorBuffer);
   1267 	m_gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_texColorBuffer);
   1268 	m_gl.texStorage3D(GL_TEXTURE_2D_ARRAY, 1, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, numLayers);
   1269 	m_gl.bindImageTexture(0, m_texColorBuffer, 0, GL_FALSE, 0, GL_READ_ONLY, m_format);
   1270 
   1271 	layerData.setSize(VIEWPORT_WIDTH, VIEWPORT_HEIGHT, numLayers);
   1272 
   1273 	for (int layer = 0; layer < numLayers; layer++)
   1274 	{
   1275 		clear(layerData.getAccess(), colors[layer]);
   1276 		m_gl.texSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, layer, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1, m_transferFmt.format, m_transferFmt.dataType, layerData.getAccess().getDataPtr());
   1277 	}
   1278 
   1279 	m_gl.bindTexture(GL_TEXTURE_2D_ARRAY, 0);
   1280 	GLU_EXPECT_NO_ERROR(m_gl.getError(), "create2DTextureArrayLayers()");
   1281 }
   1282 
   1283 tcu::TextureLevel TextureLayerTestCase::genReferenceTexture (int layer, const vector<tcu::Vec4>& colors, const tcu::Vec4& uniformColor)
   1284 {
   1285 	tcu::TextureLevel	reference	(glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
   1286 	clear(reference.getAccess(), colors[layer] + uniformColor);
   1287 
   1288 	return reference;
   1289 }
   1290 
   1291 // Test description
   1292 // - Create 2D texture array containing three layers.
   1293 // - Each layer is assigned a different color.
   1294 // - Attach single layer to framebuffer and draw full screen quad.
   1295 // - Sum framebuffer read color with passed in uniform color.
   1296 // - Compare resulting surface with reference.
   1297 // - Repeat for subsequent texture layers.
   1298 
   1299 TextureLayerTestCase::IterateResult TextureLayerTestCase::iterate (void)
   1300 {
   1301 	const tcu::Vec4		uniformColor	= scaleColorValue(m_texFmt, tcu::Vec4(0.1f, 0.1f, 0.1f, 1.0f));
   1302 	tcu::TextureLevel	result			(getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
   1303 	vector<tcu::Vec4>	layerColors;
   1304 
   1305 	layerColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.4f, 0.0f, 0.0f, 1.0f)));
   1306 	layerColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.2f, 0.0f, 0.0f, 1.0f)));
   1307 	layerColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)));
   1308 
   1309 	m_gl.genFramebuffers(1, &m_framebuffer);
   1310 	m_gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
   1311 
   1312 	create2DTextureArrayLayers(layerColors);
   1313 
   1314 	for (int layer = 0; layer < (int)layerColors.size(); ++layer)
   1315 	{
   1316 		std::ostringstream name, desc;
   1317 		name << "Layer " << layer;
   1318 		desc << "Layer " << layer;
   1319 
   1320 		const tcu::ScopedLogSection section		(m_testCtx.getLog(), name.str(), desc.str());
   1321 		tcu::TextureLevel			reference	= genReferenceTexture(layer, layerColors, uniformColor);
   1322 
   1323 		m_gl.framebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_texColorBuffer, 0, layer);
   1324 
   1325 		genUniformColor(uniformColor);
   1326 		render();
   1327 
   1328 		glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
   1329 		verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
   1330 
   1331 		if (m_testCtx.getTestResult() != QP_TEST_RESULT_PASS)
   1332 			return STOP;
   1333 	}
   1334 
   1335 	return STOP;
   1336 }
   1337 
   1338 } // Anonymous
   1339 
   1340 ShaderFramebufferFetchTests::ShaderFramebufferFetchTests (Context& context)
   1341 	: TestCaseGroup (context, "framebuffer_fetch", "GL_EXT_shader_framebuffer_fetch tests")
   1342 {
   1343 }
   1344 
   1345 ShaderFramebufferFetchTests::~ShaderFramebufferFetchTests (void)
   1346 {
   1347 }
   1348 
   1349 void ShaderFramebufferFetchTests::init (void)
   1350 {
   1351 	tcu::TestCaseGroup* const basicTestGroup				= new tcu::TestCaseGroup(m_testCtx, "basic",				"Basic framebuffer shader fetch tests");
   1352 	tcu::TestCaseGroup* const framebufferFormatTestGroup	= new tcu::TestCaseGroup(m_testCtx, "framebuffer_format",	"Texture render target formats tests");
   1353 
   1354 	// basic
   1355 	{
   1356 		basicTestGroup->addChild(new TexelFetchTestCase				(m_context,		"texel_fetch",					"Framebuffer fetches in conjunction with shader texel fetches",			GL_RGBA8));
   1357 		basicTestGroup->addChild(new LastFragDataTestCase			(m_context,		"last_frag_data",				"Framebuffer fetches with built-in fragment output of ES 2.0",			GL_RGBA8));
   1358 		basicTestGroup->addChild(new FragmentDiscardTestCase		(m_context,		"fragment_discard",				"Framebuffer fetches in combination with fragment discards",			GL_RGBA8));
   1359 		basicTestGroup->addChild(new MultipleAssignmentTestCase		(m_context,		"multiple_assignment",			"Multiple assignments to fragment color inout",							GL_RGBA8));
   1360 		basicTestGroup->addChild(new MultipleRenderTargetsTestCase	(m_context,		"multiple_render_targets",		"Framebuffer fetches used in combination with multiple render targets",	GL_RGBA8));
   1361 		basicTestGroup->addChild(new TextureLevelTestCase			(m_context,		"framebuffer_texture_level",	"Framebuffer fetches with individual texture render target mipmaps",	GL_RGBA8));
   1362 		basicTestGroup->addChild(new TextureLayerTestCase			(m_context,		"framebuffer_texture_layer",	"Framebuffer fetches with individual texture render target layers",		GL_RGBA8));
   1363 	}
   1364 
   1365 	// framebuffer formats
   1366 	{
   1367 		static const deUint32 colorFormats[] =
   1368 		{
   1369 			// RGBA formats
   1370 			GL_RGBA32I,
   1371 			GL_RGBA32UI,
   1372 			GL_RGBA16I,
   1373 			GL_RGBA16UI,
   1374 			GL_RGBA8,
   1375 			GL_RGBA8I,
   1376 			GL_RGBA8UI,
   1377 			GL_SRGB8_ALPHA8,
   1378 			GL_RGB10_A2,
   1379 			GL_RGB10_A2UI, GL_RGBA4, GL_RGB5_A1,
   1380 
   1381 			// RGB formats
   1382 			GL_RGB8,
   1383 			GL_RGB565,
   1384 
   1385 			// RG formats
   1386 			GL_RG32I,
   1387 			GL_RG32UI,
   1388 			GL_RG16I,
   1389 			GL_RG16UI,
   1390 			GL_RG8,
   1391 			GL_RG8I,
   1392 			GL_RG8UI,
   1393 
   1394 			// R formats
   1395 			GL_R32I,
   1396 			GL_R32UI,
   1397 			GL_R16I,
   1398 			GL_R16UI,
   1399 			GL_R8,
   1400 			GL_R8I,
   1401 			GL_R8UI,
   1402 
   1403 			// GL_EXT_color_buffer_float
   1404 			GL_RGBA32F,
   1405 			GL_RGBA16F,
   1406 			GL_R11F_G11F_B10F,
   1407 			GL_RG32F,
   1408 			GL_RG16F,
   1409 			GL_R32F,
   1410 			GL_R16F,
   1411 
   1412 			// GL_EXT_color_buffer_half_float
   1413 			GL_RGB16F
   1414 		};
   1415 
   1416 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(colorFormats); ndx++)
   1417 			framebufferFormatTestGroup->addChild(new TextureFormatTestCase(m_context, getFormatName(colorFormats[ndx]), "Framebuffer fetches from texture attachments with varying formats", colorFormats[ndx]));
   1418 	}
   1419 
   1420 	addChild(basicTestGroup);
   1421 	addChild(framebufferFormatTestGroup);
   1422 }
   1423 
   1424 } // Functional
   1425 } // gles31
   1426 } // deqp
   1427