New logger

This commit is contained in:
2026-10-04 23:14:17 -07:00
parent b31c120691
commit b6098d4dc6
19 changed files with 191 additions and 170 deletions
+1 -12
View File
@@ -35,17 +35,6 @@ namespace sophia {
namespace {
struct Vertex {
glm::vec2 position;
glm::vec3 color;
};
struct PushConstants {
glm::mat4 transform;
glm::vec4 color;
glm::vec4 data;
};
std::vector<std::string> commandLineArgs;
constexpr ClearColor CLEAR_COLOR = {0.01f, 0.01f, 0.02f, 1.0f};
@@ -287,7 +276,7 @@ class Application::Impl {
auto endTime = std::chrono::high_resolution_clock::now();
double totalRuntime =
std::chrono::duration<double>(endTime - startTime).count();
log::info("Application ran for", totalRuntime, "s");
log::info("Application ran for {:.2f}s", totalRuntime);
}
void pushMesh(std::vector<CanvasVertex> vertices, std::vector<u32> indices) {
+3 -2
View File
@@ -43,8 +43,9 @@ void MeshRenderSystem::render(vk::CommandBuffer commandBuffer,
u32 available = MAX_INSTANCES_PER_FRAME - this->instanceCursor;
if (instances.size() > available) {
log::warning("MeshRenderSystem: frame instance buffer full, dropping",
instances.size() - available, "meshes");
log::warning(
"MeshRenderSystem: frame instance buffer full, dropping {} meshes",
instances.size() - available);
}
Buffer& buffer = *this->instanceBuffers[this->frameIndex];
+2 -2
View File
@@ -38,7 +38,7 @@ vk::CommandBuffer RenderContext::beginFrame() {
}
if (fenceResult != vk::Result::eSuccess) {
log::error("failed to wait for fence: " + vk::to_string(fenceResult));
log::error("failed to wait for fence: {}", vk::to_string(fenceResult));
}
vk::Semaphore imageAvailable = frame.imageAvailable.get();
@@ -62,7 +62,7 @@ vk::CommandBuffer RenderContext::beginFrame() {
imageInFlight, vk::True, std::numeric_limits<u64>::max());
if (fenceResult != vk::Result::eSuccess) {
log::error("failed to wait for fence: " + vk::to_string(fenceResult));
log::error("failed to wait for fence: {}", vk::to_string(fenceResult));
}
}
+8 -8
View File
@@ -106,8 +106,8 @@ void RenderGraph::recordRendering(vk::CommandBuffer commandBuffer, Pass& pass) {
const Image& image = *this->images[color.image.index].image;
SOPHIA_ASSERT(image.getExtent().width == extent.width &&
image.getExtent().height == extent.height,
"Pass", pass.name,
"has color attachments of different sizes");
"Pass {} has color attachments of different sizes",
pass.name);
vk::RenderingAttachmentInfo attachment{};
attachment.imageView = image.getView();
@@ -129,8 +129,8 @@ void RenderGraph::recordRendering(vk::CommandBuffer commandBuffer, Pass& pass) {
const Image& image = *this->images[pass.depthAttachment->image.index].image;
SOPHIA_ASSERT(image.getExtent().width == extent.width &&
image.getExtent().height == extent.height,
"Pass", pass.name,
"has a depth attachment of a different size");
"Pass {} has a depth attachment of a different size",
pass.name);
depthAttachment.imageView = image.getView();
depthAttachment.imageLayout =
@@ -168,8 +168,8 @@ RenderGraph::PassBuilder& RenderGraph::PassBuilder::writeColor(
RenderGraph::PassBuilder& RenderGraph::PassBuilder::writeDepth(
ImageRef image, vk::AttachmentLoadOp loadOp, float clearDepth) {
SOPHIA_ASSERT(!this->pass.depthAttachment, "Pass", this->pass.name,
"already has a depth attachment");
SOPHIA_ASSERT(!this->pass.depthAttachment,
"Pass {} already has a depth attachment", this->pass.name);
this->use(image, Access::DepthWrite);
this->pass.depthAttachment = DepthAttachment{image, loadOp, clearDepth};
return *this;
@@ -184,8 +184,8 @@ RenderGraph::PassBuilder& RenderGraph::PassBuilder::use(ImageRef image,
SOPHIA_ASSERT(image.isValid() && image.index < this->graph.images.size(),
"ImageRef doesn't belong to this graph");
for (const ImageUse& existing : this->pass.uses) {
SOPHIA_ASSERT(existing.image.index != image.index, "Pass", this->pass.name,
"uses the same image twice");
SOPHIA_ASSERT(existing.image.index != image.index,
"Pass {} uses the same image twice", this->pass.name);
}
this->pass.uses.push_back({image, access});
+3 -2
View File
@@ -45,8 +45,9 @@ void SpriteRenderSystem::render(vk::CommandBuffer commandBuffer,
u32 available = MAX_INSTANCES_PER_FRAME - this->instanceCursor;
if (instances.size() > available) {
log::warning("SpriteRenderSystem: frame instance buffer full, dropping",
instances.size() - available, "sprites");
log::warning(
"SpriteRenderSystem: frame instance buffer full, dropping {} sprites",
instances.size() - available);
}
Buffer& buffer = *this->instanceBuffers[this->frameIndex];
@@ -26,7 +26,7 @@ TextureHandle ResourceRegistryRef::load<Texture>(const std::string& path) {
// Always decode to RGBA8, whatever the file has.
stbi_uc* pixels = stbi_load(path.c_str(), &width, &height, &channels, 4);
if (pixels == nullptr) {
log::fatal("failed to load texture", path, "-", stbi_failure_reason());
log::fatal("failed to load texture {} - {}", path, stbi_failure_reason());
throw std::runtime_error("failed to load texture: " + path);
}
+1 -1
View File
@@ -75,7 +75,7 @@ AccessState getStateForLayout(vk::ImageLayout layout) {
}
}
log::fatal("Unsupported image layout:", vk::to_string(layout));
log::fatal("Unsupported image layout: {}", vk::to_string(layout));
throw std::runtime_error("Unsupported image layout.");
}
+17 -16
View File
@@ -2,6 +2,7 @@
#include <string.h>
#include <iostream>
#include <set>
#include <sophia/util/logger.hpp>
@@ -19,16 +20,16 @@ debugCallback(vk::DebugUtilsMessageSeverityFlagBitsEXT m_severity,
(void)pUser_data;
if (m_severity == vk::DebugUtilsMessageSeverityFlagBitsEXT::eError) {
log::error(pCallback_data->pMessage);
log::error("{}", pCallback_data->pMessage);
return VK_SUCCESS;
} else if (m_severity == vk::DebugUtilsMessageSeverityFlagBitsEXT::eWarning) {
log::warning(pCallback_data->pMessage);
log::warning("{}", pCallback_data->pMessage);
} else if (m_severity == vk::DebugUtilsMessageSeverityFlagBitsEXT::eInfo) {
log::info(pCallback_data->pMessage);
log::info("{}", pCallback_data->pMessage);
} else if (m_severity == vk::DebugUtilsMessageSeverityFlagBitsEXT::eVerbose) {
log::verbose(pCallback_data->pMessage);
log::verbose("{}", pCallback_data->pMessage);
} else {
log::info(pCallback_data->pMessage);
log::info("{}", pCallback_data->pMessage);
}
return VK_FALSE;
@@ -107,8 +108,8 @@ static void forEachRequiredFeature(DeviceFeatureChain& chain, Fn&& fn) {
static bool checkDeviceFeatureSupport(const vk::PhysicalDevice& device) {
vk::PhysicalDeviceProperties properties = device.getProperties();
if (properties.apiVersion < SOPHIA_VULKAN_API_VERSION) {
log::verbose("Skipping ", properties.deviceName,
": Vulkan 1.3 not supported");
log::verbose("Skipping {}: Vulkan 1.3 not supported",
properties.deviceName.data());
return false;
}
@@ -119,8 +120,8 @@ static bool checkDeviceFeatureSupport(const vk::PhysicalDevice& device) {
bool allSupported = true;
forEachRequiredFeature(supported, [&](vk::Bool32 has, const char* name) {
if (!has) {
log::verbose("Skipping ", properties.deviceName,
": missing device feature ", name);
log::verbose("Skipping {}: missing device feature {}",
properties.deviceName.data(), name);
allSupported = false;
}
});
@@ -197,7 +198,7 @@ void Device::createBuffer(vk::DeviceSize size, vk::BufferUsageFlags usage,
this->allocator, &static_cast<const VkBufferCreateInfo&>(bufferInfo),
&allocInfo, &rawBuffer, &allocation, nullptr);
if (result != VK_SUCCESS) {
log::fatal("failed to create buffer. Error: ",
log::fatal("failed to create buffer. Error: {}",
vk::to_string(static_cast<vk::Result>(result)));
throw std::runtime_error("failed to create buffer");
}
@@ -220,7 +221,7 @@ vk::CommandBuffer Device::beginSingleTimeCommands() {
throw vk::SystemError(result);
}
} catch (const vk::SystemError& error) {
log::error("failed to allocate single time commandBuffer. Error: ",
log::error("failed to allocate single time commandBuffer. Error: {}",
error.what());
throw std::runtime_error("failed to allocate single time commandBuffer");
}
@@ -234,7 +235,7 @@ vk::CommandBuffer Device::beginSingleTimeCommands() {
throw vk::SystemError(result);
}
} catch (const vk::SystemError& error) {
log::error("failed to begin single time commandBuffer. Error: ",
log::error("failed to begin single time commandBuffer. Error: {}",
error.what());
throw std::runtime_error("failed to begin single time commandBuffer");
}
@@ -278,7 +279,7 @@ void Device::createImageWithInfo(const vk::ImageCreateInfo& imageInfo,
this->allocator, &static_cast<const VkImageCreateInfo&>(imageInfo),
&allocInfo, &rawImage, &allocation, nullptr);
if (result != VK_SUCCESS) {
log::fatal("failed to create image. Error: ",
log::fatal("failed to create image. Error: {}",
vk::to_string(static_cast<vk::Result>(result)));
throw std::runtime_error("failed to create image");
}
@@ -374,7 +375,7 @@ std::vector<const char*> Device::getRequiredExtensions() {
throw std::exception();
}
log::verbose("Number of available extensions: ", available_extension_count);
log::verbose("Number of available extensions: {}", available_extension_count);
log::verbose("Available extensions:");
for (const auto& e : available_extensions) {
@@ -482,7 +483,7 @@ void Device::pickPhysicalDevice() {
log::fatal("Failed to find any physical devices.");
throw std::exception();
}
log::verbose("Physical Devices count: ", physicalDevices.size());
log::verbose("Physical Devices count: {}", physicalDevices.size());
// Select first physical device that is suitable
for (const auto& device : physicalDevices) {
@@ -498,7 +499,7 @@ void Device::pickPhysicalDevice() {
}
this->properties = this->physicalDevice.getProperties();
log::verbose("Physical Device: ", this->properties.deviceName);
log::verbose("Physical Device: {}", this->properties.deviceName.data());
}
void Device::createLogicalDevice() {
+8 -8
View File
@@ -25,7 +25,7 @@ std::vector<char> readFile(const std::string& path) {
std::ifstream file(path, std::ios::ate | std::ios::binary);
if (!file.is_open()) {
log::error("failed to open shader: " + path);
log::error("failed to open shader: {}", path);
throw std::runtime_error("failed to open: " + path);
}
@@ -46,22 +46,23 @@ void Shader::compile(const std::string& path, ShaderStage shaderStage) {
std::vector<char> source = readFile(path);
log::info("Compiling shader: " + path);
log::info("Compiling shader: {}", path);
shaderc::Compiler compiler;
shaderc::SpvCompilationResult result = compiler.CompileGlslToSpv(
source.data(), source.size(), toShadercKind(shaderStage), path.c_str());
if (result.GetCompilationStatus() != shaderc_compilation_status_success) {
log::fatal("failed to compile shader:", path, result.GetErrorMessage());
log::fatal("failed to compile shader: {}: {}", path,
result.GetErrorMessage());
throw std::runtime_error("failed to compile shader: " + path + ": " +
result.GetErrorMessage());
}
this->spirv.assign(result.cbegin(), result.cend());
log::info("Successfully compiled shader: " + path + " (" +
std::to_string(this->spirv.size() * 4) + " bytes)");
log::info("Successfully compiled shader: {} ({} bytes)", path,
this->spirv.size() * 4);
}
void Shader::load(const std::string& path, ShaderStage shaderStage) {
@@ -70,15 +71,14 @@ void Shader::load(const std::string& path, ShaderStage shaderStage) {
std::vector<char> bytes = readFile(path);
if (bytes.size() % sizeof(u32) != 0) {
log::fatal("invalid SPIR-V binary (size not a multiple of 4):", path);
log::fatal("invalid SPIR-V binary (size not a multiple of 4): {}", path);
throw std::runtime_error("invalid SPIR-V binary: " + path);
}
this->spirv.assign(reinterpret_cast<const u32*>(bytes.data()),
reinterpret_cast<const u32*>(bytes.data() + bytes.size()));
log::info("Loaded precompiled shader: " + path + " (" +
std::to_string(bytes.size()) + " bytes)");
log::info("Loaded precompiled shader: {} ({} bytes)", path, bytes.size());
}
Shader::Builder& Shader::Builder::fromGLSL(const std::string& path) {
+1 -1
View File
@@ -114,7 +114,7 @@ void Swapchain::createSwapchain() {
this->device.get()->createSwapchainKHR(this->swapchainCreateInfo);
// log::trace("created vk::SwapchainKHR");
} catch (const vk::SystemError& err) {
log::fatal("failed to create swapchain. Error: ", err.what());
log::fatal("failed to create swapchain. Error: {}", err.what());
throw std::runtime_error("failed to create swapchain");
}
}
+20
View File
@@ -0,0 +1,20 @@
#pragma once
#include <cstdio>
#include <cstdlib>
#include <source_location>
#include <vulkan/vulkan.hpp>
inline void vk_check(vk::Result result, std::source_location loc =
std::source_location::current()) {
if (result != vk::Result::eSuccess) {
std::fprintf(stderr, "%s:%u: %s: %s\n", loc.file_name(), loc.line(),
loc.function_name(), vk::to_string(result).c_str());
std::abort();
}
}
inline void vk_check(VkResult result, std::source_location loc =
std::source_location::current()) {
vk_check(static_cast<vk::Result>(result), loc);
}