mirror of https://github.com/PCSX2/pcsx2.git
gsdx ogl: add GPU timers to measure time between 2 vsync
So far only basic stuff (min/mean/max frame rendering time)
This commit is contained in:
parent
79587215bb
commit
d7c1faf563
|
@ -100,6 +100,8 @@ PFNGLQUERYCOUNTERPROC glQueryCounter = NUL
|
||||||
PFNGLGETQUERYOBJECTI64VPROC glGetQueryObjecti64v = NULL;
|
PFNGLGETQUERYOBJECTI64VPROC glGetQueryObjecti64v = NULL;
|
||||||
PFNGLGETQUERYOBJECTUI64VPROC glGetQueryObjectui64v = NULL;
|
PFNGLGETQUERYOBJECTUI64VPROC glGetQueryObjectui64v = NULL;
|
||||||
PFNGLGETINTEGER64VPROC glGetInteger64v = NULL;
|
PFNGLGETINTEGER64VPROC glGetInteger64v = NULL;
|
||||||
|
PFNGLCREATEQUERIESPROC glCreateQueries = NULL;
|
||||||
|
PFNGLDELETEQUERIESPROC glDeleteQueries = NULL;
|
||||||
// GL4.0
|
// GL4.0
|
||||||
// GL4.1
|
// GL4.1
|
||||||
PFNGLBINDPROGRAMPIPELINEPROC glBindProgramPipeline = NULL;
|
PFNGLBINDPROGRAMPIPELINEPROC glBindProgramPipeline = NULL;
|
||||||
|
|
|
@ -268,6 +268,8 @@ extern PFNGLQUERYCOUNTERPROC glQueryCounter;
|
||||||
extern PFNGLGETQUERYOBJECTI64VPROC glGetQueryObjecti64v;
|
extern PFNGLGETQUERYOBJECTI64VPROC glGetQueryObjecti64v;
|
||||||
extern PFNGLGETQUERYOBJECTUI64VPROC glGetQueryObjectui64v;
|
extern PFNGLGETQUERYOBJECTUI64VPROC glGetQueryObjectui64v;
|
||||||
extern PFNGLGETINTEGER64VPROC glGetInteger64v;
|
extern PFNGLGETINTEGER64VPROC glGetInteger64v;
|
||||||
|
extern PFNGLCREATEQUERIESPROC glCreateQueries;
|
||||||
|
extern PFNGLDELETEQUERIESPROC glDeleteQueries;
|
||||||
// GL4.0
|
// GL4.0
|
||||||
// GL4.1
|
// GL4.1
|
||||||
extern PFNGLBINDPROGRAMPIPELINEPROC glBindProgramPipeline;
|
extern PFNGLBINDPROGRAMPIPELINEPROC glBindProgramPipeline;
|
||||||
|
|
|
@ -1689,7 +1689,9 @@ EXPORT_C GSReplay(char* lpszCmdLine, int renderer)
|
||||||
// Ensure the rendering is complete to measure correctly the time.
|
// Ensure the rendering is complete to measure correctly the time.
|
||||||
glFinish();
|
glFinish();
|
||||||
|
|
||||||
if (finished > 90) {
|
if (finished >= 200) {
|
||||||
|
; // Nop for Nvidia Profiler
|
||||||
|
} else if (finished > 90) {
|
||||||
sleep(1);
|
sleep(1);
|
||||||
} else {
|
} else {
|
||||||
unsigned long end = timeGetTime();
|
unsigned long end = timeGetTime();
|
||||||
|
@ -1724,7 +1726,7 @@ EXPORT_C GSReplay(char* lpszCmdLine, int renderer)
|
||||||
fprintf(stderr, "\n\nMean: %fms\n", mean);
|
fprintf(stderr, "\n\nMean: %fms\n", mean);
|
||||||
fprintf(stderr, "Standard deviation: %fms\n", sd);
|
fprintf(stderr, "Standard deviation: %fms\n", sd);
|
||||||
fprintf(stderr, "Mean by frame: %fms (%ffps)\n", mean/(float)frame_number, 1000.0f*frame_number/mean);
|
fprintf(stderr, "Mean by frame: %fms (%ffps)\n", mean/(float)frame_number, 1000.0f*frame_number/mean);
|
||||||
fprintf(stderr, "Standard deviatin by frame: %fms\n", sd/(float)frame_number);
|
fprintf(stderr, "Standard deviation by frame: %fms\n", sd/(float)frame_number);
|
||||||
}
|
}
|
||||||
#ifdef ENABLE_OGL_DEBUG_MEM_BW
|
#ifdef ENABLE_OGL_DEBUG_MEM_BW
|
||||||
total_frame_nb *= 1024;
|
total_frame_nb *= 1024;
|
||||||
|
@ -1748,4 +1750,3 @@ EXPORT_C GSReplay(char* lpszCmdLine, int renderer)
|
||||||
GSshutdown();
|
GSshutdown();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,7 @@ GSDeviceOGL::GSDeviceOGL()
|
||||||
memset(&m_date, 0, sizeof(m_date));
|
memset(&m_date, 0, sizeof(m_date));
|
||||||
memset(&m_shadeboost, 0, sizeof(m_shadeboost));
|
memset(&m_shadeboost, 0, sizeof(m_shadeboost));
|
||||||
memset(&m_om_dss, 0, sizeof(m_om_dss));
|
memset(&m_om_dss, 0, sizeof(m_om_dss));
|
||||||
|
memset(&m_profiler, 0 , sizeof(m_profiler));
|
||||||
GLState::Clear();
|
GLState::Clear();
|
||||||
|
|
||||||
// Reset the debug file
|
// Reset the debug file
|
||||||
|
@ -94,6 +95,10 @@ GSDeviceOGL::~GSDeviceOGL()
|
||||||
|
|
||||||
GL_PUSH("GSDeviceOGL destructor");
|
GL_PUSH("GSDeviceOGL destructor");
|
||||||
|
|
||||||
|
if (GLLoader::in_replayer) {
|
||||||
|
GenerateProfilerData();
|
||||||
|
}
|
||||||
|
|
||||||
// Clean vertex buffer state
|
// Clean vertex buffer state
|
||||||
delete m_va;
|
delete m_va;
|
||||||
|
|
||||||
|
@ -139,6 +144,51 @@ GSDeviceOGL::~GSDeviceOGL()
|
||||||
m_shader = NULL;
|
m_shader = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GSDeviceOGL::GenerateProfilerData()
|
||||||
|
{
|
||||||
|
if (m_profiler.last_query < 3) return;
|
||||||
|
|
||||||
|
// Point to the last query
|
||||||
|
m_profiler.last_query--;
|
||||||
|
|
||||||
|
// Wait latest quey to get valid result
|
||||||
|
GLuint available = 0;
|
||||||
|
while (!available) {
|
||||||
|
glGetQueryObjectuiv(m_profiler.timer(), GL_QUERY_RESULT_AVAILABLE, &available);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64 time_start;
|
||||||
|
uint64 time_end;
|
||||||
|
|
||||||
|
uint64 min_time = 0xFFFFFFFFFFFFFFFFull;
|
||||||
|
uint64 max_time = 0;
|
||||||
|
uint64 total = 0;
|
||||||
|
|
||||||
|
glGetQueryObjectui64v(m_profiler.timer_query[0], GL_QUERY_RESULT, &time_start);
|
||||||
|
for (uint32 q = 1; q < m_profiler.last_query; q++) {
|
||||||
|
glGetQueryObjectui64v(m_profiler.timer_query[q], GL_QUERY_RESULT, &time_end);
|
||||||
|
uint64 t = time_end - time_start;
|
||||||
|
|
||||||
|
min_time = std::min(t, min_time);
|
||||||
|
max_time = std::max(t, max_time);
|
||||||
|
total += t;
|
||||||
|
|
||||||
|
time_start = time_end;
|
||||||
|
}
|
||||||
|
|
||||||
|
glDeleteQueries(1 << 16, m_profiler.timer_query);
|
||||||
|
|
||||||
|
// FIXME remove 1/linux_replay frame info
|
||||||
|
// Add fps, deviation
|
||||||
|
// remove glFinish
|
||||||
|
|
||||||
|
double ms = 0.000001;
|
||||||
|
fprintf(stderr, "\nGenerateProfilerData:\n");
|
||||||
|
fprintf(stderr, "Min %f\n", (double)min_time * ms);
|
||||||
|
fprintf(stderr, "Mean %f\n", (double)total/(double)m_profiler.last_query * ms);
|
||||||
|
fprintf(stderr, "Max %f\n", (double)max_time * ms);
|
||||||
|
}
|
||||||
|
|
||||||
GSTexture* GSDeviceOGL::CreateSurface(int type, int w, int h, bool msaa, int fmt)
|
GSTexture* GSDeviceOGL::CreateSurface(int type, int w, int h, bool msaa, int fmt)
|
||||||
{
|
{
|
||||||
GL_PUSH("Create surface");
|
GL_PUSH("Create surface");
|
||||||
|
@ -248,6 +298,11 @@ bool GSDeviceOGL::Create(GSWnd* wnd)
|
||||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo_read);
|
glBindFramebuffer(GL_READ_FRAMEBUFFER, m_fbo_read);
|
||||||
glReadBuffer(GL_COLOR_ATTACHMENT0);
|
glReadBuffer(GL_COLOR_ATTACHMENT0);
|
||||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
||||||
|
|
||||||
|
// Some timers to help profiling
|
||||||
|
if (GLLoader::in_replayer) {
|
||||||
|
glCreateQueries(GL_TIMESTAMP, 1 << 16, m_profiler.timer_query);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ****************************************************************
|
// ****************************************************************
|
||||||
|
@ -504,6 +559,11 @@ void GSDeviceOGL::Flip()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_wnd->Flip();
|
m_wnd->Flip();
|
||||||
|
|
||||||
|
if (GLLoader::in_replayer) {
|
||||||
|
glQueryCounter(m_profiler.timer(), GL_TIMESTAMP);
|
||||||
|
m_profiler.last_query++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GSDeviceOGL::BeforeDraw()
|
void GSDeviceOGL::BeforeDraw()
|
||||||
|
|
|
@ -449,6 +449,13 @@ public:
|
||||||
GLuint ps;
|
GLuint ps;
|
||||||
} m_shadeboost;
|
} m_shadeboost;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
uint16 last_query;
|
||||||
|
GLuint timer_query[1<<16];
|
||||||
|
|
||||||
|
GLuint timer() { return timer_query[last_query]; }
|
||||||
|
} m_profiler;
|
||||||
|
|
||||||
GLuint m_vs[1];
|
GLuint m_vs[1];
|
||||||
GLuint m_gs[1<<2];
|
GLuint m_gs[1<<2];
|
||||||
GLuint m_ps_ss[1<<4];
|
GLuint m_ps_ss[1<<4];
|
||||||
|
@ -484,6 +491,8 @@ public:
|
||||||
GSDeviceOGL();
|
GSDeviceOGL();
|
||||||
virtual ~GSDeviceOGL();
|
virtual ~GSDeviceOGL();
|
||||||
|
|
||||||
|
void GenerateProfilerData();
|
||||||
|
|
||||||
static void CheckDebugLog();
|
static void CheckDebugLog();
|
||||||
// Used by OpenGL, so the same calling convention is required.
|
// Used by OpenGL, so the same calling convention is required.
|
||||||
static void APIENTRY DebugOutputToFile(GLenum gl_source, GLenum gl_type, GLuint id, GLenum gl_severity, GLsizei gl_length, const GLchar *gl_message, const void* userParam);
|
static void APIENTRY DebugOutputToFile(GLenum gl_source, GLenum gl_type, GLuint id, GLenum gl_severity, GLsizei gl_length, const GLchar *gl_message, const void* userParam);
|
||||||
|
@ -555,7 +564,6 @@ public:
|
||||||
void SelfShaderTestRun(const string& dir, const string& file, const PSSelector& sel, int& nb_shader);
|
void SelfShaderTestRun(const string& dir, const string& file, const PSSelector& sel, int& nb_shader);
|
||||||
void SelfShaderTest();
|
void SelfShaderTest();
|
||||||
|
|
||||||
|
|
||||||
void SetupIA(const void* vertex, int vertex_count, const uint32* index, int index_count, int prim);
|
void SetupIA(const void* vertex, int vertex_count, const uint32* index, int index_count, int prim);
|
||||||
void SetupPipeline(const VSSelector& vsel, const GSSelector& gsel, const PSSelector& psel);
|
void SetupPipeline(const VSSelector& vsel, const GSSelector& gsel, const PSSelector& psel);
|
||||||
void SetupCB(const VSConstantBuffer* vs_cb, const PSConstantBuffer* ps_cb);
|
void SetupCB(const VSConstantBuffer* vs_cb, const PSConstantBuffer* ps_cb);
|
||||||
|
|
|
@ -84,15 +84,17 @@ void GSWndGL::PopulateGlFunction()
|
||||||
GL_EXT_LOAD(glClientWaitSync);
|
GL_EXT_LOAD(glClientWaitSync);
|
||||||
GL_EXT_LOAD(glFlushMappedBufferRange);
|
GL_EXT_LOAD(glFlushMappedBufferRange);
|
||||||
// Query object
|
// Query object
|
||||||
GL_EXT_LOAD(glBeginQuery);
|
GL_EXT_LOAD_OPT(glBeginQuery);
|
||||||
GL_EXT_LOAD(glEndQuery);
|
GL_EXT_LOAD_OPT(glEndQuery);
|
||||||
GL_EXT_LOAD(glGetQueryiv);
|
GL_EXT_LOAD_OPT(glGetQueryiv);
|
||||||
GL_EXT_LOAD(glGetQueryObjectiv);
|
GL_EXT_LOAD_OPT(glGetQueryObjectiv);
|
||||||
GL_EXT_LOAD(glGetQueryObjectuiv);
|
GL_EXT_LOAD_OPT(glGetQueryObjectuiv);
|
||||||
GL_EXT_LOAD(glQueryCounter);
|
GL_EXT_LOAD_OPT(glQueryCounter);
|
||||||
GL_EXT_LOAD(glGetQueryObjecti64v);
|
GL_EXT_LOAD_OPT(glGetQueryObjecti64v);
|
||||||
GL_EXT_LOAD(glGetQueryObjectui64v);
|
GL_EXT_LOAD_OPT(glGetQueryObjectui64v);
|
||||||
GL_EXT_LOAD(glGetInteger64v);
|
GL_EXT_LOAD_OPT(glGetInteger64v);
|
||||||
|
GL_EXT_LOAD_OPT(glCreateQueries);
|
||||||
|
GL_EXT_LOAD_OPT(glDeleteQueries);
|
||||||
// GL4.0
|
// GL4.0
|
||||||
GL_EXT_LOAD_OPT(glBlendEquationSeparateiARB);
|
GL_EXT_LOAD_OPT(glBlendEquationSeparateiARB);
|
||||||
GL_EXT_LOAD_OPT(glBlendFuncSeparateiARB);
|
GL_EXT_LOAD_OPT(glBlendFuncSeparateiARB);
|
||||||
|
|
Loading…
Reference in New Issue