2
3
4
5
9#include "Render/Renderer/RendererManager.h"
10#include "Render/Renderer/Renderer.h"
11#include "Render/Renderer/RenderPassStatistics/RenderPassStatistics.h"
12#include "..\..\..\..\..\..\Render\Renderer\RenderPassStatistics\TimestampQuerier.h"
13#include "..\..\..\..\..\..\Render\Renderer\RenderPassStatistics\PipelineStatisticsQuerier.h"
14#include "Core/Container/Tree.h"
19 const std::string& panelName ,
32
33
35 ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(2.0f, 4.0f));
38
39
40 static std::string searchString;
41 static bool isEnableSearch =
false;
44
45
50 ImGui::PushItemWidth(m_PanelSize.x - ImGuiH::GetLineItemSize().x * 2.0f - ImGui::GetStyle().WindowPadding.x);
51 static char search[256] = {};
52 if (ImGui::InputTextWithHint(
"##",
ICON_TEXT(ICON_MD_SEARCH, Search), search, 128))
54 searchString = std::string(search);
55 if (searchString.size() == 0) isEnableSearch =
false;
56 else isEnableSearch =
true;
58 ImGui::PopItemWidth();
60 ImGui::SameLine(m_PanelSize.x - ImGuiH::GetLineItemSize().x * 2.0f);
61 ImGui::Button(ICON_MD_FILTER_ALT, ImGuiH::GetLineItemSize());
62 ImGui::SameLine(m_PanelSize.x - ImGuiH::GetLineItemSize().x * 1.0f);
63 ImGui::Button(ICON_MD_REORDER, ImGuiH::GetLineItemSize());
67 static int selectedStatistics = 0;
68 static int selectedChannel = 0;
70 ImGui::PushStyleColor(ImGuiCol_Header, ImVec4(0.196f, 0.204f, 0.2f, 1.0f));
71 ImGui::PushStyleColor(ImGuiCol_HeaderHovered, ImVec4(0.164f, 0.18f, 0.184f, 1.0f));
72 ImGui::PushStyleColor(ImGuiCol_HeaderActive, ImVec4(0.164f, 0.18f, 0.184f, 1.0f));
73 ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0.196f, 0.204f, 0.2f, 1.0f));
76
77
82 ImGui::PushID(
"ImguiRendererProfilerHUD::Statistics Type");
83 ImGui::Columns(2, 0,
false);
84 ImGui::SetColumnWidth(0, ImGuiH::GetLineItemSize().x * 4.0f);
85 ImGui::Text(
"Statistics");
88 static const char* type[] = {
" TimeStamp",
" PipelineStatistics" };
89 ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x);
90 ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.6f, 0.6f, 0.6f, 1.0f));
91 ImGui::Combo(
"##", &selectedStatistics, type, _countof(type));
92 ImGui::PopStyleColor();
93 ImGui::PopItemWidth();
99 if (selectedStatistics == 1)
101 ImGui::PushID(
"ImguiRendererProfilerHUD::PipelineChannel");
102 ImGui::Columns(2, 0,
false);
103 ImGui::SetColumnWidth(0, ImGuiH::GetLineItemSize().x * 4.0f);
104 ImGui::Text(
"Channel");
107 static const char* channel[] = {
108 " Input Assembly Vertices",
109 " Input Assembly Primitive",
110 " Vertex Shader Invocations",
111 " Geometry Shader Invocations",
112 " Geometry Shader Primitive",
113 " Clipping Invocations",
114 " Clipping Primitive",
115 " Fragment Shader Invocations",
116 " Tessellation Control Invocations",
117 " Tessellation Evaluation Invocations",
118 " Compute Shader Invocations",
119 " Task Shader Invocations",
120 " Mesh Shader Invocations"
122 ImGui::PushItemWidth(ImGui::GetContentRegionAvail().x);
123 ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.6f, 0.6f, 0.6f, 1.0f));
124 ImGui::Combo(
"##", &selectedChannel, channel, _countof(channel));
125 ImGui::PopStyleColor();
126 ImGui::PopItemWidth();
133 ImGui::PushID(
"ImguiRendererProfilerHUD::Refresh");
134 ImGui::Columns(2, 0,
false);
135 ImGui::SetColumnWidth(0, ImGuiH::GetLineItemSize().x * 4.0f);
136 ImGui::Text(
"Refresh");
139 static bool isChecked =
false;
144 RENDERPASS_STATISTICS_CAPTUREFRAME
153 ImGui::PopStyleColor(4);
155 if (selectedStatistics == 0)
159 else if(selectedStatistics == 1)
165
166
167 ImGui::PopStyleVar();
176
177
178 struct TimestampResult
180 TimestampQuerier::Result result;
185
186
187 scl::
tree<TimestampResult> totalResult;
188 totalResult.GetData().name =
"Scene ( Viewport 0 )";
191
192
196 RendererManager::IterRenderer([&](
const std::string& rendererName,
const std::shared_ptr<
Renderer>& renderer) {
198 const auto rendererResult = totalResult.AddChild();
199 rendererResult->GetData().name = rendererName;
201 renderer->IterStatistics([&](
const std::string& subPassName,
const std::shared_ptr<RenderPassStatistics>& statistics) {
203 const auto subPassResult = rendererResult->AddChild();
204 subPassResult->GetData().name = subPassName;
206 statistics->IterStatisticsResult(Querier::Timestamp, [&](
const Querier::StatisticsBits& type, std::shared_ptr<Querier::Result>& result) {
208 TimestampQuerier::Result* res =
static_cast<TimestampQuerier::Result*>(result.get());
211 subPassResult->GetData().result = *res;
213 rendererResult->GetData().result.Combine(res);
214 rendererResult->GetData().result.valid =
true;
216 totalResult.GetData().result.Combine(res);
217 totalResult.GetData().result.valid =
true;
231 static ImGuiTableFlags flags = ImGuiTableFlags_BordersV | ImGuiTableFlags_BordersOuterH | ImGuiTableFlags_Resizable | ImGuiTableFlags_NoBordersInBody |
232 ImGuiTableFlags_Sortable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_SortMulti | ImGuiTableFlags_Hideable |
233 ImGuiTableFlags_ScrollY | ImGuiTableFlags_SortTristate;
234 static ImGuiTreeNodeFlags tree_node_flags = ImGuiTreeNodeFlags_SpanAllColumns;
237
238
239 static int sortState = 0;
242
243
244 static auto SortTimestampTreeMethod = [](
const void* lhs,
const void* rhs) ->
int {
246 const auto l =
static_cast<
const std::unique_ptr<scl::tree<TimestampResult>>*>(lhs);
247 const auto r =
static_cast<
const std::unique_ptr<scl::tree<TimestampResult>>*>(rhs);
249 ImGuiTableSortSpecs* sort_specs = ImGui::TableGetSortSpecs();
250 if (sortState == ImGuiSortDirection_Ascending)
252 return ((*l)->GetData().result.timeStamp - (*r)->GetData().result.timeStamp) * 1000;
256 return ((*r)->GetData().result.timeStamp - (*l)->GetData().result.timeStamp) * 1000;
261
262
263 static std::function<
void(
scl::
tree<TimestampResult>*)> SortTimestampTree = [&](scl::tree<TimestampResult>* node) {
265 if (sortState == 0)
return;
267 qsort((
void*)node->GetChilds().data(), (size_t)node->GetChilds().size(),
sizeof(node->GetChilds()[0]), SortTimestampTreeMethod);
269 for (
auto& child : node->GetChilds())
271 SortTimestampTree(child.get());
276
277
278 static std::function<
void(
scl::
tree<TimestampResult>*, uint32_t,
scl::
tree<TimestampResult>*)> DrawTimestampTree = [&](scl::tree<TimestampResult>* node, uint32_t depth, scl::tree<TimestampResult>* root) {
280 if (!node->GetData().result.valid)
return;
282 ImGui::TableNextRow();
283 ImGui::TableNextColumn();
285 std::stringstream space;
286 for (uint32_t i = 0; i < depth; i++)
291 ImGui::Text(space.str().c_str());
294 bool hasChild = node->GetChilds().size() > 0;
297 bool open = ImGui::TreeNodeEx(node->GetData().name.c_str(), tree_node_flags);
298 ImGui::TableNextColumn();
300 ImGui::PushStyleColor(ImGuiCol_PlotHistogram, ImVec4(0.0f, 0.8f, 0.0f, 1.0f));
301 ImGui::ProgressBar(root->GetData().result.timeStamp > 0 ? (node->GetData().result.timeStamp / root->GetData().result.timeStamp) : 0.0f, ImVec2(-FLT_MIN, 2.0f),
"##");
302 ImGui::PopStyleColor();
303 ImGui::SameLine(0.05f);
304 ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.8f, 0.8f, 0.8f, 1.0f));
305 ImGui::Text(
"%.2f ms", node->GetData().result.timeStamp);
306 ImGui::PopStyleColor();
309 for (
auto& child : node->GetChilds())
311 DrawTimestampTree(child.get(), depth + 1, root);
318 ImGui::TreeNodeEx(node->GetData().name.c_str(), tree_node_flags | ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen);
319 ImGui::TableNextColumn();
321 ImGui::PushStyleColor(ImGuiCol_PlotHistogram, ImVec4(0.0f, 0.8f, 0.0f, 1.0f));
322 ImGui::ProgressBar(root->GetData().result.timeStamp > 0 ? (node->GetData().result.timeStamp / root->GetData().result.timeStamp) : 0.0f, ImVec2(-FLT_MIN, 2.0f),
"##");
323 ImGui::PopStyleColor();
324 ImGui::SameLine(0.05f);
325 ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.8f, 0.8f, 0.8f, 1.0f));
326 ImGui::Text(
"%.2f ms", node->GetData().result.timeStamp);
327 ImGui::PopStyleColor();
331 ImGui::PushStyleVar(ImGuiStyleVar_IndentSpacing, 0.0f);
332 ImGui::PushStyleColor(ImGuiCol_Header, ImVec4(0.196f, 0.204f, 0.2f, 1.0f));
333 ImGui::PushStyleColor(ImGuiCol_HeaderHovered, ImVec4(0.164f, 0.18f, 0.184f, 1.0f));
334 ImGui::PushStyleColor(ImGuiCol_HeaderActive, ImVec4(0.164f, 0.18f, 0.184f, 1.0f));
335 ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0.196f, 0.204f, 0.2f, 1.0f));
337 if (ImGui::BeginTable(
"timestampTree", 2, flags))
340 ImGui::TableSetupColumn(
"Name", ImGuiTableColumnFlags_NoHide);
341 ImGui::TableSetupColumn(
"TimeCost", ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_PreferSortDescending, ImGuiH::GetLineItemSize().x * 3.0f);
342 ImGui::TableHeadersRow();
345 if (ImGuiTableSortSpecs* sort_specs = ImGui::TableGetSortSpecs())
348 if (sort_specs->SpecsDirty)
353 if (sort_specs->SpecsCount > 0)
355 sortState = sort_specs->Specs->SortDirection;
358 sort_specs->SpecsDirty =
false;
362 SortTimestampTree(&totalResult);
363 DrawTimestampTree(&totalResult, 0, &totalResult);
367 ImGui::PopStyleColor(4);
368 ImGui::PopStyleVar();
377
378
379 static int selectBit;
383
384
385 struct PipelineResult
387 PipelineStatisticsQuerier::Result result;
392
393
394 scl::
tree<PipelineResult> totalResult;
395 totalResult.GetData().name =
"Scene ( Viewport 0 )";
398
399
403 RendererManager::IterRenderer([&](
const std::string& rendererName,
const std::shared_ptr<
Renderer>& renderer) {
405 auto rendererResult = totalResult.AddChild();
406 rendererResult->GetData().name = rendererName;
408 renderer->IterStatistics([&](
const std::string& subPassName,
const std::shared_ptr<RenderPassStatistics>& statistics) {
410 auto subPassResult = rendererResult->AddChild();
411 subPassResult->GetData().name = subPassName;
413 statistics->IterStatisticsResult(Querier::Pipeline, [&](
const Querier::StatisticsBits& type, std::shared_ptr<Querier::Result>& result) {
415 PipelineStatisticsQuerier::Result* res =
static_cast<PipelineStatisticsQuerier::Result*>(result.get());
418 subPassResult->GetData().result = *res;
420 rendererResult->GetData().result.Combine(res);
421 rendererResult->GetData().result.valid =
true;
423 totalResult.GetData().result.Combine(res);
424 totalResult.GetData().result.valid =
true;
438 static ImGuiTableFlags flags = ImGuiTableFlags_BordersV | ImGuiTableFlags_BordersOuterH | ImGuiTableFlags_Resizable | ImGuiTableFlags_NoBordersInBody |
439 ImGuiTableFlags_Sortable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_SortMulti | ImGuiTableFlags_Hideable |
440 ImGuiTableFlags_ScrollY | ImGuiTableFlags_SortTristate;
441 static ImGuiTreeNodeFlags tree_node_flags = ImGuiTreeNodeFlags_SpanAllColumns;
444
445
446 static int sortState = 0;
449
450
451 static auto SortTimestampTreeMethod = [](
const void* lhs,
const void* rhs) ->
int {
453 const auto l =
static_cast<
const std::unique_ptr<scl::tree<PipelineResult>>*>(lhs);
454 const auto r =
static_cast<
const std::unique_ptr<scl::tree<PipelineResult>>*>(rhs);
456 ImGuiTableSortSpecs* sort_specs = ImGui::TableGetSortSpecs();
457 if (sortState == ImGuiSortDirection_Ascending)
459 return (*l)->GetData().result.statistics[selectBit] - (*r)->GetData().result.statistics[selectBit];
463 return (*r)->GetData().result.statistics[selectBit] - (*l)->GetData().result.statistics[selectBit];
468
469
470 static std::function<
void(
scl::
tree<PipelineResult>*)> SortTimestampTree = [&](scl::tree<PipelineResult>* node) {
472 if (sortState == 0)
return;
474 qsort((
void*)node->GetChilds().data(), (size_t)node->GetChilds().size(),
sizeof(node->GetChilds()[0]), SortTimestampTreeMethod);
476 for (
auto& child : node->GetChilds())
478 SortTimestampTree(child.get());
483
484
485 static std::function<
void(
scl::
tree<PipelineResult>*, uint32_t depth,
scl::
tree<PipelineResult>*)> DrawTimestampTree = [&](scl::tree<PipelineResult>* node, uint32_t depth, scl::tree<PipelineResult>* root) {
487 if (!node->GetData().result.valid)
return;
489 ImGui::TableNextRow();
490 ImGui::TableNextColumn();
492 std::stringstream space;
493 for (uint32_t i = 0; i < depth; i++)
498 ImGui::Text(space.str().c_str());
501 bool hasChild = node->GetChilds().size() > 0;
504 bool open = ImGui::TreeNodeEx(node->GetData().name.c_str(), tree_node_flags);
505 ImGui::TableNextColumn();
507 ImGui::PushStyleColor(ImGuiCol_PlotHistogram, ImVec4(0.0f, 0.8f, 0.0f, 1.0f));
508 ImGui::ProgressBar(root->GetData().result.statistics[bit] > 0 ? (node->GetData().result.statistics[bit] /
float(root->GetData().result.statistics[bit])) : 0.0f, ImVec2(-FLT_MIN, 2.0f),
"##");
509 ImGui::PopStyleColor();
510 ImGui::SameLine(0.05f);
511 ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.8f, 0.8f, 0.8f, 1.0f));
512 ImGui::Text(
"%d", node->GetData().result.statistics[bit]);
513 ImGui::PopStyleColor();
516 for (
auto& child : node->GetChilds())
518 DrawTimestampTree(child.get(), depth + 1, root);
525 ImGui::TreeNodeEx(node->GetData().name.c_str(), tree_node_flags | ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen);
526 ImGui::TableNextColumn();
528 ImGui::PushStyleColor(ImGuiCol_PlotHistogram, ImVec4(0.0f, 0.8f, 0.0f, 1.0f));
529 ImGui::ProgressBar(root->GetData().result.statistics[bit] > 0 ? (node->GetData().result.statistics[bit] /
float(root->GetData().result.statistics[bit])) : 0.0f, ImVec2(-FLT_MIN, 2.0f),
"##");
530 ImGui::PopStyleColor();
531 ImGui::SameLine(0.05f);
532 ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0.8f, 0.8f, 0.8f, 1.0f));
533 ImGui::Text(
"%d", node->GetData().result.statistics[bit]);
534 ImGui::PopStyleColor();
538 ImGui::PushStyleVar(ImGuiStyleVar_IndentSpacing, 0.0f);
539 ImGui::PushStyleColor(ImGuiCol_Header, ImVec4(0.196f, 0.204f, 0.2f, 1.0f));
540 ImGui::PushStyleColor(ImGuiCol_HeaderHovered, ImVec4(0.164f, 0.18f, 0.184f, 1.0f));
541 ImGui::PushStyleColor(ImGuiCol_HeaderActive, ImVec4(0.164f, 0.18f, 0.184f, 1.0f));
542 ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0.196f, 0.204f, 0.2f, 1.0f));
544 if (ImGui::BeginTable(
"pipelineTree", 2, flags))
547 ImGui::TableSetupColumn(
"Name", ImGuiTableColumnFlags_NoSort | ImGuiTableColumnFlags_NoHide);
548 ImGui::TableSetupColumn(
"Invocation Count", ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_PreferSortDescending, ImGuiH::GetLineItemSize().x * 3.0f);
549 ImGui::TableSetupScrollFreeze(0, 1);
550 ImGui::TableHeadersRow();
553 if (ImGuiTableSortSpecs* sort_specs = ImGui::TableGetSortSpecs())
556 if (sort_specs->SpecsDirty)
561 if (sort_specs->SpecsCount > 0)
563 sortState = sort_specs->Specs->SortDirection;
566 sort_specs->SpecsDirty =
false;
570 SortTimestampTree(&totalResult);
571 DrawTimestampTree(&totalResult, 0, &totalResult);
575 ImGui::PopStyleColor(4);
576 ImGui::PopStyleVar();
#define ICON_TEXT(icon, text)
#define SPICES_PROFILE_ZONEN(...)
#define SPICES_PROFILE_ZONE
FrameInfo Class. This class defines the FrameInfo data.
static void Checkbox(bool *isChecked)
ImGuiHelper Style Checkbox.
The ImGuiH Class. This class defines helper function for slate render.
void DrawTimeStamp() const
void DrawPipelineStatistics(int bit) const
virtual void OnRender() override
This interface is called On SlateRenderer Render.
ImguiRendererProfilerHUD(const std::string &panelName, FrameInfo &frameInfo)
Constructor Function.
ImguiSlate(const std::string &panelName, FrameInfo &frameInfo)
Constructor Function. Init with Slate's name.
This Class defines the basic behaves of specific slate. When we add an new Slate, we need inherit fro...
RendererManager Class. This class Manages all renderer.
Renderer Class. This class defines the basic behaves of renderer. When we add an new Renderer,...