Split large allocations on Windows due to Wddm limitation

Resolves: NEO-4479

Change-Id: Iffb862a93570a60c2126620d9e5106359acba64a
Signed-off-by: Igor Venevtsev <igor.venevtsev@intel.com>
This commit is contained in:
Igor Venevtsev
2020-04-21 13:16:45 +02:00
committed by sys_ocldev
parent af2fe237b4
commit 3859e13322
27 changed files with 312 additions and 76 deletions

View File

@@ -27,19 +27,35 @@ constexpr size_t trimListUnusedPosition = std::numeric_limits<size_t>::max();
class WddmAllocation : public GraphicsAllocation {
public:
WddmAllocation(uint32_t rootDeviceIndex, AllocationType allocationType, void *cpuPtrIn, size_t sizeIn, void *reservedAddr, MemoryPool::Type pool)
: GraphicsAllocation(rootDeviceIndex, allocationType, cpuPtrIn, castToUint64(cpuPtrIn), 0llu, sizeIn, pool), trimCandidateListPositions(MemoryManager::maxOsContextCount, trimListUnusedPosition) {
: WddmAllocation(rootDeviceIndex, 1, allocationType, cpuPtrIn, sizeIn, reservedAddr, pool) {}
WddmAllocation(uint32_t rootDeviceIndex, size_t numGmms, AllocationType allocationType, void *cpuPtrIn, size_t sizeIn,
void *reservedAddr, MemoryPool::Type pool)
: GraphicsAllocation(rootDeviceIndex, numGmms, allocationType, cpuPtrIn, castToUint64(cpuPtrIn), 0llu, sizeIn, pool), trimCandidateListPositions(MemoryManager::maxOsContextCount, trimListUnusedPosition) {
reservedAddressRangeInfo.addressPtr = reservedAddr;
reservedAddressRangeInfo.rangeSize = sizeIn;
handles.resize(gmms.size());
}
WddmAllocation(uint32_t rootDeviceIndex, AllocationType allocationType, void *cpuPtrIn, size_t sizeIn, void *reservedAddr, MemoryPool::Type pool, uint32_t shareable)
: GraphicsAllocation(rootDeviceIndex, allocationType, cpuPtrIn, castToUint64(cpuPtrIn), 0llu, sizeIn, pool), shareable(shareable), trimCandidateListPositions(MemoryManager::maxOsContextCount, trimListUnusedPosition) {
: WddmAllocation(rootDeviceIndex, 1, allocationType, cpuPtrIn, sizeIn, reservedAddr, pool, shareable) {}
WddmAllocation(uint32_t rootDeviceIndex, size_t numGmms, AllocationType allocationType, void *cpuPtrIn, size_t sizeIn,
void *reservedAddr, MemoryPool::Type pool, uint32_t shareable)
: GraphicsAllocation(rootDeviceIndex, numGmms, allocationType, cpuPtrIn, castToUint64(cpuPtrIn), 0llu, sizeIn, pool), shareable(shareable), trimCandidateListPositions(MemoryManager::maxOsContextCount, trimListUnusedPosition) {
reservedAddressRangeInfo.addressPtr = reservedAddr;
reservedAddressRangeInfo.rangeSize = sizeIn;
handles.resize(gmms.size());
}
WddmAllocation(uint32_t rootDeviceIndex, AllocationType allocationType, void *cpuPtrIn, size_t sizeIn, osHandle sharedHandle, MemoryPool::Type pool)
: GraphicsAllocation(rootDeviceIndex, allocationType, cpuPtrIn, sizeIn, sharedHandle, pool), trimCandidateListPositions(MemoryManager::maxOsContextCount, trimListUnusedPosition) {}
: WddmAllocation(rootDeviceIndex, 1, allocationType, cpuPtrIn, sizeIn, sharedHandle, pool) {}
WddmAllocation(uint32_t rootDeviceIndex, size_t numGmms, AllocationType allocationType, void *cpuPtrIn, size_t sizeIn,
osHandle sharedHandle, MemoryPool::Type pool)
: GraphicsAllocation(rootDeviceIndex, numGmms, allocationType, cpuPtrIn, sizeIn, sharedHandle, pool), trimCandidateListPositions(MemoryManager::maxOsContextCount, trimListUnusedPosition) {
handles.resize(gmms.size());
}
void *getAlignedCpuPtr() const {
return alignDown(this->cpuPtr, MemoryConstants::pageSize);
@@ -52,11 +68,15 @@ class WddmAllocation : public GraphicsAllocation {
ResidencyData &getResidencyData() {
return residency;
}
const std::array<D3DKMT_HANDLE, EngineLimits::maxHandleCount> &getHandles() const { return handles; }
const StackVec<D3DKMT_HANDLE, EngineLimits::maxHandleCount> &getHandles() const { return handles; }
D3DKMT_HANDLE &getHandleToModify(uint32_t handleIndex) { return handles[handleIndex]; }
D3DKMT_HANDLE getDefaultHandle() const { return handles[0]; }
D3DKMT_HANDLE getHandle(uint32_t handleIndex) const { return handles[handleIndex]; }
void setDefaultHandle(D3DKMT_HANDLE handle) {
handles[0] = handle;
setHandle(handle, 0);
}
void setHandle(D3DKMT_HANDLE handle, uint32_t handleIndex) {
handles[handleIndex] = handle;
}
D3DKMT_HANDLE *getSharedHandleToModify() {
@@ -98,8 +118,8 @@ class WddmAllocation : public GraphicsAllocation {
}
return ss.str();
}
std::array<D3DKMT_HANDLE, EngineLimits::maxHandleCount> handles{};
ResidencyData residency;
std::vector<size_t> trimCandidateListPositions;
StackVec<D3DKMT_HANDLE, EngineLimits::maxHandleCount> handles;
};
} // namespace NEO

View File

@@ -79,6 +79,9 @@ GraphicsAllocation *WddmMemoryManager::allocateGraphicsMemoryForImageImpl(const
GraphicsAllocation *WddmMemoryManager::allocateGraphicsMemory64kb(const AllocationData &allocationData) {
size_t sizeAligned = alignUp(allocationData.size, MemoryConstants::pageSize64k);
if (sizeAligned > getHugeGfxMemoryChunkSize()) {
return allocateHugeGraphicsMemory(allocationData);
}
auto wddmAllocation = std::make_unique<WddmAllocation>(allocationData.rootDeviceIndex, allocationData.type, nullptr, sizeAligned, nullptr, MemoryPool::System64KBPages);
@@ -100,6 +103,59 @@ GraphicsAllocation *WddmMemoryManager::allocateGraphicsMemory64kb(const Allocati
return wddmAllocation.release();
}
GraphicsAllocation *WddmMemoryManager::allocateHugeGraphicsMemory(const AllocationData &allocationData) {
void *hostPtr = nullptr, *alignedPtr = nullptr;
size_t alignedSize = 0;
bool uncacheable = allocationData.flags.uncacheable;
auto memoryPool = MemoryPool::System64KBPages;
if (allocationData.hostPtr) {
hostPtr = const_cast<void *>(allocationData.hostPtr);
alignedSize = alignSizeWholePage(hostPtr, allocationData.size);
alignedPtr = alignDown(hostPtr, MemoryConstants::pageSize);
memoryPool = MemoryPool::System4KBPages;
} else {
alignedSize = alignUp(allocationData.size, MemoryConstants::pageSize64k);
uncacheable = false;
hostPtr = alignedPtr = allocateSystemMemory(alignedSize, MemoryConstants::pageSize64k);
if (nullptr == hostPtr) {
return nullptr;
}
}
auto chunkSize = getHugeGfxMemoryChunkSize();
auto numGmms = (alignedSize + chunkSize - 1) / chunkSize;
auto wddmAllocation = std::make_unique<WddmAllocation>(allocationData.rootDeviceIndex, numGmms, allocationData.type, hostPtr, allocationData.size, nullptr, memoryPool);
if (allocationData.hostPtr) {
wddmAllocation->setAllocationOffset(ptrDiff(hostPtr, alignedPtr));
} else {
wddmAllocation->setSize(alignedSize);
wddmAllocation->setDriverAllocatedCpuPtr(hostPtr);
}
auto sizeRemaining = alignedSize;
for (auto gmmId = 0u; gmmId < numGmms; ++gmmId) {
auto size = sizeRemaining > chunkSize ? chunkSize : sizeRemaining;
auto gmm = new Gmm(executionEnvironment.rootDeviceEnvironments[allocationData.rootDeviceIndex]->getGmmClientContext(),
static_cast<char *>(alignedPtr) + gmmId * chunkSize, size, uncacheable);
wddmAllocation->setGmm(gmm, gmmId);
sizeRemaining -= size;
}
wddmAllocation->storageInfo.multiStorage = true;
if (!createWddmAllocation(wddmAllocation.get(), nullptr)) {
for (auto gmmId = 0u; gmmId < wddmAllocation->getNumGmms(); ++gmmId) {
delete wddmAllocation->getGmm(gmmId);
}
freeSystemMemory(wddmAllocation->getDriverAllocatedCpuPtr());
return nullptr;
}
return wddmAllocation.release();
}
GraphicsAllocation *WddmMemoryManager::allocateGraphicsMemoryWithAlignment(const AllocationData &allocationData) {
size_t newAlignment = allocationData.alignment ? alignUp(allocationData.alignment, MemoryConstants::pageSize) : MemoryConstants::pageSize;
size_t sizeAligned = allocationData.size ? alignUp(allocationData.size, MemoryConstants::pageSize) : MemoryConstants::pageSize;
@@ -140,12 +196,16 @@ GraphicsAllocation *WddmMemoryManager::allocateGraphicsMemoryWithAlignment(const
}
GraphicsAllocation *WddmMemoryManager::allocateGraphicsMemoryForNonSvmHostPtr(const AllocationData &allocationData) {
auto alignedPtr = alignDown(allocationData.hostPtr, MemoryConstants::pageSize);
auto offsetInPage = ptrDiff(allocationData.hostPtr, alignedPtr);
auto alignedSize = alignSizeWholePage(allocationData.hostPtr, allocationData.size);
if (alignedSize > getHugeGfxMemoryChunkSize()) {
return allocateHugeGraphicsMemory(allocationData);
}
auto wddmAllocation = std::make_unique<WddmAllocation>(allocationData.rootDeviceIndex, allocationData.type, const_cast<void *>(allocationData.hostPtr),
allocationData.size, nullptr, MemoryPool::System4KBPages);
auto alignedPtr = alignDown(allocationData.hostPtr, MemoryConstants::pageSize);
auto offsetInPage = ptrDiff(allocationData.hostPtr, alignedPtr);
wddmAllocation->setAllocationOffset(offsetInPage);
auto gmm = new Gmm(executionEnvironment.rootDeviceEnvironments[allocationData.rootDeviceIndex]->getGmmClientContext(), alignedPtr, alignedSize, false);
@@ -161,6 +221,10 @@ GraphicsAllocation *WddmMemoryManager::allocateGraphicsMemoryForNonSvmHostPtr(co
}
GraphicsAllocation *WddmMemoryManager::allocateGraphicsMemoryWithHostPtr(const AllocationData &allocationData) {
if (allocationData.type == GraphicsAllocation::AllocationType::BUFFER_HOST_MEMORY && allocationData.size > getHugeGfxMemoryChunkSize()) {
return allocateGraphicsMemoryForNonSvmHostPtr(allocationData);
}
if (mallocRestrictions.minAddress > reinterpret_cast<uintptr_t>(allocationData.hostPtr)) {
auto inputPtr = allocationData.hostPtr;
void *reserve = nullptr;
@@ -311,7 +375,7 @@ void WddmMemoryManager::unlockResourceImpl(GraphicsAllocation &graphicsAllocatio
void WddmMemoryManager::freeAssociatedResourceImpl(GraphicsAllocation &graphicsAllocation) {
auto &wddmAllocation = static_cast<WddmAllocation &>(graphicsAllocation);
if (wddmAllocation.needsMakeResidentBeforeLock) {
for (auto i = 0u; i < wddmAllocation.getNumHandles(); i++) {
for (auto i = 0u; i < wddmAllocation.getNumGmms(); i++) {
getWddm(graphicsAllocation.getRootDeviceIndex()).getTemporaryResourcesContainer()->removeResource(wddmAllocation.getHandles()[i]);
}
}
@@ -337,7 +401,7 @@ void WddmMemoryManager::freeGraphicsMemoryImpl(GraphicsAllocation *gfxAllocation
DEBUG_BREAK_IF(!status);
}
}
for (auto handleId = 0u; handleId < EngineLimits::maxHandleCount; handleId++) {
for (auto handleId = 0u; handleId < gfxAllocation->getNumGmms(); handleId++) {
delete gfxAllocation->getGmm(handleId);
}
@@ -346,17 +410,16 @@ void WddmMemoryManager::freeGraphicsMemoryImpl(GraphicsAllocation *gfxAllocation
input->fragmentsStorage.fragmentCount > 0) {
cleanGraphicsMemoryCreatedFromHostPtr(gfxAllocation);
} else {
const D3DKMT_HANDLE *allocationHandles = nullptr;
uint32_t allocationCount = 0;
D3DKMT_HANDLE resourceHandle = 0;
if (input->peekSharedHandle()) {
resourceHandle = input->resourceHandle;
auto status = tryDeferDeletions(&input->getHandles()[0], input->getNumGmms(), input->resourceHandle, gfxAllocation->getRootDeviceIndex());
DEBUG_BREAK_IF(!status);
} else {
allocationHandles = input->getHandles().data();
allocationCount = input->getNumHandles();
for (auto handle : input->getHandles()) {
auto status = tryDeferDeletions(&handle, 1, 0, gfxAllocation->getRootDeviceIndex());
DEBUG_BREAK_IF(!status);
}
}
auto status = tryDeferDeletions(allocationHandles, allocationCount, resourceHandle, gfxAllocation->getRootDeviceIndex());
DEBUG_BREAK_IF(!status);
alignedFreeWrapper(input->getDriverAllocatedCpuPtr());
}
if (input->getReservedAddressPtr()) {
@@ -525,21 +588,56 @@ bool WddmMemoryManager::mapGpuVaForOneHandleAllocation(WddmAllocation *allocatio
if (allocation->reservedGpuVirtualAddress) {
getWddm(allocation->getRootDeviceIndex()).freeGpuVirtualAddress(allocation->reservedGpuVirtualAddress, allocation->reservedSizeForGpuVirtualAddress);
}
getWddm(allocation->getRootDeviceIndex()).destroyAllocations(allocation->getHandles().data(), allocation->getNumHandles(), allocation->resourceHandle);
getWddm(allocation->getRootDeviceIndex()).destroyAllocations(&allocation->getHandles()[0], allocation->getNumGmms(), allocation->resourceHandle);
return false;
}
return true;
}
bool WddmMemoryManager::mapMultiHandleAllocationWithRetry(WddmAllocation *allocation, Wddm *wddm, DeferredDeleter *deferredDeleter, GfxPartition &gfxPartition) {
auto alignedSize = allocation->getAlignedSize();
allocation->reservedSizeForGpuVirtualAddress = alignUp(alignedSize, MemoryConstants::pageSize64k);
allocation->reservedGpuVirtualAddress = wddm->reserveGpuVirtualAddress(gfxPartition.getHeapMinimalAddress(HeapIndex::HEAP_STANDARD64KB),
gfxPartition.getHeapLimit(HeapIndex::HEAP_STANDARD64KB),
allocation->reservedSizeForGpuVirtualAddress);
allocation->getGpuAddressToModify() = allocation->reservedGpuVirtualAddress;
auto addressToMap = allocation->reservedGpuVirtualAddress;
for (auto currentHandle = 0u; currentHandle < allocation->getNumGmms(); currentHandle++) {
uint64_t gpuAddress = 0;
auto status = wddm->mapGpuVirtualAddress(allocation->getGmm(currentHandle), allocation->getHandles()[currentHandle],
gfxPartition.getHeapMinimalAddress(HeapIndex::HEAP_STANDARD64KB), gfxPartition.getHeapLimit(HeapIndex::HEAP_STANDARD64KB),
addressToMap, gpuAddress);
if (!status && deferredDeleter) {
deferredDeleter->drain(true);
status = wddm->mapGpuVirtualAddress(allocation->getGmm(currentHandle), allocation->getHandles()[currentHandle],
gfxPartition.getHeapMinimalAddress(HeapIndex::HEAP_STANDARD64KB), gfxPartition.getHeapLimit(HeapIndex::HEAP_STANDARD64KB),
addressToMap, gpuAddress);
}
if (!status) {
if (allocation->reservedGpuVirtualAddress) {
wddm->freeGpuVirtualAddress(allocation->reservedGpuVirtualAddress, allocation->reservedSizeForGpuVirtualAddress);
}
wddm->destroyAllocations(&allocation->getHandles()[0], allocation->getNumGmms(), allocation->resourceHandle);
return false;
}
gpuAddress = GmmHelper::decanonize(gpuAddress);
UNRECOVERABLE_IF(addressToMap != gpuAddress);
addressToMap += allocation->getGmm(currentHandle)->gmmResourceInfo->getSizeAllocation();
}
return true;
}
bool WddmMemoryManager::createGpuAllocationsWithRetry(WddmAllocation *allocation) {
for (auto handleId = 0u; handleId < allocation->getNumHandles(); handleId++) {
auto status = getWddm(allocation->getRootDeviceIndex()).createAllocation(allocation->getAlignedCpuPtr(), allocation->getGmm(handleId), allocation->getHandleToModify(handleId), allocation->resourceHandle, allocation->getSharedHandleToModify());
for (auto handleId = 0u; handleId < allocation->getNumGmms(); handleId++) {
auto gmm = allocation->getGmm(handleId);
auto status = getWddm(allocation->getRootDeviceIndex()).createAllocation(gmm->gmmResourceInfo->getSystemMemPointer(), gmm, allocation->getHandleToModify(handleId), allocation->resourceHandle, allocation->getSharedHandleToModify());
if (status == STATUS_GRAPHICS_NO_VIDEO_MEMORY && deferredDeleter) {
deferredDeleter->drain(true);
status = getWddm(allocation->getRootDeviceIndex()).createAllocation(allocation->getAlignedCpuPtr(), allocation->getGmm(handleId), allocation->getHandleToModify(handleId), allocation->resourceHandle, allocation->getSharedHandleToModify());
status = getWddm(allocation->getRootDeviceIndex()).createAllocation(gmm->gmmResourceInfo->getSystemMemPointer(), gmm, allocation->getHandleToModify(handleId), allocation->resourceHandle, allocation->getSharedHandleToModify());
}
if (status != STATUS_SUCCESS) {
getWddm(allocation->getRootDeviceIndex()).destroyAllocations(allocation->getHandles().data(), handleId, allocation->resourceHandle);
getWddm(allocation->getRootDeviceIndex()).destroyAllocations(&allocation->getHandles()[0], handleId, allocation->resourceHandle);
return false;
}
}

View File

@@ -76,11 +76,15 @@ class WddmMemoryManager : public MemoryManager {
GraphicsAllocation *allocate32BitGraphicsMemoryImpl(const AllocationData &allocationData) override;
GraphicsAllocation *allocateGraphicsMemoryInDevicePool(const AllocationData &allocationData, AllocationStatus &status) override;
MOCKABLE_VIRTUAL size_t getHugeGfxMemoryChunkSize() const { return 4 * MemoryConstants::gigaByte - MemoryConstants::pageSize64k; }
GraphicsAllocation *allocateHugeGraphicsMemory(const AllocationData &allocationData);
GraphicsAllocation *createAllocationFromHandle(osHandle handle, bool requireSpecificBitness, bool ntHandle, GraphicsAllocation::AllocationType allocationType, uint32_t rootDeviceIndex);
static bool validateAllocation(WddmAllocation *alloc);
bool createWddmAllocation(WddmAllocation *allocation, void *requiredGpuPtr);
bool mapGpuVirtualAddress(WddmAllocation *graphicsAllocation, const void *requiredGpuPtr);
bool mapGpuVaForOneHandleAllocation(WddmAllocation *graphicsAllocation, const void *requiredGpuPtr);
bool mapMultiHandleAllocationWithRetry(WddmAllocation *allocation, Wddm *wddm, DeferredDeleter *deferredDeleter, GfxPartition &gfxPartition);
bool createGpuAllocationsWithRetry(WddmAllocation *graphicsAllocation);
AlignedMallocRestrictions mallocRestrictions;

View File

@@ -17,8 +17,12 @@ bool WddmMemoryManager::copyMemoryToAllocation(GraphicsAllocation *graphicsAlloc
return MemoryManager::copyMemoryToAllocation(graphicsAllocation, memoryToCopy, sizeToCopy);
}
bool WddmMemoryManager::mapGpuVirtualAddress(WddmAllocation *allocation, const void *requiredPtr) {
if (allocation->getNumGmms() > 1) {
return mapMultiHandleAllocationWithRetry(allocation, &getWddm(allocation->getRootDeviceIndex()), this->getDeferredDeleter(), *getGfxPartition(allocation->getRootDeviceIndex()));
}
return mapGpuVaForOneHandleAllocation(allocation, requiredPtr);
}
uint64_t WddmMemoryManager::getLocalMemorySize(uint32_t rootDeviceIndex) {
return 0 * GB;
}

View File

@@ -35,10 +35,10 @@ MemoryOperationsStatus WddmMemoryOperationsHandler::makeResident(ArrayRef<Graphi
}
} else {
memcpy_s(&handlesForResidency[totalHandlesCount],
wddmAllocation->getNumHandles() * sizeof(D3DKMT_HANDLE),
wddmAllocation->getHandles().data(),
wddmAllocation->getNumHandles() * sizeof(D3DKMT_HANDLE));
totalHandlesCount += wddmAllocation->getNumHandles();
wddmAllocation->getNumGmms() * sizeof(D3DKMT_HANDLE),
&wddmAllocation->getHandles()[0],
wddmAllocation->getNumGmms() * sizeof(D3DKMT_HANDLE));
totalHandlesCount += wddmAllocation->getNumGmms();
}
}
return residentAllocations->makeResidentResources(handlesForResidency.begin(), totalHandlesCount, totalSize);
@@ -57,8 +57,8 @@ MemoryOperationsStatus WddmMemoryOperationsHandler::evict(GraphicsAllocation &gf
totalHandleCount++;
}
} else {
const D3DKMT_HANDLE *handlePtr = wddmAllocation.getHandles().data();
size_t handleCount = wddmAllocation.getNumHandles();
const D3DKMT_HANDLE *handlePtr = &wddmAllocation.getHandles()[0];
size_t handleCount = wddmAllocation.getNumGmms();
for (uint32_t i = 0; i < handleCount; i++, totalHandleCount++) {
handlesForEviction.push_back(*handlePtr);
handlePtr++;

View File

@@ -201,7 +201,7 @@ void WddmResidencyController::trimResidency(D3DDDI_TRIMRESIDENCYSET_FLAGS flags,
if (wddmAllocation->fragmentsStorage.fragmentCount == 0) {
DBG_LOG(ResidencyDebugEnable, "Residency:", __FUNCTION__, "Evict allocation: default handle =", wddmAllocation->getDefaultHandle(), "lastFence =", (wddmAllocation)->getResidencyData().getFenceValueForContextId(osContextId));
this->wddm.evict(wddmAllocation->getHandles().data(), wddmAllocation->getNumHandles(), sizeToTrim);
this->wddm.evict(&wddmAllocation->getHandles()[0], wddmAllocation->getNumGmms(), sizeToTrim);
}
for (uint32_t allocationId = 0; allocationId < wddmAllocation->fragmentsStorage.fragmentCount; allocationId++) {
@@ -258,7 +258,7 @@ bool WddmResidencyController::trimResidencyToBudget(uint64_t bytes) {
}
if (wddmAllocation->fragmentsStorage.fragmentCount == 0) {
this->wddm.evict(wddmAllocation->getHandles().data(), wddmAllocation->getNumHandles(), sizeToTrim);
this->wddm.evict(&wddmAllocation->getHandles()[0], wddmAllocation->getNumGmms(), sizeToTrim);
sizeEvicted = wddmAllocation->getAlignedSize();
} else {
auto &fragmentStorageData = wddmAllocation->fragmentsStorage.fragmentStorageData;
@@ -299,7 +299,9 @@ bool WddmResidencyController::trimResidencyToBudget(uint64_t bytes) {
bool WddmResidencyController::makeResidentResidencyAllocations(const ResidencyContainer &allocationsForResidency) {
const size_t residencyCount = allocationsForResidency.size();
std::unique_ptr<D3DKMT_HANDLE[]> handlesForResidency(new D3DKMT_HANDLE[residencyCount * maxFragmentsCount * EngineLimits::maxHandleCount]);
constexpr uint32_t stackAllocations = 64;
constexpr uint32_t stackHandlesCount = NEO::maxFragmentsCount * EngineLimits::maxHandleCount * stackAllocations;
StackVec<D3DKMT_HANDLE, stackHandlesCount> handlesForResidency;
uint32_t totalHandlesCount = 0;
size_t totalSize = 0;
@@ -327,19 +329,23 @@ bool WddmResidencyController::makeResidentResidencyAllocations(const ResidencyCo
if (allocation->fragmentsStorage.fragmentCount > 0) {
for (uint32_t allocationId = 0; allocationId < allocation->fragmentsStorage.fragmentCount; allocationId++) {
if (!fragmentResidency[allocationId])
handlesForResidency[totalHandlesCount++] = allocation->fragmentsStorage.fragmentStorageData[allocationId].osHandleStorage->handle;
if (!fragmentResidency[allocationId]) {
handlesForResidency.push_back(allocation->fragmentsStorage.fragmentStorageData[allocationId].osHandleStorage->handle);
totalHandlesCount++;
}
}
} else if (!residencyData.resident[osContextId]) {
memcpy_s(&handlesForResidency[totalHandlesCount], allocation->getNumHandles() * sizeof(D3DKMT_HANDLE), allocation->getHandles().data(), allocation->getNumHandles() * sizeof(D3DKMT_HANDLE));
totalHandlesCount += allocation->getNumHandles();
for (uint32_t gmmId = 0; gmmId < allocation->getNumGmms(); ++gmmId) {
handlesForResidency.push_back(allocation->getHandle(gmmId));
totalHandlesCount++;
}
}
}
bool result = true;
if (totalHandlesCount) {
uint64_t bytesToTrim = 0;
while ((result = wddm.makeResident(handlesForResidency.get(), totalHandlesCount, false, &bytesToTrim, totalSize)) == false) {
while ((result = wddm.makeResident(&handlesForResidency[0], totalHandlesCount, false, &bytesToTrim, totalSize)) == false) {
this->setMemoryBudgetExhausted();
const bool trimmingDone = this->trimResidencyToBudget(bytesToTrim);
if (!trimmingDone) {
@@ -348,7 +354,7 @@ bool WddmResidencyController::makeResidentResidencyAllocations(const ResidencyCo
continue;
}
DEBUG_BREAK_IF(evictionStatus != MemoryOperationsStatus::MEMORY_NOT_FOUND);
result = wddm.makeResident(handlesForResidency.get(), totalHandlesCount, true, &bytesToTrim, totalSize);
result = wddm.makeResident(&handlesForResidency[0], totalHandlesCount, true, &bytesToTrim, totalSize);
break;
}
}