mirror of
https://github.com/intel/compute-runtime.git
synced 2026-01-05 17:41:26 +08:00
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:
committed by
sys_ocldev
parent
af2fe237b4
commit
3859e13322
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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++;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user