From 650152e05f34a1ece34e7d40329cc9dd1d0b207e Mon Sep 17 00:00:00 2001 From: kd-11 Date: Wed, 3 Jun 2020 21:19:38 +0300 Subject: [PATCH] rsx: Fix fragment state updates - Fix copypasta for POLYGON_STIPPLE_PATTERN vs SET_POLYGON_STIPPLE method binding - Use proper enums for ROP_control bits to avoid confusion --- rpcs3/Emu/RSX/RSXThread.cpp | 37 ++++++++++++++++++----------------- rpcs3/Emu/RSX/RSXThread.h | 11 +++++++++++ rpcs3/Emu/RSX/rsx_methods.cpp | 2 +- 3 files changed, 31 insertions(+), 19 deletions(-) diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index bab4b951bf..2ba5ef5592 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -741,20 +741,28 @@ namespace rsx void thread::fill_fragment_state_buffer(void *buffer, const RSXFragmentProgram &fragment_program) { - //TODO: Properly support alpha-to-coverage and alpha-to-one behavior in shaders - auto fragment_alpha_func = rsx::method_registers.alpha_func(); - auto alpha_ref = rsx::method_registers.alpha_ref(); - auto rop_control = rsx::method_registers.alpha_test_enabled()? 1u : 0u; + u32 rop_control = 0u; + + if (rsx::method_registers.alpha_test_enabled()) + { + const u32 alpha_func = static_cast(rsx::method_registers.alpha_func()); + rop_control |= (alpha_func << 16); + rop_control |= ROP_control::alpha_test_enable; + } + + if (rsx::method_registers.polygon_stipple_enabled()) + { + rop_control |= ROP_control::polygon_stipple_enable; + } if (rsx::method_registers.msaa_alpha_to_coverage_enabled() && !backend_config.supports_hw_a2c) { + // TODO: Properly support alpha-to-coverage and alpha-to-one behavior in shaders // Alpha values generate a coverage mask for order independent blending // Requires hardware AA to work properly (or just fragment sample stage in fragment shaders) // Simulated using combined alpha blend and alpha test - const u32 mask_bit = rsx::method_registers.msaa_sample_mask() ? 1u : 0u; - - rop_control |= (1u << 4); // CSAA enable bit - rop_control |= (mask_bit << 5); // MSAA mask enable bit + if (rsx::method_registers.msaa_sample_mask()) rop_control |= ROP_control::msaa_mask_enable; + rop_control |= ROP_control::csaa_enable; // Sample configuration bits switch (rsx::method_registers.surface_antialias()) @@ -772,11 +780,8 @@ namespace rsx const f32 fog0 = rsx::method_registers.fog_params_0(); const f32 fog1 = rsx::method_registers.fog_params_1(); - const u32 alpha_func = static_cast(fragment_alpha_func); const u32 fog_mode = static_cast(rsx::method_registers.fog_equation()); - rop_control |= (alpha_func << 16); - if (rsx::method_registers.framebuffer_srgb_enabled()) { // Check if framebuffer is actually an XRGB format and not a WZYX format @@ -787,16 +792,11 @@ namespace rsx case rsx::surface_color_format::x32: break; default: - rop_control |= (1u << 1); + rop_control |= ROP_control::framebuffer_srgb_enable; break; } } - if (rsx::method_registers.polygon_stipple_enabled()) - { - rop_control |= (1u << 9); - } - // Generate wpos coefficients // wpos equation is now as follows: // wpos.y = (frag_coord / resolution_scale) * ((window_origin!=top)?-1.: 1.) + ((window_origin!=top)? window_height : 0) @@ -808,10 +808,11 @@ namespace rsx const f32 resolution_scale = (window_height <= static_cast(g_cfg.video.min_scalable_dimension)) ? 1.f : rsx::get_resolution_scale(); const f32 wpos_scale = (window_origin == rsx::window_origin::top) ? (1.f / resolution_scale) : (-1.f / resolution_scale); const f32 wpos_bias = (window_origin == rsx::window_origin::top) ? 0.f : window_height; + const f32 alpha_ref = rsx::method_registers.alpha_ref(); u32 *dst = static_cast(buffer); stream_vector(dst, std::bit_cast(fog0), std::bit_cast(fog1), rop_control, std::bit_cast(alpha_ref)); - stream_vector(dst + 4, alpha_func, fog_mode, std::bit_cast(wpos_scale), std::bit_cast(wpos_bias)); + stream_vector(dst + 4, 0u, fog_mode, std::bit_cast(wpos_scale), std::bit_cast(wpos_bias)); } void thread::fill_fragment_texture_parameters(void *buffer, const RSXFragmentProgram &fragment_program) diff --git a/rpcs3/Emu/RSX/RSXThread.h b/rpcs3/Emu/RSX/RSXThread.h index 590abd46d9..a86263308f 100644 --- a/rpcs3/Emu/RSX/RSXThread.h +++ b/rpcs3/Emu/RSX/RSXThread.h @@ -112,6 +112,17 @@ namespace rsx result_zcull_intr = 2 }; + enum ROP_control : u32 + { + alpha_test_enable = (1u << 0), + framebuffer_srgb_enable = (1u << 1), + csaa_enable = (1u << 4), + msaa_mask_enable = (1u << 5), + msaa_config_mask = (3u << 6), + polygon_stipple_enable = (1u << 9), + alpha_func_mask = (7u << 16) + }; + u32 get_vertex_type_size_on_host(vertex_base_type type, u32 size); // TODO: Replace with std::source_location in c++20 diff --git a/rpcs3/Emu/RSX/rsx_methods.cpp b/rpcs3/Emu/RSX/rsx_methods.cpp index 2e9d3aed4d..4e17b86838 100644 --- a/rpcs3/Emu/RSX/rsx_methods.cpp +++ b/rpcs3/Emu/RSX/rsx_methods.cpp @@ -3121,7 +3121,7 @@ namespace rsx bind(); bind(); bind>(); - bind_array>(); + bind_array>(); //NV308A (0xa400..0xbffc!) bind_range();