Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions level_zero/core/source/helpers/api_specific_config_l0.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,5 +115,9 @@ bool ApiSpecificConfig::isGlobalStatelessEnabled(const RootDeviceEnvironment &ro
bool ApiSpecificConfig::isUpdateTagFromWaitEnabledForHeapless() {
return false;
}
bool ApiSpecificConfig::createBindlessHeapsHelper(const Device &device) {
return getGlobalBindlessHeapConfiguration(device.getHardwareInfo()) && getBindlessMode(device);
}


} // namespace NEO
7 changes: 7 additions & 0 deletions opencl/extensions/public/cl_ext_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -421,4 +421,11 @@ 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 0x10060
#define CL_IMAGE_BINDLESS_HANDLE_INTEL 0x10061

#endif
1 change: 1 addition & 0 deletions opencl/source/command_queue/enqueue_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -937,6 +937,7 @@ CompletionStamp CommandQueueHw<GfxFamily>::enqueueNonBlocked(
isDcFlushRequiredOnStallingCommandsOnNextFlush() // isDcFlushRequiredOnStallingCommandsOnNextFlush
);

dispatchFlags.useBindlessImages = kernel->usesBindlessImages();
dispatchFlags.isWalkerWithProfilingEnqueued = getAndClearIsWalkerWithProfilingEnqueued();
dispatchFlags.pipelineSelectArgs.systolicPipelineSelectMode = systolicPipelineSelectMode;
uint32_t lws[3] = {static_cast<uint32_t>(multiDispatchInfo.begin()->getLocalWorkgroupSize().x), static_cast<uint32_t>(multiDispatchInfo.begin()->getLocalWorkgroupSize().y), static_cast<uint32_t>(multiDispatchInfo.begin()->getLocalWorkgroupSize().z)};
Expand Down
11 changes: 7 additions & 4 deletions opencl/source/helpers/api_specific_config_ocl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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/helpers/hw_info.h"

#include "opencl/source/os_interface/ocl_reg_path.h"

Expand All @@ -19,20 +20,18 @@ namespace NEO {
StackVec<const char *, 4> validClPrefixes;
StackVec<NEO::DebugVarPrefix, 4> validClPrefixTypes;

bool ApiSpecificConfig::getGlobalBindlessHeapConfiguration(const HardwareInfo &hwInfo) {
bool ApiSpecificConfig::getGlobalBindlessHeapConfiguration(const HardwareInfo &) {
return false;
}

bool ApiSpecificConfig::getBindlessMode(const Device &device) {
if (device.getCompilerProductHelper().isHeaplessModeEnabled(device.getHardwareInfo())) {
return true;
}

if (debugManager.flags.UseBindlessMode.get() != -1) {
return debugManager.flags.UseBindlessMode.get();
} else {
return false;
}
return false;
}

bool ApiSpecificConfig::isDeviceAllocationCacheEnabled() {
Expand Down Expand Up @@ -96,4 +95,8 @@ bool ApiSpecificConfig::isUpdateTagFromWaitEnabledForHeapless() {
return true;
}

bool ApiSpecificConfig::createBindlessHeapsHelper(const Device &) {
return false;
}

} // namespace NEO
9 changes: 6 additions & 3 deletions opencl/source/helpers/cl_memory_properties_helpers.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2021-2024 Intel Corporation
* Copyright (C) 2021-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
Expand All @@ -24,7 +24,7 @@ bool ClMemoryPropertiesHelper::parseMemoryProperties(const cl_mem_properties_int
uint64_t handleType = 0;
uintptr_t hostptr = 0;
std::vector<Device *> devices;

bool bindlessImage = false;
if (properties != nullptr) {
for (int i = 0; properties[i] != 0; i += 2) {
switch (properties[i]) {
Expand Down Expand Up @@ -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;
}
Expand All @@ -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) &&
Expand Down
4 changes: 3 additions & 1 deletion opencl/source/helpers/hardware_commands_helper_base.inl
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "shared/source/device/device.h"
#include "shared/source/helpers/address_patch.h"
#include "shared/source/helpers/aligned_memory.h"
#include "shared/source/helpers/api_specific_config.h"
#include "shared/source/helpers/basic_math.h"
#include "shared/source/helpers/gfx_core_helper.h"
#include "shared/source/helpers/hw_info.h"
Expand Down Expand Up @@ -260,9 +261,10 @@ size_t HardwareCommandsHelper<GfxFamily>::sendIndirectState(
const auto &samplerTable = kernelInfo.kernelDescriptor.payloadMappings.samplerTable;
if (isValidOffset(samplerTable.tableOffset) && isValidOffset(samplerTable.borderColor)) {
samplerCount = samplerTable.numSamplers;
auto *samplerHeapHelper = ApiSpecificConfig::getBindlessMode(device) ? device.getBindlessHeapsHelper() : nullptr;
samplerStateOffset = EncodeStates<GfxFamily>::copySamplerState(&dsh, samplerTable.tableOffset,
samplerCount, samplerTable.borderColor,
kernel.getDynamicStateHeap(), device.getBindlessHeapsHelper(),
kernel.getDynamicStateHeap(), samplerHeapHelper,
device.getRootDeviceEnvironment());
if constexpr (heaplessModeEnabled) {
uint64_t bindlessSamplerStateAddress = samplerStateOffset;
Expand Down
1 change: 1 addition & 0 deletions opencl/source/helpers/task_information.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ CompletionStamp &CommandComputeKernel::submit(TaskCountType taskLevel, bool term
commandQueue.isStallingCommandsOnNextFlushRequired(), // isStallingCommandsOnNextFlushRequired
commandQueue.isDcFlushRequiredOnStallingCommandsOnNextFlush() // isDcFlushRequiredOnStallingCommandsOnNextFlush
);
dispatchFlags.useBindlessImages = kernel->usesBindlessImages();
if (commandQueue.getContext().getRootDeviceIndices().size() > 1) {
eventsRequest.fillCsrDependenciesForRootDevices(dispatchFlags.csrDependencies, commandStreamReceiver);
}
Expand Down
49 changes: 42 additions & 7 deletions opencl/source/kernel/kernel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "shared/source/gmm_helper/resource_info.h"
#include "shared/source/helpers/address_patch.h"
#include "shared/source/helpers/aligned_memory.h"
#include "shared/source/helpers/api_specific_config.h"
#include "shared/source/helpers/basic_math.h"
#include "shared/source/helpers/bindless_heaps_helper.h"
#include "shared/source/helpers/compiler_product_helper.h"
Expand All @@ -30,6 +31,7 @@
#include "shared/source/helpers/ptr_math.h"
#include "shared/source/helpers/simd_helper.h"
#include "shared/source/helpers/surface_format_info.h"
#include "shared/source/indirect_heap/indirect_heap.h"
#include "shared/source/kernel/local_ids_cache.h"
#include "shared/source/memory_manager/compression_selector.h"
#include "shared/source/memory_manager/memory_manager.h"
Expand Down Expand Up @@ -147,9 +149,9 @@ void Kernel::patchWithImplicitSurface(uint64_t ptrToPatchInCrossThreadData, Grap
void *surfaceState = nullptr;
auto surfaceStateSize = gfxCoreHelper.getRenderSurfaceStateSize(clDevice.getRootDeviceEnvironment());

if (clDevice.getDevice().getBindlessHeapsHelper()) {
if (clDevice.getDevice().getBindlessHeapsHelper() &&
ApiSpecificConfig::getBindlessMode(clDevice.getDevice())) {
UNRECOVERABLE_IF(clDevice.getDevice().getCompilerProductHelper().isHeaplessModeEnabled(clDevice.getHardwareInfo()));

auto &ssInHeap = allocation.getBindlessInfo();
surfaceState = ssInHeap.ssPtr;
auto patchLocation = ptrOffset(crossThreadData, arg.bindless);
Expand Down Expand Up @@ -1341,7 +1343,17 @@ void Kernel::makeResident(CommandStreamReceiver &commandStreamReceiver) {
pageFaultManager->moveAllocationsWithinUMAllocsManagerToGpuDomain(this->getContext().getSVMAllocsManager());
}
makeArgsResident(commandStreamReceiver);

auto bindlessHelper = getDevice().getDevice().getBindlessHeapsHelper();
if (bindlessHelper) {
for (auto heapType : {NEO::BindlessHeapsHelper::specialSsh,
NEO::BindlessHeapsHelper::globalSsh,
NEO::BindlessHeapsHelper::globalDsh}) {
auto heap = bindlessHelper->getHeap(heapType);
if (heap) {
commandStreamReceiver.makeResident(*heap->getGraphicsAllocation());
}
}
}
auto kernelIsaAllocation = this->kernelInfo.getIsaGraphicsAllocation();
if (kernelIsaAllocation) {
commandStreamReceiver.makeResident(*kernelIsaAllocation);
Expand Down Expand Up @@ -1523,6 +1535,10 @@ void Kernel::getAllocationsInfo(std::vector<cl_kernel_allocation_info_intel> &al
}
}

bool Kernel::usesBindlessImages() const {
return program->usesBindlessImages(clDevice.getRootDeviceIndex());
}

cl_int Kernel::setArgLocal(uint32_t argIndexIn,
size_t argSize,
const void *argVal) {
Expand Down Expand Up @@ -1715,7 +1731,19 @@ cl_int Kernel::setArgImageWithMipLevel(uint32_t argIndex,
imageFromBufferArgsCount += (pImage->isImageFromBuffer() ? 1 : 0) - (wasImageFromBuffer ? 1 : 0);

void *surfaceState = nullptr;
if (isValidOffset(argAsImg.bindless)) {
if (isValidOffset(argAsImg.bindless) && pImage->isBindlessImage()) {
auto bindlessSlot = pImage->getBindlessSlot();
if (bindlessSlot && bindlessSlot->ssPtr) {
surfaceState = bindlessSlot->ssPtr;

auto &gfxCoreHelper = this->getGfxCoreHelper();
auto patchLocation = ptrOffset(getCrossThreadData(), argAsImg.bindless);
uint64_t patchValue = gfxCoreHelper.getBindlessSurfaceExtendedMessageDescriptorValue(
static_cast<uint32_t>(bindlessSlot->surfaceStateOffset));
uint32_t patchSize = NEO::isUndefinedOffset(argAsImg.size) ? 0 : argAsImg.size;
patchWithRequiredSize(reinterpret_cast<uint8_t *>(patchLocation), patchSize, patchValue);
}
} else if (isValidOffset(argAsImg.bindless)) {
auto ssIndex = getSurfaceStateIndexForBindlessOffset(argAsImg.bindless);
if (ssIndex < std::numeric_limits<uint32_t>::max()) {
auto &gfxCoreHelper = this->getGfxCoreHelper();
Expand All @@ -1727,10 +1755,8 @@ cl_int Kernel::setArgImageWithMipLevel(uint32_t argIndex,
surfaceState = ptrOffset(getSurfaceStateHeap(), argAsImg.bindful);
}

// Sets SS structure
UNRECOVERABLE_IF(surfaceState == nullptr);
pImage->setImageArg(surfaceState, arg.getExtendedTypeInfo().isMediaBlockImage, mipLevel, rootDeviceIndex);

auto &imageDesc = pImage->getImageDesc();
auto &imageFormat = pImage->getImageFormat();

Expand Down Expand Up @@ -2075,13 +2101,22 @@ void Kernel::patchBindlessSurfaceStatesInCrossThreadData(uint64_t bindlessSurfac
auto surfaceStateSize = gfxCoreHelper.getRenderSurfaceStateSize(getDevice().getRootDeviceEnvironment());
auto *crossThreadDataPtr = reinterpret_cast<uint8_t *>(getCrossThreadData());

for (auto &arg : kernelInfo.kernelDescriptor.payloadMappings.explicitArgs) {
const auto &explicitArgs = kernelInfo.kernelDescriptor.payloadMappings.explicitArgs;
for (size_t argIndex = 0; argIndex < explicitArgs.size(); argIndex++) {
const auto &arg = explicitArgs[argIndex];

auto offset = NEO::undefined<NEO::CrossThreadDataOffset>;
if (arg.type == NEO::ArgDescriptor::argTPointer) {
offset = arg.as<NEO::ArgDescPointer>().bindless;
} else if (arg.type == NEO::ArgDescriptor::argTImage) {
offset = arg.as<NEO::ArgDescImage>().bindless;
if (NEO::isValidOffset(offset)) {
auto clMem = static_cast<cl_mem>(kernelArguments[argIndex].object);
auto pImage = castToObject<Image>(clMem);
if (pImage && pImage->isBindlessImage()) {
continue;
}
}
} else {
continue;
}
Expand Down
2 changes: 2 additions & 0 deletions opencl/source/kernel/kernel.h
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,8 @@ class Kernel : public ReferenceTrackedObject<Kernel>, NEO::NonCopyableAndNonMova

MOCKABLE_VIRTUAL void getAllocationsInfo(std::vector<cl_kernel_allocation_info_intel> &allocationsInfo) const;

bool usesBindlessImages() const;

protected:
Kernel(Program *programArg, const KernelInfo &kernelInfo, ClDevice &clDevice);

Expand Down
30 changes: 29 additions & 1 deletion opencl/source/mem_obj/image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,30 @@ Image *Image::create(Context *context,

setImageProperties(image, *imageDesc, imgInfo, parentImage, parentBuffer, hostPtrRowPitch, hostPtrSlicePitch, imageCount, hostPtrMinSize);

auto defaultRootDeviceEnv = defaultDevice->getExecutionEnvironment()->rootDeviceEnvironments[defaultRootDeviceIndex].get();

if (image && memoryProperties.flags.bindlessImage &&
defaultRootDeviceEnv->getBindlessHeapsHelper() == nullptr) {
auto *rootDevice = defaultDevice->getRootDevice();
defaultRootDeviceEnv->createBindlessHeapsHelper(
rootDevice, rootDevice->getNumGenericSubDevices() > 1);
}

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<uint64_t>::max()) {
image->bindlessInfo = std::make_unique<SurfaceStateInHeapInfo>(allocation->getBindlessInfo());
image->bindlessImage = true;
if (image->bindlessInfo->ssPtr) {
image->setImageArg(image->bindlessInfo->ssPtr, false, 0, defaultRootDeviceIndex);
}
}
}
}

errcodeRet = CL_SUCCESS;
auto &defaultHwInfo = defaultDevice->getHardwareInfo();
if (context->isProvidingPerformanceHints()) {
Expand Down Expand Up @@ -870,7 +894,11 @@ cl_int Image::getImageInfo(cl_image_info paramName,
srcParamSize = sizeof(cl_uint);
srcParam = &(imageDesc.num_samples);
break;

case CL_IMAGE_BINDLESS_HANDLE_INTEL:
srcParamSize = sizeof(uint64_t);
retParam = getBindlessHandle();
srcParam = &retParam;
break;
default:
getOsSpecificImageInfo(paramName, &srcParamSize, &srcParam);
break;
Expand Down
6 changes: 6 additions & 0 deletions opencl/source/mem_obj/image.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -209,6 +210,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; }

Expand Down Expand Up @@ -252,6 +256,8 @@ class Image : public MemObj {
ImagePlane plane = ImagePlane::noPlane;
bool is3DUAVOrRTV = false;
bool isPackedFormat = false;
std::unique_ptr<SurfaceStateInHeapInfo> bindlessInfo;
bool bindlessImage = false;

static bool isValidSingleChannelFormat(const cl_image_format *imageFormat);
static bool isValidIntensityFormat(const cl_image_format *imageFormat);
Expand Down
11 changes: 11 additions & 0 deletions opencl/source/program/build.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,15 @@ cl_int Program::build(
options = "";
}
}
const bool hasBindlessImages = CompilerOptions::extract(CompilerOptions::bindlessImages, options);
const bool hasBindlessAdvancedMode = CompilerOptions::extract(CompilerOptions::bindlessAdvancedMode, options);

if (hasBindlessImages) {
CompilerOptions::concatenateAppend(internalOptions, CompilerOptions::bindlessImages);
}
if (hasBindlessAdvancedMode) {
CompilerOptions::concatenateAppend(internalOptions, CompilerOptions::bindlessAdvancedMode);
}
const bool shouldSuppressRebuildWarning{CompilerOptions::extract(CompilerOptions::noRecompiledFromIr, options)};
extractInternalOptions(options, internalOptions);
CompilerOptions::applyAdditionalApiOptions(options);
Expand Down Expand Up @@ -133,6 +141,9 @@ cl_int Program::build(
}
this->replaceDeviceBinary(std::move(compilerOuput.deviceBinary.mem), compilerOuput.deviceBinary.size, clDevice->getRootDeviceIndex());
phaseReached[clDevice->getRootDeviceIndex()] = BuildPhase::binaryCreation;

this->buildInfos[clDevice->getRootDeviceIndex()].useBindlessImages = hasBindlessImages;

}
if (retVal != CL_SUCCESS) {
break;
Expand Down
6 changes: 6 additions & 0 deletions opencl/source/program/program.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,10 @@ class Program : public BaseObject<_cl_program> {
return isSpirV;
}

bool usesBindlessImages(uint32_t rootDeviceIndex) const {
return buildInfos[rootDeviceIndex].useBindlessImages;
}

void freeGlobalBufferAllocation(std::unique_ptr<NEO::SharedPoolAllocation> &buffer);

NEO::SharedPoolAllocation *getConstantSurface(uint32_t rootDeviceIndex) const;
Expand Down Expand Up @@ -381,6 +385,8 @@ class Program : public BaseObject<_cl_program> {
std::unique_ptr<char[]> debugData;
size_t debugDataSize = 0U;
size_t kernelMiscInfoPos = std::string::npos;

bool useBindlessImages = false;
};

std::vector<BuildInfo> buildInfos;
Expand Down
Loading