From 9982f1be6f11c6d341197487867239b822e91350 Mon Sep 17 00:00:00 2001 From: psucien Date: Thu, 27 Jun 2024 22:10:55 +0200 Subject: [PATCH] renderer_vulkan: skip redundant FCE and FMask decompression passes --- src/video_core/amdgpu/liverpool.h | 18 ++++++++++++++++- .../renderer_vulkan/vk_pipeline_cache.cpp | 20 ++++++++++++++++++- .../renderer_vulkan/vk_rasterizer.cpp | 8 ++++++++ 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/src/video_core/amdgpu/liverpool.h b/src/video_core/amdgpu/liverpool.h index a170a30cf..68f7dc37f 100644 --- a/src/video_core/amdgpu/liverpool.h +++ b/src/video_core/amdgpu/liverpool.h @@ -606,6 +606,20 @@ struct Liverpool { BitField<30, 1, u32> enable; }; + union ColorControl { + enum class OperationMode : u32 { + Disable = 0u, + Normal = 1u, + EliminateFastClear = 2u, + Resolve = 3u, + FmaskDecompress = 5u, + }; + + BitField<3, 1, u32> degamma_enable; + BitField<4, 3, OperationMode> mode; + BitField<16, 8, u32> rop3; + }; + struct ColorBuffer { enum class EndianSwap : u32 { None = 0, @@ -825,7 +839,8 @@ struct Liverpool { u32 draw_initiator; INSERT_PADDING_WORDS(0xA200 - 0xA1F9 - 4); DepthControl depth_control; - INSERT_PADDING_WORDS(2); + INSERT_PADDING_WORDS(1); + ColorControl color_control; DepthBufferControl depth_buffer_control; ClipperControl clipper_control; PolygonControl polygon_control; @@ -995,6 +1010,7 @@ static_assert(GFX6_3D_REG_INDEX(blend_control) == 0xA1E0); static_assert(GFX6_3D_REG_INDEX(index_base_address) == 0xA1F9); static_assert(GFX6_3D_REG_INDEX(draw_initiator) == 0xA1FC); static_assert(GFX6_3D_REG_INDEX(depth_control) == 0xA200); +static_assert(GFX6_3D_REG_INDEX(color_control) == 0xA202); static_assert(GFX6_3D_REG_INDEX(clipper_control) == 0xA204); static_assert(GFX6_3D_REG_INDEX(viewport_control) == 0xA206); static_assert(GFX6_3D_REG_INDEX(vs_output_control) == 0xA207); diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index cb72edafb..96e731956 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -120,6 +120,11 @@ void PipelineCache::RefreshGraphicsKey() { key.depth_format = LiverpoolToVK::DepthFormat(db.z_info.format, db.stencil_info.format); key.depth.depth_enable.Assign(key.depth_format != vk::Format::eUndefined); } + + // TODO: Should be a check for `OperationMode::Disable` once we emulate HW state init packet + // sent by system software. + const auto skip_cb_binding = false; + // `RenderingInfo` is assumed to be initialized with a contiguous array of valid color // attachments. This might be not a case as HW color buffers can be bound in an arbitrary order. // We need to do some arrays compaction at this stage @@ -129,7 +134,7 @@ void PipelineCache::RefreshGraphicsKey() { int remapped_cb{}; for (auto cb = 0u; cb < Liverpool::NumColorBuffers; ++cb) { auto const& col_buf = regs.color_buffers[cb]; - if (!col_buf) { + if (!col_buf || skip_cb_binding) { continue; } const auto base_format = @@ -160,6 +165,19 @@ void PipelineCache::RefreshGraphicsKey() { std::unique_ptr PipelineCache::CreateGraphicsPipeline() { const auto& regs = liverpool->regs; + // There are several cases (e.g. FCE, FMask/HTile decompression) where we don't need to do an + // actual draw hence can skip pipeline creation. + if (regs.color_control.mode == Liverpool::ColorControl::OperationMode::EliminateFastClear) { + LOG_TRACE(Render_Vulkan, "FCE pass skipped"); + return {}; + } + + if (regs.color_control.mode == Liverpool::ColorControl::OperationMode::FmaskDecompress) { + // TODO: check for a valid MRT1 to promote the draw to the resolve pass. + LOG_TRACE(Render_Vulkan, "FMask decompression pass skipped"); + return {}; + } + u32 binding{}; std::array programs; std::array infos{}; diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 70c574366..ef937025b 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -40,6 +40,10 @@ void Rasterizer::Draw(bool is_indexed, u32 index_offset) { const auto& regs = liverpool->regs; const u32 num_indices = SetupIndexBuffer(is_indexed, index_offset); const GraphicsPipeline* pipeline = pipeline_cache.GetGraphicsPipeline(); + if (!pipeline) { + return; + } + pipeline->BindResources(memory, vertex_index_buffer, texture_cache); boost::container::static_vector @@ -117,6 +121,10 @@ void Rasterizer::DispatchDirect() { const auto cmdbuf = scheduler.CommandBuffer(); const auto& cs_program = liverpool->regs.cs_program; const ComputePipeline* pipeline = pipeline_cache.GetComputePipeline(); + if (!pipeline) { + return; + } + pipeline->BindResources(memory, vertex_index_buffer, texture_cache); cmdbuf.bindPipeline(vk::PipelineBindPoint::eCompute, pipeline->Handle());