better debug

This commit is contained in:
Richard Ward
2025-12-19 11:25:05 +00:00
parent 42545375cf
commit 4cf3f2d2f0
9 changed files with 93 additions and 1 deletions

View File

@@ -1,4 +1,5 @@
#include "app/sdl3_app.hpp"
#include "app/trace.hpp"
#include <cstring>
#include <stdexcept>
@@ -8,6 +9,7 @@
namespace sdl3cpp::app {
void Sdl3App::LoadSceneData() {
TRACE_FUNCTION();
shaderPathMap_ = cubeScript_.LoadShaderPathsMap();
if (shaderPathMap_.empty()) {
throw std::runtime_error("Lua script did not provide shader paths");
@@ -52,6 +54,7 @@ void Sdl3App::LoadSceneData() {
}
void Sdl3App::CreateVertexBuffer() {
TRACE_FUNCTION();
VkDeviceSize bufferSize = sizeof(vertices_[0]) * vertices_.size();
vulkan::CreateBuffer(device_, physicalDevice_, bufferSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, vertexBuffer_,
@@ -64,6 +67,7 @@ void Sdl3App::CreateVertexBuffer() {
}
void Sdl3App::CreateIndexBuffer() {
TRACE_FUNCTION();
VkDeviceSize bufferSize = sizeof(indices_[0]) * indices_.size();
vulkan::CreateBuffer(device_, physicalDevice_, bufferSize, VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, indexBuffer_,

View File

@@ -1,10 +1,12 @@
#include "app/sdl3_app.hpp"
#include "app/trace.hpp"
#include <stdexcept>
namespace sdl3cpp::app {
void Sdl3App::CreateFramebuffers() {
TRACE_FUNCTION();
swapChainFramebuffers_.resize(swapChainImageViews_.size());
for (size_t i = 0; i < swapChainImageViews_.size(); ++i) {
VkImageView attachments[] = {swapChainImageViews_[i]};
@@ -26,6 +28,7 @@ void Sdl3App::CreateFramebuffers() {
}
void Sdl3App::CreateCommandPool() {
TRACE_FUNCTION();
QueueFamilyIndices indices = FindQueueFamilies(physicalDevice_);
VkCommandPoolCreateInfo poolInfo{};
@@ -39,6 +42,7 @@ void Sdl3App::CreateCommandPool() {
}
void Sdl3App::CreateSyncObjects() {
TRACE_FUNCTION();
VkSemaphoreCreateInfo semaphoreInfo{};
semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;

View File

@@ -1,4 +1,5 @@
#include "app/sdl3_app.hpp"
#include "app/trace.hpp"
#include <chrono>
#include <fstream>
@@ -12,6 +13,7 @@
namespace sdl3cpp::app {
std::vector<char> ReadFile(const std::string& path) {
TRACE_FUNCTION();
std::ifstream file(path, std::ios::ate | std::ios::binary);
if (!file) {
throw std::runtime_error("failed to open file: " + path);
@@ -79,9 +81,12 @@ void ThrowSdlErrorIfFailed(int result, const char* context) {
} // namespace
Sdl3App::Sdl3App(const std::filesystem::path& scriptPath) : cubeScript_(scriptPath) {}
Sdl3App::Sdl3App(const std::filesystem::path& scriptPath) : cubeScript_(scriptPath) {
TRACE_FUNCTION();
}
void Sdl3App::Run() {
TRACE_FUNCTION();
InitSDL();
InitVulkan();
MainLoop();
@@ -89,6 +94,7 @@ void Sdl3App::Run() {
}
void Sdl3App::InitSDL() {
TRACE_FUNCTION();
ThrowSdlErrorIfFailed(SDL_Init(SDL_INIT_VIDEO), "SDL_Init failed");
ThrowSdlErrorIfFailed(SDL_Vulkan_LoadLibrary(nullptr), "SDL_Vulkan_LoadLibrary failed");
window_ = SDL_CreateWindow("SDL3 Vulkan Demo", kWidth, kHeight, SDL_WINDOW_VULKAN | SDL_WINDOW_RESIZABLE);
@@ -99,6 +105,7 @@ void Sdl3App::InitSDL() {
}
void Sdl3App::InitVulkan() {
TRACE_FUNCTION();
CreateInstance();
CreateSurface();
PickPhysicalDevice();
@@ -118,6 +125,7 @@ void Sdl3App::InitVulkan() {
}
void Sdl3App::MainLoop() {
TRACE_FUNCTION();
bool running = true;
auto start = std::chrono::steady_clock::now();
while (running) {
@@ -156,6 +164,7 @@ void Sdl3App::MainLoop() {
}
void Sdl3App::Cleanup() {
TRACE_FUNCTION();
CleanupSwapChain();
vkDestroyBuffer(device_, vertexBuffer_, nullptr);

View File

@@ -1,4 +1,5 @@
#include "app/sdl3_app.hpp"
#include "app/trace.hpp"
#include <set>
#include <stdexcept>
@@ -7,6 +8,7 @@
namespace sdl3cpp::app {
void Sdl3App::CreateInstance() {
TRACE_FUNCTION();
VkApplicationInfo appInfo{};
appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
appInfo.pApplicationName = "SDL3 Vulkan";
@@ -35,12 +37,14 @@ void Sdl3App::CreateInstance() {
}
void Sdl3App::CreateSurface() {
TRACE_FUNCTION();
if (!SDL_Vulkan_CreateSurface(window_, instance_, nullptr, &surface_)) {
throw std::runtime_error("Failed to create Vulkan surface");
}
}
void Sdl3App::PickPhysicalDevice() {
TRACE_FUNCTION();
uint32_t deviceCount = 0;
vkEnumeratePhysicalDevices(instance_, &deviceCount, nullptr);
if (deviceCount == 0) {
@@ -62,6 +66,7 @@ void Sdl3App::PickPhysicalDevice() {
}
void Sdl3App::CreateLogicalDevice() {
TRACE_FUNCTION();
QueueFamilyIndices indices = FindQueueFamilies(physicalDevice_);
std::vector<VkDeviceQueueCreateInfo> queueCreateInfos;
@@ -96,6 +101,7 @@ void Sdl3App::CreateLogicalDevice() {
}
QueueFamilyIndices Sdl3App::FindQueueFamilies(VkPhysicalDevice device) {
TRACE_FUNCTION();
QueueFamilyIndices indices;
uint32_t queueFamilyCount = 0;
@@ -127,6 +133,7 @@ QueueFamilyIndices Sdl3App::FindQueueFamilies(VkPhysicalDevice device) {
}
bool Sdl3App::CheckDeviceExtensionSupport(VkPhysicalDevice device) {
TRACE_FUNCTION();
uint32_t extensionCount = 0;
vkEnumerateDeviceExtensionProperties(device, nullptr, &extensionCount, nullptr);
@@ -142,6 +149,7 @@ bool Sdl3App::CheckDeviceExtensionSupport(VkPhysicalDevice device) {
}
SwapChainSupportDetails Sdl3App::QuerySwapChainSupport(VkPhysicalDevice device) {
TRACE_FUNCTION();
SwapChainSupportDetails details;
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device, surface_, &details.capabilities);
@@ -164,6 +172,7 @@ SwapChainSupportDetails Sdl3App::QuerySwapChainSupport(VkPhysicalDevice device)
}
bool Sdl3App::IsDeviceSuitable(VkPhysicalDevice device) {
TRACE_FUNCTION();
QueueFamilyIndices indices = FindQueueFamilies(device);
bool extensionsSupported = CheckDeviceExtensionSupport(device);

View File

@@ -1,4 +1,5 @@
#include "app/sdl3_app.hpp"
#include "app/trace.hpp"
#include <array>
#include <stdexcept>
@@ -6,6 +7,7 @@
namespace sdl3cpp::app {
VkShaderModule Sdl3App::CreateShaderModule(const std::vector<char>& code) {
TRACE_FUNCTION();
VkShaderModuleCreateInfo createInfo{};
createInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
createInfo.codeSize = code.size();
@@ -19,6 +21,7 @@ VkShaderModule Sdl3App::CreateShaderModule(const std::vector<char>& code) {
}
void Sdl3App::CreateGraphicsPipeline() {
TRACE_FUNCTION();
if (shaderPathMap_.empty()) {
throw std::runtime_error("No shader paths were loaded before pipeline creation");
}

View File

@@ -1,4 +1,5 @@
#include "app/sdl3_app.hpp"
#include "app/trace.hpp"
#include <limits>
#include <stdexcept>
@@ -21,6 +22,7 @@ const std::unordered_map<SDL_Keycode, std::string> kGuiKeyNames = {
namespace sdl3cpp::app {
void Sdl3App::CreateCommandBuffers() {
TRACE_FUNCTION();
commandBuffers_.resize(swapChainFramebuffers_.size());
VkCommandBufferAllocateInfo allocInfo{};
@@ -36,6 +38,7 @@ void Sdl3App::CreateCommandBuffers() {
void Sdl3App::RecordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex, float time,
const std::array<float, 16>& viewProj) {
TRACE_FUNCTION();
VkCommandBufferBeginInfo beginInfo{};
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
@@ -82,6 +85,7 @@ void Sdl3App::RecordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageI
}
void Sdl3App::ProcessGuiEvent(const SDL_Event& event) {
TRACE_FUNCTION();
switch (event.type) {
case SDL_EVENT_MOUSE_MOTION:
guiInputSnapshot_.mouseX = static_cast<float>(event.motion.x);
@@ -114,6 +118,7 @@ void Sdl3App::ProcessGuiEvent(const SDL_Event& event) {
}
void Sdl3App::SetupGuiRenderer() {
TRACE_FUNCTION();
guiHasCommands_ = cubeScript_.HasGuiCommands();
if (!guiHasCommands_) {
guiRenderer_.reset();
@@ -128,6 +133,7 @@ void Sdl3App::SetupGuiRenderer() {
}
void Sdl3App::DrawFrame(float time) {
TRACE_FUNCTION();
vkWaitForFences(device_, 1, &inFlightFence_, VK_TRUE, std::numeric_limits<uint64_t>::max());
vkResetFences(device_, 1, &inFlightFence_);

View File

@@ -1,4 +1,5 @@
#include "app/sdl3_app.hpp"
#include "app/trace.hpp"
#include "app/vulkan_api.hpp"
#include <stdexcept>
@@ -6,6 +7,7 @@
namespace sdl3cpp::app {
void Sdl3App::CreateSwapChain() {
TRACE_FUNCTION();
SwapChainSupportDetails support = QuerySwapChainSupport(physicalDevice_);
VkSurfaceFormatKHR surfaceFormat = ChooseSwapSurfaceFormat(support.formats);
@@ -55,6 +57,7 @@ void Sdl3App::CreateSwapChain() {
}
void Sdl3App::CreateImageViews() {
TRACE_FUNCTION();
swapChainImageViews_.resize(swapChainImages_.size());
for (size_t i = 0; i < swapChainImages_.size(); ++i) {
VkImageViewCreateInfo viewInfo{};
@@ -77,6 +80,7 @@ void Sdl3App::CreateImageViews() {
}
void Sdl3App::CreateRenderPass() {
TRACE_FUNCTION();
VkAttachmentDescription colorAttachment{};
colorAttachment.format = swapChainImageFormat_;
colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
@@ -119,6 +123,7 @@ void Sdl3App::CreateRenderPass() {
}
void Sdl3App::CleanupSwapChain() {
TRACE_FUNCTION();
for (auto framebuffer : swapChainFramebuffers_) {
vkDestroyFramebuffer(device_, framebuffer, nullptr);
}
@@ -140,6 +145,7 @@ void Sdl3App::CleanupSwapChain() {
}
void Sdl3App::RecreateSwapChain() {
TRACE_FUNCTION();
int width = 0;
int height = 0;
while (width == 0 || height == 0) {
@@ -160,6 +166,7 @@ void Sdl3App::RecreateSwapChain() {
}
VkSurfaceFormatKHR Sdl3App::ChooseSwapSurfaceFormat(const std::vector<VkSurfaceFormatKHR>& availableFormats) {
TRACE_FUNCTION();
for (const auto& availableFormat : availableFormats) {
if (availableFormat.format == VK_FORMAT_B8G8R8A8_SRGB &&
availableFormat.colorSpace == VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) {
@@ -170,6 +177,7 @@ VkSurfaceFormatKHR Sdl3App::ChooseSwapSurfaceFormat(const std::vector<VkSurfaceF
}
VkPresentModeKHR Sdl3App::ChooseSwapPresentMode(const std::vector<VkPresentModeKHR>& availablePresentModes) {
TRACE_FUNCTION();
for (const auto& availablePresentMode : availablePresentModes) {
if (availablePresentMode == VK_PRESENT_MODE_MAILBOX_KHR) {
return availablePresentMode;

43
src/app/trace.hpp Normal file
View File

@@ -0,0 +1,43 @@
#ifndef SDL3CPP_APP_TRACE_HPP
#define SDL3CPP_APP_TRACE_HPP
#include <atomic>
#include <iostream>
namespace sdl3cpp::app {
class TraceLogger {
public:
static void SetEnabled(bool enabled) noexcept {
enabled_.store(enabled, std::memory_order_relaxed);
}
static bool Enabled() noexcept {
return enabled_.load(std::memory_order_relaxed);
}
static void Log(const char* message) {
if (Enabled()) {
std::cout << "[TRACE] " << message << '\n';
}
}
private:
static inline std::atomic_bool enabled_{false};
};
class TraceScope {
public:
explicit TraceScope(const char* name) : name_(name) {
TraceLogger::Log(name_);
}
private:
const char* name_;
};
} // namespace sdl3cpp::app
#define TRACE_FUNCTION() sdl3cpp::app::TraceScope traceScope##__COUNTER__{__func__}
#endif // SDL3CPP_APP_TRACE_HPP

View File

@@ -14,6 +14,7 @@
#include <string>
#include <utility>
#include "app/trace.hpp"
#include "app/sdl3_app.hpp"
namespace {
@@ -156,6 +157,7 @@ struct AppOptions {
std::optional<std::filesystem::path> seedOutput;
bool saveDefaultJson = false;
bool dumpRuntimeJson = false;
bool traceEnabled = false;
};
AppOptions ParseCommandLine(int argc, char** argv) {
@@ -163,6 +165,7 @@ AppOptions ParseCommandLine(int argc, char** argv) {
std::string seedOutputText;
std::string setDefaultJsonPath;
bool dumpRuntimeJson = false;
bool traceRuntime = false;
CLI::App app("SDL3 + Vulkan runtime helper");
app.add_option("-j,--json-file-in", jsonInputText, "Path to a runtime JSON config")
@@ -177,6 +180,7 @@ AppOptions ParseCommandLine(int argc, char** argv) {
setDefaultJsonOption->type_size(1, 1);
setDefaultJsonOption->expected(0, 1);
app.add_flag("--dump-json", dumpRuntimeJson, "Print the runtime JSON that was loaded");
app.add_flag("--trace", traceRuntime, "Emit a log line when key functions/methods run");
try {
app.parse(argc, argv);
@@ -214,6 +218,7 @@ AppOptions ParseCommandLine(int argc, char** argv) {
}
options.saveDefaultJson = shouldSaveDefault;
options.dumpRuntimeJson = dumpRuntimeJson;
options.traceEnabled = traceRuntime;
return options;
}
@@ -275,6 +280,7 @@ void WriteRuntimeConfigJson(const RuntimeConfig& runtimeConfig,
int main(int argc, char** argv) {
try {
AppOptions options = ParseCommandLine(argc, argv);
TraceLogger::SetEnabled(options.traceEnabled);
if (options.seedOutput) {
WriteRuntimeConfigJson(options.runtimeConfig, *options.seedOutput);
}