mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-11-02 12:56:05 +00:00
The per-draw capture of a shader's memory (the SRT walk and the guest pages it reads) cost about 15 us per draw packet in GTA V Performance mode; it now costs about 6.6. - The SRT evaluator memoizes per plan value in a thread's reused, stamped array instead of a hash table allocated and grown on every walk (evaluate 5.3 -> 3.6 us per capture). - ExtractPlan also stores the plan's values as 32-byte records with argument ids, and the walk evaluates that compact copy: the IR walk spent most of its time in cache misses (3.6 -> 2.7 us). The evaluator is a template over the node view, so both walks share every opcode's semantics, memo, cycle and failure rules. A plan that cannot be expressed compactly keeps the IR walk. APS5_VERIFY_SRT_COMPACT=1 walks both and throws on any difference. - ShaderMemory's valid/read/recent marks are arrays of 64-bit words scanned with countr_zero instead of bitsets tested bit by bit (about 1 us per draw packet). - Captured pages come from a per-thread pool, are found through a short vector with a last-page shortcut, and a page no recorded GPU work writes gets the flush hook a whole-page read would make, then has each 64-byte block copied when a word of it is first read (about 0.3 us per packet). Pages with pending GPU writes and unmapped pages are read as before. - APS5_PROFILE_DRAW splits the capture time into SRT evaluation and materialization, and prints the [capture] line once per 10 s instead of every 500 captures (it cost about 2 us per capture). Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Co-Authored-By: Gjon Gojcevic <[email protected]>
81 lines
3.1 KiB
C++
81 lines
3.1 KiB
C++
#ifndef CORE_SHADER_RECOMPILER_SHADERDISKCACHE_HPP
|
|
#define CORE_SHADER_RECOMPILER_SHADERDISKCACHE_HPP
|
|
|
|
#include "CompiledVariant.hpp"
|
|
#include "IntermediateRepresentation/IrMetadata/ResourcePlan.hpp"
|
|
#include <cstddef>
|
|
#include <cstdint>
|
|
#include <filesystem>
|
|
#include <memory>
|
|
#include <span>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
namespace ShaderRecompiler::ShaderDiskCache {
|
|
|
|
inline constexpr std::uint32_t FormatVersion = 36;
|
|
|
|
enum class LoadStatus {
|
|
Loaded,
|
|
Absent,
|
|
KeyMismatch,
|
|
Rejected,
|
|
};
|
|
|
|
struct Counters {
|
|
std::uint64_t hits = 0;
|
|
std::uint64_t misses = 0;
|
|
std::uint64_t writes = 0;
|
|
std::uint64_t loadFailures = 0;
|
|
std::uint64_t writeFailures = 0;
|
|
std::uint64_t bytesRead = 0;
|
|
std::uint64_t bytesWritten = 0;
|
|
std::uint64_t planHits = 0;
|
|
std::uint64_t planMisses = 0;
|
|
std::uint64_t planWrites = 0;
|
|
std::uint64_t planLoadFailures = 0;
|
|
std::uint64_t prebuiltHits = 0;
|
|
std::uint64_t prebuiltMisses = 0;
|
|
std::uint64_t prebuiltRejected = 0;
|
|
std::uint64_t lookupNanoseconds = 0;
|
|
std::uint64_t readNanoseconds = 0;
|
|
std::uint64_t decodeNanoseconds = 0;
|
|
std::uint64_t loadNanoseconds = 0;
|
|
std::uint64_t maxLoadNanoseconds = 0;
|
|
std::uint64_t prebuiltBytesRead = 0;
|
|
std::uint64_t prebuiltLoadNanoseconds = 0;
|
|
};
|
|
|
|
[[nodiscard]] std::uint64_t SourceVersion();
|
|
|
|
void BuildKey(const RecompileRequest& request, std::uint32_t hostSubgroupSize, std::vector<std::byte>& key);
|
|
|
|
[[nodiscard]] std::string EntryName(std::span<const std::byte> key);
|
|
|
|
void EncodeResult(const RecompileResult& result, std::vector<std::byte>& out);
|
|
[[nodiscard]] bool DecodeResult(std::span<const std::byte> bytes, RecompileResult& result);
|
|
|
|
[[nodiscard]] std::vector<std::byte> EncodeEntry(std::span<const std::byte> key, const CompiledVariant& variant);
|
|
[[nodiscard]] LoadStatus DecodeEntry(std::span<const std::byte> file, std::span<const std::byte> key, CompiledVariant& variant, std::shared_ptr<const void> owner = nullptr);
|
|
|
|
void BuildPlanKey(const RecompileRequest& request, std::uint32_t hostSubgroupSize, std::vector<std::byte>& key);
|
|
[[nodiscard]] bool EncodePlan(const IrResourcePlan& plan, std::vector<std::byte>& out);
|
|
[[nodiscard]] bool DecodePlan(std::span<const std::byte> bytes, IrResourcePlan& plan);
|
|
[[nodiscard]] std::vector<std::byte> EncodePlanEntry(std::span<const std::byte> key, const IrResourcePlan& plan);
|
|
[[nodiscard]] LoadStatus DecodePlanEntry(std::span<const std::byte> file, std::span<const std::byte> key, IrResourcePlan& plan);
|
|
|
|
[[nodiscard]] bool Enabled();
|
|
[[nodiscard]] std::filesystem::path EntryDirectory();
|
|
|
|
[[nodiscard]] bool Load(std::span<const std::byte> key, CompiledVariant& variant);
|
|
void Store(std::vector<std::byte> key, std::shared_ptr<const CompiledVariant> variant);
|
|
[[nodiscard]] std::shared_ptr<const CompiledVariant> Persist(std::span<const std::byte> key, const CompiledVariant& variant);
|
|
[[nodiscard]] bool LoadPlan(std::span<const std::byte> key, IrResourcePlan& plan);
|
|
void StorePlan(std::vector<std::byte> key, std::shared_ptr<const IrResourcePlan> plan);
|
|
void Flush();
|
|
[[nodiscard]] Counters Totals();
|
|
|
|
}
|
|
|
|
#endif
|