From 3eb8000b75789ef7fadabf348369decab3d2a4b3 Mon Sep 17 00:00:00 2001 From: Fire Cube Date: Thu, 1 May 2025 20:58:38 +0200 Subject: [PATCH] some progress --- src/common/binary_helper.h | 30 ++--- .../renderer_vulkan/shader_cache.cpp | 105 +++++++++++++----- src/video_core/renderer_vulkan/shader_cache.h | 10 +- .../renderer_vulkan/vk_pipeline_cache.cpp | 15 ++- 4 files changed, 102 insertions(+), 58 deletions(-) diff --git a/src/common/binary_helper.h b/src/common/binary_helper.h index cfcc213ae..564896f11 100644 --- a/src/common/binary_helper.h +++ b/src/common/binary_helper.h @@ -2,44 +2,46 @@ #include #include +#include "common/logging/log.h" using u32 = uint32_t; template -void writeBin(std::ostream& os, const T& v) { - os.write(reinterpret_cast(&v), sizeof(T)); +void writeBin(std::ostream& os, const T& v) { + LOG_INFO(Render_Recompiler, "BinaryHelper: Pos: {}", static_cast(os.tellp())); + os.write(reinterpret_cast(&v), sizeof(T)); } template void readBin(std::istream& is, T& v) { - is.read(reinterpret_cast(&v), sizeof(T)); + is.read(reinterpret_cast(&v), sizeof(T)); } // Spezialfall für Arrays/Blöcke template void writeBlock(std::ostream& os, const T* data, size_t count) { - os.write(reinterpret_cast(data), sizeof(T) * count); + os.write(reinterpret_cast(data), sizeof(T) * count); } template void readBlock(std::istream& is, T* data, size_t count) { - is.read(reinterpret_cast(data), sizeof(T) * count); + is.read(reinterpret_cast(data), sizeof(T) * count); } // Spezialfall für Container template void writeContainer(std::ostream& os, const std::vector& v) { - u32 n = static_cast(v.size()); - writeBin(os, n); - if (n) - writeBlock(os, v.data(), n); + u32 n = static_cast(v.size()); + writeBin(os, n); + if (n) + writeBlock(os, v.data(), n); } template void readContainer(std::istream& is, std::vector& v) { - u32 n; - readBin(is, n); - v.resize(n); - if (n) - readBlock(is, v.data(), n); + u32 n; + readBin(is, n); + v.resize(n); + if (n) + readBlock(is, v.data(), n); } \ No newline at end of file diff --git a/src/video_core/renderer_vulkan/shader_cache.cpp b/src/video_core/renderer_vulkan/shader_cache.cpp index 65df6e295..4097b140a 100644 --- a/src/video_core/renderer_vulkan/shader_cache.cpp +++ b/src/video_core/renderer_vulkan/shader_cache.cpp @@ -5,28 +5,93 @@ #include "common/path_util.h" #include "common/io_file.h" #include "common/binary_helper.h" +#include "common/logging/log.h" #include "shader_recompiler/info.h" using u64 = uint64_t; +using u32 = uint32_t; namespace ShaderCache { const auto shader_cache_dir = Common::FS::GetUserPath(Common::FS::PathType::ShaderDir) / "cache"; -std::string CreateShaderID(u64 pgm_hash, size_t perm_idx, std::ostream& info_serialized, std::ostream& profile_serialized) { - std::ostringstream info_stream, profile_stream; - info_stream << pgm_hash << perm_idx; - info_stream << info_serialized.rdbuf(); - profile_stream << profile_serialized.rdbuf(); - - std::string combined_data = info_stream.str() + profile_stream.str(); - +std::string CreateShaderID(u64 pgm_hash, size_t perm_idx, std::ostream& info_serialized) { + std::ostringstream data_stream; + data_stream << pgm_hash << perm_idx; + data_stream << info_serialized.rdbuf(); std::hash hasher; - size_t shader_id = hasher(combined_data); + size_t shader_id = hasher(data_stream.str()); return std::to_string(shader_id); } void SerializeInfo(std::ostream& info_serialized, Shader::Info info) { + // UD Mask + writeBin(info_serialized, info.ud_mask.mask); + + // Buffer-Resources + u32 count = static_cast(info.buffers.size()); + writeBin(info_serialized, count); // Buffer Amount + LOG_INFO(Render_Recompiler, "ShaderCache: Buffer count: {}", info.buffers.size()); + + for (const auto& buffer : info.buffers) { + writeBin(info_serialized, buffer.sharp_idx); + writeBin(info_serialized, static_cast(buffer.used_types)); + writeBin(info_serialized, static_cast(buffer.buffer_type)); + writeBin(info_serialized, buffer.instance_attrib); + writeBin(info_serialized, static_cast(buffer.is_written ? 1 : 0)); + writeBin(info_serialized, static_cast(buffer.is_formatted ? 1 : 0)); + } + + // Image-Resources + count = static_cast(info.images.size()); + writeBin(info_serialized, count); // Image Amount + LOG_INFO(Render_Recompiler, "ShaderCache: Image count: {}", info.images.size()); + for (const auto& image : info.images) { + writeBin(info_serialized, image.sharp_idx); + writeBin(info_serialized, static_cast(image.is_depth ? 1 : 0)); + writeBin(info_serialized, static_cast(image.is_atomic ? 1 : 0)); + writeBin(info_serialized, static_cast(image.is_array ? 1 : 0)); + writeBin(info_serialized, static_cast(image.is_written ? 1 : 0)); + } + + // Sampler-Resources + count = static_cast(info.samplers.size()); + writeBin(info_serialized, count); // Sampler Amount + LOG_INFO(Render_Recompiler, "ShaderCache: Sampler count: {}", info.samplers.size()); + for (const auto& sampler : info.samplers) { + writeBin(info_serialized, sampler.sharp_idx); + } + + // FMask-Resources + count = static_cast(info.fmasks.size()); + writeBin(info_serialized, count); // FMask Amount + LOG_INFO(Render_Recompiler, "ShaderCache: FMask count: {}", info.fmasks.size()); + for (const auto& fmask : info.fmasks) { + writeBin(info_serialized, fmask.sharp_idx); + } + + // GS Copy Data + writeBin(info_serialized, info.gs_copy_data.num_attrs); + + u32 mapCount = static_cast(info.gs_copy_data.attr_map.size()); + writeBin(info_serialized, mapCount); + + for (auto const& [loc, idx] : info.gs_copy_data.attr_map) { + writeBin(info_serialized, loc); + writeBin(info_serialized, idx); + } + + // SRT Info + u32 srtCount = static_cast(info.srt_info.srt_reservations.size()); + writeBin(info_serialized, count); + + for (const auto& res : info.srt_info.srt_reservations) { + writeBin(info_serialized, res.sgpr_base); + writeBin(info_serialized, res.dword_offset); + writeBin(info_serialized, res.num_dwords); + } + + // MRT Mask writeBin(info_serialized, info.mrt_mask); } @@ -34,19 +99,11 @@ void DeserializeInfo(std::istream& info_serialized, Shader::Info& info) { readBin(info_serialized, info.mrt_mask); } -void SerializeProfile(std::ostream& profile_serialized, Shader::Profile profile) { - writeBin(profile_serialized, profile.has_broken_spirv_clamp); -} - -void DeserializeProfile(std::istream& profile_serialized, Shader::Profile& profile) { - readBin(profile_serialized, profile.has_broken_spirv_clamp); -} - bool CheckShaderCache(std::string shader_id) { return 0; } -void GetShader(std::string shader_id, Shader::Info& info, Shader::Profile& profile) { +void GetShader(std::string shader_id, Shader::Info& info) { std::string 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, @@ -74,13 +131,9 @@ void GetShader(std::string shader_id, Shader::Info& info, Shader::Profile& profi info_stream.str(std::string(resources_data.begin(), resources_data.end())); DeserializeInfo(info_stream, info); - std::istringstream profile_stream; - profile_stream.str( - std::string(resources_data.begin() + info_stream.tellg(), resources_data.end())); - DeserializeProfile(profile_stream, profile); } -void AddShader(std::string shader_id, std::vector spv, std::ostream& info_serialized, std::ostream& profile_serialized) { +void AddShader(std::string shader_id, std::vector spv, std::ostream& info_serialized) { // SPIR-V-Datei speichern std::string spirv_cache_filename = shader_id + ".spv"; std::filesystem::path spirv_cache_file_path = shader_cache_dir / spirv_cache_filename; @@ -99,12 +152,6 @@ void AddShader(std::string shader_id, std::vector spv, std::ostream& info_s resources_dump_file.WriteSpan(std::span(info_data.data(), info_data.size())); } - if (std::ostringstream* profile_oss = dynamic_cast(&profile_serialized)) { - std::string profile_data = profile_oss->str(); - resources_dump_file.WriteSpan( - std::span(profile_data.data(), profile_data.size())); - } - resources_dump_file.Close(); } diff --git a/src/video_core/renderer_vulkan/shader_cache.h b/src/video_core/renderer_vulkan/shader_cache.h index 4f885a99d..2b5c1ae75 100644 --- a/src/video_core/renderer_vulkan/shader_cache.h +++ b/src/video_core/renderer_vulkan/shader_cache.h @@ -8,16 +8,12 @@ namespace ShaderCache { -std::string CreateShaderID(u64 pgm_hash, size_t perm_idx, std::ostream& info_dump, - std::ostream& profile_dump); +std::string CreateShaderID(u64 pgm_hash, size_t perm_idx, std::ostream& info_dump); void SerializeInfo(std::ostream& info_serialized, Shader::Info info); -void SerializeProfile(std::ostream& profile_serialized, Shader::Profile profile); void DeserializeInfo(std::istream& info_serialized, Shader::Info& info); -void DeserializeProfile(std::istream& profile_serialized, Shader::Profile& profile); bool CheckShaderCache(std::string shader_id); -void GetShader(std::string shader_id, Shader::Info& info, Shader::Profile& profile); -void AddShader(std::string shader_id, std::vector spv, std::ostream& info_serialized, - std::ostream& profile_serialized); +void GetShader(std::string shader_id, Shader::Info& info); +void AddShader(std::string shader_id, std::vector spv, std::ostream& info_serialized); } // namespace ShaderCache diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index ca6b19c91..cb4a6c0ce 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -493,12 +493,6 @@ vk::ShaderModule PipelineCache::CompileModule(Shader::Info& info, Shader::Runtim perm_idx != 0 ? "(permutation)" : ""); DumpShader(code, info.pgm_hash, info.stage, perm_idx, "bin"); - std::ostringstream info_serialized, profile_serialized; - ::ShaderCache::SerializeInfo(info_serialized, info); - ::ShaderCache::SerializeProfile(profile_serialized, profile); - std::string shader_id = ::ShaderCache::CreateShaderID(info.pgm_hash, perm_idx, info_serialized, profile_serialized); - ::ShaderCache::AddShader(shader_id, std::vector{}, info_serialized, profile_serialized); - LOG_INFO(Render_Vulkan, "Shader ID: {}", shader_id); const auto ir_program = Shader::TranslateProgram(code, pools, info, runtime_info, profile); @@ -508,11 +502,16 @@ vk::ShaderModule PipelineCache::CompileModule(Shader::Info& info, Shader::Runtim std::vector spv; - if (::ShaderCache::CheckShaderCache(shader_id)) { + if (false){ //(::ShaderCache::CheckShaderCache(shader_id)) { LOG_INFO(Render_Vulkan, "Loaded SPIR-V from cache"); } else { spv = Shader::Backend::SPIRV::EmitSPIRV(profile, runtime_info, ir_program, binding); - + std::ostringstream info_serialized; + ::ShaderCache::SerializeInfo(info_serialized, info); + std::string shader_id = + ::ShaderCache::CreateShaderID(info.pgm_hash, perm_idx, info_serialized); + ::ShaderCache::AddShader(shader_id, spv, info_serialized); + LOG_INFO(Render_Vulkan, "Shader ID: {}", shader_id); DumpShader(spv, info.pgm_hash, info.stage, perm_idx, "spv");