405 lines
21 KiB
C++
405 lines
21 KiB
C++
/*
|
|
* Copyright (C) 2018-2022 Intel Corporation
|
|
*
|
|
* SPDX-License-Identifier: MIT
|
|
*
|
|
*/
|
|
|
|
#pragma once
|
|
#include "shared/source/helpers/string.h"
|
|
#include "shared/source/image/image_surface_state.h"
|
|
|
|
#include "opencl/source/helpers/cl_validators.h"
|
|
#include "opencl/source/helpers/surface_formats.h"
|
|
#include "opencl/source/mem_obj/buffer.h"
|
|
#include "opencl/source/mem_obj/mem_obj.h"
|
|
|
|
namespace NEO {
|
|
class Image;
|
|
struct KernelInfo;
|
|
struct SurfaceFormatInfo;
|
|
class GfxCoreHelper;
|
|
|
|
using ImageCreateFunc = Image *(*)(Context *context,
|
|
const MemoryProperties &memoryProperties,
|
|
uint64_t flags,
|
|
uint64_t flagsIntel,
|
|
size_t size,
|
|
void *hostPtr,
|
|
const cl_image_format &imageFormat,
|
|
const cl_image_desc &imageDesc,
|
|
bool zeroCopy,
|
|
MultiGraphicsAllocation multiGraphicsAllocation,
|
|
bool isImageRedescribed,
|
|
uint32_t baseMipLevel,
|
|
uint32_t mipCount,
|
|
const ClSurfaceFormatInfo *surfaceFormatInfo,
|
|
const SurfaceOffsets *surfaceOffsets);
|
|
|
|
struct ImageFactoryFuncs {
|
|
ImageCreateFunc createImageFunction;
|
|
};
|
|
|
|
namespace ImageFunctions {
|
|
using ValidateAndCreateImageFunc = std::function<cl_mem(cl_context context,
|
|
const uint64_t *properties,
|
|
uint64_t flags,
|
|
uint64_t flagsIntel,
|
|
const cl_image_format *imageFormat,
|
|
const cl_image_desc *imageDesc,
|
|
const void *hostPtr,
|
|
int32_t &errcodeRet)>;
|
|
extern ValidateAndCreateImageFunc validateAndCreateImage;
|
|
} // namespace ImageFunctions
|
|
|
|
class Image : public MemObj {
|
|
public:
|
|
const static cl_ulong maskMagic = 0xFFFFFFFFFFFFFFFFLL;
|
|
static const cl_ulong objectMagic = MemObj::objectMagic | 0x01;
|
|
|
|
~Image() override = default;
|
|
|
|
static Image *create(Context *context,
|
|
const MemoryProperties &memoryProperties,
|
|
cl_mem_flags flags,
|
|
cl_mem_flags_intel flagsIntel,
|
|
const ClSurfaceFormatInfo *surfaceFormat,
|
|
const cl_image_desc *imageDesc,
|
|
const void *hostPtr,
|
|
cl_int &errcodeRet);
|
|
|
|
static cl_mem validateAndCreateImage(cl_context context,
|
|
const cl_mem_properties *properties,
|
|
cl_mem_flags flags,
|
|
cl_mem_flags_intel flagsIntel,
|
|
const cl_image_format *imageFormat,
|
|
const cl_image_desc *imageDesc,
|
|
const void *hostPtr,
|
|
cl_int &errcodeRet);
|
|
|
|
static Image *createImageHw(Context *context, const MemoryProperties &memoryProperties, cl_mem_flags flags,
|
|
cl_mem_flags_intel flagsIntel, size_t size, void *hostPtr,
|
|
const cl_image_format &imageFormat, const cl_image_desc &imageDesc,
|
|
bool zeroCopy, MultiGraphicsAllocation multiGraphicsAllocation,
|
|
bool isObjectRedescribed, uint32_t baseMipLevel, uint32_t mipCount, const ClSurfaceFormatInfo *surfaceFormatInfo = nullptr);
|
|
|
|
static Image *createSharedImage(Context *context, SharingHandler *sharingHandler, const McsSurfaceInfo &mcsSurfaceInfo,
|
|
MultiGraphicsAllocation multiGraphicsAllocation, GraphicsAllocation *mcsAllocation,
|
|
cl_mem_flags flags, cl_mem_flags_intel flagsIntel, const ClSurfaceFormatInfo *surfaceFormat, ImageInfo &imgInfo, uint32_t cubeFaceIndex, uint32_t baseMipLevel, uint32_t mipCount);
|
|
|
|
static cl_int validate(Context *context,
|
|
const MemoryProperties &memoryProperties,
|
|
const ClSurfaceFormatInfo *surfaceFormat,
|
|
const cl_image_desc *imageDesc,
|
|
const void *hostPtr);
|
|
static cl_int validateImageFormat(const cl_image_format *imageFormat);
|
|
|
|
static int32_t validatePlanarYUV(Context *context,
|
|
const MemoryProperties &memoryProperties,
|
|
const cl_image_desc *imageDesc,
|
|
const void *hostPtr);
|
|
|
|
static int32_t validatePackedYUV(const MemoryProperties &memoryProperties, const cl_image_desc *imageDesc);
|
|
|
|
static cl_int validateImageTraits(Context *context, const MemoryProperties &memoryProperties, const cl_image_format *imageFormat, const cl_image_desc *imageDesc, const void *hostPtr);
|
|
|
|
static size_t calculateHostPtrSize(const size_t *region, size_t rowPitch, size_t slicePitch, size_t pixelSize, uint32_t imageType);
|
|
|
|
static void calculateHostPtrOffset(size_t *imageOffset, const size_t *origin, const size_t *region, size_t rowPitch, size_t slicePitch, uint32_t imageType, size_t bytesPerPixel);
|
|
|
|
static cl_int getImageParams(Context *context,
|
|
cl_mem_flags flags,
|
|
const ClSurfaceFormatInfo *surfaceFormat,
|
|
const cl_image_desc *imageDesc,
|
|
size_t *imageRowPitch,
|
|
size_t *imageSlicePitch);
|
|
|
|
static bool isImage1d(const cl_image_desc &imageDesc);
|
|
static bool isImage2d(cl_mem_object_type imageType);
|
|
static bool isImage3d(cl_mem_object_type imageType);
|
|
static bool isImage2dOr2dArray(cl_mem_object_type imageType);
|
|
static bool isImageArray(cl_mem_object_type imageType);
|
|
|
|
static bool isDepthFormat(const cl_image_format &imageFormat);
|
|
|
|
static bool hasSlices(cl_mem_object_type type) {
|
|
return (type == CL_MEM_OBJECT_IMAGE3D) || (type == CL_MEM_OBJECT_IMAGE1D_ARRAY) || (type == CL_MEM_OBJECT_IMAGE2D_ARRAY);
|
|
}
|
|
|
|
static ImageType convertType(const cl_mem_object_type type);
|
|
static cl_mem_object_type convertType(const ImageType type);
|
|
static ImageDescriptor convertDescriptor(const cl_image_desc &imageDesc);
|
|
static cl_image_desc convertDescriptor(const ImageDescriptor &imageDesc);
|
|
|
|
cl_int getImageInfo(cl_image_info paramName,
|
|
size_t paramValueSize,
|
|
void *paramValue,
|
|
size_t *paramValueSizeRet);
|
|
|
|
virtual void setImageArg(void *memory, bool isMediaBlockImage, uint32_t mipLevel, uint32_t rootDeviceIndex, bool useGlobalAtomics) = 0;
|
|
virtual void setMediaImageArg(void *memory, uint32_t rootDeviceIndex) = 0;
|
|
virtual void setMediaSurfaceRotation(void *memory) = 0;
|
|
virtual void setSurfaceMemoryObjectControlState(void *memory, uint32_t value) = 0;
|
|
|
|
const cl_image_desc &getImageDesc() const;
|
|
const cl_image_format &getImageFormat() const;
|
|
const ClSurfaceFormatInfo &getSurfaceFormatInfo() const;
|
|
|
|
void transferDataToHostPtr(MemObjSizeArray ©Size, MemObjOffsetArray ©Offset) override;
|
|
void transferDataFromHostPtr(MemObjSizeArray ©Size, MemObjOffsetArray ©Offset) override;
|
|
|
|
Image *redescribe();
|
|
Image *redescribeFillImage();
|
|
ImageCreateFunc createFunction = nullptr;
|
|
|
|
uint32_t getQPitch() { return qPitch; }
|
|
void setQPitch(uint32_t qPitch) { this->qPitch = qPitch; }
|
|
size_t getHostPtrRowPitch() const { return hostPtrRowPitch; }
|
|
void setHostPtrRowPitch(size_t pitch) { this->hostPtrRowPitch = pitch; }
|
|
size_t getHostPtrSlicePitch() const { return hostPtrSlicePitch; }
|
|
void setHostPtrSlicePitch(size_t pitch) { this->hostPtrSlicePitch = pitch; }
|
|
size_t getImageCount() const { return imageCount; }
|
|
void setImageCount(size_t imageCount) { this->imageCount = imageCount; }
|
|
void setImageRowPitch(size_t rowPitch) { imageDesc.image_row_pitch = rowPitch; }
|
|
void setImageSlicePitch(size_t slicePitch) { imageDesc.image_slice_pitch = slicePitch; }
|
|
void setSurfaceOffsets(uint64_t offset, uint32_t xOffset, uint32_t yOffset, uint32_t yOffsetForUVPlane) {
|
|
surfaceOffsets.offset = offset;
|
|
surfaceOffsets.xOffset = xOffset;
|
|
surfaceOffsets.yOffset = yOffset;
|
|
surfaceOffsets.yOffsetForUVplane = yOffsetForUVPlane;
|
|
}
|
|
void getSurfaceOffsets(SurfaceOffsets &surfaceOffsetsOut) { surfaceOffsetsOut = this->surfaceOffsets; }
|
|
|
|
void setCubeFaceIndex(uint32_t index) { cubeFaceIndex = index; }
|
|
uint32_t getCubeFaceIndex() { return cubeFaceIndex; }
|
|
void setMediaPlaneType(cl_uint type) { mediaPlaneType = type; }
|
|
cl_uint getMediaPlaneType() const { return mediaPlaneType; }
|
|
int peekBaseMipLevel() { return baseMipLevel; }
|
|
void setBaseMipLevel(int level) { this->baseMipLevel = level; }
|
|
|
|
uint32_t peekMipCount() { return mipCount; }
|
|
void setMipCount(uint32_t mipCountNew) { this->mipCount = mipCountNew; }
|
|
|
|
static const ClSurfaceFormatInfo *getSurfaceFormatFromTable(cl_mem_flags flags, const cl_image_format *imageFormat, bool supportsOcl20Features);
|
|
static cl_int validateRegionAndOrigin(const size_t *origin, const size_t *region, const cl_image_desc &imgDesc);
|
|
|
|
cl_int writeNV12Planes(const void *hostPtr, size_t hostPtrRowPitch, uint32_t rootDeviceIndex);
|
|
void setMcsSurfaceInfo(const McsSurfaceInfo &info) { mcsSurfaceInfo = info; }
|
|
const McsSurfaceInfo &getMcsSurfaceInfo() { return mcsSurfaceInfo; }
|
|
void setPlane(const GMM_YUV_PLANE_ENUM plane) { this->plane = plane; }
|
|
GMM_YUV_PLANE_ENUM getPlane() const { return this->plane; }
|
|
size_t calculateOffsetForMapping(const MemObjOffsetArray &origin) const override;
|
|
|
|
virtual void transformImage2dArrayTo3d(void *memory) = 0;
|
|
virtual void transformImage3dTo2dArray(void *memory) = 0;
|
|
|
|
bool hasSameDescriptor(const cl_image_desc &imageDesc) const;
|
|
bool hasValidParentImageFormat(const cl_image_format &imageFormat) const;
|
|
|
|
bool isImageFromBuffer() const { return castToObject<Buffer>(static_cast<cl_mem>(associatedMemObject)) ? true : false; }
|
|
bool isImageFromImage() const { return castToObject<Image>(static_cast<cl_mem>(associatedMemObject)) ? true : false; }
|
|
|
|
static cl_int checkIfDeviceSupportsImages(cl_context context);
|
|
|
|
void fillImageRegion(size_t *region) const;
|
|
|
|
protected:
|
|
Image(Context *context,
|
|
const MemoryProperties &memoryProperties,
|
|
cl_mem_flags flags,
|
|
cl_mem_flags_intel flagsIntel,
|
|
size_t size,
|
|
void *memoryStorage,
|
|
void *hostPtr,
|
|
cl_image_format imageFormat,
|
|
const cl_image_desc &imageDesc,
|
|
bool zeroCopy,
|
|
MultiGraphicsAllocation multiGraphicsAllocation,
|
|
bool isObjectRedescribed,
|
|
uint32_t baseMipLevel,
|
|
uint32_t mipCount,
|
|
const ClSurfaceFormatInfo &surfaceFormatInfo,
|
|
const SurfaceOffsets *surfaceOffsets = nullptr);
|
|
|
|
void getOsSpecificImageInfo(const cl_mem_info ¶mName, size_t *srcParamSize, void **srcParam);
|
|
|
|
MOCKABLE_VIRTUAL void transferData(void *dst, size_t dstRowPitch, size_t dstSlicePitch,
|
|
void *src, size_t srcRowPitch, size_t srcSlicePitch,
|
|
std::array<size_t, 3> copyRegion, std::array<size_t, 3> copyOrigin);
|
|
|
|
cl_image_format imageFormat;
|
|
cl_image_desc imageDesc;
|
|
ClSurfaceFormatInfo surfaceFormatInfo;
|
|
McsSurfaceInfo mcsSurfaceInfo = {};
|
|
uint32_t qPitch = 0;
|
|
size_t hostPtrRowPitch = 0;
|
|
size_t hostPtrSlicePitch = 0;
|
|
size_t imageCount = 0;
|
|
uint32_t cubeFaceIndex = __GMM_NO_CUBE_MAP;
|
|
cl_uint mediaPlaneType = 0;
|
|
SurfaceOffsets surfaceOffsets = {0};
|
|
uint32_t baseMipLevel = 0;
|
|
uint32_t mipCount = 1;
|
|
GMM_YUV_PLANE_ENUM plane = GMM_NO_PLANE;
|
|
|
|
static bool isValidSingleChannelFormat(const cl_image_format *imageFormat);
|
|
static bool isValidIntensityFormat(const cl_image_format *imageFormat);
|
|
static bool isValidLuminanceFormat(const cl_image_format *imageFormat);
|
|
static bool isValidDepthFormat(const cl_image_format *imageFormat);
|
|
static bool isValidDoubleChannelFormat(const cl_image_format *imageFormat);
|
|
static bool isValidTripleChannelFormat(const cl_image_format *imageFormat);
|
|
static bool isValidRGBAFormat(const cl_image_format *imageFormat);
|
|
static bool isValidSRGBFormat(const cl_image_format *imageFormat);
|
|
static bool isValidARGBFormat(const cl_image_format *imageFormat);
|
|
static bool isValidDepthStencilFormat(const cl_image_format *imageFormat);
|
|
static bool isValidYUVFormat(const cl_image_format *imageFormat);
|
|
static bool hasAlphaChannel(const cl_image_format *imageFormat);
|
|
static size_t getImageHeight(const cl_image_desc &imageDesc);
|
|
static size_t getImageDepth(const cl_image_desc &imageDesc);
|
|
static size_t getHostPtrMinSize(cl_mem_object_type imageType, const cl_image_format &imageFormat,
|
|
size_t hostPtrRowPitch, size_t hostPtrSlicePitch, size_t imageHeight, size_t imageDepth, size_t imageCount);
|
|
static size_t getHostPtrSlicePitch(const cl_image_desc &imageDesc, size_t hostPtrRowPitch, size_t imageHeight);
|
|
static bool isParentMemObject(const cl_image_desc &imageDesc);
|
|
static bool isImageFromBuffer(const cl_image_desc &imageDesc, Buffer *buffer);
|
|
static void setImageProperties(Image *image, const cl_image_desc &imageDesc, const ImageInfo &imageInfo, Image *parentImage, Buffer *parentBuffer,
|
|
size_t hostPtrRowPitch, size_t hostPtrSlicePitch, size_t imageCount, size_t hostPtrMinSize);
|
|
|
|
static void adjustImagePropertiesFromParentImage(size_t &width, size_t &height, size_t &depth, ImageInfo &imageInfo, cl_image_desc &descriptor, Image *parentImage);
|
|
|
|
static void setAllocationInfoFromParentBuffer(CreateMemObj::AllocationInfo &allocationInfo, const void *&hostPtr, void *&hostPtrToSet,
|
|
Buffer *parentBuffer, ImageInfo &imageInfo, uint32_t rootDeviceIndex);
|
|
|
|
static void setAllocationInfoFromHostPtrWithSharedContext(CreateMemObj::AllocationInfo &allocationInfo, uint32_t rootDeviceIndex, ImageInfo &imageInfo,
|
|
Context *context, bool preferCompression, MemoryManager *memoryManager, const void *hostPtr);
|
|
|
|
static void setAllocationInfoFromHostPtr(CreateMemObj::AllocationInfo &allocationInfo, uint32_t rootDeviceIndex, const HardwareInfo &hwInfo,
|
|
const MemoryProperties &memoryProperties, ImageInfo &imageInfo, Context *context, bool preferCompression,
|
|
MemoryManager *memoryManager, const void *hostPtr, size_t hostPtrMinSize);
|
|
|
|
static void setAllocationInfoFromImageInfo(CreateMemObj::AllocationInfo &allocationInfo, uint32_t rootDeviceIndex, const HardwareInfo &hwInfo,
|
|
const MemoryProperties &memoryProperties, ImageInfo &imageInfo, Context *context, bool preferCompression,
|
|
MemoryManager *memoryManager);
|
|
|
|
static void providePerformanceHintForCreateImage(Image *image, const HardwareInfo &hwInfo, CreateMemObj::AllocationInfo &allocationInfo, Context *context);
|
|
|
|
static void setImageDesriptorIfParentImage(cl_image_desc &imageDescriptor, size_t imageWidth, size_t imageHeight, cl_mem memObject);
|
|
};
|
|
|
|
template <typename GfxFamily>
|
|
class ImageHw : public Image {
|
|
using RENDER_SURFACE_STATE = typename GfxFamily::RENDER_SURFACE_STATE;
|
|
using AUXILIARY_SURFACE_MODE = typename RENDER_SURFACE_STATE::AUXILIARY_SURFACE_MODE;
|
|
|
|
public:
|
|
ImageHw(Context *context,
|
|
const MemoryProperties &memoryProperties,
|
|
cl_mem_flags flags,
|
|
cl_mem_flags_intel flagsIntel,
|
|
size_t size,
|
|
void *memoryStorage,
|
|
void *hostPtr,
|
|
const cl_image_format &imageFormat,
|
|
const cl_image_desc &imageDesc,
|
|
bool zeroCopy,
|
|
MultiGraphicsAllocation multiGraphicsAllocation,
|
|
bool isObjectRedescribed,
|
|
uint32_t baseMipLevel,
|
|
uint32_t mipCount,
|
|
const ClSurfaceFormatInfo &surfaceFormatInfo,
|
|
const SurfaceOffsets *surfaceOffsets = nullptr)
|
|
: Image(context, memoryProperties, flags, flagsIntel, size, memoryStorage, hostPtr, imageFormat, imageDesc,
|
|
zeroCopy, std::move(multiGraphicsAllocation), isObjectRedescribed, baseMipLevel, mipCount, surfaceFormatInfo, surfaceOffsets) {
|
|
|
|
if (!isImage3d(imageDesc.image_type)) {
|
|
this->imageDesc.image_depth = 0;
|
|
}
|
|
|
|
switch (imageDesc.image_type) {
|
|
case CL_MEM_OBJECT_IMAGE1D:
|
|
case CL_MEM_OBJECT_IMAGE1D_BUFFER:
|
|
case CL_MEM_OBJECT_IMAGE1D_ARRAY:
|
|
surfaceType = RENDER_SURFACE_STATE::SURFACE_TYPE_SURFTYPE_1D;
|
|
break;
|
|
default:
|
|
case CL_MEM_OBJECT_IMAGE2D_ARRAY:
|
|
case CL_MEM_OBJECT_IMAGE2D:
|
|
surfaceType = RENDER_SURFACE_STATE::SURFACE_TYPE_SURFTYPE_2D;
|
|
break;
|
|
case CL_MEM_OBJECT_IMAGE3D:
|
|
surfaceType = RENDER_SURFACE_STATE::SURFACE_TYPE_SURFTYPE_3D;
|
|
break;
|
|
}
|
|
}
|
|
|
|
void setImageArg(void *memory, bool setAsMediaBlockImage, uint32_t mipLevel, uint32_t rootDeviceIndex, bool useGlobalAtomics) override;
|
|
void setAuxParamsForMultisamples(RENDER_SURFACE_STATE *surfaceState);
|
|
void setMediaImageArg(void *memory, uint32_t rootDeviceIndex) override;
|
|
void setMediaSurfaceRotation(void *memory) override;
|
|
void setSurfaceMemoryObjectControlState(void *memory, uint32_t value) override;
|
|
void appendSurfaceStateParams(RENDER_SURFACE_STATE *surfaceState, uint32_t rootDeviceIndex, bool useGlobalAtomics);
|
|
void appendSurfaceStateDepthParams(RENDER_SURFACE_STATE *surfaceState, Gmm *gmm);
|
|
void appendSurfaceStateExt(void *memory);
|
|
void transformImage2dArrayTo3d(void *memory) override;
|
|
void transformImage3dTo2dArray(void *memory) override;
|
|
static Image *create(Context *context,
|
|
const MemoryProperties &memoryProperties,
|
|
cl_mem_flags flags,
|
|
cl_mem_flags_intel flagsIntel,
|
|
size_t size,
|
|
void *hostPtr,
|
|
const cl_image_format &imageFormat,
|
|
const cl_image_desc &imageDesc,
|
|
bool zeroCopy,
|
|
MultiGraphicsAllocation multiGraphicsAllocation,
|
|
bool isObjectRedescribed,
|
|
uint32_t baseMipLevel,
|
|
uint32_t mipCount,
|
|
const ClSurfaceFormatInfo *surfaceFormatInfo,
|
|
const SurfaceOffsets *surfaceOffsets) {
|
|
UNRECOVERABLE_IF(surfaceFormatInfo == nullptr);
|
|
auto memoryStorage = multiGraphicsAllocation.getDefaultGraphicsAllocation()->getUnderlyingBuffer();
|
|
return new ImageHw<GfxFamily>(context,
|
|
memoryProperties,
|
|
flags,
|
|
flagsIntel,
|
|
size,
|
|
memoryStorage,
|
|
hostPtr,
|
|
imageFormat,
|
|
imageDesc,
|
|
zeroCopy,
|
|
std::move(multiGraphicsAllocation),
|
|
isObjectRedescribed,
|
|
baseMipLevel,
|
|
mipCount,
|
|
*surfaceFormatInfo,
|
|
surfaceOffsets);
|
|
}
|
|
|
|
static int getShaderChannelValue(int inputShaderChannel, cl_channel_order imageChannelOrder) {
|
|
if (imageChannelOrder == CL_A) {
|
|
if (inputShaderChannel == RENDER_SURFACE_STATE::SHADER_CHANNEL_SELECT_RED ||
|
|
inputShaderChannel == RENDER_SURFACE_STATE::SHADER_CHANNEL_SELECT_GREEN ||
|
|
inputShaderChannel == RENDER_SURFACE_STATE::SHADER_CHANNEL_SELECT_BLUE) {
|
|
return RENDER_SURFACE_STATE::SHADER_CHANNEL_SELECT_ZERO;
|
|
}
|
|
} else if (imageChannelOrder == CL_R ||
|
|
imageChannelOrder == CL_RA ||
|
|
imageChannelOrder == CL_Rx) {
|
|
if (inputShaderChannel == RENDER_SURFACE_STATE::SHADER_CHANNEL_SELECT_GREEN ||
|
|
inputShaderChannel == RENDER_SURFACE_STATE::SHADER_CHANNEL_SELECT_BLUE) {
|
|
return RENDER_SURFACE_STATE::SHADER_CHANNEL_SELECT_ZERO;
|
|
}
|
|
} else if (imageChannelOrder == CL_RG ||
|
|
imageChannelOrder == CL_RGx) {
|
|
if (inputShaderChannel == RENDER_SURFACE_STATE::SHADER_CHANNEL_SELECT_BLUE) {
|
|
return RENDER_SURFACE_STATE::SHADER_CHANNEL_SELECT_ZERO;
|
|
}
|
|
}
|
|
return inputShaderChannel;
|
|
}
|
|
typename RENDER_SURFACE_STATE::SURFACE_TYPE surfaceType;
|
|
};
|
|
|
|
} // namespace NEO
|