diff --git a/opencl/extensions/public/cl_ext_private.h b/opencl/extensions/public/cl_ext_private.h index 7ee6d576b40a3..5c38172763f3a 100644 --- a/opencl/extensions/public/cl_ext_private.h +++ b/opencl/extensions/public/cl_ext_private.h @@ -421,4 +421,10 @@ typedef struct _cl_kernel_allocation_info_intel { // cl_device bfloat16 atomic capabilities #if !defined(CL_DEVICE_BFLOAT16_FP_ATOMIC_CAPABILITIES_EXT) #define CL_DEVICE_BFLOAT16_FP_ATOMIC_CAPABILITIES_EXT 0x10012 + +/****************************************************** + * cl_intel_bindless_images extension * + ******************************************************/ +#define CL_MEM_BINDLESS_IMAGE_INTEL 0x4220 + #endif diff --git a/opencl/source/helpers/api_specific_config_ocl.cpp b/opencl/source/helpers/api_specific_config_ocl.cpp index 495dcd7cb4a42..ae64356b674e2 100644 --- a/opencl/source/helpers/api_specific_config_ocl.cpp +++ b/opencl/source/helpers/api_specific_config_ocl.cpp @@ -9,6 +9,7 @@ #include "shared/source/device/device.h" #include "shared/source/helpers/api_specific_config.h" #include "shared/source/helpers/compiler_product_helper.h" +#include "shared/source/release_helper/release_helper.h" #include "opencl/source/os_interface/ocl_reg_path.h" @@ -20,7 +21,10 @@ StackVec validClPrefixes; StackVec validClPrefixTypes; bool ApiSpecificConfig::getGlobalBindlessHeapConfiguration(const ReleaseHelper &releaseHelper) { - return false; + if (debugManager.flags.UseExternalAllocatorForSshAndDsh.get() != -1) { + return debugManager.flags.UseExternalAllocatorForSshAndDsh.get(); + } + return releaseHelper.isGlobalBindlessAllocatorEnabled(); } bool ApiSpecificConfig::getBindlessMode(const Device &device) { diff --git a/opencl/source/helpers/cl_memory_properties_helpers.cpp b/opencl/source/helpers/cl_memory_properties_helpers.cpp index 68843602c6564..61f97e36d1924 100644 --- a/opencl/source/helpers/cl_memory_properties_helpers.cpp +++ b/opencl/source/helpers/cl_memory_properties_helpers.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021-2024 Intel Corporation + * Copyright (C) 2021-2025 Intel Corporation * * SPDX-License-Identifier: MIT * @@ -24,7 +24,7 @@ bool ClMemoryPropertiesHelper::parseMemoryProperties(const cl_mem_properties_int uint64_t handleType = 0; uintptr_t hostptr = 0; std::vector devices; - + bool bindlessImage = false; if (properties != nullptr) { for (int i = 0; properties[i] != 0; i += 2) { switch (properties[i]) { @@ -73,6 +73,9 @@ bool ClMemoryPropertiesHelper::parseMemoryProperties(const cl_mem_properties_int i++; } break; + case CL_MEM_BINDLESS_IMAGE_INTEL: // Avoiding get a false when using bindless image extension + bindlessImage = true; + break; default: return false; } @@ -84,7 +87,7 @@ bool ClMemoryPropertiesHelper::parseMemoryProperties(const cl_mem_properties_int memoryProperties.handle = handle; memoryProperties.hostptr = hostptr; memoryProperties.associatedDevices = devices; - + memoryProperties.flags.bindlessImage = bindlessImage; switch (objectType) { case ClMemoryPropertiesHelper::ObjType::buffer: return isFieldValid(flags, MemObjHelper::validFlagsForBuffer) && diff --git a/opencl/source/mem_obj/image.cpp b/opencl/source/mem_obj/image.cpp index 5d2d8541f296f..769836d18465c 100644 --- a/opencl/source/mem_obj/image.cpp +++ b/opencl/source/mem_obj/image.cpp @@ -300,6 +300,19 @@ Image *Image::create(Context *context, setImageProperties(image, *imageDesc, imgInfo, parentImage, parentBuffer, hostPtrRowPitch, hostPtrSlicePitch, imageCount, hostPtrMinSize); + auto defaultRootDeviceEnv = defaultDevice->getExecutionEnvironment()->rootDeviceEnvironments[defaultRootDeviceIndex].get(); + auto bindlessHelper = defaultRootDeviceEnv->getBindlessHeapsHelper(); + if (bindlessHelper && image && memoryProperties.flags.bindlessImage) { + auto allocation = image->getGraphicsAllocation(defaultRootDeviceIndex); + auto memManager = context->getMemoryManager(); + if (memManager->allocateBindlessSlot(allocation)) { + if (allocation->getBindlessOffset() != std::numeric_limits::max()) { + image->bindlessInfo = std::make_unique(allocation->getBindlessInfo()); + image->bindlessImage = true; + } + } + } + errcodeRet = CL_SUCCESS; auto &defaultHwInfo = defaultDevice->getHardwareInfo(); if (context->isProvidingPerformanceHints()) { diff --git a/opencl/source/mem_obj/image.h b/opencl/source/mem_obj/image.h index 55b8f7d3b2b95..cc61e210a1174 100644 --- a/opencl/source/mem_obj/image.h +++ b/opencl/source/mem_obj/image.h @@ -6,6 +6,7 @@ */ #pragma once +#include "shared/source/helpers/bindless_heaps_helper.h" #include "shared/source/memory_manager/graphics_allocation.h" #include "opencl/source/helpers/surface_formats.h" @@ -205,6 +206,9 @@ class Image : public MemObj { void fillImageRegion(size_t *region) const; static bool validateHandleType(MemoryProperties &memoryProperties, UnifiedSharingMemoryDescription &extMem); + SurfaceStateInHeapInfo *getBindlessSlot() const { return bindlessInfo.get(); } + uint64_t getBindlessHandle() const { return bindlessInfo ? bindlessInfo->surfaceStateOffset : 0; } + bool isBindlessImage() const { return bindlessImage; } void setAs3DUavOrRtvImage(bool isUavOrRtv); void setIsPackedFormat(bool isPackedFormat) { this->isPackedFormat = isPackedFormat; } @@ -248,6 +252,8 @@ class Image : public MemObj { ImagePlane plane = ImagePlane::noPlane; bool is3DUAVOrRTV = false; bool isPackedFormat = false; + std::unique_ptr bindlessInfo; + bool bindlessImage = false; static bool isValidSingleChannelFormat(const cl_image_format *imageFormat); static bool isValidIntensityFormat(const cl_image_format *imageFormat); diff --git a/opencl/test/unit_test/helpers/api_specific_config_ocl_tests.cpp b/opencl/test/unit_test/helpers/api_specific_config_ocl_tests.cpp index 10547f82f8d33..362a6284061e5 100644 --- a/opencl/test/unit_test/helpers/api_specific_config_ocl_tests.cpp +++ b/opencl/test/unit_test/helpers/api_specific_config_ocl_tests.cpp @@ -8,7 +8,9 @@ #include "shared/source/helpers/api_specific_config.h" #include "shared/source/memory_manager/allocation_properties.h" #include "shared/source/memory_manager/compression_selector.h" +#include "shared/source/release_helper/release_helper.h" #include "shared/test/common/helpers/debug_manager_state_restore.h" +#include "shared/test/common/mocks/mock_release_helper.h" #include "opencl/source/os_interface/ocl_reg_path.h" @@ -57,4 +59,15 @@ TEST(ApiSpecificConfigOclTests, WhenCheckingIfDeviceUsmPoolingIsEnabledThenRetur EXPECT_TRUE(ApiSpecificConfig::isDeviceUsmPoolingEnabled()); } +TEST(ApiSpecificConfigOclTests, WhenGettingGlobalBindlessHeapConfigurationWithDebugFlagThenReturnDebugFlagValue) { + DebugManagerStateRestore restorer; + MockReleaseHelper releaseHelper; + + debugManager.flags.UseExternalAllocatorForSshAndDsh.set(1); + EXPECT_TRUE(ApiSpecificConfig::getGlobalBindlessHeapConfiguration(releaseHelper)); + + debugManager.flags.UseExternalAllocatorForSshAndDsh.set(0); + EXPECT_FALSE(ApiSpecificConfig::getGlobalBindlessHeapConfiguration(releaseHelper)); +} + } // namespace NEO diff --git a/opencl/test/unit_test/helpers/cl_memory_properties_helpers_tests.cpp b/opencl/test/unit_test/helpers/cl_memory_properties_helpers_tests.cpp index ca4b1d3c2ee03..7c950592ae2db 100644 --- a/opencl/test/unit_test/helpers/cl_memory_properties_helpers_tests.cpp +++ b/opencl/test/unit_test/helpers/cl_memory_properties_helpers_tests.cpp @@ -14,6 +14,7 @@ #include "shared/test/common/mocks/mock_graphics_allocation.h" #include "shared/test/common/mocks/ult_device_factory.h" +#include "opencl/extensions/public/cl_ext_private.h" #include "opencl/source/helpers/cl_memory_properties_helpers.h" #include "opencl/source/mem_obj/mem_obj_helper.h" #include "opencl/test/unit_test/mocks/mock_cl_device.h" @@ -599,3 +600,20 @@ TEST_F(MemoryPropertiesHelperTests, givenSubDeviceIdWhenParsingExtraMemoryProper EXPECT_EQ(0b10u, memoryProperties.pDevice->getDeviceBitfield().to_ulong()); EXPECT_EQ(&context.pSubDevice1->getDevice(), memoryProperties.pDevice); } +TEST_F(MemoryPropertiesHelperTests, givenBindlessImagePropertyWhenParsingMemoryPropertiesForImageThenTrueIsReturnedAndFlagIsSet) { + cl_mem_properties_intel properties[] = { + CL_MEM_BINDLESS_IMAGE_INTEL, 1, + 0}; + EXPECT_TRUE(ClMemoryPropertiesHelper::parseMemoryProperties(properties, memoryProperties, flags, flagsIntel, allocflags, + ClMemoryPropertiesHelper::ObjType::image, context)); + EXPECT_TRUE(memoryProperties.flags.bindlessImage); +} + +TEST_F(MemoryPropertiesHelperTests, givenNoBindlessImagePropertyWhenParsingMemoryPropertiesForImageThenBindlessFlagIsNotSet) { + cl_mem_properties_intel properties[] = { + CL_MEM_FLAGS, CL_MEM_READ_WRITE, + 0}; + EXPECT_TRUE(ClMemoryPropertiesHelper::parseMemoryProperties(properties, memoryProperties, flags, flagsIntel, allocflags, + ClMemoryPropertiesHelper::ObjType::image, context)); + EXPECT_FALSE(memoryProperties.flags.bindlessImage); +} diff --git a/shared/source/helpers/memory_properties_flags.h b/shared/source/helpers/memory_properties_flags.h index 5611a3c206d64..4d2c03667501d 100644 --- a/shared/source/helpers/memory_properties_flags.h +++ b/shared/source/helpers/memory_properties_flags.h @@ -35,6 +35,7 @@ struct MemoryFlags { uint32_t compressedHint : 1; uint32_t uncompressedHint : 1; uint32_t ipcSupportedAllocationByDefault : 1; + uint32_t bindlessImage : 1; bool operator==(const MemoryFlags &) const = default; };