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 Texture format tests.
22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/
23e5c31af7Sopenharmony_ci
24e5c31af7Sopenharmony_ci#include "es31fSRGBDecodeTests.hpp"
25e5c31af7Sopenharmony_ci#include "gluContextInfo.hpp"
26e5c31af7Sopenharmony_ci#include "gluCallLogWrapper.hpp"
27e5c31af7Sopenharmony_ci#include "gluRenderContext.hpp"
28e5c31af7Sopenharmony_ci#include "gluTexture.hpp"
29e5c31af7Sopenharmony_ci#include "glsTextureTestUtil.hpp"
30e5c31af7Sopenharmony_ci#include "tcuPixelFormat.hpp"
31e5c31af7Sopenharmony_ci#include "tcuTestContext.hpp"
32e5c31af7Sopenharmony_ci#include "tcuRenderTarget.hpp"
33e5c31af7Sopenharmony_ci#include "gluTextureUtil.hpp"
34e5c31af7Sopenharmony_ci#include "tcuTextureUtil.hpp"
35e5c31af7Sopenharmony_ci#include "glwFunctions.hpp"
36e5c31af7Sopenharmony_ci#include "gluDefs.hpp"
37e5c31af7Sopenharmony_ci#include "glwEnums.hpp"
38e5c31af7Sopenharmony_ci#include "deUniquePtr.hpp"
39e5c31af7Sopenharmony_ci#include "gluPixelTransfer.hpp"
40e5c31af7Sopenharmony_ci#include "tcuDefs.hpp"
41e5c31af7Sopenharmony_ci#include "tcuVectorUtil.hpp"
42e5c31af7Sopenharmony_ci#include "gluObjectWrapper.hpp"
43e5c31af7Sopenharmony_ci#include "gluStrUtil.hpp"
44e5c31af7Sopenharmony_ci#include "tcuTestLog.hpp"
45e5c31af7Sopenharmony_ci#include "deStringUtil.hpp"
46e5c31af7Sopenharmony_ci
47e5c31af7Sopenharmony_cinamespace deqp
48e5c31af7Sopenharmony_ci{
49e5c31af7Sopenharmony_cinamespace gles31
50e5c31af7Sopenharmony_ci{
51e5c31af7Sopenharmony_cinamespace Functional
52e5c31af7Sopenharmony_ci{
53e5c31af7Sopenharmony_cinamespace
54e5c31af7Sopenharmony_ci{
55e5c31af7Sopenharmony_ci
56e5c31af7Sopenharmony_ciusing glu::TextureTestUtil::TEXTURETYPE_2D;
57e5c31af7Sopenharmony_ci
58e5c31af7Sopenharmony_cienum SRGBDecode
59e5c31af7Sopenharmony_ci{
60e5c31af7Sopenharmony_ci	SRGBDECODE_SKIP_DECODE		= 0,
61e5c31af7Sopenharmony_ci	SRGBDECODE_DECODE,
62e5c31af7Sopenharmony_ci	SRGBDECODE_DECODE_DEFAULT
63e5c31af7Sopenharmony_ci};
64e5c31af7Sopenharmony_ci
65e5c31af7Sopenharmony_cienum ShaderOutputs
66e5c31af7Sopenharmony_ci{
67e5c31af7Sopenharmony_ci	SHADEROUTPUTS_ONE	= 1,
68e5c31af7Sopenharmony_ci	SHADEROUTPUTS_TWO,
69e5c31af7Sopenharmony_ci};
70e5c31af7Sopenharmony_ci
71e5c31af7Sopenharmony_cienum ShaderUniforms
72e5c31af7Sopenharmony_ci{
73e5c31af7Sopenharmony_ci	SHADERUNIFORMS_ONE	= 1,
74e5c31af7Sopenharmony_ci	SHADERUNIFORMS_TWO,
75e5c31af7Sopenharmony_ci};
76e5c31af7Sopenharmony_ci
77e5c31af7Sopenharmony_cienum ShaderSamplingGroup
78e5c31af7Sopenharmony_ci{
79e5c31af7Sopenharmony_ci	SHADERSAMPLINGGROUP_TEXTURE		= 0,
80e5c31af7Sopenharmony_ci	SHADERSAMPLINGGROUP_TEXEL_FETCH
81e5c31af7Sopenharmony_ci};
82e5c31af7Sopenharmony_ci
83e5c31af7Sopenharmony_cienum ShaderSamplingType
84e5c31af7Sopenharmony_ci{
85e5c31af7Sopenharmony_ci	TEXTURESAMPLING_TEXTURE													= 0,
86e5c31af7Sopenharmony_ci	TEXTURESAMPLING_TEXTURE_LOD,
87e5c31af7Sopenharmony_ci	TEXTURESAMPLING_TEXTURE_GRAD,
88e5c31af7Sopenharmony_ci	TEXTURESAMPLING_TEXTURE_OFFSET,
89e5c31af7Sopenharmony_ci	TEXTURESAMPLING_TEXTURE_PROJ,
90e5c31af7Sopenharmony_ci	TEXTURESAMPLING_TEXELFETCH,
91e5c31af7Sopenharmony_ci	TEXTURESAMPLING_TEXELFETCH_OFFSET,
92e5c31af7Sopenharmony_ci
93e5c31af7Sopenharmony_ci	// ranges required for looping mechanism in a case nodes iteration function
94e5c31af7Sopenharmony_ci	TEXTURESAMPLING_TEXTURE_START		= TEXTURESAMPLING_TEXTURE,
95e5c31af7Sopenharmony_ci	TEXTURESAMPLING_TEXTURE_END			= TEXTURESAMPLING_TEXTURE_PROJ		+ 1,
96e5c31af7Sopenharmony_ci	TEXTURESAMPLING_TEXELFETCH_START	= TEXTURESAMPLING_TEXELFETCH,
97e5c31af7Sopenharmony_ci	TEXTURESAMPLING_TEXELFETCH_END		= TEXTURESAMPLING_TEXELFETCH_OFFSET	+ 1
98e5c31af7Sopenharmony_ci};
99e5c31af7Sopenharmony_ci
100e5c31af7Sopenharmony_cienum FunctionParameters
101e5c31af7Sopenharmony_ci{
102e5c31af7Sopenharmony_ci	FUNCTIONPARAMETERS_ONE = 1,
103e5c31af7Sopenharmony_ci	FUNCTIONPARAMETERS_TWO
104e5c31af7Sopenharmony_ci};
105e5c31af7Sopenharmony_ci
106e5c31af7Sopenharmony_cienum Blending
107e5c31af7Sopenharmony_ci{
108e5c31af7Sopenharmony_ci	BLENDING_REQUIRED		= 0,
109e5c31af7Sopenharmony_ci	BLENDING_NOT_REQUIRED
110e5c31af7Sopenharmony_ci};
111e5c31af7Sopenharmony_ci
112e5c31af7Sopenharmony_cienum Toggling
113e5c31af7Sopenharmony_ci{
114e5c31af7Sopenharmony_ci	TOGGLING_REQUIRED		= 0,
115e5c31af7Sopenharmony_ci	TOGGLING_NOT_REQUIRED
116e5c31af7Sopenharmony_ci};
117e5c31af7Sopenharmony_ci
118e5c31af7Sopenharmony_citcu::Vec4 getColorReferenceLinear (void)
119e5c31af7Sopenharmony_ci{
120e5c31af7Sopenharmony_ci	return tcu::Vec4(0.2f, 0.3f, 0.4f, 1.0f);
121e5c31af7Sopenharmony_ci}
122e5c31af7Sopenharmony_ci
123e5c31af7Sopenharmony_citcu::Vec4 getColorReferenceSRGB (void)
124e5c31af7Sopenharmony_ci{
125e5c31af7Sopenharmony_ci	return tcu::linearToSRGB(tcu::Vec4(0.2f, 0.3f, 0.4f, 1.0f));
126e5c31af7Sopenharmony_ci}
127e5c31af7Sopenharmony_ci
128e5c31af7Sopenharmony_citcu::Vec4 getColorGreenPass (void)
129e5c31af7Sopenharmony_ci{
130e5c31af7Sopenharmony_ci	return tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
131e5c31af7Sopenharmony_ci}
132e5c31af7Sopenharmony_ci
133e5c31af7Sopenharmony_cinamespace TestDimensions
134e5c31af7Sopenharmony_ci{
135e5c31af7Sopenharmony_ci	const int WIDTH		= 128;
136e5c31af7Sopenharmony_ci	const int HEIGHT	= 128;
137e5c31af7Sopenharmony_ci} // global test texture dimensions
138e5c31af7Sopenharmony_ci
139e5c31af7Sopenharmony_cinamespace TestSamplingPositions
140e5c31af7Sopenharmony_ci{
141e5c31af7Sopenharmony_ci	const int X_POS = 0;
142e5c31af7Sopenharmony_ci	const int Y_POS = 0;
143e5c31af7Sopenharmony_ci} // global test sampling positions
144e5c31af7Sopenharmony_ci
145e5c31af7Sopenharmony_ciconst char* getFunctionDefinitionSRGBToLinearCheck (void)
146e5c31af7Sopenharmony_ci{
147e5c31af7Sopenharmony_ci	static const char* functionDefinition =
148e5c31af7Sopenharmony_ci			"mediump vec4 srgbToLinearCheck(in mediump vec4 texelSRGBA, in mediump vec4 texelLinear) \n"
149e5c31af7Sopenharmony_ci			"{ \n"
150e5c31af7Sopenharmony_ci			"	const int NUM_CHANNELS = 4;"
151e5c31af7Sopenharmony_ci			"	mediump vec4 texelSRGBAConverted; \n"
152e5c31af7Sopenharmony_ci			"	mediump vec4 epsilonErr = vec4(0.005); \n"
153e5c31af7Sopenharmony_ci			"	mediump vec4 testResult; \n"
154e5c31af7Sopenharmony_ci			"	for (int idx = 0; idx < NUM_CHANNELS; idx++) \n"
155e5c31af7Sopenharmony_ci			"	{ \n"
156e5c31af7Sopenharmony_ci			"		texelSRGBAConverted[idx] = pow( (texelSRGBA[idx] + 0.055) / 1.055, 1.0 / 0.4116); \n"
157e5c31af7Sopenharmony_ci			"	} \n"
158e5c31af7Sopenharmony_ci			"	if ( all(lessThan(abs(texelSRGBAConverted - texelLinear), epsilonErr)) || all(equal(texelSRGBAConverted, texelLinear)) ) \n"
159e5c31af7Sopenharmony_ci			"	{ \n"
160e5c31af7Sopenharmony_ci			"		return testResult = vec4(0.0, 1.0, 0.0, 1.0); \n"
161e5c31af7Sopenharmony_ci			"	} \n"
162e5c31af7Sopenharmony_ci			"	else \n"
163e5c31af7Sopenharmony_ci			"	{ \n"
164e5c31af7Sopenharmony_ci			"		return testResult = vec4(1.0, 0.0, 0.0, 1.0); \n"
165e5c31af7Sopenharmony_ci			"	} \n"
166e5c31af7Sopenharmony_ci			"} \n";
167e5c31af7Sopenharmony_ci
168e5c31af7Sopenharmony_ci	return functionDefinition;
169e5c31af7Sopenharmony_ci}
170e5c31af7Sopenharmony_ci
171e5c31af7Sopenharmony_ciconst char* getFunctionDefinitionEqualCheck (void)
172e5c31af7Sopenharmony_ci{
173e5c31af7Sopenharmony_ci	static const char* functionDefinition =
174e5c31af7Sopenharmony_ci			"mediump vec4 colorsEqualCheck(in mediump vec4 colorA, in mediump vec4 colorB) \n"
175e5c31af7Sopenharmony_ci			"{ \n"
176e5c31af7Sopenharmony_ci			"	mediump vec4 epsilonErr = vec4(0.005); \n"
177e5c31af7Sopenharmony_ci			"	mediump vec4 testResult; \n"
178e5c31af7Sopenharmony_ci			"	if ( all(lessThan(abs(colorA - colorB), epsilonErr)) || all(equal(colorA, colorB)) ) \n"
179e5c31af7Sopenharmony_ci			"	{ \n"
180e5c31af7Sopenharmony_ci			"		return testResult = vec4(0.0, 1.0, 0.0, 1.0); \n"
181e5c31af7Sopenharmony_ci			"	} \n"
182e5c31af7Sopenharmony_ci			"	else \n"
183e5c31af7Sopenharmony_ci			"	{ \n"
184e5c31af7Sopenharmony_ci			"		return testResult = vec4(1.0, 0.0, 0.0, 1.0); \n"
185e5c31af7Sopenharmony_ci			"	} \n"
186e5c31af7Sopenharmony_ci			"} \n";
187e5c31af7Sopenharmony_ci
188e5c31af7Sopenharmony_ci	return functionDefinition;
189e5c31af7Sopenharmony_ci}
190e5c31af7Sopenharmony_ci
191e5c31af7Sopenharmony_cinamespace EpsilonError
192e5c31af7Sopenharmony_ci{
193e5c31af7Sopenharmony_ci	const float CPU = 0.005f;
194e5c31af7Sopenharmony_ci}
195e5c31af7Sopenharmony_ci
196e5c31af7Sopenharmony_cistruct TestGroupConfig
197e5c31af7Sopenharmony_ci{
198e5c31af7Sopenharmony_ci	TestGroupConfig			(const char* groupName, const char* groupDescription, const tcu::TextureFormat groupInternalFormat)
199e5c31af7Sopenharmony_ci		: name				(groupName)
200e5c31af7Sopenharmony_ci		, description		(groupDescription)
201e5c31af7Sopenharmony_ci		, internalFormat	(groupInternalFormat) {}
202e5c31af7Sopenharmony_ci
203e5c31af7Sopenharmony_ci	~TestGroupConfig		(void) {}
204e5c31af7Sopenharmony_ci
205e5c31af7Sopenharmony_ci	const char*					name;
206e5c31af7Sopenharmony_ci	const char*					description;
207e5c31af7Sopenharmony_ci	const tcu::TextureFormat	internalFormat;
208e5c31af7Sopenharmony_ci};
209e5c31af7Sopenharmony_ci
210e5c31af7Sopenharmony_cistruct UniformData
211e5c31af7Sopenharmony_ci{
212e5c31af7Sopenharmony_ci	UniformData			(glw::GLuint uniformLocation, const std::string& uniformName)
213e5c31af7Sopenharmony_ci		: location		(uniformLocation)
214e5c31af7Sopenharmony_ci		, name			(uniformName)
215e5c31af7Sopenharmony_ci		, toggleDecode	(false) {}
216e5c31af7Sopenharmony_ci
217e5c31af7Sopenharmony_ci	~UniformData		(void) {}
218e5c31af7Sopenharmony_ci
219e5c31af7Sopenharmony_ci	glw::GLuint	location;
220e5c31af7Sopenharmony_ci	std::string	name;
221e5c31af7Sopenharmony_ci	bool		toggleDecode;
222e5c31af7Sopenharmony_ci};
223e5c31af7Sopenharmony_ci
224e5c31af7Sopenharmony_cistruct UniformToToggle
225e5c31af7Sopenharmony_ci{
226e5c31af7Sopenharmony_ci	UniformToToggle		(const int uniformProgramIdx, const std::string& uniformName)
227e5c31af7Sopenharmony_ci		: programIdx	(uniformProgramIdx)
228e5c31af7Sopenharmony_ci		, name			(uniformName) {}
229e5c31af7Sopenharmony_ci
230e5c31af7Sopenharmony_ci	~UniformToToggle	(void) {}
231e5c31af7Sopenharmony_ci
232e5c31af7Sopenharmony_ci	int			programIdx;
233e5c31af7Sopenharmony_ci	std::string	name;
234e5c31af7Sopenharmony_ci};
235e5c31af7Sopenharmony_ci
236e5c31af7Sopenharmony_cistruct ComparisonFunction
237e5c31af7Sopenharmony_ci{
238e5c31af7Sopenharmony_ci	ComparisonFunction		(const std::string& funcName, const FunctionParameters funcParameters, const std::string& funcImplementation)
239e5c31af7Sopenharmony_ci		: name				(funcName)
240e5c31af7Sopenharmony_ci		, parameters		(funcParameters)
241e5c31af7Sopenharmony_ci		, implementation	(funcImplementation) {}
242e5c31af7Sopenharmony_ci
243e5c31af7Sopenharmony_ci	~ComparisonFunction		(void) {}
244e5c31af7Sopenharmony_ci
245e5c31af7Sopenharmony_ci	std::string			name;
246e5c31af7Sopenharmony_ci	FunctionParameters	parameters;
247e5c31af7Sopenharmony_ci	std::string			implementation;
248e5c31af7Sopenharmony_ci};
249e5c31af7Sopenharmony_ci
250e5c31af7Sopenharmony_cistruct FragmentShaderParameters
251e5c31af7Sopenharmony_ci{
252e5c31af7Sopenharmony_ci	FragmentShaderParameters	(const ShaderOutputs	outputTotal,
253e5c31af7Sopenharmony_ci								 const ShaderUniforms	uniformTotal,
254e5c31af7Sopenharmony_ci								 ComparisonFunction*	comparisonFunction,
255e5c31af7Sopenharmony_ci								 Blending				blendRequired,
256e5c31af7Sopenharmony_ci								 Toggling				toggleRequired);
257e5c31af7Sopenharmony_ci
258e5c31af7Sopenharmony_ci	~FragmentShaderParameters	(void);
259e5c31af7Sopenharmony_ci
260e5c31af7Sopenharmony_ci	ShaderOutputs				outputTotal;
261e5c31af7Sopenharmony_ci	ShaderUniforms				uniformTotal;
262e5c31af7Sopenharmony_ci	ShaderSamplingType			samplingType;
263e5c31af7Sopenharmony_ci	std::string					functionName;
264e5c31af7Sopenharmony_ci	FunctionParameters			functionParameters;
265e5c31af7Sopenharmony_ci	std::string					functionImplementation;
266e5c31af7Sopenharmony_ci	bool						hasFunction;
267e5c31af7Sopenharmony_ci	Blending					blendRequired;
268e5c31af7Sopenharmony_ci	Toggling					toggleRequired;
269e5c31af7Sopenharmony_ci	std::vector<std::string>	uniformsToToggle;
270e5c31af7Sopenharmony_ci};
271e5c31af7Sopenharmony_ci
272e5c31af7Sopenharmony_ciFragmentShaderParameters::FragmentShaderParameters	(const ShaderOutputs	paramsOutputTotal,
273e5c31af7Sopenharmony_ci													 const ShaderUniforms	paramsUniformTotal,
274e5c31af7Sopenharmony_ci													 ComparisonFunction*	paramsComparisonFunction,
275e5c31af7Sopenharmony_ci													 Blending				paramsBlendRequired,
276e5c31af7Sopenharmony_ci													 Toggling				paramsToggleRequired)
277e5c31af7Sopenharmony_ci	: outputTotal									(paramsOutputTotal)
278e5c31af7Sopenharmony_ci	, uniformTotal									(paramsUniformTotal)
279e5c31af7Sopenharmony_ci	, samplingType									(TEXTURESAMPLING_TEXTURE)
280e5c31af7Sopenharmony_ci	, blendRequired									(paramsBlendRequired)
281e5c31af7Sopenharmony_ci	, toggleRequired								(paramsToggleRequired)
282e5c31af7Sopenharmony_ci{
283e5c31af7Sopenharmony_ci	if (paramsComparisonFunction != DE_NULL)
284e5c31af7Sopenharmony_ci	{
285e5c31af7Sopenharmony_ci		functionName			= paramsComparisonFunction->name;
286e5c31af7Sopenharmony_ci		functionParameters		= paramsComparisonFunction->parameters;
287e5c31af7Sopenharmony_ci		functionImplementation	= paramsComparisonFunction->implementation;
288e5c31af7Sopenharmony_ci
289e5c31af7Sopenharmony_ci		hasFunction = true;
290e5c31af7Sopenharmony_ci	}
291e5c31af7Sopenharmony_ci	else
292e5c31af7Sopenharmony_ci	{
293e5c31af7Sopenharmony_ci		hasFunction = false;
294e5c31af7Sopenharmony_ci	}
295e5c31af7Sopenharmony_ci}
296e5c31af7Sopenharmony_ci
297e5c31af7Sopenharmony_ciFragmentShaderParameters::~FragmentShaderParameters (void)
298e5c31af7Sopenharmony_ci{
299e5c31af7Sopenharmony_ci}
300e5c31af7Sopenharmony_ci
301e5c31af7Sopenharmony_ciclass SRGBTestSampler
302e5c31af7Sopenharmony_ci{
303e5c31af7Sopenharmony_cipublic:
304e5c31af7Sopenharmony_ci				SRGBTestSampler		(Context&						context,
305e5c31af7Sopenharmony_ci									 const tcu::Sampler::WrapMode	wrapS,
306e5c31af7Sopenharmony_ci									 const tcu::Sampler::WrapMode	wrapT,
307e5c31af7Sopenharmony_ci									 const tcu::Sampler::FilterMode	minFilter,
308e5c31af7Sopenharmony_ci									 const tcu::Sampler::FilterMode	magFilter,
309e5c31af7Sopenharmony_ci									 const SRGBDecode				decoding);
310e5c31af7Sopenharmony_ci				~SRGBTestSampler	(void);
311e5c31af7Sopenharmony_ci
312e5c31af7Sopenharmony_ci	void		setDecode			(const SRGBDecode decoding);
313e5c31af7Sopenharmony_ci	void		setTextureUnit		(const deUint32 textureUnit);
314e5c31af7Sopenharmony_ci	void		setIsActive			(const bool isActive);
315e5c31af7Sopenharmony_ci
316e5c31af7Sopenharmony_ci	bool		getIsActive			(void) const;
317e5c31af7Sopenharmony_ci
318e5c31af7Sopenharmony_ci	void		bindToTexture		(void);
319e5c31af7Sopenharmony_ci
320e5c31af7Sopenharmony_ciprivate:
321e5c31af7Sopenharmony_ci	const glw::Functions*		m_gl;
322e5c31af7Sopenharmony_ci	deUint32					m_samplerHandle;
323e5c31af7Sopenharmony_ci	tcu::Sampler::WrapMode		m_wrapS;
324e5c31af7Sopenharmony_ci	tcu::Sampler::WrapMode		m_wrapT;
325e5c31af7Sopenharmony_ci	tcu::Sampler::FilterMode	m_minFilter;
326e5c31af7Sopenharmony_ci	tcu::Sampler::FilterMode	m_magFilter;
327e5c31af7Sopenharmony_ci	SRGBDecode					m_decoding;
328e5c31af7Sopenharmony_ci	deUint32					m_textureUnit;
329e5c31af7Sopenharmony_ci	bool						m_isActive;
330e5c31af7Sopenharmony_ci};
331e5c31af7Sopenharmony_ci
332e5c31af7Sopenharmony_ciSRGBTestSampler::SRGBTestSampler	(Context&						context,
333e5c31af7Sopenharmony_ci									 const tcu::Sampler::WrapMode	wrapS,
334e5c31af7Sopenharmony_ci									 const tcu::Sampler::WrapMode	wrapT,
335e5c31af7Sopenharmony_ci									 const tcu::Sampler::FilterMode	minFilter,
336e5c31af7Sopenharmony_ci									 const tcu::Sampler::FilterMode	magFilter,
337e5c31af7Sopenharmony_ci									 const SRGBDecode				decoding)
338e5c31af7Sopenharmony_ci	: m_gl							(&context.getRenderContext().getFunctions())
339e5c31af7Sopenharmony_ci	, m_wrapS						(wrapS)
340e5c31af7Sopenharmony_ci	, m_wrapT						(wrapT)
341e5c31af7Sopenharmony_ci	, m_minFilter					(minFilter)
342e5c31af7Sopenharmony_ci	, m_magFilter					(magFilter)
343e5c31af7Sopenharmony_ci	, m_isActive					(false)
344e5c31af7Sopenharmony_ci{
345e5c31af7Sopenharmony_ci	m_gl->genSamplers(1, &m_samplerHandle);
346e5c31af7Sopenharmony_ci
347e5c31af7Sopenharmony_ci	m_gl->samplerParameteri(m_samplerHandle, GL_TEXTURE_WRAP_S, glu::getGLWrapMode(m_wrapS));
348e5c31af7Sopenharmony_ci	m_gl->samplerParameteri(m_samplerHandle, GL_TEXTURE_WRAP_T, glu::getGLWrapMode(m_wrapT));
349e5c31af7Sopenharmony_ci	m_gl->samplerParameteri(m_samplerHandle, GL_TEXTURE_MIN_FILTER, glu::getGLFilterMode(m_minFilter));
350e5c31af7Sopenharmony_ci	m_gl->samplerParameteri(m_samplerHandle, GL_TEXTURE_MAG_FILTER, glu::getGLFilterMode(m_magFilter));
351e5c31af7Sopenharmony_ci
352e5c31af7Sopenharmony_ci	this->setDecode(decoding);
353e5c31af7Sopenharmony_ci}
354e5c31af7Sopenharmony_ci
355e5c31af7Sopenharmony_ciSRGBTestSampler::~SRGBTestSampler (void)
356e5c31af7Sopenharmony_ci{
357e5c31af7Sopenharmony_ci	m_gl->deleteSamplers(1, &m_samplerHandle);
358e5c31af7Sopenharmony_ci}
359e5c31af7Sopenharmony_ci
360e5c31af7Sopenharmony_civoid SRGBTestSampler::setDecode (const SRGBDecode decoding)
361e5c31af7Sopenharmony_ci{
362e5c31af7Sopenharmony_ci	if (decoding == SRGBDECODE_SKIP_DECODE)
363e5c31af7Sopenharmony_ci	{
364e5c31af7Sopenharmony_ci		m_gl->samplerParameteri(m_samplerHandle, GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT);
365e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(m_gl->getError(), "samplerParameteri(m_samplerID, GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT)");
366e5c31af7Sopenharmony_ci	}
367e5c31af7Sopenharmony_ci	else if (decoding == SRGBDECODE_DECODE)
368e5c31af7Sopenharmony_ci	{
369e5c31af7Sopenharmony_ci		m_gl->samplerParameteri(m_samplerHandle, GL_TEXTURE_SRGB_DECODE_EXT, GL_DECODE_EXT);
370e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(m_gl->getError(), "samplerParameteri(m_samplerID, GL_TEXTURE_SRGB_DECODE_EXT, GL_DECODE_EXT)");
371e5c31af7Sopenharmony_ci	}
372e5c31af7Sopenharmony_ci	else
373e5c31af7Sopenharmony_ci	{
374e5c31af7Sopenharmony_ci		DE_FATAL("sRGB texture sampler must have either GL_SKIP_DECODE_EXT or GL_DECODE_EXT settings");
375e5c31af7Sopenharmony_ci	}
376e5c31af7Sopenharmony_ci
377e5c31af7Sopenharmony_ci	m_decoding = decoding;
378e5c31af7Sopenharmony_ci}
379e5c31af7Sopenharmony_ci
380e5c31af7Sopenharmony_civoid SRGBTestSampler::setTextureUnit (const deUint32 textureUnit)
381e5c31af7Sopenharmony_ci{
382e5c31af7Sopenharmony_ci	m_textureUnit = textureUnit;
383e5c31af7Sopenharmony_ci}
384e5c31af7Sopenharmony_ci
385e5c31af7Sopenharmony_civoid SRGBTestSampler::setIsActive (const bool isActive)
386e5c31af7Sopenharmony_ci{
387e5c31af7Sopenharmony_ci	m_isActive = isActive;
388e5c31af7Sopenharmony_ci}
389e5c31af7Sopenharmony_ci
390e5c31af7Sopenharmony_cibool SRGBTestSampler::getIsActive (void) const
391e5c31af7Sopenharmony_ci{
392e5c31af7Sopenharmony_ci	return m_isActive;
393e5c31af7Sopenharmony_ci}
394e5c31af7Sopenharmony_ci
395e5c31af7Sopenharmony_civoid SRGBTestSampler::bindToTexture (void)
396e5c31af7Sopenharmony_ci{
397e5c31af7Sopenharmony_ci	m_gl->bindSampler(m_textureUnit, m_samplerHandle);
398e5c31af7Sopenharmony_ci}
399e5c31af7Sopenharmony_ci
400e5c31af7Sopenharmony_ciclass SRGBTestTexture
401e5c31af7Sopenharmony_ci{
402e5c31af7Sopenharmony_cipublic:
403e5c31af7Sopenharmony_ci				SRGBTestTexture		(Context&									context,
404e5c31af7Sopenharmony_ci									 const glu::TextureTestUtil::TextureType	targetType,
405e5c31af7Sopenharmony_ci									 const tcu::TextureFormat					internalFormat,
406e5c31af7Sopenharmony_ci									 const int									width,
407e5c31af7Sopenharmony_ci									 const int									height,
408e5c31af7Sopenharmony_ci									 const tcu::Vec4							color,
409e5c31af7Sopenharmony_ci									 const tcu::Sampler::WrapMode				wrapS,
410e5c31af7Sopenharmony_ci									 const tcu::Sampler::WrapMode				wrapT,
411e5c31af7Sopenharmony_ci									 const tcu::Sampler::FilterMode				minFilter,
412e5c31af7Sopenharmony_ci									 const tcu::Sampler::FilterMode				magFilter,
413e5c31af7Sopenharmony_ci									 const SRGBDecode							decoding);
414e5c31af7Sopenharmony_ci				~SRGBTestTexture	(void);
415e5c31af7Sopenharmony_ci
416e5c31af7Sopenharmony_ci	void		setParameters		(void);
417e5c31af7Sopenharmony_ci	void		setDecode			(const SRGBDecode decoding);
418e5c31af7Sopenharmony_ci	void		setHasSampler		(const bool hasSampler);
419e5c31af7Sopenharmony_ci
420e5c31af7Sopenharmony_ci	deUint32	getHandle			(void) const;
421e5c31af7Sopenharmony_ci	deUint32	getGLTargetType		(void) const;
422e5c31af7Sopenharmony_ci	SRGBDecode	getDecode			(void) const;
423e5c31af7Sopenharmony_ci
424e5c31af7Sopenharmony_ci	void		upload				(void);
425e5c31af7Sopenharmony_ci
426e5c31af7Sopenharmony_ciprivate:
427e5c31af7Sopenharmony_ci	void		setColor			(void);
428e5c31af7Sopenharmony_ci
429e5c31af7Sopenharmony_ci	Context&							m_context;
430e5c31af7Sopenharmony_ci	glu::Texture2D						m_source;
431e5c31af7Sopenharmony_ci	glu::TextureTestUtil::TextureType	m_targetType;
432e5c31af7Sopenharmony_ci	const tcu::TextureFormat			m_internalFormat;
433e5c31af7Sopenharmony_ci	const int							m_width;
434e5c31af7Sopenharmony_ci	const int							m_height;
435e5c31af7Sopenharmony_ci	tcu::Vec4							m_color;
436e5c31af7Sopenharmony_ci	tcu::Sampler::WrapMode				m_wrapS;
437e5c31af7Sopenharmony_ci	tcu::Sampler::WrapMode				m_wrapT;
438e5c31af7Sopenharmony_ci	tcu::Sampler::FilterMode			m_minFilter;
439e5c31af7Sopenharmony_ci	tcu::Sampler::FilterMode			m_magFilter;
440e5c31af7Sopenharmony_ci	SRGBDecode							m_decoding;
441e5c31af7Sopenharmony_ci	bool								m_hasSampler;
442e5c31af7Sopenharmony_ci};
443e5c31af7Sopenharmony_ci
444e5c31af7Sopenharmony_ciSRGBTestTexture::SRGBTestTexture	(Context&									context,
445e5c31af7Sopenharmony_ci									 const glu::TextureTestUtil::TextureType	targetType,
446e5c31af7Sopenharmony_ci									 const tcu::TextureFormat					internalFormat,
447e5c31af7Sopenharmony_ci									 const int									width,
448e5c31af7Sopenharmony_ci									 const int									height,
449e5c31af7Sopenharmony_ci									 const tcu::Vec4							color,
450e5c31af7Sopenharmony_ci									 const tcu::Sampler::WrapMode				wrapS,
451e5c31af7Sopenharmony_ci									 const tcu::Sampler::WrapMode				wrapT,
452e5c31af7Sopenharmony_ci									 const tcu::Sampler::FilterMode				minFilter,
453e5c31af7Sopenharmony_ci									 const tcu::Sampler::FilterMode				magFilter,
454e5c31af7Sopenharmony_ci									 SRGBDecode									decoding)
455e5c31af7Sopenharmony_ci	: m_context						(context)
456e5c31af7Sopenharmony_ci	, m_source						(context.getRenderContext(), glu::getInternalFormat(internalFormat), width, height)
457e5c31af7Sopenharmony_ci	, m_targetType					(targetType)
458e5c31af7Sopenharmony_ci	, m_internalFormat				(internalFormat)
459e5c31af7Sopenharmony_ci	, m_width						(width)
460e5c31af7Sopenharmony_ci	, m_height						(height)
461e5c31af7Sopenharmony_ci	, m_color						(color)
462e5c31af7Sopenharmony_ci	, m_wrapS						(wrapS)
463e5c31af7Sopenharmony_ci	, m_wrapT						(wrapT)
464e5c31af7Sopenharmony_ci	, m_minFilter					(minFilter)
465e5c31af7Sopenharmony_ci	, m_magFilter					(magFilter)
466e5c31af7Sopenharmony_ci	, m_decoding					(decoding)
467e5c31af7Sopenharmony_ci	, m_hasSampler					(false)
468e5c31af7Sopenharmony_ci{
469e5c31af7Sopenharmony_ci	this->setColor();
470e5c31af7Sopenharmony_ci}
471e5c31af7Sopenharmony_ci
472e5c31af7Sopenharmony_ciSRGBTestTexture::~SRGBTestTexture (void)
473e5c31af7Sopenharmony_ci{
474e5c31af7Sopenharmony_ci}
475e5c31af7Sopenharmony_ci
476e5c31af7Sopenharmony_civoid SRGBTestTexture::setParameters (void)
477e5c31af7Sopenharmony_ci{
478e5c31af7Sopenharmony_ci	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
479e5c31af7Sopenharmony_ci
480e5c31af7Sopenharmony_ci	gl.bindTexture(this->getGLTargetType(), this->getHandle());
481e5c31af7Sopenharmony_ci
482e5c31af7Sopenharmony_ci	gl.texParameteri(this->getGLTargetType(), GL_TEXTURE_WRAP_S, glu::getGLWrapMode(m_wrapS));
483e5c31af7Sopenharmony_ci	gl.texParameteri(this->getGLTargetType(), GL_TEXTURE_WRAP_T, glu::getGLWrapMode(m_wrapT));
484e5c31af7Sopenharmony_ci	gl.texParameteri(this->getGLTargetType(), GL_TEXTURE_MIN_FILTER, glu::getGLFilterMode(m_minFilter));
485e5c31af7Sopenharmony_ci	gl.texParameteri(this->getGLTargetType(), GL_TEXTURE_MAG_FILTER, glu::getGLFilterMode(m_magFilter));
486e5c31af7Sopenharmony_ci
487e5c31af7Sopenharmony_ci	gl.bindTexture(this->getGLTargetType(), 0);
488e5c31af7Sopenharmony_ci
489e5c31af7Sopenharmony_ci	setDecode(m_decoding);
490e5c31af7Sopenharmony_ci}
491e5c31af7Sopenharmony_ci
492e5c31af7Sopenharmony_civoid SRGBTestTexture::setDecode (const SRGBDecode decoding)
493e5c31af7Sopenharmony_ci{
494e5c31af7Sopenharmony_ci	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
495e5c31af7Sopenharmony_ci
496e5c31af7Sopenharmony_ci	gl.bindTexture(this->getGLTargetType(), this->getHandle());
497e5c31af7Sopenharmony_ci
498e5c31af7Sopenharmony_ci	switch (decoding)
499e5c31af7Sopenharmony_ci	{
500e5c31af7Sopenharmony_ci		case SRGBDECODE_SKIP_DECODE:
501e5c31af7Sopenharmony_ci		{
502e5c31af7Sopenharmony_ci			gl.texParameteri(this->getGLTargetType(), GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT);
503e5c31af7Sopenharmony_ci			GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri(this->getGLTargetType(), GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT)");
504e5c31af7Sopenharmony_ci			break;
505e5c31af7Sopenharmony_ci		}
506e5c31af7Sopenharmony_ci		case SRGBDECODE_DECODE:
507e5c31af7Sopenharmony_ci		{
508e5c31af7Sopenharmony_ci			gl.texParameteri(this->getGLTargetType(), GL_TEXTURE_SRGB_DECODE_EXT, GL_DECODE_EXT);
509e5c31af7Sopenharmony_ci			GLU_EXPECT_NO_ERROR(gl.getError(), "glTexParameteri(this->getGLTargetType(), GL_TEXTURE_SRGB_DECODE_EXT, GL_DECODE_EXT)");
510e5c31af7Sopenharmony_ci			break;
511e5c31af7Sopenharmony_ci		}
512e5c31af7Sopenharmony_ci		case SRGBDECODE_DECODE_DEFAULT:
513e5c31af7Sopenharmony_ci		{
514e5c31af7Sopenharmony_ci			// do not use srgb decode options. Set to default
515e5c31af7Sopenharmony_ci			break;
516e5c31af7Sopenharmony_ci		}
517e5c31af7Sopenharmony_ci		default:
518e5c31af7Sopenharmony_ci			DE_FATAL("Error: Decoding option not recognised");
519e5c31af7Sopenharmony_ci	}
520e5c31af7Sopenharmony_ci
521e5c31af7Sopenharmony_ci	gl.bindTexture(this->getGLTargetType(), 0);
522e5c31af7Sopenharmony_ci
523e5c31af7Sopenharmony_ci	m_decoding = decoding;
524e5c31af7Sopenharmony_ci}
525e5c31af7Sopenharmony_ci
526e5c31af7Sopenharmony_civoid SRGBTestTexture::setHasSampler (const bool hasSampler)
527e5c31af7Sopenharmony_ci{
528e5c31af7Sopenharmony_ci	m_hasSampler = hasSampler;
529e5c31af7Sopenharmony_ci}
530e5c31af7Sopenharmony_ci
531e5c31af7Sopenharmony_cideUint32 SRGBTestTexture::getHandle (void) const
532e5c31af7Sopenharmony_ci{
533e5c31af7Sopenharmony_ci	return m_source.getGLTexture();
534e5c31af7Sopenharmony_ci}
535e5c31af7Sopenharmony_ci
536e5c31af7Sopenharmony_cideUint32 SRGBTestTexture::getGLTargetType (void) const
537e5c31af7Sopenharmony_ci{
538e5c31af7Sopenharmony_ci	switch (m_targetType)
539e5c31af7Sopenharmony_ci	{
540e5c31af7Sopenharmony_ci		case TEXTURETYPE_2D:
541e5c31af7Sopenharmony_ci		{
542e5c31af7Sopenharmony_ci			return GL_TEXTURE_2D;
543e5c31af7Sopenharmony_ci		}
544e5c31af7Sopenharmony_ci		default:
545e5c31af7Sopenharmony_ci		{
546e5c31af7Sopenharmony_ci			DE_FATAL("Error: Target type not recognised");
547e5c31af7Sopenharmony_ci			return -1;
548e5c31af7Sopenharmony_ci		}
549e5c31af7Sopenharmony_ci	}
550e5c31af7Sopenharmony_ci}
551e5c31af7Sopenharmony_ci
552e5c31af7Sopenharmony_ciSRGBDecode SRGBTestTexture::getDecode (void) const
553e5c31af7Sopenharmony_ci{
554e5c31af7Sopenharmony_ci	return m_decoding;
555e5c31af7Sopenharmony_ci}
556e5c31af7Sopenharmony_ci
557e5c31af7Sopenharmony_civoid SRGBTestTexture::upload (void)
558e5c31af7Sopenharmony_ci{
559e5c31af7Sopenharmony_ci	m_source.upload();
560e5c31af7Sopenharmony_ci}
561e5c31af7Sopenharmony_ci
562e5c31af7Sopenharmony_civoid SRGBTestTexture::setColor (void)
563e5c31af7Sopenharmony_ci{
564e5c31af7Sopenharmony_ci	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
565e5c31af7Sopenharmony_ci
566e5c31af7Sopenharmony_ci	gl.bindTexture(this->getGLTargetType(), this->getHandle());
567e5c31af7Sopenharmony_ci
568e5c31af7Sopenharmony_ci	m_source.getRefTexture().allocLevel(0);
569e5c31af7Sopenharmony_ci
570e5c31af7Sopenharmony_ci	for (int py = 0; py < m_height; py++)
571e5c31af7Sopenharmony_ci	{
572e5c31af7Sopenharmony_ci		for (int px = 0; px < m_width; px++)
573e5c31af7Sopenharmony_ci		{
574e5c31af7Sopenharmony_ci			m_source.getRefTexture().getLevel(0).setPixel(m_color, px, py);
575e5c31af7Sopenharmony_ci		}
576e5c31af7Sopenharmony_ci	}
577e5c31af7Sopenharmony_ci
578e5c31af7Sopenharmony_ci	gl.bindTexture(this->getGLTargetType(), 0);
579e5c31af7Sopenharmony_ci}
580e5c31af7Sopenharmony_ci
581e5c31af7Sopenharmony_ciclass SRGBTestProgram
582e5c31af7Sopenharmony_ci{
583e5c31af7Sopenharmony_cipublic:
584e5c31af7Sopenharmony_ci									SRGBTestProgram			(Context& context, const FragmentShaderParameters& shaderParameters);
585e5c31af7Sopenharmony_ci									~SRGBTestProgram		(void);
586e5c31af7Sopenharmony_ci
587e5c31af7Sopenharmony_ci	void							setBlendRequired		(bool blendRequired);
588e5c31af7Sopenharmony_ci	void							setToggleRequired		(bool toggleRequired);
589e5c31af7Sopenharmony_ci	void							setUniformToggle		(int location, bool toggleDecodeValue);
590e5c31af7Sopenharmony_ci
591e5c31af7Sopenharmony_ci	const std::vector<UniformData>&	getUniformDataList		(void) const;
592e5c31af7Sopenharmony_ci	int								getUniformLocation		(const std::string& name);
593e5c31af7Sopenharmony_ci	deUint32						getHandle				(void) const;
594e5c31af7Sopenharmony_ci	bool							getBlendRequired		(void) const;
595e5c31af7Sopenharmony_ci
596e5c31af7Sopenharmony_ciprivate:
597e5c31af7Sopenharmony_ci	std::string						genFunctionCall			(ShaderSamplingType samplingType, const int uniformIdx);
598e5c31af7Sopenharmony_ci	void							genFragmentShader		(void);
599e5c31af7Sopenharmony_ci
600e5c31af7Sopenharmony_ci	Context&						m_context;
601e5c31af7Sopenharmony_ci	de::MovePtr<glu::ShaderProgram>	m_program;
602e5c31af7Sopenharmony_ci	FragmentShaderParameters		m_shaderFragmentParameters;
603e5c31af7Sopenharmony_ci	std::string						m_shaderVertex;
604e5c31af7Sopenharmony_ci	std::string						m_shaderFragment;
605e5c31af7Sopenharmony_ci	std::vector<UniformData>		m_uniformDataList;
606e5c31af7Sopenharmony_ci	bool							m_blendRequired;
607e5c31af7Sopenharmony_ci	bool							m_toggleRequired;
608e5c31af7Sopenharmony_ci};
609e5c31af7Sopenharmony_ci
610e5c31af7Sopenharmony_ciSRGBTestProgram::SRGBTestProgram	(Context& context, const FragmentShaderParameters& shaderParameters)
611e5c31af7Sopenharmony_ci	: m_context						(context)
612e5c31af7Sopenharmony_ci	, m_shaderFragmentParameters	(shaderParameters)
613e5c31af7Sopenharmony_ci	, m_blendRequired				(false)
614e5c31af7Sopenharmony_ci	, m_toggleRequired				(false)
615e5c31af7Sopenharmony_ci{
616e5c31af7Sopenharmony_ci	const glw::Functions&	gl					= m_context.getRenderContext().getFunctions();
617e5c31af7Sopenharmony_ci	tcu::TestLog&			log					= m_context.getTestContext().getLog();
618e5c31af7Sopenharmony_ci	glu::ShaderProgramInfo	buildInfo;
619e5c31af7Sopenharmony_ci	const int				totalShaderStages	= 2;
620e5c31af7Sopenharmony_ci
621e5c31af7Sopenharmony_ci	// default vertex shader used in all tests
622e5c31af7Sopenharmony_ci	std::string ver(glu::isContextTypeGLCore(m_context.getRenderContext().getType()) ? "#version 450\n" : "#version 310 es\n");
623e5c31af7Sopenharmony_ci	m_shaderVertex =	ver +
624e5c31af7Sopenharmony_ci						"layout (location = 0) in mediump vec3 aPosition; \n"
625e5c31af7Sopenharmony_ci						"layout (location = 1) in mediump vec2 aTexCoord; \n"
626e5c31af7Sopenharmony_ci						"out mediump vec2 vs_aTexCoord; \n"
627e5c31af7Sopenharmony_ci						"void main () \n"
628e5c31af7Sopenharmony_ci						"{ \n"
629e5c31af7Sopenharmony_ci						"	gl_Position = vec4(aPosition, 1.0); \n"
630e5c31af7Sopenharmony_ci						"	vs_aTexCoord = aTexCoord; \n"
631e5c31af7Sopenharmony_ci						"} \n";
632e5c31af7Sopenharmony_ci
633e5c31af7Sopenharmony_ci	this->genFragmentShader();
634e5c31af7Sopenharmony_ci
635e5c31af7Sopenharmony_ci	m_program = de::MovePtr<glu::ShaderProgram>(new glu::ShaderProgram(m_context.getRenderContext(), glu::makeVtxFragSources(m_shaderVertex, m_shaderFragment)));
636e5c31af7Sopenharmony_ci
637e5c31af7Sopenharmony_ci	if (!m_program->isOk())
638e5c31af7Sopenharmony_ci	{
639e5c31af7Sopenharmony_ci		TCU_FAIL("Failed to compile shaders and link program");
640e5c31af7Sopenharmony_ci	}
641e5c31af7Sopenharmony_ci
642e5c31af7Sopenharmony_ci	glw::GLint activeUniforms, maxLen;
643e5c31af7Sopenharmony_ci	glw::GLint size, location;
644e5c31af7Sopenharmony_ci	glw::GLenum type;
645e5c31af7Sopenharmony_ci
646e5c31af7Sopenharmony_ci	gl.getProgramiv(this->getHandle(), GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLen);
647e5c31af7Sopenharmony_ci	gl.getProgramiv(this->getHandle(), GL_ACTIVE_UNIFORMS, &activeUniforms);
648e5c31af7Sopenharmony_ci
649e5c31af7Sopenharmony_ci	std::vector<glw::GLchar> uniformName(static_cast<int>(maxLen));
650e5c31af7Sopenharmony_ci	for (int idx = 0; idx < activeUniforms; idx++)
651e5c31af7Sopenharmony_ci	{
652e5c31af7Sopenharmony_ci		gl.getActiveUniform(this->getHandle(), idx, maxLen, NULL, &size, &type, &uniformName[0]);
653e5c31af7Sopenharmony_ci		location = gl.getUniformLocation(this->getHandle(), &uniformName[0]);
654e5c31af7Sopenharmony_ci
655e5c31af7Sopenharmony_ci		UniformData uniformData(location, std::string(&uniformName[0], strlen(&uniformName[0])));
656e5c31af7Sopenharmony_ci		m_uniformDataList.push_back(uniformData);
657e5c31af7Sopenharmony_ci	}
658e5c31af7Sopenharmony_ci
659e5c31af7Sopenharmony_ci	// log shader program info. Only vertex and fragment shaders included
660e5c31af7Sopenharmony_ci	buildInfo.program = m_program->getProgramInfo();
661e5c31af7Sopenharmony_ci	for (int shaderIdx = 0; shaderIdx < totalShaderStages; shaderIdx++)
662e5c31af7Sopenharmony_ci	{
663e5c31af7Sopenharmony_ci		glu::ShaderInfo shaderInfo = m_program->getShaderInfo(static_cast<glu::ShaderType>(static_cast<int>(glu::SHADERTYPE_VERTEX) + static_cast<int>(shaderIdx)), 0);
664e5c31af7Sopenharmony_ci		buildInfo.shaders.push_back(shaderInfo);
665e5c31af7Sopenharmony_ci	}
666e5c31af7Sopenharmony_ci
667e5c31af7Sopenharmony_ci	log << buildInfo;
668e5c31af7Sopenharmony_ci}
669e5c31af7Sopenharmony_ci
670e5c31af7Sopenharmony_ciSRGBTestProgram::~SRGBTestProgram (void)
671e5c31af7Sopenharmony_ci{
672e5c31af7Sopenharmony_ci	m_program	= de::MovePtr<glu::ShaderProgram>(DE_NULL);
673e5c31af7Sopenharmony_ci}
674e5c31af7Sopenharmony_ci
675e5c31af7Sopenharmony_civoid SRGBTestProgram::setBlendRequired (bool blendRequired)
676e5c31af7Sopenharmony_ci{
677e5c31af7Sopenharmony_ci	m_blendRequired = blendRequired;
678e5c31af7Sopenharmony_ci}
679e5c31af7Sopenharmony_ci
680e5c31af7Sopenharmony_civoid SRGBTestProgram::setToggleRequired (bool toggleRequired)
681e5c31af7Sopenharmony_ci{
682e5c31af7Sopenharmony_ci	m_toggleRequired = toggleRequired;
683e5c31af7Sopenharmony_ci}
684e5c31af7Sopenharmony_ci
685e5c31af7Sopenharmony_civoid SRGBTestProgram::setUniformToggle (int location, bool toggleDecodeValue)
686e5c31af7Sopenharmony_ci{
687e5c31af7Sopenharmony_ci	if ( (m_uniformDataList.empty() == false) && (location >= 0) && (location <= (int)m_uniformDataList.size()) )
688e5c31af7Sopenharmony_ci	{
689e5c31af7Sopenharmony_ci		m_uniformDataList[location].toggleDecode = toggleDecodeValue;
690e5c31af7Sopenharmony_ci	}
691e5c31af7Sopenharmony_ci	else
692e5c31af7Sopenharmony_ci	{
693e5c31af7Sopenharmony_ci		TCU_THROW(TestError, "Error: Uniform location not found. glGetActiveUniforms returned uniforms incorrectly ");
694e5c31af7Sopenharmony_ci	}
695e5c31af7Sopenharmony_ci}
696e5c31af7Sopenharmony_ci
697e5c31af7Sopenharmony_ciconst std::vector<UniformData>& SRGBTestProgram::getUniformDataList (void) const
698e5c31af7Sopenharmony_ci{
699e5c31af7Sopenharmony_ci	return m_uniformDataList;
700e5c31af7Sopenharmony_ci}
701e5c31af7Sopenharmony_ci
702e5c31af7Sopenharmony_ciint SRGBTestProgram::getUniformLocation (const std::string& name)
703e5c31af7Sopenharmony_ci{
704e5c31af7Sopenharmony_ci	for (std::size_t idx = 0; idx < m_uniformDataList.size(); idx++)
705e5c31af7Sopenharmony_ci	{
706e5c31af7Sopenharmony_ci		if (m_uniformDataList[idx].name == name)
707e5c31af7Sopenharmony_ci		{
708e5c31af7Sopenharmony_ci			return m_uniformDataList[idx].location;
709e5c31af7Sopenharmony_ci		}
710e5c31af7Sopenharmony_ci	}
711e5c31af7Sopenharmony_ci
712e5c31af7Sopenharmony_ci	TCU_THROW(TestError, "Error: If name correctly requested then glGetActiveUniforms() returned active uniform data incorrectly");
713e5c31af7Sopenharmony_ci	return -1;
714e5c31af7Sopenharmony_ci}
715e5c31af7Sopenharmony_ci
716e5c31af7Sopenharmony_ciglw::GLuint SRGBTestProgram::getHandle (void) const
717e5c31af7Sopenharmony_ci{
718e5c31af7Sopenharmony_ci	return m_program->getProgram();
719e5c31af7Sopenharmony_ci}
720e5c31af7Sopenharmony_ci
721e5c31af7Sopenharmony_cibool SRGBTestProgram::getBlendRequired (void) const
722e5c31af7Sopenharmony_ci{
723e5c31af7Sopenharmony_ci	return m_blendRequired;
724e5c31af7Sopenharmony_ci}
725e5c31af7Sopenharmony_ci
726e5c31af7Sopenharmony_cistd::string SRGBTestProgram::genFunctionCall (ShaderSamplingType samplingType, const int uniformIdx)
727e5c31af7Sopenharmony_ci{
728e5c31af7Sopenharmony_ci	std::ostringstream functionCall;
729e5c31af7Sopenharmony_ci
730e5c31af7Sopenharmony_ci	functionCall << "	mediump vec4 texelColor" << uniformIdx << " = ";
731e5c31af7Sopenharmony_ci
732e5c31af7Sopenharmony_ci	switch (samplingType)
733e5c31af7Sopenharmony_ci		{
734e5c31af7Sopenharmony_ci			case TEXTURESAMPLING_TEXTURE:
735e5c31af7Sopenharmony_ci			{
736e5c31af7Sopenharmony_ci				functionCall << "texture(uTexture" << uniformIdx << ", vs_aTexCoord); \n";
737e5c31af7Sopenharmony_ci				break;
738e5c31af7Sopenharmony_ci			}
739e5c31af7Sopenharmony_ci			case TEXTURESAMPLING_TEXTURE_LOD:
740e5c31af7Sopenharmony_ci			{
741e5c31af7Sopenharmony_ci				functionCall << "textureLod(uTexture" << uniformIdx << ", vs_aTexCoord, 0.0); \n";
742e5c31af7Sopenharmony_ci				break;
743e5c31af7Sopenharmony_ci			}
744e5c31af7Sopenharmony_ci			case TEXTURESAMPLING_TEXTURE_GRAD:
745e5c31af7Sopenharmony_ci			{
746e5c31af7Sopenharmony_ci				functionCall << "textureGrad(uTexture" << uniformIdx << ", vs_aTexCoord, vec2(0.0, 0.0), vec2(0.0, 0.0)); \n";
747e5c31af7Sopenharmony_ci				break;
748e5c31af7Sopenharmony_ci			}
749e5c31af7Sopenharmony_ci			case TEXTURESAMPLING_TEXTURE_OFFSET:
750e5c31af7Sopenharmony_ci			{
751e5c31af7Sopenharmony_ci				functionCall << "textureOffset(uTexture" << uniformIdx << ", vs_aTexCoord, ivec2(0.0, 0.0)); \n";
752e5c31af7Sopenharmony_ci				break;
753e5c31af7Sopenharmony_ci			}
754e5c31af7Sopenharmony_ci			case TEXTURESAMPLING_TEXTURE_PROJ:
755e5c31af7Sopenharmony_ci			{
756e5c31af7Sopenharmony_ci				functionCall << "textureProj(uTexture" << uniformIdx << ", vec3(vs_aTexCoord, 1.0)); \n";
757e5c31af7Sopenharmony_ci				break;
758e5c31af7Sopenharmony_ci			}
759e5c31af7Sopenharmony_ci			case TEXTURESAMPLING_TEXELFETCH:
760e5c31af7Sopenharmony_ci			{
761e5c31af7Sopenharmony_ci				functionCall << "texelFetch(uTexture" << uniformIdx << ", ivec2(vs_aTexCoord), 0); \n";
762e5c31af7Sopenharmony_ci				break;
763e5c31af7Sopenharmony_ci			}
764e5c31af7Sopenharmony_ci			case TEXTURESAMPLING_TEXELFETCH_OFFSET:
765e5c31af7Sopenharmony_ci			{
766e5c31af7Sopenharmony_ci				functionCall << "texelFetchOffset(uTexture" << uniformIdx << ", ivec2(vs_aTexCoord), 0, ivec2(0.0, 0.0)); \n";
767e5c31af7Sopenharmony_ci				break;
768e5c31af7Sopenharmony_ci			}
769e5c31af7Sopenharmony_ci			default:
770e5c31af7Sopenharmony_ci			{
771e5c31af7Sopenharmony_ci				DE_FATAL("Error: Sampling type not recognised");
772e5c31af7Sopenharmony_ci			}
773e5c31af7Sopenharmony_ci		}
774e5c31af7Sopenharmony_ci
775e5c31af7Sopenharmony_ci	return functionCall.str();
776e5c31af7Sopenharmony_ci}
777e5c31af7Sopenharmony_ci
778e5c31af7Sopenharmony_civoid SRGBTestProgram::genFragmentShader (void)
779e5c31af7Sopenharmony_ci{
780e5c31af7Sopenharmony_ci	std::ostringstream source;
781e5c31af7Sopenharmony_ci	std::ostringstream sampleTexture;
782e5c31af7Sopenharmony_ci	std::ostringstream functionParameters;
783e5c31af7Sopenharmony_ci	std::ostringstream shaderOutputs;
784e5c31af7Sopenharmony_ci
785e5c31af7Sopenharmony_ci	// if comparison function is present resulting shader requires precisely one output
786e5c31af7Sopenharmony_ci	DE_ASSERT( !(m_shaderFragmentParameters.hasFunction && (static_cast<int>(m_shaderFragmentParameters.outputTotal) != static_cast<int>(SHADEROUTPUTS_ONE))) );
787e5c31af7Sopenharmony_ci
788e5c31af7Sopenharmony_ci	// function parameters must equal the number of uniforms i.e. textures passed into the function
789e5c31af7Sopenharmony_ci	DE_ASSERT( !(m_shaderFragmentParameters.hasFunction && (static_cast<int>(m_shaderFragmentParameters.uniformTotal) != static_cast<int>(m_shaderFragmentParameters.functionParameters))) );
790e5c31af7Sopenharmony_ci
791e5c31af7Sopenharmony_ci	// fragment shader cannot contain more outputs than the number of texture uniforms
792e5c31af7Sopenharmony_ci	DE_ASSERT( !(static_cast<int>(m_shaderFragmentParameters.outputTotal) > static_cast<int>(m_shaderFragmentParameters.uniformTotal)) ) ;
793e5c31af7Sopenharmony_ci
794e5c31af7Sopenharmony_ci	source << (glu::isContextTypeGLCore(m_context.getRenderContext().getType()) ? "#version 450\n" : "#version 310 es\n")
795e5c31af7Sopenharmony_ci		<< "in mediump vec2 vs_aTexCoord; \n";
796e5c31af7Sopenharmony_ci
797e5c31af7Sopenharmony_ci	for (int output = 0; output < m_shaderFragmentParameters.outputTotal; output++)
798e5c31af7Sopenharmony_ci	{
799e5c31af7Sopenharmony_ci		source << "layout (location = " << output << ") out mediump vec4 fs_aColor" << output << "; \n";
800e5c31af7Sopenharmony_ci	}
801e5c31af7Sopenharmony_ci
802e5c31af7Sopenharmony_ci	for (int uniform = 0; uniform < m_shaderFragmentParameters.uniformTotal; uniform++)
803e5c31af7Sopenharmony_ci	{
804e5c31af7Sopenharmony_ci		source << "uniform sampler2D uTexture" << uniform << "; \n";
805e5c31af7Sopenharmony_ci	}
806e5c31af7Sopenharmony_ci
807e5c31af7Sopenharmony_ci	if (m_shaderFragmentParameters.hasFunction == true)
808e5c31af7Sopenharmony_ci	{
809e5c31af7Sopenharmony_ci		source << m_shaderFragmentParameters.functionImplementation;
810e5c31af7Sopenharmony_ci	}
811e5c31af7Sopenharmony_ci
812e5c31af7Sopenharmony_ci	source << "void main () \n"
813e5c31af7Sopenharmony_ci		<< "{ \n";
814e5c31af7Sopenharmony_ci
815e5c31af7Sopenharmony_ci	for (int uniformIdx = 0; uniformIdx < m_shaderFragmentParameters.uniformTotal; uniformIdx++)
816e5c31af7Sopenharmony_ci	{
817e5c31af7Sopenharmony_ci		source << this->genFunctionCall(m_shaderFragmentParameters.samplingType, uniformIdx);
818e5c31af7Sopenharmony_ci	}
819e5c31af7Sopenharmony_ci
820e5c31af7Sopenharmony_ci	if (m_shaderFragmentParameters.hasFunction == true)
821e5c31af7Sopenharmony_ci	{
822e5c31af7Sopenharmony_ci		switch ( static_cast<FunctionParameters>(m_shaderFragmentParameters.functionParameters) )
823e5c31af7Sopenharmony_ci		{
824e5c31af7Sopenharmony_ci			case FUNCTIONPARAMETERS_ONE:
825e5c31af7Sopenharmony_ci			{
826e5c31af7Sopenharmony_ci				functionParameters << "(texelColor0)";
827e5c31af7Sopenharmony_ci				break;
828e5c31af7Sopenharmony_ci			}
829e5c31af7Sopenharmony_ci			case FUNCTIONPARAMETERS_TWO:
830e5c31af7Sopenharmony_ci			{
831e5c31af7Sopenharmony_ci				functionParameters << "(texelColor0, texelColor1)";
832e5c31af7Sopenharmony_ci				break;
833e5c31af7Sopenharmony_ci			}
834e5c31af7Sopenharmony_ci			default:
835e5c31af7Sopenharmony_ci			{
836e5c31af7Sopenharmony_ci				DE_FATAL("Error: Number of comparison function parameters invalid");
837e5c31af7Sopenharmony_ci			}
838e5c31af7Sopenharmony_ci		}
839e5c31af7Sopenharmony_ci
840e5c31af7Sopenharmony_ci		shaderOutputs << "	fs_aColor0 = " << m_shaderFragmentParameters.functionName << functionParameters.str() << "; \n";
841e5c31af7Sopenharmony_ci	}
842e5c31af7Sopenharmony_ci	else
843e5c31af7Sopenharmony_ci	{
844e5c31af7Sopenharmony_ci		for (int output = 0; output < m_shaderFragmentParameters.outputTotal; output++)
845e5c31af7Sopenharmony_ci		{
846e5c31af7Sopenharmony_ci			shaderOutputs << "	fs_aColor" << output << " = texelColor" << output << "; \n";
847e5c31af7Sopenharmony_ci		}
848e5c31af7Sopenharmony_ci	}
849e5c31af7Sopenharmony_ci
850e5c31af7Sopenharmony_ci	source << shaderOutputs.str();
851e5c31af7Sopenharmony_ci	source << "} \n";
852e5c31af7Sopenharmony_ci
853e5c31af7Sopenharmony_ci	m_shaderFragment = source.str();
854e5c31af7Sopenharmony_ci}
855e5c31af7Sopenharmony_ci
856e5c31af7Sopenharmony_ciclass SRGBTestCase : public TestCase
857e5c31af7Sopenharmony_ci{
858e5c31af7Sopenharmony_cipublic:
859e5c31af7Sopenharmony_ci							SRGBTestCase					(Context& context, const char* name, const char* description, const tcu::TextureFormat internalFormat);
860e5c31af7Sopenharmony_ci							~SRGBTestCase					(void);
861e5c31af7Sopenharmony_ci
862e5c31af7Sopenharmony_ci	void					init							(void);
863e5c31af7Sopenharmony_ci	void					deinit							(void);
864e5c31af7Sopenharmony_ci	virtual IterateResult	iterate							(void);
865e5c31af7Sopenharmony_ci
866e5c31af7Sopenharmony_ci	void					setSamplingGroup				(const ShaderSamplingGroup samplingGroup);
867e5c31af7Sopenharmony_ci	void					setSamplingLocations			(const int px, const int py);
868e5c31af7Sopenharmony_ci	void					setUniformToggle				(const int programIdx, const std::string& uniformName, bool toggleDecode);
869e5c31af7Sopenharmony_ci
870e5c31af7Sopenharmony_ci	void					addTexture						(const glu::TextureTestUtil::TextureType	targetType,
871e5c31af7Sopenharmony_ci															 const int									width,
872e5c31af7Sopenharmony_ci															 const int									height,
873e5c31af7Sopenharmony_ci															 const tcu::Vec4							color,
874e5c31af7Sopenharmony_ci															 const tcu::Sampler::WrapMode				wrapS,
875e5c31af7Sopenharmony_ci															 const tcu::Sampler::WrapMode				wrapT,
876e5c31af7Sopenharmony_ci															 const tcu::Sampler::FilterMode				minFilter,
877e5c31af7Sopenharmony_ci															 const tcu::Sampler::FilterMode				magFilter,
878e5c31af7Sopenharmony_ci															 const SRGBDecode							decoding);
879e5c31af7Sopenharmony_ci	void					addSampler						(const tcu::Sampler::WrapMode	wrapS,
880e5c31af7Sopenharmony_ci															 const tcu::Sampler::WrapMode	wrapT,
881e5c31af7Sopenharmony_ci															 const tcu::Sampler::FilterMode	minFilter,
882e5c31af7Sopenharmony_ci															 const tcu::Sampler::FilterMode	magFilter,
883e5c31af7Sopenharmony_ci															 const SRGBDecode				decoding);
884e5c31af7Sopenharmony_ci	void					addShaderProgram				(const FragmentShaderParameters& shaderParameters);
885e5c31af7Sopenharmony_ci
886e5c31af7Sopenharmony_ci	void					genShaderPrograms				(ShaderSamplingType samplingType);
887e5c31af7Sopenharmony_ci	void					deleteShaderPrograms			(void);
888e5c31af7Sopenharmony_ci
889e5c31af7Sopenharmony_ci	void					readResultTextures				(void);
890e5c31af7Sopenharmony_ci	void					storeResultPixels				(std::vector<tcu::Vec4>& resultPixelData);
891e5c31af7Sopenharmony_ci
892e5c31af7Sopenharmony_ci	void					toggleDecode					(const std::vector<UniformData>& uniformDataList);
893e5c31af7Sopenharmony_ci	void					bindSamplerToTexture			(const int samplerIdx, const int textureIdx, const deUint32 textureUnit);
894e5c31af7Sopenharmony_ci	void					activateSampler					(const int samplerIdx, const bool active);
895e5c31af7Sopenharmony_ci	void					logColor						(const std::string& colorLogMessage, int colorIdx, tcu::Vec4 color) const;
896e5c31af7Sopenharmony_ci	tcu::Vec4				formatReferenceColor			(tcu::Vec4 referenceColor);
897e5c31af7Sopenharmony_ci
898e5c31af7Sopenharmony_ci	// render function has a default implentation. Can be overriden for special cases
899e5c31af7Sopenharmony_ci	virtual void			render							(void);
900e5c31af7Sopenharmony_ci
901e5c31af7Sopenharmony_ci	// following functions must be overidden to perform individual test cases
902e5c31af7Sopenharmony_ci	virtual void			setupTest						(void) = 0;
903e5c31af7Sopenharmony_ci	virtual bool			verifyResult					(void) = 0;
904e5c31af7Sopenharmony_ci
905e5c31af7Sopenharmony_ciprotected:
906e5c31af7Sopenharmony_ci	de::MovePtr<glu::Framebuffer>			m_framebuffer;
907e5c31af7Sopenharmony_ci	std::vector<SRGBTestTexture*>			m_textureSourceList;
908e5c31af7Sopenharmony_ci	std::vector<SRGBTestSampler*>			m_samplerList;
909e5c31af7Sopenharmony_ci	std::vector<glw::GLuint>				m_renderBufferList;
910e5c31af7Sopenharmony_ci	const tcu::Vec4							m_epsilonError;
911e5c31af7Sopenharmony_ci	std::vector<tcu::TextureLevel>			m_textureResultList;
912e5c31af7Sopenharmony_ci	int										m_resultOutputTotal;
913e5c31af7Sopenharmony_ci	tcu::TextureFormat						m_resultTextureFormat;
914e5c31af7Sopenharmony_ci	glw::GLuint								m_vaoID;
915e5c31af7Sopenharmony_ci	glw::GLuint								m_vertexDataID;
916e5c31af7Sopenharmony_ci	std::vector<FragmentShaderParameters>	m_shaderParametersList;
917e5c31af7Sopenharmony_ci	std::vector<SRGBTestProgram*>			m_shaderProgramList;
918e5c31af7Sopenharmony_ci	ShaderSamplingGroup						m_samplingGroup;
919e5c31af7Sopenharmony_ci	int										m_px;
920e5c31af7Sopenharmony_ci	int										m_py;
921e5c31af7Sopenharmony_ci	const tcu::TextureFormat				m_internalFormat;
922e5c31af7Sopenharmony_ci
923e5c31af7Sopenharmony_ciprivate:
924e5c31af7Sopenharmony_ci	void			uploadTextures	(void);
925e5c31af7Sopenharmony_ci	void			initFrameBuffer	(void);
926e5c31af7Sopenharmony_ci	void			initVertexData	(void);
927e5c31af7Sopenharmony_ci
928e5c31af7Sopenharmony_ci					SRGBTestCase	(const SRGBTestCase&);
929e5c31af7Sopenharmony_ci	SRGBTestCase&	operator=		(const SRGBTestCase&);
930e5c31af7Sopenharmony_ci};
931e5c31af7Sopenharmony_ci
932e5c31af7Sopenharmony_ciSRGBTestCase::SRGBTestCase	(Context& context, const char* name, const char* description, const tcu::TextureFormat internalFormat)
933e5c31af7Sopenharmony_ci	: TestCase				(context, name, description)
934e5c31af7Sopenharmony_ci	, m_epsilonError		(EpsilonError::CPU)
935e5c31af7Sopenharmony_ci	, m_resultOutputTotal	(0)
936e5c31af7Sopenharmony_ci	, m_resultTextureFormat	(tcu::TextureFormat(tcu::TextureFormat::sRGBA, tcu::TextureFormat::UNORM_INT8))
937e5c31af7Sopenharmony_ci	, m_vaoID				(0)
938e5c31af7Sopenharmony_ci	, m_vertexDataID		(0)
939e5c31af7Sopenharmony_ci	, m_samplingGroup		(SHADERSAMPLINGGROUP_TEXTURE)
940e5c31af7Sopenharmony_ci	, m_px					(0)
941e5c31af7Sopenharmony_ci	, m_py					(0)
942e5c31af7Sopenharmony_ci	, m_internalFormat		(internalFormat)
943e5c31af7Sopenharmony_ci{
944e5c31af7Sopenharmony_ci}
945e5c31af7Sopenharmony_ci
946e5c31af7Sopenharmony_ciSRGBTestCase::~SRGBTestCase (void)
947e5c31af7Sopenharmony_ci{
948e5c31af7Sopenharmony_ci	deinit();
949e5c31af7Sopenharmony_ci}
950e5c31af7Sopenharmony_ci
951e5c31af7Sopenharmony_civoid SRGBTestCase::init (void)
952e5c31af7Sopenharmony_ci{
953e5c31af7Sopenharmony_ci	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
954e5c31af7Sopenharmony_ci
955e5c31af7Sopenharmony_ci	// extension requirements for test
956e5c31af7Sopenharmony_ci	if ( (glu::getInternalFormat(m_internalFormat) == GL_SRGB8_ALPHA8) && !m_context.getContextInfo().isExtensionSupported("GL_EXT_texture_sRGB_decode") )
957e5c31af7Sopenharmony_ci	{
958e5c31af7Sopenharmony_ci		throw tcu::NotSupportedError("Test requires GL_EXT_texture_sRGB_decode extension");
959e5c31af7Sopenharmony_ci	}
960e5c31af7Sopenharmony_ci
961e5c31af7Sopenharmony_ci	if ( (glu::getInternalFormat(m_internalFormat) == GL_SRG8_EXT) && !(m_context.getContextInfo().isExtensionSupported("GL_EXT_texture_sRGB_RG8")) )
962e5c31af7Sopenharmony_ci	{
963e5c31af7Sopenharmony_ci		throw tcu::NotSupportedError("Test requires GL_EXT_texture_sRGB_RG8 extension");
964e5c31af7Sopenharmony_ci	}
965e5c31af7Sopenharmony_ci
966e5c31af7Sopenharmony_ci	if ( (glu::getInternalFormat(m_internalFormat) == GL_SR8_EXT) && !(m_context.getContextInfo().isExtensionSupported("GL_EXT_texture_sRGB_R8")) )
967e5c31af7Sopenharmony_ci	{
968e5c31af7Sopenharmony_ci		throw tcu::NotSupportedError("Test requires GL_EXT_texture_sRGB_R8 extension");
969e5c31af7Sopenharmony_ci	}
970e5c31af7Sopenharmony_ci
971e5c31af7Sopenharmony_ci	m_framebuffer = de::MovePtr<glu::Framebuffer>(new glu::Framebuffer(m_context.getRenderContext()));
972e5c31af7Sopenharmony_ci
973e5c31af7Sopenharmony_ci	if (glu::isContextTypeGLCore(m_context.getRenderContext().getType()))
974e5c31af7Sopenharmony_ci	{
975e5c31af7Sopenharmony_ci		gl.enable(GL_FRAMEBUFFER_SRGB);
976e5c31af7Sopenharmony_ci	}
977e5c31af7Sopenharmony_ci}
978e5c31af7Sopenharmony_ci
979e5c31af7Sopenharmony_civoid SRGBTestCase::deinit (void)
980e5c31af7Sopenharmony_ci{
981e5c31af7Sopenharmony_ci	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
982e5c31af7Sopenharmony_ci
983e5c31af7Sopenharmony_ci	m_framebuffer	= de::MovePtr<glu::Framebuffer>(DE_NULL);
984e5c31af7Sopenharmony_ci
985e5c31af7Sopenharmony_ci	for (std::size_t renderBufferIdx = 0; renderBufferIdx < m_renderBufferList.size(); renderBufferIdx++)
986e5c31af7Sopenharmony_ci	{
987e5c31af7Sopenharmony_ci		gl.deleteRenderbuffers(1, &m_renderBufferList[renderBufferIdx]);
988e5c31af7Sopenharmony_ci	}
989e5c31af7Sopenharmony_ci	m_renderBufferList.clear();
990e5c31af7Sopenharmony_ci
991e5c31af7Sopenharmony_ci	if (glu::isContextTypeGLCore(m_context.getRenderContext().getType()))
992e5c31af7Sopenharmony_ci	{
993e5c31af7Sopenharmony_ci		gl.disable(GL_FRAMEBUFFER_SRGB);
994e5c31af7Sopenharmony_ci	}
995e5c31af7Sopenharmony_ci
996e5c31af7Sopenharmony_ci	for (std::size_t textureSourceIdx = 0; textureSourceIdx < m_textureSourceList.size(); textureSourceIdx++)
997e5c31af7Sopenharmony_ci	{
998e5c31af7Sopenharmony_ci		delete m_textureSourceList[textureSourceIdx];
999e5c31af7Sopenharmony_ci	}
1000e5c31af7Sopenharmony_ci	m_textureSourceList.clear();
1001e5c31af7Sopenharmony_ci
1002e5c31af7Sopenharmony_ci	for (std::size_t samplerIdx = 0; samplerIdx < m_samplerList.size(); samplerIdx++)
1003e5c31af7Sopenharmony_ci	{
1004e5c31af7Sopenharmony_ci		delete m_samplerList[samplerIdx];
1005e5c31af7Sopenharmony_ci	}
1006e5c31af7Sopenharmony_ci	m_samplerList.clear();
1007e5c31af7Sopenharmony_ci
1008e5c31af7Sopenharmony_ci	if (m_vaoID != 0)
1009e5c31af7Sopenharmony_ci	{
1010e5c31af7Sopenharmony_ci		gl.deleteVertexArrays(1, &m_vaoID);
1011e5c31af7Sopenharmony_ci		m_vaoID = 0;
1012e5c31af7Sopenharmony_ci	}
1013e5c31af7Sopenharmony_ci
1014e5c31af7Sopenharmony_ci	if (m_vertexDataID != 0)
1015e5c31af7Sopenharmony_ci	{
1016e5c31af7Sopenharmony_ci		gl.deleteBuffers(1, &m_vertexDataID);
1017e5c31af7Sopenharmony_ci		m_vertexDataID = 0;
1018e5c31af7Sopenharmony_ci	}
1019e5c31af7Sopenharmony_ci}
1020e5c31af7Sopenharmony_ci
1021e5c31af7Sopenharmony_ciSRGBTestCase::IterateResult SRGBTestCase::iterate (void)
1022e5c31af7Sopenharmony_ci{
1023e5c31af7Sopenharmony_ci	bool	result;
1024e5c31af7Sopenharmony_ci	int		startIdx	= -1;
1025e5c31af7Sopenharmony_ci	int		endIdx		= -1;
1026e5c31af7Sopenharmony_ci
1027e5c31af7Sopenharmony_ci	this->setupTest();
1028e5c31af7Sopenharmony_ci
1029e5c31af7Sopenharmony_ci	if (m_samplingGroup == SHADERSAMPLINGGROUP_TEXTURE)
1030e5c31af7Sopenharmony_ci	{
1031e5c31af7Sopenharmony_ci		startIdx	= static_cast<int>(TEXTURESAMPLING_TEXTURE_START);
1032e5c31af7Sopenharmony_ci		endIdx		= static_cast<int>(TEXTURESAMPLING_TEXTURE_END);
1033e5c31af7Sopenharmony_ci	}
1034e5c31af7Sopenharmony_ci	else if (m_samplingGroup == SHADERSAMPLINGGROUP_TEXEL_FETCH)
1035e5c31af7Sopenharmony_ci	{
1036e5c31af7Sopenharmony_ci		startIdx	= static_cast<int>(TEXTURESAMPLING_TEXELFETCH_START);
1037e5c31af7Sopenharmony_ci		endIdx		= static_cast<int>(TEXTURESAMPLING_TEXELFETCH_END);
1038e5c31af7Sopenharmony_ci	}
1039e5c31af7Sopenharmony_ci	else
1040e5c31af7Sopenharmony_ci	{
1041e5c31af7Sopenharmony_ci		DE_FATAL("Error: Sampling group not defined");
1042e5c31af7Sopenharmony_ci	}
1043e5c31af7Sopenharmony_ci
1044e5c31af7Sopenharmony_ci	this->initVertexData();
1045e5c31af7Sopenharmony_ci	this->initFrameBuffer();
1046e5c31af7Sopenharmony_ci
1047e5c31af7Sopenharmony_ci	// loop through all sampling types in the required sampling group, performing individual tests for each
1048e5c31af7Sopenharmony_ci	for (int samplingTypeIdx = startIdx; samplingTypeIdx < endIdx; samplingTypeIdx++)
1049e5c31af7Sopenharmony_ci	{
1050e5c31af7Sopenharmony_ci		this->genShaderPrograms(static_cast<ShaderSamplingType>(samplingTypeIdx));
1051e5c31af7Sopenharmony_ci		this->uploadTextures();
1052e5c31af7Sopenharmony_ci		this->render();
1053e5c31af7Sopenharmony_ci
1054e5c31af7Sopenharmony_ci		result = this->verifyResult();
1055e5c31af7Sopenharmony_ci
1056e5c31af7Sopenharmony_ci		this->deleteShaderPrograms();
1057e5c31af7Sopenharmony_ci
1058e5c31af7Sopenharmony_ci		if (result == true)
1059e5c31af7Sopenharmony_ci		{
1060e5c31af7Sopenharmony_ci			m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1061e5c31af7Sopenharmony_ci		}
1062e5c31af7Sopenharmony_ci		else
1063e5c31af7Sopenharmony_ci		{
1064e5c31af7Sopenharmony_ci			m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Result verification failed");
1065e5c31af7Sopenharmony_ci			return STOP;
1066e5c31af7Sopenharmony_ci		}
1067e5c31af7Sopenharmony_ci	}
1068e5c31af7Sopenharmony_ci
1069e5c31af7Sopenharmony_ci	return STOP;
1070e5c31af7Sopenharmony_ci}
1071e5c31af7Sopenharmony_ci
1072e5c31af7Sopenharmony_civoid SRGBTestCase::setSamplingGroup (const ShaderSamplingGroup samplingGroup)
1073e5c31af7Sopenharmony_ci{
1074e5c31af7Sopenharmony_ci	m_samplingGroup = samplingGroup;
1075e5c31af7Sopenharmony_ci}
1076e5c31af7Sopenharmony_ci
1077e5c31af7Sopenharmony_civoid SRGBTestCase::setSamplingLocations (const int px, const int py)
1078e5c31af7Sopenharmony_ci{
1079e5c31af7Sopenharmony_ci	m_px = px;
1080e5c31af7Sopenharmony_ci	m_py = py;
1081e5c31af7Sopenharmony_ci}
1082e5c31af7Sopenharmony_ci
1083e5c31af7Sopenharmony_civoid SRGBTestCase::addTexture (	const glu::TextureTestUtil::TextureType	targetType,
1084e5c31af7Sopenharmony_ci								const int								width,
1085e5c31af7Sopenharmony_ci								const int								height,
1086e5c31af7Sopenharmony_ci								const tcu::Vec4							color,
1087e5c31af7Sopenharmony_ci								const tcu::Sampler::WrapMode			wrapS,
1088e5c31af7Sopenharmony_ci								const tcu::Sampler::WrapMode			wrapT,
1089e5c31af7Sopenharmony_ci								const tcu::Sampler::FilterMode			minFilter,
1090e5c31af7Sopenharmony_ci								const tcu::Sampler::FilterMode			magFilter,
1091e5c31af7Sopenharmony_ci								const SRGBDecode						decoding)
1092e5c31af7Sopenharmony_ci{
1093e5c31af7Sopenharmony_ci	SRGBTestTexture* texture = new SRGBTestTexture(m_context, targetType, m_internalFormat, width, height, color, wrapS, wrapT, minFilter, magFilter, decoding);
1094e5c31af7Sopenharmony_ci	m_textureSourceList.push_back(texture);
1095e5c31af7Sopenharmony_ci}
1096e5c31af7Sopenharmony_ci
1097e5c31af7Sopenharmony_civoid SRGBTestCase::addSampler (	const tcu::Sampler::WrapMode	wrapS,
1098e5c31af7Sopenharmony_ci								const tcu::Sampler::WrapMode	wrapT,
1099e5c31af7Sopenharmony_ci								const tcu::Sampler::FilterMode	minFilter,
1100e5c31af7Sopenharmony_ci								const tcu::Sampler::FilterMode	magFilter,
1101e5c31af7Sopenharmony_ci								const SRGBDecode				decoding)
1102e5c31af7Sopenharmony_ci{
1103e5c31af7Sopenharmony_ci	SRGBTestSampler *sampler = new SRGBTestSampler(m_context, wrapS, wrapT, minFilter, magFilter, decoding);
1104e5c31af7Sopenharmony_ci	m_samplerList.push_back(sampler);
1105e5c31af7Sopenharmony_ci}
1106e5c31af7Sopenharmony_ci
1107e5c31af7Sopenharmony_civoid SRGBTestCase::addShaderProgram (const FragmentShaderParameters& shaderParameters)
1108e5c31af7Sopenharmony_ci{
1109e5c31af7Sopenharmony_ci	m_shaderParametersList.push_back(shaderParameters);
1110e5c31af7Sopenharmony_ci	m_resultOutputTotal = shaderParameters.outputTotal;
1111e5c31af7Sopenharmony_ci}
1112e5c31af7Sopenharmony_ci
1113e5c31af7Sopenharmony_civoid SRGBTestCase::genShaderPrograms (ShaderSamplingType samplingType)
1114e5c31af7Sopenharmony_ci{
1115e5c31af7Sopenharmony_ci	for (int shaderParamsIdx = 0; shaderParamsIdx < (int)m_shaderParametersList.size(); shaderParamsIdx++)
1116e5c31af7Sopenharmony_ci	{
1117e5c31af7Sopenharmony_ci		m_shaderParametersList[shaderParamsIdx].samplingType = samplingType;
1118e5c31af7Sopenharmony_ci		SRGBTestProgram* shaderProgram = new SRGBTestProgram(m_context, m_shaderParametersList[shaderParamsIdx]);
1119e5c31af7Sopenharmony_ci
1120e5c31af7Sopenharmony_ci		if (m_shaderParametersList[shaderParamsIdx].blendRequired == BLENDING_REQUIRED)
1121e5c31af7Sopenharmony_ci		{
1122e5c31af7Sopenharmony_ci			shaderProgram->setBlendRequired(true);
1123e5c31af7Sopenharmony_ci		}
1124e5c31af7Sopenharmony_ci
1125e5c31af7Sopenharmony_ci		if (m_shaderParametersList[shaderParamsIdx].toggleRequired == TOGGLING_REQUIRED)
1126e5c31af7Sopenharmony_ci		{
1127e5c31af7Sopenharmony_ci			shaderProgram->setToggleRequired(true);
1128e5c31af7Sopenharmony_ci			std::vector<std::string> uniformsToToggle = m_shaderParametersList[shaderParamsIdx].uniformsToToggle;
1129e5c31af7Sopenharmony_ci
1130e5c31af7Sopenharmony_ci			for (int uniformNameIdx = 0; uniformNameIdx < (int)uniformsToToggle.size(); uniformNameIdx++)
1131e5c31af7Sopenharmony_ci			{
1132e5c31af7Sopenharmony_ci				shaderProgram->setUniformToggle(shaderProgram->getUniformLocation(uniformsToToggle[uniformNameIdx]), true);
1133e5c31af7Sopenharmony_ci			}
1134e5c31af7Sopenharmony_ci		}
1135e5c31af7Sopenharmony_ci
1136e5c31af7Sopenharmony_ci		m_shaderProgramList.push_back(shaderProgram);
1137e5c31af7Sopenharmony_ci	}
1138e5c31af7Sopenharmony_ci}
1139e5c31af7Sopenharmony_ci
1140e5c31af7Sopenharmony_civoid SRGBTestCase::deleteShaderPrograms (void)
1141e5c31af7Sopenharmony_ci{
1142e5c31af7Sopenharmony_ci	for (std::size_t idx = 0; idx < m_shaderProgramList.size(); idx++)
1143e5c31af7Sopenharmony_ci	{
1144e5c31af7Sopenharmony_ci		delete m_shaderProgramList[idx];
1145e5c31af7Sopenharmony_ci	}
1146e5c31af7Sopenharmony_ci	m_shaderProgramList.clear();
1147e5c31af7Sopenharmony_ci}
1148e5c31af7Sopenharmony_ci
1149e5c31af7Sopenharmony_civoid SRGBTestCase::readResultTextures (void)
1150e5c31af7Sopenharmony_ci{
1151e5c31af7Sopenharmony_ci	const glw::Functions&	gl		= m_context.getRenderContext().getFunctions();
1152e5c31af7Sopenharmony_ci	int						width	= m_context.getRenderContext().getRenderTarget().getWidth();
1153e5c31af7Sopenharmony_ci	int						height	= m_context.getRenderContext().getRenderTarget().getHeight();
1154e5c31af7Sopenharmony_ci
1155e5c31af7Sopenharmony_ci	gl.bindFramebuffer(GL_FRAMEBUFFER, **m_framebuffer);
1156e5c31af7Sopenharmony_ci
1157e5c31af7Sopenharmony_ci	m_textureResultList.resize(m_renderBufferList.size());
1158e5c31af7Sopenharmony_ci
1159e5c31af7Sopenharmony_ci	for (std::size_t renderBufferIdx = 0; renderBufferIdx < m_renderBufferList.size(); renderBufferIdx++)
1160e5c31af7Sopenharmony_ci	{
1161e5c31af7Sopenharmony_ci		gl.readBuffer(GL_COLOR_ATTACHMENT0 + (glw::GLenum)renderBufferIdx);
1162e5c31af7Sopenharmony_ci		m_textureResultList[renderBufferIdx].setStorage(m_resultTextureFormat, width, height);
1163e5c31af7Sopenharmony_ci		glu::readPixels(m_context.getRenderContext(), 0, 0, m_textureResultList[renderBufferIdx].getAccess());
1164e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels()");
1165e5c31af7Sopenharmony_ci	}
1166e5c31af7Sopenharmony_ci
1167e5c31af7Sopenharmony_ci	gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
1168e5c31af7Sopenharmony_ci}
1169e5c31af7Sopenharmony_ci
1170e5c31af7Sopenharmony_civoid SRGBTestCase::storeResultPixels (std::vector<tcu::Vec4>& resultPixelData)
1171e5c31af7Sopenharmony_ci{
1172e5c31af7Sopenharmony_ci	tcu::TestLog&		log			= m_context.getTestContext().getLog();
1173e5c31af7Sopenharmony_ci	std::ostringstream	message;
1174e5c31af7Sopenharmony_ci	int					width		= m_context.getRenderContext().getRenderTarget().getWidth();
1175e5c31af7Sopenharmony_ci	int					height		= m_context.getRenderContext().getRenderTarget().getHeight();
1176e5c31af7Sopenharmony_ci
1177e5c31af7Sopenharmony_ci	// ensure result sampling coordinates are within range of the result color attachment
1178e5c31af7Sopenharmony_ci	DE_ASSERT((m_px >= 0) && (m_px < width));
1179e5c31af7Sopenharmony_ci	DE_ASSERT((m_py >= 0) && (m_py < height));
1180e5c31af7Sopenharmony_ci	DE_UNREF(width && height);
1181e5c31af7Sopenharmony_ci
1182e5c31af7Sopenharmony_ci	for (int idx = 0; idx < (int)m_textureResultList.size(); idx++)
1183e5c31af7Sopenharmony_ci	{
1184e5c31af7Sopenharmony_ci		resultPixelData.push_back(m_textureResultList[idx].getAccess().getPixel(m_px, m_py));
1185e5c31af7Sopenharmony_ci		this->logColor(std::string("Result color: "), idx, resultPixelData[idx]);
1186e5c31af7Sopenharmony_ci	}
1187e5c31af7Sopenharmony_ci
1188e5c31af7Sopenharmony_ci	// log error rate (threshold)
1189e5c31af7Sopenharmony_ci	message << m_epsilonError;
1190e5c31af7Sopenharmony_ci	log << tcu::TestLog::Message << std::string("Epsilon error: ") << message.str() << tcu::TestLog::EndMessage;
1191e5c31af7Sopenharmony_ci}
1192e5c31af7Sopenharmony_ci
1193e5c31af7Sopenharmony_civoid SRGBTestCase::toggleDecode (const std::vector<UniformData>& uniformDataList)
1194e5c31af7Sopenharmony_ci{
1195e5c31af7Sopenharmony_ci	DE_ASSERT( uniformDataList.size() <= m_textureSourceList.size() );
1196e5c31af7Sopenharmony_ci
1197e5c31af7Sopenharmony_ci	for (int uniformIdx = 0; uniformIdx < (int)uniformDataList.size(); uniformIdx++)
1198e5c31af7Sopenharmony_ci	{
1199e5c31af7Sopenharmony_ci		if (uniformDataList[uniformIdx].toggleDecode == true)
1200e5c31af7Sopenharmony_ci		{
1201e5c31af7Sopenharmony_ci			if (m_textureSourceList[uniformIdx]->getDecode() == SRGBDECODE_DECODE_DEFAULT)
1202e5c31af7Sopenharmony_ci			{
1203e5c31af7Sopenharmony_ci				// cannot toggle default
1204e5c31af7Sopenharmony_ci				continue;
1205e5c31af7Sopenharmony_ci			}
1206e5c31af7Sopenharmony_ci
1207e5c31af7Sopenharmony_ci			// toggle sRGB decode values (ignoring value if set to default)
1208e5c31af7Sopenharmony_ci			m_textureSourceList[uniformIdx]->setDecode((SRGBDecode)((m_textureSourceList[uniformIdx]->getDecode() + 1) % SRGBDECODE_DECODE_DEFAULT));
1209e5c31af7Sopenharmony_ci		}
1210e5c31af7Sopenharmony_ci	}
1211e5c31af7Sopenharmony_ci}
1212e5c31af7Sopenharmony_ci
1213e5c31af7Sopenharmony_civoid SRGBTestCase::bindSamplerToTexture (const int samplerIdx, const int textureIdx, const deUint32 textureUnit)
1214e5c31af7Sopenharmony_ci{
1215e5c31af7Sopenharmony_ci	deUint32 enumConversion = textureUnit - GL_TEXTURE0;
1216e5c31af7Sopenharmony_ci	m_textureSourceList[textureIdx]->setHasSampler(true);
1217e5c31af7Sopenharmony_ci	m_samplerList[samplerIdx]->setTextureUnit(enumConversion);
1218e5c31af7Sopenharmony_ci}
1219e5c31af7Sopenharmony_ci
1220e5c31af7Sopenharmony_civoid SRGBTestCase::activateSampler (const int samplerIdx, const bool active)
1221e5c31af7Sopenharmony_ci{
1222e5c31af7Sopenharmony_ci	m_samplerList[samplerIdx]->setIsActive(active);
1223e5c31af7Sopenharmony_ci}
1224e5c31af7Sopenharmony_ci
1225e5c31af7Sopenharmony_civoid SRGBTestCase::logColor (const std::string& colorLogMessage, int colorIdx, tcu::Vec4 color) const
1226e5c31af7Sopenharmony_ci{
1227e5c31af7Sopenharmony_ci	tcu::TestLog&			log		= m_context.getTestContext().getLog();
1228e5c31af7Sopenharmony_ci	std::ostringstream		message;
1229e5c31af7Sopenharmony_ci
1230e5c31af7Sopenharmony_ci	message << colorLogMessage << colorIdx << " = (" << color.x() << ", " << color.y() << ", " << color.z() << ", " << color.w() << ")";
1231e5c31af7Sopenharmony_ci	log << tcu::TestLog::Message << message.str() << tcu::TestLog::EndMessage;
1232e5c31af7Sopenharmony_ci}
1233e5c31af7Sopenharmony_ci
1234e5c31af7Sopenharmony_citcu::Vec4 SRGBTestCase::formatReferenceColor (tcu::Vec4 referenceColor)
1235e5c31af7Sopenharmony_ci{
1236e5c31af7Sopenharmony_ci	switch (glu::getInternalFormat(m_internalFormat))
1237e5c31af7Sopenharmony_ci	{
1238e5c31af7Sopenharmony_ci		case GL_SRGB8_ALPHA8:
1239e5c31af7Sopenharmony_ci		{
1240e5c31af7Sopenharmony_ci			return referenceColor;
1241e5c31af7Sopenharmony_ci		}
1242e5c31af7Sopenharmony_ci		case GL_SRG8_EXT:
1243e5c31af7Sopenharmony_ci		{
1244e5c31af7Sopenharmony_ci			// zero unwanted color channels
1245e5c31af7Sopenharmony_ci			referenceColor.z() = 0;
1246e5c31af7Sopenharmony_ci			return referenceColor;
1247e5c31af7Sopenharmony_ci		}
1248e5c31af7Sopenharmony_ci		case GL_SR8_EXT:
1249e5c31af7Sopenharmony_ci		{
1250e5c31af7Sopenharmony_ci			// zero unwanted color channels
1251e5c31af7Sopenharmony_ci			referenceColor.y() = 0;
1252e5c31af7Sopenharmony_ci			referenceColor.z() = 0;
1253e5c31af7Sopenharmony_ci			return referenceColor;
1254e5c31af7Sopenharmony_ci		}
1255e5c31af7Sopenharmony_ci		default:
1256e5c31af7Sopenharmony_ci		{
1257e5c31af7Sopenharmony_ci			DE_FATAL("Error: Internal format not recognised");
1258e5c31af7Sopenharmony_ci			return referenceColor;
1259e5c31af7Sopenharmony_ci		}
1260e5c31af7Sopenharmony_ci	}
1261e5c31af7Sopenharmony_ci}
1262e5c31af7Sopenharmony_ci
1263e5c31af7Sopenharmony_civoid SRGBTestCase::render (void)
1264e5c31af7Sopenharmony_ci{
1265e5c31af7Sopenharmony_ci	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1266e5c31af7Sopenharmony_ci
1267e5c31af7Sopenharmony_ci	// default rendering only uses one program
1268e5c31af7Sopenharmony_ci	gl.bindFramebuffer(GL_FRAMEBUFFER, **m_framebuffer);
1269e5c31af7Sopenharmony_ci	gl.bindVertexArray(m_vaoID);
1270e5c31af7Sopenharmony_ci
1271e5c31af7Sopenharmony_ci	gl.useProgram(m_shaderProgramList[0]->getHandle());
1272e5c31af7Sopenharmony_ci
1273e5c31af7Sopenharmony_ci	for (int textureSourceIdx = 0; textureSourceIdx < (int)m_textureSourceList.size(); textureSourceIdx++)
1274e5c31af7Sopenharmony_ci	{
1275e5c31af7Sopenharmony_ci		gl.activeTexture(GL_TEXTURE0 + (glw::GLenum)textureSourceIdx);
1276e5c31af7Sopenharmony_ci		gl.bindTexture(m_textureSourceList[textureSourceIdx]->getGLTargetType(), m_textureSourceList[textureSourceIdx]->getHandle());
1277e5c31af7Sopenharmony_ci		glw::GLuint samplerUniformLocationID = gl.getUniformLocation(m_shaderProgramList[0]->getHandle(), (std::string("uTexture") + de::toString(textureSourceIdx)).c_str());
1278e5c31af7Sopenharmony_ci		TCU_CHECK(samplerUniformLocationID != (glw::GLuint)-1);
1279e5c31af7Sopenharmony_ci		gl.uniform1i(samplerUniformLocationID, (glw::GLenum)textureSourceIdx);
1280e5c31af7Sopenharmony_ci	}
1281e5c31af7Sopenharmony_ci
1282e5c31af7Sopenharmony_ci	for (int samplerIdx = 0; samplerIdx < (int)m_samplerList.size(); samplerIdx++)
1283e5c31af7Sopenharmony_ci	{
1284e5c31af7Sopenharmony_ci		if (m_samplerList[samplerIdx]->getIsActive() == true)
1285e5c31af7Sopenharmony_ci		{
1286e5c31af7Sopenharmony_ci			m_samplerList[samplerIdx]->bindToTexture();
1287e5c31af7Sopenharmony_ci		}
1288e5c31af7Sopenharmony_ci	}
1289e5c31af7Sopenharmony_ci
1290e5c31af7Sopenharmony_ci	gl.drawArrays(GL_TRIANGLES, 0, 6);
1291e5c31af7Sopenharmony_ci
1292e5c31af7Sopenharmony_ci	for (std::size_t textureSourceIdx = 0; textureSourceIdx < m_textureSourceList.size(); textureSourceIdx++)
1293e5c31af7Sopenharmony_ci	{
1294e5c31af7Sopenharmony_ci		gl.bindTexture(m_textureSourceList[textureSourceIdx]->getGLTargetType(), 0);
1295e5c31af7Sopenharmony_ci	}
1296e5c31af7Sopenharmony_ci	gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
1297e5c31af7Sopenharmony_ci	gl.bindVertexArray(0);
1298e5c31af7Sopenharmony_ci	gl.bindBuffer(GL_ARRAY_BUFFER, 0);
1299e5c31af7Sopenharmony_ci}
1300e5c31af7Sopenharmony_ci
1301e5c31af7Sopenharmony_civoid SRGBTestCase::uploadTextures (void)
1302e5c31af7Sopenharmony_ci{
1303e5c31af7Sopenharmony_ci	for (std::size_t idx = 0; idx < m_textureSourceList.size(); idx++)
1304e5c31af7Sopenharmony_ci	{
1305e5c31af7Sopenharmony_ci		m_textureSourceList[idx]->upload();
1306e5c31af7Sopenharmony_ci		m_textureSourceList[idx]->setParameters();
1307e5c31af7Sopenharmony_ci	}
1308e5c31af7Sopenharmony_ci}
1309e5c31af7Sopenharmony_ci
1310e5c31af7Sopenharmony_civoid SRGBTestCase::initFrameBuffer (void)
1311e5c31af7Sopenharmony_ci{
1312e5c31af7Sopenharmony_ci	const glw::Functions&	gl		= m_context.getRenderContext().getFunctions();
1313e5c31af7Sopenharmony_ci	int						width	= m_context.getRenderContext().getRenderTarget().getWidth();
1314e5c31af7Sopenharmony_ci	int						height	= m_context.getRenderContext().getRenderTarget().getHeight();
1315e5c31af7Sopenharmony_ci
1316e5c31af7Sopenharmony_ci	if (m_resultOutputTotal == 0)
1317e5c31af7Sopenharmony_ci	{
1318e5c31af7Sopenharmony_ci		throw std::invalid_argument("SRGBTestExecutor must have at least 1 rendered result");
1319e5c31af7Sopenharmony_ci	}
1320e5c31af7Sopenharmony_ci
1321e5c31af7Sopenharmony_ci	gl.bindFramebuffer(GL_FRAMEBUFFER, **m_framebuffer);
1322e5c31af7Sopenharmony_ci
1323e5c31af7Sopenharmony_ci	DE_ASSERT(m_renderBufferList.empty());
1324e5c31af7Sopenharmony_ci	for (int outputIdx = 0; outputIdx < m_resultOutputTotal; outputIdx++)
1325e5c31af7Sopenharmony_ci	{
1326e5c31af7Sopenharmony_ci		glw::GLuint renderBuffer = -1;
1327e5c31af7Sopenharmony_ci		m_renderBufferList.push_back(renderBuffer);
1328e5c31af7Sopenharmony_ci	}
1329e5c31af7Sopenharmony_ci
1330e5c31af7Sopenharmony_ci	for (std::size_t renderBufferIdx = 0; renderBufferIdx < m_renderBufferList.size(); renderBufferIdx++)
1331e5c31af7Sopenharmony_ci	{
1332e5c31af7Sopenharmony_ci		gl.genRenderbuffers(1, &m_renderBufferList[renderBufferIdx]);
1333e5c31af7Sopenharmony_ci		gl.bindRenderbuffer(GL_RENDERBUFFER, m_renderBufferList[renderBufferIdx]);
1334e5c31af7Sopenharmony_ci		gl.renderbufferStorage(GL_RENDERBUFFER, glu::getInternalFormat(m_resultTextureFormat), width, height);
1335e5c31af7Sopenharmony_ci		gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + (glw::GLenum)renderBufferIdx, GL_RENDERBUFFER, m_renderBufferList[renderBufferIdx]);
1336e5c31af7Sopenharmony_ci		GLU_EXPECT_NO_ERROR(gl.getError(), "Create and setup renderbuffer object");
1337e5c31af7Sopenharmony_ci	}
1338e5c31af7Sopenharmony_ci	TCU_CHECK(gl.checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
1339e5c31af7Sopenharmony_ci
1340e5c31af7Sopenharmony_ci	std::vector<glw::GLenum> renderBufferTargets(m_renderBufferList.size());
1341e5c31af7Sopenharmony_ci	for (std::size_t renderBufferIdx = 0; renderBufferIdx < m_renderBufferList.size(); renderBufferIdx++)
1342e5c31af7Sopenharmony_ci	{
1343e5c31af7Sopenharmony_ci		renderBufferTargets[renderBufferIdx] = GL_COLOR_ATTACHMENT0 + (glw::GLenum)renderBufferIdx;
1344e5c31af7Sopenharmony_ci	}
1345e5c31af7Sopenharmony_ci	gl.drawBuffers((glw::GLsizei)renderBufferTargets.size(), &renderBufferTargets[0]);
1346e5c31af7Sopenharmony_ci	GLU_EXPECT_NO_ERROR(gl.getError(), "glDrawBuffer()");
1347e5c31af7Sopenharmony_ci
1348e5c31af7Sopenharmony_ci	gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
1349e5c31af7Sopenharmony_ci}
1350e5c31af7Sopenharmony_ci
1351e5c31af7Sopenharmony_civoid SRGBTestCase::initVertexData (void)
1352e5c31af7Sopenharmony_ci{
1353e5c31af7Sopenharmony_ci	const glw::Functions&	gl				= m_context.getRenderContext().getFunctions();
1354e5c31af7Sopenharmony_ci
1355e5c31af7Sopenharmony_ci	static const glw::GLfloat squareVertexData[] =
1356e5c31af7Sopenharmony_ci	{
1357e5c31af7Sopenharmony_ci		// position				// texcoord
1358e5c31af7Sopenharmony_ci		-1.0f, -1.0f, 0.0f,		0.0f, 0.0f, // bottom left corner
1359e5c31af7Sopenharmony_ci		 1.0f, -1.0f, 0.0f,		1.0f, 0.0f, // bottom right corner
1360e5c31af7Sopenharmony_ci		 1.0f,  1.0f, 0.0f,		1.0f, 1.0f, // Top right corner
1361e5c31af7Sopenharmony_ci
1362e5c31af7Sopenharmony_ci		-1.0f,  1.0f, 0.0f,		0.0f, 1.0f, // top left corner
1363e5c31af7Sopenharmony_ci		 1.0f,  1.0f, 0.0f,		1.0f, 1.0f, // Top right corner
1364e5c31af7Sopenharmony_ci		-1.0f, -1.0f, 0.0f,		0.0f, 0.0f  // bottom left corner
1365e5c31af7Sopenharmony_ci	};
1366e5c31af7Sopenharmony_ci
1367e5c31af7Sopenharmony_ci	DE_ASSERT(m_vaoID == 0);
1368e5c31af7Sopenharmony_ci	gl.genVertexArrays(1, &m_vaoID);
1369e5c31af7Sopenharmony_ci	gl.bindVertexArray(m_vaoID);
1370e5c31af7Sopenharmony_ci
1371e5c31af7Sopenharmony_ci	gl.genBuffers(1, &m_vertexDataID);
1372e5c31af7Sopenharmony_ci	gl.bindBuffer(GL_ARRAY_BUFFER, m_vertexDataID);
1373e5c31af7Sopenharmony_ci	gl.bufferData(GL_ARRAY_BUFFER, (glw::GLsizei)sizeof(squareVertexData), squareVertexData, GL_STATIC_DRAW);
1374e5c31af7Sopenharmony_ci
1375e5c31af7Sopenharmony_ci	gl.vertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * (glw::GLsizei)sizeof(float), (glw::GLvoid *)0);
1376e5c31af7Sopenharmony_ci	gl.enableVertexAttribArray(0);
1377e5c31af7Sopenharmony_ci	gl.vertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * (glw::GLsizei)sizeof(float), (glw::GLvoid *)(3 * sizeof(float)));
1378e5c31af7Sopenharmony_ci	gl.enableVertexAttribArray(1);
1379e5c31af7Sopenharmony_ci
1380e5c31af7Sopenharmony_ci	gl.bindVertexArray(0);
1381e5c31af7Sopenharmony_ci	gl.bindBuffer(GL_ARRAY_BUFFER, 0);
1382e5c31af7Sopenharmony_ci}
1383e5c31af7Sopenharmony_ci
1384e5c31af7Sopenharmony_ciclass TextureDecodeSkippedCase : public SRGBTestCase
1385e5c31af7Sopenharmony_ci{
1386e5c31af7Sopenharmony_cipublic:
1387e5c31af7Sopenharmony_ci			TextureDecodeSkippedCase	(Context& context, const char* name, const char* description, const tcu::TextureFormat internalFormat)
1388e5c31af7Sopenharmony_ci				: SRGBTestCase			(context, name, description, internalFormat) {}
1389e5c31af7Sopenharmony_ci
1390e5c31af7Sopenharmony_ci			~TextureDecodeSkippedCase	(void) {}
1391e5c31af7Sopenharmony_ci
1392e5c31af7Sopenharmony_ci	void	setupTest					(void);
1393e5c31af7Sopenharmony_ci	bool	verifyResult				(void);
1394e5c31af7Sopenharmony_ci};
1395e5c31af7Sopenharmony_ci
1396e5c31af7Sopenharmony_civoid TextureDecodeSkippedCase::setupTest (void)
1397e5c31af7Sopenharmony_ci{
1398e5c31af7Sopenharmony_ci	// TEST STEPS:
1399e5c31af7Sopenharmony_ci	//	- create and set texture to DECODE_SKIP_EXT
1400e5c31af7Sopenharmony_ci	//	- store texture on GPU
1401e5c31af7Sopenharmony_ci	//	- in fragment shader, sample the texture using texture*() and render texel values to a color attachment in the FBO
1402e5c31af7Sopenharmony_ci	//	- on the host, read back the pixel values into a tcu::TextureLevel
1403e5c31af7Sopenharmony_ci	//	- analyse the texel values, expecting them in sRGB format i.e. linear space decoding was skipped
1404e5c31af7Sopenharmony_ci
1405e5c31af7Sopenharmony_ci	FragmentShaderParameters shaderParameters(SHADEROUTPUTS_ONE, SHADERUNIFORMS_ONE, NULL, BLENDING_NOT_REQUIRED, TOGGLING_NOT_REQUIRED);
1406e5c31af7Sopenharmony_ci
1407e5c31af7Sopenharmony_ci	this->addTexture(	TEXTURETYPE_2D,
1408e5c31af7Sopenharmony_ci						TestDimensions::WIDTH,
1409e5c31af7Sopenharmony_ci						TestDimensions::HEIGHT,
1410e5c31af7Sopenharmony_ci						getColorReferenceLinear(),
1411e5c31af7Sopenharmony_ci						tcu::Sampler::MIRRORED_REPEAT_GL,
1412e5c31af7Sopenharmony_ci						tcu::Sampler::MIRRORED_REPEAT_GL,
1413e5c31af7Sopenharmony_ci						tcu::Sampler::LINEAR,
1414e5c31af7Sopenharmony_ci						tcu::Sampler::LINEAR,
1415e5c31af7Sopenharmony_ci						SRGBDECODE_SKIP_DECODE);
1416e5c31af7Sopenharmony_ci
1417e5c31af7Sopenharmony_ci	this->addShaderProgram(shaderParameters);
1418e5c31af7Sopenharmony_ci	this->setSamplingLocations(TestSamplingPositions::X_POS, TestSamplingPositions::Y_POS);
1419e5c31af7Sopenharmony_ci
1420e5c31af7Sopenharmony_ci	this->setSamplingGroup(SHADERSAMPLINGGROUP_TEXTURE);
1421e5c31af7Sopenharmony_ci}
1422e5c31af7Sopenharmony_ci
1423e5c31af7Sopenharmony_cibool TextureDecodeSkippedCase::verifyResult (void)
1424e5c31af7Sopenharmony_ci{
1425e5c31af7Sopenharmony_ci	tcu::TestLog&			log				= m_context.getTestContext().getLog();
1426e5c31af7Sopenharmony_ci	const int				resultColorIdx	= 0;
1427e5c31af7Sopenharmony_ci	std::vector<tcu::Vec4>	pixelResultList;
1428e5c31af7Sopenharmony_ci	tcu::Vec4				pixelConverted;
1429e5c31af7Sopenharmony_ci	tcu::Vec4				pixelReference;
1430e5c31af7Sopenharmony_ci	tcu::Vec4				pixelExpected;
1431e5c31af7Sopenharmony_ci
1432e5c31af7Sopenharmony_ci	this->readResultTextures();
1433e5c31af7Sopenharmony_ci	this->storeResultPixels(pixelResultList);
1434e5c31af7Sopenharmony_ci
1435e5c31af7Sopenharmony_ci	pixelConverted = tcu::sRGBToLinear(pixelResultList[resultColorIdx]);
1436e5c31af7Sopenharmony_ci	pixelReference = this->formatReferenceColor(getColorReferenceLinear());
1437e5c31af7Sopenharmony_ci	pixelExpected = this->formatReferenceColor(getColorReferenceSRGB());
1438e5c31af7Sopenharmony_ci
1439e5c31af7Sopenharmony_ci	this->formatReferenceColor(pixelReference);
1440e5c31af7Sopenharmony_ci	this->logColor(std::string("Expected color: "), resultColorIdx, pixelExpected);
1441e5c31af7Sopenharmony_ci
1442e5c31af7Sopenharmony_ci	// result color 0 should be sRGB. Compare with linear reference color
1443e5c31af7Sopenharmony_ci	if ( (tcu::boolAll(tcu::lessThan(tcu::abs(pixelConverted - pixelReference), m_epsilonError))) || (tcu::boolAll(tcu::equal(pixelConverted, pixelReference))) )
1444e5c31af7Sopenharmony_ci	{
1445e5c31af7Sopenharmony_ci		log << tcu::TestLog::Message << std::string("sRGB as expected") << tcu::TestLog::EndMessage;
1446e5c31af7Sopenharmony_ci		return true;
1447e5c31af7Sopenharmony_ci	}
1448e5c31af7Sopenharmony_ci	else
1449e5c31af7Sopenharmony_ci	{
1450e5c31af7Sopenharmony_ci		log << tcu::TestLog::Message << std::string("not sRGB as expected") << tcu::TestLog::EndMessage;
1451e5c31af7Sopenharmony_ci		return false;
1452e5c31af7Sopenharmony_ci	}
1453e5c31af7Sopenharmony_ci}
1454e5c31af7Sopenharmony_ci
1455e5c31af7Sopenharmony_ciclass TextureDecodeEnabledCase : public SRGBTestCase
1456e5c31af7Sopenharmony_ci{
1457e5c31af7Sopenharmony_cipublic:
1458e5c31af7Sopenharmony_ci		TextureDecodeEnabledCase	(Context& context, const char* name, const char* description, const tcu::TextureFormat internalFormat)
1459e5c31af7Sopenharmony_ci			: SRGBTestCase			(context, name, description, internalFormat) {}
1460e5c31af7Sopenharmony_ci
1461e5c31af7Sopenharmony_ci		~TextureDecodeEnabledCase	(void) {}
1462e5c31af7Sopenharmony_ci
1463e5c31af7Sopenharmony_ci		void	setupTest			(void);
1464e5c31af7Sopenharmony_ci		bool	verifyResult		(void);
1465e5c31af7Sopenharmony_ci};
1466e5c31af7Sopenharmony_ci
1467e5c31af7Sopenharmony_civoid TextureDecodeEnabledCase::setupTest (void)
1468e5c31af7Sopenharmony_ci{
1469e5c31af7Sopenharmony_ci	// TEST STEPS:
1470e5c31af7Sopenharmony_ci	//	- create and set texture to DECODE_EXT
1471e5c31af7Sopenharmony_ci	//	- store texture on GPU
1472e5c31af7Sopenharmony_ci	//	- in fragment shader, sample the texture using texture*() and render texel values to a color attachment in the FBO
1473e5c31af7Sopenharmony_ci	//	- on the host, read back the pixel values into a tcu::TextureLevel
1474e5c31af7Sopenharmony_ci	//	- analyse the texel values, expecting them in lRGB format i.e. linear space decoding was enabled
1475e5c31af7Sopenharmony_ci
1476e5c31af7Sopenharmony_ci	FragmentShaderParameters shaderParameters(SHADEROUTPUTS_ONE, SHADERUNIFORMS_ONE, NULL, BLENDING_NOT_REQUIRED, TOGGLING_NOT_REQUIRED);
1477e5c31af7Sopenharmony_ci
1478e5c31af7Sopenharmony_ci	this->addTexture(	TEXTURETYPE_2D,
1479e5c31af7Sopenharmony_ci						TestDimensions::WIDTH,
1480e5c31af7Sopenharmony_ci						TestDimensions::HEIGHT,
1481e5c31af7Sopenharmony_ci						getColorReferenceLinear(),
1482e5c31af7Sopenharmony_ci						tcu::Sampler::MIRRORED_REPEAT_GL,
1483e5c31af7Sopenharmony_ci						tcu::Sampler::MIRRORED_REPEAT_GL,
1484e5c31af7Sopenharmony_ci						tcu::Sampler::LINEAR,
1485e5c31af7Sopenharmony_ci						tcu::Sampler::LINEAR,
1486e5c31af7Sopenharmony_ci						SRGBDECODE_DECODE);
1487e5c31af7Sopenharmony_ci
1488e5c31af7Sopenharmony_ci	this->addShaderProgram(shaderParameters);
1489e5c31af7Sopenharmony_ci
1490e5c31af7Sopenharmony_ci	this->setSamplingLocations(TestSamplingPositions::X_POS, TestSamplingPositions::Y_POS);
1491e5c31af7Sopenharmony_ci
1492e5c31af7Sopenharmony_ci	this->setSamplingGroup(SHADERSAMPLINGGROUP_TEXTURE);
1493e5c31af7Sopenharmony_ci}
1494e5c31af7Sopenharmony_ci
1495e5c31af7Sopenharmony_cibool TextureDecodeEnabledCase::verifyResult (void)
1496e5c31af7Sopenharmony_ci{
1497e5c31af7Sopenharmony_ci	tcu::TestLog&			log				= m_context.getTestContext().getLog();
1498e5c31af7Sopenharmony_ci	const int				resultColorIdx	= 0;
1499e5c31af7Sopenharmony_ci	std::vector<tcu::Vec4>	pixelResultList;
1500e5c31af7Sopenharmony_ci	tcu::Vec4				pixelConverted;
1501e5c31af7Sopenharmony_ci	tcu::Vec4				pixelReference;
1502e5c31af7Sopenharmony_ci	tcu::Vec4				pixelExpected;
1503e5c31af7Sopenharmony_ci
1504e5c31af7Sopenharmony_ci	this->readResultTextures();
1505e5c31af7Sopenharmony_ci	this->storeResultPixels(pixelResultList);
1506e5c31af7Sopenharmony_ci
1507e5c31af7Sopenharmony_ci	pixelConverted = tcu::linearToSRGB(pixelResultList[resultColorIdx]);
1508e5c31af7Sopenharmony_ci	pixelReference = this->formatReferenceColor(getColorReferenceSRGB());
1509e5c31af7Sopenharmony_ci	pixelExpected = this->formatReferenceColor(getColorReferenceLinear());
1510e5c31af7Sopenharmony_ci
1511e5c31af7Sopenharmony_ci	this->logColor(std::string("Expected color: "), resultColorIdx, pixelExpected);
1512e5c31af7Sopenharmony_ci
1513e5c31af7Sopenharmony_ci	// result color 0 should be SRGB. Compare with sRGB reference color
1514e5c31af7Sopenharmony_ci	if ( (tcu::boolAll(tcu::lessThan(tcu::abs(pixelConverted - pixelReference), m_epsilonError))) || (tcu::boolAll(tcu::equal(pixelConverted, pixelReference))) )
1515e5c31af7Sopenharmony_ci	{
1516e5c31af7Sopenharmony_ci		log << tcu::TestLog::Message << std::string("linear as expected") << tcu::TestLog::EndMessage;
1517e5c31af7Sopenharmony_ci		return true;
1518e5c31af7Sopenharmony_ci	}
1519e5c31af7Sopenharmony_ci	else
1520e5c31af7Sopenharmony_ci	{
1521e5c31af7Sopenharmony_ci		log << tcu::TestLog::Message << std::string("not linear as expected") << tcu::TestLog::EndMessage;
1522e5c31af7Sopenharmony_ci		return false;
1523e5c31af7Sopenharmony_ci	}
1524e5c31af7Sopenharmony_ci}
1525e5c31af7Sopenharmony_ci
1526e5c31af7Sopenharmony_ciclass TexelFetchDecodeSkippedcase : public SRGBTestCase
1527e5c31af7Sopenharmony_ci{
1528e5c31af7Sopenharmony_cipublic:
1529e5c31af7Sopenharmony_ci			TexelFetchDecodeSkippedcase		(Context& context, const char* name, const char* description, const tcu::TextureFormat internalFormat)
1530e5c31af7Sopenharmony_ci				: SRGBTestCase				(context, name, description, internalFormat) {}
1531e5c31af7Sopenharmony_ci
1532e5c31af7Sopenharmony_ci			~TexelFetchDecodeSkippedcase	(void) {}
1533e5c31af7Sopenharmony_ci
1534e5c31af7Sopenharmony_ci	void	setupTest						(void);
1535e5c31af7Sopenharmony_ci	bool	verifyResult					(void);
1536e5c31af7Sopenharmony_ci};
1537e5c31af7Sopenharmony_ci
1538e5c31af7Sopenharmony_civoid TexelFetchDecodeSkippedcase::setupTest (void)
1539e5c31af7Sopenharmony_ci{
1540e5c31af7Sopenharmony_ci	// TEST STEPS:
1541e5c31af7Sopenharmony_ci	//	- create and set texture to DECODE_SKIP_EXT
1542e5c31af7Sopenharmony_ci	//	- store texture on GPU
1543e5c31af7Sopenharmony_ci	//	- in fragment shader, sample the texture using texelFetch*() and render texel values to a color attachment in the FBO
1544e5c31af7Sopenharmony_ci	//	- on the host, read back the pixel values into a tcu::TextureLevel
1545e5c31af7Sopenharmony_ci	//	- analyse the texel values, expecting them in lRGB format i.e. linear space decoding is always enabled with texelFetch*()
1546e5c31af7Sopenharmony_ci
1547e5c31af7Sopenharmony_ci	FragmentShaderParameters shaderParameters(SHADEROUTPUTS_ONE, SHADERUNIFORMS_ONE, NULL, BLENDING_NOT_REQUIRED, TOGGLING_NOT_REQUIRED);
1548e5c31af7Sopenharmony_ci
1549e5c31af7Sopenharmony_ci	this->addTexture(	TEXTURETYPE_2D,
1550e5c31af7Sopenharmony_ci						TestDimensions::WIDTH,
1551e5c31af7Sopenharmony_ci						TestDimensions::HEIGHT,
1552e5c31af7Sopenharmony_ci						getColorReferenceLinear(),
1553e5c31af7Sopenharmony_ci						tcu::Sampler::MIRRORED_REPEAT_GL,
1554e5c31af7Sopenharmony_ci						tcu::Sampler::MIRRORED_REPEAT_GL,
1555e5c31af7Sopenharmony_ci						tcu::Sampler::LINEAR,
1556e5c31af7Sopenharmony_ci						tcu::Sampler::LINEAR,
1557e5c31af7Sopenharmony_ci						SRGBDECODE_SKIP_DECODE);
1558e5c31af7Sopenharmony_ci
1559e5c31af7Sopenharmony_ci	this->addShaderProgram(shaderParameters);
1560e5c31af7Sopenharmony_ci
1561e5c31af7Sopenharmony_ci	this->setSamplingLocations(TestSamplingPositions::X_POS, TestSamplingPositions::Y_POS);
1562e5c31af7Sopenharmony_ci
1563e5c31af7Sopenharmony_ci	this->setSamplingGroup(SHADERSAMPLINGGROUP_TEXEL_FETCH);
1564e5c31af7Sopenharmony_ci}
1565e5c31af7Sopenharmony_ci
1566e5c31af7Sopenharmony_cibool TexelFetchDecodeSkippedcase::verifyResult (void)
1567e5c31af7Sopenharmony_ci{
1568e5c31af7Sopenharmony_ci	tcu::TestLog&			log				= m_context.getTestContext().getLog();
1569e5c31af7Sopenharmony_ci	const int				resultColorIdx	= 0;
1570e5c31af7Sopenharmony_ci	std::vector<tcu::Vec4>	pixelResultList;
1571e5c31af7Sopenharmony_ci	tcu::Vec4				pixelReference;
1572e5c31af7Sopenharmony_ci	tcu::Vec4				pixelExpected;
1573e5c31af7Sopenharmony_ci
1574e5c31af7Sopenharmony_ci	this->readResultTextures();
1575e5c31af7Sopenharmony_ci	this->storeResultPixels(pixelResultList);
1576e5c31af7Sopenharmony_ci
1577e5c31af7Sopenharmony_ci	pixelReference = pixelExpected = this->formatReferenceColor(getColorReferenceLinear());
1578e5c31af7Sopenharmony_ci
1579e5c31af7Sopenharmony_ci	this->logColor(std::string("Expected color: "), resultColorIdx, pixelExpected);
1580e5c31af7Sopenharmony_ci
1581e5c31af7Sopenharmony_ci	// result color 0 should be linear due to automatic conversion via texelFetch*(). Compare with linear reference color
1582e5c31af7Sopenharmony_ci	if ( (tcu::boolAll(tcu::lessThan(tcu::abs(pixelResultList[0] - pixelReference), m_epsilonError))) || (tcu::boolAll(tcu::equal(pixelResultList[0], pixelReference))) )
1583e5c31af7Sopenharmony_ci	{
1584e5c31af7Sopenharmony_ci		log << tcu::TestLog::Message << std::string("linear as expected") << tcu::TestLog::EndMessage;
1585e5c31af7Sopenharmony_ci		return true;
1586e5c31af7Sopenharmony_ci	}
1587e5c31af7Sopenharmony_ci	else
1588e5c31af7Sopenharmony_ci	{
1589e5c31af7Sopenharmony_ci		log << tcu::TestLog::Message << std::string("not linear as expected") << tcu::TestLog::EndMessage;
1590e5c31af7Sopenharmony_ci		return false;
1591e5c31af7Sopenharmony_ci	}
1592e5c31af7Sopenharmony_ci}
1593e5c31af7Sopenharmony_ci
1594e5c31af7Sopenharmony_ciclass GPUConversionDecodeEnabledCase : public SRGBTestCase
1595e5c31af7Sopenharmony_ci{
1596e5c31af7Sopenharmony_cipublic:
1597e5c31af7Sopenharmony_ci			GPUConversionDecodeEnabledCase	(Context& context, const char* name, const char* description, const tcu::TextureFormat internalFormat)
1598e5c31af7Sopenharmony_ci				: SRGBTestCase				(context, name, description, internalFormat) {}
1599e5c31af7Sopenharmony_ci
1600e5c31af7Sopenharmony_ci			~GPUConversionDecodeEnabledCase	(void) {}
1601e5c31af7Sopenharmony_ci
1602e5c31af7Sopenharmony_ci	void	setupTest						(void);
1603e5c31af7Sopenharmony_ci	bool	verifyResult					(void);
1604e5c31af7Sopenharmony_ci};
1605e5c31af7Sopenharmony_ci
1606e5c31af7Sopenharmony_civoid GPUConversionDecodeEnabledCase::setupTest (void)
1607e5c31af7Sopenharmony_ci{
1608e5c31af7Sopenharmony_ci	// TEST STEPS:
1609e5c31af7Sopenharmony_ci	//	- create and set texture_a to DECODE_SKIP_EXT and texture_b to default
1610e5c31af7Sopenharmony_ci	//	- store textures on GPU
1611e5c31af7Sopenharmony_ci	//	- in fragment shader, sample both textures using texture*() and manually perform sRGB to lRGB conversion on texture_b
1612e5c31af7Sopenharmony_ci	//	- in fragment shader, compare converted texture_b with texture_a
1613e5c31af7Sopenharmony_ci	//	- render green image for pass or red for fail
1614e5c31af7Sopenharmony_ci
1615e5c31af7Sopenharmony_ci	ComparisonFunction comparisonFunction("srgbToLinearCheck", FUNCTIONPARAMETERS_TWO, getFunctionDefinitionSRGBToLinearCheck());
1616e5c31af7Sopenharmony_ci
1617e5c31af7Sopenharmony_ci	FragmentShaderParameters shaderParameters(SHADEROUTPUTS_ONE, SHADERUNIFORMS_TWO, &comparisonFunction, BLENDING_NOT_REQUIRED, TOGGLING_NOT_REQUIRED);
1618e5c31af7Sopenharmony_ci
1619e5c31af7Sopenharmony_ci	this->addTexture(	TEXTURETYPE_2D,
1620e5c31af7Sopenharmony_ci						TestDimensions::WIDTH,
1621e5c31af7Sopenharmony_ci						TestDimensions::HEIGHT,
1622e5c31af7Sopenharmony_ci						getColorReferenceLinear(),
1623e5c31af7Sopenharmony_ci						tcu::Sampler::MIRRORED_REPEAT_GL,
1624e5c31af7Sopenharmony_ci						tcu::Sampler::MIRRORED_REPEAT_GL,
1625e5c31af7Sopenharmony_ci						tcu::Sampler::LINEAR,
1626e5c31af7Sopenharmony_ci						tcu::Sampler::LINEAR,
1627e5c31af7Sopenharmony_ci						SRGBDECODE_SKIP_DECODE);
1628e5c31af7Sopenharmony_ci
1629e5c31af7Sopenharmony_ci	this->addTexture(	TEXTURETYPE_2D,
1630e5c31af7Sopenharmony_ci						TestDimensions::WIDTH,
1631e5c31af7Sopenharmony_ci						TestDimensions::HEIGHT,
1632e5c31af7Sopenharmony_ci						getColorReferenceLinear(),
1633e5c31af7Sopenharmony_ci						tcu::Sampler::MIRRORED_REPEAT_GL,
1634e5c31af7Sopenharmony_ci						tcu::Sampler::MIRRORED_REPEAT_GL,
1635e5c31af7Sopenharmony_ci						tcu::Sampler::LINEAR,
1636e5c31af7Sopenharmony_ci						tcu::Sampler::LINEAR,
1637e5c31af7Sopenharmony_ci						SRGBDECODE_DECODE_DEFAULT);
1638e5c31af7Sopenharmony_ci
1639e5c31af7Sopenharmony_ci	this->addShaderProgram(shaderParameters);
1640e5c31af7Sopenharmony_ci
1641e5c31af7Sopenharmony_ci	this->setSamplingLocations(TestSamplingPositions::X_POS, TestSamplingPositions::Y_POS);
1642e5c31af7Sopenharmony_ci
1643e5c31af7Sopenharmony_ci	this->setSamplingGroup(SHADERSAMPLINGGROUP_TEXTURE);
1644e5c31af7Sopenharmony_ci}
1645e5c31af7Sopenharmony_ci
1646e5c31af7Sopenharmony_cibool GPUConversionDecodeEnabledCase::verifyResult (void)
1647e5c31af7Sopenharmony_ci{
1648e5c31af7Sopenharmony_ci	tcu::TestLog&			log				= m_context.getTestContext().getLog();
1649e5c31af7Sopenharmony_ci	const int				resultColorIdx	= 0;
1650e5c31af7Sopenharmony_ci	std::vector<tcu::Vec4>	pixelResultList;
1651e5c31af7Sopenharmony_ci
1652e5c31af7Sopenharmony_ci	this->readResultTextures();
1653e5c31af7Sopenharmony_ci	this->storeResultPixels(pixelResultList);
1654e5c31af7Sopenharmony_ci	this->logColor(std::string("Expected color: "), resultColorIdx, getColorGreenPass());
1655e5c31af7Sopenharmony_ci
1656e5c31af7Sopenharmony_ci	// result color returned from GPU is either green (pass) or fail (red)
1657e5c31af7Sopenharmony_ci	if ( tcu::boolAll(tcu::equal(pixelResultList[resultColorIdx], getColorGreenPass())) )
1658e5c31af7Sopenharmony_ci	{
1659e5c31af7Sopenharmony_ci		log << tcu::TestLog::Message << std::string("returned pass color from GPU") << tcu::TestLog::EndMessage;
1660e5c31af7Sopenharmony_ci		return true;
1661e5c31af7Sopenharmony_ci	}
1662e5c31af7Sopenharmony_ci	else
1663e5c31af7Sopenharmony_ci	{
1664e5c31af7Sopenharmony_ci		log << tcu::TestLog::Message << std::string("returned fail color from GPU") << tcu::TestLog::EndMessage;
1665e5c31af7Sopenharmony_ci		return false;
1666e5c31af7Sopenharmony_ci	}
1667e5c31af7Sopenharmony_ci}
1668e5c31af7Sopenharmony_ci
1669e5c31af7Sopenharmony_ciclass DecodeToggledCase : public SRGBTestCase
1670e5c31af7Sopenharmony_ci{
1671e5c31af7Sopenharmony_cipublic:
1672e5c31af7Sopenharmony_ci			DecodeToggledCase	(Context& context, const char* name, const char* description, const tcu::TextureFormat internalFormat)
1673e5c31af7Sopenharmony_ci				: SRGBTestCase	(context, name, description, internalFormat) {}
1674e5c31af7Sopenharmony_ci
1675e5c31af7Sopenharmony_ci			~DecodeToggledCase	(void) {}
1676e5c31af7Sopenharmony_ci
1677e5c31af7Sopenharmony_ci	void	render				(void);
1678e5c31af7Sopenharmony_ci	void	setupTest			(void);
1679e5c31af7Sopenharmony_ci	bool	verifyResult		(void);
1680e5c31af7Sopenharmony_ci};
1681e5c31af7Sopenharmony_ci
1682e5c31af7Sopenharmony_civoid DecodeToggledCase::render (void)
1683e5c31af7Sopenharmony_ci{
1684e5c31af7Sopenharmony_ci	// override the base SRGBTestCase render function with the purpose of switching between shader programs,
1685e5c31af7Sopenharmony_ci	// toggling texture sRGB decode state between draw calls
1686e5c31af7Sopenharmony_ci	const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1687e5c31af7Sopenharmony_ci
1688e5c31af7Sopenharmony_ci	gl.bindFramebuffer(GL_FRAMEBUFFER, **m_framebuffer);
1689e5c31af7Sopenharmony_ci	gl.bindVertexArray(m_vaoID);
1690e5c31af7Sopenharmony_ci
1691e5c31af7Sopenharmony_ci	for (std::size_t programIdx = 0; programIdx < m_shaderProgramList.size(); programIdx++)
1692e5c31af7Sopenharmony_ci	{
1693e5c31af7Sopenharmony_ci		gl.useProgram(m_shaderProgramList[programIdx]->getHandle());
1694e5c31af7Sopenharmony_ci
1695e5c31af7Sopenharmony_ci		this->toggleDecode(m_shaderProgramList[programIdx]->getUniformDataList());
1696e5c31af7Sopenharmony_ci
1697e5c31af7Sopenharmony_ci		for (int textureSourceIdx = 0; textureSourceIdx < (int)m_textureSourceList.size(); textureSourceIdx++)
1698e5c31af7Sopenharmony_ci		{
1699e5c31af7Sopenharmony_ci			gl.activeTexture(GL_TEXTURE0 + (glw::GLenum)textureSourceIdx);
1700e5c31af7Sopenharmony_ci			gl.bindTexture(m_textureSourceList[textureSourceIdx]->getGLTargetType(), m_textureSourceList[textureSourceIdx]->getHandle());
1701e5c31af7Sopenharmony_ci			glw::GLuint samplerUniformLocationID = gl.getUniformLocation(m_shaderProgramList[programIdx]->getHandle(), (std::string("uTexture") + de::toString(textureSourceIdx)).c_str());
1702e5c31af7Sopenharmony_ci			TCU_CHECK(samplerUniformLocationID != (glw::GLuint) - 1);
1703e5c31af7Sopenharmony_ci			gl.uniform1i(samplerUniformLocationID, (glw::GLenum)textureSourceIdx);
1704e5c31af7Sopenharmony_ci		}
1705e5c31af7Sopenharmony_ci
1706e5c31af7Sopenharmony_ci		for (int samplerIdx = 0; samplerIdx < (int)m_samplerList.size(); samplerIdx++)
1707e5c31af7Sopenharmony_ci		{
1708e5c31af7Sopenharmony_ci			if (m_samplerList[samplerIdx]->getIsActive() == true)
1709e5c31af7Sopenharmony_ci			{
1710e5c31af7Sopenharmony_ci				m_samplerList[samplerIdx]->bindToTexture();
1711e5c31af7Sopenharmony_ci			}
1712e5c31af7Sopenharmony_ci		}
1713e5c31af7Sopenharmony_ci
1714e5c31af7Sopenharmony_ci		if (m_shaderProgramList[programIdx]->getBlendRequired() == true)
1715e5c31af7Sopenharmony_ci		{
1716e5c31af7Sopenharmony_ci			gl.enable(GL_BLEND);
1717e5c31af7Sopenharmony_ci			gl.blendEquation(GL_MAX);
1718e5c31af7Sopenharmony_ci			gl.blendFunc(GL_ONE, GL_ONE);
1719e5c31af7Sopenharmony_ci		}
1720e5c31af7Sopenharmony_ci		else
1721e5c31af7Sopenharmony_ci		{
1722e5c31af7Sopenharmony_ci			gl.disable(GL_BLEND);
1723e5c31af7Sopenharmony_ci		}
1724e5c31af7Sopenharmony_ci
1725e5c31af7Sopenharmony_ci		gl.drawArrays(GL_TRIANGLES, 0, 6);
1726e5c31af7Sopenharmony_ci
1727e5c31af7Sopenharmony_ci		// reset sRGB decode state on textures
1728e5c31af7Sopenharmony_ci		this->toggleDecode(m_shaderProgramList[programIdx]->getUniformDataList());
1729e5c31af7Sopenharmony_ci	}
1730e5c31af7Sopenharmony_ci
1731e5c31af7Sopenharmony_ci	for (std::size_t textureSourceIdx = 0; textureSourceIdx < m_textureSourceList.size(); textureSourceIdx++)
1732e5c31af7Sopenharmony_ci	{
1733e5c31af7Sopenharmony_ci		gl.bindTexture(m_textureSourceList[textureSourceIdx]->getGLTargetType(), 0);
1734e5c31af7Sopenharmony_ci	}
1735e5c31af7Sopenharmony_ci	gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
1736e5c31af7Sopenharmony_ci	gl.bindVertexArray(0);
1737e5c31af7Sopenharmony_ci	gl.bindBuffer(GL_ARRAY_BUFFER, 0);
1738e5c31af7Sopenharmony_ci}
1739e5c31af7Sopenharmony_ci
1740e5c31af7Sopenharmony_civoid DecodeToggledCase::setupTest (void)
1741e5c31af7Sopenharmony_ci{
1742e5c31af7Sopenharmony_ci	// TEST STEPS:
1743e5c31af7Sopenharmony_ci	//	- create and set texture_a to DECODE_SKIP_EXT and texture_b to DECODE_EXT
1744e5c31af7Sopenharmony_ci	//	- create and use two seperate shader programs, program_a and program_b, each using different fragment shaders
1745e5c31af7Sopenharmony_ci	//	- store texture_a and texture_b on GPU
1746e5c31af7Sopenharmony_ci	// FIRST PASS:
1747e5c31af7Sopenharmony_ci	//	- use program_a
1748e5c31af7Sopenharmony_ci	//	- in fragment shader, sample both textures using texture*() and manually perform sRGB to lRGB conversion on texture_a
1749e5c31af7Sopenharmony_ci	//	- in fragment shader, test converted texture_a value with texture_b
1750e5c31af7Sopenharmony_ci	//	- render green image for pass or red for fail
1751e5c31af7Sopenharmony_ci	//	- store result in a color attachement 0
1752e5c31af7Sopenharmony_ci	// TOGGLE STAGE
1753e5c31af7Sopenharmony_ci	//	- during rendering, toggle texture_a from DECODE_SKIP_EXT to DECODE_EXT
1754e5c31af7Sopenharmony_ci	// SECOND PASS:
1755e5c31af7Sopenharmony_ci	//	- use program_b
1756e5c31af7Sopenharmony_ci	//	- in fragment shader, sample both textures using texture*() and manually perform equality check. Both should be linear
1757e5c31af7Sopenharmony_ci	//	- blend first pass result with second pass. Anything but a green result equals fail
1758e5c31af7Sopenharmony_ci
1759e5c31af7Sopenharmony_ci	ComparisonFunction srgbToLinearFunction("srgbToLinearCheck", FUNCTIONPARAMETERS_TWO, getFunctionDefinitionSRGBToLinearCheck());
1760e5c31af7Sopenharmony_ci	ComparisonFunction colorsEqualFunction("colorsEqualCheck", FUNCTIONPARAMETERS_TWO, getFunctionDefinitionEqualCheck());
1761e5c31af7Sopenharmony_ci
1762e5c31af7Sopenharmony_ci	FragmentShaderParameters shaderParametersA(SHADEROUTPUTS_ONE, SHADERUNIFORMS_TWO, &srgbToLinearFunction, BLENDING_NOT_REQUIRED, TOGGLING_NOT_REQUIRED);
1763e5c31af7Sopenharmony_ci	FragmentShaderParameters shaderParametersB(SHADEROUTPUTS_ONE, SHADERUNIFORMS_TWO, &colorsEqualFunction, BLENDING_REQUIRED, TOGGLING_REQUIRED);
1764e5c31af7Sopenharmony_ci
1765e5c31af7Sopenharmony_ci	// need to specify which texture uniform to toggle DECODE_EXT/SKIP_DECODE_EXT
1766e5c31af7Sopenharmony_ci	shaderParametersB.uniformsToToggle.push_back("uTexture0");
1767e5c31af7Sopenharmony_ci
1768e5c31af7Sopenharmony_ci	this->addTexture(	TEXTURETYPE_2D,
1769e5c31af7Sopenharmony_ci						TestDimensions::WIDTH,
1770e5c31af7Sopenharmony_ci						TestDimensions::HEIGHT,
1771e5c31af7Sopenharmony_ci						getColorReferenceLinear(),
1772e5c31af7Sopenharmony_ci						tcu::Sampler::MIRRORED_REPEAT_GL,
1773e5c31af7Sopenharmony_ci						tcu::Sampler::MIRRORED_REPEAT_GL,
1774e5c31af7Sopenharmony_ci						tcu::Sampler::LINEAR,
1775e5c31af7Sopenharmony_ci						tcu::Sampler::LINEAR,
1776e5c31af7Sopenharmony_ci						SRGBDECODE_SKIP_DECODE);
1777e5c31af7Sopenharmony_ci
1778e5c31af7Sopenharmony_ci	this->addTexture(	TEXTURETYPE_2D,
1779e5c31af7Sopenharmony_ci						TestDimensions::WIDTH,
1780e5c31af7Sopenharmony_ci						TestDimensions::HEIGHT,
1781e5c31af7Sopenharmony_ci						getColorReferenceLinear(),
1782e5c31af7Sopenharmony_ci						tcu::Sampler::MIRRORED_REPEAT_GL,
1783e5c31af7Sopenharmony_ci						tcu::Sampler::MIRRORED_REPEAT_GL,
1784e5c31af7Sopenharmony_ci						tcu::Sampler::LINEAR,
1785e5c31af7Sopenharmony_ci						tcu::Sampler::LINEAR,
1786e5c31af7Sopenharmony_ci						SRGBDECODE_DECODE);
1787e5c31af7Sopenharmony_ci
1788e5c31af7Sopenharmony_ci	this->addShaderProgram(shaderParametersA);
1789e5c31af7Sopenharmony_ci	this->addShaderProgram(shaderParametersB);
1790e5c31af7Sopenharmony_ci
1791e5c31af7Sopenharmony_ci	this->setSamplingLocations(TestSamplingPositions::X_POS, TestSamplingPositions::Y_POS);
1792e5c31af7Sopenharmony_ci	this->setSamplingGroup(SHADERSAMPLINGGROUP_TEXTURE);
1793e5c31af7Sopenharmony_ci}
1794e5c31af7Sopenharmony_ci
1795e5c31af7Sopenharmony_cibool DecodeToggledCase::verifyResult (void)
1796e5c31af7Sopenharmony_ci{
1797e5c31af7Sopenharmony_ci	tcu::TestLog&			log				= m_context.getTestContext().getLog();
1798e5c31af7Sopenharmony_ci	const int				resultColorIdx	= 0;
1799e5c31af7Sopenharmony_ci	std::vector<tcu::Vec4>	pixelResultList;
1800e5c31af7Sopenharmony_ci
1801e5c31af7Sopenharmony_ci	this->readResultTextures();
1802e5c31af7Sopenharmony_ci	this->storeResultPixels(pixelResultList);
1803e5c31af7Sopenharmony_ci	this->logColor(std::string("Expected color: "), resultColorIdx, getColorGreenPass());
1804e5c31af7Sopenharmony_ci
1805e5c31af7Sopenharmony_ci	//	result color is either green (pass) or fail (red)
1806e5c31af7Sopenharmony_ci	if ( tcu::boolAll(tcu::equal(pixelResultList[resultColorIdx], getColorGreenPass())) )
1807e5c31af7Sopenharmony_ci	{
1808e5c31af7Sopenharmony_ci		log << tcu::TestLog::Message << std::string("returned pass color from GPU") << tcu::TestLog::EndMessage;
1809e5c31af7Sopenharmony_ci		return true;
1810e5c31af7Sopenharmony_ci	}
1811e5c31af7Sopenharmony_ci	else
1812e5c31af7Sopenharmony_ci	{
1813e5c31af7Sopenharmony_ci		log << tcu::TestLog::Message << std::string("returned fail color from GPU") << tcu::TestLog::EndMessage;
1814e5c31af7Sopenharmony_ci		return false;
1815e5c31af7Sopenharmony_ci	}
1816e5c31af7Sopenharmony_ci}
1817e5c31af7Sopenharmony_ci
1818e5c31af7Sopenharmony_ciclass DecodeMultipleTexturesCase : public SRGBTestCase
1819e5c31af7Sopenharmony_ci{
1820e5c31af7Sopenharmony_cipublic:
1821e5c31af7Sopenharmony_ci			DecodeMultipleTexturesCase	(Context& context, const char* name, const char* description, const tcu::TextureFormat internalFormat)
1822e5c31af7Sopenharmony_ci				: SRGBTestCase			(context, name, description, internalFormat) {}
1823e5c31af7Sopenharmony_ci
1824e5c31af7Sopenharmony_ci			~DecodeMultipleTexturesCase	(void) {}
1825e5c31af7Sopenharmony_ci
1826e5c31af7Sopenharmony_ci	void	setupTest					(void);
1827e5c31af7Sopenharmony_ci	bool	verifyResult				(void);
1828e5c31af7Sopenharmony_ci};
1829e5c31af7Sopenharmony_ci
1830e5c31af7Sopenharmony_civoid DecodeMultipleTexturesCase::setupTest (void)
1831e5c31af7Sopenharmony_ci{
1832e5c31af7Sopenharmony_ci	// TEST STEPS:
1833e5c31af7Sopenharmony_ci	//	- create and set texture_a to DECODE_SKIP_EXT and texture_b to DECODE_EXT
1834e5c31af7Sopenharmony_ci	//	- upload textures to the GPU and bind to seperate uniform variables
1835e5c31af7Sopenharmony_ci	//	- sample both textures using texture*()
1836e5c31af7Sopenharmony_ci	//	- read texel values back to the CPU
1837e5c31af7Sopenharmony_ci	//	- compare the texel values, both should be different from each other
1838e5c31af7Sopenharmony_ci
1839e5c31af7Sopenharmony_ci	FragmentShaderParameters shaderParameters(SHADEROUTPUTS_TWO, SHADERUNIFORMS_TWO, NULL,  BLENDING_NOT_REQUIRED, TOGGLING_NOT_REQUIRED);
1840e5c31af7Sopenharmony_ci
1841e5c31af7Sopenharmony_ci	this->addTexture(	TEXTURETYPE_2D,
1842e5c31af7Sopenharmony_ci						TestDimensions::WIDTH,
1843e5c31af7Sopenharmony_ci						TestDimensions::HEIGHT,
1844e5c31af7Sopenharmony_ci						getColorReferenceLinear(),
1845e5c31af7Sopenharmony_ci						tcu::Sampler::MIRRORED_REPEAT_GL,
1846e5c31af7Sopenharmony_ci						tcu::Sampler::MIRRORED_REPEAT_GL,
1847e5c31af7Sopenharmony_ci						tcu::Sampler::LINEAR,
1848e5c31af7Sopenharmony_ci						tcu::Sampler::LINEAR,
1849e5c31af7Sopenharmony_ci						SRGBDECODE_SKIP_DECODE);
1850e5c31af7Sopenharmony_ci
1851e5c31af7Sopenharmony_ci	this->addTexture(	TEXTURETYPE_2D,
1852e5c31af7Sopenharmony_ci						TestDimensions::WIDTH,
1853e5c31af7Sopenharmony_ci						TestDimensions::HEIGHT,
1854e5c31af7Sopenharmony_ci						getColorReferenceLinear(),
1855e5c31af7Sopenharmony_ci						tcu::Sampler::MIRRORED_REPEAT_GL,
1856e5c31af7Sopenharmony_ci						tcu::Sampler::MIRRORED_REPEAT_GL,
1857e5c31af7Sopenharmony_ci						tcu::Sampler::LINEAR,
1858e5c31af7Sopenharmony_ci						tcu::Sampler::LINEAR,
1859e5c31af7Sopenharmony_ci						SRGBDECODE_DECODE);
1860e5c31af7Sopenharmony_ci
1861e5c31af7Sopenharmony_ci	this->addShaderProgram(shaderParameters);
1862e5c31af7Sopenharmony_ci
1863e5c31af7Sopenharmony_ci	this->setSamplingLocations(TestSamplingPositions::X_POS, TestSamplingPositions::Y_POS);
1864e5c31af7Sopenharmony_ci	this->setSamplingGroup(SHADERSAMPLINGGROUP_TEXTURE);
1865e5c31af7Sopenharmony_ci}
1866e5c31af7Sopenharmony_ci
1867e5c31af7Sopenharmony_cibool DecodeMultipleTexturesCase::verifyResult (void)
1868e5c31af7Sopenharmony_ci{
1869e5c31af7Sopenharmony_ci	tcu::TestLog&			log				= m_context.getTestContext().getLog();
1870e5c31af7Sopenharmony_ci	const int				resultColorIdx	= 0;
1871e5c31af7Sopenharmony_ci	std::vector<tcu::Vec4>	pixelResultList;
1872e5c31af7Sopenharmony_ci	tcu::Vec4				pixelExpected0;
1873e5c31af7Sopenharmony_ci	tcu::Vec4				pixelExpected1;
1874e5c31af7Sopenharmony_ci
1875e5c31af7Sopenharmony_ci	this->readResultTextures();
1876e5c31af7Sopenharmony_ci	this->storeResultPixels(pixelResultList);
1877e5c31af7Sopenharmony_ci
1878e5c31af7Sopenharmony_ci	pixelExpected0 = this->formatReferenceColor(getColorReferenceSRGB());
1879e5c31af7Sopenharmony_ci	pixelExpected1 = this->formatReferenceColor(getColorReferenceLinear());
1880e5c31af7Sopenharmony_ci
1881e5c31af7Sopenharmony_ci	this->logColor(std::string("Expected color: "), resultColorIdx, pixelExpected0);
1882e5c31af7Sopenharmony_ci	this->logColor(std::string("Expected color: "), resultColorIdx +1, pixelExpected1);
1883e5c31af7Sopenharmony_ci
1884e5c31af7Sopenharmony_ci	//	check if the two textures have different values i.e. uTexture0 = sRGB and uTexture1 = linear
1885e5c31af7Sopenharmony_ci	if ( !(tcu::boolAll(tcu::equal(pixelResultList[resultColorIdx], pixelResultList[resultColorIdx +1]))) )
1886e5c31af7Sopenharmony_ci	{
1887e5c31af7Sopenharmony_ci		log << tcu::TestLog::Message << std::string("texel values are different") << tcu::TestLog::EndMessage;
1888e5c31af7Sopenharmony_ci		return true;
1889e5c31af7Sopenharmony_ci	}
1890e5c31af7Sopenharmony_ci	else
1891e5c31af7Sopenharmony_ci	{
1892e5c31af7Sopenharmony_ci		log << tcu::TestLog::Message << std::string("texel values are equal") << tcu::TestLog::EndMessage;
1893e5c31af7Sopenharmony_ci		return false;
1894e5c31af7Sopenharmony_ci	}
1895e5c31af7Sopenharmony_ci}
1896e5c31af7Sopenharmony_ci
1897e5c31af7Sopenharmony_ciclass DecodeSamplerCase : public SRGBTestCase
1898e5c31af7Sopenharmony_ci{
1899e5c31af7Sopenharmony_cipublic:
1900e5c31af7Sopenharmony_ci			DecodeSamplerCase	(Context& context, const char* name, const char* description, const tcu::TextureFormat internalFormat)
1901e5c31af7Sopenharmony_ci				: SRGBTestCase	(context, name, description, internalFormat) {}
1902e5c31af7Sopenharmony_ci
1903e5c31af7Sopenharmony_ci			~DecodeSamplerCase	(void) {}
1904e5c31af7Sopenharmony_ci
1905e5c31af7Sopenharmony_ci	void	setupTest			(void);
1906e5c31af7Sopenharmony_ci	bool	verifyResult		(void);
1907e5c31af7Sopenharmony_ci};
1908e5c31af7Sopenharmony_ci
1909e5c31af7Sopenharmony_civoid DecodeSamplerCase::setupTest (void)
1910e5c31af7Sopenharmony_ci{
1911e5c31af7Sopenharmony_ci	// TEST STEPS:
1912e5c31af7Sopenharmony_ci	//	- create and set texture_a to DECODE_SKIP_EXT
1913e5c31af7Sopenharmony_ci	//	- upload texture to the GPU and bind to sampler
1914e5c31af7Sopenharmony_ci	//	- sample texture using texture*()
1915e5c31af7Sopenharmony_ci	//	- read texel values back to the CPU
1916e5c31af7Sopenharmony_ci	//	- compare the texel values, should be in sampler format (linear)
1917e5c31af7Sopenharmony_ci
1918e5c31af7Sopenharmony_ci	FragmentShaderParameters shaderParameters(SHADEROUTPUTS_ONE, SHADERUNIFORMS_ONE, NULL, BLENDING_NOT_REQUIRED, TOGGLING_NOT_REQUIRED);
1919e5c31af7Sopenharmony_ci
1920e5c31af7Sopenharmony_ci	this->addTexture(	TEXTURETYPE_2D,
1921e5c31af7Sopenharmony_ci						TestDimensions::WIDTH,
1922e5c31af7Sopenharmony_ci						TestDimensions::HEIGHT,
1923e5c31af7Sopenharmony_ci						getColorReferenceLinear(),
1924e5c31af7Sopenharmony_ci						tcu::Sampler::MIRRORED_REPEAT_GL,
1925e5c31af7Sopenharmony_ci						tcu::Sampler::MIRRORED_REPEAT_GL,
1926e5c31af7Sopenharmony_ci						tcu::Sampler::LINEAR,
1927e5c31af7Sopenharmony_ci						tcu::Sampler::LINEAR,
1928e5c31af7Sopenharmony_ci						SRGBDECODE_SKIP_DECODE);
1929e5c31af7Sopenharmony_ci
1930e5c31af7Sopenharmony_ci	this->addSampler(	tcu::Sampler::MIRRORED_REPEAT_GL,
1931e5c31af7Sopenharmony_ci						tcu::Sampler::MIRRORED_REPEAT_GL,
1932e5c31af7Sopenharmony_ci						tcu::Sampler::LINEAR,
1933e5c31af7Sopenharmony_ci						tcu::Sampler::LINEAR,
1934e5c31af7Sopenharmony_ci						SRGBDECODE_DECODE);
1935e5c31af7Sopenharmony_ci
1936e5c31af7Sopenharmony_ci	this->addShaderProgram(shaderParameters);
1937e5c31af7Sopenharmony_ci
1938e5c31af7Sopenharmony_ci	this->bindSamplerToTexture(0, 0, GL_TEXTURE0);
1939e5c31af7Sopenharmony_ci	this->activateSampler(0, true);
1940e5c31af7Sopenharmony_ci
1941e5c31af7Sopenharmony_ci	this->setSamplingLocations(TestSamplingPositions::X_POS, TestSamplingPositions::Y_POS);
1942e5c31af7Sopenharmony_ci	this->setSamplingGroup(SHADERSAMPLINGGROUP_TEXTURE);
1943e5c31af7Sopenharmony_ci}
1944e5c31af7Sopenharmony_ci
1945e5c31af7Sopenharmony_cibool DecodeSamplerCase::verifyResult (void)
1946e5c31af7Sopenharmony_ci{
1947e5c31af7Sopenharmony_ci	tcu::TestLog&			log				= m_context.getTestContext().getLog();
1948e5c31af7Sopenharmony_ci	const int				resultColorIdx	= 0;
1949e5c31af7Sopenharmony_ci	std::vector<tcu::Vec4>	pixelResultList;
1950e5c31af7Sopenharmony_ci	tcu::Vec4				pixelConverted;
1951e5c31af7Sopenharmony_ci	tcu::Vec4				pixelReference;
1952e5c31af7Sopenharmony_ci	tcu::Vec4				pixelExpected;
1953e5c31af7Sopenharmony_ci
1954e5c31af7Sopenharmony_ci	this->readResultTextures();
1955e5c31af7Sopenharmony_ci	this->storeResultPixels(pixelResultList);
1956e5c31af7Sopenharmony_ci
1957e5c31af7Sopenharmony_ci	pixelConverted = tcu::linearToSRGB(pixelResultList[resultColorIdx]);
1958e5c31af7Sopenharmony_ci	pixelReference = this->formatReferenceColor(getColorReferenceSRGB());
1959e5c31af7Sopenharmony_ci	pixelExpected = this->formatReferenceColor(getColorReferenceLinear());
1960e5c31af7Sopenharmony_ci
1961e5c31af7Sopenharmony_ci	this->logColor(std::string("Expected color: "), resultColorIdx, pixelExpected);
1962e5c31af7Sopenharmony_ci
1963e5c31af7Sopenharmony_ci	//	texture was rendered using a sampler object with setting DECODE_EXT, therefore, results should be linear
1964e5c31af7Sopenharmony_ci	if ( (tcu::boolAll(tcu::lessThan(tcu::abs(pixelConverted - pixelReference), m_epsilonError))) || (tcu::boolAll(tcu::equal(pixelConverted, pixelReference))) )
1965e5c31af7Sopenharmony_ci	{
1966e5c31af7Sopenharmony_ci		log << tcu::TestLog::Message << std::string("linear as expected") << tcu::TestLog::EndMessage;
1967e5c31af7Sopenharmony_ci		return true;
1968e5c31af7Sopenharmony_ci	}
1969e5c31af7Sopenharmony_ci	else
1970e5c31af7Sopenharmony_ci	{
1971e5c31af7Sopenharmony_ci		log << tcu::TestLog::Message << std::string("not linear as expected") << tcu::TestLog::EndMessage;
1972e5c31af7Sopenharmony_ci		return false;
1973e5c31af7Sopenharmony_ci	}
1974e5c31af7Sopenharmony_ci}
1975e5c31af7Sopenharmony_ci
1976e5c31af7Sopenharmony_ci} // anonymous
1977e5c31af7Sopenharmony_ci
1978e5c31af7Sopenharmony_ciSRGBDecodeTests::SRGBDecodeTests	(Context& context)
1979e5c31af7Sopenharmony_ci	: TestCaseGroup					(context, "skip_decode", "sRGB skip decode tests")
1980e5c31af7Sopenharmony_ci{
1981e5c31af7Sopenharmony_ci}
1982e5c31af7Sopenharmony_ci
1983e5c31af7Sopenharmony_ciSRGBDecodeTests::~SRGBDecodeTests (void)
1984e5c31af7Sopenharmony_ci{
1985e5c31af7Sopenharmony_ci}
1986e5c31af7Sopenharmony_ci
1987e5c31af7Sopenharmony_civoid SRGBDecodeTests::init (void)
1988e5c31af7Sopenharmony_ci{
1989e5c31af7Sopenharmony_ci	const TestGroupConfig testGroupConfigList[] =
1990e5c31af7Sopenharmony_ci	{
1991e5c31af7Sopenharmony_ci		TestGroupConfig("srgba8",	"srgb decode tests using srgba internal format",	tcu::TextureFormat(tcu::TextureFormat::sRGBA, tcu::TextureFormat::UNORM_INT8)),
1992e5c31af7Sopenharmony_ci		TestGroupConfig("srg8",		"srgb decode tests using srg8 internal format",		tcu::TextureFormat(tcu::TextureFormat::sRG, tcu::TextureFormat::UNORM_INT8)),
1993e5c31af7Sopenharmony_ci		TestGroupConfig("sr8",		"srgb decode tests using sr8 internal format",		tcu::TextureFormat(tcu::TextureFormat::sR, tcu::TextureFormat::UNORM_INT8))
1994e5c31af7Sopenharmony_ci	};
1995e5c31af7Sopenharmony_ci
1996e5c31af7Sopenharmony_ci	// create groups for all desired internal formats, adding test cases to each
1997e5c31af7Sopenharmony_ci	for (std::size_t idx = 0; idx < DE_LENGTH_OF_ARRAY(testGroupConfigList); idx++)
1998e5c31af7Sopenharmony_ci	{
1999e5c31af7Sopenharmony_ci		tcu::TestCaseGroup* const testGroup = new tcu::TestCaseGroup(m_testCtx, testGroupConfigList[idx].name, testGroupConfigList[idx].description);
2000e5c31af7Sopenharmony_ci		tcu::TestNode::addChild(testGroup);
2001e5c31af7Sopenharmony_ci
2002e5c31af7Sopenharmony_ci		testGroup->addChild(new TextureDecodeSkippedCase		(m_context, "skipped",			"testing for sRGB color values with sRGB texture decoding skipped",		testGroupConfigList[idx].internalFormat));
2003e5c31af7Sopenharmony_ci		testGroup->addChild(new TextureDecodeEnabledCase		(m_context, "enabled",			"testing for linear color values with sRGB texture decoding enabled",	testGroupConfigList[idx].internalFormat));
2004e5c31af7Sopenharmony_ci		testGroup->addChild(new TexelFetchDecodeSkippedcase		(m_context, "texel_fetch",		"testing for linear color values with sRGB texture decoding skipped",	testGroupConfigList[idx].internalFormat));
2005e5c31af7Sopenharmony_ci		testGroup->addChild(new GPUConversionDecodeEnabledCase	(m_context, "conversion_gpu",	"sampling linear values and performing conversion on the gpu",			testGroupConfigList[idx].internalFormat));
2006e5c31af7Sopenharmony_ci		testGroup->addChild(new DecodeToggledCase				(m_context, "toggled",			"toggle the sRGB decoding between draw calls",							testGroupConfigList[idx].internalFormat));
2007e5c31af7Sopenharmony_ci		testGroup->addChild(new DecodeMultipleTexturesCase		(m_context, "multiple_textures","upload multiple textures with different sRGB decode values and sample",testGroupConfigList[idx].internalFormat));
2008e5c31af7Sopenharmony_ci		testGroup->addChild(new DecodeSamplerCase				(m_context, "using_sampler",	"testing that sampler object takes priority over texture state",		testGroupConfigList[idx].internalFormat));
2009e5c31af7Sopenharmony_ci	}
2010e5c31af7Sopenharmony_ci}
2011e5c31af7Sopenharmony_ci
2012e5c31af7Sopenharmony_ci} // Functional
2013e5c31af7Sopenharmony_ci} // gles31
2014e5c31af7Sopenharmony_ci} // deqp
2015