#include "Emulator/Graphics/Pm4.h" #include "Kyty/Core/DbgAssert.h" #include "Kyty/Core/File.h" #ifdef KYTY_EMU_ENABLED namespace Kyty::Libs::Graphics::Pm4 { static const char* g_names[256] = {}; static const char* g_r_names[64] = {}; static bool g_names_initialized = false; static void init_names() { if (!g_names_initialized) { for (auto& n: g_names) { n = ""; } for (auto& n: g_r_names) { n = ""; } g_r_names[R_ZERO] = "R_ZERO"; g_r_names[R_VS] = "R_VS"; g_r_names[R_PS] = "R_PS"; g_r_names[R_DRAW_INDEX] = "R_DRAW_INDEX"; g_r_names[R_DRAW_INDEX_AUTO] = "R_DRAW_INDEX_AUTO"; g_r_names[R_DRAW_RESET] = "R_DRAW_RESET"; g_r_names[R_WAIT_FLIP_DONE] = "R_WAIT_FLIP_DONE"; g_r_names[R_CS] = "R_CS"; g_r_names[R_DISPATCH_DIRECT] = "R_DISPATCH_DIRECT"; g_r_names[R_DISPATCH_RESET] = "R_DISPATCH_RESET"; g_r_names[R_DISPATCH_WAIT_MEM] = "R_DISPATCH_WAIT_MEM"; g_r_names[R_PUSH_MARKER] = "R_PUSH_MARKER"; g_r_names[R_POP_MARKER] = "R_POP_MARKER"; g_r_names[R_VS_EMBEDDED] = "R_VS_EMBEDDED"; g_names[IT_NOP] = "IT_NOP"; g_names[IT_SET_BASE] = "IT_SET_BASE"; g_names[IT_CLEAR_STATE] = "IT_CLEAR_STATE"; g_names[IT_INDEX_BUFFER_SIZE] = "IT_INDEX_BUFFER_SIZE"; g_names[IT_DISPATCH_DIRECT] = "IT_DISPATCH_DIRECT"; g_names[IT_DISPATCH_INDIRECT] = "IT_DISPATCH_INDIRECT"; g_names[IT_SET_PREDICATION] = "IT_SET_PREDICATION"; g_names[IT_COND_EXEC] = "IT_COND_EXEC"; g_names[IT_DRAW_INDIRECT] = "IT_DRAW_INDIRECT"; g_names[IT_DRAW_INDEX_INDIRECT] = "IT_DRAW_INDEX_INDIRECT"; g_names[IT_INDEX_BASE] = "IT_INDEX_BASE"; g_names[IT_DRAW_INDEX_2] = "IT_DRAW_INDEX_2"; g_names[IT_CONTEXT_CONTROL] = "IT_CONTEXT_CONTROL"; g_names[IT_INDEX_TYPE] = "IT_INDEX_TYPE"; g_names[IT_DRAW_INDIRECT_MULTI] = "IT_DRAW_INDIRECT_MULTI"; g_names[IT_DRAW_INDEX_AUTO] = "IT_DRAW_INDEX_AUTO"; g_names[IT_NUM_INSTANCES] = "IT_NUM_INSTANCES"; g_names[IT_INDIRECT_BUFFER_CNST] = "IT_INDIRECT_BUFFER_CNST"; g_names[IT_DRAW_INDEX_OFFSET_2] = "IT_DRAW_INDEX_OFFSET_2"; g_names[IT_WRITE_DATA] = "IT_WRITE_DATA"; g_names[IT_MEM_SEMAPHORE] = "IT_MEM_SEMAPHORE"; g_names[IT_DRAW_INDEX_INDIRECT_MULTI] = "IT_DRAW_INDEX_INDIRECT_MULTI"; g_names[IT_WAIT_REG_MEM] = "IT_WAIT_REG_MEM"; g_names[IT_INDIRECT_BUFFER] = "IT_INDIRECT_BUFFER"; g_names[IT_COPY_DATA] = "IT_COPY_DATA"; g_names[IT_CP_DMA] = "IT_CP_DMA"; g_names[IT_PFP_SYNC_ME] = "IT_PFP_SYNC_ME"; g_names[IT_SURFACE_SYNC] = "IT_SURFACE_SYNC"; g_names[IT_EVENT_WRITE] = "IT_EVENT_WRITE"; g_names[IT_EVENT_WRITE_EOP] = "IT_EVENT_WRITE_EOP"; g_names[IT_EVENT_WRITE_EOS] = "IT_EVENT_WRITE_EOS"; g_names[IT_RELEASE_MEM] = "IT_RELEASE_MEM"; g_names[IT_DMA_DATA] = "IT_DMA_DATA"; g_names[IT_ACQUIRE_MEM] = "IT_ACQUIRE_MEM"; g_names[IT_REWIND] = "IT_REWIND"; g_names[IT_SET_CONFIG_REG] = "IT_SET_CONFIG_REG"; g_names[IT_SET_CONTEXT_REG] = "IT_SET_CONTEXT_REG"; g_names[IT_SET_SH_REG] = "IT_SET_SH_REG"; g_names[IT_SET_QUEUE_REG] = "IT_SET_QUEUE_REG"; g_names[IT_SET_UCONFIG_REG] = "IT_SET_UCONFIG_REG"; g_names[IT_WRITE_CONST_RAM] = "IT_WRITE_CONST_RAM"; g_names[IT_DUMP_CONST_RAM] = "IT_DUMP_CONST_RAM"; g_names[IT_INCREMENT_CE_COUNTER] = "IT_INCREMENT_CE_COUNTER"; g_names[IT_INCREMENT_DE_COUNTER] = "IT_INCREMENT_DE_COUNTER"; g_names[IT_WAIT_ON_CE_COUNTER] = "IT_WAIT_ON_CE_COUNTER"; g_names[IT_WAIT_ON_DE_COUNTER_DIFF] = "IT_WAIT_ON_DE_COUNTER_DIFF"; g_names[IT_DISPATCH_DRAW_PREAMBLE] = "IT_DISPATCH_DRAW_PREAMBLE"; g_names[IT_DISPATCH_DRAW] = "IT_DISPATCH_DRAW"; g_names_initialized = true; } } void DumpPm4PacketStream(Core::File* file, uint32_t* cmd_buffer, uint32_t start_dw, uint32_t num_dw) { init_names(); // db_dump(); file->Printf("----- Buffer --- dwords: 0x%05" PRIx32 ", offset : %u, addr: %016" PRIx64 " ----- \n", num_dw, start_dw, reinterpret_cast(cmd_buffer)); auto* cmd = cmd_buffer + start_dw; auto dw = num_dw; for (;;) { if (dw == 0) { break; } EXIT_NOT_IMPLEMENTED(dw < 2); EXIT_NOT_IMPLEMENTED(dw > num_dw); auto cmd_id = *cmd++; file->Printf("%05" PRIx32 " | 0x%08" PRIx32 " | ", start_dw, cmd_id); uint32_t len = 0; if ((cmd_id & 0xC0000000u) == 0xC0000000u) { bool sh_gx = (cmd_id & 0x2u) == 0; len = ((cmd_id >> 16u) & 0x3fffu) + 1; uint8_t op = ((cmd_id >> 8u) & 0xffu); auto r = ((cmd_id >> 2u) & 0x3fu); file->Printf("%s %s(OP:0x%02" PRIx8 ") SH:%s CNT:%u\n", g_names[op], (op == IT_NOP ? g_r_names[r] : ""), op, sh_gx ? "GX" : "CX", len); for (uint32_t i = 0; i < len; i++) { file->Printf(" | 0x%08" PRIx32 " | \n", cmd[i]); } } else { printf("?????\n"); } cmd += len; dw -= len + 1; start_dw += len + 1; } } } // namespace Kyty::Libs::Graphics::Pm4 #endif // KYTY_EMU_ENABLED