From 5b2e9d81e4b21a428290aff8456332be68f9ff57 Mon Sep 17 00:00:00 2001 From: PancakeTAS Date: Fri, 8 Aug 2025 16:24:23 +0200 Subject: [PATCH] feat(test): move image uploading util --- 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, 121 insertions(+), 94 deletions(-) create mode 100644 test/include/utils.hpp create mode 100644 test/src/utils.cpp diff --git a/framegen/include/common/utils.hpp b/framegen/include/common/utils.hpp index 82e7039..f9b5cf3 100644 --- a/framegen/include/common/utils.hpp +++ b/framegen/include/common/utils.hpp @@ -13,7 +13,6 @@ #include #include #include -#include #include #include @@ -64,21 +63,6 @@ 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 20346c5..b3b95c9 100644 --- a/framegen/src/common/utils.cpp +++ b/framegen/src/common/utils.cpp @@ -2,7 +2,6 @@ #include #include "common/utils.hpp" -#include "core/buffer.hpp" #include "core/image.hpp" #include "core/device.hpp" #include "core/commandpool.hpp" @@ -10,12 +9,7 @@ #include "common/exception.hpp" #include -#include -#include -#include #include -#include -#include #include using namespace LSFG; @@ -72,78 +66,6 @@ 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 new file mode 100644 index 0000000..dbaf42f --- /dev/null +++ b/test/include/utils.hpp @@ -0,0 +1,28 @@ +#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 new file mode 100644 index 0000000..2004b7b --- /dev/null +++ b/test/src/utils.cpp @@ -0,0 +1,93 @@ +#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"); +}