gnmdriver: added support for gpu context reset

This commit is contained in:
psucien 2024-08-25 00:48:26 +02:00
parent c79b10edc1
commit 6fba987df2
5 changed files with 118 additions and 17 deletions

View File

@ -472,6 +472,7 @@ set(VIDEO_CORE src/video_core/amdgpu/liverpool.cpp
src/video_core/amdgpu/pm4_cmds.h src/video_core/amdgpu/pm4_cmds.h
src/video_core/amdgpu/pm4_opcodes.h src/video_core/amdgpu/pm4_opcodes.h
src/video_core/amdgpu/resource.h src/video_core/amdgpu/resource.h
src/video_core/amdgpu/default_context.cpp
src/video_core/buffer_cache/buffer.cpp src/video_core/buffer_cache/buffer.cpp
src/video_core/buffer_cache/buffer.h src/video_core/buffer_cache/buffer.h
src/video_core/buffer_cache/buffer_cache.cpp src/video_core/buffer_cache/buffer_cache.cpp

View File

@ -55,6 +55,10 @@ static constexpr auto HwInitPacketSize = 0x100u;
// clang-format off // clang-format off
static constexpr std::array InitSequence{ static constexpr std::array InitSequence{
// A fake preamble to mimic context reset sent by FW
0xc0001200u, 0u, // IT_CLEAR_STATE
// Actual init state sequence
0xc0017600u, 0x216u, 0xffffffffu, 0xc0017600u, 0x216u, 0xffffffffu,
0xc0017600u, 0x217u, 0xffffffffu, 0xc0017600u, 0x217u, 0xffffffffu,
0xc0017600u, 0x215u, 0u, 0xc0017600u, 0x215u, 0u,
@ -94,9 +98,13 @@ static constexpr std::array InitSequence{
0xc0036900u, 0x295u, 0x100u, 0x100u, 4u, 0xc0036900u, 0x295u, 0x100u, 0x100u, 4u,
0xc0017900u, 0x200u, 0xe0000000u, 0xc0017900u, 0x200u, 0xe0000000u,
}; };
static_assert(InitSequence.size() == 0x73); static_assert(InitSequence.size() == 0x73 + 2);
static constexpr std::array InitSequence175{ static constexpr std::array InitSequence175{
// A fake preamble to mimic context reset sent by FW
0xc0001200u, 0u, // IT_CLEAR_STATE
// Actual init state sequence
0xc0017600u, 0x216u, 0xffffffffu, 0xc0017600u, 0x216u, 0xffffffffu,
0xc0017600u, 0x217u, 0xffffffffu, 0xc0017600u, 0x217u, 0xffffffffu,
0xc0017600u, 0x215u, 0u, 0xc0017600u, 0x215u, 0u,
@ -136,9 +144,13 @@ static constexpr std::array InitSequence175{
0xc0036900u, 0x295u, 0x100u, 0x100u, 4u, 0xc0036900u, 0x295u, 0x100u, 0x100u, 4u,
0xc0017900u, 0x200u, 0xe0000000u, 0xc0017900u, 0x200u, 0xe0000000u,
}; };
static_assert(InitSequence175.size() == 0x73); static_assert(InitSequence175.size() == 0x73 + 2);
static constexpr std::array InitSequence200{ static constexpr std::array InitSequence200{
// A fake preamble to mimic context reset sent by FW
0xc0001200u, 0u, // IT_CLEAR_STATE
// Actual init state sequence
0xc0017600u, 0x216u, 0xffffffffu, 0xc0017600u, 0x216u, 0xffffffffu,
0xc0017600u, 0x217u, 0xffffffffu, 0xc0017600u, 0x217u, 0xffffffffu,
0xc0017600u, 0x215u, 0u, 0xc0017600u, 0x215u, 0u,
@ -179,9 +191,13 @@ static constexpr std::array InitSequence200{
0xc0036900u, 0x295u, 0x100u, 0x100u, 4u, 0xc0036900u, 0x295u, 0x100u, 0x100u, 4u,
0xc0017900u, 0x200u, 0xe0000000u, 0xc0017900u, 0x200u, 0xe0000000u,
}; };
static_assert(InitSequence200.size() == 0x76); static_assert(InitSequence200.size() == 0x76 + 2);
static constexpr std::array InitSequence350{ static constexpr std::array InitSequence350{
// A fake preamble to mimic context reset sent by FW
0xc0001200u, 0u, // IT_CLEAR_STATE
// Actual init state sequence
0xc0017600u, 0x216u, 0xffffffffu, 0xc0017600u, 0x216u, 0xffffffffu,
0xc0017600u, 0x217u, 0xffffffffu, 0xc0017600u, 0x217u, 0xffffffffu,
0xc0017600u, 0x215u, 0u, 0xc0017600u, 0x215u, 0u,
@ -224,7 +240,7 @@ static constexpr std::array InitSequence350{
0xc0017900u, 0x200u, 0xe0000000u, 0xc0017900u, 0x200u, 0xe0000000u,
0xc0016900u, 0x2aau, 0xffu, 0xc0016900u, 0x2aau, 0xffu,
}; };
static_assert(InitSequence350.size() == 0x7c); static_assert(InitSequence350.size() == 0x7c + 2);
static constexpr std::array CtxInitSequence{ static constexpr std::array CtxInitSequence{
0xc0012800u, 0x80000000u, 0x80000000u, 0xc0012800u, 0x80000000u, 0x80000000u,
@ -735,11 +751,11 @@ u32 PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState(u32* cmdbuf, u32 size) {
cmdbuf = ClearContextState(cmdbuf); cmdbuf = ClearContextState(cmdbuf);
} }
std::memcpy(cmdbuf, InitSequence.data(), InitSequence.size() * 4); std::memcpy(cmdbuf, &InitSequence[2], (InitSequence.size() - 2) * 4);
cmdbuf += InitSequence.size(); cmdbuf += InitSequence.size() - 2;
const auto cmdbuf_left = const auto cmdbuf_left =
HwInitPacketSize - InitSequence.size() - (clear_state ? 0xc : 0) - 1; HwInitPacketSize - (InitSequence.size() - 2) - (clear_state ? 0xc : 0) - 1;
cmdbuf = WriteHeader<PM4ItOpcode::Nop>(cmdbuf, cmdbuf_left); cmdbuf = WriteHeader<PM4ItOpcode::Nop>(cmdbuf, cmdbuf_left);
cmdbuf = WriteBody(cmdbuf, 0u); cmdbuf = WriteBody(cmdbuf, 0u);
@ -757,10 +773,10 @@ u32 PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState175(u32* cmdbuf, u32 size) {
} }
cmdbuf = ClearContextState(cmdbuf); cmdbuf = ClearContextState(cmdbuf);
std::memcpy(cmdbuf, InitSequence175.data(), InitSequence175.size() * 4); std::memcpy(cmdbuf, &InitSequence175[2], (InitSequence175.size() - 2) * 4);
cmdbuf += InitSequence175.size(); cmdbuf += InitSequence175.size() - 2;
constexpr auto cmdbuf_left = HwInitPacketSize - InitSequence175.size() - 0xc - 1; constexpr auto cmdbuf_left = HwInitPacketSize - (InitSequence175.size() - 2) - 0xc - 1;
WriteTrailingNop<cmdbuf_left>(cmdbuf); WriteTrailingNop<cmdbuf_left>(cmdbuf);
return HwInitPacketSize; return HwInitPacketSize;
@ -778,11 +794,11 @@ u32 PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState200(u32* cmdbuf, u32 size) {
cmdbuf = ClearContextState(cmdbuf); cmdbuf = ClearContextState(cmdbuf);
} }
std::memcpy(cmdbuf, InitSequence200.data(), InitSequence200.size() * 4); std::memcpy(cmdbuf, &InitSequence200[2], (InitSequence200.size() - 2) * 4);
cmdbuf += InitSequence200.size(); cmdbuf += InitSequence200.size() - 2;
const auto cmdbuf_left = const auto cmdbuf_left =
HwInitPacketSize - InitSequence200.size() - (clear_state ? 0xc : 0) - 1; HwInitPacketSize - (InitSequence200.size() - 2) - (clear_state ? 0xc : 0) - 1;
cmdbuf = WriteHeader<PM4ItOpcode::Nop>(cmdbuf, cmdbuf_left); cmdbuf = WriteHeader<PM4ItOpcode::Nop>(cmdbuf, cmdbuf_left);
cmdbuf = WriteBody(cmdbuf, 0u); cmdbuf = WriteBody(cmdbuf, 0u);
@ -804,11 +820,11 @@ u32 PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState350(u32* cmdbuf, u32 size) {
cmdbuf = ClearContextState(cmdbuf); cmdbuf = ClearContextState(cmdbuf);
} }
std::memcpy(cmdbuf, InitSequence350.data(), InitSequence350.size() * 4); std::memcpy(cmdbuf, &InitSequence350[2], (InitSequence350.size() - 2) * 4);
cmdbuf += InitSequence350.size(); cmdbuf += InitSequence350.size() - 2;
const auto cmdbuf_left = const auto cmdbuf_left =
HwInitPacketSize - InitSequence350.size() - (clear_state ? 0xc : 0) - 1; HwInitPacketSize - (InitSequence350.size() - 2) - (clear_state ? 0xc : 0) - 1;
cmdbuf = WriteHeader<PM4ItOpcode::Nop>(cmdbuf, cmdbuf_left); cmdbuf = WriteHeader<PM4ItOpcode::Nop>(cmdbuf, cmdbuf_left);
cmdbuf = WriteBody(cmdbuf, 0u); cmdbuf = WriteBody(cmdbuf, 0u);
@ -1743,7 +1759,7 @@ s32 PS4_SYSV_ABI sceGnmSetVsShader(u32* cmdbuf, u32 size, const u32* vs_regs, u3
return -1; return -1;
} }
const u32 var = shader_modifier == 0 ? vs_regs[2] : (vs_regs[2] & 0xfcfffc3f | shader_modifier); const u32 var = shader_modifier == 0 ? vs_regs[2] : (vs_regs[2] & 0xfcfffc3f) | shader_modifier;
cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 0x48u, vs_regs[0], 0u); // SPI_SHADER_PGM_LO_VS cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 0x48u, vs_regs[0], 0u); // SPI_SHADER_PGM_LO_VS
cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 0x4au, var, vs_regs[3]); // SPI_SHADER_PGM_RSRC1_VS cmdbuf = PM4CmdSetData::SetShReg(cmdbuf, 0x4au, var, vs_regs[3]); // SPI_SHADER_PGM_RSRC1_VS
cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x207u, vs_regs[6]); // PA_CL_VS_OUT_CNTL cmdbuf = PM4CmdSetData::SetContextReg(cmdbuf, 0x207u, vs_regs[6]); // PA_CL_VS_OUT_CNTL

View File

@ -0,0 +1,82 @@
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include "common/types.h"
#include "video_core/amdgpu/liverpool.h"
#include <array>
namespace AmdGpu {
// The following values are taken from fpPS4:
// https://github.com/red-prig/fpPS4/blob/436b43064be4c78229500f3d3c054fc76639247d/chip/pm4_pfp.pas#L410
//
const std::array<u32, Liverpool::NumRegs> Liverpool::reg_array_default{
0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,
0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x40004000u, 0x00000000u, 0x00000000u,
0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,
0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,
0x00000000u, 0x00000000u, 0x80000000u, 0x40004000u, 0x00000000u, 0x40004000u, 0x00000000u,
0x40004000u, 0x00000000u, 0x40004000u, 0x00000000u, 0x40004000u, 0xaa99aaaau, 0x00000000u,
0x80000000u, 0x40004000u, 0x00000000u, 0x00000000u, 0x80000000u, 0x40004000u, 0x80000000u,
0x40004000u, 0x80000000u, 0x40004000u, 0x80000000u, 0x40004000u, 0x80000000u, 0x40004000u,
0x80000000u, 0x40004000u, 0x80000000u, 0x40004000u, 0x80000000u, 0x40004000u, 0x80000000u,
0x40004000u, 0x80000000u, 0x40004000u, 0x80000000u, 0x40004000u, 0x80000000u, 0x40004000u,
0x80000000u, 0x40004000u, 0x80000000u, 0x40004000u, 0x80000000u, 0x40004000u, 0x80000000u,
0x40004000u, 0x00000000u, 0x3f800000u, 0x00000000u, 0x3f800000u, 0x00000000u, 0x3f800000u,
0x00000000u, 0x3f800000u, 0x00000000u, 0x3f800000u, 0x00000000u, 0x3f800000u, 0x00000000u,
0x3f800000u, 0x00000000u, 0x3f800000u, 0x00000000u, 0x3f800000u, 0x00000000u, 0x3f800000u,
0x00000000u, 0x3f800000u, 0x00000000u, 0x3f800000u, 0x00000000u, 0x3f800000u, 0x00000000u,
0x3f800000u, 0x00000000u, 0x3f800000u, 0x00000000u, 0x3f800000u, 0x2a00161au, 0x00000000u,
0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,
0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,
0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,
0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,
0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,
0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,
0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,
0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,
0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,
0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,
0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,
0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,
0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,
0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,
0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,
0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,
0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,
0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,
0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,
0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,
0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,
0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,
0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,
0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000002u, 0x00000000u,
0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,
0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,
0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00090000u,
0x00000004u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,
0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,
0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,
0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,
0x00000100u, 0x00000080u, 0x00000002u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,
0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,
0x000000ffu, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,
0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,
0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,
0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,
0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,
0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,
0x00000000u, 0x00000000u, 0x00000000u, 0x00001000u, 0x00000000u, 0x00000005u, 0x3f800000u,
0x3f800000u, 0x3f800000u, 0x3f800000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,
0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,
0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x0000000eu, 0x00000010u,
0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,
0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,
0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,
0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,
0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,
0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u, 0x00000000u,
};
} // namespace AmdGpu

View File

@ -216,6 +216,7 @@ Liverpool::Task Liverpool::ProcessGraphics(std::span<const u32> dcb, std::span<c
break; break;
} }
case PM4ItOpcode::ClearState: { case PM4ItOpcode::ClearState: {
std::memcpy(regs.reg_array.data(), reg_array_default.data(), NumRegs * sizeof(u32));
break; break;
} }
case PM4ItOpcode::SetConfigReg: { case PM4ItOpcode::SetConfigReg: {

View File

@ -1020,6 +1020,7 @@ struct Liverpool {
}; };
Regs regs{}; Regs regs{};
static const std::array<u32, NumRegs> reg_array_default;
// See for a comment in context reg parsing code // See for a comment in context reg parsing code
union CbDbExtent { union CbDbExtent {