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