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