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