/*------------------------------------------------------------------------- * drawElements Quality Program OpenGL ES 2.0 Module * ------------------------------------------------- * * Copyright 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ /*! * \file * \brief GL_EXT_multisample_render_to_texture tests. */ /*--------------------------------------------------------------------*/ #include "es2fMultisampledRenderToTextureTests.hpp" #include "deString.h" #include "deStringUtil.hpp" #include "gluContextInfo.hpp" #include "gluPixelTransfer.hpp" #include "gluShaderProgram.hpp" #include "glw.h" #include "glwEnums.hpp" #include "glwFunctions.hpp" #include "tcuRenderTarget.hpp" #include "tcuSurface.hpp" #include "tcuTestLog.hpp" #include "tcuVector.hpp" using tcu::TestLog; using tcu::Vec4; namespace deqp { namespace gles2 { namespace Functional { class MultisampledRenderToTextureReadPixelsCase : public TestCase { public: MultisampledRenderToTextureReadPixelsCase(Context& context, const char* name, const char* description); ~MultisampledRenderToTextureReadPixelsCase(); void init(); IterateResult iterate(); private: MultisampledRenderToTextureReadPixelsCase(const MultisampledRenderToTextureReadPixelsCase& other); MultisampledRenderToTextureReadPixelsCase& operator=(const MultisampledRenderToTextureReadPixelsCase& other); }; MultisampledRenderToTextureReadPixelsCase::MultisampledRenderToTextureReadPixelsCase(Context& context, const char* name, const char* description) : TestCase(context, name, description) { } MultisampledRenderToTextureReadPixelsCase::~MultisampledRenderToTextureReadPixelsCase() { } void MultisampledRenderToTextureReadPixelsCase::init() { const glu::ContextInfo& contextInfo = m_context.getContextInfo(); if (!contextInfo.isExtensionSupported("GL_EXT_multisampled_render_to_texture")) { TCU_THROW(NotSupportedError, "EXT_multisampled_render_to_texture is not supported"); } } MultisampledRenderToTextureReadPixelsCase::IterateResult MultisampledRenderToTextureReadPixelsCase::iterate() { // Test for a bug where ReadPixels fails on multisampled textures. // See http://crbug.com/890002 // Note that this does not test whether multisampling is working properly, // only that ReadPixels is able to read from the texture. const glw::Functions& gl = m_context.getRenderContext().getFunctions(); // Create a framebuffer with a multisampled texture and a depth-stencil // renderbuffer. GLuint framebuffer = 0; GLuint texture = 0; gl.genFramebuffers(1, &framebuffer); gl.genTextures(1, &texture); gl.bindFramebuffer(GL_FRAMEBUFFER, framebuffer); gl.bindTexture(GL_TEXTURE_2D, texture); gl.texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); GLint max_samples = 0; gl.getIntegerv(GL_MAX_SAMPLES_EXT, &max_samples); gl.framebufferTexture2DMultisampleEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0, max_samples); GLuint depthStencil = 0; gl.genRenderbuffers(1, &depthStencil); gl.bindRenderbuffer(GL_RENDERBUFFER, depthStencil); gl.renderbufferStorageMultisampleEXT(GL_RENDERBUFFER, max_samples, GL_DEPTH24_STENCIL8, 1, 1); gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthStencil); gl.framebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthStencil); if (gl.checkFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { TCU_THROW(NotSupportedError, "Framebuffer format not supported."); } gl.clearColor(1, 0, 1, 0); gl.clear(GL_COLOR_BUFFER_BIT); GLU_EXPECT_NO_ERROR(gl.getError(), "init"); // ReadPixels should implicitly resolve the multisampled buffer. GLubyte pixel[4] = { 0, 1, 0, 1 }; gl.readPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &pixel); GLU_EXPECT_NO_ERROR(gl.getError(), "ReadPixels"); if (pixel[0] != 255 || pixel[1] != 0 || pixel[2] != 255 || pixel[3] != 0) { std::ostringstream msg; msg << "ReadPixels read incorrect values: [" << (int)pixel[0] << ", " << (int)pixel[1] << ", " << (int)pixel[2] << ", " << (int)pixel[3] << "]"; m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, msg.str().c_str()); } else { m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass"); } gl.bindFramebuffer(GL_FRAMEBUFFER, 0); gl.bindTexture(GL_TEXTURE_2D, 0); gl.bindRenderbuffer(GL_RENDERBUFFER, 0); gl.deleteFramebuffers(1, &framebuffer); gl.deleteRenderbuffers(1, &depthStencil); gl.deleteTextures(1, &texture); return STOP; } MultisampledRenderToTextureTests::MultisampledRenderToTextureTests(Context& context) : TestCaseGroup(context, "multisampled_render_to_texture", "EXT_multisampled_render_to_texture tests") { } MultisampledRenderToTextureTests::~MultisampledRenderToTextureTests() { } void MultisampledRenderToTextureTests::init() { addChild(new MultisampledRenderToTextureReadPixelsCase(m_context, "readpixels", "Test ReadPixels with EXT_multisampled_render_to_texture")); } } // namespace Functional } // namespace gles2 } // namespace deqp