Merge pull request #4924 from stenzek/vulkan-list-restart

Vulkan: Fix GPU hangs on AMD Polaris
This commit is contained in:
Stenzek 2017-02-18 21:58:30 +10:00 committed by GitHub
commit b8eb1080ce
4 changed files with 31 additions and 2 deletions

View File

@ -72,6 +72,14 @@ bool ObjectCache::Initialize()
return true;
}
static bool IsStripPrimitiveTopology(VkPrimitiveTopology topology)
{
return topology == VK_PRIMITIVE_TOPOLOGY_LINE_STRIP ||
topology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP ||
topology == VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY ||
topology == VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY;
}
static VkPipelineRasterizationStateCreateInfo
GetVulkanRasterizationState(const RasterizationState& state)
{
@ -185,9 +193,20 @@ VkPipeline ObjectCache::CreatePipeline(const PipelineInfo& info)
nullptr, // const void* pNext
0, // VkPipelineInputAssemblyStateCreateFlags flags
info.primitive_topology, // VkPrimitiveTopology topology
VK_TRUE // VkBool32 primitiveRestartEnable
VK_FALSE // VkBool32 primitiveRestartEnable
};
// See Vulkan spec, section 19:
// If topology is VK_PRIMITIVE_TOPOLOGY_POINT_LIST, VK_PRIMITIVE_TOPOLOGY_LINE_LIST,
// VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY,
// VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY or VK_PRIMITIVE_TOPOLOGY_PATCH_LIST,
// primitiveRestartEnable must be VK_FALSE
if (g_ActiveConfig.backend_info.bSupportsPrimitiveRestart &&
IsStripPrimitiveTopology(info.primitive_topology))
{
input_assembly_state.primitiveRestartEnable = VK_TRUE;
}
// Shaders to stages
VkPipelineShaderStageCreateInfo shader_stages[3];
uint32_t num_shader_stages = 0;

View File

@ -153,7 +153,10 @@ void VertexManager::vFlush()
break;
case PRIMITIVE_TRIANGLES:
StateTracker::GetInstance()->SetPrimitiveTopology(VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP);
StateTracker::GetInstance()->SetPrimitiveTopology(
g_ActiveConfig.backend_info.bSupportsPrimitiveRestart ?
VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP :
VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST);
g_renderer->SetGenerationMode();
break;
}

View File

@ -276,6 +276,11 @@ void VulkanContext::PopulateBackendInfoFeatures(VideoConfig* config, VkPhysicalD
// Depth clamping implies shaderClipDistance and depthClamp
config->backend_info.bSupportsDepthClamp =
(features.depthClamp == VK_TRUE && features.shaderClipDistance == VK_TRUE);
// Our usage of primitive restart appears to be broken on AMD's binary drivers.
// Seems to be fine on GCN Gen 1-2, unconfirmed on GCN Gen 3, causes driver resets on GCN Gen 4.
if (DriverDetails::HasBug(DriverDetails::BUG_PRIMITIVE_RESTART))
config->backend_info.bSupportsPrimitiveRestart = false;
}
void VulkanContext::PopulateBackendInfoMultisampleModes(

View File

@ -90,6 +90,8 @@ static BugInfo m_known_bugs[] = {
BUG_BROKEN_DUAL_SOURCE_BLENDING, -1.0, -1.0, true},
{API_OPENGL, OS_OSX, VENDOR_INTEL, DRIVER_INTEL, Family::UNKNOWN,
BUG_BROKEN_DUAL_SOURCE_BLENDING, -1.0, -1.0, true},
{API_VULKAN, OS_ALL, VENDOR_ATI, DRIVER_ATI, Family::UNKNOWN, BUG_PRIMITIVE_RESTART, -1.0, -1.0,
true},
};
static std::map<Bug, BugInfo> m_bugs;