From 5c10d6eb1e03015f7dfcc17552982fd7aeffa948 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Wed, 29 Apr 2020 18:40:06 +0200 Subject: [PATCH] GL: implemented ARB_pipeline_statistics_query from GL 4.6. Need this for the upcoming FrameProfiler. --- doc/changelog.dox | 1 + doc/opengl-support.dox | 2 +- src/Magnum/GL/AbstractQuery.cpp | 17 ++ src/Magnum/GL/AbstractQuery.h | 5 +- src/Magnum/GL/CMakeLists.txt | 4 +- src/Magnum/GL/GL.h | 3 + src/Magnum/GL/Implementation/QueryState.cpp | 5 +- .../GL/Implementation/driverSpecific.cpp | 8 +- src/Magnum/GL/PipelineStatisticsQuery.h | 186 ++++++++++++++++++ src/Magnum/GL/PrimitiveQuery.h | 3 +- src/Magnum/GL/SampleQuery.h | 2 +- src/Magnum/GL/Test/CMakeLists.txt | 12 +- .../GL/Test/PipelineStatisticsQueryGLTest.cpp | 144 ++++++++++++++ .../GL/Test/PipelineStatisticsQueryTest.cpp | 60 ++++++ src/Magnum/GL/TimeQuery.h | 3 +- 15 files changed, 443 insertions(+), 12 deletions(-) create mode 100644 src/Magnum/GL/PipelineStatisticsQuery.h create mode 100644 src/Magnum/GL/Test/PipelineStatisticsQueryGLTest.cpp create mode 100644 src/Magnum/GL/Test/PipelineStatisticsQueryTest.cpp diff --git a/doc/changelog.dox b/doc/changelog.dox index 04ca99fe2..137b1775e 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -92,6 +92,7 @@ See also: @ref GL::Renderer::setPatchDefaultOuterLevel() as the last missing bits for @gl_extension{ARB,tessellation_shader} / @gl_extension{EXT,tessellation_shader} support (see [mosra/magnum#164](https://github.com/mosra/magnum/issues/164)) +- Implemented @ref GL::PipelineStatisticsQuery from GL 4.6 - Recognizing @gl_extension{AMD,shader_explicit_vertex_parameter} desktop and @gl_extension{NV,fragment_shader_barycentric} desktop / ES extensions. These add only shading language features. diff --git a/doc/opengl-support.dox b/doc/opengl-support.dox index 50e5ccba8..626a7bd6c 100644 --- a/doc/opengl-support.dox +++ b/doc/opengl-support.dox @@ -267,7 +267,7 @@ GLSL 4.60 | done @gl_extension{ARB,indirect_parameters} | | @gl_extension{ARB,shader_draw_parameters} | done (shading language only) @gl_extension{ARB,shader_group_vote} | done (shading language only) -@gl_extension{ARB,pipeline_statistics_query} | | +@gl_extension{ARB,pipeline_statistics_query} | done @gl_extension{ARB,transform_feedback_overflow_query} | done @gl_extension{ARB,shader_atomic_counter_ops} | done (shading language only) @gl_extension{ARB,gl_spirv} | | diff --git a/src/Magnum/GL/AbstractQuery.cpp b/src/Magnum/GL/AbstractQuery.cpp index 2ff831238..537746225 100644 --- a/src/Magnum/GL/AbstractQuery.cpp +++ b/src/Magnum/GL/AbstractQuery.cpp @@ -71,6 +71,23 @@ void AbstractQuery::createImplementationDSAExceptXfbOverflow() { else createImplementationDSA(); } + +void AbstractQuery::createImplementationDSAExceptPipelineStats() { + if(_target == GL_VERTICES_SUBMITTED || + _target == GL_PRIMITIVES_SUBMITTED || + _target == GL_VERTEX_SHADER_INVOCATIONS || + _target == GL_TESS_CONTROL_SHADER_PATCHES || + _target == GL_TESS_EVALUATION_SHADER_INVOCATIONS || + _target == GL_GEOMETRY_SHADER_INVOCATIONS || + _target == GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED || + _target == GL_FRAGMENT_SHADER_INVOCATIONS || + _target == GL_COMPUTE_SHADER_INVOCATIONS || + _target == GL_CLIPPING_INPUT_PRIMITIVES || + _target == GL_CLIPPING_OUTPUT_PRIMITIVES) + createImplementationDefault(); + else + createImplementationDSA(); +} #endif #ifndef MAGNUM_TARGET_WEBGL diff --git a/src/Magnum/GL/AbstractQuery.h b/src/Magnum/GL/AbstractQuery.h index 8eff1b608..9185d17cb 100644 --- a/src/Magnum/GL/AbstractQuery.h +++ b/src/Magnum/GL/AbstractQuery.h @@ -44,8 +44,8 @@ namespace Implementation { struct QueryState; } /** @brief Base class for queries -See @ref PrimitiveQuery, @ref SampleQuery and @ref TimeQuery documentation for -more information. +See @ref PipelineStatisticsQuery, @ref PrimitiveQuery, @ref SampleQuery and +@ref TimeQuery documentation for more information. @todo `QUERY_COUNTER_BITS` (not sure since when this is supported) */ class MAGNUM_GL_EXPORT AbstractQuery: public AbstractObject { @@ -191,6 +191,7 @@ class MAGNUM_GL_EXPORT AbstractQuery: public AbstractObject { #ifndef MAGNUM_TARGET_GLES void MAGNUM_GL_LOCAL createImplementationDSA(); void MAGNUM_GL_LOCAL createImplementationDSAExceptXfbOverflow(); + void MAGNUM_GL_LOCAL createImplementationDSAExceptPipelineStats(); #endif ObjectFlags _flags; diff --git a/src/Magnum/GL/CMakeLists.txt b/src/Magnum/GL/CMakeLists.txt index c412fe9de..9c2a74cfa 100644 --- a/src/Magnum/GL/CMakeLists.txt +++ b/src/Magnum/GL/CMakeLists.txt @@ -109,7 +109,9 @@ set(MagnumGL_PRIVATE_HEADERS # Desktop-only stuff if(NOT TARGET_GLES) list(APPEND MagnumGL_SRCS RectangleTexture.cpp) - list(APPEND MagnumGL_HEADERS RectangleTexture.h) + list(APPEND MagnumGL_HEADERS + PipelineStatisticsQuery.h + RectangleTexture.h) endif() # OpenGL ES 3.0 and WebGL 2.0 stuff diff --git a/src/Magnum/GL/GL.h b/src/Magnum/GL/GL.h index b1051b422..e652cd633 100644 --- a/src/Magnum/GL/GL.h +++ b/src/Magnum/GL/GL.h @@ -109,6 +109,9 @@ enum class CompressedPixelFormat: GLenum; /* ObjectFlag, ObjectFlags are used only in conjunction with *::wrap() function */ +#ifndef MAGNUM_TARGET_GLES +class PipelineStatisticsQuery; +#endif #ifndef MAGNUM_TARGET_GLES2 class PrimitiveQuery; #endif diff --git a/src/Magnum/GL/Implementation/QueryState.cpp b/src/Magnum/GL/Implementation/QueryState.cpp index 2660b0f82..db50da706 100644 --- a/src/Magnum/GL/Implementation/QueryState.cpp +++ b/src/Magnum/GL/Implementation/QueryState.cpp @@ -43,7 +43,10 @@ QueryState::QueryState(Context& context, std::vector& extensions) { createImplementation = &AbstractQuery::createImplementationDSAExceptXfbOverflow; } else #endif - { + if((context.detectedDriver() & Context::DetectedDriver::Mesa) && !context.isDriverWorkaroundDisabled("mesa-dsa-createquery-except-pipeline-stats")) { + extensions.emplace_back(Extensions::ARB::direct_state_access::string()); + createImplementation = &AbstractQuery::createImplementationDSAExceptPipelineStats; + } else { extensions.emplace_back(Extensions::ARB::direct_state_access::string()); createImplementation = &AbstractQuery::createImplementationDSA; } diff --git a/src/Magnum/GL/Implementation/driverSpecific.cpp b/src/Magnum/GL/Implementation/driverSpecific.cpp index 03c7dde19..86376d10b 100644 --- a/src/Magnum/GL/Implementation/driverSpecific.cpp +++ b/src/Magnum/GL/Implementation/driverSpecific.cpp @@ -90,7 +90,7 @@ namespace { /* AMD Windows glCreateQueries() works for everything except GL_TRANSFORM_FEEDBACK_[STREAM_]OVERFLOW, probably they just forgot to adapt it to this new GL 4.6 addition. Calling the non-DSA code path in that case - instead. */ + instead. Similar to "mesa-dsa-createquery-except-pipeline-stats". */ "amd-windows-dsa-createquery-except-xfb-overflow", #endif @@ -108,6 +108,12 @@ namespace { #endif #ifndef MAGNUM_TARGET_GLES +/* Mesa glCreateQueries() works for everything except stuff from GL 4.6 + ARB_pipeline_statistics_query, probably just forgotten. Calling the non-DSA + code path in that case instead. Similar to + "amd-windows-dsa-createquery-except-xfb-overflow". */ +"mesa-dsa-createquery-except-pipeline-stats", + /* Forward-compatible GL contexts on Mesa still report line width range as [1, 7], but setting wide line width fails. According to the specs the max value on forward compatible contexts should be 1.0, so patching it. */ diff --git a/src/Magnum/GL/PipelineStatisticsQuery.h b/src/Magnum/GL/PipelineStatisticsQuery.h new file mode 100644 index 000000000..4eb967ce0 --- /dev/null +++ b/src/Magnum/GL/PipelineStatisticsQuery.h @@ -0,0 +1,186 @@ +#ifndef Magnum_GL_PipelineStatisticsQuery_h +#define Magnum_GL_PipelineStatisticsQuery_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#ifndef MAGNUM_TARGET_GLES +/** @file + * @brief Class @ref Magnum::GL::PipelineStatisticsQuery + * @m_since_latest + */ +#endif + +#include "Magnum/GL/AbstractQuery.h" + +#ifndef MAGNUM_TARGET_GLES +namespace Magnum { namespace GL { + +/** +@brief Pipeline statistics query +@m_since_latest + +Provides various data about the rendering pipeline, useful for profiling and +performance measurements. +@requires_gl46 Extension @gl_extension{ARB,pipeline_statistics_query} +@requires_gl Pipeline statistics queries are not available in OpenGL ES and + WebGL. +@see @ref PrimitiveQuery, @ref SampleQuery, @ref TimeQuery +*/ +class PipelineStatisticsQuery: public AbstractQuery { + public: + /** + * @brief Query target + * + * @m_enum_values_as_keywords + */ + enum class Target: GLenum { + /** + * Count of vertices submitted to the primitive assembler. Note + * that this doesn't take index buffer or strips/fans into account. + */ + VerticesSubmitted = GL_VERTICES_SUBMITTED, + + /** Count of primitives submitted to the primitive assembler. */ + PrimitivesSubmitted = GL_PRIMITIVES_SUBMITTED, + + /** + * Count of vertex shader invocations. For indexed draws this is + * usually less than @ref Target::VerticesSubmitted, depending on + * how well is the post-transform vertex cache used. + */ + VertexShaderInvocations = GL_VERTEX_SHADER_INVOCATIONS, + + /** + * Count of patches processed by tessellation control shader stage. + */ + TessellationControlShaderPatches = GL_TESS_CONTROL_SHADER_PATCHES, + + /** Count of tessellation evaluation shader invocations. */ + TessellationEvaluationShaderInvocations = GL_TESS_EVALUATION_SHADER_INVOCATIONS, + + /** Count of geometry shader invocations. */ + GeometryShaderInvocations = GL_GEOMETRY_SHADER_INVOCATIONS, + + /** + * Count of primitives emitted by a geometry shader. Compared to + * @ref PrimitiveQuery::Target::PrimitivesGenerated, the query + * considers all vertex streams and implementation may not count + * primitives that aren't processed further. + */ + GeometryShaderPrimitivesEmitted = GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED, + + /** Count of fragment shader invocations. */ + FragmentShaderInvocations = GL_FRAGMENT_SHADER_INVOCATIONS, + + /** Count of compute shader invocations. */ + ComputeShaderInvocations = GL_COMPUTE_SHADER_INVOCATIONS, + + /** Count of primitives that entered the clipping stage. */ + ClippingInputPrimitives = GL_CLIPPING_INPUT_PRIMITIVES, + + /** + * Count of primitives that passed the clipping stage. In an ideal + * case of CPU-side frustum culling, the value reported by this + * query is the same as @ref Target::ClippingInputPrimitives. + */ + ClippingOutputPrimitives = GL_CLIPPING_OUTPUT_PRIMITIVES + }; + + /** + * @brief Wrap existing OpenGL time query object + * @param id OpenGL time query ID + * @param target Query target + * @param flags Object creation flags + * + * The @p id is expected to be of an existing OpenGL query object. + * Unlike query created using constructor, the OpenGL object is by + * default not deleted on destruction, use @p flags for different + * behavior. + * @see @ref release() + */ + static PipelineStatisticsQuery wrap(GLuint id, Target target, ObjectFlags flags = {}) { + return PipelineStatisticsQuery{id, target, flags}; + } + + /** + * @brief Constructor + * + * Creates new OpenGL query object. If @gl_extension{ARB,direct_state_access} + * (part of OpenGL 4.5) is not available, the query is created on first + * use. + * @see @ref PipelineStatisticsQuery(NoCreateT), @ref wrap(), @fn_gl_keyword{CreateQueries}, + * eventually @fn_gl_keyword{GenQueries} + */ + explicit PipelineStatisticsQuery(Target target): AbstractQuery(GLenum(target)) {} + + /** + * @brief Construct without creating the underlying OpenGL object + * + * The constructed instance is equivalent to moved-from state. Useful + * in cases where you will overwrite the instance later anyway. Move + * another object over it to make it useful. + * + * This function can be safely used for constructing (and later + * destructing) objects even without any OpenGL context being active. + * However note that this is a low-level and a potentially dangerous + * API, see the documentation of @ref NoCreate for alternatives. + * @see @ref PipelineStatisticsQuery(Target), @ref wrap() + */ + explicit PipelineStatisticsQuery(NoCreateT) noexcept: AbstractQuery{NoCreate, GLenum(Target::VerticesSubmitted)} {} + + /** @brief Copying is not allowed */ + PipelineStatisticsQuery(const PipelineStatisticsQuery&) = delete; + + /** @brief Move constructor */ + PipelineStatisticsQuery(PipelineStatisticsQuery&&) noexcept = default; + + /** @brief Copying is not allowed */ + PipelineStatisticsQuery& operator=(const PipelineStatisticsQuery&) = delete; + + /** @brief Move assignment */ + PipelineStatisticsQuery& operator=(PipelineStatisticsQuery&&) noexcept = default; + + /* Overloads to remove WTF-factor from method chaining order */ + #if !defined(DOXYGEN_GENERATING_OUTPUT) && !defined(MAGNUM_TARGET_WEBGL) + PipelineStatisticsQuery& setLabel(const std::string& label) { + AbstractQuery::setLabel(label); + return *this; + } + template PipelineStatisticsQuery& setLabel(const char(&label)[size]) { + AbstractQuery::setLabel(label); + return *this; + } + #endif + + private: + explicit PipelineStatisticsQuery(GLuint id, Target target, ObjectFlags flags) noexcept: AbstractQuery{id, GLenum(target), flags} {} +}; + +}} +#else +#error this header is not available in OpenGL ES build +#endif + +#endif diff --git a/src/Magnum/GL/PrimitiveQuery.h b/src/Magnum/GL/PrimitiveQuery.h index 85cd79368..7e952fbee 100644 --- a/src/Magnum/GL/PrimitiveQuery.h +++ b/src/Magnum/GL/PrimitiveQuery.h @@ -44,7 +44,8 @@ transform feedback. Example usage: @snippet MagnumGL.cpp PrimitiveQuery-usage -@see @ref SampleQuery, @ref TimeQuery, @ref TransformFeedback +@see @ref PipelineStatisticsQuery, @ref SampleQuery, @ref TimeQuery, + @ref TransformFeedback @requires_gl30 Extension @gl_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. diff --git a/src/Magnum/GL/SampleQuery.h b/src/Magnum/GL/SampleQuery.h index 412b99bb4..e4152e7d0 100644 --- a/src/Magnum/GL/SampleQuery.h +++ b/src/Magnum/GL/SampleQuery.h @@ -53,7 +53,7 @@ waiting for the result. @snippet MagnumGL.cpp SampleQuery-conditional-render -@see @ref PrimitiveQuery, @ref TimeQuery +@see @ref PipelineStatisticsQuery, @ref PrimitiveQuery, @ref TimeQuery @requires_gles30 Extension @gl_extension{EXT,occlusion_query_boolean} in OpenGL ES 2.0. @requires_webgl20 Queries are not available in WebGL 1.0. diff --git a/src/Magnum/GL/Test/CMakeLists.txt b/src/Magnum/GL/Test/CMakeLists.txt index 1dface78d..e78bf03bd 100644 --- a/src/Magnum/GL/Test/CMakeLists.txt +++ b/src/Magnum/GL/Test/CMakeLists.txt @@ -96,8 +96,12 @@ if(NOT (MAGNUM_TARGET_WEBGL AND MAGNUM_TARGET_GLES2)) endif() if(NOT MAGNUM_TARGET_GLES) + corrade_add_test(GLPipelineStatisticsQueryTest PipelineStatisticsQueryTest.cpp LIBRARIES MagnumGL) corrade_add_test(GLRectangleTextureTest RectangleTextureTest.cpp LIBRARIES MagnumGL) - set_target_properties(GLRectangleTextureTest PROPERTIES FOLDER "Magnum/GL/Test") + set_target_properties( + GLPipelineStatisticsQueryTest + GLRectangleTextureTest + PROPERTIES FOLDER "Magnum/GL/Test") endif() if(BUILD_GL_TESTS) @@ -237,8 +241,12 @@ if(BUILD_GL_TESTS) endif() if(NOT MAGNUM_TARGET_GLES) + corrade_add_test(GLPipelineStatisticsQueryGLTest PipelineStatisticsQueryGLTest.cpp LIBRARIES MagnumOpenGLTester) corrade_add_test(GLRectangleTextureGLTest RectangleTextureGLTest.cpp LIBRARIES MagnumOpenGLTester) - set_target_properties(GLRectangleTextureGLTest PROPERTIES FOLDER "Magnum/GL/Test") + set_target_properties( + GLPipelineStatisticsQueryGLTest + GLRectangleTextureGLTest + PROPERTIES FOLDER "Magnum/GL/Test") endif() if(MAGNUM_BUILD_STATIC AND NOT CORRADE_TARGET_EMSCRIPTEN AND NOT CORRADE_TARGET_IOS AND NOT CORRADE_TARGET_ANDROID AND NOT CORRADE_TARGET_WINDOWS_RT) diff --git a/src/Magnum/GL/Test/PipelineStatisticsQueryGLTest.cpp b/src/Magnum/GL/Test/PipelineStatisticsQueryGLTest.cpp new file mode 100644 index 000000000..5788d96c1 --- /dev/null +++ b/src/Magnum/GL/Test/PipelineStatisticsQueryGLTest.cpp @@ -0,0 +1,144 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include + +#include "Magnum/GL/AbstractShaderProgram.h" +#include "Magnum/GL/Buffer.h" +#include "Magnum/GL/Context.h" +#include "Magnum/GL/Extensions.h" +#include "Magnum/GL/Framebuffer.h" +#include "Magnum/GL/Mesh.h" +#include "Magnum/GL/OpenGLTester.h" +#include "Magnum/GL/PipelineStatisticsQuery.h" +#include "Magnum/GL/Renderbuffer.h" +#include "Magnum/GL/RenderbufferFormat.h" +#include "Magnum/GL/Shader.h" + +namespace Magnum { namespace GL { namespace Test { namespace { + +struct PipelineStatisticsQueryGLTest: OpenGLTester { + explicit PipelineStatisticsQueryGLTest(); + + void wrap(); + + void queryVerticesSubmitted(); +}; + +PipelineStatisticsQueryGLTest::PipelineStatisticsQueryGLTest() { + addTests({&PipelineStatisticsQueryGLTest::wrap, + + &PipelineStatisticsQueryGLTest::queryVerticesSubmitted}); +} + +void PipelineStatisticsQueryGLTest::wrap() { + if(!Context::current().isExtensionSupported()) + CORRADE_SKIP(Extensions::ARB::pipeline_statistics_query::string() + std::string(" is not available")); + + GLuint id; + glGenQueries(1, &id); + + /* Releasing won't delete anything */ + { + auto query = PipelineStatisticsQuery::wrap(id, PipelineStatisticsQuery::Target::ClippingInputPrimitives, ObjectFlag::DeleteOnDestruction); + CORRADE_COMPARE(query.release(), id); + } + + /* ...so we can wrap it again */ + PipelineStatisticsQuery::wrap(id, PipelineStatisticsQuery::Target::ClippingInputPrimitives); + glDeleteQueries(1, &id); +} + +void PipelineStatisticsQueryGLTest::queryVerticesSubmitted() { + if(!Context::current().isExtensionSupported()) + CORRADE_SKIP(Extensions::ARB::pipeline_statistics_query::string() + std::string(" is not available")); + + /* 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 { + typedef Attribute<0, Vector2> Position; + + explicit MyShader() { + Shader vert( + #ifdef CORRADE_TARGET_APPLE + Version::GL310 + #else + Version::GL210 + #endif + , Shader::Type::Vertex); + + CORRADE_INTERNAL_ASSERT_OUTPUT(vert.addSource( + "#if __VERSION__ >= 130\n" + "#define attribute in\n" + "#endif\n" + "attribute vec4 position;\n" + "void main() {\n" + " gl_Position = position;\n" + "}\n").compile()); + + attachShader(vert); + bindAttributeLocation(Position::Location, "position"); + CORRADE_INTERNAL_ASSERT_OUTPUT(link()); + } + } shader; + + Buffer vertices; + vertices.setData({nullptr, 9*sizeof(Vector2)}, BufferUsage::StaticDraw); + + Mesh mesh; + mesh.setPrimitive(MeshPrimitive::Triangles) + .setCount(9) + .addVertexBuffer(vertices, 0, MyShader::Position()); + + MAGNUM_VERIFY_NO_GL_ERROR(); + + PipelineStatisticsQuery q{PipelineStatisticsQuery::Target::VerticesSubmitted}; + q.begin(); + + Renderer::enable(Renderer::Feature::RasterizerDiscard); + shader.draw(mesh); + + q.end(); + const bool availableBefore = q.resultAvailable(); + const UnsignedInt count = q.result(); + const bool availableAfter = q.resultAvailable(); + + MAGNUM_VERIFY_NO_GL_ERROR(); + { + CORRADE_EXPECT_FAIL_IF(availableBefore, "GPU faster than light?"); + CORRADE_VERIFY(!availableBefore); + } + CORRADE_VERIFY(availableAfter); + CORRADE_COMPARE(count, 9); +} + +}}}} + +CORRADE_TEST_MAIN(Magnum::GL::Test::PipelineStatisticsQueryGLTest) diff --git a/src/Magnum/GL/Test/PipelineStatisticsQueryTest.cpp b/src/Magnum/GL/Test/PipelineStatisticsQueryTest.cpp new file mode 100644 index 000000000..7b2bf90b2 --- /dev/null +++ b/src/Magnum/GL/Test/PipelineStatisticsQueryTest.cpp @@ -0,0 +1,60 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include + +#include "Magnum/GL/PipelineStatisticsQuery.h" + +namespace Magnum { namespace GL { namespace Test { namespace { + +struct PipelineStatisticsQueryTest: TestSuite::Tester { + explicit PipelineStatisticsQueryTest(); + + void constructNoCreate(); + void constructCopy(); +}; + +PipelineStatisticsQueryTest::PipelineStatisticsQueryTest() { + addTests({&PipelineStatisticsQueryTest::constructNoCreate, + &PipelineStatisticsQueryTest::constructCopy}); +} + +void PipelineStatisticsQueryTest::constructNoCreate() { + { + PipelineStatisticsQuery query{NoCreate}; + CORRADE_COMPARE(query.id(), 0); + } + + CORRADE_VERIFY(true); +} + +void PipelineStatisticsQueryTest::constructCopy() { + CORRADE_VERIFY(!(std::is_constructible{})); + CORRADE_VERIFY(!(std::is_assignable{})); +} + +}}}} + +CORRADE_TEST_MAIN(Magnum::GL::Test::PipelineStatisticsQueryTest) diff --git a/src/Magnum/GL/TimeQuery.h b/src/Magnum/GL/TimeQuery.h index ae868f836..f6fe4e65f 100644 --- a/src/Magnum/GL/TimeQuery.h +++ b/src/Magnum/GL/TimeQuery.h @@ -51,8 +51,7 @@ times are reported in nanoseconds. @requires_es_extension Extension @gl_extension{EXT,disjoint_timer_query} @requires_webgl_extension Extension @webgl_extension{EXT,disjoint_timer_query} on WebGL 1, @gl_extension{EXT,disjoint_timer_query_webgl2} on WebGL 2 - -@see @ref PrimitiveQuery, @ref SampleQuery +@see @ref PipelineStatisticsQuery, @ref PrimitiveQuery, @ref SampleQuery @todo timestamp with glGet + example usage @todo @gl_extension{EXT,disjoint_timer_query} --- GL_GPU_DISJOINT_EXT support? where? */