diff --git a/README.md b/README.md index a20bc0d..2d6eada 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ The project is in its early stage. Licensed under the MIT license. --- -Graphics for PS5 is not yet implemented +Graphics for PS5 is under development. It is possible to run some simple games for PS4 diff --git a/appveyor.yml b/appveyor.yml index d679a9c..6738ced 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 0.1.8.build-{build} +version: 0.1.9.build-{build} image: Visual Studio 2019 environment: matrix: diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt index 8fcbf6d..8457075 100644 --- a/source/CMakeLists.txt +++ b/source/CMakeLists.txt @@ -82,7 +82,7 @@ if (KYTY_LINKER STREQUAL LD) set(KYTY_LD_OPTIONS "-Wl,--image-base=0x100000000000") endif() -project(Kyty${KYTY_PROJECT_NAME}${CMAKE_BUILD_TYPE}${KYTY_COMPILER} VERSION 0.1.8) +project(Kyty${KYTY_PROJECT_NAME}${CMAKE_BUILD_TYPE}${KYTY_COMPILER} VERSION 0.1.9) include(src_script.cmake) diff --git a/source/emulator/include/Emulator/Graphics/Graphics.h b/source/emulator/include/Emulator/Graphics/Graphics.h index 54ae6b9..be62dbf 100644 --- a/source/emulator/include/Emulator/Graphics/Graphics.h +++ b/source/emulator/include/Emulator/Graphics/Graphics.h @@ -19,6 +19,8 @@ KYTY_SUBSYSTEM_DEFINE(Graphics); void GraphicsDbgDumpDcb(const char* type, uint32_t num_dw, uint32_t* cmd_buffer); +namespace Gen4 { + int KYTY_SYSV_ABI GraphicsSetVsShader(uint32_t* cmd, uint64_t size, const HW::VsStageRegisters* vs_regs, uint32_t shader_modifier); int KYTY_SYSV_ABI GraphicsUpdateVsShader(uint32_t* cmd, uint64_t size, const HW::VsStageRegisters* vs_regs, uint32_t shader_modifier); int KYTY_SYSV_ABI GraphicsSetPsShader(uint32_t* cmd, uint64_t size, const uint32_t* ps_regs); @@ -67,6 +69,39 @@ int KYTY_SYSV_ABI GraphicsUnregisterAllResourcesForOwner(uint32_t owner_handle); int KYTY_SYSV_ABI GraphicsUnregisterOwnerAndResources(uint32_t owner_handle); int KYTY_SYSV_ABI GraphicsUnregisterResource(uint32_t resource_handle); +} // namespace Gen4 + +namespace Gen5 { + +struct Shader; +struct CommandBuffer; +struct ShaderRegister; + +int KYTY_SYSV_ABI GraphicsInit(uint32_t* state, uint32_t ver); +void* KYTY_SYSV_ABI GraphicsGetRegisterDefaults2(uint32_t ver); +void* KYTY_SYSV_ABI GraphicsGetRegisterDefaults2Internal(uint32_t ver); +int KYTY_SYSV_ABI GraphicsCreateShader(Shader** dst, void* header, const volatile void* code); +uint32_t* KYTY_SYSV_ABI GraphicsDcbResetQueue(CommandBuffer* buf, uint32_t op, uint32_t state); +uint32_t* KYTY_SYSV_ABI GraphicsDcbWaitUntilSafeForRendering(CommandBuffer* buf, uint32_t video_out_handle, uint32_t display_buffer_index); +uint32_t* KYTY_SYSV_ABI GraphicsDcbSetCxRegistersIndirect(CommandBuffer* buf, const volatile ShaderRegister* regs, uint32_t num_regs); +uint32_t* KYTY_SYSV_ABI GraphicsDcbSetShRegistersIndirect(CommandBuffer* buf, const volatile ShaderRegister* regs, uint32_t num_regs); +uint32_t* KYTY_SYSV_ABI GraphicsDcbSetUcRegistersIndirect(CommandBuffer* buf, const volatile ShaderRegister* regs, uint32_t num_regs); +uint32_t* KYTY_SYSV_ABI GraphicsDcbSetIndexSize(CommandBuffer* buf, uint8_t index_size, uint8_t cache_policy); +uint32_t* KYTY_SYSV_ABI GraphicsDcbDrawIndexAuto(CommandBuffer* buf, uint32_t index_count, uint64_t modifier); +int KYTY_SYSV_ABI GraphicsSetCxRegIndirectPatchSetAddress(uint32_t* cmd, const volatile ShaderRegister* regs); +int KYTY_SYSV_ABI GraphicsSetShRegIndirectPatchSetAddress(uint32_t* cmd, const volatile ShaderRegister* regs); +int KYTY_SYSV_ABI GraphicsSetUcRegIndirectPatchSetAddress(uint32_t* cmd, const volatile ShaderRegister* regs); +int KYTY_SYSV_ABI GraphicsSetCxRegIndirectPatchAddRegisters(uint32_t* cmd, uint32_t num_regs); +int KYTY_SYSV_ABI GraphicsSetShRegIndirectPatchAddRegisters(uint32_t* cmd, uint32_t num_regs); +int KYTY_SYSV_ABI GraphicsSetUcRegIndirectPatchAddRegisters(uint32_t* cmd, uint32_t num_regs); +int KYTY_SYSV_ABI GraphicsCreatePrimState(ShaderRegister* cx_regs, ShaderRegister* uc_regs, const Shader* hs, const Shader* gs, + uint32_t prim_type); +int KYTY_SYSV_ABI GraphicsCreateInterpolantMapping(ShaderRegister* regs, const Shader* gs, const Shader* ps); +uint32_t* KYTY_SYSV_ABI GraphicsCbSetShRegisterRangeDirect(CommandBuffer* buf, uint32_t offset, const uint32_t* values, + uint32_t num_values); +int KYTY_SYSV_ABI GraphicsGetDataPacketPayloadAddress(uint32_t** addr, uint32_t* cmd, int type); +} // namespace Gen5 + } // namespace Kyty::Libs::Graphics #endif // KYTY_EMU_ENABLED diff --git a/source/emulator/include/Emulator/Graphics/Objects/VideoOutBuffer.h b/source/emulator/include/Emulator/Graphics/Objects/VideoOutBuffer.h index 2bf36e8..d5abf9a 100644 --- a/source/emulator/include/Emulator/Graphics/Objects/VideoOutBuffer.h +++ b/source/emulator/include/Emulator/Graphics/Objects/VideoOutBuffer.h @@ -10,6 +10,13 @@ namespace Kyty::Libs::Graphics { +enum class VideoOutBufferFormat : uint64_t +{ + Unknown, + R8G8B8A8Srgb, + B8G8R8A8Srgb, +}; + class VideoOutBufferObject: public GpuObject { public: @@ -20,9 +27,9 @@ public: static constexpr int PARAM_NEO = 4; static constexpr int PARAM_PITCH = 5; - explicit VideoOutBufferObject(uint32_t pixel_format, uint32_t width, uint32_t height, bool tiled, bool neo, uint32_t pitch) + explicit VideoOutBufferObject(VideoOutBufferFormat pixel_format, uint32_t width, uint32_t height, bool tiled, bool neo, uint32_t pitch) { - params[PARAM_FORMAT] = pixel_format; + params[PARAM_FORMAT] = static_cast(pixel_format); params[PARAM_WIDTH] = width; params[PARAM_HEIGHT] = height; params[PARAM_TILED] = tiled ? 1 : 0; diff --git a/source/emulator/include/Emulator/Graphics/Pm4.h b/source/emulator/include/Emulator/Graphics/Pm4.h index aaa626c..62f7bf6 100644 --- a/source/emulator/include/Emulator/Graphics/Pm4.h +++ b/source/emulator/include/Emulator/Graphics/Pm4.h @@ -16,6 +16,8 @@ class File; #define KYTY_PM4(len, op, r) \ (0xC0000000u | (((static_cast(len) - 2u) & 0x3fffu) << 16u) | (((op)&0xffu) << 8u) | (((r)&0x3fu) << 2u)) +#define KYTY_PM4_LEN(cmd_id) ((((cmd_id) >> 16u) & 0x3fffu) + 2u) + namespace Kyty::Libs::Graphics::Pm4 { constexpr uint32_t IT_NOP = 0x10; @@ -84,6 +86,9 @@ constexpr uint32_t R_VS_EMBEDDED = 0x0D; constexpr uint32_t R_PS_EMBEDDED = 0x0E; constexpr uint32_t R_VS_UPDATE = 0x0F; constexpr uint32_t R_PS_UPDATE = 0x10; +constexpr uint32_t R_SH_REGS = 0x11; +constexpr uint32_t R_CX_REGS = 0x12; +constexpr uint32_t R_UC_REGS = 0x13; constexpr uint32_t DB_RENDER_CONTROL = 0x0; constexpr uint32_t DB_RENDER_CONTROL_DEPTH_CLEAR_ENABLE_SHIFT = 0; @@ -107,9 +112,8 @@ constexpr uint32_t DB_DEPTH_VIEW_SLICE_START_MASK = 0x7FF; constexpr uint32_t DB_DEPTH_VIEW_SLICE_MAX_SHIFT = 13; constexpr uint32_t DB_DEPTH_VIEW_SLICE_MAX_MASK = 0x7FF; -constexpr uint32_t DB_HTILE_DATA_BASE = 0x5; -constexpr uint32_t DB_HTILE_DATA_BASE_BASE_256B_SHIFT = 0; -constexpr uint32_t DB_HTILE_DATA_BASE_BASE_256B_MASK = 0xFFFFFFFF; +constexpr uint32_t DB_HTILE_DATA_BASE = 0x5; +constexpr uint32_t DB_DEPTH_SIZE_XY = 0x7; constexpr uint32_t DB_STENCIL_CLEAR = 0xA; constexpr uint32_t DB_STENCIL_CLEAR_CLEAR_SHIFT = 0; @@ -167,18 +171,15 @@ constexpr uint32_t DB_STENCIL_INFO_TILE_MODE_INDEX_MASK = 0x7; constexpr uint32_t DB_STENCIL_INFO_TILE_STENCIL_DISABLE_SHIFT = 29; constexpr uint32_t DB_STENCIL_INFO_TILE_STENCIL_DISABLE_MASK = 0x1; -constexpr uint32_t DB_Z_READ_BASE = 0x12; -constexpr uint32_t DB_Z_READ_BASE_BASE_256B_SHIFT = 0; -constexpr uint32_t DB_Z_READ_BASE_BASE_256B_MASK = 0xFFFFFFFF; -constexpr uint32_t DB_STENCIL_READ_BASE = 0x13; -constexpr uint32_t DB_STENCIL_READ_BASE_BASE_256B_SHIFT = 0; -constexpr uint32_t DB_STENCIL_READ_BASE_BASE_256B_MASK = 0xFFFFFFFF; -constexpr uint32_t DB_Z_WRITE_BASE = 0x14; -constexpr uint32_t DB_Z_WRITE_BASE_BASE_256B_SHIFT = 0; -constexpr uint32_t DB_Z_WRITE_BASE_BASE_256B_MASK = 0xFFFFFFFF; -constexpr uint32_t DB_STENCIL_WRITE_BASE = 0x15; -constexpr uint32_t DB_STENCIL_WRITE_BASE_BASE_256B_SHIFT = 0; -constexpr uint32_t DB_STENCIL_WRITE_BASE_BASE_256B_MASK = 0xFFFFFFFF; +constexpr uint32_t DB_Z_READ_BASE = 0x12; +constexpr uint32_t DB_STENCIL_READ_BASE = 0x13; +constexpr uint32_t DB_Z_WRITE_BASE = 0x14; +constexpr uint32_t DB_STENCIL_WRITE_BASE = 0x15; +constexpr uint32_t DB_Z_READ_BASE_HI = 0x1A; +constexpr uint32_t DB_STENCIL_READ_BASE_HI = 0x1B; +constexpr uint32_t DB_Z_WRITE_BASE_HI = 0x1C; +constexpr uint32_t DB_STENCIL_WRITE_BASE_HI = 0x1D; +constexpr uint32_t DB_HTILE_DATA_BASE_HI = 0x1E; constexpr uint32_t DB_DEPTH_SIZE = 0x16; constexpr uint32_t DB_DEPTH_SIZE_PITCH_TILE_MAX_SHIFT = 0; @@ -345,6 +346,8 @@ constexpr uint32_t PA_SC_MODE_CNTL_0_VPORT_SCISSOR_ENABLE_MASK = 0x1; constexpr uint32_t PA_SC_MODE_CNTL_0_LINE_STIPPLE_ENABLE_SHIFT = 2; constexpr uint32_t PA_SC_MODE_CNTL_0_LINE_STIPPLE_ENABLE_MASK = 0x1; +constexpr uint32_t VGT_GS_OUT_PRIM_TYPE = 0x29B; + constexpr uint32_t DB_HTILE_SURFACE = 0x2AF; constexpr uint32_t DB_HTILE_SURFACE_LINEAR_SHIFT = 0; constexpr uint32_t DB_HTILE_SURFACE_LINEAR_MASK = 0x1; @@ -377,8 +380,22 @@ constexpr uint32_t PA_SC_AA_CONFIG_MSAA_EXPOSED_SAMPLES_MASK = 0x7; constexpr uint32_t PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0 = 0x2FE; -constexpr uint32_t CB_COLOR0_BASE = 0x318; -constexpr uint32_t CB_COLOR0_INFO = 0x31C; +constexpr uint32_t CB_COLOR0_BASE = 0x318; +constexpr uint32_t CB_COLOR0_VIEW = 0x31B; +constexpr uint32_t CB_COLOR0_INFO = 0x31C; +constexpr uint32_t CB_COLOR0_ATTRIB = 0x31D; +constexpr uint32_t CB_COLOR0_DCC_CONTROL = 0x31E; +constexpr uint32_t CB_COLOR0_CMASK = 0x31F; +constexpr uint32_t CB_COLOR0_FMASK = 0x321; +constexpr uint32_t CB_COLOR0_CLEAR_WORD0 = 0x323; +constexpr uint32_t CB_COLOR0_CLEAR_WORD1 = 0x324; +constexpr uint32_t CB_COLOR0_DCC_BASE = 0x325; +constexpr uint32_t CB_COLOR0_BASE_EXT = 0x390; +constexpr uint32_t CB_COLOR0_CMASK_BASE_EXT = 0x398; +constexpr uint32_t CB_COLOR0_FMASK_BASE_EXT = 0x3A0; +constexpr uint32_t CB_COLOR0_DCC_BASE_EXT = 0x3A8; +constexpr uint32_t CB_COLOR0_ATTRIB2 = 0x3B0; +constexpr uint32_t CB_COLOR0_ATTRIB3 = 0x3B8; constexpr uint32_t SPI_SHADER_PGM_RSRC1_PS = 0xA; constexpr uint32_t SPI_SHADER_PGM_RSRC1_PS_VGPRS_SHIFT = 0; @@ -429,6 +446,12 @@ constexpr uint32_t COMPUTE_PGM_RSRC2_LDS_SIZE_MASK = 0x1FF; constexpr uint32_t COMPUTE_USER_DATA_0 = 0x240; constexpr uint32_t COMPUTE_USER_DATA_15 = 0x24F; +/* User config registers */ + +constexpr uint32_t GE_CNTL = 0x25b; +constexpr uint32_t GE_USER_VGPR_EN = 0x262; +constexpr uint32_t PRIMITIVE_TYPE = 0x242; + void DumpPm4PacketStream(Core::File* file, uint32_t* cmd_buffer, uint32_t start_dw, uint32_t num_dw); } // namespace Kyty::Libs::Graphics::Pm4 diff --git a/source/emulator/include/Emulator/Graphics/VideoOut.h b/source/emulator/include/Emulator/Graphics/VideoOut.h index c21513c..c0b96ae 100644 --- a/source/emulator/include/Emulator/Graphics/VideoOut.h +++ b/source/emulator/include/Emulator/Graphics/VideoOut.h @@ -18,8 +18,10 @@ namespace Kyty::Libs::VideoOut { struct VideoOutResolutionStatus; struct VideoOutBufferAttribute; +struct VideoOutBufferAttribute2; struct VideoOutFlipStatus; struct VideoOutVblankStatus; +struct VideoOutBuffers; struct VideoOutBufferImageInfo { @@ -38,11 +40,16 @@ KYTY_SYSV_ABI int VideoOutClose(int handle); KYTY_SYSV_ABI int VideoOutGetResolutionStatus(int handle, VideoOutResolutionStatus* status); KYTY_SYSV_ABI void VideoOutSetBufferAttribute(VideoOutBufferAttribute* attribute, uint32_t pixel_format, uint32_t tiling_mode, uint32_t aspect_ratio, uint32_t width, uint32_t height, uint32_t pitch_in_pixel); +KYTY_SYSV_ABI void VideoOutSetBufferAttribute2(VideoOutBufferAttribute2* attribute, uint64_t pixel_format, uint32_t tiling_mode, + uint32_t width, uint32_t height, uint64_t option, uint32_t dcc_control, + uint64_t dcc_cb_register_clear_color); KYTY_SYSV_ABI int VideoOutSetFlipRate(int handle, int rate); KYTY_SYSV_ABI int VideoOutAddFlipEvent(LibKernel::EventQueue::KernelEqueue eq, int handle, void* udata); KYTY_SYSV_ABI int VideoOutAddVblankEvent(LibKernel::EventQueue::KernelEqueue eq, int handle, void* udata); KYTY_SYSV_ABI int VideoOutRegisterBuffers(int handle, int start_index, void* const* addresses, int buffer_num, const VideoOutBufferAttribute* attribute); +KYTY_SYSV_ABI int VideoOutRegisterBuffers2(int handle, int set_index, int buffer_index_start, const VideoOutBuffers* buffers, + int buffer_num, const VideoOutBufferAttribute2* attribute, int category, void* option); KYTY_SYSV_ABI int VideoOutSubmitFlip(int handle, int index, int flip_mode, int64_t flip_arg); KYTY_SYSV_ABI int VideoOutGetFlipStatus(int handle, VideoOutFlipStatus* status); KYTY_SYSV_ABI int VideoOutGetVblankStatus(int handle, VideoOutVblankStatus* status); diff --git a/source/emulator/include/Emulator/Kernel/Memory.h b/source/emulator/include/Emulator/Kernel/Memory.h index 7e192cf..d49dbf2 100644 --- a/source/emulator/include/Emulator/Kernel/Memory.h +++ b/source/emulator/include/Emulator/Kernel/Memory.h @@ -18,11 +18,15 @@ int KYTY_SYSV_ABI KernelMunmap(uint64_t vaddr, size_t len); size_t KYTY_SYSV_ABI KernelGetDirectMemorySize(); int KYTY_SYSV_ABI KernelAllocateDirectMemory(int64_t search_start, int64_t search_end, size_t len, size_t alignment, int memory_type, int64_t* phys_addr_out); +int KYTY_SYSV_ABI KernelAllocateMainDirectMemory(size_t len, size_t alignment, int memory_type, int64_t* phys_addr_out); int KYTY_SYSV_ABI KernelReleaseDirectMemory(int64_t start, size_t len); int KYTY_SYSV_ABI KernelMapDirectMemory(void** addr, size_t len, int prot, int flags, int64_t direct_memory_start, size_t alignment); +int KYTY_SYSV_ABI KernelMapNamedDirectMemory(void** addr, size_t len, int prot, int flags, off_t direct_memory_start, size_t alignment, + const char* name); int KYTY_SYSV_ABI KernelQueryMemoryProtection(void* addr, void** start, void** end, int* prot); int KYTY_SYSV_ABI KernelDirectMemoryQuery(int64_t offset, int flags, void* info, size_t info_size); int KYTY_SYSV_ABI KernelAvailableFlexibleMemorySize(size_t* size); +int KYTY_SYSV_ABI KernelMprotect(const void* addr, size_t len, int prot); } // namespace Kyty::Libs::LibKernel::Memory diff --git a/source/emulator/src/Graphics/Graphics.cpp b/source/emulator/src/Graphics/Graphics.cpp index 19d6c88..34e7e82 100644 --- a/source/emulator/src/Graphics/Graphics.cpp +++ b/source/emulator/src/Graphics/Graphics.cpp @@ -20,14 +20,13 @@ #include "Emulator/Libs/Libs.h" #include "Emulator/Loader/VirtualMemory.h" +#include #include #ifdef KYTY_EMU_ENABLED namespace Kyty::Libs::Graphics { -LIB_NAME("GraphicsDriver", "GraphicsDriver"); - KYTY_SUBSYSTEM_INIT(Graphics) { auto width = Config::GetScreenWidth(); @@ -47,6 +46,33 @@ KYTY_SUBSYSTEM_UNEXPECTED_SHUTDOWN(Graphics) {} KYTY_SUBSYSTEM_DESTROY(Graphics) {} +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(); + } +} + +namespace Gen4 { + +LIB_NAME("GraphicsDriver", "GraphicsDriver"); + int KYTY_SYSV_ABI GraphicsSetVsShader(uint32_t* cmd, uint64_t size, const HW::VsStageRegisters* vs_regs, uint32_t shader_modifier) { PRINT_NAME(); @@ -312,10 +338,10 @@ int KYTY_SYSV_ABI GraphicsDrawIndexAuto(uint32_t* cmd, uint64_t size, uint32_t i 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); + printf("\t cmd_buffer = %016" PRIx64 "\n", reinterpret_cast(cmd)); + printf("\t size = %" PRIu64 "\n", size); + printf("\t index_count = %" PRIu32 "\n", index_count); + printf("\t flags = %08" PRIx32 "\n", flags); cmd[0] = KYTY_PM4(size, Pm4::IT_NOP, Pm4::R_DRAW_INDEX_AUTO); cmd[1] = index_count; @@ -330,10 +356,10 @@ int KYTY_SYSV_ABI GraphicsInsertWaitFlipDone(uint32_t* cmd, uint64_t size, uint3 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); + printf("\t cmd_buffer = %016" PRIx64 "\n", reinterpret_cast(cmd)); + printf("\t size = %" PRIu64 "\n", size); + printf("\t video_out_handle = %" PRIu32 "\n", video_out_handle); + printf("\t display_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; @@ -435,29 +461,6 @@ uint32_t KYTY_SYSV_ABI GraphicsDispatchInitDefaultHardwareState(uint32_t* cmd, u 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) { @@ -746,6 +749,810 @@ int KYTY_SYSV_ABI GraphicsUnregisterResource(uint32_t resource_handle) return OK; } +} // namespace Gen4 + +namespace Gen5 { + +LIB_NAME("Graphics5", "Graphics5"); + +struct ShaderRegister +{ + uint32_t offset; + uint32_t value; +}; + +struct RegisterDefaultInfo +{ + uint32_t type; + ShaderRegister reg[16]; +}; + +struct RegisterDefaults +{ + ShaderRegister** tbl0 = nullptr; + ShaderRegister** tbl1 = nullptr; + ShaderRegister** tbl2 = nullptr; + ShaderRegister** tbl3 = nullptr; + uint64_t unknown[2] = {}; + uint32_t* types = nullptr; + uint32_t count = 0; +}; + +struct ShaderSharp +{ + uint16_t offset_dw : 15; + uint16_t size : 1; +}; + +struct ShaderUserData +{ + uint16_t* direct_resource_offset; + ShaderSharp* sharp_resource_offset[4]; + uint16_t eud_size_dw; + uint16_t srt_size_dw; + uint16_t direct_resource_count; + uint16_t sharp_resource_count[4]; +}; + +struct ShaderRegisterRange +{ + uint16_t start; + uint16_t end; +}; + +struct ShaderDrawModifier +{ + uint32_t enbl_start_vertex_offset : 1; + uint32_t enbl_start_index_offset : 1; + uint32_t enbl_start_instance_offset : 1; + uint32_t enbl_draw_index : 1; + uint32_t enbl_user_vgprs : 1; + uint32_t render_target_slice_offset : 3; + uint32_t fuse_draws : 1; + uint32_t compiler_flags : 23; + uint32_t is_default : 1; + uint32_t reserved : 31; +}; + +struct ShaderSpecialRegs +{ + ShaderRegister ge_cntl; + ShaderRegister vgt_shader_stages_en; + uint32_t dispatch_modifier; + ShaderRegisterRange user_data_range; + ShaderDrawModifier draw_modifier; + ShaderRegister vgt_gs_out_prim_type; + ShaderRegister ge_user_vgpr_en; +}; + +struct ShaderSemantic +{ + uint32_t semantic : 8; + uint32_t hardware_mapping : 8; + uint32_t size_in_elements : 4; + uint32_t is_f16 : 2; + uint32_t is_flat_shaded : 1; + uint32_t is_linear : 1; + uint32_t is_custom : 1; + uint32_t static_vb_index : 1; + uint32_t static_attribute : 1; + uint32_t reserved : 1; + uint32_t default_value : 2; + uint32_t default_value_hi : 2; +}; + +struct Shader +{ + uint32_t file_header; + uint32_t version; + ShaderUserData* user_data; + const volatile void* code; + ShaderRegister* cx_registers; + ShaderRegister* sh_registers; + ShaderSpecialRegs* specials; + ShaderSemantic* input_semantics; + ShaderSemantic* output_semantics; + uint32_t header_size; + uint32_t shader_size; + uint32_t embedded_constant_buffer_size_dqw; + uint32_t target; + uint32_t num_input_semantics; + uint16_t scratch_size_dw_per_thread; + uint16_t num_output_semantics; + uint16_t special_sizes_bytes; + uint8_t type; + uint8_t num_cx_registers; + uint8_t num_sh_registers; +}; + +struct CommandBuffer +{ + using Callback = KYTY_SYSV_ABI bool (*)(CommandBuffer*, uint32_t, void*); + + uint32_t* bottom; + uint32_t* top; + uint32_t* cursor_up; + uint32_t* cursor_down; + Callback callback; + void* user_data; + uint32_t reserved_dw; + + void DbgDump() const + { + printf("\t bottom = 0x%016" PRIx64 "\n", reinterpret_cast(bottom)); + printf("\t top = 0x%016" PRIx64 "\n", reinterpret_cast(top)); + printf("\t cursor_up = 0x%016" PRIx64 "\n", reinterpret_cast(cursor_up)); + printf("\t cursor_down = 0x%016" PRIx64 "\n", reinterpret_cast(cursor_down)); + printf("\t callback = 0x%016" PRIx64 "\n", reinterpret_cast(callback)); + printf("\t user_data = 0x%016" PRIx64 "\n", reinterpret_cast(user_data)); + printf("\t reserved_dw = %" PRIu32 "\n", reserved_dw); + } + + [[nodiscard]] KYTY_SYSV_ABI uint32_t GetAvailableSizeDW() const + { + auto available = static_cast(cursor_down - cursor_up); + return std::max(available, reserved_dw) - reserved_dw; + } + + KYTY_SYSV_ABI bool ReserveDW(uint32_t num_dw) + { + uint32_t remaining = GetAvailableSizeDW(); + if (num_dw > remaining) + { + bool result = callback(this, num_dw + reserved_dw, user_data); + if (!result) + { + return false; + } + EXIT_NOT_IMPLEMENTED(!(GetAvailableSizeDW() >= num_dw)); + } + return true; + } + + KYTY_SYSV_ABI uint32_t* AllocateDW(uint32_t size_dw) + { + if (size_dw == 0 || !ReserveDW(size_dw)) + { + return nullptr; + } + auto* ret_ptr = cursor_up; + cursor_up += size_dw; + return ret_ptr; + } +}; + +static RegisterDefaultInfo g_reg_info0[] = { + /* 0 */ {0x5f5a3e7b, {{Pm4::VGT_GS_OUT_PRIM_TYPE, 0x00000002}}}, + /* 1 */ {0x105971c2, {{Pm4::GE_CNTL, 0}}}, + /* 2 */ {0x40d49ad1, {{Pm4::GE_USER_VGPR_EN, 0}}}, + /* 3 */ {0x9ebfab10, {{Pm4::PRIMITIVE_TYPE, 0}}}, + /* 4 */ {0x48531062, {{Pm4::SPI_PS_INPUT_CNTL_0, 0}}}, +}; + +static RegisterDefaultInfo g_reg_info1[] = { + /* 0 - DepthRenderTarget */ {0x67096014, + {{Pm4::DB_Z_INFO, 0}, + {Pm4::DB_STENCIL_INFO, 0}, + {Pm4::DB_Z_READ_BASE, 0}, + {Pm4::DB_STENCIL_READ_BASE, 0}, + {Pm4::DB_Z_WRITE_BASE, 0}, + {Pm4::DB_STENCIL_WRITE_BASE, 0}, + {Pm4::DB_Z_READ_BASE_HI, 0}, + {Pm4::DB_STENCIL_READ_BASE_HI, 0}, + {Pm4::DB_Z_WRITE_BASE_HI, 0}, + {Pm4::DB_STENCIL_WRITE_BASE_HI, 0}, + {Pm4::DB_HTILE_DATA_BASE_HI, 0}, + {Pm4::DB_DEPTH_VIEW, 0}, + {Pm4::DB_HTILE_DATA_BASE, 0}, + {Pm4::DB_DEPTH_SIZE_XY, 0}, + {Pm4::DB_DEPTH_CLEAR, 0}, + {Pm4::DB_STENCIL_CLEAR, 0}}}, + /* 1 - RenderTarget */ {0x38e92c91, + {{Pm4::CB_COLOR0_BASE, 0}, + {Pm4::CB_COLOR0_VIEW, 0}, + {Pm4::CB_COLOR0_INFO, 0}, + {Pm4::CB_COLOR0_ATTRIB, 0}, + {Pm4::CB_COLOR0_DCC_CONTROL, 0}, + {Pm4::CB_COLOR0_CMASK, 0}, + {Pm4::CB_COLOR0_FMASK, 0}, + {Pm4::CB_COLOR0_CLEAR_WORD0, 0}, + {Pm4::CB_COLOR0_CLEAR_WORD1, 0}, + {Pm4::CB_COLOR0_DCC_BASE, 0}, + {Pm4::CB_COLOR0_BASE_EXT, 0}, + {Pm4::CB_COLOR0_CMASK_BASE_EXT, 0}, + {Pm4::CB_COLOR0_FMASK_BASE_EXT, 0}, + {Pm4::CB_COLOR0_DCC_BASE_EXT, 0}, + {Pm4::CB_COLOR0_ATTRIB2, 0}, + {Pm4::CB_COLOR0_ATTRIB3, 0}}}}; + +#define KYTY_ID(id, tbl) ((id)*4 + (tbl)) +#define KYTY_INDEX0(id) g_reg_info0[id].type, KYTY_ID(id, 0), 0 +#define KYTY_INDEX1(id) g_reg_info1[id].type, KYTY_ID(id, 1), 0 +#define KYTY_REG0(id) &g_reg_info0[id].reg[0] +#define KYTY_REG1(id) &g_reg_info1[id].reg[0] + +static ShaderRegister* g_tbl0[] = {KYTY_REG0(0), KYTY_REG0(1), KYTY_REG0(2), KYTY_REG0(3), KYTY_REG0(4)}; +static ShaderRegister* g_tbl1[] = {KYTY_REG1(0), KYTY_REG1(1)}; +static uint32_t g_tbl_index[] = {KYTY_INDEX0(0), KYTY_INDEX0(1), KYTY_INDEX0(2), KYTY_INDEX0(3), + KYTY_INDEX0(4), KYTY_INDEX1(0), KYTY_INDEX1(1)}; + +static RegisterDefaults g_reg_defaults = { // @suppress("Invalid arguments") + g_tbl0, g_tbl1, nullptr, nullptr, {0, 0}, g_tbl_index, sizeof(g_tbl_index) / 12}; + +int KYTY_SYSV_ABI GraphicsInit(uint32_t* state, uint32_t ver) +{ + PRINT_NAME(); + + printf("\t state = 0x%016" PRIx64 "\n", reinterpret_cast(state)); + printf("\t ver = %u\n", ver); + + EXIT_NOT_IMPLEMENTED(state == nullptr); + EXIT_NOT_IMPLEMENTED(ver != 8); + + return OK; +} + +void* KYTY_SYSV_ABI GraphicsGetRegisterDefaults2(uint32_t ver) +{ + PRINT_NAME(); + + EXIT_NOT_IMPLEMENTED(ver != 8); + EXIT_NOT_IMPLEMENTED(offsetof(RegisterDefaults, count) != 0x38); + + // g_reg_defaults.count = 0; + + return &g_reg_defaults; +} + +void* KYTY_SYSV_ABI GraphicsGetRegisterDefaults2Internal(uint32_t ver) +{ + PRINT_NAME(); + + EXIT_NOT_IMPLEMENTED(ver != 8); + EXIT_NOT_IMPLEMENTED(offsetof(RegisterDefaults, count) != 0x38); + + g_reg_defaults.count = 0; + + return &g_reg_defaults; +} + +static void dbg_dump_shader(const Shader* h) +{ + printf("\t file_header = 0x%08" PRIx32 "\n", h->file_header); + printf("\t version = 0x%08" PRIx32 "\n", h->version); + printf("\t user_data = 0x%016" PRIx64 "\n", reinterpret_cast(h->user_data)); + if (h->user_data != nullptr) + { + printf("\t\t direct_resource_count = 0x%04" PRIx16 "\n", h->user_data->direct_resource_count); + printf("\t\t direct_resource_offset = 0x%016" PRIx64 "\n", reinterpret_cast(h->user_data->direct_resource_offset)); + for (int i = 0; i < static_cast(h->user_data->direct_resource_count); i++) + { + printf("\t\t\t offset[%02d] = %04" PRIx16 "\n", i, h->user_data->direct_resource_offset[i]); + } + for (int imm = 0; imm < 4; imm++) + { + printf("\t\t sharp_resource_count [%d] = 0x%04" PRIx16 "\n", imm, h->user_data->sharp_resource_count[imm]); + printf("\t\t sharp_resource_offset [%d] = 0x%016" PRIx64 "\n", imm, + reinterpret_cast(h->user_data->sharp_resource_offset[imm])); + for (int i = 0; i < static_cast(h->user_data->sharp_resource_count[imm]); i++) + { + printf("\t\t\t offset_dw[%d] = %04" PRIx16 ", size = %" PRIu16 "\n", i, + h->user_data->sharp_resource_offset[imm][i].offset_dw, h->user_data->sharp_resource_offset[imm][i].size); + } + } + printf("\t\t eud_size_dw = 0x%04" PRIx16 "\n", h->user_data->eud_size_dw); + printf("\t\t srt_size_dw = 0x%04" PRIx16 "\n", h->user_data->srt_size_dw); + } + printf("\t code = 0x%016" PRIx64 "\n", reinterpret_cast(h->code)); + printf("\t num_cx_registers = 0x%02" PRIx8 "\n", h->num_cx_registers); + printf("\t cx_registers = 0x%016" PRIx64 "\n", reinterpret_cast(h->cx_registers)); + for (int i = 0; i < static_cast(h->num_cx_registers); i++) + { + printf("\t\t cx[%d]: offset = %08" PRIx32 ", value = %08" PRIx32 "\n", i, h->cx_registers[i].offset, h->cx_registers[i].value); + } + printf("\t num_sh_registers = 0x%02" PRIx8 "\n", h->num_sh_registers); + printf("\t sh_registers = 0x%016" PRIx64 "\n", reinterpret_cast(h->sh_registers)); + for (int i = 0; i < static_cast(h->num_sh_registers); i++) + { + printf("\t\t sh[%d]: offset = %08" PRIx32 ", value = %08" PRIx32 "\n", i, h->sh_registers[i].offset, h->sh_registers[i].value); + } + printf("\t specials = 0x%016" PRIx64 "\n", reinterpret_cast(h->specials)); + printf("\t\t ge_cntl: offset = %08" PRIx32 ", value = %08" PRIx32 "\n", h->specials->ge_cntl.offset, + h->specials->ge_cntl.value); + printf("\t\t vgt_shader_stages_en: offset = %08" PRIx32 ", value = %08" PRIx32 "\n", h->specials->vgt_shader_stages_en.offset, + h->specials->vgt_shader_stages_en.value); + printf("\t\t vgt_gs_out_prim_type: offset = %08" PRIx32 ", value = %08" PRIx32 "\n", h->specials->vgt_gs_out_prim_type.offset, + h->specials->vgt_gs_out_prim_type.value); + printf("\t\t ge_user_vgpr_en: offset = %08" PRIx32 ", value = %08" PRIx32 "\n", h->specials->ge_user_vgpr_en.offset, + h->specials->ge_user_vgpr_en.value); + printf("\t\t dispatch_modifier = %08" PRIx32 "\n", h->specials->dispatch_modifier); + printf("\t\t user_data_range: start = %08" PRIx32 ", end = %08" PRIx32 "\n", h->specials->user_data_range.start, + h->specials->user_data_range.end); + printf("\t\t draw_modifier: enbl_start_vertex_offset = %08" PRIx32 "\n", h->specials->draw_modifier.enbl_start_vertex_offset); + printf("\t\t draw_modifier: enbl_start_index_offset = %08" PRIx32 "\n", h->specials->draw_modifier.enbl_start_index_offset); + printf("\t\t draw_modifier: enbl_start_instance_offset = %08" PRIx32 "\n", h->specials->draw_modifier.enbl_start_instance_offset); + printf("\t\t draw_modifier: enbl_draw_index = %08" PRIx32 "\n", h->specials->draw_modifier.enbl_draw_index); + printf("\t\t draw_modifier: enbl_user_vgprs = %08" PRIx32 "\n", h->specials->draw_modifier.enbl_user_vgprs); + printf("\t\t draw_modifier: render_target_slice_offset = %08" PRIx32 "\n", h->specials->draw_modifier.render_target_slice_offset); + printf("\t\t draw_modifier: fuse_draws = %08" PRIx32 "\n", h->specials->draw_modifier.fuse_draws); + printf("\t\t draw_modifier: compiler_flags = %08" PRIx32 "\n", h->specials->draw_modifier.compiler_flags); + printf("\t\t draw_modifier: is_default = %08" PRIx32 "\n", h->specials->draw_modifier.is_default); + printf("\t\t draw_modifier: reserved = %08" PRIx32 "\n", h->specials->draw_modifier.reserved); + printf("\t num_input_semantics = 0x%08" PRIx32 "\n", h->num_input_semantics); + printf("\t input_semantics = 0x%016" PRIx64 "\n", reinterpret_cast(h->input_semantics)); + for (int i = 0; i < static_cast(h->num_input_semantics); i++) + { + printf("\t\t input_semantics[%d]: semantic = %08" PRIx32 "\n", i, h->input_semantics[i].semantic); + printf("\t\t input_semantics[%d]: hardware_mapping = %08" PRIx32 "\n", i, h->input_semantics[i].hardware_mapping); + printf("\t\t input_semantics[%d]: size_in_elements = %08" PRIx32 "\n", i, h->input_semantics[i].size_in_elements); + printf("\t\t input_semantics[%d]: is_f16 = %08" PRIx32 "\n", i, h->input_semantics[i].is_f16); + printf("\t\t input_semantics[%d]: is_flat_shaded = %08" PRIx32 "\n", i, h->input_semantics[i].is_flat_shaded); + printf("\t\t input_semantics[%d]: is_linear = %08" PRIx32 "\n", i, h->input_semantics[i].is_linear); + printf("\t\t input_semantics[%d]: is_custom = %08" PRIx32 "\n", i, h->input_semantics[i].is_custom); + printf("\t\t input_semantics[%d]: static_vb_index = %08" PRIx32 "\n", i, h->input_semantics[i].static_vb_index); + printf("\t\t input_semantics[%d]: static_attribute = %08" PRIx32 "\n", i, h->input_semantics[i].static_attribute); + printf("\t\t input_semantics[%d]: reserved = %08" PRIx32 "\n", i, h->input_semantics[i].reserved); + printf("\t\t input_semantics[%d]: default_value = %08" PRIx32 "\n", i, h->input_semantics[i].default_value); + printf("\t\t input_semantics[%d]: default_value_hi = %08" PRIx32 "\n", i, h->input_semantics[i].default_value_hi); + } + printf("\t num_output_semantics = 0x%04" PRIx16 "\n", h->num_output_semantics); + printf("\t output_semantics = 0x%016" PRIx64 "\n", reinterpret_cast(h->output_semantics)); + for (int i = 0; i < static_cast(h->num_output_semantics); i++) + { + printf("\t\t output_semantics[%d]: semantic = %08" PRIx32 "\n", i, h->output_semantics[i].semantic); + printf("\t\t output_semantics[%d]: hardware_mapping = %08" PRIx32 "\n", i, h->output_semantics[i].hardware_mapping); + printf("\t\t output_semantics[%d]: size_in_elements = %08" PRIx32 "\n", i, h->output_semantics[i].size_in_elements); + printf("\t\t output_semantics[%d]: is_f16 = %08" PRIx32 "\n", i, h->output_semantics[i].is_f16); + printf("\t\t output_semantics[%d]: is_flat_shaded = %08" PRIx32 "\n", i, h->output_semantics[i].is_flat_shaded); + printf("\t\t output_semantics[%d]: is_linear = %08" PRIx32 "\n", i, h->output_semantics[i].is_linear); + printf("\t\t output_semantics[%d]: is_custom = %08" PRIx32 "\n", i, h->output_semantics[i].is_custom); + printf("\t\t output_semantics[%d]: static_vb_index = %08" PRIx32 "\n", i, h->output_semantics[i].static_vb_index); + printf("\t\t output_semantics[%d]: static_attribute = %08" PRIx32 "\n", i, h->output_semantics[i].static_attribute); + printf("\t\t output_semantics[%d]: reserved = %08" PRIx32 "\n", i, h->output_semantics[i].reserved); + printf("\t\t output_semantics[%d]: default_value = %08" PRIx32 "\n", i, h->output_semantics[i].default_value); + printf("\t\t output_semantics[%d]: default_value_hi = %08" PRIx32 "\n", i, h->output_semantics[i].default_value_hi); + } + printf("\t header_size = 0x%08" PRIx32 "\n", h->header_size); + printf("\t shader_size = 0x%08" PRIx32 "\n", h->shader_size); + printf("\t embedded_constant_buffer_size_dqw = 0x%08" PRIx32 "\n", h->embedded_constant_buffer_size_dqw); + printf("\t target = 0x%08" PRIx32 "\n", h->target); + printf("\t scratch_size_dw_per_thread = 0x%04" PRIx16 "\n", h->scratch_size_dw_per_thread); + printf("\t special_sizes_bytes = 0x%04" PRIx16 "\n", h->special_sizes_bytes); + printf("\t type = 0x%02" PRIx8 "\n", h->type); +} + +int KYTY_SYSV_ABI GraphicsCreateShader(Shader** dst, void* header, const volatile void* code) +{ + PRINT_NAME(); + + EXIT_NOT_IMPLEMENTED(dst == nullptr); + EXIT_NOT_IMPLEMENTED(header == nullptr); + EXIT_NOT_IMPLEMENTED(code == nullptr); + + printf("\t header = 0x%016" PRIx64 "\n", reinterpret_cast(header)); + printf("\t code = 0x%016" PRIx64 "\n", reinterpret_cast(code)); + + auto* h = static_cast(header); + + auto update_addr = [](auto& m) + { + if (m != nullptr) + { + m = reinterpret_cast::type>(reinterpret_cast(m) + + reinterpret_cast(&m)); + } + }; + + update_addr(h->cx_registers); + update_addr(h->sh_registers); + update_addr(h->user_data); + update_addr(h->specials); + update_addr(h->input_semantics); + update_addr(h->output_semantics); + update_addr(h->user_data->direct_resource_offset); + update_addr(h->user_data->sharp_resource_offset[0]); + update_addr(h->user_data->sharp_resource_offset[1]); + update_addr(h->user_data->sharp_resource_offset[2]); + update_addr(h->user_data->sharp_resource_offset[3]); + + h->code = code; + + dbg_dump_shader(h); + + EXIT_NOT_IMPLEMENTED(h->file_header != 0x34333231); + EXIT_NOT_IMPLEMENTED(h->version != 0x00000018); + + *dst = h; + + return OK; +} + +uint32_t* KYTY_SYSV_ABI GraphicsDcbResetQueue(CommandBuffer* buf, uint32_t op, uint32_t state) +{ + PRINT_NAME(); + + printf("\t op = 0x%08" PRIx32 "\n", op); + printf("\t state = 0x%08" PRIx32 "\n", state); + + EXIT_NOT_IMPLEMENTED(buf == nullptr); + EXIT_NOT_IMPLEMENTED(op != 0x3ff); + EXIT_NOT_IMPLEMENTED(state != 0); + + buf->DbgDump(); + + auto* cmd = buf->AllocateDW(2); + + EXIT_NOT_IMPLEMENTED(cmd == nullptr); + + cmd[0] = KYTY_PM4(2, Pm4::IT_NOP, Pm4::R_DRAW_RESET); + cmd[1] = 0; + + return cmd; +} + +uint32_t* KYTY_SYSV_ABI GraphicsDcbWaitUntilSafeForRendering(CommandBuffer* buf, uint32_t video_out_handle, uint32_t display_buffer_index) +{ + PRINT_NAME(); + + printf("\t video_out_handle = %" PRIu32 "\n", video_out_handle); + printf("\t display_buffer_index = %" PRIu32 "\n", display_buffer_index); + + EXIT_NOT_IMPLEMENTED(buf == nullptr); + + buf->DbgDump(); + + auto* cmd = buf->AllocateDW(3); + + EXIT_NOT_IMPLEMENTED(cmd == nullptr); + + cmd[0] = KYTY_PM4(3, Pm4::IT_NOP, Pm4::R_WAIT_FLIP_DONE); + cmd[1] = video_out_handle; + cmd[2] = display_buffer_index; + + return cmd; +} + +uint32_t* KYTY_SYSV_ABI GraphicsDcbSetCxRegistersIndirect(CommandBuffer* buf, const volatile ShaderRegister* regs, uint32_t num_regs) +{ + PRINT_NAME(); + + printf("\t regs = 0x%016" PRIx64 "\n", reinterpret_cast(regs)); + printf("\t num_regs = %" PRIu32 "\n", num_regs); + + EXIT_NOT_IMPLEMENTED(buf == nullptr); + + buf->DbgDump(); + + auto* cmd = buf->AllocateDW(4); + + EXIT_NOT_IMPLEMENTED(cmd == nullptr); + + auto vaddr = reinterpret_cast(regs); + + cmd[0] = KYTY_PM4(4, Pm4::IT_NOP, Pm4::R_CX_REGS); + cmd[1] = num_regs; + cmd[2] = vaddr & 0xffffffffu; + cmd[3] = (vaddr >> 32u) & 0xffffffffu; + + return cmd; +} + +uint32_t* KYTY_SYSV_ABI GraphicsDcbSetShRegistersIndirect(CommandBuffer* buf, const volatile ShaderRegister* regs, uint32_t num_regs) +{ + PRINT_NAME(); + + printf("\t regs = 0x%016" PRIx64 "\n", reinterpret_cast(regs)); + printf("\t num_regs = %" PRIu32 "\n", num_regs); + + EXIT_NOT_IMPLEMENTED(buf == nullptr); + + buf->DbgDump(); + + auto* cmd = buf->AllocateDW(4); + + EXIT_NOT_IMPLEMENTED(cmd == nullptr); + + auto vaddr = reinterpret_cast(regs); + + cmd[0] = KYTY_PM4(4, Pm4::IT_NOP, Pm4::R_SH_REGS); + cmd[1] = num_regs; + cmd[2] = vaddr & 0xffffffffu; + cmd[3] = (vaddr >> 32u) & 0xffffffffu; + + return cmd; +} + +uint32_t* KYTY_SYSV_ABI GraphicsDcbSetUcRegistersIndirect(CommandBuffer* buf, const volatile ShaderRegister* regs, uint32_t num_regs) +{ + PRINT_NAME(); + + printf("\t regs = 0x%016" PRIx64 "\n", reinterpret_cast(regs)); + printf("\t num_regs = %" PRIu32 "\n", num_regs); + + EXIT_NOT_IMPLEMENTED(buf == nullptr); + + buf->DbgDump(); + + auto* cmd = buf->AllocateDW(4); + + EXIT_NOT_IMPLEMENTED(cmd == nullptr); + + auto vaddr = reinterpret_cast(regs); + + cmd[0] = KYTY_PM4(4, Pm4::IT_NOP, Pm4::R_UC_REGS); + cmd[1] = num_regs; + cmd[2] = vaddr & 0xffffffffu; + cmd[3] = (vaddr >> 32u) & 0xffffffffu; + + return cmd; +} + +uint32_t* KYTY_SYSV_ABI GraphicsDcbSetIndexSize(CommandBuffer* buf, uint8_t index_size, uint8_t cache_policy) +{ + PRINT_NAME(); + + printf("\t index_size = 0x%" PRIx8 "\n", index_size); + printf("\t cache_policy = 0x%" PRIx8 "\n", cache_policy); + + EXIT_NOT_IMPLEMENTED(buf == nullptr); + EXIT_NOT_IMPLEMENTED(cache_policy != 0); + + buf->DbgDump(); + + auto* cmd = buf->AllocateDW(2); + + EXIT_NOT_IMPLEMENTED(cmd == nullptr); + + cmd[0] = KYTY_PM4(2, Pm4::IT_INDEX_TYPE, 0u); + cmd[1] = index_size; + + return cmd; +} + +uint32_t* KYTY_SYSV_ABI GraphicsDcbDrawIndexAuto(CommandBuffer* buf, uint32_t index_count, uint64_t modifier) +{ + PRINT_NAME(); + + printf("\t index_count = 0x%" PRIx32 "\n", index_count); + printf("\t modifier = 0x%016" PRIx64 "\n", modifier); + + EXIT_NOT_IMPLEMENTED(buf == nullptr); + EXIT_NOT_IMPLEMENTED(modifier != 0x40000000); + + // auto *m = reinterpret_cast(&modifier); + + buf->DbgDump(); + + auto* cmd = buf->AllocateDW(7); + + EXIT_NOT_IMPLEMENTED(cmd == nullptr); + + cmd[0] = KYTY_PM4(7, Pm4::IT_NOP, Pm4::R_DRAW_INDEX_AUTO); + cmd[1] = index_count; + cmd[2] = 0; + + return cmd; +} + +int KYTY_SYSV_ABI GraphicsSetCxRegIndirectPatchSetAddress(uint32_t* cmd, const volatile ShaderRegister* regs) +{ + PRINT_NAME(); + + printf("\t cmd = 0x%016" PRIx64 "\n", reinterpret_cast(cmd)); + printf("\t regs = 0x%016" PRIx64 "\n", reinterpret_cast(regs)); + + EXIT_NOT_IMPLEMENTED(cmd == nullptr); + EXIT_NOT_IMPLEMENTED(regs == nullptr); + + auto vaddr = reinterpret_cast(regs); + + cmd[2] = vaddr & 0xffffffffu; + cmd[3] = (vaddr >> 32u) & 0xffffffffu; + + return OK; +} + +int KYTY_SYSV_ABI GraphicsSetShRegIndirectPatchSetAddress(uint32_t* cmd, const volatile ShaderRegister* regs) +{ + PRINT_NAME(); + + printf("\t cmd = 0x%016" PRIx64 "\n", reinterpret_cast(cmd)); + printf("\t regs = 0x%016" PRIx64 "\n", reinterpret_cast(regs)); + + EXIT_NOT_IMPLEMENTED(cmd == nullptr); + EXIT_NOT_IMPLEMENTED(regs == nullptr); + + auto vaddr = reinterpret_cast(regs); + + cmd[2] = vaddr & 0xffffffffu; + cmd[3] = (vaddr >> 32u) & 0xffffffffu; + + return OK; +} + +int KYTY_SYSV_ABI GraphicsSetUcRegIndirectPatchSetAddress(uint32_t* cmd, const volatile ShaderRegister* regs) +{ + PRINT_NAME(); + + printf("\t cmd = 0x%016" PRIx64 "\n", reinterpret_cast(cmd)); + printf("\t regs = 0x%016" PRIx64 "\n", reinterpret_cast(regs)); + + EXIT_NOT_IMPLEMENTED(cmd == nullptr); + EXIT_NOT_IMPLEMENTED(regs == nullptr); + + auto vaddr = reinterpret_cast(regs); + + cmd[2] = vaddr & 0xffffffffu; + cmd[3] = (vaddr >> 32u) & 0xffffffffu; + + return OK; +} + +int KYTY_SYSV_ABI GraphicsSetCxRegIndirectPatchAddRegisters(uint32_t* cmd, uint32_t num_regs) +{ + PRINT_NAME(); + + printf("\t cmd = 0x%016" PRIx64 "\n", reinterpret_cast(cmd)); + printf("\t num_regs = %" PRIu32 "\n", num_regs); + + EXIT_NOT_IMPLEMENTED(cmd == nullptr); + + cmd[1] += num_regs; + + return OK; +} + +int KYTY_SYSV_ABI GraphicsSetShRegIndirectPatchAddRegisters(uint32_t* cmd, uint32_t num_regs) +{ + PRINT_NAME(); + + printf("\t cmd = 0x%016" PRIx64 "\n", reinterpret_cast(cmd)); + printf("\t num_regs = %" PRIu32 "\n", num_regs); + + EXIT_NOT_IMPLEMENTED(cmd == nullptr); + + cmd[1] += num_regs; + + return OK; +} + +int KYTY_SYSV_ABI GraphicsSetUcRegIndirectPatchAddRegisters(uint32_t* cmd, uint32_t num_regs) +{ + PRINT_NAME(); + + printf("\t cmd = 0x%016" PRIx64 "\n", reinterpret_cast(cmd)); + printf("\t num_regs = %" PRIu32 "\n", num_regs); + + EXIT_NOT_IMPLEMENTED(cmd == nullptr); + + cmd[1] += num_regs; + + return OK; +} + +int KYTY_SYSV_ABI GraphicsCreatePrimState(ShaderRegister* cx_regs, ShaderRegister* uc_regs, const Shader* hs, const Shader* gs, + uint32_t prim_type) +{ + PRINT_NAME(); + + printf("\t cx_regs = 0x%016" PRIx64 "\n", reinterpret_cast(cx_regs)); + printf("\t uc_regs = 0x%016" PRIx64 "\n", reinterpret_cast(uc_regs)); + printf("\t hs = 0x%016" PRIx64 "\n", reinterpret_cast(hs)); + printf("\t gs = 0x%016" PRIx64 "\n", reinterpret_cast(gs)); + printf("\t prim_type = %" PRIu32 "\n", prim_type); + + EXIT_NOT_IMPLEMENTED(hs != nullptr); + EXIT_NOT_IMPLEMENTED(gs == nullptr); + EXIT_NOT_IMPLEMENTED(cx_regs == nullptr); + EXIT_NOT_IMPLEMENTED(uc_regs == nullptr); + + EXIT_NOT_IMPLEMENTED(gs->type != 2); + EXIT_NOT_IMPLEMENTED(gs->specials->vgt_shader_stages_en.offset != Pm4::VGT_SHADER_STAGES_EN); + EXIT_NOT_IMPLEMENTED(gs->specials->vgt_gs_out_prim_type.offset != Pm4::VGT_GS_OUT_PRIM_TYPE); + EXIT_NOT_IMPLEMENTED(gs->specials->ge_cntl.offset != Pm4::GE_CNTL); + EXIT_NOT_IMPLEMENTED(gs->specials->ge_user_vgpr_en.offset != Pm4::GE_USER_VGPR_EN); + + cx_regs[0] = gs->specials->vgt_shader_stages_en; + cx_regs[1] = gs->specials->vgt_gs_out_prim_type; + + uc_regs[0] = gs->specials->ge_cntl; + uc_regs[1] = gs->specials->ge_user_vgpr_en; + uc_regs[2].offset = Pm4::PRIMITIVE_TYPE; + uc_regs[2].value = 0; + + return OK; +} + +int KYTY_SYSV_ABI GraphicsCreateInterpolantMapping(ShaderRegister* regs, const Shader* gs, const Shader* ps) +{ + PRINT_NAME(); + + printf("\t regs = 0x%016" PRIx64 "\n", reinterpret_cast(regs)); + printf("\t gs = 0x%016" PRIx64 "\n", reinterpret_cast(gs)); + printf("\t ps = 0x%016" PRIx64 "\n", reinterpret_cast(ps)); + + EXIT_NOT_IMPLEMENTED(gs == nullptr); + EXIT_NOT_IMPLEMENTED(gs == nullptr && ps == nullptr); + EXIT_NOT_IMPLEMENTED(regs == nullptr); + + EXIT_NOT_IMPLEMENTED(gs->type != 2); + EXIT_NOT_IMPLEMENTED(ps != nullptr && ps->type != 1); + + EXIT_NOT_IMPLEMENTED(sizeof(ShaderSemantic) != 4); + EXIT_NOT_IMPLEMENTED(ps != nullptr && gs->num_output_semantics != ps->num_input_semantics); + + auto* out32 = reinterpret_cast(gs->output_semantics); + auto* in32 = (ps != nullptr ? reinterpret_cast(ps->input_semantics) : nullptr); + + for (int i = 0; i < 32; i++) + { + regs[i].offset = Pm4::SPI_PS_INPUT_CNTL_0 + i; + regs[i].value = 0; + + if (i < static_cast(gs->num_output_semantics)) + { + EXIT_NOT_IMPLEMENTED(out32[i] != 0x0000000f); + EXIT_NOT_IMPLEMENTED(in32 != nullptr && out32[i] != in32[i]); + regs[i].value = i; + } + } + + return OK; +} + +uint32_t* KYTY_SYSV_ABI GraphicsCbSetShRegisterRangeDirect(CommandBuffer* buf, uint32_t offset, const uint32_t* values, uint32_t num_values) +{ + PRINT_NAME(); + + printf("\t buf = 0x%016" PRIx64 "\n", reinterpret_cast(buf)); + printf("\t offset = %" PRIx32 "\n", offset); + printf("\t values = 0x%016" PRIx64 "\n", reinterpret_cast(values)); + printf("\t num_values = %" PRIu32 "\n", num_values); + + EXIT_NOT_IMPLEMENTED(buf == nullptr); + EXIT_NOT_IMPLEMENTED(num_values == 0); + EXIT_NOT_IMPLEMENTED(offset == 0); + EXIT_NOT_IMPLEMENTED(offset > 0x3ffu); + + buf->DbgDump(); + + auto* cmd = buf->AllocateDW(num_values + 2); + + EXIT_NOT_IMPLEMENTED(cmd == nullptr); + + cmd[0] = KYTY_PM4(num_values + 2, Pm4::IT_SET_SH_REG, 0u); + cmd[1] = offset; + + if (values == nullptr) + { + memset(cmd + 2, 0, static_cast(num_values) * 4); + } else + { + memcpy(cmd + 2, values, static_cast(num_values) * 4); + } + + return cmd; +} + +int KYTY_SYSV_ABI GraphicsGetDataPacketPayloadAddress(uint32_t** addr, uint32_t* cmd, int type) +{ + PRINT_NAME(); + + printf("\t addr = 0x%016" PRIx64 "\n", reinterpret_cast(addr)); + printf("\t cmd = 0x%016" PRIx64 "\n", reinterpret_cast(cmd)); + printf("\t type = %d\n", type); + + EXIT_NOT_IMPLEMENTED(addr == nullptr); + EXIT_NOT_IMPLEMENTED(cmd == nullptr); + EXIT_NOT_IMPLEMENTED(type != 1); + + *addr = cmd + 2; + + return OK; +} + +} // namespace Gen5 + } // namespace Kyty::Libs::Graphics #endif // KYTY_EMU_ENABLED diff --git a/source/emulator/src/Graphics/GraphicsRun.cpp b/source/emulator/src/Graphics/GraphicsRun.cpp index 15c1f72..458b069 100644 --- a/source/emulator/src/Graphics/GraphicsRun.cpp +++ b/source/emulator/src/Graphics/GraphicsRun.cpp @@ -1408,14 +1408,6 @@ KYTY_HW_CTX_PARSER(hw_ctx_set_depth_render_target) z.stencil_info.tile_mode_index = KYTY_PM4_GET(buffer[1], DB_STENCIL_INFO, TILE_MODE_INDEX); z.stencil_info.tile_stencil_disable = KYTY_PM4_GET(buffer[1], DB_STENCIL_INFO, TILE_STENCIL_DISABLE); - // if (Config::IsNeo()) - // { - // EXIT_NOT_IMPLEMENTED((buffer[2] & 0xffu) != 0); - // EXIT_NOT_IMPLEMENTED((buffer[3] & 0xffu) != 0); - // EXIT_NOT_IMPLEMENTED((buffer[4] & 0xffu) != 0); - // EXIT_NOT_IMPLEMENTED((buffer[5] & 0xffu) != 0); - // } - z.z_read_base_addr = static_cast(buffer[2]) << 8u; z.stencil_read_base_addr = static_cast(buffer[3]) << 8u; z.z_write_base_addr = static_cast(buffer[4]) << 8u; @@ -2200,7 +2192,7 @@ KYTY_CP_OP_PARSER(cp_op_set_uconfig_reg) switch (cmd_offset & 0x1fffu) { - case 0x0242: + case Pm4::PRIMITIVE_TYPE: cp->GetUcfg()->SetPrimitiveType(buffer[1]); return 2; break; diff --git a/source/emulator/src/Graphics/Objects/VideoOutBuffer.cpp b/source/emulator/src/Graphics/Objects/VideoOutBuffer.cpp index 7b15f87..5849226 100644 --- a/source/emulator/src/Graphics/Objects/VideoOutBuffer.cpp +++ b/source/emulator/src/Graphics/Objects/VideoOutBuffer.cpp @@ -78,15 +78,24 @@ static void* create_func(GraphicContext* ctx, const uint64_t* params, const uint auto width = params[VideoOutBufferObject::PARAM_WIDTH]; auto height = params[VideoOutBufferObject::PARAM_HEIGHT]; - EXIT_NOT_IMPLEMENTED(pixel_format != 0x80000000); + // EXIT_NOT_IMPLEMENTED(pixel_format != 0x80000000); EXIT_NOT_IMPLEMENTED(width == 0); EXIT_NOT_IMPLEMENTED(height == 0); auto* vk_obj = new VideoOutVulkanImage; + VkFormat vk_format = VK_FORMAT_UNDEFINED; + + switch (pixel_format) + { + case static_cast(VideoOutBufferFormat::R8G8B8A8Srgb): vk_format = VK_FORMAT_R8G8B8A8_SRGB; break; + case static_cast(VideoOutBufferFormat::B8G8R8A8Srgb): vk_format = VK_FORMAT_B8G8R8A8_SRGB; break; + default: EXIT("unknown format: %" PRIu64 "\n", pixel_format); + } + vk_obj->extent.width = width; vk_obj->extent.height = height; - vk_obj->format = VK_FORMAT_B8G8R8A8_SRGB; + vk_obj->format = vk_format; vk_obj->image = nullptr; vk_obj->layout = VK_IMAGE_LAYOUT_UNDEFINED; diff --git a/source/emulator/src/Graphics/Pm4.cpp b/source/emulator/src/Graphics/Pm4.cpp index 36d83ec..9cb4ea0 100644 --- a/source/emulator/src/Graphics/Pm4.cpp +++ b/source/emulator/src/Graphics/Pm4.cpp @@ -42,6 +42,9 @@ static void init_names() g_r_names[R_PS_EMBEDDED] = "R_PS_EMBEDDED"; g_r_names[R_VS_UPDATE] = "R_VS_UPDATE"; g_r_names[R_PS_UPDATE] = "R_PS_UPDATE"; + g_r_names[R_CX_REGS] = "R_CX_REGS"; + g_r_names[R_SH_REGS] = "R_SH_REGS"; + g_r_names[R_UC_REGS] = "R_UC_REGS"; g_names[IT_NOP] = "IT_NOP"; g_names[IT_SET_BASE] = "IT_SET_BASE"; diff --git a/source/emulator/src/Graphics/ShaderSpirv.cpp b/source/emulator/src/Graphics/ShaderSpirv.cpp index 1815398..cd198a5 100644 --- a/source/emulator/src/Graphics/ShaderSpirv.cpp +++ b/source/emulator/src/Graphics/ShaderSpirv.cpp @@ -6153,6 +6153,8 @@ void Spirv::WriteAnnotations() { for (uint32_t i = 0; i < m_ps_input_info->input_num; i++) { + EXIT_NOT_IMPLEMENTED((m_ps_input_info->interpolator_settings[i] & ~static_cast(0x1f)) != 0); + vars.Add(String::FromPrintf("OpDecorate %%attr%d Location %d", i, m_ps_input_info->interpolator_settings[i])); } if (m_ps_input_info->ps_pos_xy) diff --git a/source/emulator/src/Graphics/VideoOut.cpp b/source/emulator/src/Graphics/VideoOut.cpp index 012966e..f8f2f34 100644 --- a/source/emulator/src/Graphics/VideoOut.cpp +++ b/source/emulator/src/Graphics/VideoOut.cpp @@ -50,17 +50,33 @@ struct VideoOutResolutionStatus struct VideoOutBufferAttribute { - uint32_t pixelFormat; - uint32_t tilingMode; - uint32_t aspectRatio; + uint32_t pixel_format; + uint32_t tiling_mode; + uint32_t aspect_ratio; uint32_t width; uint32_t height; - uint32_t pitchInPixel; + uint32_t pitch_in_pixel; uint32_t option; uint32_t reserved0; uint64_t reserved1; }; +struct VideoOutBufferAttribute2 +{ + uint32_t reserved0; + uint32_t tiling_mode; + uint32_t aspect_ratio; + uint32_t width; + uint32_t height; + uint32_t pitch_in_pixel; + uint64_t option; + uint64_t pixel_format; + uint64_t dcc_cb_register_clear_color; + uint32_t dcc_control; + uint32_t pad0; + uint64_t reserved1[3]; +}; + struct VideoOutFlipStatus { uint64_t count = 0; @@ -85,16 +101,32 @@ struct VideoOutVblankStatus uint8_t pad1[7] = {}; }; +struct VideoOutBuffers +{ + const void* data; + const void* metadata; + const void* reserved[2]; +}; + +union VideoOutBufferAttributeUnion +{ + VideoOutBufferAttribute gen4; + VideoOutBufferAttribute2 gen5; +}; + struct VideoOutBufferSet { - VideoOutBufferAttribute attr = {}; - int start_index = 0; - int num = 0; + VideoOutBufferAttributeUnion attr; + + bool gen5 = false; + int start_index = 0; + int num = 0; + int set_id = 0; }; struct VideoOutBufferInfo { - void* buffer = nullptr; + const void* buffer = nullptr; Graphics::VideoOutVulkanImage* buffer_vulkan = nullptr; uint64_t buffer_size = 0; uint64_t buffer_pitch = 0; @@ -114,8 +146,8 @@ struct VideoOutConfig VideoOutVblankStatus pre_vblank_status; VideoOutVblankStatus vblank_status; VideoOutBufferInfo buffers[16]; - VideoOutBufferSet buffers_sets[16]; - int buffers_sets_num = 0; + Vector buffers_sets; + int buffers_sets_seq = 0; }; class FlipQueue @@ -159,7 +191,7 @@ public: void Close(int handle); VideoOutConfig* Get(int handle); - VideoOutBufferImageInfo FindImage(void* buffer); + VideoOutBufferImageInfo FindImage(const void* buffer); void Init(uint32_t width, uint32_t height); @@ -189,21 +221,30 @@ private: static VideoOutContext* g_video_out_context = nullptr; -static void calc_buffer_size(const VideoOutBufferAttribute* attribute, uint64_t* out_size, uint64_t* out_align, uint64_t* out_pitch) +static void calc_buffer_size(const VideoOutBufferAttribute* attribute, const VideoOutBufferAttribute2* attribute2, uint64_t* out_size, + uint64_t* out_align, uint64_t* out_pitch) { EXIT_IF(out_size == nullptr); EXIT_IF(out_pitch == nullptr); + EXIT_IF((attribute == nullptr && attribute2 == nullptr) || (attribute != nullptr && attribute2 != nullptr)); - bool tile = attribute->tilingMode == 0; - bool neo = Config::IsNeo(); - uint32_t width = attribute->width; - uint32_t height = attribute->height; - uint32_t pitch = attribute->pitchInPixel; + bool tile = (attribute2 != nullptr ? (attribute2->tiling_mode == 0) : (attribute->tiling_mode == 0)); + bool neo = (attribute2 != nullptr ? true : Config::IsNeo()); + uint32_t width = (attribute2 != nullptr ? attribute2->width : attribute->width); + uint32_t height = (attribute2 != nullptr ? attribute2->height : attribute->height); + uint32_t pitch = (attribute2 != nullptr ? attribute2->width : attribute->pitch_in_pixel); - // EXIT_NOT_IMPLEMENTED(attribute->width != attribute->pitchInPixel); - EXIT_NOT_IMPLEMENTED(attribute->option != 0); - EXIT_NOT_IMPLEMENTED(attribute->aspectRatio != 0); - EXIT_NOT_IMPLEMENTED(attribute->pixelFormat != 0x80000000); + if (attribute2 != nullptr) + { + EXIT_NOT_IMPLEMENTED(attribute2->option != 0); + EXIT_NOT_IMPLEMENTED(attribute2->aspect_ratio != 0); + EXIT_NOT_IMPLEMENTED(attribute2->pixel_format != 0x8000000000000000ULL && attribute2->pixel_format != 0x8000000022000000ULL); + } else + { + EXIT_NOT_IMPLEMENTED(attribute->option != 0); + EXIT_NOT_IMPLEMENTED(attribute->aspect_ratio != 0); + EXIT_NOT_IMPLEMENTED(attribute->pixel_format != 0x80000000 && attribute->pixel_format != 0x80002200); + } Graphics::TileSizeAlign size32 {}; Graphics::TileGetVideoOutSize(width, height, pitch, tile, neo, &size32); @@ -305,17 +346,17 @@ void VideoOutContext::Close(int handle) m_video_out_ctx[handle].flip_rate = 0; - for (int i = 0; i < 16; i++) + for (auto& buffer: m_video_out_ctx[handle].buffers) { - m_video_out_ctx[handle].buffers[i].buffer = nullptr; - m_video_out_ctx[handle].buffers[i].buffer_vulkan = nullptr; - m_video_out_ctx[handle].buffers[i].buffer_size = 0; - m_video_out_ctx[handle].buffers[i].set_id = 0; - m_video_out_ctx[handle].buffers_sets[i].num = 0; - m_video_out_ctx[handle].buffers_sets[i].start_index = 0; + buffer.buffer = nullptr; + buffer.buffer_vulkan = nullptr; + buffer.buffer_size = 0; + buffer.set_id = 0; } - m_video_out_ctx[handle].buffers_sets_num = 0; + m_video_out_ctx[handle].buffers_sets.Clear(); + + m_video_out_ctx[handle].buffers_sets_seq = 0; } VideoOutConfig* VideoOutContext::Get(int handle) @@ -382,7 +423,7 @@ void VideoOutContext::VblankEnd() } } -VideoOutBufferImageInfo VideoOutContext::FindImage(void* buffer) +VideoOutBufferImageInfo VideoOutContext::FindImage(const void* buffer) { VideoOutBufferImageInfo ret; @@ -392,16 +433,16 @@ VideoOutBufferImageInfo VideoOutContext::FindImage(void* buffer) { if (ctx.opened) { - for (int i = 0; i < ctx.buffers_sets_num; i++) + for (const auto& set: ctx.buffers_sets) { - for (int j = ctx.buffers_sets[i].start_index; j < ctx.buffers_sets[i].num; j++) + for (int j = set.start_index; j < set.num; j++) { if (ctx.buffers[j].buffer == buffer) { ret.image = ctx.buffers[j].buffer_vulkan; ret.buffer_size = ctx.buffers[j].buffer_size; ret.buffer_pitch = ctx.buffers[j].buffer_pitch; - ret.index = j - ctx.buffers_sets[i].start_index; + ret.index = j - set.start_index; goto END; } } @@ -591,21 +632,50 @@ KYTY_SYSV_ABI void VideoOutSetBufferAttribute(VideoOutBufferAttribute* attribute EXIT_NOT_IMPLEMENTED(attribute == nullptr); - printf("\tpixel_format = %08" PRIx32 "\n", pixel_format); - printf("\ttiling_mode = %" PRIu32 "\n", tiling_mode); - printf("\taspect_ratio = %" PRIu32 "\n", aspect_ratio); - printf("\twidth = %" PRIu32 "\n", width); - printf("\theight = %" PRIu32 "\n", height); - printf("\tpitch_in_pixel = %" PRIu32 "\n", pitch_in_pixel); + printf("\t pixel_format = %08" PRIx32 "\n", pixel_format); + printf("\t tiling_mode = %" PRIu32 "\n", tiling_mode); + printf("\t aspect_ratio = %" PRIu32 "\n", aspect_ratio); + printf("\t width = %" PRIu32 "\n", width); + printf("\t height = %" PRIu32 "\n", height); + printf("\t pitch_in_pixel = %" PRIu32 "\n", pitch_in_pixel); memset(attribute, 0, sizeof(VideoOutBufferAttribute)); - attribute->pixelFormat = pixel_format; - attribute->tilingMode = tiling_mode; - attribute->aspectRatio = aspect_ratio; - attribute->width = width; - attribute->height = height; - attribute->pitchInPixel = pitch_in_pixel; + attribute->pixel_format = pixel_format; + attribute->tiling_mode = tiling_mode; + attribute->aspect_ratio = aspect_ratio; + attribute->width = width; + attribute->height = height; + attribute->pitch_in_pixel = pitch_in_pixel; +} + +KYTY_SYSV_ABI void VideoOutSetBufferAttribute2(VideoOutBufferAttribute2* attribute, uint64_t pixel_format, uint32_t tiling_mode, + uint32_t width, uint32_t height, uint64_t option, uint32_t dcc_control, + uint64_t dcc_cb_register_clear_color) +{ + PRINT_NAME(); + + EXIT_NOT_IMPLEMENTED(attribute == nullptr); + + printf("\t pixel_format = %016" PRIx64 "\n", pixel_format); + printf("\t tiling_mode = %" PRIu32 "\n", tiling_mode); + printf("\t width = %" PRIu32 "\n", width); + printf("\t height = %" PRIu32 "\n", height); + printf("\t option = %016" PRIx64 "\n", option); + printf("\t dcc_control = %08" PRIx32 "\n", dcc_control); + printf("\t dcc_cb_register_clear_color = %016" PRIx64 "\n", dcc_cb_register_clear_color); + + memset(attribute, 0, sizeof(VideoOutBufferAttribute2)); + + attribute->tiling_mode = tiling_mode; + attribute->aspect_ratio = 0; + attribute->width = width; + attribute->height = height; + attribute->pitch_in_pixel = 0; + attribute->option = option; + attribute->pixel_format = pixel_format; + attribute->dcc_cb_register_clear_color = dcc_cb_register_clear_color; + attribute->dcc_control = dcc_control; } KYTY_SYSV_ABI int VideoOutSetFlipRate(int handle, int rate) @@ -771,6 +841,92 @@ KYTY_SYSV_ABI int VideoOutAddVblankEvent(LibKernel::EventQueue::KernelEqueue eq, return result; } +static int register_buffers_internal(VideoOutConfig* ctx, int set_id, int start_index, const void* const* addresses, int buffer_num, + const VideoOutBufferAttribute* attribute, const VideoOutBufferAttribute2* attribute2) +{ + Graphics::WindowWaitForGraphicInitialized(); + Graphics::GraphicsRenderCreateContext(); + + uint64_t buffer_size = 0; + uint64_t buffer_align = 0; + uint64_t buffer_pitch = 0; + calc_buffer_size(attribute, attribute2, &buffer_size, &buffer_align, &buffer_pitch); + + EXIT_NOT_IMPLEMENTED(buffer_size == 0); + EXIT_NOT_IMPLEMENTED(buffer_pitch == 0); + + VideoOutBufferSet new_set {}; + + new_set.start_index = start_index; + new_set.num = buffer_num; + new_set.set_id = set_id; + if (attribute2 != nullptr) + { + new_set.attr.gen5 = *attribute2; + new_set.gen5 = true; + } else + { + new_set.attr.gen4 = *attribute; + new_set.gen5 = false; + } + + ctx->buffers_sets.Add(new_set); + + bool tile = (attribute2 != nullptr ? (attribute2->tiling_mode == 0) : (attribute->tiling_mode == 0)); + bool neo = (attribute2 != nullptr ? true : Config::IsNeo()); + uint32_t width = (attribute2 != nullptr ? attribute2->width : attribute->width); + uint32_t height = (attribute2 != nullptr ? attribute2->height : attribute->height); + + Graphics::VideoOutBufferFormat format = Graphics::VideoOutBufferFormat::Unknown; + + if (attribute2 != nullptr) + { + if (attribute2->pixel_format == 0x8000000000000000ULL) + { + format = Graphics::VideoOutBufferFormat::B8G8R8A8Srgb; + } else if (attribute2->pixel_format == 0x8000000022000000ULL) + { + format = Graphics::VideoOutBufferFormat::R8G8B8A8Srgb; + } + } else + { + if (attribute->pixel_format == 0x80000000) + { + format = Graphics::VideoOutBufferFormat::B8G8R8A8Srgb; + } else if (attribute->pixel_format == 0x80002200) + { + format = Graphics::VideoOutBufferFormat::R8G8B8A8Srgb; + } + } + + Graphics::VideoOutBufferObject vulkan_buffer_info(format, width, height, tile, neo, buffer_pitch); + + for (int i = 0; i < buffer_num; i++) + { + if (ctx->buffers[i + start_index].buffer != nullptr) + { + return VIDEO_OUT_ERROR_SLOT_OCCUPIED; + } + + EXIT_NOT_IMPLEMENTED((reinterpret_cast(addresses[i]) & (buffer_align - 1u)) != 0); + + ctx->buffers[i + start_index].set_id = set_id; + ctx->buffers[i + start_index].buffer = addresses[i]; + ctx->buffers[i + start_index].buffer_size = buffer_size; + ctx->buffers[i + start_index].buffer_pitch = buffer_pitch; + ctx->buffers[i + start_index].buffer_vulkan = static_cast(Graphics::GpuMemoryCreateObject( + 0, g_video_out_context->GetGraphicCtx(), nullptr, reinterpret_cast(addresses[i]), buffer_size, vulkan_buffer_info)); + + EXIT_NOT_IMPLEMENTED(ctx->buffers[i + start_index].buffer_vulkan == nullptr); + + printf("\tbuffers[%d] = %016" PRIx64 "\n", i + start_index, reinterpret_cast(addresses[i])); + } + + // Graphics::GpuMemoryDbgDump(); + + return OK; +} + KYTY_SYSV_ABI int VideoOutRegisterBuffers(int handle, int start_index, void* const* addresses, int buffer_num, const VideoOutBufferAttribute* attribute) { @@ -795,71 +951,84 @@ KYTY_SYSV_ABI int VideoOutRegisterBuffers(int handle, int start_index, void* con return VIDEO_OUT_ERROR_INVALID_VALUE; } - Graphics::WindowWaitForGraphicInitialized(); - Graphics::GraphicsRenderCreateContext(); + int set_id = ctx->buffers_sets_seq++; - int set_index = ctx->buffers_sets_num++; + printf("\t start_index = %d\n", start_index); + printf("\t buffer_num = %d\n", buffer_num); + printf("\t pixel_format = 0x%08" PRIx32 "\n", attribute->pixel_format); + printf("\t tiling_mode = %" PRIu32 "\n", attribute->tiling_mode); + printf("\t aspect_ratio = %" PRIu32 "\n", attribute->aspect_ratio); + printf("\t width = %" PRIu32 "\n", attribute->width); + printf("\t height = %" PRIu32 "\n", attribute->height); + printf("\t pitch_in_pixel = %" PRIu32 "\n", attribute->pitch_in_pixel); + printf("\t option = %" PRIu32 "\n", attribute->option); - if (set_index > 15) - { - return VIDEO_OUT_ERROR_NO_EMPTY_SLOT; - } - - printf("\tstart_index = %d\n", start_index); - printf("\tbuffer_num = %d\n", buffer_num); - printf("\tpixel_format = 0x%08" PRIx32 "\n", attribute->pixelFormat); - printf("\ttiling_mode = %" PRIu32 "\n", attribute->tilingMode); - printf("\taspect_ratio = %" PRIu32 "\n", attribute->aspectRatio); - printf("\twidth = %" PRIu32 "\n", attribute->width); - printf("\theight = %" PRIu32 "\n", attribute->height); - printf("\tpitch_in_pixel = %" PRIu32 "\n", attribute->pitchInPixel); - printf("\toption = %" PRIu32 "\n", attribute->option); - - EXIT_NOT_IMPLEMENTED(attribute->pixelFormat != 0x80000000); - EXIT_NOT_IMPLEMENTED(attribute->tilingMode != 0); - EXIT_NOT_IMPLEMENTED(attribute->aspectRatio != 0); - EXIT_NOT_IMPLEMENTED(attribute->pitchInPixel != attribute->width); + // EXIT_NOT_IMPLEMENTED(attribute->pixel_format != 0x80000000); + EXIT_NOT_IMPLEMENTED(attribute->tiling_mode != 0); + EXIT_NOT_IMPLEMENTED(attribute->aspect_ratio != 0); + EXIT_NOT_IMPLEMENTED(attribute->pitch_in_pixel != attribute->width); EXIT_NOT_IMPLEMENTED(attribute->option != 0); - uint64_t buffer_size = 0; - uint64_t buffer_align = 0; - uint64_t buffer_pitch = 0; - calc_buffer_size(attribute, &buffer_size, &buffer_align, &buffer_pitch); + int result = register_buffers_internal(ctx, set_id, start_index, addresses, buffer_num, attribute, nullptr); - EXIT_NOT_IMPLEMENTED(buffer_size == 0); - EXIT_NOT_IMPLEMENTED(buffer_pitch == 0); + return (result == OK ? set_id : result); +} - ctx->buffers_sets[set_index].start_index = start_index; - ctx->buffers_sets[set_index].num = buffer_num; - ctx->buffers_sets[set_index].attr = *attribute; +KYTY_SYSV_ABI int VideoOutRegisterBuffers2(int handle, int set_index, int buffer_index_start, const VideoOutBuffers* buffers, + int buffer_num, const VideoOutBufferAttribute2* attribute, int category, void* option) +{ + PRINT_NAME(); - Graphics::VideoOutBufferObject vulkan_buffer_info(attribute->pixelFormat, attribute->width, attribute->height, - (attribute->tilingMode == 0), Config::IsNeo(), buffer_pitch); + EXIT_IF(g_video_out_context == nullptr); + + auto* ctx = g_video_out_context->Get(handle); + + if (buffers == nullptr) + { + return VIDEO_OUT_ERROR_INVALID_ADDRESS; + } + + if (attribute == nullptr) + { + return VIDEO_OUT_ERROR_INVALID_OPTION; + } + + if (buffer_index_start < 0 || buffer_index_start > 15 || buffer_num < 1 || buffer_num > 16 || buffer_index_start + buffer_num > 15) + { + return VIDEO_OUT_ERROR_INVALID_VALUE; + } + + printf("\t start_index = %d\n", buffer_index_start); + printf("\t buffer_num = %d\n", buffer_num); + printf("\t set_index = %d\n", set_index); + printf("\t pixel_format = 0x%016" PRIx64 "\n", attribute->pixel_format); + printf("\t tiling_mode = %" PRIu32 "\n", attribute->tiling_mode); + printf("\t aspect_ratio = %" PRIu32 "\n", attribute->aspect_ratio); + printf("\t width = %" PRIu32 "\n", attribute->width); + printf("\t height = %" PRIu32 "\n", attribute->height); + printf("\t pitch_in_pixel = %" PRIu32 "\n", attribute->pitch_in_pixel); + printf("\t option = %" PRIu64 "\n", attribute->option); + + // EXIT_NOT_IMPLEMENTED(attribute->pixel_format != 0x80000000); + EXIT_NOT_IMPLEMENTED(option != nullptr); + EXIT_NOT_IMPLEMENTED(category != 0); + EXIT_NOT_IMPLEMENTED(attribute->tiling_mode != 0); + EXIT_NOT_IMPLEMENTED(attribute->aspect_ratio != 0); + EXIT_NOT_IMPLEMENTED(attribute->pitch_in_pixel != 0); + EXIT_NOT_IMPLEMENTED(attribute->option != 0); + EXIT_NOT_IMPLEMENTED(attribute->dcc_cb_register_clear_color != 0); + EXIT_NOT_IMPLEMENTED(attribute->dcc_control != 0); + + Vector addresses(buffer_num); for (int i = 0; i < buffer_num; i++) { - if (ctx->buffers[i + start_index].buffer != nullptr) - { - return VIDEO_OUT_ERROR_SLOT_OCCUPIED; - } + EXIT_NOT_IMPLEMENTED(buffers[i].metadata != nullptr); - EXIT_NOT_IMPLEMENTED((reinterpret_cast(addresses[i]) & (buffer_align - 1u)) != 0); - - ctx->buffers[i + start_index].set_id = set_index; - ctx->buffers[i + start_index].buffer = addresses[i]; - ctx->buffers[i + start_index].buffer_size = buffer_size; - ctx->buffers[i + start_index].buffer_pitch = buffer_pitch; - ctx->buffers[i + start_index].buffer_vulkan = static_cast(Graphics::GpuMemoryCreateObject( - 0, g_video_out_context->GetGraphicCtx(), nullptr, reinterpret_cast(addresses[i]), buffer_size, vulkan_buffer_info)); - - EXIT_NOT_IMPLEMENTED(ctx->buffers[i + start_index].buffer_vulkan == nullptr); - - printf("\tbuffers[%d] = %016" PRIx64 "\n", i + start_index, reinterpret_cast(addresses[i])); + addresses[i] = buffers[i].data; } - // Graphics::GpuMemoryDbgDump(); - - return set_index; + return register_buffers_internal(ctx, set_index, buffer_index_start, addresses.GetDataConst(), buffer_num, nullptr, attribute); } VideoOutBufferImageInfo VideoOutGetImage(uint64_t addr) diff --git a/source/emulator/src/Kernel/Memory.cpp b/source/emulator/src/Kernel/Memory.cpp index 66cf573..2db2bbe 100644 --- a/source/emulator/src/Kernel/Memory.cpp +++ b/source/emulator/src/Kernel/Memory.cpp @@ -576,6 +576,36 @@ int KYTY_SYSV_ABI KernelAllocateDirectMemory(int64_t search_start, int64_t searc return OK; } +int KYTY_SYSV_ABI KernelAllocateMainDirectMemory(size_t len, size_t alignment, int memory_type, int64_t* phys_addr_out) +{ + PRINT_NAME(); + + EXIT_IF(g_physical_memory == nullptr); + + printf("\t len = 0x%016" PRIx64 "\n", len); + printf("\t alignment = 0x%016" PRIx64 "\n", alignment); + printf("\t memory_type = %d\n", memory_type); + + if (len == 0 || phys_addr_out == nullptr) + { + return KERNEL_ERROR_EINVAL; + } + + uint64_t addr = 0; + if (!g_physical_memory->Alloc(0, UINT64_MAX, len, alignment, &addr, memory_type)) + { + printf(FG_RED "\t[Fail]\n" FG_DEFAULT); + return KERNEL_ERROR_EAGAIN; + } + + *phys_addr_out = static_cast(addr); + + printf("\tphys_addr = %016" PRIx64 "\n", addr); + printf(FG_GREEN "\t[Ok]\n" FG_DEFAULT); + + return OK; +} + int KYTY_SYSV_ABI KernelReleaseDirectMemory(int64_t start, size_t len) { PRINT_NAME(); @@ -697,6 +727,16 @@ int KYTY_SYSV_ABI KernelMapDirectMemory(void** addr, size_t len, int prot, int f return OK; } +int KYTY_SYSV_ABI KernelMapNamedDirectMemory(void** addr, size_t len, int prot, int flags, off_t direct_memory_start, size_t alignment, + const char* name) +{ + PRINT_NAME(); + + printf("\t name = %s\n", name); + + return KernelMapDirectMemory(addr, len, prot, flags, direct_memory_start, alignment); +} + int KYTY_SYSV_ABI KernelQueryMemoryProtection(void* addr, void** start, void** end, int* prot) { PRINT_NAME(); @@ -749,6 +789,46 @@ int KYTY_SYSV_ABI KernelAvailableFlexibleMemorySize(size_t* size) return OK; } +int KYTY_SYSV_ABI KernelMprotect(const void* addr, size_t len, int prot) +{ + PRINT_NAME(); + + auto vaddr = reinterpret_cast(addr); + + printf("\t addr = 0x%016" PRIx64 "\n", vaddr); + printf("\t len = 0x%016" PRIx64 "\n", reinterpret_cast(len)); + + VirtualMemory::Mode mode = VirtualMemory::Mode::NoAccess; + Graphics::GpuMemoryMode gpu_mode = Graphics::GpuMemoryMode::NoAccess; + + switch (prot) + { + case 0x11: + mode = VirtualMemory::Mode::Read; + gpu_mode = Graphics::GpuMemoryMode::Read; + break; + case 0x12: + mode = VirtualMemory::Mode::ReadWrite; + gpu_mode = Graphics::GpuMemoryMode::Read; + break; + default: EXIT("unknown prot: %d\n", prot); + } + + VirtualMemory::Mode old_mode {}; + bool ok = VirtualMemory::Protect(vaddr, len, mode, &old_mode); + + EXIT_NOT_IMPLEMENTED(!ok); + + if (gpu_mode != Graphics::GpuMemoryMode::NoAccess) + { + Graphics::GpuMemorySetAllocatedRange(vaddr, len); + } + + printf("\t prot: %s -> %s\n", Core::EnumName(old_mode).C_Str(), Core::EnumName(mode).C_Str()); + + return OK; +} + } // namespace Kyty::Libs::LibKernel::Memory #endif // KYTY_EMU_ENABLED diff --git a/source/emulator/src/Libs/LibGraphicsDriver.cpp b/source/emulator/src/Libs/LibGraphicsDriver.cpp index 7fded80..61d8d0f 100644 --- a/source/emulator/src/Libs/LibGraphicsDriver.cpp +++ b/source/emulator/src/Libs/LibGraphicsDriver.cpp @@ -7,47 +7,94 @@ namespace Kyty::Libs { +namespace LibGen4 { + LIB_VERSION("GraphicsDriver", 1, "GraphicsDriver", 1, 1); +namespace Gen4 = Graphics::Gen4; + LIB_DEFINE(InitGraphicsDriver_1) { PRINT_NAME_ENABLE(true); - LIB_FUNC("gAhCn6UiU4Y", Graphics::GraphicsSetVsShader); - LIB_FUNC("V31V01UiScY", Graphics::GraphicsUpdateVsShader); - LIB_FUNC("bQVd5YzCal0", Graphics::GraphicsSetPsShader); - LIB_FUNC("5uFKckiJYRM", Graphics::GraphicsSetPsShader350); - LIB_FUNC("4MgRw-bVNQU", Graphics::GraphicsUpdatePsShader); - LIB_FUNC("mLVL7N7BVBg", Graphics::GraphicsUpdatePsShader350); - LIB_FUNC("Kx-h-nWQJ8A", Graphics::GraphicsSetCsShaderWithModifier); - LIB_FUNC("HlTPoZ-oY7Y", Graphics::GraphicsDrawIndex); - LIB_FUNC("GGsn7jMTxw4", Graphics::GraphicsDrawIndexAuto); - LIB_FUNC("zwY0YV91TTI", Graphics::GraphicsSubmitCommandBuffers); - LIB_FUNC("xbxNatawohc", Graphics::GraphicsSubmitAndFlipCommandBuffers); - LIB_FUNC("yvZ73uQUqrk", Graphics::GraphicsSubmitDone); - LIB_FUNC("b08AgtPlHPg", Graphics::GraphicsAreSubmitsAllowed); - LIB_FUNC("iBt3Oe00Kvc", Graphics::GraphicsFlushMemory); - LIB_FUNC("b0xyllnVY-I", Graphics::GraphicsAddEqEvent); - LIB_FUNC("PVT+fuoS9gU", Graphics::GraphicsDeleteEqEvent); - LIB_FUNC("Idffwf3yh8s", Graphics::GraphicsDrawInitDefaultHardwareState); - LIB_FUNC("QhnyReteJ1M", Graphics::GraphicsDrawInitDefaultHardwareState175); - LIB_FUNC("0H2vBYbTLHI", Graphics::GraphicsDrawInitDefaultHardwareState200); - LIB_FUNC("yb2cRhagD1I", Graphics::GraphicsDrawInitDefaultHardwareState350); - LIB_FUNC("nF6bFRUBRAU", Graphics::GraphicsDispatchInitDefaultHardwareState); - LIB_FUNC("1qXLHIpROPE", Graphics::GraphicsInsertWaitFlipDone); - LIB_FUNC("0BzLGljcwBo", Graphics::GraphicsDispatchDirect); - LIB_FUNC("29oKvKXzEZo", Graphics::GraphicsMapComputeQueue); - LIB_FUNC("ArSg-TGinhk", Graphics::GraphicsUnmapComputeQueue); - LIB_FUNC("ffrNQOshows", Graphics::GraphicsComputeWaitOnAddress); - LIB_FUNC("bX5IbRvECXk", Graphics::GraphicsDingDong); - LIB_FUNC("W1Etj-jlW7Y", Graphics::GraphicsInsertPushMarker); - LIB_FUNC("7qZVNgEu+SY", Graphics::GraphicsInsertPopMarker); - LIB_FUNC("+AFvOEXrKJk", Graphics::GraphicsSetEmbeddedVsShader); - LIB_FUNC("ZFqKFl23aMc", Graphics::GraphicsRegisterOwner); - LIB_FUNC("nvEwfYAImTs", Graphics::GraphicsRegisterResource); - LIB_FUNC("Fwvh++m9IQI", Graphics::GraphicsGetGpuCoreClockFrequency); - LIB_FUNC("jg33rEKLfVs", Graphics::GraphicsIsUserPaEnabled); - LIB_FUNC("ln33zjBrfjk", Graphics::GraphicsGetTheTessellationFactorRingBufferBaseAddress); + LIB_FUNC("gAhCn6UiU4Y", Gen4::GraphicsSetVsShader); + LIB_FUNC("V31V01UiScY", Gen4::GraphicsUpdateVsShader); + LIB_FUNC("bQVd5YzCal0", Gen4::GraphicsSetPsShader); + LIB_FUNC("5uFKckiJYRM", Gen4::GraphicsSetPsShader350); + LIB_FUNC("4MgRw-bVNQU", Gen4::GraphicsUpdatePsShader); + LIB_FUNC("mLVL7N7BVBg", Gen4::GraphicsUpdatePsShader350); + LIB_FUNC("Kx-h-nWQJ8A", Gen4::GraphicsSetCsShaderWithModifier); + LIB_FUNC("HlTPoZ-oY7Y", Gen4::GraphicsDrawIndex); + LIB_FUNC("GGsn7jMTxw4", Gen4::GraphicsDrawIndexAuto); + LIB_FUNC("zwY0YV91TTI", Gen4::GraphicsSubmitCommandBuffers); + LIB_FUNC("xbxNatawohc", Gen4::GraphicsSubmitAndFlipCommandBuffers); + LIB_FUNC("yvZ73uQUqrk", Gen4::GraphicsSubmitDone); + LIB_FUNC("b08AgtPlHPg", Gen4::GraphicsAreSubmitsAllowed); + LIB_FUNC("iBt3Oe00Kvc", Gen4::GraphicsFlushMemory); + LIB_FUNC("b0xyllnVY-I", Gen4::GraphicsAddEqEvent); + LIB_FUNC("PVT+fuoS9gU", Gen4::GraphicsDeleteEqEvent); + LIB_FUNC("Idffwf3yh8s", Gen4::GraphicsDrawInitDefaultHardwareState); + LIB_FUNC("QhnyReteJ1M", Gen4::GraphicsDrawInitDefaultHardwareState175); + LIB_FUNC("0H2vBYbTLHI", Gen4::GraphicsDrawInitDefaultHardwareState200); + LIB_FUNC("yb2cRhagD1I", Gen4::GraphicsDrawInitDefaultHardwareState350); + LIB_FUNC("nF6bFRUBRAU", Gen4::GraphicsDispatchInitDefaultHardwareState); + LIB_FUNC("1qXLHIpROPE", Gen4::GraphicsInsertWaitFlipDone); + LIB_FUNC("0BzLGljcwBo", Gen4::GraphicsDispatchDirect); + LIB_FUNC("29oKvKXzEZo", Gen4::GraphicsMapComputeQueue); + LIB_FUNC("ArSg-TGinhk", Gen4::GraphicsUnmapComputeQueue); + LIB_FUNC("ffrNQOshows", Gen4::GraphicsComputeWaitOnAddress); + LIB_FUNC("bX5IbRvECXk", Gen4::GraphicsDingDong); + LIB_FUNC("W1Etj-jlW7Y", Gen4::GraphicsInsertPushMarker); + LIB_FUNC("7qZVNgEu+SY", Gen4::GraphicsInsertPopMarker); + LIB_FUNC("+AFvOEXrKJk", Gen4::GraphicsSetEmbeddedVsShader); + LIB_FUNC("ZFqKFl23aMc", Gen4::GraphicsRegisterOwner); + LIB_FUNC("nvEwfYAImTs", Gen4::GraphicsRegisterResource); + LIB_FUNC("Fwvh++m9IQI", Gen4::GraphicsGetGpuCoreClockFrequency); + LIB_FUNC("jg33rEKLfVs", Gen4::GraphicsIsUserPaEnabled); + LIB_FUNC("ln33zjBrfjk", Gen4::GraphicsGetTheTessellationFactorRingBufferBaseAddress); +} + +} // namespace LibGen4 + +namespace LibGen5 { + +LIB_VERSION("Graphics5", 1, "Graphics5", 1, 1); + +namespace Gen5 = Graphics::Gen5; + +LIB_DEFINE(InitGraphicsDriver_1) +{ + PRINT_NAME_ENABLE(true); + + LIB_FUNC("23LRUSvYu1M", Gen5::GraphicsInit); + LIB_FUNC("2JtWUUiYBXs", Gen5::GraphicsGetRegisterDefaults2); + LIB_FUNC("wRbq6ZjNop4", Gen5::GraphicsGetRegisterDefaults2Internal); + LIB_FUNC("f3dg2CSgRKY", Gen5::GraphicsCreateShader); + LIB_FUNC("TRO721eVt4g", Gen5::GraphicsDcbResetQueue); + LIB_FUNC("MWiElSNE8j8", Gen5::GraphicsDcbWaitUntilSafeForRendering); + LIB_FUNC("ZvwO9euwYzc", Gen5::GraphicsDcbSetCxRegistersIndirect); + LIB_FUNC("-HOOCn0JY48", Gen5::GraphicsDcbSetShRegistersIndirect); + LIB_FUNC("hvUfkUIQcOE", Gen5::GraphicsDcbSetUcRegistersIndirect); + LIB_FUNC("GIIW2J37e70", Gen5::GraphicsDcbSetIndexSize); + LIB_FUNC("Yw0jKSqop+E", Gen5::GraphicsDcbDrawIndexAuto); + LIB_FUNC("vcmNN+AAXnY", Gen5::GraphicsSetCxRegIndirectPatchSetAddress); + LIB_FUNC("Qrj4c+61z4A", Gen5::GraphicsSetShRegIndirectPatchSetAddress); + LIB_FUNC("6lNcCp+fxi4", Gen5::GraphicsSetUcRegIndirectPatchSetAddress); + LIB_FUNC("d-6uF9sZDIU", Gen5::GraphicsSetCxRegIndirectPatchAddRegisters); + LIB_FUNC("z2duB-hHQSM", Gen5::GraphicsSetShRegIndirectPatchAddRegisters); + LIB_FUNC("vRoArM9zaIk", Gen5::GraphicsSetUcRegIndirectPatchAddRegisters); + LIB_FUNC("D9sr1xGUriE", Gen5::GraphicsCreatePrimState); + LIB_FUNC("HV4j+E0MBHE", Gen5::GraphicsCreateInterpolantMapping); + LIB_FUNC("n2fD4A+pb+g", Gen5::GraphicsCbSetShRegisterRangeDirect); + LIB_FUNC("V++UgBtQhn0", Gen5::GraphicsGetDataPacketPayloadAddress); +} + +} // namespace LibGen5 + +LIB_DEFINE(InitGraphicsDriver_1) +{ + LibGen4::InitGraphicsDriver_1(s); + LibGen5::InitGraphicsDriver_1(s); } } // namespace Kyty::Libs diff --git a/source/emulator/src/Libs/LibKernel.cpp b/source/emulator/src/Libs/LibKernel.cpp index 5ae1f90..a099ad7 100644 --- a/source/emulator/src/Libs/LibKernel.cpp +++ b/source/emulator/src/Libs/LibKernel.cpp @@ -507,11 +507,14 @@ LIB_DEFINE(InitLibKernel_1_Mem) LIB_FUNC("cQke9UuBQOk", Memory::KernelMunmap); LIB_FUNC("pO96TwzOm5E", Memory::KernelGetDirectMemorySize); LIB_FUNC("rTXw65xmLIA", Memory::KernelAllocateDirectMemory); + LIB_FUNC("B+vc2AO2Zrc", Memory::KernelAllocateMainDirectMemory); LIB_FUNC("L-Q3LEjIbgA", Memory::KernelMapDirectMemory); + LIB_FUNC("NcaWUxfMNIQ", Memory::KernelMapNamedDirectMemory); LIB_FUNC("MBuItvba6z8", Memory::KernelReleaseDirectMemory); LIB_FUNC("WFcfL2lzido", Memory::KernelQueryMemoryProtection); LIB_FUNC("BHouLQzh0X0", Memory::KernelDirectMemoryQuery); LIB_FUNC("aNz11fnnzi4", Memory::KernelAvailableFlexibleMemorySize); + LIB_FUNC("vSMAm3cxYTY", Memory::KernelMprotect); } LIB_DEFINE(InitLibKernel_1_Equeue) diff --git a/source/emulator/src/Libs/LibVideoOut.cpp b/source/emulator/src/Libs/LibVideoOut.cpp index b398aa8..b6454bc 100644 --- a/source/emulator/src/Libs/LibVideoOut.cpp +++ b/source/emulator/src/Libs/LibVideoOut.cpp @@ -7,6 +7,8 @@ namespace Kyty::Libs { +namespace LibGen4 { + LIB_VERSION("VideoOut", 1, "VideoOut", 0, 0); LIB_DEFINE(InitVideoOut_1) @@ -27,6 +29,29 @@ LIB_DEFINE(InitVideoOut_1) LIB_FUNC("MTxxrOCeSig", VideoOut::VideoOutSetWindowModeMargins); } +} // namespace LibGen4 + +namespace LibGen5 { + +LIB_VERSION("VideoOut", 1, "VideoOut", 1, 1); + +LIB_DEFINE(InitVideoOut_1) +{ + PRINT_NAME_ENABLE(true); + + LIB_FUNC("Up36PTk687E", VideoOut::VideoOutOpen); + LIB_FUNC("PjS5uASwcV8", VideoOut::VideoOutSetBufferAttribute2); + LIB_FUNC("rKBUtgRrtbk", VideoOut::VideoOutRegisterBuffers2); +} + +} // namespace LibGen5 + +LIB_DEFINE(InitVideoOut_1) +{ + LibGen4::InitVideoOut_1(s); + LibGen5::InitVideoOut_1(s); +} + } // namespace Kyty::Libs #endif // KYTY_EMU_ENABLED diff --git a/source/emulator/src/Loader/SymbolDatabase.cpp b/source/emulator/src/Loader/SymbolDatabase.cpp index 5add15a..d784c06 100644 --- a/source/emulator/src/Loader/SymbolDatabase.cpp +++ b/source/emulator/src/Loader/SymbolDatabase.cpp @@ -9,13 +9,16 @@ namespace Kyty::Loader { constexpr char32_t LIB_PREFIX[] = {0x0000006c, 0x00000069, 0x00000062, 0x00000053, 0x00000063, 0x00000065, 0}; -constexpr char32_t LIB_OLD[] = {0x00000047, 0x0000006e, 0x0000006d, 0}; -constexpr char32_t LIB_NEW[] = {0x00000047, 0x00000072, 0x00000061, 0x00000070, 0x00000068, 0x00000069, 0x00000063, 0x00000073, 0}; +constexpr char32_t LIB_OLD_4[] = {0x00000047, 0x0000006e, 0x0000006d, 0}; +constexpr char32_t LIB_NEW_4[] = {0x00000047, 0x00000072, 0x00000061, 0x00000070, 0x00000068, 0x00000069, 0x00000063, 0x00000073, 0}; +constexpr char32_t LIB_OLD_5[] = {0x00000041, 0x00000067, 0x00000063, 0}; +constexpr char32_t LIB_NEW_5[] = {0x00000047, 0x00000072, 0x00000061, 0x00000070, 0x00000068, + 0x00000069, 0x00000063, 0x00000073, 0x00000035, 0}; static String update_name(const String& str) { auto ret = (str.StartsWith(LIB_PREFIX) ? str.RemoveFirst(6) : str); - return ret.ReplaceStr(LIB_OLD, LIB_NEW); + return ret.ReplaceStr(LIB_OLD_4, LIB_NEW_4).ReplaceStr(LIB_OLD_5, LIB_NEW_5); } String SymbolDatabase::GenerateName(const SymbolResolve& s)