mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-20 19:07:01 +02:00
graphics: execute valid PM4 rewind packets
This commit is contained in:
@@ -112,6 +112,7 @@ public:
|
|||||||
void SetCeComplete(bool complete) { m_ce_complete = complete; }
|
void SetCeComplete(bool complete) { m_ce_complete = complete; }
|
||||||
void WaitCe();
|
void WaitCe();
|
||||||
void WaitDeDiff(uint32_t diff);
|
void WaitDeDiff(uint32_t diff);
|
||||||
|
void WaitForRewind(bool valid);
|
||||||
void IncrementDe();
|
void IncrementDe();
|
||||||
void IncrementCe();
|
void IncrementCe();
|
||||||
|
|
||||||
|
|||||||
@@ -224,6 +224,7 @@ constexpr auto MakeOpcodeDispatchTable() {
|
|||||||
g_cp_op_func[Pm4::IT_EVENT_WRITE_EOS] = CpOpEventWriteEos;
|
g_cp_op_func[Pm4::IT_EVENT_WRITE_EOS] = CpOpEventWriteEos;
|
||||||
g_cp_op_func[Pm4::IT_DMA_DATA] = CpOpDmaData;
|
g_cp_op_func[Pm4::IT_DMA_DATA] = CpOpDmaData;
|
||||||
g_cp_op_func[Pm4::IT_ACQUIRE_MEM] = CpOpAcquireMem;
|
g_cp_op_func[Pm4::IT_ACQUIRE_MEM] = CpOpAcquireMem;
|
||||||
|
g_cp_op_func[Pm4::IT_REWIND] = CpOpRewind;
|
||||||
g_cp_op_func[Pm4::IT_SET_CONTEXT_REG] = CpOpSetContextReg;
|
g_cp_op_func[Pm4::IT_SET_CONTEXT_REG] = CpOpSetContextReg;
|
||||||
g_cp_op_func[Pm4::IT_SET_SH_REG] = CpOpSetShaderReg;
|
g_cp_op_func[Pm4::IT_SET_SH_REG] = CpOpSetShaderReg;
|
||||||
g_cp_op_func[Pm4::IT_SET_UCONFIG_REG] = CpOpSetUconfigReg;
|
g_cp_op_func[Pm4::IT_SET_UCONFIG_REG] = CpOpSetUconfigReg;
|
||||||
|
|||||||
@@ -133,6 +133,7 @@ uint32_t CpOpDrawIndirectMulti(CommandProcessor&, uint32_t, const uint32_t*, uin
|
|||||||
uint32_t CpOpDrawIndex(CommandProcessor&, uint32_t, const uint32_t*, uint32_t, uint32_t);
|
uint32_t CpOpDrawIndex(CommandProcessor&, uint32_t, const uint32_t*, uint32_t, uint32_t);
|
||||||
uint32_t CpOpDrawIndexOffset(CommandProcessor&, uint32_t, const uint32_t*, uint32_t, uint32_t);
|
uint32_t CpOpDrawIndexOffset(CommandProcessor&, uint32_t, const uint32_t*, uint32_t, uint32_t);
|
||||||
uint32_t CpOpPfpSyncMe(CommandProcessor&, uint32_t, const uint32_t*, uint32_t, uint32_t);
|
uint32_t CpOpPfpSyncMe(CommandProcessor&, uint32_t, const uint32_t*, uint32_t, uint32_t);
|
||||||
|
uint32_t CpOpRewind(CommandProcessor&, uint32_t, const uint32_t*, uint32_t, uint32_t);
|
||||||
uint32_t CpOpIndexType(CommandProcessor&, uint32_t, const uint32_t*, uint32_t, uint32_t);
|
uint32_t CpOpIndexType(CommandProcessor&, uint32_t, const uint32_t*, uint32_t, uint32_t);
|
||||||
uint32_t CpOpNumInstances(CommandProcessor&, uint32_t, const uint32_t*, uint32_t, uint32_t);
|
uint32_t CpOpNumInstances(CommandProcessor&, uint32_t, const uint32_t*, uint32_t, uint32_t);
|
||||||
uint32_t CpOpDrawIndexAuto(CommandProcessor&, uint32_t, const uint32_t*, uint32_t, uint32_t);
|
uint32_t CpOpDrawIndexAuto(CommandProcessor&, uint32_t, const uint32_t*, uint32_t, uint32_t);
|
||||||
|
|||||||
@@ -1830,6 +1830,17 @@ KYTY_CP_OP_PARSER(CpOpPfpSyncMe) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KYTY_CP_OP_PARSER(CpOpRewind) {
|
||||||
|
KYTY_PROFILER_FUNCTION();
|
||||||
|
|
||||||
|
EXIT_NOT_IMPLEMENTED(cmd_id != 0xc0005900);
|
||||||
|
EXIT_NOT_IMPLEMENTED((buffer[0] & ~0x81000000u) != 0);
|
||||||
|
|
||||||
|
cp.WaitForRewind((buffer[0] & 0x80000000u) != 0);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
KYTY_CP_OP_PARSER(CpOpSetPredication) {
|
KYTY_CP_OP_PARSER(CpOpSetPredication) {
|
||||||
KYTY_PROFILER_FUNCTION();
|
KYTY_PROFILER_FUNCTION();
|
||||||
|
|
||||||
|
|||||||
@@ -374,6 +374,12 @@ void CommandProcessor::WaitDeDiff(uint32_t diff) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CommandProcessor::WaitForRewind(bool valid) {
|
||||||
|
if (!valid) {
|
||||||
|
SuspendPm4();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CommandProcessor::IncrementDe() {
|
void CommandProcessor::IncrementDe() {
|
||||||
m_de_count++;
|
m_de_count++;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21096,6 +21096,39 @@ void CheckPm4WaitResume(RenderContext &renderer) {
|
|||||||
std::printf("[host] %-32s ok\n", "Pm4WaitResume");
|
std::printf("[host] %-32s ok\n", "Pm4WaitResume");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CheckPm4RewindResume(RenderContext &renderer) {
|
||||||
|
GraphicsInitJmpTables();
|
||||||
|
CommandProcessor processor(renderer);
|
||||||
|
|
||||||
|
uint32_t suffix = 0;
|
||||||
|
const auto address = reinterpret_cast<uint64_t>(&suffix);
|
||||||
|
std::array<uint32_t, 7> commands{};
|
||||||
|
commands[0] = KYTY_PM4(2, Pm4::IT_REWIND, 0);
|
||||||
|
commands[1] = 0;
|
||||||
|
commands[2] = KYTY_PM4(5, Pm4::IT_WRITE_DATA, 0);
|
||||||
|
commands[3] = 0;
|
||||||
|
commands[4] = static_cast<uint32_t>(address);
|
||||||
|
commands[5] = static_cast<uint32_t>(address >> 32u);
|
||||||
|
commands[6] = 33;
|
||||||
|
|
||||||
|
Pm4Execution execution;
|
||||||
|
Require("Pm4RewindResume", "pending",
|
||||||
|
processor.Process(execution, commands.data(), commands.size()) ==
|
||||||
|
Pm4ProcessResult::Blocked &&
|
||||||
|
suffix == 0,
|
||||||
|
"pending rewind did not preserve its command position");
|
||||||
|
Require("Pm4RewindResume", "patch valid",
|
||||||
|
Gen5::AgcRewindPatchSetRewindState(commands.data(), 1) == 0 &&
|
||||||
|
commands[1] == 0x80000000u,
|
||||||
|
"rewind state patch did not set the valid bit");
|
||||||
|
Require("Pm4RewindResume", "resume",
|
||||||
|
processor.Process(execution, commands.data(), commands.size()) ==
|
||||||
|
Pm4ProcessResult::Complete &&
|
||||||
|
suffix == 33,
|
||||||
|
"valid rewind did not resume at the following packet");
|
||||||
|
std::printf("[host] %-32s ok\n", "Pm4RewindResume");
|
||||||
|
}
|
||||||
|
|
||||||
void CheckPm4CeCompletion(RenderContext &renderer) {
|
void CheckPm4CeCompletion(RenderContext &renderer) {
|
||||||
GraphicsInitJmpTables();
|
GraphicsInitJmpTables();
|
||||||
CommandProcessor processor(renderer);
|
CommandProcessor processor(renderer);
|
||||||
@@ -21223,6 +21256,11 @@ int main(int argc, char **argv) {
|
|||||||
CheckPm4ContextStateOperations(vulkan.RuntimeRenderer());
|
CheckPm4ContextStateOperations(vulkan.RuntimeRenderer());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if (argc == 2 && std::strcmp(argv[1], "--rewind-only") == 0) {
|
||||||
|
VulkanHarness vulkan;
|
||||||
|
CheckPm4RewindResume(vulkan.RuntimeRenderer());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
if (argc == 2 && std::strcmp(argv[1], "--image-overlap-only") == 0) {
|
if (argc == 2 && std::strcmp(argv[1], "--image-overlap-only") == 0) {
|
||||||
CheckDepthAttachmentWrites();
|
CheckDepthAttachmentWrites();
|
||||||
CheckDynamicRenderingState();
|
CheckDynamicRenderingState();
|
||||||
@@ -21381,6 +21419,7 @@ int main(int argc, char **argv) {
|
|||||||
CheckPm4PolygonOffsetRegisters(vulkan.RuntimeRenderer());
|
CheckPm4PolygonOffsetRegisters(vulkan.RuntimeRenderer());
|
||||||
CheckPm4ContextStateOperations(vulkan.RuntimeRenderer());
|
CheckPm4ContextStateOperations(vulkan.RuntimeRenderer());
|
||||||
CheckPm4WaitResume(vulkan.RuntimeRenderer());
|
CheckPm4WaitResume(vulkan.RuntimeRenderer());
|
||||||
|
CheckPm4RewindResume(vulkan.RuntimeRenderer());
|
||||||
CheckPm4CeCompletion(vulkan.RuntimeRenderer());
|
CheckPm4CeCompletion(vulkan.RuntimeRenderer());
|
||||||
CheckEmbeddedFetchVertexOffset();
|
CheckEmbeddedFetchVertexOffset();
|
||||||
CheckEmbeddedFetchLaneSpill();
|
CheckEmbeddedFetchLaneSpill();
|
||||||
|
|||||||
Reference in New Issue
Block a user