Implement fs::get_cache_dir

Win32: equal to config dir for now
Linux: respect XDG_CACHE_HOME if specified
OSX: possibly incomplete
This commit is contained in:
Nekotekina 2018-12-24 18:47:46 +03:00
parent 20efed66e9
commit bd9131ae1c
15 changed files with 69 additions and 28 deletions

View file

@ -1403,8 +1403,8 @@ const std::string& fs::get_config_dir()
if (const char* home = ::getenv("HOME")) if (const char* home = ::getenv("HOME"))
dir = home + "/Library/Application Support"s; dir = home + "/Library/Application Support"s;
#else #else
if (const char* home = ::getenv("XDG_CONFIG_HOME")) if (const char* conf = ::getenv("XDG_CONFIG_HOME"))
dir = home; dir = conf;
else if (const char* home = ::getenv("HOME")) else if (const char* home = ::getenv("HOME"))
dir = home + "/.config"s; dir = home + "/.config"s;
#endif #endif
@ -1425,15 +1425,53 @@ const std::string& fs::get_config_dir()
return s_dir; return s_dir;
} }
const std::string& fs::get_cache_dir()
{
static const std::string s_dir = []
{
std::string dir;
#ifdef _WIN32
dir = get_config_dir();
#else
#ifdef __APPLE__
if (const char* home = ::getenv("HOME"))
dir = home + "/Library/Caches"s;
#else
if (const char* cache = ::getenv("XDG_CACHE_HOME"))
dir = cache;
else if (const char* conf = ::getenv("XDG_CONFIG_HOME"))
dir = conf;
else if (const char* home = ::getenv("HOME"))
dir = home + "/.cache"s;
#endif
else // Just in case
dir = "./cache";
dir += "/rpcs3/";
if (!create_path(dir))
{
std::printf("Failed to create configuration directory '%s' (%d).\n", dir.c_str(), errno);
}
#endif
return dir;
}();
return s_dir;
}
std::string fs::get_data_dir(const std::string& prefix, const std::string& location, const std::string& suffix) std::string fs::get_data_dir(const std::string& prefix, const std::string& location, const std::string& suffix)
{ {
static const std::string s_dir = [] static const std::string s_dir = []
{ {
const std::string dir = get_config_dir() + "data/"; const std::string dir = get_cache_dir() + "data/";
if (!create_path(dir)) if (!create_path(dir))
{ {
return get_config_dir(); return get_cache_dir();
} }
return dir; return dir;

View file

@ -484,6 +484,9 @@ namespace fs
// Get configuration directory // Get configuration directory
const std::string& get_config_dir(); const std::string& get_config_dir();
// Get common cache directory
const std::string& get_cache_dir();
// Get data/cache directory for specified prefix and suffix // Get data/cache directory for specified prefix and suffix
std::string get_data_dir(const std::string& prefix, const std::string& location, const std::string& suffix); std::string get_data_dir(const std::string& prefix, const std::string& location, const std::string& suffix);

View file

@ -322,8 +322,8 @@ void logs::message::broadcast(const char* fmt, const fmt_type_info* sup, ...) co
logs::file_writer::file_writer(const std::string& name) logs::file_writer::file_writer(const std::string& name)
: m_name(name) : m_name(name)
{ {
const std::string log_name = fs::get_config_dir() + name + ".log"; const std::string log_name = fs::get_cache_dir() + name + ".log";
const std::string buf_name = fs::get_config_dir() + name + ".buf"; const std::string buf_name = fs::get_cache_dir() + name + ".buf";
try try
{ {
@ -352,7 +352,7 @@ logs::file_writer::file_writer(const std::string& name)
// Check free space // Check free space
fs::device_stat stats{}; fs::device_stat stats{};
if (!fs::statfs(fs::get_config_dir(), stats) || stats.avail_free < s_log_size * 8) if (!fs::statfs(fs::get_cache_dir(), stats) || stats.avail_free < s_log_size * 8)
{ {
fmt::throw_exception("Not enough free space (%f KB)", stats.avail_free / 1000000.); fmt::throw_exception("Not enough free space (%f KB)", stats.avail_free / 1000000.);
} }
@ -372,9 +372,9 @@ logs::file_writer::file_writer(const std::string& name)
verify(name.c_str()), m_fptr; verify(name.c_str()), m_fptr;
// Rotate backups (TODO) // Rotate backups (TODO)
fs::remove_file(fs::get_config_dir() + name + "1.log.gz"); fs::remove_file(fs::get_cache_dir() + name + "1.log.gz");
fs::create_dir(fs::get_config_dir() + "old_logs"); fs::create_dir(fs::get_cache_dir() + "old_logs");
fs::rename(fs::get_config_dir() + m_name + ".log.gz", fs::get_config_dir() + "old_logs/" + m_name + ".log.gz", true); fs::rename(fs::get_cache_dir() + m_name + ".log.gz", fs::get_cache_dir() + "old_logs/" + m_name + ".log.gz", true);
// Actual log file (allowed to fail) // Actual log file (allowed to fail)
m_fout.open(log_name, fs::rewrite); m_fout.open(log_name, fs::rewrite);

View file

@ -7,7 +7,7 @@ AudioDumper::AudioDumper(u16 ch)
{ {
if (GetCh()) if (GetCh())
{ {
m_output.open(fs::get_config_dir() + "audio.wav", fs::rewrite); m_output.open(fs::get_cache_dir() + "audio.wav", fs::rewrite);
m_output.write(m_header); // write initial file header m_output.write(m_header); // write initial file header
} }
} }

View file

@ -1225,7 +1225,7 @@ extern void ppu_initialize()
} }
// New PPU cache location // New PPU cache location
_main->cache = fs::get_config_dir() + "data/"; _main->cache = fs::get_cache_dir() + "data/";
if (!Emu.GetTitleID().empty() && Emu.GetCat() != "1P") if (!Emu.GetTitleID().empty() && Emu.GetCat() != "1P")
{ {

View file

@ -175,7 +175,7 @@ vertex_program_utils::vertex_program_metadata vertex_program_utils::analyse_vert
if (g_cfg.video.log_programs) if (g_cfg.video.log_programs)
{ {
fs::file dump(fs::get_config_dir() + "shaderlog/vp_analyser.bin", fs::rewrite); fs::file dump(fs::get_cache_dir() + "shaderlog/vp_analyser.bin", fs::rewrite);
dump.write(&entry, 4); dump.write(&entry, 4);
dump.write(data, 512 * 16); dump.write(data, 512 * 16);
dump.close(); dump.close();

View file

@ -130,7 +130,7 @@ struct D3D12Traits
} }
} }
fs::file(fs::get_config_dir() + "shaderlog/FragmentProgram" + std::to_string(ID) + ".hlsl", fs::rewrite).write(shader); fs::file(fs::get_cache_dir() + "shaderlog/FragmentProgram" + std::to_string(ID) + ".hlsl", fs::rewrite).write(shader);
fragmentProgramData.id = (u32)ID; fragmentProgramData.id = (u32)ID;
} }
@ -141,7 +141,7 @@ struct D3D12Traits
std::string shaderCode = VS.Decompile(); std::string shaderCode = VS.Decompile();
vertexProgramData.Compile(shaderCode, Shader::SHADER_TYPE::SHADER_TYPE_VERTEX); vertexProgramData.Compile(shaderCode, Shader::SHADER_TYPE::SHADER_TYPE_VERTEX);
vertexProgramData.vertex_shader_input_count = RSXVP.rsx_vertex_inputs.size(); vertexProgramData.vertex_shader_input_count = RSXVP.rsx_vertex_inputs.size();
fs::file(fs::get_config_dir() + "shaderlog/VertexProgram" + std::to_string(ID) + ".hlsl", fs::rewrite).write(shaderCode); fs::file(fs::get_cache_dir() + "shaderlog/VertexProgram" + std::to_string(ID) + ".hlsl", fs::rewrite).write(shaderCode);
vertexProgramData.id = (u32)ID; vertexProgramData.id = (u32)ID;
} }

View file

@ -388,7 +388,7 @@ void GLFragmentProgram::Compile()
const char* str = shader.c_str(); const char* str = shader.c_str();
const int strlen = ::narrow<int>(shader.length()); const int strlen = ::narrow<int>(shader.length());
fs::file(fs::get_config_dir() + "shaderlog/FragmentProgram" + std::to_string(id) + ".glsl", fs::rewrite).write(str); fs::file(fs::get_cache_dir() + "shaderlog/FragmentProgram" + std::to_string(id) + ".glsl", fs::rewrite).write(str);
glShaderSource(id, 1, &str, &strlen); glShaderSource(id, 1, &str, &strlen);
glCompileShader(id); glCompileShader(id);

View file

@ -2398,7 +2398,7 @@ public:
break; break;
} }
fs::file(fs::get_config_dir() + base_name + std::to_string(m_id) + ".glsl", fs::rewrite).write(str); fs::file(fs::get_cache_dir() + base_name + std::to_string(m_id) + ".glsl", fs::rewrite).write(str);
} }
glShaderSource(m_id, 1, &str, &length); glShaderSource(m_id, 1, &str, &length);

View file

@ -299,11 +299,11 @@ void GLVertexDecompilerThread::insertMainEnd(std::stringstream & OS)
//RSX matrices passed already map to the [0, 1] range but mapping to classic OGL requires that we undo this step //RSX matrices passed already map to the [0, 1] range but mapping to classic OGL requires that we undo this step
//This can be made unnecessary using the call glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE). //This can be made unnecessary using the call glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE).
//However, ClipControl only made it to opengl core in ver 4.5 though, so this is a workaround. //However, ClipControl only made it to opengl core in ver 4.5 though, so this is a workaround.
//NOTE: It is completely valid for games to use very large w values, causing the post-multiplied z to be in the hundreds //NOTE: It is completely valid for games to use very large w values, causing the post-multiplied z to be in the hundreds
//It is therefore critical that this step is done post-transform and the result re-scaled by w //It is therefore critical that this step is done post-transform and the result re-scaled by w
//SEE Naruto: UNS //SEE Naruto: UNS
//NOTE: On GPUs, poor fp32 precision means dividing z by w, then multiplying by w again gives slightly incorrect results //NOTE: On GPUs, poor fp32 precision means dividing z by w, then multiplying by w again gives slightly incorrect results
//This equation is simplified algebraically to an addition and subreaction which gives more accurate results (Fixes flickering skybox in Dark Souls 2) //This equation is simplified algebraically to an addition and subreaction which gives more accurate results (Fixes flickering skybox in Dark Souls 2)
//OS << " float ndc_z = gl_Position.z / gl_Position.w;\n"; //OS << " float ndc_z = gl_Position.z / gl_Position.w;\n";
@ -345,7 +345,7 @@ void GLVertexProgram::Compile()
const char* str = shader.c_str(); const char* str = shader.c_str();
const int strlen = ::narrow<int>(shader.length()); const int strlen = ::narrow<int>(shader.length());
fs::file(fs::get_config_dir() + "shaderlog/VertexProgram" + std::to_string(id) + ".glsl", fs::rewrite).write(str); fs::file(fs::get_cache_dir() + "shaderlog/VertexProgram" + std::to_string(id) + ".glsl", fs::rewrite).write(str);
glShaderSource(id, 1, &str, &strlen); glShaderSource(id, 1, &str, &strlen);
glCompileShader(id); glCompileShader(id);

View file

@ -403,7 +403,7 @@ void VKFragmentProgram::Decompile(const RSXFragmentProgram& prog)
decompiler.Task(); decompiler.Task();
shader.create(::glsl::program_domain::glsl_fragment_program, source); shader.create(::glsl::program_domain::glsl_fragment_program, source);
for (const ParamType& PT : decompiler.m_parr.params[PF_PARAM_UNIFORM]) for (const ParamType& PT : decompiler.m_parr.params[PF_PARAM_UNIFORM])
{ {
for (const ParamItem& PI : PT.items) for (const ParamItem& PI : PT.items)
@ -422,7 +422,7 @@ void VKFragmentProgram::Decompile(const RSXFragmentProgram& prog)
void VKFragmentProgram::Compile() void VKFragmentProgram::Compile()
{ {
fs::file(fs::get_config_dir() + "shaderlog/FragmentProgram" + std::to_string(id) + ".spirv", fs::rewrite).write(shader.get_source()); fs::file(fs::get_cache_dir() + "shaderlog/FragmentProgram" + std::to_string(id) + ".spirv", fs::rewrite).write(shader.get_source());
handle = shader.compile(); handle = shader.compile();
} }

View file

@ -353,7 +353,7 @@ void VKVertexProgram::Decompile(const RSXVertexProgram& prog)
void VKVertexProgram::Compile() void VKVertexProgram::Compile()
{ {
fs::file(fs::get_config_dir() + "shaderlog/VertexProgram" + std::to_string(id) + ".spirv", fs::rewrite).write(shader.get_source()); fs::file(fs::get_cache_dir() + "shaderlog/VertexProgram" + std::to_string(id) + ".spirv", fs::rewrite).write(shader.get_source());
handle = shader.compile(); handle = shader.compile();
} }

View file

@ -276,7 +276,7 @@ void Emulator::Init()
{ {
if (!g_tty) if (!g_tty)
{ {
g_tty.open(fs::get_config_dir() + "TTY.log", fs::rewrite + fs::append); g_tty.open(fs::get_cache_dir() + "TTY.log", fs::rewrite + fs::append);
} }
idm::init(); idm::init();
@ -318,7 +318,7 @@ void Emulator::Init()
fs::create_dir(dev_hdd1 + "game/"); fs::create_dir(dev_hdd1 + "game/");
} }
fs::create_path(fs::get_config_dir() + "shaderlog/"); fs::create_path(fs::get_cache_dir() + "shaderlog/");
fs::create_path(fs::get_config_dir() + "captures/"); fs::create_path(fs::get_config_dir() + "captures/");
#ifdef WITH_GDB_DEBUGGER #ifdef WITH_GDB_DEBUGGER
@ -771,7 +771,7 @@ void Emulator::Load(bool add_only)
// Initialize data/cache directory // Initialize data/cache directory
if (fs::is_dir(m_path)) if (fs::is_dir(m_path))
{ {
m_cache_path = fs::get_config_dir() + "data/" + GetTitleID() + '/'; m_cache_path = fs::get_cache_dir() + "data/" + GetTitleID() + '/';
LOG_NOTICE(LOADER, "Cache: %s", GetCachePath()); LOG_NOTICE(LOADER, "Cache: %s", GetCachePath());
} }
else else

View file

@ -155,7 +155,7 @@ log_frame::log_frame(std::shared_ptr<gui_settings> guiSettings, QWidget *parent)
setWidget(m_tabWidget); setWidget(m_tabWidget);
// Open or create TTY.log // Open or create TTY.log
m_tty_file.open(fs::get_config_dir() + "TTY.log", fs::read + fs::create); m_tty_file.open(fs::get_cache_dir() + "TTY.log", fs::read + fs::create);
CreateAndConnectActions(); CreateAndConnectActions();

View file

@ -671,7 +671,7 @@ void rsx_debugger::GetMemory()
dump += '\n'; dump += '\n';
} }
fs::file(fs::get_config_dir() + "command_dump.log", fs::rewrite).write(dump); fs::file(fs::get_cache_dir() + "command_dump.log", fs::rewrite).write(dump);
for (u32 i = 0;i < frame_debug.draw_calls.size(); i++) for (u32 i = 0;i < frame_debug.draw_calls.size(); i++)
m_list_captured_draw_calls->setItem(i, 0, new QTableWidgetItem(qstr(frame_debug.draw_calls[i].name))); m_list_captured_draw_calls->setItem(i, 0, new QTableWidgetItem(qstr(frame_debug.draw_calls[i].name)));