12#include <vulkan/vulkan.hpp>
31 if (res != VK_SUCCESS) \
32 engine_abort("Vulkan error: " #x); \
40inline std::expected<void, std::string>
43 const std::function<
void(
const vk::CommandBuffer&)>&
action) {
47 if (
alloc_res.result != vk::Result::eSuccess) {
48 return std::unexpected(
"Failed to allocate command buffers: " +
53 vk::CommandBufferBeginInfo
begin_info(vk::CommandBufferUsageFlagBits::eOneTimeSubmit);
56 return std::unexpected(
"Failed to begin cmdBuffer: " + vk::to_string(
res));
63 return std::unexpected(
"Failed to end cmdbuffer: " + vk::to_string(
res));
67 if (
fence_res.result != vk::Result::eSuccess) {
69 return std::unexpected(
"Failed to create fence: " + vk::to_string(
fence_res.result));
77 return std::unexpected(
"Failed to submit to queue: " + vk::to_string(
res));
81 res != vk::Result::eSuccess) {
83 return std::unexpected(
"Failed to wait for fence: " + vk::to_string(
res));
96inline std::pair<vk::UniqueBuffer, vk::UniqueDeviceMemory>
98 vk::DeviceSize size, vk::BufferUsageFlags
usage, vk::MemoryPropertyFlags
properties) {
101 vk::BufferCreateInfo
buffer_info({}, size,
usage, vk::SharingMode::eExclusive);
103 "Failed to create unique buffer: ");
111 device.allocateMemoryUnique(
allocate_info),
"Failed to allocate unique memory for buffer: ");
114 "Failed to bind buffer memory");
123inline std::pair<vk::UniqueImage, vk::UniqueDeviceMemory>
129 vk::ImageCreateInfo
image_info({}, vk::ImageType::e2D,
format, vk::Extent3D(width, height, 1), 1,
131 vk::SharingMode::eExclusive);
133 vk::UniqueImage image =
144 "Failed to bind image memory: ");
146 return {std::move(image), std::move(image_memory)};
154 vk::BufferImageCopy
region(0, 0, 0,
155 vk::ImageSubresourceLayers(vk::ImageAspectFlagBits::eColor, 0, 0, 1),
156 vk::Offset3D(0, 0, 0), vk::Extent3D(width, height, 1));
169 vk::ImageMemoryBarrier
barrier;
175 barrier.subresourceRange.aspectMask = vk::ImageAspectFlagBits::eColor;
176 barrier.subresourceRange.baseMipLevel = 0;
177 barrier.subresourceRange.levelCount = 1;
178 barrier.subresourceRange.baseArrayLayer = 0;
179 barrier.subresourceRange.layerCount = 1;
184 if (
old_layout == vk::ImageLayout::eUndefined &&
185 new_layout == vk::ImageLayout::eTransferDstOptimal) {
187 barrier.dstAccessMask = vk::AccessFlagBits::eTransferWrite;
191 }
else if (
old_layout == vk::ImageLayout::eTransferDstOptimal &&
192 new_layout == vk::ImageLayout::eShaderReadOnlyOptimal) {
193 barrier.srcAccessMask = vk::AccessFlagBits::eTransferWrite;
194 barrier.dstAccessMask = vk::AccessFlagBits::eShaderRead;
226 const std::filesystem::path&
file_path) {
233 return std::unexpected(
"Failed to load texture image: " +
file_path.string());
238 vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent);
241 "Failed to map texture image: ");
248 auto [image, image_memory] =
250 vk::ImageTiling::eOptimal,
251 vk::ImageUsageFlagBits::eTransferDst | vk::ImageUsageFlagBits::eSampled,
252 vk::MemoryPropertyFlagBits::eDeviceLocal);
257 vk::ImageLayout::eUndefined, vk::ImageLayout::eTransferDstOptimal);
261 vk::ImageLayout::eTransferDstOptimal,
262 vk::ImageLayout::eShaderReadOnlyOptimal);
266 return std::unexpected(
cmd_res.error());
269 vk::ImageViewCreateInfo
view_info({}, *image, vk::ImageViewType::e2D, vk::Format::eR8G8B8A8Srgb,
270 {}, {vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1});
272 "Failed to create unique image view: ");
274 return Texture{std::move(image), std::move(image_memory), std::move(image_view)};
284 const std::vector<char>&
code) {
285 ASSERT_ALWAYS(
code.size() % 4 == 0 &&
"SPIR-V code size must be a multiple of 4");
289 "Failed to create unique shaderModule: ");
#define ASSERT_ALWAYS(x)
Definition base.hpp:14
Definition Application.hpp:28
void transition_image_layout(const vk::CommandBuffer &cmd_buffer, const vk::Image &image, vk::Format format, vk::ImageLayout old_layout, vk::ImageLayout new_layout)
Definition utils.hpp:165
auto check_vulkan_res_val(T &&result, std::string_view message, std::source_location loc=std::source_location::current())
Definition vulkan_utils.hpp:20
void engine_abort()
Definition base.hpp:46
vk::UniqueShaderModule create_shader_module(const vk::Device &device, const std::vector< char > &code)
Definition utils.hpp:283
u32 find_memory_type(const vk::PhysicalDevice &physical_device, u32 type_filter, vk::MemoryPropertyFlags properties)
Definition vulkan_utils.hpp:37
std::pair< vk::UniqueImage, vk::UniqueDeviceMemory > create_image(const vk::Device &device, const vk::PhysicalDevice &physical_device, uint32_t width, uint32_t height, vk::Format format, vk::ImageTiling tiling, vk::ImageUsageFlags usage, vk::MemoryPropertyFlags properties)
Definition utils.hpp:124
void check_vulkan_res(vk::Result result, std::string_view message, std::source_location loc=std::source_location::current())
Definition vulkan_utils.hpp:10
void copy_buffer_to_image(const vk::CommandBuffer &cmd_buffer, const vk::Buffer &buffer, const vk::Image &image, uint32_t width, uint32_t height)
Definition utils.hpp:152
std::pair< vk::UniqueBuffer, vk::UniqueDeviceMemory > create_buffer(const vk::Device &device, const vk::PhysicalDevice &physical_device, vk::DeviceSize size, vk::BufferUsageFlags usage, vk::MemoryPropertyFlags properties)
Definition utils.hpp:97
std::expected< void, std::string > single_time_command(const vk::Device &device, const vk::Queue &queue, const vk::CommandPool &command_pool, const std::function< void(const vk::CommandBuffer &)> &action)
Definition utils.hpp:41
std::expected< Texture, std::string > create_texture(const vk::Device &device, const vk::PhysicalDevice &physical_device, const vk::Queue &graphics_queue, const vk::CommandPool &command_pool, const std::filesystem::path &file_path)
Definition utils.hpp:222
vk::UniqueDeviceMemory image_memory
Definition utils.hpp:212
vk::UniqueImageView image_view
Definition utils.hpp:213
vk::UniqueImage image
Definition utils.hpp:211
constexpr T g_type_max
Definition types.hpp:21