Skip to content

Commit

Permalink
Implemented ARB_transform_feedback_overflow_query.
Browse files Browse the repository at this point in the history
  • Loading branch information
mosra committed Oct 9, 2016
1 parent 9373a2e commit 9642869
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 4 deletions.
2 changes: 1 addition & 1 deletion doc/opengl-support.dox
Expand Up @@ -244,7 +244,7 @@ Extension | Status
@extension{ARB,sparse_texture} | |
@extension{ARB,pipeline_statistics_query} | |
@extension{ARB,sparse_buffer} | |
@extension{ARB,transform_feedback_overflow_query} | |
@extension{ARB,transform_feedback_overflow_query} | done
@extension{KHR,blend_equation_advanced} | done
@extension3{KHR,blend_equation_advanced_coherent,blend_equation_advanced} | done
@extension{KHR,no_error} | done
Expand Down
26 changes: 24 additions & 2 deletions src/Magnum/PrimitiveQuery.h
Expand Up @@ -63,7 +63,6 @@ UnsignedInt primitiveCount = q.result<UnsignedInt>();
@requires_gl30 Extension @extension{EXT,transform_feedback}
@requires_gles30 Only sample queries are available in OpenGL ES 2.0.
@requires_webgl20 Queries are not available in WebGL 1.0.
@todo @extension{ARB,transform_feedback_overflow_query}
*/
class MAGNUM_EXPORT PrimitiveQuery: public AbstractQuery {
public:
Expand Down Expand Up @@ -95,7 +94,30 @@ class MAGNUM_EXPORT PrimitiveQuery: public AbstractQuery {
* @ref result<UnsignedInt>() or @ref result<Int>() to retrieve the
* result.
*/
TransformFeedbackPrimitivesWritten = GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN
TransformFeedbackPrimitivesWritten = GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN,

#ifndef MAGNUM_TARGET_GLES
/**
* Transform feedback overflow. When used with @ref begin(UnsignedInt),
* the index must be `0`. Use @ref result<bool>() to retrieve the
* result.
* @requires_extension Extension @extension{ARB,transform_feedback_overflow_query}
* @requires_gl Transform feedback overflow query is not available
* in OpenGL ES or WebGL.
*/
TransformFeedbackOverflow = GL_TRANSFORM_FEEDBACK_OVERFLOW_ARB,

/**
* Transform feedback stream overflow. When used with
* @ref begin(UnsignedInt), the index must be lower than
* @ref TransformFeedback::maxVertexStreams(). Use @ref result<bool>()
* to retrieve the result.
* @requires_extension Extension @extension{ARB,transform_feedback_overflow_query}
* @requires_gl Transform feedback overflow query is not available
* in OpenGL ES or WebGL.
*/
TransformFeedbackStreamOverflow = GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW_ARB
#endif
};

/**
Expand Down
94 changes: 93 additions & 1 deletion src/Magnum/Test/PrimitiveQueryGLTest.cpp
Expand Up @@ -51,6 +51,9 @@ struct PrimitiveQueryGLTest: AbstractOpenGLTester {
void primitivesGeneratedIndexed();
#endif
void transformFeedbackPrimitivesWritten();
#ifndef MAGNUM_TARGET_GLES
void transformFeedbackOverflow();
#endif
};

PrimitiveQueryGLTest::PrimitiveQueryGLTest() {
Expand All @@ -61,7 +64,11 @@ PrimitiveQueryGLTest::PrimitiveQueryGLTest() {
&PrimitiveQueryGLTest::primitivesGenerated,
&PrimitiveQueryGLTest::primitivesGeneratedIndexed,
#endif
&PrimitiveQueryGLTest::transformFeedbackPrimitivesWritten});
&PrimitiveQueryGLTest::transformFeedbackPrimitivesWritten,
#ifndef MAGNUM_TARGET_GLES
&PrimitiveQueryGLTest::transformFeedbackOverflow
#endif
});
}

void PrimitiveQueryGLTest::constructNoCreate() {
Expand Down Expand Up @@ -301,6 +308,91 @@ void PrimitiveQueryGLTest::transformFeedbackPrimitivesWritten() {
CORRADE_COMPARE(count, 3); /* Three triangles (9 vertices) */
}

#ifndef MAGNUM_TARGET_GLES
void PrimitiveQueryGLTest::transformFeedbackOverflow() {
#ifndef MAGNUM_TARGET_GLES
if(!Context::current().isExtensionSupported<Extensions::GL::ARB::transform_feedback_overflow_query>())
CORRADE_SKIP(Extensions::GL::ARB::transform_feedback_overflow_query::string() + std::string(" is not available."));
#endif

/* Bind some FB to avoid errors on contexts w/o default FB */
Renderbuffer color;
color.setStorage(RenderbufferFormat::RGBA8, Vector2i{32});
Framebuffer fb{{{}, Vector2i{32}}};
fb.attachRenderbuffer(Framebuffer::ColorAttachment{0}, color)
.bind();

struct MyShader: AbstractShaderProgram {
explicit MyShader() {
#ifndef MAGNUM_TARGET_GLES
Shader vert(
#ifndef CORRADE_TARGET_APPLE
Version::GL300
#else
Version::GL310
#endif
, Shader::Type::Vertex);
#else
Shader vert(Version::GLES300, Shader::Type::Vertex);
Shader frag(Version::GLES300, Shader::Type::Fragment);
#endif

CORRADE_INTERNAL_ASSERT_OUTPUT(vert.addSource(
"out mediump vec2 outputData;\n"
"void main() {\n"
" outputData = vec2(1.0, -1.0);\n"
/* Mesa drivers complain that vertex shader doesn't write to
gl_Position otherwise */
" gl_Position = vec4(1.0);\n"
"}\n").compile());
#ifndef MAGNUM_TARGET_GLES
attachShader(vert);
#else
/* ES for some reason needs both vertex and fragment shader */
CORRADE_INTERNAL_ASSERT_OUTPUT(frag.addSource("void main() {}\n").compile());
attachShaders({vert, frag});
#endif

setTransformFeedbackOutputs({"outputData"}, TransformFeedbackBufferMode::SeparateAttributes);
CORRADE_INTERNAL_ASSERT_OUTPUT(link());
}
} shader;

Buffer output;
output.setData({nullptr, 18*sizeof(Vector2)}, BufferUsage::StaticDraw);

Mesh mesh;
mesh.setPrimitive(MeshPrimitive::Triangles)
.setCount(9);

MAGNUM_VERIFY_NO_ERROR();

TransformFeedback feedback;
/* Deliberately one vertex smaller to not fit two of them */
feedback.attachBuffer(0, output, 0, 17*sizeof(Vector2));

Renderer::enable(Renderer::Feature::RasterizerDiscard);

feedback.begin(shader, TransformFeedback::PrimitiveMode::Triangles);
PrimitiveQuery q1{PrimitiveQuery::Target::TransformFeedbackOverflow},
q2{PrimitiveQuery::Target::TransformFeedbackOverflow};
q1.begin();
mesh.draw(shader);
q1.end();
q2.begin();
mesh.draw(shader);
q2.end();
feedback.end();

const bool overflown1 = q1.result<bool>();
const bool overflown2 = q2.result<bool>();

MAGNUM_VERIFY_NO_ERROR();
CORRADE_VERIFY(!overflown1);
CORRADE_VERIFY(overflown2); /* Got space for only 17 vertices instead of 2*9 */
}
#endif

}}

MAGNUM_GL_TEST_MAIN(Magnum::Test::PrimitiveQueryGLTest)

0 comments on commit 9642869

Please sign in to comment.