1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES 3.1 Module
3 * -------------------------------------------------
5 * Copyright 2017 The Android Open Source Project
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * \brief FBO sRGB tests.
22 *//*--------------------------------------------------------------------*/
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"
48 tcu::Vec4 getTestColorLinear (void)
50 return tcu::Vec4(0.2f, 0.3f, 0.4f, 1.0f);
53 tcu::Vec4 getTestColorSRGB (void)
55 return linearToSRGB(tcu::Vec4(0.2f, 0.3f, 0.4f, 1.0f));
58 tcu::Vec4 getTestColorBlank (void)
60 return tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f);
63 tcu::Vec4 getEpsilonError (void)
65 return tcu::Vec4(0.005f);
70 QUERYTYPE_ISENABLED = 0,
88 FRAMEBUFFERSRGB_ENABLED = 0,
89 FRAMEBUFFERSRGB_DISABLED
94 FRAMEBUFFERBLEND_ENABLED = 0,
95 FRAMEBUFFERBLEND_DISABLED
98 enum TextureSourcesType
100 TEXTURESOURCESTYPE_RGBA = 0,
101 TEXTURESOURCESTYPE_SRGBA,
102 TEXTURESOURCESTYPE_BOTH,
103 TEXTURESOURCESTYPE_NONE
114 RENDERERTASK_DRAW = 0,
120 SAMPLINGTYPE_TEXTURE = 0,
121 SAMPLINGTYPE_TEXTURE_LOD,
122 SAMPLINGTYPE_TEXTURE_GRAD,
123 SAMPLINGTYPE_TEXTURE_OFFSET,
124 SAMPLINGTYPE_TEXTURE_PROJ,
127 namespace TestTextureSizes
129 const int WIDTH = 128;
130 const int HEIGHT = 128;
131 } // global test texture sizes
133 namespace SampligTypeCount
136 } // global max number of sampling types
138 std::string buildSamplingPassType (const int samplerTotal)
140 std::ostringstream shaderFragment;
142 const SamplingType samplingTypeList [] =
144 SAMPLINGTYPE_TEXTURE, SAMPLINGTYPE_TEXTURE_LOD, SAMPLINGTYPE_TEXTURE_GRAD, SAMPLINGTYPE_TEXTURE_OFFSET, SAMPLINGTYPE_TEXTURE_PROJ
147 for (int samplerTypeIdx = 0; samplerTypeIdx < DE_LENGTH_OF_ARRAY(samplingTypeList); samplerTypeIdx++)
150 << " if (uFunctionType == " << samplerTypeIdx << ") \n"
153 for (int samplerIdx = 0; samplerIdx < samplerTotal; samplerIdx++)
155 switch (static_cast<SamplingType>(samplerTypeIdx))
157 case SAMPLINGTYPE_TEXTURE:
160 << " texelColor" << samplerIdx << " = texture(uTexture" << samplerIdx << ", vs_aTexCoord); \n";
163 case SAMPLINGTYPE_TEXTURE_LOD:
166 << " texelColor" << samplerIdx << " = textureLod(uTexture" << samplerIdx << ", vs_aTexCoord, 0.0f); \n";
169 case SAMPLINGTYPE_TEXTURE_GRAD:
172 << " texelColor" << samplerIdx << " = textureGrad(uTexture" << samplerIdx << ", vs_aTexCoord, vec2(0.0f, 0.0f), vec2(0.0f, 0.0f)); \n";
175 case SAMPLINGTYPE_TEXTURE_OFFSET:
178 << " texelColor" << samplerIdx << " = textureOffset(uTexture" << samplerIdx << ", vs_aTexCoord, ivec2(0.0f, 0.0f)); \n";
181 case SAMPLINGTYPE_TEXTURE_PROJ:
184 << " texelColor" << samplerIdx << " = textureProj(uTexture" << samplerIdx << ", vec3(vs_aTexCoord, 1.0f)); \n";
188 DE_FATAL("Error: sampling type unrecognised");
196 return shaderFragment.str();
199 void logColor (Context& context, const std::string& colorLogMessage, const tcu::Vec4 resultColor)
201 tcu::TestLog& log = context.getTestContext().getLog();
202 std::ostringstream message;
204 message << colorLogMessage << " = (" << resultColor.x() << ", " << resultColor.y() << ", " << resultColor.z() << ", " << resultColor.w() << ")";
205 log << tcu::TestLog::Message << message.str() << tcu::TestLog::EndMessage;
210 explicit TestFunction (const bool hasFunctionValue)
211 : hasFunction (hasFunctionValue) {}
212 TestFunction (const char* const functionNameValue, const char* const functionDefinition)
214 , functionName (functionNameValue)
215 , functionDefintion (functionDefinition) {}
216 ~TestFunction (void) {}
219 const char* functionName;
220 const char* functionDefintion;
223 TestFunction getFunctionBlendLinearToSRGBCheck (void)
225 const char* const functionName = "blendPlusLinearToSRGB";
227 const char* const functionDefinition =
228 "mediump vec4 blendPlusLinearToSRGB(in mediump vec4 colorSrc, in mediump vec4 colorDst) \n"
230 " const int MAX_VECTOR_SIZE = 4; \n"
231 " mediump vec4 colorConverted; \n"
232 " mediump vec4 colorBlended; \n"
233 " for (int idx = 0; idx < MAX_VECTOR_SIZE; idx++) \n"
235 " if (uBlendFunctionType == 0) \n"
237 " colorBlended[idx] = (colorSrc[idx] * uFactorSrc) + colorDst[idx] * uFactorDst; \n"
239 " if (uBlendFunctionType == 1) \n"
241 " colorBlended[idx] = (colorSrc[idx] * uFactorSrc) - (colorDst[idx] * uFactorDst); \n"
243 "if (uBlendFunctionType == 2) \n"
245 " colorBlended[idx] = (colorDst[idx] * uFactorDst) - (colorSrc[idx] * uFactorSrc); \n"
247 " if (colorBlended[idx] < 0.0031308f) \n"
249 " colorConverted[idx] = 12.92f * colorBlended[idx]; \n"
253 " colorConverted[idx] = 1.055f * pow(colorBlended[idx], 0.41666f) - 0.055f; \n"
256 " return colorConverted; \n"
259 TestFunction testFunction(functionName, functionDefinition);
266 FBOConfig (const deUint32 textureInternalFormatValue,
267 const tcu::Vec4 textureColorValue,
268 const deUint32 fboTargetTypeValue,
269 const deUint32 fboColorAttachmentValue,
270 const FboType fboTypeValue)
271 : textureInternalFormat (textureInternalFormatValue)
272 , textureColor (textureColorValue)
273 , fboTargetType (fboTargetTypeValue)
274 , fboColorAttachment (fboColorAttachmentValue)
275 , fboType (fboTypeValue) {}
278 deUint32 textureInternalFormat;
279 tcu::Vec4 textureColor;
280 deUint32 fboTargetType;
281 deUint32 fboColorAttachment;
292 std::vector<BlendConfig> getBlendingConfigList (void)
294 BlendConfig blendConfigs[12];
296 // add function permutations
297 blendConfigs[0].equation = GL_FUNC_ADD;
298 blendConfigs[1].equation = GL_FUNC_ADD;
299 blendConfigs[2].equation = GL_FUNC_ADD;
300 blendConfigs[3].equation = GL_FUNC_ADD;
302 blendConfigs[0].funcSrc = GL_ONE;
303 blendConfigs[0].funcDst = GL_ONE;
304 blendConfigs[1].funcSrc = GL_ONE;
305 blendConfigs[1].funcDst = GL_ZERO;
306 blendConfigs[2].funcSrc = GL_ZERO;
307 blendConfigs[2].funcDst = GL_ONE;
308 blendConfigs[3].funcSrc = GL_ZERO;
309 blendConfigs[3].funcDst = GL_ZERO;
311 // subtract function permutations
312 blendConfigs[4].equation = GL_FUNC_SUBTRACT;
313 blendConfigs[5].equation = GL_FUNC_SUBTRACT;
314 blendConfigs[6].equation = GL_FUNC_SUBTRACT;
315 blendConfigs[7].equation = GL_FUNC_SUBTRACT;
317 blendConfigs[4].funcSrc = GL_ONE;
318 blendConfigs[4].funcDst = GL_ONE;
319 blendConfigs[5].funcSrc = GL_ONE;
320 blendConfigs[5].funcDst = GL_ZERO;
321 blendConfigs[6].funcSrc = GL_ZERO;
322 blendConfigs[6].funcDst = GL_ONE;
323 blendConfigs[7].funcSrc = GL_ZERO;
324 blendConfigs[7].funcDst = GL_ZERO;
326 // reverse subtract function permutations
327 blendConfigs[8].equation = GL_FUNC_REVERSE_SUBTRACT;
328 blendConfigs[9].equation = GL_FUNC_REVERSE_SUBTRACT;
329 blendConfigs[10].equation = GL_FUNC_REVERSE_SUBTRACT;
330 blendConfigs[11].equation = GL_FUNC_REVERSE_SUBTRACT;
332 blendConfigs[8].funcSrc = GL_ONE;
333 blendConfigs[8].funcDst = GL_ONE;
334 blendConfigs[9].funcSrc = GL_ONE;
335 blendConfigs[9].funcDst = GL_ZERO;
336 blendConfigs[10].funcSrc = GL_ZERO;
337 blendConfigs[10].funcDst = GL_ONE;
338 blendConfigs[11].funcSrc = GL_ZERO;
339 blendConfigs[11].funcDst = GL_ZERO;
341 std::vector<BlendConfig> configList(blendConfigs, blendConfigs + DE_LENGTH_OF_ARRAY(blendConfigs));
346 struct TestRenderPassConfig
348 TestRenderPassConfig (void)
349 : testFunction (false) {}
351 TestRenderPassConfig (const TextureSourcesType textureSourcesTypeValue,
352 FBOConfig fboConfigListValue,
353 const FramebufferSRGB framebufferSRGBValue,
354 const FramebufferBlend framebufferBendValue,
355 const RendererTask rendererTaskValue)
356 : textureSourcesType (textureSourcesTypeValue)
357 , framebufferSRGB (framebufferSRGBValue)
358 , frameBufferBlend (framebufferBendValue)
359 , testFunction (false)
360 , rendererTask (rendererTaskValue) {fboConfigList.push_back(fboConfigListValue);}
362 TestRenderPassConfig (const TextureSourcesType textureSourcesTypeValue,
363 FBOConfig fboConfigListValue,
364 const FramebufferSRGB framebufferSRGBValue,
365 const FramebufferBlend framebufferBendValue,
366 TestFunction testFunctionValue,
367 const RendererTask rendererTaskValue)
368 : textureSourcesType (textureSourcesTypeValue)
369 , framebufferSRGB (framebufferSRGBValue)
370 , frameBufferBlend (framebufferBendValue)
371 , testFunction (testFunctionValue)
372 , rendererTask (rendererTaskValue) {fboConfigList.push_back(fboConfigListValue);}
374 TestRenderPassConfig (const TextureSourcesType textureSourcesTypeValue,
375 std::vector<FBOConfig> fboConfigListValue,
376 const FramebufferSRGB framebufferSRGBValue,
377 const FramebufferBlend framebufferBendValue,
378 TestFunction testFunctionValue,
379 const RendererTask rendererTaskValue)
380 : textureSourcesType (textureSourcesTypeValue)
381 , fboConfigList (fboConfigListValue)
382 , framebufferSRGB (framebufferSRGBValue)
383 , frameBufferBlend (framebufferBendValue)
384 , testFunction (testFunctionValue)
385 , rendererTask (rendererTaskValue) {}
387 ~TestRenderPassConfig (void) {}
389 TextureSourcesType textureSourcesType;
390 std::vector<FBOConfig> fboConfigList;
391 FramebufferSRGB framebufferSRGB;
392 FramebufferBlend frameBufferBlend;
393 TestFunction testFunction;
394 RendererTask rendererTask;
400 TestVertexData (Context& context);
401 ~TestVertexData (void);
405 void bind (void) const;
406 void unbind (void) const;
409 const glw::Functions* m_gl;
410 std::vector<float> m_data;
411 glw::GLuint m_vboHandle;
412 glw::GLuint m_vaoHandle;
415 TestVertexData::TestVertexData (Context& context)
416 : m_gl (&context.getRenderContext().getFunctions())
418 const glw::GLfloat vertexData[] =
420 // position // texcoord
421 -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, // bottom left corner
422 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, // bottom right corner
423 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, // Top right corner
425 -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, // top left corner
426 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, // Top right corner
427 -1.0f, -1.0f, 0.0f, 0.0f, 0.0f // bottom left corner
430 m_data.resize(DE_LENGTH_OF_ARRAY(vertexData));
431 for (int idx = 0; idx < (int)m_data.size(); idx++)
432 m_data[idx] = vertexData[idx];
434 m_gl->genVertexArrays(1, &m_vaoHandle);
435 m_gl->bindVertexArray(m_vaoHandle);
437 m_gl->genBuffers(1, &m_vboHandle);
438 m_gl->bindBuffer(GL_ARRAY_BUFFER, m_vboHandle);
440 m_gl->bufferData(GL_ARRAY_BUFFER, (glw::GLsizei)(m_data.size() * sizeof(glw::GLfloat)), &m_data[0], GL_STATIC_DRAW);
442 m_gl->enableVertexAttribArray(0);
443 m_gl->vertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * (glw::GLsizei)sizeof(GL_FLOAT), (glw::GLvoid *)0);
444 m_gl->enableVertexAttribArray(1);
445 m_gl->vertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * (glw::GLsizei)sizeof(GL_FLOAT), (glw::GLvoid *)(3 * sizeof(GL_FLOAT)));
447 m_gl->bindVertexArray(0);
448 m_gl->bindBuffer(GL_ARRAY_BUFFER, 0);
449 GLU_EXPECT_NO_ERROR(m_gl->getError(), "gl error during vertex data setup");
452 TestVertexData::~TestVertexData (void)
454 m_gl->deleteBuffers(1, &m_vboHandle);
455 m_gl->deleteVertexArrays(1, &m_vaoHandle);
458 void TestVertexData::bind (void) const
460 m_gl->bindVertexArray(m_vaoHandle);
463 void TestVertexData::unbind (void) const
465 m_gl->bindVertexArray(0);
471 TestTexture2D (Context& context, const deUint32 internalFormatValue, const deUint32 transferFormatValue, const deUint32 transferTypeValue, const tcu::Vec4 imageColorValue, const int idx);
472 ~TestTexture2D (void);
474 int getTextureUnit (void) const;
475 deUint32 getHandle (void) const;
476 int getIdx (void) const;
478 void bind (const int textureUnit);
479 void unbind (void) const;
482 const glw::Functions* m_gl;
483 glw::GLuint m_handle;
484 const deUint32 m_internalFormat;
485 tcu::TextureFormat m_transferFormat;
488 tcu::TextureLevel m_imageData;
493 TestTexture2D::TestTexture2D (Context& context, const deUint32 internalFormat, const deUint32 transferFormat, const deUint32 transferType, const tcu::Vec4 imageColor, const int idx)
494 : m_gl (&context.getRenderContext().getFunctions())
495 , m_internalFormat (internalFormat)
496 , m_transferFormat (tcu::TextureFormat(glu::mapGLTransferFormat(transferFormat, transferType)))
497 , m_width (TestTextureSizes::WIDTH)
498 , m_height (TestTextureSizes::HEIGHT)
499 , m_imageData (tcu::TextureLevel(glu::mapGLInternalFormat(internalFormat), m_width, m_height, 1))
502 // fill image data with a solid test color
503 tcu::clear(m_imageData.getAccess(), tcu::Vec4(0.0f));
504 for (int py = 0; py < m_imageData.getHeight(); py++)
506 for (int px = 0; px < m_imageData.getWidth(); px++)
507 m_imageData.getAccess().setPixel(imageColor, px, py);
510 m_gl->genTextures(1, &m_handle);
512 m_gl->bindTexture(GL_TEXTURE_2D, m_handle);
513 m_gl->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
514 m_gl->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
515 m_gl->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
516 m_gl->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
518 m_gl->texImage2D(GL_TEXTURE_2D, 0, m_internalFormat, m_width, m_height, 0, transferFormat, transferType, m_imageData.getAccess().getDataPtr());
520 m_gl->bindTexture(GL_TEXTURE_2D, 0);
523 TestTexture2D::~TestTexture2D (void)
525 m_gl->deleteTextures(1, &m_handle);
528 int TestTexture2D::getTextureUnit (void) const
530 return m_textureUnit;
533 deUint32 TestTexture2D::getHandle (void) const
538 int TestTexture2D::getIdx (void) const
543 void TestTexture2D::bind (const int textureUnit)
545 m_textureUnit = textureUnit;
546 m_gl->activeTexture(GL_TEXTURE0 + m_textureUnit);
547 m_gl->bindTexture(GL_TEXTURE_2D, m_handle);
550 void TestTexture2D::unbind (void) const
552 m_gl->bindTexture(GL_TEXTURE_2D, 0);
555 class TestFramebuffer
558 TestFramebuffer (void);
559 TestFramebuffer (Context& context, const deUint32 targetType, const deUint32 colorAttachment, glw::GLuint textureAttachmentHandle, const bool isSRGB, const FboType fboType, const int idx);
560 ~TestFramebuffer (void);
562 void setTargetType (const deUint32 targetType);
564 FboType getType (void) const;
565 deUint32 getHandle (void) const;
566 deUint32 getColorAttachment (void) const;
567 int getIdx (void) const;
568 deUint32 getTargetType (void) const;
573 typedef de::UniquePtr<glu::Framebuffer> fboUniquePtr;
576 const glw::Functions* m_gl;
577 fboUniquePtr m_referenceSource;
578 deUint32 m_targetType;
583 deUint32 m_colorAttachment;
586 TestFramebuffer::TestFramebuffer (Context& context, const deUint32 targetType, const deUint32 colorAttachment, glw::GLuint textureAttachmentHandle, const bool isSRGB, const FboType fboType, const int idx)
587 : m_gl (&context.getRenderContext().getFunctions())
588 , m_referenceSource (new glu::Framebuffer(context.getRenderContext()))
589 , m_targetType (targetType)
594 , m_colorAttachment (colorAttachment)
596 m_gl->bindFramebuffer(m_targetType, **m_referenceSource);
598 m_gl->framebufferTexture2D(m_targetType, m_colorAttachment, GL_TEXTURE_2D, textureAttachmentHandle, 0);
600 TCU_CHECK(m_gl->checkFramebufferStatus(m_targetType) == GL_FRAMEBUFFER_COMPLETE);
602 if (targetType == GL_DRAW_BUFFER)
604 glw::GLuint textureAttachments[] = {m_colorAttachment};
605 m_gl->drawBuffers(DE_LENGTH_OF_ARRAY(textureAttachments), textureAttachments);
606 GLU_EXPECT_NO_ERROR(m_gl->getError(), "glDrawBuffer()");
609 if (targetType == GL_READ_BUFFER)
611 m_gl->readBuffer(m_colorAttachment);
612 GLU_EXPECT_NO_ERROR(m_gl->getError(), "glReadBuffer()");
615 m_gl->bindFramebuffer(m_targetType, 0);
618 TestFramebuffer::~TestFramebuffer (void)
622 void TestFramebuffer::setTargetType (const deUint32 targetType)
624 m_targetType = targetType;
627 FboType TestFramebuffer::getType (void) const
632 deUint32 TestFramebuffer::getHandle (void) const
634 return **m_referenceSource;
637 deUint32 TestFramebuffer::getColorAttachment (void) const
639 return m_colorAttachment;
642 int TestFramebuffer::getIdx (void) const
647 deUint32 TestFramebuffer::getTargetType (void) const
652 void TestFramebuffer::bind (void)
656 m_gl->bindFramebuffer(m_targetType, **m_referenceSource);
661 void TestFramebuffer::unbind (void)
665 m_gl->bindFramebuffer(m_targetType, 0);
670 class TestShaderProgram
673 TestShaderProgram (Context& context, const int samplerTotal, TestFunction testFunction);
674 ~TestShaderProgram (void);
676 glw::GLuint getHandle (void) const;
677 int getSamplerTotal (void) const;
679 void use (void) const;
680 void unuse (void) const;
682 glu::ShaderProgramInfo getLogInfo (void);
685 const glw::Functions* m_gl;
686 de::MovePtr<glu::ShaderProgram> m_referenceSource;
687 const int m_samplerTotal;
688 const int m_shaderStagesTotal;
691 TestShaderProgram::TestShaderProgram (Context& context, const int samplerTotal, TestFunction testFunction)
692 : m_gl (&context.getRenderContext().getFunctions())
693 , m_samplerTotal (samplerTotal)
694 , m_shaderStagesTotal (2)
696 std::ostringstream shaderFragment;
698 const char* const shaderVertex =
700 "layout (location = 0) in mediump vec3 aPosition; \n"
701 "layout (location = 1) in mediump vec2 aTexCoord; \n"
702 "out mediump vec2 vs_aTexCoord; \n"
705 " gl_Position = vec4(aPosition, 1.0f); \n"
706 " vs_aTexCoord = aTexCoord; \n"
710 << "#version 310 es \n"
711 << "in mediump vec2 vs_aTexCoord; \n"
712 << "layout (location = 0) out mediump vec4 fs_aColor0; \n";
714 for (int samplerIdx = 0; samplerIdx < m_samplerTotal; samplerIdx++)
716 << "uniform sampler2D uTexture" << samplerIdx << "; \n";
719 << "uniform int uFunctionType; \n";
721 if (testFunction.hasFunction)
723 << "uniform int uBlendFunctionType; \n"
724 << "uniform mediump float uFactorSrc; \n"
725 << "uniform mediump float uFactorDst; \n"
726 << testFunction.functionDefintion;
732 for (int samplerIdx = 0; samplerIdx < m_samplerTotal; samplerIdx++)
734 <<" mediump vec4 texelColor" << samplerIdx << " = vec4(0.0f, 0.0f, 0.0f, 1.0f); \n";
737 << buildSamplingPassType(m_samplerTotal);
739 if (testFunction.hasFunction)
741 << " fs_aColor0 = " << testFunction.functionName << "(texelColor0, texelColor1); \n";
744 << " fs_aColor0 = texelColor0; \n";
749 m_referenceSource = de::MovePtr<glu::ShaderProgram>(new glu::ShaderProgram(context.getRenderContext(), glu::makeVtxFragSources(shaderVertex, shaderFragment.str())));
750 if (!m_referenceSource->isOk())
752 tcu::TestLog& log = context.getTestContext().getLog();
753 log << this->getLogInfo();
754 TCU_FAIL("Failed to compile shaders and link program");
758 TestShaderProgram::~TestShaderProgram (void)
760 m_referenceSource = de::MovePtr<glu::ShaderProgram>(DE_NULL);
761 m_referenceSource.clear();
764 deUint32 TestShaderProgram::getHandle (void) const
766 return m_referenceSource->getProgram();
769 int TestShaderProgram::getSamplerTotal (void) const
771 return m_samplerTotal;
774 void TestShaderProgram::use (void) const
776 m_gl->useProgram(this->getHandle());
779 void TestShaderProgram::unuse (void) const
784 glu::ShaderProgramInfo TestShaderProgram::getLogInfo (void)
786 glu::ShaderProgramInfo buildInfo;
788 // log shader program info. Only vertex and fragment shaders included
789 buildInfo.program = m_referenceSource->getProgramInfo();
790 for (int shaderIdx = 0; shaderIdx < m_shaderStagesTotal; shaderIdx++)
792 glu::ShaderInfo shaderInfo = m_referenceSource->getShaderInfo(static_cast<glu::ShaderType>(static_cast<int>(glu::SHADERTYPE_VERTEX) + static_cast<int>(shaderIdx)), 0);
793 buildInfo.shaders.push_back(shaderInfo);
801 Renderer (Context& context);
804 void init (const TestRenderPassConfig& renderPassConfig, const int renderpass);
807 void setSamplingType (const SamplingType samplerIdx);
808 void setBlendIteration (const int blendIteration);
809 void setFramebufferBlend (const bool blend);
810 void setFramebufferSRGB (const bool sRGB);
812 std::vector<tcu::Vec4> getResultsPreDraw (void) const;
813 std::vector<tcu::Vec4> getResultsPostDraw (void) const;
814 int getBlendConfigCount (void) const;
815 glu::ShaderProgramInfo getShaderProgramInfo (void);
817 void copyFrameBufferTexture (const int srcPx, const int srcPy, const int dstPx, const int dstPy);
819 void storeShaderProgramInfo (void);
820 void logShaderProgramInfo (void);
822 typedef de::SharedPtr<TestTexture2D> TextureSp;
823 typedef de::SharedPtr<TestFramebuffer> FboSp;
826 void createFBOwithColorAttachment (const std::vector<FBOConfig> fboConfigList);
827 void setShaderProgramSamplingType (const int samplerIdx);
828 void setShaderBlendFunctionType (void);
829 void setShaderBlendSrcDstValues (void);
830 void bindActiveTexturesSamplers (void);
831 void bindAllRequiredSourceTextures (const TextureSourcesType texturesRequired);
832 void unbindAllSourceTextures (void);
833 void bindFramebuffer (const int framebufferIdx);
834 void unbindFramebuffer (const int framebufferIdx);
835 void enableFramebufferSRGB (void);
836 void enableFramebufferBlend (void);
837 bool isFramebufferAttachmentSRGB (const deUint32 targetType, const deUint32 attachment) const;
838 void readTexels (const int px, const int py, const deUint32 attachment, tcu::Vec4& texelData);
839 void logState (const deUint32 targetType, const deUint32 attachment, const SamplingType samplingType) const;
841 // renderer specific constants initialized during constructor
843 const TestVertexData m_vertexData;
844 const int m_textureSourceTotal;
846 // additional resources monitored by the renderer
847 std::vector<BlendConfig> m_blendConfigList;
848 std::vector<TextureSp> m_textureSourceList;
849 TestRenderPassConfig m_renderPassConfig;
850 std::vector<TextureSp> m_fboTextureList;
851 TestShaderProgram* m_shaderProgram;
852 std::vector<FboSp> m_framebufferList;
853 std::vector<tcu::Vec4> m_resultsListPreDraw;
854 std::vector<tcu::Vec4> m_resultsListPostDraw;
856 // mutable state variables (internal access only)
857 bool m_hasShaderProgramInfo;
859 int m_samplersRequired;
861 bool m_blittingEnabled;
862 glu::ShaderProgramInfo m_shaderProgramInfo;
864 // mutable state variables (external access via setters)
865 SamplingType m_samplingType;
866 int m_blendIteration;
867 bool m_framebufferBlendEnabled;
868 bool m_framebufferSRGBEnabled;
871 Renderer::Renderer (Context& context)
872 : m_context (context)
873 , m_vertexData (context)
874 , m_textureSourceTotal (2)
875 , m_blendConfigList (getBlendingConfigList())
876 , m_hasShaderProgramInfo (false)
878 TextureSp textureLinear(new TestTexture2D(m_context, GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, getTestColorLinear(), 0));
879 m_textureSourceList.push_back(textureLinear);
881 TextureSp textureSRGB(new TestTexture2D(m_context, GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, getTestColorLinear(), 1));
882 m_textureSourceList.push_back(textureSRGB);
885 Renderer::~Renderer (void)
887 m_textureSourceList.clear();
891 void Renderer::init (const TestRenderPassConfig& renderPassConfig, const int renderpass)
893 m_renderPassConfig = renderPassConfig;
894 m_renderPass = renderpass;
896 this->createFBOwithColorAttachment(m_renderPassConfig.fboConfigList);
898 if (m_renderPassConfig.textureSourcesType != TEXTURESOURCESTYPE_NONE)
900 if (m_renderPassConfig.textureSourcesType == TEXTURESOURCESTYPE_RGBA || m_renderPassConfig.textureSourcesType == TEXTURESOURCESTYPE_SRGBA)
901 m_samplersRequired = 1;
902 else if (m_renderPassConfig.textureSourcesType ==TEXTURESOURCESTYPE_BOTH )
903 m_samplersRequired = 2;
905 DE_FATAL("Error: Texture source required not recognised");
907 m_shaderProgram = new TestShaderProgram(m_context, m_samplersRequired, m_renderPassConfig.testFunction);
908 m_hasFunction = m_renderPassConfig.testFunction.hasFunction;
911 m_shaderProgram = DE_NULL;
914 void Renderer::deinit (void)
916 if (m_shaderProgram != DE_NULL)
918 delete m_shaderProgram;
919 m_shaderProgram = DE_NULL;
922 m_fboTextureList.clear();
923 m_framebufferList.clear();
926 void Renderer::setSamplingType (const SamplingType samplingType)
928 m_samplingType = samplingType;
931 void Renderer::setBlendIteration (const int blendIteration)
933 m_blendIteration = blendIteration;
936 void Renderer::setFramebufferBlend (const bool blend)
938 m_framebufferBlendEnabled = blend;
941 void Renderer::setFramebufferSRGB (const bool sRGB)
943 m_framebufferSRGBEnabled = sRGB;
946 std::vector<tcu::Vec4> Renderer::getResultsPreDraw (void) const
948 return m_resultsListPreDraw;
951 std::vector<tcu::Vec4> Renderer::getResultsPostDraw (void) const
953 return m_resultsListPostDraw;
956 int Renderer::getBlendConfigCount (void) const
958 return (int)m_blendConfigList.size();
961 void Renderer::copyFrameBufferTexture (const int srcPx, const int srcPy, const int dstPx, const int dstPy)
963 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
966 deUint32 fboSrcColAttachment = GL_NONE;
967 deUint32 fboDstColAttachment = GL_NONE;
969 for (int idx = 0; idx < (int)m_framebufferList.size(); idx++)
970 this->bindFramebuffer(idx);
972 // cache fbo attachments and idx locations
973 for (int idx = 0; idx < (int)m_framebufferList.size(); idx++)
975 if (m_framebufferList[idx]->getType() == FBOTYPE_SOURCE)
977 fboSrcIdx = m_framebufferList[idx]->getIdx();
978 fboSrcColAttachment = m_framebufferList[fboSrcIdx]->getColorAttachment();
980 if (m_framebufferList[idx]->getType() == FBOTYPE_DESTINATION)
982 fboDstIdx = m_framebufferList[idx]->getIdx();
983 fboDstColAttachment = m_framebufferList[fboDstIdx]->getColorAttachment();
987 for (int idx = 0; idx < (int)m_framebufferList.size(); idx++)
988 m_framebufferList[idx]->unbind();
990 // store texel data from both src and dst before performing the copy
991 m_resultsListPreDraw.resize(2);
992 m_framebufferList[fboSrcIdx]->bind();
993 this->readTexels(0, 0, fboSrcColAttachment, m_resultsListPreDraw[0]);
994 m_framebufferList[fboSrcIdx]->unbind();
995 m_framebufferList[fboDstIdx]->setTargetType(GL_READ_FRAMEBUFFER);
996 m_framebufferList[fboDstIdx]->bind();
997 this->readTexels(0, 0, fboDstColAttachment, m_resultsListPreDraw[1]);
998 m_framebufferList[fboDstIdx]->unbind();
999 m_framebufferList[fboDstIdx]->setTargetType(GL_DRAW_FRAMEBUFFER);
1001 m_framebufferList[fboSrcIdx]->bind();
1002 m_framebufferList[fboDstIdx]->bind();
1004 this->enableFramebufferSRGB();
1005 this->enableFramebufferBlend();
1007 gl.blitFramebuffer( srcPx, srcPy, TestTextureSizes::WIDTH, TestTextureSizes::HEIGHT,
1008 dstPx, dstPy, TestTextureSizes::WIDTH, TestTextureSizes::HEIGHT,
1009 GL_COLOR_BUFFER_BIT, GL_NEAREST);
1011 m_resultsListPostDraw.resize(2);
1012 this->readTexels(0, 0, fboSrcColAttachment, m_resultsListPostDraw[0]);
1013 m_framebufferList[fboSrcIdx]->unbind();
1014 m_framebufferList[fboDstIdx]->unbind();
1016 m_framebufferList[fboDstIdx]->setTargetType(GL_READ_FRAMEBUFFER);
1017 m_framebufferList[fboDstIdx]->bind();
1018 this->readTexels(0, 0, fboDstColAttachment, m_resultsListPostDraw[1]);
1019 m_framebufferList[fboDstIdx]->unbind();
1022 void Renderer::draw (void)
1024 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1026 if (m_renderPassConfig.textureSourcesType == TEXTURESOURCESTYPE_NONE)
1027 DE_FATAL("Error: Attempted to draw with no texture sources");
1029 // resize results storage with each render pass
1030 m_resultsListPreDraw.resize(m_renderPass + 1);
1031 m_resultsListPostDraw.resize(m_renderPass + 1);
1033 m_shaderProgram->use();
1034 m_vertexData.bind();
1036 for (int idx = 0; idx < (int)m_framebufferList.size(); idx++)
1037 this->bindFramebuffer(idx);
1039 this->bindAllRequiredSourceTextures(m_renderPassConfig.textureSourcesType);
1040 this->bindActiveTexturesSamplers();
1042 this->enableFramebufferSRGB();
1043 this->enableFramebufferBlend();
1045 this->readTexels(0, 0, GL_COLOR_ATTACHMENT0, m_resultsListPreDraw[m_renderPass]);
1046 this->setShaderProgramSamplingType(m_samplingType);
1049 this->setShaderBlendFunctionType();
1050 this->setShaderBlendSrcDstValues();
1053 gl.drawArrays(GL_TRIANGLES, 0, 6);
1055 this->readTexels(0, 0, GL_COLOR_ATTACHMENT0, m_resultsListPostDraw[m_renderPass]);
1056 this->logState(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_samplingType);
1058 this->unbindAllSourceTextures();
1059 for (int idx = 0; idx < (int)m_framebufferList.size(); idx++)
1060 this->unbindFramebuffer(idx);
1061 m_vertexData.unbind();
1062 m_shaderProgram->unuse();
1065 void Renderer::storeShaderProgramInfo (void)
1067 m_shaderProgramInfo = m_shaderProgram->getLogInfo();
1068 m_hasShaderProgramInfo = true;
1071 void Renderer::logShaderProgramInfo (void)
1073 tcu::TestLog& log = m_context.getTestContext().getLog();
1075 if (m_hasShaderProgramInfo)
1076 log << m_shaderProgramInfo;
1079 void Renderer::createFBOwithColorAttachment (const std::vector<FBOConfig> fboConfigList)
1081 const int size = (int)fboConfigList.size();
1082 for (int idx = 0; idx < size; idx++)
1084 TextureSp texture(new TestTexture2D(m_context, fboConfigList[idx].textureInternalFormat, GL_RGBA, GL_UNSIGNED_BYTE, fboConfigList[idx].textureColor, idx));
1085 m_fboTextureList.push_back(texture);
1088 if (fboConfigList[idx].textureInternalFormat == GL_SRGB8_ALPHA8)
1093 FboSp framebuffer(new TestFramebuffer(m_context, fboConfigList[idx].fboTargetType, fboConfigList[idx].fboColorAttachment, texture->getHandle(), isSRGB, fboConfigList[idx].fboType, idx));
1094 m_framebufferList.push_back(framebuffer);
1098 void Renderer::setShaderProgramSamplingType (const int samplerIdx)
1100 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1102 glw::GLuint location = gl.getUniformLocation(m_shaderProgram->getHandle(), "uFunctionType");
1103 DE_ASSERT(location != (glw::GLuint)-1);
1104 gl.uniform1i(location, samplerIdx);
1107 void Renderer::setShaderBlendFunctionType (void)
1109 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1112 if (m_blendConfigList[m_blendIteration].equation == GL_FUNC_ADD)
1114 else if (m_blendConfigList[m_blendIteration].equation == GL_FUNC_SUBTRACT)
1116 else if (m_blendConfigList[m_blendIteration].equation == GL_FUNC_REVERSE_SUBTRACT)
1119 DE_FATAL("Error: Blend function not recognised");
1121 glw::GLuint location = gl.getUniformLocation(m_shaderProgram->getHandle(), "uBlendFunctionType");
1122 DE_ASSERT(location != (glw::GLuint)-1);
1123 gl.uniform1i(location, function);
1126 void Renderer::setShaderBlendSrcDstValues (void)
1128 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1131 if (m_blendConfigList[m_blendIteration].funcSrc == GL_ONE)
1137 if (m_blendConfigList[m_blendIteration].funcDst == GL_ONE)
1142 glw::GLuint locationSrc = gl.getUniformLocation(m_shaderProgram->getHandle(), "uFactorSrc");
1143 gl.uniform1f(locationSrc, funcSrc);
1144 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1f()");
1146 glw::GLuint locationDst = gl.getUniformLocation(m_shaderProgram->getHandle(), "uFactorDst");
1147 gl.uniform1f(locationDst, funcDst);
1148 GLU_EXPECT_NO_ERROR(gl.getError(), "glUniform1f()");
1151 void Renderer::bindActiveTexturesSamplers (void)
1153 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1155 for (int idx = 0; idx < m_samplersRequired; idx++)
1157 std::ostringstream stream;
1158 stream << "uTexture" << idx;
1159 std::string uniformName(stream.str());
1160 glw::GLint location = gl.getUniformLocation(m_shaderProgram->getHandle(), uniformName.c_str());
1161 DE_ASSERT(location != -1);
1162 gl.uniform1i(location, m_textureSourceList[idx]->getTextureUnit());
1163 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation()");
1167 void Renderer::bindAllRequiredSourceTextures (const TextureSourcesType texturesRequired)
1169 if (texturesRequired == TEXTURESOURCESTYPE_RGBA)
1170 m_textureSourceList[0]->bind(0);
1171 else if (texturesRequired == TEXTURESOURCESTYPE_SRGBA)
1172 m_textureSourceList[1]->bind(0);
1173 else if (texturesRequired == TEXTURESOURCESTYPE_BOTH)
1175 m_textureSourceList[0]->bind(0);
1176 m_textureSourceList[1]->bind(1);
1179 DE_FATAL("Error: Invalid sources requested in bind all");
1182 void Renderer::unbindAllSourceTextures (void)
1184 for (int idx = 0; idx < (int)m_textureSourceList.size(); idx++)
1185 m_textureSourceList[idx]->unbind();
1188 void Renderer::bindFramebuffer (const int framebufferIdx)
1190 m_framebufferList[framebufferIdx]->bind();
1193 void Renderer::unbindFramebuffer (const int framebufferIdx)
1195 m_framebufferList[framebufferIdx]->unbind();
1198 void Renderer::enableFramebufferSRGB (void)
1200 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1202 if (m_framebufferSRGBEnabled)
1203 gl.enable(GL_FRAMEBUFFER_SRGB);
1205 gl.disable(GL_FRAMEBUFFER_SRGB);
1208 void Renderer::enableFramebufferBlend (void)
1210 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1211 tcu::TestLog& log = m_context.getTestContext().getLog();
1212 std::ostringstream message;
1214 message << "Blend settings = ";
1216 if (m_framebufferBlendEnabled)
1218 gl.enable(GL_BLEND);
1219 gl.blendEquation(m_blendConfigList[m_blendIteration].equation);
1220 gl.blendFunc(m_blendConfigList[m_blendIteration].funcSrc, m_blendConfigList[m_blendIteration].funcDst);
1222 std::string equation, src, dst;
1223 if (m_blendConfigList[m_blendIteration].equation == GL_FUNC_ADD)
1224 equation = "GL_FUNC_ADD";
1225 if (m_blendConfigList[m_blendIteration].equation == GL_FUNC_SUBTRACT)
1226 equation = "GL_FUNC_SUBTRACT";
1227 if (m_blendConfigList[m_blendIteration].equation == GL_FUNC_REVERSE_SUBTRACT)
1228 equation = "GL_FUNC_REVERSE_SUBTRACT";
1229 if (m_blendConfigList[m_blendIteration].funcSrc == GL_ONE)
1233 if (m_blendConfigList[m_blendIteration].funcDst == GL_ONE)
1238 message << "Enabled: equation = " << equation << ", func src = " << src << ", func dst = " << dst;
1242 gl.disable(GL_BLEND);
1243 message << "Disabled";
1246 log << tcu::TestLog::Message << message.str() << tcu::TestLog::EndMessage;
1249 bool Renderer::isFramebufferAttachmentSRGB (const deUint32 targetType, const deUint32 attachment) const
1251 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1252 glw::GLint encodingType;
1254 gl.getFramebufferAttachmentParameteriv(targetType, attachment, GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, &encodingType);
1255 GLU_EXPECT_NO_ERROR(gl.getError(), "glGetNamedFramebufferAttachmentParameteriv()");
1257 switch (static_cast<glw::GLenum>(encodingType))
1271 DE_FATAL("Error: Color attachment format not recognised");
1277 void Renderer::readTexels (const int px, const int py, const deUint32 mode, tcu::Vec4& texelData)
1279 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1280 tcu::TextureLevel textureRead;
1282 // ensure result sampling coordinates are within range of the result color attachment
1283 DE_ASSERT((px >= 0) && (px < m_context.getRenderTarget().getWidth()));
1284 DE_ASSERT((py >= 0) && (py < m_context.getRenderTarget().getHeight()));
1286 gl.readBuffer(mode);
1287 textureRead.setStorage(glu::mapGLTransferFormat(GL_RGBA, GL_UNSIGNED_BYTE), TestTextureSizes::WIDTH, TestTextureSizes::HEIGHT);
1288 glu::readPixels(m_context.getRenderContext(), px, py, textureRead.getAccess());
1289 GLU_EXPECT_NO_ERROR(gl.getError(), "glReadPixels()");
1290 texelData = textureRead.getAccess().getPixel(px, py);
1293 void Renderer::logState (const deUint32 targetType, const deUint32 attachment, const SamplingType samplingType) const
1295 tcu::TestLog& log = m_context.getTestContext().getLog();
1296 std::ostringstream message;
1298 bool fboAttachmentSRGB = this->isFramebufferAttachmentSRGB(targetType, attachment);
1300 message << "getFramebufferAttachmentParameteriv() check = ";
1301 if (fboAttachmentSRGB)
1302 message << "GL_SRGB";
1304 message << "GL_LINEAR";
1305 log << tcu::TestLog::Message << message.str() << tcu::TestLog::EndMessage;
1308 message << "Framebuffer color attachment value BEFORE draw call";
1309 logColor(m_context, message.str(), m_resultsListPreDraw[m_renderPass]);
1312 message << "Framebuffer color attachment value AFTER draw call";
1313 logColor(m_context, message.str(), m_resultsListPostDraw[m_renderPass]);
1316 message << "Sampling type = ";
1318 if (samplingType == 0)
1320 else if (samplingType == 1)
1321 type = "textureLOD()";
1322 else if (samplingType == 2)
1323 type = "textureGrad()";
1324 else if (samplingType == 3)
1325 type = "textureOffset()";
1326 else if (samplingType == 4)
1327 type = "textureProj()";
1329 DE_FATAL("Error: Sampling type unregonised");
1331 log << tcu::TestLog::Message << message.str() << tcu::TestLog::EndMessage;
1334 if (m_framebufferSRGBEnabled)
1335 message << "Framebuffer SRGB = enabled";
1337 message << "Framebuffer SRGB = disabled";
1338 log << tcu::TestLog::Message << message.str() << tcu::TestLog::EndMessage;
1341 class FboSRGBTestCase : public TestCase
1344 FboSRGBTestCase (Context& context, const char* const name, const char* const desc);
1345 ~FboSRGBTestCase (void);
1349 IterateResult iterate (void);
1351 void setTestConfig (std::vector<TestRenderPassConfig> renderPassConfigList);
1353 virtual void setupTest (void) = 0;
1354 virtual bool verifyResult (void) = 0;
1357 bool m_hasTestConfig;
1358 std::vector<TestRenderPassConfig> m_renderPassConfigList;
1359 bool m_testcaseRequiresBlend;
1360 std::vector<tcu::Vec4> m_resultsPreDraw;
1361 std::vector<tcu::Vec4> m_resultsPostDraw;
1364 FboSRGBTestCase (const FboSRGBTestCase&);
1365 FboSRGBTestCase& operator= (const FboSRGBTestCase&);
1368 FboSRGBTestCase::FboSRGBTestCase (Context& context, const char* const name, const char* const desc)
1369 : TestCase (context, name, desc)
1370 , m_hasTestConfig (false)
1374 FboSRGBTestCase::~FboSRGBTestCase (void)
1376 FboSRGBTestCase::deinit();
1379 void FboSRGBTestCase::init (void)
1381 // extensions requirements for test
1382 if (!glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)))
1383 TCU_THROW(NotSupportedError, "Test requires a context version equal or higher than 3.2");
1385 if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_sRGB_write_control"))
1386 TCU_THROW(NotSupportedError, "Test requires extension GL_EXT_sRGB_write_control");
1388 if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_texture_sRGB_decode"))
1389 TCU_THROW(NotSupportedError, "Test requires GL_EXT_texture_sRGB_decode extension");
1392 void FboSRGBTestCase::deinit (void)
1396 FboSRGBTestCase::IterateResult FboSRGBTestCase::iterate (void)
1400 DE_ASSERT(m_hasTestConfig && "Error: Renderer was not supplied a test config");
1402 Renderer renderer(m_context);
1404 // loop through each sampling type
1405 for (int samplingIdx = 0; samplingIdx < SampligTypeCount::MAX; samplingIdx++)
1407 renderer.setSamplingType(static_cast<SamplingType>(samplingIdx));
1409 // loop through each blend configuration
1410 const int blendCount = renderer.getBlendConfigCount();
1411 for (int blendIdx = 0; blendIdx < blendCount; blendIdx++)
1413 // loop through each render pass
1414 const int renderPassCount = (int)m_renderPassConfigList.size();
1415 for (int renderPassIdx = 0; renderPassIdx < renderPassCount; renderPassIdx++)
1417 TestRenderPassConfig renderPassConfig = m_renderPassConfigList[renderPassIdx];
1419 renderer.init(renderPassConfig, renderPassIdx);
1421 if (blendIdx == 0 && renderPassConfig.rendererTask == RENDERERTASK_DRAW)
1422 renderer.storeShaderProgramInfo();
1424 if (renderPassConfig.frameBufferBlend == FRAMEBUFFERBLEND_ENABLED)
1426 renderer.setBlendIteration(blendIdx);
1427 renderer.setFramebufferBlend(true);
1430 renderer.setFramebufferBlend(false);
1432 if (renderPassConfig.framebufferSRGB == FRAMEBUFFERSRGB_ENABLED)
1433 renderer.setFramebufferSRGB(true);
1435 renderer.setFramebufferSRGB(false);
1437 if (renderPassConfig.rendererTask == RENDERERTASK_DRAW)
1439 else if (renderPassConfig.rendererTask == RENDERERTASK_COPY)
1440 renderer.copyFrameBufferTexture(0, 0, 0, 0);
1442 DE_FATAL("Error: render task not recognised");
1448 m_resultsPreDraw = renderer.getResultsPreDraw();
1449 m_resultsPostDraw = renderer.getResultsPostDraw();
1451 bool testPassed = this->verifyResult();
1453 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1456 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Result verification failed");
1457 renderer.logShaderProgramInfo();
1461 if (!m_testcaseRequiresBlend)
1465 renderer.logShaderProgramInfo();
1471 void FboSRGBTestCase::setTestConfig (std::vector<TestRenderPassConfig> renderPassConfigList)
1473 m_renderPassConfigList = renderPassConfigList;
1474 m_hasTestConfig = true;
1476 for (int idx = 0; idx < (int)renderPassConfigList.size(); idx++)
1478 if (renderPassConfigList[idx].frameBufferBlend == FRAMEBUFFERBLEND_ENABLED)
1480 m_testcaseRequiresBlend = true;
1484 m_testcaseRequiresBlend = false;
1487 class FboSRGBQueryCase : public TestCase
1490 FboSRGBQueryCase (Context& context, const char* const name, const char* const description);
1491 ~FboSRGBQueryCase (void);
1495 IterateResult iterate (void);
1498 FboSRGBQueryCase::FboSRGBQueryCase (Context& context, const char* const name, const char* const description)
1499 : TestCase (context, name, description)
1503 FboSRGBQueryCase::~FboSRGBQueryCase (void)
1505 FboSRGBQueryCase::deinit();
1508 void FboSRGBQueryCase::init (void)
1510 // extension requirements for test
1511 if (!glu::contextSupports(m_context.getRenderContext().getType(), glu::ApiType::es(3, 2)) && !m_context.getContextInfo().isExtensionSupported("GL_EXT_sRGB_write_control"))
1512 TCU_THROW(NotSupportedError, "Test requires extension GL_EXT_sRGB_write_control or a context version equal or higher than 3.2");
1515 void FboSRGBQueryCase::deinit (void)
1519 FboSRGBQueryCase::IterateResult FboSRGBQueryCase::iterate (void)
1522 // API tests which check when querying FRAMEBUFFER_SRGB_EXT capability returns the correct information when using glEnabled() or glDisabled()
1524 const glw::Functions& gl = m_context.getRenderContext().getFunctions();
1525 tcu::TestLog& log = m_context.getTestContext().getLog();
1526 const char* const msgPart = ", after disabling = ";
1528 for (int idx = 0; idx < static_cast<int>(QUERYTYPE_LAST); idx++)
1530 std::ostringstream message;
1533 message << std::string("Results: After Enabling = ");
1535 gl.enable(GL_FRAMEBUFFER_SRGB);
1537 switch (static_cast<QueryType>(idx))
1539 case QUERYTYPE_ISENABLED:
1541 glw::GLboolean enabled[2];
1542 enabled[0] = gl.isEnabled(GL_FRAMEBUFFER_SRGB);
1543 gl.disable(GL_FRAMEBUFFER_SRGB);
1544 enabled[1] = gl.isEnabled(GL_FRAMEBUFFER_SRGB);
1546 message << static_cast<float>(enabled[0]) << msgPart << static_cast<float>(enabled[1]);
1547 pass = (enabled[0] && !(enabled[1])) ? true : false;
1550 case QUERYTYPE_BOOLEAN:
1552 glw::GLboolean enabled[2];
1553 gl.getBooleanv(GL_FRAMEBUFFER_SRGB,&enabled[0]);
1554 gl.disable(GL_FRAMEBUFFER_SRGB);
1555 gl.getBooleanv(GL_FRAMEBUFFER_SRGB,&enabled[1]);
1557 message << static_cast<float>(enabled[0]) << msgPart << static_cast<float>(enabled[1]);
1558 pass = (enabled[0] && !(enabled[1])) ? true : false;
1561 case QUERYTYPE_FLOAT:
1563 glw::GLfloat enabled[2];
1564 gl.getFloatv(GL_FRAMEBUFFER_SRGB, &enabled[0]);
1565 gl.disable(GL_FRAMEBUFFER_SRGB);
1566 gl.getFloatv(GL_FRAMEBUFFER_SRGB, &enabled[1]);
1568 message << static_cast<float>(enabled[0]) << msgPart << static_cast<float>(enabled[1]);
1569 pass = ((int)enabled[0] && !((int)enabled[1])) ? true : false;
1574 glw::GLint enabled[2];
1575 gl.getIntegerv(GL_FRAMEBUFFER_SRGB, &enabled[0]);
1576 gl.disable(GL_FRAMEBUFFER_SRGB);
1577 gl.getIntegerv(GL_FRAMEBUFFER_SRGB, &enabled[1]);
1579 message << static_cast<float>(enabled[0]) << msgPart << static_cast<float>(enabled[1]);
1580 pass = (enabled[0] && !(enabled[1])) ? true : false;
1583 case QUERYTYPE_INT64:
1585 glw::GLint64 enabled[2];
1586 gl.getInteger64v(GL_FRAMEBUFFER_SRGB, &enabled[0]);
1587 gl.disable(GL_FRAMEBUFFER_SRGB);
1588 gl.getInteger64v(GL_FRAMEBUFFER_SRGB, &enabled[1]);
1590 message << static_cast<float>(enabled[0]) << msgPart << static_cast<float>(enabled[1]);
1591 pass = (enabled[0] && !(enabled[1])) ? true : false;
1595 DE_FATAL("Error: Datatype not recognised");
1598 log << tcu::TestLog::Message << message.str() << tcu::TestLog::EndMessage;
1601 m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
1604 m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Result verification failed");
1611 class FboSRGBColAttachCase : public FboSRGBTestCase
1614 FboSRGBColAttachCase (Context& context, const char* const name, const char* const description)
1615 : FboSRGBTestCase (context, name, description) {}
1616 ~FboSRGBColAttachCase (void) {}
1618 void setupTest (void);
1619 bool verifyResult (void);
1622 void FboSRGBColAttachCase::setupTest (void)
1625 // Check if FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING set to SRGB and FRAMEBUFFER_SRGB_EXT enabled, destination colors are converted from SRGB to linear
1626 // before and after blending, finally the result is converted back to SRGB for storage
1629 // if fbo pre-draw color set to linaer, color values get linearlized "twice"
1630 // (0.2f, 0.3f, 0.4f, 1.0f) when sampled i.e. converted in shader = (0.0331048f, 0.073239f, 0.132868f)
1631 // 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 FBOConfig fboConfig0 = FBOConfig(GL_SRGB8_ALPHA8, getTestColorLinear(), GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FBOTYPE_SOURCE);
1634 FBOConfig fboConfig1 = FBOConfig(GL_RGBA8, getTestColorLinear(), GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FBOTYPE_SOURCE);
1636 const TestRenderPassConfig renderPassConfigs[] =
1638 TestRenderPassConfig(TEXTURESOURCESTYPE_RGBA, fboConfig0, FRAMEBUFFERSRGB_ENABLED, FRAMEBUFFERBLEND_ENABLED, RENDERERTASK_DRAW),
1639 TestRenderPassConfig(TEXTURESOURCESTYPE_BOTH, fboConfig1, FRAMEBUFFERSRGB_DISABLED, FRAMEBUFFERBLEND_DISABLED, getFunctionBlendLinearToSRGBCheck(), RENDERERTASK_DRAW)
1641 std::vector<TestRenderPassConfig> renderPassConfigList(renderPassConfigs, renderPassConfigs + DE_LENGTH_OF_ARRAY(renderPassConfigs));
1643 this->setTestConfig(renderPassConfigList);
1646 bool FboSRGBColAttachCase::verifyResult (void)
1648 if (tcu::boolAll(tcu::lessThan(tcu::abs(m_resultsPostDraw[0] - m_resultsPostDraw[1]), getEpsilonError())) || tcu::boolAll(tcu::equal(m_resultsPostDraw[0], m_resultsPostDraw[1])))
1654 class FboSRGBToggleBlendCase : public FboSRGBTestCase
1657 FboSRGBToggleBlendCase (Context& context, const char* const name, const char* const description)
1658 : FboSRGBTestCase (context, name, description) {}
1659 ~FboSRGBToggleBlendCase (void) {}
1661 void setupTest (void);
1662 bool verifyResult (void);
1665 void FboSRGBToggleBlendCase::setupTest (void)
1668 // Test to check if changing FRAMEBUFFER_SRGB_EXT from enabled to disabled. Enabled should produce SRGB color whilst disabled
1669 // should produce linear color. Test conducted with blending disabled.
1671 FBOConfig fboConfig0 = FBOConfig(GL_SRGB8_ALPHA8, getTestColorLinear(), GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FBOTYPE_DESTINATION);
1673 const TestRenderPassConfig renderPassConfigs[] =
1675 TestRenderPassConfig(TEXTURESOURCESTYPE_RGBA, fboConfig0, FRAMEBUFFERSRGB_ENABLED, FRAMEBUFFERBLEND_DISABLED, TestFunction(false), RENDERERTASK_DRAW),
1676 TestRenderPassConfig(TEXTURESOURCESTYPE_RGBA, fboConfig0, FRAMEBUFFERSRGB_DISABLED, FRAMEBUFFERBLEND_DISABLED, TestFunction(false), RENDERERTASK_DRAW)
1678 std::vector<TestRenderPassConfig> renderPassConfigList(renderPassConfigs, renderPassConfigs + DE_LENGTH_OF_ARRAY(renderPassConfigs));
1680 this->setTestConfig(renderPassConfigList);
1683 bool FboSRGBToggleBlendCase::verifyResult (void)
1685 if (tcu::boolAny(tcu::greaterThan(tcu::abs(m_resultsPostDraw[0] - m_resultsPostDraw[1]), getEpsilonError())))
1691 class FboSRGBRenderTargetIgnoreCase : public FboSRGBTestCase
1694 FboSRGBRenderTargetIgnoreCase (Context& context, const char* const name, const char* const description)
1695 : FboSRGBTestCase (context, name, description) {}
1696 ~FboSRGBRenderTargetIgnoreCase (void) {}
1698 void setupTest (void);
1699 bool verifyResult (void);
1702 void FboSRGBRenderTargetIgnoreCase::setupTest (void)
1705 // Check if render targets that are non-RGB ignore the state of GL_FRAMEBUFFER_SRGB_EXT. Rendering to an fbo with non-sRGB color
1706 // attachment should ignore color space conversion, producing linear color.
1708 FBOConfig fboConfig0 = FBOConfig(GL_RGBA8, getTestColorBlank(), GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FBOTYPE_DESTINATION);
1710 const TestRenderPassConfig renderPassConfigs[] =
1712 TestRenderPassConfig(TEXTURESOURCESTYPE_RGBA, fboConfig0, FRAMEBUFFERSRGB_ENABLED, FRAMEBUFFERBLEND_DISABLED, TestFunction(false), RENDERERTASK_DRAW)
1715 std::vector<TestRenderPassConfig> renderPassConfigList(renderPassConfigs, renderPassConfigs + DE_LENGTH_OF_ARRAY(renderPassConfigs));
1717 this->setTestConfig(renderPassConfigList);
1720 bool FboSRGBRenderTargetIgnoreCase::verifyResult (void)
1722 if (tcu::boolAll(tcu::lessThan(tcu::abs(m_resultsPostDraw[0] - getTestColorLinear()), getEpsilonError())) || tcu::boolAll(tcu::equal(m_resultsPostDraw[0], getTestColorLinear())))
1728 class FboSRGBCopyToLinearCase : public FboSRGBTestCase
1731 FboSRGBCopyToLinearCase (Context& context, const char* const name, const char* const description)
1732 : FboSRGBTestCase (context, name, description) {}
1733 ~FboSRGBCopyToLinearCase (void) {}
1735 void setupTest (void);
1736 bool verifyResult (void);
1739 void FboSRGBCopyToLinearCase::setupTest (void)
1742 // 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
1743 // an sRGB to linear conversion
1745 FBOConfig fboConfigs[] =
1747 FBOConfig(GL_SRGB8_ALPHA8, getTestColorSRGB(), GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FBOTYPE_SOURCE),
1748 FBOConfig(GL_RGBA8, getTestColorBlank(), GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FBOTYPE_DESTINATION)
1750 std::vector<FBOConfig> fboConfigList(fboConfigs, fboConfigs + DE_LENGTH_OF_ARRAY(fboConfigs));
1752 const TestRenderPassConfig renderPassConfigs[] =
1754 TestRenderPassConfig(TEXTURESOURCESTYPE_NONE, fboConfigList, FRAMEBUFFERSRGB_ENABLED, FRAMEBUFFERBLEND_DISABLED, TestFunction(false), RENDERERTASK_COPY)
1756 std::vector<TestRenderPassConfig> renderPassConfigList(renderPassConfigs, renderPassConfigs + DE_LENGTH_OF_ARRAY(renderPassConfigs));
1758 this->setTestConfig(renderPassConfigList);
1761 bool FboSRGBCopyToLinearCase::verifyResult (void)
1763 logColor(m_context, "pre-copy source fbo color values", m_resultsPreDraw[0]);
1764 logColor(m_context, "pre-copy destination fbo color values", m_resultsPreDraw[1]);
1765 logColor(m_context, "post-copy source fbo color values", m_resultsPostDraw[0]);
1766 logColor(m_context, "post-copy destination fbo color values", m_resultsPostDraw[1]);
1768 if (tcu::boolAll(tcu::lessThan(tcu::abs(m_resultsPostDraw[1] - getTestColorLinear()), getEpsilonError())) || tcu::boolAll(tcu::equal(m_resultsPostDraw[1], getTestColorLinear())))
1776 FboSRGBWriteControlTests::FboSRGBWriteControlTests (Context& context)
1777 : TestCaseGroup (context, "srgb_write_control", "Colorbuffer tests")
1781 FboSRGBWriteControlTests::~FboSRGBWriteControlTests (void)
1785 void FboSRGBWriteControlTests::init (void)
1787 this->addChild(new FboSRGBQueryCase (m_context, "framebuffer_srgb_enabled", "srgb enable framebuffer"));
1788 this->addChild(new FboSRGBColAttachCase (m_context, "framebuffer_srgb_enabled_col_attach", "srgb enable color attachment and framebuffer"));
1789 this->addChild(new FboSRGBToggleBlendCase (m_context, "framebuffer_srgb_enabled_blend", "toggle framebuffer srgb settings with blend disabled"));
1790 this->addChild(new FboSRGBRenderTargetIgnoreCase (m_context, "framebuffer_srgb_enabled_render_target_ignore", "enable framebuffer srgb, non-srgb render target should ignore"));
1791 this->addChild(new FboSRGBCopyToLinearCase (m_context, "framebuffer_srgb_enabled_copy_to_linear", "no conversion when blittering between framebuffer srgb and linear"));