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 FBO sRGB tests.
22 *//*--------------------------------------------------------------------*/
23
24 #include "es31fFboSRGBWriteControlTests.hpp"
25 #include "es31fFboTestUtil.hpp"
26 #include "gluTextureUtil.hpp"
27 #include "gluContextInfo.hpp"
28 #include "tcuTestLog.hpp"
29 #include "glwEnums.hpp"
30 #include "sglrContextUtil.hpp"
31 #include "glwFunctions.hpp"
32 #include "deUniquePtr.hpp"
33 #include "deSharedPtr.hpp"
34 #include "gluObjectWrapper.hpp"
35 #include "gluPixelTransfer.hpp"
36 #include "glsTextureTestUtil.hpp"
37 #include "tcuVectorUtil.hpp"
38 #include "gluStrUtil.hpp"
39
40 namespace deqp
41 {
42 namespace gles31
43 {
44 namespace Functional
45 {
46 namespace
47 {
48
getTestColorLinear(void)49 tcu::Vec4 getTestColorLinear (void)
50 {
51 return tcu::Vec4(0.2f, 0.3f, 0.4f, 1.0f);
52 }
53
getTestColorSRGB(void)54 tcu::Vec4 getTestColorSRGB (void)
55 {
56 return linearToSRGB(tcu::Vec4(0.2f, 0.3f, 0.4f, 1.0f));
57 }
58
getTestColorBlank(void)59 tcu::Vec4 getTestColorBlank (void)
60 {
61 return tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
62 }
63
getEpsilonError(void)64 tcu::Vec4 getEpsilonError (void)
65 {
66 return tcu::Vec4(0.005f);
67 }
68
69 enum QueryType
70 {
71 QUERYTYPE_ISENABLED = 0,
72 QUERYTYPE_BOOLEAN,
73 QUERYTYPE_FLOAT,
74 QUERYTYPE_INT,
75 QUERYTYPE_INT64,
76 QUERYTYPE_LAST
77 };
78
79 enum DataType
80 {
81 DATATYPE_BOOLEAN = 0,
82 DATATYPE_FLOAT,
83 DATATYPE_INT,
84 DATATYPE_INT64,
85 };
86
87 enum FramebufferSRGB
88 {
89 FRAMEBUFFERSRGB_ENABLED = 0,
90 FRAMEBUFFERSRGB_DISABLED
91 };
92
93 enum FramebufferBlend
94 {
95 FRAMEBUFFERBLEND_ENABLED = 0,
96 FRAMEBUFFERBLEND_DISABLED
97 };
98
99 enum TextureSourcesType
100 {
101 TEXTURESOURCESTYPE_RGBA = 0,
102 TEXTURESOURCESTYPE_SRGBA,
103 TEXTURESOURCESTYPE_BOTH,
104 TEXTURESOURCESTYPE_NONE
105 };
106
107 enum FboType
108 {
109 FBOTYPE_SOURCE = 0,
110 FBOTYPE_DESTINATION
111 };
112
113 enum RendererTask
114 {
115 RENDERERTASK_DRAW = 0,
116 RENDERERTASK_COPY
117 };
118
119 enum SamplingType
120 {
121 SAMPLINGTYPE_TEXTURE = 0,
122 SAMPLINGTYPE_TEXTURE_LOD,
123 SAMPLINGTYPE_TEXTURE_GRAD,
124 SAMPLINGTYPE_TEXTURE_OFFSET,
125 SAMPLINGTYPE_TEXTURE_PROJ,
126 };
127
128 namespace TestTextureSizes
129 {
130 const int WIDTH = 128;
131 const int HEIGHT = 128;
132 } // global test texture sizes
133
134 namespace SampligTypeCount
135 {
136 const int MAX = 5;
137 } // global max number of sampling types
138
buildSamplingPassType(const int samplerTotal)139 std::string buildSamplingPassType (const int samplerTotal)
140 {
141 std::ostringstream shaderFragment;
142
143 const SamplingType samplingTypeList [] =
144 {
145 SAMPLINGTYPE_TEXTURE, SAMPLINGTYPE_TEXTURE_LOD, SAMPLINGTYPE_TEXTURE_GRAD, SAMPLINGTYPE_TEXTURE_OFFSET, SAMPLINGTYPE_TEXTURE_PROJ
146 } ;
147
148 for (int samplerTypeIdx = 0; samplerTypeIdx < DE_LENGTH_OF_ARRAY(samplingTypeList); samplerTypeIdx++)
149 {
150 shaderFragment
151 << " if (uFunctionType == " << samplerTypeIdx << ") \n"
152 << " { \n";
153
154 for (int samplerIdx = 0; samplerIdx < samplerTotal; samplerIdx++)
155 {
156 switch (static_cast<SamplingType>(samplerTypeIdx))
157 {
158 case SAMPLINGTYPE_TEXTURE:
159 {
160 shaderFragment
161 << " texelColor" << samplerIdx << " = texture(uTexture" << samplerIdx << ", vs_aTexCoord); \n";
162 break;
163 }
164 case SAMPLINGTYPE_TEXTURE_LOD:
165 {
166 shaderFragment
167 << " texelColor" << samplerIdx << " = textureLod(uTexture" << samplerIdx << ", vs_aTexCoord, 0.0f); \n";
168 break;
169 }
170 case SAMPLINGTYPE_TEXTURE_GRAD:
171 {
172 shaderFragment
173 << " texelColor" << samplerIdx << " = textureGrad(uTexture" << samplerIdx << ", vs_aTexCoord, vec2(0.0f, 0.0f), vec2(0.0f, 0.0f)); \n";
174 break;
175 }
176 case SAMPLINGTYPE_TEXTURE_OFFSET:
177 {
178 shaderFragment
179 << " texelColor" << samplerIdx << " = textureOffset(uTexture" << samplerIdx << ", vs_aTexCoord, ivec2(0.0f, 0.0f)); \n";
180 break;
181 }
182 case SAMPLINGTYPE_TEXTURE_PROJ:
183 {
184 shaderFragment
185 << " texelColor" << samplerIdx << " = textureProj(uTexture" << samplerIdx << ", vec3(vs_aTexCoord, 1.0f)); \n";
186 break;
187 }
188 default:
189 DE_FATAL("Error: sampling type unrecognised");
190 }
191 }
192
193 shaderFragment
194 << " } \n";
195 }
196
197 return shaderFragment.str();
198 }
199
logColor(Context & context,const std::string & colorLogMessage,const tcu::Vec4 resultColor)200 void logColor (Context& context, const std::string& colorLogMessage, const tcu::Vec4 resultColor)
201 {
202 tcu::TestLog& log = context.getTestContext().getLog();
203 std::ostringstream message;
204
205 message << colorLogMessage << " = (" << resultColor.x() << ", " << resultColor.y() << ", " << resultColor.z() << ", " << resultColor.w() << ")";
206 log << tcu::TestLog::Message << message.str() << tcu::TestLog::EndMessage;
207 }
208
209 struct TestFunction
210 {
TestFunctiondeqp::gles31::Functional::__anon6afaefe80111::TestFunction211 explicit TestFunction (const bool hasFunctionValue)
212 : hasFunction (hasFunctionValue) {}
TestFunctiondeqp::gles31::Functional::__anon6afaefe80111::TestFunction213 TestFunction (const char* const functionNameValue, const char* const functionDefinition)
214 : hasFunction (true)
215 , functionName (functionNameValue)
216 , functionDefintion (functionDefinition) {}
~TestFunctiondeqp::gles31::Functional::__anon6afaefe80111::TestFunction217 ~TestFunction (void) {}
218
219 bool hasFunction;
220 const char* functionName;
221 const char* functionDefintion;
222 };
223
getFunctionBlendLinearToSRGBCheck(void)224 TestFunction getFunctionBlendLinearToSRGBCheck (void)
225 {
226 const char* const functionName = "blendPlusLinearToSRGB";
227
228 const char* const functionDefinition =
229 "mediump vec4 blendPlusLinearToSRGB(in mediump vec4 colorSrc, in mediump vec4 colorDst) \n"
230 "{ \n"
231 " const int MAX_VECTOR_SIZE = 4; \n"
232 " mediump vec4 colorConverted; \n"
233 " mediump vec4 colorBlended; \n"
234 " for (int idx = 0; idx < MAX_VECTOR_SIZE; idx++) \n"
235 " { \n"
236 " if (uBlendFunctionType == 0) \n"
237 " { \n"
238 " colorBlended[idx] = (colorSrc[idx] * uFactorSrc) + colorDst[idx] * uFactorDst; \n"
239 " } \n"
240 " if (uBlendFunctionType == 1) \n"
241 " { \n"
242 " colorBlended[idx] = (colorSrc[idx] * uFactorSrc) - (colorDst[idx] * uFactorDst); \n"
243 " } \n"
244 "if (uBlendFunctionType == 2) \n"
245 " { \n"
246 " colorBlended[idx] = (colorDst[idx] * uFactorDst) - (colorSrc[idx] * uFactorSrc); \n"
247 " } \n"
248 " if (colorBlended[idx] < 0.0031308f) \n"
249 " { \n"
250 " colorConverted[idx] = 12.92f * colorBlended[idx]; \n"
251 " } \n"
252 " else \n"
253 " { \n"
254 " colorConverted[idx] = 1.055f * pow(colorBlended[idx], 0.41666f) - 0.055f; \n"
255 " } \n"
256 " } \n"
257 " return colorConverted; \n"
258 "} \n";
259
260 TestFunction testFunction(functionName, functionDefinition);
261
262 return testFunction;
263 }
264
265 struct FBOConfig
266 {
FBOConfigdeqp::gles31::Functional::__anon6afaefe80111::FBOConfig267 FBOConfig (const deUint32 textureInternalFormatValue,
268 const tcu::Vec4 textureColorValue,
269 const deUint32 fboTargetTypeValue,
270 const deUint32 fboColorAttachmentValue,
271 const FboType fboTypeValue)
272 : textureInternalFormat (textureInternalFormatValue)
273 , textureColor (textureColorValue)
274 , fboTargetType (fboTargetTypeValue)
275 , fboColorAttachment (fboColorAttachmentValue)
276 , fboType (fboTypeValue) {}
~FBOConfigdeqp::gles31::Functional::__anon6afaefe80111::FBOConfig277 ~FBOConfig (void) {}
278
279 deUint32 textureInternalFormat;
280 tcu::Vec4 textureColor;
281 deUint32 fboTargetType;
282 deUint32 fboColorAttachment;
283 FboType fboType;
284 };
285
286 struct BlendConfig
287 {
288 deUint32 equation;
289 deUint32 funcSrc;
290 deUint32 funcDst;
291 };
292
getBlendingConfigList(void)293 std::vector<BlendConfig> getBlendingConfigList (void)
294 {
295 BlendConfig blendConfigs[12];
296
297 // add function permutations
298 blendConfigs[0].equation = GL_FUNC_ADD;
299 blendConfigs[1].equation = GL_FUNC_ADD;
300 blendConfigs[2].equation = GL_FUNC_ADD;
301 blendConfigs[3].equation = GL_FUNC_ADD;
302
303 blendConfigs[0].funcSrc = GL_ONE;
304 blendConfigs[0].funcDst = GL_ONE;
305 blendConfigs[1].funcSrc = GL_ONE;
306 blendConfigs[1].funcDst = GL_ZERO;
307 blendConfigs[2].funcSrc = GL_ZERO;
308 blendConfigs[2].funcDst = GL_ONE;
309 blendConfigs[3].funcSrc = GL_ZERO;
310 blendConfigs[3].funcDst = GL_ZERO;
311
312 // subtract function permutations
313 blendConfigs[4].equation = GL_FUNC_SUBTRACT;
314 blendConfigs[5].equation = GL_FUNC_SUBTRACT;
315 blendConfigs[6].equation = GL_FUNC_SUBTRACT;
316 blendConfigs[7].equation = GL_FUNC_SUBTRACT;
317
318 blendConfigs[4].funcSrc = GL_ONE;
319 blendConfigs[4].funcDst = GL_ONE;
320 blendConfigs[5].funcSrc = GL_ONE;
321 blendConfigs[5].funcDst = GL_ZERO;
322 blendConfigs[6].funcSrc = GL_ZERO;
323 blendConfigs[6].funcDst = GL_ONE;
324 blendConfigs[7].funcSrc = GL_ZERO;
325 blendConfigs[7].funcDst = GL_ZERO;
326
327 // reverse subtract function permutations
328 blendConfigs[8].equation = GL_FUNC_REVERSE_SUBTRACT;
329 blendConfigs[9].equation = GL_FUNC_REVERSE_SUBTRACT;
330 blendConfigs[10].equation = GL_FUNC_REVERSE_SUBTRACT;
331 blendConfigs[11].equation = GL_FUNC_REVERSE_SUBTRACT;
332
333 blendConfigs[8].funcSrc = GL_ONE;
334 blendConfigs[8].funcDst = GL_ONE;
335 blendConfigs[9].funcSrc = GL_ONE;
336 blendConfigs[9].funcDst = GL_ZERO;
337 blendConfigs[10].funcSrc = GL_ZERO;
338 blendConfigs[10].funcDst = GL_ONE;
339 blendConfigs[11].funcSrc = GL_ZERO;
340 blendConfigs[11].funcDst = GL_ZERO;
341
342 std::vector<BlendConfig> configList(blendConfigs, blendConfigs + DE_LENGTH_OF_ARRAY(blendConfigs));
343
344 return configList;
345 }
346
347 struct TestRenderPassConfig
348 {
TestRenderPassConfigdeqp::gles31::Functional::__anon6afaefe80111::TestRenderPassConfig349 TestRenderPassConfig (void)
350 : testFunction (false) {}
351
TestRenderPassConfigdeqp::gles31::Functional::__anon6afaefe80111::TestRenderPassConfig352 TestRenderPassConfig (const TextureSourcesType textureSourcesTypeValue,
353 FBOConfig fboConfigListValue,
354 const FramebufferSRGB framebufferSRGBValue,
355 const FramebufferBlend framebufferBendValue,
356 const RendererTask rendererTaskValue)
357 : textureSourcesType (textureSourcesTypeValue)
358 , framebufferSRGB (framebufferSRGBValue)
359 , frameBufferBlend (framebufferBendValue)
360 , testFunction (false)
361 , rendererTask (rendererTaskValue) {fboConfigList.push_back(fboConfigListValue);}
362
TestRenderPassConfigdeqp::gles31::Functional::__anon6afaefe80111::TestRenderPassConfig363 TestRenderPassConfig (const TextureSourcesType textureSourcesTypeValue,
364 FBOConfig fboConfigListValue,
365 const FramebufferSRGB framebufferSRGBValue,
366 const FramebufferBlend framebufferBendValue,
367 TestFunction testFunctionValue,
368 const RendererTask rendererTaskValue)
369 : textureSourcesType (textureSourcesTypeValue)
370 , framebufferSRGB (framebufferSRGBValue)
371 , frameBufferBlend (framebufferBendValue)
372 , testFunction (testFunctionValue)
373 , rendererTask (rendererTaskValue) {fboConfigList.push_back(fboConfigListValue);}
374
TestRenderPassConfigdeqp::gles31::Functional::__anon6afaefe80111::TestRenderPassConfig375 TestRenderPassConfig (const TextureSourcesType textureSourcesTypeValue,
376 std::vector<FBOConfig> fboConfigListValue,
377 const FramebufferSRGB framebufferSRGBValue,
378 const FramebufferBlend framebufferBendValue,
379 TestFunction testFunctionValue,
380 const RendererTask rendererTaskValue)
381 : textureSourcesType (textureSourcesTypeValue)
382 , fboConfigList (fboConfigListValue)
383 , framebufferSRGB (framebufferSRGBValue)
384 , frameBufferBlend (framebufferBendValue)
385 , testFunction (testFunctionValue)
386 , rendererTask (rendererTaskValue) {}
387
~TestRenderPassConfigdeqp::gles31::Functional::__anon6afaefe80111::TestRenderPassConfig388 ~TestRenderPassConfig (void) {}
389
390 TextureSourcesType textureSourcesType;
391 std::vector<FBOConfig> fboConfigList;
392 FramebufferSRGB framebufferSRGB;
393 FramebufferBlend frameBufferBlend;
394 TestFunction testFunction;
395 RendererTask rendererTask;
396 };
397
398 class TestVertexData
399 {
400 public:
401 TestVertexData (Context& context);
402 ~TestVertexData (void);
403
404 void init (void);
405
406 void bind (void) const;
407 void unbind (void) const;
408
409 private:
410 const glw::Functions* m_gl;
411 std::vector<float> m_data;
412 glw::GLuint m_vboHandle;
413 glw::GLuint m_vaoHandle;
414 };
415
TestVertexData(Context & context)416 TestVertexData::TestVertexData (Context& context)
417 : m_gl (&context.getRenderContext().getFunctions())
418 {
419 const glw::GLfloat vertexData[] =
420 {
421 // position // texcoord
422 -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, // bottom left corner
423 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, // bottom right corner
424 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, // Top right corner
425
426 -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, // top left corner
427 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, // Top right corner
428 -1.0f, -1.0f, 0.0f, 0.0f, 0.0f // bottom left corner
429 };
430
431 m_data.resize(DE_LENGTH_OF_ARRAY(vertexData));
432 for (int idx = 0; idx < (int)m_data.size(); idx++)
433 m_data[idx] = vertexData[idx];
434
435 m_gl->genVertexArrays(1, &m_vaoHandle);
436 m_gl->bindVertexArray(m_vaoHandle);
437
438 m_gl->genBuffers(1, &m_vboHandle);
439 m_gl->bindBuffer(GL_ARRAY_BUFFER, m_vboHandle);
440
441 m_gl->bufferData(GL_ARRAY_BUFFER, (glw::GLsizei)(m_data.size() * sizeof(glw::GLfloat)), &m_data[0], GL_STATIC_DRAW);
442
443 m_gl->enableVertexAttribArray(0);
444 m_gl->vertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * (glw::GLsizei)sizeof(GL_FLOAT), (glw::GLvoid *)0);
445 m_gl->enableVertexAttribArray(1);
446 m_gl->vertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * (glw::GLsizei)sizeof(GL_FLOAT), (glw::GLvoid *)(3 * sizeof(GL_FLOAT)));
447
448 m_gl->bindVertexArray(0);
449 m_gl->bindBuffer(GL_ARRAY_BUFFER, 0);
450 GLU_EXPECT_NO_ERROR(m_gl->getError(), "gl error during vertex data setup");
451 }
452
~TestVertexData(void)453 TestVertexData::~TestVertexData (void)
454 {
455 m_gl->deleteBuffers(1, &m_vboHandle);
456 m_gl->deleteVertexArrays(1, &m_vaoHandle);
457 }
458
bind(void) const459 void TestVertexData::bind (void) const
460 {
461 m_gl->bindVertexArray(m_vaoHandle);
462 }
463
unbind(void) const464 void TestVertexData::unbind (void) const
465 {
466 m_gl->bindVertexArray(0);
467 }
468
469 class TestTexture2D
470 {
471 public:
472 TestTexture2D (Context& context, const deUint32 internalFormatValue, const deUint32 transferFormatValue, const deUint32 transferTypeValue, const tcu::Vec4 imageColorValue, const int idx);
473 ~TestTexture2D (void);
474
475 int getTextureUnit (void) const;
476 deUint32 getHandle (void) const;
477 int getIdx (void) const;
478
479 void bind (const int textureUnit);
480 void unbind (void) const;
481
482 private:
483 const glw::Functions* m_gl;
484 glw::GLuint m_handle;
485 const deUint32 m_internalFormat;
486 tcu::TextureFormat m_transferFormat;
487 int m_width;
488 int m_height;
489 tcu::TextureLevel m_imageData;
490 int m_textureUnit;
491 const int m_idx;
492 };
493
TestTexture2D(Context & context,const deUint32 internalFormat,const deUint32 transferFormat,const deUint32 transferType,const tcu::Vec4 imageColor,const int idx)494 TestTexture2D::TestTexture2D (Context& context, const deUint32 internalFormat, const deUint32 transferFormat, const deUint32 transferType, const tcu::Vec4 imageColor, const int idx)
495 : m_gl (&context.getRenderContext().getFunctions())
496 , m_internalFormat (internalFormat)
497 , m_transferFormat (tcu::TextureFormat(glu::mapGLTransferFormat(transferFormat, transferType)))
498 , m_width (TestTextureSizes::WIDTH)
499 , m_height (TestTextureSizes::HEIGHT)
500 , m_imageData (tcu::TextureLevel(glu::mapGLInternalFormat(internalFormat), m_width, m_height, 1))
501 , m_idx (idx)
502 {
503 // fill image data with a solid test color
504 tcu::clear(m_imageData.getAccess(), tcu::Vec4(0.0f));
505 for (int py = 0; py < m_imageData.getHeight(); py++)
506 {
507 for (int px = 0; px < m_imageData.getWidth(); px++)
508 m_imageData.getAccess().setPixel(imageColor, px, py);
509 }
510
511 m_gl->genTextures(1, &m_handle);
512
513 m_gl->bindTexture(GL_TEXTURE_2D, m_handle);
514 m_gl->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
515 m_gl->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
516 m_gl->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
517 m_gl->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
518
519 m_gl->texImage2D(GL_TEXTURE_2D, 0, m_internalFormat, m_width, m_height, 0, transferFormat, transferType, m_imageData.getAccess().getDataPtr());
520
521 m_gl->bindTexture(GL_TEXTURE_2D, 0);
522 }
523
~TestTexture2D(void)524 TestTexture2D::~TestTexture2D (void)
525 {
526 m_gl->deleteTextures(1, &m_handle);
527 }
528
getTextureUnit(void) const529 int TestTexture2D::getTextureUnit (void) const
530 {
531 return m_textureUnit;
532 }
533
getHandle(void) const534 deUint32 TestTexture2D::getHandle (void) const
535 {
536 return m_handle;
537 }
538
getIdx(void) const539 int TestTexture2D::getIdx (void) const
540 {
541 return m_idx;
542 }
543
bind(const int textureUnit)544 void TestTexture2D::bind (const int textureUnit)
545 {
546 m_textureUnit = textureUnit;
547 m_gl->activeTexture(GL_TEXTURE0 + m_textureUnit);
548 m_gl->bindTexture(GL_TEXTURE_2D, m_handle);
549 }
550
unbind(void) const551 void TestTexture2D::unbind (void) const
552 {
553 m_gl->bindTexture(GL_TEXTURE_2D, 0);
554 }
555
556 class TestFramebuffer
557 {
558 public:
559 TestFramebuffer (void);
560 TestFramebuffer (Context& context, const deUint32 targetType, const deUint32 colorAttachment, glw::GLuint textureAttachmentHandle, const bool isSRGB, const FboType fboType, const int idx);
561 ~TestFramebuffer (void);
562
563 void setTargetType (const deUint32 targetType);
564
565 FboType getType (void) const;
566 deUint32 getHandle (void) const;
567 deUint32 getColorAttachment (void) const;
568 int getIdx (void) const;
569 deUint32 getTargetType (void) const;
570
571 void bind (void);
572 void unbind (void);
573
574 typedef de::UniquePtr<glu::Framebuffer> fboUniquePtr;
575
576 private:
577 const glw::Functions* m_gl;
578 fboUniquePtr m_referenceSource;
579 deUint32 m_targetType;
580 bool m_bound;
581 bool m_isSRGB;
582 FboType m_type;
583 const int m_idx;
584 deUint32 m_colorAttachment;
585 };
586
TestFramebuffer(Context & context,const deUint32 targetType,const deUint32 colorAttachment,glw::GLuint textureAttachmentHandle,const bool isSRGB,const FboType fboType,const int idx)587 TestFramebuffer::TestFramebuffer (Context& context, const deUint32 targetType, const deUint32 colorAttachment, glw::GLuint textureAttachmentHandle, const bool isSRGB, const FboType fboType, const int idx)
588 : m_gl (&context.getRenderContext().getFunctions())
589 , m_referenceSource (new glu::Framebuffer(context.getRenderContext()))
590 , m_targetType (targetType)
591 , m_bound (false)
592 , m_isSRGB (isSRGB)
593 , m_type (fboType)
594 , m_idx (idx)
595 , m_colorAttachment (colorAttachment)
596 {
597 m_gl->bindFramebuffer(m_targetType, **m_referenceSource);
598
599 m_gl->framebufferTexture2D(m_targetType, m_colorAttachment, GL_TEXTURE_2D, textureAttachmentHandle, 0);
600
601 TCU_CHECK(m_gl->checkFramebufferStatus(m_targetType) == GL_FRAMEBUFFER_COMPLETE);
602
603 if (targetType == GL_DRAW_BUFFER)
604 {
605 glw::GLuint textureAttachments[] = {m_colorAttachment};
606 m_gl->drawBuffers(DE_LENGTH_OF_ARRAY(textureAttachments), textureAttachments);
607 GLU_EXPECT_NO_ERROR(m_gl->getError(), "glDrawBuffer()");
608 }
609
610 if (targetType == GL_READ_BUFFER)
611 {
612 m_gl->readBuffer(m_colorAttachment);
613 GLU_EXPECT_NO_ERROR(m_gl->getError(), "glReadBuffer()");
614 }
615
616 m_gl->bindFramebuffer(m_targetType, 0);
617 }
618
~TestFramebuffer(void)619 TestFramebuffer::~TestFramebuffer (void)
620 {
621 }
622
setTargetType(const deUint32 targetType)623 void TestFramebuffer::setTargetType (const deUint32 targetType)
624 {
625 m_targetType = targetType;
626 }
627
getType(void) const628 FboType TestFramebuffer::getType (void) const
629 {
630 return m_type;
631 }
632
getHandle(void) const633 deUint32 TestFramebuffer::getHandle (void) const
634 {
635 return **m_referenceSource;
636 }
637
getColorAttachment(void) const638 deUint32 TestFramebuffer::getColorAttachment (void) const
639 {
640 return m_colorAttachment;
641 }
642
getIdx(void) const643 int TestFramebuffer::getIdx (void) const
644 {
645 return m_idx;
646 }
647
getTargetType(void) const648 deUint32 TestFramebuffer::getTargetType (void) const
649 {
650 return m_targetType;
651 }
652
bind(void)653 void TestFramebuffer::bind (void)
654 {
655 if (!m_bound)
656 {
657 m_gl->bindFramebuffer(m_targetType, **m_referenceSource);
658 m_bound = true;
659 }
660 }
661
unbind(void)662 void TestFramebuffer::unbind (void)
663 {
664 if (m_bound)
665 {
666 m_gl->bindFramebuffer(m_targetType, 0);
667 m_bound = false;
668 }
669 }
670
671 class TestShaderProgram
672 {
673 public:
674 TestShaderProgram (Context& context, const int samplerTotal, TestFunction testFunction);
675 ~TestShaderProgram (void);
676
677 glw::GLuint getHandle (void) const;
678 int getSamplerTotal (void) const;
679
680 void use (void) const;
681 void unuse (void) const;
682
683 glu::ShaderProgramInfo getLogInfo (void);
684
685 private:
686 const glw::Functions* m_gl;
687 de::MovePtr<glu::ShaderProgram> m_referenceSource;
688 const int m_samplerTotal;
689 const int m_shaderStagesTotal;
690 };
691
TestShaderProgram(Context & context,const int samplerTotal,TestFunction testFunction)692 TestShaderProgram::TestShaderProgram (Context& context, const int samplerTotal, TestFunction testFunction)
693 : m_gl (&context.getRenderContext().getFunctions())
694 , m_samplerTotal (samplerTotal)
695 , m_shaderStagesTotal (2)
696 {
697 std::ostringstream shaderFragment;
698
699 const char* const shaderVertex =
700 "#version 310 es \n"
701 "layout (location = 0) in mediump vec3 aPosition; \n"
702 "layout (location = 1) in mediump vec2 aTexCoord; \n"
703 "out mediump vec2 vs_aTexCoord; \n"
704 "void main () \n"
705 "{ \n"
706 " gl_Position = vec4(aPosition, 1.0f); \n"
707 " vs_aTexCoord = aTexCoord; \n"
708 "} \n";
709
710 shaderFragment
711 << "#version 310 es \n"
712 << "in mediump vec2 vs_aTexCoord; \n"
713 << "layout (location = 0) out mediump vec4 fs_aColor0; \n";
714
715 for (int samplerIdx = 0; samplerIdx < m_samplerTotal; samplerIdx++)
716 shaderFragment
717 << "uniform sampler2D uTexture" << samplerIdx << "; \n";
718
719 shaderFragment
720 << "uniform int uFunctionType; \n";
721
722 if (testFunction.hasFunction)
723 shaderFragment
724 << "uniform int uBlendFunctionType; \n"
725 << "uniform mediump float uFactorSrc; \n"
726 << "uniform mediump float uFactorDst; \n"
727 << testFunction.functionDefintion;
728
729 shaderFragment
730 << "void main () \n"
731 << "{ \n";
732
733 for (int samplerIdx = 0; samplerIdx < m_samplerTotal; samplerIdx++)
734 shaderFragment
735 <<" mediump vec4 texelColor" << samplerIdx << " = vec4(0.0f, 0.0f, 0.0f, 1.0f); \n";
736
737 shaderFragment
738 << buildSamplingPassType(m_samplerTotal);
739
740 if (testFunction.hasFunction)
741 shaderFragment
742 << " fs_aColor0 = " << testFunction.functionName << "(texelColor0, texelColor1); \n";
743 else
744 shaderFragment
745 << " fs_aColor0 = texelColor0; \n";
746
747 shaderFragment
748 << "} \n";
749
750 m_referenceSource = de::MovePtr<glu::ShaderProgram>(new glu::ShaderProgram(context.getRenderContext(), glu::makeVtxFragSources(shaderVertex, shaderFragment.str())));
751 if (!m_referenceSource->isOk())
752 {
753 tcu::TestLog& log = context.getTestContext().getLog();
754 log << this->getLogInfo();
755 TCU_FAIL("Failed to compile shaders and link program");
756 }
757 }
758
~TestShaderProgram(void)759 TestShaderProgram::~TestShaderProgram (void)
760 {
761 m_referenceSource = de::MovePtr<glu::ShaderProgram>(DE_NULL);
762 m_referenceSource.clear();
763 }
764
getHandle(void) const765 deUint32 TestShaderProgram::getHandle (void) const
766 {
767 return m_referenceSource->getProgram();
768 }
769
getSamplerTotal(void) const770 int TestShaderProgram::getSamplerTotal (void) const
771 {
772 return m_samplerTotal;
773 }
774
use(void) const775 void TestShaderProgram::use (void) const
776 {
777 m_gl->useProgram(this->getHandle());
778 }
779
unuse(void) const780 void TestShaderProgram::unuse (void) const
781 {
782 m_gl->useProgram(0);
783 }
784
getLogInfo(void)785 glu::ShaderProgramInfo TestShaderProgram::getLogInfo (void)
786 {
787 glu::ShaderProgramInfo buildInfo;
788
789 // log shader program info. Only vertex and fragment shaders included
790 buildInfo.program = m_referenceSource->getProgramInfo();
791 for (int shaderIdx = 0; shaderIdx < m_shaderStagesTotal; shaderIdx++)
792 {
793 glu::ShaderInfo shaderInfo = m_referenceSource->getShaderInfo(static_cast<glu::ShaderType>(static_cast<int>(glu::SHADERTYPE_VERTEX) + static_cast<int>(shaderIdx)), 0);
794 buildInfo.shaders.push_back(shaderInfo);
795 }
796 return buildInfo;
797 }
798
799 class Renderer
800 {
801 public:
802 Renderer (Context& context);
803 ~Renderer (void);
804
805 void init (const TestRenderPassConfig& renderPassConfig, const int renderpass);
806 void deinit (void);
807
808 void setSamplingType (const SamplingType samplerIdx);
809 void setBlendIteration (const int blendIteration);
810 void setFramebufferBlend (const bool blend);
811 void setFramebufferSRGB (const bool sRGB);
812
813 std::vector<tcu::Vec4> getResultsPreDraw (void) const;
814 std::vector<tcu::Vec4> getResultsPostDraw (void) const;
815 int getBlendConfigCount (void) const;
816 glu::ShaderProgramInfo getShaderProgramInfo (void);
817
818 void copyFrameBufferTexture (const int srcPx, const int srcPy, const int dstPx, const int dstPy);
819 void draw (void);
820 void storeShaderProgramInfo (void);
821 void logShaderProgramInfo (void);
822
823 typedef de::SharedPtr<TestTexture2D> TextureSp;
824 typedef de::SharedPtr<TestFramebuffer> FboSp;
825
826 private:
827 void createFBOwithColorAttachment (const std::vector<FBOConfig> fboConfigList);
828 void setShaderProgramSamplingType (const int samplerIdx);
829 void setShaderBlendFunctionType (void);
830 void setShaderBlendSrcDstValues (void);
831 void bindActiveTexturesSamplers (void);
832 void bindAllRequiredSourceTextures (const TextureSourcesType texturesRequired);
833 void unbindAllSourceTextures (void);
834 void bindFramebuffer (const int framebufferIdx);
835 void unbindFramebuffer (const int framebufferIdx);
836 void enableFramebufferSRGB (void);
837 void enableFramebufferBlend (void);
838 bool isFramebufferAttachmentSRGB (const deUint32 targetType, const deUint32 attachment) const;
839 void readTexels (const int px, const int py, const deUint32 attachment, tcu::Vec4& texelData);
840 void logState (const deUint32 targetType, const deUint32 attachment, const SamplingType samplingType) const;
841
842 // renderer specific constants initialized during constructor
843 Context& m_context;
844 const TestVertexData m_vertexData;
845 const int m_textureSourceTotal;
846
847 // additional resources monitored by the renderer
848 std::vector<BlendConfig> m_blendConfigList;
849 std::vector<TextureSp> m_textureSourceList;
850 TestRenderPassConfig m_renderPassConfig;
851 std::vector<TextureSp> m_fboTextureList;
852 TestShaderProgram* m_shaderProgram;
853 std::vector<FboSp> m_framebufferList;
854 std::vector<tcu::Vec4> m_resultsListPreDraw;
855 std::vector<tcu::Vec4> m_resultsListPostDraw;
856
857 // mutable state variables (internal access only)
858 bool m_hasShaderProgramInfo;
859 int m_renderPass;
860 int m_samplersRequired;
861 bool m_hasFunction;
862 bool m_blittingEnabled;
863 glu::ShaderProgramInfo m_shaderProgramInfo;
864
865 // mutable state variables (external access via setters)
866 SamplingType m_samplingType;
867 int m_blendIteration;
868 bool m_framebufferBlendEnabled;
869 bool m_framebufferSRGBEnabled;
870 };
871
Renderer(Context & context)872 Renderer::Renderer (Context& context)
873 : m_context (context)
874 , m_vertexData (context)
875 , m_textureSourceTotal (2)
876 , m_blendConfigList (getBlendingConfigList())
877 , m_hasShaderProgramInfo (false)
878 {
879 TextureSp textureLinear(new TestTexture2D(m_context, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, getTestColorLinear(), 0));
880 m_textureSourceList.push_back(textureLinear);
881
882 TextureSp textureSRGB(new TestTexture2D(m_context, GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, getTestColorLinear(), 1));
883 m_textureSourceList.push_back(textureSRGB);
884 }
885
~Renderer(void)886 Renderer::~Renderer (void)
887 {
888 m_textureSourceList.clear();
889 this->deinit();
890 }
891
init(const TestRenderPassConfig & renderPassConfig,const int renderpass)892 void Renderer::init (const TestRenderPassConfig& renderPassConfig, const int renderpass)
893 {
894 m_renderPassConfig = renderPassConfig;
895 m_renderPass = renderpass;
896
897 this->createFBOwithColorAttachment(m_renderPassConfig.fboConfigList);
898
899 if (m_renderPassConfig.textureSourcesType != TEXTURESOURCESTYPE_NONE)
900 {
901 if (m_renderPassConfig.textureSourcesType == TEXTURESOURCESTYPE_RGBA || m_renderPassConfig.textureSourcesType == TEXTURESOURCESTYPE_SRGBA)
902 m_samplersRequired = 1;
903 else if (m_renderPassConfig.textureSourcesType ==TEXTURESOURCESTYPE_BOTH )
904 m_samplersRequired = 2;
905 else
906 DE_FATAL("Error: Texture source required not recognised");
907
908 m_shaderProgram = new TestShaderProgram(m_context, m_samplersRequired, m_renderPassConfig.testFunction);
909 m_hasFunction = m_renderPassConfig.testFunction.hasFunction;
910 }
911 else
912 m_shaderProgram = DE_NULL;
913 }
914
deinit(void)915 void Renderer::deinit (void)
916 {
917 if (m_shaderProgram != DE_NULL)
918 {
919 delete m_shaderProgram;
920 m_shaderProgram = DE_NULL;
921 }
922
923 m_fboTextureList.clear();
924 m_framebufferList.clear();
925 }
926
setSamplingType(const SamplingType samplingType)927 void Renderer::setSamplingType (const SamplingType samplingType)
928 {
929 m_samplingType = samplingType;
930 }
931
setBlendIteration(const int blendIteration)932 void Renderer::setBlendIteration (const int blendIteration)
933 {
934 m_blendIteration = blendIteration;
935 }
936
setFramebufferBlend(const bool blend)937 void Renderer::setFramebufferBlend (const bool blend)
938 {
939 m_framebufferBlendEnabled = blend;
940 }
941
setFramebufferSRGB(const bool sRGB)942 void Renderer::setFramebufferSRGB (const bool sRGB)
943 {
944 m_framebufferSRGBEnabled = sRGB;
945 }
946
getResultsPreDraw(void) const947 std::vector<tcu::Vec4> Renderer::getResultsPreDraw (void) const
948 {
949 return m_resultsListPreDraw;
950 }
951
getResultsPostDraw(void) const952 std::vector<tcu::Vec4> Renderer::getResultsPostDraw (void) const
953 {
954 return m_resultsListPostDraw;
955 }
956
getBlendConfigCount(void) const957 int Renderer::getBlendConfigCount (void) const
958 {
959 return (int)m_blendConfigList.size();
960 }
961
copyFrameBufferTexture(const int srcPx,const int srcPy,const int dstPx,const int dstPy)962 void Renderer::copyFrameBufferTexture (const int srcPx, const int srcPy, const int dstPx, const int dstPy)
963 {
964 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
965 int fboSrcIdx = -1;
966 int fboDstIdx = -1;
967 deUint32 fboSrcColAttachment = GL_NONE;
968 deUint32 fboDstColAttachment = GL_NONE;
969
970 for (int idx = 0; idx < (int)m_framebufferList.size(); idx++)
971 this->bindFramebuffer(idx);
972
973 // cache fbo attachments and idx locations
974 for (int idx = 0; idx < (int)m_framebufferList.size(); idx++)
975 {
976 if (m_framebufferList[idx]->getType() == FBOTYPE_SOURCE)
977 {
978 fboSrcIdx = m_framebufferList[idx]->getIdx();
979 fboSrcColAttachment = m_framebufferList[fboSrcIdx]->getColorAttachment();
980 }
981 if (m_framebufferList[idx]->getType() == FBOTYPE_DESTINATION)
982 {
983 fboDstIdx = m_framebufferList[idx]->getIdx();
984 fboDstColAttachment = m_framebufferList[fboDstIdx]->getColorAttachment();
985 }
986 }
987
988 for (int idx = 0; idx < (int)m_framebufferList.size(); idx++)
989 m_framebufferList[idx]->unbind();
990
991 // store texel data from both src and dst before performing the copy
992 m_resultsListPreDraw.resize(2);
993 m_framebufferList[fboSrcIdx]->bind();
994 this->readTexels(0, 0, fboSrcColAttachment, m_resultsListPreDraw[0]);
995 m_framebufferList[fboSrcIdx]->unbind();
996 m_framebufferList[fboDstIdx]->setTargetType(GL_READ_FRAMEBUFFER);
997 m_framebufferList[fboDstIdx]->bind();
998 this->readTexels(0, 0, fboDstColAttachment, m_resultsListPreDraw[1]);
999 m_framebufferList[fboDstIdx]->unbind();
1000 m_framebufferList[fboDstIdx]->setTargetType(GL_DRAW_FRAMEBUFFER);
1001
1002 m_framebufferList[fboSrcIdx]->bind();
1003 m_framebufferList[fboDstIdx]->bind();
1004
1005 this->enableFramebufferSRGB();
1006 this->enableFramebufferBlend();
1007
1008 gl.blitFramebuffer( srcPx, srcPy, TestTextureSizes::WIDTH, TestTextureSizes::HEIGHT,
1009 dstPx, dstPy, TestTextureSizes::WIDTH, TestTextureSizes::HEIGHT,
1010 GL_COLOR_BUFFER_BIT, GL_NEAREST);
1011
1012 m_resultsListPostDraw.resize(2);
1013 this->readTexels(0, 0, fboSrcColAttachment, m_resultsListPostDraw[0]);
1014 m_framebufferList[fboSrcIdx]->unbind();
1015 m_framebufferList[fboDstIdx]->unbind();
1016
1017 m_framebufferList[fboDstIdx]->setTargetType(GL_READ_FRAMEBUFFER);
1018 m_framebufferList[fboDstIdx]->bind();
1019 this->readTexels(0, 0, fboDstColAttachment, m_resultsListPostDraw[1]);
1020 m_framebufferList[fboDstIdx]->unbind();
1021 }
1022
draw(void)1023 void Renderer::draw (void)
1024 {
1025 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1026
1027 if (m_renderPassConfig.textureSourcesType == TEXTURESOURCESTYPE_NONE)
1028 DE_FATAL("Error: Attempted to draw with no texture sources");
1029
1030 // resize results storage with each render pass
1031 m_resultsListPreDraw.resize(m_renderPass + 1);
1032 m_resultsListPostDraw.resize(m_renderPass + 1);
1033
1034 m_shaderProgram->use();
1035 m_vertexData.bind();
1036
1037 for (int idx = 0; idx < (int)m_framebufferList.size(); idx++)
1038 this->bindFramebuffer(idx);
1039
1040 this->bindAllRequiredSourceTextures(m_renderPassConfig.textureSourcesType);
1041 this->bindActiveTexturesSamplers();
1042
1043 this->enableFramebufferSRGB();
1044 this->enableFramebufferBlend();
1045
1046 this->readTexels(0, 0, GL_COLOR_ATTACHMENT0, m_resultsListPreDraw[m_renderPass]);
1047 this->setShaderProgramSamplingType(m_samplingType);
1048 if (m_hasFunction)
1049 {
1050 this->setShaderBlendFunctionType();
1051 this->setShaderBlendSrcDstValues();
1052 }
1053
1054 gl.drawArrays(GL_TRIANGLES, 0, 6);
1055
1056 this->readTexels(0, 0, GL_COLOR_ATTACHMENT0, m_resultsListPostDraw[m_renderPass]);
1057 this->logState(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_samplingType);
1058
1059 this->unbindAllSourceTextures();
1060 for (int idx = 0; idx < (int)m_framebufferList.size(); idx++)
1061 this->unbindFramebuffer(idx);
1062 m_vertexData.unbind();
1063 m_shaderProgram->unuse();
1064 }
1065
storeShaderProgramInfo(void)1066 void Renderer::storeShaderProgramInfo (void)
1067 {
1068 m_shaderProgramInfo = m_shaderProgram->getLogInfo();
1069 m_hasShaderProgramInfo = true;
1070 }
1071
logShaderProgramInfo(void)1072 void Renderer::logShaderProgramInfo (void)
1073 {
1074 tcu::TestLog& log = m_context.getTestContext().getLog();
1075
1076 if (m_hasShaderProgramInfo)
1077 log << m_shaderProgramInfo;
1078 }
1079
createFBOwithColorAttachment(const std::vector<FBOConfig> fboConfigList)1080 void Renderer::createFBOwithColorAttachment (const std::vector<FBOConfig> fboConfigList)
1081 {
1082 const int size = (int)fboConfigList.size();
1083 for (int idx = 0; idx < size; idx++)
1084 {
1085 TextureSp texture(new TestTexture2D(m_context, fboConfigList[idx].textureInternalFormat, GL_RGBA, GL_UNSIGNED_BYTE, fboConfigList[idx].textureColor, idx));
1086 m_fboTextureList.push_back(texture);
1087
1088 bool isSRGB;
1089 if (fboConfigList[idx].textureInternalFormat == GL_SRGB8_ALPHA8)
1090 isSRGB = true;
1091 else
1092 isSRGB = false;
1093
1094 FboSp framebuffer(new TestFramebuffer(m_context, fboConfigList[idx].fboTargetType, fboConfigList[idx].fboColorAttachment, texture->getHandle(), isSRGB, fboConfigList[idx].fboType, idx));
1095 m_framebufferList.push_back(framebuffer);
1096 }
1097 }
1098
setShaderProgramSamplingType(const int samplerIdx)1099 void Renderer::setShaderProgramSamplingType (const int samplerIdx)
1100 {
1101 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1102
1103 glw::GLuint location = gl.getUniformLocation(m_shaderProgram->getHandle(), "uFunctionType");
1104 DE_ASSERT(location != (glw::GLuint)-1);
1105 gl.uniform1i(location, samplerIdx);
1106 }
1107
setShaderBlendFunctionType(void)1108 void Renderer::setShaderBlendFunctionType (void)
1109 {
1110 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1111
1112 int function = -1;
1113 if (m_blendConfigList[m_blendIteration].equation == GL_FUNC_ADD)
1114 function = 0;
1115 else if (m_blendConfigList[m_blendIteration].equation == GL_FUNC_SUBTRACT)
1116 function = 1;
1117 else if (m_blendConfigList[m_blendIteration].equation == GL_FUNC_REVERSE_SUBTRACT)
1118 function = 2;
1119 else
1120 DE_FATAL("Error: Blend function not recognised");
1121
1122 glw::GLuint location = gl.getUniformLocation(m_shaderProgram->getHandle(), "uBlendFunctionType");
1123 DE_ASSERT(location != (glw::GLuint)-1);
1124 gl.uniform1i(location, function);
1125 }
1126
setShaderBlendSrcDstValues(void)1127 void Renderer::setShaderBlendSrcDstValues (void)
1128 {
1129 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1130
1131 float funcSrc;
1132 if (m_blendConfigList[m_blendIteration].funcSrc == GL_ONE)
1133 funcSrc = 1.0f;
1134 else
1135 funcSrc = 0.0f;
1136
1137 float funcDst;
1138 if (m_blendConfigList[m_blendIteration].funcDst == GL_ONE)
1139 funcDst = 1.0f;
1140 else
1141 funcDst = 0.0f;
1142
1143 glw::GLuint locationSrc = gl.getUniformLocation(m_shaderProgram->getHandle(), "uFactorSrc");
1144 gl.uniform1f(locationSrc, funcSrc);
1145 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1f()");
1146
1147 glw::GLuint locationDst = gl.getUniformLocation(m_shaderProgram->getHandle(), "uFactorDst");
1148 gl.uniform1f(locationDst, funcDst);
1149 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1f()");
1150 }
1151
bindActiveTexturesSamplers(void)1152 void Renderer::bindActiveTexturesSamplers (void)
1153 {
1154 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1155
1156 for (int idx = 0; idx < m_samplersRequired; idx++)
1157 {
1158 std::ostringstream stream;
1159 stream << "uTexture" << idx;
1160 std::string uniformName(stream.str());
1161 glw::GLint location = gl.getUniformLocation(m_shaderProgram->getHandle(), uniformName.c_str());
1162 DE_ASSERT(location != -1);
1163 gl.uniform1i(location, m_textureSourceList[idx]->getTextureUnit());
1164 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
1165 }
1166 }
1167
bindAllRequiredSourceTextures(const TextureSourcesType texturesRequired)1168 void Renderer::bindAllRequiredSourceTextures (const TextureSourcesType texturesRequired)
1169 {
1170 if (texturesRequired == TEXTURESOURCESTYPE_RGBA)
1171 m_textureSourceList[0]->bind(0);
1172 else if (texturesRequired == TEXTURESOURCESTYPE_SRGBA)
1173 m_textureSourceList[1]->bind(0);
1174 else if (texturesRequired == TEXTURESOURCESTYPE_BOTH)
1175 {
1176 m_textureSourceList[0]->bind(0);
1177 m_textureSourceList[1]->bind(1);
1178 }
1179 else
1180 DE_FATAL("Error: Invalid sources requested in bind all");
1181 }
1182
unbindAllSourceTextures(void)1183 void Renderer::unbindAllSourceTextures (void)
1184 {
1185 for (int idx = 0; idx < (int)m_textureSourceList.size(); idx++)
1186 m_textureSourceList[idx]->unbind();
1187 }
1188
bindFramebuffer(const int framebufferIdx)1189 void Renderer::bindFramebuffer (const int framebufferIdx)
1190 {
1191 m_framebufferList[framebufferIdx]->bind();
1192 }
1193
unbindFramebuffer(const int framebufferIdx)1194 void Renderer::unbindFramebuffer (const int framebufferIdx)
1195 {
1196 m_framebufferList[framebufferIdx]->unbind();
1197 }
1198
enableFramebufferSRGB(void)1199 void Renderer::enableFramebufferSRGB (void)
1200 {
1201 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1202
1203 if (m_framebufferSRGBEnabled)
1204 gl.enable(GL_FRAMEBUFFER_SRGB);
1205 else
1206 gl.disable(GL_FRAMEBUFFER_SRGB);
1207 }
1208
enableFramebufferBlend(void)1209 void Renderer::enableFramebufferBlend (void)
1210 {
1211 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1212 tcu::TestLog& log = m_context.getTestContext().getLog();
1213 std::ostringstream message;
1214
1215 message << "Blend settings = ";
1216
1217 if (m_framebufferBlendEnabled)
1218 {
1219 gl.enable(GL_BLEND);
1220 gl.blendEquation(m_blendConfigList[m_blendIteration].equation);
1221 gl.blendFunc(m_blendConfigList[m_blendIteration].funcSrc, m_blendConfigList[m_blendIteration].funcDst);
1222
1223 std::string equation, src, dst;
1224 if (m_blendConfigList[m_blendIteration].equation == GL_FUNC_ADD)
1225 equation = "GL_FUNC_ADD";
1226 if (m_blendConfigList[m_blendIteration].equation == GL_FUNC_SUBTRACT)
1227 equation = "GL_FUNC_SUBTRACT";
1228 if (m_blendConfigList[m_blendIteration].equation == GL_FUNC_REVERSE_SUBTRACT)
1229 equation = "GL_FUNC_REVERSE_SUBTRACT";
1230 if (m_blendConfigList[m_blendIteration].funcSrc == GL_ONE)
1231 src = "GL_ONE";
1232 else
1233 src = "GL_ZERO";
1234 if (m_blendConfigList[m_blendIteration].funcDst == GL_ONE)
1235 dst = "GL_ONE";
1236 else
1237 dst = "GL_ZERO";
1238
1239 message << "Enabled: equation = " << equation << ", func src = " << src << ", func dst = " << dst;
1240 }
1241 else
1242 {
1243 gl.disable(GL_BLEND);
1244 message << "Disabled";
1245 }
1246
1247 log << tcu::TestLog::Message << message.str() << tcu::TestLog::EndMessage;
1248 }
1249
isFramebufferAttachmentSRGB(const deUint32 targetType,const deUint32 attachment) const1250 bool Renderer::isFramebufferAttachmentSRGB (const deUint32 targetType, const deUint32 attachment) const
1251 {
1252 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1253 glw::GLint encodingType;
1254
1255 gl.getFramebufferAttachmentParameteriv(targetType, attachment, GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, &encodingType);
1256 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetNamedFramebufferAttachmentParameteriv()");
1257
1258 switch (static_cast<glw::GLenum>(encodingType))
1259 {
1260 case GL_SRGB:
1261 {
1262 return true;
1263 break;
1264 }
1265 case GL_LINEAR:
1266 {
1267 return false;
1268 break;
1269 }
1270 default:
1271 {
1272 DE_FATAL("Error: Color attachment format not recognised");
1273 return false;
1274 }
1275 }
1276 }
1277
readTexels(const int px,const int py,const deUint32 mode,tcu::Vec4 & texelData)1278 void Renderer::readTexels (const int px, const int py, const deUint32 mode, tcu::Vec4& texelData)
1279 {
1280 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1281 tcu::TextureLevel textureRead;
1282
1283 // ensure result sampling coordinates are within range of the result color attachment
1284 DE_ASSERT((px >= 0) && (px < m_context.getRenderTarget().getWidth()));
1285 DE_ASSERT((py >= 0) && (py < m_context.getRenderTarget().getHeight()));
1286
1287 gl.readBuffer(mode);
1288 textureRead.setStorage(glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE), TestTextureSizes::WIDTH, TestTextureSizes::HEIGHT);
1289 glu::readPixels(m_context.getRenderContext(), px, py, textureRead.getAccess());
1290 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels()");
1291 texelData = textureRead.getAccess().getPixel(px, py);
1292 }
1293
logState(const deUint32 targetType,const deUint32 attachment,const SamplingType samplingType) const1294 void Renderer::logState (const deUint32 targetType, const deUint32 attachment, const SamplingType samplingType) const
1295 {
1296 tcu::TestLog& log = m_context.getTestContext().getLog();
1297 std::ostringstream message;
1298
1299 bool fboAttachmentSRGB = this->isFramebufferAttachmentSRGB(targetType, attachment);
1300 message.str("");
1301 message << "getFramebufferAttachmentParameteriv() check = ";
1302 if (fboAttachmentSRGB)
1303 message << "GL_SRGB";
1304 else
1305 message << "GL_LINEAR";
1306 log << tcu::TestLog::Message << message.str() << tcu::TestLog::EndMessage;
1307
1308 message.str("");
1309 message << "Framebuffer color attachment value BEFORE draw call";
1310 logColor(m_context, message.str(), m_resultsListPreDraw[m_renderPass]);
1311
1312 message.str("");
1313 message << "Framebuffer color attachment value AFTER draw call";
1314 logColor(m_context, message.str(), m_resultsListPostDraw[m_renderPass]);
1315
1316 message.str("");
1317 message << "Sampling type = ";
1318 std::string type;
1319 if (samplingType == 0)
1320 type = "texture()";
1321 else if (samplingType == 1)
1322 type = "textureLOD()";
1323 else if (samplingType == 2)
1324 type = "textureGrad()";
1325 else if (samplingType == 3)
1326 type = "textureOffset()";
1327 else if (samplingType == 4)
1328 type = "textureProj()";
1329 else
1330 DE_FATAL("Error: Sampling type unregonised");
1331 message << type;
1332 log << tcu::TestLog::Message << message.str() << tcu::TestLog::EndMessage;
1333
1334 message.str("");
1335 if (m_framebufferSRGBEnabled)
1336 message << "Framebuffer SRGB = enabled";
1337 else
1338 message << "Framebuffer SRGB = disabled";
1339 log << tcu::TestLog::Message << message.str() << tcu::TestLog::EndMessage;
1340 }
1341
1342 class FboSRGBTestCase : public TestCase
1343 {
1344 public:
1345 FboSRGBTestCase (Context& context, const char* const name, const char* const desc);
1346 ~FboSRGBTestCase (void);
1347
1348 void init (void);
1349 void deinit (void);
1350 IterateResult iterate (void);
1351
1352 void setTestConfig (std::vector<TestRenderPassConfig> renderPassConfigList);
1353
1354 virtual void setupTest (void) = 0;
1355 virtual bool verifyResult (void) = 0;
1356
1357 protected:
1358 bool m_hasTestConfig;
1359 std::vector<TestRenderPassConfig> m_renderPassConfigList;
1360 bool m_testcaseRequiresBlend;
1361 std::vector<tcu::Vec4> m_resultsPreDraw;
1362 std::vector<tcu::Vec4> m_resultsPostDraw;
1363
1364 private:
1365 FboSRGBTestCase (const FboSRGBTestCase&);
1366 FboSRGBTestCase& operator= (const FboSRGBTestCase&);
1367 };
1368
FboSRGBTestCase(Context & context,const char * const name,const char * const desc)1369 FboSRGBTestCase::FboSRGBTestCase (Context& context, const char* const name, const char* const desc)
1370 : TestCase (context, name, desc)
1371 , m_hasTestConfig (false)
1372 {
1373 }
1374
~FboSRGBTestCase(void)1375 FboSRGBTestCase::~FboSRGBTestCase (void)
1376 {
1377 FboSRGBTestCase::deinit();
1378 }
1379
init(void)1380 void FboSRGBTestCase::init (void)
1381 {
1382 // extensions requirements for test
1383 if (!glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)))
1384 TCU_THROW(NotSupportedError, "Test requires a context version equal or higher than 3.2");
1385
1386 if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_sRGB_write_control"))
1387 TCU_THROW(NotSupportedError, "Test requires extension GL_EXT_sRGB_write_control");
1388
1389 if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_texture_sRGB_decode"))
1390 TCU_THROW(NotSupportedError, "Test requires GL_EXT_texture_sRGB_decode extension");
1391 }
1392
deinit(void)1393 void FboSRGBTestCase::deinit (void)
1394 {
1395 }
1396
iterate(void)1397 FboSRGBTestCase::IterateResult FboSRGBTestCase::iterate (void)
1398 {
1399 this->setupTest();
1400
1401 DE_ASSERT(m_hasTestConfig && "Error: Renderer was not supplied a test config");
1402
1403 Renderer renderer(m_context);
1404
1405 // loop through each sampling type
1406 for (int samplingIdx = 0; samplingIdx < SampligTypeCount::MAX; samplingIdx++)
1407 {
1408 renderer.setSamplingType(static_cast<SamplingType>(samplingIdx));
1409
1410 // loop through each blend configuration
1411 const int blendCount = renderer.getBlendConfigCount();
1412 for (int blendIdx = 0; blendIdx < blendCount; blendIdx++)
1413 {
1414 // loop through each render pass
1415 const int renderPassCount = (int)m_renderPassConfigList.size();
1416 for (int renderPassIdx = 0; renderPassIdx < renderPassCount; renderPassIdx++)
1417 {
1418 TestRenderPassConfig renderPassConfig = m_renderPassConfigList[renderPassIdx];
1419
1420 renderer.init(renderPassConfig, renderPassIdx);
1421
1422 if (blendIdx == 0 && renderPassConfig.rendererTask == RENDERERTASK_DRAW)
1423 renderer.storeShaderProgramInfo();
1424
1425 if (renderPassConfig.frameBufferBlend == FRAMEBUFFERBLEND_ENABLED)
1426 {
1427 renderer.setBlendIteration(blendIdx);
1428 renderer.setFramebufferBlend(true);
1429 }
1430 else
1431 renderer.setFramebufferBlend(false);
1432
1433 if (renderPassConfig.framebufferSRGB == FRAMEBUFFERSRGB_ENABLED)
1434 renderer.setFramebufferSRGB(true);
1435 else
1436 renderer.setFramebufferSRGB(false);
1437
1438 if (renderPassConfig.rendererTask == RENDERERTASK_DRAW)
1439 renderer.draw();
1440 else if (renderPassConfig.rendererTask == RENDERERTASK_COPY)
1441 renderer.copyFrameBufferTexture(0, 0, 0, 0);
1442 else
1443 DE_FATAL("Error: render task not recognised");
1444
1445 renderer.deinit();
1446
1447 } // render passes
1448
1449 m_resultsPreDraw = renderer.getResultsPreDraw();
1450 m_resultsPostDraw = renderer.getResultsPostDraw();
1451
1452 bool testPassed = this->verifyResult();
1453 if (testPassed)
1454 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1455 else
1456 {
1457 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Result verification failed");
1458 renderer.logShaderProgramInfo();
1459 return STOP;
1460 }
1461
1462 if (!m_testcaseRequiresBlend)
1463 break;
1464 } // blend configs
1465
1466 renderer.logShaderProgramInfo();
1467 } // sampling types
1468
1469 return STOP;
1470 }
1471
setTestConfig(std::vector<TestRenderPassConfig> renderPassConfigList)1472 void FboSRGBTestCase::setTestConfig (std::vector<TestRenderPassConfig> renderPassConfigList)
1473 {
1474 m_renderPassConfigList = renderPassConfigList;
1475 m_hasTestConfig = true;
1476
1477 for (int idx = 0; idx < (int)renderPassConfigList.size(); idx++)
1478 {
1479 if (renderPassConfigList[idx].frameBufferBlend == FRAMEBUFFERBLEND_ENABLED)
1480 {
1481 m_testcaseRequiresBlend = true;
1482 return;
1483 }
1484 }
1485 m_testcaseRequiresBlend = false;
1486 }
1487
1488 class FboSRGBQueryCase : public TestCase
1489 {
1490 public:
1491 FboSRGBQueryCase (Context& context, const char* const name, const char* const description);
1492 ~FboSRGBQueryCase (void);
1493
1494 void init (void);
1495 void deinit (void);
1496 IterateResult iterate (void);
1497 };
1498
FboSRGBQueryCase(Context & context,const char * const name,const char * const description)1499 FboSRGBQueryCase::FboSRGBQueryCase (Context& context, const char* const name, const char* const description)
1500 : TestCase (context, name, description)
1501 {
1502 }
1503
~FboSRGBQueryCase(void)1504 FboSRGBQueryCase::~FboSRGBQueryCase (void)
1505 {
1506 FboSRGBQueryCase::deinit();
1507 }
1508
init(void)1509 void FboSRGBQueryCase::init (void)
1510 {
1511 // extension requirements for test
1512 if (!glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)) && !m_context.getContextInfo().isExtensionSupported("GL_EXT_sRGB_write_control"))
1513 TCU_THROW(NotSupportedError, "Test requires extension GL_EXT_sRGB_write_control or a context version equal or higher than 3.2");
1514 }
1515
deinit(void)1516 void FboSRGBQueryCase::deinit (void)
1517 {
1518 }
1519
iterate(void)1520 FboSRGBQueryCase::IterateResult FboSRGBQueryCase::iterate (void)
1521 {
1522 // TEST INFO:
1523 // API tests which check when querying FRAMEBUFFER_SRGB_EXT capability returns the correct information when using glEnabled() or glDisabled()
1524
1525 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1526 tcu::TestLog& log = m_context.getTestContext().getLog();
1527 const char* const msgPart = ", after disabling = ";
1528
1529 for (int idx = 0; idx < static_cast<int>(QUERYTYPE_LAST); idx++)
1530 {
1531 std::ostringstream message;
1532 bool pass = false;
1533
1534 message << std::string("Results: After Enabling = ");
1535
1536 gl.enable(GL_FRAMEBUFFER_SRGB);
1537
1538 switch (static_cast<QueryType>(idx))
1539 {
1540 case QUERYTYPE_ISENABLED:
1541 {
1542 glw::GLboolean enabled[2];
1543 enabled[0] = gl.isEnabled(GL_FRAMEBUFFER_SRGB);
1544 gl.disable(GL_FRAMEBUFFER_SRGB);
1545 enabled[1] = gl.isEnabled(GL_FRAMEBUFFER_SRGB);
1546
1547 message << static_cast<float>(enabled[0]) << msgPart << static_cast<float>(enabled[1]);
1548 pass = (enabled[0] && !(enabled[1])) ? true : false;
1549 break;
1550 }
1551 case QUERYTYPE_BOOLEAN:
1552 {
1553 glw::GLboolean enabled[2];
1554 gl.getBooleanv(GL_FRAMEBUFFER_SRGB,&enabled[0]);
1555 gl.disable(GL_FRAMEBUFFER_SRGB);
1556 gl.getBooleanv(GL_FRAMEBUFFER_SRGB,&enabled[1]);
1557
1558 message << static_cast<float>(enabled[0]) << msgPart << static_cast<float>(enabled[1]);
1559 pass = (enabled[0] && !(enabled[1])) ? true : false;
1560 break;
1561 }
1562 case QUERYTYPE_FLOAT:
1563 {
1564 glw::GLfloat enabled[2];
1565 gl.getFloatv(GL_FRAMEBUFFER_SRGB, &enabled[0]);
1566 gl.disable(GL_FRAMEBUFFER_SRGB);
1567 gl.getFloatv(GL_FRAMEBUFFER_SRGB, &enabled[1]);
1568
1569 message << static_cast<float>(enabled[0]) << msgPart << static_cast<float>(enabled[1]);
1570 pass = ((int)enabled[0] && !((int)enabled[1])) ? true : false;
1571 break;
1572 }
1573 case QUERYTYPE_INT:
1574 {
1575 glw::GLint enabled[2];
1576 gl.getIntegerv(GL_FRAMEBUFFER_SRGB, &enabled[0]);
1577 gl.disable(GL_FRAMEBUFFER_SRGB);
1578 gl.getIntegerv(GL_FRAMEBUFFER_SRGB, &enabled[1]);
1579
1580 message << static_cast<float>(enabled[0]) << msgPart << static_cast<float>(enabled[1]);
1581 pass = (enabled[0] && !(enabled[1])) ? true : false;
1582 break;
1583 }
1584 case QUERYTYPE_INT64:
1585 {
1586 glw::GLint64 enabled[2];
1587 gl.getInteger64v(GL_FRAMEBUFFER_SRGB, &enabled[0]);
1588 gl.disable(GL_FRAMEBUFFER_SRGB);
1589 gl.getInteger64v(GL_FRAMEBUFFER_SRGB, &enabled[1]);
1590
1591 message << static_cast<float>(enabled[0]) << msgPart << static_cast<float>(enabled[1]);
1592 pass = (enabled[0] && !(enabled[1])) ? true : false;
1593 break;
1594 }
1595 default:
1596 DE_FATAL("Error: Datatype not recognised");
1597 }
1598
1599 log << tcu::TestLog::Message << message.str() << tcu::TestLog::EndMessage;
1600
1601 if (pass)
1602 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1603 else
1604 {
1605 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Result verification failed");
1606 return STOP;
1607 }
1608 }
1609 return STOP;
1610 }
1611
1612 class FboSRGBColAttachCase : public FboSRGBTestCase
1613 {
1614 public:
FboSRGBColAttachCase(Context & context,const char * const name,const char * const description)1615 FboSRGBColAttachCase (Context& context, const char* const name, const char* const description)
1616 : FboSRGBTestCase (context, name, description) {}
~FboSRGBColAttachCase(void)1617 ~FboSRGBColAttachCase (void) {}
1618
1619 void setupTest (void);
1620 bool verifyResult (void);
1621 };
1622
setupTest(void)1623 void FboSRGBColAttachCase::setupTest (void)
1624 {
1625 // TEST INFO:
1626 // Check if FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING set to SRGB and FRAMEBUFFER_SRGB_EXT enabled, destination colors are converted from SRGB to linear
1627 // before and after blending, finally the result is converted back to SRGB for storage
1628
1629 // NOTE:
1630 // if fbo pre-draw color set to linaer, color values get linearlized "twice"
1631 // (0.2f, 0.3f, 0.4f, 1.0f) when sampled i.e. converted in shader = (0.0331048f, 0.073239f, 0.132868f)
1632 // resulting in the follolwing blending equation (0.2f, 0.3f, 0.4f 1.0f) + (0.0331048, 0.073239, 0.132868) = (0.521569f, 0.647059f, 0.756863f, 1.0f)
1633
1634 FBOConfig fboConfig0 = FBOConfig(GL_SRGB8_ALPHA8, getTestColorLinear(), GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FBOTYPE_SOURCE);
1635 FBOConfig fboConfig1 = FBOConfig(GL_RGBA8, getTestColorLinear(), GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FBOTYPE_SOURCE);
1636
1637 const TestRenderPassConfig renderPassConfigs[] =
1638 {
1639 TestRenderPassConfig(TEXTURESOURCESTYPE_RGBA, fboConfig0, FRAMEBUFFERSRGB_ENABLED, FRAMEBUFFERBLEND_ENABLED, RENDERERTASK_DRAW),
1640 TestRenderPassConfig(TEXTURESOURCESTYPE_BOTH, fboConfig1, FRAMEBUFFERSRGB_DISABLED, FRAMEBUFFERBLEND_DISABLED, getFunctionBlendLinearToSRGBCheck(), RENDERERTASK_DRAW)
1641 };
1642 std::vector<TestRenderPassConfig> renderPassConfigList(renderPassConfigs, renderPassConfigs + DE_LENGTH_OF_ARRAY(renderPassConfigs));
1643
1644 this->setTestConfig(renderPassConfigList);
1645 }
1646
verifyResult(void)1647 bool FboSRGBColAttachCase::verifyResult (void)
1648 {
1649 if (tcu::boolAll(tcu::lessThan(tcu::abs(m_resultsPostDraw[0] - m_resultsPostDraw[1]), getEpsilonError())) || tcu::boolAll(tcu::equal(m_resultsPostDraw[0], m_resultsPostDraw[1])))
1650 return true;
1651 else
1652 return false;
1653 }
1654
1655 class FboSRGBToggleBlendCase : public FboSRGBTestCase
1656 {
1657 public:
FboSRGBToggleBlendCase(Context & context,const char * const name,const char * const description)1658 FboSRGBToggleBlendCase (Context& context, const char* const name, const char* const description)
1659 : FboSRGBTestCase (context, name, description) {}
~FboSRGBToggleBlendCase(void)1660 ~FboSRGBToggleBlendCase (void) {}
1661
1662 void setupTest (void);
1663 bool verifyResult (void);
1664 };
1665
setupTest(void)1666 void FboSRGBToggleBlendCase::setupTest (void)
1667 {
1668 // TEST INFO:
1669 // Test to check if changing FRAMEBUFFER_SRGB_EXT from enabled to disabled. Enabled should produce SRGB color whilst disabled
1670 // should produce linear color. Test conducted with blending disabled.
1671
1672 FBOConfig fboConfig0 = FBOConfig(GL_SRGB8_ALPHA8, getTestColorLinear(), GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FBOTYPE_DESTINATION);
1673
1674 const TestRenderPassConfig renderPassConfigs[] =
1675 {
1676 TestRenderPassConfig(TEXTURESOURCESTYPE_RGBA, fboConfig0, FRAMEBUFFERSRGB_ENABLED, FRAMEBUFFERBLEND_DISABLED, TestFunction(false), RENDERERTASK_DRAW),
1677 TestRenderPassConfig(TEXTURESOURCESTYPE_RGBA, fboConfig0, FRAMEBUFFERSRGB_DISABLED, FRAMEBUFFERBLEND_DISABLED, TestFunction(false), RENDERERTASK_DRAW)
1678 };
1679 std::vector<TestRenderPassConfig> renderPassConfigList(renderPassConfigs, renderPassConfigs + DE_LENGTH_OF_ARRAY(renderPassConfigs));
1680
1681 this->setTestConfig(renderPassConfigList);
1682 }
1683
verifyResult(void)1684 bool FboSRGBToggleBlendCase::verifyResult (void)
1685 {
1686 if (tcu::boolAny(tcu::greaterThan(tcu::abs(m_resultsPostDraw[0] - m_resultsPostDraw[1]), getEpsilonError())))
1687 return true;
1688 else
1689 return false;
1690 }
1691
1692 class FboSRGBRenderTargetIgnoreCase : public FboSRGBTestCase
1693 {
1694 public:
FboSRGBRenderTargetIgnoreCase(Context & context,const char * const name,const char * const description)1695 FboSRGBRenderTargetIgnoreCase (Context& context, const char* const name, const char* const description)
1696 : FboSRGBTestCase (context, name, description) {}
~FboSRGBRenderTargetIgnoreCase(void)1697 ~FboSRGBRenderTargetIgnoreCase (void) {}
1698
1699 void setupTest (void);
1700 bool verifyResult (void);
1701 };
1702
setupTest(void)1703 void FboSRGBRenderTargetIgnoreCase::setupTest (void)
1704 {
1705 // TEST INFO:
1706 // Check if render targets that are non-RGB ignore the state of GL_FRAMEBUFFER_SRGB_EXT. Rendering to an fbo with non-sRGB color
1707 // attachment should ignore color space conversion, producing linear color.
1708
1709 FBOConfig fboConfig0 = FBOConfig(GL_RGBA8, getTestColorBlank(), GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FBOTYPE_DESTINATION);
1710
1711 const TestRenderPassConfig renderPassConfigs[] =
1712 {
1713 TestRenderPassConfig(TEXTURESOURCESTYPE_RGBA, fboConfig0, FRAMEBUFFERSRGB_ENABLED, FRAMEBUFFERBLEND_DISABLED, TestFunction(false), RENDERERTASK_DRAW)
1714
1715 };
1716 std::vector<TestRenderPassConfig> renderPassConfigList(renderPassConfigs, renderPassConfigs + DE_LENGTH_OF_ARRAY(renderPassConfigs));
1717
1718 this->setTestConfig(renderPassConfigList);
1719 }
1720
verifyResult(void)1721 bool FboSRGBRenderTargetIgnoreCase::verifyResult (void)
1722 {
1723 if (tcu::boolAll(tcu::lessThan(tcu::abs(m_resultsPostDraw[0] - getTestColorLinear()), getEpsilonError())) || tcu::boolAll(tcu::equal(m_resultsPostDraw[0], getTestColorLinear())))
1724 return true;
1725 else
1726 return false;
1727 }
1728
1729 class FboSRGBCopyToLinearCase : public FboSRGBTestCase
1730 {
1731 public:
FboSRGBCopyToLinearCase(Context & context,const char * const name,const char * const description)1732 FboSRGBCopyToLinearCase (Context& context, const char* const name, const char* const description)
1733 : FboSRGBTestCase (context, name, description) {}
~FboSRGBCopyToLinearCase(void)1734 ~FboSRGBCopyToLinearCase (void) {}
1735
1736 void setupTest (void);
1737 bool verifyResult (void);
1738 };
1739
setupTest(void)1740 void FboSRGBCopyToLinearCase::setupTest (void)
1741 {
1742 // TEST INFO:
1743 // Check if copying from an fbo with an sRGB color attachment to an fbo with a linear color attachment with FRAMEBUFFER_EXT enabled results in
1744 // an sRGB to linear conversion
1745
1746 FBOConfig fboConfigs[] =
1747 {
1748 FBOConfig(GL_SRGB8_ALPHA8, getTestColorSRGB(), GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FBOTYPE_SOURCE),
1749 FBOConfig(GL_RGBA8, getTestColorBlank(), GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FBOTYPE_DESTINATION)
1750 };
1751 std::vector<FBOConfig> fboConfigList(fboConfigs, fboConfigs + DE_LENGTH_OF_ARRAY(fboConfigs));
1752
1753 const TestRenderPassConfig renderPassConfigs[] =
1754 {
1755 TestRenderPassConfig(TEXTURESOURCESTYPE_NONE, fboConfigList, FRAMEBUFFERSRGB_ENABLED, FRAMEBUFFERBLEND_DISABLED, TestFunction(false), RENDERERTASK_COPY)
1756 };
1757 std::vector<TestRenderPassConfig> renderPassConfigList(renderPassConfigs, renderPassConfigs + DE_LENGTH_OF_ARRAY(renderPassConfigs));
1758
1759 this->setTestConfig(renderPassConfigList);
1760 }
1761
verifyResult(void)1762 bool FboSRGBCopyToLinearCase::verifyResult (void)
1763 {
1764 logColor(m_context, "pre-copy source fbo color values", m_resultsPreDraw[0]);
1765 logColor(m_context, "pre-copy destination fbo color values", m_resultsPreDraw[1]);
1766 logColor(m_context, "post-copy source fbo color values", m_resultsPostDraw[0]);
1767 logColor(m_context, "post-copy destination fbo color values", m_resultsPostDraw[1]);
1768
1769 if (tcu::boolAll(tcu::lessThan(tcu::abs(m_resultsPostDraw[1] - getTestColorLinear()), getEpsilonError())) || tcu::boolAll(tcu::equal(m_resultsPostDraw[1], getTestColorLinear())))
1770 return true;
1771 else
1772 return false;
1773 }
1774
1775 class FboSRGBUnsupportedEnumCase : public TestCase
1776 {
1777 public:
1778 FboSRGBUnsupportedEnumCase (Context& context, const char* const name, const char* const description);
1779 ~FboSRGBUnsupportedEnumCase (void);
1780
1781 void init (void);
1782 void deinit (void);
1783 bool isInvalidEnum (std::string functionName);
1784 IterateResult iterate (void);
1785 };
1786
FboSRGBUnsupportedEnumCase(Context & context,const char * const name,const char * const description)1787 FboSRGBUnsupportedEnumCase::FboSRGBUnsupportedEnumCase (Context& context, const char* const name, const char* const description)
1788 : TestCase (context, name, description)
1789 {
1790 }
1791
~FboSRGBUnsupportedEnumCase(void)1792 FboSRGBUnsupportedEnumCase::~FboSRGBUnsupportedEnumCase (void)
1793 {
1794 FboSRGBUnsupportedEnumCase::deinit();
1795 }
1796
init(void)1797 void FboSRGBUnsupportedEnumCase::init (void)
1798 {
1799 // extension requirements for test
1800 if (glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)) || m_context.getContextInfo().isExtensionSupported("GL_EXT_sRGB_write_control"))
1801 TCU_THROW(NotSupportedError, "Test requires extension GL_EXT_sRGB_write_control to be unsupported and a context version less than 3.2");
1802 }
1803
deinit(void)1804 void FboSRGBUnsupportedEnumCase::deinit (void)
1805 {
1806 }
1807
isInvalidEnum(std::string functionName)1808 bool FboSRGBUnsupportedEnumCase::isInvalidEnum (std::string functionName)
1809 {
1810 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1811 tcu::TestLog& log = m_context.getTestContext().getLog();
1812 bool isOk = true;
1813 glw::GLenum error = GL_NO_ERROR;
1814
1815 log << tcu::TestLog::Message << "Checking call to " << functionName << tcu::TestLog::EndMessage;
1816
1817 error = gl.getError();
1818
1819 if (error != GL_INVALID_ENUM)
1820 {
1821 log << tcu::TestLog::Message << " returned wrong value [" << glu::getErrorStr(error) << ", expected " << glu::getErrorStr(GL_INVALID_ENUM) << "]" << tcu::TestLog::EndMessage;
1822 isOk = false;
1823 }
1824
1825 return isOk;
1826 }
1827
iterate(void)1828 FboSRGBUnsupportedEnumCase::IterateResult FboSRGBUnsupportedEnumCase::iterate (void)
1829 {
1830 // TEST INFO:
1831 // API tests that check calls using enum GL_FRAMEBUFFER_SRGB return GL_INVALID_ENUM when GL_EXT_sRGB_write_control is not supported
1832
1833 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1834 bool allPass = true;
1835 glw::GLboolean bEnabled = GL_FALSE;
1836 glw::GLfloat fEnabled = 0;
1837 glw::GLint iEnabled = 0;
1838 glw::GLint64 lEnabled = 0;
1839
1840 m_context.getTestContext().getLog() << tcu::TestLog::Message
1841 << "Check calls using enum GL_FRAMEBUFFER_SRGB return GL_INVALID_ENUM when GL_EXT_sRGB_write_control is not supported\n\n"
1842 << tcu::TestLog::EndMessage;
1843
1844 gl.enable(GL_FRAMEBUFFER_SRGB);
1845 allPass &= isInvalidEnum("glEnable()");
1846
1847 gl.disable(GL_FRAMEBUFFER_SRGB);
1848 allPass &= isInvalidEnum("glDisable()");
1849
1850 gl.isEnabled(GL_FRAMEBUFFER_SRGB);
1851 allPass &= isInvalidEnum("glIsEnabled()");
1852
1853 gl.getBooleanv(GL_FRAMEBUFFER_SRGB, &bEnabled);
1854 allPass &= isInvalidEnum("glGetBooleanv()");
1855
1856 gl.getFloatv(GL_FRAMEBUFFER_SRGB, &fEnabled);
1857 allPass &= isInvalidEnum("glGetFloatv()");
1858
1859 gl.getIntegerv(GL_FRAMEBUFFER_SRGB, &iEnabled);
1860 allPass &= isInvalidEnum("glGetIntegerv()");
1861
1862 gl.getInteger64v(GL_FRAMEBUFFER_SRGB, &lEnabled);
1863 allPass &= isInvalidEnum("glGetInteger64v()");
1864
1865 if (allPass)
1866 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1867 else
1868 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
1869
1870 return STOP;
1871 }
1872
1873 } // anonymous
1874
FboSRGBWriteControlTests(Context & context)1875 FboSRGBWriteControlTests::FboSRGBWriteControlTests (Context& context)
1876 : TestCaseGroup (context, "srgb_write_control", "Colorbuffer tests")
1877 {
1878 }
1879
~FboSRGBWriteControlTests(void)1880 FboSRGBWriteControlTests::~FboSRGBWriteControlTests (void)
1881 {
1882 }
1883
init(void)1884 void FboSRGBWriteControlTests::init (void)
1885 {
1886 this->addChild(new FboSRGBQueryCase (m_context, "framebuffer_srgb_enabled", "srgb enable framebuffer"));
1887 this->addChild(new FboSRGBColAttachCase (m_context, "framebuffer_srgb_enabled_col_attach", "srgb enable color attachment and framebuffer"));
1888 this->addChild(new FboSRGBToggleBlendCase (m_context, "framebuffer_srgb_enabled_blend", "toggle framebuffer srgb settings with blend disabled"));
1889 this->addChild(new FboSRGBRenderTargetIgnoreCase (m_context, "framebuffer_srgb_enabled_render_target_ignore", "enable framebuffer srgb, non-srgb render target should ignore"));
1890 this->addChild(new FboSRGBCopyToLinearCase (m_context, "framebuffer_srgb_enabled_copy_to_linear", "no conversion when blittering between framebuffer srgb and linear"));
1891
1892 // negative
1893 this->addChild(new FboSRGBUnsupportedEnumCase (m_context, "framebuffer_srgb_unsupported_enum", "check error codes for query functions when extension is not supported"));
1894 }
1895
1896 }
1897 } // gles31
1898 } // deqp
1899