#include "command.h" VkCommandBuffer command_begin_single(VkDevice device, VkCommandPool transfer_pool) { VkCommandBufferAllocateInfo command_info = { .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY, .commandPool = transfer_pool, .commandBufferCount = 1, }; VkCommandBuffer command_buffer; VkResult result = vkAllocateCommandBuffers(device, &command_info, &command_buffer); if(result != VK_SUCCESS) { return VK_NULL_HANDLE; } VkCommandBufferBeginInfo begin_info = { .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, .flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, }; result = vkBeginCommandBuffer(command_buffer, &begin_info); if(result != VK_SUCCESS) { vkFreeCommandBuffers(device, transfer_pool, 1, &command_buffer); return VK_NULL_HANDLE; } return command_buffer; } VkResult command_end_single(VkDevice device, VkCommandBuffer command_buffer, VkCommandPool transfer_pool, Queue transfer_queue) { VkResult result = vkEndCommandBuffer(command_buffer); if(result != VK_SUCCESS) { vkFreeCommandBuffers(device, transfer_pool, 1, &command_buffer); return result; } VkSubmitInfo submit_info = { .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, .commandBufferCount = 1, .pCommandBuffers = &command_buffer, }; result = vkQueueSubmit(transfer_queue.handle, 1, &submit_info, 0); if(result != VK_SUCCESS) { vkFreeCommandBuffers(device, transfer_pool, 1, &command_buffer); return result; } result = vkQueueWaitIdle(transfer_queue.handle); vkFreeCommandBuffers(device, transfer_pool, 1, &command_buffer); return result; } VkResult command_transition_image_layout(VkDevice device, VkCommandPool transfer_pool, Queue transfer_queue, VkImageLayout old_layout, VkImageLayout new_layout, VkImage image, VkAccessFlags src_mask, VkAccessFlags dst_mask, VkPipelineStageFlags source, VkPipelineStageFlags dest, uint32_t source_family, uint32_t dest_family, VkImageAspectFlags aspect_flags) { VkCommandBuffer command_buffer = command_begin_single(device, transfer_pool); VkImageMemoryBarrier barrier = { .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, .oldLayout = old_layout, .newLayout = new_layout, .srcQueueFamilyIndex = source_family, .dstQueueFamilyIndex = dest_family, .image = image, .subresourceRange = { .aspectMask = aspect_flags, .levelCount = 1, .layerCount = 1, .baseMipLevel = 0, .baseArrayLayer = 0, }, .srcAccessMask = src_mask, .dstAccessMask = dst_mask, }; vkCmdPipelineBarrier(command_buffer, source, dest, 0, 0, 0, 0, 0, 1, &barrier); return command_end_single(device, command_buffer, transfer_pool, transfer_queue); }