Add support for createInternalGraphicsAllocation in DRM

Change-Id: I84090dfc4774506dee993e9c0c78c336367c43fd
This commit is contained in:
Mrozek, Michal
2018-02-28 15:12:10 +01:00
committed by sys_ocldev
parent 9e9876cd17
commit 0b8234117b
4 changed files with 115 additions and 13 deletions

View File

@@ -40,7 +40,8 @@ class Drm;
enum StorageAllocatorType {
MMAP_ALLOCATOR,
BIT32_ALLOCATOR,
BIT32_ALLOCATOR_EXTERNAL,
BIT32_ALLOCATOR_INTERNAL,
MALLOC_ALLOCATOR,
EXTERNAL_ALLOCATOR,
UNKNOWN_ALLOCATOR

View File

@@ -124,7 +124,12 @@ uint32_t DrmMemoryManager::unreference(OCLRT::BufferObject *bo, bool synchronous
if (allocatorType == MMAP_ALLOCATOR) {
munmapFunction(address, unmapSize);
} else {
allocator32Bit->free(address, unmapSize);
if (allocatorType == BIT32_ALLOCATOR_EXTERNAL) {
allocator32Bit->free(address, unmapSize);
} else {
UNRECOVERABLE_IF(allocatorType != BIT32_ALLOCATOR_INTERNAL)
internal32bitAllocator->free(address, unmapSize);
}
}
} else {
@@ -247,11 +252,14 @@ GraphicsAllocation *DrmMemoryManager::allocateGraphicsMemoryForImage(ImageInfo &
}
DrmAllocation *DrmMemoryManager::allocate32BitGraphicsMemory(size_t size, void *ptr, MemoryType memoryType) {
auto allocatorToUse = memoryType == MemoryType::EXTERNAL_ALLOCATION ? allocator32Bit.get() : internal32bitAllocator.get();
auto allocationType = memoryType == MemoryType::EXTERNAL_ALLOCATION ? BIT32_ALLOCATOR_EXTERNAL : BIT32_ALLOCATOR_INTERNAL;
if (ptr) {
uintptr_t inputPtr = (uintptr_t)ptr;
auto allocationSize = alignSizeWholePage((void *)ptr, size);
auto realAllocationSize = allocationSize;
auto gpuVirtualAddress = allocator32Bit->allocate(realAllocationSize);
auto gpuVirtualAddress = allocatorToUse->allocate(realAllocationSize);
if (!gpuVirtualAddress) {
return nullptr;
}
@@ -260,7 +268,7 @@ DrmAllocation *DrmMemoryManager::allocate32BitGraphicsMemory(size_t size, void *
BufferObject *bo = allocUserptr(alignedUserPointer, allocationSize, 0, true);
if (!bo) {
allocator32Bit->free(gpuVirtualAddress, realAllocationSize);
allocatorToUse->free(gpuVirtualAddress, realAllocationSize);
return nullptr;
}
@@ -269,18 +277,19 @@ DrmAllocation *DrmMemoryManager::allocate32BitGraphicsMemory(size_t size, void *
bo->address = gpuVirtualAddress;
uintptr_t offset = (uintptr_t)bo->address;
bo->softPin((uint64_t)offset);
bo->setAllocationType(allocationType);
auto drmAllocation = new DrmAllocation(bo, (void *)ptr, (uint64_t)ptrOffset(gpuVirtualAddress, inputPointerOffset), allocationSize);
drmAllocation->is32BitAllocation = true;
drmAllocation->gpuBaseAddress = allocator32Bit->getBase();
drmAllocation->gpuBaseAddress = allocatorToUse->getBase();
return drmAllocation;
}
size_t alignedAllocationSize = alignUp(size, MemoryConstants::pageSize);
auto allocationSize = alignedAllocationSize;
auto res = allocator32Bit->allocate(allocationSize);
auto res = allocatorToUse->allocate(allocationSize);
if (!res) {
if (device && device->getProgramCount() == 0) {
if (memoryType == MemoryType::EXTERNAL_ALLOCATION && device && device->getProgramCount() == 0) {
this->force32bitAllocations = false;
device->setForce32BitAddressing(false);
return (DrmAllocation *)createGraphicsAllocationWithRequiredBitness(size, ptr);
@@ -292,19 +301,25 @@ DrmAllocation *DrmMemoryManager::allocate32BitGraphicsMemory(size_t size, void *
BufferObject *bo = allocUserptr(reinterpret_cast<uintptr_t>(res), alignedAllocationSize, 0, true);
if (!bo) {
allocator32Bit->free(res, allocationSize);
allocatorToUse->free(res, allocationSize);
return nullptr;
}
bo->isAllocated = true;
bo->setUnmapSize(allocationSize);
bo->setAllocationType(allocationType);
auto drmAllocation = new DrmAllocation(bo, res, alignedAllocationSize);
drmAllocation->is32BitAllocation = true;
drmAllocation->gpuBaseAddress = allocator32Bit->getBase();
drmAllocation->gpuBaseAddress = allocatorToUse->getBase();
return drmAllocation;
}
GraphicsAllocation *DrmMemoryManager::createInternalGraphicsAllocation(const void *ptr, size_t allocationSize) {
return allocate32BitGraphicsMemory(allocationSize, const_cast<void *>(ptr), MemoryType::INTERNAL_ALLOCATION);
}
BufferObject *DrmMemoryManager::findAndReferenceSharedBufferObject(int boHandle) {
BufferObject *bo = nullptr;
@@ -326,7 +341,7 @@ BufferObject *DrmMemoryManager::createSharedBufferObject(int boHandle, size_t si
if (requireSpecificBitness && this->force32bitAllocations) {
gpuRange = this->allocator32Bit->allocate(size);
storageType = BIT32_ALLOCATOR;
storageType = BIT32_ALLOCATOR_EXTERNAL;
} else {
gpuRange = mmapFunction(nullptr, size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0);
storageType = MMAP_ALLOCATOR;

View File

@@ -53,6 +53,7 @@ class DrmMemoryManager : public MemoryManager {
DrmAllocation *allocateGraphicsMemory(size_t size, const void *ptr, bool forcePin) override;
GraphicsAllocation *allocateGraphicsMemoryForImage(ImageInfo &imgInfo, Gmm *gmm) override;
DrmAllocation *allocate32BitGraphicsMemory(size_t size, void *ptr, MemoryType memoryType) override;
GraphicsAllocation *createInternalGraphicsAllocation(const void *ptr, size_t allocationSize) override;
GraphicsAllocation *createGraphicsAllocationFromSharedHandle(osHandle handle, bool requireSpecificBitness, bool reuseBO) override;
GraphicsAllocation *createPaddedAllocation(GraphicsAllocation *inputGraphicsAllocation, size_t sizeWithPadding) override;
GraphicsAllocation *createGraphicsAllocationFromNTHandle(void *handle) override { return nullptr; }

View File

@@ -304,8 +304,6 @@ TEST_F(DrmMemoryManagerTest, doNotPinAfterAllocateWhenAskedButNotAllowedHostPtr)
::alignedFree(ptr);
}
/* ---- */
TEST_F(DrmMemoryManagerTest, unreference) {
mock->ioctl_expected = 2; //create+close
BufferObject *bo = memoryManager->allocUserptr(0, (size_t)1024, 0ul, true);
@@ -613,6 +611,8 @@ TEST_F(DrmMemoryManagerTest, givenMemoryManagerWhenAskedFor32BitAllocationThen32
EXPECT_EQ(memoryManager->allocator32Bit->getBase(), allocation->gpuBaseAddress);
EXPECT_EQ(bo->peekAllocationType(), StorageAllocatorType::BIT32_ALLOCATOR_EXTERNAL);
memoryManager->freeGraphicsMemory(allocation);
}
@@ -990,6 +990,26 @@ TEST_F(DrmMemoryManagerTest, Given32BitDeviceWithMemoryManagerWhenAllHeapsAreExh
}
}
TEST_F(DrmMemoryManagerTest, Given32BitDeviceWithMemoryManagerWhenInternalHeapIsExhaustedAndNewAllocationsIsMadeThenNullIsReturned) {
DebugManager.flags.Force32bitAddressing.set(true);
mock->ioctl_expected = 0;
memoryManager->setForce32BitAllocations(true);
std::unique_ptr<Device> pDevice(Device::create<OCLRT::MockDevice>(nullptr));
memoryManager->device = pDevice.get();
auto allocator = memoryManager->getDrmInternal32BitAllocator();
size_t size = 4 * GB - 4096;
auto alloc = allocator->allocate(size);
EXPECT_NE(nullptr, alloc);
size_t allocationSize = 4096 * 3;
auto graphicsAllocation = memoryManager->createInternalGraphicsAllocation(nullptr, allocationSize);
EXPECT_EQ(nullptr, graphicsAllocation);
EXPECT_TRUE(memoryManager->device->getDeviceInfo().force32BitAddressess);
DebugManager.flags.Force32bitAddressing.set(false);
}
TEST_F(DrmMemoryManagerTest, GivenMemoryManagerWhenAllocateGraphicsMemoryForImageIsCalledThenProperIoctlsAreCalledAndUnmapSizeIsNonZero) {
//GEM CREATE + SET_TILING + WAIT + CLOSE
mock->ioctl_expected = 4;
@@ -1332,7 +1352,7 @@ TEST_F(DrmMemoryManagerTest, given32BitAddressingWhenBufferFromSharedHandleAndBi
auto drmAllocation = (DrmAllocation *)graphicsAllocation;
EXPECT_TRUE(graphicsAllocation->is32BitAllocation);
EXPECT_EQ(1, lseekCalledCount);
EXPECT_EQ(BIT32_ALLOCATOR, drmAllocation->getBO()->peekAllocationType());
EXPECT_EQ(BIT32_ALLOCATOR_EXTERNAL, drmAllocation->getBO()->peekAllocationType());
memoryManager->freeGraphicsMemory(graphicsAllocation);
EXPECT_EQ(0, mmapMockCallCount);
EXPECT_EQ(0, munmapMockCallCount);
@@ -1495,6 +1515,71 @@ TEST_F(DrmMemoryManagerTest, givenMemoryManagerSupportingVirutalPaddingWhenItIsR
memoryManager->freeGraphicsMemory(buffer);
}
TEST_F(DrmMemoryManagerTest, givenMemoryManagerWhenAskedForInternalAllocationWithNoPointerThenAllocationFromInternalHeapIsReturned) {
mock->ioctl_expected = 3;
auto bufferSize = MemoryConstants::pageSize;
void *ptr = nullptr;
auto drmAllocation = (DrmAllocation *)memoryManager->createInternalGraphicsAllocation(ptr, bufferSize);
ASSERT_NE(nullptr, drmAllocation);
auto internalAllocator = memoryManager->getDrmInternal32BitAllocator();
EXPECT_NE(nullptr, drmAllocation->getUnderlyingBuffer());
EXPECT_EQ(bufferSize, drmAllocation->getUnderlyingBufferSize());
EXPECT_TRUE(drmAllocation->is32BitAllocation);
auto gpuPtr = drmAllocation->getGpuAddress();
auto heapBase = internalAllocator->getBase();
auto heapSize = 4 * GB;
EXPECT_GE(gpuPtr, heapBase);
EXPECT_LE(gpuPtr, heapBase + heapSize);
EXPECT_EQ(drmAllocation->gpuBaseAddress, heapBase);
auto bo = drmAllocation->getBO();
EXPECT_TRUE(bo->peekIsAllocated());
EXPECT_EQ(bo->peekAllocationType(), StorageAllocatorType::BIT32_ALLOCATOR_INTERNAL);
EXPECT_EQ(bo->peekUnmapSize(), bufferSize);
memoryManager->freeGraphicsMemory(drmAllocation);
}
TEST_F(DrmMemoryManagerTest, givenMemoryManagerWhenAskedForInternalAllocationWithPointerThenAllocationFromInternalHeapIsReturned) {
mock->ioctl_expected = 3;
auto bufferSize = MemoryConstants::pageSize;
void *ptr = (void *)0x100000;
auto drmAllocation = (DrmAllocation *)memoryManager->createInternalGraphicsAllocation(ptr, bufferSize);
ASSERT_NE(nullptr, drmAllocation);
auto internalAllocator = memoryManager->getDrmInternal32BitAllocator();
EXPECT_NE(nullptr, drmAllocation->getUnderlyingBuffer());
EXPECT_EQ(ptr, drmAllocation->getUnderlyingBuffer());
EXPECT_EQ(bufferSize, drmAllocation->getUnderlyingBufferSize());
EXPECT_TRUE(drmAllocation->is32BitAllocation);
auto gpuPtr = drmAllocation->getGpuAddress();
auto heapBase = internalAllocator->getBase();
auto heapSize = 4 * GB;
EXPECT_GE(gpuPtr, heapBase);
EXPECT_LE(gpuPtr, heapBase + heapSize);
EXPECT_EQ(drmAllocation->gpuBaseAddress, heapBase);
auto bo = drmAllocation->getBO();
EXPECT_FALSE(bo->peekIsAllocated());
EXPECT_EQ(bo->peekAllocationType(), StorageAllocatorType::BIT32_ALLOCATOR_INTERNAL);
EXPECT_EQ(bo->peekUnmapSize(), bufferSize);
memoryManager->freeGraphicsMemory(drmAllocation);
}
TEST_F(DrmMemoryManagerTest, givenMemoryManagerSupportingVirutalPaddingWhenAllocUserptrFailsThenReturnsNullptr) {
mock->ioctl_expected = 7;