one step closer to run games

This commit is contained in:
InoriRus
2022-04-27 18:49:15 +10:00
parent 08b0a87225
commit bc02c0560e
47 changed files with 3020 additions and 1108 deletions
+174 -17
View File
@@ -69,10 +69,15 @@ public:
bool AudioOutSetVolume(Id handle, uint32_t bitflag, const int* volume);
uint32_t AudioOutOutputs(OutputParam* params, uint32_t num);
static constexpr int PORTS_MAX = 32;
Id AudioInOpen(uint32_t type, uint32_t samples_num, uint32_t freq, Format format);
bool AudioInValid(Id handle);
uint32_t AudioInInput(Id handle, void* dest);
static constexpr int OUT_PORTS_MAX = 32;
static constexpr int IN_PORTS_MAX = 8;
private:
struct Port
struct PortOut
{
bool used = false;
int type = 0;
@@ -84,8 +89,19 @@ private:
int volume[8] = {};
};
struct PortIn
{
bool used = false;
uint32_t type = 0;
uint32_t samples_num = 0;
uint32_t freq = 0;
Format format = Format::Unknown;
uint64_t last_input_time = 0;
};
Core::Mutex m_mutex;
Port m_ports[PORTS_MAX];
PortOut m_out_ports[OUT_PORTS_MAX];
PortIn m_in_ports[IN_PORTS_MAX];
};
static Audio* g_audio = nullptr;
@@ -105,11 +121,11 @@ Audio::Id Audio::AudioOutOpen(int type, uint32_t samples_num, uint32_t freq, For
{
Core::LockGuard lock(m_mutex);
for (int id = 0; id < PORTS_MAX; id++)
for (int id = 0; id < OUT_PORTS_MAX; id++)
{
if (!m_ports[id].used)
if (!m_out_ports[id].used)
{
auto& port = m_ports[id];
auto& port = m_out_ports[id];
port.used = true;
port.type = type;
@@ -147,7 +163,7 @@ bool Audio::AudioOutValid(Id handle)
{
Core::LockGuard lock(m_mutex);
return (handle.GetId() >= 0 && handle.GetId() < PORTS_MAX && m_ports[handle.GetId()].used);
return (handle.GetId() >= 0 && handle.GetId() < OUT_PORTS_MAX && m_out_ports[handle.GetId()].used);
}
bool Audio::AudioOutSetVolume(Id handle, uint32_t bitflag, const int* volume)
@@ -156,7 +172,7 @@ bool Audio::AudioOutSetVolume(Id handle, uint32_t bitflag, const int* volume)
if (AudioOutValid(handle))
{
auto& port = m_ports[handle.GetId()];
auto& port = m_out_ports[handle.GetId()];
for (int i = 0; i < port.channels_num; i++, bitflag >>= 1u)
{
@@ -193,7 +209,7 @@ uint32_t Audio::AudioOutOutputs(OutputParam* params, uint32_t num)
EXIT_NOT_IMPLEMENTED(num == 0);
EXIT_NOT_IMPLEMENTED(!AudioOutValid(params[0].handle));
const auto& first_port = m_ports[params[0].handle.GetId()];
const auto& first_port = m_out_ports[params[0].handle.GetId()];
uint64_t block_time = (1000000 * first_port.samples_num) / first_port.freq;
uint64_t current_time = LibKernel::KernelGetProcessTime();
@@ -202,22 +218,80 @@ uint32_t Audio::AudioOutOutputs(OutputParam* params, uint32_t num)
for (uint32_t i = 0; i < num; i++)
{
uint64_t next_time = m_ports[params[i].handle.GetId()].last_output_time + block_time;
uint64_t next_time = m_out_ports[params[i].handle.GetId()].last_output_time + block_time;
uint64_t wait_time = (next_time > current_time ? next_time - current_time : 0);
max_wait_time = (wait_time > max_wait_time ? wait_time : max_wait_time);
}
// Audio output is not yet implemented, so simulate audio delay
// TODO(): Audio output is not yet implemented, so simulate audio delay
Core::Thread::SleepMicro(max_wait_time);
for (uint32_t i = 0; i < num; i++)
{
m_ports[params[i].handle.GetId()].last_output_time = LibKernel::KernelGetProcessTime();
m_out_ports[params[i].handle.GetId()].last_output_time = LibKernel::KernelGetProcessTime();
}
return first_port.samples_num;
}
Audio::Id Audio::AudioInOpen(uint32_t type, uint32_t samples_num, uint32_t freq, Format format)
{
Core::LockGuard lock(m_mutex);
for (int id = 0; id < IN_PORTS_MAX; id++)
{
if (!m_in_ports[id].used)
{
auto& port = m_in_ports[id];
port.used = true;
port.type = type;
port.samples_num = samples_num;
port.freq = freq;
port.format = format;
switch (format)
{
case Format::Signed16bitMono:
case Format::Signed16bitStereo: break;
default: EXIT("unknown format");
}
return Id::Create(id);
}
}
return Id::Invalid();
}
bool Audio::AudioInValid(Id handle)
{
Core::LockGuard lock(m_mutex);
return (handle.GetId() >= 0 && handle.GetId() < IN_PORTS_MAX && m_in_ports[handle.GetId()].used);
}
uint32_t Audio::AudioInInput(Id handle, void* dest)
{
EXIT_NOT_IMPLEMENTED(!AudioInValid(handle));
EXIT_NOT_IMPLEMENTED(dest == nullptr);
const auto& port = m_in_ports[handle.GetId()];
uint64_t block_time = (1000000 * port.samples_num) / port.freq;
uint64_t current_time = LibKernel::KernelGetProcessTime();
uint64_t next_time = m_in_ports[handle.GetId()].last_input_time + block_time;
uint64_t wait_time = (next_time > current_time ? next_time - current_time : 0);
// TODO(): Audio input is not yet implemented, so simulate audio delay
Core::Thread::SleepMicro(wait_time);
m_in_ports[handle.GetId()].last_input_time = LibKernel::KernelGetProcessTime();
return port.samples_num;
}
namespace AudioOut {
LIB_NAME("AudioOut", "AudioOut");
@@ -245,8 +319,8 @@ int KYTY_SYSV_ABI AudioOutOpen(int user_id, int type, int index, uint32_t len, u
printf("\t len = %u\n", len);
printf("\t freq = %u\n", freq);
EXIT_NOT_IMPLEMENTED(user_id != 255);
EXIT_NOT_IMPLEMENTED(type != 0);
EXIT_NOT_IMPLEMENTED(user_id != 255 && user_id != 1);
EXIT_NOT_IMPLEMENTED(type != 0 && type != 3 && type != 4);
EXIT_NOT_IMPLEMENTED(index != 0);
Audio::Format format = Audio::Format::Unknown;
@@ -302,10 +376,14 @@ int KYTY_SYSV_ABI AudioOutOutputs(AudioOutOutputParam* param, uint32_t num)
{
PRINT_NAME();
EXIT_NOT_IMPLEMENTED(param == nullptr);
EXIT_NOT_IMPLEMENTED(num != 1);
for (uint32_t i = 0; i < num; i++)
{
printf("\t handle[%u] = %d\n", i, param[i].handle);
}
Audio::OutputParam params[Audio::PORTS_MAX];
EXIT_NOT_IMPLEMENTED(param == nullptr);
Audio::OutputParam params[Audio::OUT_PORTS_MAX];
EXIT_IF(g_audio == nullptr);
@@ -325,6 +403,67 @@ int KYTY_SYSV_ABI AudioOutOutputs(AudioOutOutputParam* param, uint32_t num)
} // namespace AudioOut
namespace AudioIn {
LIB_NAME("AudioIn", "AudioIn");
int KYTY_SYSV_ABI AudioInOpen(int user_id, uint32_t type, uint32_t index, uint32_t len, uint32_t freq, uint32_t param)
{
PRINT_NAME();
printf("\t user_id = %d\n", user_id);
printf("\t type = %u\n", type);
printf("\t index = %d\n", index);
printf("\t len = %u\n", len);
printf("\t freq = %u\n", freq);
EXIT_NOT_IMPLEMENTED(user_id != 255 && user_id != 1);
EXIT_NOT_IMPLEMENTED(type != 1);
EXIT_NOT_IMPLEMENTED(index != 0);
Audio::Format format = Audio::Format::Unknown;
switch (param)
{
case 0: format = Audio::Format::Signed16bitMono; break;
case 2: format = Audio::Format::Signed16bitStereo; break;
default:;
}
printf("\t param = %u (%s)\n", param, Core::EnumName(format).C_Str());
EXIT_NOT_IMPLEMENTED(format == Audio::Format::Unknown);
EXIT_IF(g_audio == nullptr);
auto id = g_audio->AudioInOpen(type, len, freq, format);
if (!id.IsValid())
{
return AUDIO_IN_ERROR_PORT_FULL;
}
return id.ToInt();
}
int KYTY_SYSV_ABI AudioInInput(int handle, void* dest)
{
PRINT_NAME();
EXIT_NOT_IMPLEMENTED(dest == nullptr);
EXIT_IF(g_audio == nullptr);
if (!g_audio->AudioInValid(Audio::Id(handle)))
{
return AUDIO_IN_ERROR_INVALID_HANDLE;
}
return static_cast<int>(g_audio->AudioInInput(Audio::Id(handle), dest));
}
} // namespace AudioIn
namespace VoiceQoS {
LIB_NAME("VoiceQoS", "VoiceQoS");
@@ -342,6 +481,24 @@ int KYTY_SYSV_ABI VoiceQoSInit(void* mem_block, uint32_t mem_size, int32_t app_t
} // namespace VoiceQoS
namespace Ajm {
LIB_NAME("Ajm", "Ajm");
int KYTY_SYSV_ABI AjmInitialize(int64_t reserved, uint32_t* context)
{
PRINT_NAME();
EXIT_NOT_IMPLEMENTED(context == nullptr);
EXIT_NOT_IMPLEMENTED(reserved != 0);
*context = 1;
return OK;
}
} // namespace Ajm
} // namespace Kyty::Libs::Audio
#endif // KYTY_EMU_ENABLED
+129 -2
View File
@@ -72,6 +72,12 @@ struct PadControllerInformation
int device_class;
};
struct PadVibrationParam
{
uint8_t large_motor;
uint8_t small_motor;
};
struct ControllerState
{
uint64_t time = 0;
@@ -93,10 +99,16 @@ public:
void Axis(int id, Axis axis, int value);
void GetConnectionInfo(bool* flag, int* count);
void ReadState(ControllerState* state, bool* flag, int* count);
int ReadStates(ControllerState* states, int states_num, bool* flag, int* count);
private:
static constexpr uint32_t STATES_MAX = 64;
struct StatePrivate
{
bool obtained = false;
};
void CheckActive();
[[nodiscard]] ControllerState GetLastState() const;
void AddState(const ControllerState& state);
@@ -107,6 +119,7 @@ private:
bool m_connected = false;
int m_connected_count = 0;
ControllerState m_states[STATES_MAX];
StatePrivate m_private[STATES_MAX];
ControllerState m_last_state;
uint32_t m_states_num = 0;
uint32_t m_first_state = 0;
@@ -205,8 +218,12 @@ void GameController::AddState(const ControllerState& state)
m_first_state = (m_first_state + 1) % STATES_MAX;
}
m_states[(m_first_state + m_states_num) % STATES_MAX] = state;
m_last_state = state;
auto index = (m_first_state + m_states_num) % STATES_MAX;
m_states[index] = state;
m_last_state = state;
m_private[index].obtained = false;
m_states_num++;
}
@@ -299,6 +316,48 @@ void GameController::ReadState(ControllerState* state, bool* flag, int* count)
*state = GetLastState();
}
int GameController::ReadStates(ControllerState* states, int states_num, bool* flag, int* count)
{
EXIT_IF(flag == nullptr);
EXIT_IF(count == nullptr);
EXIT_IF(states == nullptr);
EXIT_IF(states_num < 1 || states_num > STATES_MAX);
Core::LockGuard lock(m_mutex);
*flag = m_connected;
*count = m_connected_count;
int ret_num = 0;
if (m_connected)
{
if (m_states_num == 0)
{
ret_num = 1;
states[0] = m_last_state;
} else
{
for (uint32_t i = 0; i < m_states_num; i++)
{
if (ret_num >= states_num)
{
break;
}
auto index = (m_first_state + i) % STATES_MAX;
if (!m_private[index].obtained)
{
m_private[index].obtained = true;
states[ret_num++] = m_states[index];
}
}
}
}
return ret_num;
}
void ControllerConnect(int id)
{
EXIT_IF(g_controller == nullptr);
@@ -433,6 +492,74 @@ int KYTY_SYSV_ABI PadReadState(int handle, PadData* data)
return OK;
}
int KYTY_SYSV_ABI PadRead(int handle, PadData* data, int num)
{
PRINT_NAME();
EXIT_NOT_IMPLEMENTED(num < 1 || num > 64);
EXIT_NOT_IMPLEMENTED(handle != 1);
EXIT_NOT_IMPLEMENTED(data == nullptr);
EXIT_IF(g_controller == nullptr);
int connected_count = 0;
bool connected = false;
ControllerState states[64];
int ret_num = g_controller->ReadStates(states, num, &connected, &connected_count);
if (!connected)
{
ret_num = 1;
}
for (int i = 0; i < ret_num; i++)
{
data[i].buttons = states[i].buttons;
data[i].left_stick_x = states[i].axes[static_cast<int>(Axis::LeftX)];
data[i].left_stick_y = states[i].axes[static_cast<int>(Axis::LeftY)];
data[i].right_stick_x = states[i].axes[static_cast<int>(Axis::RightX)];
data[i].right_stick_y = states[i].axes[static_cast<int>(Axis::RightY)];
data[i].analog_buttons_l2 = states[i].axes[static_cast<int>(Axis::TriggerLeft)];
data[i].analog_buttons_r2 = states[i].axes[static_cast<int>(Axis::TriggerRight)];
data[i].orientation_x = 0.0f;
data[i].orientation_y = 0.0f;
data[i].orientation_z = 0.0f;
data[i].orientation_w = 1.0f;
data[i].acceleration_x = 0.0f;
data[i].acceleration_y = 0.0f;
data[i].acceleration_z = 0.0f;
data[i].angular_velocity_x = 0.0f;
data[i].angular_velocity_y = 0.0f;
data[i].angular_velocity_z = 0.0f;
data[i].touch_data_touch_num = 0;
data[i].touch_data_touch0_x = 0;
data[i].touch_data_touch0_y = 0;
data[i].touch_data_touch0_id = 1;
data[i].touch_data_touch1_x = 0;
data[i].touch_data_touch1_y = 0;
data[i].touch_data_touch1_id = 2;
data[i].connected = connected;
data[i].timestamp = states[i].time;
data[i].connected_count = connected_count;
data[i].device_unique_data_len = 0;
}
return ret_num;
}
int KYTY_SYSV_ABI PadSetVibration(int handle, const PadVibrationParam* param)
{
PRINT_NAME();
EXIT_NOT_IMPLEMENTED(handle != 1);
printf("\t large_motor = %d\n", static_cast<int>(param->large_motor));
printf("\t small_motor = %d\n", static_cast<int>(param->small_motor));
return OK;
}
} // namespace Kyty::Libs::Controller
#endif // KYTY_EMU_ENABLED
+30
View File
@@ -23,6 +23,36 @@ int KYTY_SYSV_ABI CommonDialogInitialize()
} // namespace CommonDialog
namespace SaveDataDialog {
LIB_NAME("SaveDataDialog", "SaveDataDialog");
int KYTY_SYSV_ABI SaveDataDialogUpdateStatus()
{
PRINT_NAME();
return 0;
}
int KYTY_SYSV_ABI SaveDataDialogTerminate()
{
PRINT_NAME();
return 0;
}
int KYTY_SYSV_ABI SaveDataDialogProgressBarSetValue(int target, uint32_t rate)
{
PRINT_NAME();
printf("\t target = %d\n", target);
printf("\t rate = %u\n", rate);
return OK;
}
} // namespace SaveDataDialog
} // namespace Kyty::Libs::Dialog
#endif // KYTY_EMU_ENABLED
+29
View File
@@ -225,6 +225,35 @@ int KYTY_SYSV_ABI GraphicsUpdatePsShader(uint32_t* cmd, uint64_t size, const uin
return OK;
}
int KYTY_SYSV_ABI GraphicsUpdatePsShader350(uint32_t* cmd, uint64_t size, const uint32_t* ps_regs)
{
PRINT_NAME();
EXIT_NOT_IMPLEMENTED(ps_regs == nullptr);
EXIT_NOT_IMPLEMENTED(size < 12 + 1);
printf("\t cmd_buffer = %016" PRIx64 "\n", reinterpret_cast<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_UPDATE);
memcpy(&cmd[1], ps_regs, 12 * 4);
return OK;
}
int KYTY_SYSV_ABI GraphicsSetCsShaderWithModifier(uint32_t* cmd, uint64_t size, const uint32_t* cs_regs, uint32_t shader_modifier)
{
PRINT_NAME();
File diff suppressed because it is too large Load Diff
+164 -58
View File
@@ -5,7 +5,6 @@
#include "Kyty/Core/String.h"
#include "Kyty/Core/Threads.h"
#include "Emulator/Config.h"
#include "Emulator/Graphics/AsyncJob.h"
#include "Emulator/Graphics/GraphicContext.h"
#include "Emulator/Graphics/Graphics.h"
@@ -17,6 +16,8 @@
#include "Emulator/Graphics/Window.h"
#include "Emulator/Profiler.h"
#include <atomic>
#ifdef KYTY_EMU_ENABLED
#define KYTY_HW_CTX_PARSER_ARGS \
@@ -67,6 +68,7 @@ public:
void WriteAtEndOfPipe64(uint32_t cache_policy, uint32_t event_write_dest, uint32_t eop_event_type, uint32_t cache_action,
uint32_t event_index, uint32_t event_write_source, void* dst_gpu_addr, uint64_t value,
uint32_t interrupt_selector);
void Flip();
void Flip(void* dst_gpu_addr, uint32_t value);
void FlipWithInterrupt(uint32_t eop_event_type, uint32_t cache_action, void* dst_gpu_addr, uint32_t value);
void WriteBack();
@@ -106,6 +108,9 @@ public:
[[nodiscard]] const FlipInfo& GetFlip() const { return m_flip; }
void SetFlip(const FlipInfo& flip) { m_flip = flip; }
[[nodiscard]] uint64_t GetSumbitId() const { return m_sumbit_id; }
void SetSumbitId(uint64_t sumbit_id) { m_sumbit_id = sumbit_id; }
private:
static constexpr int VK_BUFFERS_NUM = 4;
@@ -133,6 +138,7 @@ private:
uint32_t m_const_ram[0x3000] = {0};
FlipInfo m_flip;
uint64_t m_sumbit_id = 0;
};
class GraphicsRing
@@ -660,6 +666,7 @@ void GraphicsRing::Submit(uint32_t* cmd_draw_buffer, uint32_t num_draw_dw, uint3
m_idle_cond_var.Wait(&m_mutex);
}
m_done = false;
m_cp->Reset();
}
@@ -714,6 +721,7 @@ GraphicsRing::CmdBatch GraphicsRing::GetCmdBatch()
{
m_idle = true;
m_idle_cond_var.Signal();
m_cond_var.Wait(&m_mutex);
}
@@ -732,6 +740,8 @@ void GraphicsRing::ThreadBatchRun(void* data)
{
EXIT_IF(data == nullptr);
static std::atomic_uint64_t seq = 0;
auto* ring = static_cast<GraphicsRing*>(data);
auto* cp = ring->m_cp;
@@ -745,6 +755,7 @@ void GraphicsRing::ThreadBatchRun(void* data)
cp->BufferInit();
cp->ResetDeCe();
cp->SetFlip(buf.flip);
cp->SetSumbitId(++seq);
ring->m_job1.Execute([cp, buf](void* /*unused*/) { cp->Run(buf.draw_buffer.data, buf.draw_buffer.num_dw); });
ring->m_job2.Execute([cp, buf](void* /*unused*/) { cp->Run(buf.const_buffer.data, buf.const_buffer.num_dw); });
@@ -968,7 +979,8 @@ void CommandProcessor::DrawIndex(uint32_t index_count, const void* index_addr, u
EXIT_IF(m_current_buffer < 0 || m_current_buffer >= VK_BUFFERS_NUM);
GraphicsRenderDrawIndex(m_buffer[m_current_buffer], &m_ctx, &m_ucfg, m_index_type_and_size, index_count, index_addr, flags, type);
GraphicsRenderDrawIndex(m_sumbit_id, m_buffer[m_current_buffer], &m_ctx, &m_ucfg, m_index_type_and_size, index_count, index_addr, flags,
type);
}
void CommandProcessor::DispatchDirect(uint32_t thread_group_x, uint32_t thread_group_y, uint32_t thread_group_z, uint32_t mode)
@@ -977,7 +989,7 @@ void CommandProcessor::DispatchDirect(uint32_t thread_group_x, uint32_t thread_g
EXIT_IF(m_current_buffer < 0 || m_current_buffer >= VK_BUFFERS_NUM);
GraphicsRenderDispatchDirect(m_buffer[m_current_buffer], &m_ctx, thread_group_x, thread_group_y, thread_group_z, mode);
GraphicsRenderDispatchDirect(m_sumbit_id, m_buffer[m_current_buffer], &m_ctx, thread_group_x, thread_group_y, thread_group_z, mode);
}
void CommandProcessor::DrawIndexAuto(uint32_t index_count, uint32_t flags)
@@ -986,7 +998,7 @@ void CommandProcessor::DrawIndexAuto(uint32_t index_count, uint32_t flags)
EXIT_IF(m_current_buffer < 0 || m_current_buffer >= VK_BUFFERS_NUM);
GraphicsRenderDrawIndexAuto(m_buffer[m_current_buffer], &m_ctx, &m_ucfg, index_count, flags);
GraphicsRenderDrawIndexAuto(m_sumbit_id, m_buffer[m_current_buffer], &m_ctx, &m_ucfg, index_count, flags);
}
void CommandProcessor::ClearGds(uint64_t dw_offset, uint32_t dw_num, uint32_t clear_value)
@@ -1035,10 +1047,11 @@ void CommandProcessor::WriteAtEndOfPipe32(uint32_t cache_policy, uint32_t event_
if (event_write_source == 0x00000002 && eop_event_type == 0x0000002f && cache_action == 0x00000000 && event_index == 0x00000006)
{
GraphicsRenderWriteAtEndOfPipe(m_buffer[m_current_buffer], static_cast<uint32_t*>(dst_gpu_addr), value);
GraphicsRenderWriteAtEndOfPipe32(m_sumbit_id, m_buffer[m_current_buffer], static_cast<uint32_t*>(dst_gpu_addr), value);
} else if (event_write_source == 0x00000001 && eop_event_type == 0x0000002f && cache_action == 0x00000000 && event_index == 0x00000006)
{
GraphicsRenderWriteAtEndOfPipeGds(m_buffer[m_current_buffer], static_cast<uint32_t*>(dst_gpu_addr), value & 0xffffu, value >> 16u);
GraphicsRenderWriteAtEndOfPipeGds32(m_sumbit_id, m_buffer[m_current_buffer], static_cast<uint32_t*>(dst_gpu_addr), value & 0xffffu,
value >> 16u);
} else
{
EXIT("unknown event type\n");
@@ -1067,31 +1080,43 @@ void CommandProcessor::WriteAtEndOfPipe64(uint32_t cache_policy, uint32_t event_
EXIT_NOT_IMPLEMENTED(cache_policy != 0x00000000);
EXIT_NOT_IMPLEMENTED(event_write_dest != 0x00000000);
if (eop_event_type == 0x04 && cache_action == 0x00 && event_index == 0x05 && event_write_source == 0x02 &&
(interrupt_selector == 0x00 || interrupt_selector == 0x03))
bool with_interrupt = false;
bool source64 = (event_write_source == 0x02);
bool source32 = (event_write_source == 0x01);
bool source_counter = (event_write_source == 0x04);
switch (interrupt_selector)
{
GraphicsRenderWriteAtEndOfPipe(m_buffer[m_current_buffer], static_cast<uint64_t*>(dst_gpu_addr), value);
} else if (eop_event_type == 0x04 && cache_action == 0x00 && event_index == 0x05 && event_write_source == 0x01 &&
(interrupt_selector == 0x00 || interrupt_selector == 0x03))
case 0x00:
case 0x03: with_interrupt = false; break;
case 0x02: with_interrupt = true; break;
default: EXIT("unknown interrupt_selector\n");
}
if (eop_event_type == 0x04 && cache_action == 0x00 && event_index == 0x05 && source64 && !with_interrupt)
{
GraphicsRenderWriteAtEndOfPipe(m_buffer[m_current_buffer], static_cast<uint32_t*>(dst_gpu_addr), value);
GraphicsRenderWriteAtEndOfPipe64(m_sumbit_id, m_buffer[m_current_buffer], static_cast<uint64_t*>(dst_gpu_addr), value);
} else if (eop_event_type == 0x04 && cache_action == 0x00 && event_index == 0x05 && source32 && !with_interrupt)
{
GraphicsRenderWriteAtEndOfPipe32(m_sumbit_id, m_buffer[m_current_buffer], static_cast<uint32_t*>(dst_gpu_addr), value);
} else if (((eop_event_type == 0x04 && event_index == 0x05) || (eop_event_type == 0x28 && event_index == 0x05) ||
(eop_event_type == 0x2f && event_index == 0x06)) &&
cache_action == 0x38 && event_write_source == 0x02 && (interrupt_selector == 0x00 || interrupt_selector == 0x03))
cache_action == 0x38 && source64 && !with_interrupt)
{
GraphicsRenderWriteAtEndOfPipeWithWriteBack(m_buffer[m_current_buffer], static_cast<uint64_t*>(dst_gpu_addr), value);
} else if (eop_event_type == 0x04 && cache_action == 0x00 && event_index == 0x05 && event_write_source == 0x04 &&
(interrupt_selector == 0x00 || interrupt_selector == 0x03))
GraphicsRenderWriteAtEndOfPipeWithWriteBack64(m_sumbit_id, m_buffer[m_current_buffer], static_cast<uint64_t*>(dst_gpu_addr), value);
} else if (eop_event_type == 0x04 && cache_action == 0x00 && event_index == 0x05 && source_counter && !with_interrupt)
{
GraphicsRenderWriteAtEndOfPipeClockCounter(m_buffer[m_current_buffer], static_cast<uint64_t*>(dst_gpu_addr));
} else if ((eop_event_type == 0x04 && event_index == 0x05) && cache_action == 0x00 && event_write_source == 0x02 &&
interrupt_selector == 0x02)
GraphicsRenderWriteAtEndOfPipeClockCounter(m_sumbit_id, m_buffer[m_current_buffer], static_cast<uint64_t*>(dst_gpu_addr));
} else if ((eop_event_type == 0x04 && event_index == 0x05) && cache_action == 0x00 && source64 && with_interrupt)
{
GraphicsRenderWriteAtEndOfPipeWithInterrupt(m_buffer[m_current_buffer], static_cast<uint64_t*>(dst_gpu_addr), value);
} else if ((eop_event_type == 0x04 && event_index == 0x05) && cache_action == 0x3b && event_write_source == 0x02 &&
interrupt_selector == 0x02)
GraphicsRenderWriteAtEndOfPipeWithInterrupt64(m_sumbit_id, m_buffer[m_current_buffer], static_cast<uint64_t*>(dst_gpu_addr), value);
} else if ((eop_event_type == 0x04 && event_index == 0x05) && cache_action == 0x00 && source32 && with_interrupt)
{
GraphicsRenderWriteAtEndOfPipeWithInterruptWriteBack(m_buffer[m_current_buffer], static_cast<uint64_t*>(dst_gpu_addr), value);
GraphicsRenderWriteAtEndOfPipeWithInterrupt32(m_sumbit_id, m_buffer[m_current_buffer], static_cast<uint32_t*>(dst_gpu_addr), value);
} else if ((eop_event_type == 0x04 && event_index == 0x05) && cache_action == 0x3b && source64 && with_interrupt)
{
GraphicsRenderWriteAtEndOfPipeWithInterruptWriteBack64(m_sumbit_id, m_buffer[m_current_buffer],
static_cast<uint64_t*>(dst_gpu_addr), value);
} else
{
EXIT("unknown event type\n");
@@ -1147,6 +1172,18 @@ void CommandProcessor::TriggerEvent(uint32_t event_type, uint32_t event_index)
}
}
void CommandProcessor::Flip()
{
Core::LockGuard lock(m_mutex);
EXIT_IF(m_current_buffer < 0 || m_current_buffer >= VK_BUFFERS_NUM);
printf("CommandProcessor::Flip()\n");
GraphicsRenderWriteAtEndOfPipeOnlyFlip(m_sumbit_id, m_buffer[m_current_buffer], m_flip.handle, m_flip.index, m_flip.flip_mode,
m_flip.flip_arg);
}
void CommandProcessor::Flip(void* dst_gpu_addr, uint32_t value)
{
Core::LockGuard lock(m_mutex);
@@ -1157,8 +1194,8 @@ void CommandProcessor::Flip(void* dst_gpu_addr, uint32_t value)
printf("\t dst_gpu_addr = 0x%016" PRIx64 "\n", reinterpret_cast<uint64_t>(dst_gpu_addr));
printf("\t value = 0x%08" PRIx32 "\n", value);
GraphicsRenderWriteAtEndOfPipeWithFlip(m_buffer[m_current_buffer], static_cast<uint32_t*>(dst_gpu_addr), value, m_flip.handle,
m_flip.index, m_flip.flip_mode, m_flip.flip_arg);
GraphicsRenderWriteAtEndOfPipeWithFlip32(m_sumbit_id, m_buffer[m_current_buffer], static_cast<uint32_t*>(dst_gpu_addr), value,
m_flip.handle, m_flip.index, m_flip.flip_mode, m_flip.flip_arg);
}
void CommandProcessor::FlipWithInterrupt(uint32_t eop_event_type, uint32_t cache_action, void* dst_gpu_addr, uint32_t value)
@@ -1175,8 +1212,9 @@ void CommandProcessor::FlipWithInterrupt(uint32_t eop_event_type, uint32_t cache
if (eop_event_type == 0x00000004 && cache_action == 0x00000038)
{
GraphicsRenderWriteAtEndOfPipeWithInterruptWriteBackFlip(m_buffer[m_current_buffer], static_cast<uint32_t*>(dst_gpu_addr), value,
m_flip.handle, m_flip.index, m_flip.flip_mode, m_flip.flip_arg);
GraphicsRenderWriteAtEndOfPipeWithInterruptWriteBackFlip32(m_sumbit_id, m_buffer[m_current_buffer],
static_cast<uint32_t*>(dst_gpu_addr), value, m_flip.handle, m_flip.index,
m_flip.flip_mode, m_flip.flip_arg);
} else
{
EXIT("unknown event type\n");
@@ -1308,13 +1346,13 @@ 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);
}
// 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;
@@ -1479,6 +1517,65 @@ KYTY_HW_CTX_PARSER(hw_ctx_set_line_control)
return 1;
}
KYTY_HW_CTX_PARSER(hw_ctx_set_scan_mode_control)
{
EXIT_NOT_IMPLEMENTED(cmd_id != 0xc0016900);
EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::PA_SC_MODE_CNTL_0);
HW::ScanModeControl r;
r.msaa_enable = KYTY_PM4_GET(buffer[0], PA_SC_MODE_CNTL_0, MSAA_ENABLE) != 0;
r.vport_scissor_enable = KYTY_PM4_GET(buffer[0], PA_SC_MODE_CNTL_0, VPORT_SCISSOR_ENABLE) != 0;
r.line_stipple_enable = KYTY_PM4_GET(buffer[0], PA_SC_MODE_CNTL_0, LINE_STIPPLE_ENABLE) != 0;
cp->GetCtx()->SetScanModeControl(r);
return 1;
}
KYTY_HW_CTX_PARSER(hw_ctx_set_aa_config)
{
EXIT_NOT_IMPLEMENTED(cmd_id != 0xc0016900);
EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::PA_SC_AA_CONFIG);
HW::AaConfig r;
r.msaa_num_samples = KYTY_PM4_GET(buffer[0], PA_SC_AA_CONFIG, MSAA_NUM_SAMPLES);
r.aa_mask_centroid_dtmn = KYTY_PM4_GET(buffer[0], PA_SC_AA_CONFIG, AA_MASK_CENTROID_DTMN) != 0;
r.max_sample_dist = KYTY_PM4_GET(buffer[0], PA_SC_AA_CONFIG, MAX_SAMPLE_DIST);
r.msaa_exposed_samples = KYTY_PM4_GET(buffer[0], PA_SC_AA_CONFIG, MSAA_EXPOSED_SAMPLES);
cp->GetCtx()->SetAaConfig(r);
return 1;
}
KYTY_HW_CTX_PARSER(hw_ctx_set_aa_sample_control)
{
EXIT_NOT_IMPLEMENTED(cmd_id != 0xc0106900);
EXIT_NOT_IMPLEMENTED(cmd_offset != Pm4::PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0);
uint32_t count = 1;
if (dw >= 20 && buffer[16] == 0xc0026900 && buffer[17] == Pm4::PA_SC_CENTROID_PRIORITY_0)
{
count = 20;
HW::AaSampleControl r;
memcpy(r.locations, buffer, 16 * 4);
r.centroid_priority = static_cast<uint64_t>(buffer[18]) | (static_cast<uint64_t>(buffer[19]) << 32u);
cp->GetCtx()->SetAaSampleControl(r);
} else
{
KYTY_NOT_IMPLEMENTED;
}
return count;
}
KYTY_HW_CTX_PARSER(hw_ctx_set_depth_control)
{
EXIT_NOT_IMPLEMENTED(cmd_id != 0xC0016900);
@@ -2478,11 +2575,12 @@ KYTY_CP_OP_PARSER(cp_op_acquire_mem)
{
case 0x02c40040:
case 0x02c43fc0:
case 0x02c47fc0:
{
// target_mask: 0x00000040 (rt0), 0x00003fc0 (all rt)
// target_mask: 0x00000040 (rt0), 0x00003fc0 (all rt), 0x00007fc0 (all rt and depth)
// extended_action: 0x02000000 (FlushAndInvalidateCbCache)
// action: 0x38 (WriteBackAndInvalidateL1andL2)
EXIT_IF(target_mask != 0x00000040 && target_mask != 0x00003FC0);
EXIT_IF(target_mask != 0x00000040 && target_mask != 0x00003FC0 && target_mask != 0x00007FC0);
EXIT_IF(extended_action != 0x02000000);
EXIT_IF(action != 0x38);
EXIT_NOT_IMPLEMENTED(size_lo == 0);
@@ -2624,6 +2722,11 @@ KYTY_CP_OP_PARSER(cp_op_marker)
case 0x0: cp->SetEmbeddedDataMarker(buffer + 1, len_dw, align); break;
case 0x4: cp->SetUserDataMarker(HW::UserSgprType::Vsharp); break;
case 0xd: cp->SetUserDataMarker(HW::UserSgprType::Region); break;
case 0x777:
{
cp->Flip();
break;
}
case 0x778:
{
auto* addr = reinterpret_cast<void*>(buffer[1] | (static_cast<uint64_t>(buffer[2]) << 32u));
@@ -2730,28 +2833,31 @@ static void graphics_init_jmp_tables()
func = nullptr;
}
g_hw_ctx_func[Pm4::DB_RENDER_CONTROL] = hw_ctx_set_render_control;
g_hw_ctx_func[Pm4::DB_STENCIL_CLEAR] = hw_ctx_set_stencil_clear;
g_hw_ctx_func[Pm4::DB_DEPTH_CLEAR] = hw_ctx_set_depth_clear;
g_hw_ctx_func[Pm4::PA_SC_SCREEN_SCISSOR_TL] = hw_ctx_set_screen_scissor;
g_hw_ctx_func[Pm4::DB_Z_INFO] = hw_ctx_set_depth_render_target;
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::PA_SC_GENERIC_SCISSOR_TL] = hw_ctx_set_generic_scissor;
g_hw_ctx_func[Pm4::CB_BLEND_RED] = hw_ctx_set_blend_color;
g_hw_ctx_func[Pm4::DB_STENCIL_CONTROL] = hw_ctx_set_stencil_control;
g_hw_ctx_func[Pm4::DB_STENCILREFMASK] = hw_ctx_set_stencil_mask;
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[Pm4::CB_COLOR_CONTROL] = hw_ctx_set_color_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;
g_hw_ctx_func[Pm4::PA_SU_LINE_CNTL] = hw_ctx_set_line_control;
g_hw_ctx_func[Pm4::VGT_SHADER_STAGES_EN] = hw_ctx_set_shader_stages;
g_hw_ctx_func[0x2fa] = hw_ctx_set_guard_bands;
g_hw_ctx_func[Pm4::DB_RENDER_CONTROL] = hw_ctx_set_render_control;
g_hw_ctx_func[Pm4::DB_STENCIL_CLEAR] = hw_ctx_set_stencil_clear;
g_hw_ctx_func[Pm4::DB_DEPTH_CLEAR] = hw_ctx_set_depth_clear;
g_hw_ctx_func[Pm4::PA_SC_SCREEN_SCISSOR_TL] = hw_ctx_set_screen_scissor;
g_hw_ctx_func[Pm4::DB_Z_INFO] = hw_ctx_set_depth_render_target;
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::PA_SC_GENERIC_SCISSOR_TL] = hw_ctx_set_generic_scissor;
g_hw_ctx_func[Pm4::CB_BLEND_RED] = hw_ctx_set_blend_color;
g_hw_ctx_func[Pm4::DB_STENCIL_CONTROL] = hw_ctx_set_stencil_control;
g_hw_ctx_func[Pm4::DB_STENCILREFMASK] = hw_ctx_set_stencil_mask;
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[Pm4::CB_COLOR_CONTROL] = hw_ctx_set_color_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;
g_hw_ctx_func[Pm4::PA_SU_LINE_CNTL] = hw_ctx_set_line_control;
g_hw_ctx_func[Pm4::PA_SC_MODE_CNTL_0] = hw_ctx_set_scan_mode_control;
g_hw_ctx_func[Pm4::PA_SC_AA_CONFIG] = hw_ctx_set_aa_config;
g_hw_ctx_func[Pm4::PA_SC_AA_SAMPLE_LOCS_PIXEL_X0Y0_0] = hw_ctx_set_aa_sample_control;
g_hw_ctx_func[Pm4::VGT_SHADER_STAGES_EN] = hw_ctx_set_shader_stages;
g_hw_ctx_func[0x2fa] = hw_ctx_set_guard_bands;
for (uint32_t slot = 0; slot < 8; slot++)
{
@@ -159,6 +159,12 @@ bool DepthStencilBufferObject::Equal(const uint64_t* other) const
params[PARAM_HEIGHT] == other[PARAM_HEIGHT] && params[PARAM_HTILE] == other[PARAM_HTILE]);
}
// bool DepthStencilBufferObject::Reuse(const uint64_t* other) const
//{
// return (params[PARAM_FORMAT] == other[PARAM_FORMAT] && params[PARAM_WIDTH] <= other[PARAM_WIDTH] &&
// params[PARAM_HEIGHT] <= other[PARAM_HEIGHT] && params[PARAM_HTILE] == other[PARAM_HTILE]);
//}
GpuObject::create_func_t DepthStencilBufferObject::GetCreateFunc() const
{
return create_func;
File diff suppressed because it is too large Load Diff
+62 -37
View File
@@ -54,16 +54,19 @@ public:
virtual ~LabelManager() { KYTY_NOT_IMPLEMENTED; }
KYTY_CLASS_NO_COPY(LabelManager);
Label* Create(GraphicContext* ctx, uint64_t* dst_gpu_addr, uint64_t value, LabelGpuObject::callback_t callback_1,
LabelGpuObject::callback_t callback_2, const uint64_t* args);
Label* Create(GraphicContext* ctx, uint32_t* dst_gpu_addr, uint32_t value, LabelGpuObject::callback_t callback_1,
LabelGpuObject::callback_t callback_2, const uint64_t* args);
Label* Create64(GraphicContext* ctx, uint64_t* dst_gpu_addr, uint64_t value, LabelGpuObject::callback_t callback_1,
LabelGpuObject::callback_t callback_2, const uint64_t* args);
Label* Create32(GraphicContext* ctx, uint32_t* dst_gpu_addr, uint32_t value, LabelGpuObject::callback_t callback_1,
LabelGpuObject::callback_t callback_2, const uint64_t* args);
void Delete(Label* label);
void Set(CommandBuffer* buffer, Label* label);
private:
static void ThreadRun(void* data);
bool Remove(Label* label);
static void Destroy(Label* label);
Core::Mutex m_mutex;
Core::CondVar m_cond_var;
Vector<Label*> m_labels;
@@ -104,18 +107,24 @@ void LabelManager::ThreadRun(void* data)
}
}
for (auto& label: deleted_labels)
{
manager->Delete(label);
}
if (active_count == 0)
{
manager->m_cond_var.Wait(&manager->m_mutex);
}
for (auto& label: deleted_labels)
{
bool removed = manager->Remove(label);
EXIT_NOT_IMPLEMENTED(!removed);
}
manager->m_mutex.Unlock();
for (auto& label: deleted_labels)
{
Destroy(label);
}
for (auto& label: fired_labels)
{
bool write = true;
@@ -151,11 +160,11 @@ void LabelManager::ThreadRun(void* data)
}
}
Label* LabelManager::Create(GraphicContext* ctx, uint64_t* dst_gpu_addr, uint64_t value, LabelGpuObject::callback_t callback_1,
LabelGpuObject::callback_t callback_2, const uint64_t* args)
Label* LabelManager::Create64(GraphicContext* ctx, uint64_t* dst_gpu_addr, uint64_t value, LabelGpuObject::callback_t callback_1,
LabelGpuObject::callback_t callback_2, const uint64_t* args)
{
EXIT_IF(ctx == nullptr);
EXIT_IF(dst_gpu_addr == nullptr);
EXIT_IF(args == nullptr);
Core::LockGuard lock(m_mutex);
@@ -190,11 +199,10 @@ Label* LabelManager::Create(GraphicContext* ctx, uint64_t* dst_gpu_addr, uint64_
return label;
}
Label* LabelManager::Create(GraphicContext* ctx, uint32_t* dst_gpu_addr, uint32_t value, LabelGpuObject::callback_t callback_1,
LabelGpuObject::callback_t callback_2, const uint64_t* args)
Label* LabelManager::Create32(GraphicContext* ctx, uint32_t* dst_gpu_addr, uint32_t value, LabelGpuObject::callback_t callback_1,
LabelGpuObject::callback_t callback_2, const uint64_t* args)
{
EXIT_IF(ctx == nullptr);
EXIT_IF(dst_gpu_addr == nullptr);
EXIT_IF(args == nullptr);
Core::LockGuard lock(m_mutex);
@@ -229,7 +237,7 @@ Label* LabelManager::Create(GraphicContext* ctx, uint32_t* dst_gpu_addr, uint32_
return label;
}
void LabelManager::Delete(Label* label)
bool LabelManager::Remove(Label* label)
{
EXIT_IF(label == nullptr);
EXIT_IF(label->event == nullptr);
@@ -246,18 +254,35 @@ void LabelManager::Delete(Label* label)
if (label->status == LabelStatus::Active)
{
label->status = LabelStatus::ActiveDeleted;
} else
return false;
}
m_labels.RemoveAt(index);
return true;
}
void LabelManager::Destroy(Label* label)
{
EXIT_IF(label == nullptr);
EXIT_IF(label->event == nullptr);
EXIT_IF(label->device == nullptr);
EXIT_IF(label->buffer == nullptr);
// All submitted commands that refer to event must have completed execution
label->buffer->CommandProcessorWait();
vkDestroyEvent(label->device, label->event, nullptr);
delete label;
}
void LabelManager::Delete(Label* label)
{
if (Remove(label))
{
m_labels.RemoveAt(index);
EXIT_IF(label->buffer == nullptr);
// All submitted commands that refer to event must have completed execution
label->buffer->CommandProcessorWait();
vkDestroyEvent(label->device, label->event, nullptr);
delete label;
Destroy(label);
}
}
@@ -300,20 +325,20 @@ void LabelInit()
g_label_manager = new LabelManager;
}
Label* LabelCreate(GraphicContext* ctx, uint64_t* dst_gpu_addr, uint64_t value, LabelGpuObject::callback_t callback_1,
LabelGpuObject::callback_t callback_2, const uint64_t* args)
Label* LabelCreate64(GraphicContext* ctx, uint64_t* dst_gpu_addr, uint64_t value, LabelGpuObject::callback_t callback_1,
LabelGpuObject::callback_t callback_2, const uint64_t* args)
{
EXIT_IF(g_label_manager == nullptr);
return g_label_manager->Create(ctx, dst_gpu_addr, value, callback_1, callback_2, args);
return g_label_manager->Create64(ctx, dst_gpu_addr, value, callback_1, callback_2, args);
}
Label* LabelCreate(GraphicContext* ctx, uint32_t* dst_gpu_addr, uint32_t value, LabelGpuObject::callback_t callback_1,
LabelGpuObject::callback_t callback_2, const uint64_t* args)
Label* LabelCreate32(GraphicContext* ctx, uint32_t* dst_gpu_addr, uint32_t value, LabelGpuObject::callback_t callback_1,
LabelGpuObject::callback_t callback_2, const uint64_t* args)
{
EXIT_IF(g_label_manager == nullptr);
return g_label_manager->Create(ctx, dst_gpu_addr, value, callback_1, callback_2, args);
return g_label_manager->Create32(ctx, dst_gpu_addr, value, callback_1, callback_2, args);
}
void LabelDelete(Label* label)
@@ -343,10 +368,10 @@ static void* create_func(GraphicContext* ctx, const uint64_t* params, const uint
auto callback_1 = reinterpret_cast<LabelGpuObject::callback_t>(params[LabelGpuObject::PARAM_CALLBACK_1]);
auto callback_2 = reinterpret_cast<LabelGpuObject::callback_t>(params[LabelGpuObject::PARAM_CALLBACK_2]);
auto* label_obj = (*size == 8 ? LabelCreate(ctx, reinterpret_cast<uint64_t*>(*vaddr), value, callback_1, callback_2,
params + LabelGpuObject::PARAM_ARG_1)
: (*size == 4 ? LabelCreate(ctx, reinterpret_cast<uint32_t*>(*vaddr), static_cast<uint32_t>(value),
callback_1, callback_2, params + LabelGpuObject::PARAM_ARG_1)
auto* label_obj = (*size == 8 ? LabelCreate64(ctx, reinterpret_cast<uint64_t*>(*vaddr), value, callback_1, callback_2,
params + LabelGpuObject::PARAM_ARG_1)
: (*size == 4 ? LabelCreate32(ctx, reinterpret_cast<uint32_t*>(*vaddr), static_cast<uint32_t>(value),
callback_1, callback_2, params + LabelGpuObject::PARAM_ARG_1)
: nullptr));
EXIT_NOT_IMPLEMENTED(label_obj == nullptr);
+48 -3
View File
@@ -354,7 +354,7 @@ String ShaderCode::DbgDump() const
String ret;
for (const auto& inst: m_instructions)
{
if (m_labels.Contains(inst.pc, [](auto label, auto pc) { return label.dst == pc; }))
if (m_labels.Contains(inst.pc, [](auto label, auto pc) { return label.GetDst() == pc; }))
{
ret += String::FromPrintf("label_%04" PRIx32 ":\n", inst.pc);
}
@@ -363,6 +363,51 @@ String ShaderCode::DbgDump() const
return ret;
}
bool ShaderCode::IsDiscardInstruction(uint32_t index) const
{
if (!(index == 0 || index + 1 >= m_instructions.Size()))
{
const auto& prev_inst = m_instructions.At(index - 1);
const auto& inst = m_instructions.At(index);
const auto& next_inst = m_instructions.At(index + 1);
return (inst.type == ShaderInstructionType::Exp && inst.format == ShaderInstructionFormat::Mrt0OffOffComprVmDone &&
prev_inst.type == ShaderInstructionType::SMovB64 && prev_inst.format == ShaderInstructionFormat::Sdst2Ssrc02 &&
prev_inst.dst.type == ShaderOperandType::ExecLo && prev_inst.src[0].type == ShaderOperandType::IntegerInlineConstant &&
prev_inst.src[0].constant.i == 0 && next_inst.type == ShaderInstructionType::SEndpgm);
}
return false;
}
bool ShaderCode::IsDiscardBlock(uint32_t pc) const
{
auto inst_count = m_instructions.Size();
for (uint32_t index = 0; index < inst_count; index++)
{
const auto& inst = m_instructions.At(index);
if (inst.pc == pc)
{
for (uint32_t i = index; i < inst_count; i++)
{
const auto& inst = m_instructions.At(i);
if (inst.type == ShaderInstructionType::SEndpgm || inst.type == ShaderInstructionType::SCbranchExecz ||
inst.type == ShaderInstructionType::SCbranchScc0)
{
return false;
}
if (IsDiscardInstruction(i))
{
return true;
}
}
return false;
}
}
return false;
}
static ShaderOperand operand_parse(uint32_t code)
{
ShaderOperand ret;
@@ -555,7 +600,7 @@ KYTY_SHADER_PARSER(shader_parse_sopp)
if (inst.type == ShaderInstructionType::SCbranchScc0 || inst.type == ShaderInstructionType::SCbranchExecz)
{
dst->GetLabels().Add(ShaderLabel({inst.pc + 4 + inst.src[0].constant.i, inst.pc}));
dst->GetLabels().Add(ShaderLabel(inst));
}
return 1;
@@ -1782,7 +1827,7 @@ KYTY_SHADER_PARSER(shader_parse)
}
if ((instruction == 0xBF810000 && (type == ShaderType::Vertex || type == ShaderType::Pixel || type == ShaderType::Compute) &&
!dst->GetLabels().Contains(4 * static_cast<uint32_t>(ptr - src), [](auto label, auto pc) { return label.dst == pc; })) ||
!dst->GetLabels().Contains(4 * static_cast<uint32_t>(ptr - src), [](auto label, auto pc) { return label.GetDst() == pc; })) ||
(instruction == 0xBE802000 && type == ShaderType::Fetch))
{
break;
+33 -13
View File
@@ -2036,17 +2036,24 @@ KYTY_RECOMPILER_FUNC(Recompile_Exp_Mrt0OffOffComprVmDone)
{
EXIT_NOT_IMPLEMENTED(index == 0 || index + 1 >= code.GetInstructions().Size());
const auto& prev_inst = code.GetInstructions().At(index - 1);
const auto& inst = code.GetInstructions().At(index);
const auto& next_inst = code.GetInstructions().At(index + 1);
if (!(prev_inst.type == ShaderInstructionType::SMovB64 && prev_inst.format == ShaderInstructionFormat::Sdst2Ssrc02 &&
prev_inst.dst.type == ShaderOperandType::ExecLo && prev_inst.src[0].type == ShaderOperandType::IntegerInlineConstant &&
prev_inst.src[0].constant.i == 0 && next_inst.type == ShaderInstructionType::SEndpgm))
if (!code.IsDiscardInstruction(index))
{
return false;
}
// const auto& prev_inst = code.GetInstructions().At(index - 1);
// const auto& inst = code.GetInstructions().At(index);
// const auto& next_inst = code.GetInstructions().At(index + 1);
//
// if (!(prev_inst.type == ShaderInstructionType::SMovB64 && prev_inst.format == ShaderInstructionFormat::Sdst2Ssrc02 &&
// prev_inst.dst.type == ShaderOperandType::ExecLo && prev_inst.src[0].type == ShaderOperandType::IntegerInlineConstant &&
// prev_inst.src[0].constant.i == 0 && next_inst.type == ShaderInstructionType::SEndpgm))
// {
// return false;
// }
const auto& inst = code.GetInstructions().At(index);
const auto* info = spirv->GetPsInputInfo();
EXIT_NOT_IMPLEMENTED(info == nullptr || !info->ps_pixel_kill_enable);
@@ -3188,7 +3195,7 @@ KYTY_RECOMPILER_FUNC(Recompile_SCbranchExecz_Label)
EXIT_NOT_IMPLEMENTED(!operand_is_constant(inst.src[0]));
String label = String::FromPrintf("label_%04" PRIx32 "_%04" PRIx32, inst.pc + 4 + inst.src[0].constant.i, inst.pc);
String label = ShaderLabel(inst).ToString();
static const char32_t* text = UR"(
%execz_u_<index> = OpLoad %uint %execz
@@ -3209,17 +3216,30 @@ KYTY_RECOMPILER_FUNC(Recompile_SCbranchScc0_Label)
EXIT_NOT_IMPLEMENTED(!operand_is_constant(inst.src[0]));
String label = String::FromPrintf("label_%04" PRIx32 "_%04" PRIx32, inst.pc + 4 + inst.src[0].constant.i, inst.pc);
auto label = ShaderLabel(inst);
String label_str = label.ToString();
static const char32_t* text = UR"(
// TODO(): analyze control flow graph
bool discard = code.IsDiscardBlock(label.GetDst());
static const char32_t* text_variant_a = UR"(
%scc_u_<index> = OpLoad %uint %scc
%scc_b_<index> = OpIEqual %bool %scc_u_<index> %uint_0
OpSelectionMerge %<label> None
OpBranchConditional %scc_b_<index> %<label> %t230_<index>
%t230_<index> = OpLabel
)";
static const char32_t* text_variant_b = UR"(
%scc_u_<index> = OpLoad %uint %scc
%scc_b_<index> = OpIEqual %bool %scc_u_<index> %uint_0
OpSelectionMerge %t230_<index> None
OpBranchConditional %scc_b_<index> %<label> %t230_<index>
%t230_<index> = OpLabel
)";
*dst_source += String(text).ReplaceStr(U"<index>", String::FromPrintf("%u", index)).ReplaceStr(U"<label>", label);
*dst_source += String(discard ? text_variant_b : text_variant_a)
.ReplaceStr(U"<index>", String::FromPrintf("%u", index))
.ReplaceStr(U"<label>", label_str);
return true;
}
@@ -6158,7 +6178,7 @@ void Spirv::WriteInstructions()
for (uint32_t i = labels.Size(); i > 0; i--)
{
auto label = labels.At(i - 1);
if (index > 0 && label.dst == inst.pc)
if (index > 0 && label.GetDst() == inst.pc)
{
static const char32_t* text = UR"(
<branch>
@@ -6170,7 +6190,7 @@ void Spirv::WriteInstructions()
m_source += String(text)
.ReplaceStr(U"<branch>", (skip_branch ? U"" : U"OpBranch %<label>"))
.ReplaceStr(U"<label>", String::FromPrintf("label_%04" PRIx32 "_%04" PRIx32, label.dst, label.src));
.ReplaceStr(U"<label>", label.ToString());
}
}
+150 -155
View File
@@ -452,27 +452,21 @@ void TileConvertTiledToLinear(void* dst, const void* src, TileMode mode, uint32_
}
}
void TileGetDepthSize(uint32_t width, uint32_t height, uint32_t z_format, uint32_t stencil_format, bool htile, bool neo,
uint32_t* stencil_size, uint32_t* htile_size, uint32_t* depth_size, uint32_t* pitch)
bool TileGetDepthSize(uint32_t width, uint32_t height, uint32_t pitch, uint32_t z_format, uint32_t stencil_format, bool htile, bool neo,
TileSizeAlign* stencil_size, TileSizeAlign* htile_size, TileSizeAlign* depth_size)
{
struct SizeAlign
{
uint32_t size;
uint32_t align;
};
struct DepthInfo
{
uint32_t width;
uint32_t height;
uint32_t z_format;
uint32_t stencil_format;
bool tile;
bool neo;
uint32_t pitch;
SizeAlign stencil;
SizeAlign htile;
SizeAlign depth;
uint32_t width = 0;
uint32_t height = 0;
uint32_t z_format = 0;
uint32_t stencil_format = 0;
bool tile = false;
bool neo = false;
uint32_t pitch = 0;
TileSizeAlign stencil = {};
TileSizeAlign htile = {};
TileSizeAlign depth = {};
};
static const DepthInfo infos_base[] = {
@@ -513,6 +507,8 @@ void TileGetDepthSize(uint32_t width, uint32_t height, uint32_t z_format, uint32
{3840, 2160, 3, 0, false, true, 3840, {0, 0}, {0, 0}, {33423360, 65536}},
{1920, 1080, 3, 0, true, true, 1920, {0, 0}, {196608, 4096}, {8847360, 65536}},
{1920, 1080, 3, 0, false, true, 1920, {0, 0}, {0, 0}, {8847360, 65536}},
{1920, 1080, 3, 0, true, true, 2048, {0, 0}, {196608, 4096}, {9437184, 65536}},
{1920, 1080, 3, 0, false, true, 2048, {0, 0}, {0, 0}, {9437184, 65536}},
{1280, 720, 3, 0, true, true, 1280, {0, 0}, {131072, 4096}, {3932160, 65536}},
{1280, 720, 3, 0, false, true, 1280, {0, 0}, {0, 0}, {3932160, 65536}},
{3840, 2160, 1, 0, true, true, 3840, {0, 0}, {655360, 4096}, {16711680, 65536}},
@@ -544,187 +540,184 @@ void TileGetDepthSize(uint32_t width, uint32_t height, uint32_t z_format, uint32
EXIT_IF(depth_size == nullptr);
EXIT_IF(htile_size == nullptr);
EXIT_IF(stencil_size == nullptr);
EXIT_IF(pitch == nullptr);
if (neo)
{
for (const auto& i: infos_neo)
{
if (i.width == width && i.height == height && i.tile == htile && i.z_format == z_format && i.stencil_format == stencil_format)
if (i.width == width && i.height == height && i.pitch == pitch && i.tile == htile && i.z_format == z_format &&
i.stencil_format == stencil_format)
{
*depth_size = i.depth.size;
*htile_size = i.htile.size;
*stencil_size = i.stencil.size;
*pitch = i.pitch;
return;
*depth_size = i.depth;
*htile_size = i.htile;
*stencil_size = i.stencil;
return true;
}
}
} else
{
for (const auto& i: infos_base)
{
if (i.width == width && i.height == height && i.tile == htile && i.z_format == z_format && i.stencil_format == stencil_format)
if (i.width == width && i.height == height && i.pitch == pitch && i.tile == htile && i.z_format == z_format &&
i.stencil_format == stencil_format)
{
*depth_size = i.depth.size;
*htile_size = i.htile.size;
*stencil_size = i.stencil.size;
*pitch = i.pitch;
return;
*depth_size = i.depth;
*htile_size = i.htile;
*stencil_size = i.stencil;
return true;
}
}
}
*depth_size = 0;
*htile_size = 0;
*stencil_size = 0;
*depth_size = TileSizeAlign();
*htile_size = TileSizeAlign();
*stencil_size = TileSizeAlign();
return false;
}
void TileGetVideoOutSize(uint32_t width, uint32_t height, bool tile, bool neo, uint32_t* size, uint32_t* pitch)
void TileGetVideoOutSize(uint32_t width, uint32_t height, uint32_t pitch, bool tile, bool neo, TileSizeAlign* size)
{
EXIT_IF(size == nullptr);
EXIT_IF(pitch == nullptr);
uint32_t ret_size = 0;
uint32_t ret_pitch = 0;
uint32_t ret_align = 0;
if (width == 3840 && height == 2160 && tile && !neo)
if (pitch == 3840)
{
ret_size = 33423360;
ret_pitch = 3840;
}
if (width == 3840 && height == 2160 && tile && neo)
{
ret_size = 33423360;
ret_pitch = 3840;
}
if (width == 3840 && height == 2160 && !tile && !neo)
{
ret_size = 33177600;
ret_pitch = 3840;
}
if (width == 3840 && height == 2160 && !tile && neo)
{
ret_size = 33177600;
ret_pitch = 3840;
if (width == 3840 && height == 2160 && tile && !neo)
{
ret_size = 33423360;
ret_align = 32768;
}
if (width == 3840 && height == 2160 && tile && neo)
{
ret_size = 33423360;
ret_align = 65536;
}
if (width == 3840 && height == 2160 && !tile && !neo)
{
ret_size = 33177600;
ret_align = 256;
}
if (width == 3840 && height == 2160 && !tile && neo)
{
ret_size = 33177600;
ret_align = 256;
}
}
if (width == 1920 && height == 1080 && tile && !neo)
if (pitch == 1920)
{
ret_size = 8355840;
ret_pitch = 1920;
}
if (width == 1920 && height == 1080 && tile && neo)
{
ret_size = 8847360;
ret_pitch = 1920;
}
if (width == 1920 && height == 1080 && !tile && !neo)
{
ret_size = 8294400;
ret_pitch = 1920;
}
if (width == 1920 && height == 1080 && !tile && neo)
{
ret_size = 8294400;
ret_pitch = 1920;
if (width == 1920 && height == 1080 && tile && !neo)
{
ret_size = 8355840;
ret_align = 32768;
}
if (width == 1920 && height == 1080 && tile && neo)
{
ret_size = 8847360;
ret_align = 65536;
}
if (width == 1920 && height == 1080 && !tile && !neo)
{
ret_size = 8294400;
ret_align = 256;
}
if (width == 1920 && height == 1080 && !tile && neo)
{
ret_size = 8294400;
ret_align = 256;
}
}
if (width == 1280 && height == 720 && tile && !neo)
if (pitch == 1280)
{
ret_size = 3932160;
ret_pitch = 1280;
}
if (width == 1280 && height == 720 && tile && neo)
{
ret_size = 3932160;
ret_pitch = 1280;
}
if (width == 1280 && height == 720 && !tile && !neo)
{
ret_size = 3686400;
ret_pitch = 1280;
}
if (width == 1280 && height == 720 && !tile && neo)
{
ret_size = 3686400;
ret_pitch = 1280;
if (width == 1280 && height == 720 && tile && !neo)
{
ret_size = 3932160;
ret_align = 32768;
}
if (width == 1280 && height == 720 && tile && neo)
{
ret_size = 3932160;
ret_align = 65536;
}
if (width == 1280 && height == 720 && !tile && !neo)
{
ret_size = 3686400;
ret_align = 256;
}
if (width == 1280 && height == 720 && !tile && neo)
{
ret_size = 3686400;
ret_align = 256;
}
}
*size = ret_size;
*pitch = ret_pitch;
size->size = ret_size;
size->align = ret_align;
}
void TileGetTextureSize(uint32_t dfmt, uint32_t nfmt, uint32_t width, uint32_t height, uint32_t pitch, uint32_t levels, uint32_t tile,
bool neo, uint32_t* total_size, uint32_t* level_sizes, uint32_t* padded_width, uint32_t* padded_height)
bool neo, TileSizeAlign* total_size, uint32_t* level_sizes, uint32_t* padded_width, uint32_t* padded_height)
{
KYTY_PROFILER_FUNCTION();
struct Padded
{
uint32_t width;
uint32_t height;
uint32_t width = 0;
uint32_t height = 0;
};
struct TextureInfo
{
uint32_t dfmt;
uint32_t nfmt;
uint32_t width;
uint32_t height;
uint32_t levels;
uint32_t tile;
bool neo;
uint32_t size[16];
Padded padded[16];
uint32_t dfmt = 0;
uint32_t nfmt = 0;
uint32_t width = 0;
uint32_t height = 0;
uint32_t pitch = 0;
uint32_t levels = 0;
uint32_t tile = 0;
bool neo = false;
TileSizeAlign size[16];
Padded padded[16];
};
static const TextureInfo infos[] = {
// clang-format off
// kDataFormatB8G8R8A8UnormSrgb, 512, 512, kTileModeDisplay_LinearAligned
{ 10, 9, 512, 512, 10, 8, false, {1048576, 262144, 65536, 16384, 4096, 1024, 512, 256, 256, 256, },
{ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, } },
{ 10, 9, 512, 512, 10, 8, true, {1048576, 262144, 65536, 16384, 4096, 1024, 512, 256, 256, 256, },
{ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, } },
// kDataFormatB8G8R8A8UnormSrgb, 512, 512, kTileModeThin_1dThin
{ 10, 9, 512, 512, 10, 13, false, {1048576, 262144, 65536, 16384, 4096, 1024, 256, 256, 256, 256, },
{ {512, 512}, {256, 256}, {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
{ 10, 9, 512, 512, 10, 13, true, {1048576, 262144, 65536, 16384, 4096, 1024, 256, 256, 256, 256, },
{ {512, 512}, {256, 256}, {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
// kDataFormatBc3UnormSrgb, 512, 512, kTileModeDisplay_LinearAligned
{ 37, 9, 512, 512, 10, 8, false, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
{ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, } },
{ 37, 9, 512, 512, 10, 8, true, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },
{ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, } },
// kDataFormatBc3UnormSrgb, 512, 512, kTileModeThin_1dThin
{ 37, 9, 512, 512, 10, 13, false, {262144, 65536, 16384, 4096, 1024, 1024, 1024, 1024, 1024, 1024, },
{ {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
{ 37, 9, 512, 512, 10, 13, true, {262144, 65536, 16384, 4096, 1024, 1024, 1024, 1024, 1024, 1024, },
{ {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
// kDataFormatB8G8R8A8Unorm, 512, 512, kTileModeThin_1dThin
{ 10, 0, 512, 512, 10, 13, false, {1048576, 262144, 65536, 16384, 4096, 1024, 256, 256, 256, 256, },
{ {512, 512}, {256, 256}, {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
{ 10, 0, 512, 512, 10, 13, true, {1048576, 262144, 65536, 16384, 4096, 1024, 256, 256, 256, 256, },
{ {512, 512}, {256, 256}, {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
// kDataFormatB8G8R8A8Unorm, 512, 768, kTileModeThin_1dThin
{ 10, 0, 512, 768, 10, 13, false, {1572864, 1048576, 131072, 32768, 8192, 2048, 512, 256, 256, 256, },
{ {512, 768}, {256, 512}, {128, 256}, {64, 128}, {32, 64}, {16, 32}, {8, 16}, {8, 8}, {8, 8}, {8, 8}, } },
{ 10, 0, 512, 768, 10, 13, true, {1572864, 1048576, 131072, 32768, 8192, 2048, 512, 256, 256, 256, },
{ {512, 768}, {256, 512}, {128, 256}, {64, 128}, {32, 64}, {16, 32}, {8, 16}, {8, 8}, {8, 8}, {8, 8}, } },
// kDataFormatB8G8R8A8Unorm, 256, 256, kTileModeThin_2dThin
{ 10, 0, 256, 256, 9, 14, false, {262144, 65536, 16384, 4096, 1024, 256, 256, 256, 256, },
{ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, } },
{ 10, 0, 256, 256, 9, 14, true, {262144, 65536, 16384, 4096, 1024, 256, 256, 256, 256, },
{ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, } },
// kDataFormatR32Float, 1920, 1080, kTileModeDepth_2dThin_256
{ 4, 7, 1920, 1080, 11, 2, false, {8355840, 12615680, 1048576, 262144, 65536, 16384, 2048, 1024, 1024, 1024, 1024, },
{ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, } },
{ 4, 7, 1920, 1080, 11, 2, true, {8847360, 12124160, 1048576, 262144, 65536, 16384, 2048, 1024, 1024, 1024, 1024, },
{ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, } },
// kDataFormatR8Unorm, 2048, 2048, kTileModeDisplay_LinearAligned
{ 1, 0, 2048, 2048, 12, 8, false, {4194304, 1048576, 262144, 65536, 16384, 4096, 2048, 1024, 512, 256, 256, 256, },
{ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, } },
{ 1, 0, 2048, 2048, 12, 8, true, {4194304, 1048576, 262144, 65536, 16384, 4096, 2048, 1024, 512, 256, 256, 256, },
{ {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, } },
// kDataFormatB8G8R8A8UnormSrgb, 512, 512, 0, 0, kTileModeDisplay_LinearAligned
{ 10, 9, 512, 512, 512, 10, 8, false, {{1048576, 256}, {262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {1024, 256}, {512, 256}, {256, 256}, {256, 256}, {256, 256}, }, { {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, } },
{ 10, 9, 512, 512, 512, 10, 8, true, {{1048576, 256}, {262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {1024, 256}, {512, 256}, {256, 256}, {256, 256}, {256, 256}, }, { {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, } },
// kDataFormatB8G8R8A8UnormSrgb, 512, 512, 0, 0, kTileModeThin_1dThin
{ 10, 9, 512, 512, 512, 10, 13, false, {{1048576, 256}, {262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {1024, 256}, {256, 256}, {256, 256}, {256, 256}, {256, 256}, }, { {512, 512}, {256, 256}, {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
{ 10, 9, 512, 512, 512, 10, 13, true, {{1048576, 256}, {262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {1024, 256}, {256, 256}, {256, 256}, {256, 256}, {256, 256}, }, { {512, 512}, {256, 256}, {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
// kDataFormatBc3UnormSrgb, 512, 512, 0, 0, kTileModeThin_1dThin
{ 37, 9, 512, 512, 512, 10, 13, false, {{262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, }, { {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
{ 37, 9, 512, 512, 512, 10, 13, true, {{262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, {1024, 256}, }, { {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
// kDataFormatB8G8R8A8Unorm, 512, 512, 0, 0, kTileModeThin_1dThin
{ 10, 0, 512, 512, 512, 10, 13, false, {{1048576, 256}, {262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {1024, 256}, {256, 256}, {256, 256}, {256, 256}, {256, 256}, }, { {512, 512}, {256, 256}, {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
{ 10, 0, 512, 512, 512, 10, 13, true, {{1048576, 256}, {262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {1024, 256}, {256, 256}, {256, 256}, {256, 256}, {256, 256}, }, { {512, 512}, {256, 256}, {128, 128}, {64, 64}, {32, 32}, {16, 16}, {8, 8}, {8, 8}, {8, 8}, {8, 8}, } },
// kDataFormatB8G8R8A8Unorm, 512, 768, 0, 0, kTileModeThin_1dThin
{ 10, 0, 512, 768, 512, 10, 13, false, {{1572864, 256}, {1048576, 256}, {131072, 256}, {32768, 256}, {8192, 256}, {2048, 256}, {512, 256}, {256, 256}, {256, 256}, {256, 256}, }, { {512, 768}, {256, 512}, {128, 256}, {64, 128}, {32, 64}, {16, 32}, {8, 16}, {8, 8}, {8, 8}, {8, 8}, } },
{ 10, 0, 512, 768, 512, 10, 13, true, {{1572864, 256}, {1048576, 256}, {131072, 256}, {32768, 256}, {8192, 256}, {2048, 256}, {512, 256}, {256, 256}, {256, 256}, {256, 256}, }, { {512, 768}, {256, 512}, {128, 256}, {64, 128}, {32, 64}, {16, 32}, {8, 16}, {8, 8}, {8, 8}, {8, 8}, } },
// kDataFormatB8G8R8A8Unorm, 256, 256, 0, 0, kTileModeThin_2dThin
{ 10, 0, 256, 256, 256, 9, 14, false, {{262144, 32768}, {65536, 32768}, {16384, 32768}, {4096, 32768}, {1024, 32768}, {256, 32768}, {256, 32768}, {256, 32768}, {256, 32768}, }, { {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, } },
{ 10, 0, 256, 256, 256, 9, 14, true, {{262144, 65536}, {65536, 65536}, {16384, 65536}, {4096, 65536}, {1024, 65536}, {256, 65536}, {256, 65536}, {256, 65536}, {256, 65536}, }, { {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, } },
// kDataFormatB8G8R8A8Unorm, 1920, 1080, 1920, 1, kTileModeDisplay_2dThin
{ 10, 0, 1920, 1080, 1920, 1, 10, false, {{8355840, 32768}, }, { {0, 0}, } },
{ 10, 0, 1920, 1080, 1920, 1, 10, true, {{8847360, 65536}, }, { {0, 0}, } },
// kDataFormatB8G8R8A8Unorm, 3840, 2160, 3840, 1, kTileModeDisplay_2dThin
{ 10, 0, 3840, 2160, 3840, 1, 10, false, {{33423360, 32768}, }, { {0, 0}, } },
{ 10, 0, 3840, 2160, 3840, 1, 10, true, {{33423360, 65536}, }, { {0, 0}, } },
// kDataFormatR32Float, 1920, 1080, 1920, 1, kTileModeDepth_2dThin_256
{ 4, 7, 1920, 1080, 1920, 1, 2, false, {{8355840, 32768}, }, { {0, 0}, } },
{ 4, 7, 1920, 1080, 1920, 1, 2, true, {{8847360, 65536}, }, { {0, 0}, } },
// kDataFormatR8Unorm, 2048, 2048, 0, 0, kTileModeDisplay_LinearAligned
{ 1, 0, 2048, 2048, 2048, 12, 8, false, {{4194304, 256}, {1048576, 256}, {262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {2048, 256}, {1024, 256}, {512, 256}, {256, 256}, {256, 256}, {256, 256}, }, { {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, } },
{ 1, 0, 2048, 2048, 2048, 12, 8, true, {{4194304, 256}, {1048576, 256}, {262144, 256}, {65536, 256}, {16384, 256}, {4096, 256}, {2048, 256}, {1024, 256}, {512, 256}, {256, 256}, {256, 256}, {256, 256}, }, { {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, } },
// kDataFormatB8G8R8A8Unorm, 1, 1, 64, 0, kTileModeDisplay_LinearAligned
{ 10, 0, 1, 1, 64, 1, 8, false, {{256, 256}, }, { {0, 0}, } },
{ 10, 0, 1, 1, 64, 1, 8, true, {{256, 256}, }, { {0, 0}, } },
// clang-format on
};
@@ -733,18 +726,19 @@ void TileGetTextureSize(uint32_t dfmt, uint32_t nfmt, uint32_t width, uint32_t h
for (const auto& i: infos)
{
if (i.dfmt == dfmt && i.nfmt == nfmt && i.width == width && i.width == pitch && i.height == height && i.levels >= levels &&
if (i.dfmt == dfmt && i.nfmt == nfmt && i.width == width && i.pitch == pitch && i.height == height && i.levels >= levels &&
i.tile == tile && i.neo == neo)
{
for (uint32_t l = 0; l < levels; l++)
{
if (total_size != nullptr)
{
*total_size += i.size[l];
total_size->size += i.size[l].size;
total_size->align = i.size[l].align;
}
if (level_sizes != nullptr)
{
level_sizes[l] = i.size[l];
level_sizes[l] = i.size[l].size;
}
if (padded_width != nullptr)
{
@@ -759,12 +753,13 @@ void TileGetTextureSize(uint32_t dfmt, uint32_t nfmt, uint32_t width, uint32_t h
}
}
if (tile == 8 && levels == 1 && dfmt == 10 && nfmt == 9)
if (tile == 8 && levels == 1 && ((dfmt == 10 && nfmt == 9) || (dfmt == 10 && nfmt == 0)))
{
uint32_t size = pitch * height * 4;
if (total_size != nullptr)
{
*total_size = size;
total_size->size = size;
total_size->align = 256;
}
if (level_sizes != nullptr)
{
+4
View File
@@ -248,6 +248,8 @@ void UtilBlitImage(CommandBuffer* buffer, VulkanImage* src_image, VulkanSwapchai
void VulkanCreateBuffer(GraphicContext* gctx, uint64_t size, VulkanBuffer* buffer)
{
KYTY_PROFILER_FUNCTION();
EXIT_IF(gctx == nullptr);
EXIT_IF(buffer == nullptr);
EXIT_IF(buffer->buffer != nullptr);
@@ -272,6 +274,8 @@ void VulkanCreateBuffer(GraphicContext* gctx, uint64_t size, VulkanBuffer* buffe
void VulkanDeleteBuffer(GraphicContext* gctx, VulkanBuffer* buffer)
{
KYTY_PROFILER_FUNCTION();
EXIT_IF(buffer == nullptr);
EXIT_IF(gctx == nullptr);
+16 -12
View File
@@ -189,27 +189,28 @@ private:
static VideoOutContext* g_video_out_context = nullptr;
static void calc_buffer_size(const VideoOutBufferAttribute* attribute, uint64_t* size, uint64_t* pitch)
static void calc_buffer_size(const VideoOutBufferAttribute* attribute, uint64_t* out_size, uint64_t* out_align, uint64_t* out_pitch)
{
EXIT_IF(size == nullptr);
EXIT_IF(pitch == nullptr);
EXIT_IF(out_size == nullptr);
EXIT_IF(out_pitch == 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;
EXIT_NOT_IMPLEMENTED(attribute->width != attribute->pitchInPixel);
// 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);
uint32_t size32 = 0;
uint32_t pitch32 = 0;
Graphics::TileGetVideoOutSize(width, height, tile, neo, &size32, &pitch32);
Graphics::TileSizeAlign size32 {};
Graphics::TileGetVideoOutSize(width, height, pitch, tile, neo, &size32);
*size = size32;
*pitch = pitch32;
*out_size = size32.size;
*out_align = size32.align;
*out_pitch = pitch;
}
void VideoOutInit(uint32_t width, uint32_t height)
@@ -535,7 +536,7 @@ void VideoOutEndVblank()
{
EXIT_IF(g_video_out_context == nullptr);
// g_video_out_context->VblankEnd();
g_video_out_context->VblankEnd();
}
KYTY_SYSV_ABI int VideoOutOpen(int user_id, int bus_type, int index, const void* param)
@@ -821,8 +822,9 @@ KYTY_SYSV_ABI int VideoOutRegisterBuffers(int handle, int start_index, void* con
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_pitch);
calc_buffer_size(attribute, &buffer_size, &buffer_align, &buffer_pitch);
EXIT_NOT_IMPLEMENTED(buffer_size == 0);
EXIT_NOT_IMPLEMENTED(buffer_pitch == 0);
@@ -841,12 +843,14 @@ KYTY_SYSV_ABI int VideoOutRegisterBuffers(int handle, int start_index, void* con
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_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(
g_video_out_context->GetGraphicCtx(), nullptr, reinterpret_cast<uint64_t>(addresses[i]), buffer_size, vulkan_buffer_info));
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);
+19 -2
View File
@@ -50,6 +50,7 @@
namespace Kyty::Libs::Graphics {
constexpr float FPS_AVERAGE_FRAMES = 5.0f;
constexpr float FPS_UPDATE_TIME = 0.25f;
struct EventKeyboard
{
@@ -183,6 +184,8 @@ struct GameApi
double m_current_fps = {0.0};
int m_max_updates_per_frame = {4};
double m_update_fixed_time = 1.0 / 60.0;
int m_fps_frames_num = {0};
double m_fps_start_time = {0};
};
struct GameApiPrivateStruct
@@ -274,8 +277,22 @@ static void CalcFrameTime(GameApi* game, double game_time_s)
game->m_frame_num++;
game->m_current_fps = (1.0f / (game->m_current_time_seconds - game->m_previous_time_seconds)) * (1.0f / FPS_AVERAGE_FRAMES) +
game->m_current_fps * (1.0f - (1.0f / FPS_AVERAGE_FRAMES));
int fps_model = 1;
if (fps_model == 1)
{
game->m_fps_frames_num++;
if (game->m_current_time_seconds - game->m_fps_start_time > FPS_UPDATE_TIME)
{
game->m_current_fps = static_cast<double>(game->m_fps_frames_num) / (game->m_current_time_seconds - game->m_fps_start_time);
game->m_fps_frames_num = 0;
game->m_fps_start_time = game->m_current_time_seconds;
}
} else
{
game->m_current_fps = (1.0f / (game->m_current_time_seconds - game->m_previous_time_seconds)) * (1.0f / FPS_AVERAGE_FRAMES) +
game->m_current_fps * (1.0f - (1.0f / FPS_AVERAGE_FRAMES));
}
}
static bool Init(GameApi* /*game*/)
+57 -13
View File
@@ -283,9 +283,9 @@ int KYTY_SYSV_ABI KernelOpen(const char* path, int flags, uint16_t mode)
auto flags_u = static_cast<uint32_t>(flags);
printf("\tpath = %s\n", path);
printf("\tflags = %08" PRIx32 "\n", flags_u);
printf("\tmode = %04" PRIx16 "\n", mode);
printf("\t path = %s\n", path);
printf("\t flags = %08" PRIx32 "\n", flags_u);
printf("\t mode = %04" PRIx16 "\n", mode);
bool nonblock = (flags_u & 0x0004u) != 0;
bool append = (flags_u & 0x0008u) != 0;
@@ -330,14 +330,19 @@ int KYTY_SYSV_ABI KernelOpen(const char* path, int flags, uint16_t mode)
return KERNEL_ERROR_EACCES;
}
if (directory)
bool dir_exist = Core::File::IsDirectoryExisting(file->real_name);
if (directory || dir_exist)
{
if (!Core::File::IsDirectoryExisting(file->real_name))
if (!dir_exist)
{
g_files->DeleteDescriptor(descriptor);
return KERNEL_ERROR_ENOTDIR;
}
EXIT_NOT_IMPLEMENTED(!directory && rw_mode != Core::File::Mode::Read);
EXIT_NOT_IMPLEMENTED(!directory && (trunc || creat));
file->dents = Core::File::GetDirEntries(file->real_name);
file->dents_index = 0;
file->directory = true;
@@ -353,8 +358,6 @@ int KYTY_SYSV_ABI KernelOpen(const char* path, int flags, uint16_t mode)
{
bool result = false;
EXIT_NOT_IMPLEMENTED(Core::File::IsDirectoryExisting(file->real_name));
if (creat)
{
result = file->f.Create(file->real_name);
@@ -703,7 +706,7 @@ int KYTY_SYSV_ABI KernelStat(const char* path, FileStat* sb)
return KERNEL_ERROR_EINVAL;
}
printf("\tKernelStat: %s\n", path);
printf("\t KernelStat: %s\n", path);
String path_s = String::FromUtf8(path);
auto real_file_name = g_mount_points->GetRealFilename(path_s);
@@ -714,7 +717,7 @@ int KYTY_SYSV_ABI KernelStat(const char* path, FileStat* sb)
if (!is_dir && !is_file)
{
printf("\tfile not found\n");
printf("\t file not found\n");
return KERNEL_ERROR_ENOENT;
}
@@ -891,9 +894,9 @@ int KYTY_SYSV_ABI KernelGetdirentries(int fd, char* buf, int nbytes, int64_t* ba
EXIT_IF(!file->opened);
printf("\tdir = %s\n", file->real_name.C_Str());
printf("\tnbytes = %d\n", nbytes);
printf("\tindex = %d\n", file->dents_index);
printf("\t dir = %s\n", file->real_name.C_Str());
printf("\t nbytes = %d\n", nbytes);
printf("\t index = %d\n", file->dents_index);
if (basep != nullptr)
{
@@ -911,7 +914,7 @@ int KYTY_SYSV_ABI KernelGetdirentries(int fd, char* buf, int nbytes, int64_t* ba
auto str_size = str.Size() - 1;
EXIT_NOT_IMPLEMENTED(str_size > 255);
printf("\tname = %s\n", str.GetDataConst());
printf("\t name = %s\n", str.GetDataConst());
*reinterpret_cast<uint32_t*>(buf + 0) = entry.name.Hash();
*reinterpret_cast<uint16_t*>(buf + 4) = 512;
@@ -923,6 +926,47 @@ int KYTY_SYSV_ABI KernelGetdirentries(int fd, char* buf, int nbytes, int64_t* ba
return 512;
}
int KYTY_SYSV_ABI KernelGetdents(int fd, char* buf, int nbytes)
{
PRINT_NAME();
return KernelGetdirentries(fd, buf, nbytes, nullptr);
}
int KYTY_SYSV_ABI KernelMkdir(const char* path, uint16_t mode)
{
PRINT_NAME();
EXIT_IF(g_mount_points == nullptr || g_files == nullptr);
if (path == nullptr)
{
return KERNEL_ERROR_EINVAL;
}
printf("\t path = %s\n", path);
printf("\t mode = %04" PRIx16 "\n", mode);
String real_name = g_mount_points->GetRealDirectory(String::FromUtf8(path));
if (Core::File::IsDirectoryExisting(real_name))
{
return KERNEL_ERROR_EEXIST;
}
if (!Core::File::CreateDirectory(real_name))
{
return KERNEL_ERROR_EIO;
}
if (!Core::File::IsDirectoryExisting(real_name))
{
return KERNEL_ERROR_ENOENT;
}
return OK;
}
} // namespace Kyty::Libs::LibKernel::FileSystem
#endif // KYTY_EMU_ENABLED
+24
View File
@@ -1774,6 +1774,8 @@ int KYTY_SYSV_ABI PthreadCondSignal(PthreadCond* cond)
{
PRINT_NAME();
EXIT_NOT_IMPLEMENTED(cond == nullptr);
if (cond == nullptr)
{
return KERNEL_ERROR_EINVAL;
@@ -2266,6 +2268,13 @@ int KYTY_SYSV_ABI PthreadGetname(Pthread thread, char* name)
return OK;
}
void KYTY_SYSV_ABI PthreadYield()
{
PRINT_NAME();
sched_yield();
}
int KYTY_SYSV_ABI KernelClockGetres(KernelClockid clock_id, KernelTimespec* tp)
{
PRINT_NAME();
@@ -2535,6 +2544,21 @@ namespace Posix {
LIB_NAME("Posix", "libkernel");
int KYTY_SYSV_ABI pthread_create(LibKernel::Pthread* thread, const LibKernel::PthreadAttr* attr, LibKernel::pthread_entry_func_t entry,
void* arg)
{
PRINT_NAME();
return POSIX_PTHREAD_CALL(LibKernel::PthreadCreate(thread, attr, entry, arg, ""));
}
int KYTY_SYSV_ABI pthread_join(LibKernel::Pthread thread, void** value)
{
PRINT_NAME();
return POSIX_PTHREAD_CALL(LibKernel::PthreadJoin(thread, value));
}
int KYTY_SYSV_ABI pthread_cond_broadcast(LibKernel::PthreadCond* cond)
{
PRINT_NAME();
+29
View File
@@ -23,6 +23,20 @@ LIB_DEFINE(InitAudio_1_AudioOut)
} // namespace LibAudioOut
namespace LibAudioIn {
LIB_VERSION("AudioIn", 1, "AudioIn", 1, 1);
namespace AudioIn = Audio::AudioIn;
LIB_DEFINE(InitAudio_1_AudioIn)
{
LIB_FUNC("5NE8Sjc7VC8", AudioIn::AudioInOpen);
LIB_FUNC("LozEOU8+anM", AudioIn::AudioInInput);
}
} // namespace LibAudioIn
namespace LibVoiceQoS {
LIB_VERSION("VoiceQoS", 1, "VoiceQoS", 0, 0);
@@ -36,10 +50,25 @@ LIB_DEFINE(InitAudio_1_VoiceQoS)
} // namespace LibVoiceQoS
namespace LibAjm {
LIB_VERSION("Ajm", 1, "Ajm", 1, 1);
namespace Ajm = Audio::Ajm;
LIB_DEFINE(InitAudio_1_Ajm)
{
LIB_FUNC("dl+4eHSzUu4", Ajm::AjmInitialize);
}
} // namespace LibAjm
LIB_DEFINE(InitAudio_1)
{
LibAudioOut::InitAudio_1_AudioOut(s);
LibAudioIn::InitAudio_1_AudioIn(s);
LibVoiceQoS::InitAudio_1_VoiceQoS(s);
LibAjm::InitAudio_1_Ajm(s);
}
} // namespace Kyty::Libs
+16
View File
@@ -20,9 +20,25 @@ LIB_DEFINE(InitDialog_1_CommonDialog)
} // namespace LibCommonDialog
namespace LibSaveDataDialog {
LIB_VERSION("SaveDataDialog", 1, "SaveDataDialog", 1, 1);
namespace SaveDataDialog = Dialog::SaveDataDialog;
LIB_DEFINE(InitDialog_1_SaveDataDialog)
{
LIB_FUNC("KK3Bdg1RWK0", SaveDataDialog::SaveDataDialogUpdateStatus);
LIB_FUNC("YuH2FA7azqQ", SaveDataDialog::SaveDataDialogTerminate);
LIB_FUNC("hay1CfTmLyA", SaveDataDialog::SaveDataDialogProgressBarSetValue);
}
} // namespace LibSaveDataDialog
LIB_DEFINE(InitDialog_1)
{
LibCommonDialog::InitDialog_1_CommonDialog(s);
LibSaveDataDialog::InitDialog_1_SaveDataDialog(s);
}
} // namespace Kyty::Libs
@@ -18,6 +18,7 @@ LIB_DEFINE(InitGraphicsDriver_1)
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);
+15
View File
@@ -437,11 +437,21 @@ int KYTY_SYSV_ABI nanosleep(const LibKernel::KernelTimespec* rqtp, LibKernel::Ke
return POSIX_CALL(LibKernel::KernelNanosleep(rqtp, rmtp));
}
int KYTY_SYSV_ABI stat(const char* path, LibKernel::FileSystem::FileStat* sb)
{
PRINT_NAME();
return POSIX_CALL(LibKernel::FileSystem::KernelStat(path, sb));
}
LIB_DEFINE(InitLibKernel_1_Posix)
{
LIB_FUNC("lLMT9vJAck0", clock_gettime);
LIB_FUNC("yS8U2TGCe1A", nanosleep);
LIB_FUNC("E6ao34wPw+U", stat);
LIB_FUNC("OxhIB8LB-PQ", Posix::pthread_create);
LIB_FUNC("h9CcP3J0oVM", Posix::pthread_join);
LIB_FUNC("7H0iTOciTLo", Posix::pthread_mutex_lock);
LIB_FUNC("2Z+PpY6CaJg", Posix::pthread_mutex_unlock);
LIB_FUNC("ttHNfU+qDBU", Posix::pthread_mutex_init);
@@ -474,6 +484,8 @@ LIB_DEFINE(InitLibKernel_1_FS)
LIB_FUNC("AUXVxWeJU-A", FileSystem::KernelUnlink);
LIB_FUNC("taRWhTJFTgE", FileSystem::KernelGetdirentries);
LIB_FUNC("oib76F-12fk", FileSystem::KernelLseek);
LIB_FUNC("j2AIqSqJP0w", FileSystem::KernelGetdents);
LIB_FUNC("1-LFLmRFxxM", FileSystem::KernelMkdir);
}
LIB_DEFINE(InitLibKernel_1_Mem)
@@ -531,6 +543,7 @@ LIB_DEFINE(InitLibKernel_1_Pthread)
LIB_FUNC("bt3CTBKmGyI", LibKernel::PthreadSetaffinity);
LIB_FUNC("1tKyG7RlMJo", LibKernel::PthreadGetprio);
LIB_FUNC("W0Hpm2X0uPE", LibKernel::PthreadSetprio);
LIB_FUNC("T72hz6ffq08", LibKernel::PthreadYield);
LIB_FUNC("62KCwEMmzcM", LibKernel::PthreadAttrDestroy);
LIB_FUNC("x1X76arYMxU", LibKernel::PthreadAttrGet);
@@ -557,8 +570,10 @@ LIB_DEFINE(InitLibKernel_1_Pthread)
LIB_FUNC("g+PZd2hiacg", LibKernel::PthreadCondDestroy);
LIB_FUNC("WKAXJ4XBPQ4", LibKernel::PthreadCondWait);
LIB_FUNC("JGgj7Uvrl+A", LibKernel::PthreadCondBroadcast);
LIB_FUNC("kDh-NfxgMtE", LibKernel::PthreadCondSignal);
LIB_FUNC("BmMjYxmew1w", LibKernel::PthreadCondTimedwait);
LIB_FUNC("m5-2bsNfv7s", LibKernel::PthreadCondattrInit);
LIB_FUNC("waPcxYiR3WA", LibKernel::PthreadCondattrDestroy);
LIB_FUNC("QBi7HCK03hw", LibKernel::KernelClockGettime);
LIB_FUNC("ejekcaNQNq0", LibKernel::KernelGettimeofday);
+24
View File
@@ -97,6 +97,19 @@ LIB_DEFINE(InitNet_1_Http)
{
LIB_FUNC("A9cVMUtEp4Y", Http::HttpInit);
LIB_FUNC("0gYjPTR-6cY", Http::HttpCreateTemplate);
LIB_FUNC("4I8vEpuEhZ8", Http::HttpDeleteTemplate);
LIB_FUNC("s2-NPIvz+iA", Http::HttpSetNonblock);
LIB_FUNC("htyBOoWeS58", Http::HttpsSetSslCallback);
LIB_FUNC("6381dWF+xsQ", Http::HttpCreateEpoll);
LIB_FUNC("wYhXVfS2Et4", Http::HttpDestroyEpoll);
LIB_FUNC("-xm7kZQNpHI", Http::HttpSetEpoll);
LIB_FUNC("59tL1AQBb8U", Http::HttpUnsetEpoll);
LIB_FUNC("qgxDBjorUxs", Http::HttpCreateConnectionWithURL);
LIB_FUNC("P6A3ytpsiYc", Http::HttpDeleteConnection);
LIB_FUNC("Cnp77podkCU", Http::HttpCreateRequestWithURL2);
LIB_FUNC("qe7oZ+v4PWA", Http::HttpDeleteRequest);
LIB_FUNC("EY28T2bkN7k", Http::HttpAddRequestHeader);
LIB_FUNC("1e2BNwI-XzE", Http::HttpSendRequest);
}
} // namespace LibHttp
@@ -133,6 +146,13 @@ LIB_DEFINE(InitNet_1_NpManager)
LIB_FUNC("VfRSmPmj8Q8", NpManager::NpRegisterStateCallback);
LIB_FUNC("uFJpaKNBAj4", NpManager::NpRegisterGamePresenceCallback);
LIB_FUNC("GImICnh+boA", NpManager::NpRegisterPlusEventCallback);
LIB_FUNC("p-o74CnoNzY", NpManager::NpGetNpId);
LIB_FUNC("XDncXQIJUSk", NpManager::NpGetOnlineId);
LIB_FUNC("eiqMCt9UshI", NpManager::NpCreateAsyncRequest);
LIB_FUNC("S7QTn72PrDw", NpManager::NpDeleteRequest);
LIB_FUNC("2rsFmlGWleQ", NpManager::NpCheckNpAvailability);
LIB_FUNC("uqcPJLWL08M", NpManager::NpPollAsync);
LIB_FUNC("eQH7nWPcAgc", NpManager::NpGetState);
}
} // namespace LibNpManager
@@ -146,6 +166,7 @@ namespace NpManagerForToolkit = Network::NpManagerForToolkit;
LIB_DEFINE(InitNet_1_NpManagerForToolkit)
{
LIB_FUNC("0c7HbXRKUt4", NpManagerForToolkit::NpRegisterStateCallbackForToolkit);
LIB_FUNC("JELHf4xPufo", NpManagerForToolkit::NpCheckCallbackForLib);
}
} // namespace LibNpManagerForToolkit
@@ -159,6 +180,9 @@ namespace NpTrophy = Network::NpTrophy;
LIB_DEFINE(InitNet_1_NpTrophy)
{
LIB_FUNC("q7U6tEAQf7c", NpTrophy::NpTrophyCreateHandle);
LIB_FUNC("XbkjbobZlCY", NpTrophy::NpTrophyCreateContext);
LIB_FUNC("TJCAxto9SEU", NpTrophy::NpTrophyRegisterContext);
LIB_FUNC("GNcF4oidY0Y", NpTrophy::NpTrophyDestroyHandle);
}
} // namespace LibNpTrophy
+2
View File
@@ -18,6 +18,8 @@ LIB_DEFINE(InitPad_1)
LIB_FUNC("clVvL4ZDntw", Controller::PadSetMotionSensorState);
LIB_FUNC("gjP9-KQzoUk", Controller::PadGetControllerInformation);
LIB_FUNC("YndgXqQVV7c", Controller::PadReadState);
LIB_FUNC("q1cHNfGycLI", Controller::PadRead);
LIB_FUNC("yFVnOdGxvZY", Controller::PadSetVibration);
}
} // namespace Kyty::Libs
+97 -6
View File
@@ -1,8 +1,10 @@
#include "Kyty/Core/Common.h"
#include "Kyty/Core/DbgAssert.h"
#include "Kyty/Core/File.h"
#include "Kyty/Core/String.h"
#include "Emulator/Common.h"
#include "Emulator/Kernel/FileSystem.h"
#include "Emulator/Libs/Errno.h"
#include "Emulator/Libs/Libs.h"
#include "Emulator/SymbolDatabase.h"
@@ -15,6 +17,10 @@ LIB_VERSION("SaveData", 1, "SaveData", 1, 1);
namespace SaveData {
// TODO(): specify dir at launcher
static constexpr char32_t SAVE_DATA_DIR[] = U"_SaveData";
static constexpr char32_t SAVE_DATA_POINT[] = U"/savedata0";
struct SceSaveDataDirName
{
char data[32];
@@ -46,6 +52,17 @@ struct SaveDataMountResult
int pad;
};
struct SaveDataParam
{
char title[128];
char sub_title[128];
char detail[1024];
uint32_t user_param;
int pad;
int64_t mtime;
uint8_t reserved[32];
};
int KYTY_SYSV_ABI SaveDataInitialize(const void* /*init*/)
{
PRINT_NAME();
@@ -85,18 +102,90 @@ int KYTY_SYSV_ABI SaveDataMount2(const SaveDataMount2* mount, SaveDataMountResul
printf("\t blocks = %" PRIu64 "\n", mount->blocks);
printf("\t mount_mode = %" PRIu32 "\n", mount->mount_mode);
if (mount->mount_mode == 1)
{
return SAVE_DATA_ERROR_NOT_FOUND;
} else // NOLINT
String mount_dir = String(SAVE_DATA_DIR) + U"/" + String::FromUtf8(mount->dir_name->data);
String mount_point = SAVE_DATA_POINT;
bool create = (mount->mount_mode == 22);
bool open = (mount->mount_mode == 1 || mount->mount_mode == 2);
if (!create && !open)
{
EXIT("unknown mount mode: %u", mount->mount_mode);
}
strcpy(mount_result->mount_point.data, "/savedata0");
if (open)
{
EXIT_NOT_IMPLEMENTED(create);
if (!Core::File::IsDirectoryExisting(mount_dir))
{
return SAVE_DATA_ERROR_NOT_FOUND;
}
LibKernel::FileSystem::Mount(mount_dir, mount_point);
mount_result->mount_status = 0;
}
if (create)
{
EXIT_NOT_IMPLEMENTED(open);
if (Core::File::IsDirectoryExisting(mount_dir))
{
return SAVE_DATA_ERROR_EXISTS;
}
Core::File::CreateDirectories(mount_dir);
EXIT_NOT_IMPLEMENTED((!Core::File::IsDirectoryExisting(mount_dir)));
LibKernel::FileSystem::Mount(mount_dir, mount_point);
mount_result->mount_status = 1;
}
snprintf(mount_result->mount_point.data, 16, "%s", mount_point.C_Str());
mount_result->required_blocks = 0;
mount_result->mount_status = 1;
return OK;
}
int KYTY_SYSV_ABI SaveDataUmount(const SaveDataMountPoint* mount_point)
{
PRINT_NAME();
EXIT_NOT_IMPLEMENTED(mount_point == nullptr);
printf("\t mount_point = %s\n", mount_point->data);
LibKernel::FileSystem::Umount(String::FromUtf8(mount_point->data));
return OK;
}
int KYTY_SYSV_ABI SaveDataSetParam(const SaveDataMountPoint* mount_point, uint32_t param_type, const void* param_buf, size_t param_buf_size)
{
PRINT_NAME();
EXIT_NOT_IMPLEMENTED(mount_point == nullptr);
printf("\t mount_point = %s\n", mount_point->data);
printf("\t param_type = %u\n", param_type);
printf("\t param_buf_size = %" PRIu64 "\n", param_buf_size);
if (param_type == 0)
{
const auto* p = static_cast<const SaveDataParam*>(param_buf);
printf("\t title = %s\n", p->title);
printf("\t sub_title = %s\n", p->sub_title);
printf("\t detail = %s\n", p->detail);
printf("\t user_param = %u\n", p->user_param);
} else
{
KYTY_NOT_IMPLEMENTED;
}
return OK;
}
@@ -109,6 +198,8 @@ LIB_DEFINE(InitSaveData_1)
LIB_FUNC("l1NmDeDpNGU", SaveData::SaveDataInitialize2);
LIB_FUNC("TywrFKCoLGY", SaveData::SaveDataInitialize3);
LIB_FUNC("0z45PIH+SNI", SaveData::SaveDataMount2);
LIB_FUNC("BMR4F-Uek3E", SaveData::SaveDataUmount);
LIB_FUNC("85zul--eGXs", SaveData::SaveDataSetParam);
}
} // namespace Kyty::Libs
@@ -90,6 +90,12 @@ struct SystemServiceStatus
bool is_out_of_vr_play_area = false;
};
struct SystemServiceDisplaySafeAreaInfo
{
float ratio;
uint8_t reserved[128];
};
static int KYTY_SYSV_ABI SystemServiceHideSplashScreen()
{
PRINT_NAME();
@@ -141,6 +147,20 @@ static int KYTY_SYSV_ABI SystemServiceGetStatus(SystemServiceStatus* status)
return OK;
}
static int KYTY_SYSV_ABI SystemServiceGetDisplaySafeAreaInfo(SystemServiceDisplaySafeAreaInfo* info)
{
PRINT_NAME();
if (info == nullptr)
{
return SYSTEM_SERVICE_ERROR_PARAMETER;
}
info->ratio = 1.0f;
return OK;
}
} // namespace SystemService
LIB_DEFINE(InitSystemService_1)
@@ -148,6 +168,7 @@ LIB_DEFINE(InitSystemService_1)
LIB_FUNC("Vo5V8KAwCmk", SystemService::SystemServiceHideSplashScreen);
LIB_FUNC("fZo48un7LK4", SystemService::SystemServiceParamGetInt);
LIB_FUNC("rPo6tV8D9bM", SystemService::SystemServiceGetStatus);
LIB_FUNC("1n37q1Bvc5Y", SystemService::SystemServiceGetDisplaySafeAreaInfo);
}
} // namespace Kyty::Libs
@@ -6,6 +6,8 @@
#include "Emulator/Libs/Libs.h"
#include "Emulator/SymbolDatabase.h"
#include <cstdio>
#ifdef KYTY_EMU_ENABLED
namespace Kyty::Libs {
@@ -60,6 +62,16 @@ static KYTY_SYSV_ABI int UserServiceGetLoginUserIdList(UserServiceLoginUserIdLis
return OK;
}
static KYTY_SYSV_ABI int UserServiceGetUserName(int user_id, char* name, size_t size)
{
EXIT_NOT_IMPLEMENTED(user_id != 1);
EXIT_NOT_IMPLEMENTED(size < 5);
snprintf(name, size, "%s", "Kyty");
return OK;
}
} // namespace UserService
LIB_DEFINE(InitUserService_1)
@@ -68,6 +80,7 @@ LIB_DEFINE(InitUserService_1)
LIB_FUNC("CdWp0oHWGr0", UserService::UserServiceGetInitialUser);
LIB_FUNC("yH17Q6NWtVg", UserService::UserServiceGetEvent);
LIB_FUNC("fPhymKNvK-A", UserService::UserServiceGetLoginUserIdList);
LIB_FUNC("1xxcMiGu2fo", UserService::UserServiceGetUserName);
}
} // namespace Kyty::Libs
+677 -26
View File
@@ -7,9 +7,12 @@
#include "Kyty/Core/Threads.h"
#include "Kyty/Core/Vector.h"
#include "Emulator/Kernel/Pthread.h"
#include "Emulator/Libs/Errno.h"
#include "Emulator/Libs/Libs.h"
#include <atomic>
#ifdef KYTY_EMU_ENABLED
namespace Kyty::Libs::Network {
@@ -20,26 +23,54 @@ public:
class Id
{
public:
explicit Id(int id): m_id(id - 1) {}
[[nodiscard]] int ToInt() const { return m_id + 1; }
[[nodiscard]] bool IsValid() const { return m_id >= 0; }
static constexpr int MAX_ID = 65536;
enum class Type : uint32_t
{
Invalid = 0,
Http = 1,
Ssl = 2,
Template = 3,
Connection = 4,
Request = 5,
};
explicit Id(int id): m_id(static_cast<uint32_t>(id) & 0xffffu), m_type(static_cast<uint32_t>(id) >> 16u) {}
[[nodiscard]] int ToInt() const { return static_cast<int>(m_id + (static_cast<uint32_t>(m_type) << 16u)); }
[[nodiscard]] bool IsValid() const { return GetType() != Type::Invalid; }
[[nodiscard]] Type GetType() const
{
switch (m_type)
{
case static_cast<uint32_t>(Type::Http): return Type::Http; break;
case static_cast<uint32_t>(Type::Ssl): return Type::Ssl; break;
case static_cast<uint32_t>(Type::Template): return Type::Template; break;
case static_cast<uint32_t>(Type::Connection): return Type::Connection; break;
case static_cast<uint32_t>(Type::Request): return Type::Request; break;
default: return Type::Invalid;
}
}
friend class Network;
private:
Id() = default;
static Id Invalid() { return Id(); }
static Id Create(int net_id)
static Id Create(int net_id, Type type)
{
Id r;
r.m_id = net_id;
r.m_id = net_id;
r.m_type = static_cast<uint32_t>(type);
return r;
}
[[nodiscard]] int GetId() const { return m_id; }
[[nodiscard]] int GetId() const { return static_cast<int>(m_id); }
int m_id = -1;
uint32_t m_id = 0;
uint32_t m_type = static_cast<uint32_t>(Type::Invalid);
};
using HttpsCallback = int (*)(int, unsigned int, void* const*, int, void*);
Network() = default;
virtual ~Network() = default;
@@ -55,7 +86,17 @@ public:
bool HttpTerm(Id http_ctx_id);
Id HttpCreateTemplate(Id http_ctx_id, const char* user_agent, int http_ver, bool is_auto_proxy_conf);
bool HttpDeleteTemplate(Id tmpl_id);
bool HttpSetNonblock(Id id, bool enable);
bool HttpsSetSslCallback(Id id, HttpsCallback cbfunc, void* user_arg);
bool HttpAddRequestHeader(Id id, const char* name, const char* value, bool add);
bool HttpValid(Id http_ctx_id);
bool HttpValidTemplate(Id tmpl_id);
bool HttpValidConnection(Id conn_id);
bool HttpValidRequest(Id req_id);
Id HttpCreateConnectionWithURL(Id tmpl_id, const char* url, bool enable_keep_alive);
bool HttpDeleteConnection(Id conn_id);
Id HttpCreateRequestWithURL2(Id conn_id, const char* method, const char* url, uint64_t content_length);
bool HttpDeleteRequest(Id req_id);
private:
struct Pool
@@ -79,24 +120,55 @@ private:
int ssl_ctx_id = 0;
};
struct HttpTemplate
struct HttpHeader
{
String name;
String value;
};
struct HttpBase
{
bool used = false;
bool nonblock = false;
Vector<HttpHeader> headers;
HttpsCallback ssl_cbfunc = nullptr;
void* ssl_user_arg = nullptr;
};
struct HttpTemplate: public HttpBase
{
bool used = false;
int http_ctx_id = 0;
String user_agent;
int http_ver = 0;
bool is_auto_proxy_conf = true;
};
struct HttpConnection: public HttpBase
{
int tmpl_id = 0;
String url;
bool enable_keep_alive = false;
};
struct HttpRequest: public HttpBase
{
int conn_id = 0;
String method;
String url;
uint64_t content_length = 0;
};
static constexpr int POOLS_MAX = 32;
static constexpr int SSL_MAX = 32;
static constexpr int HTTP_MAX = 32;
Core::Mutex m_mutex;
Pool m_pools[POOLS_MAX];
Ssl m_ssl[SSL_MAX];
Http m_http[HTTP_MAX];
Vector<HttpTemplate> m_templates;
Core::Mutex m_mutex;
Pool m_pools[POOLS_MAX];
Ssl m_ssl[SSL_MAX];
Http m_http[HTTP_MAX];
Vector<HttpTemplate> m_templates;
Vector<HttpConnection> m_connections;
Vector<HttpRequest> m_requests;
};
static Network* g_net = nullptr;
@@ -156,7 +228,7 @@ Network::Id Network::SslInit(uint64_t pool_size)
m_ssl[id].used = true;
m_ssl[id].size = pool_size;
return Id::Create(id);
return Id::Create(id, Id::Type::Ssl);
}
}
@@ -167,7 +239,7 @@ bool Network::SslTerm(Id ssl_ctx_id)
{
Core::LockGuard lock(m_mutex);
if (ssl_ctx_id.GetId() >= 0 && ssl_ctx_id.GetId() < SSL_MAX && m_ssl[ssl_ctx_id.GetId()].used)
if (ssl_ctx_id.GetType() == Id::Type::Ssl && ssl_ctx_id.GetId() >= 0 && ssl_ctx_id.GetId() < SSL_MAX && m_ssl[ssl_ctx_id.GetId()].used)
{
m_ssl[ssl_ctx_id.GetId()].used = false;
@@ -181,8 +253,8 @@ Network::Id Network::HttpInit(int memid, Id ssl_ctx_id, uint64_t pool_size)
{
Core::LockGuard lock(m_mutex);
if (ssl_ctx_id.GetId() >= 0 && ssl_ctx_id.GetId() < SSL_MAX && m_ssl[ssl_ctx_id.GetId()].used && memid >= 0 && memid < POOLS_MAX &&
m_pools[memid].used)
if (ssl_ctx_id.GetType() == Id::Type::Ssl && ssl_ctx_id.GetId() >= 0 && ssl_ctx_id.GetId() < SSL_MAX &&
m_ssl[ssl_ctx_id.GetId()].used && memid >= 0 && memid < POOLS_MAX && m_pools[memid].used)
{
for (int id = 0; id < HTTP_MAX; id++)
{
@@ -193,7 +265,7 @@ Network::Id Network::HttpInit(int memid, Id ssl_ctx_id, uint64_t pool_size)
m_http[id].ssl_ctx_id = ssl_ctx_id.GetId();
m_http[id].memid = memid;
return Id::Create(id);
return Id::Create(id, Id::Type::Http);
}
}
}
@@ -205,7 +277,30 @@ bool Network::HttpValid(Id http_ctx_id)
{
Core::LockGuard lock(m_mutex);
return (http_ctx_id.GetId() >= 0 && http_ctx_id.GetId() < HTTP_MAX && m_http[http_ctx_id.GetId()].used);
return (http_ctx_id.GetType() == Id::Type::Http && http_ctx_id.GetId() >= 0 && http_ctx_id.GetId() < HTTP_MAX &&
m_http[http_ctx_id.GetId()].used);
}
bool Network::HttpValidTemplate(Id tmpl_id)
{
Core::LockGuard lock(m_mutex);
return (tmpl_id.GetType() == Id::Type::Template && m_templates.IndexValid(tmpl_id.GetId()) && m_templates.At(tmpl_id.GetId()).used);
}
bool Network::HttpValidConnection(Id conn_id)
{
Core::LockGuard lock(m_mutex);
return (conn_id.GetType() == Id::Type::Connection && m_connections.IndexValid(conn_id.GetId()) &&
m_connections.At(conn_id.GetId()).used);
}
bool Network::HttpValidRequest(Id req_id)
{
Core::LockGuard lock(m_mutex);
return (req_id.GetType() == Id::Type::Request && m_requests.IndexValid(req_id.GetId()) && m_requests.At(req_id.GetId()).used);
}
bool Network::HttpTerm(Id http_ctx_id)
@@ -226,7 +321,7 @@ Network::Id Network::HttpCreateTemplate(Id http_ctx_id, const char* user_agent,
{
Core::LockGuard lock(m_mutex);
if (http_ctx_id.GetId() >= 0 && http_ctx_id.GetId() < HTTP_MAX && m_http[http_ctx_id.GetId()].used)
if (HttpValid(http_ctx_id))
{
HttpTemplate tn {};
tn.used = true;
@@ -234,6 +329,7 @@ Network::Id Network::HttpCreateTemplate(Id http_ctx_id, const char* user_agent,
tn.user_agent = String::FromUtf8(user_agent);
tn.is_auto_proxy_conf = is_auto_proxy_conf;
tn.http_ctx_id = http_ctx_id.GetId();
tn.nonblock = false;
int index = 0;
for (auto& t: m_templates)
@@ -241,24 +337,121 @@ Network::Id Network::HttpCreateTemplate(Id http_ctx_id, const char* user_agent,
if (!t.used)
{
t = tn;
return Id::Create(index);
return Id::Create(index, Id::Type::Template);
}
index++;
}
m_templates.Add(tn);
return Id::Create(index);
if (index < Id::MAX_ID)
{
m_templates.Add(tn);
return Id::Create(index, Id::Type::Template);
}
}
return Id::Invalid();
}
Network::Id Network::HttpCreateConnectionWithURL(Id tmpl_id, const char* url, bool enable_keep_alive)
{
Core::LockGuard lock(m_mutex);
if (HttpValidTemplate(tmpl_id))
{
HttpConnection cn {};
cn.used = true;
cn.enable_keep_alive = enable_keep_alive;
cn.url = String::FromUtf8(url);
cn.tmpl_id = tmpl_id.ToInt();
int index = 0;
for (auto& t: m_connections)
{
if (!t.used)
{
t = cn;
return Id::Create(index, Id::Type::Connection);
}
index++;
}
if (index < Id::MAX_ID)
{
m_connections.Add(cn);
return Id::Create(index, Id::Type::Connection);
}
}
return Id::Invalid();
}
bool Network::HttpDeleteConnection(Id conn_id)
{
Core::LockGuard lock(m_mutex);
if (HttpValidConnection(conn_id))
{
m_connections[conn_id.GetId()].used = false;
return true;
}
return false;
}
Network::Id Network::HttpCreateRequestWithURL2(Id conn_id, const char* method, const char* url, uint64_t content_length)
{
Core::LockGuard lock(m_mutex);
if (HttpValidConnection(conn_id))
{
HttpRequest cn {};
cn.used = true;
cn.method = String::FromUtf8(method);
cn.url = String::FromUtf8(url);
cn.conn_id = conn_id.ToInt();
cn.content_length = content_length;
int index = 0;
for (auto& t: m_requests)
{
if (!t.used)
{
t = cn;
return Id::Create(index, Id::Type::Request);
}
index++;
}
if (index < Id::MAX_ID)
{
m_requests.Add(cn);
return Id::Create(index, Id::Type::Request);
}
}
return Id::Invalid();
}
bool Network::HttpDeleteRequest(Id req_id)
{
Core::LockGuard lock(m_mutex);
if (HttpValidRequest(req_id))
{
m_requests[req_id.GetId()].used = false;
return true;
}
return false;
}
bool Network::HttpDeleteTemplate(Id tmpl_id)
{
Core::LockGuard lock(m_mutex);
if (m_templates.IndexValid(tmpl_id.GetId()) && m_templates.At(tmpl_id.GetId()).used)
if (HttpValidTemplate(tmpl_id))
{
m_templates[tmpl_id.GetId()].used = false;
@@ -268,6 +461,98 @@ bool Network::HttpDeleteTemplate(Id tmpl_id)
return false;
}
bool Network::HttpSetNonblock(Id id, bool enable)
{
Core::LockGuard lock(m_mutex);
HttpBase* base = nullptr;
if (HttpValidTemplate(id))
{
base = &m_templates[id.GetId()];
} else if (HttpValidConnection(id))
{
base = &m_connections[id.GetId()];
} else if (HttpValidRequest(id))
{
base = &m_requests[id.GetId()];
}
if (base != nullptr)
{
base->nonblock = enable;
return true;
}
return false;
}
bool Network::HttpsSetSslCallback(Id id, HttpsCallback cbfunc, void* user_arg)
{
Core::LockGuard lock(m_mutex);
HttpBase* base = nullptr;
if (HttpValidTemplate(id))
{
base = &m_templates[id.GetId()];
} else if (HttpValidConnection(id))
{
base = &m_connections[id.GetId()];
} else if (HttpValidRequest(id))
{
base = &m_requests[id.GetId()];
}
if (base != nullptr)
{
base->ssl_cbfunc = cbfunc;
base->ssl_user_arg = user_arg;
return true;
}
return false;
}
bool Network::HttpAddRequestHeader(Id id, const char* name, const char* value, bool add)
{
Core::LockGuard lock(m_mutex);
HttpBase* base = nullptr;
if (HttpValidTemplate(id))
{
base = &m_templates[id.GetId()];
} else if (HttpValidConnection(id))
{
base = &m_connections[id.GetId()];
} else if (HttpValidRequest(id))
{
base = &m_requests[id.GetId()];
}
if (base != nullptr)
{
HttpHeader nh({String::FromUtf8(name), String::FromUtf8(value)});
if (add)
{
base->headers.Add(nh);
} else
{
for (auto& h: base->headers)
{
if (h.name == nh.name)
{
h.value = nh.value;
}
}
}
return true;
}
return false;
}
namespace Net {
LIB_NAME("Net", "Net");
@@ -416,6 +701,13 @@ int KYTY_SYSV_ABI SslTerm(int ssl_ctx_id)
namespace Http {
struct HttpEpoll
{
Network::Id http_ctx_id = Network::Id(0);
Network::Id request_id = Network::Id(0);
void* user_arg = nullptr;
};
LIB_NAME("Http", "Http");
int KYTY_SYSV_ABI HttpInit(int memid, int ssl_ctx_id, uint64_t pool_size)
@@ -489,6 +781,199 @@ int KYTY_SYSV_ABI HttpDeleteTemplate(int tmpl_id)
return OK;
}
int KYTY_SYSV_ABI HttpSetNonblock(int id, int enable)
{
PRINT_NAME();
printf("\t id = %d\n", id);
printf("\t enable = %d\n", enable);
if (!g_net->HttpSetNonblock(Network::Id(id), enable != 0))
{
return HTTP_ERROR_INVALID_ID;
}
return OK;
}
int KYTY_SYSV_ABI HttpsSetSslCallback(int id, HttpsCallback cbfunc, void* user_arg)
{
PRINT_NAME();
printf("\t id = %d\n", id);
if (!g_net->HttpsSetSslCallback(Network::Id(id), cbfunc, user_arg))
{
return HTTP_ERROR_INVALID_ID;
}
return OK;
}
int KYTY_SYSV_ABI HttpAddRequestHeader(int id, const char* name, const char* value, uint32_t mode)
{
PRINT_NAME();
printf("\t id = %d\n", id);
printf("\t name = %s\n", name);
printf("\t value = %s\n", value);
printf("\t mode = %u\n", mode);
EXIT_NOT_IMPLEMENTED(mode != 0 && mode != 1);
if (!g_net->HttpAddRequestHeader(Network::Id(id), name, value, mode == 1))
{
return HTTP_ERROR_INVALID_ID;
}
return OK;
}
int KYTY_SYSV_ABI HttpCreateEpoll(int http_ctx_id, HttpEpollHandle* eh)
{
PRINT_NAME();
printf("\t http_ctx_id = %d\n", http_ctx_id);
EXIT_IF(g_net == nullptr);
EXIT_NOT_IMPLEMENTED(eh == nullptr);
EXIT_NOT_IMPLEMENTED(!g_net->HttpValid(Network::Id(http_ctx_id)));
*eh = new HttpEpoll;
(*eh)->http_ctx_id = Network::Id(http_ctx_id);
return OK;
}
int KYTY_SYSV_ABI HttpDestroyEpoll(int http_ctx_id, HttpEpollHandle eh)
{
PRINT_NAME();
printf("\t http_ctx_id = %d\n", http_ctx_id);
EXIT_IF(g_net == nullptr);
EXIT_NOT_IMPLEMENTED(eh == nullptr);
EXIT_NOT_IMPLEMENTED(!g_net->HttpValid(Network::Id(http_ctx_id)));
delete eh;
return OK;
}
int KYTY_SYSV_ABI HttpSetEpoll(int id, HttpEpollHandle eh, void* user_arg)
{
PRINT_NAME();
printf("\t id = %d\n", id);
EXIT_NOT_IMPLEMENTED(eh == nullptr);
EXIT_NOT_IMPLEMENTED(!g_net->HttpValidRequest(Network::Id(id)));
eh->request_id = Network::Id(id);
eh->user_arg = user_arg;
return OK;
}
int KYTY_SYSV_ABI HttpUnsetEpoll(int id)
{
PRINT_NAME();
printf("\t id = %d\n", id);
EXIT_NOT_IMPLEMENTED(!g_net->HttpValidRequest(Network::Id(id)));
return OK;
}
int KYTY_SYSV_ABI HttpSendRequest(int request_id, const void* /*post_data*/, size_t /*size*/)
{
PRINT_NAME();
printf("\t request_id = %d\n", request_id);
return HTTP_ERROR_TIMEOUT;
}
int KYTY_SYSV_ABI HttpCreateConnectionWithURL(int tmpl_id, const char* url, int enable_keep_alive)
{
PRINT_NAME();
printf("\t tmpl_id = %d\n", tmpl_id);
printf("\t url = %s\n", url);
printf("\t enable_keep_alive = %d\n", enable_keep_alive);
EXIT_IF(g_net == nullptr);
auto id = g_net->HttpCreateConnectionWithURL(Network::Id(tmpl_id), url, enable_keep_alive != 0);
if (!id.IsValid())
{
return HTTP_ERROR_OUT_OF_MEMORY;
}
return id.ToInt();
}
int KYTY_SYSV_ABI HttpDeleteConnection(int conn_id)
{
PRINT_NAME();
printf("\t conn_id = %d\n", conn_id);
EXIT_IF(g_net == nullptr);
if (!g_net->HttpDeleteConnection(Network::Id(conn_id)))
{
return HTTP_ERROR_INVALID_ID;
}
return OK;
}
int KYTY_SYSV_ABI HttpCreateRequestWithURL2(int conn_id, const char* method, const char* url, uint64_t content_length)
{
PRINT_NAME();
printf("\t conn_id = %d\n", conn_id);
printf("\t url = %s\n", url);
printf("\t method = %s\n", method);
printf("\t content_length = %" PRIu64 "\n", content_length);
EXIT_IF(g_net == nullptr);
auto id = g_net->HttpCreateRequestWithURL2(Network::Id(conn_id), method, url, content_length);
if (!id.IsValid())
{
return HTTP_ERROR_OUT_OF_MEMORY;
}
return id.ToInt();
}
int KYTY_SYSV_ABI HttpDeleteRequest(int req_id)
{
PRINT_NAME();
printf("\t req_id = %d\n", req_id);
EXIT_IF(g_net == nullptr);
if (!g_net->HttpDeleteRequest(Network::Id(req_id)))
{
return HTTP_ERROR_INVALID_ID;
}
return OK;
}
} // namespace Http
namespace NetCtl {
@@ -653,6 +1138,28 @@ struct NpContentRestriction
const NpAgeRestriction* age_restriction;
};
struct NpOnlineId
{
char data[16];
char term;
char dummy[3];
};
struct NpId
{
NpOnlineId handle;
uint8_t opt[8];
uint8_t reserved[8];
};
struct NpCreateAsyncRequestParameter
{
size_t size;
LibKernel::KernelCpumask cpu_affinity_mask;
int thread_priority;
uint8_t padding[4];
};
int KYTY_SYSV_ABI NpCheckCallback()
{
PRINT_NAME();
@@ -711,6 +1218,103 @@ int KYTY_SYSV_ABI NpRegisterPlusEventCallback(void* /*callback*/, void* /*userda
return OK;
}
int KYTY_SYSV_ABI NpGetNpId(int user_id, NpId* np_id)
{
PRINT_NAME();
printf("\t user_id = %d\n", user_id);
EXIT_NOT_IMPLEMENTED(np_id == nullptr);
snprintf(np_id->handle.data, 16, "Kyty");
np_id->handle.term = 0;
return OK;
}
int KYTY_SYSV_ABI NpGetOnlineId(int user_id, NpOnlineId* online_id)
{
PRINT_NAME();
printf("\t user_id = %d\n", user_id);
EXIT_NOT_IMPLEMENTED(online_id == nullptr);
snprintf(online_id->data, 16, "Kyty");
online_id->term = 0;
return OK;
}
int KYTY_SYSV_ABI NpCreateAsyncRequest(const NpCreateAsyncRequestParameter* param)
{
PRINT_NAME();
EXIT_NOT_IMPLEMENTED(param == nullptr);
printf("\t size = %" PRIu64 "\n", param->size);
printf("\t cpu_affinity_mask = %" PRIu64 "\n", param->cpu_affinity_mask);
printf("\t thread_priority = %d\n", param->thread_priority);
static std::atomic_int id = 0;
EXIT_NOT_IMPLEMENTED(id >= 1);
return ++id;
}
int KYTY_SYSV_ABI NpDeleteRequest(int req_id)
{
PRINT_NAME();
EXIT_NOT_IMPLEMENTED(req_id != 1);
printf("\t req_id = %d\n", req_id);
return OK;
}
int KYTY_SYSV_ABI NpCheckNpAvailability(int req_id, const char* user, void* result)
{
PRINT_NAME();
EXIT_NOT_IMPLEMENTED(req_id != 1);
EXIT_NOT_IMPLEMENTED(user == nullptr);
EXIT_NOT_IMPLEMENTED(result != nullptr);
printf("\t req_id = %d\n", req_id);
printf("\t user = %s\n", user);
return OK;
}
int KYTY_SYSV_ABI NpPollAsync(int req_id, int* result)
{
PRINT_NAME();
EXIT_NOT_IMPLEMENTED(req_id != 1);
EXIT_NOT_IMPLEMENTED(result == nullptr);
printf("\t req_id = %d\n", req_id);
*result = 0;
return 0;
}
int KYTY_SYSV_ABI NpGetState(int user_id, uint32_t* state)
{
PRINT_NAME();
EXIT_NOT_IMPLEMENTED(state == nullptr);
printf("\t user_id = %d\n", user_id);
*state = 1; // Signed out
return OK;
}
} // namespace NpManager
namespace NpManagerForToolkit {
@@ -724,6 +1328,13 @@ int KYTY_SYSV_ABI NpRegisterStateCallbackForToolkit(void* /*callback*/, void* /*
return OK;
}
int KYTY_SYSV_ABI NpCheckCallbackForLib()
{
PRINT_NAME();
return OK;
}
} // namespace NpManagerForToolkit
namespace NpTrophy {
@@ -741,6 +1352,46 @@ int KYTY_SYSV_ABI NpTrophyCreateHandle(int* handle)
return OK;
}
int KYTY_SYSV_ABI NpTrophyCreateContext(int* context, int user_id, uint32_t service_label, uint64_t options)
{
PRINT_NAME();
EXIT_NOT_IMPLEMENTED(context == nullptr);
EXIT_NOT_IMPLEMENTED(options != 0);
*context = 1;
printf("\t user_id = %d\n", user_id);
printf("\t service_label = %u\n", service_label);
return OK;
}
int KYTY_SYSV_ABI NpTrophyRegisterContext(int context, int handle, uint64_t options)
{
PRINT_NAME();
EXIT_NOT_IMPLEMENTED(options != 0);
EXIT_NOT_IMPLEMENTED(context != 1);
EXIT_NOT_IMPLEMENTED(handle != 1);
printf("\t context = %d\n", context);
printf("\t handle = %d\n", handle);
return OK;
}
int KYTY_SYSV_ABI NpTrophyDestroyHandle(int handle)
{
PRINT_NAME();
EXIT_NOT_IMPLEMENTED(handle != 1);
printf("\t handle = %d\n", handle);
return OK;
}
} // namespace NpTrophy
namespace NpWebApi {