Merge pull request #225 from shadps4-emu/stabilization/10

Various fixes and improvements
This commit is contained in:
georgemoralis 2024-07-01 13:09:11 +03:00 committed by GitHub
commit 1f83824a8a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 220 additions and 38 deletions

View file

@ -8,6 +8,7 @@
#include "common/slot_vector.h"
#include "core/libraries/error_codes.h"
#include "core/libraries/gnmdriver/gnmdriver.h"
#include "core/libraries/kernel/libkernel.h"
#include "core/libraries/libs.h"
#include "core/libraries/videoout/video_out.h"
#include "core/platform.h"
@ -212,12 +213,61 @@ static constexpr std::array InitSequence350{
0xc0016900u, 0x2aau, 0xffu,
};
static_assert(InitSequence350.size() == 0x7c);
static constexpr std::array CtxInitSequence{
0xc0012800u, 0x80000000u, 0x80000000u,
0xc0001200u, 0u,
0xc0002f00u, 1u,
0xc0016900u, 0x102u, 0u,
0xc0016900u, 0x202u, 0xcc0010u,
0xc0111000u, 0u
};
static_assert(CtxInitSequence.size() == 0x0f);
static constexpr std::array CtxInitSequence400{
0xc0012800u, 0x80000000u, 0x80000000u,
0xc0001200u, 0u,
0xc0016900u, 0x2f9u, 0x2du,
0xc0016900u, 0x282u, 8u,
0xc0016900u, 0x280u, 0x80008u,
0xc0016900u, 0x281u, 0xffff0000u,
0xc0016900u, 0x204u, 0u,
0xc0016900u, 0x206u, 0x43fu,
0xc0016900u, 0x83u, 0xffffu,
0xc0016900u, 0x317u, 0x10u,
0xc0016900u, 0x2fau, 0x3f800000u,
0xc0016900u, 0x2fcu, 0x3f800000u,
0xc0016900u, 0x2fbu, 0x3f800000u,
0xc0016900u, 0x2fdu, 0x3f800000u,
0xc0016900u, 0x202u, 0xcc0010u,
0xc0016900u, 0x30eu, 0xffffffffu,
0xc0016900u, 0x30fu, 0xffffffffu,
0xc0002f00u, 1u,
0xc0016900u, 0x1b1u, 2u,
0xc0016900u, 0x101u, 0u,
0xc0016900u, 0x100u, 0xffffffffu,
0xc0016900u, 0x103u, 0u,
0xc0016900u, 0x284u, 0u,
0xc0016900u, 0x290u, 0u,
0xc0016900u, 0x2aeu, 0u,
0xc0016900u, 0x102u, 0u,
0xc0016900u, 0x292u, 0u,
0xc0016900u, 0x293u, 0x6020000u,
0xc0016900u, 0x2f8u, 0u,
0xc0016900u, 0x2deu, 0x1e9u,
0xc0036900u, 0x295u, 0x100u, 0x100u, 4u,
0xc0016900u, 0x2aau, 0xffu,
0xc09e1000u,
};
static_assert(CtxInitSequence400.size() == 0x61);
// clang-format on
// In case if `submitDone` is issued we need to block submissions until GPU idle
static u32 submission_lock{};
static std::mutex m_submission{};
static u64 frames_submitted{}; // frame counter
static u64 frames_submitted{}; // frame counter
static bool send_init_packet{true}; // initialize HW state before first game's submit in a frame
static int sdk_version{0};
struct AscQueueInfo {
VAddr map_addr;
@ -664,9 +714,10 @@ u32 PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState175(u32* cmdbuf, u32 size) {
cmdbuf = ClearContextState(cmdbuf);
std::memcpy(cmdbuf, InitSequence175.data(), InitSequence175.size() * 4);
cmdbuf += InitSequence175.size();
cmdbuf[0x7f] = 0xc07f1000;
cmdbuf[0x80] = 0;
constexpr auto cmdbuf_left = HwInitPacketSize - InitSequence175.size() - 0xc - 1;
WriteTrailingNop<cmdbuf_left>(cmdbuf);
return HwInitPacketSize;
}
@ -723,14 +774,28 @@ u32 PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState350(u32* cmdbuf, u32 size) {
return SetupContext350(cmdbuf, size, true);
}
int PS4_SYSV_ABI sceGnmDrawInitToDefaultContextState() {
LOG_ERROR(Lib_GnmDriver, "(STUBBED) called");
return ORBIS_OK;
u32 PS4_SYSV_ABI sceGnmDrawInitToDefaultContextState(u32* cmdbuf, u32 size) {
LOG_TRACE(Lib_GnmDriver, "called");
constexpr auto CtxInitPacketSize = 0x20u;
if (size != CtxInitPacketSize) {
return 0;
}
std::memcpy(cmdbuf, CtxInitSequence.data(), CtxInitSequence.size() * 4);
return CtxInitPacketSize;
}
int PS4_SYSV_ABI sceGnmDrawInitToDefaultContextState400() {
LOG_ERROR(Lib_GnmDriver, "(STUBBED) called");
return ORBIS_OK;
u32 PS4_SYSV_ABI sceGnmDrawInitToDefaultContextState400(u32* cmdbuf, u32 size) {
LOG_TRACE(Lib_GnmDriver, "called");
constexpr auto CtxInitPacketSize = 0x100u;
if (size != CtxInitPacketSize) {
return 0;
}
std::memcpy(cmdbuf, CtxInitSequence400.data(), CtxInitSequence400.size() * 4);
return CtxInitPacketSize;
}
int PS4_SYSV_ABI sceGnmDrawOpaqueAuto() {
@ -1873,6 +1938,17 @@ s32 PS4_SYSV_ABI sceGnmSubmitCommandBuffers(u32 count, const u32* dcb_gpu_addrs[
submission_lock = 0;
}
if (send_init_packet) {
if (sdk_version <= 0x1ffffffu) {
liverpool->SubmitGfx(InitSequence, {});
} else if (sdk_version <= 0x3ffffffu) {
liverpool->SubmitGfx(InitSequence200, {});
} else {
liverpool->SubmitGfx(InitSequence350, {});
}
send_init_packet = false;
}
for (auto cbpair = 0u; cbpair < count; ++cbpair) {
const auto* ccb = ccb_gpu_addrs ? ccb_gpu_addrs[cbpair] : nullptr;
const auto ccb_size_in_bytes = ccb_sizes_in_bytes ? ccb_sizes_in_bytes[cbpair] : 0;
@ -1915,6 +1991,7 @@ int PS4_SYSV_ABI sceGnmSubmitDone() {
submission_lock = true;
}
liverpool->NotifySubmitDone();
send_init_packet = true;
++frames_submitted;
return ORBIS_OK;
}
@ -2388,6 +2465,11 @@ void RegisterlibSceGnmDriver(Core::Loader::SymbolsResolver* sym) {
liverpool = std::make_unique<AmdGpu::Liverpool>();
renderer = std::make_unique<Vulkan::RendererVulkan>(*g_window, liverpool.get());
const int result = sceKernelGetCompiledSdkVersion(&sdk_version);
if (result != ORBIS_OK) {
sdk_version = 0;
}
LIB_FUNCTION("b0xyllnVY-I", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmAddEqEvent);
LIB_FUNCTION("b08AgtPlHPg", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1,
sceGnmAreSubmitsAllowed);

View file

@ -60,8 +60,8 @@ u32 PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState(u32* cmdbuf, u32 size);
u32 PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState175(u32* cmdbuf, u32 size);
u32 PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState200(u32* cmdbuf, u32 size);
u32 PS4_SYSV_ABI sceGnmDrawInitDefaultHardwareState350(u32* cmdbuf, u32 size);
int PS4_SYSV_ABI sceGnmDrawInitToDefaultContextState();
int PS4_SYSV_ABI sceGnmDrawInitToDefaultContextState400();
u32 PS4_SYSV_ABI sceGnmDrawInitToDefaultContextState(u32* cmdbuf, u32 size);
u32 PS4_SYSV_ABI sceGnmDrawInitToDefaultContextState400(u32* cmdbuf, u32 size);
int PS4_SYSV_ABI sceGnmDrawOpaqueAuto();
int PS4_SYSV_ABI sceGnmDriverCaptureInProgress();
int PS4_SYSV_ABI sceGnmDriverInternalRetrieveGnmInterface();

View file

@ -161,7 +161,7 @@ int PS4_SYSV_ABI sceKernelGetCompiledSdkVersion(int* ver) {
int version = param_sfo->GetInteger("SYSTEM_VER");
LOG_INFO(Kernel, "returned system version = {:#x}", version);
*ver = version;
return ORBIS_OK;
return (version > 0) ? ORBIS_OK : ORBIS_KERNEL_ERROR_EINVAL;
}
s64 PS4_SYSV_ABI ps4__read(int d, void* buf, u64 nbytes) {

View file

@ -30,6 +30,7 @@ typedef struct {
} OrbisKernelUuid;
int* PS4_SYSV_ABI __Error();
int PS4_SYSV_ABI sceKernelGetCompiledSdkVersion(int* ver);
void LibKernel_Register(Core::Loader::SymbolsResolver* sym);