From ef3bf642b5231e6622bf8efefae1c97efee809b6 Mon Sep 17 00:00:00 2001 From: Steven Le Rouzic Date: Sun, 2 Feb 2025 23:57:56 +0100 Subject: Get a solid color on the window --- hk21/game/gpu.cpp | 182 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 180 insertions(+), 2 deletions(-) (limited to 'hk21/game/gpu.cpp') diff --git a/hk21/game/gpu.cpp b/hk21/game/gpu.cpp index 60aa6c2..d8533be 100644 --- a/hk21/game/gpu.cpp +++ b/hk21/game/gpu.cpp @@ -180,7 +180,7 @@ static asl::status_or find_physical_device(VkInstance instan VkPhysicalDeviceProperties prps; vkGetPhysicalDeviceProperties(physical_device, &prps); - // @Todo Add from_zstr to asl::string_view + // @Todo(asl) Add from_zstr to asl::string_view asl::string_view name{prps.deviceName, asl::strlen(prps.deviceName)}; if (prps.apiVersion < kTargetVersion) @@ -378,7 +378,7 @@ public: .height = asl::min(asl::max(height, caps.minImageExtent.height), caps.maxImageExtent.height), }, .imageArrayLayers = 1, - .imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, + .imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, .imageSharingMode = VK_SHARING_MODE_EXCLUSIVE, .queueFamilyIndexCount = 1, .pQueueFamilyIndices = &m_queue_family_index, @@ -413,6 +413,184 @@ public: return asl::ok(); } + + asl::status frame_opt() + { + VkSemaphoreCreateInfo semaphore_create_info{ + .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + }; + + VkSemaphore acquire_semaphore{}; + VkSemaphore queue_semaphore{}; + vkCreateSemaphore(m_device, &semaphore_create_info, VK_ALLOCATOR, &acquire_semaphore); + vkCreateSemaphore(m_device, &semaphore_create_info, VK_ALLOCATOR, &queue_semaphore); + + uint32_t image_index{}; + VkResult res = vkAcquireNextImageKHR(m_device, m_swapchain.value(), 0xffff'ffff'ffff'ffffLLU, acquire_semaphore, VK_NULL_HANDLE, &image_index); + if (res != VK_SUCCESS) + { + return asl::runtime_error("Couldn't acquire swapchain image: {}", res); + } + + VkCommandPoolCreateInfo command_pool_create_info{ + .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, + .pNext = nullptr, + .flags = 0, + .queueFamilyIndex = m_queue_family_index, + }; + + VkCommandPool command_pool{}; + res = vkCreateCommandPool(m_device, &command_pool_create_info, VK_ALLOCATOR, &command_pool); + if (res != VK_SUCCESS) + { + return asl::runtime_error("Couldn't create command pool: {}", res); + } + + VkCommandBufferAllocateInfo alloc_info{ + .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, + .pNext = nullptr, + .commandPool = command_pool, + .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY, + .commandBufferCount = 1, + }; + + VkCommandBuffer command_buffer{}; + res = vkAllocateCommandBuffers(m_device, &alloc_info, &command_buffer); + if (res != VK_SUCCESS) + { + return asl::runtime_error("Couldn't allocate command buffer: {}", res); + } + + VkCommandBufferBeginInfo begin_info{ + .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, + .pNext = nullptr, + .flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, + .pInheritanceInfo = nullptr, + }; + + res = vkBeginCommandBuffer(command_buffer, &begin_info); + if (res != VK_SUCCESS) + { + return asl::runtime_error("Couldn't begin command buffer: {}", res); + } + + VkImageMemoryBarrier barrier1{ + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + .pNext = nullptr, + .srcAccessMask = 0, + .dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, + .oldLayout = VK_IMAGE_LAYOUT_UNDEFINED, + .newLayout = VK_IMAGE_LAYOUT_GENERAL, + .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .image = m_swapchain_images[image_index], + .subresourceRange = { + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .baseMipLevel = 0, + .levelCount = 1, + .baseArrayLayer = 0, + .layerCount = 1, + }, + }; + + vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, &barrier1); + + VkClearColorValue clear_color{ + .float32 = { 0.0F, 0.137F, 0.4F, 1.0F }, + }; + + VkImageSubresourceRange range{ + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .baseMipLevel = 0, + .levelCount = 1, + .baseArrayLayer = 0, + .layerCount = 1, + }; + + vkCmdClearColorImage(command_buffer, m_swapchain_images[image_index], VK_IMAGE_LAYOUT_GENERAL, &clear_color, 1, &range); + + VkImageMemoryBarrier barrier2{ + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + .pNext = nullptr, + .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT, + .dstAccessMask = VK_ACCESS_MEMORY_READ_BIT, + .oldLayout = VK_IMAGE_LAYOUT_GENERAL, + .newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR, + .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .image = m_swapchain_images[image_index], + .subresourceRange = { + .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT, + .baseMipLevel = 0, + .levelCount = 1, + .baseArrayLayer = 0, + .layerCount = 1, + }, + }; + + vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, nullptr, 0, nullptr, 1, &barrier2); + + res = vkEndCommandBuffer(command_buffer); + if (res != VK_SUCCESS) + { + return asl::runtime_error("Couldn't end command buffer: {}", res); + } + + VkPipelineStageFlags wait_dst_stage_mask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + + VkSubmitInfo submit_info{ + .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, + .pNext = nullptr, + .waitSemaphoreCount = 1, + .pWaitSemaphores = &acquire_semaphore, + .pWaitDstStageMask = &wait_dst_stage_mask, + .commandBufferCount = 1, + .pCommandBuffers = &command_buffer, + .signalSemaphoreCount = 1, + .pSignalSemaphores = &queue_semaphore, + }; + + res = vkQueueSubmit(m_queue, 1, &submit_info, VK_NULL_HANDLE); + if (res != VK_SUCCESS) + { + return asl::runtime_error("Couldn't submit queue: {}", res); + } + + VkPresentInfoKHR present_info{ + .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR, + .pNext = nullptr, + .waitSemaphoreCount = 1, + .pWaitSemaphores = &queue_semaphore, + .swapchainCount = 1, + .pSwapchains = &m_swapchain.value(), + .pImageIndices = &image_index, + .pResults = nullptr, + }; + + res = vkQueuePresentKHR(m_queue, &present_info); + if (res != VK_SUCCESS) + { + return asl::runtime_error("Couldn't present queue: {}", res); + } + + vkDeviceWaitIdle(m_device); + vkDestroySemaphore(m_device, acquire_semaphore, VK_ALLOCATOR); + vkDestroySemaphore(m_device, queue_semaphore, VK_ALLOCATOR); + vkDestroyCommandPool(m_device, command_pool, VK_ALLOCATOR); + + return asl::ok(); + } + + void frame() override + { + auto s = frame_opt(); + if (!s.ok()) + { + ASL_LOG_ERROR("{}", s); + } + } }; asl::status_or> init(SDL_Window* window) -- cgit