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