summaryrefslogtreecommitdiff
path: root/src/vulkan_helper.cpp
diff options
context:
space:
mode:
authorChuyan Zhang <me@zcy.moe>2024-09-14 22:38:51 -0700
committerChuyan Zhang <me@zcy.moe>2024-09-14 22:38:51 -0700
commite5eed5bdfa01cf549436c6001eaf334d266acc40 (patch)
tree0cef8c1c20aca8380d058c2676e0718040e3beda /src/vulkan_helper.cpp
parent7f14138e1baa2c40fb30d90ebcd45ad17b12e0a3 (diff)
downloadiris-e5eed5bdfa01cf549436c6001eaf334d266acc40.tar.gz
iris-e5eed5bdfa01cf549436c6001eaf334d266acc40.zip
fix lifetime problem
Diffstat (limited to 'src/vulkan_helper.cpp')
-rw-r--r--src/vulkan_helper.cpp133
1 files changed, 113 insertions, 20 deletions
diff --git a/src/vulkan_helper.cpp b/src/vulkan_helper.cpp
index 339b9c0..69617c4 100644
--- a/src/vulkan_helper.cpp
+++ b/src/vulkan_helper.cpp
@@ -12,12 +12,33 @@
#include <vk_mem_alloc.h>
#ifdef USE_VULKAN_VALIDATION_LAYERS
-static VKAPI_ATTR VkBool32 VKAPI_CALL debug_report(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object, size_t location, int32_t messageCode, const char* pLayerPrefix, const char* pMessage, void* pUserData)
+static VKAPI_ATTR VkBool32 VKAPI_CALL debug_report(
+ VkDebugReportFlagsEXT flags,
+ VkDebugReportObjectTypeEXT objectType,
+ uint64_t object,
+ size_t location,
+ int32_t messageCode,
+ const char* pLayerPrefix,
+ const char* pMessage,
+ void* pUserData)
{
(void)flags; (void)object; (void)location; (void)messageCode; (void)pUserData; (void)pLayerPrefix; // Unused arguments
fprintf(stderr, "[vulkan] Debug report from ObjectType: %i\nMessage: %s\n\n", objectType, pMessage);
return VK_FALSE;
}
+
+VKAPI_ATTR VkBool32 VKAPI_CALL debug_callback(
+ VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
+ VkDebugUtilsMessageTypeFlagsEXT messageType,
+ const VkDebugUtilsMessengerCallbackDataEXT* pCallbackData,
+ void* pUserData)
+{
+ (void) messageSeverity;
+ (void) messageType;
+ (void) pUserData;
+ std::cerr << "Validation layer: " << pCallbackData->pMessage << std::endl;
+ return VK_FALSE;
+}
#endif
namespace iris {
@@ -25,20 +46,24 @@ namespace iris {
Device::Device(std::vector<std::string> layers, std::vector<std::string> instance_extensions) {
VkApplicationInfo app_info = {
.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO,
- .pApplicationName = "IrisRenderer",
+ .pApplicationName = "Iris Renderer",
.applicationVersion = VK_MAKE_VERSION(1, 0, 0),
.pEngineName = "No Engine",
.engineVersion = VK_MAKE_VERSION(1, 0, 0),
.apiVersion = VK_API_VERSION_1_3,
};
+#ifdef USE_VULKAN_VALIDATION_LAYERS
+ layers.push_back("VK_LAYER_KHRONOS_validation");
+ instance_extensions.push_back("VK_EXT_debug_utils");
+#endif
+
// Create the Vulkan instance
uint32_t enabled_layer_count = layers.size();
std::vector<const char*> layers_cstr;
for (const auto& layer : layers) {
layers_cstr.push_back(layer.c_str());
}
-
uint32_t enabled_extension_count = instance_extensions.size();
std::vector<const char*> instance_extensions_cstr;
for (const auto& extension : instance_extensions) {
@@ -59,16 +84,32 @@ Device::Device(std::vector<std::string> layers, std::vector<std::string> instanc
&instance));
#ifdef USE_VULKAN_VALIDATION_LAYERS
- layers.push_back("VK_LAYER_KHRONOS_validation");
- auto vkCreateDebugReportCallback = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT");
+ auto vkCreateDebugReportCallback = (PFN_vkCreateDebugReportCallbackEXT)
+ vkGetInstanceProcAddr(instance, "vkCreateDebugReportCallbackEXT");
if (vkCreateDebugReportCallback) {
VkDebugReportCallbackCreateInfoEXT debug_report_create_info = {
.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT,
- .flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
+ .flags = VK_DEBUG_REPORT_ERROR_BIT_EXT |
+ VK_DEBUG_REPORT_WARNING_BIT_EXT |
+ VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT,
.pfnCallback = debug_report,
};
CHECK_VULKAN(vkCreateDebugReportCallback(instance, &debug_report_create_info, nullptr, &debugReportCallback));
}
+ auto vkCreateDebugUtilsMessenger = (PFN_vkCreateDebugUtilsMessengerEXT)
+ vkGetInstanceProcAddr(instance, "vkCreateDebugUtilsMessengerEXT");
+ if (vkCreateDebugUtilsMessenger) {
+ VkDebugUtilsMessengerCreateInfoEXT debug_utils_create_info = {
+ .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,
+ .messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT |
+ VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT,
+ .messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT |
+ VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
+ VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT,
+ .pfnUserCallback = debug_callback,
+ };
+ CHECK_VULKAN(vkCreateDebugUtilsMessenger(instance, &debug_utils_create_info, nullptr, &debugUtilsMessenger));
+ }
#endif
// Enumerate and select the physical device
@@ -196,6 +237,7 @@ CommandBuffer::CommandBuffer(VkDevice device,
{
VkCommandPoolCreateInfo pool_info = {
.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
+ .flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
.queueFamilyIndex = queue_family_index, // TODO: query capabilities to find a proper queue index
};
CHECK_VULKAN(vkCreateCommandPool(
@@ -225,7 +267,41 @@ CommandBuffer::CommandBuffer(VkDevice device,
&fence));
}
-CommandBuffer::~CommandBuffer() {
+AsyncCommandBuffer::AsyncCommandBuffer(VkDevice device,
+ uint32_t queue_family_index,
+ VkQueue queue)
+ : device(device), queue(queue)
+{
+ VkCommandPoolCreateInfo pool_info = {
+ .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
+ .flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
+ .queueFamilyIndex = queue_family_index, // TODO: query capabilities to find a proper queue index
+ };
+ CHECK_VULKAN(vkCreateCommandPool(
+ device,
+ &pool_info,
+ VK_NULL_HANDLE,
+ &this->pool));
+
+ VkCommandBufferAllocateInfo buffer_info = {
+ .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
+ .commandPool = this->pool,
+ .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
+ .commandBufferCount = 1,
+ };
+ CHECK_VULKAN(vkAllocateCommandBuffers(
+ device,
+ &buffer_info,
+ &buffer));
+}
+
+void AsyncCommandBuffer::destroy() {
+ vkFreeCommandBuffers(device, pool, 1, &buffer);
+ vkDestroyCommandPool(device, pool, VK_NULL_HANDLE);
+}
+
+
+void CommandBuffer::destroy() {
vkDestroyFence(device, fence, VK_NULL_HANDLE);
vkFreeCommandBuffers(device, pool, 1, &buffer);
vkDestroyCommandPool(device, pool, VK_NULL_HANDLE);
@@ -235,6 +311,10 @@ CommandBuffer Device::create_command_buffer() {
return CommandBuffer(device, main_queue_family_index, graphics_queue);
}
+AsyncCommandBuffer Device::create_async_command_buffer() {
+ return AsyncCommandBuffer(device, main_queue_family_index, graphics_queue);
+}
+
void CommandBuffer::begin(VkCommandBufferUsageFlags flags) {
CHECK_VULKAN(vkResetFences(device, 1, &fence));
CHECK_VULKAN(vkResetCommandPool(device, pool, 0u));
@@ -284,8 +364,12 @@ void Buffer_t::unmap() {
}
}
-Buffer_t::~Buffer_t() {
- vmaDestroyBuffer(allocator, buffer, allocation);
+void Buffer_t::release() {
+ if (buffer != VK_NULL_HANDLE) {
+ std::cerr << "Destroying buffer: 0x" << std::hex << (uint64_t)buffer << std::endl;
+ vmaDestroyBuffer(allocator, buffer, allocation);
+ buffer = VK_NULL_HANDLE;
+ }
}
Buffer_t Device::create_buffer_raw(VkDeviceSize size,
@@ -319,9 +403,12 @@ Buffer Device::create_buffer(VkDeviceSize size,
return std::make_shared<Buffer_t>(create_buffer_raw(size, usage, create_info));
}
-Texture2D_t::~Texture2D_t() {
- vmaDestroyImage(allocator, image, allocation);
- // TODO: optionally destroy image view, if created
+void Texture2D_t::release() {
+ if (image != VK_NULL_HANDLE) {
+ std::cerr << "Destroying image: 0x" << std::hex << (uint64_t)image << std::endl;
+ vmaDestroyImage(allocator, image, allocation);
+ image = VK_NULL_HANDLE;
+ }
}
Texture2D_t Device::create_texture_raw(VkExtent2D extent,
@@ -353,6 +440,7 @@ Texture2D_t Device::create_texture_raw(VkExtent2D extent,
&texture.image,
&texture.allocation,
VK_NULL_HANDLE));
+ std::cerr << "Created image: 0x" << std::hex << (uint64_t)texture.image << std::endl;
return texture;
}
@@ -361,7 +449,9 @@ Texture2D Device::create_texture(VkExtent2D extent,
VkImageUsageFlags usage,
VmaAllocationCreateInfo create_info)
{
- return std::make_shared<Texture2D_t>(create_texture_raw(extent, format, usage, create_info));
+ auto t = std::make_shared<Texture2D_t>(create_texture_raw(extent, format, usage, create_info));
+ std::cerr << "Before create texture terminates" << std::endl;
+ return t;
}
Texture2D Device::create_texture_from_image(const char* filename,
@@ -393,7 +483,7 @@ Texture2D Device::create_texture_from_image(const char* filename,
stbi_image_free(pixels);
VkExtent2D extent = {static_cast<uint32_t>(width), static_cast<uint32_t>(height)};
- Texture2D_t texture = create_texture_raw(extent, format, usage, create_info);
+ Texture2D texture = create_texture(extent, format, usage, create_info);
// Transit image layout for copying
{
@@ -403,15 +493,16 @@ Texture2D Device::create_texture_from_image(const char* filename,
.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
};
CHECK_VULKAN(vkBeginCommandBuffer(cmd_buf.buffer, &begin_info));
+ std::cerr << "Image layout transition for 0x" << std::hex << (uint64_t)texture->image << std::endl;
VkImageMemoryBarrier barrier = {
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
- .srcAccessMask = 0,
+ .srcAccessMask = VK_ACCESS_NONE,
.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
- .image = texture.image,
+ .image = texture->image,
.subresourceRange = {
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.levelCount = 1,
@@ -460,7 +551,7 @@ Texture2D Device::create_texture_from_image(const char* filename,
vkCmdCopyBufferToImage(
cmd_buf.buffer,
staging_buf.buffer,
- texture.image,
+ texture->image,
VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1,
&region);
@@ -490,7 +581,7 @@ Texture2D Device::create_texture_from_image(const char* filename,
.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
- .image = texture.image,
+ .image = texture->image,
.subresourceRange = {
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.levelCount = 1,
@@ -514,8 +605,10 @@ Texture2D Device::create_texture_from_image(const char* filename,
CHECK_VULKAN(vkQueueSubmit(graphics_queue, 1, &submit_info, cmd_buf.fence));
CHECK_VULKAN(vkWaitForFences(cmd_buf.device, 1, &cmd_buf.fence, VK_TRUE, std::numeric_limits<uint64_t>::max()));
}
- texture.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
- return std::make_shared<Texture2D_t>(texture);
+ texture->layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
+ std::cerr << "Image layout transition done" << std::endl;
+ staging_buf.release();
+ return texture;
}
} // namespace iris \ No newline at end of file