diff --git a/runtime/memory_manager/graphics_allocation.cpp b/runtime/memory_manager/graphics_allocation.cpp index 447d55fb2d..ea8e7ecca0 100644 --- a/runtime/memory_manager/graphics_allocation.cpp +++ b/runtime/memory_manager/graphics_allocation.cpp @@ -16,19 +16,19 @@ bool GraphicsAllocation::isL3Capable() { } return false; } -GraphicsAllocation::GraphicsAllocation(void *cpuPtrIn, uint64_t gpuAddress, uint64_t baseAddress, size_t sizeIn, uint32_t osContextCount, bool isShareable) : gpuBaseAddress(baseAddress), - size(sizeIn), - cpuPtr(cpuPtrIn), - gpuAddress(gpuAddress), - isShareable(isShareable) { +GraphicsAllocation::GraphicsAllocation(void *cpuPtrIn, uint64_t gpuAddress, uint64_t baseAddress, size_t sizeIn, uint32_t osContextCount, bool shareable) : gpuBaseAddress(baseAddress), + size(sizeIn), + cpuPtr(cpuPtrIn), + gpuAddress(gpuAddress), + shareable(shareable) { usageInfos.resize(maxOsContextCount); } -GraphicsAllocation::GraphicsAllocation(void *cpuPtrIn, size_t sizeIn, osHandle sharedHandleIn, uint32_t osContextCount, bool isShareable) : size(sizeIn), - cpuPtr(cpuPtrIn), - gpuAddress(castToUint64(cpuPtrIn)), - sharedHandle(sharedHandleIn), - isShareable(isShareable) { +GraphicsAllocation::GraphicsAllocation(void *cpuPtrIn, size_t sizeIn, osHandle sharedHandleIn, uint32_t osContextCount, bool shareable) : size(sizeIn), + cpuPtr(cpuPtrIn), + gpuAddress(castToUint64(cpuPtrIn)), + sharedHandle(sharedHandleIn), + shareable(shareable) { usageInfos.resize(maxOsContextCount); } GraphicsAllocation::~GraphicsAllocation() = default; diff --git a/runtime/memory_manager/graphics_allocation.h b/runtime/memory_manager/graphics_allocation.h index 8ab6f83188..84cf0de46f 100644 --- a/runtime/memory_manager/graphics_allocation.h +++ b/runtime/memory_manager/graphics_allocation.h @@ -133,6 +133,8 @@ class GraphicsAllocation : public IDNode { void resetResidencyTaskCount(uint32_t contextId) { updateResidencyTaskCount(objectNotResident, contextId); } bool isResidencyTaskCountBelow(uint32_t taskCount, uint32_t contextId) { return !isResident(contextId) || getResidencyTaskCount(contextId) < taskCount; } + bool isShareable() const { return shareable; } + protected: constexpr static uint32_t objectNotResident = (uint32_t)-1; constexpr static uint32_t objectNotUsed = (uint32_t)-1; @@ -160,6 +162,6 @@ class GraphicsAllocation : public IDNode { bool memObjectsAllocationWithWritableFlags = false; std::vector usageInfos; std::atomic registeredContextsNum{0}; - bool isShareable = false; + bool shareable = false; }; } // namespace OCLRT diff --git a/runtime/memory_manager/memory_manager.cpp b/runtime/memory_manager/memory_manager.cpp index f0a87df6ba..3b0f81964f 100644 --- a/runtime/memory_manager/memory_manager.cpp +++ b/runtime/memory_manager/memory_manager.cpp @@ -193,6 +193,7 @@ bool MemoryManager::getAllocationData(AllocationData &allocationData, const Allo bool forcePin = properties.flags.forcePin; bool uncacheable = properties.flags.uncacheable; bool mustBeZeroCopy = false; + bool shareable = properties.flags.shareable; switch (properties.allocationType) { case GraphicsAllocation::AllocationType::BUFFER: @@ -254,6 +255,7 @@ bool MemoryManager::getAllocationData(AllocationData &allocationData, const Allo allocationData.flags.uncacheable = uncacheable; allocationData.flags.flushL3 = properties.flags.flushL3RequiredForRead | properties.flags.flushL3RequiredForWrite; allocationData.flags.preferRenderCompressed = GraphicsAllocation::AllocationType::BUFFER_COMPRESSED == properties.allocationType; + allocationData.flags.shareable = shareable; if (allocationData.flags.mustBeZeroCopy) { allocationData.flags.useSystemMemory = true; diff --git a/runtime/memory_manager/memory_manager.h b/runtime/memory_manager/memory_manager.h index ac82790e78..11ac9d6bda 100644 --- a/runtime/memory_manager/memory_manager.h +++ b/runtime/memory_manager/memory_manager.h @@ -45,7 +45,8 @@ struct AllocationProperties { uint32_t flushL3RequiredForWrite : 1; uint32_t forcePin : 1; uint32_t uncacheable : 1; - uint32_t reserved : 27; + uint32_t shareable : 1; + uint32_t reserved : 26; } flags; uint32_t allFlags = 0; }; @@ -201,7 +202,8 @@ class MemoryManager { uint32_t uncacheable : 1; uint32_t flushL3 : 1; uint32_t preferRenderCompressed : 1; - uint32_t reserved : 23; + uint32_t shareable : 1; + uint32_t reserved : 22; } flags; uint32_t allFlags = 0; }; diff --git a/runtime/memory_manager/os_agnostic_memory_manager.cpp b/runtime/memory_manager/os_agnostic_memory_manager.cpp index 293a07d956..4f415a3737 100644 --- a/runtime/memory_manager/os_agnostic_memory_manager.cpp +++ b/runtime/memory_manager/os_agnostic_memory_manager.cpp @@ -37,7 +37,7 @@ GraphicsAllocation *OsAgnosticMemoryManager::allocateGraphicsMemoryWithAlignment if (fakeBigAllocations && allocationData.size > bigAllocation) { memoryAllocation = new MemoryAllocation(nullptr, (void *)dummyAddress, static_cast(dummyAddress), allocationData.size, counter, - MemoryPool::System4KBPages, this->getOsContextCount(), false); + MemoryPool::System4KBPages, this->getOsContextCount(), allocationData.flags.shareable); counter++; memoryAllocation->uncacheable = allocationData.flags.uncacheable; return memoryAllocation; @@ -45,7 +45,7 @@ GraphicsAllocation *OsAgnosticMemoryManager::allocateGraphicsMemoryWithAlignment auto ptr = allocateSystemMemory(sizeAligned, allocationData.alignment ? alignUp(allocationData.alignment, MemoryConstants::pageSize) : MemoryConstants::pageSize); if (ptr != nullptr) { memoryAllocation = new MemoryAllocation(ptr, ptr, reinterpret_cast(ptr), allocationData.size, counter, MemoryPool::System4KBPages, - this->getOsContextCount(), false); + this->getOsContextCount(), allocationData.flags.shareable); if (!memoryAllocation) { alignedFreeWrapper(ptr); return nullptr; diff --git a/runtime/os_interface/linux/drm_memory_manager.cpp b/runtime/os_interface/linux/drm_memory_manager.cpp index d30b9bb3e4..195fb45ebd 100644 --- a/runtime/os_interface/linux/drm_memory_manager.cpp +++ b/runtime/os_interface/linux/drm_memory_manager.cpp @@ -228,7 +228,7 @@ DrmAllocation *DrmMemoryManager::allocateGraphicsMemoryWithAlignment(const Alloc if (forcePinEnabled && pinBB != nullptr && allocationData.flags.forcePin && allocationData.size >= this->pinThreshold) { pinBB->pin(&bo, 1, getDefaultCommandStreamReceiver(0)->getOsContext().get()->getDrmContextId()); } - return new DrmAllocation(bo, res, cSize, MemoryPool::System4KBPages, getOsContextCount(), false); + return new DrmAllocation(bo, res, cSize, MemoryPool::System4KBPages, getOsContextCount(), allocationData.flags.shareable); } DrmAllocation *DrmMemoryManager::allocateGraphicsMemoryWithHostPtr(const AllocationData &allocationData) { diff --git a/runtime/os_interface/windows/wddm_memory_manager.cpp b/runtime/os_interface/windows/wddm_memory_manager.cpp index 08f4d09988..a2fe5a6dfd 100644 --- a/runtime/os_interface/windows/wddm_memory_manager.cpp +++ b/runtime/os_interface/windows/wddm_memory_manager.cpp @@ -67,7 +67,7 @@ GraphicsAllocation *WddmMemoryManager::allocateGraphicsMemory64kb(AllocationData size_t sizeAligned = alignUp(allocationData.size, MemoryConstants::pageSize64k); Gmm *gmm = nullptr; - auto wddmAllocation = std::make_unique(nullptr, sizeAligned, nullptr, MemoryPool::System64KBPages, getOsContextCount(), false); + auto wddmAllocation = std::make_unique(nullptr, sizeAligned, nullptr, MemoryPool::System64KBPages, getOsContextCount(), !!allocationData.flags.shareable); gmm = new Gmm(nullptr, sizeAligned, false, allocationData.flags.preferRenderCompressed, true); wddmAllocation->gmm = gmm; @@ -98,7 +98,7 @@ GraphicsAllocation *WddmMemoryManager::allocateGraphicsMemoryWithAlignment(const return nullptr; } - auto wddmAllocation = std::make_unique(pSysMem, sizeAligned, nullptr, MemoryPool::System4KBPages, getOsContextCount(), false); + auto wddmAllocation = std::make_unique(pSysMem, sizeAligned, nullptr, MemoryPool::System4KBPages, getOsContextCount(), allocationData.flags.shareable); wddmAllocation->driverAllocatedCpuPointer = pSysMem; gmm = new Gmm(pSysMem, sizeAligned, allocationData.flags.uncacheable); diff --git a/unit_tests/memory_manager/memory_manager_allocate_in_preferred_pool_tests.inl b/unit_tests/memory_manager/memory_manager_allocate_in_preferred_pool_tests.inl index cd1cedd638..66f5fc27d8 100644 --- a/unit_tests/memory_manager/memory_manager_allocate_in_preferred_pool_tests.inl +++ b/unit_tests/memory_manager/memory_manager_allocate_in_preferred_pool_tests.inl @@ -377,3 +377,31 @@ TEST(MemoryManagerTest, givenTimestampTagBufferTypeWhenGetAllocationDataIsCalled MockMemoryManager::getAllocationData(allocData, {1, GraphicsAllocation::AllocationType::TIMESTAMP_TAG_BUFFER}, 0, nullptr); EXPECT_TRUE(allocData.flags.useSystemMemory); } + +TEST(MemoryManagerTest, givenAllocationPropertiesWithShareableFlagEnabledWhenAllocateMemoryThenAllocationIsShareable) { + MockMemoryManager memoryManager(false); + AllocationProperties properties{MemoryConstants::pageSize, GraphicsAllocation::AllocationType::BUFFER}; + properties.flags.shareable = true; + + AllocationData allocData; + MockMemoryManager::getAllocationData(allocData, properties, 0, nullptr); + EXPECT_TRUE(allocData.flags.shareable); + + auto allocation = memoryManager.allocateGraphicsMemoryWithProperties(properties); + EXPECT_TRUE(allocation->isShareable()); + memoryManager.freeGraphicsMemory(allocation); +} + +TEST(MemoryManagerTest, givenAllocationPropertiesWithShareableFlagDisabledWhenAllocateMemoryThenAllocationIsNotShareable) { + MockMemoryManager memoryManager(false); + AllocationProperties properties{MemoryConstants::pageSize, GraphicsAllocation::AllocationType::BUFFER}; + properties.flags.shareable = false; + + AllocationData allocData; + MockMemoryManager::getAllocationData(allocData, properties, 0, nullptr); + EXPECT_FALSE(allocData.flags.shareable); + + auto allocation = memoryManager.allocateGraphicsMemoryWithProperties(properties); + EXPECT_FALSE(allocation->isShareable()); + memoryManager.freeGraphicsMemory(allocation); +} diff --git a/unit_tests/mocks/mock_memory_manager.cpp b/unit_tests/mocks/mock_memory_manager.cpp index 26f1c9be53..b5ec3fd1f9 100644 --- a/unit_tests/mocks/mock_memory_manager.cpp +++ b/unit_tests/mocks/mock_memory_manager.cpp @@ -30,7 +30,9 @@ void *MockMemoryManager::allocateSystemMemory(size_t size, size_t alignment) { } GraphicsAllocation *MockMemoryManager::allocateGraphicsMemoryWithProperties(const AllocationProperties &properties) { - return OsAgnosticMemoryManager::allocateGraphicsMemoryWithProperties({redundancyRatio * properties.size, properties.allocationType}); + AllocationProperties adjustedProperties(properties); + adjustedProperties.size = redundancyRatio * properties.size; + return OsAgnosticMemoryManager::allocateGraphicsMemoryWithProperties(adjustedProperties); } GraphicsAllocation *MockMemoryManager::allocateGraphicsMemoryForImage(ImageInfo &imgInfo, const void *hostPtr) { diff --git a/unit_tests/os_interface/linux/drm_memory_manager_tests.cpp b/unit_tests/os_interface/linux/drm_memory_manager_tests.cpp index 1453e1c6cb..6ee08a242d 100644 --- a/unit_tests/os_interface/linux/drm_memory_manager_tests.cpp +++ b/unit_tests/os_interface/linux/drm_memory_manager_tests.cpp @@ -651,6 +651,26 @@ TEST_F(DrmMemoryManagerTest, GivenNoInputsWhenOsHandleIsCreatedThenAllBoHandlesA EXPECT_EQ(nullptr, boHandle2->bo); } +TEST_F(DrmMemoryManagerTest, givenAllocationPropertiesWithShareableFlagEnabledWhenAllocateMemoryThenAllocationIsShareable) { + mock->ioctl_expected.total = -1; + AllocationProperties properties{MemoryConstants::pageSize, GraphicsAllocation::AllocationType::BUFFER}; + properties.flags.shareable = true; + + auto allocation = memoryManager->allocateGraphicsMemoryWithProperties(properties); + EXPECT_TRUE(allocation->isShareable()); + memoryManager->freeGraphicsMemory(allocation); +} + +TEST_F(DrmMemoryManagerTest, givenAllocationPropertiesWithShareableFlagDisabledWhenAllocateMemoryThenAllocationIsNotShareable) { + mock->ioctl_expected.total = -1; + AllocationProperties properties{MemoryConstants::pageSize, GraphicsAllocation::AllocationType::BUFFER}; + properties.flags.shareable = false; + + auto allocation = memoryManager->allocateGraphicsMemoryWithProperties(properties); + EXPECT_FALSE(allocation->isShareable()); + memoryManager->freeGraphicsMemory(allocation); +} + TEST_F(DrmMemoryManagerTest, GivenPointerAndSizeWhenAskedToCreateGrahicsAllocationThenGraphicsAllocationIsCreated) { OsHandleStorage handleStorage; auto ptr = reinterpret_cast(0x1000); diff --git a/unit_tests/os_interface/windows/wddm_memory_manager_tests.cpp b/unit_tests/os_interface/windows/wddm_memory_manager_tests.cpp index 7c0ebedbc2..c3bd253798 100644 --- a/unit_tests/os_interface/windows/wddm_memory_manager_tests.cpp +++ b/unit_tests/os_interface/windows/wddm_memory_manager_tests.cpp @@ -228,6 +228,24 @@ TEST_F(WddmMemoryManagerTest, givenDefaultWddmMemoryManagerWhenAskedForVirtualPa EXPECT_FALSE(memoryManager->peekVirtualPaddingSupport()); } +TEST_F(WddmMemoryManagerTest, givenAllocationPropertiesWithShareableFlagEnabledWhenAllocateMemoryThenAllocationIsShareable) { + AllocationProperties properties{MemoryConstants::pageSize, GraphicsAllocation::AllocationType::BUFFER}; + properties.flags.shareable = true; + + auto allocation = memoryManager->allocateGraphicsMemoryWithProperties(properties); + EXPECT_TRUE(allocation->isShareable()); + memoryManager->freeGraphicsMemory(allocation); +} + +TEST_F(WddmMemoryManagerTest, givenAllocationPropertiesWithShareableFlagDisabledWhenAllocateMemoryThenAllocationIsNotShareable) { + AllocationProperties properties{MemoryConstants::pageSize, GraphicsAllocation::AllocationType::BUFFER}; + properties.flags.shareable = false; + + auto allocation = memoryManager->allocateGraphicsMemoryWithProperties(properties); + EXPECT_FALSE(allocation->isShareable()); + memoryManager->freeGraphicsMemory(allocation); +} + TEST_F(WddmMemoryManagerTest, GivenGraphicsAllocationWhenAddAndRemoveAllocationToHostPtrManagerThenfragmentHasCorrectValues) { void *cpuPtr = (void *)0x30000; size_t size = 0x1000;