mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-07-23 18:45:36 +00:00
some progress
This commit is contained in:
parent
b32ba2918b
commit
3eb8000b75
@ -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);
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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");
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user