Skip to content

Commit 7a237d9

Browse files
authored
Logging / editor upgrades (#39)
* Improve editor windows, log, stats - Follow pattern of taking existing window as parameter. - Add auto-scrolling. - Display GPU name in stats. - Put ImGui demo window in list of windows in Main Menu (only in Debug). * Move MSAA selection to Renderer - Expose supported MSAA flags. - Display current MSAA in stats. * Log GPU name, swapchain, renderer metadata, etc.
1 parent a541780 commit 7a237d9

File tree

13 files changed

+134
-110
lines changed

13 files changed

+134
-110
lines changed
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
#pragma once
2+
#include <facade/editor/common.hpp>
23
#include <facade/util/enum_array.hpp>
34
#include <facade/util/logger.hpp>
45
#include <vector>
56

67
namespace facade::editor {
78
class Log : public logger::Accessor {
89
public:
9-
void render();
10-
11-
bool show{};
10+
void render(NotClosed<Window> window);
1211

1312
private:
1413
void operator()(std::span<logger::Entry const> entries) final;
1514

1615
std::vector<logger::Entry const*> m_list{};
1716
EnumArray<logger::Level, bool> m_level_filter{true, true, true, debug_v};
1817
int m_display_count{50};
18+
bool m_auto_scroll{true};
1919
};
2020
} // namespace facade::editor

lib/editor/src/log.cpp

Lines changed: 39 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,57 @@
11
#include <imgui.h>
2+
#include <imgui_internal.h>
23
#include <facade/editor/common.hpp>
34
#include <facade/editor/log.hpp>
45
#include <facade/util/fixed_string.hpp>
56

67
namespace facade::editor {
7-
void Log::render() {
8-
ImGui::SetNextWindowSize({500.0f, 200.0f}, ImGuiCond_Once);
9-
if (auto window = editor::Window{"Log", &show}) {
10-
ImGui::Text("%s", FixedString{"Count: {}", m_display_count}.c_str());
11-
ImGui::SameLine();
12-
float spacing = ImGui::GetStyle().ItemInnerSpacing.x;
13-
ImGui::PushButtonRepeat(true);
14-
if (ImGui::ArrowButton("##left", ImGuiDir_Left)) { m_display_count = std::clamp(m_display_count - 10, 0, 1000); }
15-
ImGui::SameLine(0.0f, spacing);
16-
if (ImGui::ArrowButton("##right", ImGuiDir_Right)) { m_display_count = std::clamp(m_display_count + 10, 0, 1000); }
17-
ImGui::PopButtonRepeat();
8+
void Log::render(NotClosed<Window> window) {
9+
ImGui::Text("%s", FixedString{"Count: {}", m_display_count}.c_str());
10+
ImGui::SameLine();
11+
float spacing = ImGui::GetStyle().ItemInnerSpacing.x;
12+
ImGui::PushButtonRepeat(true);
13+
auto const max_logs = static_cast<int>(logger::buffer_size().total());
14+
if (ImGui::ArrowButton("##left", ImGuiDir_Left)) { m_display_count = std::clamp(m_display_count - 10, 0, max_logs); }
15+
ImGui::SameLine(0.0f, spacing);
16+
if (ImGui::ArrowButton("##right", ImGuiDir_Right)) { m_display_count = std::clamp(m_display_count + 10, 0, max_logs); }
17+
ImGui::PopButtonRepeat();
1818

19-
static constexpr std::string_view levels_v[] = {"Error", "Warn", "Info", "Debug"};
20-
static constexpr auto max_log_level_v = debug_v ? logger::Level::eDebug : logger::Level::eInfo;
21-
for (logger::Level l = logger::Level::eError; l <= max_log_level_v; l = static_cast<logger::Level>(static_cast<int>(l) + 1)) {
22-
ImGui::SameLine();
23-
ImGui::Checkbox(levels_v[static_cast<std::size_t>(l)].data(), &m_level_filter[l]);
24-
}
19+
static constexpr std::string_view levels_v[] = {"Error", "Warn", "Info", "Debug"};
20+
static constexpr auto max_log_level_v = debug_v ? logger::Level::eDebug : logger::Level::eInfo;
21+
for (logger::Level l = logger::Level::eError; l <= max_log_level_v; l = static_cast<logger::Level>(static_cast<int>(l) + 1)) {
22+
ImGui::SameLine();
23+
ImGui::Checkbox(levels_v[static_cast<std::size_t>(l)].data(), &m_level_filter[l]);
24+
}
25+
ImGui::SameLine();
26+
ImGui::SeparatorEx(ImGuiSeparatorFlags_Vertical);
27+
ImGui::SameLine();
28+
ImGui::Checkbox("Auto-scroll", &m_auto_scroll);
2529

26-
logger::access_buffer(*this);
27-
auto child = editor::Window{window, "scroll", {}, {}, ImGuiWindowFlags_HorizontalScrollbar};
28-
static constexpr auto im_colour = [](logger::Level const l) {
29-
switch (l) {
30-
case logger::Level::eError: return ImVec4{1.0f, 0.0f, 0.0f, 1.0f};
31-
case logger::Level::eWarn: return ImVec4{1.0f, 1.0f, 0.0f, 1.0f};
32-
default:
33-
case logger::Level::eInfo: return ImVec4{1.0f, 1.0f, 1.0f, 1.0f};
34-
case logger::Level::eDebug: return ImVec4{0.5f, 0.5f, 0.5f, 1.0f};
35-
}
36-
};
37-
if (auto style = editor::StyleVar{ImGuiStyleVar_ItemSpacing, glm::vec2{}}) {
38-
for (auto const* entry : m_list) ImGui::TextColored(im_colour(entry->level), "%s", entry->message.c_str());
30+
ImGui::Separator();
31+
logger::access_buffer(*this);
32+
auto child = editor::Window{window, "scroll", {}, {}, ImGuiWindowFlags_HorizontalScrollbar};
33+
static constexpr auto im_colour = [](logger::Level const l) {
34+
switch (l) {
35+
case logger::Level::eError: return ImVec4{1.0f, 0.0f, 0.0f, 1.0f};
36+
case logger::Level::eWarn: return ImVec4{1.0f, 1.0f, 0.0f, 1.0f};
37+
default:
38+
case logger::Level::eInfo: return ImVec4{1.0f, 1.0f, 1.0f, 1.0f};
39+
case logger::Level::eDebug: return ImVec4{0.5f, 0.5f, 0.5f, 1.0f};
3940
}
41+
};
42+
auto span = std::span{m_list};
43+
auto const max_size = static_cast<std::size_t>(m_display_count);
44+
if (span.size() > max_size) { span = span.subspan(span.size() - max_size); }
45+
if (auto style = editor::StyleVar{ImGuiStyleVar_ItemSpacing, glm::vec2{}}) {
46+
for (auto const* entry : span) ImGui::TextColored(im_colour(entry->level), "%s", entry->message.c_str());
4047
}
48+
49+
if (m_auto_scroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY()) { ImGui::SetScrollHereY(1.0f); }
4150
}
4251

4352
void Log::operator()(std::span<logger::Entry const> entries) {
4453
m_list.clear();
4554
for (auto const& entry : entries) {
46-
if (m_list.size() >= static_cast<std::size_t>(m_display_count)) { break; }
4755
if (!m_level_filter[entry.level]) { continue; }
4856
m_list.push_back(&entry);
4957
}

lib/engine/src/engine.cpp

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,31 +12,17 @@ UniqueWin make_window(glm::ivec2 extent, char const* title) {
1212
glfwSetWindowSize(ret.get(), extent.x, extent.y);
1313
return ret;
1414
}
15-
16-
constexpr auto get_samples(vk::SampleCountFlags supported, std::uint8_t desired) {
17-
if (desired >= 32 && (supported & vk::SampleCountFlagBits::e32)) { return vk::SampleCountFlagBits::e32; }
18-
if (desired >= 16 && (supported & vk::SampleCountFlagBits::e16)) { return vk::SampleCountFlagBits::e16; }
19-
if (desired >= 8 && (supported & vk::SampleCountFlagBits::e8)) { return vk::SampleCountFlagBits::e8; }
20-
if (desired >= 4 && (supported & vk::SampleCountFlagBits::e4)) { return vk::SampleCountFlagBits::e4; }
21-
if (desired >= 2 && (supported & vk::SampleCountFlagBits::e2)) { return vk::SampleCountFlagBits::e2; }
22-
return vk::SampleCountFlagBits::e1;
23-
}
24-
25-
Renderer::CreateInfo make_renderer_info(Gpu const& gpu, std::uint8_t sample_count) {
26-
return Renderer::CreateInfo{command_buffers_v, get_samples(gpu.properties.limits.framebufferColorSampleCounts, sample_count)};
27-
}
2815
} // namespace
2916

3017
struct Engine::Impl {
3118
UniqueWin window;
3219
Vulkan vulkan;
3320
Gfx gfx;
34-
3521
Renderer renderer;
3622

3723
Impl(CreateInfo const& info)
3824
: window(make_window(info.extent, info.title)), vulkan(GlfwWsi{window}), gfx{vulkan.gfx()},
39-
renderer(gfx, window, make_renderer_info(vulkan.gpu(), info.msaa_samples)) {}
25+
renderer(gfx, window, Renderer::CreateInfo{command_buffers_v, info.msaa_samples}) {}
4026
};
4127

4228
Engine::Engine(Engine&&) noexcept = default;

lib/render/include/facade/render/renderer.hpp

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
namespace facade {
1010
struct FrameStats {
11+
std::string_view gpu_name{};
1112
///
1213
/// \brief Total frames so far
1314
///
@@ -28,20 +29,23 @@ struct FrameStats {
2829
/// \brief Current present mode
2930
///
3031
vk::PresentModeKHR mode{};
32+
///
33+
/// \brief Multi-sampled anti-aliasing level
34+
///
35+
vk::SampleCountFlagBits msaa{};
3136
};
3237

3338
struct RendererCreateInfo {
3439
std::size_t command_buffers{1};
35-
vk::SampleCountFlagBits samples{vk::SampleCountFlagBits::e1};
40+
std::uint8_t desired_msaa{1};
3641
};
3742

3843
class Renderer {
3944
public:
4045
using CreateInfo = RendererCreateInfo;
4146

4247
struct Info {
43-
vk::PresentModeKHR mode{};
44-
vk::SampleCountFlagBits samples{};
48+
vk::SampleCountFlags supported_msaa{};
4549
ColourSpace colour_space{};
4650
std::size_t cbs_per_frame{};
4751
};

lib/render/src/renderer.cpp

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,15 @@ vk::Format depth_format(vk::PhysicalDevice const gpu) {
1717
return vk::Format::eD16Unorm;
1818
}
1919

20+
constexpr auto get_samples(vk::SampleCountFlags supported, std::uint8_t desired) {
21+
if (desired >= 32 && (supported & vk::SampleCountFlagBits::e32)) { return vk::SampleCountFlagBits::e32; }
22+
if (desired >= 16 && (supported & vk::SampleCountFlagBits::e16)) { return vk::SampleCountFlagBits::e16; }
23+
if (desired >= 8 && (supported & vk::SampleCountFlagBits::e8)) { return vk::SampleCountFlagBits::e8; }
24+
if (desired >= 4 && (supported & vk::SampleCountFlagBits::e4)) { return vk::SampleCountFlagBits::e4; }
25+
if (desired >= 2 && (supported & vk::SampleCountFlagBits::e2)) { return vk::SampleCountFlagBits::e2; }
26+
return vk::SampleCountFlagBits::e1;
27+
}
28+
2029
///
2130
/// \brief Tracks frames per second
2231
///
@@ -38,6 +47,8 @@ struct Fps {
3847

3948
struct Renderer::Impl {
4049
Gfx gfx;
50+
vk::SampleCountFlags supported_msaa{};
51+
vk::SampleCountFlagBits msaa{};
4152
Glfw::Window window;
4253
Swapchain swapchain;
4354

@@ -66,18 +77,20 @@ struct Renderer::Impl {
6677

6778
struct {
6879
FrameStats stats{};
80+
std::string gpu_name{};
6981
std::uint64_t triangles{}; // reset every frame
7082
std::uint32_t draw_calls{}; // reset every frame
7183
} stats{};
7284

7385
Impl(Gfx gfx, Glfw::Window window, Renderer::CreateInfo const& info)
74-
: gfx{gfx}, window{window}, swapchain{gfx, GlfwWsi{window}.make_surface(gfx.instance)}, pipes(gfx, info.samples),
75-
render_pass(gfx, info.samples, this->swapchain.info.imageFormat, depth_format(gfx.gpu)), render_frames(make_render_frames(gfx, info.command_buffers)),
86+
: gfx{gfx}, supported_msaa(gfx.gpu.getProperties().limits.framebufferColorSampleCounts),
87+
msaa(get_samples(supported_msaa, info.desired_msaa)), window{window}, swapchain{gfx, GlfwWsi{window}.make_surface(gfx.instance)}, pipes(gfx, msaa),
88+
render_pass(gfx, msaa, this->swapchain.info.imageFormat, depth_format(gfx.gpu)), render_frames(make_render_frames(gfx, info.command_buffers)),
7689
dear_imgui(DearImGui::CreateInfo{
7790
gfx,
7891
window,
7992
render_pass.render_pass(),
80-
info.samples,
93+
msaa,
8194
Swapchain::colour_space(swapchain.info.imageFormat),
8295
}) {}
8396

@@ -92,6 +105,10 @@ struct Renderer::Impl {
92105

93106
Renderer::Renderer(Gfx gfx, Glfw::Window window, CreateInfo const& info) : m_impl{std::make_unique<Impl>(std::move(gfx), window, info)} {
94107
m_impl->swapchain.refresh(Swapchain::Spec{window.framebuffer_extent()});
108+
m_impl->stats.gpu_name = m_impl->gfx.gpu.getProperties().deviceName.data();
109+
m_impl->stats.stats.gpu_name = m_impl->stats.gpu_name;
110+
m_impl->stats.stats.msaa = m_impl->msaa;
111+
logger::info("[Renderer] buffering (frames): [{}] | MSAA: [{}x] | max threads: [{}] |", buffering_v, to_int(m_impl->msaa), info.command_buffers);
95112
}
96113

97114
Renderer::Renderer(Renderer&&) noexcept = default;
@@ -100,8 +117,7 @@ Renderer::~Renderer() noexcept = default;
100117

101118
auto Renderer::info() const -> Info {
102119
return {
103-
.mode = m_impl->swapchain.info.presentMode,
104-
.samples = m_impl->render_pass.samples(),
120+
.supported_msaa = m_impl->supported_msaa,
105121
.colour_space = m_impl->swapchain.colour_space(),
106122
.cbs_per_frame = m_impl->render_frames.get().secondary.size(),
107123
};

lib/util/include/facade/util/logger.hpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,26 @@ struct Entry {
1616
Level level{};
1717
};
1818

19+
struct BufferSize {
20+
std::size_t limit{500};
21+
std::size_t delta{100};
22+
23+
constexpr std::size_t total() const { return limit + delta; }
24+
};
25+
1926
struct Accessor {
2027
virtual void operator()(std::span<Entry const> entries) = 0;
2128
};
2229

2330
int thread_id();
2431
std::string format(Level level, std::string_view const message);
2532
void log_to(Pipe pipe, Entry entry);
33+
BufferSize const& buffer_size();
2634
void access_buffer(Accessor& accessor);
2735

2836
class Instance : public Pinned {
2937
public:
30-
Instance(std::size_t buffer_limit = 500, std::size_t buffer_extra = 100);
38+
Instance(BufferSize const& buffer_size = {});
3139
~Instance();
3240
};
3341

lib/util/src/logger.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,7 @@ class FileLogger : Pinned {
8484

8585
struct Storage {
8686
struct Buffer {
87-
std::size_t limit{};
88-
std::size_t extra{};
87+
logger::BufferSize size{};
8988

9089
std::vector<logger::Entry> entries{};
9190
};
@@ -118,14 +117,16 @@ void logger::log_to(Pipe pipe, Entry entry) {
118117
g_storage.buffer.entries.push_back(std::move(entry));
119118
}
120119

120+
logger::BufferSize const& logger::buffer_size() { return g_storage.buffer.size; }
121+
121122
void logger::access_buffer(Accessor& accessor) {
122123
auto lock = std::scoped_lock{g_storage.mutex};
123124
accessor(g_storage.buffer.entries);
124125
}
125126

126-
logger::Instance::Instance(std::size_t buffer_limit, std::size_t buffer_extra) {
127+
logger::Instance::Instance(logger::BufferSize const& buffer_size) {
127128
auto lock = std::scoped_lock{g_storage.mutex};
128-
g_storage.buffer = Storage::Buffer{buffer_limit, buffer_extra};
129+
g_storage.buffer = Storage::Buffer{buffer_size};
129130
g_storage.file_logger.emplace("facade.log");
130131
}
131132

lib/vk/include/facade/vk/render_pass.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ class RenderPass {
1212
void bind(vk::CommandBuffer cb, vk::Pipeline pipeline);
1313
void execute(Framebuffer const& framebuffer, vk::ClearColorValue const& clear);
1414

15-
vk::SampleCountFlagBits samples() const { return m_samples; }
1615
vk::RenderPass render_pass() const { return *m_render_pass; }
1716

1817
private:

lib/vk/include/facade/vk/vma.hpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ template <typename T, typename U = T>
88
using Pair = std::pair<T, U>;
99

1010
template <typename Type>
11-
concept BufferWrite = !std::is_pointer_v<Type> && std::is_trivially_destructible_v<Type>;
11+
concept BufferWrite = (!std::is_pointer_v<Type>) && std::is_trivially_destructible_v<Type>;
1212

1313
constexpr vk::Format srgb_formats_v[] = {vk::Format::eR8G8B8A8Srgb, vk::Format::eB8G8R8A8Srgb, vk::Format::eA8B8G8R8SrgbPack32};
1414
constexpr vk::Format linear_formats_v[] = {vk::Format::eR8G8B8A8Unorm, vk::Format::eB8G8R8A8Unorm};
@@ -30,6 +30,19 @@ constexpr std::string_view present_mode_str(vk::PresentModeKHR const mode) {
3030
}
3131
}
3232

33+
constexpr int to_int(vk::SampleCountFlagBits const samples) {
34+
switch (samples) {
35+
case vk::SampleCountFlagBits::e64: return 64;
36+
case vk::SampleCountFlagBits::e32: return 32;
37+
case vk::SampleCountFlagBits::e16: return 16;
38+
case vk::SampleCountFlagBits::e8: return 8;
39+
case vk::SampleCountFlagBits::e4: return 4;
40+
case vk::SampleCountFlagBits::e2: return 2;
41+
default:
42+
case vk::SampleCountFlagBits::e1: return 1;
43+
}
44+
}
45+
3346
struct BufferView {
3447
vk::Buffer buffer{};
3548
vk::DeviceSize size{};

lib/vk/src/render_pass.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,10 @@ vk::UniqueRenderPass create_render_pass(vk::Device device, vk::SampleCountFlagBi
6767
} // namespace
6868

6969
RenderPass::RenderPass(Gfx const& gfx, vk::SampleCountFlagBits samples, vk::Format colour, vk::Format depth)
70-
: m_gfx{gfx}, m_render_pass{create_render_pass(gfx.vma.device, samples, colour, depth)} {
70+
: m_gfx{gfx}, m_render_pass{create_render_pass(gfx.vma.device, samples, colour, depth)}, m_samples(samples) {
7171
m_colour.image = m_gfx.shared->defer_queue;
7272
m_depth.image = m_gfx.shared->defer_queue;
7373
m_depth.format = depth;
74-
m_samples = samples;
7574
if (m_samples > vk::SampleCountFlagBits::e1) { m_colour.format = colour; }
7675
}
7776

lib/vk/src/swapchain.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#include <facade/util/logger.hpp>
12
#include <facade/vk/swapchain.hpp>
23
#include <cassert>
34
#include <limits>
@@ -85,6 +86,7 @@ vk::Result Swapchain::refresh(Spec const& spec) {
8586
m_storage.views.insert(m_gfx.vma.make_image_view(image, info.imageFormat));
8687
m_storage.images.insert({image, *m_storage.views.span().back(), info.imageExtent});
8788
}
89+
logger::info("[Swapchain] images: [{}] | colour space: [{}] |", m_storage.images.size(), is_srgb(info.imageFormat) ? "sRGB" : "linear");
8890
return ret;
8991
}
9092

lib/vk/src/vk.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,12 +171,13 @@ UniqueVma Vulkan::make_vma(vk::Instance instance, vk::PhysicalDevice gpu, vk::De
171171
return ret;
172172
}
173173

174-
Vulkan ::Vulkan(Wsi const& wsi) noexcept(false) {
174+
Vulkan::Vulkan(Wsi const& wsi) noexcept(false) {
175175
instance = Vulkan::Instance::make(wsi.extensions(), Vulkan::eValidation);
176176
auto surface = wsi.make_surface(*instance.instance);
177177
device = Vulkan::Device::make(instance, *surface);
178178
vma = Vulkan::make_vma(*instance.instance, device.gpu.device, *device.device);
179179
shared = std::make_unique<Gfx::Shared>(*device.device, device.gpu.properties);
180+
logger::info("[Device] GPU: [{}] |", device.gpu.properties.deviceName.data());
180181
}
181182

182183
Gfx Vulkan::gfx() const {

0 commit comments

Comments
 (0)