Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ class Driver {
void dispatch(QueueState& queue, std::span<const std::uint32_t> packet, const Submission& submission, std::uint64_t indirectArguments = 0);
void verifyDataHit(const ShaderSnapshot& snapshot, std::size_t codeOffset, ShaderRecompiler::RecompileRequest request, std::span<const ShaderRecompiler::MemoryRegion> memory, std::uint64_t address, const DispatchVariant& variant, std::span<const std::uint32_t> liveWords, const ShaderRecompiler::RecompileResult& patched);
static bool drawEntries();
bool drawCacheBypassed();
void noteDrawCacheOutcome(bool hit);
static bool verifyDrawEntries();
static bool registerKeyEnabled();
static bool verifyDrawRecipe();
Expand Down Expand Up @@ -309,6 +311,8 @@ class Driver {
std::unordered_map<std::uint64_t, std::shared_ptr<DrawEntry>> drawCache;
std::list<std::uint64_t> drawOrder;
std::mutex drawCacheMutex;
std::atomic<std::uint32_t> drawCacheProbeLookups{0}, drawCacheProbeHits{0}, drawCacheBypassLeft{0};
std::atomic<std::uint64_t> drawCacheBypassedDraws{0};
std::uint64_t drawCacheHits = 0, drawCacheEvictions = 0, drawCacheVariants = 0, drawCacheVariantBytes = 0;

DrawEntryCounters drawEntryCounters;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ DrawVerdict Driver::draw(QueueState& queue, std::span<const std::uint32_t> packe
timing.Mark("device_setup");
phaseTiming.Phase(DrawRowVectors);

const bool useDrawEntries = drawEntries() && !ShaderRecompiler::DebugProbeActive() && dumpTarget == 0 && dumpSlot1 == 0;
const bool useDrawEntries = drawEntries() && !drawCacheBypassed() && !ShaderRecompiler::DebugProbeActive() && dumpTarget == 0 && dumpSlot1 == 0;
const bool registerKey = useDrawEntries && registerKeyEnabled();
std::uint64_t drawKey = 0;
std::shared_ptr<DrawEntry> entry;
Expand Down Expand Up @@ -170,6 +170,7 @@ DrawVerdict Driver::draw(QueueState& queue, std::span<const std::uint32_t> packe
bool drawHit = false;
bool verifyHit = false;
lookupDraw(submission, localDevice, graphics, pixel, programs, roles, vertexInfos, useDrawEntries, registerKey, profile, drawKey, entry, matched, matchedRegions, drawHit, verifyHit, phaseTiming, phaseMs);
if (useDrawEntries) noteDrawCacheOutcome(drawHit);

if (registerKey) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,30 @@
return entries;
}

bool Driver::drawCacheBypassed() {
static const bool adaptive = std::getenv("APS5_NO_DRAW_CACHE_BYPASS") == nullptr;

Check failure on line 26 in core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawCache.cpp

View workflow job for this annotation

GitHub Actions / conventions

env-reference

Every APS5_* or ANYPS5_* name a pull request adds to the code has a row in docs/dev/ENVIRONMENT.md, a row whose name the pull request stops reading is removed, and a row the pull request removes is no longer read: APS5_NO_DRAW_CACHE_BYPASS is read here but has no row in docs/dev/ENVIRONMENT.md

Check failure on line 26 in core/libs/prx/libSceAgcDriver/Execution/src/Driver/Draw/DrawCache.cpp

View workflow job for this annotation

GitHub Actions / conventions

env-reference

Every APS5_* or ANYPS5_* name a pull request adds to the code has a row in docs/dev/ENVIRONMENT.md, a row whose name the pull request stops reading is removed, and a row the pull request removes is no longer read: APS5_NO_DRAW_CACHE_BYPASS is read here but has no row in docs/dev/ENVIRONMENT.md
if (!adaptive) return false;
auto left = drawCacheBypassLeft.load(std::memory_order_relaxed);
while (left != 0) {
if (drawCacheBypassLeft.compare_exchange_weak(left, left - 1, std::memory_order_relaxed)) {
drawCacheBypassedDraws.fetch_add(1, std::memory_order_relaxed);
return true;
}
}
return false;
}

void Driver::noteDrawCacheOutcome(bool hit) {
constexpr std::uint32_t Window = 2048;
constexpr std::uint32_t MinHitsPerWindow = Window / 20;
constexpr std::uint32_t BypassDraws = 16384;
if (hit) drawCacheProbeHits.fetch_add(1, std::memory_order_relaxed);
if (drawCacheProbeLookups.fetch_add(1, std::memory_order_relaxed) + 1 < Window) return;
const auto hits = drawCacheProbeHits.exchange(0, std::memory_order_relaxed);
drawCacheProbeLookups.store(0, std::memory_order_relaxed);
if (hits < MinHitsPerWindow) drawCacheBypassLeft.store(BypassDraws, std::memory_order_relaxed);
}

bool Driver::verifyDrawEntries() {
static const bool verify = std::getenv("APS5_VERIFY_DRAW_ENTRIES") != nullptr;
return verify;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ void Driver::reportDrawCache(DrawEntryCounters& counters) {
}
AgcDriver::ProfilePrint_nid_no_patch( "[draw-cache] %llu lookups (10 s): %llu no entry, %llu validated in %.1f us each (key, lookup and every stage): %llu hits (every stage equal; stage hits by variant rank 1..k %s), misses by reason: front stage differing %llu, fragment differing %llu, other stage differing %llu, layout (push offset) %llu, gate %llu, stage count %llu; %llu stage validations (%llu equal, %.2f variants compared each); %llu inserts (%llu variants inserted, %llu evicted beyond k, %llu already present, %llu unstable), %zu entries (%llu variants, ~%.1f MiB), %llu evictions in total, %llu LRU moves; verify: %llu hits captured again, %llu stages differed\n", count(counters.lookups), count(counters.absent), count(validated), validated != 0 ? counters.validateUs / static_cast<double>(validated) : 0.0, count(counters.hits), ranks.c_str(), miss(DrawMiss::FrontDiffering), miss(DrawMiss::FragmentDiffering), miss(DrawMiss::OtherDiffering), miss(DrawMiss::Layout), miss(DrawMiss::Gate), miss(DrawMiss::Stages), count(counters.stageValidations), count(counters.stageEqual), counters.stageValidations != 0 ? static_cast<double>(counters.variantsCompared) / static_cast<double>(counters.stageValidations) : 0.0, count(counters.inserts), count(counters.variantsInserted), count(counters.variantsEvicted), count(counters.present), count(counters.unstable), drawCache.size(), count(drawCacheVariants), static_cast<double>(drawCacheVariantBytes) / (1024.0 * 1024.0), count(drawCacheEvictions), count(counters.touches), count(counters.verifyHits), count(counters.verifyMismatches));
AgcDriver::ProfilePrint_nid_no_patch( "[draw-cache] register key (10 s): %llu lookups, %llu hits, key build %.1f us each; decode skipped %llu, partial (state/pixel/programs from the entry) %llu; facade log != table %llu; verify: %llu decodes compared, %llu differed\n", count(counters.registerKeyLookups), count(counters.registerKeyHits), counters.registerKeyLookups != 0 ? counters.keyUs / static_cast<double>(counters.registerKeyLookups) : 0.0, count(counters.decodeSkipped), count(counters.decodePartial), count(counters.facadeMismatches), count(counters.verifyDecodes), count(counters.verifyDecodeMismatches));
const auto bypassed = drawCacheBypassedDraws.exchange(0, std::memory_order_relaxed);
if (bypassed != 0) AgcDriver::ProfilePrint_nid_no_patch("[draw-cache] bypassed %llu draws (10 s): the hit rate stayed under 5%%, entries are neither looked up nor inserted\n", count(bypassed));
counters = DrawEntryCounters{};
}

Expand Down
Loading