Merge pull request #2092 from Sonicadvance1/gles_occlusion_queries
Implement full occlusion queries for the Nexus 9.
This commit is contained in:
commit
70977fd6b1
|
@ -776,6 +776,15 @@ PFNGLPUSHDEBUGGROUPPROC glPushDebugGroup;
|
||||||
PFNGLBUFFERSTORAGEPROC glBufferStorage;
|
PFNGLBUFFERSTORAGEPROC glBufferStorage;
|
||||||
PFNGLNAMEDBUFFERSTORAGEEXTPROC glNamedBufferStorageEXT;
|
PFNGLNAMEDBUFFERSTORAGEEXTPROC glNamedBufferStorageEXT;
|
||||||
|
|
||||||
|
// GL_NV_occlusion_query_samples
|
||||||
|
PFNGLGENOCCLUSIONQUERIESNVPROC glGenOcclusionQueriesNV;
|
||||||
|
PFNGLDELETEOCCLUSIONQUERIESNVPROC glDeleteOcclusionQueriesNV;
|
||||||
|
PFNGLISOCCLUSIONQUERYNVPROC glIsOcclusionQueryNV;
|
||||||
|
PFNGLBEGINOCCLUSIONQUERYNVPROC glBeginOcclusionQueryNV;
|
||||||
|
PFNGLENDOCCLUSIONQUERYNVPROC glEndOcclusionQueryNV;
|
||||||
|
PFNGLGETOCCLUSIONQUERYIVNVPROC glGetOcclusionQueryivNV;
|
||||||
|
PFNGLGETOCCLUSIONQUERYUIVNVPROC glGetOcclusionQueryuivNV;
|
||||||
|
|
||||||
// Creates a GLFunc object that requires a feature
|
// Creates a GLFunc object that requires a feature
|
||||||
#define GLFUNC_REQUIRES(x, y) { (void**)&x, #x, y }
|
#define GLFUNC_REQUIRES(x, y) { (void**)&x, #x, y }
|
||||||
// Creates a GLFunc object with a different function suffix
|
// Creates a GLFunc object with a different function suffix
|
||||||
|
@ -1254,6 +1263,15 @@ const GLFunc gl_function_array[] =
|
||||||
// EXT_geometry_shader
|
// EXT_geometry_shader
|
||||||
GLFUNC_SUFFIX(glFramebufferTexture, EXT, "GL_EXT_geometry_shader !VERSION_3_2"),
|
GLFUNC_SUFFIX(glFramebufferTexture, EXT, "GL_EXT_geometry_shader !VERSION_3_2"),
|
||||||
|
|
||||||
|
// NV_occlusion_query_samples
|
||||||
|
GLFUNC_REQUIRES(glGenOcclusionQueriesNV, "GL_NV_occlusion_query_samples"),
|
||||||
|
GLFUNC_REQUIRES(glDeleteOcclusionQueriesNV, "GL_NV_occlusion_query_samples"),
|
||||||
|
GLFUNC_REQUIRES(glIsOcclusionQueryNV, "GL_NV_occlusion_query_samples"),
|
||||||
|
GLFUNC_REQUIRES(glBeginOcclusionQueryNV, "GL_NV_occlusion_query_samples"),
|
||||||
|
GLFUNC_REQUIRES(glEndOcclusionQueryNV, "GL_NV_occlusion_query_samples"),
|
||||||
|
GLFUNC_REQUIRES(glGetOcclusionQueryivNV, "GL_NV_occlusion_query_samples"),
|
||||||
|
GLFUNC_REQUIRES(glGetOcclusionQueryuivNV, "GL_NV_occlusion_query_samples"),
|
||||||
|
|
||||||
// gl_1_1
|
// gl_1_1
|
||||||
// OpenGL 1.1 is at the end due to a bug in Android's EGL stack.
|
// OpenGL 1.1 is at the end due to a bug in Android's EGL stack.
|
||||||
// eglGetProcAddress can only return a finite amount of function pointers
|
// eglGetProcAddress can only return a finite amount of function pointers
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "VideoBackends/OGL/GLExtensions/gl_3_1.h"
|
#include "VideoBackends/OGL/GLExtensions/gl_3_1.h"
|
||||||
#include "VideoBackends/OGL/GLExtensions/gl_3_2.h"
|
#include "VideoBackends/OGL/GLExtensions/gl_3_2.h"
|
||||||
#include "VideoBackends/OGL/GLExtensions/KHR_debug.h"
|
#include "VideoBackends/OGL/GLExtensions/KHR_debug.h"
|
||||||
|
#include "VideoBackends/OGL/GLExtensions/NV_occlusion_query_samples.h"
|
||||||
#include "VideoBackends/OGL/GLExtensions/NV_primitive_restart.h"
|
#include "VideoBackends/OGL/GLExtensions/NV_primitive_restart.h"
|
||||||
|
|
||||||
namespace GLExtensions
|
namespace GLExtensions
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
// Copyright 2013 Dolphin Emulator Project
|
||||||
|
// Licensed under GPLv2
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include "VideoBackends/OGL/GLExtensions/gl_common.h"
|
||||||
|
|
||||||
|
extern PFNGLGENOCCLUSIONQUERIESNVPROC glGenOcclusionQueriesNV;
|
||||||
|
extern PFNGLDELETEOCCLUSIONQUERIESNVPROC glDeleteOcclusionQueriesNV;
|
||||||
|
extern PFNGLISOCCLUSIONQUERYNVPROC glIsOcclusionQueryNV;
|
||||||
|
extern PFNGLBEGINOCCLUSIONQUERYNVPROC glBeginOcclusionQueryNV;
|
||||||
|
extern PFNGLENDOCCLUSIONQUERYNVPROC glEndOcclusionQueryNV;
|
||||||
|
extern PFNGLGETOCCLUSIONQUERYIVNVPROC glGetOcclusionQueryivNV;
|
||||||
|
extern PFNGLGETOCCLUSIONQUERYUIVNVPROC glGetOcclusionQueryuivNV;
|
|
@ -83,6 +83,7 @@
|
||||||
<ClInclude Include="GLExtensions\gl_3_2.h" />
|
<ClInclude Include="GLExtensions\gl_3_2.h" />
|
||||||
<ClInclude Include="GLExtensions\gl_common.h" />
|
<ClInclude Include="GLExtensions\gl_common.h" />
|
||||||
<ClInclude Include="GLExtensions\KHR_debug.h" />
|
<ClInclude Include="GLExtensions\KHR_debug.h" />
|
||||||
|
<ClInclude Include="GLExtensions\NV_occlusion_query_samples.h" />
|
||||||
<ClInclude Include="GLExtensions\NV_primitive_restart.h" />
|
<ClInclude Include="GLExtensions\NV_primitive_restart.h" />
|
||||||
<ClInclude Include="GLInterface\WGL.h" />
|
<ClInclude Include="GLInterface\WGL.h" />
|
||||||
<ClInclude Include="GLUtil.h" />
|
<ClInclude Include="GLUtil.h" />
|
||||||
|
|
|
@ -187,6 +187,9 @@
|
||||||
<ClInclude Include="GLExtensions\GLExtensions.h">
|
<ClInclude Include="GLExtensions\GLExtensions.h">
|
||||||
<Filter>GLExtensions</Filter>
|
<Filter>GLExtensions</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="GLExtensions\NV_occlusion_query_samples.h">
|
||||||
|
<Filter>GLExtensions</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="GLExtensions\NV_primitive_restart.h">
|
<ClInclude Include="GLExtensions\NV_primitive_restart.h">
|
||||||
<Filter>GLExtensions</Filter>
|
<Filter>GLExtensions</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|
|
@ -9,54 +9,32 @@
|
||||||
|
|
||||||
namespace OGL
|
namespace OGL
|
||||||
{
|
{
|
||||||
|
PerfQueryBase* GetPerfQuery()
|
||||||
|
{
|
||||||
|
if (GLInterface->GetMode() == GLInterfaceMode::MODE_OPENGLES3 &&
|
||||||
|
GLExtensions::Supports("GL_NV_occlusion_query_samples"))
|
||||||
|
return new PerfQueryGLESNV();
|
||||||
|
else if (GLInterface->GetMode() == GLInterfaceMode::MODE_OPENGLES3)
|
||||||
|
return new PerfQueryGL(GL_ANY_SAMPLES_PASSED);
|
||||||
|
else
|
||||||
|
return new PerfQueryGL(GL_SAMPLES_PASSED);
|
||||||
|
}
|
||||||
|
|
||||||
PerfQuery::PerfQuery()
|
PerfQuery::PerfQuery()
|
||||||
: m_query_read_pos()
|
: m_query_read_pos()
|
||||||
, m_query_count()
|
, m_query_count()
|
||||||
{
|
{
|
||||||
for (ActiveQuery& query : m_query_buffer)
|
|
||||||
glGenQueries(1, &query.query_id);
|
|
||||||
|
|
||||||
ResetQuery();
|
ResetQuery();
|
||||||
}
|
}
|
||||||
|
|
||||||
PerfQuery::~PerfQuery()
|
|
||||||
{
|
|
||||||
for (ActiveQuery& query : m_query_buffer)
|
|
||||||
glDeleteQueries(1, &query.query_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PerfQuery::EnableQuery(PerfQueryGroup type)
|
void PerfQuery::EnableQuery(PerfQueryGroup type)
|
||||||
{
|
{
|
||||||
// Is this sane?
|
m_query->EnableQuery(type);
|
||||||
if (m_query_count > m_query_buffer.size() / 2)
|
|
||||||
WeakFlush();
|
|
||||||
|
|
||||||
if (m_query_buffer.size() == m_query_count)
|
|
||||||
{
|
|
||||||
FlushOne();
|
|
||||||
//ERROR_LOG(VIDEO, "Flushed query buffer early!");
|
|
||||||
}
|
|
||||||
|
|
||||||
// start query
|
|
||||||
if (type == PQG_ZCOMP_ZCOMPLOC || type == PQG_ZCOMP)
|
|
||||||
{
|
|
||||||
auto& entry = m_query_buffer[(m_query_read_pos + m_query_count) % m_query_buffer.size()];
|
|
||||||
|
|
||||||
glBeginQuery(GLInterface->GetMode() == GLInterfaceMode::MODE_OPENGL ? GL_SAMPLES_PASSED : GL_ANY_SAMPLES_PASSED, entry.query_id);
|
|
||||||
entry.query_type = type;
|
|
||||||
|
|
||||||
++m_query_count;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PerfQuery::DisableQuery(PerfQueryGroup type)
|
void PerfQuery::DisableQuery(PerfQueryGroup type)
|
||||||
{
|
{
|
||||||
// stop query
|
m_query->DisableQuery(type);
|
||||||
if (type == PQG_ZCOMP_ZCOMPLOC || type == PQG_ZCOMP)
|
|
||||||
{
|
|
||||||
glEndQuery(GLInterface->GetMode() == GLInterfaceMode::MODE_OPENGL ? GL_SAMPLES_PASSED : GL_ANY_SAMPLES_PASSED);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PerfQuery::IsFlushed() const
|
bool PerfQuery::IsFlushed() const
|
||||||
|
@ -64,45 +42,10 @@ bool PerfQuery::IsFlushed() const
|
||||||
return 0 == m_query_count;
|
return 0 == m_query_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PerfQuery::FlushOne()
|
|
||||||
{
|
|
||||||
auto& entry = m_query_buffer[m_query_read_pos];
|
|
||||||
|
|
||||||
GLuint result = 0;
|
|
||||||
glGetQueryObjectuiv(entry.query_id, GL_QUERY_RESULT, &result);
|
|
||||||
|
|
||||||
// NOTE: Reported pixel metrics should be referenced to native resolution
|
|
||||||
m_results[entry.query_type] += (u64)result * EFB_WIDTH / g_renderer->GetTargetWidth() * EFB_HEIGHT / g_renderer->GetTargetHeight();
|
|
||||||
|
|
||||||
m_query_read_pos = (m_query_read_pos + 1) % m_query_buffer.size();
|
|
||||||
--m_query_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: could selectively flush things, but I don't think that will do much
|
// TODO: could selectively flush things, but I don't think that will do much
|
||||||
void PerfQuery::FlushResults()
|
void PerfQuery::FlushResults()
|
||||||
{
|
{
|
||||||
while (!IsFlushed())
|
m_query->FlushResults();
|
||||||
FlushOne();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PerfQuery::WeakFlush()
|
|
||||||
{
|
|
||||||
while (!IsFlushed())
|
|
||||||
{
|
|
||||||
auto& entry = m_query_buffer[m_query_read_pos];
|
|
||||||
|
|
||||||
GLuint result = GL_FALSE;
|
|
||||||
glGetQueryObjectuiv(entry.query_id, GL_QUERY_RESULT_AVAILABLE, &result);
|
|
||||||
|
|
||||||
if (GL_TRUE == result)
|
|
||||||
{
|
|
||||||
FlushOne();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PerfQuery::ResetQuery()
|
void PerfQuery::ResetQuery()
|
||||||
|
@ -135,4 +78,176 @@ u32 PerfQuery::GetQueryResult(PerfQueryType type)
|
||||||
return result / 4;
|
return result / 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Implementations
|
||||||
|
PerfQueryGL::PerfQueryGL(GLenum query_type)
|
||||||
|
: m_query_type(query_type)
|
||||||
|
{
|
||||||
|
for (ActiveQuery& query : m_query_buffer)
|
||||||
|
glGenQueries(1, &query.query_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
PerfQueryGL::~PerfQueryGL()
|
||||||
|
{
|
||||||
|
for (ActiveQuery& query : m_query_buffer)
|
||||||
|
glDeleteQueries(1, &query.query_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PerfQueryGL::EnableQuery(PerfQueryGroup type)
|
||||||
|
{
|
||||||
|
// Is this sane?
|
||||||
|
if (m_query_count > m_query_buffer.size() / 2)
|
||||||
|
WeakFlush();
|
||||||
|
|
||||||
|
if (m_query_buffer.size() == m_query_count)
|
||||||
|
{
|
||||||
|
FlushOne();
|
||||||
|
//ERROR_LOG(VIDEO, "Flushed query buffer early!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// start query
|
||||||
|
if (type == PQG_ZCOMP_ZCOMPLOC || type == PQG_ZCOMP)
|
||||||
|
{
|
||||||
|
auto& entry = m_query_buffer[(m_query_read_pos + m_query_count) % m_query_buffer.size()];
|
||||||
|
|
||||||
|
glBeginQuery(m_query_type, entry.query_id);
|
||||||
|
entry.query_type = type;
|
||||||
|
|
||||||
|
++m_query_count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void PerfQueryGL::DisableQuery(PerfQueryGroup type)
|
||||||
|
{
|
||||||
|
// stop query
|
||||||
|
if (type == PQG_ZCOMP_ZCOMPLOC || type == PQG_ZCOMP)
|
||||||
|
{
|
||||||
|
glEndQuery(m_query_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PerfQueryGL::WeakFlush()
|
||||||
|
{
|
||||||
|
while (!IsFlushed())
|
||||||
|
{
|
||||||
|
auto& entry = m_query_buffer[m_query_read_pos];
|
||||||
|
|
||||||
|
GLuint result = GL_FALSE;
|
||||||
|
glGetQueryObjectuiv(entry.query_id, GL_QUERY_RESULT_AVAILABLE, &result);
|
||||||
|
|
||||||
|
if (GL_TRUE == result)
|
||||||
|
{
|
||||||
|
FlushOne();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PerfQueryGL::FlushOne()
|
||||||
|
{
|
||||||
|
auto& entry = m_query_buffer[m_query_read_pos];
|
||||||
|
|
||||||
|
GLuint result = 0;
|
||||||
|
glGetQueryObjectuiv(entry.query_id, GL_QUERY_RESULT, &result);
|
||||||
|
|
||||||
|
// NOTE: Reported pixel metrics should be referenced to native resolution
|
||||||
|
m_results[entry.query_type] += (u64)result * EFB_WIDTH / g_renderer->GetTargetWidth() * EFB_HEIGHT / g_renderer->GetTargetHeight();
|
||||||
|
|
||||||
|
m_query_read_pos = (m_query_read_pos + 1) % m_query_buffer.size();
|
||||||
|
--m_query_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: could selectively flush things, but I don't think that will do much
|
||||||
|
void PerfQueryGL::FlushResults()
|
||||||
|
{
|
||||||
|
while (!IsFlushed())
|
||||||
|
FlushOne();
|
||||||
|
}
|
||||||
|
|
||||||
|
PerfQueryGLESNV::PerfQueryGLESNV()
|
||||||
|
{
|
||||||
|
for (ActiveQuery& query : m_query_buffer)
|
||||||
|
glGenOcclusionQueriesNV(1, &query.query_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
PerfQueryGLESNV::~PerfQueryGLESNV()
|
||||||
|
{
|
||||||
|
for (ActiveQuery& query : m_query_buffer)
|
||||||
|
glDeleteOcclusionQueriesNV(1, &query.query_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PerfQueryGLESNV::EnableQuery(PerfQueryGroup type)
|
||||||
|
{
|
||||||
|
// Is this sane?
|
||||||
|
if (m_query_count > m_query_buffer.size() / 2)
|
||||||
|
WeakFlush();
|
||||||
|
|
||||||
|
if (m_query_buffer.size() == m_query_count)
|
||||||
|
{
|
||||||
|
FlushOne();
|
||||||
|
//ERROR_LOG(VIDEO, "Flushed query buffer early!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// start query
|
||||||
|
if (type == PQG_ZCOMP_ZCOMPLOC || type == PQG_ZCOMP)
|
||||||
|
{
|
||||||
|
auto& entry = m_query_buffer[(m_query_read_pos + m_query_count) % m_query_buffer.size()];
|
||||||
|
|
||||||
|
glBeginOcclusionQueryNV(entry.query_id);
|
||||||
|
entry.query_type = type;
|
||||||
|
|
||||||
|
++m_query_count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void PerfQueryGLESNV::DisableQuery(PerfQueryGroup type)
|
||||||
|
{
|
||||||
|
// stop query
|
||||||
|
if (type == PQG_ZCOMP_ZCOMPLOC || type == PQG_ZCOMP)
|
||||||
|
{
|
||||||
|
glEndOcclusionQueryNV();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PerfQueryGLESNV::WeakFlush()
|
||||||
|
{
|
||||||
|
while (!IsFlushed())
|
||||||
|
{
|
||||||
|
auto& entry = m_query_buffer[m_query_read_pos];
|
||||||
|
|
||||||
|
GLuint result = GL_FALSE;
|
||||||
|
glGetOcclusionQueryuivNV(entry.query_id, GL_PIXEL_COUNT_AVAILABLE_NV, &result);
|
||||||
|
|
||||||
|
if (GL_TRUE == result)
|
||||||
|
{
|
||||||
|
FlushOne();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PerfQueryGLESNV::FlushOne()
|
||||||
|
{
|
||||||
|
auto& entry = m_query_buffer[m_query_read_pos];
|
||||||
|
|
||||||
|
GLuint result = 0;
|
||||||
|
glGetOcclusionQueryuivNV(entry.query_id, GL_OCCLUSION_TEST_RESULT_HP, &result);
|
||||||
|
|
||||||
|
// NOTE: Reported pixel metrics should be referenced to native resolution
|
||||||
|
m_results[entry.query_type] += (u64)result * EFB_WIDTH / g_renderer->GetTargetWidth() * EFB_HEIGHT / g_renderer->GetTargetHeight();
|
||||||
|
|
||||||
|
m_query_read_pos = (m_query_read_pos + 1) % m_query_buffer.size();
|
||||||
|
--m_query_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: could selectively flush things, but I don't think that will do much
|
||||||
|
void PerfQueryGLESNV::FlushResults()
|
||||||
|
{
|
||||||
|
while (!IsFlushed())
|
||||||
|
FlushOne();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -1,18 +1,20 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include "VideoBackends/OGL/GLExtensions/GLExtensions.h"
|
#include "VideoBackends/OGL/GLExtensions/GLExtensions.h"
|
||||||
#include "VideoCommon/PerfQueryBase.h"
|
#include "VideoCommon/PerfQueryBase.h"
|
||||||
|
|
||||||
namespace OGL
|
namespace OGL
|
||||||
{
|
{
|
||||||
|
PerfQueryBase* GetPerfQuery();
|
||||||
|
|
||||||
class PerfQuery : public PerfQueryBase
|
class PerfQuery : public PerfQueryBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PerfQuery();
|
PerfQuery();
|
||||||
~PerfQuery();
|
~PerfQuery() {}
|
||||||
|
|
||||||
void EnableQuery(PerfQueryGroup type) override;
|
void EnableQuery(PerfQueryGroup type) override;
|
||||||
void DisableQuery(PerfQueryGroup type) override;
|
void DisableQuery(PerfQueryGroup type) override;
|
||||||
|
@ -21,7 +23,7 @@ public:
|
||||||
void FlushResults() override;
|
void FlushResults() override;
|
||||||
bool IsFlushed() const override;
|
bool IsFlushed() const override;
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
struct ActiveQuery
|
struct ActiveQuery
|
||||||
{
|
{
|
||||||
GLuint query_id;
|
GLuint query_id;
|
||||||
|
@ -31,10 +33,6 @@ private:
|
||||||
// when testing in SMS: 64 was too small, 128 was ok
|
// when testing in SMS: 64 was too small, 128 was ok
|
||||||
static const u32 PERF_QUERY_BUFFER_SIZE = 512;
|
static const u32 PERF_QUERY_BUFFER_SIZE = 512;
|
||||||
|
|
||||||
void WeakFlush();
|
|
||||||
// Only use when non-empty
|
|
||||||
void FlushOne();
|
|
||||||
|
|
||||||
// This contains gl query objects with unretrieved results.
|
// This contains gl query objects with unretrieved results.
|
||||||
std::array<ActiveQuery, PERF_QUERY_BUFFER_SIZE> m_query_buffer;
|
std::array<ActiveQuery, PERF_QUERY_BUFFER_SIZE> m_query_buffer;
|
||||||
u32 m_query_read_pos;
|
u32 m_query_read_pos;
|
||||||
|
@ -42,6 +40,48 @@ private:
|
||||||
// TODO: sloppy
|
// TODO: sloppy
|
||||||
volatile u32 m_query_count;
|
volatile u32 m_query_count;
|
||||||
volatile u32 m_results[PQG_NUM_MEMBERS];
|
volatile u32 m_results[PQG_NUM_MEMBERS];
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Implementation
|
||||||
|
std::unique_ptr<PerfQuery> m_query;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Implementations
|
||||||
|
class PerfQueryGL : public PerfQuery
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PerfQueryGL(GLenum query_type);
|
||||||
|
~PerfQueryGL();
|
||||||
|
|
||||||
|
void EnableQuery(PerfQueryGroup type) override;
|
||||||
|
void DisableQuery(PerfQueryGroup type) override;
|
||||||
|
void FlushResults() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void WeakFlush();
|
||||||
|
// Only use when non-empty
|
||||||
|
void FlushOne();
|
||||||
|
|
||||||
|
GLenum m_query_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
class PerfQueryGLESNV : public PerfQuery
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PerfQueryGLESNV();
|
||||||
|
~PerfQueryGLESNV();
|
||||||
|
|
||||||
|
void EnableQuery(PerfQueryGroup type) override;
|
||||||
|
void DisableQuery(PerfQueryGroup type) override;
|
||||||
|
void FlushResults() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
void WeakFlush();
|
||||||
|
// Only use when non-empty
|
||||||
|
void FlushOne();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -196,7 +196,7 @@ void VideoBackend::Video_Prepare()
|
||||||
|
|
||||||
BPInit();
|
BPInit();
|
||||||
g_vertex_manager = new VertexManager;
|
g_vertex_manager = new VertexManager;
|
||||||
g_perf_query = new PerfQuery;
|
g_perf_query = GetPerfQuery();
|
||||||
Fifo_Init(); // must be done before OpcodeDecoder_Init()
|
Fifo_Init(); // must be done before OpcodeDecoder_Init()
|
||||||
OpcodeDecoder_Init();
|
OpcodeDecoder_Init();
|
||||||
IndexGenerator::Init();
|
IndexGenerator::Init();
|
||||||
|
|
Loading…
Reference in New Issue