mirror of
https://github.com/intel/compute-runtime.git
synced 2026-01-10 15:12:56 +08:00
L0 Virtual Memory Reservation support
- Enable support for L0 Virtual Memory reservation on Linux and Windows. - Excludes support for Linux to allow pStart option Related-To: LOCI-3397, LOCI-1543 Signed-off-by: Spruit, Neil R <neil.r.spruit@intel.com>
This commit is contained in:
committed by
Compute-Runtime-Automation
parent
467119931c
commit
d81b0b14a1
@@ -51,7 +51,10 @@ void DebuggerL0::initialize() {
|
||||
device->getDeviceBitfield()};
|
||||
|
||||
if (!singleAddressSpaceSbaTracking) {
|
||||
sbaTrackingGpuVa = device->getMemoryManager()->reserveGpuAddress(MemoryConstants::pageSize, device->getRootDeviceIndex());
|
||||
RootDeviceIndicesContainer rootDevices;
|
||||
rootDevices.push_back(device->getRootDeviceIndex());
|
||||
uint32_t rootDeviceIndexReserved = 0;
|
||||
sbaTrackingGpuVa = device->getMemoryManager()->reserveGpuAddress(nullptr, MemoryConstants::pageSize, rootDevices, &rootDeviceIndexReserved);
|
||||
properties.gpuAddress = sbaTrackingGpuVa.address;
|
||||
}
|
||||
|
||||
|
||||
@@ -52,6 +52,13 @@ struct AddressRange {
|
||||
size_t size;
|
||||
};
|
||||
|
||||
struct VirtualMemoryReservation {
|
||||
AddressRange virtualAddressRange;
|
||||
MemoryFlags flags;
|
||||
bool mapped;
|
||||
uint32_t rootDeviceIndex;
|
||||
};
|
||||
|
||||
constexpr size_t paddingBufferSize = 2 * MemoryConstants::megaByte;
|
||||
|
||||
namespace MemoryTransferHelper {
|
||||
@@ -211,7 +218,7 @@ class MemoryManager {
|
||||
GmmHelper *getGmmHelper(uint32_t rootDeviceIndex) {
|
||||
return executionEnvironment.rootDeviceEnvironments[rootDeviceIndex]->getGmmHelper();
|
||||
}
|
||||
virtual AddressRange reserveGpuAddress(size_t size, uint32_t rootDeviceIndex) = 0;
|
||||
virtual AddressRange reserveGpuAddress(const void *requiredStartAddress, size_t size, RootDeviceIndicesContainer rootDeviceIndices, uint32_t *reservedOnRootDeviceIndex) = 0;
|
||||
virtual void freeGpuAddress(AddressRange addressRange, uint32_t rootDeviceIndex) = 0;
|
||||
static HeapIndex selectInternalHeap(bool useLocalMemory) { return useLocalMemory ? HeapIndex::HEAP_INTERNAL_DEVICE_MEMORY : HeapIndex::HEAP_INTERNAL; }
|
||||
static HeapIndex selectExternalHeap(bool useLocalMemory) { return useLocalMemory ? HeapIndex::HEAP_EXTERNAL_DEVICE_MEMORY : HeapIndex::HEAP_EXTERNAL; }
|
||||
@@ -264,6 +271,8 @@ class MemoryManager {
|
||||
|
||||
std::unordered_map<std::string, KernelAllocationInfo> &getKernelAllocationMap() { return this->kernelAllocationMap; };
|
||||
[[nodiscard]] std::unique_lock<std::mutex> lockKernelAllocationMap() { return std::unique_lock<std::mutex>(this->kernelAllocationMutex); };
|
||||
std::map<void *, VirtualMemoryReservation *> &getVirtualMemoryReservationMap() { return this->virtualMemoryReservationMap; };
|
||||
[[nodiscard]] std::unique_lock<std::mutex> lockVirtualMemoryReservationMap() { return std::unique_lock<std::mutex>(this->virtualMemoryReservationMapMutex); };
|
||||
|
||||
protected:
|
||||
bool getAllocationData(AllocationData &allocationData, const AllocationProperties &properties, const void *hostPtr, const StorageInfo &storageInfo);
|
||||
@@ -329,6 +338,8 @@ class MemoryManager {
|
||||
std::vector<bool> isaInLocalMemory;
|
||||
std::unordered_map<std::string, KernelAllocationInfo> kernelAllocationMap;
|
||||
std::mutex kernelAllocationMutex;
|
||||
std::map<void *, VirtualMemoryReservation *> virtualMemoryReservationMap;
|
||||
std::mutex virtualMemoryReservationMapMutex;
|
||||
};
|
||||
|
||||
std::unique_ptr<DeferredDeleter> createDeferredDeleter();
|
||||
|
||||
@@ -453,10 +453,21 @@ MemoryAllocation *OsAgnosticMemoryManager::createMemoryAllocation(AllocationType
|
||||
return memoryAllocation;
|
||||
}
|
||||
|
||||
AddressRange OsAgnosticMemoryManager::reserveGpuAddress(size_t size, uint32_t rootDeviceIndex) {
|
||||
auto gfxPartition = getGfxPartition(rootDeviceIndex);
|
||||
auto gmmHelper = getGmmHelper(rootDeviceIndex);
|
||||
auto gpuVa = gmmHelper->canonize(gfxPartition->heapAllocate(HeapIndex::HEAP_STANDARD, size));
|
||||
AddressRange OsAgnosticMemoryManager::reserveGpuAddress(const void *requiredStartAddress, size_t size, RootDeviceIndicesContainer rootDeviceIndices, uint32_t *reservedOnRootDeviceIndex) {
|
||||
uint64_t gpuVa = 0u;
|
||||
*reservedOnRootDeviceIndex = 0;
|
||||
if (requiredStartAddress) {
|
||||
return AddressRange{0, 0};
|
||||
}
|
||||
for (uint32_t rootDeviceIndex = 0; rootDeviceIndex < rootDeviceIndices.size(); rootDeviceIndex++) {
|
||||
auto gfxPartition = getGfxPartition(rootDeviceIndex);
|
||||
auto gmmHelper = getGmmHelper(rootDeviceIndex);
|
||||
gpuVa = gmmHelper->canonize(gfxPartition->heapAllocate(HeapIndex::HEAP_STANDARD, size));
|
||||
if (gpuVa != 0u) {
|
||||
*reservedOnRootDeviceIndex = rootDeviceIndex;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return AddressRange{gpuVa, size};
|
||||
}
|
||||
|
||||
|
||||
@@ -90,7 +90,7 @@ class OsAgnosticMemoryManager : public MemoryManager {
|
||||
void *reserveCpuAddressRange(size_t size, uint32_t rootDeviceIndex) override;
|
||||
void releaseReservedCpuAddressRange(void *reserved, size_t size, uint32_t rootDeviceIndex) override;
|
||||
|
||||
AddressRange reserveGpuAddress(size_t size, uint32_t rootDeviceIndex) override;
|
||||
AddressRange reserveGpuAddress(const void *requiredStartAddress, size_t size, RootDeviceIndicesContainer rootDeviceIndices, uint32_t *reservedOnRootDeviceIndex) override;
|
||||
void freeGpuAddress(AddressRange addressRange, uint32_t rootDeviceIndex) override;
|
||||
bool is64kbPagesEnabled(const HardwareInfo *hwInfo);
|
||||
|
||||
|
||||
@@ -1156,8 +1156,19 @@ uint32_t DrmMemoryManager::getRootDeviceIndex(const Drm *drm) {
|
||||
return CommonConstants::unspecifiedDeviceIndex;
|
||||
}
|
||||
|
||||
AddressRange DrmMemoryManager::reserveGpuAddress(size_t size, uint32_t rootDeviceIndex) {
|
||||
auto gpuVa = acquireGpuRange(size, rootDeviceIndex, HeapIndex::HEAP_STANDARD);
|
||||
AddressRange DrmMemoryManager::reserveGpuAddress(const void *requiredStartAddress, size_t size, RootDeviceIndicesContainer rootDeviceIndices, uint32_t *reservedOnRootDeviceIndex) {
|
||||
uint64_t gpuVa = 0u;
|
||||
*reservedOnRootDeviceIndex = 0;
|
||||
if (requiredStartAddress) {
|
||||
return AddressRange{0, 0};
|
||||
}
|
||||
for (uint32_t rootDeviceIndex = 0; rootDeviceIndex < rootDeviceIndices.size(); rootDeviceIndex++) {
|
||||
gpuVa = acquireGpuRange(size, rootDeviceIndex, HeapIndex::HEAP_STANDARD);
|
||||
if (gpuVa != 0u) {
|
||||
*reservedOnRootDeviceIndex = rootDeviceIndex;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return AddressRange{gpuVa, size};
|
||||
}
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ class DrmMemoryManager : public MemoryManager {
|
||||
bool copyMemoryToAllocationBanks(GraphicsAllocation *graphicsAllocation, size_t destinationOffset, const void *memoryToCopy, size_t sizeToCopy, DeviceBitfield handleMask) override;
|
||||
|
||||
MOCKABLE_VIRTUAL int obtainFdFromHandle(int boHandle, uint32_t rootDeviceindex);
|
||||
AddressRange reserveGpuAddress(size_t size, uint32_t rootDeviceIndex) override;
|
||||
AddressRange reserveGpuAddress(const void *requiredStartAddress, size_t size, RootDeviceIndicesContainer rootDeviceIndices, uint32_t *reservedOnRootDeviceIndex) override;
|
||||
void freeGpuAddress(AddressRange addressRange, uint32_t rootDeviceIndex) override;
|
||||
MOCKABLE_VIRTUAL BufferObject *createBufferObjectInMemoryRegion(Drm *drm, Gmm *gmm, AllocationType allocationType, uint64_t gpuAddress, size_t size,
|
||||
uint32_t memoryBanks, size_t maxOsContextCount, int32_t pairHandle);
|
||||
|
||||
@@ -558,11 +558,13 @@ bool Wddm::mapGpuVirtualAddress(Gmm *gmm, D3DKMT_HANDLE handle, D3DGPU_VIRTUAL_A
|
||||
return ret;
|
||||
}
|
||||
|
||||
D3DGPU_VIRTUAL_ADDRESS Wddm::reserveGpuVirtualAddress(D3DGPU_VIRTUAL_ADDRESS minimumAddress,
|
||||
D3DGPU_VIRTUAL_ADDRESS Wddm::reserveGpuVirtualAddress(D3DGPU_VIRTUAL_ADDRESS baseAddress,
|
||||
D3DGPU_VIRTUAL_ADDRESS minimumAddress,
|
||||
D3DGPU_VIRTUAL_ADDRESS maximumAddress,
|
||||
D3DGPU_SIZE_T size) {
|
||||
UNRECOVERABLE_IF(size % MemoryConstants::pageSize64k);
|
||||
D3DDDI_RESERVEGPUVIRTUALADDRESS reserveGpuVirtualAddress = {};
|
||||
reserveGpuVirtualAddress.BaseAddress = baseAddress;
|
||||
reserveGpuVirtualAddress.MinimumAddress = minimumAddress;
|
||||
reserveGpuVirtualAddress.MaximumAddress = maximumAddress;
|
||||
reserveGpuVirtualAddress.hPagingQueue = this->pagingQueue;
|
||||
|
||||
@@ -64,7 +64,7 @@ class Wddm : public DriverModel {
|
||||
MOCKABLE_VIRTUAL bool makeResident(const D3DKMT_HANDLE *handles, uint32_t count, bool cantTrimFurther, uint64_t *numberOfBytesToTrim, size_t totalSize);
|
||||
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);
|
||||
MOCKABLE_VIRTUAL 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 baseAddress, 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, const HardwareInfo &hwInfo);
|
||||
MOCKABLE_VIRTUAL void applyAdditionalMapGPUVAFields(D3DDDI_MAPGPUVIRTUALADDRESS &mapGPUVA, Gmm *gmm);
|
||||
|
||||
@@ -749,6 +749,26 @@ bool WddmMemoryManager::createWddmAllocation(WddmAllocation *allocation, void *r
|
||||
return mapGpuVirtualAddress(allocation, requiredGpuPtr);
|
||||
}
|
||||
|
||||
AddressRange WddmMemoryManager::reserveGpuAddress(const void *requiredStartAddress, size_t size, RootDeviceIndicesContainer rootDeviceIndices, uint32_t *reservedOnRootDeviceIndex) {
|
||||
uint64_t gpuVa = 0u;
|
||||
*reservedOnRootDeviceIndex = 0;
|
||||
size_t reservedSize = 0;
|
||||
for (uint32_t rootDeviceIndex = 0; rootDeviceIndex < rootDeviceIndices.size(); rootDeviceIndex++) {
|
||||
auto gfxPartition = getGfxPartition(rootDeviceIndex);
|
||||
gpuVa = getWddm(rootDeviceIndex).reserveGpuVirtualAddress(reinterpret_cast<uint64_t>(requiredStartAddress), gfxPartition->getHeapMinimalAddress(HeapIndex::HEAP_STANDARD64KB), gfxPartition->getHeapLimit(HeapIndex::HEAP_STANDARD64KB), size);
|
||||
if (gpuVa != 0u) {
|
||||
*reservedOnRootDeviceIndex = rootDeviceIndex;
|
||||
reservedSize = size;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return AddressRange{gpuVa, reservedSize};
|
||||
}
|
||||
|
||||
void WddmMemoryManager::freeGpuAddress(AddressRange addressRange, uint32_t rootDeviceIndex) {
|
||||
getWddm(rootDeviceIndex).freeGpuVirtualAddress(addressRange.address, addressRange.size);
|
||||
}
|
||||
|
||||
bool WddmMemoryManager::mapGpuVaForOneHandleAllocation(WddmAllocation *allocation, const void *preferredGpuVirtualAddress) {
|
||||
D3DGPU_VIRTUAL_ADDRESS addressToMap = castToUint64(preferredGpuVirtualAddress);
|
||||
auto heapIndex = selectHeap(allocation, preferredGpuVirtualAddress != nullptr, is32bit || executionEnvironment.rootDeviceEnvironments[allocation->getRootDeviceIndex()]->isFullRangeSvm(), allocation->allocInFrontWindowPool);
|
||||
@@ -795,7 +815,7 @@ bool WddmMemoryManager::mapMultiHandleAllocationWithRetry(WddmAllocation *alloca
|
||||
allocation->getGpuAddressToModify() = addressToMap;
|
||||
} else {
|
||||
allocation->reservedSizeForGpuVirtualAddress = alignUp(alignedSize, MemoryConstants::pageSize64k);
|
||||
allocation->reservedGpuVirtualAddress = wddm.reserveGpuVirtualAddress(gfxPartition->getHeapMinimalAddress(heapIndex), gfxPartition->getHeapLimit(heapIndex),
|
||||
allocation->reservedGpuVirtualAddress = wddm.reserveGpuVirtualAddress(0ull, gfxPartition->getHeapMinimalAddress(heapIndex), gfxPartition->getHeapLimit(heapIndex),
|
||||
allocation->reservedSizeForGpuVirtualAddress);
|
||||
auto gmmHelper = getGmmHelper(allocation->getRootDeviceIndex());
|
||||
allocation->getGpuAddressToModify() = gmmHelper->canonize(allocation->reservedGpuVirtualAddress);
|
||||
|
||||
@@ -73,8 +73,8 @@ class WddmMemoryManager : public MemoryManager {
|
||||
bool isCpuCopyRequired(const void *ptr) override;
|
||||
bool isWCMemory(const void *ptr) override;
|
||||
|
||||
AddressRange reserveGpuAddress(size_t size, uint32_t rootDeviceIndex) override { return AddressRange{0, 0}; };
|
||||
void freeGpuAddress(AddressRange addressRange, uint32_t rootDeviceIndex) override{};
|
||||
AddressRange reserveGpuAddress(const void *requiredStartAddress, size_t size, RootDeviceIndicesContainer rootDeviceIndices, uint32_t *reservedOnRootDeviceIndex) override;
|
||||
void freeGpuAddress(AddressRange addressRange, uint32_t rootDeviceIndex) override;
|
||||
bool verifyHandle(osHandle handle, uint32_t rootDeviceIndex, bool ntHandle) override;
|
||||
bool isNTHandle(osHandle handle, uint32_t rootDeviceIndex) override;
|
||||
void releaseDeviceSpecificMemResources(uint32_t rootDeviceIndex) override{};
|
||||
|
||||
@@ -292,9 +292,13 @@ VOID *WddmMock::registerTrimCallback(PFND3DKMT_TRIMNOTIFICATIONCALLBACK callback
|
||||
return Wddm::registerTrimCallback(callback, residencyController);
|
||||
}
|
||||
|
||||
D3DGPU_VIRTUAL_ADDRESS WddmMock::reserveGpuVirtualAddress(D3DGPU_VIRTUAL_ADDRESS minimumAddress, D3DGPU_VIRTUAL_ADDRESS maximumAddress, D3DGPU_SIZE_T size) {
|
||||
D3DGPU_VIRTUAL_ADDRESS WddmMock::reserveGpuVirtualAddress(D3DGPU_VIRTUAL_ADDRESS baseAddress, D3DGPU_VIRTUAL_ADDRESS minimumAddress, D3DGPU_VIRTUAL_ADDRESS maximumAddress, D3DGPU_SIZE_T size) {
|
||||
reserveGpuVirtualAddressResult.called++;
|
||||
return Wddm::reserveGpuVirtualAddress(minimumAddress, maximumAddress, size);
|
||||
if (failReserveGpuVirtualAddress) {
|
||||
D3DGPU_VIRTUAL_ADDRESS nullAddress = {};
|
||||
return nullAddress;
|
||||
}
|
||||
return Wddm::reserveGpuVirtualAddress(baseAddress, minimumAddress, maximumAddress, size);
|
||||
}
|
||||
|
||||
uint64_t *WddmMock::getPagingFenceAddress() {
|
||||
|
||||
@@ -89,7 +89,7 @@ class WddmMock : public Wddm {
|
||||
void virtualFree(void *ptr, size_t size) override;
|
||||
void releaseReservedAddress(void *reservedAddress) override;
|
||||
VOID *registerTrimCallback(PFND3DKMT_TRIMNOTIFICATIONCALLBACK callback, WddmResidencyController &residencyController) override;
|
||||
D3DGPU_VIRTUAL_ADDRESS reserveGpuVirtualAddress(D3DGPU_VIRTUAL_ADDRESS minimumAddress, D3DGPU_VIRTUAL_ADDRESS maximumAddress, D3DGPU_SIZE_T size) override;
|
||||
D3DGPU_VIRTUAL_ADDRESS reserveGpuVirtualAddress(D3DGPU_VIRTUAL_ADDRESS baseAddress, D3DGPU_VIRTUAL_ADDRESS minimumAddress, D3DGPU_VIRTUAL_ADDRESS maximumAddress, D3DGPU_SIZE_T size) override;
|
||||
bool reserveValidAddressRange(size_t size, void *&reservedMem) override;
|
||||
PLATFORM *getGfxPlatform() { return gfxPlatform.get(); }
|
||||
uint64_t *getPagingFenceAddress() override;
|
||||
@@ -185,5 +185,6 @@ class WddmMock : public Wddm {
|
||||
bool shutdownStatus = false;
|
||||
bool callBaseSetAllocationPriority = true;
|
||||
bool callBaseWaitFromCpu = true;
|
||||
bool failReserveGpuVirtualAddress = false;
|
||||
};
|
||||
} // namespace NEO
|
||||
|
||||
@@ -352,7 +352,7 @@ TEST_F(DeviceGetCapsTest, givenFlagEnabled64kbPagesWhenCallConstructorMemoryMana
|
||||
};
|
||||
uint64_t getLocalMemorySize(uint32_t rootDeviceIndex, uint32_t deviceBitfield) override { return 0; };
|
||||
double getPercentOfGlobalMemoryAvailable(uint32_t rootDeviceIndex) override { return 0; }
|
||||
AddressRange reserveGpuAddress(size_t size, uint32_t rootDeviceIndex) override {
|
||||
AddressRange reserveGpuAddress(const void *requiredStartAddress, size_t size, RootDeviceIndicesContainer rootDeviceIndices, uint32_t *reservedOnRootDeviceIndex) override {
|
||||
return {};
|
||||
}
|
||||
void freeGpuAddress(AddressRange addressRange, uint32_t rootDeviceIndex) override{};
|
||||
|
||||
@@ -234,7 +234,10 @@ TEST_F(DrmMemoryManagerTest, GivenGraphicsAllocationWhenAddAndRemoveAllocationTo
|
||||
|
||||
TEST_F(DrmMemoryManagerWithExplicitExpectationsTest, givenDrmMemoryManagerWhenGpuAddressIsReservedAndFreedThenAddressFromGfxPartitionIsUsed) {
|
||||
auto memoryManager = std::make_unique<TestedDrmMemoryManager>(false, true, false, *executionEnvironment);
|
||||
auto addressRange = memoryManager->reserveGpuAddress(MemoryConstants::pageSize, 0);
|
||||
RootDeviceIndicesContainer rootDevices;
|
||||
rootDevices.push_back(0);
|
||||
uint32_t rootDeviceIndexReserved = 1;
|
||||
auto addressRange = memoryManager->reserveGpuAddress(nullptr, MemoryConstants::pageSize, rootDevices, &rootDeviceIndexReserved);
|
||||
auto gmmHelper = memoryManager->getGmmHelper(0);
|
||||
|
||||
EXPECT_LE(memoryManager->getGfxPartition(0)->getHeapBase(HeapIndex::HEAP_STANDARD), gmmHelper->decanonize(addressRange.address));
|
||||
@@ -242,6 +245,30 @@ TEST_F(DrmMemoryManagerWithExplicitExpectationsTest, givenDrmMemoryManagerWhenGp
|
||||
memoryManager->freeGpuAddress(addressRange, 0);
|
||||
}
|
||||
|
||||
TEST_F(DrmMemoryManagerWithExplicitExpectationsTest, givenDrmMemoryManagerWhenGpuAddressReservationIsAttemptedWithARequiredPtrThenNullRangeReturned) {
|
||||
auto memoryManager = std::make_unique<TestedDrmMemoryManager>(false, true, false, *executionEnvironment);
|
||||
void *requiredPtr = reinterpret_cast<void *>(0x1234);
|
||||
RootDeviceIndicesContainer rootDevices;
|
||||
rootDevices.push_back(0);
|
||||
uint32_t rootDeviceIndexReserved = 1;
|
||||
auto addressRange = memoryManager->reserveGpuAddress(requiredPtr, MemoryConstants::pageSize, rootDevices, &rootDeviceIndexReserved);
|
||||
EXPECT_EQ(static_cast<int>(addressRange.address), 0);
|
||||
EXPECT_EQ(static_cast<int>(addressRange.size), 0);
|
||||
}
|
||||
|
||||
TEST_F(DrmMemoryManagerWithExplicitExpectationsTest, givenDrmMemoryManagerWhenGpuAddressReservationIsAttemptedWhichFailsThenNullRangeReturned) {
|
||||
auto memoryManager = std::make_unique<TestedDrmMemoryManager>(false, true, false, *executionEnvironment);
|
||||
RootDeviceIndicesContainer rootDevices;
|
||||
rootDevices.push_back(0);
|
||||
uint32_t rootDeviceIndexReserved = 1;
|
||||
// emulate GPU address space exhaust
|
||||
memoryManager->forceLimitedRangeAllocator(0xFFFFFFFFF);
|
||||
memoryManager->getGfxPartition(0)->heapInit(HeapIndex::HEAP_STANDARD, 0x0, 0x10000);
|
||||
size_t invalidSize = (size_t)memoryManager->getGfxPartition(0)->getHeapLimit(HeapIndex::HEAP_STANDARD) + MemoryConstants::pageSize;
|
||||
auto addressRange = memoryManager->reserveGpuAddress(nullptr, invalidSize, rootDevices, &rootDeviceIndexReserved);
|
||||
EXPECT_EQ(static_cast<int>(addressRange.address), 0);
|
||||
}
|
||||
|
||||
TEST_F(DrmMemoryManagerWithExplicitExpectationsTest, givenSmallSizeAndGpuAddressSetWhenGraphicsMemoryIsAllocatedThenAllocationWithSpecifiedGpuAddressInSystemMemoryIsCreated) {
|
||||
auto memoryManager = std::make_unique<TestedDrmMemoryManager>(false, true, false, *executionEnvironment);
|
||||
auto osContext = device->getDefaultEngine().osContext;
|
||||
|
||||
@@ -28,6 +28,7 @@ if(WIN32)
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wddm_shared_allocations_test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wddm_special_heap_test.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wddm_tests.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wddm_memory_reservation_tests.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "shared/source/execution_environment/root_device_environment.h"
|
||||
#include "shared/source/gmm_helper/gmm_helper.h"
|
||||
#include "shared/source/os_interface/device_factory.h"
|
||||
#include "shared/source/os_interface/os_interface.h"
|
||||
#include "shared/test/common/fixtures/device_fixture.h"
|
||||
#include "shared/test/common/helpers/debug_manager_state_restore.h"
|
||||
#include "shared/test/common/mocks/mock_wddm.h"
|
||||
#include "shared/test/common/os_interface/windows/mock_wddm_memory_manager.h"
|
||||
#include "shared/test/common/test_macros/hw_test.h"
|
||||
|
||||
namespace NEO {
|
||||
|
||||
struct MemoryReservationMock : public MockWddmMemoryManager {
|
||||
using MemoryManager::freeGpuAddress;
|
||||
using MemoryManager::reserveGpuAddress;
|
||||
MemoryReservationMock(NEO::ExecutionEnvironment &executionEnvironment) : MockWddmMemoryManager(executionEnvironment) {}
|
||||
};
|
||||
|
||||
class WddmMemManagerFixture {
|
||||
public:
|
||||
void setUp() {
|
||||
executionEnvironment = std::make_unique<ExecutionEnvironment>();
|
||||
executionEnvironment->prepareRootDeviceEnvironments(1);
|
||||
executionEnvironment->rootDeviceEnvironments[0]->setHwInfo(defaultHwInfo.get());
|
||||
executionEnvironment->rootDeviceEnvironments[0]->initGmm();
|
||||
|
||||
DeviceFactory::prepareDeviceEnvironments(*executionEnvironment);
|
||||
auto wddm = static_cast<WddmMock *>(executionEnvironment->rootDeviceEnvironments[0]->osInterface->getDriverModel()->as<Wddm>());
|
||||
wddm->callBaseMapGpuVa = false;
|
||||
memManager = std::unique_ptr<MemoryReservationMock>(new MemoryReservationMock(*executionEnvironment));
|
||||
}
|
||||
void tearDown() {
|
||||
}
|
||||
std::unique_ptr<MemoryReservationMock> memManager;
|
||||
std::unique_ptr<ExecutionEnvironment> executionEnvironment;
|
||||
};
|
||||
|
||||
typedef ::Test<WddmMemManagerFixture> WddmMemoryReservationTests;
|
||||
|
||||
TEST_F(WddmMemoryReservationTests, givenWddmMemoryManagerWhenGpuAddressIsReservedAndFreedThenAddressFromGfxPartitionIsUsed) {
|
||||
RootDeviceIndicesContainer rootDevices;
|
||||
rootDevices.push_back(0);
|
||||
uint32_t rootDeviceIndexReserved = 1;
|
||||
auto addressRange = memManager->reserveGpuAddress(nullptr, MemoryConstants::pageSize64k, rootDevices, &rootDeviceIndexReserved);
|
||||
auto gmmHelper = memManager->getGmmHelper(0);
|
||||
|
||||
EXPECT_LE(memManager->getGfxPartition(0)->getHeapBase(HeapIndex::HEAP_STANDARD64KB), gmmHelper->decanonize(addressRange.address));
|
||||
EXPECT_GT(memManager->getGfxPartition(0)->getHeapLimit(HeapIndex::HEAP_STANDARD64KB), gmmHelper->decanonize(addressRange.address));
|
||||
memManager->freeGpuAddress(addressRange, 0);
|
||||
}
|
||||
|
||||
TEST(WddmMemoryReservationFailTest, givenWddmMemoryManagerWhenGpuAddressReservationIsAttemptedThenNullPtrAndSizeReturned) {
|
||||
std::unique_ptr<MemoryReservationMock> memManager;
|
||||
std::unique_ptr<ExecutionEnvironment> executionEnvironment;
|
||||
|
||||
executionEnvironment = std::make_unique<ExecutionEnvironment>();
|
||||
executionEnvironment->prepareRootDeviceEnvironments(1);
|
||||
executionEnvironment->rootDeviceEnvironments[0]->setHwInfo(defaultHwInfo.get());
|
||||
executionEnvironment->rootDeviceEnvironments[0]->initGmm();
|
||||
|
||||
DeviceFactory::prepareDeviceEnvironments(*executionEnvironment);
|
||||
auto wddm = static_cast<WddmMock *>(executionEnvironment->rootDeviceEnvironments[0]->osInterface->getDriverModel()->as<Wddm>());
|
||||
wddm->callBaseMapGpuVa = false;
|
||||
wddm->failReserveGpuVirtualAddress = true;
|
||||
memManager = std::unique_ptr<MemoryReservationMock>(new MemoryReservationMock(*executionEnvironment));
|
||||
|
||||
RootDeviceIndicesContainer rootDevices;
|
||||
rootDevices.push_back(0);
|
||||
uint32_t rootDeviceIndexReserved = 1;
|
||||
auto addressRange = memManager->reserveGpuAddress(nullptr, MemoryConstants::pageSize64k, rootDevices, &rootDeviceIndexReserved);
|
||||
EXPECT_EQ(addressRange.address, 0ull);
|
||||
EXPECT_EQ(addressRange.size, 0u);
|
||||
}
|
||||
} // namespace NEO
|
||||
Reference in New Issue
Block a user