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