diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index c9ba120e0..354e22331 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp @@ -28,6 +28,15 @@ static constexpr std::array LogicalStageToStageBit = { vk::ShaderStageFlagBits::eCompute, }; +static bool IsPrimitiveTopologyList(const vk::PrimitiveTopology topology) { + return topology == vk::PrimitiveTopology::ePointList || + topology == vk::PrimitiveTopology::eLineList || + topology == vk::PrimitiveTopology::eTriangleList || + topology == vk::PrimitiveTopology::eLineListWithAdjacency || + topology == vk::PrimitiveTopology::eTriangleListWithAdjacency || + topology == vk::PrimitiveTopology::ePatchList; +} + GraphicsPipeline::GraphicsPipeline( const Instance& instance, Scheduler& scheduler, DescriptorHeap& desc_heap, const Shader::Profile& profile, const GraphicsPipelineKey& key_, @@ -75,8 +84,13 @@ GraphicsPipeline::GraphicsPipeline( .pVertexAttributeDescriptions = vertex_attributes.data(), }; + const auto topology = LiverpoolToVK::PrimitiveType(key.prim_type); const vk::PipelineInputAssemblyStateCreateInfo input_assembly = { - .topology = LiverpoolToVK::PrimitiveType(key.prim_type), + .topology = topology, + // Avoid warning spam on all pipelines about unsupported restart disable, if not supported. + // However, must be false for list topologies to avoid validation errors. + .primitiveRestartEnable = + !instance.IsPrimitiveRestartDisableSupported() && !IsPrimitiveTopologyList(topology), }; const bool is_rect_list = key.prim_type == AmdGpu::PrimitiveType::RectList; @@ -114,10 +128,13 @@ GraphicsPipeline::GraphicsPipeline( vk::DynamicState::eDepthBiasEnableEXT, vk::DynamicState::eDepthBias, vk::DynamicState::eStencilTestEnableEXT, vk::DynamicState::eStencilReference, vk::DynamicState::eStencilCompareMask, vk::DynamicState::eStencilWriteMask, - vk::DynamicState::eStencilOpEXT, vk::DynamicState::ePrimitiveRestartEnableEXT, - vk::DynamicState::eCullModeEXT, vk::DynamicState::eFrontFaceEXT, + vk::DynamicState::eStencilOpEXT, vk::DynamicState::eCullModeEXT, + vk::DynamicState::eFrontFaceEXT, }; + if (instance.IsPrimitiveRestartDisableSupported()) { + dynamic_states.push_back(vk::DynamicState::ePrimitiveRestartEnableEXT); + } if (instance.IsDepthBoundsSupported()) { dynamic_states.push_back(vk::DynamicState::eDepthBoundsTestEnableEXT); dynamic_states.push_back(vk::DynamicState::eDepthBounds); diff --git a/src/video_core/renderer_vulkan/vk_instance.h b/src/video_core/renderer_vulkan/vk_instance.h index 04b68c1d0..6de419041 100644 --- a/src/video_core/renderer_vulkan/vk_instance.h +++ b/src/video_core/renderer_vulkan/vk_instance.h @@ -292,6 +292,11 @@ public: properties.limits.framebufferStencilSampleCounts; } + /// Returns whether disabling primitive restart is supported. + bool IsPrimitiveRestartDisableSupported() const { + return driver_id != vk::DriverId::eMoltenvk; + } + private: /// Creates the logical device opportunistically enabling extensions bool CreateDevice(); diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 3b63c3420..30102960a 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -1133,33 +1133,14 @@ void Rasterizer::UpdateDepthStencilState() const { } } -static bool IsPrimitiveListTopology(const AmdGpu::PrimitiveType prim_type) { - return prim_type == AmdGpu::PrimitiveType::PointList || - prim_type == AmdGpu::PrimitiveType::LineList || - prim_type == AmdGpu::PrimitiveType::TriangleList || - prim_type == AmdGpu::PrimitiveType::AdjLineList || - prim_type == AmdGpu::PrimitiveType::AdjTriangleList || - prim_type == AmdGpu::PrimitiveType::RectList || - prim_type == AmdGpu::PrimitiveType::QuadList; -} - void Rasterizer::UpdatePrimitiveState() const { const auto& regs = liverpool->regs; auto& dynamic_state = scheduler.GetDynamicState(); - auto prim_restart = (regs.enable_primitive_restart & 1) != 0; - if (prim_restart) { - ASSERT_MSG(regs.primitive_restart_index == 0xFFFF || - regs.primitive_restart_index == 0xFFFFFFFF, - "Primitive restart index other than -1 is not supported yet"); - - if (IsPrimitiveListTopology(regs.primitive_type) && !instance.IsListRestartSupported()) { - LOG_TRACE( - Render_Vulkan, - "Primitive restart is enabled for list topology but not supported by driver."); - prim_restart = false; - } - } + const auto prim_restart = (regs.enable_primitive_restart & 1) != 0; + ASSERT_MSG(!prim_restart || regs.primitive_restart_index == 0xFFFF || + regs.primitive_restart_index == 0xFFFFFFFF, + "Primitive restart index other than -1 is not supported yet"); const auto cull_mode = LiverpoolToVK::IsPrimitiveCulled(regs.primitive_type) ? LiverpoolToVK::CullMode(regs.polygon_control.CullingMode()) diff --git a/src/video_core/renderer_vulkan/vk_scheduler.cpp b/src/video_core/renderer_vulkan/vk_scheduler.cpp index 5101c562e..a48d93dee 100644 --- a/src/video_core/renderer_vulkan/vk_scheduler.cpp +++ b/src/video_core/renderer_vulkan/vk_scheduler.cpp @@ -290,7 +290,9 @@ void DynamicState::Commit(const Instance& instance, const vk::CommandBuffer& cmd } if (dirty_state.primitive_restart_enable) { dirty_state.primitive_restart_enable = false; - cmdbuf.setPrimitiveRestartEnableEXT(primitive_restart_enable); + if (instance.IsPrimitiveRestartDisableSupported()) { + cmdbuf.setPrimitiveRestartEnableEXT(primitive_restart_enable); + } } if (dirty_state.cull_mode) { dirty_state.cull_mode = false;