| /*------------------------------------------------------------------------- |
| * drawElements Quality Program OpenGL ES 3.0 Module |
| * ------------------------------------------------- |
| * |
| * Copyright 2014 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 FBO invalidate tests. |
| *//*--------------------------------------------------------------------*/ |
| |
| #include "es3fFboInvalidateTests.hpp" |
| #include "es3fFboTestCase.hpp" |
| #include "es3fFboTestUtil.hpp" |
| #include "gluTextureUtil.hpp" |
| #include "tcuImageCompare.hpp" |
| #include "tcuTextureUtil.hpp" |
| #include "sglrContextUtil.hpp" |
| |
| #include "glwEnums.hpp" |
| |
| #include <algorithm> |
| |
| namespace deqp |
| { |
| namespace gles3 |
| { |
| namespace Functional |
| { |
| |
| using std::string; |
| using std::vector; |
| using tcu::Vec2; |
| using tcu::Vec3; |
| using tcu::Vec4; |
| using tcu::IVec2; |
| using tcu::IVec3; |
| using tcu::IVec4; |
| using tcu::UVec4; |
| using namespace FboTestUtil; |
| |
| static std::vector<deUint32> getDefaultFBDiscardAttachments (deUint32 discardBufferBits) |
| { |
| vector<deUint32> attachments; |
| |
| if (discardBufferBits & GL_COLOR_BUFFER_BIT) |
| attachments.push_back(GL_COLOR); |
| |
| if (discardBufferBits & GL_DEPTH_BUFFER_BIT) |
| attachments.push_back(GL_DEPTH); |
| |
| if (discardBufferBits & GL_STENCIL_BUFFER_BIT) |
| attachments.push_back(GL_STENCIL); |
| |
| return attachments; |
| } |
| |
| static std::vector<deUint32> getFBODiscardAttachments (deUint32 discardBufferBits) |
| { |
| vector<deUint32> attachments; |
| |
| if (discardBufferBits & GL_COLOR_BUFFER_BIT) |
| attachments.push_back(GL_COLOR_ATTACHMENT0); |
| |
| // \note DEPTH_STENCIL_ATTACHMENT is allowed when discarding FBO, but not with default FB |
| if ((discardBufferBits & (GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)) == (GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)) |
| attachments.push_back(GL_DEPTH_STENCIL_ATTACHMENT); |
| else if (discardBufferBits & GL_DEPTH_BUFFER_BIT) |
| attachments.push_back(GL_DEPTH_ATTACHMENT); |
| else if (discardBufferBits & GL_STENCIL_BUFFER_BIT) |
| attachments.push_back(GL_STENCIL_ATTACHMENT); |
| |
| return attachments; |
| } |
| |
| static inline bool hasAttachment (const std::vector<deUint32>& attachmentList, deUint32 attachment) |
| { |
| return std::find(attachmentList.begin(), attachmentList.end(), attachment) != attachmentList.end(); |
| } |
| |
| static deUint32 getCompatibleColorFormat (const tcu::RenderTarget& renderTargetInfo) |
| { |
| const tcu::PixelFormat& pxFmt = renderTargetInfo.getPixelFormat(); |
| DE_ASSERT(de::inBounds(pxFmt.redBits, 0, 0xff) && |
| de::inBounds(pxFmt.greenBits, 0, 0xff) && |
| de::inBounds(pxFmt.blueBits, 0, 0xff) && |
| de::inBounds(pxFmt.alphaBits, 0, 0xff)); |
| |
| #define PACK_FMT(R, G, B, A) (((R) << 24) | ((G) << 16) | ((B) << 8) | (A)) |
| |
| // \note [pyry] This may not hold true on some implementations - best effort guess only. |
| switch (PACK_FMT(pxFmt.redBits, pxFmt.greenBits, pxFmt.blueBits, pxFmt.alphaBits)) |
| { |
| case PACK_FMT(8,8,8,8): return GL_RGBA8; |
| case PACK_FMT(8,8,8,0): return GL_RGB8; |
| case PACK_FMT(4,4,4,4): return GL_RGBA4; |
| case PACK_FMT(5,5,5,1): return GL_RGB5_A1; |
| case PACK_FMT(5,6,5,0): return GL_RGB565; |
| default: return GL_NONE; |
| } |
| |
| #undef PACK_FMT |
| } |
| |
| static deUint32 getCompatibleDepthStencilFormat (const tcu::RenderTarget& renderTargetInfo) |
| { |
| const int depthBits = renderTargetInfo.getDepthBits(); |
| const int stencilBits = renderTargetInfo.getStencilBits(); |
| const bool hasDepth = depthBits > 0; |
| const bool hasStencil = stencilBits > 0; |
| |
| if (!hasDepth || !hasStencil || (stencilBits != 8)) |
| return GL_NONE; |
| |
| if (depthBits == 32) |
| return GL_DEPTH32F_STENCIL8; |
| else if (depthBits == 24) |
| return GL_DEPTH24_STENCIL8; |
| else |
| return GL_NONE; |
| } |
| |
| class InvalidateDefaultFramebufferRenderCase : public FboTestCase |
| { |
| public: |
| InvalidateDefaultFramebufferRenderCase (Context& context, const char* name, const char* description, deUint32 buffers, deUint32 fboTarget = GL_FRAMEBUFFER) |
| : FboTestCase (context, name, description) |
| , m_buffers (buffers) |
| , m_fboTarget (fboTarget) |
| { |
| } |
| |
| void render (tcu::Surface& dst) |
| { |
| FlatColorShader flatShader (glu::TYPE_FLOAT_VEC4); |
| vector<deUint32> attachments = getDefaultFBDiscardAttachments(m_buffers); |
| deUint32 flatShaderID= getCurrentContext()->createProgram(&flatShader); |
| |
| glClearColor (0.0f, 0.0f, 0.0f, 1.0f); |
| glClear (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); |
| |
| glEnable (GL_DEPTH_TEST); |
| glEnable (GL_STENCIL_TEST); |
| glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE); |
| glStencilFunc (GL_ALWAYS, 1, 0xff); |
| |
| flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(1.0f, 0.0f, 0.0f, 1.0f)); |
| sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f)); |
| |
| glInvalidateFramebuffer(m_fboTarget, (int)attachments.size(), attachments.empty() ? DE_NULL : &attachments[0]); |
| |
| if ((m_buffers & GL_COLOR_BUFFER_BIT) != 0) |
| { |
| // Color was not preserved - fill with green. |
| glDisable(GL_DEPTH_TEST); |
| glDisable(GL_STENCIL_TEST); |
| |
| flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 1.0f, 0.0f, 1.0f)); |
| sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); |
| |
| glEnable(GL_DEPTH_TEST); |
| glEnable(GL_STENCIL_TEST); |
| } |
| |
| if ((m_buffers & GL_DEPTH_BUFFER_BIT) != 0) |
| { |
| // Depth was not preserved. |
| glDepthFunc(GL_ALWAYS); |
| } |
| |
| if ((m_buffers & GL_STENCIL_BUFFER_BIT) == 0) |
| { |
| // Stencil was preserved. |
| glStencilFunc(GL_EQUAL, 1, 0xff); |
| } |
| |
| glEnable (GL_BLEND); |
| glBlendFunc (GL_ONE, GL_ONE); |
| glBlendEquation (GL_FUNC_ADD); |
| |
| flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 0.0f, 1.0f, 1.0f)); |
| sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); |
| |
| readPixels(dst, 0, 0, getWidth(), getHeight()); |
| } |
| |
| private: |
| deUint32 m_buffers; |
| deUint32 m_fboTarget; |
| }; |
| |
| class InvalidateDefaultFramebufferBindCase : public FboTestCase |
| { |
| public: |
| InvalidateDefaultFramebufferBindCase (Context& context, const char* name, const char* description, deUint32 buffers) |
| : FboTestCase (context, name, description) |
| , m_buffers (buffers) |
| { |
| } |
| |
| void render (tcu::Surface& dst) |
| { |
| deUint32 fbo = 0; |
| deUint32 tex = 0; |
| FlatColorShader flatShader (glu::TYPE_FLOAT_VEC4); |
| Texture2DShader texShader (DataTypes() << glu::TYPE_SAMPLER_2D, glu::TYPE_FLOAT_VEC4); |
| GradientShader gradShader (glu::TYPE_FLOAT_VEC4); |
| vector<deUint32> attachments = getDefaultFBDiscardAttachments(m_buffers); |
| deUint32 flatShaderID= getCurrentContext()->createProgram(&flatShader); |
| deUint32 texShaderID = getCurrentContext()->createProgram(&texShader); |
| deUint32 gradShaderID= getCurrentContext()->createProgram(&gradShader); |
| |
| glClearColor (0.0f, 0.0f, 0.0f, 1.0f); |
| glClear (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); |
| |
| // Create fbo. |
| glGenFramebuffers (1, &fbo); |
| glGenTextures (1, &tex); |
| glBindTexture (GL_TEXTURE_2D, tex); |
| glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, getWidth(), getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL); |
| glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
| glBindFramebuffer (GL_FRAMEBUFFER, fbo); |
| glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0); |
| glBindTexture (GL_TEXTURE_2D, 0); |
| checkFramebufferStatus (GL_FRAMEBUFFER); |
| |
| glBindFramebuffer (GL_FRAMEBUFFER, 0); |
| |
| glEnable (GL_DEPTH_TEST); |
| glEnable (GL_STENCIL_TEST); |
| glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE); |
| glStencilFunc (GL_ALWAYS, 1, 0xff); |
| |
| flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(1.0f, 0.0f, 0.0f, 1.0f)); |
| sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f)); |
| |
| glInvalidateFramebuffer(GL_FRAMEBUFFER, (int)attachments.size(), attachments.empty() ? DE_NULL : &attachments[0]); |
| |
| // Switch to fbo and render gradient into it. |
| glDisable (GL_DEPTH_TEST); |
| glDisable (GL_STENCIL_TEST); |
| glBindFramebuffer (GL_FRAMEBUFFER, fbo); |
| |
| gradShader.setGradient(*getCurrentContext(), gradShaderID, Vec4(0.0f), Vec4(1.0f)); |
| sglr::drawQuad(*getCurrentContext(), gradShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); |
| |
| // Restore default fbo. |
| glBindFramebuffer (GL_FRAMEBUFFER, 0); |
| |
| if ((m_buffers & GL_COLOR_BUFFER_BIT) != 0) |
| { |
| // Color was not preserved - fill with green. |
| flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 1.0f, 0.0f, 1.0f)); |
| sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); |
| } |
| |
| if ((m_buffers & GL_DEPTH_BUFFER_BIT) != 0) |
| { |
| // Depth was not preserved. |
| glDepthFunc(GL_ALWAYS); |
| } |
| |
| if ((m_buffers & GL_STENCIL_BUFFER_BIT) == 0) |
| { |
| // Stencil was preserved. |
| glStencilFunc(GL_EQUAL, 1, 0xff); |
| } |
| |
| glEnable (GL_DEPTH_TEST); |
| glEnable (GL_STENCIL_TEST); |
| glEnable (GL_BLEND); |
| glBlendFunc (GL_ONE, GL_ONE); |
| glBlendEquation (GL_FUNC_ADD); |
| glBindTexture (GL_TEXTURE_2D, tex); |
| |
| texShader.setUniforms(*getCurrentContext(), texShaderID); |
| sglr::drawQuad(*getCurrentContext(), texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); |
| |
| readPixels(dst, 0, 0, getWidth(), getHeight()); |
| } |
| |
| private: |
| deUint32 m_buffers; |
| }; |
| |
| class InvalidateDefaultSubFramebufferRenderCase : public FboTestCase |
| { |
| public: |
| InvalidateDefaultSubFramebufferRenderCase (Context& context, const char* name, const char* description, deUint32 buffers) |
| : FboTestCase (context, name, description) |
| , m_buffers (buffers) |
| { |
| } |
| |
| void render (tcu::Surface& dst) |
| { |
| int invalidateX = getWidth() / 4; |
| int invalidateY = getHeight() / 4; |
| int invalidateW = getWidth() / 2; |
| int invalidateH = getHeight() / 2; |
| FlatColorShader flatShader (glu::TYPE_FLOAT_VEC4); |
| vector<deUint32> attachments = getDefaultFBDiscardAttachments(m_buffers); |
| deUint32 flatShaderID = getCurrentContext()->createProgram(&flatShader); |
| |
| glClearColor (0.0f, 0.0f, 0.0f, 1.0f); |
| glClear (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); |
| |
| glEnable (GL_DEPTH_TEST); |
| glEnable (GL_STENCIL_TEST); |
| glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE); |
| glStencilFunc (GL_ALWAYS, 1, 0xff); |
| |
| flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(1.0f, 0.0f, 0.0f, 1.0f)); |
| sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f)); |
| |
| glInvalidateSubFramebuffer(GL_FRAMEBUFFER, (int)attachments.size(), &attachments[0], invalidateX, invalidateY, invalidateW, invalidateH); |
| |
| // Clear invalidated buffers. |
| glClearColor (0.0f, 1.0f, 0.0f, 1.0f); |
| glClearStencil (1); |
| glScissor (invalidateX, invalidateY, invalidateW, invalidateH); |
| glEnable (GL_SCISSOR_TEST); |
| glClear (m_buffers); |
| glDisable (GL_SCISSOR_TEST); |
| |
| glEnable (GL_BLEND); |
| glBlendFunc (GL_ONE, GL_ONE); |
| glBlendEquation (GL_FUNC_ADD); |
| |
| flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 0.0f, 1.0f, 1.0f)); |
| sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); |
| |
| readPixels(dst, 0, 0, getWidth(), getHeight()); |
| } |
| |
| private: |
| deUint32 m_buffers; |
| }; |
| |
| class InvalidateDefaultSubFramebufferBindCase : public FboTestCase |
| { |
| public: |
| InvalidateDefaultSubFramebufferBindCase (Context& context, const char* name, const char* description, deUint32 buffers) |
| : FboTestCase (context, name, description) |
| , m_buffers (buffers) |
| { |
| } |
| |
| void render (tcu::Surface& dst) |
| { |
| deUint32 fbo = 0; |
| deUint32 tex = 0; |
| FlatColorShader flatShader (glu::TYPE_FLOAT_VEC4); |
| Texture2DShader texShader (DataTypes() << glu::TYPE_SAMPLER_2D, glu::TYPE_FLOAT_VEC4); |
| GradientShader gradShader (glu::TYPE_FLOAT_VEC4); |
| vector<deUint32> attachments = getDefaultFBDiscardAttachments(m_buffers); |
| deUint32 flatShaderID = getCurrentContext()->createProgram(&flatShader); |
| deUint32 texShaderID = getCurrentContext()->createProgram(&texShader); |
| deUint32 gradShaderID = getCurrentContext()->createProgram(&gradShader); |
| |
| int invalidateX = getWidth() / 4; |
| int invalidateY = getHeight() / 4; |
| int invalidateW = getWidth() / 2; |
| int invalidateH = getHeight() / 2; |
| |
| |
| flatShader.setColor (*getCurrentContext(), flatShaderID, Vec4(1.0f, 0.0f, 0.0f, 1.0f)); |
| texShader.setUniforms (*getCurrentContext(), texShaderID); |
| gradShader.setGradient(*getCurrentContext(), gradShaderID, Vec4(0.0f), Vec4(1.0f)); |
| |
| glClearColor (0.0f, 0.0f, 0.0f, 1.0f); |
| glClear (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); |
| |
| // Create fbo. |
| glGenFramebuffers (1, &fbo); |
| glGenTextures (1, &tex); |
| glBindTexture (GL_TEXTURE_2D, tex); |
| glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, getWidth(), getHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, DE_NULL); |
| glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
| glBindFramebuffer (GL_FRAMEBUFFER, fbo); |
| glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0); |
| glBindTexture (GL_TEXTURE_2D, 0); |
| checkFramebufferStatus (GL_FRAMEBUFFER); |
| |
| glBindFramebuffer (GL_FRAMEBUFFER, 0); |
| |
| glEnable (GL_DEPTH_TEST); |
| glEnable (GL_STENCIL_TEST); |
| glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE); |
| glStencilFunc (GL_ALWAYS, 1, 0xff); |
| |
| sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f)); |
| |
| glInvalidateSubFramebuffer(GL_FRAMEBUFFER, (int)attachments.size(), &attachments[0], invalidateX, invalidateY, invalidateW, invalidateH); |
| |
| // Switch to fbo and render gradient into it. |
| glDisable (GL_DEPTH_TEST); |
| glDisable (GL_STENCIL_TEST); |
| glBindFramebuffer (GL_FRAMEBUFFER, fbo); |
| |
| sglr::drawQuad(*getCurrentContext(), gradShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); |
| |
| // Restore default fbo. |
| glBindFramebuffer (GL_FRAMEBUFFER, 0); |
| |
| // Clear invalidated buffers. |
| glClearColor (0.0f, 1.0f, 0.0f, 1.0f); |
| glClearStencil (1); |
| glScissor (invalidateX, invalidateY, invalidateW, invalidateH); |
| glEnable (GL_SCISSOR_TEST); |
| glClear (m_buffers); |
| glDisable (GL_SCISSOR_TEST); |
| |
| glEnable (GL_DEPTH_TEST); |
| glEnable (GL_STENCIL_TEST); |
| glEnable (GL_BLEND); |
| glBlendFunc (GL_ONE, GL_ONE); |
| glBlendEquation (GL_FUNC_ADD); |
| glBindTexture (GL_TEXTURE_2D, tex); |
| |
| sglr::drawQuad(*getCurrentContext(), texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); |
| |
| readPixels(dst, 0, 0, getWidth(), getHeight()); |
| } |
| |
| private: |
| deUint32 m_buffers; |
| }; |
| |
| class InvalidateFboRenderCase : public FboTestCase |
| { |
| public: |
| InvalidateFboRenderCase (Context& context, const char* name, const char* description, deUint32 colorFmt, deUint32 depthStencilFmt, deUint32 invalidateBuffers) |
| : FboTestCase (context, name, description) |
| , m_colorFmt (colorFmt) |
| , m_depthStencilFmt (depthStencilFmt) |
| , m_invalidateBuffers (invalidateBuffers) |
| { |
| } |
| |
| protected: |
| void preCheck (void) |
| { |
| if (m_colorFmt != GL_NONE) checkFormatSupport(m_colorFmt); |
| if (m_depthStencilFmt != GL_NONE) checkFormatSupport(m_depthStencilFmt); |
| } |
| |
| void render (tcu::Surface& dst) |
| { |
| tcu::TextureFormat colorFmt = glu::mapGLInternalFormat(m_colorFmt); |
| tcu::TextureFormat depthStencilFmt = m_depthStencilFmt != GL_NONE ? glu::mapGLInternalFormat(m_depthStencilFmt) : tcu::TextureFormat(); |
| tcu::TextureFormatInfo colorFmtInfo = tcu::getTextureFormatInfo(colorFmt); |
| bool depth = depthStencilFmt.order == tcu::TextureFormat::D || depthStencilFmt.order == tcu::TextureFormat::DS; |
| bool stencil = depthStencilFmt.order == tcu::TextureFormat::S || depthStencilFmt.order == tcu::TextureFormat::DS; |
| const tcu::Vec4& cBias = colorFmtInfo.valueMin; |
| tcu::Vec4 cScale = colorFmtInfo.valueMax-colorFmtInfo.valueMin; |
| deUint32 fbo = 0; |
| deUint32 colorRbo = 0; |
| deUint32 depthStencilRbo = 0; |
| FlatColorShader flatShader (glu::TYPE_FLOAT_VEC4); |
| vector<deUint32> attachments = getFBODiscardAttachments(m_invalidateBuffers); |
| deUint32 flatShaderID = getCurrentContext()->createProgram(&flatShader); |
| |
| // Create fbo. |
| glGenRenderbuffers (1, &colorRbo); |
| glBindRenderbuffer (GL_RENDERBUFFER, colorRbo); |
| glRenderbufferStorage (GL_RENDERBUFFER, m_colorFmt, getWidth(), getHeight()); |
| |
| if (m_depthStencilFmt != GL_NONE) |
| { |
| glGenRenderbuffers (1, &depthStencilRbo); |
| glBindRenderbuffer (GL_RENDERBUFFER, depthStencilRbo); |
| glRenderbufferStorage (GL_RENDERBUFFER, m_depthStencilFmt, getWidth(), getHeight()); |
| } |
| |
| glGenFramebuffers (1, &fbo); |
| glBindFramebuffer (GL_FRAMEBUFFER, fbo); |
| glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRbo); |
| |
| if (depth) |
| glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo); |
| |
| if (stencil) |
| glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo); |
| |
| checkFramebufferStatus (GL_FRAMEBUFFER); |
| |
| glClearColor (0.0f, 0.0f, 0.0f, 1.0f); |
| glClear (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); |
| |
| glEnable (GL_DEPTH_TEST); |
| glEnable (GL_STENCIL_TEST); |
| glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE); |
| glStencilFunc (GL_ALWAYS, 1, 0xff); |
| |
| flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias); |
| sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f)); |
| |
| glInvalidateFramebuffer(GL_FRAMEBUFFER, (int)attachments.size(), attachments.empty() ? DE_NULL : &attachments[0]); |
| |
| if ((m_invalidateBuffers & GL_COLOR_BUFFER_BIT) != 0) |
| { |
| // Color was not preserved - fill with green. |
| glDisable(GL_DEPTH_TEST); |
| glDisable(GL_STENCIL_TEST); |
| |
| flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias); |
| sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); |
| |
| glEnable(GL_DEPTH_TEST); |
| glEnable(GL_STENCIL_TEST); |
| } |
| |
| if ((m_invalidateBuffers & GL_DEPTH_BUFFER_BIT) != 0) |
| { |
| // Depth was not preserved. |
| glDepthFunc(GL_ALWAYS); |
| } |
| |
| if ((m_invalidateBuffers & GL_STENCIL_BUFFER_BIT) == 0) |
| { |
| // Stencil was preserved. |
| glStencilFunc(GL_EQUAL, 1, 0xff); |
| } |
| |
| glEnable (GL_BLEND); |
| glBlendFunc (GL_ONE, GL_ONE); |
| glBlendEquation (GL_FUNC_ADD); |
| |
| flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 0.0f, 1.0f, 1.0f)*cScale + cBias); |
| sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); |
| |
| readPixels(dst, 0, 0, getWidth(), getHeight(), colorFmt, colorFmtInfo.lookupScale, colorFmtInfo.lookupBias); |
| } |
| |
| private: |
| deUint32 m_colorFmt; |
| deUint32 m_depthStencilFmt; |
| deUint32 m_invalidateBuffers; |
| }; |
| |
| class InvalidateFboUnbindReadCase : public FboTestCase |
| { |
| public: |
| InvalidateFboUnbindReadCase (Context& context, const char* name, const char* description, deUint32 colorFmt, deUint32 depthStencilFmt, deUint32 invalidateBuffers) |
| : FboTestCase (context, name, description) |
| , m_colorFmt (colorFmt) |
| , m_depthStencilFmt (depthStencilFmt) |
| , m_invalidateBuffers (invalidateBuffers) |
| { |
| DE_ASSERT((m_invalidateBuffers & (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)) != (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)); |
| } |
| |
| protected: |
| void preCheck (void) |
| { |
| if (m_colorFmt != GL_NONE) checkFormatSupport(m_colorFmt); |
| if (m_depthStencilFmt != GL_NONE) checkFormatSupport(m_depthStencilFmt); |
| } |
| |
| void render (tcu::Surface& dst) |
| { |
| tcu::TextureFormat colorFmt = glu::mapGLInternalFormat(m_colorFmt); |
| tcu::TextureFormat depthStencilFmt = m_depthStencilFmt != GL_NONE ? glu::mapGLInternalFormat(m_depthStencilFmt) : tcu::TextureFormat(); |
| tcu::TextureFormatInfo colorFmtInfo = tcu::getTextureFormatInfo(colorFmt); |
| bool depth = depthStencilFmt.order == tcu::TextureFormat::D || depthStencilFmt.order == tcu::TextureFormat::DS; |
| bool stencil = depthStencilFmt.order == tcu::TextureFormat::S || depthStencilFmt.order == tcu::TextureFormat::DS; |
| deUint32 fbo = 0; |
| deUint32 colorTex = 0; |
| deUint32 depthStencilTex = 0; |
| GradientShader gradShader (getFragmentOutputType(colorFmt)); |
| vector<deUint32> attachments = getFBODiscardAttachments(m_invalidateBuffers); |
| deUint32 gradShaderID = getCurrentContext()->createProgram(&gradShader); |
| |
| // Create fbo. |
| { |
| glu::TransferFormat transferFmt = glu::getTransferFormat(colorFmt); |
| |
| glGenTextures (1, &colorTex); |
| glBindTexture (GL_TEXTURE_2D, colorTex); |
| glTexImage2D (GL_TEXTURE_2D, 0, m_colorFmt, getWidth(), getHeight(), 0, transferFmt.format, transferFmt.dataType, DE_NULL); |
| glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
| } |
| |
| if (m_depthStencilFmt != GL_NONE) |
| { |
| glu::TransferFormat transferFmt = glu::getTransferFormat(depthStencilFmt); |
| |
| glGenTextures (1, &depthStencilTex); |
| glBindTexture (GL_TEXTURE_2D, depthStencilTex); |
| glTexImage2D (GL_TEXTURE_2D, 0, m_depthStencilFmt, getWidth(), getHeight(), 0, transferFmt.format, transferFmt.dataType, DE_NULL); |
| glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
| glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
| } |
| |
| glGenFramebuffers (1, &fbo); |
| glBindFramebuffer (GL_FRAMEBUFFER, fbo); |
| glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0); |
| |
| if (depth) |
| glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthStencilTex, 0); |
| |
| if (stencil) |
| glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, depthStencilTex, 0); |
| |
| checkFramebufferStatus (GL_FRAMEBUFFER); |
| |
| glClearColor (0.0f, 0.0f, 0.0f, 1.0f); |
| glClear (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); |
| |
| glEnable (GL_DEPTH_TEST); |
| glEnable (GL_STENCIL_TEST); |
| glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE); |
| glStencilFunc (GL_ALWAYS, 1, 0xff); |
| |
| gradShader.setGradient(*getCurrentContext(), gradShaderID, colorFmtInfo.valueMin, colorFmtInfo.valueMax); |
| sglr::drawQuad(*getCurrentContext(), gradShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f)); |
| |
| glInvalidateFramebuffer(GL_FRAMEBUFFER, (int)attachments.size(), &attachments[0]); |
| |
| glBindFramebuffer (GL_FRAMEBUFFER, 0); |
| glDisable (GL_DEPTH_TEST); |
| glDisable (GL_STENCIL_TEST); |
| |
| if ((m_invalidateBuffers & GL_DEPTH_BUFFER_BIT) != 0) |
| { |
| // Render color. |
| Texture2DShader texShader(DataTypes() << glu::getSampler2DType(colorFmt), glu::TYPE_FLOAT_VEC4); |
| deUint32 texShaderID = getCurrentContext()->createProgram(&texShader); |
| |
| texShader.setTexScaleBias(0, colorFmtInfo.lookupScale, colorFmtInfo.lookupBias); |
| texShader.setUniforms(*getCurrentContext(), texShaderID); |
| |
| glBindTexture(GL_TEXTURE_2D, colorTex); |
| sglr::drawQuad(*getCurrentContext(), texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); |
| } |
| else |
| { |
| // Render depth. |
| Texture2DShader texShader(DataTypes() << glu::getSampler2DType(depthStencilFmt), glu::TYPE_FLOAT_VEC4); |
| deUint32 texShaderID = getCurrentContext()->createProgram(&texShader); |
| |
| texShader.setUniforms(*getCurrentContext(), texShaderID); |
| |
| glBindTexture(GL_TEXTURE_2D, depthStencilTex); |
| sglr::drawQuad(*getCurrentContext(), texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); |
| } |
| |
| readPixels(dst, 0, 0, getWidth(), getHeight()); |
| } |
| |
| private: |
| deUint32 m_colorFmt; |
| deUint32 m_depthStencilFmt; |
| deUint32 m_invalidateBuffers; |
| }; |
| |
| class InvalidateFboUnbindBlitCase : public FboTestCase |
| { |
| public: |
| InvalidateFboUnbindBlitCase (Context& context, const char* name, const char* description, int numSamples, deUint32 invalidateBuffers) |
| : FboTestCase (context, name, description, numSamples > 0) // \note Use fullscreen viewport when multisampling - we can't allow GLES3Context do its |
| // behing-the-scenes viewport position randomization, because with glBlitFramebuffer, |
| // source and destination rectangles must match when multisampling. |
| , m_colorFmt (0) |
| , m_depthStencilFmt (0) |
| , m_numSamples (numSamples) |
| , m_invalidateBuffers (invalidateBuffers) |
| { |
| // Figure out formats that are compatible with default framebuffer. |
| m_colorFmt = getCompatibleColorFormat(m_context.getRenderTarget()); |
| m_depthStencilFmt = getCompatibleDepthStencilFormat(m_context.getRenderTarget()); |
| } |
| |
| protected: |
| void preCheck (void) |
| { |
| if (m_context.getRenderTarget().getNumSamples() > 0) |
| throw tcu::NotSupportedError("Not supported in MSAA config"); |
| |
| if (m_colorFmt == GL_NONE) |
| throw tcu::NotSupportedError("Unsupported color format"); |
| |
| if (m_depthStencilFmt == GL_NONE) |
| throw tcu::NotSupportedError("Unsupported depth/stencil format"); |
| |
| checkFormatSupport(m_colorFmt); |
| checkFormatSupport(m_depthStencilFmt); |
| } |
| |
| void render (tcu::Surface& dst) |
| { |
| // \note When using fullscreen viewport (when m_numSamples > 0), still only use a 128x128 pixel quad at most. |
| IVec2 quadSizePixels (m_numSamples == 0 ? getWidth() : de::min(128, getWidth()), |
| m_numSamples == 0 ? getHeight() : de::min(128, getHeight())); |
| Vec2 quadNDCLeftBottomXY (-1.0f, -1.0f); |
| Vec2 quadNDCSize (2.0f*(float)quadSizePixels.x()/(float)getWidth(), 2.0f*(float)quadSizePixels.y()/(float)getHeight()); |
| Vec2 quadNDCRightTopXY = quadNDCLeftBottomXY + quadNDCSize; |
| tcu::TextureFormat depthStencilFmt = m_depthStencilFmt != GL_NONE ? glu::mapGLInternalFormat(m_depthStencilFmt) : tcu::TextureFormat(); |
| bool depth = depthStencilFmt.order == tcu::TextureFormat::D || depthStencilFmt.order == tcu::TextureFormat::DS; |
| bool stencil = depthStencilFmt.order == tcu::TextureFormat::S || depthStencilFmt.order == tcu::TextureFormat::DS; |
| deUint32 fbo = 0; |
| deUint32 colorRbo = 0; |
| deUint32 depthStencilRbo = 0; |
| FlatColorShader flatShader (glu::TYPE_FLOAT_VEC4); |
| vector<deUint32> attachments = getFBODiscardAttachments(m_invalidateBuffers); |
| deUint32 flatShaderID = getCurrentContext()->createProgram(&flatShader); |
| |
| glClearColor (0.0f, 0.0f, 0.0f, 1.0f); |
| glClear (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); |
| |
| // Create fbo. |
| glGenRenderbuffers (1, &colorRbo); |
| glBindRenderbuffer (GL_RENDERBUFFER, colorRbo); |
| glRenderbufferStorageMultisample (GL_RENDERBUFFER, m_numSamples, m_colorFmt, quadSizePixels.x(), quadSizePixels.y()); |
| |
| if (m_depthStencilFmt != GL_NONE) |
| { |
| glGenRenderbuffers (1, &depthStencilRbo); |
| glBindRenderbuffer (GL_RENDERBUFFER, depthStencilRbo); |
| glRenderbufferStorageMultisample (GL_RENDERBUFFER, m_numSamples, m_depthStencilFmt, quadSizePixels.x(), quadSizePixels.y()); |
| } |
| |
| glGenFramebuffers (1, &fbo); |
| glBindFramebuffer (GL_FRAMEBUFFER, fbo); |
| glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRbo); |
| |
| if (depth) |
| glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo); |
| |
| if (stencil) |
| glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo); |
| |
| checkFramebufferStatus (GL_FRAMEBUFFER); |
| |
| glClear (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); |
| |
| glEnable (GL_DEPTH_TEST); |
| glEnable (GL_STENCIL_TEST); |
| glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE); |
| glStencilFunc (GL_ALWAYS, 1, 0xff); |
| |
| flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(1.0f, 0.0f, 0.0f, 1.0f)); |
| sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(quadNDCLeftBottomXY.x(), quadNDCLeftBottomXY.y(), -1.0f), Vec3(quadNDCRightTopXY.x(), quadNDCRightTopXY.y(), 1.0f)); |
| |
| glInvalidateFramebuffer(GL_FRAMEBUFFER, (int)attachments.size(), &attachments[0]); |
| |
| // Set default framebuffer as draw framebuffer and blit preserved buffers. |
| glBindFramebuffer (GL_DRAW_FRAMEBUFFER, 0); |
| glBlitFramebuffer (0, 0, quadSizePixels.x(), quadSizePixels.y(), |
| 0, 0, quadSizePixels.x(), quadSizePixels.y(), |
| (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT) & ~m_invalidateBuffers, GL_NEAREST); |
| glBindFramebuffer (GL_READ_FRAMEBUFFER, 0); |
| |
| if ((m_invalidateBuffers & GL_COLOR_BUFFER_BIT) != 0) |
| { |
| // Color was not preserved - fill with green. |
| glDisable(GL_DEPTH_TEST); |
| glDisable(GL_STENCIL_TEST); |
| |
| flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 1.0f, 0.0f, 1.0f)); |
| sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(quadNDCLeftBottomXY.x(), quadNDCLeftBottomXY.y(), 0.0f), Vec3(quadNDCRightTopXY.x(), quadNDCRightTopXY.y(), 0.0f)); |
| |
| glEnable(GL_DEPTH_TEST); |
| glEnable(GL_STENCIL_TEST); |
| } |
| |
| if ((m_invalidateBuffers & GL_DEPTH_BUFFER_BIT) != 0) |
| { |
| // Depth was not preserved. |
| glDepthFunc(GL_ALWAYS); |
| } |
| |
| if ((m_invalidateBuffers & GL_STENCIL_BUFFER_BIT) == 0) |
| { |
| // Stencil was preserved. |
| glStencilFunc(GL_EQUAL, 1, 0xff); |
| } |
| |
| glEnable (GL_BLEND); |
| glBlendFunc (GL_ONE, GL_ONE); |
| glBlendEquation (GL_FUNC_ADD); |
| |
| flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 0.0f, 1.0f, 1.0f)); |
| sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(quadNDCLeftBottomXY.x(), quadNDCLeftBottomXY.y(), 0.0f), Vec3(quadNDCRightTopXY.x(), quadNDCRightTopXY.y(), 0.0f)); |
| |
| readPixels(dst, 0, 0, quadSizePixels.x(), quadSizePixels.y()); |
| } |
| |
| private: |
| deUint32 m_colorFmt; |
| deUint32 m_depthStencilFmt; |
| int m_numSamples; |
| deUint32 m_invalidateBuffers; |
| }; |
| |
| class InvalidateSubFboRenderCase : public FboTestCase |
| { |
| public: |
| InvalidateSubFboRenderCase (Context& context, const char* name, const char* description, deUint32 colorFmt, deUint32 depthStencilFmt, deUint32 invalidateBuffers) |
| : FboTestCase (context, name, description) |
| , m_colorFmt (colorFmt) |
| , m_depthStencilFmt (depthStencilFmt) |
| , m_invalidateBuffers (invalidateBuffers) |
| { |
| } |
| |
| protected: |
| void preCheck (void) |
| { |
| if (m_colorFmt != GL_NONE) checkFormatSupport(m_colorFmt); |
| if (m_depthStencilFmt != GL_NONE) checkFormatSupport(m_depthStencilFmt); |
| } |
| |
| void render (tcu::Surface& dst) |
| { |
| tcu::TextureFormat colorFmt = glu::mapGLInternalFormat(m_colorFmt); |
| tcu::TextureFormat depthStencilFmt = m_depthStencilFmt != GL_NONE ? glu::mapGLInternalFormat(m_depthStencilFmt) : tcu::TextureFormat(); |
| tcu::TextureFormatInfo colorFmtInfo = tcu::getTextureFormatInfo(colorFmt); |
| bool depth = depthStencilFmt.order == tcu::TextureFormat::D || depthStencilFmt.order == tcu::TextureFormat::DS; |
| bool stencil = depthStencilFmt.order == tcu::TextureFormat::S || depthStencilFmt.order == tcu::TextureFormat::DS; |
| const tcu::Vec4& cBias = colorFmtInfo.valueMin; |
| tcu::Vec4 cScale = colorFmtInfo.valueMax-colorFmtInfo.valueMin; |
| deUint32 fbo = 0; |
| deUint32 colorRbo = 0; |
| deUint32 depthStencilRbo = 0; |
| int invalidateX = getWidth() / 4; |
| int invalidateY = getHeight() / 4; |
| int invalidateW = getWidth() / 2; |
| int invalidateH = getHeight() / 2; |
| FlatColorShader flatShader (glu::TYPE_FLOAT_VEC4); |
| vector<deUint32> attachments = getFBODiscardAttachments(m_invalidateBuffers); |
| deUint32 flatShaderID = getCurrentContext()->createProgram(&flatShader); |
| |
| // Create fbo. |
| glGenRenderbuffers (1, &colorRbo); |
| glBindRenderbuffer (GL_RENDERBUFFER, colorRbo); |
| glRenderbufferStorage (GL_RENDERBUFFER, m_colorFmt, getWidth(), getHeight()); |
| |
| if (m_depthStencilFmt != GL_NONE) |
| { |
| glGenRenderbuffers (1, &depthStencilRbo); |
| glBindRenderbuffer (GL_RENDERBUFFER, depthStencilRbo); |
| glRenderbufferStorage (GL_RENDERBUFFER, m_depthStencilFmt, getWidth(), getHeight()); |
| } |
| |
| glGenFramebuffers (1, &fbo); |
| glBindFramebuffer (GL_FRAMEBUFFER, fbo); |
| glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRbo); |
| |
| if (depth) |
| glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo); |
| |
| if (stencil) |
| glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo); |
| |
| checkFramebufferStatus (GL_FRAMEBUFFER); |
| |
| glClearBufferfv (GL_COLOR, 0, (Vec4(0.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias).getPtr()); |
| glClearBufferfi (GL_DEPTH_STENCIL, 0, 1.0f, 0); |
| |
| glEnable (GL_DEPTH_TEST); |
| glEnable (GL_STENCIL_TEST); |
| glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE); |
| glStencilFunc (GL_ALWAYS, 1, 0xff); |
| |
| flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias); |
| sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f)); |
| |
| glInvalidateSubFramebuffer(GL_FRAMEBUFFER, (int)attachments.size(), attachments.empty() ? DE_NULL : &attachments[0], invalidateX, invalidateY, invalidateW, invalidateH); |
| |
| // Clear invalidated buffers. |
| glScissor (invalidateX, invalidateY, invalidateW, invalidateH); |
| glEnable (GL_SCISSOR_TEST); |
| |
| if (m_invalidateBuffers & GL_COLOR_BUFFER_BIT) |
| glClearBufferfv(GL_COLOR, 0, (Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias).getPtr()); |
| |
| glClear (m_invalidateBuffers & ~GL_COLOR_BUFFER_BIT); |
| glDisable (GL_SCISSOR_TEST); |
| |
| glEnable (GL_BLEND); |
| glBlendFunc (GL_ONE, GL_ONE); |
| glBlendEquation (GL_FUNC_ADD); |
| |
| flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 0.0f, 1.0f, 1.0f)*cScale + cBias); |
| sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); |
| |
| readPixels(dst, 0, 0, getWidth(), getHeight(), colorFmt, colorFmtInfo.lookupScale, colorFmtInfo.lookupBias); |
| } |
| |
| private: |
| deUint32 m_colorFmt; |
| deUint32 m_depthStencilFmt; |
| deUint32 m_invalidateBuffers; |
| }; |
| |
| class InvalidateSubFboUnbindReadCase : public FboTestCase |
| { |
| public: |
| InvalidateSubFboUnbindReadCase (Context& context, const char* name, const char* description, deUint32 colorFmt, deUint32 depthStencilFmt, deUint32 invalidateBuffers) |
| : FboTestCase (context, name, description) |
| , m_colorFmt (colorFmt) |
| , m_depthStencilFmt (depthStencilFmt) |
| , m_invalidateBuffers (invalidateBuffers) |
| { |
| DE_ASSERT((m_invalidateBuffers & (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)) != (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)); |
| } |
| |
| protected: |
| void preCheck (void) |
| { |
| if (m_colorFmt != GL_NONE) checkFormatSupport(m_colorFmt); |
| if (m_depthStencilFmt != GL_NONE) checkFormatSupport(m_depthStencilFmt); |
| } |
| |
| void render (tcu::Surface& dst) |
| { |
| tcu::TextureFormat colorFmt = glu::mapGLInternalFormat(m_colorFmt); |
| tcu::TextureFormat depthStencilFmt = m_depthStencilFmt != GL_NONE ? glu::mapGLInternalFormat(m_depthStencilFmt) : tcu::TextureFormat(); |
| tcu::TextureFormatInfo colorFmtInfo = tcu::getTextureFormatInfo(colorFmt); |
| bool depth = depthStencilFmt.order == tcu::TextureFormat::D || depthStencilFmt.order == tcu::TextureFormat::DS; |
| bool stencil = depthStencilFmt.order == tcu::TextureFormat::S || depthStencilFmt.order == tcu::TextureFormat::DS; |
| deUint32 fbo = 0; |
| deUint32 colorTex = 0; |
| deUint32 depthStencilTex = 0; |
| int invalidateX = 0; |
| int invalidateY = 0; |
| int invalidateW = getWidth()/2; |
| int invalidateH = getHeight(); |
| int readX = invalidateW; |
| int readY = 0; |
| int readW = getWidth()/2; |
| int readH = getHeight(); |
| GradientShader gradShader (getFragmentOutputType(colorFmt)); |
| vector<deUint32> attachments = getFBODiscardAttachments(m_invalidateBuffers); |
| deUint32 gradShaderID = getCurrentContext()->createProgram(&gradShader); |
| |
| // Create fbo. |
| { |
| glu::TransferFormat transferFmt = glu::getTransferFormat(colorFmt); |
| |
| glGenTextures (1, &colorTex); |
| glBindTexture (GL_TEXTURE_2D, colorTex); |
| glTexImage2D (GL_TEXTURE_2D, 0, m_colorFmt, getWidth(), getHeight(), 0, transferFmt.format, transferFmt.dataType, DE_NULL); |
| glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
| glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
| } |
| |
| if (m_depthStencilFmt != GL_NONE) |
| { |
| glu::TransferFormat transferFmt = glu::getTransferFormat(depthStencilFmt); |
| |
| glGenTextures (1, &depthStencilTex); |
| glBindTexture (GL_TEXTURE_2D, depthStencilTex); |
| glTexImage2D (GL_TEXTURE_2D, 0, m_depthStencilFmt, getWidth(), getHeight(), 0, transferFmt.format, transferFmt.dataType, DE_NULL); |
| glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
| glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
| } |
| |
| glGenFramebuffers (1, &fbo); |
| glBindFramebuffer (GL_FRAMEBUFFER, fbo); |
| glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0); |
| |
| if (depth) |
| glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthStencilTex, 0); |
| |
| if (stencil) |
| glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, depthStencilTex, 0); |
| |
| checkFramebufferStatus (GL_FRAMEBUFFER); |
| |
| clearColorBuffer(colorFmt, tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)); |
| glClear (GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); |
| |
| glEnable (GL_DEPTH_TEST); |
| glEnable (GL_STENCIL_TEST); |
| glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE); |
| glStencilFunc (GL_ALWAYS, 1, 0xff); |
| |
| gradShader.setGradient(*getCurrentContext(), gradShaderID, colorFmtInfo.valueMin, colorFmtInfo.valueMax); |
| sglr::drawQuad(*getCurrentContext(), gradShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f)); |
| |
| glInvalidateSubFramebuffer(GL_FRAMEBUFFER, (int)attachments.size(), &attachments[0], invalidateX, invalidateY, invalidateW, invalidateH); |
| |
| glBindFramebuffer (GL_FRAMEBUFFER, 0); |
| glDisable (GL_DEPTH_TEST); |
| glDisable (GL_STENCIL_TEST); |
| |
| glClearColor (0.25f, 0.5f, 0.75f, 1.0f); |
| glClear (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); |
| |
| // Limit read area using scissor. |
| glScissor (readX, readY, readW, readH); |
| glEnable (GL_SCISSOR_TEST); |
| |
| if ((m_invalidateBuffers & GL_COLOR_BUFFER_BIT) != 0) |
| { |
| // Render color. |
| Texture2DShader texShader(DataTypes() << glu::getSampler2DType(colorFmt), glu::TYPE_FLOAT_VEC4); |
| deUint32 texShaderID = getCurrentContext()->createProgram(&texShader); |
| |
| texShader.setTexScaleBias(0, colorFmtInfo.lookupScale, colorFmtInfo.lookupBias); |
| texShader.setUniforms(*getCurrentContext(), texShaderID); |
| |
| glBindTexture(GL_TEXTURE_2D, colorTex); |
| sglr::drawQuad(*getCurrentContext(), texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); |
| } |
| else |
| { |
| // Render depth. |
| Texture2DShader texShader(DataTypes() << glu::getSampler2DType(depthStencilFmt), glu::TYPE_FLOAT_VEC4); |
| deUint32 texShaderID = getCurrentContext()->createProgram(&texShader); |
| |
| texShader.setUniforms(*getCurrentContext(), texShaderID); |
| |
| glBindTexture(GL_TEXTURE_2D, depthStencilTex); |
| sglr::drawQuad(*getCurrentContext(), texShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); |
| } |
| |
| readPixels(dst, 0, 0, getWidth(), getHeight()); |
| } |
| |
| bool compare (const tcu::Surface& reference, const tcu::Surface& result) |
| { |
| const tcu::RGBA threshold (tcu::max(getFormatThreshold(m_colorFmt), tcu::RGBA(12, 12, 12, 12))); |
| |
| return tcu::bilinearCompare(m_testCtx.getLog(), "Result", "Image comparison result", reference.getAccess(), result.getAccess(), threshold, tcu::COMPARE_LOG_RESULT); |
| } |
| |
| private: |
| deUint32 m_colorFmt; |
| deUint32 m_depthStencilFmt; |
| deUint32 m_invalidateBuffers; |
| }; |
| |
| class InvalidateSubFboUnbindBlitCase : public FboTestCase |
| { |
| public: |
| InvalidateSubFboUnbindBlitCase (Context& context, const char* name, const char* description, int numSamples, deUint32 invalidateBuffers) |
| : FboTestCase (context, name, description, numSamples > 0) // \note Use fullscreen viewport when multisampling - we can't allow GLES3Context do its |
| // behing-the-scenes viewport position randomization, because with glBlitFramebuffer, |
| // source and destination rectangles must match when multisampling. |
| , m_colorFmt (0) |
| , m_depthStencilFmt (0) |
| , m_numSamples (numSamples) |
| , m_invalidateBuffers (invalidateBuffers) |
| { |
| // Figure out formats that are compatible with default framebuffer. |
| m_colorFmt = getCompatibleColorFormat(m_context.getRenderTarget()); |
| m_depthStencilFmt = getCompatibleDepthStencilFormat(m_context.getRenderTarget()); |
| } |
| |
| protected: |
| void preCheck (void) |
| { |
| if (m_context.getRenderTarget().getNumSamples() > 0) |
| throw tcu::NotSupportedError("Not supported in MSAA config"); |
| |
| if (m_colorFmt == GL_NONE) |
| throw tcu::NotSupportedError("Unsupported color format"); |
| |
| if (m_depthStencilFmt == GL_NONE) |
| throw tcu::NotSupportedError("Unsupported depth/stencil format"); |
| |
| checkFormatSupport(m_colorFmt); |
| checkFormatSupport(m_depthStencilFmt); |
| } |
| |
| void render (tcu::Surface& dst) |
| { |
| // \note When using fullscreen viewport (when m_numSamples > 0), still only use a 128x128 pixel quad at most. |
| IVec2 quadSizePixels (m_numSamples == 0 ? getWidth() : de::min(128, getWidth()), |
| m_numSamples == 0 ? getHeight() : de::min(128, getHeight())); |
| Vec2 quadNDCLeftBottomXY (-1.0f, -1.0f); |
| Vec2 quadNDCSize (2.0f*(float)quadSizePixels.x()/(float)getWidth(), 2.0f*(float)quadSizePixels.y()/(float)getHeight()); |
| Vec2 quadNDCRightTopXY = quadNDCLeftBottomXY + quadNDCSize; |
| tcu::TextureFormat depthStencilFmt = m_depthStencilFmt != GL_NONE ? glu::mapGLInternalFormat(m_depthStencilFmt) : tcu::TextureFormat(); |
| bool depth = depthStencilFmt.order == tcu::TextureFormat::D || depthStencilFmt.order == tcu::TextureFormat::DS; |
| bool stencil = depthStencilFmt.order == tcu::TextureFormat::S || depthStencilFmt.order == tcu::TextureFormat::DS; |
| deUint32 fbo = 0; |
| deUint32 colorRbo = 0; |
| deUint32 depthStencilRbo = 0; |
| int invalidateX = 0; |
| int invalidateY = 0; |
| int invalidateW = quadSizePixels.x()/2; |
| int invalidateH = quadSizePixels.y(); |
| int blitX0 = invalidateW; |
| int blitY0 = 0; |
| int blitX1 = blitX0 + quadSizePixels.x()/2; |
| int blitY1 = blitY0 + quadSizePixels.y(); |
| FlatColorShader flatShader (glu::TYPE_FLOAT_VEC4); |
| vector<deUint32> attachments = getFBODiscardAttachments(m_invalidateBuffers); |
| deUint32 flatShaderID = getCurrentContext()->createProgram(&flatShader); |
| |
| glClearColor (0.0f, 0.0f, 0.0f, 1.0f); |
| glClear (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); |
| |
| // Create fbo. |
| glGenRenderbuffers (1, &colorRbo); |
| glBindRenderbuffer (GL_RENDERBUFFER, colorRbo); |
| glRenderbufferStorageMultisample (GL_RENDERBUFFER, m_numSamples, m_colorFmt, quadSizePixels.x(), quadSizePixels.y()); |
| |
| if (m_depthStencilFmt != GL_NONE) |
| { |
| glGenRenderbuffers (1, &depthStencilRbo); |
| glBindRenderbuffer (GL_RENDERBUFFER, depthStencilRbo); |
| glRenderbufferStorageMultisample (GL_RENDERBUFFER, m_numSamples, m_depthStencilFmt, quadSizePixels.x(), quadSizePixels.y()); |
| } |
| |
| glGenFramebuffers (1, &fbo); |
| glBindFramebuffer (GL_FRAMEBUFFER, fbo); |
| glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRbo); |
| |
| if (depth) |
| glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo); |
| |
| if (stencil) |
| glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo); |
| |
| checkFramebufferStatus (GL_FRAMEBUFFER); |
| |
| glClear (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); |
| |
| glEnable (GL_DEPTH_TEST); |
| glEnable (GL_STENCIL_TEST); |
| glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE); |
| glStencilFunc (GL_ALWAYS, 1, 0xff); |
| |
| flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(1.0f, 0.0f, 0.0f, 1.0f)); |
| sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(quadNDCLeftBottomXY.x(), quadNDCLeftBottomXY.y(), -1.0f), Vec3(quadNDCRightTopXY.x(), quadNDCRightTopXY.y(), 1.0f)); |
| |
| glInvalidateSubFramebuffer(GL_FRAMEBUFFER, (int)attachments.size(), &attachments[0], invalidateX, invalidateY, invalidateW, invalidateH); |
| |
| // Set default framebuffer as draw framebuffer and blit preserved buffers. |
| glBindFramebuffer (GL_DRAW_FRAMEBUFFER, 0); |
| glBlitFramebuffer (blitX0, blitY0, blitX1, blitY1, blitX0, blitY0, blitX1, blitY1, (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT) & ~m_invalidateBuffers, GL_NEAREST); |
| glBindFramebuffer (GL_READ_FRAMEBUFFER, 0); |
| |
| if ((m_invalidateBuffers & GL_COLOR_BUFFER_BIT) != 0) |
| { |
| // Color was not preserved - fill with green. |
| glDisable(GL_DEPTH_TEST); |
| glDisable(GL_STENCIL_TEST); |
| |
| flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 1.0f, 0.0f, 1.0f)); |
| sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(quadNDCLeftBottomXY.x(), quadNDCLeftBottomXY.y(), 0.0f), Vec3(quadNDCRightTopXY.x(), quadNDCRightTopXY.y(), 0.0f)); |
| |
| glEnable(GL_DEPTH_TEST); |
| glEnable(GL_STENCIL_TEST); |
| } |
| |
| if ((m_invalidateBuffers & GL_DEPTH_BUFFER_BIT) != 0) |
| { |
| // Depth was not preserved. |
| glDepthFunc(GL_ALWAYS); |
| } |
| |
| if ((m_invalidateBuffers & GL_STENCIL_BUFFER_BIT) == 0) |
| { |
| // Stencil was preserved. |
| glStencilFunc(GL_EQUAL, 1, 0xff); |
| } |
| |
| glEnable (GL_BLEND); |
| glBlendFunc (GL_ONE, GL_ONE); |
| glBlendEquation (GL_FUNC_ADD); |
| |
| flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 0.0f, 1.0f, 1.0f)); |
| sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(quadNDCLeftBottomXY.x(), quadNDCLeftBottomXY.y(), 0.0f), Vec3(quadNDCRightTopXY.x(), quadNDCRightTopXY.y(), 0.0f)); |
| |
| readPixels(dst, 0, 0, quadSizePixels.x(), quadSizePixels.y()); |
| } |
| |
| private: |
| deUint32 m_colorFmt; |
| deUint32 m_depthStencilFmt; |
| int m_numSamples; |
| deUint32 m_invalidateBuffers; |
| }; |
| |
| class InvalidateFboTargetCase : public FboTestCase |
| { |
| public: |
| InvalidateFboTargetCase (Context& context, const char* name, const char* description, deUint32 boundTarget, deUint32 invalidateTarget, const deUint32* invalidateAttachments, int numAttachments) |
| : FboTestCase (context, name, description) |
| , m_boundTarget (boundTarget) |
| , m_invalidateTarget (invalidateTarget) |
| , m_invalidateAttachments (invalidateAttachments, invalidateAttachments+numAttachments) |
| { |
| } |
| |
| protected: |
| void render (tcu::Surface& dst) |
| { |
| const deUint32 colorFormat = GL_RGBA8; |
| const deUint32 depthStencilFormat = GL_DEPTH24_STENCIL8; |
| const tcu::TextureFormat colorFmt = glu::mapGLInternalFormat(colorFormat); |
| const tcu::TextureFormatInfo colorFmtInfo = tcu::getTextureFormatInfo(colorFmt); |
| const tcu::Vec4& cBias = colorFmtInfo.valueMin; |
| const tcu::Vec4 cScale = colorFmtInfo.valueMax-colorFmtInfo.valueMin; |
| const bool isDiscarded = (m_boundTarget == GL_FRAMEBUFFER) || |
| (m_invalidateTarget == GL_FRAMEBUFFER && m_boundTarget == GL_DRAW_FRAMEBUFFER) || |
| (m_invalidateTarget == m_boundTarget); |
| const bool isColorDiscarded = isDiscarded && hasAttachment(m_invalidateAttachments, GL_COLOR_ATTACHMENT0); |
| const bool isDepthDiscarded = isDiscarded && (hasAttachment(m_invalidateAttachments, GL_DEPTH_ATTACHMENT) || hasAttachment(m_invalidateAttachments, GL_DEPTH_STENCIL_ATTACHMENT)); |
| const bool isStencilDiscarded = isDiscarded && (hasAttachment(m_invalidateAttachments, GL_STENCIL_ATTACHMENT) || hasAttachment(m_invalidateAttachments, GL_DEPTH_STENCIL_ATTACHMENT)); |
| |
| deUint32 fbo = 0; |
| deUint32 colorRbo = 0; |
| deUint32 depthStencilRbo = 0; |
| FlatColorShader flatShader (glu::TYPE_FLOAT_VEC4); |
| deUint32 flatShaderID = getCurrentContext()->createProgram(&flatShader); |
| |
| // Create fbo. |
| glGenRenderbuffers (1, &colorRbo); |
| glBindRenderbuffer (GL_RENDERBUFFER, colorRbo); |
| glRenderbufferStorage (GL_RENDERBUFFER, colorFormat, getWidth(), getHeight()); |
| |
| glGenRenderbuffers (1, &depthStencilRbo); |
| glBindRenderbuffer (GL_RENDERBUFFER, depthStencilRbo); |
| glRenderbufferStorage (GL_RENDERBUFFER, depthStencilFormat, getWidth(), getHeight()); |
| |
| glGenFramebuffers (1, &fbo); |
| glBindFramebuffer (GL_FRAMEBUFFER, fbo); |
| glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRbo); |
| glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo); |
| glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo); |
| |
| checkFramebufferStatus (GL_FRAMEBUFFER); |
| |
| glClearColor (0.0f, 0.0f, 0.0f, 1.0f); |
| glClear (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); |
| |
| glEnable (GL_DEPTH_TEST); |
| glEnable (GL_STENCIL_TEST); |
| glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE); |
| glStencilFunc (GL_ALWAYS, 1, 0xff); |
| |
| flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(1.0f, 0.0f, 0.0f, 1.0f)*cScale + cBias); |
| sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(1.0f, 1.0f, 1.0f)); |
| |
| // Bound FBO to test target and default to other |
| if (m_boundTarget != GL_FRAMEBUFFER) |
| { |
| // Dummy fbo is used as complemeting target (read when discarding draw for example). |
| // \note Framework takes care of deleting objects at the end of test case. |
| const deUint32 dummyTarget = m_boundTarget == GL_DRAW_FRAMEBUFFER ? GL_READ_FRAMEBUFFER : GL_DRAW_FRAMEBUFFER; |
| deUint32 dummyFbo = 0; |
| deUint32 dummyColorRbo = 0; |
| |
| glGenRenderbuffers (1, &dummyColorRbo); |
| glBindRenderbuffer (GL_RENDERBUFFER, dummyColorRbo); |
| glRenderbufferStorage (GL_RENDERBUFFER, GL_RGBA8, 64, 64); |
| glGenFramebuffers (1, &dummyFbo); |
| glBindFramebuffer (dummyTarget, dummyFbo); |
| glFramebufferRenderbuffer (dummyTarget, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, dummyColorRbo); |
| |
| glBindFramebuffer (m_boundTarget, fbo); |
| } |
| |
| glInvalidateFramebuffer(m_invalidateTarget, (int)m_invalidateAttachments.size(), m_invalidateAttachments.empty() ? DE_NULL : &m_invalidateAttachments[0]); |
| |
| if (m_boundTarget != GL_FRAMEBUFFER) |
| glBindFramebuffer(GL_FRAMEBUFFER, fbo); |
| |
| if (isColorDiscarded) |
| { |
| // Color was not preserved - fill with green. |
| glDisable(GL_DEPTH_TEST); |
| glDisable(GL_STENCIL_TEST); |
| |
| flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 1.0f, 0.0f, 1.0f)*cScale + cBias); |
| sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); |
| |
| glEnable(GL_DEPTH_TEST); |
| glEnable(GL_STENCIL_TEST); |
| } |
| |
| if (isDepthDiscarded) |
| { |
| // Depth was not preserved. |
| glDepthFunc(GL_ALWAYS); |
| } |
| |
| if (!isStencilDiscarded) |
| { |
| // Stencil was preserved. |
| glStencilFunc(GL_EQUAL, 1, 0xff); |
| } |
| |
| glEnable (GL_BLEND); |
| glBlendFunc (GL_ONE, GL_ONE); |
| glBlendEquation (GL_FUNC_ADD); |
| |
| flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 0.0f, 1.0f, 1.0f)*cScale + cBias); |
| sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(1.0f, 1.0f, 0.0f)); |
| |
| readPixels(dst, 0, 0, getWidth(), getHeight(), colorFmt, colorFmtInfo.lookupScale, colorFmtInfo.lookupBias); |
| } |
| |
| private: |
| deUint32 m_boundTarget; |
| deUint32 m_invalidateTarget; |
| std::vector<deUint32> m_invalidateAttachments; |
| }; |
| |
| FboInvalidateTests::FboInvalidateTests (Context& context) |
| : TestCaseGroup(context, "invalidate", "Framebuffer invalidate tests") |
| { |
| } |
| |
| FboInvalidateTests::~FboInvalidateTests (void) |
| { |
| } |
| |
| void FboInvalidateTests::init (void) |
| { |
| // invalidate.default. |
| { |
| tcu::TestCaseGroup* defaultFbGroup = new tcu::TestCaseGroup(m_testCtx, "default", "Default framebuffer invalidate tests"); |
| addChild(defaultFbGroup); |
| |
| defaultFbGroup->addChild(new InvalidateDefaultFramebufferRenderCase (m_context, "render_none", "Invalidating no framebuffers (ref)", 0)); |
| defaultFbGroup->addChild(new InvalidateDefaultFramebufferRenderCase (m_context, "render_color", "Rendering after invalidating colorbuffer", GL_COLOR_BUFFER_BIT)); |
| defaultFbGroup->addChild(new InvalidateDefaultFramebufferRenderCase (m_context, "render_depth", "Rendering after invalidating depthbuffer", GL_DEPTH_BUFFER_BIT)); |
| defaultFbGroup->addChild(new InvalidateDefaultFramebufferRenderCase (m_context, "render_stencil", "Rendering after invalidating stencilbuffer", GL_STENCIL_BUFFER_BIT)); |
| defaultFbGroup->addChild(new InvalidateDefaultFramebufferRenderCase (m_context, "render_depth_stencil", "Rendering after invalidating depth- and stencilbuffers", GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)); |
| defaultFbGroup->addChild(new InvalidateDefaultFramebufferRenderCase (m_context, "render_all", "Rendering after invalidating all buffers", GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)); |
| |
| defaultFbGroup->addChild(new InvalidateDefaultFramebufferBindCase (m_context, "bind_color", "Binding fbo after invalidating colorbuffer", GL_COLOR_BUFFER_BIT)); |
| defaultFbGroup->addChild(new InvalidateDefaultFramebufferBindCase (m_context, "bind_depth", "Binding fbo after invalidating depthbuffer", GL_DEPTH_BUFFER_BIT)); |
| defaultFbGroup->addChild(new InvalidateDefaultFramebufferBindCase (m_context, "bind_stencil", "Binding fbo after invalidating stencilbuffer", GL_STENCIL_BUFFER_BIT)); |
| defaultFbGroup->addChild(new InvalidateDefaultFramebufferBindCase (m_context, "bind_depth_stencil", "Binding fbo after invalidating depth- and stencilbuffers", GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)); |
| defaultFbGroup->addChild(new InvalidateDefaultFramebufferBindCase (m_context, "bind_all", "Binding fbo after invalidating all buffers", GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)); |
| |
| defaultFbGroup->addChild(new InvalidateDefaultSubFramebufferRenderCase (m_context, "sub_render_color", "Rendering after invalidating colorbuffer", GL_COLOR_BUFFER_BIT)); |
| defaultFbGroup->addChild(new InvalidateDefaultSubFramebufferRenderCase (m_context, "sub_render_depth", "Rendering after invalidating depthbuffer", GL_DEPTH_BUFFER_BIT)); |
| defaultFbGroup->addChild(new InvalidateDefaultSubFramebufferRenderCase (m_context, "sub_render_stencil", "Rendering after invalidating stencilbuffer", GL_STENCIL_BUFFER_BIT)); |
| defaultFbGroup->addChild(new InvalidateDefaultSubFramebufferRenderCase (m_context, "sub_render_depth_stencil", "Rendering after invalidating depth- and stencilbuffers", GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)); |
| defaultFbGroup->addChild(new InvalidateDefaultSubFramebufferRenderCase (m_context, "sub_render_all", "Rendering after invalidating all buffers", GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)); |
| |
| defaultFbGroup->addChild(new InvalidateDefaultSubFramebufferBindCase (m_context, "sub_bind_color", "Binding fbo after invalidating colorbuffer", GL_COLOR_BUFFER_BIT)); |
| defaultFbGroup->addChild(new InvalidateDefaultSubFramebufferBindCase (m_context, "sub_bind_depth", "Binding fbo after invalidating depthbuffer", GL_DEPTH_BUFFER_BIT)); |
| defaultFbGroup->addChild(new InvalidateDefaultSubFramebufferBindCase (m_context, "sub_bind_stencil", "Binding fbo after invalidating stencilbuffer", GL_STENCIL_BUFFER_BIT)); |
| defaultFbGroup->addChild(new InvalidateDefaultSubFramebufferBindCase (m_context, "sub_bind_depth_stencil", "Binding fbo after invalidating depth- and stencilbuffers", GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)); |
| defaultFbGroup->addChild(new InvalidateDefaultSubFramebufferBindCase (m_context, "sub_bind_all", "Binding fbo after invalidating all buffers", GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)); |
| |
| defaultFbGroup->addChild(new InvalidateDefaultFramebufferRenderCase (m_context, "draw_framebuffer_color", "Invalidating GL_COLOR in GL_DRAW_FRAMEBUFFER", GL_COLOR_BUFFER_BIT, GL_DRAW_FRAMEBUFFER)); |
| defaultFbGroup->addChild(new InvalidateDefaultFramebufferRenderCase (m_context, "draw_framebuffer_all", "Invalidating all in GL_DRAW_FRAMEBUFFER", GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT, GL_DRAW_FRAMEBUFFER)); |
| defaultFbGroup->addChild(new InvalidateDefaultFramebufferRenderCase (m_context, "read_framebuffer_color", "Invalidating GL_COLOR in GL_READ_FRAMEBUFFER", GL_COLOR_BUFFER_BIT, GL_READ_FRAMEBUFFER)); |
| defaultFbGroup->addChild(new InvalidateDefaultFramebufferRenderCase (m_context, "read_framebuffer_all", "Invalidating all in GL_READ_FRAMEBUFFER", GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT, GL_READ_FRAMEBUFFER)); |
| } |
| |
| // invalidate.whole. |
| { |
| tcu::TestCaseGroup* wholeFboGroup = new tcu::TestCaseGroup(m_testCtx, "whole", "Invalidating whole framebuffer object"); |
| addChild(wholeFboGroup); |
| |
| wholeFboGroup->addChild(new InvalidateFboRenderCase (m_context, "render_none", "", GL_RGBA8, GL_DEPTH24_STENCIL8, 0)); |
| wholeFboGroup->addChild(new InvalidateFboRenderCase (m_context, "render_color", "", GL_RGBA8, GL_DEPTH24_STENCIL8, GL_COLOR_BUFFER_BIT)); |
| wholeFboGroup->addChild(new InvalidateFboRenderCase (m_context, "render_depth", "", GL_RGBA8, GL_DEPTH24_STENCIL8, GL_DEPTH_BUFFER_BIT)); |
| wholeFboGroup->addChild(new InvalidateFboRenderCase (m_context, "render_stencil", "", GL_RGBA8, GL_DEPTH24_STENCIL8, GL_STENCIL_BUFFER_BIT)); |
| wholeFboGroup->addChild(new InvalidateFboRenderCase (m_context, "render_depth_stencil", "", GL_RGBA8, GL_DEPTH24_STENCIL8, GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)); |
| wholeFboGroup->addChild(new InvalidateFboRenderCase (m_context, "render_all", "", GL_RGBA8, GL_DEPTH24_STENCIL8, GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)); |
| |
| wholeFboGroup->addChild(new InvalidateFboUnbindReadCase (m_context, "unbind_read_color", "", GL_RGBA8, GL_DEPTH24_STENCIL8, GL_COLOR_BUFFER_BIT)); |
| wholeFboGroup->addChild(new InvalidateFboUnbindReadCase (m_context, "unbind_read_depth", "", GL_RGBA8, GL_DEPTH24_STENCIL8, GL_DEPTH_BUFFER_BIT)); |
| wholeFboGroup->addChild(new InvalidateFboUnbindReadCase (m_context, "unbind_read_stencil", "", GL_RGBA8, GL_DEPTH24_STENCIL8, GL_STENCIL_BUFFER_BIT)); |
| wholeFboGroup->addChild(new InvalidateFboUnbindReadCase (m_context, "unbind_read_depth_stencil", "", GL_RGBA8, GL_DEPTH24_STENCIL8, GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)); |
| wholeFboGroup->addChild(new InvalidateFboUnbindReadCase (m_context, "unbind_read_color_stencil", "", GL_RGBA8, GL_DEPTH24_STENCIL8, GL_COLOR_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)); |
| |
| wholeFboGroup->addChild(new InvalidateFboUnbindBlitCase (m_context, "unbind_blit_color", "", 0, GL_COLOR_BUFFER_BIT)); |
| wholeFboGroup->addChild(new InvalidateFboUnbindBlitCase (m_context, "unbind_blit_depth", "", 0, GL_DEPTH_BUFFER_BIT)); |
| wholeFboGroup->addChild(new InvalidateFboUnbindBlitCase (m_context, "unbind_blit_stencil", "", 0, GL_STENCIL_BUFFER_BIT)); |
| wholeFboGroup->addChild(new InvalidateFboUnbindBlitCase (m_context, "unbind_blit_depth_stencil", "", 0, GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)); |
| |
| wholeFboGroup->addChild(new InvalidateFboUnbindBlitCase (m_context, "unbind_blit_msaa_color", "", 4, GL_COLOR_BUFFER_BIT)); |
| wholeFboGroup->addChild(new InvalidateFboUnbindBlitCase (m_context, "unbind_blit_msaa_depth", "", 4, GL_DEPTH_BUFFER_BIT)); |
| wholeFboGroup->addChild(new InvalidateFboUnbindBlitCase (m_context, "unbind_blit_msaa_stencil", "", 4, GL_STENCIL_BUFFER_BIT)); |
| wholeFboGroup->addChild(new InvalidateFboUnbindBlitCase (m_context, "unbind_blit_msaa_depth_stencil", "", 4, GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)); |
| } |
| |
| // invalidate.sub. |
| { |
| tcu::TestCaseGroup* subFboGroup = new tcu::TestCaseGroup(m_testCtx, "sub", "Invalidating subsection of framebuffer object"); |
| addChild(subFboGroup); |
| |
| subFboGroup->addChild(new InvalidateSubFboRenderCase (m_context, "render_none", "", GL_RGBA8, GL_DEPTH24_STENCIL8, 0)); |
| subFboGroup->addChild(new InvalidateSubFboRenderCase (m_context, "render_color", "", GL_RGBA8, GL_DEPTH24_STENCIL8, GL_COLOR_BUFFER_BIT)); |
| subFboGroup->addChild(new InvalidateSubFboRenderCase (m_context, "render_depth", "", GL_RGBA8, GL_DEPTH24_STENCIL8, GL_DEPTH_BUFFER_BIT)); |
| subFboGroup->addChild(new InvalidateSubFboRenderCase (m_context, "render_stencil", "", GL_RGBA8, GL_DEPTH24_STENCIL8, GL_STENCIL_BUFFER_BIT)); |
| subFboGroup->addChild(new InvalidateSubFboRenderCase (m_context, "render_depth_stencil", "", GL_RGBA8, GL_DEPTH24_STENCIL8, GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)); |
| subFboGroup->addChild(new InvalidateSubFboRenderCase (m_context, "render_all", "", GL_RGBA8, GL_DEPTH24_STENCIL8, GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)); |
| |
| subFboGroup->addChild(new InvalidateSubFboUnbindReadCase(m_context, "unbind_read_color", "", GL_RGBA8, GL_DEPTH24_STENCIL8, GL_COLOR_BUFFER_BIT)); |
| subFboGroup->addChild(new InvalidateSubFboUnbindReadCase(m_context, "unbind_read_depth", "", GL_RGBA8, GL_DEPTH24_STENCIL8, GL_DEPTH_BUFFER_BIT)); |
| subFboGroup->addChild(new InvalidateSubFboUnbindReadCase(m_context, "unbind_read_stencil", "", GL_RGBA8, GL_DEPTH24_STENCIL8, GL_STENCIL_BUFFER_BIT)); |
| subFboGroup->addChild(new InvalidateSubFboUnbindReadCase(m_context, "unbind_read_depth_stencil", "", GL_RGBA8, GL_DEPTH24_STENCIL8, GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)); |
| subFboGroup->addChild(new InvalidateSubFboUnbindReadCase(m_context, "unbind_read_color_stencil", "", GL_RGBA8, GL_DEPTH24_STENCIL8, GL_COLOR_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)); |
| |
| subFboGroup->addChild(new InvalidateSubFboUnbindBlitCase(m_context, "unbind_blit_color", "", 0, GL_COLOR_BUFFER_BIT)); |
| subFboGroup->addChild(new InvalidateSubFboUnbindBlitCase(m_context, "unbind_blit_depth", "", 0, GL_DEPTH_BUFFER_BIT)); |
| subFboGroup->addChild(new InvalidateSubFboUnbindBlitCase(m_context, "unbind_blit_stencil", "", 0, GL_STENCIL_BUFFER_BIT)); |
| subFboGroup->addChild(new InvalidateSubFboUnbindBlitCase(m_context, "unbind_blit_depth_stencil", "", 0, GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)); |
| |
| subFboGroup->addChild(new InvalidateSubFboUnbindBlitCase(m_context, "unbind_blit_msaa_color", "", 4, GL_COLOR_BUFFER_BIT)); |
| subFboGroup->addChild(new InvalidateSubFboUnbindBlitCase(m_context, "unbind_blit_msaa_depth", "", 4, GL_DEPTH_BUFFER_BIT)); |
| subFboGroup->addChild(new InvalidateSubFboUnbindBlitCase(m_context, "unbind_blit_msaa_stencil", "", 4, GL_STENCIL_BUFFER_BIT)); |
| subFboGroup->addChild(new InvalidateSubFboUnbindBlitCase(m_context, "unbind_blit_msaa_depth_stencil", "", 4, GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)); |
| } |
| |
| // invalidate.format. |
| { |
| tcu::TestCaseGroup* formatGroup = new tcu::TestCaseGroup(m_testCtx, "format", "Invalidating framebuffers with selected formats"); |
| addChild(formatGroup); |
| |
| // Color buffer formats. |
| static const deUint32 colorFormats[] = |
| { |
| // RGBA formats |
| GL_RGBA32I, |
| GL_RGBA32UI, |
| GL_RGBA16I, |
| GL_RGBA16UI, |
| GL_RGBA8, |
| GL_RGBA8I, |
| GL_RGBA8UI, |
| GL_SRGB8_ALPHA8, |
| GL_RGB10_A2, |
| GL_RGB10_A2UI, |
| GL_RGBA4, |
| GL_RGB5_A1, |
| |
| // RGB formats |
| GL_RGB8, |
| GL_RGB565, |
| |
| // RG formats |
| GL_RG32I, |
| GL_RG32UI, |
| GL_RG16I, |
| GL_RG16UI, |
| GL_RG8, |
| GL_RG8I, |
| GL_RG8UI, |
| |
| // R formats |
| GL_R32I, |
| GL_R32UI, |
| GL_R16I, |
| GL_R16UI, |
| GL_R8, |
| GL_R8I, |
| GL_R8UI, |
| |
| // GL_EXT_color_buffer_float |
| GL_RGBA32F, |
| GL_RGBA16F, |
| GL_R11F_G11F_B10F, |
| GL_RG32F, |
| GL_RG16F, |
| GL_R32F, |
| GL_R16F |
| }; |
| |
| // Depth/stencilbuffer formats. |
| static const deUint32 depthStencilFormats[] = |
| { |
| GL_DEPTH_COMPONENT32F, |
| GL_DEPTH_COMPONENT24, |
| GL_DEPTH_COMPONENT16, |
| GL_DEPTH32F_STENCIL8, |
| GL_DEPTH24_STENCIL8, |
| GL_STENCIL_INDEX8 |
| }; |
| |
| // Colorbuffer tests use invalidate, unbind, read test. |
| for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(colorFormats); ndx++) |
| formatGroup->addChild(new InvalidateSubFboUnbindReadCase(m_context, getFormatName(colorFormats[ndx]), "", colorFormats[ndx], GL_NONE, GL_COLOR_BUFFER_BIT)); |
| |
| // Depth/stencilbuffer tests use invalidate, render test. |
| for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(depthStencilFormats); ndx++) |
| formatGroup->addChild(new InvalidateSubFboRenderCase(m_context, getFormatName(depthStencilFormats[ndx]), "", GL_RGBA8, depthStencilFormats[ndx], GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT)); |
| } |
| |
| // invalidate.target |
| { |
| tcu::TestCaseGroup* targetGroup = new tcu::TestCaseGroup(m_testCtx, "target", "Invalidate target"); |
| addChild(targetGroup); |
| |
| static const struct |
| { |
| const char* name; |
| deUint32 invalidateTarget; |
| deUint32 boundTarget; |
| } s_targetCases[] = |
| { |
| { "framebuffer_framebuffer", GL_FRAMEBUFFER, GL_FRAMEBUFFER }, |
| { "framebuffer_read_framebuffer", GL_FRAMEBUFFER, GL_READ_FRAMEBUFFER }, |
| { "framebuffer_draw_framebuffer", GL_FRAMEBUFFER, GL_DRAW_FRAMEBUFFER }, |
| { "read_framebuffer_framebuffer", GL_READ_FRAMEBUFFER, GL_FRAMEBUFFER }, |
| { "read_framebuffer_read_framebuffer", GL_READ_FRAMEBUFFER, GL_READ_FRAMEBUFFER }, |
| { "read_framebuffer_draw_framebuffer", GL_READ_FRAMEBUFFER, GL_DRAW_FRAMEBUFFER }, |
| { "draw_framebuffer_framebuffer", GL_DRAW_FRAMEBUFFER, GL_FRAMEBUFFER }, |
| { "draw_framebuffer_read_framebuffer", GL_DRAW_FRAMEBUFFER, GL_READ_FRAMEBUFFER }, |
| { "draw_framebuffer_draw_framebuffer", GL_DRAW_FRAMEBUFFER, GL_DRAW_FRAMEBUFFER }, |
| }; |
| |
| static const deUint32 colorAttachment[] = { GL_COLOR_ATTACHMENT0 }; |
| static const deUint32 depthStencilAttachment[] = { GL_DEPTH_STENCIL_ATTACHMENT }; |
| static const deUint32 allAttachments[] = { GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT }; |
| |
| for (int caseNdx = 0; caseNdx < DE_LENGTH_OF_ARRAY(s_targetCases); caseNdx++) |
| { |
| const std::string baseName = s_targetCases[caseNdx].name; |
| const deUint32 invalidateT = s_targetCases[caseNdx].invalidateTarget; |
| const deUint32 boundT = s_targetCases[caseNdx].boundTarget; |
| |
| targetGroup->addChild(new InvalidateFboTargetCase(m_context, (baseName + "_color").c_str(), "", boundT, invalidateT, &colorAttachment[0], DE_LENGTH_OF_ARRAY(colorAttachment))); |
| targetGroup->addChild(new InvalidateFboTargetCase(m_context, (baseName + "_depth_stencil").c_str(), "", boundT, invalidateT, &depthStencilAttachment[0], DE_LENGTH_OF_ARRAY(depthStencilAttachment))); |
| targetGroup->addChild(new InvalidateFboTargetCase(m_context, (baseName + "_all").c_str(), "", boundT, invalidateT, &allAttachments[0], DE_LENGTH_OF_ARRAY(allAttachments))); |
| } |
| } |
| } |
| |
| } // Functional |
| } // gles3 |
| } // deqp |