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 @@ -3544,10 +3544,7 @@ bool ImportMappedRanges(const Context& context, const GuestAllocations::Mapped&
const std::array<std::pair<std::uint64_t, std::uint64_t>, 1> span{{{run.base, run.base + run.bytes}}};
if (wouldRetireImport(state, run) || StorageTexture::AnyPendingOverlaps(span)) return false;
}
if (importAllocation(context, state, range->address, current, ImportRequester::Map, 0, false) == nullptr && GuestAllocations::GuestAllocationsGeneration_nid_postfix() != generation) {
state.failed.erase(importRun(current, range->address, std::numeric_limits<std::uint64_t>::max(), effectiveBudget(context, state)).base);
state.failed.erase(range->address);
}
importAllocation(context, state, range->address, current, ImportRequester::Map, 0, false);
} catch (const std::exception& error) {
std::fprintf(stderr, "[gpu] import of GPU memory mapped at 0x%llx+0x%zx failed: %s\n", static_cast<unsigned long long>(range->address), range->bytes, error.what());
}
Expand Down
46 changes: 46 additions & 0 deletions core/libs/prx/libSceAgcDriver/tests/BdaResources.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -761,6 +761,8 @@ class ImportAllocationProbe {
ImportAllocationProbe& operator=(const ImportAllocationProbe&) = delete;

std::vector<ObservedHostImport> calls;
VkResult failure = VK_SUCCESS;
std::function<void()> onImport;

private:
static PFN_vkVoidFunction VKAPI_CALL Resolve(VkDevice device, const char* name) {
Expand All @@ -774,6 +776,11 @@ class ImportAllocationProbe {
if (next->sType != VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT) continue;
const auto* imported = reinterpret_cast<const VkImportMemoryHostPointerInfoEXT*>(next);
active->calls.push_back({imported->pHostPointer, info->allocationSize});
if (active->onImport) {
auto callback = std::move(active->onImport);
callback();
}
if (active->failure != VK_SUCCESS) return active->failure;
}
const auto allocate = reinterpret_cast<PFN_vkAllocateMemory>(active->original(device, "vkAllocateMemory"));
Require(allocate != nullptr, "import allocation probe has no original allocator");
Expand All @@ -800,6 +807,44 @@ class UnrelatedImportProbeRange {
std::array<std::byte, 64> storage{};
};

void importMappedFailureGenerationTests(const Context& context) {
ClearHostImports(context.device);
WindowedRange range(context, WindowedRange::piece, 1);
ImportAllocationProbe probe(range.importing);
probe.failure = VK_ERROR_INVALID_EXTERNAL_HANDLE;
GuestAllocations::Mapped mapped;
const auto collect = [&] {
mapped.clear();
const auto lease = GuestAllocations::GuestAllocationsAcquire_nid_postfix();
for (const auto& owner : lease) if (owner->address == range.First()) mapped.push_back(owner);
Require(mapped.size() == 1u, "the map failure fixture lost its registered range");
};
collect();
std::unique_ptr<UnrelatedImportProbeRange> unrelated;
probe.onImport = [&] { unrelated = std::make_unique<UnrelatedImportProbeRange>(); };
const auto generation = GuestAllocations::GuestAllocationsGeneration_nid_postfix();
{
std::lock_guard gpu(AgcDriver::GuestMemory::GpuMutex());
Require(ImportMappedRanges(range.importing, mapped, generation, true), "the first failed map import was deferred");
Require(probe.calls.size() == 1u && unrelated != nullptr, "the map failure fixture did not mutate an unrelated range during allocation");
Require(GuestAllocations::GuestAllocationsGeneration_nid_postfix() != generation, "the concurrent unrelated mapping did not advance the registry");
Require(ImportMappedRanges(range.importing, mapped, GuestAllocations::GuestAllocationsGeneration_nid_postfix(), true), "the repeated failed map import was deferred");
Require(probe.calls.size() == 1u, "an unrelated mapping during a failed import discarded its owner failure memo");
}
{
GuestAllocations::Mutation mutation;
mutation.Remove(reinterpret_cast<void*>(range.First()));
mutation.Add(reinterpret_cast<void*>(range.First()), range.bytes, true, false, true);
}
collect();
{
std::lock_guard gpu(AgcDriver::GuestMemory::GpuMutex());
Require(ImportMappedRanges(range.importing, mapped, GuestAllocations::GuestAllocationsGeneration_nid_postfix(), true), "the replacement owner map import was deferred");
Require(probe.calls.size() == 2u, "a replacement owner did not retry its predecessor's failed import");
}
ClearHostImports(context.device);
}

void importStaleProbeTests(const Context& context, const BdaTestAccess& access) {
for (const auto scenario : {0u, 1u, 2u}) {
const bool held = scenario == 1u;
Expand Down Expand Up @@ -3362,6 +3407,7 @@ void RunBdaResourceTests(const Context& context, const BdaTestAccess& access) {
importCoverageHintBudgetTests(context, access);
failedImportJoinProbeBudgetTests(context, access);
importWholeRangeOverWindowTests(context);
importMappedFailureGenerationTests(context);
importStaleProbeTests(context, access);
importRefusedWholeRangeTests(context);
importNeighbouringEdgesTests(context);
Expand Down
Loading