feature: bindless image extension

- support for zeMemGetPitchFor2dImage() and
zeImageGetDeviceOffsetExp()

Related-To: NEO-10352

Signed-off-by: Mateusz Hoppe <mateusz.hoppe@intel.com>
This commit is contained in:
Mateusz Hoppe
2024-02-14 11:07:01 +00:00
committed by Compute-Runtime-Automation
parent 88c5872682
commit 3051c5ef2b
14 changed files with 297 additions and 13 deletions

View File

@@ -47,7 +47,14 @@ struct Image : _ze_image_handle_t {
virtual ze_result_t getMemoryProperties(ze_image_memory_properties_exp_t *pMemoryProperties) = 0;
virtual ze_result_t allocateBindlessSlot() = 0;
virtual NEO::SurfaceStateInHeapInfo *getBindlessSlot() = 0;
virtual ze_result_t getDeviceOffset(uint64_t *deviceOffset) = 0;
static ze_result_t getPitchFor2dImage(
ze_device_handle_t hDevice,
size_t imageWidth,
size_t imageHeight,
unsigned int elementSizeInByte,
size_t *rowPitch);
static Image *fromHandle(ze_image_handle_t handle) { return static_cast<Image *>(handle); }
inline ze_image_handle_t toHandle() { return this; }

View File

@@ -18,6 +18,7 @@ template <GFXCORE_FAMILY gfxCoreFamily>
struct ImageCoreFamily : public ImageImp {
using GfxFamily = typename NEO::GfxFamilyMapper<gfxCoreFamily>::GfxFamily;
using RENDER_SURFACE_STATE = typename GfxFamily::RENDER_SURFACE_STATE;
using ImageImp::bindlessImage;
ze_result_t initialize(Device *device, const ze_image_desc_t *desc) override;
void copySurfaceStateToSSH(void *surfaceStateHeap, const uint32_t surfaceStateOffset, bool isMediaBlockArg) override;

View File

@@ -36,8 +36,6 @@ ze_result_t ImageCoreFamily<gfxCoreFamily>::initialize(Device *device, const ze_
using RENDER_SURFACE_STATE = typename GfxFamily::RENDER_SURFACE_STATE;
const auto &rootDeviceEnvironment = device->getNEODevice()->getRootDeviceEnvironment();
const bool isBindlessMode = rootDeviceEnvironment.getReleaseHelper() ? NEO::ApiSpecificConfig::getBindlessMode(rootDeviceEnvironment.getReleaseHelper()) : false;
StructuresLookupTable lookupTable = {};
lookupTable.areImageProperties = true;
@@ -84,6 +82,11 @@ ze_result_t ImageCoreFamily<gfxCoreFamily>::initialize(Device *device, const ze_
imgInfo.plane = lookupTable.imageProperties.isPlanarExtension ? static_cast<GMM_YUV_PLANE>(lookupTable.imageProperties.planeIndex + 1u) : GMM_NO_PLANE;
imgInfo.useLocalMemory = false;
if (lookupTable.bindlessImage && this->device->getNEODevice()->getBindlessHeapsHelper() == nullptr) {
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
this->bindlessImage = lookupTable.bindlessImage;
if (!isImageView()) {
if (lookupTable.isSharedHandle) {
if (!lookupTable.sharedHandleType.isSupportedHandle) {
@@ -113,7 +116,11 @@ ze_result_t ImageCoreFamily<gfxCoreFamily>::initialize(Device *device, const ze_
}
}
if (isBindlessMode) {
if (this->bindlessImage) {
auto result = allocateBindlessSlot();
if (result != ZE_RESULT_SUCCESS) {
return result;
}
NEO::AllocationProperties imgImplicitArgsAllocProperties(device->getRootDeviceIndex(), NEO::ImageImplicitArgs::getSize(), NEO::AllocationType::buffer, device->getNEODevice()->getDeviceBitfield());
implicitArgsAllocation = device->getNEODevice()->getMemoryManager()->allocateGraphicsMemoryWithProperties(imgImplicitArgsAllocProperties);
}
@@ -172,7 +179,7 @@ ze_result_t ImageCoreFamily<gfxCoreFamily>::initialize(Device *device, const ze_
}
}
if (isBindlessMode && implicitArgsAllocation) {
if (this->bindlessImage && implicitArgsAllocation) {
implicitArgsSurfaceState = GfxFamily::cmdInitRenderSurfaceState;
auto clChannelType = getClChannelDataType(imageFormatDesc.format);

View File

@@ -10,6 +10,8 @@
#include "shared/source/device/device.h"
#include "shared/source/execution_environment/execution_environment.h"
#include "shared/source/execution_environment/root_device_environment.h"
#include "shared/source/gmm_helper/gmm.h"
#include "shared/source/helpers/basic_math.h"
#include "shared/source/helpers/bindless_heaps_helper.h"
#include "shared/source/helpers/gfx_core_helper.h"
#include "shared/source/helpers/hw_info.h"
@@ -18,6 +20,7 @@
#include "level_zero/core/source/device/device.h"
#include "level_zero/core/source/device/device_imp.h"
#include "level_zero/core/source/driver/driver_handle_imp.h"
#include "level_zero/core/source/image/image_formats.h"
#include "igfxfmid.h"
@@ -143,4 +146,55 @@ ze_result_t Image::create(uint32_t productFamily, Device *device, const ze_image
return result;
}
ze_result_t Image::getPitchFor2dImage(
ze_device_handle_t hDevice,
size_t imageWidth,
size_t imageHeight,
unsigned int elementSizeInByte,
size_t *rowPitch) {
NEO::StorageInfo storageInfo = {};
NEO::GmmRequirements gmmRequirements{};
gmmRequirements.allowLargePages = true;
NEO::ImageInfo imgInfo = {};
imgInfo.imgDesc.imageType = NEO::ImageType::image2D;
imgInfo.imgDesc.imageWidth = imageWidth;
imgInfo.imgDesc.imageHeight = imageHeight;
imgInfo.linearStorage = true;
const uint32_t exponent = Math::log2(elementSizeInByte);
if (exponent >= 5u) {
return ZE_RESULT_ERROR_INVALID_ARGUMENT;
}
imgInfo.surfaceFormat = &ImageFormats::surfaceFormatsForRedescribe[exponent % 5];
DeviceImp *deviceImp = static_cast<DeviceImp *>(Device::fromHandle(hDevice));
NEO::Gmm gmm(deviceImp->getNEODevice()->getExecutionEnvironment()->rootDeviceEnvironments[deviceImp->getRootDeviceIndex()]->getGmmHelper(),
imgInfo,
storageInfo,
false);
*rowPitch = imgInfo.rowPitch;
return ZE_RESULT_SUCCESS;
}
ze_result_t ImageImp::getDeviceOffset(uint64_t *deviceOffset) {
if (!this->bindlessImage) {
return ZE_RESULT_ERROR_NOT_AVAILABLE;
}
auto result = allocateBindlessSlot();
if (result == ZE_RESULT_SUCCESS) {
DEBUG_BREAK_IF(this->getBindlessSlot() == nullptr);
*deviceOffset = this->getBindlessSlot()->surfaceStateOffset;
}
return result;
}
} // namespace L0

View File

@@ -48,6 +48,7 @@ struct ImageImp : public Image, NEO::NonCopyableOrMovableClass {
ze_result_t allocateBindlessSlot() override;
NEO::SurfaceStateInHeapInfo *getBindlessSlot() override;
ze_result_t getDeviceOffset(uint64_t *deviceOffset) override;
protected:
Device *device = nullptr;
@@ -57,5 +58,6 @@ struct ImageImp : public Image, NEO::NonCopyableOrMovableClass {
ze_image_desc_t imageFormatDesc = {};
std::optional<ze_image_desc_t> sourceImageFormatDesc = {};
std::unique_ptr<NEO::SurfaceStateInHeapInfo> bindlessInfo;
bool bindlessImage = false;
};
} // namespace L0