Skip to content
Merged
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 @@ -82,6 +82,8 @@ struct DataMask {

enum class EntryOutcome { Equal, EqualData, Differing, Inaccessible, QueuedLabel, FlushingImage, PublishMoved, PendingMoved, ForgetMoved };

bool CacheableResult(const ShaderRecompiler::RecompileResult& compiled);

}

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ class ShaderMemory {
};

static bool read(void* context, std::uint64_t address, std::uint32_t* value);
static bool accessible(void* context, std::uint64_t address, std::uint64_t bytes);
Page& page(std::uint64_t base);

// Regions given at construction (the registered shader's code and header), referenced as given:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ void Driver::dispatch(QueueState& queue, std::span<const std::uint32_t> packet,
}
recompileMs += phaseTiming.Elapsed();
phaseTiming.Phase(PhaseRecompile);
insertDispatch(address, key, noDispatchCache, profile, registeredShader, forgetAtCapture, memory, shaderMemory, captured, capture, compiledResult, missedEntry, missedDiffering, attachVariant, phaseTiming);
insertDispatch(address, key, noDispatchCache || !CacheableResult(*compiledResult), profile, registeredShader, forgetAtCapture, memory, shaderMemory, captured, capture, compiledResult, missedEntry, missedDiffering, attachVariant, phaseTiming);
}
if (verifyDataHits() && dataHit) verifyDataHit(snapshot, codeOffset, request, memory, address, *keepVariant, liveWords, *compiledResult);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@

namespace AgcDriver::DriverDetail {

bool CacheableResult(const ShaderRecompiler::RecompileResult& compiled) {
return compiled.poisonedSrtReads == 0u;
}

void Driver::insertDispatch(std::uint64_t address, std::uint64_t key, bool noDispatchCache, bool profile, const std::shared_ptr<const ShaderSnapshot>& registeredShader, std::uint64_t forgetAtCapture, std::span<const ShaderRecompiler::MemoryRegion> memory, const std::shared_ptr<ShaderMemory>& shaderMemory, const std::vector<ShaderRecompiler::MemoryRegion>& captured, const std::shared_ptr<const ShaderRecompiler::ResourceCapture>& capture, const std::shared_ptr<const ShaderRecompiler::RecompileResult>& compiledResult, const std::shared_ptr<DispatchEntry>& missedEntry, bool missedDiffering, std::shared_ptr<DispatchVariant>& attachVariant, DispatchPhaseTiming& phaseTiming) {
if (!noDispatchCache) {
auto fresh = std::make_shared<DispatchVariant>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ void Driver::cacheDrawStages(bool useDrawEntries, bool drawHit, const Pm4::DrawP
std::uint64_t unstable = 0, mismatches = 0;
for (std::size_t i = 0; i < programs.size(); ++i) {
const auto& stageCapture = stageCaptures[i];
if (stageCapture.compiled == nullptr) continue;
if (stageCapture.compiled == nullptr || !CacheableResult(*stageCapture.compiled)) continue;
auto variant = std::make_shared<DispatchVariant>();
variant->compiled = stageCapture.compiled;
variant->shader = programs[i].snapshot;
Expand Down
23 changes: 23 additions & 0 deletions core/libs/prx/libSceAgcDriver/Execution/src/ShaderMemory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,28 @@ bool ShaderMemory::read(void* context, std::uint64_t address, std::uint32_t* val
return true;
}

bool ShaderMemory::accessible(void* context, std::uint64_t address, std::uint64_t bytes) {
auto& self = *static_cast<ShaderMemory*>(context);
if (bytes == 0 || address > std::numeric_limits<std::uint64_t>::max() - bytes) return false;
const auto end = address + bytes;
while (address < end) {
const auto next = self.initial.upper_bound(address);
if (next != self.initial.begin()) {
const auto previous = std::prev(next);
if (address - previous->first < previous->second.size()) {
address = previous->first + previous->second.size();
continue;
}
}
const auto base = address & ~static_cast<std::uint64_t>(PageBytes - 1);
const auto pageEnd = std::min<std::uint64_t>(base + PageBytes, end);
const auto& page = self.page(base);
if (!page.wordwise && !page.valid.all() && !GuestMemory::Accessible(reinterpret_cast<const void*>(address), static_cast<std::size_t>(pageEnd - address))) return false;
address = pageEnd;
}
return true;
}

ShaderMemory::KnownValueCounts ShaderMemory::KnownValues() {
auto& totals = CaptureTotals();
return {totals.wordsKnown.load(std::memory_order_relaxed), totals.wordsKnownVerified.load(std::memory_order_relaxed), totals.wordsKnownMismatches.load(std::memory_order_relaxed)};
Expand Down Expand Up @@ -233,6 +255,7 @@ std::shared_ptr<const ShaderRecompiler::ResourceCapture> ShaderMemory::capture(c
runtime.userContext = this;
runtime.readMemory = &read;
runtime.readSpecializationMemory = &read;
runtime.accessible = &accessible;
auto capture = invocation != nullptr ? invocation->Capture(runtime) : handle != nullptr ? ShaderRecompiler::CaptureResources(request, runtime, *handle) : ShaderRecompiler::CaptureResources(request, runtime);
if (profile) {
totals.captureNanoseconds += NanosecondsSince(started);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ void ShaderResources::prepareAddressBindings(std::span<const CompiledShader> sha
if (binding.role == ShaderRecompiler::DescriptorRole::BdaPagetable) ++tables;
else ++faults;
}
const bool rectListFault = shader.stage == ShaderRecompiler::ShaderStage::TessellationControl && tables == 0 && faults == 1;
Require((tables == faults || rectListFault) && tables <= 1 && faults <= 1, "invalid BDA table and fault descriptors");
const bool faultOnly = tables == 0 && faults == 1 && shader.program->bdaAbiVersion == ShaderRecompiler::BdaAbi::Version;
Require((tables == faults || faultOnly) && tables <= 1 && faults <= 1, "invalid BDA table and fault descriptors");
Require(shader.program->bdaAbiVersion == (faults == 0 ? 0u : ShaderRecompiler::BdaAbi::Version), "incompatible BDA ABI version");
// Rect-list validation needs a fault buffer, but never accesses guest addresses.
usesBda = usesBda || tables != 0;
Expand Down
3 changes: 3 additions & 0 deletions core/libs/prx/libSceAgcDriver/tests/ShaderDiskCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ void requireSameResult(const RecompileResult& left, const RecompileResult& right
require(sameBindings(left.bindings, right.bindings), prefix + "bindings differ");
require(left.pushConstants == right.pushConstants, prefix + "push constants differ");
require(left.specialization == right.specialization, prefix + "specialization constants differ");
require(left.poisonedSrtReads == right.poisonedSrtReads, prefix + "poisoned SRT read counts differ");
require(left.vertexAttributes.size() == right.vertexAttributes.size(), prefix + "vertex attribute count differs");
for (std::size_t i = 0; i < left.vertexAttributes.size(); ++i) {
const auto& a = left.vertexAttributes[i];
Expand Down Expand Up @@ -149,6 +150,7 @@ RecompileResult sampleResult() {
result.instanceOffsetConflict = true;
result.parameterExports = {0, 3, 7};
result.fragmentParameters = {{0, 1, true, false, true}, {2, 3, false, true}};
result.poisonedSrtReads = 3;
result.variantId = 99;
return result;
}
Expand Down Expand Up @@ -220,6 +222,7 @@ CompiledVariant sampleVariant() {
info.info.vertexOffsetSgpr = 6;
info.info.hasBitwiseXor = true;
info.info.usesDma = true;
info.info.usesFaultBuffer = true;
info.bindings.pushDataStartDword = 2;
info.bindings.memoryOffsetDword = 1;
info.bindings.memoryOffsetCount = 5;
Expand Down
Loading
Loading