diff --git a/Dev/Cpp/Effekseer/Effekseer/Effekseer.Manager.cpp b/Dev/Cpp/Effekseer/Effekseer/Effekseer.Manager.cpp index 472b7cebd2..ca15256a1e 100644 --- a/Dev/Cpp/Effekseer/Effekseer/Effekseer.Manager.cpp +++ b/Dev/Cpp/Effekseer/Effekseer/Effekseer.Manager.cpp @@ -637,7 +637,17 @@ GpuTimerRef ManagerImplemented::GetGpuTimer() void ManagerImplemented::SetGpuTimer(GpuTimerRef gpuTimer) { + if (m_gpuTimer && m_gpuParticleSystem) + { + m_gpuTimer->RemoveTimer(m_gpuParticleSystem.Get()); + } + m_gpuTimer = gpuTimer; + + if (m_gpuTimer && m_gpuParticleSystem) + { + m_gpuTimer->AddTimer(m_gpuParticleSystem.Get()); + } } GpuParticleSystemRef ManagerImplemented::GetGpuParticleSystem() @@ -647,7 +657,17 @@ GpuParticleSystemRef ManagerImplemented::GetGpuParticleSystem() void ManagerImplemented::SetGpuParticleSystem(GpuParticleSystemRef system) { + if (m_gpuTimer && m_gpuParticleSystem) + { + m_gpuTimer->RemoveTimer(m_gpuParticleSystem.Get()); + } + m_gpuParticleSystem = system; + + if (m_gpuTimer && m_gpuParticleSystem) + { + m_gpuTimer->AddTimer(m_gpuParticleSystem.Get()); + } } GpuParticleFactoryRef ManagerImplemented::GetGpuParticleFactory() @@ -1798,8 +1818,12 @@ void ManagerImplemented::ResetAndPlayWithDataSet(DrawSet& drawSet, float frame) void ManagerImplemented::Compute() { + ScopedGpuStage gpuPass(m_gpuTimer, GpuStage::Compute); + if (auto gpuParticleSystem = GetGpuParticleSystem()) { + ScopedGpuTime gpuTime(m_gpuTimer, gpuParticleSystem.Get()); + for (int i = 0; i < m_nextComputeCount; i++) { gpuParticleSystem->ComputeFrame(); @@ -1821,10 +1845,7 @@ void ManagerImplemented::Draw(const Manager::DrawParameter& drawParameter) // start to record a time int64_t beginTime = ::Effekseer::GetTime(); - if (m_gpuTimer != nullptr) - { - m_gpuTimer->BeginFrame(); - } + ScopedGpuStage gpuPass(m_gpuTimer, GpuStage::Draw); const auto cullingPlanes = GeometryUtility::CalculateFrustumPlanes(drawParameter.ViewProjectionMatrix, drawParameter.ZNear, drawParameter.ZFar, GetSetting()->GetCoordinateSystem()); @@ -1837,8 +1858,7 @@ void ManagerImplemented::Draw(const Manager::DrawParameter& drawParameter) if (drawSet.IsAutoDrawing) { - if (m_gpuTimer != nullptr) - m_gpuTimer->Start(drawSet.GlobalPointer, 0); + ScopedGpuTime gpuTime(m_gpuTimer, drawSet.GlobalPointer); if (drawSet.GlobalPointer->RenderedInstanceContainers.size() > 0) { @@ -1854,9 +1874,6 @@ void ManagerImplemented::Draw(const Manager::DrawParameter& drawParameter) { drawSet.InstanceContainerPointer->Draw(true); } - - if (m_gpuTimer != nullptr) - m_gpuTimer->Stop(drawSet.GlobalPointer, 0); } }; @@ -1879,12 +1896,9 @@ void ManagerImplemented::Draw(const Manager::DrawParameter& drawParameter) if (auto gpuParticleSystem = GetGpuParticleSystem()) { - gpuParticleSystem->RenderFrame(); - } + ScopedGpuTime gpuTime(m_gpuTimer, gpuParticleSystem.Get()); - if (m_gpuTimer != nullptr) - { - m_gpuTimer->EndFrame(); + gpuParticleSystem->RenderFrame(); } // calculate a time @@ -1898,6 +1912,8 @@ void ManagerImplemented::DrawBack(const Manager::DrawParameter& drawParameter) // start to record a time int64_t beginTime = ::Effekseer::GetTime(); + ScopedGpuStage gpuPass(m_gpuTimer, GpuStage::DrawBack); + const auto cullingPlanes = GeometryUtility::CalculateFrustumPlanes(drawParameter.ViewProjectionMatrix, drawParameter.ZNear, drawParameter.ZFar, GetSetting()->GetCoordinateSystem()); const auto render = [this, &drawParameter, &cullingPlanes](DrawSet& drawSet) -> void @@ -1909,8 +1925,7 @@ void ManagerImplemented::DrawBack(const Manager::DrawParameter& drawParameter) if (drawSet.IsAutoDrawing) { - if (m_gpuTimer != nullptr) - m_gpuTimer->Start(drawSet.GlobalPointer, 0); + ScopedGpuTime gpuTime(m_gpuTimer, drawSet.GlobalPointer); auto e = (EffectImplemented*)drawSet.ParameterPointer.Get(); for (int32_t j = 0; j < e->renderingNodesThreshold; j++) @@ -1920,9 +1935,6 @@ void ManagerImplemented::DrawBack(const Manager::DrawParameter& drawParameter) drawSet.GlobalPointer->RenderedInstanceContainers[j]->Draw(false); } - - if (m_gpuTimer != nullptr) - m_gpuTimer->Stop(drawSet.GlobalPointer, 0); } }; @@ -1953,11 +1965,8 @@ void ManagerImplemented::DrawFront(const Manager::DrawParameter& drawParameter) // start to record a time int64_t beginTime = ::Effekseer::GetTime(); - - if (m_gpuTimer != nullptr) - { - m_gpuTimer->BeginFrame(); - } + + ScopedGpuStage gpuPass(m_gpuTimer, GpuStage::DrawFront); const auto cullingPlanes = GeometryUtility::CalculateFrustumPlanes(drawParameter.ViewProjectionMatrix, drawParameter.ZNear, drawParameter.ZFar, GetSetting()->GetCoordinateSystem()); @@ -1970,8 +1979,7 @@ void ManagerImplemented::DrawFront(const Manager::DrawParameter& drawParameter) if (drawSet.IsAutoDrawing) { - if (m_gpuTimer != nullptr) - m_gpuTimer->Start(drawSet.GlobalPointer, 1); + ScopedGpuTime gpuTime(m_gpuTimer, drawSet.GlobalPointer); if (drawSet.GlobalPointer->RenderedInstanceContainers.size() > 0) { @@ -1988,9 +1996,6 @@ void ManagerImplemented::DrawFront(const Manager::DrawParameter& drawParameter) { drawSet.InstanceContainerPointer->Draw(true); } - - if (m_gpuTimer != nullptr) - m_gpuTimer->Stop(drawSet.GlobalPointer, 1); } }; @@ -2013,12 +2018,9 @@ void ManagerImplemented::DrawFront(const Manager::DrawParameter& drawParameter) if (auto gpuParticleSystem = GetGpuParticleSystem()) { - gpuParticleSystem->RenderFrame(); - } + ScopedGpuTime gpuTime(m_gpuTimer, gpuParticleSystem.Get()); - if (m_gpuTimer != nullptr) - { - m_gpuTimer->EndFrame(); + gpuParticleSystem->RenderFrame(); } // calculate a time @@ -2111,9 +2113,6 @@ void ManagerImplemented::DrawHandle(Handle handle, const Manager::DrawParameter& return; } - if (m_gpuTimer != nullptr) - m_gpuTimer->Start(drawSet.GlobalPointer, 0); - if (drawSet.GlobalPointer->RenderedInstanceContainers.size() > 0) { for (auto& c : drawSet.GlobalPointer->RenderedInstanceContainers) @@ -2128,9 +2127,6 @@ void ManagerImplemented::DrawHandle(Handle handle, const Manager::DrawParameter& { drawSet.InstanceContainerPointer->Draw(true); } - - if (m_gpuTimer != nullptr) - m_gpuTimer->Stop(drawSet.GlobalPointer, 0); } } @@ -2156,9 +2152,6 @@ void ManagerImplemented::DrawHandleBack(Handle handle, const Manager::DrawParame return; } - if (m_gpuTimer != nullptr) - m_gpuTimer->Start(drawSet.GlobalPointer, 0); - for (int32_t i = 0; i < e->renderingNodesThreshold; i++) { if (IsClippedWithDepth(drawSet, drawSet.GlobalPointer->RenderedInstanceContainers[i], drawParameter)) @@ -2166,9 +2159,6 @@ void ManagerImplemented::DrawHandleBack(Handle handle, const Manager::DrawParame drawSet.GlobalPointer->RenderedInstanceContainers[i]->Draw(false); } - - if (m_gpuTimer != nullptr) - m_gpuTimer->Stop(drawSet.GlobalPointer, 0); } } @@ -2194,9 +2184,6 @@ void ManagerImplemented::DrawHandleFront(Handle handle, const Manager::DrawParam return; } - if (m_gpuTimer != nullptr) - m_gpuTimer->Start(drawSet.GlobalPointer, 1); - if (drawSet.GlobalPointer->RenderedInstanceContainers.size() > 0) { for (size_t i = e->renderingNodesThreshold; i < drawSet.GlobalPointer->RenderedInstanceContainers.size(); i++) @@ -2211,9 +2198,6 @@ void ManagerImplemented::DrawHandleFront(Handle handle, const Manager::DrawParam { drawSet.InstanceContainerPointer->Draw(true); } - - if (m_gpuTimer != nullptr) - m_gpuTimer->Stop(drawSet.GlobalPointer, 1); } } @@ -2248,6 +2232,11 @@ int32_t ManagerImplemented::GetGpuTime() const { timeCount += m_gpuTimer->GetResult(kv.second.GlobalPointer); } + + if (m_gpuParticleSystem) + { + timeCount += m_gpuTimer->GetResult(m_gpuParticleSystem.Get()); + } return timeCount; } return 0; diff --git a/Dev/Cpp/Effekseer/Effekseer/Renderer/Effekseer.GpuTimer.h b/Dev/Cpp/Effekseer/Effekseer/Renderer/Effekseer.GpuTimer.h index 90a540748f..a32fbd8f86 100644 --- a/Dev/Cpp/Effekseer/Effekseer/Renderer/Effekseer.GpuTimer.h +++ b/Dev/Cpp/Effekseer/Effekseer/Renderer/Effekseer.GpuTimer.h @@ -10,6 +10,15 @@ namespace Effekseer class GpuTimer; using GpuTimerRef = RefPtr; +enum class GpuStage : uint8_t +{ + None, + Compute, + Draw, + DrawBack, + DrawFront, +}; + class GpuTimer : public ReferenceObject { public: @@ -17,21 +26,71 @@ class GpuTimer : public ReferenceObject virtual ~GpuTimer() = default; - virtual void BeginFrame() {} + virtual void BeginStage(GpuStage stage) {} - virtual void EndFrame() {} + virtual void EndStage(GpuStage stage) {} virtual void AddTimer(const void* object) {} virtual void RemoveTimer(const void* object) {} - virtual void Start(const void* object, uint32_t phase) {} + virtual void Start(const void* object) {} - virtual void Stop(const void* object, uint32_t phase) {} + virtual void Stop(const void* object) {} virtual int32_t GetResult(const void* object) { return -1; } }; +class ScopedGpuStage +{ +public: + ScopedGpuStage(GpuTimerRef timer, GpuStage stage) + : m_timer(timer), m_stage(stage) + { + if (m_timer) + { + m_timer->BeginStage(m_stage); + } + } + + ~ScopedGpuStage() + { + if (m_timer) + { + m_timer->EndStage(m_stage); + } + } + +private: + GpuTimerRef m_timer; + GpuStage m_stage; +}; + +class ScopedGpuTime +{ +public: + ScopedGpuTime(GpuTimerRef timer, const void* object) + : m_timer(timer), m_object(object) + { + if (m_timer) + { + m_timer->Start(m_object); + } + } + + ~ScopedGpuTime() + { + if (m_timer) + { + m_timer->Stop(m_object); + } + } + +private: + GpuTimerRef m_timer; + const void* m_object; +}; + } // namespace Effekseer #endif // __EFFEKSEER_GPU_TIMER_H__ diff --git a/Dev/Cpp/EffekseerRendererDX11/EffekseerRendererDX11/EffekseerRendererDX11.GpuTimer.cpp b/Dev/Cpp/EffekseerRendererDX11/EffekseerRendererDX11/EffekseerRendererDX11.GpuTimer.cpp index 4c1a6abcb7..9fde6d6d87 100644 --- a/Dev/Cpp/EffekseerRendererDX11/EffekseerRendererDX11/EffekseerRendererDX11.GpuTimer.cpp +++ b/Dev/Cpp/EffekseerRendererDX11/EffekseerRendererDX11/EffekseerRendererDX11.GpuTimer.cpp @@ -46,9 +46,13 @@ void GpuTimer::InitDevice() { D3D11_QUERY_DESC desc = {}; desc.Query = D3D11_QUERY_TIMESTAMP_DISJOINT; - ID3D11Query* disjoint = nullptr; - device->CreateQuery(&desc, &disjoint); - m_disjoint.reset(disjoint); + + for (uint32_t index = 1; index < 5; index++) + { + ID3D11Query* disjoint = nullptr; + device->CreateQuery(&desc, &disjoint); + m_disjoint[index].reset(disjoint); + } } for (auto& kv : m_timeData) @@ -58,15 +62,15 @@ void GpuTimer::InitDevice() D3D11_QUERY_DESC desc = {}; desc.Query = D3D11_QUERY_TIMESTAMP; - for (uint32_t i = 0; i < NUM_PHASES; i++) + for (uint32_t phase = 0; phase < NUM_PHASES; phase++) { ID3D11Query* startQuery = nullptr; device->CreateQuery(&desc, &startQuery); - timeData.startQuery[i].reset(startQuery); + timeData.startQuery[phase].reset(startQuery); ID3D11Query* stopQuery = nullptr; device->CreateQuery(&desc, &stopQuery); - timeData.stopQuery[i].reset(stopQuery); + timeData.stopQuery[phase].reset(stopQuery); } } } @@ -79,14 +83,17 @@ void GpuTimer::ReleaseDevice() for (auto& kv : m_timeData) { TimeData& timeData = kv.second; - for (uint32_t i = 0; i < NUM_PHASES; i++) + for (uint32_t phase = 0; phase < NUM_PHASES; phase++) { - timeData.startQuery[i].reset(); - timeData.stopQuery[i].reset(); + timeData.startQuery[phase].reset(); + timeData.stopQuery[phase].reset(); } } - m_disjoint.reset(); + for (uint32_t index = 1; index < 5; index++) + { + m_disjoint[index].reset(); + } } //----------------------------------------------------------------------------------- @@ -108,49 +115,73 @@ void GpuTimer::OnResetDevice() //----------------------------------------------------------------------------------- // //----------------------------------------------------------------------------------- -void GpuTimer::BeginFrame() +void GpuTimer::BeginStage(Effekseer::GpuStage stage) { - assert(m_state != State::DuringFrame); + assert(stage != Effekseer::GpuStage::None); + + uint32_t index = static_cast(stage); + assert(m_stageState[index] != State::DuringStage); - if (m_state == State::AfterFrame) + if (m_stageState[index] == State::AfterStage) { // Avoid D3D11 warning - UpdateResults(); + UpdateResults(stage); } auto context = GetRenderer()->GetContext(); - context->Begin(m_disjoint.get()); - m_state = State::DuringFrame; + context->Begin(m_disjoint[index].get()); + + m_stageState[index] = State::DuringStage; + m_currentStage = stage; } //----------------------------------------------------------------------------------- // //----------------------------------------------------------------------------------- -void GpuTimer::EndFrame() +void GpuTimer::EndStage(Effekseer::GpuStage stage) { - assert(m_state == State::DuringFrame); + assert(stage != Effekseer::GpuStage::None); + + uint32_t index = static_cast(stage); + assert(m_stageState[index] == State::DuringStage); auto context = GetRenderer()->GetContext(); - context->End(m_disjoint.get()); - m_state = State::AfterFrame; + context->End(m_disjoint[index].get()); + + m_stageState[index] = State::AfterStage; + m_currentStage = Effekseer::GpuStage::None; } //----------------------------------------------------------------------------------- // //----------------------------------------------------------------------------------- -void GpuTimer::UpdateResults() +void GpuTimer::UpdateResults(Effekseer::GpuStage stage) { HRESULT hr = S_OK; auto context = GetRenderer()->GetContext(); + assert(stage != Effekseer::GpuStage::None); + uint32_t index = static_cast(stage); + D3D11_QUERY_DATA_TIMESTAMP_DISJOINT disjoint = {1, TRUE}; - hr = context->GetData(m_disjoint.get(), &disjoint, sizeof(disjoint), 0); - if (hr != S_OK) + + while (true) { - return; + hr = context->GetData(m_disjoint[index].get(), &disjoint, sizeof(disjoint), 0); + if (hr == S_OK) + { + break; + } + else if (hr == S_FALSE) + { + Sleep(1); + } + else + { + return; + } } - auto getTimeStamp = [context](ID3D11Query* query, uint64_t& time) { while (true) @@ -177,21 +208,21 @@ void GpuTimer::UpdateResults() timeData.result = 0; uint64_t elapsedTime = 0; - for (uint32_t i = 0; i < NUM_PHASES; i++) + for (uint32_t phase = 0; phase < NUM_PHASES; phase++) { - if (timeData.queryRequested[i]) + if (timeData.queryedStage[phase] == stage) { uint64_t startTime, stopTime; - if (!getTimeStamp(timeData.startQuery[i].get(), startTime)) continue; - if (!getTimeStamp(timeData.stopQuery[i].get(), stopTime)) continue; + if (!getTimeStamp(timeData.startQuery[phase].get(), startTime)) continue; + if (!getTimeStamp(timeData.stopQuery[phase].get(), stopTime)) continue; elapsedTime += (stopTime - startTime) * 1000000 / disjoint.Frequency; - timeData.queryRequested[i] = false; + timeData.queryedStage[phase] = Effekseer::GpuStage::None; } } timeData.result = static_cast(elapsedTime); } - m_state = State::ResultUpdated; + m_stageState[index] = State::ResultUpdated; } //----------------------------------------------------------------------------------- @@ -232,9 +263,9 @@ void GpuTimer::RemoveTimer(const void* object) //----------------------------------------------------------------------------------- // //----------------------------------------------------------------------------------- -void GpuTimer::Start(const void* object, uint32_t phase) +void GpuTimer::Start(const void* object) { - assert(phase < NUM_PHASES); + assert(m_currentStage != Effekseer::GpuStage::None); auto context = GetRenderer()->GetContext(); @@ -242,17 +273,24 @@ void GpuTimer::Start(const void* object, uint32_t phase) if (it != m_timeData.end()) { TimeData& timeData = it->second; - context->End(timeData.startQuery[phase].get()); - timeData.queryRequested[phase] = true; + for (uint32_t phase = 0; phase < NUM_PHASES; phase++) + { + if (timeData.queryedStage[phase] == Effekseer::GpuStage::None) + { + context->End(timeData.startQuery[phase].get()); + timeData.queryedStage[phase] = m_currentStage; + break; + } + } } } //----------------------------------------------------------------------------------- // //----------------------------------------------------------------------------------- -void GpuTimer::Stop(const void* object, uint32_t phase) +void GpuTimer::Stop(const void* object) { - assert(phase < NUM_PHASES); + assert(m_currentStage != Effekseer::GpuStage::None); auto context = GetRenderer()->GetContext(); @@ -260,7 +298,14 @@ void GpuTimer::Stop(const void* object, uint32_t phase) if (it != m_timeData.end()) { TimeData& timeData = it->second; - context->End(timeData.stopQuery[phase].get()); + for (uint32_t phase = 0; phase < NUM_PHASES; phase++) + { + if (timeData.queryedStage[phase] == m_currentStage) + { + context->End(timeData.stopQuery[phase].get()); + break; + } + } } } @@ -269,11 +314,12 @@ void GpuTimer::Stop(const void* object, uint32_t phase) //----------------------------------------------------------------------------------- int32_t GpuTimer::GetResult(const void* object) { - assert(m_state == State::ResultUpdated || m_state == State::AfterFrame); - - if (m_state == State::AfterFrame) + for (uint32_t index = 1; index < 5; index++) { - UpdateResults(); + if (m_stageState[index] == State::AfterStage) + { + UpdateResults(static_cast(index)); + } } auto it = m_timeData.find(object); diff --git a/Dev/Cpp/EffekseerRendererDX11/EffekseerRendererDX11/EffekseerRendererDX11.GpuTimer.h b/Dev/Cpp/EffekseerRendererDX11/EffekseerRendererDX11/EffekseerRendererDX11.GpuTimer.h index 6f8e504e75..b91e153bf3 100644 --- a/Dev/Cpp/EffekseerRendererDX11/EffekseerRendererDX11/EffekseerRendererDX11.GpuTimer.h +++ b/Dev/Cpp/EffekseerRendererDX11/EffekseerRendererDX11/EffekseerRendererDX11.GpuTimer.h @@ -26,19 +26,19 @@ class GpuTimer : public DeviceObject, public ::Effekseer::GpuTimer void InitDevice(); void ReleaseDevice(); - void UpdateResults(); + void UpdateResults(Effekseer::GpuStage stage); public: // For device restore virtual void OnLostDevice(); virtual void OnResetDevice(); public: // GpuTimer - virtual void BeginFrame() override; - virtual void EndFrame() override; + virtual void BeginStage(Effekseer::GpuStage stage) override; + virtual void EndStage(Effekseer::GpuStage stage) override; virtual void AddTimer(const void* object) override; virtual void RemoveTimer(const void* object) override; - virtual void Start(const void* object, uint32_t phase) override; - virtual void Stop(const void* object, uint32_t phase) override; + virtual void Start(const void* object) override; + virtual void Stop(const void* object) override; virtual int32_t GetResult(const void* object) override; private: @@ -46,19 +46,20 @@ class GpuTimer : public DeviceObject, public ::Effekseer::GpuTimer { Backend::D3D11QueryPtr startQuery[NUM_PHASES]; Backend::D3D11QueryPtr stopQuery[NUM_PHASES]; - bool queryRequested[NUM_PHASES] = {}; + Effekseer::GpuStage queryedStage[NUM_PHASES] = {}; int32_t result = 0; }; std::unordered_map m_timeData; - Backend::D3D11QueryPtr m_disjoint; + Backend::D3D11QueryPtr m_disjoint[8]; enum class State { NoResult, - DuringFrame, - AfterFrame, + DuringStage, + AfterStage, ResultUpdated, }; - State m_state = State::NoResult; + State m_stageState[8] = {}; + Effekseer::GpuStage m_currentStage = {}; }; //----------------------------------------------------------------------------------- diff --git a/Dev/Cpp/EffekseerRendererGL/EffekseerRendererGL/EffekseerRendererGL.GpuTimer.cpp b/Dev/Cpp/EffekseerRendererGL/EffekseerRendererGL/EffekseerRendererGL.GpuTimer.cpp index 7708a8f592..2a4b461a26 100644 --- a/Dev/Cpp/EffekseerRendererGL/EffekseerRendererGL/EffekseerRendererGL.GpuTimer.cpp +++ b/Dev/Cpp/EffekseerRendererGL/EffekseerRendererGL/EffekseerRendererGL.GpuTimer.cpp @@ -78,53 +78,64 @@ void GpuTimer::OnResetDevice() //----------------------------------------------------------------------------------- // //----------------------------------------------------------------------------------- -void GpuTimer::BeginFrame() +void GpuTimer::BeginStage(Effekseer::GpuStage stage) { - assert(m_state != State::DuringFrame); + assert(stage != Effekseer::GpuStage::None); - if (m_state == State::AfterFrame) + uint32_t index = static_cast(stage); + assert(m_stageState[index] != State::DuringStage); + + if (m_stageState[index] == State::AfterStage) { - UpdateResults(); + UpdateResults(stage); } - m_state = State::DuringFrame; + m_stageState[index] = State::DuringStage; + m_currentStage = stage; } //----------------------------------------------------------------------------------- // //----------------------------------------------------------------------------------- -void GpuTimer::EndFrame() +void GpuTimer::EndStage(Effekseer::GpuStage stage) { - assert(m_state == State::DuringFrame); + assert(stage != Effekseer::GpuStage::None); + + uint32_t index = static_cast(stage); + assert(m_stageState[index] == State::DuringStage); - m_state = State::AfterFrame; + m_stageState[index] = State::AfterStage; + m_currentStage = Effekseer::GpuStage::None; } //----------------------------------------------------------------------------------- // //----------------------------------------------------------------------------------- -void GpuTimer::UpdateResults() +void GpuTimer::UpdateResults(Effekseer::GpuStage stage) { + assert(stage != Effekseer::GpuStage::None); + uint32_t index = static_cast(stage); + for (auto& kv : m_timeData) { auto& timeData = kv.second; timeData.result = 0; uint64_t elapsedTime = 0; - for (uint32_t i = 0; i < NUM_PHASES; i++) + for (uint32_t phase = 0; phase < NUM_PHASES; phase++) { - if (timeData.queryRequested[i]) + if (timeData.queryedStage[phase] == stage) { uint64_t result = 0; - GLExt::glGetQueryObjectui64v(timeData.timeElapsedQuery[i], GL_QUERY_RESULT, &result); + GLExt::glGetQueryObjectui64v(timeData.timeElapsedQuery[phase], GL_QUERY_RESULT, &result); elapsedTime += result / 1000; // nanoseconds -> microseconds - timeData.queryRequested[i] = false; + timeData.queryedStage[phase] = Effekseer::GpuStage::None; } } timeData.result = static_cast(elapsedTime); } - m_state = State::ResultUpdated; + m_stageState[index] = State::ResultUpdated; GLCheckError(); } @@ -163,16 +174,23 @@ void GpuTimer::RemoveTimer(const void* object) //----------------------------------------------------------------------------------- // //----------------------------------------------------------------------------------- -void GpuTimer::Start(const void* object, uint32_t phase) +void GpuTimer::Start(const void* object) { - assert(phase < NUM_PHASES); + assert(m_currentStage != Effekseer::GpuStage::None); auto it = m_timeData.find(object); if (it != m_timeData.end()) { TimeData& timeData = it->second; - GLExt::glBeginQuery(GL_TIME_ELAPSED, timeData.timeElapsedQuery[phase]); - timeData.queryRequested[phase] = true; + for (uint32_t phase = 0; phase < NUM_PHASES; phase++) + { + if (timeData.queryedStage[phase] == Effekseer::GpuStage::None) + { + GLExt::glBeginQuery(GL_TIME_ELAPSED, timeData.timeElapsedQuery[phase]); + timeData.queryedStage[phase] = m_currentStage; + break; + } + } } GLCheckError(); @@ -181,15 +199,22 @@ void GpuTimer::Start(const void* object, uint32_t phase) //----------------------------------------------------------------------------------- // //----------------------------------------------------------------------------------- -void GpuTimer::Stop(const void* object, uint32_t phase) +void GpuTimer::Stop(const void* object) { - assert(phase < NUM_PHASES); + assert(m_currentStage != Effekseer::GpuStage::None); auto it = m_timeData.find(object); if (it != m_timeData.end()) { TimeData& timeData = it->second; - GLExt::glEndQuery(GL_TIME_ELAPSED); + for (uint32_t phase = 0; phase < NUM_PHASES; phase++) + { + if (timeData.queryedStage[phase] == m_currentStage) + { + GLExt::glEndQuery(GL_TIME_ELAPSED); + break; + } + } } GLCheckError(); @@ -200,11 +225,12 @@ void GpuTimer::Stop(const void* object, uint32_t phase) //----------------------------------------------------------------------------------- int32_t GpuTimer::GetResult(const void* object) { - assert(m_state == State::ResultUpdated || m_state == State::AfterFrame); - - if (m_state == State::AfterFrame) + for (uint32_t index = 1; index < 5; index++) { - UpdateResults(); + if (m_stageState[index] == State::AfterStage) + { + UpdateResults(static_cast(index)); + } } auto it = m_timeData.find(object); diff --git a/Dev/Cpp/EffekseerRendererGL/EffekseerRendererGL/EffekseerRendererGL.GpuTimer.h b/Dev/Cpp/EffekseerRendererGL/EffekseerRendererGL/EffekseerRendererGL.GpuTimer.h index 793da9ced3..5313cc40b6 100644 --- a/Dev/Cpp/EffekseerRendererGL/EffekseerRendererGL/EffekseerRendererGL.GpuTimer.h +++ b/Dev/Cpp/EffekseerRendererGL/EffekseerRendererGL/EffekseerRendererGL.GpuTimer.h @@ -27,19 +27,19 @@ class GpuTimer : public DeviceObject, public ::Effekseer::GpuTimer void InitDevice(); void ReleaseDevice(); - void UpdateResults(); + void UpdateResults(Effekseer::GpuStage stage); public: // For device restore virtual void OnLostDevice(); virtual void OnResetDevice(); public: // GpuTimer - virtual void BeginFrame() override; - virtual void EndFrame() override; + virtual void BeginStage(Effekseer::GpuStage stage) override; + virtual void EndStage(Effekseer::GpuStage stage) override; virtual void AddTimer(const void* object) override; virtual void RemoveTimer(const void* object) override; - virtual void Start(const void* object, uint32_t phase) override; - virtual void Stop(const void* object, uint32_t phase) override; + virtual void Start(const void* object) override; + virtual void Stop(const void* object) override; virtual int32_t GetResult(const void* object) override; private: @@ -47,19 +47,20 @@ class GpuTimer : public DeviceObject, public ::Effekseer::GpuTimer struct TimeData { - GLuint timeElapsedQuery[NUM_PHASES]; - bool queryRequested[NUM_PHASES] = {}; + GLuint timeElapsedQuery[NUM_PHASES] = {}; + Effekseer::GpuStage queryedStage[NUM_PHASES] = {}; int32_t result = 0; }; std::unordered_map m_timeData; - enum class State { + enum class State : uint8_t { NoResult, - DuringFrame, - AfterFrame, + DuringStage, + AfterStage, ResultUpdated, }; - State m_state = State::NoResult; + State m_stageState[8] = {}; + Effekseer::GpuStage m_currentStage = {}; }; //----------------------------------------------------------------------------------- diff --git a/Dev/release/resources/languages/ja/Effekseer_Profiler.csv b/Dev/release/resources/languages/ja/Effekseer_Profiler.csv index 28498c0b24..9387d5816c 100644 --- a/Dev/release/resources/languages/ja/Effekseer_Profiler.csv +++ b/Dev/release/resources/languages/ja/Effekseer_Profiler.csv @@ -2,6 +2,6 @@ Profiler,プロファイラ Profiler_Start,プロファイル開始 Profiler_Stop,プロファイル停止 Profiler_Reset,記録クリア -Profiler_CpuUsage,CPU使用率 -Profiler_GpuUsage,GPU使用率 +Profiler_CpuUsage,CPU使用時間 +Profiler_GpuUsage,GPU使用時間 Profiler_Handles,エフェクト数