• 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::clear(reference.getAccess(), tcu::clamp(fbColor.asInt() + uniformColor.asInt(), formatMinValue.asInt(), formatMaxValue.asInt()));
617 	}
618 	else
619 	{
620 		if (tcu::isSRGB(m_texFmt))
621 		{
622 			const tcu::Vec4	fragmentColor = tcu::clamp(tcu::sRGBToLinear(fbColor) + uniformColor, formatMinValue, formatMaxValue);
623 			tcu::clear(reference.getAccess(), tcu::linearToSRGB(fragmentColor));
624 		}
625 		else
626 		{
627 			tcu::clear(reference.getAccess(), tcu::clamp(fbColor + uniformColor, formatMinValue, formatMaxValue));
628 		}
629 	}
630 
631 	return reference;
632 }
633 
iterate(void)634 TextureFormatTestCase::IterateResult TextureFormatTestCase::iterate (void)
635 {
636 	const tcu::Vec4		uniformColor	= scaleColorValue(m_texFmt, tcu::Vec4(0.1f, 0.1f, 0.1f, 1.0f));
637 	const tcu::Vec4		fbColor			= scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f));
638 
639 	tcu::TextureLevel	reference		= genReferenceTexture(fbColor, uniformColor);
640 	tcu::TextureLevel	result			(getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
641 
642 	genFramebufferWithTexture(fbColor);
643 	genUniformColor(uniformColor);
644 	render();
645 
646 	glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
647 	verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
648 
649 	return STOP;
650 }
651 
652 // Test description:
653 // - Attach multiple textures containing solid colors to framebuffer.
654 // - Draw full quad covering the entire viewport.
655 // - For each render target sum framebuffer read color with passed in uniform color.
656 // - Compare resulting surfaces with references.
657 
658 class MultipleRenderTargetsTestCase : public FramebufferFetchTestCase
659 {
660 public:
661 						MultipleRenderTargetsTestCase		(Context& context, const char* name, const char* desc, deUint32 format);
662 						~MultipleRenderTargetsTestCase		(void);
663 
664 	IterateResult		iterate								(void);
665 	void				deinit								(void);
666 
667 private:
668 	void				genFramebufferWithTextures			(const vector<tcu::Vec4>& colors);
669 	void				genAttachmentTextures				(const vector<tcu::Vec4>& colors);
670 	tcu::TextureLevel	genReferenceTexture					(const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor);
671 	glu::ProgramSources genShaderSources					(void);
672 
673 	enum
674 	{
675 		MAX_COLOR_BUFFERS = 4
676 	};
677 
678 	GLuint				m_texColorBuffers					[MAX_COLOR_BUFFERS];
679 	GLenum				m_colorBuffers						[MAX_COLOR_BUFFERS];
680 };
681 
MultipleRenderTargetsTestCase(Context & context,const char * name,const char * desc,deUint32 format)682 MultipleRenderTargetsTestCase::MultipleRenderTargetsTestCase (Context& context, const char* name, const char* desc, deUint32 format)
683 	: FramebufferFetchTestCase(context, name, desc, format)
684 	, m_texColorBuffers ()
685 {
686 	m_colorBuffers[0] = GL_COLOR_ATTACHMENT0;
687 	m_colorBuffers[1] = GL_COLOR_ATTACHMENT1;
688 	m_colorBuffers[2] = GL_COLOR_ATTACHMENT2;
689 	m_colorBuffers[3] = GL_COLOR_ATTACHMENT3;
690 }
691 
~MultipleRenderTargetsTestCase(void)692 MultipleRenderTargetsTestCase::~MultipleRenderTargetsTestCase (void)
693 {
694 	MultipleRenderTargetsTestCase::deinit();
695 }
696 
deinit(void)697 void MultipleRenderTargetsTestCase::deinit (void)
698 {
699 	// Clean up texture data
700 	for (int i = 0; i < DE_LENGTH_OF_ARRAY(m_texColorBuffers); ++i)
701 	{
702 		if (m_texColorBuffers[i])
703 			m_context.getRenderContext().getFunctions().deleteTextures(1, &m_texColorBuffers[i]);
704 	}
705 
706 	FramebufferFetchTestCase::deinit();
707 }
708 
genFramebufferWithTextures(const vector<tcu::Vec4> & colors)709 void MultipleRenderTargetsTestCase::genFramebufferWithTextures (const vector<tcu::Vec4>& colors)
710 {
711 	m_gl.genFramebuffers(1, &m_framebuffer);
712 	m_gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
713 
714 	genAttachmentTextures(colors);
715 
716 	for (int i = 0; i < DE_LENGTH_OF_ARRAY(m_texColorBuffers); ++i)
717 		m_gl.framebufferTexture2D(GL_FRAMEBUFFER, m_colorBuffers[i], GL_TEXTURE_2D, m_texColorBuffers[i], 0);
718 
719 	TCU_CHECK(m_gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
720 
721 	m_gl.drawBuffers((glw::GLsizei)MAX_COLOR_BUFFERS, &m_colorBuffers[0]);
722 	GLU_EXPECT_NO_ERROR(m_gl.getError(), "genFramebufferWithTextures()");
723 }
724 
genAttachmentTextures(const vector<tcu::Vec4> & colors)725 void MultipleRenderTargetsTestCase::genAttachmentTextures (const vector<tcu::Vec4>& colors)
726 {
727 	tcu::TextureLevel	data	(glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
728 
729 	m_gl.genTextures(MAX_COLOR_BUFFERS, m_texColorBuffers);
730 
731 	for (int i = 0; i < DE_LENGTH_OF_ARRAY(m_texColorBuffers); ++i)
732 	{
733 		m_gl.bindTexture(GL_TEXTURE_2D, m_texColorBuffers[i]);
734 
735 		m_gl.texParameteri(GL_TEXTURE_2D,	GL_TEXTURE_WRAP_S,		GL_CLAMP_TO_EDGE);
736 		m_gl.texParameteri(GL_TEXTURE_2D,	GL_TEXTURE_WRAP_T,		GL_CLAMP_TO_EDGE);
737 		m_gl.texParameteri(GL_TEXTURE_2D,	GL_TEXTURE_WRAP_R,		GL_CLAMP_TO_EDGE);
738 		m_gl.texParameteri(GL_TEXTURE_2D,	GL_TEXTURE_MIN_FILTER,	m_isFilterable ? GL_LINEAR : GL_NEAREST);
739 		m_gl.texParameteri(GL_TEXTURE_2D,	GL_TEXTURE_MAG_FILTER,	m_isFilterable ? GL_LINEAR : GL_NEAREST);
740 
741 		clear(data.getAccess(), colors[i]);
742 		m_gl.texImage2D(GL_TEXTURE_2D, 0, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 0, m_transferFmt.format, m_transferFmt.dataType, data.getAccess().getDataPtr());
743 	}
744 
745 	m_gl.bindTexture(GL_TEXTURE_2D, 0);
746 	GLU_EXPECT_NO_ERROR(m_gl.getError(), "genAttachmentTextures()");
747 }
748 
genReferenceTexture(const tcu::Vec4 & fbColor,const tcu::Vec4 & uniformColor)749 tcu::TextureLevel MultipleRenderTargetsTestCase::genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor)
750 {
751 	tcu::TextureLevel	reference	(glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
752 	tcu::clear(reference.getAccess(), fbColor + uniformColor);
753 
754 	return reference;
755 }
756 
genShaderSources(void)757 glu::ProgramSources MultipleRenderTargetsTestCase::genShaderSources (void)
758 {
759 	const string		vecType	= getColorOutputType(m_texFmt);
760 	std::ostringstream	fragShaderSource;
761 
762 	fragShaderSource	<< "#version 310 es\n"
763 						<< "#extension GL_EXT_shader_framebuffer_fetch : require\n"
764 						<< "layout(location = 0) inout highp " << vecType << " o_color0;\n"
765 						<< "layout(location = 1) inout highp " << vecType << " o_color1;\n"
766 						<< "layout(location = 2) inout highp " << vecType << " o_color2;\n"
767 						<< "layout(location = 3) inout highp " << vecType << " o_color3;\n"
768 						<< "uniform highp " << vecType << " u_color;\n"
769 						<< "\n"
770 						<< "void main (void)\n"
771 						<< "{\n"
772 						<< "	o_color0 += u_color;\n"
773 						<< "	o_color1 += u_color;\n"
774 						<< "	o_color2 += u_color;\n"
775 						<< "	o_color3 += u_color;\n"
776 						<< "}\n";
777 
778 	return glu::makeVtxFragSources(genPassThroughVertSource(), fragShaderSource.str());
779 }
780 
iterate(void)781 MultipleRenderTargetsTestCase::IterateResult MultipleRenderTargetsTestCase::iterate (void)
782 {
783 	const tcu::Vec4		uniformColor	= scaleColorValue(m_texFmt, tcu::Vec4(0.1f, 0.1f, 0.1f, 1.0f));
784 	tcu::TextureLevel	result			(getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
785 
786 	vector<tcu::Vec4> colors;
787 	colors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.9f, 0.0f, 0.0f, 1.0f)));
788 	colors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 0.9f, 0.0f, 1.0f)));
789 	colors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 0.0f, 0.9f, 1.0f)));
790 	colors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 0.9f, 0.9f, 1.0f)));
791 
792 	genFramebufferWithTextures(colors);
793 	genUniformColor(uniformColor);
794 	render();
795 
796 	for (int i = 0; i < DE_LENGTH_OF_ARRAY(m_colorBuffers); ++i)
797 	{
798 		tcu::TextureLevel	reference		= genReferenceTexture(colors[i], uniformColor);
799 
800 		m_gl.readBuffer(m_colorBuffers[i]);
801 		glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
802 		verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
803 	}
804 
805 	return STOP;
806 }
807 
808 // Test description:
809 // - Same as TextureFormatTestCase except uses built-in fragment output of ES 2.0
810 
811 class LastFragDataTestCase : public FramebufferFetchTestCase
812 {
813 public:
814 						LastFragDataTestCase			(Context& context, const char* name, const char* desc, deUint32 format);
~LastFragDataTestCase(void)815 						~LastFragDataTestCase			(void) {}
816 
817 	IterateResult		iterate							(void);
818 
819 private:
820 	glu::ProgramSources genShaderSources				(void);
821 	tcu::TextureLevel	genReferenceTexture				(const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor);
822 };
823 
LastFragDataTestCase(Context & context,const char * name,const char * desc,deUint32 format)824 LastFragDataTestCase::LastFragDataTestCase (Context& context, const char* name, const char* desc, deUint32 format)
825 	: FramebufferFetchTestCase(context, name, desc, format)
826 {
827 }
828 
genShaderSources(void)829 glu::ProgramSources LastFragDataTestCase::genShaderSources (void)
830 {
831 	const string		vecType	= getColorOutputType(m_texFmt);
832 	std::ostringstream	vertShaderSource;
833 	std::ostringstream	fragShaderSource;
834 
835 	vertShaderSource	<< "#version 100\n"
836 						<< "attribute vec4 a_position;\n"
837 						<< "\n"
838 						<< "void main (void)\n"
839 						<< "{\n"
840 						<< "	gl_Position = a_position;\n"
841 						<< "}\n";
842 
843 	fragShaderSource	<< "#version 100\n"
844 						<< "#extension GL_EXT_shader_framebuffer_fetch : require\n"
845 						<< "uniform highp " << vecType << " u_color;\n"
846 						<< "\n"
847 						<< "void main (void)\n"
848 						<< "{\n"
849 						<< "	gl_FragColor = u_color + gl_LastFragData[0];\n"
850 						<< "}\n";
851 
852 	return glu::makeVtxFragSources(vertShaderSource.str(), fragShaderSource.str());
853 }
854 
genReferenceTexture(const tcu::Vec4 & fbColor,const tcu::Vec4 & uniformColor)855 tcu::TextureLevel LastFragDataTestCase::genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor)
856 {
857 	tcu::TextureLevel	reference	(glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
858 	tcu::clear(reference.getAccess(), fbColor + uniformColor);
859 
860 	return reference;
861 }
862 
iterate(void)863 LastFragDataTestCase::IterateResult LastFragDataTestCase::iterate (void)
864 {
865 	const tcu::Vec4		uniformColor	= scaleColorValue(m_texFmt, tcu::Vec4(0.1f, 0.1f, 0.1f, 1.0f));
866 	const tcu::Vec4		fbColor			= scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f));
867 
868 	tcu::TextureLevel	reference		= genReferenceTexture(fbColor, uniformColor);
869 	tcu::TextureLevel	result			(getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
870 
871 	genFramebufferWithTexture(fbColor);
872 	genUniformColor(uniformColor);
873 	render();
874 
875 	glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
876 	verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
877 
878 	return STOP;
879 }
880 
881 // Test description:
882 // - Attach texture containing solid color to framebuffer.
883 // - Create one 2D texture for sampler with a grid pattern
884 // - Draw full screen quad covering the entire viewport.
885 // - Sum color values taken from framebuffer texture and sampled texture
886 // - Compare resulting surface with reference.
887 
888 class TexelFetchTestCase : public FramebufferFetchTestCase
889 {
890 public:
891 						TexelFetchTestCase		(Context& context, const char* name, const char* desc, deUint32 format);
~TexelFetchTestCase(void)892 						~TexelFetchTestCase		(void) {}
893 
894 	IterateResult		iterate					(void);
895 
896 private:
897 	glu::ProgramSources genShaderSources		(void);
898 	tcu::TextureLevel	genReferenceTexture		(const tcu::Vec4& colorEven, const tcu::Vec4& colorOdd, const tcu::Vec4& fbColor);
899 	void				genSamplerTexture		(const tcu::Vec4& colorEven, const tcu::Vec4& colorOdd);
900 
901 	GLuint				m_samplerTexture;
902 };
903 
TexelFetchTestCase(Context & context,const char * name,const char * desc,deUint32 format)904 TexelFetchTestCase::TexelFetchTestCase (Context& context, const char* name, const char* desc, deUint32 format)
905 	: FramebufferFetchTestCase(context, name, desc, format)
906 	, m_samplerTexture(0)
907 {
908 }
909 
genSamplerTexture(const tcu::Vec4 & colorEven,const tcu::Vec4 & colorOdd)910 void TexelFetchTestCase::genSamplerTexture (const tcu::Vec4& colorEven, const tcu::Vec4& colorOdd)
911 {
912 	tcu::TextureLevel	data	(glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
913 
914 	m_gl.activeTexture(GL_TEXTURE1);
915 
916 	m_gl.genTextures(1, &m_samplerTexture);
917 	m_gl.bindTexture(GL_TEXTURE_2D, m_texColorBuffer);
918 	m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
919 	m_gl.texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
920 
921 	tcu::fillWithGrid(data.getAccess(), 8, colorEven, colorOdd);
922 
923 	m_gl.texImage2D(GL_TEXTURE_2D, 0, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 0, m_transferFmt.format, m_transferFmt.dataType, data.getAccess().getDataPtr());
924 	m_gl.bindTexture(GL_TEXTURE_2D, 0);
925 
926 	const GLuint samplerLocation = m_gl.getUniformLocation(m_program->getProgram(), "u_sampler");
927 	m_gl.uniform1i(samplerLocation, 1);
928 
929 	GLU_EXPECT_NO_ERROR(m_gl.getError(), "genSamplerTexture()");
930 }
931 
genShaderSources(void)932 glu::ProgramSources TexelFetchTestCase::genShaderSources (void)
933 {
934 	const string		vecType	= getColorOutputType(m_texFmt);
935 	std::ostringstream	fragShaderSource;
936 
937 	fragShaderSource	<< "#version 310 es\n"
938 						<< "#extension GL_EXT_shader_framebuffer_fetch : require\n"
939 						<< "layout(location = 0) inout highp " << vecType << " o_color;\n"
940 						<< "\n"
941 						<< "uniform sampler2D u_sampler;\n"
942 						<< "void main (void)\n"
943 						<< "{\n"
944 						<< "	o_color += texelFetch(u_sampler, ivec2(gl_FragCoord), 0);\n"
945 						<< "}\n";
946 
947 	return glu::makeVtxFragSources(genPassThroughVertSource(), fragShaderSource.str());
948 }
949 
genReferenceTexture(const tcu::Vec4 & colorEven,const tcu::Vec4 & colorOdd,const tcu::Vec4 & fbColor)950 tcu::TextureLevel TexelFetchTestCase::genReferenceTexture (const tcu::Vec4& colorEven, const tcu::Vec4& colorOdd, const tcu::Vec4& fbColor)
951 {
952 	tcu::TextureLevel	reference	(glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
953 	tcu::fillWithGrid(reference.getAccess(), 8, colorEven + fbColor, colorOdd + fbColor);
954 
955 	return reference;
956 }
957 
iterate(void)958 TexelFetchTestCase::IterateResult TexelFetchTestCase::iterate (void)
959 {
960 	const tcu::Vec4		fbColor			= scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 0.5f, 1.0f));
961 	const tcu::Vec4		colorEven		= scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.5f, 0.0f, 1.0f));
962 	const tcu::Vec4		colorOdd		= scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 0.5f, 1.0f));
963 
964 	genSamplerTexture(colorEven, colorOdd);
965 	tcu::TextureLevel	reference		= genReferenceTexture(colorEven, colorOdd, fbColor);
966 	tcu::TextureLevel	result			(getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
967 
968 	genFramebufferWithTexture(fbColor);
969 	render();
970 
971 	glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
972 	verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
973 
974 	// cleanup
975 	m_gl.deleteTextures(1, &m_samplerTexture);
976 
977 	return STOP;
978 }
979 
980 // Test description:
981 // - Attach texture containing solid color to framebuffer.
982 // - Draw full screen quad covering the entire viewport.
983 // - Multiple assignments are made to the output color for fragments on the right vertical half of the screen.
984 // - A single assignment is made to the output color for fragments on the left vertical centre of the screen.
985 // - Values are calculated using the sum of the passed in uniform color and the previous framebuffer color.
986 // - Compare resulting surface with reference.
987 
988 class MultipleAssignmentTestCase : public FramebufferFetchTestCase
989 {
990 public:
991 						MultipleAssignmentTestCase		(Context& context, const char* name, const char* desc, deUint32 format);
~MultipleAssignmentTestCase(void)992 						~MultipleAssignmentTestCase		(void) {}
993 
994 	IterateResult		iterate							(void);
995 
996 private:
997 	glu::ProgramSources genShaderSources				(void);
998 	tcu::TextureLevel	genReferenceTexture				(const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor);
999 };
1000 
MultipleAssignmentTestCase(Context & context,const char * name,const char * desc,deUint32 format)1001 MultipleAssignmentTestCase::MultipleAssignmentTestCase (Context& context, const char* name, const char* desc, deUint32 format)
1002 	: FramebufferFetchTestCase(context, name, desc, format)
1003 {
1004 }
1005 
genShaderSources(void)1006 glu::ProgramSources MultipleAssignmentTestCase::genShaderSources (void)
1007 {
1008 	const string		vecType = getColorOutputType(m_texFmt);
1009 	std::ostringstream	vertShaderSource;
1010 	std::ostringstream	fragShaderSource;
1011 
1012 	vertShaderSource	<< "#version 310 es\n"
1013 						<< "in highp vec4 a_position;\n"
1014 						<< "out highp vec4 v_position;\n"
1015 						<< "\n"
1016 						<< "void main (void)\n"
1017 						<< "{\n"
1018 						<< "	gl_Position = a_position;\n"
1019 						<< "	v_position  = gl_Position;\n"
1020 						<< "}\n";
1021 
1022 	fragShaderSource	<< "#version 310 es\n"
1023 						<< "#extension GL_EXT_shader_framebuffer_fetch : require\n"
1024 						<< "in highp vec4 v_position;\n"
1025 						<< "layout(location = 0) inout highp " << vecType << " o_color;\n"
1026 						<< "uniform highp " << vecType << " u_color;\n"
1027 						<< "\n"
1028 						<< "void main (void)\n"
1029 						<< "{\n"
1030 						<< "	if (v_position.x > 0.0f)\n"
1031 						<< "		o_color += u_color;\n"
1032 						<< "\n"
1033 						<< "	o_color += u_color;\n"
1034 						<< "}\n";
1035 
1036 	return glu::makeVtxFragSources(vertShaderSource.str(), fragShaderSource.str());
1037 }
1038 
genReferenceTexture(const tcu::Vec4 & fbColor,const tcu::Vec4 & uniformColor)1039 tcu::TextureLevel MultipleAssignmentTestCase::genReferenceTexture (const tcu::Vec4& fbColor, const tcu::Vec4& uniformColor)
1040 {
1041 	tcu::TextureLevel	reference	(glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
1042 
1043 	int	width	= reference.getAccess().getWidth();
1044 	int	height	= reference.getAccess().getHeight();
1045 	int	left	= width /2;
1046 	int	top		= height/2;
1047 
1048 	tcu::Vec4 compositeColor(uniformColor * 2.0f);
1049 
1050 	tcu::clear(getSubregion(reference.getAccess(), left,		0,		0, width-left,	top,		1),	fbColor + compositeColor);
1051 	tcu::clear(getSubregion(reference.getAccess(), 0,			top,	0, left,		height-top,	1), fbColor + uniformColor);
1052 	tcu::clear(getSubregion(reference.getAccess(), left,		top,	0, width-left,	height-top, 1), fbColor + compositeColor);
1053 	tcu::clear(getSubregion(reference.getAccess(), 0,			0,		0, left,		top,		1),	fbColor + uniformColor);
1054 
1055 	return reference;
1056 }
1057 
iterate(void)1058 MultipleAssignmentTestCase::IterateResult MultipleAssignmentTestCase::iterate (void)
1059 {
1060 	const tcu::Vec4		fbColor			= scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 0.0f, 1.0f));
1061 	const tcu::Vec4		uniformColor	= scaleColorValue(m_texFmt, tcu::Vec4(0.25f, 0.0f, 0.0f, 1.0f));
1062 
1063 	tcu::TextureLevel	reference		= genReferenceTexture(fbColor, uniformColor);
1064 	tcu::TextureLevel	result			(getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
1065 
1066 	genFramebufferWithTexture(fbColor);
1067 	genUniformColor(uniformColor);
1068 	render();
1069 
1070 	glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
1071 	verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
1072 
1073 	return STOP;
1074 }
1075 
1076 // Test description:
1077 // - Attach texture containing grid pattern to framebuffer.
1078 // - Using framebuffer reads discard odd squares in the grid.
1079 // - The even squares framebuffer color is added to the passed in uniform color.
1080 
1081 class FragmentDiscardTestCase : public FramebufferFetchTestCase
1082 {
1083 public:
1084 						FragmentDiscardTestCase		(Context& context, const char* name, const char* desc, deUint32 format);
~FragmentDiscardTestCase(void)1085 						~FragmentDiscardTestCase	(void) {}
1086 
1087 	IterateResult		iterate						(void);
1088 
1089 private:
1090 	glu::ProgramSources genShaderSources			(void);
1091 	void				genFramebufferWithGrid		(const tcu::Vec4& fbColorEven, const tcu::Vec4& fbColorOdd);
1092 	tcu::TextureLevel	genReferenceTexture			(const tcu::Vec4& fbColorEven, const tcu::Vec4& fbColorOdd);
1093 };
1094 
FragmentDiscardTestCase(Context & context,const char * name,const char * desc,deUint32 format)1095 FragmentDiscardTestCase::FragmentDiscardTestCase (Context& context, const char* name, const char* desc, deUint32 format)
1096 	: FramebufferFetchTestCase(context, name, desc, format)
1097 {
1098 }
1099 
genShaderSources(void)1100 glu::ProgramSources FragmentDiscardTestCase::genShaderSources (void)
1101 {
1102 	const string		vecType	= getColorOutputType(m_texFmt);
1103 	std::ostringstream	fragShaderSource;
1104 
1105 	fragShaderSource	<< "#version 310 es\n"
1106 						<< "#extension GL_EXT_shader_framebuffer_fetch : require\n"
1107 						<< "layout(location = 0) inout highp " << vecType << " o_color;\n"
1108 						<< "uniform highp " << vecType << " u_color;\n"
1109 						<< "\n"
1110 						<< "void main (void)\n"
1111 						<< "{\n"
1112 						<< "	const highp float threshold = 0.0005f;\n"
1113 						<< "	bool valuesEqual = all(lessThan(abs(o_color - u_color), vec4(threshold)));\n\n"
1114 						<< "	if (valuesEqual)\n"
1115 						<< "		o_color += u_color;\n"
1116 						<< "	else\n"
1117 						<< "		discard;\n"
1118 						<< "}\n";
1119 
1120 	return glu::makeVtxFragSources(genPassThroughVertSource(), fragShaderSource.str());
1121 }
1122 
genFramebufferWithGrid(const tcu::Vec4 & fbColorEven,const tcu::Vec4 & fbColorOdd)1123 void FragmentDiscardTestCase::genFramebufferWithGrid (const tcu::Vec4& fbColorEven, const tcu::Vec4& fbColorOdd)
1124 {
1125 	tcu::TextureLevel data	(glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
1126 
1127 	m_gl.genFramebuffers(1, &m_framebuffer);
1128 	m_gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
1129 
1130 	m_gl.genTextures(1, &m_texColorBuffer);
1131 	m_gl.bindTexture(GL_TEXTURE_2D, m_texColorBuffer);
1132 
1133 	tcu::fillWithGrid(data.getAccess(), 8, fbColorEven, fbColorOdd);
1134 
1135 	m_gl.texImage2D(GL_TEXTURE_2D, 0, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 0, m_transferFmt.format, m_transferFmt.dataType, data.getAccess().getDataPtr());
1136 	m_gl.bindTexture(GL_TEXTURE_2D, 0);
1137 
1138 	m_gl.framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texColorBuffer, 0);
1139 	TCU_CHECK(m_gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
1140 }
1141 
genReferenceTexture(const tcu::Vec4 & fbColorEven,const tcu::Vec4 & fbColorOdd)1142 tcu::TextureLevel FragmentDiscardTestCase::genReferenceTexture (const tcu::Vec4& fbColorEven, const tcu::Vec4& fbColorOdd)
1143 {
1144 	tcu::TextureLevel	reference	(glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
1145 	tcu::fillWithGrid(reference.getAccess(), 8, fbColorEven + fbColorEven, fbColorOdd);
1146 
1147 	return reference;
1148 }
1149 
iterate(void)1150 FragmentDiscardTestCase::IterateResult FragmentDiscardTestCase::iterate (void)
1151 {
1152 	const tcu::Vec4		fbColorEven		= scaleColorValue(m_texFmt, tcu::Vec4(0.5f, 0.0f, 1.0f, 1.0f));
1153 	const tcu::Vec4		fbColorOdd		= scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 1.0f, 1.0f, 1.0f));
1154 
1155 	tcu::TextureLevel	reference		= genReferenceTexture(fbColorEven, fbColorOdd);
1156 	tcu::TextureLevel	result			(getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
1157 	genFramebufferWithGrid(fbColorEven, fbColorOdd);
1158 
1159 	genUniformColor(fbColorEven);
1160 	render();
1161 
1162 	glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
1163 	verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
1164 
1165 	return STOP;
1166 }
1167 
1168 // Test description:
1169 // - Create 2D texture array containing three mipmaps.
1170 // - Each mipmap level is assigned a different color.
1171 // - Attach single mipmap level to framebuffer and draw full screen quad.
1172 // - Sum framebuffer read color with passed in uniform color.
1173 // - Compare resulting surface with reference.
1174 // - Repeat for subsequent mipmap levels.
1175 
1176 class TextureLevelTestCase : public FramebufferFetchTestCase
1177 {
1178 public:
1179 						TextureLevelTestCase			(Context& context, const char* name, const char* desc, deUint32 format);
~TextureLevelTestCase(void)1180 						~TextureLevelTestCase			(void) {}
1181 
1182 	IterateResult		iterate							(void);
1183 
1184 private:
1185 	void				create2DTextureArrayMipMaps		(const vector<tcu::Vec4>& colors);
1186 	tcu::TextureLevel	genReferenceTexture				(int level, const vector<tcu::Vec4>& colors, const tcu::Vec4& uniformColor);
1187 	void				genReferenceMipmap				(const tcu::Vec4& color, tcu::TextureLevel& reference);
1188 };
1189 
TextureLevelTestCase(Context & context,const char * name,const char * desc,deUint32 format)1190 TextureLevelTestCase::TextureLevelTestCase (Context& context, const char* name, const char* desc, deUint32 format)
1191 	: FramebufferFetchTestCase(context, name, desc, format)
1192 {
1193 }
1194 
create2DTextureArrayMipMaps(const vector<tcu::Vec4> & colors)1195 void TextureLevelTestCase::create2DTextureArrayMipMaps (const vector<tcu::Vec4>& colors)
1196 {
1197 	int						numLevels	= (int)colors.size();
1198 	tcu::TextureLevel		levelData	(glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType));
1199 
1200 	m_gl.genTextures(1, &m_texColorBuffer);
1201 	m_gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_texColorBuffer);
1202 
1203 	m_gl.texImage3D(GL_TEXTURE_2D_ARRAY, 0, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1, 0, m_transferFmt.format, m_transferFmt.dataType, DE_NULL);
1204 	m_gl.generateMipmap(GL_TEXTURE_2D_ARRAY);
1205 
1206 	for (int level = 0; level < numLevels; level++)
1207 	{
1208 		int		levelW		= de::max(1, VIEWPORT_WIDTH		>> level);
1209 		int		levelH		= de::max(1, VIEWPORT_HEIGHT	>> level);
1210 
1211 		levelData.setSize(levelW, levelH, 1);
1212 
1213 		clear(levelData.getAccess(), colors[level]);
1214 		m_gl.texImage3D(GL_TEXTURE_2D_ARRAY, level, m_format, levelW, levelH, 1, 0, m_transferFmt.format, m_transferFmt.dataType, levelData.getAccess().getDataPtr());
1215 	}
1216 
1217 	m_gl.bindTexture(GL_TEXTURE_2D_ARRAY, 0);
1218 	GLU_EXPECT_NO_ERROR(m_gl.getError(), "create2DTextureArrayMipMaps()");
1219 }
1220 
genReferenceTexture(int level,const vector<tcu::Vec4> & colors,const tcu::Vec4 & uniformColor)1221 tcu::TextureLevel TextureLevelTestCase::genReferenceTexture (int level, const vector<tcu::Vec4>& colors, const tcu::Vec4& uniformColor)
1222 {
1223 	tcu::TextureLevel	reference	(glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH >> level, VIEWPORT_HEIGHT >> level, 1);
1224 
1225 	genReferenceMipmap(colors[level] + uniformColor, reference);
1226 
1227 	return reference;
1228 }
1229 
genReferenceMipmap(const tcu::Vec4 & color,tcu::TextureLevel & reference)1230 void TextureLevelTestCase::genReferenceMipmap (const tcu::Vec4& color, tcu::TextureLevel& reference)
1231 {
1232 	const int	width	= reference.getAccess().getWidth();
1233 	const int	height	= reference.getAccess().getHeight();
1234 	const int	left	= width  / 2;
1235 	const int	top		= height / 2;
1236 
1237 	clear(getSubregion(reference.getAccess(), left,		0,		0, width-left,	top,		1),	color);
1238 	clear(getSubregion(reference.getAccess(), 0,		top,	0, left,		height-top,	1), color);
1239 	clear(getSubregion(reference.getAccess(), left,		top,	0, width-left,	height-top, 1), color);
1240 	clear(getSubregion(reference.getAccess(), 0,		0,		0, left,		top,		1),	color);
1241 }
1242 
iterate(void)1243 TextureLevelTestCase::IterateResult TextureLevelTestCase::iterate (void)
1244 {
1245 	const tcu::Vec4		uniformColor	= scaleColorValue(m_texFmt, tcu::Vec4(0.1f, 0.0f, 0.0f, 1.0f));
1246 	vector<tcu::Vec4>	levelColors;
1247 
1248 	levelColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.4f, 0.0f, 0.0f, 1.0f)));
1249 	levelColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.2f, 0.0f, 0.0f, 1.0f)));
1250 	levelColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)));
1251 
1252 	m_gl.genFramebuffers(1, &m_framebuffer);
1253 	m_gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
1254 
1255 	create2DTextureArrayMipMaps(levelColors);
1256 
1257 	// attach successive mipmap layers to framebuffer and render
1258 	for (int level = 0; level < (int)levelColors.size(); ++level)
1259 	{
1260 		std::ostringstream name, desc;
1261 		name << "Level "		<< level;
1262 		desc << "Mipmap level " << level;
1263 
1264 		const tcu::ScopedLogSection	section			(m_testCtx.getLog(), name.str(), desc.str());
1265 		tcu::TextureLevel			result			(getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH >> level, VIEWPORT_HEIGHT >> level);
1266 		tcu::TextureLevel			reference		= genReferenceTexture(level, levelColors, uniformColor);
1267 
1268 		m_gl.framebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_texColorBuffer, level, 0);
1269 
1270 		genUniformColor(uniformColor);
1271 		render();
1272 
1273 		glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
1274 		verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
1275 
1276 		if (m_testCtx.getTestResult() != QP_TEST_RESULT_PASS)
1277 			return STOP;
1278 	}
1279 
1280 	return STOP;
1281 }
1282 
1283 class TextureLayerTestCase : public FramebufferFetchTestCase
1284 {
1285 public:
1286 						TextureLayerTestCase		(Context& context, const char* name, const char* desc, deUint32 format);
~TextureLayerTestCase(void)1287 						~TextureLayerTestCase		(void) {}
1288 
1289 	IterateResult		iterate						(void);
1290 
1291 private:
1292 	void				create2DTextureArrayLayers	(const vector<tcu::Vec4>&  colors);
1293 	tcu::TextureLevel	genReferenceTexture			(int layer, const vector<tcu::Vec4>& colors, const tcu::Vec4& uniformColor);
1294 };
1295 
TextureLayerTestCase(Context & context,const char * name,const char * desc,deUint32 format)1296 TextureLayerTestCase::TextureLayerTestCase (Context& context, const char* name, const char* desc, deUint32 format)
1297 	: FramebufferFetchTestCase(context, name, desc, format)
1298 {
1299 }
1300 
create2DTextureArrayLayers(const vector<tcu::Vec4> & colors)1301 void TextureLayerTestCase::create2DTextureArrayLayers (const vector<tcu::Vec4>& colors)
1302 {
1303 	int						numLayers	= (int)colors.size();
1304 	tcu::TextureLevel		layerData	(glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType));
1305 
1306 	m_gl.genTextures(1, &m_texColorBuffer);
1307 	m_gl.bindTexture(GL_TEXTURE_2D_ARRAY, m_texColorBuffer);
1308 	m_gl.texStorage3D(GL_TEXTURE_2D_ARRAY, 1, m_format, VIEWPORT_WIDTH, VIEWPORT_HEIGHT, numLayers);
1309 	m_gl.bindImageTexture(0, m_texColorBuffer, 0, GL_FALSE, 0, GL_READ_ONLY, m_format);
1310 
1311 	layerData.setSize(VIEWPORT_WIDTH, VIEWPORT_HEIGHT, numLayers);
1312 
1313 	for (int layer = 0; layer < numLayers; layer++)
1314 	{
1315 		clear(layerData.getAccess(), colors[layer]);
1316 		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());
1317 	}
1318 
1319 	m_gl.bindTexture(GL_TEXTURE_2D_ARRAY, 0);
1320 	GLU_EXPECT_NO_ERROR(m_gl.getError(), "create2DTextureArrayLayers()");
1321 }
1322 
genReferenceTexture(int layer,const vector<tcu::Vec4> & colors,const tcu::Vec4 & uniformColor)1323 tcu::TextureLevel TextureLayerTestCase::genReferenceTexture (int layer, const vector<tcu::Vec4>& colors, const tcu::Vec4& uniformColor)
1324 {
1325 	tcu::TextureLevel	reference	(glu::mapGLTransferFormat(m_transferFmt.format, m_transferFmt.dataType), VIEWPORT_WIDTH, VIEWPORT_HEIGHT, 1);
1326 	clear(reference.getAccess(), colors[layer] + uniformColor);
1327 
1328 	return reference;
1329 }
1330 
1331 // Test description
1332 // - Create 2D texture array containing three layers.
1333 // - Each layer is assigned a different color.
1334 // - Attach single layer to framebuffer and draw full screen quad.
1335 // - Sum framebuffer read color with passed in uniform color.
1336 // - Compare resulting surface with reference.
1337 // - Repeat for subsequent texture layers.
1338 
iterate(void)1339 TextureLayerTestCase::IterateResult TextureLayerTestCase::iterate (void)
1340 {
1341 	const tcu::Vec4		uniformColor	= scaleColorValue(m_texFmt, tcu::Vec4(0.1f, 0.1f, 0.1f, 1.0f));
1342 	tcu::TextureLevel	result			(getReadPixelFormat(m_texFmt), VIEWPORT_WIDTH, VIEWPORT_HEIGHT);
1343 	vector<tcu::Vec4>	layerColors;
1344 
1345 	layerColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.4f, 0.0f, 0.0f, 1.0f)));
1346 	layerColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.2f, 0.0f, 0.0f, 1.0f)));
1347 	layerColors.push_back(scaleColorValue(m_texFmt, tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)));
1348 
1349 	m_gl.genFramebuffers(1, &m_framebuffer);
1350 	m_gl.bindFramebuffer(GL_FRAMEBUFFER, m_framebuffer);
1351 
1352 	create2DTextureArrayLayers(layerColors);
1353 
1354 	for (int layer = 0; layer < (int)layerColors.size(); ++layer)
1355 	{
1356 		std::ostringstream name, desc;
1357 		name << "Layer " << layer;
1358 		desc << "Layer " << layer;
1359 
1360 		const tcu::ScopedLogSection section		(m_testCtx.getLog(), name.str(), desc.str());
1361 		tcu::TextureLevel			reference	= genReferenceTexture(layer, layerColors, uniformColor);
1362 
1363 		m_gl.framebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_texColorBuffer, 0, layer);
1364 
1365 		genUniformColor(uniformColor);
1366 		render();
1367 
1368 		glu::readPixels(m_context.getRenderContext(), 0, 0, result.getAccess());
1369 		verifyRenderbuffer(m_testCtx.getLog(), m_texFmt, reference, result);
1370 
1371 		if (m_testCtx.getTestResult() != QP_TEST_RESULT_PASS)
1372 			return STOP;
1373 	}
1374 
1375 	return STOP;
1376 }
1377 
1378 } // Anonymous
1379 
ShaderFramebufferFetchTests(Context & context)1380 ShaderFramebufferFetchTests::ShaderFramebufferFetchTests (Context& context)
1381 	: TestCaseGroup (context, "framebuffer_fetch", "GL_EXT_shader_framebuffer_fetch tests")
1382 {
1383 }
1384 
~ShaderFramebufferFetchTests(void)1385 ShaderFramebufferFetchTests::~ShaderFramebufferFetchTests (void)
1386 {
1387 }
1388 
init(void)1389 void ShaderFramebufferFetchTests::init (void)
1390 {
1391 	tcu::TestCaseGroup* const basicTestGroup				= new tcu::TestCaseGroup(m_testCtx, "basic",				"Basic framebuffer shader fetch tests");
1392 	tcu::TestCaseGroup* const framebufferFormatTestGroup	= new tcu::TestCaseGroup(m_testCtx, "framebuffer_format",	"Texture render target formats tests");
1393 
1394 	// basic
1395 	{
1396 		basicTestGroup->addChild(new TexelFetchTestCase				(m_context,		"texel_fetch",					"Framebuffer fetches in conjunction with shader texel fetches",			GL_RGBA8));
1397 		basicTestGroup->addChild(new LastFragDataTestCase			(m_context,		"last_frag_data",				"Framebuffer fetches with built-in fragment output of ES 2.0",			GL_RGBA8));
1398 		basicTestGroup->addChild(new FragmentDiscardTestCase		(m_context,		"fragment_discard",				"Framebuffer fetches in combination with fragment discards",			GL_RGBA8));
1399 		basicTestGroup->addChild(new MultipleAssignmentTestCase		(m_context,		"multiple_assignment",			"Multiple assignments to fragment color inout",							GL_RGBA8));
1400 		basicTestGroup->addChild(new MultipleRenderTargetsTestCase	(m_context,		"multiple_render_targets",		"Framebuffer fetches used in combination with multiple render targets",	GL_RGBA8));
1401 		basicTestGroup->addChild(new TextureLevelTestCase			(m_context,		"framebuffer_texture_level",	"Framebuffer fetches with individual texture render target mipmaps",	GL_RGBA8));
1402 		basicTestGroup->addChild(new TextureLayerTestCase			(m_context,		"framebuffer_texture_layer",	"Framebuffer fetches with individual texture render target layers",		GL_RGBA8));
1403 	}
1404 
1405 	// framebuffer formats
1406 	{
1407 		static const deUint32 colorFormats[] =
1408 		{
1409 			// RGBA formats
1410 			GL_RGBA32I,
1411 			GL_RGBA32UI,
1412 			GL_RGBA16I,
1413 			GL_RGBA16UI,
1414 			GL_RGBA8,
1415 			GL_RGBA8I,
1416 			GL_RGBA8UI,
1417 			GL_SRGB8_ALPHA8,
1418 			GL_RGB10_A2,
1419 			GL_RGB10_A2UI, GL_RGBA4, GL_RGB5_A1,
1420 
1421 			// RGB formats
1422 			GL_RGB8,
1423 			GL_RGB565,
1424 
1425 			// RG formats
1426 			GL_RG32I,
1427 			GL_RG32UI,
1428 			GL_RG16I,
1429 			GL_RG16UI,
1430 			GL_RG8,
1431 			GL_RG8I,
1432 			GL_RG8UI,
1433 
1434 			// R formats
1435 			GL_R32I,
1436 			GL_R32UI,
1437 			GL_R16I,
1438 			GL_R16UI,
1439 			GL_R8,
1440 			GL_R8I,
1441 			GL_R8UI,
1442 
1443 			// GL_EXT_color_buffer_float
1444 			GL_RGBA32F,
1445 			GL_RGBA16F,
1446 			GL_R11F_G11F_B10F,
1447 			GL_RG32F,
1448 			GL_RG16F,
1449 			GL_R32F,
1450 			GL_R16F,
1451 
1452 			// GL_EXT_color_buffer_half_float
1453 			GL_RGB16F
1454 		};
1455 
1456 		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(colorFormats); ndx++)
1457 			framebufferFormatTestGroup->addChild(new TextureFormatTestCase(m_context, getFormatName(colorFormats[ndx]), "Framebuffer fetches from texture attachments with varying formats", colorFormats[ndx]));
1458 	}
1459 
1460 	addChild(basicTestGroup);
1461 	addChild(framebufferFormatTestGroup);
1462 }
1463 
1464 } // Functional
1465 } // gles31
1466 } // deqp
1467