]> git.tdb.fi Git - libs/gl.git/commitdiff
Add an abstraction for queries
authorMikko Rasa <tdb@tdb.fi>
Fri, 1 Oct 2021 09:51:31 +0000 (12:51 +0300)
committerMikko Rasa <tdb@tdb.fi>
Fri, 1 Oct 2021 10:54:03 +0000 (13:54 +0300)
source/core/commands.cpp
source/core/commands.h
source/core/query.cpp [new file with mode: 0644]
source/core/query.h [new file with mode: 0644]
source/render/renderer.cpp
source/render/renderer.h

index 19ff10115e53e10faf612220c2daf3f4697f841e..a0a4336ade77c6951a1fd511e884e7f6e9dd0f7c 100644 (file)
@@ -1,6 +1,7 @@
 #include <algorithm>
 #include <msp/gl/extensions/arb_direct_state_access.h>
 #include <msp/gl/extensions/arb_draw_instanced.h>
+#include <msp/gl/extensions/arb_occlusion_query.h>
 #include <msp/gl/extensions/ext_framebuffer_blit.h>
 #include <msp/gl/extensions/ext_framebuffer_object.h>
 #include <msp/gl/extensions/msp_clear_buffer.h>
@@ -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
index ca10f7845b78a54dd588f60c37c0fc3d7c958f55..d290e34ecdfe8a5a4f4f14d4ec7fb51136c85402 100644 (file)
@@ -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 (file)
index 0000000..a6d77ed
--- /dev/null
@@ -0,0 +1,73 @@
+#include <stdexcept>
+#include <msp/gl/extensions/arb_occlusion_query.h>
+#include <msp/gl/extensions/arb_occlusion_query2.h>
+#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(s<queries.size())
+               glDeleteQueries(queries.size()-s, queries.data()+s);
+
+       unsigned old_size = queries.size();
+       queries.resize(s);
+       if(s>old_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 (file)
index 0000000..aaa993e
--- /dev/null
@@ -0,0 +1,54 @@
+#ifndef MSP_GL_QUERY_H_
+#define MSP_GL_QUERY_H_
+
+#include <vector>
+#include <msp/core/noncopyable.h>
+
+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<unsigned> 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
index 19148a4dbf5a4f9bf1c9743481336ecf80297bb3..1d729200dc8909e78d875911942718c930a30ba0 100644 (file)
@@ -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)
index 5139c4ce925fd978d8136e6b5655f6ddfd4087d2..3e0e50d83d80290a08642b81b978cc3048152c35 100644 (file)
@@ -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();
 };