#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>
#include "error.h"
#include "gl.h"
#include "pipelinestate.h"
+#include "query.h"
using namespace std;
}
}
+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
class Batch;
class PipelineState;
+class QueryPool;
class Commands
{
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
--- /dev/null
+#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
--- /dev/null
+#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
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)
class Mesh;
class Lighting;
class Program;
+class QueryPool;
class Renderable;
class Sampler;
class Texture;
void resolve_multisample(Framebuffer &);
+ void begin_query(const QueryPool &, unsigned);
+ void end_query(const QueryPool &, unsigned);
+
private:
void apply_state();
};