libraries: gnmdriver: added initialization preamble to every first submit in a frame

This commit is contained in:
psucien 2024-06-30 18:22:39 +02:00
parent 14377b39b5
commit 1f55eff9d8
5 changed files with 29 additions and 9 deletions

View File

@ -8,6 +8,7 @@
#include "common/slot_vector.h" #include "common/slot_vector.h"
#include "core/libraries/error_codes.h" #include "core/libraries/error_codes.h"
#include "core/libraries/gnmdriver/gnmdriver.h" #include "core/libraries/gnmdriver/gnmdriver.h"
#include "core/libraries/kernel/libkernel.h"
#include "core/libraries/libs.h" #include "core/libraries/libs.h"
#include "core/libraries/videoout/video_out.h" #include "core/libraries/videoout/video_out.h"
#include "core/platform.h" #include "core/platform.h"
@ -265,6 +266,8 @@ static_assert(CtxInitSequence400.size() == 0x61);
static u32 submission_lock{}; static u32 submission_lock{};
static std::mutex m_submission{}; 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 { struct AscQueueInfo {
VAddr map_addr; VAddr map_addr;
@ -1935,6 +1938,17 @@ s32 PS4_SYSV_ABI sceGnmSubmitCommandBuffers(u32 count, const u32* dcb_gpu_addrs[
submission_lock = 0; 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) { for (auto cbpair = 0u; cbpair < count; ++cbpair) {
const auto* ccb = ccb_gpu_addrs ? ccb_gpu_addrs[cbpair] : nullptr; 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; const auto ccb_size_in_bytes = ccb_sizes_in_bytes ? ccb_sizes_in_bytes[cbpair] : 0;
@ -1977,6 +1991,7 @@ int PS4_SYSV_ABI sceGnmSubmitDone() {
submission_lock = true; submission_lock = true;
} }
liverpool->NotifySubmitDone(); liverpool->NotifySubmitDone();
send_init_packet = true;
++frames_submitted; ++frames_submitted;
return ORBIS_OK; return ORBIS_OK;
} }
@ -2450,6 +2465,11 @@ void RegisterlibSceGnmDriver(Core::Loader::SymbolsResolver* sym) {
liverpool = std::make_unique<AmdGpu::Liverpool>(); liverpool = std::make_unique<AmdGpu::Liverpool>();
renderer = std::make_unique<Vulkan::RendererVulkan>(*g_window, liverpool.get()); 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("b0xyllnVY-I", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, sceGnmAddEqEvent);
LIB_FUNCTION("b08AgtPlHPg", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1, LIB_FUNCTION("b08AgtPlHPg", "libSceGnmDriver", 1, "libSceGnmDriver", 1, 1,
sceGnmAreSubmitsAllowed); sceGnmAreSubmitsAllowed);

View File

@ -154,7 +154,7 @@ int PS4_SYSV_ABI sceKernelGetCompiledSdkVersion(int* ver) {
int version = param_sfo->GetInteger("SYSTEM_VER"); int version = param_sfo->GetInteger("SYSTEM_VER");
LOG_INFO(Kernel, "returned system version = {:#x}", version); LOG_INFO(Kernel, "returned system version = {:#x}", version);
*ver = 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) { s64 PS4_SYSV_ABI ps4__read(int d, void* buf, u64 nbytes) {

View File

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

View File

@ -42,10 +42,6 @@ Emulator::Emulator() : window{WindowWidth, WindowHeight, controller} {
// Start logger. // Start logger.
Common::Log::Initialize(); Common::Log::Initialize();
Common::Log::Start(); Common::Log::Start();
// Initialize kernel and library facilities.
Libraries::Kernel::init_pthreads();
Libraries::InitHLELibs(&linker->GetHLESymbols());
} }
Emulator::~Emulator() { Emulator::~Emulator() {
@ -93,6 +89,10 @@ void Emulator::Run(const std::filesystem::path& file) {
const auto& mount_temp_dir = Common::FS::GetUserPath(Common::FS::PathType::TempDataDir) / id; const auto& mount_temp_dir = Common::FS::GetUserPath(Common::FS::PathType::TempDataDir) / id;
mnt->Mount(mount_temp_dir, "/temp0"); // called in app_content ==> stat/mkdir mnt->Mount(mount_temp_dir, "/temp0"); // called in app_content ==> stat/mkdir
// Initialize kernel and library facilities.
Libraries::Kernel::init_pthreads();
Libraries::InitHLELibs(&linker->GetHLESymbols());
// Load the module with the linker // Load the module with the linker
linker->LoadModule(file); linker->LoadModule(file);

View File

@ -122,9 +122,8 @@ void PipelineCache::RefreshGraphicsKey() {
key.depth.depth_enable.Assign(key.depth_format != vk::Format::eUndefined); key.depth.depth_enable.Assign(key.depth_format != vk::Format::eUndefined);
} }
// TODO: Should be a check for `OperationMode::Disable` once we emulate HW state init packet const auto skip_cb_binding =
// sent by system software. regs.color_control.mode == AmdGpu::Liverpool::ColorControl::OperationMode::Disable;
const auto skip_cb_binding = false;
// `RenderingInfo` is assumed to be initialized with a contiguous array of valid color // `RenderingInfo` is assumed to be initialized with a contiguous array of valid color
// attachments. This might be not a case as HW color buffers can be bound in an arbitrary order. // attachments. This might be not a case as HW color buffers can be bound in an arbitrary order.