You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
287 lines
10 KiB
287 lines
10 KiB
/*-------------------------------------------------------------------------
|
|
* 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 stencilbuffer tests.
|
|
*//*--------------------------------------------------------------------*/
|
|
|
|
#include "es3fFboStencilbufferTests.hpp"
|
|
#include "es3fFboTestCase.hpp"
|
|
#include "es3fFboTestUtil.hpp"
|
|
#include "gluTextureUtil.hpp"
|
|
#include "tcuTextureUtil.hpp"
|
|
#include "sglrContextUtil.hpp"
|
|
#include "glwEnums.hpp"
|
|
|
|
namespace deqp
|
|
{
|
|
namespace gles3
|
|
{
|
|
namespace Functional
|
|
{
|
|
|
|
using std::string;
|
|
using tcu::Vec2;
|
|
using tcu::Vec3;
|
|
using tcu::Vec4;
|
|
using tcu::IVec2;
|
|
using tcu::IVec3;
|
|
using tcu::IVec4;
|
|
using tcu::UVec4;
|
|
using namespace FboTestUtil;
|
|
|
|
class BasicFboStencilCase : public FboTestCase
|
|
{
|
|
public:
|
|
BasicFboStencilCase (Context& context, const char* name, const char* desc, deUint32 format, IVec2 size, bool useDepth)
|
|
: FboTestCase (context, name, desc)
|
|
, m_format (format)
|
|
, m_size (size)
|
|
, m_useDepth (useDepth)
|
|
{
|
|
}
|
|
|
|
protected:
|
|
void preCheck (void)
|
|
{
|
|
checkFormatSupport(m_format);
|
|
}
|
|
|
|
void render (tcu::Surface& dst)
|
|
{
|
|
const deUint32 colorFormat = GL_RGBA8;
|
|
|
|
GradientShader gradShader (glu::TYPE_FLOAT_VEC4);
|
|
FlatColorShader flatShader (glu::TYPE_FLOAT_VEC4);
|
|
deUint32 flatShaderID = getCurrentContext()->createProgram(&flatShader);
|
|
deUint32 gradShaderID = getCurrentContext()->createProgram(&gradShader);
|
|
|
|
deUint32 fbo = 0;
|
|
deUint32 colorRbo = 0;
|
|
deUint32 depthStencilRbo = 0;
|
|
|
|
// Colorbuffer.
|
|
glGenRenderbuffers(1, &colorRbo);
|
|
glBindRenderbuffer(GL_RENDERBUFFER, colorRbo);
|
|
glRenderbufferStorage(GL_RENDERBUFFER, colorFormat, m_size.x(), m_size.y());
|
|
|
|
// Stencil (and depth) buffer.
|
|
glGenRenderbuffers(1, &depthStencilRbo);
|
|
glBindRenderbuffer(GL_RENDERBUFFER, depthStencilRbo);
|
|
glRenderbufferStorage(GL_RENDERBUFFER, m_format, m_size.x(), m_size.y());
|
|
|
|
// Framebuffer.
|
|
glGenFramebuffers(1, &fbo);
|
|
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
|
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRbo);
|
|
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo);
|
|
if (m_useDepth)
|
|
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthStencilRbo);
|
|
checkError();
|
|
checkFramebufferStatus(GL_FRAMEBUFFER);
|
|
|
|
glViewport(0, 0, m_size.x(), m_size.y());
|
|
|
|
// Clear framebuffer.
|
|
glClearBufferfv(GL_COLOR, 0, Vec4(0.0f).getPtr());
|
|
glClearBufferfi(GL_DEPTH_STENCIL, 0, 1.0f, 0);
|
|
|
|
// Render intersecting quads - increment stencil on depth pass
|
|
glEnable(GL_DEPTH_TEST);
|
|
glEnable(GL_STENCIL_TEST);
|
|
glStencilFunc(GL_ALWAYS, 0, 0xffu);
|
|
glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
|
|
|
|
flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(1.0f, 0.0f, 0.0f, 1.0f));
|
|
sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(+1.0f, +1.0f, 0.0f));
|
|
|
|
gradShader.setGradient(*getCurrentContext(), gradShaderID, Vec4(0.0f), Vec4(1.0f));
|
|
sglr::drawQuad(*getCurrentContext(), gradShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(+1.0f, +1.0f, +1.0f));
|
|
|
|
glDisable(GL_DEPTH_TEST);
|
|
|
|
// Draw quad with stencil test (stencil == 1 or 2 depending on depth) - decrement on stencil failure
|
|
glStencilFunc(GL_EQUAL, m_useDepth ? 2 : 1, 0xffu);
|
|
glStencilOp(GL_DECR, GL_KEEP, GL_KEEP);
|
|
|
|
flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 1.0f, 0.0f, 1.0));
|
|
sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-0.5f, -0.5f, 0.0f), Vec3(+0.5f, +0.5f, 0.0f));
|
|
|
|
// Draw quad with stencil test where stencil > 1 or 2 depending on depth buffer
|
|
glStencilFunc(GL_GREATER, m_useDepth ? 1 : 2, 0xffu);
|
|
|
|
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, m_size.x(), m_size.y(), glu::mapGLInternalFormat(colorFormat), Vec4(1.0f), Vec4(0.0f));
|
|
}
|
|
|
|
private:
|
|
deUint32 m_format;
|
|
IVec2 m_size;
|
|
bool m_useDepth;
|
|
};
|
|
|
|
class DepthStencilAttachCase : public FboTestCase
|
|
{
|
|
public:
|
|
DepthStencilAttachCase (Context& context, const char* name, const char* desc, deUint32 attachDepth, deUint32 attachStencil)
|
|
: FboTestCase (context, name, desc)
|
|
, m_attachDepth (attachDepth)
|
|
, m_attachStencil (attachStencil)
|
|
{
|
|
DE_ASSERT(m_attachDepth == GL_DEPTH_ATTACHMENT || m_attachDepth == GL_DEPTH_STENCIL_ATTACHMENT || m_attachDepth == GL_NONE);
|
|
DE_ASSERT(m_attachStencil == GL_STENCIL_ATTACHMENT || m_attachStencil == GL_NONE);
|
|
DE_ASSERT(m_attachDepth != GL_DEPTH_STENCIL || m_attachStencil == GL_NONE);
|
|
}
|
|
|
|
protected:
|
|
void render (tcu::Surface& dst)
|
|
{
|
|
const deUint32 colorFormat = GL_RGBA8;
|
|
const deUint32 depthStencilFormat = GL_DEPTH24_STENCIL8;
|
|
const int width = 128;
|
|
const int height = 128;
|
|
const bool hasDepth = (m_attachDepth == GL_DEPTH_STENCIL || m_attachDepth == GL_DEPTH_ATTACHMENT);
|
|
// const bool hasStencil = (m_attachDepth == GL_DEPTH_STENCIL || m_attachStencil == GL_DEPTH_STENCIL_ATTACHMENT);
|
|
|
|
GradientShader gradShader (glu::TYPE_FLOAT_VEC4);
|
|
FlatColorShader flatShader (glu::TYPE_FLOAT_VEC4);
|
|
deUint32 flatShaderID = getCurrentContext()->createProgram(&flatShader);
|
|
deUint32 gradShaderID = getCurrentContext()->createProgram(&gradShader);
|
|
|
|
deUint32 fbo = 0;
|
|
deUint32 colorRbo = 0;
|
|
deUint32 depthStencilRbo = 0;
|
|
|
|
// Colorbuffer.
|
|
glGenRenderbuffers(1, &colorRbo);
|
|
glBindRenderbuffer(GL_RENDERBUFFER, colorRbo);
|
|
glRenderbufferStorage(GL_RENDERBUFFER, colorFormat, width, height);
|
|
|
|
// Depth-stencil buffer.
|
|
glGenRenderbuffers(1, &depthStencilRbo);
|
|
glBindRenderbuffer(GL_RENDERBUFFER, depthStencilRbo);
|
|
glRenderbufferStorage(GL_RENDERBUFFER, depthStencilFormat, width, height);
|
|
|
|
// Framebuffer.
|
|
glGenFramebuffers(1, &fbo);
|
|
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
|
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRbo);
|
|
|
|
if (m_attachDepth != GL_NONE)
|
|
glFramebufferRenderbuffer(GL_FRAMEBUFFER, m_attachDepth, GL_RENDERBUFFER, depthStencilRbo);
|
|
if (m_attachStencil != GL_NONE)
|
|
glFramebufferRenderbuffer(GL_FRAMEBUFFER, m_attachStencil, GL_RENDERBUFFER, depthStencilRbo);
|
|
|
|
checkError();
|
|
checkFramebufferStatus(GL_FRAMEBUFFER);
|
|
|
|
glViewport(0, 0, width, height);
|
|
|
|
// Clear framebuffer.
|
|
glClearBufferfv(GL_COLOR, 0, Vec4(0.0f).getPtr());
|
|
glClearBufferfi(GL_DEPTH_STENCIL, 0, 1.0f, 0);
|
|
|
|
// Render intersecting quads - increment stencil on depth pass
|
|
glEnable(GL_DEPTH_TEST);
|
|
glEnable(GL_STENCIL_TEST);
|
|
glStencilFunc(GL_ALWAYS, 0, 0xffu);
|
|
glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
|
|
|
|
flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(1.0f, 0.0f, 0.0f, 1.0f));
|
|
sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-1.0f, -1.0f, 0.0f), Vec3(+1.0f, +1.0f, 0.0f));
|
|
|
|
gradShader.setGradient(*getCurrentContext(), gradShaderID, Vec4(0.0f), Vec4(1.0f));
|
|
sglr::drawQuad(*getCurrentContext(), gradShaderID, Vec3(-1.0f, -1.0f, -1.0f), Vec3(+1.0f, +1.0f, +1.0f));
|
|
|
|
glDisable(GL_DEPTH_TEST);
|
|
|
|
// Draw quad with stencil test (stencil == 1 or 2 depending on depth) - decrement on stencil failure
|
|
glStencilFunc(GL_EQUAL, hasDepth ? 2 : 1, 0xffu);
|
|
glStencilOp(GL_DECR, GL_KEEP, GL_KEEP);
|
|
|
|
flatShader.setColor(*getCurrentContext(), flatShaderID, Vec4(0.0f, 1.0f, 0.0f, 1.0));
|
|
sglr::drawQuad(*getCurrentContext(), flatShaderID, Vec3(-0.5f, -0.5f, 0.0f), Vec3(+0.5f, +0.5f, 0.0f));
|
|
|
|
// Draw quad with stencil test where stencil > 1 or 2 depending on depth buffer
|
|
glStencilFunc(GL_GREATER, hasDepth ? 1 : 2, 0xffu);
|
|
|
|
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, width, height, glu::mapGLInternalFormat(colorFormat), Vec4(1.0f), Vec4(0.0f));
|
|
}
|
|
|
|
private:
|
|
deUint32 m_attachDepth;
|
|
deUint32 m_attachStencil;
|
|
};
|
|
|
|
FboStencilTests::FboStencilTests (Context& context)
|
|
: TestCaseGroup(context, "stencil", "FBO Stencilbuffer tests")
|
|
{
|
|
}
|
|
|
|
FboStencilTests::~FboStencilTests (void)
|
|
{
|
|
}
|
|
|
|
void FboStencilTests::init (void)
|
|
{
|
|
static const deUint32 stencilFormats[] =
|
|
{
|
|
GL_DEPTH32F_STENCIL8,
|
|
GL_DEPTH24_STENCIL8,
|
|
GL_STENCIL_INDEX8
|
|
};
|
|
|
|
// .basic
|
|
{
|
|
tcu::TestCaseGroup* basicGroup = new tcu::TestCaseGroup(m_testCtx, "basic", "Basic stencil tests");
|
|
addChild(basicGroup);
|
|
|
|
for (int fmtNdx = 0; fmtNdx < DE_LENGTH_OF_ARRAY(stencilFormats); fmtNdx++)
|
|
{
|
|
deUint32 format = stencilFormats[fmtNdx];
|
|
tcu::TextureFormat texFmt = glu::mapGLInternalFormat(format);
|
|
|
|
basicGroup->addChild(new BasicFboStencilCase(m_context, getFormatName(format), "", format, IVec2(111, 132), false));
|
|
|
|
if (texFmt.order == tcu::TextureFormat::DS)
|
|
basicGroup->addChild(new BasicFboStencilCase(m_context, (string(getFormatName(format)) + "_depth").c_str(), "", format, IVec2(111, 132), true));
|
|
}
|
|
}
|
|
|
|
// .attach
|
|
{
|
|
tcu::TestCaseGroup* attachGroup = new tcu::TestCaseGroup(m_testCtx, "attach", "Attaching depth stencil");
|
|
addChild(attachGroup);
|
|
|
|
attachGroup->addChild(new DepthStencilAttachCase(m_context, "depth_only", "Only depth part of depth-stencil RBO attached", GL_DEPTH_ATTACHMENT, GL_NONE));
|
|
attachGroup->addChild(new DepthStencilAttachCase(m_context, "stencil_only", "Only stencil part of depth-stencil RBO attached", GL_NONE, GL_STENCIL_ATTACHMENT));
|
|
attachGroup->addChild(new DepthStencilAttachCase(m_context, "depth_stencil_separate", "Depth and stencil attached separately", GL_DEPTH_ATTACHMENT, GL_STENCIL_ATTACHMENT));
|
|
attachGroup->addChild(new DepthStencilAttachCase(m_context, "depth_stencil_attachment", "Depth and stencil attached with DEPTH_STENCIL_ATTACHMENT", GL_DEPTH_STENCIL_ATTACHMENT, GL_NONE));
|
|
}
|
|
}
|
|
|
|
} // Functional
|
|
} // gles3
|
|
} // deqp
|