vk_pipeline_cache: Fix pipeline and shader caches

This commit is contained in:
ReinUsesLisp 2021-03-27 02:56:09 -03:00 committed by ameerj
parent f0031babeb
commit cb6039ccea
2 changed files with 21 additions and 6 deletions

View file

@ -62,7 +62,7 @@ public:
~GenericEnvironment() override = default; ~GenericEnvironment() override = default;
std::optional<u128> Analyze() { std::optional<u128> Analyze() {
const std::optional<u64> size{TryFindSize(start_address)}; const std::optional<u64> size{TryFindSize()};
if (!size) { if (!size) {
return std::nullopt; return std::nullopt;
} }
@ -71,6 +71,13 @@ public:
return Common::CityHash128(reinterpret_cast<const char*>(code.data()), code.size()); return Common::CityHash128(reinterpret_cast<const char*>(code.data()), code.size());
} }
void SetCachedSize(size_t size_bytes) {
cached_lowest = start_address;
cached_highest = start_address + static_cast<u32>(size_bytes);
code.resize(CachedSize());
gpu_memory->ReadBlock(program_base + cached_lowest, code.data(), code.size() * sizeof(u64));
}
[[nodiscard]] size_t CachedSize() const noexcept { [[nodiscard]] size_t CachedSize() const noexcept {
return cached_highest - cached_lowest + INST_SIZE; return cached_highest - cached_lowest + INST_SIZE;
} }
@ -80,7 +87,7 @@ public:
} }
[[nodiscard]] bool CanBeSerialized() const noexcept { [[nodiscard]] bool CanBeSerialized() const noexcept {
return has_unbound_instructions; return !has_unbound_instructions;
} }
[[nodiscard]] u128 CalculateHash() const { [[nodiscard]] u128 CalculateHash() const {
@ -95,7 +102,7 @@ public:
read_highest = std::max(read_highest, address); read_highest = std::max(read_highest, address);
if (address >= cached_lowest && address < cached_highest) { if (address >= cached_lowest && address < cached_highest) {
return code[address / INST_SIZE]; return code[(address - cached_lowest) / INST_SIZE];
} }
has_unbound_instructions = true; has_unbound_instructions = true;
return gpu_memory->Read<u64>(program_base + address); return gpu_memory->Read<u64>(program_base + address);
@ -117,30 +124,34 @@ public:
.write(reinterpret_cast<const char*>(&read_highest), sizeof(read_highest)) .write(reinterpret_cast<const char*>(&read_highest), sizeof(read_highest))
.write(reinterpret_cast<const char*>(&stage), sizeof(stage)) .write(reinterpret_cast<const char*>(&stage), sizeof(stage))
.write(data.get(), code_size); .write(data.get(), code_size);
file.flush();
for (const auto [key, type] : texture_types) { for (const auto [key, type] : texture_types) {
file.write(reinterpret_cast<const char*>(&key), sizeof(key)) file.write(reinterpret_cast<const char*>(&key), sizeof(key))
.write(reinterpret_cast<const char*>(&type), sizeof(type)); .write(reinterpret_cast<const char*>(&type), sizeof(type));
} }
file.flush();
if (stage == Shader::Stage::Compute) { if (stage == Shader::Stage::Compute) {
const std::array<u32, 3> workgroup_size{WorkgroupSize()}; const std::array<u32, 3> workgroup_size{WorkgroupSize()};
file.write(reinterpret_cast<const char*>(&workgroup_size), sizeof(workgroup_size)); file.write(reinterpret_cast<const char*>(&workgroup_size), sizeof(workgroup_size));
} else { } else {
file.write(reinterpret_cast<const char*>(&sph), sizeof(sph)); file.write(reinterpret_cast<const char*>(&sph), sizeof(sph));
} }
file.flush();
} }
protected: protected:
static constexpr size_t INST_SIZE = sizeof(u64); static constexpr size_t INST_SIZE = sizeof(u64);
std::optional<u64> TryFindSize(GPUVAddr guest_addr) { std::optional<u64> TryFindSize() {
constexpr size_t BLOCK_SIZE = 0x1000; constexpr size_t BLOCK_SIZE = 0x1000;
constexpr size_t MAXIMUM_SIZE = 0x100000; constexpr size_t MAXIMUM_SIZE = 0x100000;
constexpr u64 SELF_BRANCH_A = 0xE2400FFFFF87000FULL; constexpr u64 SELF_BRANCH_A = 0xE2400FFFFF87000FULL;
constexpr u64 SELF_BRANCH_B = 0xE2400FFFFF07000FULL; constexpr u64 SELF_BRANCH_B = 0xE2400FFFFF07000FULL;
size_t offset = 0; GPUVAddr guest_addr{program_base + start_address};
size_t size = BLOCK_SIZE; size_t offset{0};
size_t size{BLOCK_SIZE};
while (size <= MAXIMUM_SIZE) { while (size <= MAXIMUM_SIZE) {
code.resize(size / INST_SIZE); code.resize(size / INST_SIZE);
u64* const data = code.data() + offset / INST_SIZE; u64* const data = code.data() + offset / INST_SIZE;
@ -623,6 +634,7 @@ bool PipelineCache::RefreshStages() {
GraphicsEnvironment env{maxwell3d, gpu_memory, program, base_addr, start_address}; GraphicsEnvironment env{maxwell3d, gpu_memory, program, base_addr, start_address};
shader_info = MakeShaderInfo(env, *cpu_shader_addr); shader_info = MakeShaderInfo(env, *cpu_shader_addr);
} }
shader_infos[index] = shader_info;
graphics_key.unique_hashes[index] = shader_info->unique_hash; graphics_key.unique_hashes[index] = shader_info->unique_hash;
} }
return true; return true;
@ -707,6 +719,8 @@ GraphicsPipeline PipelineCache::CreateGraphicsPipeline() {
GraphicsEnvironment& env{graphics_envs[index]}; GraphicsEnvironment& env{graphics_envs[index]};
const u32 start_address{maxwell3d.regs.shader_config[index].offset}; const u32 start_address{maxwell3d.regs.shader_config[index].offset};
env = GraphicsEnvironment{maxwell3d, gpu_memory, program, base_addr, start_address}; env = GraphicsEnvironment{maxwell3d, gpu_memory, program, base_addr, start_address};
env.SetCachedSize(shader_infos[index]->size_bytes);
generic_envs.push_back(&env); generic_envs.push_back(&env);
envs.push_back(&env); envs.push_back(&env);
} }

View file

@ -172,6 +172,7 @@ private:
TextureCache& texture_cache; TextureCache& texture_cache;
GraphicsPipelineCacheKey graphics_key{}; GraphicsPipelineCacheKey graphics_key{};
std::array<const ShaderInfo*, 6> shader_infos{};
std::unordered_map<ComputePipelineCacheKey, ComputePipeline> compute_cache; std::unordered_map<ComputePipelineCacheKey, ComputePipeline> compute_cache;
std::unordered_map<GraphicsPipelineCacheKey, GraphicsPipeline> graphics_cache; std::unordered_map<GraphicsPipelineCacheKey, GraphicsPipeline> graphics_cache;