• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
checkExtensionSupport(Context & context,const char * extName)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 
checkFramebufferFetchSupport(Context & context)68 static void checkFramebufferFetchSupport (Context& context)
69 {
70 	checkExtensionSupport(context, "GL_EXT_shader_framebuffer_fetch");
71 }
72 
isRequiredFormat(deUint32 format,glu::RenderContext & renderContext)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 
getReadPixelFormat(const tcu::TextureFormat & format)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 
getFixedPointFormatThreshold(const tcu::TextureFormat & sourceFormat,const tcu::TextureFormat & readPixelsFormat)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 
getFloatULPThreshold(const tcu::TextureFormat & sourceFormat,const tcu::TextureFormat & readPixelsFormat)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 
isAnyExtensionSupported(Context & context,const std::vector<std::string> & requiredExts)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 
getColorOutputType(tcu::TextureFormat format)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 
getEnablingExtensions(deUint32 format,glu::RenderContext & renderContext)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 
checkFormatSupport(Context & context,deUint32 sizedFormat)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 
scaleColorValue(tcu::TextureFormat format,const tcu::Vec4 & color)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 
FramebufferFetchTestCase(Context & context,const char * name,const char * desc,deUint32 format)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 
~FramebufferFetchTestCase(void)311 FramebufferFetchTestCase::~FramebufferFetchTestCase (void)
312 {
313 	FramebufferFetchTestCase::deinit();
314 }
315 
init(void)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 
deinit(void)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 
genPassThroughVertSource(void)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 
genShaderSources(void)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 
genFramebufferWithTexture(const tcu::Vec4 & color)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 
genAttachementTexture(const tcu::Vec4 & color)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 
verifyRenderbuffer(TestLog & log,const tcu::TextureFormat & format,const tcu::TextureLevel & reference,const tcu::TextureLevel & result)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 
genUniformColor(const tcu::Vec4 & color)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 
render(void)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);
~TextureFormatTestCase(void)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 
TextureFormatTestCase(Context & context,const char * name,const char * desc,deUint32 format)560 TextureFormatTestCase::TextureFormatTestCase (Context& context, const char* name, const char* desc, deUint32 format)
561 	: FramebufferFetchTestCase(context, name, desc, format)
562 {
563 }
564 
genReferenceTexture(const tcu::Vec4 & fbColor,const tcu::Vec4 & uniformColor)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 
iterate(void)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 
MultipleRenderTargetsTestCase(Context & context,const char * name,const char * desc,deUint32 format)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 
~MultipleRenderTargetsTestCase(void)652 MultipleRenderTargetsTestCase::~MultipleRenderTargetsTestCase (void)
653 {
654 	MultipleRenderTargetsTestCase::deinit();
655 }
656 
deinit(void)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 
genFramebufferWithTextures(const vector<tcu::Vec4> & colors)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 
genAttachmentTextures(const vector<tcu::Vec4> & colors)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 
genReferenceTexture(const tcu::Vec4 & fbColor,const tcu::Vec4 & uniformColor)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 
genShaderSources(void)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 
iterate(void)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);
~LastFragDataTestCase(void)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 
LastFragDataTestCase(Context & context,const char * name,const char * desc,deUint32 format)784 LastFragDataTestCase::LastFragDataTestCase (Context& context, const char* name, const char* desc, deUint32 format)
785 	: FramebufferFetchTestCase(context, name, desc, format)
786 {
787 }
788 
genShaderSources(void)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 
genReferenceTexture(const tcu::Vec4 & fbColor,const tcu::Vec4 & uniformColor)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 
iterate(void)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);
~TexelFetchTestCase(void)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 
TexelFetchTestCase(Context & context,const char * name,const char * desc,deUint32 format)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 
genSamplerTexture(const tcu::Vec4 & colorEven,const tcu::Vec4 & colorOdd)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 
genShaderSources(void)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 
genReferenceTexture(const tcu::Vec4 & colorEven,const tcu::Vec4 & colorOdd,const tcu::Vec4 & fbColor)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 
iterate(void)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);
~MultipleAssignmentTestCase(void)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 
MultipleAssignmentTestCase(Context & context,const char * name,const char * desc,deUint32 format)961 MultipleAssignmentTestCase::MultipleAssignmentTestCase (Context& context, const char* name, const char* desc, deUint32 format)
962 	: FramebufferFetchTestCase(context, name, desc, format)
963 {
964 }
965 
genShaderSources(void)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 
genReferenceTexture(const tcu::Vec4 & fbColor,const tcu::Vec4 & uniformColor)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 
iterate(void)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);
~FragmentDiscardTestCase(void)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 
FragmentDiscardTestCase(Context & context,const char * name,const char * desc,deUint32 format)1055 FragmentDiscardTestCase::FragmentDiscardTestCase (Context& context, const char* name, const char* desc, deUint32 format)
1056 	: FramebufferFetchTestCase(context, name, desc, format)
1057 {
1058 }
1059 
genShaderSources(void)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 
genFramebufferWithGrid(const tcu::Vec4 & fbColorEven,const tcu::Vec4 & fbColorOdd)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 
genReferenceTexture(const tcu::Vec4 & fbColorEven,const tcu::Vec4 & fbColorOdd)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 
iterate(void)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);
~TextureLevelTestCase(void)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 
TextureLevelTestCase(Context & context,const char * name,const char * desc,deUint32 format)1150 TextureLevelTestCase::TextureLevelTestCase (Context& context, const char* name, const char* desc, deUint32 format)
1151 	: FramebufferFetchTestCase(context, name, desc, format)
1152 {
1153 }
1154 
create2DTextureArrayMipMaps(const vector<tcu::Vec4> & colors)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 
genReferenceTexture(int level,const vector<tcu::Vec4> & colors,const tcu::Vec4 & uniformColor)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 
genReferenceMipmap(const tcu::Vec4 & color,tcu::TextureLevel & reference)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 
iterate(void)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);
~TextureLayerTestCase(void)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 
TextureLayerTestCase(Context & context,const char * name,const char * desc,deUint32 format)1256 TextureLayerTestCase::TextureLayerTestCase (Context& context, const char* name, const char* desc, deUint32 format)
1257 	: FramebufferFetchTestCase(context, name, desc, format)
1258 {
1259 }
1260 
create2DTextureArrayLayers(const vector<tcu::Vec4> & colors)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 
genReferenceTexture(int layer,const vector<tcu::Vec4> & colors,const tcu::Vec4 & uniformColor)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 
iterate(void)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 
ShaderFramebufferFetchTests(Context & context)1340 ShaderFramebufferFetchTests::ShaderFramebufferFetchTests (Context& context)
1341 	: TestCaseGroup (context, "framebuffer_fetch", "GL_EXT_shader_framebuffer_fetch tests")
1342 {
1343 }
1344 
~ShaderFramebufferFetchTests(void)1345 ShaderFramebufferFetchTests::~ShaderFramebufferFetchTests (void)
1346 {
1347 }
1348 
init(void)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