mirror of
https://github.com/InoriRus/Kyty.git
synced 2026-08-28 13:16:40 +00:00
some minor improvements
This commit is contained in:
@@ -69,6 +69,31 @@ int KYTY_SYSV_ABI GraphicsSetVsShader(uint32_t* cmd, uint64_t size, const VsStag
|
||||
return OK;
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI GraphicsUpdateVsShader(uint32_t* cmd, uint64_t size, const VsStageRegisters* vs_regs, uint32_t shader_modifier)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(size < sizeof(VsStageRegisters) / 4 + 2);
|
||||
|
||||
printf("\t cmd_buffer = %016" PRIx64 "\n", reinterpret_cast<uint64_t>(cmd));
|
||||
printf("\t size = %" PRIu64 "\n", size);
|
||||
printf("\t shader_modifier = %" PRIu32 "\n", shader_modifier);
|
||||
|
||||
printf("\t vs_regs.m_spiShaderPgmLoVs = %08" PRIx32 "\n", vs_regs->m_spiShaderPgmLoVs);
|
||||
printf("\t vs_regs.m_spiShaderPgmHiVs = %08" PRIx32 "\n", vs_regs->m_spiShaderPgmHiVs);
|
||||
printf("\t vs_regs.m_spiShaderPgmRsrc1Vs = %08" PRIx32 "\n", vs_regs->m_spiShaderPgmRsrc1Vs);
|
||||
printf("\t vs_regs.m_spiShaderPgmRsrc2Vs = %08" PRIx32 "\n", vs_regs->m_spiShaderPgmRsrc2Vs);
|
||||
printf("\t vs_regs.m_spiVsOutConfig = %08" PRIx32 "\n", vs_regs->m_spiVsOutConfig);
|
||||
printf("\t vs_regs.m_spiShaderPosFormat = %08" PRIx32 "\n", vs_regs->m_spiShaderPosFormat);
|
||||
printf("\t vs_regs.m_paClVsOutCntl = %08" PRIx32 "\n", vs_regs->m_paClVsOutCntl);
|
||||
|
||||
cmd[0] = KYTY_PM4(size, Pm4::IT_NOP, Pm4::R_VS_UPDATE);
|
||||
cmd[1] = shader_modifier;
|
||||
memcpy(&cmd[2], vs_regs, sizeof(VsStageRegisters));
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI GraphicsSetEmbeddedVsShader(uint32_t* cmd, uint64_t size, uint32_t id, uint32_t shader_modifier)
|
||||
{
|
||||
PRINT_NAME();
|
||||
@@ -87,12 +112,94 @@ int KYTY_SYSV_ABI GraphicsSetEmbeddedVsShader(uint32_t* cmd, uint64_t size, uint
|
||||
return OK;
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI GraphicsSetPsShader(uint32_t* cmd, uint64_t size, const uint32_t* ps_regs)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
if (ps_regs == nullptr)
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(size < 1 + 1);
|
||||
|
||||
printf("\t cmd_buffer = %016" PRIx64 "\n", reinterpret_cast<uint64_t>(cmd));
|
||||
printf("\t size = %" PRIu64 "\n", size);
|
||||
printf("\t embedded_id = %d\n", 0);
|
||||
|
||||
cmd[0] = KYTY_PM4(size, Pm4::IT_NOP, Pm4::R_PS_EMBEDDED);
|
||||
cmd[1] = 0;
|
||||
} else
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(size < 12 + 1);
|
||||
|
||||
printf("\t cmd_buffer = %016" PRIx64 "\n", reinterpret_cast<uint64_t>(cmd));
|
||||
printf("\t size = %" PRIu64 "\n", size);
|
||||
|
||||
printf("\t ps_regs.m_spiShaderPgmLoPs = %08" PRIx32 "\n", ps_regs[0]);
|
||||
printf("\t ps_regs.m_spiShaderPgmHiPs = %08" PRIx32 "\n", ps_regs[1]);
|
||||
printf("\t ps_regs.m_spiShaderPgmRsrc1Ps = %08" PRIx32 "\n", ps_regs[2]);
|
||||
printf("\t ps_regs.m_spiShaderPgmRsrc2Ps = %08" PRIx32 "\n", ps_regs[3]);
|
||||
printf("\t ps_regs.m_spiShaderZFormat = %08" PRIx32 "\n", ps_regs[4]);
|
||||
printf("\t ps_regs.m_spiShaderColFormat = %08" PRIx32 "\n", ps_regs[5]);
|
||||
printf("\t ps_regs.m_spiPsInputEna = %08" PRIx32 "\n", ps_regs[6]);
|
||||
printf("\t ps_regs.m_spiPsInputAddr = %08" PRIx32 "\n", ps_regs[7]);
|
||||
printf("\t ps_regs.m_spiPsInControl = %08" PRIx32 "\n", ps_regs[8]);
|
||||
printf("\t ps_regs.m_spiBarycCntl = %08" PRIx32 "\n", ps_regs[9]);
|
||||
printf("\t ps_regs.m_dbShaderControl = %08" PRIx32 "\n", ps_regs[10]);
|
||||
printf("\t ps_regs.m_cbShaderMask = %08" PRIx32 "\n", ps_regs[11]);
|
||||
|
||||
cmd[0] = KYTY_PM4(size, Pm4::IT_NOP, Pm4::R_PS);
|
||||
memcpy(&cmd[1], ps_regs, 12 * 4);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI GraphicsSetPsShader350(uint32_t* cmd, uint64_t size, const uint32_t* ps_regs)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
if (ps_regs == nullptr)
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(size < 1 + 1);
|
||||
|
||||
printf("\t cmd_buffer = %016" PRIx64 "\n", reinterpret_cast<uint64_t>(cmd));
|
||||
printf("\t size = %" PRIu64 "\n", size);
|
||||
printf("\t embedded_id = %d\n", 0);
|
||||
|
||||
cmd[0] = KYTY_PM4(size, Pm4::IT_NOP, Pm4::R_PS_EMBEDDED);
|
||||
cmd[1] = 0;
|
||||
} else
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(size < 12 + 1);
|
||||
|
||||
printf("\t cmd_buffer = %016" PRIx64 "\n", reinterpret_cast<uint64_t>(cmd));
|
||||
printf("\t size = %" PRIu64 "\n", size);
|
||||
|
||||
printf("\t ps_regs.m_spiShaderPgmLoPs = %08" PRIx32 "\n", ps_regs[0]);
|
||||
printf("\t ps_regs.m_spiShaderPgmHiPs = %08" PRIx32 "\n", ps_regs[1]);
|
||||
printf("\t ps_regs.m_spiShaderPgmRsrc1Ps = %08" PRIx32 "\n", ps_regs[2]);
|
||||
printf("\t ps_regs.m_spiShaderPgmRsrc2Ps = %08" PRIx32 "\n", ps_regs[3]);
|
||||
printf("\t ps_regs.m_spiShaderZFormat = %08" PRIx32 "\n", ps_regs[4]);
|
||||
printf("\t ps_regs.m_spiShaderColFormat = %08" PRIx32 "\n", ps_regs[5]);
|
||||
printf("\t ps_regs.m_spiPsInputEna = %08" PRIx32 "\n", ps_regs[6]);
|
||||
printf("\t ps_regs.m_spiPsInputAddr = %08" PRIx32 "\n", ps_regs[7]);
|
||||
printf("\t ps_regs.m_spiPsInControl = %08" PRIx32 "\n", ps_regs[8]);
|
||||
printf("\t ps_regs.m_spiBarycCntl = %08" PRIx32 "\n", ps_regs[9]);
|
||||
printf("\t ps_regs.m_dbShaderControl = %08" PRIx32 "\n", ps_regs[10]);
|
||||
printf("\t ps_regs.m_cbShaderMask = %08" PRIx32 "\n", ps_regs[11]);
|
||||
|
||||
cmd[0] = KYTY_PM4(size, Pm4::IT_NOP, Pm4::R_PS);
|
||||
memcpy(&cmd[1], ps_regs, 12 * 4);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI GraphicsUpdatePsShader(uint32_t* cmd, uint64_t size, const uint32_t* ps_regs)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(ps_regs == nullptr);
|
||||
EXIT_NOT_IMPLEMENTED(size < sizeof(PsStageRegisters) / 12 + 1);
|
||||
EXIT_NOT_IMPLEMENTED(size < 12 + 1);
|
||||
|
||||
printf("\t cmd_buffer = %016" PRIx64 "\n", reinterpret_cast<uint64_t>(cmd));
|
||||
printf("\t size = %" PRIu64 "\n", size);
|
||||
@@ -110,7 +217,7 @@ int KYTY_SYSV_ABI GraphicsSetPsShader350(uint32_t* cmd, uint64_t size, const uin
|
||||
printf("\t ps_regs.m_dbShaderControl = %08" PRIx32 "\n", ps_regs[10]);
|
||||
printf("\t ps_regs.m_cbShaderMask = %08" PRIx32 "\n", ps_regs[11]);
|
||||
|
||||
cmd[0] = KYTY_PM4(size, Pm4::IT_NOP, Pm4::R_PS);
|
||||
cmd[0] = KYTY_PM4(size, Pm4::IT_NOP, Pm4::R_PS_UPDATE);
|
||||
memcpy(&cmd[1], ps_regs, 12 * 4);
|
||||
|
||||
return OK;
|
||||
@@ -224,6 +331,48 @@ int KYTY_SYSV_ABI GraphicsDispatchDirect(uint32_t* cmd, uint64_t size, uint32_t
|
||||
return OK;
|
||||
}
|
||||
|
||||
uint32_t KYTY_SYSV_ABI GraphicsDrawInitDefaultHardwareState(uint32_t* cmd, uint64_t size)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(size < 2);
|
||||
|
||||
printf("\t cmd_buffer = %016" PRIx64 "\n", reinterpret_cast<uint64_t>(cmd));
|
||||
printf("\t size = %" PRIu64 "\n", size);
|
||||
|
||||
cmd[0] = KYTY_PM4(2, Pm4::IT_NOP, Pm4::R_DRAW_RESET);
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
uint32_t KYTY_SYSV_ABI GraphicsDrawInitDefaultHardwareState175(uint32_t* cmd, uint64_t size)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(size < 2);
|
||||
|
||||
printf("\t cmd_buffer = %016" PRIx64 "\n", reinterpret_cast<uint64_t>(cmd));
|
||||
printf("\t size = %" PRIu64 "\n", size);
|
||||
|
||||
cmd[0] = KYTY_PM4(2, Pm4::IT_NOP, Pm4::R_DRAW_RESET);
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
uint32_t KYTY_SYSV_ABI GraphicsDrawInitDefaultHardwareState200(uint32_t* cmd, uint64_t size)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(size < 2);
|
||||
|
||||
printf("\t cmd_buffer = %016" PRIx64 "\n", reinterpret_cast<uint64_t>(cmd));
|
||||
printf("\t size = %" PRIu64 "\n", size);
|
||||
|
||||
cmd[0] = KYTY_PM4(2, Pm4::IT_NOP, Pm4::R_DRAW_RESET);
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
uint32_t KYTY_SYSV_ABI GraphicsDrawInitDefaultHardwareState350(uint32_t* cmd, uint64_t size)
|
||||
{
|
||||
PRINT_NAME();
|
||||
@@ -464,6 +613,11 @@ uint64_t KYTY_SYSV_ABI GraphicsGetGpuCoreClockFrequency()
|
||||
return LibKernel::KernelGetTscFrequency();
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI GraphicsIsUserPaEnabled()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI GraphicsRegisterOwner(uint32_t* owner_handle, const char* name)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
@@ -70,6 +70,10 @@ struct PipelineParameters
|
||||
uint8_t alpha_destblend = 0;
|
||||
bool separate_alpha_blend = false;
|
||||
bool blend_enable = false;
|
||||
float blend_color_red = 0.0f;
|
||||
float blend_color_green = 0.0f;
|
||||
float blend_color_blue = 0.0f;
|
||||
float blend_color_alpha = 0.0f;
|
||||
|
||||
bool operator==(const PipelineParameters& other) const;
|
||||
};
|
||||
@@ -99,7 +103,8 @@ public:
|
||||
VulkanPipeline* CreatePipeline(VulkanFramebuffer* framebuffer, RenderColorInfo* color, RenderDepthInfo* depth,
|
||||
const ShaderVertexInputInfo* vs_input_info, const VertexShaderInfo* vs_regs,
|
||||
const ShaderPixelInputInfo* ps_input_info, const PixelShaderInfo* ps_regs, VkPrimitiveTopology topology,
|
||||
uint32_t color_mask, const ModeControl& mc, const BlendControl& bc, const ScreenViewport& vp);
|
||||
uint32_t color_mask, const ModeControl& mc, const BlendControl& bc, const BlendColor& bclr,
|
||||
const ScreenViewport& vp);
|
||||
VulkanPipeline* CreatePipeline(const ShaderComputeInputInfo* input_info, const ComputeShaderInfo* cs_regs);
|
||||
void DeletePipeline(VulkanPipeline* pipeline);
|
||||
void DeletePipelines(VulkanFramebuffer* framebuffer);
|
||||
@@ -446,6 +451,7 @@ static void rt_check(const RenderTarget& rt)
|
||||
{
|
||||
if (rt.base_addr != 0)
|
||||
{
|
||||
bool render_to_texture = (rt.tile_mode == 0x0d);
|
||||
// EXIT_NOT_IMPLEMENTED(rt.base_addr == 0);
|
||||
// EXIT_NOT_IMPLEMENTED(rt.pitch_div8_minus1 != 0x000000ef);
|
||||
// EXIT_NOT_IMPLEMENTED(rt.fmask_pitch_div8_minus1 != 0x000000ef);
|
||||
@@ -456,7 +462,7 @@ static void rt_check(const RenderTarget& rt)
|
||||
EXIT_NOT_IMPLEMENTED(rt.fmask_compression_mode != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(rt.cmask_fast_clear_enable != false);
|
||||
EXIT_NOT_IMPLEMENTED(rt.dcc_compression_enable != false);
|
||||
EXIT_NOT_IMPLEMENTED(rt.neo_mode != Config::IsNeo());
|
||||
EXIT_NOT_IMPLEMENTED(!render_to_texture && rt.neo_mode != Config::IsNeo());
|
||||
EXIT_NOT_IMPLEMENTED(rt.cmask_tile_mode != 0x00000000);
|
||||
EXIT_NOT_IMPLEMENTED(rt.cmask_tile_mode_neo != 0x00000000);
|
||||
// EXIT_NOT_IMPLEMENTED(rt.format != 0x0000000a);
|
||||
@@ -686,7 +692,7 @@ static void mc_check(const ModeControl& c)
|
||||
EXIT_NOT_IMPLEMENTED(c.persp_corr_dis != false);
|
||||
}
|
||||
|
||||
static void bc_print(const char* func, const BlendControl& c)
|
||||
static void bc_print(const char* func, const BlendControl& c, const BlendColor& color)
|
||||
{
|
||||
printf("%s\n", func);
|
||||
|
||||
@@ -698,9 +704,13 @@ static void bc_print(const char* func, const BlendControl& c)
|
||||
printf("\t alpha_destblend = %" PRIu8 "\n", c.alpha_destblend);
|
||||
printf("\t separate_alpha_blend = %s\n", c.separate_alpha_blend ? "true" : "false");
|
||||
printf("\t enable = %s\n", c.enable ? "true" : "false");
|
||||
printf("\t red = %f\n", color.red);
|
||||
printf("\t green = %f\n", color.green);
|
||||
printf("\t blue = %f\n", color.blue);
|
||||
printf("\t alpha = %f\n", color.alpha);
|
||||
}
|
||||
|
||||
static void bc_check(const BlendControl& c)
|
||||
static void bc_check(const BlendControl& c, const BlendColor& color)
|
||||
{
|
||||
// EXIT_NOT_IMPLEMENTED(c.color_srcblend != 0);
|
||||
EXIT_NOT_IMPLEMENTED(c.color_comb_fcn != 0);
|
||||
@@ -710,6 +720,10 @@ static void bc_check(const BlendControl& c)
|
||||
EXIT_NOT_IMPLEMENTED(c.alpha_destblend != 0);
|
||||
EXIT_NOT_IMPLEMENTED(c.separate_alpha_blend != false);
|
||||
// EXIT_NOT_IMPLEMENTED(c.enable != false);
|
||||
EXIT_NOT_IMPLEMENTED(color.red != 0.0f);
|
||||
EXIT_NOT_IMPLEMENTED(color.green != 0.0f);
|
||||
EXIT_NOT_IMPLEMENTED(color.blue != 0.0f);
|
||||
EXIT_NOT_IMPLEMENTED(color.alpha != 0.0f);
|
||||
}
|
||||
|
||||
static void d_print(const char* func, const DepthControl& c)
|
||||
@@ -738,6 +752,32 @@ static void d_check(const DepthControl& c)
|
||||
EXIT_NOT_IMPLEMENTED(c.stencilfunc_bf != 0);
|
||||
}
|
||||
|
||||
static void eqaa_print(const char* func, const EqaaControl& c)
|
||||
{
|
||||
printf("%s\n", func);
|
||||
|
||||
printf("\t max_anchor_samples = %" PRIu8 "\n", c.max_anchor_samples);
|
||||
printf("\t ps_iter_samples = %" PRIu8 "\n", c.ps_iter_samples);
|
||||
printf("\t mask_export_num_samples = %" PRIu8 "\n", c.mask_export_num_samples);
|
||||
printf("\t alpha_to_mask_num_samples = %" PRIu8 "\n", c.alpha_to_mask_num_samples);
|
||||
printf("\t high_quality_intersections = %s\n", c.high_quality_intersections ? "true" : "false");
|
||||
printf("\t incoherent_eqaa_reads = %s\n", c.incoherent_eqaa_reads ? "true" : "false");
|
||||
printf("\t interpolate_comp_z = %s\n", c.interpolate_comp_z ? "true" : "false");
|
||||
printf("\t static_anchor_associations = %s\n", c.static_anchor_associations ? "true" : "false");
|
||||
}
|
||||
|
||||
static void eqaa_check(const EqaaControl& c)
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(c.max_anchor_samples != 0);
|
||||
EXIT_NOT_IMPLEMENTED(c.ps_iter_samples != 0);
|
||||
EXIT_NOT_IMPLEMENTED(c.mask_export_num_samples != 0);
|
||||
EXIT_NOT_IMPLEMENTED(c.alpha_to_mask_num_samples != 0);
|
||||
EXIT_NOT_IMPLEMENTED(c.high_quality_intersections != false);
|
||||
EXIT_NOT_IMPLEMENTED(c.incoherent_eqaa_reads != false);
|
||||
EXIT_NOT_IMPLEMENTED(c.interpolate_comp_z != false);
|
||||
EXIT_NOT_IMPLEMENTED(c.static_anchor_associations != false);
|
||||
}
|
||||
|
||||
static void vp_print(const char* func, const ScreenViewport& vp)
|
||||
{
|
||||
printf("%s\n", func);
|
||||
@@ -788,14 +828,16 @@ static void vp_check(const ScreenViewport& vp)
|
||||
|
||||
static void hw_check(const HardwareContext& hw)
|
||||
{
|
||||
const auto& rt = hw.GetRenderTargets(0);
|
||||
const auto& bc = hw.GetBlendControl(0);
|
||||
const auto& vp = hw.GetScreenViewport();
|
||||
const auto& z = hw.GetDepthRenderTarget();
|
||||
const auto& c = hw.GetClipControl();
|
||||
const auto& rc = hw.GetRenderControl();
|
||||
const auto& d = hw.GetDepthControl();
|
||||
const auto& mc = hw.GetModeControl();
|
||||
const auto& rt = hw.GetRenderTargets(0);
|
||||
const auto& bc = hw.GetBlendControl(0);
|
||||
const auto& bclr = hw.GetBlendColor();
|
||||
const auto& vp = hw.GetScreenViewport();
|
||||
const auto& z = hw.GetDepthRenderTarget();
|
||||
const auto& c = hw.GetClipControl();
|
||||
const auto& rc = hw.GetRenderControl();
|
||||
const auto& d = hw.GetDepthControl();
|
||||
const auto& mc = hw.GetModeControl();
|
||||
const auto& eqaa = hw.GetEqaaControl();
|
||||
|
||||
rt_check(rt);
|
||||
vp_check(vp);
|
||||
@@ -804,7 +846,8 @@ static void hw_check(const HardwareContext& hw)
|
||||
rc_check(rc);
|
||||
d_check(d);
|
||||
mc_check(mc);
|
||||
bc_check(bc);
|
||||
bc_check(bc, bclr);
|
||||
eqaa_check(eqaa);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(hw.GetRenderTargetMask() != 0xF && hw.GetRenderTargetMask() != 0x0);
|
||||
EXIT_NOT_IMPLEMENTED(hw.GetDepthClearValue() != 0.0f && hw.GetDepthClearValue() != 1.0f);
|
||||
@@ -812,14 +855,16 @@ static void hw_check(const HardwareContext& hw)
|
||||
|
||||
static void hw_print(const HardwareContext& hw)
|
||||
{
|
||||
const auto& rt = hw.GetRenderTargets(0);
|
||||
const auto& bc = hw.GetBlendControl(0);
|
||||
const auto& vp = hw.GetScreenViewport();
|
||||
const auto& z = hw.GetDepthRenderTarget();
|
||||
const auto& c = hw.GetClipControl();
|
||||
const auto& rc = hw.GetRenderControl();
|
||||
const auto& d = hw.GetDepthControl();
|
||||
const auto& mc = hw.GetModeControl();
|
||||
const auto& rt = hw.GetRenderTargets(0);
|
||||
const auto& bc = hw.GetBlendControl(0);
|
||||
const auto& bclr = hw.GetBlendColor();
|
||||
const auto& vp = hw.GetScreenViewport();
|
||||
const auto& z = hw.GetDepthRenderTarget();
|
||||
const auto& c = hw.GetClipControl();
|
||||
const auto& rc = hw.GetRenderControl();
|
||||
const auto& d = hw.GetDepthControl();
|
||||
const auto& mc = hw.GetModeControl();
|
||||
const auto& eqaa = hw.GetEqaaControl();
|
||||
|
||||
printf("HardwareContext\n");
|
||||
printf("\t GetRenderTargetMask() = 0x%08" PRIx32 "\n", hw.GetRenderTargetMask());
|
||||
@@ -832,7 +877,8 @@ static void hw_print(const HardwareContext& hw)
|
||||
rc_print("RenderControl:", rc);
|
||||
d_print("DepthControl:", d);
|
||||
mc_print("ModeControl:", mc);
|
||||
bc_print("BlendControl:", bc);
|
||||
bc_print("BlendControl:", bc, bclr);
|
||||
eqaa_print("EqaaControl:", eqaa);
|
||||
}
|
||||
|
||||
void GraphicsRenderInit()
|
||||
@@ -1749,10 +1795,10 @@ static VulkanPipeline* CreatePipelineInternal(VkRenderPass render_pass, const Sh
|
||||
color_blending.logicOp = VK_LOGIC_OP_COPY;
|
||||
color_blending.attachmentCount = 1;
|
||||
color_blending.pAttachments = &color_blend_attachment;
|
||||
color_blending.blendConstants[0] = 0.0f;
|
||||
color_blending.blendConstants[1] = 0.0f;
|
||||
color_blending.blendConstants[2] = 0.0f;
|
||||
color_blending.blendConstants[3] = 0.0f;
|
||||
color_blending.blendConstants[0] = params->blend_color_red;
|
||||
color_blending.blendConstants[1] = params->blend_color_green;
|
||||
color_blending.blendConstants[2] = params->blend_color_blue;
|
||||
color_blending.blendConstants[3] = params->blend_color_alpha;
|
||||
|
||||
VkDescriptorSetLayout set_layouts[2] = {};
|
||||
uint32_t set_layouts_num = 0;
|
||||
@@ -1957,7 +2003,7 @@ VulkanPipeline* PipelineCache::CreatePipeline(VulkanFramebuffer* framebuffer, Re
|
||||
const ShaderVertexInputInfo* vs_input_info, const VertexShaderInfo* vs_regs,
|
||||
const ShaderPixelInputInfo* ps_input_info, const PixelShaderInfo* ps_regs,
|
||||
VkPrimitiveTopology topology, uint32_t color_mask, const ModeControl& mc,
|
||||
const BlendControl& bc, const ScreenViewport& vp)
|
||||
const BlendControl& bc, const BlendColor& bclr, const ScreenViewport& vp)
|
||||
{
|
||||
KYTY_PROFILER_BLOCK("PipelineCache::CreatePipeline(Gfx)", profiler::colors::DeepOrangeA200);
|
||||
|
||||
@@ -2012,6 +2058,10 @@ VulkanPipeline* PipelineCache::CreatePipeline(VulkanFramebuffer* framebuffer, Re
|
||||
p.params->alpha_destblend = bc.alpha_destblend;
|
||||
p.params->separate_alpha_blend = bc.separate_alpha_blend;
|
||||
p.params->blend_enable = bc.enable;
|
||||
p.params->blend_color_red = bclr.red;
|
||||
p.params->blend_color_green = bclr.green;
|
||||
p.params->blend_color_blue = bclr.blue;
|
||||
p.params->blend_color_alpha = bclr.alpha;
|
||||
|
||||
auto* found = Find(p);
|
||||
|
||||
@@ -2869,12 +2919,13 @@ static void FindRenderColorInfo(const HardwareContext& hw, RenderColorInfo* r)
|
||||
|
||||
if (rt.base_addr != 0)
|
||||
{
|
||||
auto width = rt.width;
|
||||
auto height = rt.height;
|
||||
auto pitch = (rt.pitch_div8_minus1 + 1) * 8;
|
||||
auto size = (rt.slice_div64_minus1 + 1) * 64 * 4;
|
||||
bool tile = false;
|
||||
uint32_t format = 0;
|
||||
auto width = rt.width;
|
||||
auto height = rt.height;
|
||||
auto pitch = (rt.pitch_div8_minus1 + 1) * 8;
|
||||
auto size = (rt.slice_div64_minus1 + 1) * 64 * 4;
|
||||
bool tile = false;
|
||||
uint32_t format = 0;
|
||||
bool render_to_texture = false;
|
||||
|
||||
if (rt.tile_mode == 0x8)
|
||||
{
|
||||
@@ -2882,38 +2933,48 @@ static void FindRenderColorInfo(const HardwareContext& hw, RenderColorInfo* r)
|
||||
} else if (rt.tile_mode == 0xa)
|
||||
{
|
||||
tile = true;
|
||||
} else if (rt.tile_mode == 0xd)
|
||||
{
|
||||
tile = true;
|
||||
render_to_texture = true;
|
||||
} else
|
||||
{
|
||||
EXIT("unknown tile mode: %u\n", rt.tile_mode);
|
||||
}
|
||||
|
||||
if (rt.format == 0xa && rt.channel_type == 0x6 && rt.channel_order == 0x1)
|
||||
if (render_to_texture)
|
||||
{
|
||||
format = 0x80000000;
|
||||
EXIT("not implemented");
|
||||
} else
|
||||
{
|
||||
EXIT("unknown format");
|
||||
}
|
||||
if (rt.format == 0xa && rt.channel_type == 0x6 && rt.channel_order == 0x1)
|
||||
{
|
||||
format = 0x80000000;
|
||||
} else
|
||||
{
|
||||
EXIT("unknown format");
|
||||
}
|
||||
|
||||
auto video_image = VideoOut::VideoOutGetImage(rt.base_addr);
|
||||
if (video_image.image == nullptr)
|
||||
{
|
||||
// Offscreen buffer
|
||||
VideoOutBufferObject vulkan_buffer_info(format, width, height, tile, Config::IsNeo(), pitch);
|
||||
auto* buffer_vulkan = static_cast<Graphics::VideoOutVulkanImage*>(
|
||||
Graphics::GpuMemoryGetObject(g_render_ctx->GetGraphicCtx(), rt.base_addr, size, vulkan_buffer_info));
|
||||
EXIT_NOT_IMPLEMENTED(buffer_vulkan == nullptr);
|
||||
r->base_addr = rt.base_addr;
|
||||
r->vulkan_buffer = buffer_vulkan;
|
||||
r->buffer_size = size;
|
||||
} else
|
||||
{
|
||||
// Display buffer
|
||||
EXIT_NOT_IMPLEMENTED(video_image.buffer_size != size);
|
||||
EXIT_NOT_IMPLEMENTED(video_image.buffer_pitch != pitch);
|
||||
r->base_addr = rt.base_addr;
|
||||
r->vulkan_buffer = video_image.image;
|
||||
r->buffer_size = video_image.buffer_size;
|
||||
auto video_image = VideoOut::VideoOutGetImage(rt.base_addr);
|
||||
if (video_image.image == nullptr)
|
||||
{
|
||||
// Offscreen buffer
|
||||
VideoOutBufferObject vulkan_buffer_info(format, width, height, tile, Config::IsNeo(), pitch);
|
||||
auto* buffer_vulkan = static_cast<Graphics::VideoOutVulkanImage*>(
|
||||
Graphics::GpuMemoryGetObject(g_render_ctx->GetGraphicCtx(), rt.base_addr, size, vulkan_buffer_info));
|
||||
EXIT_NOT_IMPLEMENTED(buffer_vulkan == nullptr);
|
||||
r->base_addr = rt.base_addr;
|
||||
r->vulkan_buffer = buffer_vulkan;
|
||||
r->buffer_size = size;
|
||||
} else
|
||||
{
|
||||
// Display buffer
|
||||
EXIT_NOT_IMPLEMENTED(video_image.buffer_size != size);
|
||||
EXIT_NOT_IMPLEMENTED(video_image.buffer_pitch != pitch);
|
||||
r->base_addr = rt.base_addr;
|
||||
r->vulkan_buffer = video_image.image;
|
||||
r->buffer_size = video_image.buffer_size;
|
||||
}
|
||||
}
|
||||
} else
|
||||
{
|
||||
@@ -3269,9 +3330,10 @@ void GraphicsRenderDrawIndex(CommandBuffer* buffer, HardwareContext* ctx, UserCo
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(vs_input_info.buffers_num > 1);
|
||||
|
||||
auto* pipeline = g_render_ctx->GetPipelineCache()->CreatePipeline(
|
||||
framebuffer, &color_info, &depth_info, &vs_input_info, &ctx->GetVs(), &ps_input_info, &ctx->GetPs(),
|
||||
VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, ctx->GetRenderTargetMask(), ctx->GetModeControl(), bc, ctx->GetScreenViewport());
|
||||
auto* pipeline = g_render_ctx->GetPipelineCache()->CreatePipeline(framebuffer, &color_info, &depth_info, &vs_input_info, &ctx->GetVs(),
|
||||
&ps_input_info, &ctx->GetPs(), VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
|
||||
ctx->GetRenderTargetMask(), ctx->GetModeControl(), bc,
|
||||
ctx->GetBlendColor(), ctx->GetScreenViewport());
|
||||
|
||||
vkCmdBindPipeline(vk_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->pipeline);
|
||||
|
||||
@@ -3376,7 +3438,7 @@ void GraphicsRenderDrawIndexAuto(CommandBuffer* buffer, HardwareContext* ctx, Us
|
||||
|
||||
auto* pipeline = g_render_ctx->GetPipelineCache()->CreatePipeline(
|
||||
framebuffer, &color_info, &depth_info, &vs_input_info, &vertex_shader_info, &ps_input_info, &pixel_shader_info, topology,
|
||||
ctx->GetRenderTargetMask(), ctx->GetModeControl(), bc, ctx->GetScreenViewport());
|
||||
ctx->GetRenderTargetMask(), ctx->GetModeControl(), bc, ctx->GetBlendColor(), ctx->GetScreenViewport());
|
||||
|
||||
vkCmdBindPipeline(vk_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->pipeline);
|
||||
|
||||
|
||||
@@ -1455,6 +1455,27 @@ KYTY_HW_CTX_PARSER(hw_ctx_set_depth_control)
|
||||
return 1;
|
||||
}
|
||||
|
||||
KYTY_HW_CTX_PARSER(hw_ctx_set_eqaa_control)
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0016900);
|
||||
EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::DB_EQAA);
|
||||
|
||||
EqaaControl r;
|
||||
|
||||
r.max_anchor_samples = KYTY_PM4_GET(buffer[0], DB_EQAA, MAX_ANCHOR_SAMPLES);
|
||||
r.ps_iter_samples = KYTY_PM4_GET(buffer[0], DB_EQAA, PS_ITER_SAMPLES);
|
||||
r.mask_export_num_samples = KYTY_PM4_GET(buffer[0], DB_EQAA, MASK_EXPORT_NUM_SAMPLES);
|
||||
r.alpha_to_mask_num_samples = KYTY_PM4_GET(buffer[0], DB_EQAA, ALPHA_TO_MASK_NUM_SAMPLES);
|
||||
r.high_quality_intersections = KYTY_PM4_GET(buffer[0], DB_EQAA, HIGH_QUALITY_INTERSECTIONS) != 0;
|
||||
r.incoherent_eqaa_reads = KYTY_PM4_GET(buffer[0], DB_EQAA, INCOHERENT_EQAA_READS) != 0;
|
||||
r.interpolate_comp_z = KYTY_PM4_GET(buffer[0], DB_EQAA, INTERPOLATE_COMP_Z) != 0;
|
||||
r.static_anchor_associations = KYTY_PM4_GET(buffer[0], DB_EQAA, STATIC_ANCHOR_ASSOCIATIONS) != 0;
|
||||
|
||||
cp->GetCtx()->SetEqaaControl(r);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
KYTY_HW_CTX_PARSER(hw_ctx_set_depth_clear)
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0016900);
|
||||
@@ -1671,6 +1692,23 @@ KYTY_HW_CTX_PARSER(hw_ctx_set_guard_bands)
|
||||
return 4;
|
||||
}
|
||||
|
||||
KYTY_HW_CTX_PARSER(hw_ctx_set_blend_color)
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(cmd_id != 0xc0046900);
|
||||
EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::CB_BLEND_RED);
|
||||
|
||||
BlendColor r;
|
||||
|
||||
r.red = *reinterpret_cast<const float*>(&buffer[0]);
|
||||
r.green = *reinterpret_cast<const float*>(&buffer[1]);
|
||||
r.blue = *reinterpret_cast<const float*>(&buffer[2]);
|
||||
r.alpha = *reinterpret_cast<const float*>(&buffer[3]);
|
||||
|
||||
cp->GetCtx()->SetBlendColor(r);
|
||||
|
||||
return 4;
|
||||
}
|
||||
|
||||
KYTY_HW_CTX_PARSER(hw_ctx_set_vs_shader)
|
||||
{
|
||||
EXIT_NOT_IMPLEMENTED(cmd_id != 0xC01B1004);
|
||||
@@ -2350,8 +2388,10 @@ static void graphics_init_jmp_tables()
|
||||
g_hw_ctx_func[Pm4::DB_STENCIL_INFO] = hw_ctx_set_stencil_info;
|
||||
g_hw_ctx_func[0x08d] = hw_ctx_hardware_screen_offset;
|
||||
g_hw_ctx_func[0x08e] = hw_ctx_set_render_target_mask;
|
||||
g_hw_ctx_func[Pm4::CB_BLEND_RED] = hw_ctx_set_blend_color;
|
||||
g_hw_ctx_func[Pm4::SPI_PS_INPUT_CNTL_0] = hw_ctx_set_ps_input;
|
||||
g_hw_ctx_func[Pm4::DB_DEPTH_CONTROL] = hw_ctx_set_depth_control;
|
||||
g_hw_ctx_func[Pm4::DB_EQAA] = hw_ctx_set_eqaa_control;
|
||||
g_hw_ctx_func[0x204] = hw_ctx_set_clip_control;
|
||||
g_hw_ctx_func[Pm4::PA_SU_SC_MODE_CNTL] = hw_ctx_set_mode_control;
|
||||
g_hw_ctx_func[0x206] = hw_ctx_set_viewport_transform_control;
|
||||
|
||||
@@ -39,6 +39,9 @@ static void init_names()
|
||||
g_r_names[R_PUSH_MARKER] = "R_PUSH_MARKER";
|
||||
g_r_names[R_POP_MARKER] = "R_POP_MARKER";
|
||||
g_r_names[R_VS_EMBEDDED] = "R_VS_EMBEDDED";
|
||||
g_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_names[IT_NOP] = "IT_NOP";
|
||||
g_names[IT_SET_BASE] = "IT_SET_BASE";
|
||||
|
||||
@@ -2205,7 +2205,7 @@ static void ShaderGetTextureBuffer(ShaderTextureResources* info, int start_index
|
||||
EXIT_IF(info == nullptr);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(info->textures_num < 0 || info->textures_num >= ShaderTextureResources::RES_MAX);
|
||||
EXIT_NOT_IMPLEMENTED(info->textures_num != slot);
|
||||
// EXIT_NOT_IMPLEMENTED(info->textures_num != slot);
|
||||
|
||||
int index = info->textures_num;
|
||||
bool extended = (extended_buffer != nullptr);
|
||||
@@ -2215,6 +2215,7 @@ static void ShaderGetTextureBuffer(ShaderTextureResources* info, int start_index
|
||||
|
||||
info->start_register[index] = start_index;
|
||||
info->extended[index] = extended;
|
||||
info->slots[index] = slot;
|
||||
|
||||
if (!extended)
|
||||
{
|
||||
@@ -2243,7 +2244,7 @@ static void ShaderGetSampler(ShaderSamplerResources* info, int start_index, int
|
||||
EXIT_IF(info == nullptr);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(info->samplers_num < 0 || info->samplers_num >= ShaderSamplerResources::RES_MAX);
|
||||
EXIT_NOT_IMPLEMENTED(info->samplers_num != slot);
|
||||
// EXIT_NOT_IMPLEMENTED(info->samplers_num != slot);
|
||||
|
||||
int index = info->samplers_num;
|
||||
bool extended = (extended_buffer != nullptr);
|
||||
@@ -2253,6 +2254,7 @@ static void ShaderGetSampler(ShaderSamplerResources* info, int start_index, int
|
||||
|
||||
info->start_register[index] = start_index;
|
||||
info->extended[index] = extended;
|
||||
info->slots[index] = slot;
|
||||
|
||||
if (!extended)
|
||||
{
|
||||
@@ -2277,7 +2279,7 @@ static void ShaderGetGdsPointer(ShaderGdsResources* info, int start_index, int s
|
||||
EXIT_IF(info == nullptr);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(info->pointers_num < 0 || info->pointers_num >= ShaderGdsResources::POINTERS_MAX);
|
||||
EXIT_NOT_IMPLEMENTED(info->pointers_num != slot);
|
||||
// EXIT_NOT_IMPLEMENTED(info->pointers_num != slot);
|
||||
|
||||
int index = info->pointers_num;
|
||||
bool extended = (extended_buffer != nullptr);
|
||||
@@ -2287,6 +2289,7 @@ static void ShaderGetGdsPointer(ShaderGdsResources* info, int start_index, int s
|
||||
|
||||
info->start_register[index] = start_index;
|
||||
info->extended[index] = extended;
|
||||
info->slots[index] = slot;
|
||||
|
||||
if (!extended)
|
||||
{
|
||||
@@ -2514,9 +2517,16 @@ void ShaderGetInputInfoCS(const ComputeShaderInfo* regs, ShaderComputeInputInfo*
|
||||
switch (usage.type)
|
||||
{
|
||||
case 0x00:
|
||||
EXIT_NOT_IMPLEMENTED(usage.flags != 0);
|
||||
ShaderGetStorageBuffer(&info->bind.storage_buffers, usage.start_register, usage.slot, ShaderStorageUsage::ReadOnly,
|
||||
regs->cs_user_sgpr, extended_buffer);
|
||||
EXIT_NOT_IMPLEMENTED(usage.flags != 0 && usage.flags != 3);
|
||||
if (usage.flags == 0)
|
||||
{
|
||||
ShaderGetStorageBuffer(&info->bind.storage_buffers, usage.start_register, usage.slot, ShaderStorageUsage::ReadOnly,
|
||||
regs->cs_user_sgpr, extended_buffer);
|
||||
} else if (usage.flags == 3)
|
||||
{
|
||||
ShaderGetTextureBuffer(&info->bind.textures2D, usage.start_register, usage.slot, regs->cs_user_sgpr, extended_buffer);
|
||||
EXIT_NOT_IMPLEMENTED(info->bind.textures2D.textures[info->bind.textures2D.textures_num - 1].Type() != 9);
|
||||
}
|
||||
break;
|
||||
case 0x02:
|
||||
EXIT_NOT_IMPLEMENTED(usage.flags != 0);
|
||||
@@ -2627,6 +2637,7 @@ static void ShaderDbgDumpResources(const ShaderBindResources& bind)
|
||||
printf("\t\t MinLodWarn() = %" PRIu16 "\n", r.MinLodWarn());
|
||||
printf("\t\t CounterBankId() = %" PRIu8 "\n", r.CounterBankId());
|
||||
printf("\t\t LodHdwCntEn() = %s\n", r.LodHdwCntEn() ? "true" : "false");
|
||||
printf("\t\t slot = %d\n", bind.textures2D.slots[i]);
|
||||
printf("\t\t start_register = %d\n", bind.textures2D.start_register[i]);
|
||||
printf("\t\t extended = %s\n", (bind.textures2D.extended[i] ? "true" : "false"));
|
||||
}
|
||||
@@ -2664,6 +2675,7 @@ static void ShaderDbgDumpResources(const ShaderBindResources& bind)
|
||||
printf("\t\t MipFilter() = %" PRIu8 "\n", r.MipFilter());
|
||||
printf("\t\t BorderColorPtr() = %" PRIu16 "\n", r.BorderColorPtr());
|
||||
printf("\t\t BorderColorType() = %" PRIu8 "\n", r.BorderColorType());
|
||||
printf("\t\t slot = %d\n", bind.samplers.slots[i]);
|
||||
printf("\t\t start_register = %d\n", bind.samplers.start_register[i]);
|
||||
printf("\t\t extended = %s\n", (bind.samplers.extended[i] ? "true" : "false"));
|
||||
}
|
||||
@@ -3208,6 +3220,7 @@ static void ShaderGetBindIds(ShaderId* ret, const ShaderBindResources& bind)
|
||||
ret->ids.Add(r.MinLodWarn());
|
||||
ret->ids.Add(r.CounterBankId());
|
||||
ret->ids.Add(static_cast<uint32_t>(r.LodHdwCntEn()));
|
||||
ret->ids.Add(bind.textures2D.slots[i]);
|
||||
ret->ids.Add(bind.textures2D.start_register[i]);
|
||||
ret->ids.Add(static_cast<uint32_t>(bind.textures2D.extended[i]));
|
||||
}
|
||||
@@ -3243,6 +3256,7 @@ static void ShaderGetBindIds(ShaderId* ret, const ShaderBindResources& bind)
|
||||
ret->ids.Add(r.MipFilter());
|
||||
ret->ids.Add(r.BorderColorPtr());
|
||||
ret->ids.Add(r.BorderColorType());
|
||||
ret->ids.Add(bind.samplers.slots[i]);
|
||||
ret->ids.Add(bind.samplers.start_register[i]);
|
||||
ret->ids.Add(static_cast<uint32_t>(bind.samplers.extended[i]));
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ public:
|
||||
int prot;
|
||||
VirtualMemory::Mode mode;
|
||||
Graphics::GpuMemoryMode gpu_mode;
|
||||
int memory_type;
|
||||
};
|
||||
|
||||
PhysicalMemory() { EXIT_NOT_IMPLEMENTED(!Core::Thread::IsMainThread()); }
|
||||
@@ -44,11 +45,12 @@ public:
|
||||
|
||||
static uint64_t Size() { return static_cast<uint64_t>(5376) * 1024 * 1024; }
|
||||
|
||||
bool Alloc(uint64_t search_start, uint64_t search_end, size_t len, size_t alignment, uint64_t* phys_addr_out);
|
||||
bool Alloc(uint64_t search_start, uint64_t search_end, size_t len, size_t alignment, uint64_t* phys_addr_out, int memory_type);
|
||||
bool Release(uint64_t start, size_t len, uint64_t* vaddr, uint64_t* size, Graphics::GpuMemoryMode* gpu_mode);
|
||||
bool Map(uint64_t vaddr, uint64_t phys_addr, size_t len, int prot, VirtualMemory::Mode mode, Graphics::GpuMemoryMode gpu_mode);
|
||||
bool Unmap(uint64_t vaddr, uint64_t size, Graphics::GpuMemoryMode* gpu_mode);
|
||||
bool Find(uint64_t vaddr, uint64_t* base_addr, size_t* len, int* prot, VirtualMemory::Mode* mode, Graphics::GpuMemoryMode* gpu_mode);
|
||||
bool Find(uint64_t phys_addr, bool next, PhysicalMemory::AllocatedBlock* out);
|
||||
|
||||
private:
|
||||
Vector<AllocatedBlock> m_allocated;
|
||||
@@ -99,7 +101,8 @@ static uint64_t get_aligned_pos(uint64_t pos, size_t align)
|
||||
return (align != 0 ? (pos + (align - 1)) & ~(align - 1) : pos);
|
||||
}
|
||||
|
||||
bool PhysicalMemory::Alloc(uint64_t search_start, uint64_t search_end, size_t len, size_t alignment, uint64_t* phys_addr_out)
|
||||
bool PhysicalMemory::Alloc(uint64_t search_start, uint64_t search_end, size_t len, size_t alignment, uint64_t* phys_addr_out,
|
||||
int memory_type)
|
||||
{
|
||||
if (phys_addr_out == nullptr)
|
||||
{
|
||||
@@ -124,13 +127,14 @@ bool PhysicalMemory::Alloc(uint64_t search_start, uint64_t search_end, size_t le
|
||||
if (free_pos >= search_start && free_pos + len <= search_end)
|
||||
{
|
||||
AllocatedBlock b {};
|
||||
b.size = len;
|
||||
b.start_addr = free_pos;
|
||||
b.gpu_mode = Graphics::GpuMemoryMode::NoAccess;
|
||||
b.map_size = 0;
|
||||
b.map_vaddr = 0;
|
||||
b.prot = 0;
|
||||
b.mode = VirtualMemory::Mode::NoAccess;
|
||||
b.size = len;
|
||||
b.start_addr = free_pos;
|
||||
b.gpu_mode = Graphics::GpuMemoryMode::NoAccess;
|
||||
b.map_size = 0;
|
||||
b.map_vaddr = 0;
|
||||
b.prot = 0;
|
||||
b.mode = VirtualMemory::Mode::NoAccess;
|
||||
b.memory_type = memory_type;
|
||||
|
||||
m_allocated.Add(b);
|
||||
|
||||
@@ -219,6 +223,43 @@ bool PhysicalMemory::Unmap(uint64_t vaddr, uint64_t size, Graphics::GpuMemoryMod
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PhysicalMemory::Find(uint64_t phys_addr, bool next, AllocatedBlock* out)
|
||||
{
|
||||
EXIT_IF(out == nullptr);
|
||||
|
||||
Core::LockGuard lock(m_mutex);
|
||||
|
||||
for (auto& b: m_allocated)
|
||||
{
|
||||
if (phys_addr >= b.start_addr && phys_addr < b.start_addr + b.size)
|
||||
{
|
||||
*out = b;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (next)
|
||||
{
|
||||
uint64_t min_start_addr = UINT64_MAX;
|
||||
AllocatedBlock* next = nullptr;
|
||||
for (auto& b: m_allocated)
|
||||
{
|
||||
if (b.start_addr > phys_addr && b.start_addr < min_start_addr)
|
||||
{
|
||||
min_start_addr = b.start_addr;
|
||||
next = &b;
|
||||
}
|
||||
}
|
||||
if (next != nullptr)
|
||||
{
|
||||
*out = *next;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PhysicalMemory::Find(uint64_t vaddr, uint64_t* base_addr, size_t* len, int* prot, VirtualMemory::Mode* mode,
|
||||
Graphics::GpuMemoryMode* gpu_mode)
|
||||
{
|
||||
@@ -428,6 +469,49 @@ size_t KYTY_SYSV_ABI KernelGetDirectMemorySize()
|
||||
return PhysicalMemory::Size();
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI KernelDirectMemoryQuery(int64_t offset, int flags, void* info, size_t info_size)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
EXIT_IF(g_physical_memory == nullptr);
|
||||
|
||||
printf("\t offset = 0x%016" PRIx64 "\n", offset);
|
||||
printf("\t flags = 0x%08" PRIx32 "\n", flags);
|
||||
printf("\t info_size = 0x%016" PRIx64 "\n", info_size);
|
||||
|
||||
struct QueryInfo
|
||||
{
|
||||
int64_t start;
|
||||
int64_t end;
|
||||
int memory_type;
|
||||
};
|
||||
|
||||
if (offset < 0 || info_size != sizeof(QueryInfo) || info == nullptr)
|
||||
{
|
||||
return KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
|
||||
PhysicalMemory::AllocatedBlock block {};
|
||||
if (!g_physical_memory->Find(offset, flags != 0, &block))
|
||||
{
|
||||
printf(FG_RED "\t[Fail]\n" FG_DEFAULT);
|
||||
return KERNEL_ERROR_EACCES;
|
||||
}
|
||||
|
||||
auto* query_info = static_cast<QueryInfo*>(info);
|
||||
|
||||
query_info->start = static_cast<int64_t>(block.start_addr);
|
||||
query_info->end = static_cast<int64_t>(block.start_addr + block.size);
|
||||
query_info->memory_type = block.memory_type;
|
||||
|
||||
printf("\t start = %016" PRIx64 "\n", query_info->start);
|
||||
printf("\t end = %016" PRIx64 "\n", query_info->end);
|
||||
printf("\t memory_type = %d\n", query_info->memory_type);
|
||||
printf(FG_GREEN "\t[Ok]\n" FG_DEFAULT);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -447,7 +531,7 @@ int KYTY_SYSV_ABI KernelAllocateDirectMemory(int64_t search_start, int64_t searc
|
||||
}
|
||||
|
||||
uint64_t addr = 0;
|
||||
if (!g_physical_memory->Alloc(search_start, search_end, len, alignment, &addr))
|
||||
if (!g_physical_memory->Alloc(search_start, search_end, len, alignment, &addr, memory_type))
|
||||
{
|
||||
printf(FG_RED "\t[Fail]\n" FG_DEFAULT);
|
||||
return KERNEL_ERROR_EAGAIN;
|
||||
|
||||
@@ -23,10 +23,15 @@
|
||||
#include <pthread.h>
|
||||
#include <pthread_time.h>
|
||||
|
||||
namespace Kyty::Libs::LibKernel {
|
||||
namespace Kyty::Libs {
|
||||
|
||||
namespace LibKernel {
|
||||
|
||||
LIB_NAME("libkernel", "libkernel");
|
||||
|
||||
constexpr int KEYS_MAX = 256;
|
||||
constexpr int DESTRUCTOR_ITERATIONS = 4;
|
||||
|
||||
struct PthreadMutexPrivate
|
||||
{
|
||||
uint8_t reserved[256];
|
||||
@@ -123,6 +128,38 @@ private:
|
||||
Core::Mutex m_mutex;
|
||||
};
|
||||
|
||||
class PthreadKeys
|
||||
{
|
||||
public:
|
||||
PthreadKeys() { EXIT_NOT_IMPLEMENTED(!Core::Thread::IsMainThread()); }
|
||||
virtual ~PthreadKeys() { KYTY_NOT_IMPLEMENTED; }
|
||||
|
||||
KYTY_CLASS_NO_COPY(PthreadKeys);
|
||||
|
||||
bool Create(int* key, pthread_key_destructor_func_t destructor);
|
||||
bool Delete(int key);
|
||||
void Destruct(int thread_id);
|
||||
bool Set(int key, int thread_id, void* data);
|
||||
bool Get(int key, int thread_id, void** data);
|
||||
|
||||
private:
|
||||
struct Map
|
||||
{
|
||||
int thread_id = -1;
|
||||
void* data = nullptr;
|
||||
};
|
||||
|
||||
struct Key
|
||||
{
|
||||
bool used = false;
|
||||
pthread_key_destructor_func_t destructor = nullptr;
|
||||
Vector<Map> specific_values;
|
||||
};
|
||||
|
||||
Core::Mutex m_mutex;
|
||||
Key m_keys[KEYS_MAX];
|
||||
};
|
||||
|
||||
class PthreadPool
|
||||
{
|
||||
public:
|
||||
@@ -160,18 +197,21 @@ public:
|
||||
void SetPthreadPool(PthreadPool* pool) { m_pthread_pool = pool; }
|
||||
PthreadStaticObjects* GetPthreadStaticObjects() { return m_pthread_static_objects; }
|
||||
void SetPthreadStaticObjects(PthreadStaticObjects* objs) { m_pthread_static_objects = objs; }
|
||||
PthreadKeys* GetPthreadKeys() { return m_pthread_keys; }
|
||||
void SetPthreadKeys(PthreadKeys* keys) { m_pthread_keys = keys; }
|
||||
|
||||
[[nodiscard]] thread_dtors_func_t GetThreadDtors() const { return m_thread_dtors; }
|
||||
void SetThreadDtors(thread_dtors_func_t dtors) { m_thread_dtors = dtors; }
|
||||
|
||||
private:
|
||||
Core::Mutex m_mutex;
|
||||
// Core::Mutex m_mutex;
|
||||
PthreadMutexattr m_default_mutexattr = nullptr;
|
||||
PthreadRwlockattr m_default_rwlockattr = nullptr;
|
||||
PthreadCondattr m_default_condattr = nullptr;
|
||||
PthreadAttr m_default_attr = nullptr;
|
||||
PthreadPool* m_pthread_pool = nullptr;
|
||||
PthreadStaticObjects* m_pthread_static_objects = nullptr;
|
||||
PthreadKeys* m_pthread_keys = nullptr;
|
||||
|
||||
std::atomic<thread_dtors_func_t> m_thread_dtors = nullptr;
|
||||
};
|
||||
@@ -233,6 +273,7 @@ KYTY_SUBSYSTEM_INIT(Pthread)
|
||||
|
||||
g_pthread_context->SetPthreadStaticObjects(new PthreadStaticObjects);
|
||||
g_pthread_context->SetPthreadPool(new PthreadPool);
|
||||
g_pthread_context->SetPthreadKeys(new PthreadKeys);
|
||||
|
||||
PthreadMutexattr default_mutexattr = nullptr;
|
||||
PthreadRwlockattr default_rwlockattr = nullptr;
|
||||
@@ -461,6 +502,131 @@ void PthreadPool::FreeDetachedThreads()
|
||||
}
|
||||
}
|
||||
|
||||
bool PthreadKeys::Create(int* key, pthread_key_destructor_func_t destructor)
|
||||
{
|
||||
EXIT_IF(key == nullptr);
|
||||
|
||||
Core::LockGuard lock(m_mutex);
|
||||
|
||||
for (int index = 0; index < KEYS_MAX; index++)
|
||||
{
|
||||
if (!m_keys[index].used)
|
||||
{
|
||||
*key = index;
|
||||
m_keys[index].used = true;
|
||||
m_keys[index].destructor = destructor;
|
||||
m_keys[index].specific_values.Clear();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PthreadKeys::Delete(int key)
|
||||
{
|
||||
Core::LockGuard lock(m_mutex);
|
||||
|
||||
if (key < 0 || key >= KEYS_MAX || !m_keys[key].used)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
m_keys[key].used = false;
|
||||
m_keys[key].destructor = nullptr;
|
||||
m_keys[key].specific_values.Clear();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void PthreadKeys::Destruct(int thread_id)
|
||||
{
|
||||
Core::LockGuard lock(m_mutex);
|
||||
|
||||
struct CallInfo
|
||||
{
|
||||
pthread_key_destructor_func_t destructor;
|
||||
void* data;
|
||||
};
|
||||
|
||||
for (int iter = 0; iter < DESTRUCTOR_ITERATIONS; iter++)
|
||||
{
|
||||
Vector<CallInfo> delete_list;
|
||||
|
||||
for (auto& key: m_keys)
|
||||
{
|
||||
if (key.used && key.destructor != nullptr)
|
||||
{
|
||||
for (auto& v: key.specific_values)
|
||||
{
|
||||
if (v.thread_id == thread_id && v.data != nullptr)
|
||||
{
|
||||
delete_list.Add(CallInfo({key.destructor, v.data}));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (delete_list.IsEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto& d: delete_list)
|
||||
{
|
||||
d.destructor(d.data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool PthreadKeys::Set(int key, int thread_id, void* data)
|
||||
{
|
||||
Core::LockGuard lock(m_mutex);
|
||||
|
||||
if (key < 0 || key >= KEYS_MAX || !m_keys[key].used)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (auto& v: m_keys[key].specific_values)
|
||||
{
|
||||
if (v.thread_id == thread_id)
|
||||
{
|
||||
v.data = data;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
m_keys[key].specific_values.Add(Map({thread_id, data}));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PthreadKeys::Get(int key, int thread_id, void** data)
|
||||
{
|
||||
EXIT_IF(data == nullptr);
|
||||
|
||||
Core::LockGuard lock(m_mutex);
|
||||
|
||||
if (key < 0 || key >= KEYS_MAX || !m_keys[key].used)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (auto& v: m_keys[key].specific_values)
|
||||
{
|
||||
if (v.thread_id == thread_id)
|
||||
{
|
||||
*data = v.data;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
*data = nullptr;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI PthreadMutexattrInit(PthreadMutexattr* attr)
|
||||
{
|
||||
// PRINT_NAME();
|
||||
@@ -548,7 +714,10 @@ int KYTY_SYSV_ABI PthreadMutexattrSetprotocol([[maybe_unused]] PthreadMutexattr*
|
||||
|
||||
int KYTY_SYSV_ABI PthreadMutexInit(PthreadMutex* mutex, const PthreadMutexattr* attr, const char* name)
|
||||
{
|
||||
PRINT_NAME();
|
||||
if (name != nullptr)
|
||||
{
|
||||
PRINT_NAME();
|
||||
}
|
||||
|
||||
// EXIT_NOT_IMPLEMENTED(!Core::Thread::IsMainThread());
|
||||
if (mutex == nullptr)
|
||||
@@ -569,7 +738,10 @@ int KYTY_SYSV_ABI PthreadMutexInit(PthreadMutex* mutex, const PthreadMutexattr*
|
||||
|
||||
int result = pthread_mutex_init(&(*mutex)->p, &(*attr)->p);
|
||||
|
||||
printf("\tmutex init: %s, %d\n", (*mutex)->name.C_Str(), result);
|
||||
if (name != nullptr)
|
||||
{
|
||||
printf("\tmutex init: %s, %d\n", (*mutex)->name.C_Str(), result);
|
||||
}
|
||||
|
||||
switch (result)
|
||||
{
|
||||
@@ -1867,6 +2039,8 @@ int KYTY_SYSV_ABI PthreadJoin(Pthread thread, void** value)
|
||||
auto* rt = Core::Singleton<Loader::RuntimeLinker>::Instance();
|
||||
rt->DeleteTlss(id);
|
||||
|
||||
g_pthread_context->GetPthreadKeys()->Destruct(id);
|
||||
|
||||
switch (result)
|
||||
{
|
||||
case 0: return OK;
|
||||
@@ -1898,6 +2072,20 @@ int KYTY_SYSV_ABI PthreadCancel(Pthread thread)
|
||||
}
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI PthreadSetaffinity(Pthread thread, KernelCpumask mask)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
if (thread == nullptr)
|
||||
{
|
||||
return KERNEL_ERROR_ESRCH;
|
||||
}
|
||||
|
||||
auto result = PthreadAttrSetaffinity(&thread->attr, mask);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI PthreadSetcancelstate(int state, int* old_state)
|
||||
{
|
||||
PRINT_NAME();
|
||||
@@ -1960,6 +2148,83 @@ int KYTY_SYSV_ABI PthreadSetcanceltype(int type, int* old_type)
|
||||
return KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI PthreadGetprio(Pthread thread, int* prio)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
if (thread == nullptr)
|
||||
{
|
||||
return KERNEL_ERROR_ESRCH;
|
||||
}
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(prio == nullptr);
|
||||
|
||||
sched_param param {};
|
||||
int pol = 0;
|
||||
|
||||
int result = pthread_getschedparam(thread->p, &pol, ¶m);
|
||||
|
||||
if (result == 0)
|
||||
{
|
||||
if (param.sched_priority <= -2)
|
||||
{
|
||||
*prio = 767;
|
||||
} else if (param.sched_priority >= +2)
|
||||
{
|
||||
*prio = 256;
|
||||
} else
|
||||
{
|
||||
*prio = 700;
|
||||
}
|
||||
|
||||
printf("\t PthreadGetprio: %d, %d\n", thread->unique_id, *prio);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
return KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI PthreadSetprio(Pthread thread, int prio)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
if (thread == nullptr)
|
||||
{
|
||||
return KERNEL_ERROR_ESRCH;
|
||||
}
|
||||
|
||||
sched_param param {};
|
||||
int pol = 0;
|
||||
|
||||
int result = pthread_getschedparam(thread->p, &pol, ¶m);
|
||||
|
||||
if (result == 0)
|
||||
{
|
||||
if (prio <= 478)
|
||||
{
|
||||
param.sched_priority = +2;
|
||||
} else if (prio >= 733)
|
||||
{
|
||||
param.sched_priority = -2;
|
||||
} else
|
||||
{
|
||||
param.sched_priority = 0;
|
||||
}
|
||||
|
||||
result = pthread_setschedparam(thread->p, pol, ¶m);
|
||||
|
||||
if (result == 0)
|
||||
{
|
||||
printf("\t PthreadSetprio: %d, %d\n", thread->unique_id, prio);
|
||||
|
||||
return OK;
|
||||
}
|
||||
}
|
||||
|
||||
return KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
|
||||
void KYTY_SYSV_ABI PthreadTestcancel()
|
||||
{
|
||||
PRINT_NAME();
|
||||
@@ -2126,84 +2391,6 @@ void KYTY_SYSV_ABI KernelSetThreadDtors(thread_dtors_func_t dtors)
|
||||
// g_thread_dtors = dtors;
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI pthread_cond_broadcast_s(PthreadCond* cond)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
// EXIT_IF(g_pthread_static_objects == nullptr);
|
||||
|
||||
// auto* obj = static_cast<PthreadCond*>(g_pthread_static_objects->CreateObject(cond, PthreadStaticObject::Type::Cond));
|
||||
|
||||
return PthreadCondBroadcast(cond);
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI pthread_cond_wait_s(PthreadCond* cond, PthreadMutex* mutex)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
// EXIT_IF(g_pthread_static_objects == nullptr);
|
||||
|
||||
// auto* obj_c = static_cast<PthreadCond*>(g_pthread_static_objects->CreateObject(cond, PthreadStaticObject::Type::Cond));
|
||||
// auto* obj_m = static_cast<PthreadMutex*>(g_pthread_static_objects->CreateObject(mutex, PthreadStaticObject::Type::Mutex));
|
||||
|
||||
return PthreadCondWait(cond, mutex);
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI pthread_mutex_lock_s(PthreadMutex* mutex)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
// EXIT_IF(g_pthread_static_objects == nullptr);
|
||||
|
||||
// auto* obj = static_cast<PthreadMutex*>(g_pthread_static_objects->CreateObject(mutex, PthreadStaticObject::Type::Mutex));
|
||||
|
||||
return PthreadMutexLock(mutex);
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI pthread_mutex_unlock_s(PthreadMutex* mutex)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
// EXIT_IF(g_pthread_static_objects == nullptr);
|
||||
|
||||
// auto* obj = static_cast<PthreadMutex*>(g_pthread_static_objects->CreateObject(mutex, PthreadStaticObject::Type::Mutex));
|
||||
|
||||
return PthreadMutexUnlock(mutex);
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI pthread_rwlock_rdlock_s(PthreadRwlock* rwlock)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
// EXIT_IF(g_pthread_static_objects == nullptr);
|
||||
|
||||
// auto* obj = static_cast<PthreadRwlock*>(g_pthread_static_objects->CreateObject(rwlock, PthreadStaticObject::Type::Rwlock));
|
||||
|
||||
return PthreadRwlockRdlock(rwlock);
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI pthread_rwlock_unlock_s(PthreadRwlock* rwlock)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
// EXIT_IF(g_pthread_static_objects == nullptr);
|
||||
|
||||
// auto* obj = static_cast<PthreadRwlock*>(g_pthread_static_objects->CreateObject(rwlock, PthreadStaticObject::Type::Rwlock));
|
||||
|
||||
return PthreadRwlockUnlock(rwlock);
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI pthread_rwlock_wrlock_s(PthreadRwlock* rwlock)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
// EXIT_IF(g_pthread_static_objects == nullptr);
|
||||
|
||||
// auto* obj = static_cast<PthreadRwlock*>(g_pthread_static_objects->CreateObject(rwlock, PthreadStaticObject::Type::Rwlock));
|
||||
|
||||
return PthreadRwlockWrlock(rwlock);
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI KernelUsleep(KernelUseconds microseconds)
|
||||
{
|
||||
PRINT_NAME();
|
||||
@@ -2256,6 +2443,179 @@ int KYTY_SYSV_ABI KernelNanosleep(const KernelTimespec* rqtp, KernelTimespec* rm
|
||||
return OK;
|
||||
}
|
||||
|
||||
} // namespace Kyty::Libs::LibKernel
|
||||
int KYTY_SYSV_ABI PthreadKeyCreate(PthreadKey* key, pthread_key_destructor_func_t destructor)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
if (key == nullptr)
|
||||
{
|
||||
return KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
|
||||
EXIT_IF(g_pthread_context == nullptr || g_pthread_context->GetPthreadKeys() == nullptr);
|
||||
|
||||
if (!g_pthread_context->GetPthreadKeys()->Create(key, destructor))
|
||||
{
|
||||
return KERNEL_ERROR_EAGAIN;
|
||||
}
|
||||
|
||||
printf("\t destructor = %016" PRIx64 "\n", reinterpret_cast<uint64_t>(destructor));
|
||||
printf("\t key = %d\n", *key);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI PthreadKeyDelete(PthreadKey key)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
printf("\t key = %d\n", key);
|
||||
|
||||
EXIT_IF(g_pthread_context == nullptr || g_pthread_context->GetPthreadKeys() == nullptr);
|
||||
|
||||
if (!g_pthread_context->GetPthreadKeys()->Delete(key))
|
||||
{
|
||||
return KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI PthreadSetspecific(PthreadKey key, void* value)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
int thread_id = Core::Thread::GetThreadIdUnique();
|
||||
|
||||
printf("\t key = %d\n", key);
|
||||
printf("\t thread_id = %d\n", thread_id);
|
||||
printf("\t value = %016" PRIx64 "\n", reinterpret_cast<uint64_t>(value));
|
||||
|
||||
EXIT_IF(g_pthread_context == nullptr || g_pthread_context->GetPthreadKeys() == nullptr);
|
||||
|
||||
if (!g_pthread_context->GetPthreadKeys()->Set(key, thread_id, value))
|
||||
{
|
||||
return KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
void* KYTY_SYSV_ABI PthreadGetspecific(PthreadKey key)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
int thread_id = Core::Thread::GetThreadIdUnique();
|
||||
|
||||
printf("\t key = %d\n", key);
|
||||
printf("\t thread_id = %d\n", thread_id);
|
||||
|
||||
EXIT_IF(g_pthread_context == nullptr || g_pthread_context->GetPthreadKeys() == nullptr);
|
||||
|
||||
void* value = nullptr;
|
||||
|
||||
if (!g_pthread_context->GetPthreadKeys()->Get(key, thread_id, &value))
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
printf("\t value = %016" PRIx64 "\n", reinterpret_cast<uint64_t>(value));
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
} // namespace LibKernel
|
||||
|
||||
namespace Posix {
|
||||
|
||||
LIB_NAME("Posix", "libkernel");
|
||||
|
||||
int KYTY_SYSV_ABI pthread_cond_broadcast(LibKernel::PthreadCond* cond)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
return POSIX_PTHREAD_CALL(LibKernel::PthreadCondBroadcast(cond));
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI pthread_cond_wait(LibKernel::PthreadCond* cond, LibKernel::PthreadMutex* mutex)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
return POSIX_PTHREAD_CALL(LibKernel::PthreadCondWait(cond, mutex));
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI pthread_mutex_lock(LibKernel::PthreadMutex* mutex)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
return POSIX_PTHREAD_CALL(LibKernel::PthreadMutexLock(mutex));
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI pthread_mutex_unlock(LibKernel::PthreadMutex* mutex)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
return POSIX_PTHREAD_CALL(LibKernel::PthreadMutexUnlock(mutex));
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI pthread_rwlock_rdlock(LibKernel::PthreadRwlock* rwlock)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
return POSIX_PTHREAD_CALL(LibKernel::PthreadRwlockRdlock(rwlock));
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI pthread_rwlock_unlock(LibKernel::PthreadRwlock* rwlock)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
return POSIX_PTHREAD_CALL(LibKernel::PthreadRwlockUnlock(rwlock));
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI pthread_rwlock_wrlock(LibKernel::PthreadRwlock* rwlock)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
return POSIX_PTHREAD_CALL(LibKernel::PthreadRwlockWrlock(rwlock));
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI pthread_key_create(LibKernel::PthreadKey* key, LibKernel::pthread_key_destructor_func_t destructor)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
return POSIX_PTHREAD_CALL(LibKernel::PthreadKeyCreate(key, destructor));
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI pthread_key_delete(LibKernel::PthreadKey key)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
return POSIX_PTHREAD_CALL(LibKernel::PthreadKeyDelete(key));
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI pthread_setspecific(LibKernel::PthreadKey key, void* value)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
return POSIX_PTHREAD_CALL(LibKernel::PthreadSetspecific(key, value));
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI pthread_mutex_destroy(LibKernel::PthreadMutex* mutex)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
return POSIX_PTHREAD_CALL(LibKernel::PthreadMutexDestroy(mutex));
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI pthread_mutex_init(LibKernel::PthreadMutex* mutex, const LibKernel::PthreadMutexattr* attr)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
return POSIX_PTHREAD_CALL(LibKernel::PthreadMutexInit(mutex, attr, nullptr));
|
||||
}
|
||||
|
||||
} // namespace Posix
|
||||
|
||||
} // namespace Kyty::Libs
|
||||
|
||||
#endif // KYTY_EMU_ENABLED
|
||||
|
||||
@@ -0,0 +1,379 @@
|
||||
#include "Emulator/Kernel/Semaphore.h"
|
||||
|
||||
#include "Kyty/Core/DbgAssert.h"
|
||||
#include "Kyty/Core/String.h"
|
||||
#include "Kyty/Core/Threads.h"
|
||||
#include "Kyty/Core/Timer.h"
|
||||
#include "Kyty/Core/Vector.h"
|
||||
|
||||
#include "Emulator/Libs/Errno.h"
|
||||
#include "Emulator/Libs/Libs.h"
|
||||
|
||||
#ifdef KYTY_EMU_ENABLED
|
||||
|
||||
namespace Kyty::Libs::LibKernel::Semaphore {
|
||||
|
||||
LIB_NAME("libkernel", "libkernel");
|
||||
|
||||
class KernelSemaPrivate
|
||||
{
|
||||
public:
|
||||
enum class Result
|
||||
{
|
||||
Ok,
|
||||
TimedOut,
|
||||
Canceled,
|
||||
Deleted,
|
||||
InvalCount
|
||||
};
|
||||
|
||||
KernelSemaPrivate(const String& name, bool fifo, int init_count, int max_count)
|
||||
: m_name(name), m_fifo_order(fifo), m_count(init_count), m_init_count(init_count), m_max_count(max_count) {};
|
||||
virtual ~KernelSemaPrivate();
|
||||
|
||||
KYTY_CLASS_NO_COPY(KernelSemaPrivate);
|
||||
|
||||
Result Cancel(int set_count, int* num_waiting_threads);
|
||||
Result Signal(int signal_count);
|
||||
Result Wait(int need_count, uint32_t* ptr_micros);
|
||||
|
||||
Result Poll(int need_count)
|
||||
{
|
||||
uint32_t micros = 0;
|
||||
return Wait(need_count, µs);
|
||||
}
|
||||
|
||||
[[nodiscard]] const String& GetName() const { return m_name; }
|
||||
|
||||
private:
|
||||
enum class Status
|
||||
{
|
||||
Set,
|
||||
Canceled,
|
||||
Deleted
|
||||
};
|
||||
|
||||
Core::Mutex m_mutex;
|
||||
Core::CondVar m_cond_var;
|
||||
String m_name;
|
||||
Status m_status = Status::Set;
|
||||
Vector<int> m_waiting_threads;
|
||||
[[maybe_unused]] bool m_fifo_order;
|
||||
int m_count;
|
||||
int m_init_count;
|
||||
int m_max_count;
|
||||
};
|
||||
|
||||
KernelSemaPrivate::~KernelSemaPrivate()
|
||||
{
|
||||
Core::LockGuard lock(m_mutex);
|
||||
|
||||
while (m_status != Status::Set)
|
||||
{
|
||||
m_mutex.Unlock();
|
||||
Core::Thread::SleepMicro(10);
|
||||
m_mutex.Lock();
|
||||
}
|
||||
|
||||
m_status = Status::Deleted;
|
||||
|
||||
m_cond_var.SignalAll();
|
||||
|
||||
while (!m_waiting_threads.IsEmpty())
|
||||
{
|
||||
m_mutex.Unlock();
|
||||
Core::Thread::SleepMicro(10);
|
||||
m_mutex.Lock();
|
||||
}
|
||||
}
|
||||
|
||||
KernelSemaPrivate::Result KernelSemaPrivate::Cancel(int set_count, int* num_waiting_threads)
|
||||
{
|
||||
Core::LockGuard lock(m_mutex);
|
||||
|
||||
if (set_count > m_max_count)
|
||||
{
|
||||
return Result::InvalCount;
|
||||
}
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(m_status == Status::Deleted);
|
||||
|
||||
while (m_status != Status::Set)
|
||||
{
|
||||
m_mutex.Unlock();
|
||||
Core::Thread::SleepMicro(10);
|
||||
m_mutex.Lock();
|
||||
}
|
||||
|
||||
if (num_waiting_threads != nullptr)
|
||||
{
|
||||
*num_waiting_threads = static_cast<int>(m_waiting_threads.Size());
|
||||
}
|
||||
|
||||
m_status = Status::Canceled;
|
||||
|
||||
m_count = (set_count < 0 ? m_init_count : set_count);
|
||||
|
||||
m_cond_var.SignalAll();
|
||||
|
||||
while (!m_waiting_threads.IsEmpty())
|
||||
{
|
||||
m_mutex.Unlock();
|
||||
Core::Thread::SleepMicro(10);
|
||||
m_mutex.Lock();
|
||||
}
|
||||
|
||||
m_status = Status::Set;
|
||||
|
||||
return Result::Ok;
|
||||
}
|
||||
|
||||
KernelSemaPrivate::Result KernelSemaPrivate::Signal(int signal_count)
|
||||
{
|
||||
Core::LockGuard lock(m_mutex);
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(m_status == Status::Deleted);
|
||||
|
||||
while (m_status != Status::Set)
|
||||
{
|
||||
m_mutex.Unlock();
|
||||
Core::Thread::SleepMicro(10);
|
||||
m_mutex.Lock();
|
||||
}
|
||||
|
||||
if (m_count + signal_count > m_max_count)
|
||||
{
|
||||
return Result::InvalCount;
|
||||
}
|
||||
|
||||
m_count += signal_count;
|
||||
|
||||
m_cond_var.SignalAll();
|
||||
|
||||
return Result::Ok;
|
||||
}
|
||||
|
||||
KernelSemaPrivate::Result KernelSemaPrivate::Wait(int need_count, uint32_t* ptr_micros)
|
||||
{
|
||||
Core::LockGuard lock(m_mutex);
|
||||
|
||||
if (need_count < 1 || need_count > m_max_count)
|
||||
{
|
||||
return Result::InvalCount;
|
||||
}
|
||||
|
||||
uint32_t micros = 0;
|
||||
bool infinitely = true;
|
||||
if (ptr_micros != nullptr)
|
||||
{
|
||||
micros = *ptr_micros;
|
||||
infinitely = false;
|
||||
}
|
||||
|
||||
uint32_t elapsed = 0;
|
||||
Core::Timer t;
|
||||
t.Start();
|
||||
|
||||
int id = Core::Thread::GetThreadIdUnique();
|
||||
|
||||
while (!(m_count - need_count >= 0))
|
||||
{
|
||||
if ((elapsed >= micros && !infinitely))
|
||||
{
|
||||
*ptr_micros = 0;
|
||||
return Result::TimedOut;
|
||||
}
|
||||
|
||||
m_waiting_threads.Add(id);
|
||||
|
||||
if (infinitely)
|
||||
{
|
||||
m_cond_var.Wait(&m_mutex);
|
||||
} else
|
||||
{
|
||||
m_cond_var.WaitFor(&m_mutex, micros - elapsed);
|
||||
}
|
||||
|
||||
m_waiting_threads.Remove(id);
|
||||
|
||||
elapsed = static_cast<uint32_t>(t.GetTimeS() * 1000000.0);
|
||||
|
||||
if (m_status == Status::Canceled)
|
||||
{
|
||||
if (ptr_micros != nullptr)
|
||||
{
|
||||
*ptr_micros = (elapsed >= micros ? 0 : micros - elapsed);
|
||||
}
|
||||
return Result::Canceled;
|
||||
}
|
||||
|
||||
if (m_status == Status::Deleted)
|
||||
{
|
||||
if (ptr_micros != nullptr)
|
||||
{
|
||||
*ptr_micros = (elapsed >= micros ? 0 : micros - elapsed);
|
||||
}
|
||||
return Result::Deleted;
|
||||
}
|
||||
}
|
||||
|
||||
m_count -= need_count;
|
||||
|
||||
if (ptr_micros != nullptr)
|
||||
{
|
||||
*ptr_micros = (elapsed >= micros ? 0 : micros - elapsed);
|
||||
}
|
||||
|
||||
return Result::Ok;
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI KernelCreateSema(KernelSema* sem, const char* name, uint32_t attr, int init, int max, void* opt)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
EXIT_NOT_IMPLEMENTED(sem == nullptr);
|
||||
|
||||
if (name == nullptr || init < 0 || init > max || opt != nullptr)
|
||||
{
|
||||
return KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
|
||||
bool fifo = false;
|
||||
|
||||
switch (attr)
|
||||
{
|
||||
case 0x01: fifo = true; break;
|
||||
case 0x02:
|
||||
default: fifo = false; break;
|
||||
}
|
||||
|
||||
*sem = new KernelSemaPrivate(String::FromUtf8(name), fifo, init, max);
|
||||
|
||||
printf("\t Semaphore create: %s, %d, %d\n", name, init, max);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI KernelDeleteSema(KernelSema sem)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
if (sem == nullptr)
|
||||
{
|
||||
return KERNEL_ERROR_ESRCH;
|
||||
}
|
||||
|
||||
delete sem;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI KernelWaitSema(KernelSema sem, int need, KernelUseconds* time)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
if (sem == nullptr)
|
||||
{
|
||||
return KERNEL_ERROR_ESRCH;
|
||||
}
|
||||
|
||||
printf("\t Semaphore wait: %s, %d, %d\n", sem->GetName().C_Str(), need, (time != nullptr ? *time : -1));
|
||||
|
||||
auto result = sem->Wait(need, time);
|
||||
|
||||
int ret = OK;
|
||||
|
||||
switch (result)
|
||||
{
|
||||
case KernelSemaPrivate::Result::Ok: ret = OK; break;
|
||||
case KernelSemaPrivate::Result::InvalCount: ret = KERNEL_ERROR_EINVAL; break;
|
||||
case KernelSemaPrivate::Result::TimedOut: ret = KERNEL_ERROR_ETIMEDOUT; break;
|
||||
case KernelSemaPrivate::Result::Canceled: ret = KERNEL_ERROR_ECANCELED; break;
|
||||
case KernelSemaPrivate::Result::Deleted: ret = KERNEL_ERROR_EACCES; break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI KernelPollSema(KernelSema sem, int need)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
if (sem == nullptr)
|
||||
{
|
||||
return KERNEL_ERROR_ESRCH;
|
||||
}
|
||||
|
||||
printf("\t Semaphore poll: %s, %d\n", sem->GetName().C_Str(), need);
|
||||
|
||||
auto result = sem->Poll(need);
|
||||
|
||||
int ret = OK;
|
||||
|
||||
switch (result)
|
||||
{
|
||||
case KernelSemaPrivate::Result::Ok: ret = OK; break;
|
||||
case KernelSemaPrivate::Result::InvalCount: ret = KERNEL_ERROR_EINVAL; break;
|
||||
case KernelSemaPrivate::Result::TimedOut:
|
||||
case KernelSemaPrivate::Result::Canceled:
|
||||
case KernelSemaPrivate::Result::Deleted: ret = KERNEL_ERROR_EBUSY; break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI KernelSignalSema(KernelSema sem, int count)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
if (sem == nullptr)
|
||||
{
|
||||
return KERNEL_ERROR_ESRCH;
|
||||
}
|
||||
|
||||
printf("\t Semaphore signal: %s, %d\n", sem->GetName().C_Str(), count);
|
||||
|
||||
auto result = sem->Signal(count);
|
||||
|
||||
int ret = OK;
|
||||
|
||||
switch (result)
|
||||
{
|
||||
case KernelSemaPrivate::Result::Ok: ret = OK; break;
|
||||
case KernelSemaPrivate::Result::InvalCount:
|
||||
case KernelSemaPrivate::Result::TimedOut:
|
||||
case KernelSemaPrivate::Result::Canceled:
|
||||
case KernelSemaPrivate::Result::Deleted: ret = KERNEL_ERROR_EINVAL; break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int KYTY_SYSV_ABI KernelCancelSema(KernelSema sem, int count, int* threads)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
if (sem == nullptr)
|
||||
{
|
||||
return KERNEL_ERROR_ESRCH;
|
||||
}
|
||||
|
||||
auto result = sem->Cancel(count, threads);
|
||||
|
||||
int ret = OK;
|
||||
|
||||
switch (result)
|
||||
{
|
||||
case KernelSemaPrivate::Result::Ok: ret = OK; break;
|
||||
case KernelSemaPrivate::Result::InvalCount:
|
||||
case KernelSemaPrivate::Result::TimedOut:
|
||||
case KernelSemaPrivate::Result::Canceled:
|
||||
case KernelSemaPrivate::Result::Deleted: ret = KERNEL_ERROR_EINVAL; break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace Kyty::Libs::LibKernel::Semaphore
|
||||
|
||||
#endif
|
||||
@@ -104,6 +104,20 @@ static void Init(const Scripts::ScriptVar& cfg)
|
||||
slist->InitAll(true);
|
||||
}
|
||||
|
||||
KYTY_SCRIPT_FUNC(kyty_load_cfg_func)
|
||||
{
|
||||
if (Scripts::ArgGetVarCount() != 1)
|
||||
{
|
||||
EXIT("invalid args\n");
|
||||
}
|
||||
|
||||
Scripts::ScriptVar cfg = Scripts::ArgGetVar(0);
|
||||
|
||||
Config::Load(cfg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
KYTY_SCRIPT_FUNC(kyty_init_func)
|
||||
{
|
||||
if (Scripts::ArgGetVarCount() != 1)
|
||||
@@ -326,6 +340,7 @@ void kyty_help() {}
|
||||
void kyty_reg()
|
||||
{
|
||||
Scripts::RegisterFunc("kyty_init", LuaFunc::kyty_init_func, LuaFunc::kyty_help);
|
||||
Scripts::RegisterFunc("kyty_load_cfg", LuaFunc::kyty_load_cfg_func, LuaFunc::kyty_help);
|
||||
Scripts::RegisterFunc("kyty_load_elf", LuaFunc::kyty_load_elf_func, LuaFunc::kyty_help);
|
||||
Scripts::RegisterFunc("kyty_load_symbols", LuaFunc::kyty_load_symbols_func, LuaFunc::kyty_help);
|
||||
Scripts::RegisterFunc("kyty_dbg_dump", LuaFunc::kyty_dbg_dump_func, LuaFunc::kyty_help);
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
#include "Emulator/Libs/Errno.h"
|
||||
|
||||
#ifdef KYTY_EMU_ENABLED
|
||||
|
||||
namespace Kyty::Libs::Posix {
|
||||
|
||||
static thread_local int g_errno = 0;
|
||||
|
||||
KYTY_SYSV_ABI int* GetErrorAddr()
|
||||
{
|
||||
return &g_errno;
|
||||
}
|
||||
|
||||
} // namespace Kyty::Libs::Posix
|
||||
|
||||
#endif
|
||||
@@ -13,6 +13,13 @@ LIB_VERSION("DiscMap", 1, "DiscMap", 1, 1);
|
||||
|
||||
namespace DiscMap {
|
||||
|
||||
/*
|
||||
DISC_MAP_ERROR_INVALID_ARGUMENT = 0x81100001;
|
||||
DISC_MAP_ERROR_LOCATION_NOT_MAPPED = 0x81100002;
|
||||
DISC_MAP_ERROR_FILE_NOT_FOUND = 0x81100003;
|
||||
DISC_MAP_ERROR_NO_BITMAP_INFO = 0x81100004;
|
||||
*/
|
||||
|
||||
static KYTY_SYSV_ABI int DiscMapIsRequestOnHDD(const char* file, uint64_t a2, uint64_t a3, const int* a4)
|
||||
{
|
||||
PRINT_NAME();
|
||||
@@ -25,7 +32,21 @@ static KYTY_SYSV_ABI int DiscMapIsRequestOnHDD(const char* file, uint64_t a2, ui
|
||||
return 0;
|
||||
}
|
||||
|
||||
static KYTY_SYSV_ABI int Unknown(const char* file, uint64_t a2, uint64_t a3, const uint64_t* a4, const uint64_t* a5, const uint64_t* a6)
|
||||
static KYTY_SYSV_ABI int Unknown1(const char* file, uint64_t a2, uint64_t a3, const uint64_t* a4, const uint64_t* a5, const uint64_t* a6)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
printf("\tfile = %s\n", file);
|
||||
printf("\ta2 = %016" PRIx64 "\n", a2);
|
||||
printf("\ta3 = %016" PRIx64 "\n", a3);
|
||||
printf("\t*a4 = %016" PRIx64 "\n", *a4);
|
||||
printf("\t*a5 = %016" PRIx64 "\n", *a5);
|
||||
printf("\t*a6 = %016" PRIx64 "\n", *a6);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static KYTY_SYSV_ABI int Unknown2(const char* file, uint64_t a2, uint64_t a3, const uint64_t* a4, const uint64_t* a5, const uint64_t* a6)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
@@ -44,7 +65,8 @@ static KYTY_SYSV_ABI int Unknown(const char* file, uint64_t a2, uint64_t a3, con
|
||||
LIB_DEFINE(InitDiscMap_1)
|
||||
{
|
||||
LIB_FUNC("lbQKqsERhtE", DiscMap::DiscMapIsRequestOnHDD);
|
||||
LIB_FUNC("fJgP+wqifno", DiscMap::Unknown);
|
||||
LIB_FUNC("fJgP+wqifno", DiscMap::Unknown1);
|
||||
LIB_FUNC("ioKMruft1ek", DiscMap::Unknown2);
|
||||
}
|
||||
|
||||
} // namespace Kyty::Libs
|
||||
|
||||
@@ -14,7 +14,10 @@ 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("Kx-h-nWQJ8A", Graphics::GraphicsSetCsShaderWithModifier);
|
||||
LIB_FUNC("HlTPoZ-oY7Y", Graphics::GraphicsDrawIndex);
|
||||
LIB_FUNC("GGsn7jMTxw4", Graphics::GraphicsDrawIndexAuto);
|
||||
@@ -25,6 +28,9 @@ LIB_DEFINE(InitGraphicsDriver_1)
|
||||
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);
|
||||
@@ -39,6 +45,7 @@ LIB_DEFINE(InitGraphicsDriver_1)
|
||||
LIB_FUNC("ZFqKFl23aMc", Graphics::GraphicsRegisterOwner);
|
||||
LIB_FUNC("nvEwfYAImTs", Graphics::GraphicsRegisterResource);
|
||||
LIB_FUNC("Fwvh++m9IQI", Graphics::GraphicsGetGpuCoreClockFrequency);
|
||||
LIB_FUNC("jg33rEKLfVs", Graphics::GraphicsIsUserPaEnabled);
|
||||
}
|
||||
|
||||
} // namespace Kyty::Libs
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "Emulator/Kernel/FileSystem.h"
|
||||
#include "Emulator/Kernel/Memory.h"
|
||||
#include "Emulator/Kernel/Pthread.h"
|
||||
#include "Emulator/Kernel/Semaphore.h"
|
||||
#include "Emulator/Libs/Errno.h"
|
||||
#include "Emulator/Libs/Libs.h"
|
||||
#include "Emulator/RuntimeLinker.h"
|
||||
@@ -102,23 +103,16 @@ static const char* g_progname = g_progname_buf;
|
||||
static get_thread_atexit_count_func_t g_get_thread_atexit_count_func = nullptr;
|
||||
static thread_atexit_report_func_t g_thread_atexit_report_func = nullptr;
|
||||
|
||||
static thread_local int g_errno = 0;
|
||||
|
||||
void SetProgName(const String& name)
|
||||
{
|
||||
strncpy(g_progname_buf, name.C_Str(), PROGNAME_MAX_SIZE);
|
||||
}
|
||||
|
||||
// struct KernelContext
|
||||
//{
|
||||
// Vector<Loader::Program*> programs;
|
||||
//};
|
||||
|
||||
static KYTY_SYSV_ABI int* get_error_addr()
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
return &g_errno;
|
||||
return Posix::GetErrorAddr();
|
||||
}
|
||||
|
||||
static KYTY_SYSV_ABI void stack_chk_fail()
|
||||
@@ -415,17 +409,22 @@ int KYTY_SYSV_ABI clock_gettime(int clock_id, LibKernel::KernelTimespec* time)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
if (LibKernel::KernelClockGettime(clock_id, time) < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return POSIX_CALL(LibKernel::KernelClockGettime(clock_id, time));
|
||||
}
|
||||
|
||||
LIB_DEFINE(InitLibKernel_1_Posix)
|
||||
{
|
||||
LIB_FUNC("lLMT9vJAck0", clock_gettime);
|
||||
|
||||
LIB_FUNC("7H0iTOciTLo", Posix::pthread_mutex_lock);
|
||||
LIB_FUNC("2Z+PpY6CaJg", Posix::pthread_mutex_unlock);
|
||||
LIB_FUNC("ttHNfU+qDBU", Posix::pthread_mutex_init);
|
||||
LIB_FUNC("ltCfaGr2JGE", Posix::pthread_mutex_destroy);
|
||||
LIB_FUNC("mkx2fVhNMsg", Posix::pthread_cond_broadcast);
|
||||
LIB_FUNC("Op8TBGY5KHg", Posix::pthread_cond_wait);
|
||||
LIB_FUNC("mqULNdimTn0", Posix::pthread_key_create);
|
||||
LIB_FUNC("6BpEZuDT7YI", Posix::pthread_key_delete);
|
||||
LIB_FUNC("WrOLvHU0yQM", Posix::pthread_setspecific);
|
||||
}
|
||||
|
||||
} // namespace Posix
|
||||
@@ -434,6 +433,7 @@ namespace FileSystem = LibKernel::FileSystem;
|
||||
namespace Memory = LibKernel::Memory;
|
||||
namespace EventQueue = LibKernel::EventQueue;
|
||||
namespace EventFlag = LibKernel::EventFlag;
|
||||
namespace Semaphore = LibKernel::Semaphore;
|
||||
|
||||
LIB_DEFINE(InitLibKernel_1_FS)
|
||||
{
|
||||
@@ -459,6 +459,7 @@ LIB_DEFINE(InitLibKernel_1_Mem)
|
||||
LIB_FUNC("L-Q3LEjIbgA", Memory::KernelMapDirectMemory);
|
||||
LIB_FUNC("MBuItvba6z8", Memory::KernelReleaseDirectMemory);
|
||||
LIB_FUNC("WFcfL2lzido", Memory::KernelQueryMemoryProtection);
|
||||
LIB_FUNC("BHouLQzh0X0", Memory::KernelDirectMemoryQuery);
|
||||
}
|
||||
|
||||
LIB_DEFINE(InitLibKernel_1_Equeue)
|
||||
@@ -475,6 +476,14 @@ LIB_DEFINE(InitLibKernel_1_EventFlag)
|
||||
LIB_FUNC("JTvBflhYazQ", EventFlag::KernelWaitEventFlag);
|
||||
}
|
||||
|
||||
LIB_DEFINE(InitLibKernel_1_Semaphore)
|
||||
{
|
||||
LIB_FUNC("188x57JYp0g", Semaphore::KernelCreateSema);
|
||||
LIB_FUNC("R1Jvn8bSCW8", Semaphore::KernelDeleteSema);
|
||||
LIB_FUNC("Zxa0VhQVTsk", Semaphore::KernelWaitSema);
|
||||
LIB_FUNC("4czppHBiriw", Semaphore::KernelSignalSema);
|
||||
}
|
||||
|
||||
LIB_DEFINE(InitLibKernel_1_Pthread)
|
||||
{
|
||||
LIB_FUNC("9UK1vLZQft4", LibKernel::PthreadMutexLock);
|
||||
@@ -493,6 +502,9 @@ LIB_DEFINE(InitLibKernel_1_Pthread)
|
||||
LIB_FUNC("onNY9Byn-W8", LibKernel::PthreadJoin);
|
||||
LIB_FUNC("4qGrR6eoP9Y", LibKernel::PthreadDetach);
|
||||
LIB_FUNC("How7B8Oet6k", LibKernel::PthreadGetname);
|
||||
LIB_FUNC("bt3CTBKmGyI", LibKernel::PthreadSetaffinity);
|
||||
LIB_FUNC("1tKyG7RlMJo", LibKernel::PthreadGetprio);
|
||||
LIB_FUNC("W0Hpm2X0uPE", LibKernel::PthreadSetprio);
|
||||
|
||||
LIB_FUNC("62KCwEMmzcM", LibKernel::PthreadAttrDestroy);
|
||||
LIB_FUNC("x1X76arYMxU", LibKernel::PthreadAttrGet);
|
||||
@@ -504,6 +516,7 @@ LIB_DEFINE(InitLibKernel_1_Pthread)
|
||||
LIB_FUNC("eXbUSpEaTsA", LibKernel::PthreadAttrSetinheritsched);
|
||||
LIB_FUNC("DzES9hQF4f4", LibKernel::PthreadAttrSetschedparam);
|
||||
LIB_FUNC("4+h9EzwKF4I", LibKernel::PthreadAttrSetschedpolicy);
|
||||
LIB_FUNC("3qxgM4ezETA", LibKernel::PthreadAttrSetaffinity);
|
||||
|
||||
LIB_FUNC("6ULAa0fq4jA", LibKernel::PthreadRwlockInit);
|
||||
LIB_FUNC("BB+kb08Tl9A", LibKernel::PthreadRwlockDestroy);
|
||||
@@ -522,10 +535,10 @@ LIB_DEFINE(InitLibKernel_1_Pthread)
|
||||
LIB_FUNC("1j3S3n-tTW4", LibKernel::KernelGetTscFrequency);
|
||||
LIB_FUNC("4J2sUJmuHZQ", LibKernel::KernelGetProcessTime);
|
||||
|
||||
LIB_FUNC("7H0iTOciTLo", LibKernel::pthread_mutex_lock_s);
|
||||
LIB_FUNC("2Z+PpY6CaJg", LibKernel::pthread_mutex_unlock_s);
|
||||
LIB_FUNC("mkx2fVhNMsg", LibKernel::pthread_cond_broadcast_s);
|
||||
LIB_FUNC("Op8TBGY5KHg", LibKernel::pthread_cond_wait_s);
|
||||
LIB_FUNC("7H0iTOciTLo", Posix::pthread_mutex_lock);
|
||||
LIB_FUNC("2Z+PpY6CaJg", Posix::pthread_mutex_unlock);
|
||||
LIB_FUNC("mkx2fVhNMsg", Posix::pthread_cond_broadcast);
|
||||
LIB_FUNC("Op8TBGY5KHg", Posix::pthread_cond_wait);
|
||||
}
|
||||
|
||||
LIB_DEFINE(InitLibKernel_1)
|
||||
@@ -534,6 +547,7 @@ LIB_DEFINE(InitLibKernel_1)
|
||||
InitLibKernel_1_Mem(s);
|
||||
InitLibKernel_1_Equeue(s);
|
||||
InitLibKernel_1_EventFlag(s);
|
||||
InitLibKernel_1_Semaphore(s);
|
||||
InitLibKernel_1_Pthread(s);
|
||||
Posix::InitLibKernel_1_Posix(s);
|
||||
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
#include "Kyty/Core/DbgAssert.h"
|
||||
#include "Kyty/Core/String.h"
|
||||
|
||||
#include "Emulator/Common.h"
|
||||
#include "Emulator/Libs/Errno.h"
|
||||
#include "Emulator/Libs/Libs.h"
|
||||
#include "Emulator/SymbolDatabase.h"
|
||||
|
||||
#ifdef KYTY_EMU_ENABLED
|
||||
|
||||
namespace Kyty::Libs {
|
||||
|
||||
LIB_VERSION("SystemService", 1, "SystemService", 1, 1);
|
||||
|
||||
namespace SystemService {
|
||||
|
||||
[[maybe_unused]] constexpr int PARAM_ID_LANG = 1;
|
||||
[[maybe_unused]] constexpr int PARAM_ID_DATE_FORMAT = 2;
|
||||
[[maybe_unused]] constexpr int PARAM_ID_TIME_FORMAT = 3;
|
||||
[[maybe_unused]] constexpr int PARAM_ID_TIME_ZONE = 4;
|
||||
[[maybe_unused]] constexpr int PARAM_ID_SUMMERTIME = 5;
|
||||
[[maybe_unused]] constexpr int PARAM_ID_SYSTEM_NAME = 6;
|
||||
[[maybe_unused]] constexpr int PARAM_ID_GAME_PARENTAL_LEVEL = 7;
|
||||
[[maybe_unused]] constexpr int PARAM_ID_ENTER_BUTTON_ASSIGN = 1000;
|
||||
|
||||
[[maybe_unused]] constexpr int PARAM_LANG_JAPANESE = 0;
|
||||
[[maybe_unused]] constexpr int PARAM_LANG_ENGLISH_US = 1;
|
||||
[[maybe_unused]] constexpr int PARAM_LANG_FRENCH = 2;
|
||||
[[maybe_unused]] constexpr int PARAM_LANG_SPANISH = 3;
|
||||
[[maybe_unused]] constexpr int PARAM_LANG_GERMAN = 4;
|
||||
[[maybe_unused]] constexpr int PARAM_LANG_ITALIAN = 5;
|
||||
[[maybe_unused]] constexpr int PARAM_LANG_DUTCH = 6;
|
||||
[[maybe_unused]] constexpr int PARAM_LANG_PORTUGUESE_PT = 7;
|
||||
[[maybe_unused]] constexpr int PARAM_LANG_RUSSIAN = 8;
|
||||
[[maybe_unused]] constexpr int PARAM_LANG_KOREAN = 9;
|
||||
[[maybe_unused]] constexpr int PARAM_LANG_CHINESE_T = 10;
|
||||
[[maybe_unused]] constexpr int PARAM_LANG_CHINESE_S = 11;
|
||||
[[maybe_unused]] constexpr int PARAM_LANG_FINNISH = 12;
|
||||
[[maybe_unused]] constexpr int PARAM_LANG_SWEDISH = 13;
|
||||
[[maybe_unused]] constexpr int PARAM_LANG_DANISH = 14;
|
||||
[[maybe_unused]] constexpr int PARAM_LANG_NORWEGIAN = 15;
|
||||
[[maybe_unused]] constexpr int PARAM_LANG_POLISH = 16;
|
||||
[[maybe_unused]] constexpr int PARAM_LANG_PORTUGUESE_BR = 17;
|
||||
[[maybe_unused]] constexpr int PARAM_LANG_ENGLISH_GB = 18;
|
||||
[[maybe_unused]] constexpr int PARAM_LANG_TURKISH = 19;
|
||||
[[maybe_unused]] constexpr int PARAM_LANG_SPANISH_LA = 20;
|
||||
[[maybe_unused]] constexpr int PARAM_LANG_ARABIC = 21;
|
||||
[[maybe_unused]] constexpr int PARAM_LANG_FRENCH_CA = 22;
|
||||
[[maybe_unused]] constexpr int PARAM_LANG_CZECH = 23;
|
||||
[[maybe_unused]] constexpr int PARAM_LANG_HUNGARIAN = 24;
|
||||
[[maybe_unused]] constexpr int PARAM_LANG_GREEK = 25;
|
||||
[[maybe_unused]] constexpr int PARAM_LANG_ROMANIAN = 26;
|
||||
[[maybe_unused]] constexpr int PARAM_LANG_THAI = 27;
|
||||
[[maybe_unused]] constexpr int PARAM_LANG_VIETNAMESE = 28;
|
||||
[[maybe_unused]] constexpr int PARAM_LANG_INDONESIAN = 29;
|
||||
|
||||
[[maybe_unused]] constexpr int PARAM_DATE_FORMAT_YYYYMMDD = 0;
|
||||
[[maybe_unused]] constexpr int PARAM_DATE_FORMAT_DDMMYYYY = 1;
|
||||
[[maybe_unused]] constexpr int PARAM_DATE_FORMAT_MMDDYYYY = 2;
|
||||
|
||||
[[maybe_unused]] constexpr int PARAM_TIME_FORMAT_12HOUR = 0;
|
||||
[[maybe_unused]] constexpr int PARAM_TIME_FORMAT_24HOUR = 1;
|
||||
|
||||
[[maybe_unused]] constexpr int MAX_SYSTEM_NAME_LENGTH = 65;
|
||||
|
||||
[[maybe_unused]] constexpr int PARAM_GAME_PARENTAL_OFF = 0;
|
||||
[[maybe_unused]] constexpr int PARAM_GAME_PARENTAL_LEVEL01 = 1;
|
||||
[[maybe_unused]] constexpr int PARAM_GAME_PARENTAL_LEVEL02 = 2;
|
||||
[[maybe_unused]] constexpr int PARAM_GAME_PARENTAL_LEVEL03 = 3;
|
||||
[[maybe_unused]] constexpr int PARAM_GAME_PARENTAL_LEVEL04 = 4;
|
||||
[[maybe_unused]] constexpr int PARAM_GAME_PARENTAL_LEVEL05 = 5;
|
||||
[[maybe_unused]] constexpr int PARAM_GAME_PARENTAL_LEVEL06 = 6;
|
||||
[[maybe_unused]] constexpr int PARAM_GAME_PARENTAL_LEVEL07 = 7;
|
||||
[[maybe_unused]] constexpr int PARAM_GAME_PARENTAL_LEVEL08 = 8;
|
||||
[[maybe_unused]] constexpr int PARAM_GAME_PARENTAL_LEVEL09 = 9;
|
||||
[[maybe_unused]] constexpr int PARAM_GAME_PARENTAL_LEVEL10 = 10;
|
||||
[[maybe_unused]] constexpr int PARAM_GAME_PARENTAL_LEVEL11 = 11;
|
||||
|
||||
[[maybe_unused]] constexpr int PARAM_ENTER_BUTTON_ASSIGN_CIRCLE = 0;
|
||||
[[maybe_unused]] constexpr int PARAM_ENTER_BUTTON_ASSIGN_CROSS = 1;
|
||||
|
||||
static int KYTY_SYSV_ABI SystemServiceHideSplashScreen()
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int KYTY_SYSV_ABI SystemServiceParamGetInt(int param_id, int* value)
|
||||
{
|
||||
PRINT_NAME();
|
||||
|
||||
if (value == nullptr)
|
||||
{
|
||||
return SYSTEM_SERVICE_ERROR_PARAMETER;
|
||||
}
|
||||
|
||||
int v = 0;
|
||||
|
||||
switch (param_id)
|
||||
{
|
||||
case PARAM_ID_LANG: v = PARAM_LANG_RUSSIAN; break;
|
||||
case PARAM_ID_DATE_FORMAT: v = PARAM_DATE_FORMAT_DDMMYYYY; break;
|
||||
case PARAM_ID_TIME_FORMAT: v = PARAM_TIME_FORMAT_24HOUR; break;
|
||||
case PARAM_ID_TIME_ZONE: v = +180; break;
|
||||
case PARAM_ID_SUMMERTIME: v = 0; break;
|
||||
case PARAM_ID_GAME_PARENTAL_LEVEL: v = PARAM_GAME_PARENTAL_OFF; break;
|
||||
case PARAM_ID_ENTER_BUTTON_ASSIGN: v = PARAM_ENTER_BUTTON_ASSIGN_CROSS; break;
|
||||
default: EXIT("unknown param_id: %d\n", param_id);
|
||||
}
|
||||
|
||||
printf(" %d = %d\n", param_id, v);
|
||||
|
||||
*value = v;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
} // namespace SystemService
|
||||
|
||||
LIB_DEFINE(InitSystemService_1)
|
||||
{
|
||||
LIB_FUNC("Vo5V8KAwCmk", SystemService::SystemServiceHideSplashScreen);
|
||||
LIB_FUNC("fZo48un7LK4", SystemService::SystemServiceParamGetInt);
|
||||
}
|
||||
|
||||
} // namespace Kyty::Libs
|
||||
|
||||
#endif // KYTY_EMU_ENABLED
|
||||
@@ -15,6 +15,7 @@ LIB_DEFINE(InitSysmodule_1);
|
||||
LIB_DEFINE(InitDiscMap_1);
|
||||
LIB_DEFINE(InitDebug_1);
|
||||
LIB_DEFINE(InitGraphicsDriver_1);
|
||||
LIB_DEFINE(InitSystemService_1);
|
||||
LIB_DEFINE(InitUserService_1);
|
||||
LIB_DEFINE(InitPad_1);
|
||||
|
||||
@@ -29,6 +30,7 @@ bool Init(const String& id, Loader::SymbolDatabase* s)
|
||||
LIB_CHECK(U"libDebug_1", InitDebug_1);
|
||||
LIB_CHECK(U"libGraphicsDriver_1", InitGraphicsDriver_1);
|
||||
LIB_CHECK(U"libUserService_1", InitUserService_1);
|
||||
LIB_CHECK(U"libSystemService_1", InitSystemService_1);
|
||||
LIB_CHECK(U"libPad_1", InitPad_1);
|
||||
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user