From 3aeae1b0bc1e09a47199747169fa585e6fc0f1a4 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Thu, 20 Jul 2023 00:17:48 +0200 Subject: [PATCH] [dxvk] Do not pass line rasterization info if not needed Works around some weird RADV issue and also ensures that we don't accidentally invalidate all sorts of shader caches. --- src/dxvk/dxvk_graphics.cpp | 33 +++++++++++++++++++++++++++++++-- src/dxvk/dxvk_graphics.h | 9 ++++++++- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/src/dxvk/dxvk_graphics.cpp b/src/dxvk/dxvk_graphics.cpp index 64c2f5619d9..a7943efe834 100644 --- a/src/dxvk/dxvk_graphics.cpp +++ b/src/dxvk/dxvk_graphics.cpp @@ -459,6 +459,7 @@ namespace dxvk { DxvkGraphicsPipelinePreRasterizationState::DxvkGraphicsPipelinePreRasterizationState( const DxvkDevice* device, const DxvkGraphicsPipelineStateInfo& state, + const DxvkShader* tes, const DxvkShader* gs) { // Set up tessellation state tsInfo.patchControlPoints = state.ia.patchVertexCount(); @@ -498,7 +499,7 @@ namespace dxvk { // Set up line rasterization mode as requested by the application. // Line width for rectangular lines matches D3D11 behaviour. - if (state.rs.lineMode() != VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT) { + if (state.rs.lineMode() != VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT && isLineRendering(state, tes, gs)) { rsLineInfo.pNext = std::exchange(rsInfo.pNext, &rsLineInfo); rsLineInfo.lineRasterizationMode = state.rs.lineMode(); @@ -560,6 +561,29 @@ namespace dxvk { } + bool DxvkGraphicsPipelinePreRasterizationState::isLineRendering( + const DxvkGraphicsPipelineStateInfo& state, + const DxvkShader* tes, + const DxvkShader* gs) { + bool isLineRendering = state.rs.polygonMode() == VK_POLYGON_MODE_LINE; + + if (gs) { + isLineRendering |= gs->info().outputTopology == VK_PRIMITIVE_TOPOLOGY_LINE_LIST; + } else if (tes) { + isLineRendering |= tes->info().outputTopology == VK_PRIMITIVE_TOPOLOGY_LINE_LIST; + } else { + VkPrimitiveTopology topology = state.ia.primitiveTopology(); + + isLineRendering |= topology == VK_PRIMITIVE_TOPOLOGY_LINE_LIST + || topology == VK_PRIMITIVE_TOPOLOGY_LINE_STRIP + || topology == VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY + || topology == VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY; + } + + return isLineRendering; + } + + DxvkGraphicsPipelineFragmentShaderState::DxvkGraphicsPipelineFragmentShaderState() { } @@ -1095,7 +1119,12 @@ namespace dxvk { // We do not implement setting certain rarely used render // states dynamically since they are generally not used - bool isLineRendering = state.rs.polygonMode() == VK_POLYGON_MODE_LINE; + bool isLineRendering = DxvkGraphicsPipelinePreRasterizationState::isLineRendering(state, m_shaders.tes.ptr(), m_shaders.gs.ptr()); + + if (state.rs.polygonMode() != VK_POLYGON_MODE_FILL + || state.rs.conservativeMode() != VK_CONSERVATIVE_RASTERIZATION_MODE_DISABLED_EXT + || (state.rs.lineMode() != VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT && isLineRendering)) + return false; if (m_shaders.gs != nullptr) { isLineRendering |= m_shaders.gs->info().outputTopology == VK_PRIMITIVE_TOPOLOGY_LINE_LIST; diff --git a/src/dxvk/dxvk_graphics.h b/src/dxvk/dxvk_graphics.h index f6f7dbe8fb8..a7129a459d7 100644 --- a/src/dxvk/dxvk_graphics.h +++ b/src/dxvk/dxvk_graphics.h @@ -168,6 +168,7 @@ namespace dxvk { DxvkGraphicsPipelinePreRasterizationState( const DxvkDevice* device, const DxvkGraphicsPipelineStateInfo& state, + const DxvkShader* tes, const DxvkShader* gs); VkPipelineViewportStateCreateInfo vpInfo = { VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO }; @@ -181,6 +182,12 @@ namespace dxvk { bool eq(const DxvkGraphicsPipelinePreRasterizationState& other) const; size_t hash() const; + + static bool isLineRendering( + const DxvkGraphicsPipelineStateInfo& state, + const DxvkShader* tes, + const DxvkShader* gs); + }; @@ -407,7 +414,7 @@ namespace dxvk { : shState(shaders, state), dyState(device, state, flags), viState(device, state, shaders.vs.ptr()), - prState(device, state, shaders.gs.ptr()), + prState(device, state, shaders.tes.ptr(), shaders.gs.ptr()), fsState(device, state), foState(device, state, shaders.fs.ptr()), scState(specConstantMask, state.sc) { }