libraries: gnmdriver: an option to dump application command lists

This commit is contained in:
psucien 2024-06-01 15:16:39 +02:00
parent d2321dbd9b
commit 44c8de5be9
5 changed files with 48 additions and 1 deletions

View File

@ -20,6 +20,7 @@ static bool isLibc = true;
static bool isShowSplash = false;
static bool isNullGpu = false;
static bool shouldDumpShaders = false;
static bool shouldDumpPM4 = false;
bool isLleLibc() {
return isLibc;
@ -64,6 +65,10 @@ bool dumpShaders() {
return shouldDumpShaders;
}
bool dumpPM4() {
return shouldDumpPM4;
}
void load(const std::filesystem::path& path) {
// If the configuration file does not exist, create it and return
std::error_code error;
@ -102,6 +107,7 @@ void load(const std::filesystem::path& path) {
gpuId = toml::find_or<toml::integer>(gpu, "gpuId", 0);
isNullGpu = toml::find_or<toml::boolean>(gpu, "nullGpu", false);
shouldDumpShaders = toml::find_or<toml::boolean>(gpu, "dumpShaders", false);
shouldDumpPM4 = toml::find_or<toml::boolean>(gpu, "dumpPM4", false);
}
}
if (data.contains("Debug")) {
@ -149,6 +155,7 @@ void save(const std::filesystem::path& path) {
data["GPU"]["screenHeight"] = screenHeight;
data["GPU"]["nullGpu"] = isNullGpu;
data["GPU"]["dumpShaders"] = shouldDumpShaders;
data["GPU"]["dumpPM4"] = shouldDumpPM4;
data["Debug"]["DebugDump"] = isDebugDump;
data["LLE"]["libc"] = isLibc;

View File

@ -23,5 +23,6 @@ bool isLleLibc();
bool showSplash();
bool nullGpu();
bool dumpShaders();
bool dumpPM4();
}; // namespace Config

View File

@ -35,6 +35,7 @@ static auto UserPaths = [] {
create_path(PathType::LogDir, user_dir / LOG_DIR);
create_path(PathType::ScreenshotsDir, user_dir / SCREENSHOTS_DIR);
create_path(PathType::ShaderDir, user_dir / SHADER_DIR);
create_path(PathType::PM4Dir, user_dir / PM4_DIR);
create_path(PathType::SaveDataDir, user_dir / SAVEDATA_DIR);
create_path(PathType::SysModuleDir, user_dir / SYSMODULES_DIR);

View File

@ -13,6 +13,7 @@ enum class PathType {
LogDir, // Where log files are stored.
ScreenshotsDir, // Where screenshots are stored.
ShaderDir, // Where shaders are stored.
PM4Dir, // Where command lists are stored.
SaveDataDir, // Where guest save data is stored.
SysModuleDir, // Where system modules are stored.
};
@ -23,6 +24,7 @@ constexpr auto PORTABLE_DIR = "user";
constexpr auto LOG_DIR = "log";
constexpr auto SCREENSHOTS_DIR = "screenshots";
constexpr auto SHADER_DIR = "shader";
constexpr auto PM4_DIR = "pm4";
constexpr auto SAVEDATA_DIR = "savedata";
constexpr auto SYSMODULES_DIR = "sys_modules";

View File

@ -2,7 +2,9 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include "common/assert.h"
#include "common/config.h"
#include "common/logging/log.h"
#include "common/path_util.h"
#include "core/libraries/error_codes.h"
#include "core/libraries/gnmdriver/gnmdriver.h"
#include "core/libraries/libs.h"
@ -28,6 +30,21 @@ static constexpr bool g_fair_hw_init = false;
// In case if `submitDone` is issued we need to block submissions until GPU idle
static u32 submission_lock{};
static u64 frames_submitted{}; // frame counter
static void DumpCommandList(std::span<const u32> cmd_list, const std::string& postfix) {
using namespace Common::FS;
const auto dump_dir = GetUserPath(PathType::PM4Dir);
if (!std::filesystem::exists(dump_dir)) {
std::filesystem::create_directories(dump_dir);
}
if (cmd_list.empty()) {
return;
}
const auto filename = std::format("{:08}_{}", frames_submitted, postfix);
const auto file = IOFile{dump_dir / filename, FileAccessMode::Write};
file.WriteSpan(cmd_list);
}
// Write a special ending NOP packet with N DWs data block
template <u32 data_block_size>
@ -1439,7 +1456,25 @@ s32 PS4_SYSV_ABI sceGnmSubmitCommandBuffers(u32 count, const u32* dcb_gpu_addrs[
const auto dcb_size_dw = dcb_sizes_in_bytes[cbpair] >> 2;
const auto ccb_size_dw = ccb_size_in_bytes >> 2;
liverpool->SubmitGfx({dcb_gpu_addrs[cbpair], dcb_size_dw}, {ccb, ccb_size_dw});
const auto& dcb_span = std::span<const u32>{dcb_gpu_addrs[cbpair], dcb_size_dw};
const auto& ccb_span = std::span<const u32>{ccb, ccb_size_dw};
if (Config::dumpPM4()) {
static auto last_frame_num = frames_submitted;
static u32 seq_num{};
if (last_frame_num == frames_submitted) {
++seq_num;
} else {
last_frame_num = frames_submitted;
seq_num = 0u;
}
// File name format is: <queue>_<submit num>_<buffer_in_submit>
DumpCommandList(dcb_span, std::format("dcb_{}_{}", seq_num, cbpair));
DumpCommandList(ccb_span, std::format("ccb_{}_{}", seq_num, cbpair));
}
liverpool->SubmitGfx(dcb_span, ccb_span);
}
return ORBIS_OK;
@ -1456,6 +1491,7 @@ int PS4_SYSV_ABI sceGnmSubmitDone() {
submission_lock = true;
}
liverpool->NotifySubmitDone();
++frames_submitted;
return ORBIS_OK;
}