summaryrefslogtreecommitdiff
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
parent7f14138e1baa2c40fb30d90ebcd45ad17b12e0a3 (diff)
downloadiris-e5eed5bdfa01cf549436c6001eaf334d266acc40.tar.gz
iris-e5eed5bdfa01cf549436c6001eaf334d266acc40.zip
fix lifetime problem
-rw-r--r--CMakeLists.txt18
-rw-r--r--src/app.cpp20
-rw-r--r--src/vulkan_helper.cpp133
-rw-r--r--src/vulkan_helper.h20
-rw-r--r--src/vulkan_swapchain.cpp33
-rw-r--r--src/vulkan_swapchain.h2
6 files changed, 166 insertions, 60 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 10fb56f..b2dc213 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -2,13 +2,15 @@
cmake_minimum_required(VERSION 3.11)
-project(IrisRenderer VERSION 1.0)
+project(iris_renderer VERSION 1.0)
set(CMAKE_CXX_STANDARD 20)
set(PROJECT_ROOT ${CMAKE_SOURCE_DIR})
set(SRC_DIR ${PROJECT_ROOT}/src)
set(EXT_DIR ${PROJECT_ROOT}/ext)
-set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DUSE_VULKAN_VALIDATION_LAYERS")
+if (CMAKE_BUILD_TYPE STREQUAL "Debug")
+ add_compile_definitions(USE_VULKAN_VALIDATION_LAYERS)
+endif()
# Add external libraries
include(${EXT_DIR}/imgui.cmake)
@@ -28,21 +30,21 @@ target_include_directories(stb INTERFACE ${EXT_DIR}/stb)
file(GLOB_RECURSE SOURCES "${SRC_DIR}/*.cpp")
# Add executable from your source files
-add_executable(IrisRenderer ${SOURCES})
+add_executable(iris_renderer ${SOURCES})
find_package(glfw3 REQUIRED)
-target_link_libraries(IrisRenderer PRIVATE glfw)
+target_link_libraries(iris_renderer PRIVATE glfw)
find_package(Vulkan REQUIRED)
-target_link_libraries(IrisRenderer PRIVATE Vulkan::Vulkan)
+target_link_libraries(iris_renderer PRIVATE Vulkan::Vulkan)
find_package(VulkanMemoryAllocator CONFIG REQUIRED)
-target_link_libraries(IrisRenderer PRIVATE GPUOpen::VulkanMemoryAllocator)
+target_link_libraries(iris_renderer PRIVATE GPUOpen::VulkanMemoryAllocator)
# Link external libraries to your project
-target_link_libraries(IrisRenderer PRIVATE
+target_link_libraries(iris_renderer PRIVATE
argparse imgui tinygltf tinyobjloader stb
dl pthread X11 Xxf86vm Xrandr Xi)
# Optional: Include additional compiler options or flags
-target_compile_options(IrisRenderer PRIVATE -Wall -Wextra -Wno-missing-field-initializers)
+target_compile_options(iris_renderer PRIVATE -Wall -Wextra -Wno-missing-field-initializers)
diff --git a/src/app.cpp b/src/app.cpp
index 6148e04..f48edd9 100644
--- a/src/app.cpp
+++ b/src/app.cpp
@@ -16,7 +16,7 @@
#include <vector>
int main(int argc, char** argv) {
- argparse::ArgumentParser program("IrisRenderer");
+ argparse::ArgumentParser program("Iris Renderer");
program.add_argument("width")
.help("display width of the window")
.scan<'i', int>();
@@ -48,15 +48,11 @@ int main(int argc, char** argv) {
return -1;
}
auto glfw_extensions = get_glfw_instance_extensions();
- for (const auto& extension : glfw_extensions) {
- std::cerr << "GLFW extension: " << extension << std::endl;
- }
-
std::vector<std::string> layers;
- iris::Device device({}, glfw_extensions);
+ iris::Device device(layers, glfw_extensions);
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
- auto window = glfwCreateWindow(window_width, window_height, "IrisRenderer", nullptr, nullptr);
+ auto window = glfwCreateWindow(window_width, window_height, "Iris Renderer", nullptr, nullptr);
if (window == nullptr) {
std::cerr << "Failed to create GLFW window" << std::endl;
abort();
@@ -66,7 +62,9 @@ int main(int argc, char** argv) {
iris::Texture2D debug_texture = device.create_texture_from_image(
"assets/debug.png",
VK_FORMAT_R8G8B8A8_UNORM,
- VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT,
+ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
+ VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
+ VK_IMAGE_USAGE_TRANSFER_DST_BIT,
VmaAllocationCreateInfo {
.flags = VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT,
.usage = VMA_MEMORY_USAGE_AUTO,
@@ -74,7 +72,6 @@ int main(int argc, char** argv) {
// end load debug image
auto swapchain = iris::Swapchain(window, device, window_width, window_height);
- std::cerr << "Swapchain created" << std::endl;
while (!glfwWindowShouldClose(swapchain.window)) {
glfwPollEvents();
@@ -92,19 +89,16 @@ int main(int argc, char** argv) {
swapchain.needs_recreate = false;
}
- std::cerr << "Rendering frame" << std::endl;
ImGui_ImplVulkan_NewFrame();
ImGui_ImplGlfw_NewFrame();
swapchain.start_frame();
- std::cerr << "Frame started" << std::endl;
ImGui::NewFrame();
ImGui::ShowDemoWindow();
ImGui::Render();
- std::cerr << "ImGui rendered" << std::endl;
swapchain.display(debug_texture);
- std::cerr << "Frame displayed" << std::endl;
}
+ debug_texture->release();
ImGui_ImplVulkan_Shutdown();
glfwDestroyWindow(swapchain.window);
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
diff --git a/src/vulkan_helper.h b/src/vulkan_helper.h
index ebdd691..c2b1c8c 100644
--- a/src/vulkan_helper.h
+++ b/src/vulkan_helper.h
@@ -23,14 +23,13 @@ struct Buffer_t {
VkBuffer buffer;
VmaAllocator allocator;
VmaAllocation allocation;
-
VkBufferUsageFlags flags;
VkDeviceSize size;
void *mapped_data = nullptr;
- ~Buffer_t();
void* map();
void unmap();
+ void release();
};
typedef std::shared_ptr<Buffer_t> Buffer;
@@ -45,7 +44,7 @@ struct Texture2D_t {
VkImageUsageFlags flags;
VkExtent2D extent;
- ~Texture2D_t();
+ void release();
};
typedef std::shared_ptr<Texture2D_t> Texture2D;
@@ -60,12 +59,21 @@ struct CommandBuffer {
VkQueue queue;
CommandBuffer(VkDevice device, uint32_t queue_family_index, VkQueue queue);
- ~CommandBuffer();
-
+ void destroy();
void begin(VkCommandBufferUsageFlags flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT);
void submit_sync();
};
+struct AsyncCommandBuffer {
+ VkDevice device;
+ VkCommandPool pool;
+ VkCommandBuffer buffer;
+ VkQueue queue;
+
+ AsyncCommandBuffer(VkDevice device, uint32_t queue_family_index, VkQueue queue);
+ void destroy();
+};
+
struct Device {
VkInstance instance;
VkPhysicalDevice physical_device;
@@ -75,6 +83,7 @@ struct Device {
VmaAllocator allocator;
#ifdef USE_VULKAN_VALIDATION_LAYERS
VkDebugReportCallbackEXT debugReportCallback;
+ VkDebugUtilsMessengerEXT debugUtilsMessenger;
#endif
Device() = delete;
@@ -122,6 +131,7 @@ struct Device {
});
CommandBuffer create_command_buffer();
+ AsyncCommandBuffer create_async_command_buffer();
};
} // namespace iris \ No newline at end of file
diff --git a/src/vulkan_swapchain.cpp b/src/vulkan_swapchain.cpp
index 41d27a5..7916a3b 100644
--- a/src/vulkan_swapchain.cpp
+++ b/src/vulkan_swapchain.cpp
@@ -152,7 +152,7 @@ Swapchain::Swapchain(GLFWwindow *window,
, window(window)
, width(width)
, height(height)
- , cmd_buf(device.create_command_buffer())
+ , cmd_buf(device.create_async_command_buffer())
{
if (!glfwVulkanSupported()) {
std::cerr << "GLFW failed to find Vulkan support" << std::endl;
@@ -160,7 +160,6 @@ Swapchain::Swapchain(GLFWwindow *window,
abort();
}
- std::cerr << "Creating surface" << std::endl;
// Create the surface
CHECK_VULKAN(glfwCreateWindowSurface(
device.instance,
@@ -326,7 +325,6 @@ void Swapchain::start_frame() {
}
void Swapchain::display(Texture2D& texture) {
- std::cerr << "Displaying" << std::endl;
VkResult present_result = vkAcquireNextImageKHR(
device.device,
swapchain,
@@ -345,14 +343,13 @@ void Swapchain::display(Texture2D& texture) {
CHECK_VULKAN(present_result);
}
- std::cerr << "starting image layout transition" << std::endl;
// Command buffer begins at the very start of the frame
// Blit the texture to the swapchain image
{
// swapchain image layout, undefined -> transfer dst
VkImageMemoryBarrier swapchain_image_barrier = {
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
- .srcAccessMask = 0,
+ .srcAccessMask = VK_ACCESS_MEMORY_WRITE_BIT,
.dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
@@ -368,7 +365,7 @@ void Swapchain::display(Texture2D& texture) {
// src image layout, whatever -> transfer src
VkImageMemoryBarrier src_image_barrier = {
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
- .srcAccessMask = 0,
+ .srcAccessMask = VK_ACCESS_MEMORY_READ_BIT,
.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT,
.oldLayout = texture->layout,
.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
@@ -381,8 +378,9 @@ void Swapchain::display(Texture2D& texture) {
.layerCount = 1,
},
};
- VkImageMemoryBarrier barriers[2] = {swapchain_image_barrier, src_image_barrier};
- std::cerr << "starting image layout transition of 2" << std::endl;
+ VkImageMemoryBarrier barriers[] = {src_image_barrier, swapchain_image_barrier};
+ uint32_t barrier_count = sizeof(barriers) / sizeof(VkImageMemoryBarrier);
+
vkCmdPipelineBarrier(
cmd_buf.buffer,
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
@@ -390,7 +388,7 @@ void Swapchain::display(Texture2D& texture) {
0,
0, nullptr,
0, nullptr,
- 2, barriers);
+ barrier_count, barriers);
// Blit the texture to the swapchain image
VkImageBlit blit = {
@@ -415,7 +413,6 @@ void Swapchain::display(Texture2D& texture) {
{static_cast<int32_t>(width), static_cast<int32_t>(height), 1},
},
};
- std::cerr << "Starting blit" << std::endl;
vkCmdBlitImage(
cmd_buf.buffer,
texture->image,
@@ -435,15 +432,26 @@ void Swapchain::display(Texture2D& texture) {
VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
vkCmdPipelineBarrier(
cmd_buf.buffer,
- VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
+ VK_PIPELINE_STAGE_TRANSFER_BIT,
VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
0,
0, nullptr,
0, nullptr,
1, &swapchain_image_barrier);
+ src_image_barrier.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+ src_image_barrier.newLayout = texture->layout;
+ src_image_barrier.srcAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
+ src_image_barrier.dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
+ vkCmdPipelineBarrier(
+ cmd_buf.buffer,
+ VK_PIPELINE_STAGE_TRANSFER_BIT,
+ VK_PIPELINE_STAGE_TRANSFER_BIT,
+ 0,
+ 0, nullptr,
+ 0, nullptr,
+ 1, &src_image_barrier);
}
- std::cerr << "starting render pass" << std::endl;
// Render
VkRenderPassBeginInfo render_pass_begin_info = {
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
@@ -459,7 +467,6 @@ void Swapchain::display(Texture2D& texture) {
cmd_buf.buffer,
&render_pass_begin_info,
VK_SUBPASS_CONTENTS_INLINE);
- std::cerr << "rendering imgui" << std::endl;
ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmd_buf.buffer);
vkCmdEndRenderPass(cmd_buf.buffer);
diff --git a/src/vulkan_swapchain.h b/src/vulkan_swapchain.h
index b15028f..257840a 100644
--- a/src/vulkan_swapchain.h
+++ b/src/vulkan_swapchain.h
@@ -28,7 +28,7 @@ struct Swapchain {
VkFramebuffer framebuffers[SWAPCHAIN_IMAGE_COUNT];
VkSemaphore image_available_semaphores[SWAPCHAIN_IMAGE_COUNT];
VkSemaphore render_finished_semaphores[SWAPCHAIN_IMAGE_COUNT];
- CommandBuffer cmd_buf;
+ AsyncCommandBuffer cmd_buf;
Texture2D upload_texture;