some progress

This commit is contained in:
Fire Cube 2025-05-01 20:58:38 +02:00
parent b32ba2918b
commit 3eb8000b75
4 changed files with 102 additions and 58 deletions

View File

@ -2,44 +2,46 @@
#include <iostream>
#include <vector>
#include "common/logging/log.h"
using u32 = uint32_t;
template <typename T>
void writeBin(std::ostream& os, const T& v) {
os.write(reinterpret_cast<const char*>(&v), sizeof(T));
void writeBin(std::ostream& os, const T& v) {
LOG_INFO(Render_Recompiler, "BinaryHelper: Pos: {}", static_cast<int64_t>(os.tellp()));
os.write(reinterpret_cast<const char*>(&v), sizeof(T));
}
template <typename T>
void readBin(std::istream& is, T& v) {
is.read(reinterpret_cast<char*>(&v), sizeof(T));
is.read(reinterpret_cast<char*>(&v), sizeof(T));
}
// Spezialfall für Arrays/Blöcke
template <typename T>
void writeBlock(std::ostream& os, const T* data, size_t count) {
os.write(reinterpret_cast<const char*>(data), sizeof(T) * count);
os.write(reinterpret_cast<const char*>(data), sizeof(T) * count);
}
template <typename T>
void readBlock(std::istream& is, T* data, size_t count) {
is.read(reinterpret_cast<char*>(data), sizeof(T) * count);
is.read(reinterpret_cast<char*>(data), sizeof(T) * count);
}
// Spezialfall für Container
template <typename T>
void writeContainer(std::ostream& os, const std::vector<T>& v) {
u32 n = static_cast<u32>(v.size());
writeBin(os, n);
if (n)
writeBlock(os, v.data(), n);
u32 n = static_cast<u32>(v.size());
writeBin(os, n);
if (n)
writeBlock(os, v.data(), n);
}
template <typename T>
void readContainer(std::istream& is, std::vector<T>& 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);
}

View File

@ -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<std::string> 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<u32>(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<u32>(buffer.used_types));
writeBin(info_serialized, static_cast<u32>(buffer.buffer_type));
writeBin(info_serialized, buffer.instance_attrib);
writeBin(info_serialized, static_cast<u8>(buffer.is_written ? 1 : 0));
writeBin(info_serialized, static_cast<u8>(buffer.is_formatted ? 1 : 0));
}
// Image-Resources
count = static_cast<u32>(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<u8>(image.is_depth ? 1 : 0));
writeBin(info_serialized, static_cast<u8>(image.is_atomic ? 1 : 0));
writeBin(info_serialized, static_cast<u8>(image.is_array ? 1 : 0));
writeBin(info_serialized, static_cast<u8>(image.is_written ? 1 : 0));
}
// Sampler-Resources
count = static_cast<u32>(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<u32>(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<u32>(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<u32>(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<u32> spv, std::ostream& info_serialized, std::ostream& profile_serialized) {
void AddShader(std::string shader_id, std::vector<u32> 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<u32> spv, std::ostream& info_s
resources_dump_file.WriteSpan(std::span<const char>(info_data.data(), info_data.size()));
}
if (std::ostringstream* profile_oss = dynamic_cast<std::ostringstream*>(&profile_serialized)) {
std::string profile_data = profile_oss->str();
resources_dump_file.WriteSpan(
std::span<const char>(profile_data.data(), profile_data.size()));
}
resources_dump_file.Close();
}

View File

@ -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<u32> 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<u32> spv, std::ostream& info_serialized);
} // namespace ShaderCache

View File

@ -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<u32>{}, 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<u32> 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");