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