From 052b85720688900bc36f8844a94269cb1c0cdd52 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Fri, 1 Oct 2021 12:51:31 +0300 Subject: [PATCH] Add an abstraction for queries --- source/core/commands.cpp | 14 ++++++++ source/core/commands.h | 4 +++ source/core/query.cpp | 73 ++++++++++++++++++++++++++++++++++++++ source/core/query.h | 54 ++++++++++++++++++++++++++++ source/render/renderer.cpp | 10 ++++++ source/render/renderer.h | 4 +++ 6 files changed, 159 insertions(+) create mode 100644 source/core/query.cpp create mode 100644 source/core/query.h diff --git a/source/core/commands.cpp b/source/core/commands.cpp index 19ff1011..a0a4336a 100644 --- a/source/core/commands.cpp +++ b/source/core/commands.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -9,6 +10,7 @@ #include "error.h" #include "gl.h" #include "pipelinestate.h" +#include "query.h" using namespace std; @@ -107,5 +109,17 @@ void Commands::resolve_multisample(Framebuffer &target) } } +void Commands::begin_query(const QueryPool &pool, unsigned index) +{ + if(index>=pool.queries.size()) + throw out_of_range("OpenGLCommands::begin_query"); + glBeginQuery(pool.gl_type, pool.queries[index]); +} + +void Commands::end_query(const QueryPool &pool, unsigned) +{ + glEndQuery(pool.gl_type); +} + } // namespace GL } // namespace Msp diff --git a/source/core/commands.h b/source/core/commands.h index ca10f784..d290e34e 100644 --- a/source/core/commands.h +++ b/source/core/commands.h @@ -8,6 +8,7 @@ namespace GL { class Batch; class PipelineState; +class QueryPool; class Commands { @@ -22,6 +23,9 @@ public: void draw(const Batch &); void draw_instanced(const Batch &, unsigned); void resolve_multisample(Framebuffer &); + + void begin_query(const QueryPool &, unsigned); + void end_query(const QueryPool &, unsigned); }; } // namespace GL diff --git a/source/core/query.cpp b/source/core/query.cpp new file mode 100644 index 00000000..a6d77eda --- /dev/null +++ b/source/core/query.cpp @@ -0,0 +1,73 @@ +#include +#include +#include +#include "query.h" +#include "renderer.h" + +using namespace std; + +namespace Msp { +namespace GL { + +QueryPool::QueryPool(QueryType t, unsigned s): + type(t), + gl_type(get_gl_query_type(type)) +{ + if(type==OCCLUSION_QUERY) + { + static Require req(ARB_occlusion_query); + static Require req2(ARB_occlusion_query2); + } + + resize(s); +} + +QueryPool::~QueryPool() +{ + glDeleteQueries(queries.size(), queries.data()); +} + +void QueryPool::resize(unsigned s) +{ + if(sold_size) + glGenQueries(s-old_size, queries.data()+old_size); +} + +unsigned QueryPool::get_result(unsigned i) const +{ + unsigned result = 0; + glGetQueryObjectuiv(queries[i], GL_QUERY_RESULT, &result); + return result; +} + + +QueryPool::Activate::Activate(Renderer &r, const QueryPool &p, unsigned i): + renderer(r), + pool(p), + index(i) +{ + renderer.begin_query(pool, index); +} + +QueryPool::Activate::~Activate() +{ + renderer.end_query(pool, index); +} + + +unsigned get_gl_query_type(QueryType t) +{ + switch(t) + { + case OCCLUSION_QUERY: return GL_ANY_SAMPLES_PASSED; + default: throw invalid_argument("get_gl_query_type"); + } +} + +} // namespace GL +} // namespace Msp diff --git a/source/core/query.h b/source/core/query.h new file mode 100644 index 00000000..aaa993e3 --- /dev/null +++ b/source/core/query.h @@ -0,0 +1,54 @@ +#ifndef MSP_GL_QUERY_H_ +#define MSP_GL_QUERY_H_ + +#include +#include + +namespace Msp { +namespace GL { + +class Renderer; + +enum QueryType +{ + OCCLUSION_QUERY +}; + +class QueryPool: public Msp::NonCopyable +{ + friend class Commands; + +public: + class Activate + { + private: + Renderer &renderer; + const QueryPool &pool; + unsigned index; + + public: + Activate(Renderer &, const QueryPool &, unsigned); + ~Activate(); + }; + +private: + QueryType type; + unsigned gl_type; + std::vector queries; + +public: + QueryPool(QueryType type, unsigned); + ~QueryPool(); + + void resize(unsigned); + unsigned get_size() const { return queries.size(); } + + unsigned get_result(unsigned) const; +}; + +unsigned get_gl_query_type(QueryType); + +} // namespace Msp +} // namespace GL + +#endif diff --git a/source/render/renderer.cpp b/source/render/renderer.cpp index 19148a4d..1d729200 100644 --- a/source/render/renderer.cpp +++ b/source/render/renderer.cpp @@ -280,6 +280,16 @@ void Renderer::resolve_multisample(Framebuffer &target) commands.resolve_multisample(target); } +void Renderer::begin_query(const QueryPool &pool, unsigned index) +{ + commands.begin_query(pool, index); +} + +void Renderer::end_query(const QueryPool &pool, unsigned index) +{ + commands.end_query(pool, index); +} + void Renderer::apply_state() { if(!state->shprog) diff --git a/source/render/renderer.h b/source/render/renderer.h index 5139c4ce..3e0e50d8 100644 --- a/source/render/renderer.h +++ b/source/render/renderer.h @@ -21,6 +21,7 @@ class Material; class Mesh; class Lighting; class Program; +class QueryPool; class Renderable; class Sampler; class Texture; @@ -203,6 +204,9 @@ public: void resolve_multisample(Framebuffer &); + void begin_query(const QueryPool &, unsigned); + void end_query(const QueryPool &, unsigned); + private: void apply_state(); }; -- 2.45.2