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.
386 lines
11 KiB
386 lines
11 KiB
/*------------------------------------------------------------------------- |
|
* drawElements Quality Program OpenGL (ES) 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 Framebuffer completeness tests. |
|
*//*--------------------------------------------------------------------*/ |
|
|
|
#include "es2fFboCompletenessTests.hpp" |
|
|
|
#include "glsFboCompletenessTests.hpp" |
|
#include "gluObjectWrapper.hpp" |
|
|
|
using namespace glw; |
|
using deqp::gls::Range; |
|
using namespace deqp::gls::FboUtil; |
|
using namespace deqp::gls::FboUtil::config; |
|
namespace fboc = deqp::gls::fboc; |
|
typedef tcu::TestCase::IterateResult IterateResult; |
|
|
|
namespace deqp |
|
{ |
|
namespace gles2 |
|
{ |
|
namespace Functional |
|
{ |
|
|
|
static const FormatKey s_es2ColorRenderables[] = |
|
{ |
|
GL_RGBA4, GL_RGB5_A1, GL_RGB565, |
|
}; |
|
|
|
// GLES2 does not strictly allow these, but this seems to be a bug in the |
|
// specification. For now, let's assume the unsized formats corresponding to |
|
// the color-renderable sized formats are allowed. |
|
// See https://cvs.khronos.org/bugzilla/show_bug.cgi?id=7333 |
|
|
|
static const FormatKey s_es2UnsizedColorRenderables[] = |
|
{ |
|
GLS_UNSIZED_FORMATKEY(GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4), |
|
GLS_UNSIZED_FORMATKEY(GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1), |
|
GLS_UNSIZED_FORMATKEY(GL_RGB, GL_UNSIGNED_SHORT_5_6_5) |
|
}; |
|
|
|
static const FormatKey s_es2DepthRenderables[] = |
|
{ |
|
GL_DEPTH_COMPONENT16, |
|
}; |
|
|
|
static const FormatKey s_es2StencilRenderables[] = |
|
{ |
|
GL_STENCIL_INDEX8, |
|
}; |
|
|
|
static const FormatEntry s_es2Formats[] = |
|
{ |
|
{ COLOR_RENDERABLE | TEXTURE_VALID, |
|
GLS_ARRAY_RANGE(s_es2UnsizedColorRenderables) }, |
|
{ REQUIRED_RENDERABLE | COLOR_RENDERABLE | RENDERBUFFER_VALID, |
|
GLS_ARRAY_RANGE(s_es2ColorRenderables) }, |
|
{ REQUIRED_RENDERABLE | DEPTH_RENDERABLE | RENDERBUFFER_VALID, |
|
GLS_ARRAY_RANGE(s_es2DepthRenderables) }, |
|
{ REQUIRED_RENDERABLE | STENCIL_RENDERABLE | RENDERBUFFER_VALID, |
|
GLS_ARRAY_RANGE(s_es2StencilRenderables) }, |
|
}; |
|
|
|
// We have here only the extensions that are redundant in vanilla GLES3. Those |
|
// that are applicable both to GLES2 and GLES3 are in glsFboCompletenessTests.cpp. |
|
|
|
// GL_OES_texture_float |
|
static const FormatKey s_oesTextureFloatFormats[] = |
|
{ |
|
GLS_UNSIZED_FORMATKEY(GL_RGBA, GL_FLOAT), |
|
GLS_UNSIZED_FORMATKEY(GL_RGB, GL_FLOAT), |
|
}; |
|
|
|
// GL_OES_texture_half_float |
|
static const FormatKey s_oesTextureHalfFloatFormats[] = |
|
{ |
|
GLS_UNSIZED_FORMATKEY(GL_RGBA, GL_HALF_FLOAT_OES), |
|
GLS_UNSIZED_FORMATKEY(GL_RGB, GL_HALF_FLOAT_OES), |
|
}; |
|
|
|
// GL_EXT_sRGB_write_control |
|
static const FormatKey s_extSrgbWriteControlFormats[] = |
|
{ |
|
GL_SRGB8_ALPHA8 |
|
}; |
|
|
|
// DEQP_gles3_core_no_extension_features |
|
static const FormatKey s_es3NoExtRboFormats[] = |
|
{ |
|
GL_RGB10_A2, |
|
}; |
|
static const FormatKey s_es3NoExtTextureFormats[] = |
|
{ |
|
GL_R16F, |
|
GL_RG16F, |
|
GL_RGB16F, |
|
GL_RGBA16F, |
|
GL_R11F_G11F_B10F, |
|
}; |
|
static const FormatKey s_es3NoExtTextureColorRenderableFormats[] = |
|
{ |
|
GL_R8, |
|
GL_RG8, |
|
}; |
|
|
|
// with ES3 core and GL_EXT_color_buffer_float |
|
static const FormatKey s_es3NoExtExtColorBufferFloatFormats[] = |
|
{ |
|
// \note Only the GLES2+exts subset of formats |
|
GL_R11F_G11F_B10F, GL_RGBA16F, GL_RG16F, GL_R16F, |
|
}; |
|
|
|
// with ES3 core with OES_texture_stencil8 |
|
static const FormatKey s_es3NoExtOesTextureStencil8Formats[] = |
|
{ |
|
GL_STENCIL_INDEX8, |
|
}; |
|
|
|
static const FormatExtEntry s_es2ExtFormats[] = |
|
{ |
|
// The extension does not specify these to be color-renderable. |
|
{ |
|
"GL_OES_texture_float", |
|
(deUint32)TEXTURE_VALID, |
|
GLS_ARRAY_RANGE(s_oesTextureFloatFormats) |
|
}, |
|
{ |
|
"GL_OES_texture_half_float", |
|
(deUint32)TEXTURE_VALID, |
|
GLS_ARRAY_RANGE(s_oesTextureHalfFloatFormats) |
|
}, |
|
|
|
// GL_EXT_sRGB_write_control makes SRGB8_ALPHA8 color-renderable |
|
{ |
|
"GL_EXT_sRGB_write_control", |
|
(deUint32)(REQUIRED_RENDERABLE | TEXTURE_VALID | COLOR_RENDERABLE | RENDERBUFFER_VALID), |
|
GLS_ARRAY_RANGE(s_extSrgbWriteControlFormats) |
|
}, |
|
|
|
// Since GLES3 is "backwards compatible" to GLES2, we might actually be running on a GLES3 |
|
// context. Since GLES3 added some features to core with no corresponding GLES2 extension, |
|
// some tests might produce wrong results (since they are using rules of GLES2 & extensions) |
|
// |
|
// To avoid this, require new features of GLES3 that have no matching GLES2 extension if |
|
// context is GLES3. This can be done with a DEQP_* extensions. |
|
// |
|
// \note Not all feature changes are listed here but only those that alter GLES2 subset of |
|
// the formats |
|
{ |
|
"DEQP_gles3_core_compatible", |
|
(deUint32)(REQUIRED_RENDERABLE | COLOR_RENDERABLE | RENDERBUFFER_VALID), |
|
GLS_ARRAY_RANGE(s_es3NoExtRboFormats) |
|
}, |
|
{ |
|
"DEQP_gles3_core_compatible", |
|
(deUint32)TEXTURE_VALID, |
|
GLS_ARRAY_RANGE(s_es3NoExtTextureFormats) |
|
}, |
|
{ |
|
"DEQP_gles3_core_compatible", |
|
(deUint32)(REQUIRED_RENDERABLE | TEXTURE_VALID | COLOR_RENDERABLE | RENDERBUFFER_VALID), |
|
GLS_ARRAY_RANGE(s_es3NoExtTextureColorRenderableFormats) |
|
}, |
|
{ |
|
"DEQP_gles3_core_compatible GL_EXT_color_buffer_float", |
|
(deUint32)(REQUIRED_RENDERABLE | COLOR_RENDERABLE | RENDERBUFFER_VALID), |
|
GLS_ARRAY_RANGE(s_es3NoExtExtColorBufferFloatFormats) |
|
}, |
|
{ |
|
"DEQP_gles3_core_compatible GL_OES_texture_stencil8", |
|
(deUint32)(REQUIRED_RENDERABLE | STENCIL_RENDERABLE | TEXTURE_VALID), |
|
GLS_ARRAY_RANGE(s_es3NoExtOesTextureStencil8Formats) |
|
}, |
|
}; |
|
|
|
class ES2Checker : public Checker |
|
{ |
|
public: |
|
ES2Checker (const glu::RenderContext& ctx); |
|
void check (GLenum attPoint, const Attachment& att, |
|
const Image* image); |
|
private: |
|
GLsizei m_width; //< The common width of images |
|
GLsizei m_height; //< The common height of images |
|
}; |
|
|
|
ES2Checker::ES2Checker (const glu::RenderContext& ctx)\ |
|
: Checker (ctx) |
|
, m_width (-1) |
|
, m_height (-1) |
|
{ |
|
} |
|
|
|
void ES2Checker::check (GLenum attPoint, const Attachment& att, const Image* image) |
|
{ |
|
DE_UNREF(attPoint); |
|
DE_UNREF(att); |
|
// GLES2: "All attached images have the same width and height." |
|
if (m_width == -1) |
|
{ |
|
m_width = image->width; |
|
m_height = image->height; |
|
} |
|
else if (image->width != m_width || image->height != m_height) |
|
{ |
|
// Since GLES3 is "backwards compatible" to GLES2, we might actually be running |
|
// on a GLES3 context. On GLES3, FRAMEBUFFER_INCOMPLETE_DIMENSIONS is not generated |
|
// if attachments have different sizes. |
|
if (!gls::FboUtil::checkExtensionSupport(m_renderCtx, "DEQP_gles3_core_compatible")) |
|
{ |
|
// running on GLES2 |
|
addFBOStatus(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS, "Sizes of attachments differ"); |
|
} |
|
} |
|
// GLES2, 4.4.5: "some implementations may not support rendering to |
|
// particular combinations of internal formats. If the combination of |
|
// formats of the images attached to a framebuffer object are not |
|
// supported by the implementation, then the framebuffer is not complete |
|
// under the clause labeled FRAMEBUFFER_UNSUPPORTED." |
|
// |
|
// Hence it is _always_ allowed to report FRAMEBUFFER_UNSUPPORTED. |
|
addPotentialFBOStatus(GL_FRAMEBUFFER_UNSUPPORTED, "Particular format combinations need not to be supported"); |
|
} |
|
|
|
struct FormatCombination |
|
{ |
|
GLenum colorKind; |
|
ImageFormat colorFmt; |
|
GLenum depthKind; |
|
ImageFormat depthFmt; |
|
GLenum stencilKind; |
|
ImageFormat stencilFmt; |
|
}; |
|
|
|
class SupportedCombinationTest : public fboc::TestBase |
|
{ |
|
public: |
|
SupportedCombinationTest (fboc::Context& ctx, |
|
const char* name, const char* desc) |
|
: TestBase (ctx, name, desc) {} |
|
|
|
IterateResult iterate (void); |
|
bool tryCombination (const FormatCombination& comb); |
|
GLenum formatKind (ImageFormat fmt); |
|
}; |
|
|
|
bool SupportedCombinationTest::tryCombination (const FormatCombination& comb) |
|
{ |
|
glu::Framebuffer fbo(m_ctx.getRenderContext()); |
|
FboBuilder builder(*fbo, GL_FRAMEBUFFER, fboc::gl(*this)); |
|
|
|
attachTargetToNew(GL_COLOR_ATTACHMENT0, comb.colorKind, comb.colorFmt, |
|
64, 64, builder); |
|
attachTargetToNew(GL_DEPTH_ATTACHMENT, comb.depthKind, comb.depthFmt, |
|
64, 64, builder); |
|
attachTargetToNew(GL_STENCIL_ATTACHMENT, comb.stencilKind, comb.stencilFmt, |
|
64, 64, builder); |
|
|
|
const GLenum glStatus = fboc::gl(*this).checkFramebufferStatus(GL_FRAMEBUFFER); |
|
|
|
return (glStatus == GL_FRAMEBUFFER_COMPLETE); |
|
} |
|
|
|
GLenum SupportedCombinationTest::formatKind (ImageFormat fmt) |
|
{ |
|
if (fmt.format == GL_NONE) |
|
return GL_NONE; |
|
|
|
const FormatFlags flags = m_ctx.getCoreFormats().getFormatInfo(fmt); |
|
const bool rbo = (flags & RENDERBUFFER_VALID) != 0; |
|
// exactly one of renderbuffer and texture is supported by vanilla GLES2 formats |
|
DE_ASSERT(rbo != ((flags & TEXTURE_VALID) != 0)); |
|
|
|
return rbo ? GL_RENDERBUFFER : GL_TEXTURE; |
|
} |
|
|
|
IterateResult SupportedCombinationTest::iterate (void) |
|
{ |
|
const FormatDB& db = m_ctx.getCoreFormats(); |
|
const ImageFormat none = ImageFormat::none(); |
|
Formats colorFmts = db.getFormats(COLOR_RENDERABLE); |
|
Formats depthFmts = db.getFormats(DEPTH_RENDERABLE); |
|
Formats stencilFmts = db.getFormats(STENCIL_RENDERABLE); |
|
FormatCombination comb; |
|
bool succ = false; |
|
|
|
colorFmts.insert(none); |
|
depthFmts.insert(none); |
|
stencilFmts.insert(none); |
|
|
|
for (Formats::const_iterator col = colorFmts.begin(); col != colorFmts.end(); col++) |
|
{ |
|
comb.colorFmt = *col; |
|
comb.colorKind = formatKind(*col); |
|
for (Formats::const_iterator dep = depthFmts.begin(); dep != depthFmts.end(); dep++) |
|
{ |
|
comb.depthFmt = *dep; |
|
comb.depthKind = formatKind(*dep); |
|
for (Formats::const_iterator stc = stencilFmts.begin(); |
|
stc != stencilFmts.end(); stc++) |
|
{ |
|
comb.stencilFmt = *stc; |
|
comb.stencilKind = formatKind(*stc); |
|
succ = tryCombination(comb); |
|
if (succ) |
|
break; |
|
} |
|
} |
|
} |
|
|
|
if (succ) |
|
pass(); |
|
else |
|
fail("No supported format combination found"); |
|
|
|
return STOP; |
|
} |
|
|
|
class ES2CheckerFactory : public CheckerFactory |
|
{ |
|
public: |
|
Checker* createChecker (const glu::RenderContext& ctx) { return new ES2Checker(ctx); } |
|
}; |
|
|
|
class TestGroup : public TestCaseGroup |
|
{ |
|
public: |
|
TestGroup (Context& ctx); |
|
void init (void); |
|
private: |
|
ES2CheckerFactory m_checkerFactory; |
|
fboc::Context m_fboc; |
|
}; |
|
|
|
TestGroup::TestGroup (Context& ctx) |
|
: TestCaseGroup (ctx, "completeness", "Completeness tests") |
|
, m_checkerFactory () |
|
, m_fboc (ctx.getTestContext(), ctx.getRenderContext(), m_checkerFactory) |
|
{ |
|
const FormatEntries stdRange = GLS_ARRAY_RANGE(s_es2Formats); |
|
const FormatExtEntries extRange = GLS_ARRAY_RANGE(s_es2ExtFormats); |
|
|
|
m_fboc.addFormats(stdRange); |
|
m_fboc.addExtFormats(extRange); |
|
m_fboc.setHaveMulticolorAtts( |
|
ctx.getContextInfo().isExtensionSupported("GL_NV_fbo_color_attachments")); |
|
} |
|
|
|
void TestGroup::init (void) |
|
{ |
|
tcu::TestCaseGroup* attCombTests = m_fboc.createAttachmentTests(); |
|
addChild(m_fboc.createRenderableTests()); |
|
attCombTests->addChild(new SupportedCombinationTest( |
|
m_fboc, |
|
"exists_supported", |
|
"Test for existence of a supported combination of formats")); |
|
addChild(attCombTests); |
|
addChild(m_fboc.createSizeTests()); |
|
} |
|
|
|
tcu::TestCaseGroup* createFboCompletenessTests (Context& context) |
|
{ |
|
return new TestGroup(context); |
|
} |
|
|
|
} // Functional |
|
} // gles2 |
|
} // deqp
|
|
|