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