feat: add tracy / various fixes

This commit is contained in:
2026-06-24 03:00:53 +02:00
parent 067caf5fe6
commit 9d3d14a54d
33 changed files with 1492 additions and 336 deletions
+130 -57
View File
@@ -6,6 +6,7 @@
#include <destrum/Graphics/Init.h>
#include "volk.h"
#include "tracy/Tracy.hpp"
void Swapchain::initSync(VkDevice device) {
@@ -23,30 +24,40 @@ void Swapchain::initSync(VkDevice device) {
}
void Swapchain::createSwapchain(GfxDevice* gfxDevice, VkFormat format, std::uint32_t width, std::uint32_t height, bool vSync) {
ZoneScopedN("Swapchain::createSwapchain");
m_gfxDevice = gfxDevice;
assert(format == VK_FORMAT_B8G8R8A8_SRGB && "TODO: test other formats");
vSync = true;
// vSync = true;
auto res = vkb::SwapchainBuilder{gfxDevice->getDevice()}
.set_desired_format(VkSurfaceFormatKHR{
.format = format,
.colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR,
})
.add_image_usage_flags(VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
.set_desired_present_mode(
vSync ? VK_PRESENT_MODE_FIFO_KHR : VK_PRESENT_MODE_IMMEDIATE_KHR)
.set_desired_extent(width, height)
.build();
if (!res.has_value()) {
// throw std::runtime_error(std::format(
// "failed to create swapchain: error = {}, vk result = {}",
// res.full_error().type.message(),
// string_VkResult(res.full_error().vk_result)));
{
ZoneScopedN("vkb::SwapchainBuilder::build");
auto res = vkb::SwapchainBuilder{gfxDevice->getDevice()}
.set_desired_format(VkSurfaceFormatKHR{
.format = format,
.colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR,
})
.add_image_usage_flags(VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
.set_desired_present_mode(
vSync ? VK_PRESENT_MODE_FIFO_KHR : VK_PRESENT_MODE_IMMEDIATE_KHR)
.set_desired_extent(width, height)
.build();
if (!res.has_value()) {
// throw std::runtime_error(std::format(
// "failed to create swapchain: error = {}, vk result = {}",
// res.full_error().type.message(),
// string_VkResult(res.full_error().vk_result)));
}
m_swapchain = res.value();
}
m_swapchain = res.value();
images = m_swapchain.get_images().value();
imageViews = m_swapchain.get_image_views().value();
{
ZoneScopedN("Get Swapchain Images / Views");
images = m_swapchain.get_images().value();
imageViews = m_swapchain.get_image_views().value();
}
imageRenderSemaphores.resize(images.size());
@@ -55,6 +66,8 @@ void Swapchain::createSwapchain(GfxDevice* gfxDevice, VkFormat format, std::uint
};
for (auto& sem: imageRenderSemaphores) {
ZoneScopedN("Create Image Render Semaphore");
VK_CHECK(vkCreateSemaphore(m_gfxDevice->getDevice(), &sci, nullptr, &sem));
}
@@ -71,6 +84,8 @@ void Swapchain::recreateSwapchain(
std::uint32_t height,
bool vSync)
{
ZoneScopedN("Swapchain::recreateSwapchain");
if (width == 0 || height == 0) {
dirty = true;
return;
@@ -78,45 +93,67 @@ void Swapchain::recreateSwapchain(
VkDevice device = gfxDevice.getDevice();
vkDeviceWaitIdle(device);
{
ZoneScopedN("vkDeviceWaitIdle");
vkDeviceWaitIdle(device);
}
auto oldSwapchain = m_swapchain;
auto res = vkb::SwapchainBuilder{gfxDevice.getVkbDevice()}
.set_old_swapchain(oldSwapchain)
.set_desired_format(VkSurfaceFormatKHR{
.format = format,
.colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR,
})
.add_image_usage_flags(VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
.set_desired_present_mode(
vSync ? VK_PRESENT_MODE_FIFO_KHR : VK_PRESENT_MODE_IMMEDIATE_KHR)
.set_desired_extent(width, height)
.build();
{
ZoneScopedN("vkb::SwapchainBuilder::rebuild");
if (!res.has_value()) {
// throw std::runtime_error(std::format(
// "failed to create swapchain: error = {}, vk result = {}",
// res.full_error().type.message(),
// string_VkResult(res.full_error().vk_result)));
auto res = vkb::SwapchainBuilder{gfxDevice.getVkbDevice()}
.set_old_swapchain(oldSwapchain)
.set_desired_format(VkSurfaceFormatKHR{
.format = format,
.colorSpace = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR,
})
.add_image_usage_flags(VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
.set_desired_present_mode(
vSync ? VK_PRESENT_MODE_FIFO_KHR : VK_PRESENT_MODE_IMMEDIATE_KHR)
.set_desired_extent(width, height)
.build();
if (!res.has_value()) {
// throw std::runtime_error(std::format(
// "failed to create swapchain: error = {}, vk result = {}",
// res.full_error().type.message(),
// string_VkResult(res.full_error().vk_result)));
}
m_swapchain = res.value();
}
for (auto sem : imageRenderSemaphores) {
vkDestroySemaphore(device, sem, nullptr);
{
ZoneScopedN("Destroy Old Image Render Semaphores");
for (auto sem : imageRenderSemaphores) {
vkDestroySemaphore(device, sem, nullptr);
}
imageRenderSemaphores.clear();
}
imageRenderSemaphores.clear();
for (auto imageView : imageViews) {
vkDestroyImageView(device, imageView, nullptr);
{
ZoneScopedN("Destroy Old Image Views");
for (auto imageView : imageViews) {
vkDestroyImageView(device, imageView, nullptr);
}
imageViews.clear();
}
imageViews.clear();
vkb::destroy_swapchain(oldSwapchain);
{
ZoneScopedN("Destroy Old Swapchain");
vkb::destroy_swapchain(oldSwapchain);
}
m_swapchain = res.value();
{
ZoneScopedN("Get New Swapchain Images / Views");
images = m_swapchain.get_images().value();
imageViews = m_swapchain.get_image_views().value();
images = m_swapchain.get_images().value();
imageViews = m_swapchain.get_image_views().value();
}
VkSemaphoreCreateInfo sci{
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
@@ -125,6 +162,8 @@ void Swapchain::recreateSwapchain(
imageRenderSemaphores.resize(images.size());
for (auto& sem : imageRenderSemaphores) {
ZoneScopedN("Create New Image Render Semaphore");
VK_CHECK(vkCreateSemaphore(device, &sci, nullptr, &sem));
}
@@ -148,13 +187,25 @@ void Swapchain::cleanup() {
}
void Swapchain::beginFrame(int index) const {
ZoneScopedN("Swapchain::beginFrame");
auto& frame = frames[index];
VK_CHECK(vkWaitForFences(m_gfxDevice->getDevice(), 1, &frame.renderFence, true, std::numeric_limits<std::uint64_t>::max()));
{
ZoneScopedN("vkWaitForFences");
VK_CHECK(vkWaitForFences(m_gfxDevice->getDevice(), 1, &frame.renderFence, true, std::numeric_limits<std::uint64_t>::max()));
}
}
void Swapchain::resetFences(int index) const {
ZoneScopedN("Swapchain::resetFences");
auto& frame = frames[index];
VK_CHECK(vkResetFences(m_gfxDevice->getDevice(), 1, &frame.renderFence));
{
ZoneScopedN("vkResetFences");
VK_CHECK(vkResetFences(m_gfxDevice->getDevice(), 1, &frame.renderFence));
}
}
struct SwapchainAcquireResult {
@@ -164,14 +215,24 @@ struct SwapchainAcquireResult {
};
std::pair<VkImage, int> Swapchain::acquireNextImage(int index) {
ZoneScopedN("Swapchain::acquireNextImage");
std::uint32_t swapchainImageIndex{};
const auto result = vkAcquireNextImageKHR(
m_gfxDevice->getDevice(),
m_swapchain,
std::numeric_limits<std::uint64_t>::max(),
frames[index].swapchainSemaphore,
VK_NULL_HANDLE,
&swapchainImageIndex);
VkResult result = VK_SUCCESS;
{
ZoneScopedN("vkAcquireNextImageKHR");
result = vkAcquireNextImageKHR(
m_gfxDevice->getDevice(),
m_swapchain,
std::numeric_limits<std::uint64_t>::max(),
frames[index].swapchainSemaphore,
VK_NULL_HANDLE,
&swapchainImageIndex);
}
if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR) {
dirty = true;
return {images[swapchainImageIndex], swapchainImageIndex};
@@ -188,6 +249,8 @@ void Swapchain::submitAndPresent(
uint32_t imageIndex, // from vkAcquireNextImageKHR
uint32_t frameIndex) // 0..FRAMES_IN_FLIGHT-1
{
ZoneScopedN("Swapchain::submitAndPresent");
auto& frame = frames[frameIndex]; // ✅ per-frame
VkSemaphore renderFinished = imageRenderSemaphores[imageIndex]; // ✅ per-image
@@ -209,7 +272,11 @@ void Swapchain::submitAndPresent(
renderFinished); // ✅ signal semaphore (per-image)
VkSubmitInfo2 submit = vkinit::submitInfo(&cmdInfo, &waitInfo, &signalInfo);
VK_CHECK(vkQueueSubmit2(graphicsQueue, 1, &submit, frame.renderFence)); // ✅ fence (per-frame)
{
ZoneScopedN("vkQueueSubmit2");
VK_CHECK(vkQueueSubmit2(graphicsQueue, 1, &submit, frame.renderFence)); // ✅ fence (per-frame)
}
// present
VkPresentInfoKHR presentInfo{
@@ -221,7 +288,13 @@ void Swapchain::submitAndPresent(
.pImageIndices = &imageIndex, // ✅ imageIndex, NOT frameIndex
};
VkResult res = vkQueuePresentKHR(graphicsQueue, &presentInfo);
VkResult res = VK_SUCCESS;
{
ZoneScopedN("vkQueuePresentKHR");
res = vkQueuePresentKHR(graphicsQueue, &presentInfo);
}
if (res == VK_ERROR_OUT_OF_DATE_KHR || res == VK_SUBOPTIMAL_KHR) dirty = true;
else if (res != VK_SUCCESS) dirty = true;
}