diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.h b/rpcs3/Emu/RSX/VK/VKGSRender.h index 2596b71345..a335e1ad2e 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.h +++ b/rpcs3/Emu/RSX/VK/VKGSRender.h @@ -66,7 +66,7 @@ struct command_buffer_chunk: public vk::command_buffer VkFenceCreateInfo info = {}; info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; - vkCreateFence(m_device, &info, nullptr, &submit_fence); + CHECK_RESULT(vkCreateFence(m_device, &info, nullptr, &submit_fence)); } void destroy() @@ -90,7 +90,7 @@ struct command_buffer_chunk: public vk::command_buffer if (pending) wait(); - vkResetCommandBuffer(commands, 0); + CHECK_RESULT(vkResetCommandBuffer(commands, 0)); } bool poke() @@ -101,7 +101,7 @@ struct command_buffer_chunk: public vk::command_buffer if (pending) { - vkResetFences(m_device, 1, &submit_fence); + vk::reset_fence(&submit_fence); pending = false; } } @@ -121,11 +121,11 @@ struct command_buffer_chunk: public vk::command_buffer case VK_SUCCESS: break; case VK_NOT_READY: - vkWaitForFences(m_device, 1, &submit_fence, VK_TRUE, UINT64_MAX); + CHECK_RESULT(vkWaitForFences(m_device, 1, &submit_fence, VK_TRUE, UINT64_MAX)); break; } - vkResetFences(m_device, 1, &submit_fence); + vk::reset_fence(&submit_fence); pending = false; } }; diff --git a/rpcs3/Emu/RSX/VK/VKHelpers.cpp b/rpcs3/Emu/RSX/VK/VKHelpers.cpp index 1f186c806d..84d7aa2a8b 100644 --- a/rpcs3/Emu/RSX/VK/VKHelpers.cpp +++ b/rpcs3/Emu/RSX/VK/VKHelpers.cpp @@ -19,6 +19,7 @@ namespace vk bool g_drv_no_primitive_restart_flag = false; bool g_drv_force_32bit_indices = false; bool g_drv_sanitize_fp_values = false; + bool g_drv_disable_fence_reset = false; u64 g_num_processed_frames = 0; u64 g_num_total_frames = 0; @@ -307,7 +308,7 @@ namespace vk g_current_renderer = device; const auto gpu_name = g_current_renderer.gpu().name(); -#ifdef _WIN32 + bool gcn4_proprietary = false; const std::array black_listed = { // Black list all polaris unless its proven they dont have a problem with primitive restart @@ -326,16 +327,18 @@ namespace vk if (gpu_name.find(test) != std::string::npos) { g_drv_no_primitive_restart_flag = !g_cfg.video.vk.force_primitive_restart; + gcn4_proprietary = true; break; } } //Older cards back to GCN1 break primitive restart on 16-bit indices - if (gpu_name.find("Radeon") != std::string::npos) + if (!gcn4_proprietary && gpu_name.find("Radeon") != std::string::npos) { + //gcn1 - gcn3 workarounds g_drv_force_32bit_indices = true; + g_drv_disable_fence_reset = true; } -#endif //Nvidia cards are easily susceptible to NaN poisoning if (gpu_name.find("NVIDIA") != std::string::npos || gpu_name.find("GeForce") != std::string::npos) @@ -359,6 +362,11 @@ namespace vk return g_drv_sanitize_fp_values; } + bool fence_reset_disabled() + { + return g_drv_disable_fence_reset; + } + void change_image_layout(VkCommandBuffer cmd, VkImage image, VkImageLayout current_layout, VkImageLayout new_layout, VkImageSubresourceRange range) { //Prepare an image to match the new layout.. @@ -534,6 +542,22 @@ namespace vk return (g_num_processed_frames > 0)? g_num_processed_frames - 1: 0; } + void reset_fence(VkFence *pFence) + { + if (g_drv_disable_fence_reset) + { + vkDestroyFence(g_current_renderer, *pFence, nullptr); + + VkFenceCreateInfo info = {}; + info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; + CHECK_RESULT(vkCreateFence(g_current_renderer, &info, nullptr, pFence)); + } + else + { + CHECK_RESULT(vkResetFences(g_current_renderer, 1, pFence)); + } + } + void die_with_error(const char* faulting_addr, VkResult error_code) { std::string error_message; diff --git a/rpcs3/Emu/RSX/VK/VKHelpers.h b/rpcs3/Emu/RSX/VK/VKHelpers.h index 4c6025c6b7..cecac23e68 100644 --- a/rpcs3/Emu/RSX/VK/VKHelpers.h +++ b/rpcs3/Emu/RSX/VK/VKHelpers.h @@ -73,6 +73,7 @@ namespace vk bool emulate_primitive_restart(); bool force_32bit_index_buffer(); bool sanitize_fp_values(); + bool fence_reset_disabled(); VkComponentMapping default_component_map(); VkComponentMapping apply_swizzle_remap(const std::array& base_remap, const std::pair, std::array>& remap_vector); @@ -113,6 +114,9 @@ namespace vk const u64 get_current_frame_id(); const u64 get_last_completed_frame_id(); + //Fence reset with driver workarounds in place + void reset_fence(VkFence *pFence); + void die_with_error(const char* faulting_addr, VkResult error_code); struct memory_type_mapping diff --git a/rpcs3/Emu/RSX/VK/VKTextureCache.h b/rpcs3/Emu/RSX/VK/VKTextureCache.h index 67053f7012..c6fa488551 100644 --- a/rpcs3/Emu/RSX/VK/VKTextureCache.h +++ b/rpcs3/Emu/RSX/VK/VKTextureCache.h @@ -204,7 +204,7 @@ namespace vk //Now we need to restart the command-buffer to restore it to the way it was before... CHECK_RESULT(vkWaitForFences(*m_device, 1, &dma_fence, VK_TRUE, UINT64_MAX)); CHECK_RESULT(vkResetCommandBuffer(cmd, 0)); - CHECK_RESULT(vkResetFences(*m_device, 1, &dma_fence)); + vk::reset_fence(&dma_fence); if (cmd.access_hint != vk::command_buffer::access_type_hint::all) cmd.begin();