From 1fd265d316c0b050f69172de99f4888183619a17 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Mon, 5 Dec 2022 01:51:14 +0300 Subject: [PATCH] rsx: Properly flag the program control if needed --- rpcs3/Emu/RSX/RSXThread.cpp | 20 +++++++++++++++----- rpcs3/Emu/RSX/RSXThread.h | 2 ++ rpcs3/Emu/RSX/rsx_methods.h | 14 ++++++++++++++ 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index ebf795192b..f470b7997f 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -609,9 +609,14 @@ namespace rsx if (!backend_config.supports_normalized_barycentrics) { - // TODO - // Store a global flag to track raster mode between polygon and non-polygon - // Check if flag changed. If state is the same, ignore. + // Check for mode change between rasterized polys vs lines and points + // Luckily this almost never happens in real games + const auto current_mode = rsx::method_registers.current_draw_clause.classify_mode(); + if (current_mode != m_current_draw_mode) + { + m_graphics_state |= (rsx::vertex_program_state_dirty | rsx::fragment_program_state_dirty); + m_current_draw_mode = current_mode; + } } in_begin_end = true; @@ -1942,6 +1947,7 @@ namespace rsx ensure(!(m_graphics_state & rsx::pipeline_state::vertex_program_ucode_dirty)); current_vertex_program.output_mask = rsx::method_registers.vertex_attrib_output_mask(); + current_vertex_program.ctrl = rsx::method_registers.current_draw_clause.classify_mode() == primitive_class::polygon ? RSX_SHADER_CONTROL_POLYGON_RASTER : 0; for (u32 textures_ref = current_vp_metadata.referenced_textures_mask, i = 0; textures_ref; textures_ref >>= 1, ++i) { @@ -2149,8 +2155,12 @@ namespace rsx current_fragment_program.texcoord_control_mask = rsx::method_registers.texcoord_control_mask(); current_fragment_program.two_sided_lighting = rsx::method_registers.two_side_light_en(); - if (method_registers.current_draw_clause.primitive == primitive_type::points && - method_registers.point_sprite_enabled()) + if (method_registers.current_draw_clause.classify_mode() == primitive_class::polygon) + { + current_fragment_program.ctrl |= RSX_SHADER_CONTROL_POLYGON_RASTER; + } + else if (method_registers.point_sprite_enabled() && + method_registers.current_draw_clause.primitive == primitive_type::points) { // Set high word of the control mask to store point sprite control current_fragment_program.texcoord_control_mask |= u32(method_registers.point_sprite_control_mask()) << 16; diff --git a/rpcs3/Emu/RSX/RSXThread.h b/rpcs3/Emu/RSX/RSXThread.h index 06244ad834..21e9f9ea94 100644 --- a/rpcs3/Emu/RSX/RSXThread.h +++ b/rpcs3/Emu/RSX/RSXThread.h @@ -497,6 +497,8 @@ namespace rsx s32 m_skip_frame_ctr = 0; bool skip_current_frame = false; + primitive_class m_current_draw_mode = primitive_class::polygon; + backend_configuration backend_config{}; // FIFO diff --git a/rpcs3/Emu/RSX/rsx_methods.h b/rpcs3/Emu/RSX/rsx_methods.h index 03ff6fbc31..f9bce70ea6 100644 --- a/rpcs3/Emu/RSX/rsx_methods.h +++ b/rpcs3/Emu/RSX/rsx_methods.h @@ -35,6 +35,12 @@ namespace rsx vertex_arrays_changed = (1 << 2), }; + enum class primitive_class + { + polygon, + non_polygon + }; + struct barrier_t { u32 draw_id; @@ -260,6 +266,14 @@ namespace rsx return count; } + primitive_class classify_mode() const + { + return primitive >= rsx::primitive_type::triangles + ? primitive_class::polygon + : primitive_class::non_polygon; + } + + void reset(rsx::primitive_type type); void begin()