Skip to content

Commit

Permalink
Merge pull request #4924 from stenzek/vulkan-list-restart
Browse files Browse the repository at this point in the history
Vulkan: Fix GPU hangs on AMD Polaris
  • Loading branch information
stenzek committed Feb 18, 2017
2 parents 6acad27 + e2ddb38 commit b8eb108
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 2 deletions.
21 changes: 20 additions & 1 deletion Source/Core/VideoBackends/Vulkan/ObjectCache.cpp
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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;
Expand Down
5 changes: 4 additions & 1 deletion Source/Core/VideoBackends/Vulkan/VertexManager.cpp
Expand Up @@ -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;
}
Expand Down
5 changes: 5 additions & 0 deletions Source/Core/VideoBackends/Vulkan/VulkanContext.cpp
Expand Up @@ -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(
Expand Down
2 changes: 2 additions & 0 deletions Source/Core/VideoCommon/DriverDetails.cpp
Expand Up @@ -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;
Expand Down

0 comments on commit b8eb108

Please sign in to comment.