diff --git a/parallel-rdp/rdp_device.cpp b/parallel-rdp/rdp_device.cpp index b51a22c0..b6d489ee 100644 --- a/parallel-rdp/rdp_device.cpp +++ b/parallel-rdp/rdp_device.cpp @@ -39,6 +39,9 @@ using namespace Vulkan; if (cond) (flag) |= (mask); \ } while(0) +static bool is_dither_mode_forced = false; +static uint8_t forced_dither_mode = 0; + namespace RDP { CommandProcessor::CommandProcessor(Vulkan::Device &device_, void *rdram_ptr, @@ -491,7 +494,7 @@ void CommandProcessor::op_set_other_modes(const uint32_t *words) STATE_MASK(static_state.flags, bool(words[1] & (1 << 1)), RASTERIZATION_ALPHA_TEST_DITHER_BIT); STATE_MASK(static_state.flags, bool(words[1] & (1 << 0)), RASTERIZATION_ALPHA_TEST_BIT); - static_state.dither = (words[0] >> 4) & 0x0f; + static_state.dither = (is_dither_mode_forced) ? (forced_dither_mode) : ((words[0] >> 4) & 0x0f); STATE_MASK(depth_blend.flags, RGBDitherMode(static_state.dither >> 2) != RGBDitherMode::Off, DEPTH_BLEND_DITHER_ENABLE_BIT); depth_blend.coverage_mode = static_cast((words[1] >> 8) & 3); depth_blend.z_mode = static_cast((words[1] >> 10) & 3); @@ -1124,6 +1127,11 @@ void CommandProcessor::drain_command_ring() void CommandProcessor::scanout_async_buffer(VIScanoutBuffer &buffer, const ScanoutOptions &opts) { + if (opts.force_dither_mode.enable) + { + is_dither_mode_forced = opts.force_dither_mode.enable; + forced_dither_mode = (opts.force_dither_mode.mode << 2); + } auto handle = scanout(opts, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); if (!handle) { diff --git a/parallel-rdp/video_interface.hpp b/parallel-rdp/video_interface.hpp index f3cb4533..50622475 100644 --- a/parallel-rdp/video_interface.hpp +++ b/parallel-rdp/video_interface.hpp @@ -72,6 +72,15 @@ struct ScanoutOptions bool divot_filter = true; bool gamma_dither = true; } vi; + + // If enabled, will force a specific dither mode to be used, + // rather than using the one that is native to the game. + struct + { + // Values equal to enum RGBDitherMode + uint8_t mode = 0; + bool enable = false; + } force_dither_mode; }; struct VIScanoutBuffer