From ffe81338651a739b698dcd6ff015cdeafcc8ec2e Mon Sep 17 00:00:00 2001 From: kd-11 Date: Thu, 6 Oct 2022 20:42:22 +0300 Subject: [PATCH] vk: Avoid unnecessary dynamic state updates --- rpcs3/Emu/RSX/RSXThread.h | 5 +++ rpcs3/Emu/RSX/VK/VKDraw.cpp | 52 ++++++++++++++++++++--------- rpcs3/Emu/RSX/VK/VKGSRender.cpp | 3 ++ rpcs3/Emu/RSX/VK/vkutils/commands.h | 13 ++++---- rpcs3/Emu/RSX/rsx_methods.cpp | 3 ++ 5 files changed, 55 insertions(+), 21 deletions(-) diff --git a/rpcs3/Emu/RSX/RSXThread.h b/rpcs3/Emu/RSX/RSXThread.h index bb7b865ab5..d6cd96d274 100644 --- a/rpcs3/Emu/RSX/RSXThread.h +++ b/rpcs3/Emu/RSX/RSXThread.h @@ -148,12 +148,17 @@ namespace rsx push_buffer_arrays_dirty = 0x20000, // Push buffers have data written to them (immediate mode vertex buffers) + polygon_offset_state_dirty = 0x40000, // Polygon offset config was changed + fragment_program_dirty = fragment_program_ucode_dirty | fragment_program_state_dirty, vertex_program_dirty = vertex_program_ucode_dirty | vertex_program_state_dirty, invalidate_pipeline_bits = fragment_program_dirty | vertex_program_dirty, invalidate_zclip_bits = vertex_state_dirty | zclip_config_state_dirty, memory_barrier_bits = framebuffer_reads_dirty, + // Vulkan-specific signals + invalidate_vk_dynamic_state = zclip_config_state_dirty | scissor_config_state_dirty | polygon_offset_state_dirty, + all_dirty = ~0u }; diff --git a/rpcs3/Emu/RSX/VK/VKDraw.cpp b/rpcs3/Emu/RSX/VK/VKDraw.cpp index 11b5ed653d..9e366ba38b 100644 --- a/rpcs3/Emu/RSX/VK/VKDraw.cpp +++ b/rpcs3/Emu/RSX/VK/VKDraw.cpp @@ -128,26 +128,18 @@ void VKGSRender::update_draw_state() { m_profiler.start(); - const float actual_line_width = - m_device->get_wide_lines_support() ? rsx::method_registers.line_width() * rsx::get_resolution_scale() : 1.f; - vkCmdSetLineWidth(*m_current_command_buffer, actual_line_width); - - if (rsx::method_registers.poly_offset_fill_enabled()) + // Update conditional dynamic state + if (rsx::method_registers.current_draw_clause.primitive >= rsx::primitive_type::lines && + rsx::method_registers.current_draw_clause.primitive <= rsx::primitive_type::line_strip) { - //offset_bias is the constant factor, multiplied by the implementation factor R - //offst_scale is the slope factor, multiplied by the triangle slope factor M - vkCmdSetDepthBias(*m_current_command_buffer, rsx::method_registers.poly_offset_bias(), 0.f, rsx::method_registers.poly_offset_scale()); - } - else - { - //Zero bias value - disables depth bias - vkCmdSetDepthBias(*m_current_command_buffer, 0.f, 0.f, 0.f); + const float actual_line_width = + m_device->get_wide_lines_support() ? rsx::method_registers.line_width() * rsx::get_resolution_scale() : 1.f; + vkCmdSetLineWidth(*m_current_command_buffer, actual_line_width); } - //Update dynamic state if (rsx::method_registers.blend_enabled()) { - //Update blend constants + // Update blend constants auto blend_colors = rsx::get_constant_blend_colors(); vkCmdSetBlendConstants(*m_current_command_buffer, blend_colors.data()); } @@ -169,6 +161,26 @@ void VKGSRender::update_draw_state() } } + // The remaining dynamic state should only be set once and we have signals to enable/disable mid-renderpass + if (!(m_current_command_buffer->flags & vk::command_buffer::cb_reload_dynamic_state)) + { + // Dynamic state already set + m_frame_stats.setup_time += m_profiler.duration(); + return; + } + + if (rsx::method_registers.poly_offset_fill_enabled()) + { + // offset_bias is the constant factor, multiplied by the implementation factor R + // offst_scale is the slope factor, multiplied by the triangle slope factor M + vkCmdSetDepthBias(*m_current_command_buffer, rsx::method_registers.poly_offset_bias(), 0.f, rsx::method_registers.poly_offset_scale()); + } + else + { + // Zero bias value - disables depth bias + vkCmdSetDepthBias(*m_current_command_buffer, 0.f, 0.f, 0.f); + } + if (m_device->get_depth_bounds_support()) { f32 bounds_min, bounds_max; @@ -198,6 +210,7 @@ void VKGSRender::update_draw_state() //TODO: Set up other render-state parameters into the program pipeline + m_current_command_buffer->flags &= ~vk::command_buffer::cb_reload_dynamic_state; m_frame_stats.setup_time += m_profiler.duration(); } @@ -817,6 +830,9 @@ void VKGSRender::emit_geometry(u32 sub_index) vk::end_renderpass(cmd); } + // Starting a new renderpass should clobber dynamic state + m_current_command_buffer->flags |= vk::command_buffer::cb_reload_dynamic_state; + reload_state = true; }); @@ -1025,6 +1041,12 @@ void VKGSRender::end() u32 sub_index = 0; // RSX subdraw ID m_current_draw.subdraw_id = 0; // Host subdraw ID. Invalid RSX subdraws do not increment this value + if (m_graphics_state & rsx::pipeline_state::invalidate_vk_dynamic_state) + { + m_current_command_buffer->flags |= vk::command_buffer::cb_reload_dynamic_state; + m_graphics_state &= ~rsx::pipeline_state::invalidate_vk_dynamic_state; + } + rsx::method_registers.current_draw_clause.begin(); do { diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index 7b493ac0cc..8c9fad5df0 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -1169,6 +1169,7 @@ void VKGSRender::set_viewport() m_viewport.maxDepth = 1.f; } + m_current_command_buffer->flags |= vk::command_buffer::cb_reload_dynamic_state; m_graphics_state &= ~(rsx::pipeline_state::zclip_config_state_dirty); } @@ -1181,6 +1182,8 @@ void VKGSRender::set_scissor(bool clip_viewport) m_scissor.extent.width = scissor.width(); m_scissor.offset.x = scissor.x1; m_scissor.offset.y = scissor.y1; + + m_current_command_buffer->flags |= vk::command_buffer::cb_reload_dynamic_state; } } diff --git a/rpcs3/Emu/RSX/VK/vkutils/commands.h b/rpcs3/Emu/RSX/VK/vkutils/commands.h index 1374a89409..9ba6af0ccb 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/commands.h +++ b/rpcs3/Emu/RSX/VK/vkutils/commands.h @@ -81,12 +81,13 @@ namespace vk enum command_buffer_data_flag : u32 { - cb_has_occlusion_task = 1, - cb_has_blit_transfer = 2, - cb_has_dma_transfer = 4, - cb_has_open_query = 8, - cb_load_occluson_task = 16, - cb_has_conditional_render = 32 + cb_has_occlusion_task = 0x01, + cb_has_blit_transfer = 0x02, + cb_has_dma_transfer = 0x04, + cb_has_open_query = 0x08, + cb_load_occluson_task = 0x10, + cb_has_conditional_render = 0x20, + cb_reload_dynamic_state = 0x40 }; u32 flags = 0; diff --git a/rpcs3/Emu/RSX/rsx_methods.cpp b/rpcs3/Emu/RSX/rsx_methods.cpp index bbda7beaa4..9663550165 100644 --- a/rpcs3/Emu/RSX/rsx_methods.cpp +++ b/rpcs3/Emu/RSX/rsx_methods.cpp @@ -3473,6 +3473,9 @@ namespace rsx bind(NV4097_SET_BLEND_FUNC_DFACTOR, nv4097::set_blend_factor); bind(NV4097_SET_POLYGON_STIPPLE, nv4097::notify_state_changed); bind_array(NV4097_SET_POLYGON_STIPPLE_PATTERN, 1, 32, nv4097::notify_state_changed); + bind(NV4097_SET_POLY_OFFSET_FILL_ENABLE, nv4097::notify_state_changed); + bind(NV4097_SET_POLYGON_OFFSET_SCALE_FACTOR, nv4097::notify_state_changed); + bind(NV4097_SET_POLYGON_OFFSET_BIAS, nv4097::notify_state_changed); //NV308A (0xa400..0xbffc!) bind_array(NV308A_COLOR, 1, 256 * 7, nv308a::color::impl);