From 6965dc04814a8eea3668c77de2e5e7f10eea2fef Mon Sep 17 00:00:00 2001 From: Stenzek Date: Sat, 18 Feb 2017 13:40:32 +1000 Subject: [PATCH 1/4] Vulkan: Don't enable primitive restart on list topologies --- .../Core/VideoBackends/Vulkan/ObjectCache.cpp | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/Source/Core/VideoBackends/Vulkan/ObjectCache.cpp b/Source/Core/VideoBackends/Vulkan/ObjectCache.cpp index 21459e8a8a..e484c27dac 100644 --- a/Source/Core/VideoBackends/Vulkan/ObjectCache.cpp +++ b/Source/Core/VideoBackends/Vulkan/ObjectCache.cpp @@ -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; From 40942680092418b0e213da9ef0576514557e53eb Mon Sep 17 00:00:00 2001 From: Stenzek Date: Sat, 18 Feb 2017 14:05:40 +1000 Subject: [PATCH 2/4] Vulkan: Use TRIANGLE_LIST when primitive restart is not supported --- Source/Core/VideoBackends/Vulkan/VertexManager.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Source/Core/VideoBackends/Vulkan/VertexManager.cpp b/Source/Core/VideoBackends/Vulkan/VertexManager.cpp index 63857a8c42..bbc187ff32 100644 --- a/Source/Core/VideoBackends/Vulkan/VertexManager.cpp +++ b/Source/Core/VideoBackends/Vulkan/VertexManager.cpp @@ -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; } From 50fa1355942162f7fc0f018cf528fc52a6c6e4e0 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Sat, 18 Feb 2017 14:13:32 +1000 Subject: [PATCH 3/4] Vulkan: Handle BUG_PRIMITIVE_RESTART --- Source/Core/VideoBackends/Vulkan/VulkanContext.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp b/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp index a7d1b628fb..7dc809e6b2 100644 --- a/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp +++ b/Source/Core/VideoBackends/Vulkan/VulkanContext.cpp @@ -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( From e2ddb3853eb8b285ceb488543d68f8c48af2b64d Mon Sep 17 00:00:00 2001 From: Stenzek Date: Sat, 18 Feb 2017 14:13:45 +1000 Subject: [PATCH 4/4] DriverDetails: Set BUG_PRIMITIVE_RESTART for AMD drivers --- Source/Core/VideoCommon/DriverDetails.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Source/Core/VideoCommon/DriverDetails.cpp b/Source/Core/VideoCommon/DriverDetails.cpp index 8d3c4715fb..072f7b69de 100644 --- a/Source/Core/VideoCommon/DriverDetails.cpp +++ b/Source/Core/VideoCommon/DriverDetails.cpp @@ -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 m_bugs;