From 0b7d2da162eee87df32d985f95fbe91e3c231542 Mon Sep 17 00:00:00 2001 From: Krzysztof Gibala Date: Wed, 24 Mar 2021 13:19:30 +0000 Subject: [PATCH] Create image allocations in system memory pool Create image allocations in multi device setup in system memory pool Related-To: NEO-5508 Signed-off-by: Krzysztof Gibala --- opencl/source/mem_obj/image.cpp | 45 ++++++++++++-- .../unit_test/api/cl_create_image_tests.cpp | 48 +++++++++++++++ opencl/test/unit_test/mem_obj/image_tests.cpp | 59 +++++++++++++++---- ...nager_allocate_in_preferred_pool_tests.inl | 54 +++++++++++++---- .../memory_manager/memory_manager_tests.cpp | 38 ++++++++++++ .../memory_manager/allocation_properties.h | 3 +- .../source/memory_manager/memory_manager.cpp | 3 +- 7 files changed, 219 insertions(+), 31 deletions(-) diff --git a/opencl/source/mem_obj/image.cpp b/opencl/source/mem_obj/image.cpp index f100c7c4c9..ee5a9c288e 100644 --- a/opencl/source/mem_obj/image.cpp +++ b/opencl/source/mem_obj/image.cpp @@ -239,6 +239,8 @@ Image *Image::create(Context *context, AllocationInfoType allocationInfo; allocationInfo.resize(maxRootDeviceIndex + 1u); bool isParentObject = parentBuffer || parentImage; + void *cpuPtr = nullptr; + void *hostPtrForced = nullptr; for (auto &rootDeviceIndex : context->getRootDeviceIndices()) { allocationInfo[rootDeviceIndex] = {}; @@ -321,11 +323,39 @@ Image *Image::create(Context *context, allocationInfo[rootDeviceIndex].mapAllocation = memoryManager->allocateGraphicsMemoryWithProperties(properties, hostPtr); } } else { - AllocationProperties allocProperties = MemObjHelper::getAllocationPropertiesWithImageInfo(rootDeviceIndex, imgInfo, - true, // allocateMemory - memoryProperties, hwInfo, - context->getDeviceBitfieldForAllocation(rootDeviceIndex)); - allocationInfo[rootDeviceIndex].memory = memoryManager->allocateGraphicsMemoryWithProperties(allocProperties); + if (context->getRootDeviceIndices().size() > 1) { + MemoryProperties memoryPropertiesToSet = memoryProperties; + memoryPropertiesToSet.flags.useHostPtr = true; + memoryPropertiesToSet.flags.copyHostPtr = false; + + if (cpuPtr) { + AllocationProperties allocProperties = MemObjHelper::getAllocationPropertiesWithImageInfo(rootDeviceIndex, imgInfo, + false, // allocateMemory + const_cast(memoryPropertiesToSet), hwInfo, + context->getDeviceBitfieldForAllocation(rootDeviceIndex)); + allocProperties.flags.crossRootDeviceAccess = true; + + allocationInfo[rootDeviceIndex].memory = memoryManager->allocateGraphicsMemoryWithProperties(allocProperties, cpuPtr); + } else { + AllocationProperties allocProperties = MemObjHelper::getAllocationPropertiesWithImageInfo(rootDeviceIndex, imgInfo, + false, // allocateMemory + const_cast(memoryPropertiesToSet), hwInfo, + context->getDeviceBitfieldForAllocation(rootDeviceIndex)); + allocProperties.flags.crossRootDeviceAccess = true; + + hostPtrForced = alignedMalloc(hostPtrMinSize, MemoryConstants::pageSize64k); + allocationInfo[rootDeviceIndex].memory = memoryManager->allocateGraphicsMemoryWithProperties(allocProperties, hostPtrForced); + if (allocationInfo[rootDeviceIndex].memory) { + cpuPtr = reinterpret_cast(allocationInfo[rootDeviceIndex].memory->getUnderlyingBuffer()); + } + } + } else { + AllocationProperties allocProperties = MemObjHelper::getAllocationPropertiesWithImageInfo(rootDeviceIndex, imgInfo, + true, // allocateMemory + memoryProperties, hwInfo, + context->getDeviceBitfieldForAllocation(rootDeviceIndex)); + allocationInfo[rootDeviceIndex].memory = memoryManager->allocateGraphicsMemoryWithProperties(allocProperties); + } if (allocationInfo[rootDeviceIndex].memory && MemoryPool::isSystemMemoryPool(allocationInfo[rootDeviceIndex].memory->getMemoryPool())) { allocationInfo[rootDeviceIndex].zeroCopyAllowed = true; @@ -336,6 +366,9 @@ Image *Image::create(Context *context, if (!allocationInfo[rootDeviceIndex].memory) { cleanAllGraphicsAllocations(*context, *memoryManager, allocationInfo, isParentObject); + if (hostPtrForced) { + alignedFree(hostPtrForced); + } return image; } @@ -371,6 +404,8 @@ Image *Image::create(Context *context, image = createImageHw(context, memoryProperties, flags, flagsIntel, imgInfo.size, hostPtrToSet, surfaceFormat->OCLImageFormat, imageDescriptor, allocationInfo[defaultRootDeviceIndex].zeroCopyAllowed, std::move(multiGraphicsAllocation), false, 0, 0, surfaceFormat); + image->setAllocatedMapPtr(hostPtrForced); + for (auto &rootDeviceIndex : context->getRootDeviceIndices()) { auto &hwInfo = *memoryManager->peekExecutionEnvironment().rootDeviceEnvironments[rootDeviceIndex]->getHardwareInfo(); diff --git a/opencl/test/unit_test/api/cl_create_image_tests.cpp b/opencl/test/unit_test/api/cl_create_image_tests.cpp index 86331d576f..fab0841aae 100644 --- a/opencl/test/unit_test/api/cl_create_image_tests.cpp +++ b/opencl/test/unit_test/api/cl_create_image_tests.cpp @@ -12,6 +12,7 @@ #include "opencl/source/mem_obj/image.h" #include "opencl/test/unit_test/helpers/unit_test_helper.h" #include "opencl/test/unit_test/mocks/mock_cl_device.h" +#include "opencl/test/unit_test/mocks/mock_memory_manager.h" #include "opencl/test/unit_test/test_macros/test_checks_ocl.h" #include "cl_api_tests.h" @@ -1400,4 +1401,51 @@ TEST_F(clCreateImageWithMultiDeviceContextTests, GivenImageCreatedWithContextdWi clReleaseContext(context); } +TEST_F(clCreateImageWithMultiDeviceContextTests, GivenContextdWithMultiDeviceFailingAllocationThenImageAllocateFails) { + REQUIRE_IMAGES_OR_SKIP(defaultHwInfo); + + UltClDeviceFactory deviceFactory{2, 0}; + DebugManager.flags.EnableMultiRootDeviceContexts.set(true); + + cl_device_id devices[] = {deviceFactory.rootDevices[0], deviceFactory.rootDevices[1]}; + + MockContext pContext(ClDeviceVector(devices, 2)); + + EXPECT_EQ(1u, pContext.getMaxRootDeviceIndex()); + + auto bufferSize = imageDesc.image_width * imageDesc.image_height * 4; + + cl_mem_flags flags = CL_MEM_COPY_HOST_PTR; + + { + auto hostBuffer = alignedMalloc(bufferSize, MemoryConstants::pageSize64k); + auto ptrHostBuffer = static_cast(hostBuffer); + + static_cast(pContext.memoryManager)->successAllocatedGraphicsMemoryIndex = 0u; + static_cast(pContext.memoryManager)->maxSuccessAllocatedGraphicsMemoryIndex = 0u; + + auto image = clCreateImage(&pContext, flags, &imageFormat, &imageDesc, ptrHostBuffer, &retVal); + + ASSERT_EQ(CL_OUT_OF_HOST_MEMORY, retVal); + EXPECT_EQ(nullptr, image); + + alignedFree(hostBuffer); + } + + { + auto hostBuffer = alignedMalloc(bufferSize, MemoryConstants::pageSize64k); + auto ptrHostBuffer = static_cast(hostBuffer); + + static_cast(pContext.memoryManager)->successAllocatedGraphicsMemoryIndex = 0u; + static_cast(pContext.memoryManager)->maxSuccessAllocatedGraphicsMemoryIndex = 1u; + + auto image = clCreateImage(&pContext, flags, &imageFormat, &imageDesc, ptrHostBuffer, &retVal); + + ASSERT_EQ(CL_OUT_OF_HOST_MEMORY, retVal); + EXPECT_EQ(nullptr, image); + + alignedFree(hostBuffer); + } +} + } // namespace ClCreateImageTests diff --git a/opencl/test/unit_test/mem_obj/image_tests.cpp b/opencl/test/unit_test/mem_obj/image_tests.cpp index f883cbb780..881c9c359e 100644 --- a/opencl/test/unit_test/mem_obj/image_tests.cpp +++ b/opencl/test/unit_test/mem_obj/image_tests.cpp @@ -1604,6 +1604,20 @@ TEST_F(ImageMultiRootDeviceTests, WhenImageIsCreatedThenImageAllocationHasCorrec EXPECT_EQ(expectedRootDeviceIndex, graphicsAllocation->getRootDeviceIndex()); } +TEST_F(ImageMultiRootDeviceTests, WhenImageIsCreatedWithoutHostPtrThenImageMultiGraphicsAllocationIsCreatedInSystemMemoryPool) { + REQUIRE_IMAGES_OR_SKIP(defaultHwInfo); + + std::unique_ptr image(ImageHelper::create(context.get())); + + EXPECT_TRUE(MemoryPool::isSystemMemoryPool(image->getMultiGraphicsAllocation().getGraphicsAllocation(1u)->getMemoryPool())); + EXPECT_TRUE(MemoryPool::isSystemMemoryPool(image->getMultiGraphicsAllocation().getGraphicsAllocation(2u)->getMemoryPool())); + + auto graphicsAllocation1 = image->getMultiGraphicsAllocation().getGraphicsAllocation(1u); + auto graphicsAllocation2 = image->getMultiGraphicsAllocation().getGraphicsAllocation(2u); + + EXPECT_EQ(graphicsAllocation2->getUnderlyingBuffer(), graphicsAllocation1->getUnderlyingBuffer()); +} + TEST_F(ImageMultiRootDeviceTests, WhenImageIsCreatedAndEnqueueWriteImageCalledThenImageMultiGraphicsAllocationLastUsedRootDeviceIndexHasCorrectRootDeviceIndex) { REQUIRE_IMAGES_OR_SKIP(defaultHwInfo); @@ -1624,7 +1638,7 @@ TEST_F(ImageMultiRootDeviceTests, WhenImageIsCreatedAndEnqueueWriteImageCalledTh desc.image_height = height * sizeof(unsigned int); auto bufferSize = sizeof(unsigned int) * width * height; - auto hostBuffer = alignedMalloc(bufferSize, 64 * 1024); + auto hostBuffer = alignedMalloc(bufferSize, MemoryConstants::pageSize64k); cl_mem_flags flags = CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR; @@ -1674,7 +1688,7 @@ TEST_F(ImageMultiRootDeviceTests, WhenImageIsCreatedAndEnqueueReadImageCalledThe desc.image_height = height * sizeof(unsigned int); auto bufferSize = sizeof(unsigned int) * width * height; - auto hostBuffer = alignedMalloc(bufferSize, 64 * 1024); + auto hostBuffer = alignedMalloc(bufferSize, MemoryConstants::pageSize64k); cl_mem_flags flags = CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR; @@ -1724,7 +1738,7 @@ TEST_F(ImageMultiRootDeviceTests, WhenImageIsCreatedAndEnqueueFillImageCalledThe desc.image_height = height * sizeof(unsigned int); auto bufferSize = sizeof(unsigned int) * width * height; - auto hostBuffer = alignedMalloc(bufferSize, 64 * 1024); + auto hostBuffer = alignedMalloc(bufferSize, MemoryConstants::pageSize64k); cl_mem_flags flags = CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR; @@ -1774,13 +1788,17 @@ TEST_F(ImageMultiRootDeviceTests, WhenImageIsCreatedAndEnqueueCopyImageCalledThe desc.image_width = width * sizeof(unsigned int); desc.image_height = height * sizeof(unsigned int); - cl_mem_flags flags = CL_MEM_READ_WRITE; + cl_mem_flags flags = CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR; + + auto bufferSize = sizeof(unsigned int) * width * height; + auto hostBuffer1 = alignedMalloc(bufferSize, MemoryConstants::pageSize64k); + auto hostBuffer2 = alignedMalloc(bufferSize, MemoryConstants::pageSize64k); auto surfaceFormat = Image::getSurfaceFormatFromTable( flags, &format, context->getDevice(0)->getHardwareInfo().capabilityTable.supportsOcl21Features); - std::unique_ptr image1(Image::create(context.get(), MemoryPropertiesHelper::createMemoryProperties(flags, 0, 0, &context->getDevice(0)->getDevice()), flags, 0, surfaceFormat, &desc, nullptr, retVal)); - std::unique_ptr image2(Image::create(context.get(), MemoryPropertiesHelper::createMemoryProperties(flags, 0, 0, &context->getDevice(0)->getDevice()), flags, 0, surfaceFormat, &desc, nullptr, retVal)); + std::unique_ptr image1(Image::create(context.get(), MemoryPropertiesHelper::createMemoryProperties(flags, 0, 0, &context->getDevice(0)->getDevice()), flags, 0, surfaceFormat, &desc, hostBuffer1, retVal)); + std::unique_ptr image2(Image::create(context.get(), MemoryPropertiesHelper::createMemoryProperties(flags, 0, 0, &context->getDevice(0)->getDevice()), flags, 0, surfaceFormat, &desc, hostBuffer2, retVal)); auto cmdQ1 = context->getSpecialQueue(1u); cmdQ1->enqueueCopyImage(image1.get(), image2.get(), orgin, orgin, region, 0, nullptr, nullptr); @@ -1804,6 +1822,9 @@ TEST_F(ImageMultiRootDeviceTests, WhenImageIsCreatedAndEnqueueCopyImageCalledThe cmdQ2->enqueueCopyImage(image1.get(), image2.get(), orgin, orgin, region, 0, nullptr, nullptr); EXPECT_EQ(image1->getMultiGraphicsAllocation().getLastUsedRootDeviceIndex(), 2u); EXPECT_EQ(image2->getMultiGraphicsAllocation().getLastUsedRootDeviceIndex(), 2u); + + alignedFree(hostBuffer2); + alignedFree(hostBuffer1); } TEST_F(ImageMultiRootDeviceTests, WhenImageIsCreatedAndEnqueueCopyImageToBufferCalledThenImageAndBufferMultiGraphicsAllocationsLastUsedRootDeviceIndexHasCorrectRootDeviceIndex) { @@ -1825,13 +1846,17 @@ TEST_F(ImageMultiRootDeviceTests, WhenImageIsCreatedAndEnqueueCopyImageToBufferC desc.image_width = width * sizeof(unsigned int); desc.image_height = height * sizeof(unsigned int); - cl_mem_flags flags = CL_MEM_READ_WRITE; + cl_mem_flags flags = CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR; + + auto bufferSize = sizeof(unsigned int) * width * height; + auto hostBuffer1 = alignedMalloc(bufferSize, MemoryConstants::pageSize64k); + auto hostBuffer2 = alignedMalloc(bufferSize, MemoryConstants::pageSize64k); auto surfaceFormat = Image::getSurfaceFormatFromTable( flags, &format, context->getDevice(0)->getHardwareInfo().capabilityTable.supportsOcl21Features); - std::unique_ptr image(Image::create(context.get(), MemoryPropertiesHelper::createMemoryProperties(flags, 0, 0, &context->getDevice(0)->getDevice()), flags, 0, surfaceFormat, &desc, nullptr, retVal)); - std::unique_ptr buffer(Buffer::create(context.get(), flags, MemoryConstants::pageSize, nullptr, retVal)); + std::unique_ptr image(Image::create(context.get(), MemoryPropertiesHelper::createMemoryProperties(flags, 0, 0, &context->getDevice(0)->getDevice()), flags, 0, surfaceFormat, &desc, hostBuffer1, retVal)); + std::unique_ptr buffer(Buffer::create(context.get(), flags, MemoryConstants::pageSize, hostBuffer2, retVal)); auto cmdQ1 = context->getSpecialQueue(1u); cmdQ1->enqueueCopyImageToBuffer(image.get(), buffer.get(), orgin, region, 0, 0, nullptr, nullptr); @@ -1855,6 +1880,9 @@ TEST_F(ImageMultiRootDeviceTests, WhenImageIsCreatedAndEnqueueCopyImageToBufferC cmdQ2->enqueueCopyImageToBuffer(image.get(), buffer.get(), orgin, region, 0, 0, nullptr, nullptr); EXPECT_EQ(image->getMultiGraphicsAllocation().getLastUsedRootDeviceIndex(), 2u); EXPECT_EQ(buffer->getMultiGraphicsAllocation().getLastUsedRootDeviceIndex(), 2u); + + alignedFree(hostBuffer2); + alignedFree(hostBuffer1); } TEST_F(ImageMultiRootDeviceTests, WhenImageIsCreatedAndEnqueueCopyBufferToImageCalledThenImageAndBufferMultiGraphicsAllocationsLastUsedRootDeviceIndexHasCorrectRootDeviceIndex) { @@ -1876,13 +1904,17 @@ TEST_F(ImageMultiRootDeviceTests, WhenImageIsCreatedAndEnqueueCopyBufferToImageC desc.image_width = width * sizeof(unsigned int); desc.image_height = height * sizeof(unsigned int); - cl_mem_flags flags = CL_MEM_READ_WRITE; + cl_mem_flags flags = CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR; + + auto bufferSize = sizeof(unsigned int) * width * height; + auto hostBuffer1 = alignedMalloc(bufferSize, MemoryConstants::pageSize64k); + auto hostBuffer2 = alignedMalloc(bufferSize, MemoryConstants::pageSize64k); auto surfaceFormat = Image::getSurfaceFormatFromTable( flags, &format, context->getDevice(0)->getHardwareInfo().capabilityTable.supportsOcl21Features); - std::unique_ptr image(Image::create(context.get(), MemoryPropertiesHelper::createMemoryProperties(flags, 0, 0, &context->getDevice(0)->getDevice()), flags, 0, surfaceFormat, &desc, nullptr, retVal)); - std::unique_ptr buffer(Buffer::create(context.get(), flags, MemoryConstants::pageSize, nullptr, retVal)); + std::unique_ptr image(Image::create(context.get(), MemoryPropertiesHelper::createMemoryProperties(flags, 0, 0, &context->getDevice(0)->getDevice()), flags, 0, surfaceFormat, &desc, hostBuffer1, retVal)); + std::unique_ptr buffer(Buffer::create(context.get(), flags, MemoryConstants::pageSize, hostBuffer2, retVal)); auto cmdQ1 = context->getSpecialQueue(1u); cmdQ1->enqueueCopyBufferToImage(buffer.get(), image.get(), 0, orgin, region, 0, nullptr, nullptr); @@ -1906,4 +1938,7 @@ TEST_F(ImageMultiRootDeviceTests, WhenImageIsCreatedAndEnqueueCopyBufferToImageC cmdQ2->enqueueCopyBufferToImage(buffer.get(), image.get(), 0, orgin, region, 0, nullptr, nullptr); EXPECT_EQ(image->getMultiGraphicsAllocation().getLastUsedRootDeviceIndex(), 2u); EXPECT_EQ(buffer->getMultiGraphicsAllocation().getLastUsedRootDeviceIndex(), 2u); + + alignedFree(hostBuffer2); + alignedFree(hostBuffer1); } diff --git a/opencl/test/unit_test/memory_manager/memory_manager_allocate_in_preferred_pool_tests.inl b/opencl/test/unit_test/memory_manager/memory_manager_allocate_in_preferred_pool_tests.inl index 680baef064..6b26657a10 100644 --- a/opencl/test/unit_test/memory_manager/memory_manager_allocate_in_preferred_pool_tests.inl +++ b/opencl/test/unit_test/memory_manager/memory_manager_allocate_in_preferred_pool_tests.inl @@ -51,25 +51,55 @@ TEST_F(MemoryManagerGetAlloctionDataTests, givenNonHostMemoryAllocatoinTypeWhenA } TEST_F(MemoryManagerGetAlloctionDataTests, givenMultiRootDeviceIndexAllocationPropertiesWhenAllocationDataIsQueriedThenUseSystemMemoryFlagsIsSet) { - AllocationData allocData; - AllocationProperties properties(mockRootDeviceIndex, true, 10, GraphicsAllocation::AllocationType::BUFFER, false, mockDeviceBitfield); - properties.flags.crossRootDeviceAccess = true; + { + AllocationData allocData; + AllocationProperties properties(mockRootDeviceIndex, true, 10, GraphicsAllocation::AllocationType::BUFFER, false, mockDeviceBitfield); + properties.flags.crossRootDeviceAccess = true; - MockMemoryManager mockMemoryManager; - mockMemoryManager.getAllocationData(allocData, properties, nullptr, mockMemoryManager.createStorageInfoFromProperties(properties)); + MockMemoryManager mockMemoryManager; + mockMemoryManager.getAllocationData(allocData, properties, nullptr, mockMemoryManager.createStorageInfoFromProperties(properties)); - EXPECT_TRUE(allocData.flags.useSystemMemory); + EXPECT_TRUE(allocData.flags.useSystemMemory); + EXPECT_TRUE(allocData.flags.crossRootDeviceAccess); + } + + { + AllocationData allocData; + AllocationProperties properties(mockRootDeviceIndex, true, 10, GraphicsAllocation::AllocationType::IMAGE, false, mockDeviceBitfield); + properties.flags.crossRootDeviceAccess = true; + + MockMemoryManager mockMemoryManager; + mockMemoryManager.getAllocationData(allocData, properties, nullptr, mockMemoryManager.createStorageInfoFromProperties(properties)); + + EXPECT_TRUE(allocData.flags.useSystemMemory); + EXPECT_TRUE(allocData.flags.crossRootDeviceAccess); + } } TEST_F(MemoryManagerGetAlloctionDataTests, givenDisabledCrossRootDeviceAccsessFlagInAllocationPropertiesWhenAllocationDataIsQueriedThenUseSystemMemoryFlagsIsNotSet) { - AllocationData allocData; - AllocationProperties properties(mockRootDeviceIndex, true, 10, GraphicsAllocation::AllocationType::BUFFER, false, mockDeviceBitfield); - properties.flags.crossRootDeviceAccess = false; + { + AllocationData allocData; + AllocationProperties properties(mockRootDeviceIndex, true, 10, GraphicsAllocation::AllocationType::BUFFER, false, mockDeviceBitfield); + properties.flags.crossRootDeviceAccess = false; - MockMemoryManager mockMemoryManager; - mockMemoryManager.getAllocationData(allocData, properties, nullptr, mockMemoryManager.createStorageInfoFromProperties(properties)); + MockMemoryManager mockMemoryManager; + mockMemoryManager.getAllocationData(allocData, properties, nullptr, mockMemoryManager.createStorageInfoFromProperties(properties)); - EXPECT_FALSE(allocData.flags.useSystemMemory); + EXPECT_FALSE(allocData.flags.useSystemMemory); + EXPECT_FALSE(allocData.flags.crossRootDeviceAccess); + } + + { + AllocationData allocData; + AllocationProperties properties(mockRootDeviceIndex, true, 10, GraphicsAllocation::AllocationType::IMAGE, false, mockDeviceBitfield); + properties.flags.crossRootDeviceAccess = false; + + MockMemoryManager mockMemoryManager; + mockMemoryManager.getAllocationData(allocData, properties, nullptr, mockMemoryManager.createStorageInfoFromProperties(properties)); + + EXPECT_FALSE(allocData.flags.useSystemMemory); + EXPECT_FALSE(allocData.flags.crossRootDeviceAccess); + } } HWTEST_F(MemoryManagerGetAlloctionDataTests, givenCommandBufferAllocationTypeWhenGetAllocationDataIsCalledThenSystemMemoryIsRequested) { diff --git a/opencl/test/unit_test/memory_manager/memory_manager_tests.cpp b/opencl/test/unit_test/memory_manager/memory_manager_tests.cpp index bb6fcef485..af1eec7296 100644 --- a/opencl/test/unit_test/memory_manager/memory_manager_tests.cpp +++ b/opencl/test/unit_test/memory_manager/memory_manager_tests.cpp @@ -856,6 +856,44 @@ TEST(OsAgnosticMemoryManager, givenHostPointerRequiringCopyWhenAllocateGraphicsM alignedFree(hostPtr); } +TEST(OsAgnosticMemoryManager, givenEnabledCrossRootDeviceAccessFlagWhenAllocateGraphicsMemoryForImageFromHostPtrIsCalledThenGraphicsAllocationIsReturned) { + ExecutionEnvironment *executionEnvironment = platform()->peekExecutionEnvironment(); + MockMemoryManager memoryManager(false, false, *executionEnvironment); + + cl_image_desc imgDesc = {}; + imgDesc.image_width = 4; + imgDesc.image_height = 1; + imgDesc.image_type = CL_MEM_OBJECT_IMAGE1D; + + cl_image_format imageFormat = {}; + imageFormat.image_channel_data_type = CL_UNSIGNED_INT8; + imageFormat.image_channel_order = CL_RGBA; + + cl_mem_flags flags = CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR; + auto surfaceFormat = Image::getSurfaceFormatFromTable(flags, &imageFormat, defaultHwInfo->capabilityTable.supportsOcl21Features); + + auto imgInfo = MockGmm::initImgInfo(imgDesc, 0, surfaceFormat); + imgInfo.rowPitch = imgDesc.image_width * 4; + imgInfo.slicePitch = imgInfo.rowPitch * imgDesc.image_height; + imgInfo.size = imgInfo.slicePitch; + imgInfo.linearStorage = true; + + auto hostPtr = alignedMalloc(imgDesc.image_width * imgDesc.image_height * 4, MemoryConstants::pageSize); + + AllocationData allocationData; + allocationData.imgInfo = &imgInfo; + allocationData.hostPtr = hostPtr; + allocationData.size = imgInfo.size; + allocationData.flags.crossRootDeviceAccess = true; + + auto imageAllocation = memoryManager.allocateGraphicsMemoryForImageFromHostPtr(allocationData); + ASSERT_NE(nullptr, imageAllocation); + EXPECT_EQ(hostPtr, imageAllocation->getUnderlyingBuffer()); + + memoryManager.freeGraphicsMemory(imageAllocation); + alignedFree(hostPtr); +} + TEST(OsAgnosticMemoryManager, givenDefaultMemoryManagerAndUnifiedAuxCapableAllocationWhenMappingThenReturnFalse) { MockExecutionEnvironment executionEnvironment(defaultHwInfo.get()); executionEnvironment.initGmm(); diff --git a/shared/source/memory_manager/allocation_properties.h b/shared/source/memory_manager/allocation_properties.h index 7903732f62..a46554e639 100644 --- a/shared/source/memory_manager/allocation_properties.h +++ b/shared/source/memory_manager/allocation_properties.h @@ -101,7 +101,8 @@ struct AllocationData { uint32_t resource48Bit : 1; uint32_t isUSMHostAllocation : 1; uint32_t use32BitFrontWindow : 1; - uint32_t reserved : 18; + uint32_t crossRootDeviceAccess : 1; + uint32_t reserved : 17; } flags; uint32_t allFlags = 0; }; diff --git a/shared/source/memory_manager/memory_manager.cpp b/shared/source/memory_manager/memory_manager.cpp index fa54fd06a8..777e301cc1 100644 --- a/shared/source/memory_manager/memory_manager.cpp +++ b/shared/source/memory_manager/memory_manager.cpp @@ -120,7 +120,7 @@ GraphicsAllocation *MemoryManager::allocateGraphicsMemoryWithHostPtr(const Alloc GraphicsAllocation *MemoryManager::allocateGraphicsMemoryForImageFromHostPtr(const AllocationData &allocationData) { bool copyRequired = isCopyRequired(*allocationData.imgInfo, allocationData.hostPtr); - if (allocationData.hostPtr && !copyRequired) { + if (allocationData.hostPtr && (!copyRequired || allocationData.flags.crossRootDeviceAccess)) { return allocateGraphicsMemoryWithHostPtr(allocationData); } return nullptr; @@ -424,6 +424,7 @@ bool MemoryManager::getAllocationData(AllocationData &allocationData, const Allo allocationData.rootDeviceIndex = properties.rootDeviceIndex; allocationData.useMmapObject = properties.useMmapObject; + allocationData.flags.crossRootDeviceAccess = properties.flags.crossRootDeviceAccess; allocationData.flags.useSystemMemory |= properties.flags.crossRootDeviceAccess; hwHelper.setExtraAllocationData(allocationData, properties, *hwInfo);