6#include <imgui/imgui.h>
7#include <imgui_widgets/tooltips.h>
19constexpr ImVec4 usage_low_color{0.27f, 0.72f, 0.42f, 1.0f};
20constexpr ImVec4 usage_medium_color{0.93f, 0.74f, 0.20f, 1.0f};
21constexpr ImVec4 usage_high_color{0.90f, 0.32f, 0.28f, 1.0f};
22constexpr ImVec4 category_text_color{0.62f, 0.80f, 1.0f, 1.0f};
23constexpr ImVec4 muted_text_color{0.55f, 0.55f, 0.55f, 1.0f};
25constexpr float usage_medium_threshold = 0.60f;
26constexpr float usage_high_threshold = 0.85f;
27constexpr float bar_height_scale = 0.72f;
29enum class resource_unit : uint8_t
35auto pick_usage_color(
float fraction) -> ImVec4
39 return usage_high_color;
41 if(
fraction >= usage_medium_threshold)
43 return usage_medium_color;
45 return usage_low_color;
48void format_count(uint64_t value,
char* buffer,
size_t buffer_size)
50 std::array<char, 32> digits{};
51 const int written = std::snprintf(digits.data(), digits.size(),
"%llu",
static_cast<unsigned long long>(value));
54 std::snprintf(buffer, buffer_size,
"0");
58 for(
int read = 0; read < written &&
out + 1 < buffer_size; ++read)
60 if(read > 0 && ((written - read) % 3) == 0)
64 if(out + 1 < buffer_size)
66 buffer[
out++] = digits[
static_cast<size_t>(read)];
72void format_value(uint64_t value, resource_unit unit,
char* buffer,
size_t buffer_size)
74 if(unit == resource_unit::bytes)
79 format_count(value, buffer, buffer_size);
82void draw_right_aligned_text(
const char* text,
const ImVec4*
color =
nullptr)
84 const float available_width = ImGui::GetContentRegionAvail().x;
85 const float text_width = ImGui::CalcTextSize(text).x;
86 const float offset = available_width - text_width;
89 ImGui::SetCursorPosX(ImGui::GetCursorPosX() + offset);
93 ImGui::TextColored(*
color,
"%s", text);
96 ImGui::TextUnformatted(text);
99void draw_category_row(
const char*
icon,
const char* label)
101 ImGui::TableNextRow();
102 ImGui::TableSetColumnIndex(0);
103 const ImU32 background = ImGui::GetColorU32(ImVec4(0.16f, 0.20f, 0.27f, 1.0f));
104 ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0, background);
105 ImGui::AlignTextToFramePadding();
106 ImGui::TextColored(category_text_color,
"%s %s",
icon, label);
109void draw_resource_row(
const char*
name,
111 uint64_t current_value,
116 ImGui::TableNextRow();
118 ImGui::TableSetColumnIndex(0);
119 ImGui::AlignTextToFramePadding();
120 ImGui::TextUnformatted(
name);
123 std::array<char, 32> used_buffer{};
124 format_value(current_value, unit, used_buffer.data(), used_buffer.size());
125 ImGui::TableSetColumnIndex(1);
126 ImGui::AlignTextToFramePadding();
127 draw_right_aligned_text(used_buffer.data());
129 ImGui::TableSetColumnIndex(2);
130 ImGui::AlignTextToFramePadding();
133 draw_right_aligned_text(
"--", &muted_text_color);
137 std::array<char, 32> max_buffer{};
138 format_value(max_value, unit, max_buffer.data(), max_buffer.size());
139 draw_right_aligned_text(max_buffer.data());
142 ImGui::TableSetColumnIndex(3);
145 draw_right_aligned_text(
"n/a", &muted_text_color);
150 std::clamp(
static_cast<float>(current_value) /
static_cast<float>(max_value), 0.0f, 1.0f);
151 std::array<char, 16> overlay{};
152 std::snprintf(overlay.data(), overlay.size(),
"%.1f%%",
static_cast<double>(
fraction * 100.0f));
153 ImGui::PushStyleColor(ImGuiCol_PlotHistogram, pick_usage_color(
fraction));
154 ImGui::ProgressBar(
fraction, ImVec2(-1.0f, ImGui::GetFrameHeight() * bar_height_scale), overlay.data());
155 ImGui::PopStyleColor();
156 ImGui::SetItemTooltipEx(
"%s: %.2f%% used",
description,
static_cast<double>(
fraction * 100.0f));
170 if(caps ==
nullptr || stats ==
nullptr)
175 constexpr ImGuiTableFlags table_flags = ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersInnerV |
176 ImGuiTableFlags_BordersOuter | ImGuiTableFlags_PadOuterX |
177 ImGuiTableFlags_NoBordersInBodyUntilResize;
178 if(!ImGui::BeginTable(
"##gpu_resources", 4, table_flags))
183 ImGui::TableSetupColumn(
"Resource", ImGuiTableColumnFlags_WidthStretch, 0.9f);
184 ImGui::TableSetupColumn(
"Used", ImGuiTableColumnFlags_WidthFixed, 96.0f);
185 ImGui::TableSetupColumn(
"Limit", ImGuiTableColumnFlags_WidthFixed, 96.0f);
186 ImGui::TableSetupColumn(
"Usage", ImGuiTableColumnFlags_WidthStretch, 1.6f);
187 ImGui::TableHeadersRow();
190 draw_resource_row(
"Transient Index Buffer",
191 "GPU memory used by transient index buffers this frame.",
192 static_cast<uint64_t
>(stats->transientIbUsed),
193 caps->limits.maxTransientIbSize,
194 resource_unit::bytes);
195 draw_resource_row(
"Transient Vertex Buffer",
196 "GPU memory used by transient vertex buffers this frame.",
197 static_cast<uint64_t
>(stats->transientVbUsed),
198 caps->limits.maxTransientVbSize,
199 resource_unit::bytes);
200 draw_resource_row(
"Dynamic Index Buffers",
201 "Number of dynamic index buffers currently allocated.",
202 stats->numDynamicIndexBuffers,
203 caps->limits.maxDynamicIndexBuffers,
204 resource_unit::count);
205 draw_resource_row(
"Dynamic Vertex Buffers",
206 "Number of dynamic vertex buffers currently allocated.",
207 stats->numDynamicVertexBuffers,
208 caps->limits.maxDynamicVertexBuffers,
209 resource_unit::count);
210 draw_resource_row(
"Index Buffers",
211 "Number of static index buffers currently allocated.",
212 stats->numIndexBuffers,
213 caps->limits.maxIndexBuffers,
214 resource_unit::count);
215 draw_resource_row(
"Vertex Buffers",
216 "Number of static vertex buffers currently allocated.",
217 stats->numVertexBuffers,
218 caps->limits.maxVertexBuffers,
219 resource_unit::count);
222 draw_resource_row(
"Shader Programs",
223 "Number of linked shader programs currently allocated.",
225 caps->limits.maxPrograms,
226 resource_unit::count);
227 draw_resource_row(
"Shaders",
228 "Number of compiled shaders currently allocated.",
230 caps->limits.maxShaders,
231 resource_unit::count);
232 draw_resource_row(
"Uniforms",
233 "Number of uniform handles currently allocated.",
235 caps->limits.maxUniforms,
236 resource_unit::count);
239 draw_resource_row(
"Textures",
240 "Number of textures currently allocated.",
242 caps->limits.maxTextures,
243 resource_unit::count);
244 draw_resource_row(
"Frame Buffers",
245 "Number of frame buffers currently allocated.",
246 stats->numFrameBuffers,
247 caps->limits.maxFrameBuffers,
248 resource_unit::count);
249 draw_resource_row(
"Vertex Layouts",
250 "Number of vertex layouts currently allocated.",
251 stats->numVertexLayouts,
252 caps->limits.maxVertexLayouts,
253 resource_unit::count);
254 draw_resource_row(
"Occlusion Queries",
255 "Number of occlusion queries currently allocated.",
256 stats->numOcclusionQueries,
257 caps->limits.maxOcclusionQueries,
258 resource_unit::count);
261 draw_resource_row(
"Texture Memory",
262 "Estimated GPU memory used by textures.",
263 static_cast<uint64_t
>(std::max<int64_t>(0, stats->textureMemoryUsed)),
265 resource_unit::bytes);
266 draw_resource_row(
"Render Target Memory",
267 "Estimated GPU memory used by render targets.",
268 static_cast<uint64_t
>(std::max<int64_t>(0, stats->rtMemoryUsed)),
270 resource_unit::bytes);
#define ICON_MDI_DATABASE
#define ICON_MDI_CODE_BRACES
const stats * get_stats()
void profiler_draw_gpu_resources_section()
auto format_bytes(std::uint64_t bytes, std::uint8_t num_frac) -> std::string
std::vector< math::color > color