From a6501b5d7ad204c3b998c843c7ed68ef7be323ba Mon Sep 17 00:00:00 2001 From: gramanas Date: Wed, 5 Jun 2024 19:04:25 +0300 Subject: more vks, stupid mutlistep build, and imgui --- src/cplusplus.cpp | 118 +++++++++++++++++++++++++- src/cplusplus.h | 15 +++- src/render.c | 201 ++++++++++++------------------------------- src/state.h | 9 -- src/vksetup.h | 248 +++++++++++++++++++++++++++++++++++++++++++----------- 5 files changed, 385 insertions(+), 206 deletions(-) (limited to 'src') diff --git a/src/cplusplus.cpp b/src/cplusplus.cpp index 4441cc2..750a5bf 100644 --- a/src/cplusplus.cpp +++ b/src/cplusplus.cpp @@ -1,5 +1,121 @@ // not needed yet -- add custom cpp functions first -// #include "cplusplus.h" +#include "cplusplus.h" +#include "vksetup.h" #define VMA_IMPLEMENTATION #include "vk_mem_alloc.h" + +#include +#include +#include + +static void check_vk_result(VkResult err) +{ + if (err == 0) + return; + fprintf(stderr, "[vulkan] Error: VkResult = %d\n", err); + if (err < 0) + abort(); +} + +void +imgui_draw_cmd(VkCommandBuffer cmd) +{ + ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), cmd); +} + +void +imgui_draw() +{ + ImGui::Render(); +} + +void +imgui_new_frame(vks_context vk) +{ + + ImGui_ImplVulkan_NewFrame(); + ImGui_ImplSDL2_NewFrame(); + + ImGui::NewFrame(); + + + ImGui::ShowDemoWindow(); +} + + +bool +imgui_proc_event(SDL_Event* e) +{ + return ImGui_ImplSDL2_ProcessEvent(e); +} + +static VkDescriptorPool imguiPool; +void +init_imgui(vks_context vk) +{ + VkDescriptorPoolSize pool_sizes[] = { + { VK_DESCRIPTOR_TYPE_SAMPLER, 1000 }, + { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1000 }, + { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 1000 }, + { VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1000 }, + { VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, 1000 }, + { VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, 1000 }, + { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1000 }, + { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1000 }, + { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1000 }, + { VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1000 }, + { VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 1000 } + }; + + VkDescriptorPoolCreateInfo pool_info = {}; + pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; + pool_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; + pool_info.maxSets = 1000; + pool_info.poolSizeCount = std::size(pool_sizes); + pool_info.pPoolSizes = pool_sizes; + + VK_CHECK(vkCreateDescriptorPool(vk.device, &pool_info, nullptr, &imguiPool)); + + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); + io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + io.ConfigFlags |= + ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls + + ImGui_ImplSDL2_InitForVulkan(vk.window); + ImGui_ImplVulkan_InitInfo init_info = {}; + init_info.Instance = vk.instance; + init_info.PhysicalDevice = vk.physical_device; + init_info.Device = vk.device; + //init_info.QueueFamily = ; + init_info.Queue = vk.graphics_and_compute_queue; + //init_info.PipelineCache = YOUR_PIPELINE_CACHE; + init_info.DescriptorPool = imguiPool; + init_info.Subpass = 0; + init_info.MinImageCount = 2; + init_info.ImageCount = 2; + init_info.MSAASamples = vk.msaa_samples; + init_info.CheckVkResultFn = check_vk_result; + init_info.UseDynamicRendering = true; + //init_info. + init_info.PipelineRenderingCreateInfo.sType = + VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR; + init_info.PipelineRenderingCreateInfo.colorAttachmentCount = 1; + init_info.PipelineRenderingCreateInfo.pColorAttachmentFormats = &vk.swapchain.image_format; + init_info.PipelineRenderingCreateInfo.depthAttachmentFormat = findDepthFormat(vk); + + ImGui_ImplVulkan_Init(&init_info); + // (this gets a bit more complicated, see example app for full reference) + ImGui_ImplVulkan_CreateFontsTexture(); + // (your code submit a queue) + ImGui_ImplVulkan_DestroyFontsTexture(); +} + +void +imgui_destroy(vks_context vk) +{ + ImGui_ImplVulkan_Shutdown(); + vkDestroyDescriptorPool(vk.device, imguiPool, nullptr); +} diff --git a/src/cplusplus.h b/src/cplusplus.h index 1e5f962..23d6a87 100644 --- a/src/cplusplus.h +++ b/src/cplusplus.h @@ -1,11 +1,24 @@ #ifndef CPLUSPLUS_H #define CPLUSPLUS_H +//#undef VKSETUP_IMPLEMENTATION +#include "vksetup.h" + #ifdef __cplusplus extern "C" { #endif -// cpp funcs + // cpp funcs + +void imgui_destroy(vks_context vk); +void init_imgui(vks_context vk); + +bool imgui_proc_event(SDL_Event* e); + +void imgui_new_frame(vks_context vk); + +void imgui_draw(); +void imgui_draw_cmd(VkCommandBuffer cmd); #ifdef __cplusplus } diff --git a/src/render.c b/src/render.c index ae9c05b..4893d64 100644 --- a/src/render.c +++ b/src/render.c @@ -18,15 +18,15 @@ #include "vk_mem_alloc.h" #define STB_IMAGE_IMPLEMENTATION -#include "../lib/stb_image.h" +#include #define FAST_OBJ_IMPLEMENTATION -#include "../lib/fast_obj.h" +#include #define CGLTF_IMPLEMENTATION -#include "../lib/cgltf.h" +#include -//#include "cplusplus.h" +#include "cplusplus.h" //#include "vkutil.h" #include "state.h" @@ -383,78 +383,6 @@ load_compile_shader_data(const char * path, shaderc_shader_kind shader_kind) return result; } -VkFormat -findSupportedFormat(VkFormat *candidates, size_t n, - VkImageTiling tiling, - VkFormatFeatureFlags features) -{ - for (size_t i = 0; i < n; i++) { - VkFormat format = candidates[i]; - VkFormatProperties props; - vkGetPhysicalDeviceFormatProperties(s.vk.physical_device, format, &props); - - if (tiling == VK_IMAGE_TILING_LINEAR && (props.linearTilingFeatures & features) == features) { - return format; - } else if (tiling == VK_IMAGE_TILING_OPTIMAL && (props.optimalTilingFeatures & features) == features) { - return format; - } - } - - vk_log(VK_ERROR, "failed to find supported format!\n"); - abort(); -} - -VkFormat -findDepthFormat() -{ - VkFormat formats[] = { VK_FORMAT_D32_SFLOAT, VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT}; - return findSupportedFormat(formats, VK_ARRAY_LEN(formats), - VK_IMAGE_TILING_OPTIMAL, - VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT); -} - -void -vulkan_create_depth_resources() -{ - VkFormat depth_format = findDepthFormat(); - vks_create_image(s.vk, s.vk.swapchain.extent.width, s.vk.swapchain.extent.height, 1, - depth_format, VK_IMAGE_TILING_OPTIMAL, - VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, - VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, s.vk.msaa_samples, - &s.depth_image); - s.depth_image.view = vks_create_image_view(s.vk, s.depth_image.handle, depth_format, - VK_IMAGE_ASPECT_DEPTH_BIT, 1); - - vks_transition_image_layout_info transition_info = { 0 }; - transition_info.cmd_info.vk = s.vk; - transition_info.cmd_info.pool = s.vk_command_pool; - transition_info.cmd_info.queue = s.vk_graphics_and_compute_queue; - transition_info.image = s.depth_image.handle; - transition_info.format = depth_format; - transition_info.srcAccessMask = VK_ACCESS_NONE; - transition_info.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | - VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; - transition_info.srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; - transition_info.dstStageMask = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT; - transition_info.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; - transition_info.newLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; - transition_info.mipLevels = 1; - - vks_transition_image_layout(&transition_info); -} - -void vulkan_create_color_resources() { - VkFormat colorFormat = s.vk.swapchain.image_format; - - vks_create_image(s.vk, s.vk.swapchain.extent.width, s.vk.swapchain.extent.height, 1, - colorFormat, VK_IMAGE_TILING_OPTIMAL, - VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT | - VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, - VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, s.vk.msaa_samples, - &s.color_image); - s.color_image.view = vks_create_image_view(s.vk, s.color_image.handle, colorFormat, VK_IMAGE_ASPECT_COLOR_BIT, 1); -} - void vulkan_create_graphics_pipeline(VkPolygonMode polygon_mode) { @@ -634,11 +562,12 @@ vulkan_create_graphics_pipeline(VkPolygonMode polygon_mode) depthStencil.back = (VkStencilOpState){0}; // Optional VkPipelineRenderingCreateInfo pipeline_rendering_create_info = { - .sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR, - .colorAttachmentCount = 1, - .pColorAttachmentFormats = &s.vk.swapchain.image_format, - .depthAttachmentFormat = findDepthFormat(), - }; + .sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR, + .colorAttachmentCount = 1, + .pColorAttachmentFormats = &s.vk.swapchain.image_format, + .depthAttachmentFormat = findDepthFormat(s.vk), + }; + VkGraphicsPipelineCreateInfo pipelineInfo = {0}; pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO; pipelineInfo.stageCount = 2; @@ -674,20 +603,6 @@ vulkan_create_graphics_pipeline(VkPolygonMode polygon_mode) vkDestroyShaderModule(s.vk.device, vertShaderModule, NULL); } -void -vulkan_create_command_pool() -{ - QueueFamilyIndices queueFamilyIndices = vulkan_find_queue_families(s.vk.physical_device); - - VkCommandPoolCreateInfo poolInfo = {0}; - poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; - // AMD doesn't like this flag for some reason - poolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; - poolInfo.queueFamilyIndex = queueFamilyIndices.graphicsAndComputeFamily; - - VK_CHECK(vkCreateCommandPool(s.vk.device, &poolInfo, NULL, &s.vk_command_pool)); -} - void vulkan_create_command_buffer() { @@ -695,7 +610,7 @@ vulkan_create_command_buffer() for (int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) { VkCommandBufferAllocateInfo allocInfo = {0}; allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; - allocInfo.commandPool = s.vk_command_pool; + allocInfo.commandPool = s.vk.command_pool; allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; allocInfo.commandBufferCount = 1; @@ -719,9 +634,6 @@ recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex) vks_transition_image_layout_info transition_info = { 0 }; - transition_info.cmd_info.vk = s.vk; - transition_info.cmd_info.pool = s.vk_command_pool; - transition_info.cmd_info.queue = s.vk_graphics_and_compute_queue; transition_info.image = s.vk.swapchain.images[imageIndex]; transition_info.format = VK_FORMAT_R8G8B8A8_SRGB; transition_info.srcAccessMask = 0; @@ -732,11 +644,11 @@ recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex) transition_info.newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; transition_info.mipLevels = 1; - vks_transition_image_layout(&transition_info); + vks_transition_image_layout(s.vk, &transition_info); VkRenderingAttachmentInfo colorAttachment = {0}; colorAttachment.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO; - colorAttachment.imageView = s.color_image.view; + colorAttachment.imageView = s.vk.color_image.view; colorAttachment.imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; colorAttachment.resolveMode = VK_RESOLVE_MODE_AVERAGE_BIT; colorAttachment.resolveImageView = s.vk.swapchain.image_views[imageIndex]; @@ -748,7 +660,7 @@ recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex) VkRenderingAttachmentInfo depthAttachment = {0}; depthAttachment.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO; - depthAttachment.imageView = s.depth_image.view; + depthAttachment.imageView = s.vk.depth_image.view; depthAttachment.imageLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL; depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; depthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; @@ -763,6 +675,7 @@ recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex) renderingInfo.pColorAttachments = &colorAttachment; renderingInfo.pDepthAttachment = &depthAttachment; + vkCmdBeginRendering(commandBuffer, &renderingInfo); vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, @@ -791,8 +704,10 @@ recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex) s.graphics_pipeline.layout, 0, 1, &s.frames[currentFrame].vk_descriptor_set, 0, NULL); - vkCmdDrawIndexed(commandBuffer, s.indices_count, 1, 0, 0, 0); + + imgui_draw(); // does this need to be here? + imgui_draw_cmd(commandBuffer); vkCmdEndRendering(commandBuffer); transition_info.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; @@ -802,7 +717,7 @@ recordCommandBuffer(VkCommandBuffer commandBuffer, uint32_t imageIndex) transition_info.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; transition_info.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR; - vks_transition_image_layout(&transition_info); + vks_transition_image_layout(s.vk, &transition_info); VK_CHECK(vkEndCommandBuffer(commandBuffer)); } @@ -848,8 +763,7 @@ vulkan_create_vertex_buffer() VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &s.vertex_buffer); - vks_command_info cmd_info = {s.vk, s.vk_command_pool, s.vk_graphics_and_compute_queue}; - vks_copy_buffer(&cmd_info, stagingBuffer.handle, s.vertex_buffer.handle, bufferSize); + vks_copy_buffer(s.vk, stagingBuffer.handle, s.vertex_buffer.handle, bufferSize); vkDestroyBuffer(s.vk.device, stagingBuffer.handle, NULL); vkFreeMemory(s.vk.device, stagingBuffer.memory, NULL); @@ -879,8 +793,7 @@ vulkan_create_index_buffer() VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &s.index_buffer); - vks_command_info cmd_info = {s.vk, s.vk_command_pool, s.vk_graphics_and_compute_queue}; - vks_copy_buffer(&cmd_info, stagingBuffer.handle, s.index_buffer.handle, bufferSize); + vks_copy_buffer(s.vk, stagingBuffer.handle, s.index_buffer.handle, bufferSize); vkDestroyBuffer(s.vk.device, stagingBuffer.handle, NULL); vkFreeMemory(s.vk.device, stagingBuffer.memory, NULL); @@ -1031,13 +944,13 @@ vulkan_create_descriptor_sets() void cleanupSwapChain() { - vkDestroyImageView(s.vk.device, s.color_image.view, NULL); - vkDestroyImage(s.vk.device, s.color_image.handle, NULL); - vkFreeMemory(s.vk.device, s.color_image.memory, NULL); + vkDestroyImageView(s.vk.device, s.vk.color_image.view, NULL); + vkDestroyImage(s.vk.device, s.vk.color_image.handle, NULL); + vkFreeMemory(s.vk.device, s.vk.color_image.memory, NULL); - vkDestroyImageView(s.vk.device, s.depth_image.view, NULL); - vkDestroyImage(s.vk.device, s.depth_image.handle, NULL); - vkFreeMemory(s.vk.device, s.depth_image.memory, NULL); + vkDestroyImageView(s.vk.device, s.vk.depth_image.view, NULL); + vkDestroyImage(s.vk.device, s.vk.depth_image.handle, NULL); + vkFreeMemory(s.vk.device, s.vk.depth_image.memory, NULL); for (uint32_t i = 0; i < s.vk.swapchain.image_count; i++) { vkDestroyImageView(s.vk.device, s.vk.swapchain.image_views[i], NULL); @@ -1050,17 +963,17 @@ recreateSwapChain() { vkDeviceWaitIdle(s.vk.device); - cleanupSwapChain(); + vks_cleanup_swapchain(s.vk); _vulkan_create_swap_chain(&s.vk); - vulkan_create_color_resources(); - vulkan_create_depth_resources(); + _vulkan_create_color_resources(&s.vk); + _vulkan_create_depth_resources(&s.vk); } void recreate_graphics_pipeline() { - recreateSwapChain(); + vks_recreate_swapchain(&s.vk); vkDestroyPipeline(s.vk.device, s.graphics_pipeline.handle, NULL); vkDestroyPipelineLayout(s.vk.device, s.graphics_pipeline.layout, NULL); vulkan_create_graphics_pipeline(s.polygon_mode); @@ -1078,6 +991,8 @@ handle_input(bool * quit) SDL_Event e; while (SDL_PollEvent(&e) != 0) { + imgui_proc_event(&e); + // User requests quit if (e.type == SDL_QUIT) { *quit = true; @@ -1233,13 +1148,8 @@ vulkan_create_texture_image() VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_SAMPLE_COUNT_1_BIT, &s.texture_image); - vks_command_info cmd_info = {0}; - cmd_info.vk = s.vk; - cmd_info.pool = s.vk_command_pool; - cmd_info.queue = s.vk_graphics_and_compute_queue; vks_transition_image_layout_info transition_info = { 0 }; - transition_info.cmd_info = cmd_info; transition_info.image = s.texture_image.handle; transition_info.format = VK_FORMAT_R8G8B8A8_SRGB; transition_info.srcAccessMask = 0; @@ -1250,14 +1160,14 @@ vulkan_create_texture_image() transition_info.newLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; transition_info.mipLevels = s.vk_mip_levels; - vks_transition_image_layout(&transition_info); + vks_transition_image_layout(s.vk, &transition_info); - vks_copy_buffer_to_image(&cmd_info, + vks_copy_buffer_to_image(s.vk, stagingBuffer.handle, s.texture_image.handle, (uint32_t)texWidth, (uint32_t)texHeight); - vks_generate_mipmaps(&cmd_info, s.texture_image.handle, VK_FORMAT_R8G8B8A8_SRGB, texWidth, texHeight, s.vk_mip_levels); + vks_generate_mipmaps(s.vk, s.texture_image.handle, VK_FORMAT_R8G8B8A8_SRGB, texWidth, texHeight, s.vk_mip_levels); transition_info.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; transition_info.dstAccessMask = VK_ACCESS_SHADER_READ_BIT; @@ -1266,15 +1176,11 @@ vulkan_create_texture_image() transition_info.oldLayout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; transition_info.newLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - vks_transition_image_layout(&transition_info); + vks_transition_image_layout(s.vk, &transition_info); vkDestroyBuffer(s.vk.device, stagingBuffer.handle, NULL); vkFreeMemory(s.vk.device, stagingBuffer.memory, NULL); -} -void -vulkan_create_texture_image_view() -{ s.texture_image.view = vks_create_image_view(s.vk, s.texture_image.handle, VK_FORMAT_R8G8B8A8_SRGB, VK_IMAGE_ASPECT_COLOR_BIT, s.vk_mip_levels); } @@ -1425,7 +1331,6 @@ void load_model_gltf() { s.vertices = (Vertex *)malloc(s.vertices_count * sizeof(Vertex)); // Read vertex positions for (cgltf_size k = 0; k < position_accessor->count; ++k) { - float vertex[3]; cgltf_accessor_read_float(position_accessor, k, (cgltf_float *)(&s.vertices[k].pos), 3); } } @@ -1517,11 +1422,10 @@ void vulkan_create_compute_stuff() memcpy(data, particles, (size_t)bufferSize); vkUnmapMemory(s.vk.device, stagingBuffer.memory); - vks_command_info cmd_info = {s.vk, s.vk_command_pool, s.vk_graphics_and_compute_queue}; for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) { vks_create_buffer(s.vk, bufferSize, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &s.frames[i].shader_storage_buffer); // Copy data from the staging buffer (host) to the shader storage buffer (GPU) - vks_copy_buffer(&cmd_info, stagingBuffer.handle, s.frames[i].shader_storage_buffer.handle, bufferSize); + vks_copy_buffer(s.vk, stagingBuffer.handle, s.frames[i].shader_storage_buffer.handle, bufferSize); } VkDescriptorSetLayoutBinding layoutBindings[3]; @@ -1569,7 +1473,6 @@ void vulkan_create_compute_stuff() } vkDestroyShaderModule(s.vk.device, compShaderModule, NULL); - } void @@ -1579,24 +1482,27 @@ init_vulkan() vk_log(VK_WARN, " DEBUG ON \n"); vk_log(VK_WARN, "====================================\n"); - vks_create_vulkan_context(&s.vk, &s.vk_graphics_and_compute_queue, &s.vk_present_queue); + vks_create_vulkan_context(&s.vk); vulkan_create_descriptor_set_layout(); + vulkan_create_graphics_pipeline(s.polygon_mode); //vulkan_create_compute_stuff(); - vulkan_create_command_pool(); - vulkan_create_depth_resources(); - vulkan_create_color_resources(); + vulkan_create_texture_image(); - vulkan_create_texture_image_view(); vulkan_create_texture_sampler(); + + init_imgui(s.vk); + load_model_obj(); //load_model_gltf(); vulkan_create_vertex_buffer(); vulkan_create_index_buffer(); + vulkan_create_uniform_buffers(); vulkan_create_descriptor_pool(); vulkan_create_descriptor_sets(); + vulkan_create_command_buffer(); vulkan_create_sync_objects(); } @@ -1612,9 +1518,11 @@ close_vulkan() vkDestroyFence(s.vk.device, s.frames[i].in_flight_fence, NULL); } - vkDestroyCommandPool(s.vk.device, s.vk_command_pool, NULL); + vkDestroyCommandPool(s.vk.device, s.vk.command_pool, NULL); + + vks_cleanup_swapchain(s.vk); - cleanupSwapChain(); + imgui_destroy(s.vk); vkDestroySampler(s.vk.device, s.vk_texture_sampler, NULL); vkDestroyImageView(s.vk.device, s.texture_image.view, NULL); @@ -1725,7 +1633,7 @@ draw_frame() VkResult result = vkAcquireNextImageKHR(s.vk.device, s.vk.swapchain.handle, UINT64_MAX, s.frames[currentFrame].image_available_semaphore, VK_NULL_HANDLE, &imageIndex); if (result == VK_ERROR_OUT_OF_DATE_KHR) { - recreateSwapChain(); + vks_recreate_swapchain(&s.vk); return; } else if (result != VK_SUCCESS && result != VK_SUBOPTIMAL_KHR) { vk_log(VK_ERROR, "failed to acquire swap chain image!\n"); @@ -1753,7 +1661,7 @@ draw_frame() submitInfo.signalSemaphoreCount = 1; submitInfo.pSignalSemaphores = &s.frames[currentFrame].render_finished_semaphore; - VK_CHECK(vkQueueSubmit(s.vk_graphics_and_compute_queue, 1, &submitInfo, s.frames[currentFrame].in_flight_fence)); + VK_CHECK(vkQueueSubmit(s.vk.graphics_and_compute_queue, 1, &submitInfo, s.frames[currentFrame].in_flight_fence)); VkSwapchainKHR swapChains[] = {s.vk.swapchain.handle}; VkPresentInfoKHR presentInfo = {0}; @@ -1765,11 +1673,11 @@ draw_frame() presentInfo.pImageIndices = &imageIndex; presentInfo.pResults = NULL; - result = vkQueuePresentKHR(s.vk_present_queue, &presentInfo); + result = vkQueuePresentKHR(s.vk.present_queue, &presentInfo); if (result == VK_ERROR_OUT_OF_DATE_KHR || result == VK_SUBOPTIMAL_KHR || s.sdl_window_resized) { s.sdl_window_resized = 0; - recreateSwapChain(); + vks_recreate_swapchain(&s.vk); } else if (result != VK_SUCCESS) { vk_log(VK_ERROR, "failed to present swap chain image!\n"); } @@ -1820,6 +1728,7 @@ main(int argc, char* argv[]) update_camera(0, 0); while (!quit) { handle_input(&quit); + imgui_new_frame(s.vk); draw_frame(); //SDL_Delay(16); } diff --git a/src/state.h b/src/state.h index d4f7e6c..6e78d49 100644 --- a/src/state.h +++ b/src/state.h @@ -99,15 +99,9 @@ typedef struct state { vks_context vk; - VkQueue vk_graphics_and_compute_queue; - VkQueue vk_present_queue; - VkDescriptorSetLayout vk_descriptor_set_layout; - vks_pipeline graphics_pipeline; - VkCommandPool vk_command_pool; - frame_data frames[MAX_FRAMES_IN_FLIGHT]; vks_buffer vertex_buffer; @@ -123,8 +117,6 @@ typedef struct state { vks_image texture_image; VkSampler vk_texture_sampler; - vks_image depth_image; - VkPolygonMode polygon_mode; Vertex *vertices; @@ -135,7 +127,6 @@ typedef struct state { char model_path[1000]; - vks_image color_image; VkDescriptorSetLayout vk_compute_descriptor_set_layout; VkPipelineLayout vk_compute_pipeline_layout; diff --git a/src/vksetup.h b/src/vksetup.h index e3b8f75..273a785 100644 --- a/src/vksetup.h +++ b/src/vksetup.h @@ -150,6 +150,9 @@ typedef struct vks_swapchain { VkExtent2D extent; uint32_t image_count; + + // todo: relace with vks_image although + // memory is managed by the swapchain VkImage images[5]; VkImageView image_views[5]; // 5 for some reason } vks_swapchain; @@ -180,6 +183,15 @@ typedef struct vks_context { vks_swapchain swapchain; + VkQueue graphics_and_compute_queue; + VkQueue present_queue; + VkQueue transfer_queue; + + VkCommandPool command_pool; + + vks_image color_image; + vks_image depth_image; + VkSampleCountFlagBits msaa_samples; } vks_context; @@ -197,17 +209,8 @@ typedef struct vks_frame_data { } vks_frame_data; /* Info structs */ -typedef struct vks_command_info -{ - vks_context vk; - VkCommandPool pool; - VkQueue queue; -} vks_command_info; - typedef struct vks_transition_image_layout_info { - /* command */ - vks_command_info cmd_info; /* image */ VkImage image; VkFormat format; @@ -222,15 +225,15 @@ typedef struct vks_transition_image_layout_info /* Exported API */ -VKSDEF void vks_create_vulkan_context (vks_context *vk, VkQueue *graphics_and_compute_queue, VkQueue *present_queue); +VKSDEF void vks_create_vulkan_context (vks_context *vk); VKSDEF void vks_create_buffer (const vks_context vk, const VkDeviceSize size, const VkBufferUsageFlags usage, const VkMemoryPropertyFlags properties, vks_buffer *buffer); VKSDEF void vks_create_image (const vks_context vk, const uint32_t width, const uint32_t height, const uint32_t mipLevels, const VkFormat format, const VkImageTiling tiling, const VkImageUsageFlags usage, const VkMemoryPropertyFlags properties, const VkSampleCountFlagBits numSamples, vks_image *image); -VKSDEF void vks_transition_image_layout (const vks_transition_image_layout_info *info); -VKSDEF void vks_copy_buffer (const vks_command_info *cmd_info, const VkBuffer src_buffer, VkBuffer dst_buffer, const VkDeviceSize size); -VKSDEF void vks_copy_buffer_to_image (const vks_command_info* cmd_info, const VkBuffer buffer, VkImage image, const uint32_t width, const uint32_t height); -VKSDEF void vks_generate_mipmaps (const vks_command_info* cmd_info, VkImage image, const VkFormat imageFormat, const int32_t texWidth, const int32_t texHeight, const uint32_t mipLevels); +VKSDEF void vks_transition_image_layout (const vks_context vk, const vks_transition_image_layout_info *info); +VKSDEF void vks_copy_buffer (const vks_context vk, const VkBuffer src_buffer, VkBuffer dst_buffer, const VkDeviceSize size); +VKSDEF void vks_copy_buffer_to_image (const vks_context vk, const VkBuffer buffer, VkImage image, const uint32_t width, const uint32_t height); +VKSDEF void vks_generate_mipmaps (const vks_context vk, VkImage image, const VkFormat imageFormat, const int32_t texWidth, const int32_t texHeight, const uint32_t mipLevels); VKSDEF VkImageView vks_create_image_view (const vks_context vk, VkImage image, VkFormat format, VkImageAspectFlags aspectFlags, uint32_t mipLevels); - +VKSDEF VkFormat findDepthFormat(const vks_context vk); /* VKSDEF void vulkan_create_descriptor_set_layout(); */ /* VKSDEF void vulkan_create_graphics_pipeline(); */ /* VKSDEF void vulkan_create_command_pool(); */ @@ -304,17 +307,17 @@ _find_memory_type(const vks_context vk, return 9999; } -static VkCommandBuffer -_vks_begin_single_time_commands(const vks_command_info *info) +VKSDEF VkCommandBuffer +_vks_begin_single_time_commands(const vks_context vk) { VkCommandBufferAllocateInfo allocInfo = {0}; allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; - allocInfo.commandPool = info->pool; + allocInfo.commandPool = vk.command_pool; allocInfo.commandBufferCount = 1; VkCommandBuffer commandBuffer; - VK_CHECK(vkAllocateCommandBuffers(info->vk.device, &allocInfo, &commandBuffer)); + VK_CHECK(vkAllocateCommandBuffers(vk.device, &allocInfo, &commandBuffer)); VkCommandBufferBeginInfo beginInfo = {0}; beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; @@ -324,8 +327,8 @@ _vks_begin_single_time_commands(const vks_command_info *info) return commandBuffer; } -static void -_vks_end_single_time_commands(const vks_command_info *info, VkCommandBuffer command_buffer) +VKSDEF void +_vks_end_single_time_commands(const vks_context vk, VkCommandBuffer command_buffer) { VK_CHECK(vkEndCommandBuffer(command_buffer)); @@ -334,10 +337,10 @@ _vks_end_single_time_commands(const vks_command_info *info, VkCommandBuffer comm submitInfo.commandBufferCount = 1; submitInfo.pCommandBuffers = &command_buffer; - VK_CHECK(vkQueueSubmit(info->queue, 1, &submitInfo, VK_NULL_HANDLE)); - VK_CHECK(vkQueueWaitIdle(info->queue)); + VK_CHECK(vkQueueSubmit(vk.graphics_and_compute_queue, 1, &submitInfo, VK_NULL_HANDLE)); + VK_CHECK(vkQueueWaitIdle(vk.graphics_and_compute_queue)); - vkFreeCommandBuffers(info->vk.device, info->pool, 1, &command_buffer); + vkFreeCommandBuffers(vk.device, vk.command_pool, 1, &command_buffer); } static int @@ -501,6 +504,33 @@ _vulkan_find_queue_families(vks_context* vk, VkPhysicalDevice device) vkGetPhysicalDeviceQueueFamilyProperties( device, &queueFamilyCount, queueFamilies); + /* vk_log(VK_INFO, "Found %ld queues\n", queueFamilyCount); */ + /* for (uint32_t i = 0; i < queueFamilyCount; i++) { */ + /* if (queueFamilies[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) { */ + /* vk_log(VK_INFO, " %d: VK_QUEUE_GRAPHICS_BIT\n", queueFamilies[i].queueFlags); */ + /* } */ + /* if (queueFamilies[i].queueFlags & VK_QUEUE_COMPUTE_BIT) { */ + /* vk_log(VK_INFO, " %d: VK_QUEUE_COMPUTE_BIT\n", queueFamilies[i].queueFlags); */ + /* } */ + /* if (queueFamilies[i].queueFlags & VK_QUEUE_TRANSFER_BIT) { */ + /* vk_log(VK_INFO, " %d: VK_QUEUE_TRANSFER_BIT\n", queueFamilies[i].queueFlags); */ + /* } */ + /* if (queueFamilies[i].queueFlags & VK_QUEUE_SPARSE_BINDING_BIT) { */ + /* vk_log(VK_INFO, " %d: VK_QUEUE_SPARSE_BINDING_BIT\n", queueFamilies[i].queueFlags); */ + /* } */ + /* if (queueFamilies[i].queueFlags & VK_QUEUE_PROTECTED_BIT) { */ + /* vk_log(VK_INFO, " %d: VK_QUEUE_PROTECTED_BIT\n", queueFamilies[i].queueFlags); */ + /* } */ + /* if (queueFamilies[i].queueFlags & VK_QUEUE_VIDEO_DECODE_BIT_KHR) { */ + /* vk_log(VK_INFO, " %d: VK_QUEUE_VIDEO_DECODE_BIT\n", queueFamilies[i].queueFlags); */ + /* } */ + /* if (queueFamilies[i].queueFlags & VK_QUEUE_VIDEO_ENCODE_BIT_KHR) { */ + /* vk_log(VK_INFO, " %d: VK_QUEUE_VIDEO_ENCODE_BIT\n", queueFamilies[i].queueFlags); */ + /* } */ + /* if (queueFamilies[i].queueFlags & VK_QUEUE_OPTICAL_FLOW_BIT_NV) { */ + /* vk_log(VK_INFO, " %d: VK_QUEUE_OPTICAL_FLOW_BIT\n", queueFamilies[i].queueFlags); */ + /* } */ + /* } */ for (uint32_t i = 0; i < queueFamilyCount; i++) { if ((queueFamilies[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) && (queueFamilies[i].queueFlags & VK_QUEUE_COMPUTE_BIT)) { @@ -647,8 +677,7 @@ _vulkan_pick_physical_device(vks_context* vk) uint32_t extensionCount = 0; vkEnumerateInstanceExtensionProperties(NULL, &extensionCount, NULL); VkExtensionProperties extensions[extensionCount]; - VkResult result = - vkEnumerateInstanceExtensionProperties(NULL, &extensionCount, extensions); + vkEnumerateInstanceExtensionProperties(NULL, &extensionCount, extensions); vk_log(VK_INFO, "Vulkan enabled extensions:\n"); for (uint32_t i = 0; i < extensionCount; i++) { @@ -657,9 +686,7 @@ _vulkan_pick_physical_device(vks_context* vk) } static void -_vulkan_create_logical_device(vks_context* vk, - VkQueue* graphics_and_compute_queue, - VkQueue* present_queue) +_vulkan_create_logical_device(vks_context* vk) { _QueueFamilyIndices indices = _vulkan_find_queue_families(vk, vk->physical_device); @@ -710,8 +737,8 @@ _vulkan_create_logical_device(vks_context* vk, vkGetDeviceQueue(vk->device, indices.graphicsAndComputeFamily, 0, - graphics_and_compute_queue); - vkGetDeviceQueue(vk->device, indices.presentFamily, 0, present_queue); + &vk->graphics_and_compute_queue); + vkGetDeviceQueue(vk->device, indices.presentFamily, 0, &vk->present_queue); } static VkSurfaceFormatKHR @@ -776,8 +803,6 @@ _chooseSwapExtent(const vks_context* vk, } } -static void bla() {printf("blah\n");} - VKSDEF void _vulkan_create_swap_chain(vks_context* vk) { @@ -862,12 +887,131 @@ _vulkan_create_swap_chain(vks_context* vk) } } +static void +_vulkan_create_command_pool(vks_context *vk) +{ + _QueueFamilyIndices queueFamilyIndices = _vulkan_find_queue_families(vk, vk->physical_device); + + VkCommandPoolCreateInfo poolInfo = {0}; + poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; + // AMD doesn't like this flag for some reason + poolInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; + poolInfo.queueFamilyIndex = queueFamilyIndices.graphicsAndComputeFamily; + + VK_CHECK(vkCreateCommandPool(vk->device, &poolInfo, NULL, &vk->command_pool)); +} + +VkFormat +_findSupportedFormat(const vks_context vk, + VkFormat* candidates, + size_t n, + VkImageTiling tiling, + VkFormatFeatureFlags features) +{ + for (size_t i = 0; i < n; i++) { + VkFormat format = candidates[i]; + VkFormatProperties props; + vkGetPhysicalDeviceFormatProperties(vk.physical_device, format, &props); + + if (tiling == VK_IMAGE_TILING_LINEAR && + (props.linearTilingFeatures & features) == features) { + return format; + } else if (tiling == VK_IMAGE_TILING_OPTIMAL && + (props.optimalTilingFeatures & features) == features) { + return format; + } + } + + vk_log(VK_ERROR, "failed to find supported format!\n"); + abort(); +} + +VKSDEF VkFormat +findDepthFormat(const vks_context vk) +{ + VkFormat formats[] = { VK_FORMAT_D32_SFLOAT, + VK_FORMAT_D32_SFLOAT_S8_UINT, + VK_FORMAT_D24_UNORM_S8_UINT }; + return _findSupportedFormat(vk, formats, + VK_ARRAY_LEN(formats), + VK_IMAGE_TILING_OPTIMAL, + VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT); +} + +VKSDEF void +_vulkan_create_depth_resources(vks_context *vk) +{ + VkFormat depth_format = findDepthFormat(*vk); + vks_create_image(*vk, vk->swapchain.extent.width, vk->swapchain.extent.height, 1, + depth_format, VK_IMAGE_TILING_OPTIMAL, + VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, vk->msaa_samples, + &vk->depth_image); + vk->depth_image.view = vks_create_image_view(*vk, vk->depth_image.handle, depth_format, + VK_IMAGE_ASPECT_DEPTH_BIT, 1); + + vks_transition_image_layout_info transition_info = { 0 }; + transition_info.image = vk->depth_image.handle; + transition_info.format = depth_format; + transition_info.srcAccessMask = VK_ACCESS_NONE; + transition_info.dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | + VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; + transition_info.srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; + transition_info.dstStageMask = VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT; + transition_info.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; + transition_info.newLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL; + transition_info.mipLevels = 1; + + //vks_transition_image_layout(*vk, &transition_info); +} + +VKSDEF void +_vulkan_create_color_resources(vks_context *vk) +{ + VkFormat colorFormat = vk->swapchain.image_format; + + vks_create_image(*vk, vk->swapchain.extent.width, vk->swapchain.extent.height, 1, + colorFormat, VK_IMAGE_TILING_OPTIMAL, + VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT | + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, + VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, vk->msaa_samples, + &vk->color_image); + vk->color_image.view = vks_create_image_view(*vk, vk->color_image.handle, colorFormat, VK_IMAGE_ASPECT_COLOR_BIT, 1); +} + /* Vks API implementation */ VKSDEF void -vks_create_vulkan_context(vks_context* vk, - VkQueue* graphics_and_compute_queue, - VkQueue* present_queue) +vks_cleanup_swapchain(const vks_context vk) +{ + vkDestroyImageView(vk.device, vk.color_image.view, NULL); + vkDestroyImage(vk.device, vk.color_image.handle, NULL); + vkFreeMemory(vk.device, vk.color_image.memory, NULL); + + vkDestroyImageView(vk.device, vk.depth_image.view, NULL); + vkDestroyImage(vk.device, vk.depth_image.handle, NULL); + vkFreeMemory(vk.device, vk.depth_image.memory, NULL); + + for (uint32_t i = 0; i < vk.swapchain.image_count; i++) { + vkDestroyImageView(vk.device, vk.swapchain.image_views[i], NULL); + } + vkDestroySwapchainKHR(vk.device, vk.swapchain.handle, NULL); +} + +VKSDEF void +vks_recreate_swapchain(vks_context* vk) +{ + vkDeviceWaitIdle(vk->device); + + vks_cleanup_swapchain(*vk); + + _vulkan_create_swap_chain(vk); + _vulkan_create_color_resources(vk); + _vulkan_create_depth_resources(vk); +} + +VKSDEF void +vks_create_vulkan_context(vks_context* vk) { /* Create vulkan instance */ vk->instance = _vks_create_instance(enable_validation_layers, @@ -888,11 +1032,17 @@ vks_create_vulkan_context(vks_context* vk, /* Create logical device and get queues */ /* TODO: Create vks_get_queue helpers?? */ - _vulkan_create_logical_device(vk, graphics_and_compute_queue, present_queue); + _vulkan_create_logical_device(vk); + + _vulkan_create_command_pool(vk); /* Create swapchain */ /* TODO: Make swapchain api */ _vulkan_create_swap_chain(vk); + + /* Create resources */ + _vulkan_create_color_resources(vk); + _vulkan_create_depth_resources(vk); } VKSDEF VkImageView @@ -920,14 +1070,14 @@ vks_create_image_view(const vks_context vk, } VKSDEF void -vks_generate_mipmaps(const vks_command_info* cmd_info, +vks_generate_mipmaps(const vks_context vk, VkImage image, const VkFormat imageFormat, const int32_t texWidth, const int32_t texHeight, const uint32_t mipLevels) { - VkCommandBuffer command_buffer = _vks_begin_single_time_commands(cmd_info); + VkCommandBuffer command_buffer = _vks_begin_single_time_commands(vk); VkImageMemoryBarrier barrier = { 0 }; barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; @@ -1007,17 +1157,17 @@ vks_generate_mipmaps(const vks_command_info* cmd_info, mipHeight /= 2; } - _vks_end_single_time_commands(cmd_info, command_buffer); + _vks_end_single_time_commands(vk, command_buffer); } VKSDEF void -vks_copy_buffer_to_image(const vks_command_info* cmd_info, +vks_copy_buffer_to_image(const vks_context vk, const VkBuffer buffer, VkImage image, const uint32_t width, const uint32_t height) { - VkCommandBuffer command_buffer = _vks_begin_single_time_commands(cmd_info); + VkCommandBuffer command_buffer = _vks_begin_single_time_commands(vk); VkBufferImageCopy region = { 0 }; region.bufferOffset = 0; @@ -1039,16 +1189,16 @@ vks_copy_buffer_to_image(const vks_command_info* cmd_info, 1, ®ion); - _vks_end_single_time_commands(cmd_info, command_buffer); + _vks_end_single_time_commands(vk, command_buffer); } VKSDEF void -vks_copy_buffer(const vks_command_info* cmd_info, +vks_copy_buffer(const vks_context vk, const VkBuffer src_buffer, VkBuffer dst_buffer, const VkDeviceSize size) { - VkCommandBuffer command_buffer = _vks_begin_single_time_commands(cmd_info); + VkCommandBuffer command_buffer = _vks_begin_single_time_commands(vk); VkBufferCopy copy_region = { 0 }; copy_region.srcOffset = 0; // Optional @@ -1056,13 +1206,13 @@ vks_copy_buffer(const vks_command_info* cmd_info, copy_region.size = size; vkCmdCopyBuffer(command_buffer, src_buffer, dst_buffer, 1, ©_region); - _vks_end_single_time_commands(cmd_info, command_buffer); + _vks_end_single_time_commands(vk, command_buffer); } VKSDEF void -vks_transition_image_layout(const vks_transition_image_layout_info* info) +vks_transition_image_layout(const vks_context vk, const vks_transition_image_layout_info* info) { - VkCommandBuffer command_buffer = _vks_begin_single_time_commands(&info->cmd_info); + VkCommandBuffer command_buffer = _vks_begin_single_time_commands(vk); VkImageMemoryBarrier barrier = { 0 }; barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; @@ -1101,7 +1251,7 @@ vks_transition_image_layout(const vks_transition_image_layout_info* info) 1, &barrier); - _vks_end_single_time_commands(&info->cmd_info, command_buffer); + _vks_end_single_time_commands(vk, command_buffer); } VKSDEF void -- cgit v1.2.3