mirror of
https://github.com/PancakeTAS/lsfg-vk.git
synced 2026-04-28 05:11:41 +00:00
refactor: finish final methods
This commit is contained in:
parent
4c85e45485
commit
eef8d4a245
6 changed files with 57 additions and 205 deletions
|
|
@ -1,63 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "core/commandbuffer.hpp"
|
||||
#include "core/commandpool.hpp"
|
||||
#include "core/descriptorpool.hpp"
|
||||
#include "core/image.hpp"
|
||||
#include "core/device.hpp"
|
||||
#include "pool/resourcepool.hpp"
|
||||
#include "pool/shaderpool.hpp"
|
||||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
#include <optional>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <array>
|
||||
#include <vector>
|
||||
|
||||
namespace LSFG::Utils {
|
||||
|
||||
///
|
||||
/// 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.
|
||||
///
|
||||
/// @param device The Vulkan device.
|
||||
/// @param image The image to clear.
|
||||
/// @param white If true, the image will be cleared to white, otherwise to black.
|
||||
///
|
||||
/// @throws LSFG::vulkan_error If the Vulkan image cannot be cleared.
|
||||
///
|
||||
void clearImage(const Core::Device& device, Core::Image& image, bool white = false);
|
||||
|
||||
}
|
||||
|
||||
namespace LSFG {
|
||||
struct Vulkan {
|
||||
Core::Device device;
|
||||
Core::CommandPool commandPool;
|
||||
Core::DescriptorPool descriptorPool;
|
||||
|
||||
uint64_t generationCount;
|
||||
float flowScale;
|
||||
bool isHdr;
|
||||
|
||||
Pool::ShaderPool shaders;
|
||||
Pool::ResourcePool resources;
|
||||
};
|
||||
}
|
||||
|
|
@ -1,140 +0,0 @@
|
|||
#include <volk.h>
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
#include "common/utils.hpp"
|
||||
#include "core/buffer.hpp"
|
||||
#include "core/image.hpp"
|
||||
#include "core/device.hpp"
|
||||
#include "core/commandpool.hpp"
|
||||
#include "core/fence.hpp"
|
||||
#include "common/exception.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <cerrno>
|
||||
#include <cstdlib>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <ios>
|
||||
#include <system_error>
|
||||
#include <vector>
|
||||
|
||||
using namespace LSFG;
|
||||
using namespace LSFG::Utils;
|
||||
|
||||
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<char> code(static_cast<size_t>(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<uint32_t>(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);
|
||||
Core::CommandBuffer cmdBuf(device, cmdPool);
|
||||
cmdBuf.begin();
|
||||
|
||||
const VkImageMemoryBarrier2 barrier{
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
|
||||
.dstStageMask = VK_PIPELINE_STAGE_2_TRANSFER_BIT,
|
||||
.dstAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT,
|
||||
.oldLayout = image.getLayout(),
|
||||
.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
|
||||
.image = image.handle(),
|
||||
.subresourceRange = {
|
||||
.aspectMask = image.getAspectFlags(),
|
||||
.levelCount = 1,
|
||||
.layerCount = 1
|
||||
}
|
||||
};
|
||||
const VkDependencyInfo dependencyInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
|
||||
.imageMemoryBarrierCount = 1,
|
||||
.pImageMemoryBarriers = &barrier
|
||||
};
|
||||
image.setLayout(VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
|
||||
vkCmdPipelineBarrier2(cmdBuf.handle(), &dependencyInfo);
|
||||
|
||||
const float clearValue = white ? 1.0F : 0.0F;
|
||||
const VkClearColorValue clearColor = {{ clearValue, clearValue, clearValue, clearValue }};
|
||||
const VkImageSubresourceRange subresourceRange = {
|
||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
.levelCount = 1,
|
||||
.layerCount = 1
|
||||
};
|
||||
vkCmdClearColorImage(cmdBuf.handle(),
|
||||
image.handle(), image.getLayout(),
|
||||
&clearColor,
|
||||
1, &subresourceRange);
|
||||
|
||||
cmdBuf.end();
|
||||
|
||||
cmdBuf.submit(device.getComputeQueue(), fence);
|
||||
if (!fence.wait(device))
|
||||
throw LSFG::vulkan_error(VK_TIMEOUT, "Failed to wait for clearing fence.");
|
||||
}
|
||||
|
|
@ -97,8 +97,25 @@ namespace VK::Core {
|
|||
const std::vector<VkImage>& readableImages,
|
||||
const std::vector<VkImage>& writableImages) const;
|
||||
|
||||
// TODO: Method for copying a buffer to an image
|
||||
// TODO: Method for clearing an image to a color
|
||||
///
|
||||
/// Copy a buffer to an image.
|
||||
///
|
||||
/// @param buffer Vulkan buffer
|
||||
/// @param image Vulkan image
|
||||
///
|
||||
/// @throws std::logic_error if the command buffer is not in Recording state
|
||||
///
|
||||
void copyBufferToImage(const Buffer& buffer, const Image& image) const;
|
||||
|
||||
///
|
||||
/// Clear an image to a color.
|
||||
///
|
||||
/// @param image Vulkan image
|
||||
/// @param white If true, clear to white; otherwise, clear to black
|
||||
///
|
||||
/// @throws std::logic_error if the command buffer is not in Recording state
|
||||
///
|
||||
void clearImage(const Image& image, bool white) const;
|
||||
|
||||
///
|
||||
/// Dispatch a compute command.
|
||||
|
|
|
|||
|
|
@ -6,8 +6,10 @@
|
|||
#include "vk/core/commandpool.hpp"
|
||||
#include "vk/core/semaphore.hpp"
|
||||
#include "vk/core/pipeline.hpp"
|
||||
#include "vk/core/buffer.hpp"
|
||||
#include "vk/core/device.hpp"
|
||||
#include "vk/core/fence.hpp"
|
||||
#include "vk/core/image.hpp"
|
||||
#include "vk/exception.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
|
|
@ -147,6 +149,42 @@ void CommandBuffer::insertBarrier(
|
|||
vkCmdPipelineBarrier2(*this->commandBuffer, &dependencyInfo);
|
||||
}
|
||||
|
||||
void CommandBuffer::copyBufferToImage(const Buffer& buffer, const Image& image) const {
|
||||
if (*this->state != CommandBufferState::Recording)
|
||||
throw std::logic_error("Command buffer is not in Recording state");
|
||||
|
||||
const auto extent = image.getExtent();
|
||||
const VkBufferImageCopy region{
|
||||
.imageSubresource = {
|
||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
.layerCount = 1
|
||||
},
|
||||
.imageExtent = { extent.width, extent.height, 1 }
|
||||
};
|
||||
vkCmdCopyBufferToImage(
|
||||
*this->commandBuffer,
|
||||
buffer.handle(), image.handle(),
|
||||
VK_IMAGE_LAYOUT_GENERAL, 1, ®ion
|
||||
);
|
||||
}
|
||||
|
||||
void CommandBuffer::clearImage(const Image& image, bool white) const {
|
||||
if (*this->state != CommandBufferState::Recording)
|
||||
throw std::logic_error("Command buffer is not in Recording state");
|
||||
|
||||
const float clearValue = white ? 1.0F : 0.0F;
|
||||
const VkClearColorValue clearColor = {{ clearValue, clearValue, clearValue, clearValue }};
|
||||
const VkImageSubresourceRange subresourceRange = {
|
||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
.levelCount = 1,
|
||||
.layerCount = 1
|
||||
};
|
||||
vkCmdClearColorImage(*this->commandBuffer,
|
||||
image.handle(), VK_IMAGE_LAYOUT_GENERAL,
|
||||
&clearColor,
|
||||
1, &subresourceRange);
|
||||
}
|
||||
|
||||
void CommandBuffer::dispatch(uint32_t x, uint32_t y, uint32_t z) const {
|
||||
if (*this->state != CommandBufferState::Recording)
|
||||
throw std::logic_error("Command buffer is not in Recording state");
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue