diff --git a/CMakeLists.txt b/CMakeLists.txt index c0e8b0dbf..d74510d36 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -690,6 +690,7 @@ set(COMMON src/common/logging/backend.cpp src/common/rdtsc.h src/common/recursive_lock.cpp src/common/recursive_lock.h + src/common/serialization.h src/common/sha1.h src/common/shared_first_mutex.h src/common/signal_context.h diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt index 1fd4ffb2b..ae52dae9d 100644 --- a/externals/CMakeLists.txt +++ b/externals/CMakeLists.txt @@ -216,7 +216,8 @@ if (NOT TARGET stb::headers) add_library(stb::headers ALIAS stb) endif() -if (NOT TARGET cereal::cereal) +# cereal +if (NOT TARGET cereal::cereal AND NOT APPLE) set(SKIP_PERFORMANCE_COMPARISON ON "") set(BUILD_SANDBOX OFF "") set(BUILD_TESTS OFF "") diff --git a/src/emulator.cpp b/src/emulator.cpp index e2ee3e103..705060252 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -41,6 +41,7 @@ #include "core/memory.h" #include "emulator.h" #include "video_core/renderdoc.h" +#include "video_core/renderer_vulkan/shader_cache.h" Frontend::WindowSDL* g_window = nullptr; @@ -256,10 +257,9 @@ void Emulator::Run(std::filesystem::path file, const std::vector ar } VideoCore::SetOutputDir(mount_captures_dir, id); - const auto shader_cache_dir = Common::FS::GetUserPath(Common::FS::PathType::ShaderDir) / "cache"; - if (!std::filesystem::exists(shader_cache_dir)) { - std::filesystem::create_directories(shader_cache_dir); - LOG_INFO(Loader, "Created shader cache directory: {}", shader_cache_dir.string()); + if (!std::filesystem::exists(SHADER_CACHE_DIR)) { + std::filesystem::create_directories(SHADER_CACHE_DIR); + LOG_INFO(Loader, "Created shader cache directory: {}", SHADER_CACHE_DIR.string()); } // Initialize kernel and library facilities. Libraries::InitHLELibs(&linker->GetHLESymbols()); diff --git a/src/video_core/renderer_vulkan/shader_cache.cpp b/src/video_core/renderer_vulkan/shader_cache.cpp index 5c17ec480..607c2de54 100644 --- a/src/video_core/renderer_vulkan/shader_cache.cpp +++ b/src/video_core/renderer_vulkan/shader_cache.cpp @@ -29,8 +29,6 @@ using u32 = uint32_t; namespace ShaderCache { -const auto shader_cache_dir = Common::FS::GetUserPath(Common::FS::PathType::ShaderDir) / "cache"; -std::unordered_map> g_ud_storage; u64 CalculateSpecializationHash(const Shader::StageSpecialization& spec) { u64 hash = 0; @@ -246,8 +244,9 @@ u64 CalculateSpecializationHash(const Shader::StageSpecialization& spec) { } bool CheckShaderCache(std::string shader_id) { - std::filesystem::path spirv_cache_file_path = shader_cache_dir / (shader_id + ".spv"); - std::filesystem::path resources_file_path = shader_cache_dir / (shader_id + ".resources"); + std::filesystem::path spirv_cache_file_path = SHADER_CACHE_DIR / static_cast(shader_id + ".spv"); + std::filesystem::path resources_file_path = SHADER_CACHE_DIR / static_cast(shader_id + ".resources"); +; if (!std::filesystem::exists(spirv_cache_file_path)) { return false; @@ -282,14 +281,17 @@ bool CheckShaderCache(std::string shader_id) { } void GetShader(std::string shader_id, Shader::Info& info, std::vector& spv) { - std::string spirv_cache_filename = shader_id + ".spv"; - std::filesystem::path spirv_cache_file_path = shader_cache_dir / spirv_cache_filename; + // read spirv + std::filesystem::path spirv_cache_filename = shader_id + ".spv"; + std::filesystem::path spirv_cache_file_path = SHADER_CACHE_DIR / spirv_cache_filename; Common::FS::IOFile spirv_cache_file(spirv_cache_file_path, Common::FS::FileAccessMode::Read); spv.resize(spirv_cache_file.GetSize() / sizeof(u32)); spirv_cache_file.Read(spv); spirv_cache_file.Close(); - std::filesystem::path resources_dump_file_path = shader_cache_dir / (shader_id + ".resources"); + // read resources + std::filesystem::path resource_dump_filename = shader_id + ".resources"; + std::filesystem::path resources_dump_file_path = SHADER_CACHE_DIR / resource_dump_filename; Common::FS::IOFile resources_dump_file(resources_dump_file_path, Common::FS::FileAccessMode::Read); @@ -305,13 +307,14 @@ void GetShader(std::string shader_id, Shader::Info& info, std::vector& spv) } void AddShader(std::string shader_id, std::vector spv, std::ostream& info_serialized) { - std::string spirv_cache_filename = shader_id + ".spv"; - std::filesystem::path spirv_cache_file_path = shader_cache_dir / spirv_cache_filename; + std::filesystem::path spirv_cache_filename = shader_id + ".spv"; + std::filesystem::path spirv_cache_file_path = SHADER_CACHE_DIR / spirv_cache_filename; Common::FS::IOFile shader_cache_file(spirv_cache_file_path, Common::FS::FileAccessMode::Write); shader_cache_file.WriteSpan(std::span(spv)); shader_cache_file.Close(); - std::filesystem::path resources_dump_file_path = shader_cache_dir / (shader_id + ".resources"); + std::filesystem::path resource_dump_filename = shader_id + ".resources"; + std::filesystem::path resources_dump_file_path = SHADER_CACHE_DIR / resource_dump_filename; Common::FS::IOFile resources_dump_file(resources_dump_file_path, Common::FS::FileAccessMode::Write); @@ -331,6 +334,7 @@ void SerializeInfo(std::ostream& info_serialized, Shader::Info &info) { ar << info.buffers; ar << info.images; ar << info.samplers; + ar << info.fmasks; } diff --git a/src/video_core/renderer_vulkan/shader_cache.h b/src/video_core/renderer_vulkan/shader_cache.h index 4df74e115..51b2b17ed 100644 --- a/src/video_core/renderer_vulkan/shader_cache.h +++ b/src/video_core/renderer_vulkan/shader_cache.h @@ -11,6 +11,8 @@ namespace ShaderCache { +#define SHADER_CACHE_DIR (Common::FS::GetUserPath(Common::FS::PathType::ShaderDir) / "cache" / "portable") + u64 CalculateSpecializationHash(const Shader::StageSpecialization& spec); void SerializeInfo( std::ostream& info_serialized, Shader::Info& info); diff --git a/src/video_core/renderer_vulkan/shader_cache_serialization.h b/src/video_core/renderer_vulkan/shader_cache_serialization.h index bbe0bf97c..b4ee48d2f 100644 --- a/src/video_core/renderer_vulkan/shader_cache_serialization.h +++ b/src/video_core/renderer_vulkan/shader_cache_serialization.h @@ -5,27 +5,12 @@ #include #include #include + +#include "common/serialization.h" #include "shader_recompiler/info.h" namespace cereal { -// boost::small_vector -template -void save(Archive& ar, boost::container::small_vector const& smallVector) { - ar(static_cast(smallVector.size())); - for (auto const& element : smallVector) - ar(element); -} - -template -void load(Archive& ar, boost::container::small_vector& smallVector) { - std::uint32_t elementCount; - ar(elementCount); - smallVector.resize(elementCount); - for (auto& element : smallVector) - ar(element); -} - // Shader::Info::UserDataMask template void serialize(Archive& ar, Shader::Info::UserDataMask& mask) { @@ -89,4 +74,10 @@ void serialize(Archive& ar, Shader::SamplerResource& sampler) { static_cast(sampler.disable_aniso)); } +// Shader::FMaskResource +template +void serialize(Archive& ar, Shader::FMaskResource& fmask) { + cereal::binary_data(reinterpret_cast(&fmask), sizeof(fmask)); +} + } \ No newline at end of file diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 42d1d8c75..904ac96f7 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -516,13 +516,13 @@ vk::ShaderModule PipelineCache::CompileModule(Shader::Info& info, Shader::Runtim std::vector spv; std::string shader_id = std::to_string(::ShaderCache::CalculateSpecializationHash(spec)); if (::ShaderCache::CheckShaderCache(shader_id)) { - LOG_INFO(Render_Vulkan, "Loaded shader {} {:#x} {} from cache", info.stage, info.pgm_hash, - perm_idx != 0 ? "(permutation)" : ""); + LOG_INFO(Render_Vulkan, "Loaded shader {} {:#x} {}from cache", info.stage, info.pgm_hash, + perm_idx != 0 ? "(permutation) " : ""); ::ShaderCache::GetShader(shader_id, info, spv); info.RefreshFlatBuf(); } else { - LOG_INFO(Render_Vulkan, "Shader {} {:#x} {} not in cache", info.stage, - info.pgm_hash, perm_idx != 0 ? "(permutation)" : ""); + LOG_INFO(Render_Vulkan, "Shader {} {:#x} {}not in cache", info.stage, + info.pgm_hash, perm_idx != 0 ? "(permutation) " : ""); const auto ir_program = Shader::TranslateProgram(code, pools, info, runtime_info, profile); spv = Shader::Backend::SPIRV::EmitSPIRV(profile, runtime_info, ir_program, binding); std::ostringstream info_serialized; @@ -533,8 +533,8 @@ vk::ShaderModule PipelineCache::CompileModule(Shader::Info& info, Shader::Runtim DumpShader(spv, info.pgm_hash, info.stage, perm_idx, "spv"); - LOG_INFO(Render_Vulkan, "Compiled shader {} {:#x} {} and saved it to cache", info.stage, info.pgm_hash, - perm_idx != 0 ? "(permutation)" : ""); + LOG_INFO(Render_Vulkan, "Compiled shader {} {:#x} {}and saved it to cache", info.stage, info.pgm_hash, + perm_idx != 0 ? "(permutation) " : ""); } vk::ShaderModule module;