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
4 changes: 3 additions & 1 deletion core/libs/prx/libSceAgcDriver/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -732,8 +732,10 @@ if(BUILD_TESTING)
endif()
add_test(NAME agc_host_import_unmap COMMAND agc_driver_recorder_tests --host-import-unmap-only)
set_tests_properties(agc_host_import_unmap PROPERTIES SKIP_RETURN_CODE 77)
add_test(NAME agc_unit_shadow COMMAND agc_driver_recorder_tests --unit-shadow-only)
set_tests_properties(agc_unit_shadow PROPERTIES SKIP_RETURN_CODE 77 TIMEOUT 30 ENVIRONMENT "APS5_PIN_WAIT_MS=3000")
if(WIN32)
set_tests_properties(agc_host_import_unmap PROPERTIES ENVIRONMENT_MODIFICATION
set_tests_properties(agc_host_import_unmap agc_unit_shadow PROPERTIES ENVIRONMENT_MODIFICATION
"PATH=path_list_prepend:$<TARGET_FILE_DIR:libc>")
endif()
endif()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ class Recorder {
void Keep(std::shared_ptr<void> object, std::size_t bytes = 0);
void KeepBytes(const void* owner, std::size_t bytes);
std::size_t OpenKeptBytes() const { return open != nullptr ? open->keptBytes : 0; }
void FlushDeferredReleases();
static constexpr std::size_t KeptBytesBudget = std::size_t{512} << 20u;
void BoundKeptBytes();
std::size_t InFlightKeptBytes() const { return inFlightKeptBytes; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1283,6 +1283,7 @@ bool WaitForLeasesAndImports(std::uintptr_t address, std::size_t bytes) noexcept
synced = true;
drained = true;
}
if (recorder != nullptr) recorder->FlushDeferredReleases();
const auto end = static_cast<std::uint64_t>(address) + bytes;
auto& imports = Imports();
const auto lease = GuestAllocations::GuestAllocationsAcquire_nid_postfix();
Expand All @@ -1306,6 +1307,7 @@ bool WaitForLeasesAndImports(std::uintptr_t address, std::size_t bytes) noexcept
synced = true;
drained = true;
}
if (retiredImport && recorder != nullptr) recorder->FlushDeferredReleases();
} catch (const std::exception& error) {
std::fprintf(stderr, "[gpu] lease wait failed: %s\n", error.what());
}
Expand Down
4 changes: 4 additions & 0 deletions core/libs/prx/libSceAgcDriver/Graphics/src/Recorder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3227,6 +3227,10 @@ void Recorder::Sync() {
activeSyncSite = previousSite;
}

void Recorder::FlushDeferredReleases() {
ReleaseDeferredKeeps();
}

void Recorder::SyncThrough(std::uint64_t address, std::size_t bytes, bool waitUnlocked) {
if (bytes == 0) return;
const auto end = address + bytes;
Expand Down
17 changes: 10 additions & 7 deletions core/libs/prx/libSceAgcDriver/tests/Recorder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2009,10 +2009,6 @@ void unitShadowTests(const Device& device, Recorder& recorder) {
retile(*high, unit128, unit, 0x77, false);
Require(AnyShadowedOverlaps(unit128, unit), "the second slab's unit is not shadowed");
high.reset();
// Retire through the registry: the block is re-registered as its first five units, so the next
// lookup reconciles and retires the import; the fresh units still inside a registered range
// are published into its (kept) buffer, the rest (memory the title took back) are dropped.
// Under the one-slab budget unit 5's slab evicts the second one first (unit 128 published).
retile(*ShadowDestinationFor(context, *import, unit5, unit5 + unit), unit5, unit, 0x88, false);
retile(*ShadowDestinationFor(context, *import, address + 2 * unit, unit3), address + 2 * unit, unit, 0x99, false);
Require(AnyShadowedOverlaps(unit5, unit) && AnyShadowedOverlaps(address + 2 * unit, unit), "units 2 and 5 are not shadowed before the retire");
Expand All @@ -2025,9 +2021,8 @@ void unitShadowTests(const Device& device, Recorder& recorder) {
Require(!AnyShadowedOverlaps(address, bytes), "the retired import's shadow survived");
recorder.Sync();
Require(words[2 * unit] == 0x99 && words[3 * unit - 1] == 0x99, "the retire did not publish the unit still registered");
Require(words[5 * unit] == 0x11 && words[5 * unit + unit - 1] == 0x11, "the retire published a unit whose memory is no longer registered");
if (budgetMiB >= 16) Require(words[127 * unit] == 0x11 && words[128 * unit] == 0x11, "the retire published the second slab's units outside the registration");
else Require(words[128 * unit] == 0x77, "the eviction before the retire did not publish unit 128");
Require(words[5 * unit] == 0x88 && words[5 * unit + unit - 1] == 0x88, "the retire did not publish a unit covered by the old registration");
Require(words[127 * unit] == 0x66 && words[128 * unit] == 0x77, "the retire did not publish the second slab's units covered by the old registration");
}

void storageRefreshTests(const Device& device, Recorder& recorder, bool watched) {
Expand Down Expand Up @@ -4656,6 +4651,14 @@ int main(int argc, char** argv) {
hostImportUnmapTests(device, recorder);
return 0;
}
if (argc == 2 && std::string_view(argv[1]) == "--unit-shadow-only") {
if (!AgcDriver::Graphics::UnitShadowEnabled() || device.GetContext().hostImportAlignment == 0) {
std::cout << "skipped, unit shadows or host imports are unavailable\n";
return 77;
}
unitShadowTests(device, recorder);
return 0;
}
readTrackingTests(device, recorder);
writeSettledTests(device, recorder);
completionCountTests(device, recorder);
Expand Down
Loading