mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-07-24 19:14:40 +00:00
libraries: gnmdriver: an option to dump application command lists
This commit is contained in:
parent
d2321dbd9b
commit
44c8de5be9
@ -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;
|
||||
|
||||
|
@ -23,5 +23,6 @@ bool isLleLibc();
|
||||
bool showSplash();
|
||||
bool nullGpu();
|
||||
bool dumpShaders();
|
||||
bool dumpPM4();
|
||||
|
||||
}; // namespace Config
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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";
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user