PS5 graphics (#42)

This commit is contained in:
InoriRus 2022-07-15 12:09:09 +03:00
parent 498eac6a32
commit 6f9200d009
19 changed files with 1417 additions and 201 deletions

View file

@ -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

View file

@ -1,4 +1,4 @@
version: 0.1.8.build-{build}
version: 0.1.9.build-{build}
image: Visual Studio 2019
environment:
matrix:

View file

@ -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)

View file

@ -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

View file

@ -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<uint64_t>(pixel_format);
params[PARAM_WIDTH] = width;
params[PARAM_HEIGHT] = height;
params[PARAM_TILED] = tiled ? 1 : 0;

View file

@ -16,6 +16,8 @@ class File;
#define KYTY_PM4(len, op, r) \
(0xC0000000u | (((static_cast<uint16_t>(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

View file

@ -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);

View file

@ -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

View file

@ -20,14 +20,13 @@
#include "Emulator/Libs/Libs.h"
#include "Emulator/Loader/VirtualMemory.h"
#include <algorithm>
#include <atomic>
#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<uint64_t>(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<uint64_t>(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<uint64_t>(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<uint64_t>(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<uint64_t>(bottom));
printf("\t top = 0x%016" PRIx64 "\n", reinterpret_cast<uint64_t>(top));
printf("\t cursor_up = 0x%016" PRIx64 "\n", reinterpret_cast<uint64_t>(cursor_up));
printf("\t cursor_down = 0x%016" PRIx64 "\n", reinterpret_cast<uint64_t>(cursor_down));
printf("\t callback = 0x%016" PRIx64 "\n", reinterpret_cast<uint64_t>(callback));
printf("\t user_data = 0x%016" PRIx64 "\n", reinterpret_cast<uint64_t>(user_data));
printf("\t reserved_dw = %" PRIu32 "\n", reserved_dw);
}
[[nodiscard]] KYTY_SYSV_ABI uint32_t GetAvailableSizeDW() const
{
auto available = static_cast<uint32_t>(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<uint64_t>(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<uint64_t>(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<uint64_t>(h->user_data->direct_resource_offset));
for (int i = 0; i < static_cast<int>(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<uint64_t>(h->user_data->sharp_resource_offset[imm]));
for (int i = 0; i < static_cast<int>(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<uint64_t>(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<uint64_t>(h->cx_registers));
for (int i = 0; i < static_cast<int>(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<uint64_t>(h->sh_registers));
for (int i = 0; i < static_cast<int>(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<uint64_t>(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<uint64_t>(h->input_semantics));
for (int i = 0; i < static_cast<int>(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<uint64_t>(h->output_semantics));
for (int i = 0; i < static_cast<int>(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<uint64_t>(header));
printf("\t code = 0x%016" PRIx64 "\n", reinterpret_cast<uint64_t>(code));
auto* h = static_cast<Shader*>(header);
auto update_addr = [](auto& m)
{
if (m != nullptr)
{
m = reinterpret_cast<typename std::remove_reference<decltype(m)>::type>(reinterpret_cast<uintptr_t>(m) +
reinterpret_cast<uintptr_t>(&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<uint64_t>(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<uint64_t>(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<uint64_t>(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<uint64_t>(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<uint64_t>(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<uint64_t>(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<ShaderDrawModifier*>(&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<uint64_t>(cmd));
printf("\t regs = 0x%016" PRIx64 "\n", reinterpret_cast<uint64_t>(regs));
EXIT_NOT_IMPLEMENTED(cmd == nullptr);
EXIT_NOT_IMPLEMENTED(regs == nullptr);
auto vaddr = reinterpret_cast<uint64_t>(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<uint64_t>(cmd));
printf("\t regs = 0x%016" PRIx64 "\n", reinterpret_cast<uint64_t>(regs));
EXIT_NOT_IMPLEMENTED(cmd == nullptr);
EXIT_NOT_IMPLEMENTED(regs == nullptr);
auto vaddr = reinterpret_cast<uint64_t>(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<uint64_t>(cmd));
printf("\t regs = 0x%016" PRIx64 "\n", reinterpret_cast<uint64_t>(regs));
EXIT_NOT_IMPLEMENTED(cmd == nullptr);
EXIT_NOT_IMPLEMENTED(regs == nullptr);
auto vaddr = reinterpret_cast<uint64_t>(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<uint64_t>(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<uint64_t>(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<uint64_t>(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<uint64_t>(cx_regs));
printf("\t uc_regs = 0x%016" PRIx64 "\n", reinterpret_cast<uint64_t>(uc_regs));
printf("\t hs = 0x%016" PRIx64 "\n", reinterpret_cast<uint64_t>(hs));
printf("\t gs = 0x%016" PRIx64 "\n", reinterpret_cast<uint64_t>(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<uint64_t>(regs));
printf("\t gs = 0x%016" PRIx64 "\n", reinterpret_cast<uint64_t>(gs));
printf("\t ps = 0x%016" PRIx64 "\n", reinterpret_cast<uint64_t>(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<uint32_t*>(gs->output_semantics);
auto* in32 = (ps != nullptr ? reinterpret_cast<uint32_t*>(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<int>(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<uint64_t>(buf));
printf("\t offset = %" PRIx32 "\n", offset);
printf("\t values = 0x%016" PRIx64 "\n", reinterpret_cast<uint64_t>(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<size_t>(num_values) * 4);
} else
{
memcpy(cmd + 2, values, static_cast<size_t>(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<uint64_t>(addr));
printf("\t cmd = 0x%016" PRIx64 "\n", reinterpret_cast<uint64_t>(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

View file

@ -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<uint64_t>(buffer[2]) << 8u;
z.stencil_read_base_addr = static_cast<uint64_t>(buffer[3]) << 8u;
z.z_write_base_addr = static_cast<uint64_t>(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;

View file

@ -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<uint64_t>(VideoOutBufferFormat::R8G8B8A8Srgb): vk_format = VK_FORMAT_R8G8B8A8_SRGB; break;
case static_cast<uint64_t>(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;

View file

@ -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";

View file

@ -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<uint32_t>(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)

View file

@ -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<VideoOutBufferSet> 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<uint64_t>(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::VideoOutVulkanImage*>(Graphics::GpuMemoryCreateObject(
0, g_video_out_context->GetGraphicCtx(), nullptr, reinterpret_cast<uint64_t>(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<uint64_t>(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<const void*> 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<uint64_t>(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::VideoOutVulkanImage*>(Graphics::GpuMemoryCreateObject(
0, g_video_out_context->GetGraphicCtx(), nullptr, reinterpret_cast<uint64_t>(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<uint64_t>(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)

View file

@ -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<int64_t>(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<uint64_t>(addr);
printf("\t addr = 0x%016" PRIx64 "\n", vaddr);
printf("\t len = 0x%016" PRIx64 "\n", reinterpret_cast<uint64_t>(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

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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)