vk: Improve compatibility workarounds

- Disable fence reset on gcn1 - gcn3
- Enable polaris+ workarounds on linux if proprietary driver is used
This commit is contained in:
kd-11 2018-03-26 14:40:23 +03:00
parent 05fc49506a
commit fca6c4fb7f
4 changed files with 37 additions and 9 deletions

View file

@ -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;
}
};

View file

@ -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<std::string, 8> 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;

View file

@ -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<VkComponentSwizzle, 4>& base_remap, const std::pair<std::array<u8, 4>, std::array<u8, 4>>& 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

View file

@ -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();