diff --git a/level_zero/core/source/context/context_imp.cpp b/level_zero/core/source/context/context_imp.cpp index 3c3e164a5c..79a98d2455 100644 --- a/level_zero/core/source/context/context_imp.cpp +++ b/level_zero/core/source/context/context_imp.cpp @@ -84,6 +84,37 @@ ze_result_t ContextImp::allocHostMem(const ze_host_mem_alloc_desc_t *hostDesc, return ZE_RESULT_ERROR_UNSUPPORTED_SIZE; } + StructuresLookupTable lookupTable = {}; + + lookupTable.relaxedSizeAllowed = NEO::DebugManager.flags.AllowUnrestrictedSize.get(); + auto parseResult = prepareL0StructuresLookupTable(lookupTable, hostDesc->pNext); + + if (parseResult != ZE_RESULT_SUCCESS) { + return parseResult; + } + + if (lookupTable.isSharedHandle) { + if (lookupTable.sharedHandleType.isDMABUFHandle) { + ze_ipc_memory_flags_t flags = {}; + *ptr = getMemHandlePtr(this->devices.begin()->second, + lookupTable.sharedHandleType.fd, + NEO::AllocationType::BUFFER_HOST_MEMORY, + flags); + if (nullptr == *ptr) { + return ZE_RESULT_ERROR_INVALID_ARGUMENT; + } + } else { + UNRECOVERABLE_IF(!lookupTable.sharedHandleType.isNTHandle); + *ptr = this->driverHandle->importNTHandle(this->devices.begin()->second, + lookupTable.sharedHandleType.ntHnadle, + NEO::AllocationType::BUFFER_HOST_MEMORY); + if (*ptr == nullptr) { + return ZE_RESULT_ERROR_INVALID_ARGUMENT; + } + } + return ZE_RESULT_SUCCESS; + } + NEO::SVMAllocsManager::UnifiedMemoryProperties unifiedMemoryProperties(InternalMemoryType::HOST_UNIFIED_MEMORY, this->rootDeviceIndices, this->deviceBitfields); @@ -625,7 +656,7 @@ ze_result_t ContextImp::handleAllocationExtensions(NEO::GraphicsAllocation *allo if (extendedMemoryExportProperties->flags & ZE_EXTERNAL_MEMORY_TYPE_FLAG_OPAQUE_FD) { return ZE_RESULT_ERROR_UNSUPPORTED_ENUMERATION; } - if (type != ZE_MEMORY_TYPE_DEVICE) { + if (type == ZE_MEMORY_TYPE_SHARED) { return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; } uint64_t handle = 0; diff --git a/level_zero/core/test/unit_tests/fixtures/memory_ipc_fixture.h b/level_zero/core/test/unit_tests/fixtures/memory_ipc_fixture.h index cc4fc13d72..8101ed6544 100644 --- a/level_zero/core/test/unit_tests/fixtures/memory_ipc_fixture.h +++ b/level_zero/core/test/unit_tests/fixtures/memory_ipc_fixture.h @@ -67,6 +67,18 @@ struct ContextFdMock : public L0::ContextImp { return res; } + ze_result_t allocHostMem(const ze_host_mem_alloc_desc_t *hostDesc, + size_t size, + size_t alignment, void **ptr) override { + ze_result_t res = L0::ContextImp::allocHostMem(hostDesc, size, alignment, ptr); + if (ZE_RESULT_SUCCESS == res) { + driverHandle->allocationMap.first = *ptr; + driverHandle->allocationMap.second = driverHandle->mockFd; + } + + return res; + } + ze_result_t getMemAllocProperties(const void *ptr, ze_memory_allocation_properties_t *pMemAllocProperties, ze_device_handle_t *phDevice) override { diff --git a/level_zero/core/test/unit_tests/sources/driver/test_driver.cpp b/level_zero/core/test/unit_tests/sources/driver/test_driver.cpp index 72e708db34..adfc2f2ac4 100644 --- a/level_zero/core/test/unit_tests/sources/driver/test_driver.cpp +++ b/level_zero/core/test/unit_tests/sources/driver/test_driver.cpp @@ -235,6 +235,31 @@ HWTEST_F(ImportNTHandle, givenNTHandleWhenCreatingDeviceMemoryThenSuccessIsRetur EXPECT_EQ(result, ZE_RESULT_SUCCESS); } +HWTEST_F(ImportNTHandle, givenNTHandleWhenCreatingHostMemoryThenSuccessIsReturned) { + ze_host_mem_alloc_desc_t hostDesc = {}; + hostDesc.stype = ZE_STRUCTURE_TYPE_HOST_MEM_ALLOC_DESC; + + uint64_t imageHandle = 0x1; + ze_external_memory_import_win32_handle_t importNTHandle = {}; + importNTHandle.handle = &imageHandle; + importNTHandle.flags = ZE_EXTERNAL_MEMORY_TYPE_FLAG_OPAQUE_WIN32; + importNTHandle.stype = ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMPORT_WIN32; + hostDesc.pNext = &importNTHandle; + + delete driverHandle->svmAllocsManager; + execEnv->memoryManager.reset(new MemoryManagerNTHandleMock(*execEnv)); + driverHandle->setMemoryManager(execEnv->memoryManager.get()); + driverHandle->svmAllocsManager = new NEO::SVMAllocsManager(execEnv->memoryManager.get(), false); + + void *ptr = nullptr; + auto result = context->allocHostMem(&hostDesc, 100, 1, &ptr); + EXPECT_EQ(result, ZE_RESULT_SUCCESS); + auto alloc = driverHandle->getSvmAllocsManager()->getSVMAlloc(ptr); + ASSERT_EQ(alloc->gpuAllocations.getGraphicsAllocation(device->getRootDeviceIndex())->peekSharedHandle(), NEO::toOsHandle(importNTHandle.handle)); + result = context->freeMem(ptr); + EXPECT_EQ(result, ZE_RESULT_SUCCESS); +} + HWTEST_F(ImportNTHandle, whenCallingCreateGraphicsAllocationFromMultipleSharedHandlesFromOsAgnosticMemoryManagerThenNullptrIsReturned) { using RENDER_SURFACE_STATE = typename FamilyType::RENDER_SURFACE_STATE; @@ -277,6 +302,24 @@ HWTEST_F(ImportNTHandle, givenNotExistingNTHandleWhenCreatingDeviceMemoryThenErr EXPECT_EQ(result, ZE_RESULT_ERROR_INVALID_ARGUMENT); } +HWTEST_F(ImportNTHandle, givenNotExistingNTHandleWhenCreatingHostMemoryThenErrorIsReturned) { + using RENDER_SURFACE_STATE = typename FamilyType::RENDER_SURFACE_STATE; + + ze_host_mem_alloc_desc_t hostDesc = {}; + hostDesc.stype = ZE_STRUCTURE_TYPE_HOST_MEM_ALLOC_DESC; + + ze_external_memory_import_win32_handle_t importNTHandle = {}; + importNTHandle.handle = reinterpret_cast(invalidHandle); + importNTHandle.flags = ZE_EXTERNAL_MEMORY_TYPE_FLAG_OPAQUE_WIN32; + importNTHandle.stype = ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMPORT_WIN32; + hostDesc.pNext = &importNTHandle; + + void *ptr = nullptr; + auto result = context->allocHostMem(&hostDesc, 100, 1, &ptr); + + EXPECT_EQ(result, ZE_RESULT_ERROR_INVALID_ARGUMENT); +} + TEST(DriverTestFamilySupport, whenInitializingDriverOnSupportedFamilyThenDriverIsCreated) { ze_result_t returnValue; diff --git a/level_zero/core/test/unit_tests/sources/memory/test_memory.cpp b/level_zero/core/test/unit_tests/sources/memory/test_memory.cpp index 31766eaf37..3e21c4bd11 100644 --- a/level_zero/core/test/unit_tests/sources/memory/test_memory.cpp +++ b/level_zero/core/test/unit_tests/sources/memory/test_memory.cpp @@ -2328,7 +2328,39 @@ TEST_F(MemoryExportImportTest, } TEST_F(MemoryExportImportTest, - givenCallToMemAllocPropertiesWithExtendedExportPropertiesForNonDeviceAllocationThenUnsupportedFeatureIsReturned) { + givenCallToMemAllocPropertiesWithExtendedExportPropertiesForSharedAllocationThenUnsupportedFeatureIsReturned) { + size_t size = 10; + size_t alignment = 1u; + void *ptr = nullptr; + + ze_host_mem_alloc_desc_t hostDesc = {}; + ze_device_mem_alloc_desc_t deviceDesc = {}; + ze_result_t result = context->allocSharedMem(device->toHandle(), + &deviceDesc, + &hostDesc, + size, + alignment, + &ptr); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_NE(nullptr, ptr); + + ze_memory_allocation_properties_t memoryProperties = {}; + ze_external_memory_export_fd_t extendedProperties = {}; + extendedProperties.stype = ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_EXPORT_FD; + extendedProperties.flags = ZE_EXTERNAL_MEMORY_TYPE_FLAG_DMA_BUF; + extendedProperties.fd = std::numeric_limits::max(); + memoryProperties.pNext = &extendedProperties; + + result = context->getMemAllocProperties(ptr, &memoryProperties, nullptr); + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, result); + EXPECT_EQ(extendedProperties.fd, std::numeric_limits::max()); + + result = context->freeMem(ptr); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); +} + +TEST_F(MemoryExportImportTest, + givenCallToMemAllocPropertiesWithExtendedExportPropertiesForHostAllocationThenSuccessIsReturned) { size_t size = 10; size_t alignment = 1u; void *ptr = nullptr; @@ -2346,8 +2378,8 @@ TEST_F(MemoryExportImportTest, memoryProperties.pNext = &extendedProperties; result = context->getMemAllocProperties(ptr, &memoryProperties, nullptr); - EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, result); - EXPECT_EQ(extendedProperties.fd, std::numeric_limits::max()); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(extendedProperties.fd, 57); result = context->freeMem(ptr); EXPECT_EQ(ZE_RESULT_SUCCESS, result); diff --git a/level_zero/core/test/unit_tests/sources/memory/test_memory_drm.cpp b/level_zero/core/test/unit_tests/sources/memory/test_memory_drm.cpp index ae831b3e0d..18a7b6b530 100644 --- a/level_zero/core/test/unit_tests/sources/memory/test_memory_drm.cpp +++ b/level_zero/core/test/unit_tests/sources/memory/test_memory_drm.cpp @@ -288,5 +288,55 @@ TEST_F(MemoryExportImportTest, EXPECT_EQ(ZE_RESULT_SUCCESS, result); } +TEST_F(MemoryExportImportTest, + givenCallToHostAllocWithExtendedImportDescriptorAndSupportedFlagThenSuccessIsReturned) { + size_t size = 10; + size_t alignment = 1u; + void *ptr = nullptr; + + ze_host_mem_alloc_desc_t hostDesc = {}; + ze_external_memory_export_desc_t extendedDesc = {}; + extendedDesc.stype = ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_EXPORT_DESC; + extendedDesc.flags = ZE_EXTERNAL_MEMORY_TYPE_FLAG_DMA_BUF; + hostDesc.pNext = &extendedDesc; + ze_result_t result = context->allocHostMem(&hostDesc, + size, alignment, &ptr); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_NE(nullptr, ptr); + + ze_memory_allocation_properties_t memoryProperties = {}; + ze_external_memory_export_fd_t extendedProperties = {}; + extendedProperties.stype = ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_EXPORT_FD; + extendedProperties.flags = ZE_EXTERNAL_MEMORY_TYPE_FLAG_DMA_BUF; + extendedProperties.fd = std::numeric_limits::max(); + memoryProperties.pNext = &extendedProperties; + + result = context->getMemAllocProperties(ptr, &memoryProperties, nullptr); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(memoryProperties.type, ZE_MEMORY_TYPE_HOST); + EXPECT_NE(extendedProperties.fd, std::numeric_limits::max()); + EXPECT_EQ(extendedProperties.fd, driverHandle->mockFd); + + ze_host_mem_alloc_desc_t importHostDesc = {}; + ze_external_memory_import_fd_t extendedImportDesc = {}; + extendedImportDesc.stype = ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMPORT_FD; + extendedImportDesc.flags = ZE_EXTERNAL_MEMORY_TYPE_FLAG_DMA_BUF; + extendedImportDesc.fd = extendedProperties.fd; + importHostDesc.pNext = &extendedImportDesc; + + neoDevice->executionEnvironment->rootDeviceEnvironments[0]->osInterface.reset(new NEO::OSInterface()); + neoDevice->executionEnvironment->rootDeviceEnvironments[0]->osInterface->setDriverModel(std::make_unique()); + + void *importedPtr = nullptr; + result = context->allocHostMem(&importHostDesc, + size, alignment, &importedPtr); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + + EXPECT_EQ(driverHandle->allocationTypeRequested, NEO::AllocationType::BUFFER_HOST_MEMORY); + + result = context->freeMem(ptr); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); +} + } // namespace ult } // namespace L0 diff --git a/level_zero/core/test/unit_tests/sources/memory/test_memory_drm_or_wddm.cpp b/level_zero/core/test/unit_tests/sources/memory/test_memory_drm_or_wddm.cpp index 56b618ec0c..19b4fe1b08 100644 --- a/level_zero/core/test/unit_tests/sources/memory/test_memory_drm_or_wddm.cpp +++ b/level_zero/core/test/unit_tests/sources/memory/test_memory_drm_or_wddm.cpp @@ -306,6 +306,102 @@ TEST_F(MemoryExportImportTest, EXPECT_EQ(ZE_RESULT_SUCCESS, result); } +TEST_F(MemoryExportImportTest, + givenCallToHostAllocWithExtendedImportDescriptorAndSupportedFlagThenSuccessIsReturned) { + size_t size = 10; + size_t alignment = 1u; + void *ptr = nullptr; + + ze_host_mem_alloc_desc_t hostDesc = {}; + ze_external_memory_export_desc_t extendedDesc = {}; + extendedDesc.stype = ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_EXPORT_DESC; + extendedDesc.flags = ZE_EXTERNAL_MEMORY_TYPE_FLAG_DMA_BUF; + hostDesc.pNext = &extendedDesc; + ze_result_t result = context->allocHostMem(&hostDesc, + size, alignment, &ptr); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_NE(nullptr, ptr); + + ze_memory_allocation_properties_t memoryProperties = {}; + ze_external_memory_export_fd_t extendedProperties = {}; + extendedProperties.stype = ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_EXPORT_FD; + extendedProperties.flags = ZE_EXTERNAL_MEMORY_TYPE_FLAG_DMA_BUF; + extendedProperties.fd = std::numeric_limits::max(); + memoryProperties.pNext = &extendedProperties; + + result = context->getMemAllocProperties(ptr, &memoryProperties, nullptr); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(memoryProperties.type, ZE_MEMORY_TYPE_HOST); + EXPECT_NE(extendedProperties.fd, std::numeric_limits::max()); + EXPECT_EQ(extendedProperties.fd, driverHandle->mockFd); + + ze_host_mem_alloc_desc_t importHostDesc = {}; + ze_external_memory_import_fd_t extendedImportDesc = {}; + extendedImportDesc.stype = ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMPORT_FD; + extendedImportDesc.flags = ZE_EXTERNAL_MEMORY_TYPE_FLAG_DMA_BUF; + extendedImportDesc.fd = extendedProperties.fd; + importHostDesc.pNext = &extendedImportDesc; + + neoDevice->executionEnvironment->rootDeviceEnvironments[0]->osInterface.reset(new NEO::OSInterface()); + neoDevice->executionEnvironment->rootDeviceEnvironments[0]->osInterface->setDriverModel(std::make_unique()); + + void *importedPtr = nullptr; + result = context->allocHostMem(&importHostDesc, + size, alignment, &importedPtr); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + + result = context->freeMem(ptr); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); +} + +TEST_F(MemoryExportImportTest, + givenCallToHostAllocWithExtendedImportDescriptorAndWDDMDriverTypeThenFailureIsReturned) { + size_t size = 10; + size_t alignment = 1u; + void *ptr = nullptr; + + ze_host_mem_alloc_desc_t hostDesc = {}; + ze_external_memory_export_desc_t extendedDesc = {}; + extendedDesc.stype = ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_EXPORT_DESC; + extendedDesc.flags = ZE_EXTERNAL_MEMORY_TYPE_FLAG_DMA_BUF; + hostDesc.pNext = &extendedDesc; + ze_result_t result = context->allocHostMem(&hostDesc, + size, alignment, &ptr); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_NE(nullptr, ptr); + + ze_memory_allocation_properties_t memoryProperties = {}; + ze_external_memory_export_fd_t extendedProperties = {}; + extendedProperties.stype = ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_EXPORT_FD; + extendedProperties.flags = ZE_EXTERNAL_MEMORY_TYPE_FLAG_DMA_BUF; + extendedProperties.fd = std::numeric_limits::max(); + memoryProperties.pNext = &extendedProperties; + + result = context->getMemAllocProperties(ptr, &memoryProperties, nullptr); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(memoryProperties.type, ZE_MEMORY_TYPE_HOST); + EXPECT_NE(extendedProperties.fd, std::numeric_limits::max()); + EXPECT_EQ(extendedProperties.fd, driverHandle->mockFd); + + ze_host_mem_alloc_desc_t importHostDesc = {}; + ze_external_memory_import_fd_t extendedImportDesc = {}; + extendedImportDesc.stype = ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMPORT_FD; + extendedImportDesc.flags = ZE_EXTERNAL_MEMORY_TYPE_FLAG_DMA_BUF; + extendedImportDesc.fd = extendedProperties.fd; + importHostDesc.pNext = &extendedImportDesc; + + neoDevice->executionEnvironment->rootDeviceEnvironments[0]->osInterface.reset(new NEO::OSInterface()); + neoDevice->executionEnvironment->rootDeviceEnvironments[0]->osInterface->setDriverModel(std::make_unique()); + + void *importedPtr = nullptr; + result = context->allocHostMem(&importHostDesc, + size, alignment, &importedPtr); + EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, result); + + result = context->freeMem(ptr); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); +} + TEST_F(MemoryExportImportTest, givenCallToDeviceAllocWithExtendedImportDescriptorAndWDDMDriverTypeThenFailureIsReturned) { size_t size = 10;