From a9ae04c1523935cb82359cf695c5af80a3d3d38e Mon Sep 17 00:00:00 2001 From: nmzik Date: Mon, 14 Sep 2026 09:10:55 +0400 Subject: [PATCH] graphics: decode observed FSR setup registers Inspired by https://github.com/KytyPS5/KytyPS5/pull/607 Co-authored-by: BlackCAT <52720489+psnwd@users.noreply.github.com> --- .../command_processor/pm4Handlers.cpp | 19 +++++++++++++++++++ src/graphics/guest_gpu/hardwareContext.h | 15 +++++++++++++++ src/graphics/guest_gpu/pm4.h | 6 ++++++ 3 files changed, 40 insertions(+) diff --git a/src/graphics/guest_gpu/command_processor/pm4Handlers.cpp b/src/graphics/guest_gpu/command_processor/pm4Handlers.cpp index 460527f07..9aebbb752 100644 --- a/src/graphics/guest_gpu/command_processor/pm4Handlers.cpp +++ b/src/graphics/guest_gpu/command_processor/pm4Handlers.cpp @@ -3819,6 +3819,25 @@ void GraphicsInitJmpTablesUcIndirect() { for (auto& func: g_hw_uc_indirect_func) { func = nullptr; } + for (uint32_t i = 0; i < 4; ++i) { + g_hw_uc_indirect_func[Pm4::FSR_CONTROL_POINTS_LEFT_X + i] = [](KYTY_HW_UC_INDIRECT_ARGS) { + cp.GetUcfg().SetFsrControlPoint(0, cmd_offset - Pm4::FSR_CONTROL_POINTS_LEFT_X, value); + }; + g_hw_uc_indirect_func[Pm4::FSR_CONTROL_POINTS_LEFT_Y + i] = [](KYTY_HW_UC_INDIRECT_ARGS) { + cp.GetUcfg().SetFsrControlPoint(1, cmd_offset - Pm4::FSR_CONTROL_POINTS_LEFT_Y, value); + }; + } + for (uint32_t i = 0; i < 2; ++i) { + g_hw_uc_indirect_func[Pm4::FSR_ALPHA_LEFT_X + i] = [](KYTY_HW_UC_INDIRECT_ARGS) { + cp.GetUcfg().SetFsrAlpha(0, cmd_offset - Pm4::FSR_ALPHA_LEFT_X, value); + }; + g_hw_uc_indirect_func[Pm4::FSR_ALPHA_LEFT_Y + i] = [](KYTY_HW_UC_INDIRECT_ARGS) { + cp.GetUcfg().SetFsrAlpha(1, cmd_offset - Pm4::FSR_ALPHA_LEFT_Y, value); + }; + g_hw_uc_indirect_func[Pm4::FSR_WINDOW_LEFT + i] = [](KYTY_HW_UC_INDIRECT_ARGS) { + cp.GetUcfg().SetFsrWindow(cmd_offset - Pm4::FSR_WINDOW_LEFT, value); + }; + } g_hw_uc_indirect_func[Pm4::GE_CNTL] = [](KYTY_HW_UC_INDIRECT_ARGS) { HW::GeControl r; diff --git a/src/graphics/guest_gpu/hardwareContext.h b/src/graphics/guest_gpu/hardwareContext.h index ba2dd3dbf..bac95878b 100644 --- a/src/graphics/guest_gpu/hardwareContext.h +++ b/src/graphics/guest_gpu/hardwareContext.h @@ -936,6 +936,12 @@ private: ShaderRegisters m_sh_regs; }; +struct FsrView { + uint32_t control_points[2][4] {}; + uint32_t alphas[2][2] {}; + uint32_t window[2] {}; +}; + class UserConfig { public: UserConfig() = default; @@ -965,8 +971,17 @@ public: void SetGdsOaCntl(uint32_t value) { m_gds_oa.cntl = value; } void SetGdsOaCounter(uint32_t value) { m_gds_oa.counters[m_gds_oa.GetIndex()].counter = value; } void SetGdsOaAddress(uint32_t value) { m_gds_oa.counters[m_gds_oa.GetIndex()].address = value; } + void SetFsrControlPoint(uint32_t axis, uint32_t index, uint32_t value) { + m_fsr_view.control_points[axis][index] = value; + } + void SetFsrAlpha(uint32_t axis, uint32_t index, uint32_t value) { + m_fsr_view.alphas[axis][index] = value; + } + void SetFsrWindow(uint32_t index, uint32_t value) { m_fsr_view.window[index] = value; } + [[nodiscard]] const FsrView& GetFsrView() const { return m_fsr_view; } private: + FsrView m_fsr_view; Prospero::PrimitiveType m_prim_type = Prospero::PrimitiveType::kNone; uint32_t m_index_offset = 0; uint32_t m_object_id = 0; diff --git a/src/graphics/guest_gpu/pm4.h b/src/graphics/guest_gpu/pm4.h index 8d0ff1db1..7da943e3a 100644 --- a/src/graphics/guest_gpu/pm4.h +++ b/src/graphics/guest_gpu/pm4.h @@ -987,6 +987,12 @@ constexpr uint32_t GE_USER_VGPR_EN_EN_USER_VGPR2_MASK = 0x1; constexpr uint32_t GE_USER_VGPR_EN_EN_USER_VGPR3_SHIFT = 2; constexpr uint32_t GE_USER_VGPR_EN_EN_USER_VGPR3_MASK = 0x1; +constexpr uint32_t FSR_WINDOW_LEFT = 0x2BC; +constexpr uint32_t FSR_CONTROL_POINTS_LEFT_X = 0x2C4; +constexpr uint32_t FSR_CONTROL_POINTS_LEFT_Y = 0x2CC; +constexpr uint32_t FSR_ALPHA_LEFT_X = 0x2E4; +constexpr uint32_t FSR_ALPHA_LEFT_Y = 0x2E8; + constexpr uint32_t TA_CS_BC_BASE_ADDR = 0x380; constexpr uint32_t TA_CS_BC_BASE_ADDR_HI = 0x381; constexpr uint32_t TEXTURE_GRADIENT_FACTORS = 0x383;