From 9c1142d507efa2d6c455c40c767c62aa7432a984 Mon Sep 17 00:00:00 2001 From: rt Date: Sat, 16 Feb 2019 03:37:33 +0100 Subject: [PATCH] add gl.{S,G}etTimerQuery --- rts/Game/Game.cpp | 4 +-- rts/Game/UI/ProfileDrawer.cpp | 2 +- rts/Lua/LuaOpenGL.cpp | 53 ++++++++++++++++++++++++++----- rts/Lua/LuaOpenGL.h | 16 +++++++--- rts/Rendering/GlobalRendering.cpp | 12 +++---- rts/Rendering/GlobalRendering.h | 7 ++-- 6 files changed, 70 insertions(+), 24 deletions(-) diff --git a/rts/Game/Game.cpp b/rts/Game/Game.cpp index 156b6c50472..ca9e2687b9f 100644 --- a/rts/Game/Game.cpp +++ b/rts/Game/Game.cpp @@ -1226,7 +1226,7 @@ bool CGame::Draw() { const spring_time currentTimePreDraw = spring_gettime(); SCOPED_SPECIAL_TIMER("Draw"); - globalRendering->SetGLTimeStamp(0); + globalRendering->SetGLTimeStamp(CGlobalRendering::FRAME_REF_TIME_QUERY_IDX); SetDrawMode(Game::NormalDraw); @@ -1327,7 +1327,7 @@ bool CGame::Draw() { gu->avgDrawFrameTime = mix(gu->avgDrawFrameTime, currentFrameDrawTime.toMilliSecsf(), 0.05f); eventHandler.DbgTimingInfo(TIMING_VIDEO, currentTimePreDraw, currentTimePostDraw); - globalRendering->SetGLTimeStamp(CGlobalRendering::FRAME_TIME_QUERY_IDX); + globalRendering->SetGLTimeStamp(CGlobalRendering::FRAME_END_TIME_QUERY_IDX); return true; } diff --git a/rts/Game/UI/ProfileDrawer.cpp b/rts/Game/UI/ProfileDrawer.cpp index 692664b5d5f..cdda8946cfc 100644 --- a/rts/Game/UI/ProfileDrawer.cpp +++ b/rts/Game/UI/ProfileDrawer.cpp @@ -391,7 +391,7 @@ static void DrawInfoText(GL::RenderDataBufferC* buffer) (gu->avgSimFrameTime > 16) ? "\xff\xff\x01\x01" : "", gu->avgSimFrameTime, (gu->avgFrameTime > 30) ? "\xff\xff\x01\x01" : "", gu->avgFrameTime, (gu->avgDrawFrameTime > 16) ? "\xff\xff\x01\x01" : "", gu->avgDrawFrameTime, - (globalRendering->CalcGLDeltaTime(0, CGlobalRendering::FRAME_TIME_QUERY_IDX) * 0.001f) * 0.001f + (globalRendering->CalcGLDeltaTime(CGlobalRendering::FRAME_REF_TIME_QUERY_IDX, CGlobalRendering::FRAME_END_TIME_QUERY_IDX) * 0.001f) * 0.001f ); font->glFormat(0.01f, 0.08f, 0.5f, DBG_FONT_FLAGS | FONT_BUFFERED, spdFmtStr, gs->speedFactor, gs->wantedSpeedFactor); diff --git a/rts/Lua/LuaOpenGL.cpp b/rts/Lua/LuaOpenGL.cpp index 875a2240e1e..6599e812511 100644 --- a/rts/Lua/LuaOpenGL.cpp +++ b/rts/Lua/LuaOpenGL.cpp @@ -342,6 +342,9 @@ bool LuaOpenGL::PushEntries(lua_State* L) REGISTER_LUA_CFUNC(RunQuery); REGISTER_LUA_CFUNC(GetQuery); + REGISTER_LUA_CFUNC(SetTimerQuery); + REGISTER_LUA_CFUNC(GetTimerQuery); + REGISTER_LUA_CFUNC(GetShadowMapParams); REGISTER_LUA_CFUNC(GetAtmosphere); @@ -3502,7 +3505,7 @@ int LuaOpenGL::SaveImage(lua_State* L) /******************************************************************************/ -int LuaOpenGL::CreateQuery(lua_State* L) +int LuaOpenGL::CreateOcclusionQuery(lua_State* L) { GLuint id; glGenQueries(1, &id); @@ -3522,13 +3525,13 @@ int LuaOpenGL::CreateQuery(lua_State* L) return 1; } -int LuaOpenGL::DeleteQuery(lua_State* L) +int LuaOpenGL::DeleteOcclusionQuery(lua_State* L) { if (lua_isnil(L, 1)) return 0; if (!lua_islightuserdata(L, 1)) - luaL_error(L, "gl.DeleteQuery(q) expects a userdata query"); + luaL_error(L, "gl.DeleteOcclusionQuery(q) expects a userdata query"); const OcclusionQuery* qry = static_cast(lua_touserdata(L, 1)); @@ -3545,7 +3548,7 @@ int LuaOpenGL::DeleteQuery(lua_State* L) return 0; } -int LuaOpenGL::RunQuery(lua_State* L) +int LuaOpenGL::RunOcclusionQuery(lua_State* L) { static bool running = false; @@ -3563,7 +3566,7 @@ int LuaOpenGL::RunQuery(lua_State* L) return 0; if (!lua_isfunction(L, 2)) - luaL_error(L, "gl.RunQuery(q,f) expects a function"); + luaL_error(L, "gl.RunOcclusionQuery(q,f) expects a function"); const int args = lua_gettop(L); // number of arguments @@ -3574,17 +3577,17 @@ int LuaOpenGL::RunQuery(lua_State* L) running = false; if (error != 0) { - LOG_L(L_ERROR, "gl.RunQuery: error(%i) = %s", error, lua_tostring(L, -1)); + LOG_L(L_ERROR, "gl.RunOcclusionQuery: error(%i) = %s", error, lua_tostring(L, -1)); lua_error(L); } return 0; } -int LuaOpenGL::GetQuery(lua_State* L) +int LuaOpenGL::GetOcclusionQuery(lua_State* L) { if (!lua_islightuserdata(L, 1)) - luaL_error(L, "gl.GetQuery(q) expects a userdata query"); + luaL_error(L, "gl.GetOcclusionQuery(q) expects a userdata query"); const OcclusionQuery* qry = static_cast(lua_touserdata(L, 1)); @@ -3601,6 +3604,40 @@ int LuaOpenGL::GetQuery(lua_State* L) } +int LuaOpenGL::SetTimerQuery(lua_State* L) +{ + const uint32_t qi = luaL_checkinteger(L, 1); + + // FRAME_REF and FRAME_END are reserved timestamps + if (qi <= CGlobalRendering::FRAME_REF_TIME_QUERY_IDX) + return 0; + if (qi >= CGlobalRendering::FRAME_END_TIME_QUERY_IDX) + return 0; + + globalRendering->SetGLTimeStamp(qi); + return 0; +} + +int LuaOpenGL::GetTimerQuery(lua_State* L) +{ + const uint32_t qi = luaL_checkinteger(L, 1); + const uint32_t qj = luaL_checkinteger(L, 2); + + if (std::min(qi, qj) <= CGlobalRendering::FRAME_REF_TIME_QUERY_IDX) + return 0; + if (std::max(qi, qj) >= CGlobalRendering::FRAME_END_TIME_QUERY_IDX) + return 0; + + const uint64_t dt = globalRendering->CalcGLDeltaTime(std::min(qi, qj), std::max(qi, qj)); + const uint32_t lo = (dt >> 0u) & 0xFFFFFFFFu; + const uint32_t hi = (dt >> 32u) & 0xFFFFFFFFu; + + lua_pushnumber(L, lo * 1.0f); + lua_pushnumber(L, hi * 1.0f); + return 2; +} + + /******************************************************************************/ int LuaOpenGL::GetShadowMapParams(lua_State* L) diff --git a/rts/Lua/LuaOpenGL.h b/rts/Lua/LuaOpenGL.h index e1516f736b1..0afe12ca328 100644 --- a/rts/Lua/LuaOpenGL.h +++ b/rts/Lua/LuaOpenGL.h @@ -308,10 +308,18 @@ class LuaOpenGL { static int ReadPixels(lua_State* L); static int SaveImage(lua_State* L); - static int CreateQuery(lua_State* L); - static int DeleteQuery(lua_State* L); - static int RunQuery(lua_State* L); - static int GetQuery(lua_State* L); + // occlusion queries + static int CreateQuery(lua_State* L) { return (CreateOcclusionQuery(L)); } + static int DeleteQuery(lua_State* L) { return (DeleteOcclusionQuery(L)); } + static int RunQuery(lua_State* L) { return (RunOcclusionQuery(L)); } + static int GetQuery(lua_State* L) { return (GetOcclusionQuery(L)); } + static int CreateOcclusionQuery(lua_State* L); + static int DeleteOcclusionQuery(lua_State* L); + static int RunOcclusionQuery(lua_State* L); + static int GetOcclusionQuery(lua_State* L); + // timer queries + static int SetTimerQuery(lua_State* L); + static int GetTimerQuery(lua_State* L); static int GetShadowMapParams(lua_State* L); diff --git a/rts/Rendering/GlobalRendering.cpp b/rts/Rendering/GlobalRendering.cpp index 5bf662559fb..3325e353623 100644 --- a/rts/Rendering/GlobalRendering.cpp +++ b/rts/Rendering/GlobalRendering.cpp @@ -254,7 +254,7 @@ CGlobalRendering::~CGlobalRendering() // protect against aborted startup if (glContexts[0] != nullptr) { GL::KillRenderBuffers(); - glDeleteQueries(NUM_GL_TIMER_QUERIES * 2, &glTimerQueries[0]); + glDeleteQueries(NUM_OPENGL_TIMER_QUERIES * 2, &glTimerQueries[0]); } DestroyWindowAndContext(sdlWindows[0], glContexts[0]); @@ -557,21 +557,21 @@ void CGlobalRendering::PostInit() { ToggleGLDebugOutput(0, 0, 0); GL::InitRenderBuffers(); - glGenQueries(NUM_GL_TIMER_QUERIES * 2, &glTimerQueries[0]); + glGenQueries(NUM_OPENGL_TIMER_QUERIES * 2, &glTimerQueries[0]); } void CGlobalRendering::SetGLTimeStamp(uint32_t queryIdx) const { - glQueryCounter(glTimerQueries[(NUM_GL_TIMER_QUERIES * (drawFrame & 1)) + queryIdx], GL_TIMESTAMP); + glQueryCounter(glTimerQueries[(NUM_OPENGL_TIMER_QUERIES * (drawFrame & 1)) + queryIdx], GL_TIMESTAMP); } uint64_t CGlobalRendering::CalcGLDeltaTime(uint32_t queryIdx0, uint32_t queryIdx1) const { - const uint32_t queryBase = NUM_GL_TIMER_QUERIES * (1 - (drawFrame & 1)); + const uint32_t queryBase = NUM_OPENGL_TIMER_QUERIES * (1 - (drawFrame & 1)); - assert(queryIdx0 < NUM_GL_TIMER_QUERIES); - assert(queryIdx1 < NUM_GL_TIMER_QUERIES); + assert(queryIdx0 < NUM_OPENGL_TIMER_QUERIES); + assert(queryIdx1 < NUM_OPENGL_TIMER_QUERIES); assert(queryIdx0 < queryIdx1); GLuint64 t0 = 0; diff --git a/rts/Rendering/GlobalRendering.h b/rts/Rendering/GlobalRendering.h index a9199c0955c..4ab258fa20a 100644 --- a/rts/Rendering/GlobalRendering.h +++ b/rts/Rendering/GlobalRendering.h @@ -108,8 +108,9 @@ class CGlobalRendering { static constexpr int MIN_WIN_SIZE_X = 400; static constexpr int MIN_WIN_SIZE_Y = 300; - static constexpr unsigned int NUM_GL_TIMER_QUERIES = 2; - static constexpr unsigned int FRAME_TIME_QUERY_IDX = NUM_GL_TIMER_QUERIES - 1; + static constexpr unsigned int NUM_OPENGL_TIMER_QUERIES = 8; + static constexpr unsigned int FRAME_REF_TIME_QUERY_IDX = 0; + static constexpr unsigned int FRAME_END_TIME_QUERY_IDX = NUM_OPENGL_TIMER_QUERIES - 1; public: /** @@ -307,7 +308,7 @@ class CGlobalRendering { SDL_GLContext glContexts[2]; // double-buffered; results from frame N become available on frame N+1 - unsigned int glTimerQueries[NUM_GL_TIMER_QUERIES * 2]; + unsigned int glTimerQueries[NUM_OPENGL_TIMER_QUERIES * 2]; }; extern CGlobalRendering* globalRendering;