-
-
Notifications
You must be signed in to change notification settings - Fork 220
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support GpuTimer for LLGI (#1008)
- Loading branch information
Showing
36 changed files
with
488 additions
and
81 deletions.
There are no files selected for viewing
Submodule LLGI
updated
27 files
+2 −2 | .github/workflows/build.yml | |
+47 −0 | src/DX12/LLGI.CommandListDX12.cpp | |
+5 −0 | src/DX12/LLGI.CommandListDX12.h | |
+21 −0 | src/DX12/LLGI.GraphicsDX12.cpp | |
+5 −0 | src/DX12/LLGI.GraphicsDX12.h | |
+73 −0 | src/DX12/LLGI.QueryDX12.cpp | |
+37 −0 | src/DX12/LLGI.QueryDX12.h | |
+7 −0 | src/LLGI.Base.h | |
+5 −0 | src/LLGI.CommandList.h | |
+13 −0 | src/LLGI.Graphics.h | |
+6 −0 | src/LLGI.Query.cpp | |
+22 −0 | src/LLGI.Query.h | |
+5 −0 | src/Metal/LLGI.CommandListMetal.h | |
+46 −0 | src/Metal/LLGI.CommandListMetal.mm | |
+4 −0 | src/Metal/LLGI.GraphicsMetal.h | |
+18 −0 | src/Metal/LLGI.GraphicsMetal.mm | |
+32 −0 | src/Metal/LLGI.QueryMetal.h | |
+64 −0 | src/Metal/LLGI.QueryMetal.mm | |
+1 −0 | src/Vulkan/LLGI.BaseVulkan.h | |
+3 −1 | src/Vulkan/LLGI.BufferVulkan.h | |
+54 −0 | src/Vulkan/LLGI.CommandListVulkan.cpp | |
+5 −0 | src/Vulkan/LLGI.CommandListVulkan.h | |
+20 −0 | src/Vulkan/LLGI.GraphicsVulkan.cpp | |
+4 −0 | src/Vulkan/LLGI.GraphicsVulkan.h | |
+1 −1 | src/Vulkan/LLGI.PlatformVulkan.cpp | |
+59 −0 | src/Vulkan/LLGI.QueryVulkan.cpp | |
+32 −0 | src/Vulkan/LLGI.QueryVulkan.h |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
166 changes: 166 additions & 0 deletions
166
Dev/Cpp/EffekseerRendererLLGI/EffekseerRendererLLGI/EffekseerRendererLLGI.GpuTimer.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
#include "EffekseerRendererLLGI.GpuTimer.h" | ||
|
||
namespace EffekseerRendererLLGI | ||
{ | ||
|
||
GpuTimer::GpuTimer(RendererImplemented* renderer, bool hasRefCount) | ||
: m_renderer(renderer) | ||
{ | ||
m_renderer->AddRef(); | ||
m_renderer->GetStandardRenderer()->UpdateGpuTimerCount(+1); | ||
} | ||
|
||
GpuTimer::~GpuTimer() | ||
{ | ||
m_renderer->GetStandardRenderer()->UpdateGpuTimerCount(-1); | ||
m_renderer->Release(); | ||
} | ||
|
||
void GpuTimer::BeginStage(Effekseer::GpuStage stage) | ||
{ | ||
assert(stage != Effekseer::GpuStage::None); | ||
|
||
uint32_t index = static_cast<uint32_t>(stage); | ||
assert(m_stageState[index] != State::DuringStage); | ||
|
||
if (m_stageState[index] == State::AfterStage) | ||
{ | ||
UpdateResults(stage); | ||
} | ||
|
||
m_stageState[index] = State::DuringStage; | ||
m_currentStage = stage; | ||
} | ||
|
||
void GpuTimer::EndStage(Effekseer::GpuStage stage) | ||
{ | ||
assert(stage != Effekseer::GpuStage::None); | ||
|
||
uint32_t index = static_cast<uint32_t>(stage); | ||
assert(m_stageState[index] == State::DuringStage); | ||
|
||
m_stageState[index] = State::AfterStage; | ||
m_currentStage = Effekseer::GpuStage::None; | ||
} | ||
|
||
void GpuTimer::UpdateResults() | ||
{ | ||
for (uint32_t index = 1; index < 5; index++) | ||
{ | ||
if (m_stageState[index] == State::AfterStage) | ||
{ | ||
UpdateResults(static_cast<Effekseer::GpuStage>(index)); | ||
} | ||
} | ||
|
||
for (auto& [object, timeData] : m_timeData) | ||
{ | ||
m_renderer->ResetQuery(timeData.queries.get()); | ||
} | ||
} | ||
|
||
void GpuTimer::UpdateResults(Effekseer::GpuStage stage) | ||
{ | ||
auto graphicsDevice = m_renderer->GetGraphicsDevice().DownCast<EffekseerRendererLLGI::Backend::GraphicsDevice>(); | ||
|
||
assert(stage != Effekseer::GpuStage::None); | ||
uint32_t index = static_cast<uint32_t>(stage); | ||
|
||
for (auto& [object, timeData] : m_timeData) | ||
{ | ||
timeData.result = 0; | ||
|
||
uint64_t elapsedTime = 0; | ||
for (uint32_t phase = 0; phase < NUM_PHASES; phase++) | ||
{ | ||
if (timeData.queryedStage[phase] == stage) | ||
{ | ||
if (timeData.queries) | ||
{ | ||
uint64_t startTime = timeData.queries->GetQueryResult(QueryIndex(phase, TIMESTAMP_START)); | ||
uint64_t stopTime = timeData.queries->GetQueryResult(QueryIndex(phase, TIMESTAMP_STOP)); | ||
elapsedTime += graphicsDevice->GetGraphics()->TimestampToMicroseconds(stopTime - startTime); | ||
} | ||
timeData.queryedStage[phase] = Effekseer::GpuStage::None; | ||
} | ||
} | ||
timeData.result = static_cast<int32_t>(elapsedTime); | ||
} | ||
|
||
m_stageState[index] = State::ResultUpdated; | ||
} | ||
|
||
void GpuTimer::AddTimer(const void* object) | ||
{ | ||
assert(m_timeData.find(object) == m_timeData.end()); | ||
|
||
auto graphicsDevice = m_renderer->GetGraphicsDevice().DownCast<EffekseerRendererLLGI::Backend::GraphicsDevice>(); | ||
|
||
TimeData timeData; | ||
timeData.queries = LLGI::CreateUniqueReference(graphicsDevice->GetGraphics()->CreateQuery( | ||
LLGI::QueryType::Timestamp, NUM_QUERIES_PER_TIMER)); | ||
|
||
m_timeData.emplace(object, std::move(timeData)); | ||
} | ||
|
||
void GpuTimer::RemoveTimer(const void* object) | ||
{ | ||
auto it = m_timeData.find(object); | ||
if (it != m_timeData.end()) | ||
{ | ||
TimeData& timeData = it->second; | ||
m_timeData.erase(it); | ||
} | ||
} | ||
|
||
void GpuTimer::Start(const void* object) | ||
{ | ||
assert(m_currentStage != Effekseer::GpuStage::None); | ||
|
||
auto it = m_timeData.find(object); | ||
if (it != m_timeData.end()) | ||
{ | ||
TimeData& timeData = it->second; | ||
for (uint32_t phase = 0; phase < NUM_PHASES; phase++) | ||
{ | ||
if (timeData.queryedStage[phase] == Effekseer::GpuStage::None) | ||
{ | ||
m_renderer->RecordTimestamp(timeData.queries.get(), QueryIndex(phase, TIMESTAMP_START)); | ||
timeData.queryedStage[phase] = m_currentStage; | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
|
||
void GpuTimer::Stop(const void* object) | ||
{ | ||
assert(m_currentStage != Effekseer::GpuStage::None); | ||
|
||
auto it = m_timeData.find(object); | ||
if (it != m_timeData.end()) | ||
{ | ||
TimeData& timeData = it->second; | ||
for (uint32_t phase = 0; phase < NUM_PHASES; phase++) | ||
{ | ||
if (timeData.queryedStage[phase] == m_currentStage) | ||
{ | ||
m_renderer->RecordTimestamp(timeData.queries.get(), QueryIndex(phase, TIMESTAMP_STOP)); | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
|
||
int32_t GpuTimer::GetResult(const void* object) | ||
{ | ||
auto it = m_timeData.find(object); | ||
if (it != m_timeData.end()) | ||
{ | ||
TimeData& timeData = it->second; | ||
return timeData.result; | ||
} | ||
return 0; | ||
} | ||
|
||
} // namespace EffekseerRendererLLGI |
62 changes: 62 additions & 0 deletions
62
Dev/Cpp/EffekseerRendererLLGI/EffekseerRendererLLGI/EffekseerRendererLLGI.GpuTimer.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
|
||
#pragma once | ||
|
||
#include <unordered_map> | ||
#include "GraphicsDevice.h" | ||
#include "EffekseerRendererLLGI.RendererImplemented.h" | ||
#include <LLGI.Query.h> | ||
|
||
namespace EffekseerRendererLLGI | ||
{ | ||
|
||
class GpuTimer : public ::Effekseer::GpuTimer | ||
{ | ||
static constexpr uint32_t NUM_PHASES = 2; | ||
static constexpr uint32_t NUM_TIMESTAMPS = 2; | ||
static constexpr uint32_t NUM_QUERIES_PER_TIMER = NUM_PHASES * NUM_TIMESTAMPS; | ||
|
||
static constexpr uint32_t TIMESTAMP_START = 0; | ||
static constexpr uint32_t TIMESTAMP_STOP = 1; | ||
static constexpr uint32_t QueryIndex(uint32_t phase, uint32_t timestamp) { | ||
return phase * NUM_TIMESTAMPS + timestamp; | ||
} | ||
|
||
public: | ||
GpuTimer(RendererImplemented* renderer, bool hasRefCount); | ||
|
||
virtual ~GpuTimer(); | ||
|
||
void UpdateResults(Effekseer::GpuStage stage); | ||
|
||
public: // GpuTimer | ||
virtual void UpdateResults() 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) override; | ||
virtual void Stop(const void* object) override; | ||
virtual int32_t GetResult(const void* object) override; | ||
|
||
private: | ||
RendererImplemented* m_renderer = nullptr; | ||
|
||
struct TimeData | ||
{ | ||
LLGI::unique_ref<LLGI::Query> queries; | ||
Effekseer::GpuStage queryedStage[NUM_PHASES] = {}; | ||
int32_t result = 0; | ||
}; | ||
std::unordered_map<const void*, TimeData> m_timeData; | ||
|
||
enum class State { | ||
NoResult, | ||
DuringStage, | ||
AfterStage, | ||
ResultUpdated, | ||
}; | ||
State m_stageState[8] = {}; | ||
Effekseer::GpuStage m_currentStage = {}; | ||
}; | ||
|
||
} // namespace EffekseerRendererLLGI |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.