2017-12-21 07:45:38 +08:00
|
|
|
/*
|
2018-09-17 20:03:37 +08:00
|
|
|
* Copyright (C) 2017-2018 Intel Corporation
|
2017-12-21 07:45:38 +08:00
|
|
|
*
|
2018-09-17 20:03:37 +08:00
|
|
|
* SPDX-License-Identifier: MIT
|
2017-12-21 07:45:38 +08:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#pragma once
|
2018-07-23 01:27:33 +08:00
|
|
|
#include "runtime/helpers/aligned_memory.h"
|
|
|
|
#include "runtime/memory_manager/graphics_allocation.h"
|
2017-12-21 07:45:38 +08:00
|
|
|
#include "runtime/memory_manager/host_ptr_defines.h"
|
|
|
|
#include "runtime/os_interface/32bit_memory.h"
|
2018-11-26 21:04:52 +08:00
|
|
|
#include "engine_node.h"
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
#include <cstdint>
|
|
|
|
#include <mutex>
|
2018-07-23 01:27:33 +08:00
|
|
|
#include <vector>
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
namespace OCLRT {
|
2018-10-09 17:50:58 +08:00
|
|
|
class AllocationsList;
|
2017-12-21 07:45:38 +08:00
|
|
|
class Device;
|
|
|
|
class DeferredDeleter;
|
2018-10-01 22:10:54 +08:00
|
|
|
class ExecutionEnvironment;
|
2017-12-21 07:45:38 +08:00
|
|
|
class GraphicsAllocation;
|
2018-10-24 14:46:54 +08:00
|
|
|
class HostPtrManager;
|
2017-12-21 07:45:38 +08:00
|
|
|
class CommandStreamReceiver;
|
2018-10-22 22:43:20 +08:00
|
|
|
class OsContext;
|
2018-11-21 16:57:51 +08:00
|
|
|
class OSInterface;
|
2017-12-21 07:45:38 +08:00
|
|
|
class AllocsTracker;
|
|
|
|
class MapBaseAllocationTracker;
|
|
|
|
class SVMAllocsManager;
|
|
|
|
|
2018-07-05 22:31:57 +08:00
|
|
|
enum AllocationUsage {
|
2017-12-21 07:45:38 +08:00
|
|
|
TEMPORARY_ALLOCATION,
|
|
|
|
REUSABLE_ALLOCATION
|
|
|
|
};
|
|
|
|
|
2018-05-11 23:24:00 +08:00
|
|
|
enum AllocationOrigin {
|
2018-02-27 18:08:22 +08:00
|
|
|
EXTERNAL_ALLOCATION,
|
|
|
|
INTERNAL_ALLOCATION
|
|
|
|
};
|
|
|
|
|
2018-09-17 20:03:37 +08:00
|
|
|
struct AllocationFlags {
|
|
|
|
union {
|
|
|
|
struct {
|
|
|
|
uint32_t allocateMemory : 1;
|
|
|
|
uint32_t flushL3RequiredForRead : 1;
|
|
|
|
uint32_t flushL3RequiredForWrite : 1;
|
|
|
|
uint32_t reserved : 29;
|
|
|
|
} flags;
|
|
|
|
uint32_t allFlags;
|
|
|
|
};
|
|
|
|
|
|
|
|
static_assert(sizeof(AllocationFlags::flags) == sizeof(AllocationFlags::allFlags), "");
|
|
|
|
|
|
|
|
AllocationFlags() {
|
|
|
|
allFlags = 0;
|
|
|
|
flags.flushL3RequiredForRead = 1;
|
|
|
|
flags.flushL3RequiredForWrite = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
AllocationFlags(bool allocateMemory) {
|
|
|
|
allFlags = 0;
|
|
|
|
flags.flushL3RequiredForRead = 1;
|
|
|
|
flags.flushL3RequiredForWrite = 1;
|
|
|
|
flags.allocateMemory = allocateMemory;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2018-07-09 20:12:32 +08:00
|
|
|
struct AllocationData {
|
|
|
|
union {
|
|
|
|
struct {
|
|
|
|
uint32_t mustBeZeroCopy : 1;
|
|
|
|
uint32_t allocateMemory : 1;
|
|
|
|
uint32_t allow64kbPages : 1;
|
|
|
|
uint32_t allow32Bit : 1;
|
|
|
|
uint32_t useSystemMemory : 1;
|
|
|
|
uint32_t forcePin : 1;
|
|
|
|
uint32_t uncacheable : 1;
|
2018-09-21 12:07:50 +08:00
|
|
|
uint32_t flushL3 : 1;
|
|
|
|
uint32_t reserved : 24;
|
2018-07-09 20:12:32 +08:00
|
|
|
} flags;
|
|
|
|
uint32_t allFlags = 0;
|
|
|
|
};
|
|
|
|
static_assert(sizeof(AllocationData::flags) == sizeof(AllocationData::allFlags), "");
|
|
|
|
|
|
|
|
GraphicsAllocation::AllocationType type = GraphicsAllocation::AllocationType::UNKNOWN;
|
|
|
|
const void *hostPtr = nullptr;
|
|
|
|
size_t size = 0;
|
2018-09-23 21:47:27 +08:00
|
|
|
DevicesBitfield devicesBitfield = 0;
|
2018-07-09 20:12:32 +08:00
|
|
|
};
|
|
|
|
|
2018-01-22 23:43:26 +08:00
|
|
|
struct AlignedMallocRestrictions {
|
|
|
|
uintptr_t minAddress;
|
|
|
|
};
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
constexpr size_t paddingBufferSize = 2 * MemoryConstants::megaByte;
|
|
|
|
|
|
|
|
class Gmm;
|
|
|
|
struct ImageInfo;
|
|
|
|
|
|
|
|
class MemoryManager {
|
|
|
|
public:
|
2018-02-28 19:09:48 +08:00
|
|
|
enum AllocationStatus {
|
|
|
|
Success = 0,
|
|
|
|
Error,
|
|
|
|
InvalidHostPointer,
|
2018-07-18 15:48:21 +08:00
|
|
|
RetryInNonDevicePool
|
2018-02-28 19:09:48 +08:00
|
|
|
};
|
|
|
|
|
2018-10-01 22:10:54 +08:00
|
|
|
MemoryManager(bool enable64kbpages, bool enableLocalMemory, ExecutionEnvironment &executionEnvironment);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
virtual ~MemoryManager();
|
2018-01-26 23:53:18 +08:00
|
|
|
MOCKABLE_VIRTUAL void *allocateSystemMemory(size_t size, size_t alignment);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2018-05-08 16:00:23 +08:00
|
|
|
virtual void addAllocationToHostPtrManager(GraphicsAllocation *memory) = 0;
|
|
|
|
virtual void removeAllocationFromHostPtrManager(GraphicsAllocation *memory) = 0;
|
|
|
|
|
2018-07-09 20:12:32 +08:00
|
|
|
GraphicsAllocation *allocateGraphicsMemory(size_t size) {
|
|
|
|
return allocateGraphicsMemory(size, MemoryConstants::preferredAlignment, false, false);
|
2017-12-21 07:45:38 +08:00
|
|
|
}
|
|
|
|
|
2018-01-05 00:48:46 +08:00
|
|
|
virtual GraphicsAllocation *allocateGraphicsMemory(size_t size, size_t alignment, bool forcePin, bool uncacheable) = 0;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2018-07-23 01:27:33 +08:00
|
|
|
virtual GraphicsAllocation *allocateGraphicsMemory64kb(size_t size, size_t alignment, bool forcePin, bool preferRenderCompressed) = 0;
|
2018-08-24 21:23:45 +08:00
|
|
|
virtual GraphicsAllocation *allocateGraphicsMemoryForNonSvmHostPtr(size_t size, void *cpuPtr) = 0;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
virtual GraphicsAllocation *allocateGraphicsMemory(size_t size, const void *ptr) {
|
|
|
|
return MemoryManager::allocateGraphicsMemory(size, ptr, false);
|
|
|
|
}
|
|
|
|
virtual GraphicsAllocation *allocateGraphicsMemory(size_t size, const void *ptr, bool forcePin);
|
|
|
|
|
2018-11-05 21:26:45 +08:00
|
|
|
GraphicsAllocation *allocateGraphicsMemoryForHostPtr(size_t size, void *ptr, bool fullRangeSvm, bool requiresL3Flush) {
|
2018-09-10 18:50:45 +08:00
|
|
|
if (fullRangeSvm) {
|
|
|
|
return allocateGraphicsMemory(size, ptr);
|
|
|
|
} else {
|
2018-11-05 21:26:45 +08:00
|
|
|
auto allocation = allocateGraphicsMemoryForNonSvmHostPtr(size, ptr);
|
|
|
|
if (allocation) {
|
|
|
|
allocation->flushL3Required = requiresL3Flush;
|
|
|
|
}
|
|
|
|
return allocation;
|
2018-09-10 18:50:45 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-09 20:12:32 +08:00
|
|
|
virtual GraphicsAllocation *allocate32BitGraphicsMemory(size_t size, const void *ptr, AllocationOrigin allocationOrigin) = 0;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
virtual GraphicsAllocation *allocateGraphicsMemoryForImage(ImageInfo &imgInfo, Gmm *gmm) = 0;
|
|
|
|
|
2018-09-23 21:47:27 +08:00
|
|
|
MOCKABLE_VIRTUAL GraphicsAllocation *allocateGraphicsMemoryInPreferredPool(AllocationFlags flags, DevicesBitfield devicesBitfield, const void *hostPtr, size_t size, GraphicsAllocation::AllocationType type);
|
2018-07-09 20:12:32 +08:00
|
|
|
|
2017-12-28 18:25:43 +08:00
|
|
|
GraphicsAllocation *allocateGraphicsMemoryForSVM(size_t size, bool coherent);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
2018-08-29 20:50:36 +08:00
|
|
|
virtual GraphicsAllocation *createGraphicsAllocationFromSharedHandle(osHandle handle, bool requireSpecificBitness) = 0;
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
virtual GraphicsAllocation *createGraphicsAllocationFromNTHandle(void *handle) = 0;
|
|
|
|
|
2018-07-18 15:48:21 +08:00
|
|
|
virtual GraphicsAllocation *allocateGraphicsMemoryInDevicePool(const AllocationData &allocationData, AllocationStatus &status) {
|
|
|
|
status = AllocationStatus::Error;
|
|
|
|
if (!allocationData.flags.useSystemMemory && !(allocationData.flags.allow32Bit && this->force32bitAllocations)) {
|
|
|
|
auto allocation = allocateGraphicsMemory(allocationData);
|
|
|
|
if (allocation) {
|
2018-09-23 21:47:27 +08:00
|
|
|
allocation->devicesBitfield = allocationData.devicesBitfield;
|
2018-09-21 12:07:50 +08:00
|
|
|
allocation->flushL3Required = allocationData.flags.flushL3;
|
2018-07-18 15:48:21 +08:00
|
|
|
status = AllocationStatus::Success;
|
|
|
|
}
|
|
|
|
return allocation;
|
|
|
|
}
|
|
|
|
status = AllocationStatus::RetryInNonDevicePool;
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2018-01-25 22:10:07 +08:00
|
|
|
virtual bool mapAuxGpuVA(GraphicsAllocation *graphicsAllocation) { return false; };
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
virtual void *lockResource(GraphicsAllocation *graphicsAllocation) = 0;
|
|
|
|
virtual void unlockResource(GraphicsAllocation *graphicsAllocation) = 0;
|
|
|
|
|
|
|
|
void cleanGraphicsMemoryCreatedFromHostPtr(GraphicsAllocation *);
|
|
|
|
GraphicsAllocation *createGraphicsAllocationWithPadding(GraphicsAllocation *inputGraphicsAllocation, size_t sizeWithPadding);
|
|
|
|
virtual GraphicsAllocation *createPaddedAllocation(GraphicsAllocation *inputGraphicsAllocation, size_t sizeWithPadding);
|
|
|
|
|
2018-02-28 19:09:48 +08:00
|
|
|
virtual AllocationStatus populateOsHandles(OsHandleStorage &handleStorage) = 0;
|
2017-12-21 07:45:38 +08:00
|
|
|
virtual void cleanOsHandles(OsHandleStorage &handleStorage) = 0;
|
|
|
|
|
|
|
|
void freeSystemMemory(void *ptr);
|
|
|
|
|
|
|
|
virtual void freeGraphicsMemoryImpl(GraphicsAllocation *gfxAllocation) = 0;
|
|
|
|
|
|
|
|
void freeGraphicsMemory(GraphicsAllocation *gfxAllocation);
|
|
|
|
|
2018-01-19 17:55:36 +08:00
|
|
|
void checkGpuUsageAndDestroyGraphicsAllocations(GraphicsAllocation *gfxAllocation);
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
virtual uint64_t getSystemSharedMemory() = 0;
|
|
|
|
|
|
|
|
virtual uint64_t getMaxApplicationAddress() = 0;
|
|
|
|
|
2018-03-12 22:24:46 +08:00
|
|
|
virtual uint64_t getInternalHeapBaseAddress() = 0;
|
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
virtual GraphicsAllocation *createGraphicsAllocation(OsHandleStorage &handleStorage, size_t hostPtrSize, const void *hostPtr) = 0;
|
|
|
|
|
2018-07-11 15:45:20 +08:00
|
|
|
bool peek64kbPagesEnabled() const { return enable64kbpages; }
|
2017-12-21 07:45:38 +08:00
|
|
|
bool peekForce32BitAllocations() { return force32bitAllocations; }
|
2018-02-28 16:27:38 +08:00
|
|
|
void setForce32BitAllocations(bool newValue);
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
std::unique_ptr<Allocator32bit> allocator32Bit;
|
|
|
|
|
|
|
|
bool peekVirtualPaddingSupport() { return virtualPaddingAvailable; }
|
|
|
|
void setVirtualPaddingSupport(bool virtualPaddingSupport) { virtualPaddingAvailable = virtualPaddingSupport; }
|
|
|
|
GraphicsAllocation *peekPaddingAllocation() { return paddingAllocation; }
|
|
|
|
|
|
|
|
DeferredDeleter *getDeferredDeleter() const {
|
|
|
|
return deferredDeleter.get();
|
|
|
|
}
|
|
|
|
|
2018-05-10 16:16:22 +08:00
|
|
|
void waitForDeletions();
|
2017-12-21 07:45:38 +08:00
|
|
|
|
|
|
|
bool isAsyncDeleterEnabled() const;
|
2018-10-12 21:20:02 +08:00
|
|
|
bool isLocalMemorySupported() const;
|
2017-12-21 07:45:38 +08:00
|
|
|
virtual bool isMemoryBudgetExhausted() const;
|
|
|
|
|
2018-01-22 23:43:26 +08:00
|
|
|
virtual AlignedMallocRestrictions *getAlignedMallocRestrictions() {
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
MOCKABLE_VIRTUAL void *alignedMallocWrapper(size_t bytes, size_t alignment) {
|
|
|
|
return ::alignedMalloc(bytes, alignment);
|
|
|
|
}
|
|
|
|
|
|
|
|
MOCKABLE_VIRTUAL void alignedFreeWrapper(void *ptr) {
|
|
|
|
::alignedFree(ptr);
|
|
|
|
}
|
|
|
|
|
2018-11-26 21:04:52 +08:00
|
|
|
OsContext *createAndRegisterOsContext(EngineInstanceT engineType);
|
2018-11-07 20:04:10 +08:00
|
|
|
uint32_t getOsContextCount() { return static_cast<uint32_t>(registeredOsContexts.size()); }
|
2018-10-01 22:10:54 +08:00
|
|
|
CommandStreamReceiver *getCommandStreamReceiver(uint32_t contextId);
|
2018-10-24 14:46:54 +08:00
|
|
|
HostPtrManager *getHostPtrManager() const { return hostPtrManager.get(); }
|
2018-09-06 15:01:13 +08:00
|
|
|
|
2017-12-21 07:45:38 +08:00
|
|
|
protected:
|
2018-09-23 21:47:27 +08:00
|
|
|
static bool getAllocationData(AllocationData &allocationData, const AllocationFlags &flags, const DevicesBitfield devicesBitfield,
|
2018-09-21 12:07:50 +08:00
|
|
|
const void *hostPtr, size_t size, GraphicsAllocation::AllocationType type);
|
2018-07-09 20:12:32 +08:00
|
|
|
|
|
|
|
GraphicsAllocation *allocateGraphicsMemory(const AllocationData &allocationData);
|
2017-12-21 07:45:38 +08:00
|
|
|
bool force32bitAllocations = false;
|
|
|
|
bool virtualPaddingAvailable = false;
|
|
|
|
GraphicsAllocation *paddingAllocation = nullptr;
|
|
|
|
void applyCommonCleanup();
|
|
|
|
std::unique_ptr<DeferredDeleter> deferredDeleter;
|
|
|
|
bool asyncDeleterEnabled = false;
|
|
|
|
bool enable64kbpages = false;
|
2018-09-06 16:53:35 +08:00
|
|
|
bool localMemorySupported = false;
|
2018-10-01 22:10:54 +08:00
|
|
|
ExecutionEnvironment &executionEnvironment;
|
2018-09-06 15:01:13 +08:00
|
|
|
std::vector<OsContext *> registeredOsContexts;
|
2018-10-24 14:46:54 +08:00
|
|
|
std::unique_ptr<HostPtrManager> hostPtrManager;
|
2018-11-21 16:57:51 +08:00
|
|
|
uint32_t latestContextId = std::numeric_limits<uint32_t>::max();
|
2017-12-21 07:45:38 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
std::unique_ptr<DeferredDeleter> createDeferredDeleter();
|
|
|
|
} // namespace OCLRT
|