#include "Emulator/Graphics/Graphics.h" #include "Kyty/Core/DbgAssert.h" #include "Kyty/Core/File.h" #include "Kyty/Core/String.h" #include "Emulator/Config.h" #include "Emulator/Graphics/GraphicsRender.h" #include "Emulator/Graphics/GraphicsRun.h" #include "Emulator/Graphics/HardwareContext.h" #include "Emulator/Graphics/Objects/GpuMemory.h" #include "Emulator/Graphics/Objects/IndexBuffer.h" #include "Emulator/Graphics/Objects/Label.h" #include "Emulator/Graphics/Pm4.h" #include "Emulator/Graphics/Tile.h" #include "Emulator/Graphics/VideoOut.h" #include "Emulator/Graphics/Window.h" #include "Emulator/Kernel/Pthread.h" #include "Emulator/Libs/Errno.h" #include "Emulator/Libs/Libs.h" #include "Emulator/Loader/VirtualMemory.h" #include #ifdef KYTY_EMU_ENABLED namespace Kyty::Libs::Graphics { LIB_NAME("GraphicsDriver", "GraphicsDriver"); KYTY_SUBSYSTEM_INIT(Graphics) { auto width = Config::GetScreenWidth(); auto height = Config::GetScreenHeight(); WindowInit(width, height); VideoOut::VideoOutInit(width, height); GraphicsRenderInit(); GraphicsRunInit(); GpuMemoryInit(); LabelInit(); TileInit(); IndexBufferInit(); } KYTY_SUBSYSTEM_UNEXPECTED_SHUTDOWN(Graphics) {} KYTY_SUBSYSTEM_DESTROY(Graphics) {} int KYTY_SYSV_ABI GraphicsSetVsShader(uint32_t* cmd, uint64_t size, const HW::VsStageRegisters* vs_regs, uint32_t shader_modifier) { PRINT_NAME(); EXIT_NOT_IMPLEMENTED(size < sizeof(HW::VsStageRegisters) / 4 + 2); printf("\t cmd_buffer = %016" PRIx64 "\n", reinterpret_cast(cmd)); printf("\t size = %" PRIu64 "\n", size); printf("\t shader_modifier = %" PRIu32 "\n", shader_modifier); printf("\t vs_regs.m_spiShaderPgmLoVs = %08" PRIx32 "\n", vs_regs->m_spiShaderPgmLoVs); printf("\t vs_regs.m_spiShaderPgmHiVs = %08" PRIx32 "\n", vs_regs->m_spiShaderPgmHiVs); printf("\t vs_regs.m_spiShaderPgmRsrc1Vs = %08" PRIx32 "\n", vs_regs->m_spiShaderPgmRsrc1Vs); printf("\t vs_regs.m_spiShaderPgmRsrc2Vs = %08" PRIx32 "\n", vs_regs->m_spiShaderPgmRsrc2Vs); printf("\t vs_regs.m_spiVsOutConfig = %08" PRIx32 "\n", vs_regs->m_spiVsOutConfig); printf("\t vs_regs.m_spiShaderPosFormat = %08" PRIx32 "\n", vs_regs->m_spiShaderPosFormat); printf("\t vs_regs.m_paClVsOutCntl = %08" PRIx32 "\n", vs_regs->m_paClVsOutCntl); cmd[0] = KYTY_PM4(size, Pm4::IT_NOP, Pm4::R_VS); cmd[1] = shader_modifier; memcpy(&cmd[2], vs_regs, sizeof(HW::VsStageRegisters)); return OK; } int KYTY_SYSV_ABI GraphicsUpdateVsShader(uint32_t* cmd, uint64_t size, const HW::VsStageRegisters* vs_regs, uint32_t shader_modifier) { PRINT_NAME(); EXIT_NOT_IMPLEMENTED(size < sizeof(HW::VsStageRegisters) / 4 + 2); printf("\t cmd_buffer = %016" PRIx64 "\n", reinterpret_cast(cmd)); printf("\t size = %" PRIu64 "\n", size); printf("\t shader_modifier = %" PRIu32 "\n", shader_modifier); printf("\t vs_regs.m_spiShaderPgmLoVs = %08" PRIx32 "\n", vs_regs->m_spiShaderPgmLoVs); printf("\t vs_regs.m_spiShaderPgmHiVs = %08" PRIx32 "\n", vs_regs->m_spiShaderPgmHiVs); printf("\t vs_regs.m_spiShaderPgmRsrc1Vs = %08" PRIx32 "\n", vs_regs->m_spiShaderPgmRsrc1Vs); printf("\t vs_regs.m_spiShaderPgmRsrc2Vs = %08" PRIx32 "\n", vs_regs->m_spiShaderPgmRsrc2Vs); printf("\t vs_regs.m_spiVsOutConfig = %08" PRIx32 "\n", vs_regs->m_spiVsOutConfig); printf("\t vs_regs.m_spiShaderPosFormat = %08" PRIx32 "\n", vs_regs->m_spiShaderPosFormat); printf("\t vs_regs.m_paClVsOutCntl = %08" PRIx32 "\n", vs_regs->m_paClVsOutCntl); cmd[0] = KYTY_PM4(size, Pm4::IT_NOP, Pm4::R_VS_UPDATE); cmd[1] = shader_modifier; memcpy(&cmd[2], vs_regs, sizeof(HW::VsStageRegisters)); return OK; } int KYTY_SYSV_ABI GraphicsSetEmbeddedVsShader(uint32_t* cmd, uint64_t size, uint32_t id, uint32_t shader_modifier) { PRINT_NAME(); EXIT_NOT_IMPLEMENTED(size < 3); printf("\t cmd_buffer = %016" PRIx64 "\n", reinterpret_cast(cmd)); printf("\t size = %" PRIu64 "\n", size); printf("\t id = %" PRIu32 "\n", id); printf("\t shader_modifier = %" PRIu32 "\n", shader_modifier); cmd[0] = KYTY_PM4(size, Pm4::IT_NOP, Pm4::R_VS_EMBEDDED); cmd[1] = shader_modifier; cmd[2] = id; return OK; } int KYTY_SYSV_ABI GraphicsSetPsShader(uint32_t* cmd, uint64_t size, const uint32_t* ps_regs) { PRINT_NAME(); if (ps_regs == nullptr) { EXIT_NOT_IMPLEMENTED(size < 1 + 1); printf("\t cmd_buffer = %016" PRIx64 "\n", reinterpret_cast(cmd)); printf("\t size = %" PRIu64 "\n", size); printf("\t embedded_id = %d\n", 0); cmd[0] = KYTY_PM4(size, Pm4::IT_NOP, Pm4::R_PS_EMBEDDED); cmd[1] = 0; } else { EXIT_NOT_IMPLEMENTED(size < 12 + 1); printf("\t cmd_buffer = %016" PRIx64 "\n", reinterpret_cast(cmd)); printf("\t size = %" PRIu64 "\n", size); printf("\t ps_regs.m_spiShaderPgmLoPs = %08" PRIx32 "\n", ps_regs[0]); printf("\t ps_regs.m_spiShaderPgmHiPs = %08" PRIx32 "\n", ps_regs[1]); printf("\t ps_regs.m_spiShaderPgmRsrc1Ps = %08" PRIx32 "\n", ps_regs[2]); printf("\t ps_regs.m_spiShaderPgmRsrc2Ps = %08" PRIx32 "\n", ps_regs[3]); printf("\t ps_regs.m_spiShaderZFormat = %08" PRIx32 "\n", ps_regs[4]); printf("\t ps_regs.m_spiShaderColFormat = %08" PRIx32 "\n", ps_regs[5]); printf("\t ps_regs.m_spiPsInputEna = %08" PRIx32 "\n", ps_regs[6]); printf("\t ps_regs.m_spiPsInputAddr = %08" PRIx32 "\n", ps_regs[7]); printf("\t ps_regs.m_spiPsInControl = %08" PRIx32 "\n", ps_regs[8]); printf("\t ps_regs.m_spiBarycCntl = %08" PRIx32 "\n", ps_regs[9]); printf("\t ps_regs.m_dbShaderControl = %08" PRIx32 "\n", ps_regs[10]); printf("\t ps_regs.m_cbShaderMask = %08" PRIx32 "\n", ps_regs[11]); cmd[0] = KYTY_PM4(size, Pm4::IT_NOP, Pm4::R_PS); memcpy(&cmd[1], ps_regs, static_cast(12) * 4); } return OK; } int KYTY_SYSV_ABI GraphicsSetPsShader350(uint32_t* cmd, uint64_t size, const uint32_t* ps_regs) { PRINT_NAME(); if (ps_regs == nullptr) { EXIT_NOT_IMPLEMENTED(size < 1 + 1); printf("\t cmd_buffer = %016" PRIx64 "\n", reinterpret_cast(cmd)); printf("\t size = %" PRIu64 "\n", size); printf("\t embedded_id = %d\n", 0); cmd[0] = KYTY_PM4(size, Pm4::IT_NOP, Pm4::R_PS_EMBEDDED); cmd[1] = 0; } else { EXIT_NOT_IMPLEMENTED(size < 12 + 1); printf("\t cmd_buffer = %016" PRIx64 "\n", reinterpret_cast(cmd)); printf("\t size = %" PRIu64 "\n", size); printf("\t ps_regs.m_spiShaderPgmLoPs = %08" PRIx32 "\n", ps_regs[0]); printf("\t ps_regs.m_spiShaderPgmHiPs = %08" PRIx32 "\n", ps_regs[1]); printf("\t ps_regs.m_spiShaderPgmRsrc1Ps = %08" PRIx32 "\n", ps_regs[2]); printf("\t ps_regs.m_spiShaderPgmRsrc2Ps = %08" PRIx32 "\n", ps_regs[3]); printf("\t ps_regs.m_spiShaderZFormat = %08" PRIx32 "\n", ps_regs[4]); printf("\t ps_regs.m_spiShaderColFormat = %08" PRIx32 "\n", ps_regs[5]); printf("\t ps_regs.m_spiPsInputEna = %08" PRIx32 "\n", ps_regs[6]); printf("\t ps_regs.m_spiPsInputAddr = %08" PRIx32 "\n", ps_regs[7]); printf("\t ps_regs.m_spiPsInControl = %08" PRIx32 "\n", ps_regs[8]); printf("\t ps_regs.m_spiBarycCntl = %08" PRIx32 "\n", ps_regs[9]); printf("\t ps_regs.m_dbShaderControl = %08" PRIx32 "\n", ps_regs[10]); printf("\t ps_regs.m_cbShaderMask = %08" PRIx32 "\n", ps_regs[11]); cmd[0] = KYTY_PM4(size, Pm4::IT_NOP, Pm4::R_PS); memcpy(&cmd[1], ps_regs, static_cast(12) * 4); } // printf("ok\n"); return OK; } int KYTY_SYSV_ABI GraphicsUpdatePsShader(uint32_t* cmd, uint64_t size, const uint32_t* ps_regs) { PRINT_NAME(); EXIT_NOT_IMPLEMENTED(ps_regs == nullptr); EXIT_NOT_IMPLEMENTED(size < 12 + 1); printf("\t cmd_buffer = %016" PRIx64 "\n", reinterpret_cast(cmd)); printf("\t size = %" PRIu64 "\n", size); printf("\t ps_regs.m_spiShaderPgmLoPs = %08" PRIx32 "\n", ps_regs[0]); printf("\t ps_regs.m_spiShaderPgmHiPs = %08" PRIx32 "\n", ps_regs[1]); printf("\t ps_regs.m_spiShaderPgmRsrc1Ps = %08" PRIx32 "\n", ps_regs[2]); printf("\t ps_regs.m_spiShaderPgmRsrc2Ps = %08" PRIx32 "\n", ps_regs[3]); printf("\t ps_regs.m_spiShaderZFormat = %08" PRIx32 "\n", ps_regs[4]); printf("\t ps_regs.m_spiShaderColFormat = %08" PRIx32 "\n", ps_regs[5]); printf("\t ps_regs.m_spiPsInputEna = %08" PRIx32 "\n", ps_regs[6]); printf("\t ps_regs.m_spiPsInputAddr = %08" PRIx32 "\n", ps_regs[7]); printf("\t ps_regs.m_spiPsInControl = %08" PRIx32 "\n", ps_regs[8]); printf("\t ps_regs.m_spiBarycCntl = %08" PRIx32 "\n", ps_regs[9]); printf("\t ps_regs.m_dbShaderControl = %08" PRIx32 "\n", ps_regs[10]); printf("\t ps_regs.m_cbShaderMask = %08" PRIx32 "\n", ps_regs[11]); cmd[0] = KYTY_PM4(size, Pm4::IT_NOP, Pm4::R_PS_UPDATE); memcpy(&cmd[1], ps_regs, static_cast(12) * 4); return OK; } int KYTY_SYSV_ABI GraphicsUpdatePsShader350(uint32_t* cmd, uint64_t size, const uint32_t* ps_regs) { PRINT_NAME(); EXIT_NOT_IMPLEMENTED(ps_regs == nullptr); EXIT_NOT_IMPLEMENTED(size < 12 + 1); printf("\t cmd_buffer = %016" PRIx64 "\n", reinterpret_cast(cmd)); printf("\t size = %" PRIu64 "\n", size); printf("\t ps_regs.m_spiShaderPgmLoPs = %08" PRIx32 "\n", ps_regs[0]); printf("\t ps_regs.m_spiShaderPgmHiPs = %08" PRIx32 "\n", ps_regs[1]); printf("\t ps_regs.m_spiShaderPgmRsrc1Ps = %08" PRIx32 "\n", ps_regs[2]); printf("\t ps_regs.m_spiShaderPgmRsrc2Ps = %08" PRIx32 "\n", ps_regs[3]); printf("\t ps_regs.m_spiShaderZFormat = %08" PRIx32 "\n", ps_regs[4]); printf("\t ps_regs.m_spiShaderColFormat = %08" PRIx32 "\n", ps_regs[5]); printf("\t ps_regs.m_spiPsInputEna = %08" PRIx32 "\n", ps_regs[6]); printf("\t ps_regs.m_spiPsInputAddr = %08" PRIx32 "\n", ps_regs[7]); printf("\t ps_regs.m_spiPsInControl = %08" PRIx32 "\n", ps_regs[8]); printf("\t ps_regs.m_spiBarycCntl = %08" PRIx32 "\n", ps_regs[9]); printf("\t ps_regs.m_dbShaderControl = %08" PRIx32 "\n", ps_regs[10]); printf("\t ps_regs.m_cbShaderMask = %08" PRIx32 "\n", ps_regs[11]); cmd[0] = KYTY_PM4(size, Pm4::IT_NOP, Pm4::R_PS_UPDATE); memcpy(&cmd[1], ps_regs, static_cast(12) * 4); return OK; } int KYTY_SYSV_ABI GraphicsSetCsShaderWithModifier(uint32_t* cmd, uint64_t size, const uint32_t* cs_regs, uint32_t shader_modifier) { PRINT_NAME(); EXIT_NOT_IMPLEMENTED(size < 7 + 2); printf("\t cmd_buffer = %016" PRIx64 "\n", reinterpret_cast(cmd)); printf("\t size = %" PRIu64 "\n", size); printf("\t shader_modifier = %" PRIu32 "\n", shader_modifier); printf("\t cs_regs.m_computePgmLo = %08" PRIx32 "\n", cs_regs[0]); printf("\t cs_regs.m_computePgmHi = %08" PRIx32 "\n", cs_regs[1]); printf("\t cs_regs.m_computePgmRsrc1 = %08" PRIx32 "\n", cs_regs[2]); printf("\t cs_regs.m_computePgmRsrc2 = %08" PRIx32 "\n", cs_regs[3]); printf("\t cs_regs.m_computeNumThreadX = %08" PRIx32 "\n", cs_regs[4]); printf("\t cs_regs.m_computeNumThreadY = %08" PRIx32 "\n", cs_regs[5]); printf("\t cs_regs.m_computeNumThreadZ = %08" PRIx32 "\n", cs_regs[6]); cmd[0] = KYTY_PM4(size, Pm4::IT_NOP, Pm4::R_CS); cmd[1] = shader_modifier; memcpy(&cmd[2], cs_regs, static_cast(7) * 4); return OK; } int KYTY_SYSV_ABI GraphicsDrawIndex(uint32_t* cmd, uint64_t size, uint32_t index_count, const void* index_addr, uint32_t flags, uint32_t type) { PRINT_NAME(); EXIT_NOT_IMPLEMENTED(size < 6); printf("\tcmd_buffer = %016" PRIx64 "\n", reinterpret_cast(cmd)); printf("\tsize = %" PRIu64 "\n", size); printf("\tindex_count = %" PRIu32 "\n", index_count); printf("\tindex_addr = %016" PRIx64 "\n", reinterpret_cast(index_addr)); printf("\tflags = %08" PRIx32 "\n", flags); printf("\ttype = %" PRIu32 "\n", type); cmd[0] = KYTY_PM4(size, Pm4::IT_NOP, Pm4::R_DRAW_INDEX); cmd[1] = index_count; cmd[2] = static_cast(reinterpret_cast(index_addr) & 0xffffffffu); cmd[3] = static_cast((reinterpret_cast(index_addr) >> 32u) & 0xffffffffu); cmd[4] = flags; cmd[5] = type; return OK; } int KYTY_SYSV_ABI GraphicsDrawIndexAuto(uint32_t* cmd, uint64_t size, uint32_t index_count, uint32_t flags) { PRINT_NAME(); EXIT_NOT_IMPLEMENTED(size < 3); printf("\tcmd_buffer = %016" PRIx64 "\n", reinterpret_cast(cmd)); printf("\tsize = %" PRIu64 "\n", size); printf("\tindex_count = %" PRIu32 "\n", index_count); printf("\tflags = %08" PRIx32 "\n", flags); cmd[0] = KYTY_PM4(size, Pm4::IT_NOP, Pm4::R_DRAW_INDEX_AUTO); cmd[1] = index_count; cmd[2] = flags; return OK; } int KYTY_SYSV_ABI GraphicsInsertWaitFlipDone(uint32_t* cmd, uint64_t size, uint32_t video_out_handle, uint32_t display_buffer_index) { PRINT_NAME(); EXIT_NOT_IMPLEMENTED(size < 3); printf("\tcmd_buffer = %016" PRIx64 "\n", reinterpret_cast(cmd)); printf("\tsize = %" PRIu64 "\n", size); printf("\tvideo_out_handle = %" PRIu32 "\n", video_out_handle); printf("\tdisplay_buffer_index = %" PRIu32 "\n", display_buffer_index); cmd[0] = KYTY_PM4(size, Pm4::IT_NOP, Pm4::R_WAIT_FLIP_DONE); cmd[1] = video_out_handle; cmd[2] = display_buffer_index; return OK; } int KYTY_SYSV_ABI GraphicsDispatchDirect(uint32_t* cmd, uint64_t size, uint32_t thread_group_x, uint32_t thread_group_y, uint32_t thread_group_z, uint32_t mode) { PRINT_NAME(); EXIT_NOT_IMPLEMENTED(size < 5); printf("\t cmd_buffer = %016" PRIx64 "\n", reinterpret_cast(cmd)); printf("\t size = %" PRIu64 "\n", size); printf("\t thread_group_x = %" PRIu32 "\n", thread_group_x); printf("\t thread_group_y = %" PRIu32 "\n", thread_group_y); printf("\t thread_group_z = %" PRIu32 "\n", thread_group_z); printf("\t mode = %" PRIu32 "\n", mode); cmd[0] = KYTY_PM4(size, Pm4::IT_NOP, Pm4::R_DISPATCH_DIRECT); cmd[1] = thread_group_x; cmd[2] = thread_group_y; cmd[3] = thread_group_z; cmd[4] = mode; return OK; } uint32_t KYTY_SYSV_ABI GraphicsDrawInitDefaultHardwareState(uint32_t* cmd, uint64_t size) { PRINT_NAME(); EXIT_NOT_IMPLEMENTED(size < 2); printf("\t cmd_buffer = %016" PRIx64 "\n", reinterpret_cast(cmd)); printf("\t size = %" PRIu64 "\n", size); cmd[0] = KYTY_PM4(2, Pm4::IT_NOP, Pm4::R_DRAW_RESET); return 2; } uint32_t KYTY_SYSV_ABI GraphicsDrawInitDefaultHardwareState175(uint32_t* cmd, uint64_t size) { PRINT_NAME(); EXIT_NOT_IMPLEMENTED(size < 2); printf("\t cmd_buffer = %016" PRIx64 "\n", reinterpret_cast(cmd)); printf("\t size = %" PRIu64 "\n", size); cmd[0] = KYTY_PM4(2, Pm4::IT_NOP, Pm4::R_DRAW_RESET); return 2; } uint32_t KYTY_SYSV_ABI GraphicsDrawInitDefaultHardwareState200(uint32_t* cmd, uint64_t size) { PRINT_NAME(); EXIT_NOT_IMPLEMENTED(size < 2); printf("\t cmd_buffer = %016" PRIx64 "\n", reinterpret_cast(cmd)); printf("\t size = %" PRIu64 "\n", size); cmd[0] = KYTY_PM4(2, Pm4::IT_NOP, Pm4::R_DRAW_RESET); return 2; } uint32_t KYTY_SYSV_ABI GraphicsDrawInitDefaultHardwareState350(uint32_t* cmd, uint64_t size) { PRINT_NAME(); EXIT_NOT_IMPLEMENTED(size < 2); printf("\t cmd_buffer = %016" PRIx64 "\n", reinterpret_cast(cmd)); printf("\t size = %" PRIu64 "\n", size); cmd[0] = KYTY_PM4(2, Pm4::IT_NOP, Pm4::R_DRAW_RESET); return 2; } uint32_t KYTY_SYSV_ABI GraphicsDispatchInitDefaultHardwareState(uint32_t* cmd, uint64_t size) { PRINT_NAME(); EXIT_NOT_IMPLEMENTED(size < 2); printf("\t cmd_buffer = %016" PRIx64 "\n", reinterpret_cast(cmd)); printf("\t size = %" PRIu64 "\n", size); cmd[0] = KYTY_PM4(2, Pm4::IT_NOP, Pm4::R_DISPATCH_RESET); return 2; } void GraphicsDbgDumpDcb(const char* type, uint32_t num_dw, uint32_t* cmd_buffer) { EXIT_IF(type == nullptr); static std::atomic_int id = 0; if (Config::CommandBufferDumpEnabled() && num_dw > 0 && cmd_buffer != nullptr) { Core::File f; String file_name = Config::GetCommandBufferDumpFolder().FixDirectorySlash() + String::FromPrintf("%04d_%04d_buffer_%s.log", GraphicsRunGetFrameNum(), id++, type); Core::File::CreateDirectories(file_name.DirectoryWithoutFilename()); f.Create(file_name); if (f.IsInvalid()) { printf(FG_BRIGHT_RED "Can't create file: %s\n" FG_DEFAULT, file_name.C_Str()); return; } Pm4::DumpPm4PacketStream(&f, cmd_buffer, 0, num_dw); f.Close(); } } int KYTY_SYSV_ABI GraphicsSubmitCommandBuffers(uint32_t count, void* dcb_gpu_addrs[], const uint32_t* dcb_sizes_in_bytes, void* ccb_gpu_addrs[], const uint32_t* ccb_sizes_in_bytes) { PRINT_NAME(); EXIT_NOT_IMPLEMENTED(count != 1); auto* dcb = (dcb_gpu_addrs == nullptr ? nullptr : static_cast(dcb_gpu_addrs[0])); auto dcb_size = (dcb_sizes_in_bytes == nullptr ? 0 : dcb_sizes_in_bytes[0] / 4); auto* ccb = (ccb_gpu_addrs == nullptr ? nullptr : static_cast(ccb_gpu_addrs[0])); auto ccb_size = (ccb_sizes_in_bytes == nullptr ? 0 : ccb_sizes_in_bytes[0] / 4); GraphicsDbgDumpDcb("d", dcb_size, dcb); GraphicsDbgDumpDcb("c", ccb_size, ccb); GraphicsRunSubmit(dcb, dcb_size, ccb, ccb_size); return OK; } int KYTY_SYSV_ABI GraphicsSubmitAndFlipCommandBuffers(uint32_t count, void* dcb_gpu_addrs[], const uint32_t* dcb_sizes_in_bytes, void* ccb_gpu_addrs[], const uint32_t* ccb_sizes_in_bytes, int handle, int index, int flip_mode, int64_t flip_arg) { PRINT_NAME(); EXIT_NOT_IMPLEMENTED(count != 1); auto* dcb = (dcb_gpu_addrs == nullptr ? nullptr : static_cast(dcb_gpu_addrs[0])); auto dcb_size = (dcb_sizes_in_bytes == nullptr ? 0 : dcb_sizes_in_bytes[0] / 4); auto* ccb = (ccb_gpu_addrs == nullptr ? nullptr : static_cast(ccb_gpu_addrs[0])); auto ccb_size = (ccb_sizes_in_bytes == nullptr ? 0 : ccb_sizes_in_bytes[0] / 4); GraphicsDbgDumpDcb("d", dcb_size, dcb); GraphicsDbgDumpDcb("c", ccb_size, ccb); printf("\t handle = %" PRId32 "\n", handle); printf("\t index = %" PRId32 "\n", index); printf("\t flip_mode = %" PRId32 "\n", flip_mode); printf("\t flip_arg = %" PRId64 "\n", flip_arg); GraphicsRunSubmitAndFlip(dcb, dcb_size, ccb, ccb_size, handle, index, flip_mode, flip_arg); return OK; } int KYTY_SYSV_ABI GraphicsSubmitDone() { PRINT_NAME(); GraphicsRunDone(); return OK; } int KYTY_SYSV_ABI GraphicsAreSubmitsAllowed() { return GraphicsRunAreSubmitsAllowed() ? 1 : 0; } void KYTY_SYSV_ABI GraphicsFlushMemory() { PRINT_NAME(); GpuMemoryFlushAll(WindowGetGraphicContext()); } int KYTY_SYSV_ABI GraphicsAddEqEvent(LibKernel::EventQueue::KernelEqueue eq, int id, void* udata) { PRINT_NAME(); if (eq == nullptr) { return LibKernel::KERNEL_ERROR_EBADF; } return GraphicsRenderAddEqEvent(eq, id, udata); } int KYTY_SYSV_ABI GraphicsDeleteEqEvent(LibKernel::EventQueue::KernelEqueue eq, int id) { PRINT_NAME(); if (eq == nullptr) { return LibKernel::KERNEL_ERROR_EBADF; } return GraphicsRenderDeleteEqEvent(eq, id); } uint32_t KYTY_SYSV_ABI GraphicsMapComputeQueue(uint32_t pipe_id, uint32_t queue_id, uint32_t* ring_addr, uint32_t ring_size_dw, uint32_t* read_ptr_addr) { PRINT_NAME(); printf("\t pipe_id = %" PRIu32 "\n", pipe_id); printf("\t queue_id = %" PRIu32 "\n", queue_id); printf("\t ring_addr = %016" PRIx64 "\n", reinterpret_cast(ring_addr)); printf("\t ring_size_dw = %" PRIu32 "\n", ring_size_dw); printf("\t read_ptr_addr = %016" PRIx64 "\n", reinterpret_cast(read_ptr_addr)); uint32_t id = GraphicsRunMapComputeQueue(pipe_id, queue_id, ring_addr, ring_size_dw, read_ptr_addr); printf("\t queue = %" PRIu32 "\n", id); return id; } void KYTY_SYSV_ABI GraphicsUnmapComputeQueue(uint32_t id) { PRINT_NAME(); printf("\t id = %" PRIu32 "\n", id); GraphicsRunUnmapComputeQueue(id); } int KYTY_SYSV_ABI GraphicsComputeWaitOnAddress(uint32_t* cmd, uint64_t size, uint32_t* gpu_addr, uint32_t mask, uint32_t func, uint32_t ref) { PRINT_NAME(); EXIT_NOT_IMPLEMENTED(size < 6); printf("\t cmd_buffer = %016" PRIx64 "\n", reinterpret_cast(cmd)); printf("\t size = %" PRIu64 "\n", size); printf("\t gpu_addr = %016" PRIx64 "\n", reinterpret_cast(gpu_addr)); printf("\t mask = %08" PRIx32 "\n", mask); printf("\t func = %" PRIu32 "\n", func); printf("\t ref = %08" PRIx32 "\n", ref); cmd[0] = KYTY_PM4(size, Pm4::IT_NOP, Pm4::R_DISPATCH_WAIT_MEM); cmd[1] = static_cast(reinterpret_cast(gpu_addr) & 0xffffffffu); cmd[2] = static_cast((reinterpret_cast(gpu_addr) >> 32u) & 0xffffffffu); cmd[3] = mask; cmd[4] = func; cmd[5] = ref; return OK; } void KYTY_SYSV_ABI GraphicsDingDong(uint32_t ring_id, uint32_t offset_dw) { PRINT_NAME(); printf("\t ring_id = %" PRIu32 "\n", ring_id); printf("\t offset_dw = %" PRIu32 "\n", offset_dw); GraphicsRunDingDong(ring_id, offset_dw); } int KYTY_SYSV_ABI GraphicsInsertPushMarker(uint32_t* cmd, uint64_t size, const char* str) { PRINT_NAME(); auto len = strlen(str) + 1; EXIT_NOT_IMPLEMENTED(size * 4 < len + 1); printf("\t cmd_buffer = %016" PRIx64 "\n", reinterpret_cast(cmd)); printf("\t size = %" PRIu64 "\n", size); printf("\t str = %s\n", str); cmd[0] = KYTY_PM4(size, Pm4::IT_NOP, Pm4::R_PUSH_MARKER); memcpy(cmd + 1, str, len); return OK; } int KYTY_SYSV_ABI GraphicsInsertPopMarker(uint32_t* cmd, uint64_t size) { PRINT_NAME(); EXIT_NOT_IMPLEMENTED(size < 2); printf("\t cmd_buffer = %016" PRIx64 "\n", reinterpret_cast(cmd)); printf("\t size = %" PRIu64 "\n", size); cmd[0] = KYTY_PM4(size, Pm4::IT_NOP, Pm4::R_POP_MARKER); return OK; } uint64_t KYTY_SYSV_ABI GraphicsGetGpuCoreClockFrequency() { return LibKernel::KernelGetTscFrequency(); } int KYTY_SYSV_ABI GraphicsIsUserPaEnabled() { return 0; } void* KYTY_SYSV_ABI GraphicsGetTheTessellationFactorRingBufferBaseAddress() { PRINT_NAME(); auto addr = Loader::VirtualMemory::AllocAligned(0, 0x20000, Loader::VirtualMemory::Mode::ReadWrite, 256); Loader::VirtualMemory::Free(addr); bool again = Loader::VirtualMemory::AllocFixed(addr, 0x20000, Loader::VirtualMemory::Mode::ReadWrite); EXIT_NOT_IMPLEMENTED(!again); Loader::VirtualMemory::Free(addr); printf("\t addr = %016" PRIx64 "\n", addr); return reinterpret_cast(addr); } int KYTY_SYSV_ABI GraphicsRegisterOwner(uint32_t* owner_handle, const char* name) { PRINT_NAME(); EXIT_NOT_IMPLEMENTED(owner_handle == nullptr); EXIT_NOT_IMPLEMENTED(name == nullptr); printf("\t RegisterOwner: %s\n", name); GpuMemoryRegisterOwner(owner_handle, name); printf("\t handler: %" PRIu32 "\n", *owner_handle); return OK; } int KYTY_SYSV_ABI GraphicsRegisterResource(uint32_t* resource_handle, uint32_t owner_handle, const void* memory, size_t size, const char* name, uint32_t type, uint64_t user_data) { PRINT_NAME(); // EXIT_NOT_IMPLEMENTED(resource_handle == nullptr); EXIT_NOT_IMPLEMENTED(memory == nullptr); EXIT_NOT_IMPLEMENTED(name == nullptr); printf("\t RegisterResource: %s\n", name); printf("\t owner_handle: %" PRIu32 "\n", owner_handle); printf("\t addr: %016" PRIx64 "\n", reinterpret_cast(memory)); printf("\t size: %" PRIu64 "\n", size); printf("\t type: %" PRIu32 "\n", type); printf("\t user_data: %" PRIu64 "\n", user_data); uint32_t rhandle = 0; GpuMemoryRegisterResource(&rhandle, owner_handle, memory, size, name, type, user_data); printf("\t handler: %" PRIu32 "\n", rhandle); if (resource_handle != nullptr) { *resource_handle = rhandle; } return OK; } int KYTY_SYSV_ABI GraphicsUnregisterAllResourcesForOwner(uint32_t owner_handle) { PRINT_NAME(); printf("\t owner_handle: %" PRIu32 "\n", owner_handle); GpuMemoryUnregisterAllResourcesForOwner(owner_handle); return OK; } int KYTY_SYSV_ABI GraphicsUnregisterOwnerAndResources(uint32_t owner_handle) { PRINT_NAME(); printf("\t owner_handle: %" PRIu32 "\n", owner_handle); GpuMemoryUnregisterOwnerAndResources(owner_handle); return OK; } int KYTY_SYSV_ABI GraphicsUnregisterResource(uint32_t resource_handle) { PRINT_NAME(); printf("\t resource_handle: %" PRIu32 "\n", resource_handle); GpuMemoryUnregisterResource(resource_handle); return OK; } } // namespace Kyty::Libs::Graphics #endif // KYTY_EMU_ENABLED