Browse Source

DebugTools: test for underflow in FrameProfilerGL primitive clip ratio.

This was fun to debug. Currently it trips up the assertions, which is
not great.
pull/525/head
Vladimír Vondruš 5 years ago
parent
commit
e903a7d242
  1. 68
      src/Magnum/DebugTools/Test/FrameProfilerGLTest.cpp

68
src/Magnum/DebugTools/Test/FrameProfilerGLTest.cpp

@ -38,6 +38,10 @@
#include "Magnum/Primitives/Cube.h" #include "Magnum/Primitives/Cube.h"
#include "Magnum/Shaders/FlatGL.h" #include "Magnum/Shaders/FlatGL.h"
#include "Magnum/Trade/MeshData.h" #include "Magnum/Trade/MeshData.h"
#ifndef MAGNUM_TARGET_GLES
#include "Magnum/Math/Matrix4.h"
#include "Magnum/Primitives/Plane.h"
#endif
namespace Magnum { namespace DebugTools { namespace Test { namespace { namespace Magnum { namespace DebugTools { namespace Test { namespace {
@ -48,9 +52,12 @@ struct FrameProfilerGLTest: GL::OpenGLTester {
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
void vertexFetchRatioDivisionByZero(); void vertexFetchRatioDivisionByZero();
void primitiveClipRatioDivisionByZero(); void primitiveClipRatioDivisionByZero();
void primitiveClipRatioNegative();
#endif #endif
}; };
using namespace Math::Literals;
struct { struct {
const char* name; const char* name;
FrameProfilerGL::Values values; FrameProfilerGL::Values values;
@ -70,7 +77,8 @@ FrameProfilerGLTest::FrameProfilerGLTest() {
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
addTests({&FrameProfilerGLTest::vertexFetchRatioDivisionByZero, addTests({&FrameProfilerGLTest::vertexFetchRatioDivisionByZero,
&FrameProfilerGLTest::primitiveClipRatioDivisionByZero}); &FrameProfilerGLTest::primitiveClipRatioDivisionByZero,
&FrameProfilerGLTest::primitiveClipRatioNegative});
#endif #endif
} }
@ -237,6 +245,64 @@ void FrameProfilerGLTest::primitiveClipRatioDivisionByZero() {
CORRADE_VERIFY(profiler.isMeasurementAvailable(FrameProfilerGL::Value::PrimitiveClipRatio)); CORRADE_VERIFY(profiler.isMeasurementAvailable(FrameProfilerGL::Value::PrimitiveClipRatio));
CORRADE_COMPARE(profiler.primitiveClipRatioMean(), 0.0); CORRADE_COMPARE(profiler.primitiveClipRatioMean(), 0.0);
} }
void FrameProfilerGLTest::primitiveClipRatioNegative() {
if(!GL::Context::current().isExtensionSupported<GL::Extensions::ARB::pipeline_statistics_query>())
CORRADE_SKIP(GL::Extensions::ARB::pipeline_statistics_query::string() << "is not supported.");
/* Bind some FB to avoid errors on contexts w/o default FB */
GL::Renderbuffer color;
color.setStorage(
#if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
GL::RenderbufferFormat::RGBA8,
#else
GL::RenderbufferFormat::RGBA4,
#endif
Vector2i{32});
GL::Framebuffer fb{{{}, Vector2i{32}}};
fb.attachRenderbuffer(GL::Framebuffer::ColorAttachment{0}, color)
.bind();
/* Rotate a plane so it cuts through the near/far clipping plane. That
forces the primitive clipping pipeline to cut the two input primitives
into four, causing the number of output primitives being larger than the
number of input primitives, which would then result in an underflow of
the unsigned counter and tripping up various assertions if not accounted
for.
Implementations are allowed to split up primitives in other cases as
well, but this is guaranteed to happen everywhere. */
GL::Mesh mesh = MeshTools::compile(Primitives::planeSolid());
Shaders::FlatGL3D shader;
shader.setTransformationProjectionMatrix(
Matrix4::rotationX(45.0_degf)*
Matrix4::scaling(Vector3{2.0f}));
FrameProfilerGL profiler{FrameProfilerGL::Value::PrimitiveClipRatio, 4};
profiler.beginFrame();
shader.draw(mesh);
profiler.endFrame();
profiler.beginFrame();
shader.draw(mesh);
profiler.endFrame();
profiler.beginFrame();
shader.draw(mesh);
profiler.endFrame();
profiler.beginFrame();
shader.draw(mesh);
profiler.endFrame();
MAGNUM_VERIFY_NO_GL_ERROR();
/* No draws happened, so the ratio should be 0 (and not crashing with a
division by zero) */
CORRADE_VERIFY(profiler.isMeasurementAvailable(FrameProfilerGL::Value::PrimitiveClipRatio));
CORRADE_COMPARE(profiler.primitiveClipRatioMean(), 0.0);
}
#endif #endif
}}}} }}}}

Loading…
Cancel
Save