Add logic to create wddm allocation with many handles

Change-Id: I1eeffddf7108183ad867d2b05d313f0cf6941c01
Signed-off-by: Mateusz Jablonski <mateusz.jablonski@intel.com>
This commit is contained in:
Mateusz Jablonski
2019-03-07 15:14:11 +01:00
committed by sys_ocldev
parent 22c3c10679
commit 6abc3f7d9b
12 changed files with 84 additions and 18 deletions

View File

@@ -60,7 +60,7 @@ class Wddm {
MOCKABLE_VIRTUAL bool makeResident(const D3DKMT_HANDLE *handles, uint32_t count, bool cantTrimFurther, uint64_t *numberOfBytesToTrim);
MOCKABLE_VIRTUAL bool mapGpuVirtualAddress(Gmm *gmm, D3DKMT_HANDLE handle, D3DGPU_VIRTUAL_ADDRESS minimumAddress, D3DGPU_VIRTUAL_ADDRESS maximumAddress, D3DGPU_VIRTUAL_ADDRESS preferredAddress, D3DGPU_VIRTUAL_ADDRESS &gpuPtr);
bool mapGpuVirtualAddress(AllocationStorageData *allocationStorageData);
D3DGPU_VIRTUAL_ADDRESS reserveGpuVirtualAddress(D3DGPU_VIRTUAL_ADDRESS minimumAddress, D3DGPU_VIRTUAL_ADDRESS maximumAddress, D3DGPU_SIZE_T size);
MOCKABLE_VIRTUAL D3DGPU_VIRTUAL_ADDRESS reserveGpuVirtualAddress(D3DGPU_VIRTUAL_ADDRESS minimumAddress, D3DGPU_VIRTUAL_ADDRESS maximumAddress, D3DGPU_SIZE_T size);
MOCKABLE_VIRTUAL bool createContext(OsContextWin &osContext);
MOCKABLE_VIRTUAL void applyAdditionalContextFlags(CREATECONTEXT_PVTDATA &privateData, OsContextWin &osContext);
MOCKABLE_VIRTUAL bool freeGpuVirtualAddress(D3DGPU_VIRTUAL_ADDRESS &gpuPtr, uint64_t size);

View File

@@ -11,7 +11,4 @@ namespace OCLRT {
std::string WddmAllocation::getAllocationInfoString() const {
return getHandleInfoString();
}
uint32_t WddmAllocation::getNumHandles() const {
return 1u;
}
} // namespace OCLRT

View File

@@ -54,7 +54,7 @@ class WddmAllocation : public GraphicsAllocation {
void setDefaultHandle(D3DKMT_HANDLE handle) {
handles[0] = handle;
}
uint32_t getNumHandles() const;
uint32_t getNumHandles() const { return storageInfo.getNumHandles(); }
void setTrimCandidateListPosition(uint32_t osContextId, size_t position) {
trimCandidateListPositions[osContextId] = position;
@@ -76,6 +76,7 @@ class WddmAllocation : public GraphicsAllocation {
// OS assigned fields
D3DKMT_HANDLE resourceHandle = 0u; // used by shared resources
bool needsMakeResidentBeforeLock = false;
D3DGPU_VIRTUAL_ADDRESS preferredGpuAddress = 0u;
protected:
std::string getHandleInfoString() const {

View File

@@ -346,6 +346,9 @@ void WddmMemoryManager::freeGraphicsMemoryImpl(GraphicsAllocation *gfxAllocation
if (input->getReservedAddressPtr()) {
releaseReservedCpuAddressRange(input->getReservedAddressPtr(), input->getReservedAddressSize());
}
if (input->preferredGpuAddress) {
wddm->freeGpuVirtualAddress(input->preferredGpuAddress, input->getAlignedSize());
}
delete gfxAllocation;
}
@@ -488,21 +491,35 @@ AlignedMallocRestrictions *WddmMemoryManager::getAlignedMallocRestrictions() {
}
bool WddmMemoryManager::createWddmAllocation(WddmAllocation *allocation, void *requiredGpuPtr) {
auto wddmSuccess = wddm->createAllocation(allocation->getAlignedCpuPtr(), allocation->getDefaultGmm(), allocation->getHandleToModify(0u));
if (wddmSuccess == STATUS_GRAPHICS_NO_VIDEO_MEMORY && deferredDeleter) {
deferredDeleter->drain(true);
wddmSuccess = wddm->createAllocation(allocation->getAlignedCpuPtr(), allocation->getDefaultGmm(), allocation->getHandleToModify(0u));
auto status = createGpuAllocationsWithRetry(allocation);
if (!status) {
return false;
}
obtainGpuAddressIfNeeded(allocation);
bool mapSuccess = mapGpuVirtualAddressWithRetry(allocation, requiredGpuPtr);
if (!mapSuccess) {
if (allocation->preferredGpuAddress) {
wddm->freeGpuVirtualAddress(allocation->preferredGpuAddress, allocation->getAlignedSize());
}
wddm->destroyAllocations(allocation->getHandles().data(), allocation->getNumHandles(), allocation->resourceHandle);
return false;
}
return true;
}
if (wddmSuccess == STATUS_SUCCESS) {
bool mapSuccess = mapGpuVirtualAddressWithRetry(allocation, requiredGpuPtr);
if (!mapSuccess) {
wddm->destroyAllocations(allocation->getHandles().data(), allocation->getNumHandles(), allocation->resourceHandle);
bool WddmMemoryManager::createGpuAllocationsWithRetry(WddmAllocation *allocation) {
for (auto handleId = 0u; handleId < allocation->getNumHandles(); handleId++) {
auto status = wddm->createAllocation(allocation->getAlignedCpuPtr(), allocation->getGmm(handleId), allocation->getHandleToModify(handleId));
if (status == STATUS_GRAPHICS_NO_VIDEO_MEMORY && deferredDeleter) {
deferredDeleter->drain(true);
status = wddm->createAllocation(allocation->getAlignedCpuPtr(), allocation->getGmm(handleId), allocation->getHandleToModify(handleId));
}
if (status != STATUS_SUCCESS) {
wddm->destroyAllocations(allocation->getHandles().data(), handleId, allocation->resourceHandle);
return false;
}
return true;
}
return false;
return true;
}
bool WddmMemoryManager::mapGpuVirtualAddressWithRetry(WddmAllocation *graphicsAllocation, const void *preferredGpuVirtualAddress) {
@@ -516,15 +533,19 @@ bool WddmMemoryManager::mapGpuVirtualAddressWithRetry(WddmAllocation *graphicsAl
uint32_t WddmMemoryManager::mapGpuVirtualAddress(WddmAllocation *graphicsAllocation, const void *preferredGpuVirtualAddress, uint32_t startingIndex) {
auto numMappedAllocations = 0u;
D3DGPU_VIRTUAL_ADDRESS addressToMap = reinterpret_cast<D3DGPU_VIRTUAL_ADDRESS>(preferredGpuVirtualAddress);
auto heapIndex = selectHeap(graphicsAllocation, preferredGpuVirtualAddress != nullptr, executionEnvironment.isFullRangeSvm());
if (!executionEnvironment.isFullRangeSvm()) {
preferredGpuVirtualAddress = nullptr;
addressToMap = 0u;
}
if (graphicsAllocation->preferredGpuAddress) {
addressToMap = graphicsAllocation->preferredGpuAddress;
}
for (auto handleId = startingIndex; handleId < graphicsAllocation->getNumHandles(); handleId++) {
if (!wddm->mapGpuVirtualAddress(graphicsAllocation->getGmm(handleId), graphicsAllocation->getHandles()[handleId],
gfxPartition.getHeapBase(heapIndex), gfxPartition.getHeapLimit(heapIndex),
reinterpret_cast<D3DGPU_VIRTUAL_ADDRESS>(preferredGpuVirtualAddress), graphicsAllocation->getGpuAddressToModify())) {
addressToMap, graphicsAllocation->getGpuAddressToModify())) {
return numMappedAllocations;
}
numMappedAllocations++;
@@ -532,6 +553,14 @@ uint32_t WddmMemoryManager::mapGpuVirtualAddress(WddmAllocation *graphicsAllocat
return numMappedAllocations;
}
void WddmMemoryManager::obtainGpuAddressIfNeeded(WddmAllocation *allocation) {
if (allocation->getNumHandles() > 1u) {
auto heapIndex = selectHeap(allocation, false, executionEnvironment.isFullRangeSvm());
allocation->preferredGpuAddress = wddm->reserveGpuVirtualAddress(gfxPartition.getHeapBase(heapIndex), gfxPartition.getHeapLimit(heapIndex),
allocation->getAlignedSize());
}
}
void *WddmMemoryManager::reserveCpuAddressRange(size_t size) {
void *reservePtr = nullptr;
wddm->reserveValidAddressRange(size, reservePtr);

View File

@@ -82,6 +82,8 @@ class WddmMemoryManager : public MemoryManager {
bool createWddmAllocation(WddmAllocation *allocation, void *requiredGpuPtr);
bool mapGpuVirtualAddressWithRetry(WddmAllocation *graphicsAllocation, const void *preferredGpuVirtualAddress);
uint32_t mapGpuVirtualAddress(WddmAllocation *graphicsAllocation, const void *preferredGpuVirtualAddress, uint32_t startingIndex);
bool createGpuAllocationsWithRetry(WddmAllocation *graphicsAllocation);
void obtainGpuAddressIfNeeded(WddmAllocation *graphicsAllocation);
AlignedMallocRestrictions mallocRestrictions;
private: