From 9e443444197db4702c3ecb260eee1242c9248252 Mon Sep 17 00:00:00 2001 From: "Warchulski, Jaroslaw" Date: Fri, 28 Apr 2023 15:05:36 +0000 Subject: [PATCH] feature: implementation for creating image with external memory Related-To: NEO-6757 Signed-off-by: Warchulski, Jaroslaw --- opencl/source/mem_obj/CMakeLists.txt | 4 +- opencl/source/mem_obj/image.cpp | 16 +++- opencl/source/mem_obj/image.h | 8 +- opencl/source/mem_obj/image_linux.cpp | 21 +++++ opencl/source/mem_obj/image_windows.cpp | 21 +++++ .../sharings/unified/linux/CMakeLists.txt | 15 ++++ .../unified/linux/unified_image_linux.cpp | 29 +++++++ .../source/sharings/unified/unified_image.cpp | 2 + .../source/sharings/unified/unified_image.h | 3 + .../sharings/unified/windows/CMakeLists.txt | 15 ++++ .../unified/windows/unified_image_windows.cpp | 30 +++++++ .../unit_test/mem_obj/linux/CMakeLists.txt | 3 +- .../mem_obj/linux/image_linux_tests.cpp | 63 ++++++++++++++ .../unit_test/mem_obj/windows/CMakeLists.txt | 3 +- .../mem_obj/windows/image_windows_tests.cpp | 84 +++++++++++++++++++ 15 files changed, 311 insertions(+), 6 deletions(-) create mode 100644 opencl/source/mem_obj/image_linux.cpp create mode 100644 opencl/source/mem_obj/image_windows.cpp create mode 100644 opencl/source/sharings/unified/linux/CMakeLists.txt create mode 100644 opencl/source/sharings/unified/linux/unified_image_linux.cpp create mode 100644 opencl/source/sharings/unified/windows/CMakeLists.txt create mode 100644 opencl/source/sharings/unified/windows/unified_image_windows.cpp create mode 100644 opencl/test/unit_test/mem_obj/linux/image_linux_tests.cpp create mode 100644 opencl/test/unit_test/mem_obj/windows/image_windows_tests.cpp diff --git a/opencl/source/mem_obj/CMakeLists.txt b/opencl/source/mem_obj/CMakeLists.txt index 83c3c43a6237c..aabe0258f4486 100644 --- a/opencl/source/mem_obj/CMakeLists.txt +++ b/opencl/source/mem_obj/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright (C) 2018-2022 Intel Corporation +# Copyright (C) 2018-2023 Intel Corporation # # SPDX-License-Identifier: MIT # @@ -30,10 +30,12 @@ set(RUNTIME_SRCS_MEM_OBJ if(WIN32) list(APPEND RUNTIME_SRCS_MEM_OBJ ${CMAKE_CURRENT_SOURCE_DIR}/buffer_windows.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/image_windows.cpp ) else() list(APPEND RUNTIME_SRCS_MEM_OBJ ${CMAKE_CURRENT_SOURCE_DIR}/buffer_linux.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/image_linux.cpp ) endif() diff --git a/opencl/source/mem_obj/image.cpp b/opencl/source/mem_obj/image.cpp index e1219d2a72ae0..0bd989cb70a1b 100644 --- a/opencl/source/mem_obj/image.cpp +++ b/opencl/source/mem_obj/image.cpp @@ -36,6 +36,7 @@ #include "opencl/source/helpers/surface_formats.h" #include "opencl/source/mem_obj/buffer.h" #include "opencl/source/mem_obj/mem_obj_helper.h" +#include "opencl/source/sharings/unified/unified_image.h" #include "igfxfmid.h" @@ -1308,7 +1309,20 @@ cl_mem Image::validateAndCreateImage(cl_context context, return nullptr; } - auto image = Image::create(pContext, memoryProperties, flags, flagsIntel, surfaceFormat, imageDesc, hostPtr, errcodeRet); + Image *image = nullptr; + UnifiedSharingMemoryDescription extMem{}; + + if (memoryProperties.handle) { + if (validateHandleType(memoryProperties, extMem)) { + extMem.handle = reinterpret_cast(memoryProperties.handle); + image = UnifiedImage::createSharedUnifiedImage(pContext, flags, extMem, imageFormat, imageDesc, &errcodeRet); + } else { + errcodeRet = CL_INVALID_PROPERTY; + return nullptr; + } + } else { + image = Image::create(pContext, memoryProperties, flags, flagsIntel, surfaceFormat, imageDesc, hostPtr, errcodeRet); + } if (errcodeRet == CL_SUCCESS) { image->storeProperties(properties); diff --git a/opencl/source/mem_obj/image.h b/opencl/source/mem_obj/image.h index 749127fecf170..1e34f9c3a78a2 100644 --- a/opencl/source/mem_obj/image.h +++ b/opencl/source/mem_obj/image.h @@ -12,12 +12,14 @@ #include "opencl/source/mem_obj/mem_obj.h" namespace NEO { + +class GfxCoreHelper; class Gmm; -struct HardwareInfo; class Image; +struct HardwareInfo; struct KernelInfo; struct SurfaceFormatInfo; -class GfxCoreHelper; +struct UnifiedSharingMemoryDescription; using ImageCreateFunc = Image *(*)(Context *context, const MemoryProperties &memoryProperties, @@ -202,6 +204,8 @@ class Image : public MemObj { void fillImageRegion(size_t *region) const; + static bool validateHandleType(MemoryProperties &memoryProperties, UnifiedSharingMemoryDescription &extMem); + protected: Image(Context *context, const MemoryProperties &memoryProperties, diff --git a/opencl/source/mem_obj/image_linux.cpp b/opencl/source/mem_obj/image_linux.cpp new file mode 100644 index 0000000000000..64530dd95a6b9 --- /dev/null +++ b/opencl/source/mem_obj/image_linux.cpp @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "opencl/source/mem_obj/image.h" +#include "opencl/source/sharings/unified/unified_sharing_types.h" + +namespace NEO { + +bool Image::validateHandleType(MemoryProperties &memoryProperties, UnifiedSharingMemoryDescription &extMem) { + if (memoryProperties.handleType == static_cast(UnifiedSharingHandleType::LinuxFd)) { + extMem.type = UnifiedSharingHandleType::LinuxFd; + return true; + } + return false; +} + +} // namespace NEO diff --git a/opencl/source/mem_obj/image_windows.cpp b/opencl/source/mem_obj/image_windows.cpp new file mode 100644 index 0000000000000..fcd191d3b6743 --- /dev/null +++ b/opencl/source/mem_obj/image_windows.cpp @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "opencl/source/mem_obj/image.h" +#include "opencl/source/sharings/unified/unified_sharing_types.h" + +namespace NEO { + +bool Image::validateHandleType(MemoryProperties &memoryProperties, UnifiedSharingMemoryDescription &extMem) { + if (memoryProperties.handleType == static_cast(UnifiedSharingHandleType::Win32Nt)) { + extMem.type = UnifiedSharingHandleType::Win32Nt; + return true; + } + return false; +} + +} // namespace NEO diff --git a/opencl/source/sharings/unified/linux/CMakeLists.txt b/opencl/source/sharings/unified/linux/CMakeLists.txt new file mode 100644 index 0000000000000..c525c5d1e8cba --- /dev/null +++ b/opencl/source/sharings/unified/linux/CMakeLists.txt @@ -0,0 +1,15 @@ +# +# Copyright (C) 2023 Intel Corporation +# +# SPDX-License-Identifier: MIT +# + +if(UNIX) + set(RUNTIME_SRCS_SHARINGS_UNIFIED_LINUX + ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt + ${CMAKE_CURRENT_SOURCE_DIR}/unified_image_linux.cpp + ) + + target_sources(${NEO_STATIC_LIB_NAME} PRIVATE ${RUNTIME_SRCS_SHARINGS_UNIFIED_LINUX}) + set_property(GLOBAL PROPERTY RUNTIME_SRCS_SHARINGS_UNIFIED_LINUX ${RUNTIME_SRCS_SHARINGS_UNIFIED_LINUX}) +endif() diff --git a/opencl/source/sharings/unified/linux/unified_image_linux.cpp b/opencl/source/sharings/unified/linux/unified_image_linux.cpp new file mode 100644 index 0000000000000..9fa7198b7193d --- /dev/null +++ b/opencl/source/sharings/unified/linux/unified_image_linux.cpp @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "shared/source/execution_environment/root_device_environment.h" +#include "shared/source/gmm_helper/gmm.h" + +#include "opencl/source/cl_device/cl_device.h" +#include "opencl/source/context/context.h" +#include "opencl/source/sharings/unified/unified_image.h" + +namespace NEO { + +void *UnifiedImage::swapGmm(GraphicsAllocation *graphicsAllocation, Context *context, ImageInfo *imgInfo) { + if (!graphicsAllocation->getDefaultGmm()) { + auto gmmHelper = context->getDevice(0)->getRootDeviceEnvironment().getGmmHelper(); + auto gmm = std::make_unique(gmmHelper, *imgInfo, StorageInfo{}, false); + gmm->updateImgInfoAndDesc(*imgInfo, 0); + delete graphicsAllocation->getDefaultGmm(); + graphicsAllocation->setDefaultGmm(gmm.release()); + } + + return 0; +} + +} // namespace NEO diff --git a/opencl/source/sharings/unified/unified_image.cpp b/opencl/source/sharings/unified/unified_image.cpp index b8a237f74cca7..cec5b0238b22d 100644 --- a/opencl/source/sharings/unified/unified_image.cpp +++ b/opencl/source/sharings/unified/unified_image.cpp @@ -36,6 +36,8 @@ Image *UnifiedImage::createSharedUnifiedImage(Context *context, cl_mem_flags fla return nullptr; } + swapGmm(graphicsAllocation, context, &imgInfo); + graphicsAllocation->getDefaultGmm()->updateOffsetsInImgInfo(imgInfo, 0u); auto &memoryManager = *context->getMemoryManager(); diff --git a/opencl/source/sharings/unified/unified_image.h b/opencl/source/sharings/unified/unified_image.h index 54ae385a292c5..533f714842377 100644 --- a/opencl/source/sharings/unified/unified_image.h +++ b/opencl/source/sharings/unified/unified_image.h @@ -14,6 +14,7 @@ namespace NEO { class Image; class Context; +struct ImageInfo; class UnifiedImage : public UnifiedSharing { using UnifiedSharing::UnifiedSharing; @@ -21,5 +22,7 @@ class UnifiedImage : public UnifiedSharing { public: static Image *createSharedUnifiedImage(Context *context, cl_mem_flags flags, UnifiedSharingMemoryDescription description, const cl_image_format *imageFormat, const cl_image_desc *imageDesc, cl_int *errcodeRet); + + static void *swapGmm(GraphicsAllocation *graphicsAllocation, Context *context, ImageInfo *imgInfo); }; } // namespace NEO diff --git a/opencl/source/sharings/unified/windows/CMakeLists.txt b/opencl/source/sharings/unified/windows/CMakeLists.txt new file mode 100644 index 0000000000000..81f8631fe5b94 --- /dev/null +++ b/opencl/source/sharings/unified/windows/CMakeLists.txt @@ -0,0 +1,15 @@ +# +# Copyright (C) 2023 Intel Corporation +# +# SPDX-License-Identifier: MIT +# + +if(WIN32) + set(RUNTIME_SRCS_SHARINGS_UNIFIED_WINDOWS + ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt + ${CMAKE_CURRENT_SOURCE_DIR}/unified_image_windows.cpp + ) + + target_sources(${NEO_STATIC_LIB_NAME} PRIVATE ${RUNTIME_SRCS_SHARINGS_UNIFIED_WINDOWS}) + set_property(GLOBAL PROPERTY RUNTIME_SRCS_SHARINGS_UNIFIED_WINDOWS ${RUNTIME_SRCS_SHARINGS_UNIFIED_WINDOWS}) +endif() diff --git a/opencl/source/sharings/unified/windows/unified_image_windows.cpp b/opencl/source/sharings/unified/windows/unified_image_windows.cpp new file mode 100644 index 0000000000000..b693468f0d8de --- /dev/null +++ b/opencl/source/sharings/unified/windows/unified_image_windows.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "shared/source/execution_environment/root_device_environment.h" +#include "shared/source/gmm_helper/gmm.h" +#include "shared/source/gmm_helper/resource_info.h" + +#include "opencl/source/cl_device/cl_device.h" +#include "opencl/source/context/context.h" +#include "opencl/source/sharings/unified/unified_image.h" + +namespace NEO { + +void *UnifiedImage::swapGmm(GraphicsAllocation *graphicsAllocation, Context *context, ImageInfo *imgInfo) { + if (graphicsAllocation->getDefaultGmm()->gmmResourceInfo->peekGmmResourceInfo()->GetResourceType() == RESOURCE_BUFFER) { + auto gmmHelper = context->getDevice(0)->getRootDeviceEnvironment().getGmmHelper(); + auto gmm = std::make_unique(gmmHelper, *imgInfo, StorageInfo{}, false); + gmm->updateImgInfoAndDesc(*imgInfo, 0); + delete graphicsAllocation->getDefaultGmm(); + graphicsAllocation->setDefaultGmm(gmm.release()); + } + + return 0; +} + +} // namespace NEO diff --git a/opencl/test/unit_test/mem_obj/linux/CMakeLists.txt b/opencl/test/unit_test/mem_obj/linux/CMakeLists.txt index 392d7d75eb337..9633e9e4638fb 100644 --- a/opencl/test/unit_test/mem_obj/linux/CMakeLists.txt +++ b/opencl/test/unit_test/mem_obj/linux/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright (C) 2022 Intel Corporation +# Copyright (C) 2022-2023 Intel Corporation # # SPDX-License-Identifier: MIT # @@ -8,6 +8,7 @@ if(UNIX) set(IGDRCL_SRCS_tests_mem_obj_linux ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt ${CMAKE_CURRENT_SOURCE_DIR}/buffer_linux_tests.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/image_linux_tests.cpp ) target_sources(igdrcl_tests PRIVATE ${IGDRCL_SRCS_tests_mem_obj_linux}) diff --git a/opencl/test/unit_test/mem_obj/linux/image_linux_tests.cpp b/opencl/test/unit_test/mem_obj/linux/image_linux_tests.cpp new file mode 100644 index 0000000000000..68b43aa9c4ba3 --- /dev/null +++ b/opencl/test/unit_test/mem_obj/linux/image_linux_tests.cpp @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "shared/test/common/test_macros/test.h" + +#include "opencl/source/mem_obj/image.h" +#include "opencl/source/sharings/unified/unified_sharing_types.h" +#include "opencl/test/unit_test/fixtures/cl_device_fixture.h" +#include "opencl/test/unit_test/mocks/mock_context.h" +#include "opencl/test/unit_test/sharings/unified/unified_sharing_fixtures.h" + +using namespace NEO; + +using ImageLinuxTests = Test; + +TEST_F(ImageLinuxTests, givenPropertiesWithNtHandleWhenValidateAndCreateImageThenInvalidPropertyIsSet) { + cl_mem_properties properties[] = {CL_EXTERNAL_MEMORY_HANDLE_OPAQUE_WIN32_KHR, 0x1234, 0}; + + cl_image_desc imageDesc = {}; + cl_image_format imageFormat = {}; + imageFormat.image_channel_data_type = CL_UNSIGNED_INT8; + imageFormat.image_channel_order = CL_R; + + std::unique_ptr context; + context.reset(new MockContext(pClDevice)); + cl_mem_flags flags = CL_MEM_READ_WRITE; + cl_int retVal = CL_SUCCESS; + + auto image = ImageFunctions::validateAndCreateImage(context.get(), properties, flags, 0, &imageFormat, &imageDesc, nullptr, retVal); + + EXPECT_EQ(retVal, CL_INVALID_PROPERTY); + EXPECT_EQ(nullptr, image); + + clReleaseMemObject(image); +} + +using UnifiedSharingImageTests = UnifiedSharingFixture; + +TEST_F(UnifiedSharingImageTests, givenPropertiesWithDmaBufWhenValidateAndCreateImageThenCorrectImageIsSet) { + cl_mem_properties properties[] = {CL_EXTERNAL_MEMORY_HANDLE_DMA_BUF_KHR, 0x1234, 0}; + + cl_image_desc imageDesc = {}; + imageDesc.image_type = CL_MEM_OBJECT_IMAGE2D; + imageDesc.image_width = 64; + imageDesc.image_height = 64; + cl_image_format imageFormat = {}; + imageFormat.image_channel_data_type = CL_UNSIGNED_INT8; + imageFormat.image_channel_order = CL_R; + + cl_mem_flags flags = CL_MEM_READ_WRITE; + cl_int retVal = CL_INVALID_VALUE; + + auto image = ImageFunctions::validateAndCreateImage(context.get(), properties, flags, 0, &imageFormat, &imageDesc, nullptr, retVal); + + EXPECT_EQ(retVal, CL_SUCCESS); + EXPECT_NE(image, nullptr); + + clReleaseMemObject(image); +} diff --git a/opencl/test/unit_test/mem_obj/windows/CMakeLists.txt b/opencl/test/unit_test/mem_obj/windows/CMakeLists.txt index 3bb5f0bc80746..4e785f6bff12a 100644 --- a/opencl/test/unit_test/mem_obj/windows/CMakeLists.txt +++ b/opencl/test/unit_test/mem_obj/windows/CMakeLists.txt @@ -1,5 +1,5 @@ # -# Copyright (C) 2022 Intel Corporation +# Copyright (C) 2022-2023 Intel Corporation # # SPDX-License-Identifier: MIT # @@ -8,6 +8,7 @@ if(WIN32) set(IGDRCL_SRCS_tests_mem_obj_windows ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt ${CMAKE_CURRENT_SOURCE_DIR}/buffer_windows_tests.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/image_windows_tests.cpp ) target_sources(igdrcl_tests PRIVATE ${IGDRCL_SRCS_tests_mem_obj_windows}) diff --git a/opencl/test/unit_test/mem_obj/windows/image_windows_tests.cpp b/opencl/test/unit_test/mem_obj/windows/image_windows_tests.cpp new file mode 100644 index 0000000000000..d979bbd0bbe13 --- /dev/null +++ b/opencl/test/unit_test/mem_obj/windows/image_windows_tests.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2023 Intel Corporation + * + * SPDX-License-Identifier: MIT + * + */ + +#include "shared/source/gmm_helper/resource_info.h" + +#include "opencl/source/mem_obj/image.h" +#include "opencl/test/unit_test/sharings/unified/unified_sharing_fixtures.h" + +using namespace NEO; + +struct ImageWindowsTestsMockMemoryManager : MockMemoryManager { + using MockMemoryManager::MockMemoryManager; + GraphicsAllocation *createGraphicsAllocationFromNTHandle(void *handle, uint32_t rootDeviceIndex, AllocationType allocType) override { + + auto graphicsAllocation = createMemoryAllocation(allocType, nullptr, reinterpret_cast(1), 1, + 4096u, reinterpret_cast(handle), MemoryPool::SystemCpuInaccessible, + rootDeviceIndex, false, false, false); + + graphicsAllocation->setDefaultGmm(new MockGmm(executionEnvironment.rootDeviceEnvironments[rootDeviceIndex]->getGmmHelper())); + graphicsAllocation->getDefaultGmm()->gmmResourceInfo->peekGmmResourceInfo()->OverrideSurfaceType(RESOURCE_BUFFER); + + return graphicsAllocation; + } +}; + +struct ImageWindowsTests : UnifiedSharingContextFixture { + void SetUp() override { + UnifiedSharingContextFixture::SetUp(); + this->memoryManager = std::make_unique(*this->device->getExecutionEnvironment()); + this->memoryManagerBackup = std::make_unique>(&this->context->memoryManager, this->memoryManager.get()); + } + + void TearDown() override { + UnifiedSharingContextFixture::TearDown(); + } + + std::unique_ptr memoryManager; + std::unique_ptr> memoryManagerBackup; +}; + +TEST_F(ImageWindowsTests, givenPropertiesWithDmaBufWhenValidateAndCreateImageThenInvalidPropertyIsSet) { + cl_mem_properties properties[] = {CL_EXTERNAL_MEMORY_HANDLE_DMA_BUF_KHR, 0x1234, 0}; + + cl_image_desc imageDesc = {}; + cl_image_format imageFormat = {}; + imageFormat.image_channel_data_type = CL_UNSIGNED_INT8; + imageFormat.image_channel_order = CL_R; + + cl_mem_flags flags = CL_MEM_READ_WRITE; + cl_int retVal = CL_SUCCESS; + + auto image = ImageFunctions::validateAndCreateImage(context.get(), properties, flags, 0, &imageFormat, &imageDesc, nullptr, retVal); + + EXPECT_EQ(retVal, CL_INVALID_PROPERTY); + EXPECT_EQ(nullptr, image); + + clReleaseMemObject(image); +} + +TEST_F(ImageWindowsTests, givenPropertiesWithNtHandleWhenValidateAndCreateImageThenCorrectImageIsSet) { + cl_mem_properties properties[] = {CL_EXTERNAL_MEMORY_HANDLE_OPAQUE_WIN32_KHR, 0x1234, 0}; + + cl_image_desc imageDesc = {}; + imageDesc.image_type = CL_MEM_OBJECT_IMAGE2D; + imageDesc.image_width = 64; + imageDesc.image_height = 64; + cl_image_format imageFormat = {}; + imageFormat.image_channel_data_type = CL_UNSIGNED_INT8; + imageFormat.image_channel_order = CL_R; + + cl_mem_flags flags = CL_MEM_READ_WRITE; + cl_int retVal = CL_INVALID_VALUE; + + auto image = ImageFunctions::validateAndCreateImage(context.get(), properties, flags, 0, &imageFormat, &imageDesc, nullptr, retVal); + + EXPECT_EQ(retVal, CL_SUCCESS); + EXPECT_NE(image, nullptr); + + clReleaseMemObject(image); +}