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/vksetup.h | 248 ++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 199 insertions(+), 49 deletions(-) (limited to 'src/vksetup.h') 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