|
|
|
@ -29,6 +29,8 @@ using VideoCommon::Shader::KeyMap; |
|
|
|
|
|
|
|
namespace { |
|
|
|
|
|
|
|
using VideoCommon::Shader::SeparateSamplerKey; |
|
|
|
|
|
|
|
using ShaderCacheVersionHash = std::array<u8, 64>; |
|
|
|
|
|
|
|
struct ConstBufferKey { |
|
|
|
@ -37,18 +39,26 @@ struct ConstBufferKey { |
|
|
|
u32 value = 0; |
|
|
|
}; |
|
|
|
|
|
|
|
struct BoundSamplerKey { |
|
|
|
struct BoundSamplerEntry { |
|
|
|
u32 offset = 0; |
|
|
|
Tegra::Engines::SamplerDescriptor sampler; |
|
|
|
}; |
|
|
|
|
|
|
|
struct BindlessSamplerKey { |
|
|
|
struct SeparateSamplerEntry { |
|
|
|
u32 cbuf1 = 0; |
|
|
|
u32 cbuf2 = 0; |
|
|
|
u32 offset1 = 0; |
|
|
|
u32 offset2 = 0; |
|
|
|
Tegra::Engines::SamplerDescriptor sampler; |
|
|
|
}; |
|
|
|
|
|
|
|
struct BindlessSamplerEntry { |
|
|
|
u32 cbuf = 0; |
|
|
|
u32 offset = 0; |
|
|
|
Tegra::Engines::SamplerDescriptor sampler; |
|
|
|
}; |
|
|
|
|
|
|
|
constexpr u32 NativeVersion = 20; |
|
|
|
constexpr u32 NativeVersion = 21; |
|
|
|
|
|
|
|
ShaderCacheVersionHash GetShaderCacheVersionHash() { |
|
|
|
ShaderCacheVersionHash hash{}; |
|
|
|
@ -87,12 +97,14 @@ bool ShaderDiskCacheEntry::Load(FileUtil::IOFile& file) { |
|
|
|
u32 texture_handler_size_value; |
|
|
|
u32 num_keys; |
|
|
|
u32 num_bound_samplers; |
|
|
|
u32 num_separate_samplers; |
|
|
|
u32 num_bindless_samplers; |
|
|
|
if (file.ReadArray(&unique_identifier, 1) != 1 || file.ReadArray(&bound_buffer, 1) != 1 || |
|
|
|
file.ReadArray(&is_texture_handler_size_known, 1) != 1 || |
|
|
|
file.ReadArray(&texture_handler_size_value, 1) != 1 || |
|
|
|
file.ReadArray(&graphics_info, 1) != 1 || file.ReadArray(&compute_info, 1) != 1 || |
|
|
|
file.ReadArray(&num_keys, 1) != 1 || file.ReadArray(&num_bound_samplers, 1) != 1 || |
|
|
|
file.ReadArray(&num_separate_samplers, 1) != 1 || |
|
|
|
file.ReadArray(&num_bindless_samplers, 1) != 1) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
@ -101,23 +113,32 @@ bool ShaderDiskCacheEntry::Load(FileUtil::IOFile& file) { |
|
|
|
} |
|
|
|
|
|
|
|
std::vector<ConstBufferKey> flat_keys(num_keys); |
|
|
|
std::vector<BoundSamplerKey> flat_bound_samplers(num_bound_samplers); |
|
|
|
std::vector<BindlessSamplerKey> flat_bindless_samplers(num_bindless_samplers); |
|
|
|
std::vector<BoundSamplerEntry> flat_bound_samplers(num_bound_samplers); |
|
|
|
std::vector<SeparateSamplerEntry> flat_separate_samplers(num_separate_samplers); |
|
|
|
std::vector<BindlessSamplerEntry> flat_bindless_samplers(num_bindless_samplers); |
|
|
|
if (file.ReadArray(flat_keys.data(), flat_keys.size()) != flat_keys.size() || |
|
|
|
file.ReadArray(flat_bound_samplers.data(), flat_bound_samplers.size()) != |
|
|
|
flat_bound_samplers.size() || |
|
|
|
file.ReadArray(flat_separate_samplers.data(), flat_separate_samplers.size()) != |
|
|
|
flat_separate_samplers.size() || |
|
|
|
file.ReadArray(flat_bindless_samplers.data(), flat_bindless_samplers.size()) != |
|
|
|
flat_bindless_samplers.size()) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
for (const auto& key : flat_keys) { |
|
|
|
keys.insert({{key.cbuf, key.offset}, key.value}); |
|
|
|
for (const auto& entry : flat_keys) { |
|
|
|
keys.insert({{entry.cbuf, entry.offset}, entry.value}); |
|
|
|
} |
|
|
|
for (const auto& key : flat_bound_samplers) { |
|
|
|
bound_samplers.emplace(key.offset, key.sampler); |
|
|
|
for (const auto& entry : flat_bound_samplers) { |
|
|
|
bound_samplers.emplace(entry.offset, entry.sampler); |
|
|
|
} |
|
|
|
for (const auto& key : flat_bindless_samplers) { |
|
|
|
bindless_samplers.insert({{key.cbuf, key.offset}, key.sampler}); |
|
|
|
for (const auto& entry : flat_separate_samplers) { |
|
|
|
SeparateSamplerKey key; |
|
|
|
key.buffers = {entry.cbuf1, entry.cbuf2}; |
|
|
|
key.offsets = {entry.offset1, entry.offset2}; |
|
|
|
separate_samplers.emplace(key, entry.sampler); |
|
|
|
} |
|
|
|
for (const auto& entry : flat_bindless_samplers) { |
|
|
|
bindless_samplers.insert({{entry.cbuf, entry.offset}, entry.sampler}); |
|
|
|
} |
|
|
|
|
|
|
|
return true; |
|
|
|
@ -142,6 +163,7 @@ bool ShaderDiskCacheEntry::Save(FileUtil::IOFile& file) const { |
|
|
|
file.WriteObject(graphics_info) != 1 || file.WriteObject(compute_info) != 1 || |
|
|
|
file.WriteObject(static_cast<u32>(keys.size())) != 1 || |
|
|
|
file.WriteObject(static_cast<u32>(bound_samplers.size())) != 1 || |
|
|
|
file.WriteObject(static_cast<u32>(separate_samplers.size())) != 1 || |
|
|
|
file.WriteObject(static_cast<u32>(bindless_samplers.size())) != 1) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
@ -152,22 +174,34 @@ bool ShaderDiskCacheEntry::Save(FileUtil::IOFile& file) const { |
|
|
|
flat_keys.push_back(ConstBufferKey{address.first, address.second, value}); |
|
|
|
} |
|
|
|
|
|
|
|
std::vector<BoundSamplerKey> flat_bound_samplers; |
|
|
|
std::vector<BoundSamplerEntry> flat_bound_samplers; |
|
|
|
flat_bound_samplers.reserve(bound_samplers.size()); |
|
|
|
for (const auto& [address, sampler] : bound_samplers) { |
|
|
|
flat_bound_samplers.push_back(BoundSamplerKey{address, sampler}); |
|
|
|
flat_bound_samplers.push_back(BoundSamplerEntry{address, sampler}); |
|
|
|
} |
|
|
|
|
|
|
|
std::vector<SeparateSamplerEntry> flat_separate_samplers; |
|
|
|
flat_separate_samplers.reserve(separate_samplers.size()); |
|
|
|
for (const auto& [key, sampler] : separate_samplers) { |
|
|
|
SeparateSamplerEntry entry; |
|
|
|
std::tie(entry.cbuf1, entry.cbuf2) = key.buffers; |
|
|
|
std::tie(entry.offset1, entry.offset2) = key.offsets; |
|
|
|
entry.sampler = sampler; |
|
|
|
flat_separate_samplers.push_back(entry); |
|
|
|
} |
|
|
|
|
|
|
|
std::vector<BindlessSamplerKey> flat_bindless_samplers; |
|
|
|
std::vector<BindlessSamplerEntry> flat_bindless_samplers; |
|
|
|
flat_bindless_samplers.reserve(bindless_samplers.size()); |
|
|
|
for (const auto& [address, sampler] : bindless_samplers) { |
|
|
|
flat_bindless_samplers.push_back( |
|
|
|
BindlessSamplerKey{address.first, address.second, sampler}); |
|
|
|
BindlessSamplerEntry{address.first, address.second, sampler}); |
|
|
|
} |
|
|
|
|
|
|
|
return file.WriteArray(flat_keys.data(), flat_keys.size()) == flat_keys.size() && |
|
|
|
file.WriteArray(flat_bound_samplers.data(), flat_bound_samplers.size()) == |
|
|
|
flat_bound_samplers.size() && |
|
|
|
file.WriteArray(flat_separate_samplers.data(), flat_separate_samplers.size()) == |
|
|
|
flat_separate_samplers.size() && |
|
|
|
file.WriteArray(flat_bindless_samplers.data(), flat_bindless_samplers.size()) == |
|
|
|
flat_bindless_samplers.size(); |
|
|
|
} |
|
|
|
|