mirror of
https://github.com/PancakeTAS/lsfg-vk.git
synced 2025-10-30 07:01:10 +00:00
reorganize utils
This commit is contained in:
parent
10ac493312
commit
0345ec9e69
28 changed files with 285 additions and 332 deletions
|
|
@ -19,7 +19,6 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
|||
file(GLOB SOURCES
|
||||
"src/core/*.cpp"
|
||||
"src/shaderchains/*.cpp"
|
||||
"src/utils/*.cpp"
|
||||
"src/*.cpp"
|
||||
)
|
||||
|
||||
|
|
|
|||
0
include/shaderchains/alpha.hpp
Normal file
0
include/shaderchains/alpha.hpp
Normal file
106
include/utils.hpp
Normal file
106
include/utils.hpp
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
#ifndef UTILS_HPP
|
||||
#define UTILS_HPP
|
||||
|
||||
#include "core/commandbuffer.hpp"
|
||||
#include "core/image.hpp"
|
||||
#include "core/sampler.hpp"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <array>
|
||||
|
||||
namespace Vulkan::Utils {
|
||||
|
||||
///
|
||||
/// Insert memory barriers for images in a command buffer.
|
||||
///
|
||||
/// @param buffer Command buffer to insert barriers into
|
||||
/// @param r2wImages Images that are being read and will be written to
|
||||
/// @param w2rImages Images that are being written to and will be read from
|
||||
///
|
||||
/// @throws std::logic_error if the command buffer is not in Recording state
|
||||
///
|
||||
void insertBarrier(
|
||||
const Vulkan::Core::CommandBuffer& buffer,
|
||||
std::vector<Vulkan::Core::Image> r2wImages,
|
||||
std::vector<Vulkan::Core::Image> w2rImages);
|
||||
|
||||
///
|
||||
/// 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 Vulkan::Device& device,
|
||||
const Vulkan::Core::CommandPool& commandPool,
|
||||
Vulkan::Core::Image& image, const std::string& path);
|
||||
|
||||
}
|
||||
|
||||
namespace Vulkan::Globals {
|
||||
|
||||
/// Global sampler with address mode set to clamp to border.
|
||||
extern Core::Sampler samplerClampBorder;
|
||||
/// Global sampler with address mode set to clamp to edge.
|
||||
extern Core::Sampler samplerClampEdge;
|
||||
|
||||
/// Commonly used constant buffer structure for shaders.
|
||||
struct FgBuffer {
|
||||
std::array<uint32_t, 2> inputOffset;
|
||||
uint32_t firstIter;
|
||||
uint32_t firstIterS;
|
||||
uint32_t advancedColorKind;
|
||||
uint32_t hdrSupport;
|
||||
float resolutionInvScale;
|
||||
float timestamp;
|
||||
float uiThreshold;
|
||||
std::array<uint32_t, 3> pad;
|
||||
};
|
||||
|
||||
/// Default instance of the FgBuffer.
|
||||
extern FgBuffer fgBuffer;
|
||||
|
||||
static_assert(sizeof(FgBuffer) == 48, "FgBuffer must be 48 bytes in size.");
|
||||
|
||||
/// Initialize global resources.
|
||||
void initializeGlobals(const Device& device);
|
||||
|
||||
/// Uninitialize global resources.
|
||||
void uninitializeGlobals() noexcept;
|
||||
|
||||
}
|
||||
|
||||
namespace ls {
|
||||
|
||||
/// Simple exception class for Vulkan errors.
|
||||
class vulkan_error : public std::runtime_error {
|
||||
public:
|
||||
///
|
||||
/// Construct a vulkan_error with a message and a Vulkan result code.
|
||||
///
|
||||
/// @param result The Vulkan result code associated with the error.
|
||||
/// @param message The error message.
|
||||
///
|
||||
explicit vulkan_error(VkResult result, const std::string& message);
|
||||
|
||||
/// Get the Vulkan result code associated with this error.
|
||||
[[nodiscard]] VkResult error() const { return this->result; }
|
||||
|
||||
// Trivially copyable, moveable and destructible
|
||||
vulkan_error(const vulkan_error&) = default;
|
||||
vulkan_error(vulkan_error&&) = default;
|
||||
vulkan_error& operator=(const vulkan_error&) = default;
|
||||
vulkan_error& operator=(vulkan_error&&) = default;
|
||||
~vulkan_error() noexcept override;
|
||||
private:
|
||||
VkResult result;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // UTILS_HPP
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
#ifndef BARRIERS_HPP
|
||||
#define BARRIERS_HPP
|
||||
|
||||
#include "core/commandbuffer.hpp"
|
||||
#include "core/image.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
namespace Barriers {
|
||||
|
||||
///
|
||||
/// Insert memory barriers for images in a command buffer.
|
||||
///
|
||||
/// @param buffer Command buffer to insert barriers into
|
||||
/// @param r2wImages Images that are being read and will be written to
|
||||
/// @param w2rImages Images that are being written to and will be read from
|
||||
///
|
||||
/// @throws std::logic_error if the command buffer is not in Recording state
|
||||
///
|
||||
void insertBarrier(
|
||||
const Vulkan::Core::CommandBuffer& buffer,
|
||||
std::vector<Vulkan::Core::Image> r2wImages,
|
||||
std::vector<Vulkan::Core::Image> w2rImages);
|
||||
|
||||
};
|
||||
|
||||
#endif // BARRIERS_HPP
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
#ifndef EXCEPTIONS_HPP
|
||||
#define EXCEPTIONS_HPP
|
||||
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
namespace ls {
|
||||
|
||||
/// Simple exception class for Vulkan errors.
|
||||
class vulkan_error : public std::runtime_error {
|
||||
public:
|
||||
///
|
||||
/// Construct a vulkan_error with a message and a Vulkan result code.
|
||||
///
|
||||
/// @param result The Vulkan result code associated with the error.
|
||||
/// @param message The error message.
|
||||
///
|
||||
explicit vulkan_error(VkResult result, const std::string& message);
|
||||
|
||||
/// Get the Vulkan result code associated with this error.
|
||||
[[nodiscard]] VkResult error() const { return this->result; }
|
||||
|
||||
// Trivially copyable, moveable and destructible
|
||||
vulkan_error(const vulkan_error&) = default;
|
||||
vulkan_error(vulkan_error&&) = default;
|
||||
vulkan_error& operator=(const vulkan_error&) = default;
|
||||
vulkan_error& operator=(vulkan_error&&) = default;
|
||||
~vulkan_error() noexcept override;
|
||||
private:
|
||||
VkResult result;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // EXCEPTIONS_HPP
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
#ifndef GLOBAL_HPP
|
||||
#define GLOBAL_HPP
|
||||
|
||||
#include "core/sampler.hpp"
|
||||
|
||||
#include <array>
|
||||
|
||||
namespace Vulkan::Globals {
|
||||
|
||||
/// Global sampler with address mode set to clamp to border.
|
||||
extern Core::Sampler samplerClampBorder;
|
||||
/// Global sampler with address mode set to clamp to edge.
|
||||
extern Core::Sampler samplerClampEdge;
|
||||
|
||||
/// Commonly used constant buffer structure for shaders.
|
||||
struct FgBuffer {
|
||||
std::array<uint32_t, 2> inputOffset;
|
||||
uint32_t firstIter;
|
||||
uint32_t firstIterS;
|
||||
uint32_t advancedColorKind;
|
||||
uint32_t hdrSupport;
|
||||
float resolutionInvScale;
|
||||
float timestamp;
|
||||
float uiThreshold;
|
||||
std::array<uint32_t, 3> pad;
|
||||
};
|
||||
|
||||
/// Default instance of the FgBuffer.
|
||||
extern FgBuffer fgBuffer;
|
||||
|
||||
static_assert(sizeof(FgBuffer) == 48, "FgBuffer must be 48 bytes in size.");
|
||||
|
||||
/// Initialize global resources.
|
||||
void initializeGlobals(const Device& device);
|
||||
|
||||
/// Uninitialize global resources.
|
||||
void uninitializeGlobals() noexcept;
|
||||
|
||||
}
|
||||
|
||||
#endif // GLOBAL_HPP
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
#ifndef UPLOAD_HPP
|
||||
#define UPLOAD_HPP
|
||||
|
||||
#include "core/commandpool.hpp"
|
||||
#include "core/image.hpp"
|
||||
#include "device.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace Upload {
|
||||
|
||||
///
|
||||
/// 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 upload(const Vulkan::Device& device, const Vulkan::Core::CommandPool& commandPool,
|
||||
Vulkan::Core::Image& image, const std::string& path);
|
||||
|
||||
}
|
||||
|
||||
#endif // UPLOAD_HPP
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
#include "core/buffer.hpp"
|
||||
#include "utils/exceptions.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <optional>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#include "core/commandbuffer.hpp"
|
||||
#include "utils/exceptions.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
using namespace Vulkan::Core;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#include "core/commandpool.hpp"
|
||||
#include "utils/exceptions.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
using namespace Vulkan::Core;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#include "core/descriptorpool.hpp"
|
||||
#include "utils/exceptions.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
#include <array>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#include "core/descriptorset.hpp"
|
||||
#include "utils/exceptions.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
using namespace Vulkan::Core;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#include "core/fence.hpp"
|
||||
#include "utils/exceptions.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
using namespace Vulkan::Core;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#include "core/image.hpp"
|
||||
#include "utils/exceptions.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
#include <optional>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#include "core/pipeline.hpp"
|
||||
#include "utils/exceptions.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
using namespace Vulkan::Core;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#include "core/sampler.hpp"
|
||||
#include "utils/exceptions.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
using namespace Vulkan::Core;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#include "core/semaphore.hpp"
|
||||
#include "utils/exceptions.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
using namespace Vulkan::Core;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#include "core/shadermodule.hpp"
|
||||
#include "utils/exceptions.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#include "device.hpp"
|
||||
#include "utils/exceptions.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#include "instance.hpp"
|
||||
#include "utils/exceptions.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
|
|
|||
|
|
@ -6,8 +6,7 @@
|
|||
#include "device.hpp"
|
||||
#include "instance.hpp"
|
||||
#include "shaderchains/downsample.hpp"
|
||||
#include "utils/global.hpp"
|
||||
#include "utils/upload.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
|
|
@ -48,7 +47,7 @@ int main() {
|
|||
VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
|
||||
VK_IMAGE_ASPECT_COLOR_BIT
|
||||
);
|
||||
Upload::upload(device, commandPool, inputImage, "rsc/images/source.dds");
|
||||
Utils::uploadImage(device, commandPool, inputImage, "rsc/images/source.dds");
|
||||
|
||||
// create the shaderchains
|
||||
Shaderchains::Downsample downsample(device, descriptorPool, inputImage);
|
||||
|
|
|
|||
0
src/shaderchains/alpha.cpp
Normal file
0
src/shaderchains/alpha.cpp
Normal file
|
|
@ -1,6 +1,5 @@
|
|||
#include "shaderchains/downsample.hpp"
|
||||
#include "utils/global.hpp"
|
||||
#include "utils/barriers.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
using namespace Vulkan::Shaderchains;
|
||||
|
||||
|
|
@ -43,7 +42,7 @@ void Downsample::Dispatch(const Core::CommandBuffer& buf) {
|
|||
const uint32_t threadsX = (extent.width + 63) >> 6;
|
||||
const uint32_t threadsY = (extent.height + 63) >> 6;
|
||||
|
||||
Barriers::insertBarrier(
|
||||
Utils::insertBarrier(
|
||||
buf,
|
||||
this->outImages,
|
||||
{ this->inImage }
|
||||
|
|
|
|||
162
src/utils.cpp
Normal file
162
src/utils.cpp
Normal file
|
|
@ -0,0 +1,162 @@
|
|||
#include "utils.hpp"
|
||||
#include "core/buffer.hpp"
|
||||
|
||||
#include <format>
|
||||
#include <fstream>
|
||||
|
||||
using namespace Vulkan;
|
||||
|
||||
void Utils::insertBarrier(
|
||||
const Core::CommandBuffer& buffer,
|
||||
std::vector<Core::Image> r2wImages,
|
||||
std::vector<Core::Image> w2rImages) {
|
||||
std::vector<VkImageMemoryBarrier2> barriers(r2wImages.size() + w2rImages.size());
|
||||
|
||||
size_t index = 0;
|
||||
for (auto& image : r2wImages) {
|
||||
barriers[index++] = {
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
|
||||
.srcStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
|
||||
.srcAccessMask = VK_ACCESS_2_SHADER_READ_BIT,
|
||||
.dstStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
|
||||
.dstAccessMask = VK_ACCESS_2_SHADER_WRITE_BIT,
|
||||
.oldLayout = image.getLayout(),
|
||||
.newLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
.image = image.handle(),
|
||||
.subresourceRange = {
|
||||
.aspectMask = image.getAspectFlags(),
|
||||
.levelCount = 1,
|
||||
.layerCount = 1
|
||||
}
|
||||
};
|
||||
image.setLayout(VK_IMAGE_LAYOUT_GENERAL);
|
||||
}
|
||||
for (auto& image : w2rImages) {
|
||||
barriers[index++] = {
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
|
||||
.srcStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
|
||||
.srcAccessMask = VK_ACCESS_2_SHADER_WRITE_BIT,
|
||||
.dstStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
|
||||
.dstAccessMask = VK_ACCESS_2_SHADER_READ_BIT,
|
||||
.oldLayout = image.getLayout(),
|
||||
.newLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
.image = image.handle(),
|
||||
.subresourceRange = {
|
||||
.aspectMask = image.getAspectFlags(),
|
||||
.levelCount = 1,
|
||||
.layerCount = 1
|
||||
}
|
||||
};
|
||||
image.setLayout(VK_IMAGE_LAYOUT_GENERAL);
|
||||
}
|
||||
const VkDependencyInfo dependencyInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
|
||||
.imageMemoryBarrierCount = static_cast<uint32_t>(barriers.size()),
|
||||
.pImageMemoryBarriers = barriers.data()
|
||||
};
|
||||
vkCmdPipelineBarrier2(buffer.handle(), &dependencyInfo);
|
||||
}
|
||||
|
||||
void Utils::uploadImage(const Device& device, const Core::CommandPool& commandPool,
|
||||
Core::Image& image, const std::string& path) {
|
||||
// read image bytecode
|
||||
std::ifstream file(path, std::ios::ate | std::ios::binary);
|
||||
if (!file)
|
||||
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<uint8_t> code(static_cast<size_t>(size));
|
||||
|
||||
file.seekg(0, std::ios::beg);
|
||||
if (!file.read(reinterpret_cast<char*>(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 ls::vulkan_error(VK_TIMEOUT, "Upload operation timed out");
|
||||
}
|
||||
|
||||
Core::Sampler Globals::samplerClampBorder;
|
||||
Core::Sampler Globals::samplerClampEdge;
|
||||
Globals::FgBuffer Globals::fgBuffer;
|
||||
|
||||
void Globals::initializeGlobals(const Device& device) {
|
||||
// initialize global samplers
|
||||
samplerClampBorder = Core::Sampler(device, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER);
|
||||
samplerClampEdge = Core::Sampler(device, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE);
|
||||
|
||||
// initialize global constant buffer
|
||||
fgBuffer = {
|
||||
.inputOffset = { 0, 29 },
|
||||
.resolutionInvScale = 1.0F,
|
||||
.timestamp = 0.5F,
|
||||
.uiThreshold = 0.1F,
|
||||
};
|
||||
}
|
||||
|
||||
void Globals::uninitializeGlobals() noexcept {
|
||||
// uninitialize global samplers
|
||||
samplerClampBorder = Core::Sampler();
|
||||
samplerClampEdge = Core::Sampler();
|
||||
|
||||
// uninitialize global constant buffer
|
||||
fgBuffer = Globals::FgBuffer();
|
||||
}
|
||||
|
||||
ls::vulkan_error::vulkan_error(VkResult result, const std::string& message)
|
||||
: std::runtime_error(std::format("{} (error {})", message, static_cast<uint32_t>(result))), result(result) {}
|
||||
|
||||
ls::vulkan_error::~vulkan_error() noexcept = default;
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
#include "utils/barriers.hpp"
|
||||
|
||||
using namespace Barriers;
|
||||
|
||||
void Barriers::insertBarrier(
|
||||
const Vulkan::Core::CommandBuffer& buffer,
|
||||
std::vector<Vulkan::Core::Image> r2wImages,
|
||||
std::vector<Vulkan::Core::Image> w2rImages) {
|
||||
std::vector<VkImageMemoryBarrier2> barriers(r2wImages.size() + w2rImages.size());
|
||||
|
||||
size_t index = 0;
|
||||
for (auto& image : r2wImages) {
|
||||
barriers[index++] = {
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
|
||||
.srcStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
|
||||
.srcAccessMask = VK_ACCESS_2_SHADER_READ_BIT,
|
||||
.dstStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
|
||||
.dstAccessMask = VK_ACCESS_2_SHADER_WRITE_BIT,
|
||||
.oldLayout = image.getLayout(),
|
||||
.newLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
.image = image.handle(),
|
||||
.subresourceRange = {
|
||||
.aspectMask = image.getAspectFlags(),
|
||||
.levelCount = 1,
|
||||
.layerCount = 1
|
||||
}
|
||||
};
|
||||
image.setLayout(VK_IMAGE_LAYOUT_GENERAL);
|
||||
}
|
||||
for (auto& image : w2rImages) {
|
||||
barriers[index++] = {
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
|
||||
.srcStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
|
||||
.srcAccessMask = VK_ACCESS_2_SHADER_WRITE_BIT,
|
||||
.dstStageMask = VK_PIPELINE_STAGE_2_COMPUTE_SHADER_BIT,
|
||||
.dstAccessMask = VK_ACCESS_2_SHADER_READ_BIT,
|
||||
.oldLayout = image.getLayout(),
|
||||
.newLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
.image = image.handle(),
|
||||
.subresourceRange = {
|
||||
.aspectMask = image.getAspectFlags(),
|
||||
.levelCount = 1,
|
||||
.layerCount = 1
|
||||
}
|
||||
};
|
||||
image.setLayout(VK_IMAGE_LAYOUT_GENERAL);
|
||||
}
|
||||
const VkDependencyInfo dependencyInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
|
||||
.imageMemoryBarrierCount = static_cast<uint32_t>(barriers.size()),
|
||||
.pImageMemoryBarriers = barriers.data()
|
||||
};
|
||||
vkCmdPipelineBarrier2(buffer.handle(), &dependencyInfo);
|
||||
}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
#include "utils/exceptions.hpp"
|
||||
|
||||
#include <format>
|
||||
|
||||
using namespace ls;
|
||||
|
||||
vulkan_error::vulkan_error(VkResult result, const std::string& message)
|
||||
: std::runtime_error(std::format("{} (error {})", message, static_cast<uint32_t>(result))), result(result) {}
|
||||
|
||||
vulkan_error::~vulkan_error() noexcept = default;
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
#include "utils/global.hpp"
|
||||
|
||||
using namespace Vulkan;
|
||||
|
||||
Core::Sampler Globals::samplerClampBorder;
|
||||
Core::Sampler Globals::samplerClampEdge;
|
||||
Globals::FgBuffer Globals::fgBuffer;
|
||||
|
||||
void Globals::initializeGlobals(const Device& device) {
|
||||
// initialize global samplers
|
||||
samplerClampBorder = Core::Sampler(device, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_BORDER);
|
||||
samplerClampEdge = Core::Sampler(device, VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE);
|
||||
|
||||
// initialize global constant buffer
|
||||
fgBuffer = {
|
||||
.inputOffset = { 0, 29 },
|
||||
.resolutionInvScale = 1.0F,
|
||||
.timestamp = 0.5F,
|
||||
.uiThreshold = 0.1F,
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
void Globals::uninitializeGlobals() noexcept {
|
||||
// uninitialize global samplers
|
||||
samplerClampBorder = Core::Sampler();
|
||||
samplerClampEdge = Core::Sampler();
|
||||
|
||||
// uninitialize global constant buffer
|
||||
fgBuffer = Globals::FgBuffer();
|
||||
}
|
||||
|
|
@ -1,82 +0,0 @@
|
|||
#include "utils/upload.hpp"
|
||||
#include "core/buffer.hpp"
|
||||
#include "core/commandbuffer.hpp"
|
||||
#include "utils/exceptions.hpp"
|
||||
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
using namespace Upload;
|
||||
using namespace Vulkan;
|
||||
|
||||
void Upload::upload(const Device& device, const Core::CommandPool& commandPool,
|
||||
Core::Image& image, const std::string& path) {
|
||||
// read iamge bytecode
|
||||
std::ifstream file(path, std::ios::ate | std::ios::binary);
|
||||
if (!file)
|
||||
throw std::system_error(errno, std::generic_category(), "Failed to open image: " + path);
|
||||
|
||||
std::streamsize size = file.tellg();
|
||||
size -= 124 - 4;
|
||||
std::vector<uint8_t> code(static_cast<size_t>(size));
|
||||
|
||||
file.seekg(0, std::ios::beg);
|
||||
if (!file.read(reinterpret_cast<char*>(code.data()), size))
|
||||
throw std::system_error(errno, std::generic_category(), "Failed to read image: " + path);
|
||||
|
||||
file.close();
|
||||
|
||||
// copy data to buffer
|
||||
const Vulkan::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);
|
||||
|
||||
if (!fence.wait(device))
|
||||
throw ls::vulkan_error(VK_TIMEOUT, "Upload operation timed out");
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue