From a90593fdc157fd8c1e808ded4cc8de0656e0cce9 Mon Sep 17 00:00:00 2001 From: PancakeTAS Date: Fri, 8 Aug 2025 17:20:33 +0200 Subject: [PATCH] feat(test): move util back to framegen --- framegen/include/common/utils.hpp | 16 ++++++ framegen/src/common/utils.cpp | 78 ++++++++++++++++++++++++++ test/include/utils.hpp | 28 ---------- test/src/utils.cpp | 93 ------------------------------- 4 files changed, 94 insertions(+), 121 deletions(-) delete mode 100644 test/include/utils.hpp delete mode 100644 test/src/utils.cpp diff --git a/framegen/include/common/utils.hpp b/framegen/include/common/utils.hpp index f9b5cf3..82e7039 100644 --- a/framegen/include/common/utils.hpp +++ b/framegen/include/common/utils.hpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -63,6 +64,21 @@ namespace LSFG::Utils { std::vector barriers; }; + /// + /// Upload a DDS file to a Vulkan image. + /// + /// @param device The Vulkan device + /// @param commandPool The command pool + /// @param image The Vulkan image to upload to + /// @param path The path to the DDS file. + /// + /// @throws std::system_error If the file cannot be opened or read. + /// @throws ls:vulkan_error If the Vulkan image cannot be created or updated. + /// + void uploadImage(const Core::Device& device, + const Core::CommandPool& commandPool, + Core::Image& image, const std::string& path); + /// /// Clear a texture to white during setup. /// diff --git a/framegen/src/common/utils.cpp b/framegen/src/common/utils.cpp index b3b95c9..20346c5 100644 --- a/framegen/src/common/utils.cpp +++ b/framegen/src/common/utils.cpp @@ -2,6 +2,7 @@ #include #include "common/utils.hpp" +#include "core/buffer.hpp" #include "core/image.hpp" #include "core/device.hpp" #include "core/commandpool.hpp" @@ -9,7 +10,12 @@ #include "common/exception.hpp" #include +#include +#include +#include #include +#include +#include #include using namespace LSFG; @@ -66,6 +72,78 @@ void BarrierBuilder::build() const { vkCmdPipelineBarrier2(this->commandBuffer->handle(), &dependencyInfo); } +void Utils::uploadImage(const Core::Device& device, const Core::CommandPool& commandPool, + Core::Image& image, const std::string& path) { + // read image bytecode + std::ifstream file(path.data(), std::ios::binary | std::ios::ate); + if (!file.is_open()) + throw std::system_error(errno, std::generic_category(), "Failed to open image: " + path); + + std::streamsize size = file.tellg(); + size -= 124 + 4; // dds header and magic bytes + std::vector code(static_cast(size)); + + file.seekg(124 + 4, std::ios::beg); + if (!file.read(code.data(), size)) + throw std::system_error(errno, std::generic_category(), "Failed to read image: " + path); + + file.close(); + + // copy data to buffer + const Core::Buffer stagingBuffer( + device, code.data(), static_cast(code.size()), + VK_BUFFER_USAGE_TRANSFER_SRC_BIT + ); + + // perform the upload + Core::CommandBuffer commandBuffer(device, commandPool); + commandBuffer.begin(); + + const VkImageMemoryBarrier barrier{ + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + .srcAccessMask = VK_ACCESS_NONE, + .dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, + .oldLayout = image.getLayout(), + .newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + .image = image.handle(), + .subresourceRange = { + .aspectMask = image.getAspectFlags(), + .levelCount = 1, + .layerCount = 1 + } + }; + image.setLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + vkCmdPipelineBarrier( + commandBuffer.handle(), + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, + 0, 0, nullptr, 0, nullptr, 1, &barrier + ); + + auto extent = image.getExtent(); + const VkBufferImageCopy region{ + .bufferImageHeight = 0, + .imageSubresource = { + .aspectMask = image.getAspectFlags(), + .layerCount = 1 + }, + .imageExtent = { extent.width, extent.height, 1 } + }; + vkCmdCopyBufferToImage( + commandBuffer.handle(), + stagingBuffer.handle(), image.handle(), + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion + ); + + commandBuffer.end(); + + Core::Fence fence(device); + commandBuffer.submit(device.getComputeQueue(), fence); + + // wait for the upload to complete + if (!fence.wait(device)) + throw LSFG::vulkan_error(VK_TIMEOUT, "Upload operation timed out"); +} + void Utils::clearImage(const Core::Device& device, Core::Image& image, bool white) { Core::Fence fence(device); const Core::CommandPool cmdPool(device); diff --git a/test/include/utils.hpp b/test/include/utils.hpp deleted file mode 100644 index dbaf42f..0000000 --- a/test/include/utils.hpp +++ /dev/null @@ -1,28 +0,0 @@ -#include "core/commandpool.hpp" -#include "core/device.hpp" -#include "mini/image.hpp" - -#include - -#include - -namespace Utils { - - using namespace LSFG; - - /// - /// Upload a DDS file to a Vulkan image. - /// - /// @param device The Vulkan device - /// @param commandPool The command pool - /// @param image The Vulkan image to upload to - /// @param path The path to the DDS file. - /// - /// @throws std::system_error If the file cannot be opened or read. - /// @throws ls:vulkan_error If the Vulkan image cannot be created or updated. - /// - void uploadImage(const Core::Device& device, - const Core::CommandPool& commandPool, - Mini::Image& image, const std::string& path); - -} diff --git a/test/src/utils.cpp b/test/src/utils.cpp deleted file mode 100644 index 2004b7b..0000000 --- a/test/src/utils.cpp +++ /dev/null @@ -1,93 +0,0 @@ -#include "utils.hpp" - -#include "common/exception.hpp" -#include "core/buffer.hpp" -#include "core/commandbuffer.hpp" -#include "core/commandpool.hpp" -#include "core/device.hpp" -#include "core/fence.hpp" -#include "mini/image.hpp" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace LSFG; - -void Utils::uploadImage(const Core::Device& device, const Core::CommandPool& commandPool, - Mini::Image& image, const std::string& path) { - // read image bytecode - std::ifstream file(path.data(), std::ios::binary | std::ios::ate); - if (!file.is_open()) - throw std::system_error(errno, std::generic_category(), "Failed to open image: " + path); - - std::streamsize size = file.tellg(); - size -= 124 + 4; // dds header and magic bytes - std::vector code(static_cast(size)); - - file.seekg(124 + 4, std::ios::beg); - if (!file.read(code.data(), size)) - throw std::system_error(errno, std::generic_category(), "Failed to read image: " + path); - - file.close(); - - // copy data to buffer - const Core::Buffer stagingBuffer( - device, code.data(), static_cast(code.size()), - VK_BUFFER_USAGE_TRANSFER_SRC_BIT - ); - - // perform the upload - Core::CommandBuffer commandBuffer(device, commandPool); - commandBuffer.begin(); - - const VkImageMemoryBarrier barrier{ - .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, - .srcAccessMask = VK_ACCESS_NONE, - .dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, - .oldLayout = VK_IMAGE_LAYOUT_UNDEFINED, - .newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - .image = image.handle(), - .subresourceRange = { - .aspectMask = image.getAspectFlags(), - .levelCount = 1, - .layerCount = 1 - } - }; - vkCmdPipelineBarrier( - commandBuffer.handle(), - VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, - 0, 0, nullptr, 0, nullptr, 1, &barrier - ); - - auto extent = image.getExtent(); - const VkBufferImageCopy region{ - .bufferImageHeight = 0, - .imageSubresource = { - .aspectMask = image.getAspectFlags(), - .layerCount = 1 - }, - .imageExtent = { extent.width, extent.height, 1 } - }; - vkCmdCopyBufferToImage( - commandBuffer.handle(), - stagingBuffer.handle(), image.handle(), - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion - ); - - commandBuffer.end(); - - Core::Fence fence(device); - commandBuffer.submit(device.getComputeQueue(), fence); - - // wait for the upload to complete - if (!fence.wait(device)) - throw LSFG::vulkan_error(VK_TIMEOUT, "Upload operation timed out"); -}