summaryrefslogtreecommitdiff
path: root/hk21/game/gpu.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'hk21/game/gpu.cpp')
-rw-r--r--hk21/game/gpu.cpp126
1 files changed, 100 insertions, 26 deletions
diff --git a/hk21/game/gpu.cpp b/hk21/game/gpu.cpp
index c036cf2..3ea0da1 100644
--- a/hk21/game/gpu.cpp
+++ b/hk21/game/gpu.cpp
@@ -15,6 +15,11 @@
#include "hk21/vulkan_loader/api.hpp"
+// @Todo Make fences recyclable
+// @Todo Make command pool recyclable
+// @Todo Make frame structure recyclable
+// @Todo Auto barriers for images
+
#define VK_ALLOCATOR nullptr
[[maybe_unused]] static void AslFormat(asl::Formatter& formatter, VkResult res)
@@ -194,6 +199,22 @@ static asl::status_or<PhysicalDeviceInfo> find_physical_device(VkInstance instan
continue;
}
+ VkPhysicalDeviceSynchronization2Features synchronization2_features{};
+ synchronization2_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES;
+ synchronization2_features.pNext = nullptr;
+
+ VkPhysicalDeviceFeatures2 features{};
+ features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
+ features.pNext = &synchronization2_features;
+
+ vkGetPhysicalDeviceFeatures2(physical_device, &features);
+
+ if (synchronization2_features.synchronization2 != VK_TRUE)
+ {
+ ASL_LOG_INFO("Device {}: synchronization2 not supported", name);
+ continue;
+ }
+
uint32_t queue_family_count{};
vkGetPhysicalDeviceQueueFamilyProperties(physical_device, &queue_family_count, nullptr);
queue_family_prps.resize_zero(queue_family_count);
@@ -232,9 +253,14 @@ static asl::status_or<VkDevice> create_device(VkPhysicalDevice physical_device,
.pQueuePriorities = &queue_priority,
};
+ VkPhysicalDeviceSynchronization2Features synchronization2_features{};
+ synchronization2_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SYNCHRONIZATION_2_FEATURES;
+ synchronization2_features.pNext = nullptr;
+ synchronization2_features.synchronization2 = VK_TRUE;
+
VkDeviceCreateInfo create_info{
.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
- .pNext = nullptr,
+ .pNext = &synchronization2_features,
.flags = 0,
.queueCreateInfoCount = 1,
.pQueueCreateInfos = &queue_create_info,
@@ -535,11 +561,13 @@ public:
return asl::runtime_error("Couldn't begin command buffer: {}", res);
}
- VkImageMemoryBarrier barrier1{
- .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
+ VkImageMemoryBarrier2 barrier1{
+ .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
.pNext = nullptr,
- .srcAccessMask = 0,
- .dstAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
+ .srcStageMask = VK_PIPELINE_STAGE_2_NONE,
+ .srcAccessMask = VK_ACCESS_2_NONE,
+ .dstStageMask = VK_PIPELINE_STAGE_2_CLEAR_BIT,
+ .dstAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT,
.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
.newLayout = VK_IMAGE_LAYOUT_GENERAL,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
@@ -554,7 +582,19 @@ public:
},
};
- vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, 0, nullptr, 0, nullptr, 1, &barrier1);
+ VkDependencyInfo dependency_info1{
+ .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
+ .pNext = nullptr,
+ .dependencyFlags = 0,
+ .memoryBarrierCount = 0,
+ .pMemoryBarriers = nullptr,
+ .bufferMemoryBarrierCount = 0,
+ .pBufferMemoryBarriers = nullptr,
+ .imageMemoryBarrierCount = 1,
+ .pImageMemoryBarriers = &barrier1,
+ };
+
+ vkCmdPipelineBarrier2(command_buffer, &dependency_info1);
VkClearColorValue clear_color{
.float32 = { 0.0F, 0.137F, 0.4F, 1.0F },
@@ -570,11 +610,13 @@ public:
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,
+ VkImageMemoryBarrier2 barrier2{
+ .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
.pNext = nullptr,
- .srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT,
- .dstAccessMask = VK_ACCESS_MEMORY_READ_BIT,
+ .srcStageMask = VK_PIPELINE_STAGE_2_CLEAR_BIT,
+ .srcAccessMask = VK_ACCESS_2_TRANSFER_WRITE_BIT,
+ .dstStageMask = VK_PIPELINE_STAGE_2_NONE,
+ .dstAccessMask = VK_ACCESS_2_NONE,
.oldLayout = VK_IMAGE_LAYOUT_GENERAL,
.newLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED,
@@ -589,7 +631,19 @@ public:
},
};
- vkCmdPipelineBarrier(command_buffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, 0, nullptr, 0, nullptr, 1, &barrier2);
+ VkDependencyInfo dependency_info2{
+ .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO,
+ .pNext = nullptr,
+ .dependencyFlags = 0,
+ .memoryBarrierCount = 0,
+ .pMemoryBarriers = nullptr,
+ .bufferMemoryBarrierCount = 0,
+ .pBufferMemoryBarriers = nullptr,
+ .imageMemoryBarrierCount = 1,
+ .pImageMemoryBarriers = &barrier2,
+ };
+
+ vkCmdPipelineBarrier2(command_buffer, &dependency_info2);
res = vkEndCommandBuffer(command_buffer);
if (res != VK_SUCCESS)
@@ -597,23 +651,46 @@ public:
return asl::runtime_error("Couldn't end command buffer: {}", res);
}
- VkPipelineStageFlags wait_dst_stage_mask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
-
VkFence fence = create_fence();
- VkSubmitInfo submit_info{
- .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
+ VkSemaphoreSubmitInfo semaphore_wait_submit_info{
+ .sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO,
.pNext = nullptr,
- .waitSemaphoreCount = 1,
- .pWaitSemaphores = &m_swapchain_image_acquire_semaphore,
- .pWaitDstStageMask = &wait_dst_stage_mask,
- .commandBufferCount = 1,
- .pCommandBuffers = &command_buffer,
- .signalSemaphoreCount = 1,
- .pSignalSemaphores = &m_queue_complete_semaphore,
+ .semaphore = m_swapchain_image_acquire_semaphore,
+ .value = 0,
+ .stageMask = VK_PIPELINE_STAGE_2_CLEAR_BIT,
+ .deviceIndex = 0,
};
- res = vkQueueSubmit(m_queue, 1, &submit_info, fence);
+ VkSemaphoreSubmitInfo semaphore_signal_submit_info{
+ .sType = VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO,
+ .pNext = nullptr,
+ .semaphore = m_queue_complete_semaphore,
+ .value = 0,
+ .stageMask = VK_PIPELINE_STAGE_2_CLEAR_BIT,
+ .deviceIndex = 0,
+ };
+
+ VkCommandBufferSubmitInfo command_buffer_submit_info{
+ .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO,
+ .pNext = nullptr,
+ .commandBuffer = command_buffer,
+ .deviceMask = 0,
+ };
+
+ VkSubmitInfo2 submit_info{
+ .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO_2,
+ .pNext = nullptr,
+ .flags = 0,
+ .waitSemaphoreInfoCount = 1,
+ .pWaitSemaphoreInfos = &semaphore_wait_submit_info,
+ .commandBufferInfoCount = 1,
+ .pCommandBufferInfos = &command_buffer_submit_info,
+ .signalSemaphoreInfoCount = 1,
+ .pSignalSemaphoreInfos = &semaphore_signal_submit_info,
+ };
+
+ res = vkQueueSubmit2(m_queue, 1, &submit_info, fence);
if (res != VK_SUCCESS)
{
return asl::runtime_error("Couldn't submit queue: {}", res);
@@ -645,9 +722,6 @@ public:
return asl::ok();
}
- // @Todo Make fences recyclable
- // @Todo Make frame structure recyclable
-
void recycle_resources()
{
while (!m_in_flight_frames.is_empty())