mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-24 14:49:42 -06:00
Vulkan: Fix present semaphores reuse
Fixes validation errors. See https://docs.vulkan.org/guide/latest/swapchain_semaphore_reuse.html
This commit is contained in:
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include "VideoBackends/Vulkan/VulkanContext.h"
|
#include "VideoBackends/Vulkan/VulkanContext.h"
|
||||||
#include "VideoCommon/Constants.h"
|
#include "VideoCommon/Constants.h"
|
||||||
|
#include "vulkan/vulkan_core.h"
|
||||||
|
|
||||||
namespace Vulkan
|
namespace Vulkan
|
||||||
{
|
{
|
||||||
@ -32,9 +33,9 @@ CommandBufferManager::~CommandBufferManager()
|
|||||||
DestroyCommandBuffers();
|
DestroyCommandBuffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CommandBufferManager::Initialize()
|
bool CommandBufferManager::Initialize(size_t swapchain_image_count)
|
||||||
{
|
{
|
||||||
if (!CreateCommandBuffers())
|
if (!CreateCommandBuffers(swapchain_image_count))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (m_use_threaded_submission && !CreateSubmitThread())
|
if (m_use_threaded_submission && !CreateSubmitThread())
|
||||||
@ -43,7 +44,7 @@ bool CommandBufferManager::Initialize()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CommandBufferManager::CreateCommandBuffers()
|
bool CommandBufferManager::CreateCommandBuffers(size_t swapchain_image_count)
|
||||||
{
|
{
|
||||||
static constexpr VkSemaphoreCreateInfo semaphore_create_info = {
|
static constexpr VkSemaphoreCreateInfo semaphore_create_info = {
|
||||||
VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, nullptr, 0};
|
VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, nullptr, 0};
|
||||||
@ -95,11 +96,17 @@ bool CommandBufferManager::CreateCommandBuffers()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
res = vkCreateSemaphore(device, &semaphore_create_info, nullptr, &m_present_semaphore);
|
m_present_semaphores.reserve(swapchain_image_count);
|
||||||
if (res != VK_SUCCESS)
|
for (uint32_t i = 0; i < swapchain_image_count; i++)
|
||||||
{
|
{
|
||||||
LOG_VULKAN_ERROR(res, "vkCreateSemaphore failed: ");
|
VkSemaphore present_semaphore;
|
||||||
return false;
|
res = vkCreateSemaphore(device, &semaphore_create_info, nullptr, &present_semaphore);
|
||||||
|
if (res != VK_SUCCESS)
|
||||||
|
{
|
||||||
|
LOG_VULKAN_ERROR(res, "vkCreateSemaphore failed: ");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
m_present_semaphores.push_back(present_semaphore);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Activate the first command buffer. BeginCommandBuffer moves forward, so start with the last
|
// Activate the first command buffer. BeginCommandBuffer moves forward, so start with the last
|
||||||
@ -140,7 +147,10 @@ void CommandBufferManager::DestroyCommandBuffers()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vkDestroySemaphore(device, m_present_semaphore, nullptr);
|
for (VkSemaphore present_semaphore : m_present_semaphores)
|
||||||
|
{
|
||||||
|
vkDestroySemaphore(device, present_semaphore, nullptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VkDescriptorPool CommandBufferManager::CreateDescriptorPool(u32 max_descriptor_sets)
|
VkDescriptorPool CommandBufferManager::CreateDescriptorPool(u32 max_descriptor_sets)
|
||||||
@ -414,7 +424,7 @@ void CommandBufferManager::SubmitCommandBuffer(u32 command_buffer_index,
|
|||||||
if (present_swap_chain != VK_NULL_HANDLE)
|
if (present_swap_chain != VK_NULL_HANDLE)
|
||||||
{
|
{
|
||||||
submit_info.signalSemaphoreCount = 1;
|
submit_info.signalSemaphoreCount = 1;
|
||||||
submit_info.pSignalSemaphores = &m_present_semaphore;
|
submit_info.pSignalSemaphores = &m_present_semaphores[present_image_index];
|
||||||
}
|
}
|
||||||
|
|
||||||
VkResult res =
|
VkResult res =
|
||||||
@ -433,7 +443,7 @@ void CommandBufferManager::SubmitCommandBuffer(u32 command_buffer_index,
|
|||||||
VkPresentInfoKHR present_info = {VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
|
VkPresentInfoKHR present_info = {VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
|
||||||
nullptr,
|
nullptr,
|
||||||
1,
|
1,
|
||||||
&m_present_semaphore,
|
&m_present_semaphores[present_image_index],
|
||||||
1,
|
1,
|
||||||
&present_swap_chain,
|
&present_swap_chain,
|
||||||
&present_image_index,
|
&present_image_index,
|
||||||
|
@ -21,7 +21,7 @@ public:
|
|||||||
explicit CommandBufferManager(bool use_threaded_submission);
|
explicit CommandBufferManager(bool use_threaded_submission);
|
||||||
~CommandBufferManager();
|
~CommandBufferManager();
|
||||||
|
|
||||||
bool Initialize();
|
bool Initialize(size_t swapchain_image_count);
|
||||||
|
|
||||||
// These command buffers are allocated per-frame. They are valid until the command buffer
|
// These command buffers are allocated per-frame. They are valid until the command buffer
|
||||||
// is submitted, after that you should call these functions again.
|
// is submitted, after that you should call these functions again.
|
||||||
@ -94,7 +94,7 @@ public:
|
|||||||
void DeferImageViewDestruction(VkImageView object);
|
void DeferImageViewDestruction(VkImageView object);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool CreateCommandBuffers();
|
bool CreateCommandBuffers(size_t swapchain_image_count);
|
||||||
void DestroyCommandBuffers();
|
void DestroyCommandBuffers();
|
||||||
|
|
||||||
bool CreateSubmitThread();
|
bool CreateSubmitThread();
|
||||||
@ -153,7 +153,7 @@ private:
|
|||||||
u32 command_buffer_index;
|
u32 command_buffer_index;
|
||||||
};
|
};
|
||||||
Common::WorkQueueThreadSP<PendingCommandBufferSubmit> m_submit_thread;
|
Common::WorkQueueThreadSP<PendingCommandBufferSubmit> m_submit_thread;
|
||||||
VkSemaphore m_present_semaphore = VK_NULL_HANDLE;
|
std::vector<VkSemaphore> m_present_semaphores = {};
|
||||||
Common::Flag m_last_present_failed;
|
Common::Flag m_last_present_failed;
|
||||||
VkResult m_last_present_result = VK_SUCCESS;
|
VkResult m_last_present_result = VK_SUCCESS;
|
||||||
bool m_use_threaded_submission = false;
|
bool m_use_threaded_submission = false;
|
||||||
|
@ -187,15 +187,6 @@ bool VideoBackend::Initialize(const WindowSystemInfo& wsi)
|
|||||||
|
|
||||||
UpdateActiveConfig();
|
UpdateActiveConfig();
|
||||||
|
|
||||||
// Create command buffers. We do this separately because the other classes depend on it.
|
|
||||||
g_command_buffer_mgr = std::make_unique<CommandBufferManager>(g_Config.bBackendMultithreading);
|
|
||||||
if (!g_command_buffer_mgr->Initialize())
|
|
||||||
{
|
|
||||||
PanicAlertFmt("Failed to create Vulkan command buffers");
|
|
||||||
Shutdown();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remaining classes are also dependent on object cache.
|
// Remaining classes are also dependent on object cache.
|
||||||
g_object_cache = std::make_unique<ObjectCache>();
|
g_object_cache = std::make_unique<ObjectCache>();
|
||||||
if (!g_object_cache->Initialize())
|
if (!g_object_cache->Initialize())
|
||||||
@ -218,6 +209,17 @@ bool VideoBackend::Initialize(const WindowSystemInfo& wsi)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create command buffers. We do this separately because the other classes depend on it.
|
||||||
|
g_command_buffer_mgr = std::make_unique<CommandBufferManager>(g_Config.bBackendMultithreading);
|
||||||
|
size_t swapchain_image_count =
|
||||||
|
surface != VK_NULL_HANDLE ? swap_chain->GetSwapChainImageCount() : 0;
|
||||||
|
if (!g_command_buffer_mgr->Initialize(swapchain_image_count))
|
||||||
|
{
|
||||||
|
PanicAlertFmt("Failed to create Vulkan command buffers");
|
||||||
|
Shutdown();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!StateTracker::CreateInstance())
|
if (!StateTracker::CreateInstance())
|
||||||
{
|
{
|
||||||
PanicAlertFmt("Failed to create state tracker");
|
PanicAlertFmt("Failed to create state tracker");
|
||||||
|
@ -39,6 +39,7 @@ public:
|
|||||||
u32 GetHeight() const { return m_height; }
|
u32 GetHeight() const { return m_height; }
|
||||||
u32 GetCurrentImageIndex() const { return m_current_swap_chain_image_index; }
|
u32 GetCurrentImageIndex() const { return m_current_swap_chain_image_index; }
|
||||||
bool IsCurrentImageValid() const { return m_current_swap_chain_image_is_valid; }
|
bool IsCurrentImageValid() const { return m_current_swap_chain_image_is_valid; }
|
||||||
|
size_t GetSwapChainImageCount() const { return m_swap_chain_images.size(); }
|
||||||
VkImage GetCurrentImage() const
|
VkImage GetCurrentImage() const
|
||||||
{
|
{
|
||||||
return m_swap_chain_images[m_current_swap_chain_image_index].image;
|
return m_swap_chain_images[m_current_swap_chain_image_index].image;
|
||||||
|
Reference in New Issue
Block a user