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