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