diff options
author | Steven Le Rouzic <steven.lerouzic@gmail.com> | 2025-02-02 23:57:56 +0100 |
---|---|---|
committer | Steven Le Rouzic <steven.lerouzic@gmail.com> | 2025-02-02 23:57:56 +0100 |
commit | ef3bf642b5231e6622bf8efefae1c97efee809b6 (patch) | |
tree | 9fa3e31d1364453f1580e2f877a64793e38c73ff | |
parent | 41336fb9d421868fcc1b56f39232a665cabd2ef7 (diff) |
Get a solid color on the window
-rw-r--r-- | hk21/game/gpu.cpp | 182 | ||||
-rw-r--r-- | hk21/game/gpu.hpp | 2 | ||||
-rw-r--r-- | hk21/game/main.cpp | 2 | ||||
-rw-r--r-- | hk21/vulkan_loader/fns.hpp | 16 |
4 files changed, 199 insertions, 3 deletions
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<PhysicalDeviceInfo> 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<asl::box<Gpu>> init(SDL_Window* window)
diff --git a/hk21/game/gpu.hpp b/hk21/game/gpu.hpp index 40a0973..fb74e20 100644 --- a/hk21/game/gpu.hpp +++ b/hk21/game/gpu.hpp @@ -16,6 +16,8 @@ public: virtual ~Gpu() = default;
virtual void destroy() = 0;
+
+ virtual void frame() = 0;
};
asl::status_or<asl::box<Gpu>> init(SDL_Window* window);
diff --git a/hk21/game/main.cpp b/hk21/game/main.cpp index 2a9414e..ed4c738 100644 --- a/hk21/game/main.cpp +++ b/hk21/game/main.cpp @@ -32,6 +32,8 @@ int SDL_main(int /* argc */, char* /* argv */[]) }
}
+ gpu->frame();
+
SDL_Delay(16);
}
diff --git a/hk21/vulkan_loader/fns.hpp b/hk21/vulkan_loader/fns.hpp index 9994adb..8c45815 100644 --- a/hk21/vulkan_loader/fns.hpp +++ b/hk21/vulkan_loader/fns.hpp @@ -21,4 +21,18 @@ FN(vkDestroySwapchainKHR) \
FN(vkGetSwapchainImagesKHR) \
FN(vkAcquireNextImageKHR) \
- FN(vkQueuePresentKHR)
+ FN(vkQueuePresentKHR) \
+ FN(vkCreateCommandPool) \
+ FN(vkDestroyCommandPool) \
+ FN(vkResetCommandPool) \
+ FN(vkDeviceWaitIdle) \
+ FN(vkAllocateCommandBuffers) \
+ FN(vkResetCommandBuffer) \
+ FN(vkFreeCommandBuffers) \
+ FN(vkBeginCommandBuffer) \
+ FN(vkEndCommandBuffer) \
+ FN(vkQueueSubmit) \
+ FN(vkCreateSemaphore) \
+ FN(vkDestroySemaphore) \
+ FN(vkCmdPipelineBarrier) \
+ FN(vkCmdClearColorImage)
|