From 00a16f3120099e7ac8fe1f52697683c370d50a9a Mon Sep 17 00:00:00 2001 From: nmzik Date: Sun, 13 Sep 2026 07:09:14 +0400 Subject: [PATCH] gpu: retain fused hull shader user-data addresses --- .../guest_gpu/command_processor/pm4Handlers.cpp | 13 +++++++------ src/graphics/guest_gpu/hardwareContext.h | 17 ++++++++++++----- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/graphics/guest_gpu/command_processor/pm4Handlers.cpp b/src/graphics/guest_gpu/command_processor/pm4Handlers.cpp index 4bbf958f9..460527f07 100644 --- a/src/graphics/guest_gpu/command_processor/pm4Handlers.cpp +++ b/src/graphics/guest_gpu/command_processor/pm4Handlers.cpp @@ -3654,12 +3654,13 @@ void GraphicsInitJmpTablesShIndirect() { g_hw_sh_indirect_func[Pm4::SPI_GRAPHICS_SHADER_CONTROL_HS] = [](KYTY_HW_SH_INDIRECT_ARGS) { HwShIgnoreShaderRegister(cmd_offset, value); }; - g_hw_sh_indirect_func[Pm4::SPI_SHADER_USER_DATA_ADDR_LO_HS] = [](KYTY_HW_SH_INDIRECT_ARGS) { - HwShIgnoreShaderRegister(cmd_offset, value); - }; - g_hw_sh_indirect_func[Pm4::SPI_SHADER_USER_DATA_ADDR_HI_HS] = [](KYTY_HW_SH_INDIRECT_ARGS) { - HwShIgnoreShaderRegister(cmd_offset, value); - }; + for (uint32_t offset = Pm4::SPI_SHADER_USER_DATA_ADDR_LO_HS; + offset <= Pm4::SPI_SHADER_USER_DATA_ADDR_HI_HS; offset++) { + g_hw_sh_indirect_func[offset] = [](KYTY_HW_SH_INDIRECT_ARGS) { + cp.GetShCtx().SetHsUserDataAddress(cmd_offset - Pm4::SPI_SHADER_USER_DATA_ADDR_LO_HS, + value); + }; + } g_hw_sh_indirect_func[Pm4::SPI_SHADER_PGM_LO_HS] = [](KYTY_HW_SH_INDIRECT_ARGS) { auto base = cp.GetShCtx().GetVs().hs_regs.data_addr; base &= 0xFFFFFF00000000FFull; diff --git a/src/graphics/guest_gpu/hardwareContext.h b/src/graphics/guest_gpu/hardwareContext.h index e9fcede00..ba2dd3dbf 100644 --- a/src/graphics/guest_gpu/hardwareContext.h +++ b/src/graphics/guest_gpu/hardwareContext.h @@ -498,7 +498,8 @@ struct LsStageRegisters { }; struct HsStageRegisters { - uint64_t data_addr = 0; + uint64_t data_addr = 0; + uint64_t user_data_addr = 0; HsShaderResource1 rsrc1; HsShaderResource2 rsrc2; }; @@ -988,14 +989,14 @@ public: void SetEsShaderBase(uint64_t addr) { m_vs.es_regs.data_addr = addr; } void SetLsShaderBase(uint64_t addr) { m_vs.ls_regs.data_addr = addr; } void SetHsShaderBase(uint64_t addr) { m_vs.hs_regs.data_addr = addr; } + void SetHsUserDataAddress(uint32_t word, uint32_t value) { + SetUserDataAddressWord(m_vs.hs_regs.user_data_addr, word, value); + } void SetHsShaderResource1(const HsShaderResource1& rsrc1) { m_vs.hs_regs.rsrc1 = rsrc1; } void SetHsShaderResource2(const HsShaderResource2& rsrc2) { m_vs.hs_regs.rsrc2 = rsrc2; } void SetGsShaderBase(uint64_t addr) { m_vs.gs_regs.data_addr = addr; } void SetGsUserDataAddress(uint32_t word, uint32_t value) { - const auto shift = word * 32u; - auto& address = m_vs.gs_regs.user_data_addr; - address = (address & ~(uint64_t {0xffffffffu} << shift)) | - (static_cast(value) << shift); + SetUserDataAddressWord(m_vs.gs_regs.user_data_addr, word, value); } void SetGsShaderResource1(const GsShaderResource1& rsrc1) { m_vs.gs_regs.rsrc1 = rsrc1; } void SetGsShaderResource2(const GsShaderResource2& rsrc2) { m_vs.gs_regs.rsrc2 = rsrc2; } @@ -1037,6 +1038,12 @@ public: [[nodiscard]] const ComputeShaderInfo& GetCs() const { return m_cs; } private: + static void SetUserDataAddressWord(uint64_t& address, uint32_t word, uint32_t value) { + const auto shift = word * 32u; + address = (address & ~(uint64_t {0xffffffffu} << shift)) | + (static_cast(value) << shift); + } + VertexShaderInfo m_vs; PixelShaderInfo m_ps; ComputeShaderInfo m_cs;